okengine 0.3.6 → 0.4.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (89) hide show
  1. package/AGENTS.md +2 -0
  2. package/package.json +12 -12
  3. package/site/content/docs/ai/skills.mdx +5 -3
  4. package/site/content/docs/elements/ai.mdx +2 -0
  5. package/site/content/docs/elements/channel.mdx +2 -0
  6. package/site/content/docs/elements/clock.mdx +1 -4
  7. package/site/content/docs/elements/flow.mdx +4 -10
  8. package/site/content/docs/elements/gate.mdx +2 -0
  9. package/site/content/docs/elements/signal.mdx +1 -5
  10. package/site/content/docs/elements/store.mdx +27 -6
  11. package/site/content/docs/elements/vault.mdx +10 -11
  12. package/site/content/docs/get-started/basic-usage.mdx +76 -41
  13. package/site/content/docs/get-started/installation.mdx +95 -43
  14. package/site/content/docs/get-started/introduction.mdx +128 -75
  15. package/site/content/docs/get-started/meta.json +1 -1
  16. package/site/content/docs/get-started/why.mdx +141 -0
  17. package/site/content/docs/plugins/ip-allowlist.mdx +1 -2
  18. package/site/content/docs/plugins/security-headers.mdx +1 -1
  19. package/site/content/docs/reference/configuration.mdx +1 -1
  20. package/site/content/docs/reference/environment-variables.mdx +5 -3
  21. package/site/content/docs/reference/fx.mdx +16 -3
  22. package/src/cli/competitor-mention-removal.test.ts +117 -0
  23. package/src/cli/dev.ts +20 -0
  24. package/src/cli/meilisearch-local.test.ts +69 -0
  25. package/src/cli/meilisearch-local.ts +188 -0
  26. package/src/compiler/fixtures/skyport/src/flows/payments/index.ts +5 -1
  27. package/src/console/server/store.test.ts +1 -1
  28. package/src/console/server/store.ts +11 -1
  29. package/src/console/ui/dist/assets/index-CjxwRGVv.js +10 -0
  30. package/src/console/ui/dist/assets/panel-access-BGv45snf.js +64 -0
  31. package/src/console/ui/dist/assets/{panel-ai-D_m6WQI8.js → panel-ai-B2S7LEii.js} +1 -1
  32. package/src/console/ui/dist/assets/{panel-architecture-CKnXFyUx.js → panel-architecture-D7UJh91v.js} +1 -1
  33. package/src/console/ui/dist/assets/{panel-channels-DCDd4WAC.js → panel-channels-9T3ybqRu.js} +1 -1
  34. package/src/console/ui/dist/assets/panel-clock-Cb1UXGRQ.js +1 -0
  35. package/src/console/ui/dist/assets/{panel-diff-cdonmH8c.js → panel-diff-DmYbKWmN.js} +1 -1
  36. package/src/console/ui/dist/assets/panel-flows-PiHwT55z.js +48 -0
  37. package/src/console/ui/dist/assets/{panel-gates-B5eTE8XH.js → panel-gates-BQGYXvjT.js} +1 -1
  38. package/src/console/ui/dist/assets/panel-overview-BBnRO18l.js +1 -0
  39. package/src/console/ui/dist/assets/{panel-plugins-Cj7DK1er.js → panel-plugins-D0PsmVw2.js} +1 -1
  40. package/src/console/ui/dist/assets/panel-runs-CWuRDe0r.js +1 -0
  41. package/src/console/ui/dist/assets/{panel-signals-whmDXIg3.js → panel-signals-Bbg4ewpP.js} +1 -1
  42. package/src/console/ui/dist/assets/{panel-store-CEMHLvaw.js → panel-store-CPCbsDRa.js} +1 -1
  43. package/src/console/ui/dist/assets/panel-traces-DVAzuA_S.js +1 -0
  44. package/src/console/ui/dist/assets/{panel-vault-C9wjbki8.js → panel-vault-D1_MvOmo.js} +1 -1
  45. package/src/console/ui/dist/assets/{rolldown-runtime-CNC7AqOf.js → rolldown-runtime-B0Z9INg1.js} +1 -1
  46. package/src/console/ui/dist/index.html +2 -2
  47. package/src/docker/compose.ts +5 -0
  48. package/src/docker/docker.test.ts +41 -0
  49. package/src/docker/recipes/index.ts +10 -2
  50. package/src/docker/recipes/meilisearch.ts +31 -0
  51. package/src/drivers/conformance.test.ts +16 -1
  52. package/src/drivers/conformance.ts +40 -3
  53. package/src/drivers/index.ts +14 -2
  54. package/src/drivers/libsql.ts +4 -4
  55. package/src/drivers/meilisearch.integration.test.ts +77 -0
  56. package/src/drivers/meilisearch.test.ts +181 -0
  57. package/src/drivers/meilisearch.ts +208 -0
  58. package/src/drivers/memory.ts +4 -4
  59. package/src/drivers/pgvector.ts +6 -6
  60. package/src/drivers/types.ts +93 -12
  61. package/src/drivers/vault-driver-removal.test.ts +6 -0
  62. package/src/drivers/vault-types.ts +4 -4
  63. package/src/elements/ai/runtime.ts +6 -0
  64. package/src/elements/ai.test.ts +22 -0
  65. package/src/elements/store/index-boot.test.ts +49 -7
  66. package/src/elements/store/runtime.ts +50 -15
  67. package/src/elements/store.ts +2 -0
  68. package/src/elements/vault.test.ts +27 -4
  69. package/src/elements/vault.ts +1 -1
  70. package/src/index.ts +4 -0
  71. package/src/kernel/boot-bind/store.test.ts +9 -0
  72. package/src/kernel/boot-bind/store.ts +30 -2
  73. package/src/kernel/concurrency.test.ts +58 -0
  74. package/src/kernel/concurrency.ts +48 -0
  75. package/src/kernel/fx.test.ts +11 -2
  76. package/src/kernel/fx.ts +37 -5
  77. package/src/kernel/index.ts +10 -1
  78. package/src/kernel/redacted.ts +74 -0
  79. package/src/kernel/router.ts +3 -3
  80. package/src/test/provisions.integration.test.ts +1 -1
  81. package/site/content/docs/get-started/comparison.mdx +0 -65
  82. package/src/console/ui/dist/assets/index-CrKMmO__.js +0 -10
  83. package/src/console/ui/dist/assets/panel-access-C0J2D-a2.js +0 -64
  84. package/src/console/ui/dist/assets/panel-clock-DjGGFPzr.js +0 -1
  85. package/src/console/ui/dist/assets/panel-flows-DlCU5zjA.js +0 -45
  86. package/src/console/ui/dist/assets/panel-overview-BsFvDdts.js +0 -1
  87. package/src/console/ui/dist/assets/panel-runs-C0gmnoYL.js +0 -1
  88. package/src/console/ui/dist/assets/panel-traces-BDiAuVSK.js +0 -1
  89. package/src/drivers/vault-infisical.ts +0 -57
@@ -5,31 +5,43 @@ source: README.md
5
5
  icon: Download
6
6
  ---
7
7
 
8
- This page gets you from zero to a running app. Prefer Bun throughout — the engine targets **Bun ≥ 1.3**.
8
+ This page gets you from zero to a running app on Bun. The engine targets
9
+ **Bun ≥ 1.3** — prefer it for install, scaffold, and `oke dev`.
10
+
11
+ <Callout title="The one rule">
12
+ Prefer `bun add okengine` when you want the `oke` CLI on your PATH. JSR (`@omqkhafi/okengine`) is
13
+ the library API only.
14
+ </Callout>
15
+
16
+ ## Quick start
9
17
 
10
18
  <Steps>
11
19
 
20
+ <Step>
12
21
  ### Prerequisites
13
22
 
14
23
  - [Bun](https://bun.sh) ≥ 1.3 (`bun --version`)
15
24
  - A terminal and a code editor
16
25
 
17
- ### Install the package
26
+ </Step>
18
27
 
19
- Add the framework (ships the `oke` CLI):
28
+ <Step>
29
+ ### Install the package
20
30
 
21
31
  ```bash title="Terminal"
22
32
  bun add okengine
23
33
  ```
24
34
 
25
- <Callout title="JSR">
26
- Library API only: `bunx jsr add @omqkhafi/okengine`. Prefer npm / `bun add` when you want the
27
- `oke` CLI on your PATH via the package.
28
- </Callout>
35
+ Library-only via JSR:
29
36
 
30
- ### Scaffold with create-oke
37
+ ```bash title="Terminal"
38
+ bunx jsr add @omqkhafi/okengine
39
+ ```
40
+
41
+ </Step>
31
42
 
32
- Create the standard recommended project layout:
43
+ <Step>
44
+ ### Scaffold with create-oke
33
45
 
34
46
  ```bash title="Terminal"
35
47
  bunx create-oke@latest my-app
@@ -37,74 +49,114 @@ bunx create-oke@latest my-app --template standard
37
49
  bunx create-oke@latest my-app --sql postgres
38
50
  ```
39
51
 
40
- The standard template is the only starter. `--sql postgres` opts into a
41
- `pgTable` schema and pins local, Docker, and production to Postgres; the default
42
- keeps local SQLite with Docker and production on Postgres.
52
+ `standard` is the only starter. Default: local SQLite, Docker/production
53
+ Postgres. `--sql postgres` pins `store.sql` for **local, Docker, and
54
+ production** schema stays dialect-agnostic (`store.schema.table`).
55
+
56
+ </Step>
43
57
 
44
- ### Run the app
58
+ <Step>
59
+ ### Run and verify
45
60
 
46
61
  ```bash title="Terminal"
47
62
  cd my-app
48
63
  oke dev
49
64
  ```
50
65
 
51
- Local mode watches domain schema paths (`schema.ts` / `schema.decl.ts` / `app.ts`)
52
- and auto-runs `oke db push` (drizzle-kit) so the database stays in sync. Opt out
53
- with `oke dev --no-db-push` or `db: { autoPush: false }` in `oke.config.ts`. For
54
- production, generate and apply migrations deliberately:
66
+ Three ports come up together (mnemonic: **O·K·E = 6·5·3**):
67
+
68
+ <Surfaces />
69
+
70
+ Open `http://localhost:6533`. If the Console lists your flows, the install
71
+ worked — **derived, not configured.**
72
+
73
+ </Step>
74
+
75
+ </Steps>
76
+
77
+ ## Local database sync
78
+
79
+ Local mode watches schema paths and auto-runs `oke db push` so the database
80
+ stays in sync. Opt out with `oke dev --no-db-push` or
81
+ `db: { autoPush: false }` in `oke.config.ts`.
82
+
83
+ For production, generate and apply migrations deliberately — never automatic on
84
+ boot:
55
85
 
56
86
  ```bash title="Terminal"
57
87
  oke db generate # write drizzle/*.sql
58
- oke db migrate # apply — never automatic on boot
88
+ oke db migrate # apply
59
89
  ```
60
90
 
61
- Three ports come up together (mnemonic: **O·K·E = 6·5·3**):
62
-
63
- | Port | Surface |
64
- | ------- | -------- |
65
- | `:6530` | Your app |
66
- | `:6533` | Console |
67
- | `:6535` | MCP |
68
-
69
- Open the Console — flows, contracts, effects, and an architecture diagram are already there. **Derived, not configured.**
91
+ ## Docker mode
70
92
 
71
93
  Want Postgres/Redis like production while the app stays on host Bun?
72
94
 
95
+ <DevModes />
96
+
73
97
  ```bash title="Terminal"
74
98
  oke dev --docker # or: oke dev -d
75
99
  # or set the saved default: oke mode docker
76
100
  ```
77
101
 
78
- That uses the `docker` driver profile in `oke.config.ts` (filled from `prod` when omitted). Compose files and credentials land under `docker/` (`.env.docker` beside compose). Host ports — including Mailpit UI / RustFS console extras — are unique per project so multiple apps can run at once. Bare `oke dev` prompts once on a TTY (saved in `.oke/mode`); non-TTY defaults to `local`.
102
+ Uses the `docker` driver profile in `oke.config.ts` (filled from `prod` when
103
+ omitted). Compose and credentials land under `docker/` (`.env.docker` beside
104
+ compose); host ports are unique per project.
79
105
 
80
- The generated env follows each protocol instead of forcing one generic credential shape:
106
+ Bare `oke dev` prompts once on a TTY (saved in `.oke/mode`); non-TTY defaults
107
+ to `local`.
81
108
 
82
- - Postgres: `DATABASE_URL` plus `OKE_STORE_SQL_*`
83
- - Redis: `REDIS_URL` plus `OKE_STORE_KV_PASSWORD`
84
- - S3-compatible files: `S3_ENDPOINT`, `S3_ACCESS_KEY_ID`, `S3_SECRET_ACCESS_KEY`, `S3_BUCKET`, `S3_URL`, `S3_REGION`, and `S3_CONSOLE_URL`
85
- - SMTP email: `SMTP_URL`, `SMTP_HOST`, `SMTP_PORT`, and `MAILPIT_UI_URL` with optional `SMTP_USER` / `SMTP_PASSWORD`
109
+ | Protocol | Env shape (generated) |
110
+ | ------------------- | --------------------------------------------------------------------------------------------------------------- |
111
+ | Postgres | `DATABASE_URL` plus `OKE_STORE_SQL_*` |
112
+ | Redis | `REDIS_URL` plus `OKE_STORE_KV_PASSWORD` |
113
+ | S3-compatible files | `S3_ENDPOINT`, `S3_ACCESS_KEY_ID`, `S3_SECRET_ACCESS_KEY`, `S3_BUCKET`, `S3_URL`, `S3_REGION`, `S3_CONSOLE_URL` |
114
+ | SMTP email | `SMTP_URL`, `SMTP_HOST`, `SMTP_PORT`, `MAILPIT_UI_URL`, optional `SMTP_USER` / `SMTP_PASSWORD` |
86
115
 
87
- Each section also includes commented controls (for example Redis memory policy,
88
- Postgres init options, Bun S3 session tokens, and Mailpit limits). Uncommented
89
- supported controls are preserved when `oke dev --docker` regenerates the file.
116
+ Each section also includes commented controls (Redis memory policy, Postgres
117
+ init options, Bun S3 session tokens, Mailpit limits). Uncommented supported
118
+ controls are preserved when `oke dev --docker` regenerates the file.
90
119
 
91
- ### Verify the install
120
+ ## Troubleshooting
92
121
 
93
- Hit the app (path depends on the template) or open `http://localhost:6533`. If the Console lists your flows, the install worked.
122
+ <Accordions>
94
123
 
95
- </Steps>
124
+ <Accordion title="oke: command not found after install">
125
+ Use `bun add okengine` (npm package), not JSR alone — the CLI ships with the npm distribution. Or
126
+ invoke via `bunx oke dev` from the project.
127
+ </Accordion>
128
+
129
+ <Accordion title="Console is empty / no flows listed">
130
+ Confirm `oke dev` is running and you opened `:6533`, not `:6530`. Flows appear only after the app
131
+ boots and the Manifest is extracted — fix TypeScript errors in the terminal first.
132
+ </Accordion>
133
+
134
+ <Accordion title="Database out of sync after editing schema">
135
+ Local `oke dev` auto-pushes by default. If you passed `--no-db-push` or set `db.autoPush: false`,
136
+ run `oke db push` yourself, or re-enable auto-push.
137
+ </Accordion>
96
138
 
97
- ## Next steps
139
+ </Accordions>
98
140
 
99
- Continue to [Basic Usage](/docs/get-started/basic-usage) for your first Flow,
100
- typed client, and test.
141
+ ## Learn more
142
+
143
+ - [CLI Reference](/docs/reference/cli) — `oke`, `create-oke`, mode, and db commands
144
+ - [Environment variables](/docs/reference/environment-variables) — protocol-shaped env
145
+ - [Configuration](/docs/reference/configuration) — `oke.config.ts` drivers and `db.autoPush`
146
+
147
+ ## Next
101
148
 
102
149
  <Cards>
103
150
  <Card
104
151
  title="Basic Usage"
105
- description="First flows, client, and tests."
152
+ description="Health Flow, typed client, and bun:test."
106
153
  href="/docs/get-started/basic-usage"
107
154
  />
155
+ <Card
156
+ title="Introduction"
157
+ description="The one law, eight elements, ten exports."
158
+ href="/docs/get-started/introduction"
159
+ />
108
160
  <Card
109
161
  title="CLI Reference"
110
162
  description="oke and create-oke commands."
@@ -1,123 +1,176 @@
1
1
  ---
2
2
  title: Introduction
3
- description: Learn the one idea behind okengine — then the eight elements and ten exports.
3
+ description: Learn the one idea behind okengine — then the eight elements and ten exports you will use everywhere.
4
4
  source: docs/spec/unified-theory.md
5
5
  icon: BookOpen
6
6
  ---
7
7
 
8
- OKE is a Bun-first TypeScript backend. You do not learn a pile of unrelated tools (router + queue + cron + websockets). You learn **one sentence**, and everything else follows from it.
8
+ A booking API, a nightly cleanup job, a receipt email, a row-change hook in
9
+ most stacks those are four frameworks. In OKE they are **one species** with one
10
+ shape. Learn the shape once; only the trigger changes.
9
11
 
10
- ## The one law
12
+ <Callout title="The one rule">
13
+ **Every backend behavior is a Flow:** `on(Trigger) → Effects`. There are no separate species
14
+ called endpoints, handlers, consumers, jobs, or workflows.
15
+ </Callout>
11
16
 
12
- > **Every backend behavior is a Flow:** `on(Trigger) → Effects`
17
+ ## Quick start
13
18
 
14
- There are no separate species called endpoints, handlers, consumers, jobs, subscribers, or workflows. There is one species — the **Flow** — and triggers are typed values:
19
+ <Steps>
15
20
 
16
- ```ts title="flows"
17
- on(http.post("/bookings"), createBooking); // "an API endpoint"
18
- on(every("10m"), expireStale); // "a cron job"
19
- on(orderPlaced, sendReceipt); // "a queue consumer"
20
- on(db.table(users).changed("email"), reverify); // "a CDC trigger"
21
- ```
21
+ <Step>
22
+ ### Write one Flow
22
23
 
23
- Same shape every time: a trigger, a flow body, and effects inferred from what that body touches through `fx`.
24
+ Four contracts plus a `do`. This is the standard starter's health check:
24
25
 
25
- <Callout title="Why this lowers the learning curve">
26
- One law one mental model one documentation path → one trace shape → one thing for an AI agent to learn.
26
+ ```typescript title="health"
27
+ import { on, flow, http } from "okengine";
28
+ import { z } from "zod";
27
29
 
28
- **Learning OKE is learning one sentence.**
30
+ export const health = on(
31
+ http.get("/health"),
32
+ flow({
33
+ out: z.object({ ok: z.literal(true) }),
34
+ do: () => ({ ok: true as const }),
35
+ }),
36
+ );
37
+ ```
29
38
 
30
- </Callout>
39
+ </Step>
31
40
 
32
- ## What you get
41
+ <Step>
42
+ ### Change only the trigger
33
43
 
34
- You write TypeScript. At build time OKE extracts a **Manifest** — a machine-readable description of your system. From that Manifest the rest is **derived**, not configured by hand:
44
+ | Trigger | Starts when | Replaces |
45
+ | ---------------------------------- | ------------------ | ------------------ |
46
+ | `http.post("/bookings")` | a request arrives | endpoint · handler |
47
+ | `every("10m")` | time passes | cron job |
48
+ | `orderPlaced` (a signal) | another flow emits | queue consumer |
49
+ | `db.table(users).changed("email")` | a row changes | CDC pipeline |
35
50
 
36
- - Typed client (no separate codegen step to maintain)
37
- - OpenAPI / docs surfaces
38
- - Architecture diagram that _is_ the effect graph
39
- - Console panels, traces, and explorers
40
- - MCP surface for agents (`:6535`)
41
- - Least-privilege capability matrix and cache invalidation keys
51
+ ```typescript title="triggers"
52
+ on(http.post("/bookings"), createBooking);
53
+ on(every("10m"), expireStale);
54
+ on(orderPlaced, sendReceipt);
55
+ on(db.table(users).changed("email"), reverify);
56
+ ```
42
57
 
43
- ## Ten exports
58
+ </Step>
44
59
 
45
- The entire public vocabulary fits in one import:
60
+ <Step>
61
+ ### See what was derived
46
62
 
47
- ```ts title="okengine"
48
- import { on, flow, signal, store, clock, gate, vault, channel, ai, plugin } from "okengine";
49
- ```
63
+ Run `oke dev`. Three surfaces come up together — nothing configured by hand in
64
+ a separate dashboard.
50
65
 
51
- | Export | Role |
52
- | --------- | ----------------------------------------------- |
53
- | `on` | Bind a trigger to a flow |
54
- | `flow` | Define behavior + contracts |
55
- | `signal` | Data in motion (queue / pub-sub / live) |
56
- | `store` | Data at rest (`sql` · `kv` · `files` · `index`) |
57
- | `clock` | Time (cron, delay, sleep, TTL) |
58
- | `gate` | Permission to act (auth, ABAC, limits) |
59
- | `vault` | Secrets and config |
60
- | `channel` | Reach humans (email, SMS, …) |
61
- | `ai` | Reach models / agents |
62
- | `plugin` | Extend the runtime without a ninth element |
66
+ <Surfaces />
63
67
 
64
- Everything else in the docs is derived from these ten names.
68
+ </Step>
65
69
 
66
- ## The eight elements
70
+ </Steps>
67
71
 
68
- Everything a backend has ever needed reduces to eight typed elements. An element earns its place only if it has **irreducible physics**. New infrastructure becomes a new **driver** for an existing element — never a ninth element.
72
+ ## Anatomy
69
73
 
70
- <Features />
74
+ One pipeline. Only the trigger changes between an endpoint, a job, a consumer,
75
+ and a row hook.
71
76
 
72
- <details>
73
- <summary>What each element replaces</summary>
77
+ <FlowShape />
74
78
 
75
- | Element | Replaces the zoo of |
76
- | ----------- | --------------------------------------------------------- |
77
- | **Flow** | endpoint · handler · consumer · job · workflow · webhook |
78
- | **Signal** | queue · pub/sub · stream · websocket · SSE · event bus |
79
- | **Store** | database · cache · KV · file storage · search index |
80
- | **Clock** | cron · delay · timeout · durable sleep · TTL |
81
- | **Gate** | auth · session · ABAC · rate limit · quota · feature flag |
82
- | **Vault** | secrets · config · environment |
83
- | **Channel** | email · SMS · WhatsApp · push |
84
- | **AI** | model calls · prompts · embeddings · agents · RAG |
79
+ | Piece | Role |
80
+ | ------------- | -------------------------------------------------------------- |
81
+ | **Trigger** | How work starts `http`, a signal, `every`, a row change |
82
+ | **Contracts** | `in`, `out`, typed `errors` validated before and after `do` |
83
+ | **`do`** | The body every read, write, emit, and call goes through `fx` |
84
+ | **Effects** | Inferred from those `fx` calls not hand-annotated |
85
85
 
86
- </details>
86
+ | Consequence | Follows from |
87
+ | ---------------------------------- | -------------- |
88
+ | One documentation path | One species |
89
+ | One trace shape | One Flow model |
90
+ | One thing for an AI agent to learn | One law |
87
91
 
88
92
  ## The `fx` rule
89
93
 
90
- **All world access goes through `fx`.** A Flow that imports `node:fs` (or any other side-channel I/O) is a defect.
94
+ **All world access goes through `fx`.** A Flow that imports `node:fs`, calls
95
+ `fetch` directly, or uses `Date.now()` is a defect.
96
+
97
+ | Inferred from `fx` touches | Without hand annotations |
98
+ | -------------------------- | ------------------------ |
99
+ | Cache invalidation keys | Yes |
100
+ | Live queries | Yes |
101
+ | Least-privilege tokens | Yes |
102
+ | Deterministic tests | Yes |
103
+ | Manifest Diff | Yes |
104
+
105
+ ## What the Manifest derives
91
106
 
92
- That single rule is why cache invalidation, live queries, least privilege, deterministic tests, and Manifest Diff can be **inferred** instead of annotated by hand. You will see `fx` in every example from here on.
107
+ At build time OKE extracts a **Manifest** a machine-readable description of
108
+ your system. You do not maintain a second source of truth.
93
109
 
94
- ## Where to go next
110
+ <ManifestPipeline />
95
111
 
96
- Read in this order if you are new:
112
+ | Surface | Port / place | You maintain? |
113
+ | --------------------------------- | ------------------ | ----------------------------- |
114
+ | Typed client (`okengine/client`) | your app code | No separate codegen |
115
+ | Console panels, traces, explorers | `:6533` | No |
116
+ | MCP for agents | `:6535` | No |
117
+ | Architecture diagram | Console | No — it _is_ the effect graph |
118
+ | Capability matrix + cache keys | compiler / runtime | No — from `fx` |
97
119
 
98
- 1. [Comparison](/docs/get-started/comparison) — when OKE fits (and when it doesn't)
99
- 2. [Installation](/docs/get-started/installation) — scaffold an app in minutes
100
- 3. [Basic Usage](/docs/get-started/basic-usage) first flows, client, and tests
101
- 4. [Flow](/docs/elements/flow)triggers, contracts, effects, and composition
120
+ ## Eight elements
121
+
122
+ An element earns its place only if it has **irreducible physics**. New
123
+ infrastructure becomes a new **driver** never a ninth element.
124
+
125
+ <Features />
126
+
127
+ | Element | Essence | Replaces the zoo of |
128
+ | ----------- | ----------------------------- | --------------------------------------------------------- |
129
+ | **Flow** | behavior | endpoint · handler · consumer · job · workflow · webhook |
130
+ | **Signal** | data in motion | queue · pub/sub · stream · websocket · SSE · event bus |
131
+ | **Store** | data at rest | database · cache · KV · file storage · search index |
132
+ | **Clock** | time | cron · delay · timeout · durable sleep · TTL |
133
+ | **Gate** | permission to act | auth · session · ABAC · rate limit · quota · feature flag |
134
+ | **Vault** | protected knowledge | secrets · config · environment |
135
+ | **Channel** | reaching humans | email · SMS · WhatsApp · push |
136
+ | **AI** | reaching machine intelligence | model calls · prompts · embeddings · agents · RAG |
137
+
138
+ ## Ten exports
139
+
140
+ The entire public vocabulary fits in one import. Everything else in the docs is
141
+ derived from these ten names:
142
+
143
+ ```ts title="okengine"
144
+ import { on, flow, signal, store, clock, gate, vault, channel, ai, plugin } from "okengine";
145
+ ```
146
+
147
+ <Vocabulary />
148
+
149
+ ## Learn more
150
+
151
+ | Topic | Page |
152
+ | ------- | ------------------------------------------------------------------------------- |
153
+ | Why OKE | [Why OKE](/docs/get-started/why) |
154
+ | Flow | [Flow](/docs/elements/flow) |
155
+ | `fx` | [fx](/docs/reference/fx) |
156
+ | Agents | [MCP](/docs/ai/mcp) · [Skills](/docs/ai/skills) · [llms.txt](/docs/ai/llms-txt) |
157
+
158
+ ## Next
102
159
 
103
160
  <Cards>
104
161
  <Card
105
- title="Comparison"
106
- description="Positioning matrix against Hono, Elysia, Encore.ts, and iii."
107
- href="/docs/get-started/comparison"
162
+ title="Why OKE"
163
+ description="Traditional backend pain and what Manifest derivation closes."
164
+ href="/docs/get-started/why"
108
165
  />
109
166
  <Card
110
167
  title="Installation"
111
- description="Install okengine and scaffold with create-oke."
168
+ description="Scaffold with create-oke and open the Console."
112
169
  href="/docs/get-started/installation"
113
170
  />
114
171
  <Card
115
172
  title="Basic Usage"
116
- description="Flows, typed client, and tests from the Notes example."
173
+ description="Health Flow, typed client, and bun:test."
117
174
  href="/docs/get-started/basic-usage"
118
175
  />
119
176
  </Cards>
120
-
121
- ## AI resources
122
-
123
- `AGENTS.md` and MCP (`:6535`) expose the Manifest, schemas, effects, traces, and the Console's safe runtime actions. See [MCP](/docs/ai/mcp) for the runtime server, [Skills](/docs/ai/skills) for the agent contract, and [llms.txt](/docs/ai/llms-txt) for the machine-readable docs (`/llms.txt`, `/llms-full.txt`).
@@ -1,5 +1,5 @@
1
1
  {
2
2
  "title": "Get Started",
3
3
  "icon": "Rocket",
4
- "pages": ["introduction", "comparison", "installation", "basic-usage"]
4
+ "pages": ["introduction", "why", "installation", "basic-usage"]
5
5
  }
@@ -0,0 +1,141 @@
1
+ ---
2
+ title: Why OKE
3
+ description: The six seams every TypeScript backend maintains by hand — and what OKE derives from one Manifest instead.
4
+ source: docs/spec/unified-theory.md
5
+ icon: Compass
6
+ ---
7
+
8
+ Every TypeScript backend works on day one. The bill arrives later: the cache
9
+ that serves last month's schema, the secret that only exists on your laptop,
10
+ the dashboard that has never heard of your new Flow.
11
+
12
+ None of these are router problems. They are **seams** — copies of your code's
13
+ knowledge, kept in places the compiler cannot check, updated by memory.
14
+
15
+ <Callout title="The one rule">
16
+ **All world access goes through `fx`.** What a Flow reads, writes, emits, and reveals is recorded
17
+ — so the seams below are derived from one Manifest, not re-typed per project.
18
+ </Callout>
19
+
20
+ ## The six seams
21
+
22
+ ### The cache that lies
23
+
24
+ You add a column to `orders` and update three writers. The hand-bumped cache
25
+ key in `checkout` is not one of them. A customer finds it a week later.
26
+
27
+ **OKE derives:** reads and writes are recorded through `fx`, so invalidation
28
+ follows the Flow — there is no separate key to remember.
29
+
30
+ ### The secret that fails in prod
31
+
32
+ `STRIPE_KEY` lives in your laptop's `.env`, a README, and a teammate's shell
33
+ history. The deploy boots fine — the first charge request dies at 2am.
34
+
35
+ **OKE derives:** [Vault](/docs/elements/vault) contracts declare the need in
36
+ code; boot resolves every contract and fails loud with every gap listed —
37
+ never halfway.
38
+
39
+ ### The glue you rewrite
40
+
41
+ CORS rules, security headers, CSRF tokens, compression — copied from the last
42
+ repo, tweaked, and already drifting from whatever that repo does today.
43
+
44
+ **OKE derives:** the official `okengine/plugins` set ships this glue once —
45
+ shared lifecycle, optional live DB config, nothing to re-copy.
46
+
47
+ ### The dashboard that doesn't know you
48
+
49
+ Your observability stack learned your routes from sampled traffic. The Flow
50
+ you deployed an hour ago is invisible until someone wires it by hand.
51
+
52
+ **OKE derives:** the [Console](/docs/console/overview) reads the Manifest —
53
+ flows, effects, traces, architecture — current on every save, in dev and prod
54
+ (`:6533`).
55
+
56
+ ### The permission check in the wrong place
57
+
58
+ `if (!user.isAdmin)` sits in handler forty-one of sixty. Which Flows touch
59
+ `payments`? grep answers slowly; review answers never.
60
+
61
+ **OKE derives:** declared effects produce a least-privilege matrix — widening
62
+ access appears in Manifest Diff, not in a diff nobody reads.
63
+
64
+ ### Local works, prod doesn't
65
+
66
+ Local runs one vendor client, CI another, prod a third — three glue stories
67
+ for the same database. "Works on my machine" is a driver mismatch.
68
+
69
+ **OKE derives:** drivers are named after protocols (`postgres`, `redis`,
70
+ `s3`), the vendor lives in `images`, and `oke dev --docker` runs the real
71
+ stack locally.
72
+
73
+ ## The tax is drift
74
+
75
+ Every seam above is the same shape: a hand-maintained copy of knowledge the
76
+ code already has. Watch one change propagate both ways.
77
+
78
+ <DriftBoard />
79
+
80
+ On the left, versions scatter and stay scattered. On the right, one Manifest
81
+ feeds five surfaces — they cannot disagree, because none of them is a copy.
82
+
83
+ ## The answer's shape
84
+
85
+ Forty infrastructure concerns collapse into eight elements — each kept only
86
+ because it has irreducible physics. One change costs up to fifteen seams in
87
+ the zoo; here it always costs two.
88
+
89
+ <CollapseBoard />
90
+
91
+ New infrastructure becomes a **driver** for an existing element, never a
92
+ ninth element — the set of eight is closed.
93
+
94
+ ## Traditional vs OKE
95
+
96
+ | Seam | Maintained by hand | Derived by OKE |
97
+ | ------------------ | --------------------------------------------------------- | ------------------------------------------------------------------------------- |
98
+ | Behavior model | Endpoints, jobs, consumers, workflows as separate species | One species — Flow: `on(Trigger) → Effects` |
99
+ | Cache invalidation | Hand-written keys; drift from writers | Derived from effects recorded through `fx` |
100
+ | HTTP glue | Middleware copied per repo | Official plugins — `securityHeaders`, `cors`, `csrf`, compression, IP allowlist |
101
+ | Secrets / config | Env sprawl; fails on first request | Vault contracts; `VaultBootError` at boot |
102
+ | Observability | Bolted on; separate source of truth | Console from the Manifest, dev and prod (`:6533`) |
103
+ | Permissions | Ad-hoc checks scattered in handlers | Least-privilege matrix from declared effects |
104
+ | Local vs prod | Vendor clients; one-off compose | Protocol drivers; vendor in `images`; `oke dev --docker` |
105
+ | Client / agents | Separate codegen or hand-kept schemas | Typed client and MCP (`:6535`) from the same Manifest |
106
+
107
+ ## Ambition, stated plainly
108
+
109
+ | | Statement |
110
+ | --------------- | ------------------------------------------------------------------------------------------------ |
111
+ | **Ambition** | The default, most capable TypeScript backend — Bun-first, Web-Standards portable, contract-first |
112
+ | **Grounded in** | Eight elements, effect inference through `fx`, Gate and Vault, the official plugin set |
113
+ | **Maturity** | **pre-1.0** — published and usable; not independently battle-tested at scale yet |
114
+
115
+ ## Learn more
116
+
117
+ - [Introduction](/docs/get-started/introduction) — the one law, eight elements, ten exports
118
+ - [Flow](/docs/elements/flow) — how effects are recorded and inferred
119
+ - [Vault](/docs/elements/vault) — fail-loud secret contracts
120
+ - [Plugins](/docs/reference/plugins) — the official HTTP glue set
121
+ - [Console · Overview](/docs/console/overview) — the Manifest-derived operator UI
122
+
123
+ ## Next
124
+
125
+ <Cards>
126
+ <Card
127
+ title="Installation"
128
+ description="Scaffold with create-oke and open the Console."
129
+ href="/docs/get-started/installation"
130
+ />
131
+ <Card
132
+ title="Basic Usage"
133
+ description="Health Flow, typed client, and bun:test."
134
+ href="/docs/get-started/basic-usage"
135
+ />
136
+ <Card
137
+ title="Introduction"
138
+ description="The one law, eight elements, ten exports."
139
+ href="/docs/get-started/introduction"
140
+ />
141
+ </Cards>
@@ -46,8 +46,7 @@ A client whose IP is not on the list receives `403` with a typed denial:
46
46
  <Callout type="error">
47
47
  Standard reverse proxies **append** to `X-Forwarded-For` — left-side hops are attacker-controlled.
48
48
  The plugin trusts the hop `trustedProxyDepth` from the **right** (default `1` = last hop). Set
49
- this to your real proxy count — wrong depth bypasses the allowlist (topology-dependent, not
50
- drop-in).
49
+ this to your real proxy count — wrong depth bypasses the allowlist.
51
50
  </Callout>
52
51
 
53
52
  ## Notes
@@ -51,7 +51,7 @@ Every [helmet.js](https://helmet.js.org/) middleware maps to an option here —
51
51
  | `xPoweredBy` | `poweredBy` | Yes — removed; a string sets a decoy value |
52
52
  | `xXssProtection` | `xssProtection` | Yes — `0` (disables the legacy buggy auditor) |
53
53
 
54
- Beyond parity: headers land on **failures too** (helmet middleware ordering bugs are a classic Express footgun), app-set values win by default, and every option can be driven live from the database (below).
54
+ Beyond parity: headers land on **failures too** (middleware that only wraps happy paths skips error responses), app-set values win by default, and every option can be driven live from the database (below).
55
55
 
56
56
  ## Options
57
57
 
@@ -39,7 +39,7 @@ drivers: {
39
39
  | `store.sql` | env driver map | `sqlite` · `postgres` · `libsql` · `pglite` · `memory` |
40
40
  | `store.kv` | env driver map | `memory` · `redis` |
41
41
  | `store.files` | env driver map | `memory` · `fs` · `s3` |
42
- | `store.index` | env driver map | `memory` · `pgvector` · `libsql` |
42
+ | `store.index` | env driver map | `memory` · `pgvector` · `libsql` · `meilisearch` |
43
43
  | `signal` | env driver map | `memory` · `postgres` · `redis` · `nats` |
44
44
  | `clock` | env driver map | `memory` · `postgres` · `frozen` |
45
45
  | `vault` | env driver map | `dotenv` · `openbao` · `memory` |
@@ -24,9 +24,11 @@ OKE reads environment variables at boot for connection detail and secrets — ne
24
24
 
25
25
  ## Index store
26
26
 
27
- | Variable | Used for | Default when unset |
28
- | ------------------ | ------------------------- | ------------------ |
29
- | `OKE_INDEX_DRIVER` | Force the index driver id | config map |
27
+ | Variable | Used for | Default when unset |
28
+ | --------------------- | --------------------------------------------------- | ------------------ |
29
+ | `OKE_INDEX_DRIVER` | Force the index driver id | config map |
30
+ | `OKE_STORE_INDEX_URL` | Meilisearch base URL (`meilisearch` driver) | — |
31
+ | `OKE_STORE_INDEX_KEY` | Meilisearch API / master key (`meilisearch` driver) | `MEILI_MASTER_KEY` |
30
32
 
31
33
  ## KV store
32
34