0.11

Every published okengine release, newest first.

all series ยท 0.12 ยท 0.10

v0.11.2

โœจ Added

  • Prompt recovery + deadline: smart.prompt(name, { via: ["smart", "local"], timeout: "30s" }). fx.ask walks the chain with one same-model retry on retryable errors (timeout / 429 / 5xx), stops on permanent failures (401 / schema), stamps winning via on the result, and throws when the chain is exhausted. Ask-time { via, timeout } overrides the prompt.

๐Ÿ”’ Security

  • Built-in Vault rotateMaster takes a Clock/Signal-class lease (FOR UPDATE SKIP LOCKED + lease-expiry on oke_vault_status): concurrent rotators โ€” exactly one wins; the other fails loud before any DEK rewrite, so no DEK can end up wrapped under an unsaved key.
  • Audit appends serialize with SELECT โ€ฆ FOR UPDATE on the status singleton inside a transaction, so concurrent writers cannot fork the hash chain.
  • oke vault backup writes temp โ†’ fsync โ†’ atomic rename; bundles include a trailing oke-vault-backup-end marker and payload SHA-256 checked before decrypt (incomplete files no longer look restore-ready).

โ™ป๏ธ Changed

  • Durable local markers move to .oke/state.json (seededAt after the one-shot seed prompt). Legacy .oke/seeded migrates once then is removed. .oke/dev.json stays the live session lock; .oke/console.secret stays Console signing (not Vault).
  • llama.cpp entrypoint now lands in .oke/llama-entrypoint.py (generated / gitignored) instead of docker/ โ€” app trees stay TypeScript-only; compose mounts ../.oke/โ€ฆ. Stale docker/llama-entrypoint.py is pruned on derive.
  • OKE1008 / OKE1009 copy now says dev+compose/prod (ConfigEnv collapse), matching the boot warn strings.

๐Ÿ› Fixed

  • Collapse diagram hub nodes: opaque background plates mask spoke junctions; dimming hits stroke/label only so symbols stay readable on dark cards.
  • Landing element lattice: header/footer readout swaps stay absolute so the idle beat no longer briefly doubles chrome height on every step.
  • Collapse diagram hub nodes: idle element discs use a muted-into-card fill (no stroke) so dimmed symbols stay readable on dark cards.
  • create-oke: locales and PgDog answers now always write to ~/.oke/create-defaults.json (reuse / recommended), not only after customize โ€” so Previous settings keep ar / PgDog across runs.
  • oke dev schema sync: a broken schema.decl.ts (table / relation definition error) now prints a red โ— schema.decl.ts has an error โ€” โ€ฆ line instead of the soft oke db push (dev) skipped โ€” โ€ฆ framing that looked like a benign skip. Environmental gaps (no config / no images) still soft-skip; the session stays up.
  • Share one warmed in-memory PGlite per remaining dialect test file (sql-session / resource / index-boot) and raise beforeAll hook budgets to 15s so Bun does not mis-report cold WASM as a hook timeout
  • createTestApp again forces in-process memory SQL (and drops the per-harness on-disk PGLite datadir). After v0.11 made STORE_SQL_DEFAULTS.test PGLite, kernel tests that insert via the harness were paying cold WASM+pgvector init (~5s) and timing out โ€” dialect tests still opt into PGLite via boot.config.drivers.store.sql.
  • Vault logic-only unit tests (oke vault init/status seal-state CLI, security checklist audit-tamper) use an in-memory Vault SQL fake instead of cold PGlite WASM โ€” dialect proof stays on builtin-adapter.test.ts.
  • Vault/Console dialect tests share one warmed in-memory PGlite per file (beforeAll + TRUNCATE between cases) so cold WASM is paid once, not per test โ€” builtin-adapter, vault-cmd dialect cases, vault-builtin, and operator-db persistence.

v0.11.1

โ™ป๏ธ Changed

  • HTTP-only cold graphs drop kv-lua: gate.public / gate.rate defaults read DEFAULT_RATE_STRATEGY from gate/constants (strategies load only with the rate runtime).
  • oke() narrows compiler imports to dynamic + response (no extract/oxc barrel on the HTTP construction path) and defers the memory journal store until first durable use.
  • gate.auth materialization is sync-lazy via requirePackageModule (kernel/app-auth, auth/config) with matching dist/app-auth.js + dist/auth-config.js chunks for non-Bun consumers โ€” ping apps no longer pay the auth/zod graph up front.
  • Refreshed budgets.json / BUDGETS.md after the cold-graph cuts: Bun cold start ~9 ms (under the 75 ms cap), HTTP-ping gzip ~36 kB, and thinner okengine / http / kernel / gate / auth-plugin export rows.

v0.11.0

โœจ Added

  • fx.step(name, fn, { undo }) โ€” declare durable per-step compensation next to the forward work; on terminal failure the runtime runs undos LIFO as journaled undo:<name> steps under status compensating (resume-safe; execute + orphan paths).
  • Shared durable compensation phase (runCompensationPhase) so orphan/sleep resume undoes the same way as app.execute; flow.compensate still runs after auto undos.
  • Interactive oke TUI (Ink + React): bare oke on a TTY opens Dashboard / Dev / Database / Docker / Navigator panels; oke --tui forces it; non-TTY keeps help.
  • Headless DevController + .oke/dev.json session lock so a second oke can attach as Connected without starting another stack (never kills a foreign pid).
  • oke db studio โ€” drizzle-kit Studio under the same env overlay as other db commands.
  • Built-in encrypted Vault (drivers.vault: "vault") โ€” PostgreSQL/PGlite envelope encryption (AES-256-GCM + HKDF), seal/unseal, versioned secrets, resumable rotate-master, hash-chained audit, versioned backup with a separate backup KEK, and oke vault init|status|seal|unseal|rotate|rotate-master|audit|purge-expired|backup|restore.
  • vault.env / .required / .int / .bool / .json โ€” sync env helpers; required names join boot gaps before any SQL connection opens.
  • Managed Vault provider: AWS Secrets Manager (optional peer @aws-sdk/client-secrets-manager); Azure/GCP/Doppler/1Password return a clear UNSUPPORTED error. Community adapters can extend managed.
  • Optional peer @aws-sdk/client-kms for KMS auto-unseal of the built-in master key.
  • Console Vault status card (initialized / sealed / KEK generation / counts) for the built-in backend; create-oke defaults docker/prod Vault to the built-in store.
  • OkeConfig.vault element config + oke doctor warning when prod would use an env-sourced master key with the built-in Vault.
  • okengine/http, okengine/kernel, okengine/full, okengine/i18n, okengine/compiler, and okengine/journal package entries for slim imports.
  • bun run build:lib prebuilds tree-shaken ESM under dist/ (Bun still resolves src/ via the "bun" export condition; Node "import" uses dist).
  • HTTP-ping app budget samples (raw + gzip) and cold-start probe via okengine/http.
  • Upgrade codemod 0.10.3-thin-root-subpaths for deep imports that left the thin root.
  • oke test โ€” sets test posture (NODE_ENV=test, PGLite URL defaults) and runs bun test. Apps should add @electric-sql/pglite as a devDependency.

โ™ป๏ธ Changed

  • create-oke starters load locales from src/core.ts via src/locales/index.ts, so app.ts only needs one import "@/core" (no per-locale imports).
  • Durable runDurable treats returned fx.fail as terminal failure (runs undo/ compensate) and refuses to resume failed / completed journal runs โ€” crash recovery stays on running / sleeping / compensating orphans.
  • Default local AI is **openai-compatible** (llama.cpp) with model granite3.3:2b (was smollm2); env examples, oke ai setup --yes, create-oke Recommended, and the llama.cpp recipe share that default. Ollama remains a fully supported alternative.
  • Default domain Drizzle emit path is src/db/schema.drizzle.ts (was schema.generated.ts). Existing src/db/schema.generated.ts / src/schema.generated.ts paths still resolve; update db.generated and drizzle.config.ts when ready.
  • Generated docker-compose.yml (and split/stack compose files) now separate services with blank lines and role comments (# ai โ€” โ€ฆ, # store.sql โ€” โ€ฆ), matching the .env.docker section style.
  • create-oke standard / advanced ship a single src/core.ts (store, gates, vault, channels) instead of src/core/*; oke ai setup and locale apply merge into that file (legacy src/core/ still supported).
  • oke ai setup / create-oke write OKE_AI_MODEL as a **commented** hint in .env.local (same as OKE_AI_DRIVER / OKE_AI_URL) so it does not shadow docker/.env.docker. First-boot stack seeding still reads the commented value.
  • oke schema generate writes .oke/schema/oke.ts (not root schema/); create-oke emits it on scaffold / after install; oke db push|generate refreshes stubs when plugins change. drizzle.config is postgresql-only.
  • create-oke standard / advanced oke.config.ts pins only driver keys that differ from DRIVER_DEFAULTS (e.g. vault: { dev: "vault" }); customize / reuse upserts sparse maps the same way.
  • create-oke asks whether to add PgDog pooling in front of Postgres (--pgdog / --no-pgdog; default off for --yes). Templates no longer pin images.pgdog until opted in.
  • create-oke defaults to English-only i18n; the wizard asks whether to add more languages (ar or ar,fr, โ€ฆ) and --locales works non-interactively. Bootโ€™s implicit locale list is now ["en"] (was ["en", "ar"]).
  • Docker TUI: list services by compose project (oke-dev-<id>); clean picks whole stacks (not per-service) inside Ink โ€” no clack overlay fighting the frame.
  • Interactive oke TUI polish: clear viewport before Ink; green OKE wordmark + version; green active tabs / cyan focus; Esc focus layers; quieter chrome; panel-specific Dev/Database/Docker/Navigator layouts; aligned service tables; footer shortcuts + status; spinners and empty states.
  • create-oke scaffolds ship docker/docker-compose.yml + production-grade defaults (same derive path as oke docker); oke dev --docker regenerates a single infra-only docker-compose.yml.
  • TUI / command palette with Tab autofill over the full oke CLI (+ panel jumps).
  • oke dev interactive chrome uses Ink (useInput for ? r q u x) instead of custom ANSI rewritable boards / raw-mode stdin. Plain log formatters remain in term.ts.
  • create-oke templates pin built-in Vault for prod and document OKE_VAULT_MASTER_KEY / managed AWS Secrets Manager env vars.
  • oke() lazy-loads auth modules, FormatJS (intl-messageformat), the RegExp router (when not on the edge preset), and fx.runs window helpers; memory journal fallback is created on first use. Small all-static HTTP apps auto-select the edge router. gate.public no longer pulls rate-strategy Lua registration.
  • @duckdb/node-api, ajv, ajv-formats, and oxc-parser are optional peer dependencies (install when using Runs DuckDB, Manifest Ajv validate, or oxc extract).
  • create-oke app entry and get-started docs prefer okengine/http.
  • Starter templates and create-oke scaffold emit {dev,test,prod} maps, PostgreSQL drizzle defaults, committed compose artefacts, and "test": "oke test". PGLite packages are template devDependencies.
  • Doctor / db / hero-meta env flags use dev|test|prod.
  • Abstract integer columns ensure as BIGINT on Postgres/PGLite so millisecond timestamps are safe (SQLite INTEGER affinity no longer covers local-dev).
  • create-oke's local file: okengine stage skips a fresh bun install when the staged package.json and peers are already present (still refreshes package source files).

๐Ÿ’ฅ Breaking Changes

  • Console operator persistence no longer uses .oke/console.sqlite. Operators and sessions live in Postgres schema oke_console on the same database as the app (DATABASE_URL / OKE_STORE_SQL_URL; public stays for app tables). Without a Postgres URL, Console falls back to PGlite under .oke/console-pg. Delete stale console.sqlite* files and re-claim the Console once after upgrading.
  • oke schema generate default output moves from schema/oke.ts to .oke/schema/oke.ts. Re-run generate (or delete the old schema/ folder). --check still accepts a correct legacy file once during migrate.
  • oke docker defaults to a single production-grade docker/docker-compose.yml (plus Dockerfile) instead of layered compose.yml + compose.<role>.yml + compose.all.yml. Opt into --split or --stack (docker-stack.yml).
  • PgDog configs move to docker/pgdog/pgdog.toml and docker/pgdog/users.toml (was flat docker/pgdog.toml + docker/users.toml).
  • oke docker enables production overlays by default (readiness HEALTHCHECK, deploy policy, resource limits). Pass --no-prod for a bare derive. Resource limits are apportioned from a default **4 CPU / 8 GiB** host budget (--cpus / --memory to override).
  • drivers.vault: "openbao" is no longer valid. Use "vault" (built-in) or "managed" with OKE_VAULT_PROVIDER=aws-secrets-manager. OpenBao is not an official core backend.
  • fx.vault(secret) is now an object surface: use await fx.vault.get(secret) (still returns Redacted<string>). Mutations (set / rotate / delete / list / status) require a bound built-in Vault adapter.
  • Default drivers.vault.prod is "vault" (built-in) instead of "env". Prefer masterKey.source: "kms" in production, or managed + AWS Secrets Manager.
  • The root okengine entry is now a **thin** surface (ten exports + oke + HTTP runtime). Deep helpers such as createRunsRuntime, journal store factories, compileAot / extract, and boot internals move to subpaths (okengine/runs, okengine/journal, okengine/compiler, okengine/full). Prefer okengine/http for HTTP-only apps; use oke upgrade for the codemod. The previous mega-barrel remains as deprecated okengine/full.
  • Config environments collapse to three targets: dev / test / prod (replacing local / docker / test / prod). Bare driver strings expand to all three; missing dev fills from prod. No soft-compat and no upgrade codemod โ€” edit oke.config.ts by hand (see Configuration). The CLI errors if oke.config.ts still contains a local: key or "sqlite" pin.
  • oke dev always uses Docker Compose (OKE_DOCKER=1). --local / -l and oke mode local|docker are removed (oke mode exits with a migration hint).
  • The sqlite and libsql SQL drivers are removed. Pin postgres for dev / prod and pglite for test. defineConfig rejects any sqlite / libsql pin and requires drivers.store.sql.test === "pglite". Loading config via the CLI also rejects "sqlite" in source.
  • Default driver maps now follow the Docker-first / PGLite-test philosophy (see src/config/driver-defaults.ts and Configuration docs).

๐Ÿ”ฅ Removed

  • OpenBao adapter, docker recipe, bootstrap (oke dev unseal), and recipe docs from core. Official vault backends: built-in (vault), ENV, AWS Secrets Manager via managed. ManagedAdapter / createManagedVaultBag stay open for community plugins.
  • SQLite-family SQL drivers (sqlite, libsql / @libsql/client), laptop-only oke mode, and four-key env maps as the supported config surface. Vector index libsql is gone โ€” use pgvector (with postgres/pglite SQL) or memory. Drizzle emit/kit dialect is postgresql only. Migrate by hand (see Configuration); no env-model codemod.

๐Ÿ› Fixed

  • oke dev no longer reprints the elements/Docker board on every AI/compose health update (anchored in-place rewrite restored).
  • Domain schema emit writes bigint(โ€ฆ, { mode: "number" }) so oke db push no longer crashes with config.mode on abstract integer columns.
  • create-oke templates use @/ imports consistently (app, seed, tests) with an @/* path map (no deprecated baseUrl โ€” TypeScript 6+); locale scaffolding writes @/locales/<tag> too.
  • create-oke standard / advanced note flows no longer hand-declare effects โ€” the compiler infers them from fx usage (same as current Flow docs).
  • Store list-docs fixture tests pass stores: [โ€ฆ] explicitly so a second oke() after registry consume no longer falls back to .oke/pgdata and 500s.

๐Ÿ”’ Security

  • Redacted now masks valueOf / util.inspect (and Redacted.of / .map) so accidental HTTP JSON or console formatting cannot leak vault cleartext.
  • oke vault master keys accept --key - (stdin) or a hidden TTY prompt; help warns against putting keys on argv in shared shells (history risk).
  • Built-in Vault SQL retries transient Postgres/network blips; audit appends stay off the retry path so the hash chain is never duplicated.
  • oke vault purge-expired [--dry-run] [--before] hard-deletes expired secret rows (expires_at) with a single count-only audit purge event.
  • Envelope AAD binds path|version|algorithm|kek_version; master key lives only inside an Unsealer closure; VaultError never attaches crypto-bearing cause s; audit rows never store secret values; backups encrypt under a domain-separated backup KEK.