okengine 0.3.6 → 0.5.0
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.
- package/AGENTS.md +2 -0
- package/package.json +14 -12
- package/site/content/docs/ai/index.mdx +24 -0
- package/site/content/docs/ai/llms-txt.mdx +3 -0
- package/site/content/docs/ai/meta.json +1 -1
- package/site/content/docs/ai/skills.mdx +5 -3
- package/site/content/docs/console/gates.mdx +46 -8
- package/site/content/docs/console/index.mdx +54 -0
- package/site/content/docs/console/meta.json +1 -0
- package/site/content/docs/elements/ai.mdx +2 -0
- package/site/content/docs/elements/channel.mdx +2 -0
- package/site/content/docs/elements/clock.mdx +1 -4
- package/site/content/docs/elements/flow.mdx +4 -10
- package/site/content/docs/elements/gate.mdx +189 -48
- package/site/content/docs/elements/index.mdx +45 -0
- package/site/content/docs/elements/meta.json +1 -1
- package/site/content/docs/elements/signal.mdx +1 -5
- package/site/content/docs/elements/store.mdx +27 -6
- package/site/content/docs/elements/vault.mdx +10 -11
- package/site/content/docs/get-started/basic-usage.mdx +79 -43
- package/site/content/docs/get-started/index.mdx +33 -0
- package/site/content/docs/get-started/installation.mdx +95 -43
- package/site/content/docs/get-started/introduction.mdx +128 -75
- package/site/content/docs/get-started/meta.json +1 -1
- package/site/content/docs/get-started/why.mdx +141 -0
- package/site/content/docs/index.mdx +9 -31
- package/site/content/docs/plugins/anonymous.mdx +95 -0
- package/site/content/docs/plugins/compression.mdx +2 -2
- package/site/content/docs/plugins/cors.mdx +2 -2
- package/site/content/docs/plugins/csrf.mdx +2 -2
- package/site/content/docs/plugins/email-otp.mdx +111 -0
- package/site/content/docs/plugins/{security-headers.mdx → headers.mdx} +2 -2
- package/site/content/docs/plugins/index.mdx +69 -0
- package/site/content/docs/plugins/ip-allowlist.mdx +1 -2
- package/site/content/docs/plugins/magic-link.mdx +112 -0
- package/site/content/docs/plugins/maintenance-mode.mdx +8 -8
- package/site/content/docs/plugins/meta.json +10 -1
- package/site/content/docs/plugins/passkey.mdx +128 -0
- package/site/content/docs/plugins/phone-number.mdx +111 -0
- package/site/content/docs/plugins/two-factor.mdx +116 -0
- package/site/content/docs/plugins/username.mdx +117 -0
- package/site/content/docs/reference/client.mdx +331 -0
- package/site/content/docs/reference/configuration.mdx +1 -1
- package/site/content/docs/reference/environment-variables.mdx +5 -3
- package/site/content/docs/reference/fx.mdx +36 -8
- package/site/content/docs/reference/index.mdx +45 -0
- package/site/content/docs/reference/meta.json +11 -1
- package/site/content/docs/reference/plugins.mdx +25 -14
- package/src/auth/auth.test.ts +20 -2
- package/src/auth/bindings.ts +439 -0
- package/src/auth/breach-check.ts +112 -0
- package/src/auth/config.ts +288 -0
- package/src/auth/cookies.ts +123 -0
- package/src/auth/gate-auth.test.ts +379 -0
- package/src/auth/identity.ts +190 -0
- package/src/auth/index.ts +117 -1
- package/src/auth/method-context.ts +33 -0
- package/src/auth/operator.ts +27 -1
- package/src/auth/password-policy.test.ts +126 -0
- package/src/auth/password-policy.ts +77 -0
- package/src/auth/plugin.ts +62 -4
- package/src/auth/rate.ts +45 -0
- package/src/auth/schema.ts +260 -0
- package/src/auth/secondary-storage.ts +37 -0
- package/src/auth/sessions.ts +58 -1
- package/src/auth/tables.ts +4 -0
- package/src/auth/verification.ts +78 -0
- package/src/cli/competitor-mention-removal.test.ts +117 -0
- package/src/cli/dev.test.ts +3 -3
- package/src/cli/dev.ts +20 -0
- package/src/cli/meilisearch-local.test.ts +69 -0
- package/src/cli/meilisearch-local.ts +188 -0
- package/src/cli/schema.ts +95 -23
- package/src/client/auth.ts +120 -0
- package/src/client-react/index.ts +93 -0
- package/src/compiler/aot.test.ts +2 -1
- package/src/compiler/extract.ts +19 -0
- package/src/compiler/fixtures/skyport/src/flows/payments/index.ts +5 -1
- package/src/compiler/response.ts +16 -2
- package/src/console/server/app.ts +10 -6
- package/src/console/server/auth-rate.test.ts +3 -3
- package/src/console/server/bind.ts +12 -1
- package/src/console/server/channels.test.ts +1 -1
- package/src/console/server/console-gates.ts +14 -0
- package/src/console/server/console.test.ts +6 -6
- package/src/console/server/flows-invoke.test.ts +2 -2
- package/src/console/server/flows.ts +2 -0
- package/src/console/server/gates.ts +8 -1
- package/src/console/server/operator-db.test.ts +4 -4
- package/src/console/server/operator-db.ts +22 -4
- package/src/console/server/security.gate.test.ts +3 -3
- package/src/console/server/store.test.ts +1 -1
- package/src/console/server/store.ts +11 -1
- package/src/console/ui/dist/assets/index-CjxwRGVv.js +10 -0
- package/src/console/ui/dist/assets/panel-access-BGv45snf.js +64 -0
- package/src/console/ui/dist/assets/{panel-ai-D_m6WQI8.js → panel-ai-B2S7LEii.js} +1 -1
- package/src/console/ui/dist/assets/{panel-architecture-CKnXFyUx.js → panel-architecture-D7UJh91v.js} +1 -1
- package/src/console/ui/dist/assets/{panel-channels-DCDd4WAC.js → panel-channels-9T3ybqRu.js} +1 -1
- package/src/console/ui/dist/assets/panel-clock-Cb1UXGRQ.js +1 -0
- package/src/console/ui/dist/assets/{panel-diff-cdonmH8c.js → panel-diff-DmYbKWmN.js} +1 -1
- package/src/console/ui/dist/assets/panel-flows-PiHwT55z.js +48 -0
- package/src/console/ui/dist/assets/{panel-gates-B5eTE8XH.js → panel-gates-BQGYXvjT.js} +1 -1
- package/src/console/ui/dist/assets/panel-overview-BBnRO18l.js +1 -0
- package/src/console/ui/dist/assets/{panel-plugins-Cj7DK1er.js → panel-plugins-D0PsmVw2.js} +1 -1
- package/src/console/ui/dist/assets/panel-runs-CWuRDe0r.js +1 -0
- package/src/console/ui/dist/assets/{panel-signals-whmDXIg3.js → panel-signals-Bbg4ewpP.js} +1 -1
- package/src/console/ui/dist/assets/{panel-store-CEMHLvaw.js → panel-store-CPCbsDRa.js} +1 -1
- package/src/console/ui/dist/assets/panel-traces-DVAzuA_S.js +1 -0
- package/src/console/ui/dist/assets/{panel-vault-C9wjbki8.js → panel-vault-D1_MvOmo.js} +1 -1
- package/src/console/ui/dist/assets/{rolldown-runtime-CNC7AqOf.js → rolldown-runtime-B0Z9INg1.js} +1 -1
- package/src/console/ui/dist/index.html +2 -2
- package/src/console/ui/gates/fixture.ts +4 -0
- package/src/console/ui/gates/types.ts +2 -0
- package/src/console/ui/shell/client.ts +1 -0
- package/src/docker/compose.ts +5 -0
- package/src/docker/docker.test.ts +41 -0
- package/src/docker/recipes/index.ts +10 -2
- package/src/docker/recipes/meilisearch.ts +31 -0
- package/src/drivers/conformance.test.ts +16 -1
- package/src/drivers/conformance.ts +40 -3
- package/src/drivers/index.ts +14 -2
- package/src/drivers/libsql.ts +4 -4
- package/src/drivers/meilisearch.integration.test.ts +77 -0
- package/src/drivers/meilisearch.test.ts +181 -0
- package/src/drivers/meilisearch.ts +208 -0
- package/src/drivers/memory.ts +4 -4
- package/src/drivers/pgvector.ts +6 -6
- package/src/drivers/types.ts +93 -12
- package/src/drivers/vault-driver-removal.test.ts +6 -0
- package/src/drivers/vault-types.ts +4 -4
- package/src/elements/ai/runtime.ts +6 -0
- package/src/elements/ai.test.ts +22 -0
- package/src/elements/gate/boot.ts +136 -0
- package/src/elements/gate/config.ts +69 -0
- package/src/elements/gate/declare.ts +51 -1
- package/src/elements/gate/runtime.ts +3 -1
- package/src/elements/gate.test.ts +77 -0
- package/src/elements/gate.ts +20 -1
- package/src/elements/index.ts +8 -0
- package/src/elements/store/index-boot.test.ts +49 -7
- package/src/elements/store/runtime.ts +50 -15
- package/src/elements/store.ts +2 -0
- package/src/elements/vault.test.ts +27 -4
- package/src/elements/vault.ts +1 -1
- package/src/index.ts +15 -0
- package/src/kernel/app.ts +253 -32
- package/src/kernel/boot-bind/store.test.ts +9 -0
- package/src/kernel/boot-bind/store.ts +30 -2
- package/src/kernel/boot.test.ts +40 -3
- package/src/kernel/boot.ts +8 -0
- package/src/kernel/call.test.ts +46 -2
- package/src/kernel/concurrency.test.ts +58 -0
- package/src/kernel/concurrency.ts +48 -0
- package/src/kernel/edge.test.ts +3 -3
- package/src/kernel/flow.test.ts +2 -2
- package/src/kernel/fx.test.ts +12 -2
- package/src/kernel/fx.ts +97 -5
- package/src/kernel/hooks.test.ts +4 -4
- package/src/kernel/index.ts +22 -1
- package/src/kernel/pipeline.test.ts +12 -8
- package/src/kernel/pipeline.ts +23 -4
- package/src/kernel/plugin/decorate.test.ts +3 -3
- package/src/kernel/plugin/scoping.test.ts +3 -3
- package/src/kernel/plugin-elements.test.ts +51 -0
- package/src/kernel/plugin-needs.test.ts +83 -0
- package/src/kernel/plugin-needs.ts +129 -0
- package/src/kernel/plugin.ts +101 -0
- package/src/kernel/redacted.ts +74 -0
- package/src/kernel/registry-isolation.test.ts +5 -5
- package/src/kernel/registry.ts +102 -3
- package/src/kernel/router.ts +3 -3
- package/src/manifest/types.ts +2 -0
- package/src/plugins/anonymous.ts +58 -0
- package/src/plugins/auth/shared.ts +121 -0
- package/src/plugins/auth-methods.test.ts +176 -0
- package/src/plugins/compression.test.ts +5 -5
- package/src/plugins/config-source.test.ts +1 -1
- package/src/plugins/cors.test.ts +16 -10
- package/src/plugins/csrf.test.ts +1 -1
- package/src/plugins/email-otp.ts +161 -0
- package/src/plugins/index.ts +31 -0
- package/src/plugins/ip-allowlist.test.ts +19 -9
- package/src/plugins/magic-link.ts +163 -0
- package/src/plugins/maintenance-mode.test.ts +9 -5
- package/src/plugins/passkey.ts +216 -0
- package/src/plugins/phone-number.ts +149 -0
- package/src/plugins/security-headers.test.ts +14 -14
- package/src/plugins/two-factor.ts +249 -0
- package/src/plugins/username.ts +148 -0
- package/src/runs/runs.test.ts +6 -2
- package/src/runtime/primitives.ts +37 -4
- package/src/runtime/serve.test.ts +3 -2
- package/src/runtime/types.ts +25 -2
- package/src/test/create-test-app.test.ts +1 -1
- package/src/test/create-test-app.ts +4 -1
- package/src/test/provisions.integration.test.ts +2 -2
- package/site/content/docs/get-started/comparison.mdx +0 -65
- package/src/console/ui/dist/assets/index-CrKMmO__.js +0 -10
- package/src/console/ui/dist/assets/panel-access-C0J2D-a2.js +0 -64
- package/src/console/ui/dist/assets/panel-clock-DjGGFPzr.js +0 -1
- package/src/console/ui/dist/assets/panel-flows-DlCU5zjA.js +0 -45
- package/src/console/ui/dist/assets/panel-overview-BsFvDdts.js +0 -1
- package/src/console/ui/dist/assets/panel-runs-C0gmnoYL.js +0 -1
- package/src/console/ui/dist/assets/panel-traces-BDiAuVSK.js +0 -1
- package/src/drivers/vault-infisical.ts +0 -57
|
@@ -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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
17
|
+
## Quick start
|
|
13
18
|
|
|
14
|
-
|
|
19
|
+
<Steps>
|
|
15
20
|
|
|
16
|
-
|
|
17
|
-
|
|
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
|
-
|
|
24
|
+
Four contracts plus a `do`. This is the standard starter's health check:
|
|
24
25
|
|
|
25
|
-
|
|
26
|
-
|
|
26
|
+
```typescript title="health"
|
|
27
|
+
import { on, flow, http } from "okengine";
|
|
28
|
+
import { z } from "zod";
|
|
27
29
|
|
|
28
|
-
|
|
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
|
-
</
|
|
39
|
+
</Step>
|
|
31
40
|
|
|
32
|
-
|
|
41
|
+
<Step>
|
|
42
|
+
### Change only the trigger
|
|
33
43
|
|
|
34
|
-
|
|
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
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
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
|
-
|
|
58
|
+
</Step>
|
|
44
59
|
|
|
45
|
-
|
|
60
|
+
<Step>
|
|
61
|
+
### See what was derived
|
|
46
62
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
```
|
|
63
|
+
Run `oke dev`. Three surfaces come up together — nothing configured by hand in
|
|
64
|
+
a separate dashboard.
|
|
50
65
|
|
|
51
|
-
|
|
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
|
-
|
|
68
|
+
</Step>
|
|
65
69
|
|
|
66
|
-
|
|
70
|
+
</Steps>
|
|
67
71
|
|
|
68
|
-
|
|
72
|
+
## Anatomy
|
|
69
73
|
|
|
70
|
-
|
|
74
|
+
One pipeline. Only the trigger changes between an endpoint, a job, a consumer,
|
|
75
|
+
and a row hook.
|
|
71
76
|
|
|
72
|
-
<
|
|
73
|
-
<summary>What each element replaces</summary>
|
|
77
|
+
<FlowShape />
|
|
74
78
|
|
|
75
|
-
|
|
|
76
|
-
|
|
|
77
|
-
| **
|
|
78
|
-
| **
|
|
79
|
-
|
|
|
80
|
-
| **
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
110
|
+
<ManifestPipeline />
|
|
95
111
|
|
|
96
|
-
|
|
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
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
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="
|
|
106
|
-
description="
|
|
107
|
-
href="/docs/get-started/
|
|
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="
|
|
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="
|
|
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`).
|
|
@@ -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>
|
|
@@ -23,41 +23,19 @@ on(orderPlaced, sendReceipt);
|
|
|
23
23
|
<Card
|
|
24
24
|
title="Get Started"
|
|
25
25
|
description="One law → install → first flows."
|
|
26
|
-
href="/docs/get-started
|
|
27
|
-
/>
|
|
28
|
-
<Card
|
|
29
|
-
title="Basic Usage"
|
|
30
|
-
description="Build from the standard starter."
|
|
31
|
-
href="/docs/get-started/basic-usage"
|
|
32
|
-
/>
|
|
33
|
-
<Card
|
|
34
|
-
title="Elements"
|
|
35
|
-
description="Flow → AI reference, one page each."
|
|
36
|
-
href="/docs/elements/flow"
|
|
37
|
-
/>
|
|
38
|
-
<Card
|
|
39
|
-
title="Console"
|
|
40
|
-
description="Seventeen Manifest-derived panels."
|
|
41
|
-
href="/docs/console/overview"
|
|
26
|
+
href="/docs/get-started"
|
|
42
27
|
/>
|
|
28
|
+
<Card title="Elements" description="Flow → AI reference, one page each." href="/docs/elements" />
|
|
43
29
|
<Card
|
|
44
30
|
title="Plugins"
|
|
45
|
-
description="Official extensions — security
|
|
46
|
-
href="/docs/plugins
|
|
47
|
-
/>
|
|
48
|
-
<Card
|
|
49
|
-
title="CLI Reference"
|
|
50
|
-
description="`oke` and `create-oke` everyday commands."
|
|
51
|
-
href="/docs/reference/cli"
|
|
52
|
-
/>
|
|
53
|
-
<Card
|
|
54
|
-
title="Security"
|
|
55
|
-
description="Console security posture — Host, Origin, MCP."
|
|
56
|
-
href="/docs/reference/security"
|
|
31
|
+
description="Official extensions — security, ops, performance."
|
|
32
|
+
href="/docs/plugins"
|
|
57
33
|
/>
|
|
34
|
+
<Card title="Console" description="Manifest-derived operator panels." href="/docs/console" />
|
|
58
35
|
<Card
|
|
59
|
-
title="
|
|
60
|
-
description="
|
|
61
|
-
href="/docs/
|
|
36
|
+
title="Reference"
|
|
37
|
+
description="Config, fx, env, errors, CLI, security."
|
|
38
|
+
href="/docs/reference"
|
|
62
39
|
/>
|
|
40
|
+
<Card title="AI Resources" description="MCP, skills, /llms.txt." href="/docs/ai" />
|
|
63
41
|
</Cards>
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: "Anonymous"
|
|
3
|
+
description: "Official plugin — issue a user-plane session with a random id and no password."
|
|
4
|
+
icon: "UserRoundMinus"
|
|
5
|
+
source: "docs/spec/unified-theory.md"
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
`anonymous()` creates a throwaway principal: one public Flow returns hybrid session tokens for a
|
|
9
|
+
new random `userId`. Use it for guest carts or try-before-account flows.
|
|
10
|
+
|
|
11
|
+
<Callout title="The one rule">
|
|
12
|
+
Enable `gate.auth`, then `.plug(anonymous())`. Treat the session like any other Bearer principal —
|
|
13
|
+
gates still decide what it may do.
|
|
14
|
+
</Callout>
|
|
15
|
+
|
|
16
|
+
## Quick start
|
|
17
|
+
|
|
18
|
+
<Steps>
|
|
19
|
+
|
|
20
|
+
<Step>
|
|
21
|
+
### Plug it
|
|
22
|
+
|
|
23
|
+
```typescript title="src/app.ts"
|
|
24
|
+
import { oke } from "okengine";
|
|
25
|
+
import { anonymous } from "okengine/plugins";
|
|
26
|
+
|
|
27
|
+
export const app = oke({
|
|
28
|
+
name: "shop",
|
|
29
|
+
env: "local",
|
|
30
|
+
gate: { auth: {} },
|
|
31
|
+
}).plug(anonymous());
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
</Step>
|
|
35
|
+
|
|
36
|
+
<Step>
|
|
37
|
+
### Sign in anonymously
|
|
38
|
+
|
|
39
|
+
```typescript
|
|
40
|
+
const { data } = await api.auth.signInAnonymous();
|
|
41
|
+
// data.userId is a fresh UUID; store tokens like any other session
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
`POST /auth/sign-in/anonymous` — no body.
|
|
45
|
+
|
|
46
|
+
</Step>
|
|
47
|
+
|
|
48
|
+
<Step>
|
|
49
|
+
### Gate what guests can do
|
|
50
|
+
|
|
51
|
+
Attach real policies to guest-capable Flows (`gate.scope`, custom policies). Anonymous only
|
|
52
|
+
issues a session — it does not grant scopes.
|
|
53
|
+
|
|
54
|
+
</Step>
|
|
55
|
+
|
|
56
|
+
</Steps>
|
|
57
|
+
|
|
58
|
+
## Options
|
|
59
|
+
|
|
60
|
+
| Option | Type | Default | Meaning |
|
|
61
|
+
| ------------- | -------------- | ---------- | ----------------------------------------------------------- |
|
|
62
|
+
| `secret` | `string` | active\* | HMAC secret (\*from `gate.auth` when plugged after `oke()`) |
|
|
63
|
+
| `sessions` | `SessionStore` | active\* | Session store shared with Gate auth |
|
|
64
|
+
| `now` | `() => number` | `Date.now` | Injectable clock |
|
|
65
|
+
| `emailDomain` | `string` | — | Reserved; unused in v1 |
|
|
66
|
+
|
|
67
|
+
## Surfaces
|
|
68
|
+
|
|
69
|
+
| Flow | Path | Gate |
|
|
70
|
+
| ---------------------- | ------------------------------ | ---------------------------- |
|
|
71
|
+
| `auth.signInAnonymous` | `POST /auth/sign-in/anonymous` | `gate.public` + sign-in rate |
|
|
72
|
+
|
|
73
|
+
## Troubleshooting
|
|
74
|
+
|
|
75
|
+
<Accordions>
|
|
76
|
+
<Accordion title="plugin boot failed — needs "auth"">
|
|
77
|
+
|
|
78
|
+
Set `oke({ gate: { auth: { … } } })` before `.plug(anonymous())`.
|
|
79
|
+
|
|
80
|
+
</Accordion>
|
|
81
|
+
</Accordions>
|
|
82
|
+
|
|
83
|
+
## Learn more
|
|
84
|
+
|
|
85
|
+
- [Gate](/docs/elements/gate) — policies on the new principal
|
|
86
|
+
- [Username](/docs/plugins/username) — upgrade path to a real credential
|
|
87
|
+
- [Plugins](/docs/plugins) — all auth method plugins
|
|
88
|
+
|
|
89
|
+
## Next
|
|
90
|
+
|
|
91
|
+
<Cards>
|
|
92
|
+
<Card title="Username" description="Username + password." href="/docs/plugins/username" />
|
|
93
|
+
<Card title="Gate" description="Builtin auth and policies." href="/docs/elements/gate" />
|
|
94
|
+
<Card title="Magic link" description="Email link sign-in." href="/docs/plugins/magic-link" />
|
|
95
|
+
</Cards>
|
|
@@ -47,9 +47,9 @@ Thresholds and matchers can follow the database like every other official plugin
|
|
|
47
47
|
|
|
48
48
|
<Cards>
|
|
49
49
|
<Card
|
|
50
|
-
title="
|
|
50
|
+
title="Headers"
|
|
51
51
|
description="The full secure-headers set on every response."
|
|
52
|
-
href="/docs/plugins/
|
|
52
|
+
href="/docs/plugins/headers"
|
|
53
53
|
/>
|
|
54
54
|
<Card
|
|
55
55
|
title="IP Allowlist"
|
|
@@ -86,9 +86,9 @@ See [Plugins → Runtime configuration](/docs/reference/plugins#runtime-configur
|
|
|
86
86
|
href="/docs/plugins/csrf"
|
|
87
87
|
/>
|
|
88
88
|
<Card
|
|
89
|
-
title="
|
|
89
|
+
title="Headers"
|
|
90
90
|
description="The full secure-headers set on every response."
|
|
91
|
-
href="/docs/plugins/
|
|
91
|
+
href="/docs/plugins/headers"
|
|
92
92
|
/>
|
|
93
93
|
<Card
|
|
94
94
|
title="Plugin API"
|
|
@@ -89,8 +89,8 @@ See [Plugins → Runtime configuration](/docs/reference/plugins#runtime-configur
|
|
|
89
89
|
href="/docs/elements/gate"
|
|
90
90
|
/>
|
|
91
91
|
<Card
|
|
92
|
-
title="
|
|
92
|
+
title="Headers"
|
|
93
93
|
description="The full secure-headers set on every response."
|
|
94
|
-
href="/docs/plugins/
|
|
94
|
+
href="/docs/plugins/headers"
|
|
95
95
|
/>
|
|
96
96
|
</Cards>
|