okengine 0.17.2 → 0.18.4
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 +5 -3
- package/README.md +14 -10
- package/manifest.v1.schema.json +61 -2
- package/package.json +19 -5
- package/site/content/docs/ai/index.mdx +1 -1
- package/site/content/docs/ai/mcp.mdx +10 -1
- package/site/content/docs/ai/skills.mdx +9 -9
- package/site/content/docs/elements/ai.mdx +1 -1
- package/site/content/docs/elements/clock.mdx +1 -1
- package/site/content/docs/elements/flow.mdx +25 -1
- package/site/content/docs/elements/gate.mdx +3 -2
- package/site/content/docs/elements/store.mdx +289 -341
- package/site/content/docs/elements/vault.mdx +5 -5
- package/site/content/docs/get-started/basic-usage.mdx +3 -10
- package/site/content/docs/get-started/index.mdx +1 -1
- package/site/content/docs/get-started/installation.mdx +2 -3
- package/site/content/docs/get-started/introduction.mdx +58 -121
- package/site/content/docs/get-started/meta.json +9 -1
- package/site/content/docs/get-started/project-structure.mdx +4 -11
- package/site/content/docs/get-started/testing.mdx +328 -0
- package/site/content/docs/get-started/why.mdx +93 -71
- package/site/content/docs/index.mdx +44 -11
- package/site/content/docs/meta.json +8 -5
- package/site/content/docs/plugins/apple.mdx +151 -0
- package/site/content/docs/plugins/discord.mdx +139 -0
- package/site/content/docs/plugins/facebook.mdx +134 -0
- package/site/content/docs/plugins/figma.mdx +138 -0
- package/site/content/docs/plugins/github.mdx +138 -0
- package/site/content/docs/plugins/google.mdx +153 -0
- package/site/content/docs/plugins/index.mdx +47 -1
- package/site/content/docs/plugins/meta.json +10 -0
- package/site/content/docs/plugins/microsoft.mdx +151 -0
- package/site/content/docs/plugins/oauth.mdx +188 -0
- package/site/content/docs/plugins/x.mdx +125 -0
- package/site/content/docs/providers/index.mdx +2 -0
- package/site/content/docs/recipes/index.mdx +2 -0
- package/site/content/docs/reference/cli.md +3 -2
- package/site/content/docs/reference/client.mdx +58 -1
- package/site/content/docs/reference/configuration.mdx +2 -4
- package/site/content/docs/reference/fx.mdx +3 -1
- package/site/content/docs/reference/index.mdx +0 -5
- package/site/content/docs/reference/meta.json +2 -2
- package/site/content/docs/reference/okid.mdx +137 -0
- package/src/auth/bindings.ts +1 -1
- package/src/auth/config.ts +9 -0
- package/src/auth/identity-sql.ts +314 -0
- package/src/auth/identity.ts +140 -2
- package/src/auth/index.ts +17 -1
- package/src/auth/method-context.ts +3 -0
- package/src/auth/oauth-as/cimd.ts +132 -0
- package/src/auth/oauth-as/crypto.test.ts +101 -0
- package/src/auth/oauth-as/crypto.ts +393 -0
- package/src/auth/oauth-as/errors.ts +68 -0
- package/src/auth/oauth-as/http.test.ts +419 -0
- package/src/auth/oauth-as/http.ts +842 -0
- package/src/auth/oauth-as/stores.ts +61 -0
- package/src/auth/oauth-as/tables.ts +142 -0
- package/src/auth/tables.ts +0 -11
- package/src/bench/README.md +83 -0
- package/src/bench/REPORT.md +176 -0
- package/src/bench/g01-rls-stamp.bench.ts +194 -0
- package/src/bench/g02-clock-per-tenant.bench.ts +158 -0
- package/src/bench/g03-signal-once.bench.ts +157 -0
- package/src/bench/g03-signal-reconnect.bench.ts +254 -0
- package/src/bench/g03-signal-sse-memory.bench.ts +191 -0
- package/src/bench/g04-auth-vault-hotpath.bench.ts +170 -0
- package/src/bench/g05-sustained-full.bench.ts +265 -0
- package/src/bench/g06-mixed-load.bench.ts +260 -0
- package/src/bench/g07-vault-crypto.bench.ts +100 -0
- package/src/bench/g07-vault-rotate-under-read.bench.ts +285 -0
- package/src/bench/g08-conn-oversubscribe.bench.ts +194 -0
- package/src/bench/g08-store-kv-durable.bench.ts +133 -0
- package/src/bench/g08-store-sql.bench.ts +178 -0
- package/src/bench/g09-journal-sustained.bench.ts +203 -0
- package/src/bench/g10-observability-contention.bench.ts +246 -0
- package/src/bench/g11-cold-start-cycle.bench.ts +164 -0
- package/src/bench/g13-elements.bench.ts +427 -0
- package/src/bench/g14-graceful-shutdown.bench.ts +244 -0
- package/src/bench/g15-postgres-degradation.bench.ts +264 -0
- package/src/bench/g16-live-query-fanout.bench.ts +206 -0
- package/src/bench/lib/event-loop-lag.ts +26 -0
- package/src/bench/lib/infra.ts +60 -0
- package/src/bench/lib/report.ts +52 -0
- package/src/bench/lib/rss-sampler.ts +61 -0
- package/src/bench/lib/signal-pg.ts +88 -0
- package/src/bench/load-app.ts +337 -0
- package/src/bench/load-child.ts +108 -0
- package/src/bench/smoke.bench.ts +43 -0
- package/src/cli/competitor-mention-removal.test.ts +28 -0
- package/src/cli/doctor-fd.ts +117 -0
- package/src/cli/doctor.test.ts +192 -0
- package/src/cli/doctor.ts +129 -1
- package/src/client/create.ts +95 -1
- package/src/client/index.ts +9 -2
- package/src/client/transport.ts +11 -4
- package/src/client/use-live-query.ts +154 -0
- package/src/client-react/index.ts +15 -1
- package/src/client-react/live-resource.ts +246 -0
- package/src/client-react/use-live-query.test.ts +475 -0
- package/src/client-react/use-live-query.ts +530 -0
- package/src/compiler/extract.test.ts +518 -0
- package/src/compiler/extract.ts +386 -19
- package/src/console/server/invoke-user-flow.ts +2 -1
- package/src/console/ui-next/dist/assets/{access-page-DnWbnGzq.js → access-page-De7Lc2JC.js} +1 -1
- package/src/console/ui-next/dist/assets/{flows-page-BiZ4-6yQ.js → flows-page-RGy7VEA_.js} +1 -1
- package/src/console/ui-next/dist/assets/{index-C8NRK2R-.js → index-_rgpdVzo.js} +3 -3
- package/src/console/ui-next/dist/assets/{observability-page-CrB6vd1T.js → observability-page-Ds6pcnh-.js} +1 -1
- package/src/console/ui-next/dist/assets/{store-page-CS5-aETQ.js → store-page-02xOiqIK.js} +3 -3
- package/src/console/ui-next/dist/assets/{units-page-CjtdlW8l.js → units-page-4rHOePuE.js} +1 -1
- package/src/console/ui-next/dist/assets/{vault-page-C6Xxm9SA.js → vault-page-DISPgxLM.js} +1 -1
- package/src/console/ui-next/dist/index.html +1 -1
- package/src/console/ui-next/src/features/store/lib/fields-from-table.ts +36 -2
- package/src/drivers/cdc-outbox.ts +389 -0
- package/src/drivers/memory.ts +20 -0
- package/src/drivers/oauth-apple.ts +156 -0
- package/src/drivers/oauth-discord.ts +79 -0
- package/src/drivers/oauth-facebook.ts +80 -0
- package/src/drivers/oauth-figma.ts +116 -0
- package/src/drivers/oauth-github.ts +92 -0
- package/src/drivers/oauth-google.ts +142 -0
- package/src/drivers/oauth-microsoft.ts +174 -0
- package/src/drivers/oauth-oidc.ts +293 -0
- package/src/drivers/oauth-shared.ts +326 -0
- package/src/drivers/oauth-types.ts +159 -0
- package/src/drivers/oauth-x.ts +77 -0
- package/src/drivers/oauth2-common.ts +95 -0
- package/src/drivers/oauth2-token.ts +61 -0
- package/src/drivers/pg-rls-row-passes.ts +251 -0
- package/src/drivers/pg-rls.ts +2 -0
- package/src/drivers/postgres.ts +45 -2
- package/src/drivers/signal-postgres.ts +2 -1
- package/src/elements/channel/runtime.ts +29 -2
- package/src/elements/channel.test.ts +52 -0
- package/src/elements/gate/boot.ts +29 -2
- package/src/elements/store/emit-drizzle.ts +147 -14
- package/src/elements/store/field-ddl.test.ts +118 -0
- package/src/elements/store/field-types.test.ts +455 -0
- package/src/elements/store/list-query.golden.json +777 -0
- package/src/elements/store/list-query.parity.test.ts +396 -0
- package/src/elements/store/list-query.ts +792 -0
- package/src/elements/store/live-default.test.ts +136 -0
- package/src/elements/store/live-http.test.ts +160 -0
- package/src/elements/store/live-isolation.test.ts +291 -0
- package/src/elements/store/live-query-runtime.test.ts +323 -0
- package/src/elements/store/live-query-runtime.ts +403 -0
- package/src/elements/store/live-query-server.test.ts +377 -0
- package/src/elements/store/live-query-server.ts +102 -0
- package/src/elements/store/live-query.ts +97 -0
- package/src/elements/store/resource.ts +189 -680
- package/src/elements/store/rls-row-passes-policies.parity.test.ts +665 -0
- package/src/elements/store/schema-decl.ts +539 -41
- package/src/elements/store/sql-rls-stamp.test.ts +27 -0
- package/src/elements/store/sql-session.ts +297 -35
- package/src/elements/store/table.ts +102 -21
- package/src/elements/store.test.ts +3 -1
- package/src/elements/store.ts +12 -1
- package/src/elements/vault/chaos-child.ts +74 -1
- package/src/elements/vault/chaos.test.ts +4 -2
- package/src/elements/vault/storage.ts +4 -2
- package/src/index.ts +5 -2
- package/src/kernel/app-auth.ts +1 -0
- package/src/kernel/app.ts +116 -2
- package/src/kernel/auth-sharing.test.ts +196 -0
- package/src/kernel/boot.test.ts +3 -3
- package/src/kernel/errors.ts +8 -0
- package/src/kernel/fx.test.ts +1 -0
- package/src/kernel/fx.ts +14 -2
- package/src/kernel/horizontal-child.ts +2 -1
- package/src/kernel/http-resource.ts +33 -7
- package/src/kernel/identity-host-persist.test.ts +119 -0
- package/src/kernel/instance-id.ts +4 -2
- package/src/kernel/journal.ts +2 -1
- package/src/kernel/mcp-tool.test.ts +95 -0
- package/src/kernel/on.ts +9 -0
- package/src/kernel/realtime-bind.ts +326 -0
- package/src/kernel/resource-live.ts +117 -0
- package/src/kernel/triggers.ts +86 -4
- package/src/manifest/diff.ts +37 -0
- package/src/manifest/types.ts +64 -2
- package/src/okid.bench.test.ts +64 -0
- package/src/okid.test.ts +338 -0
- package/src/okid.ts +245 -0
- package/src/plugins/anonymous.ts +19 -1
- package/src/plugins/auth/shared.ts +15 -0
- package/src/plugins/index.ts +2 -0
- package/src/plugins/magic-link.ts +10 -8
- package/src/plugins/mcp-oauth.ts +208 -0
- package/src/plugins/oauth/flow-store.ts +117 -0
- package/src/plugins/oauth/link.ts +69 -0
- package/src/plugins/oauth/shared.ts +108 -0
- package/src/plugins/oauth/token-vault.ts +100 -0
- package/src/plugins/oauth.security.test.ts +535 -0
- package/src/plugins/oauth.ts +532 -0
- package/src/plugins/otp.ts +48 -6
- package/src/plugins/passkey.ts +20 -1
- package/src/plugins/two-factor.ts +11 -0
- package/src/plugins/username.ts +40 -7
- package/src/release/build-lib.ts +7 -1
- package/src/release/measure.ts +1 -0
- package/src/release/official-plugins.ts +4 -1
- package/src/runs/collect.ts +2 -1
- package/src/runs/drivers/files.ts +2 -1
- package/src/test/create-test-app.ts +114 -5
- package/src/test/export-bundle.test.ts +33 -0
- package/src/test/live-signals.test.ts +83 -0
- package/src/test/tenant-isolation.test.ts +175 -0
- package/src/testing.ts +26 -0
- package/src/upgrade/codemods.ts +1 -1
- package/site/content/docs/reference/migrating-environments.mdx +0 -158
package/AGENTS.md
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
# OKE — Agent Contract
|
|
2
2
|
|
|
3
|
+
One law. Eight elements. One contract. The backend model stays small; operational surfaces are derived from it instead of maintained separately.
|
|
4
|
+
|
|
3
5
|
This file is loaded by every later session. It prevents drift. Product documentation lives in `site/content/docs/`. **If the documentation is silent, stop and ask.**
|
|
4
6
|
|
|
5
7
|
## The one law
|
|
@@ -27,13 +29,13 @@ There are no separate species called endpoints, handlers, consumers, jobs, subsc
|
|
|
27
29
|
|
|
28
30
|
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.
|
|
29
31
|
|
|
30
|
-
##
|
|
32
|
+
## Core programming vocabulary
|
|
31
33
|
|
|
32
34
|
```typescript
|
|
33
35
|
import { on, flow, signal, store, clock, gate, vault, channel, ai, plugin } from "okengine";
|
|
34
36
|
```
|
|
35
37
|
|
|
36
|
-
That is the
|
|
38
|
+
That is the core programming vocabulary. Everything else is derived.
|
|
37
39
|
|
|
38
40
|
## Governing rule
|
|
39
41
|
|
|
@@ -80,7 +82,7 @@ Published packages:
|
|
|
80
82
|
- `okengine` — framework. Subpath exports: `.`, `./client`, `./test`, `./config`, `./auth`, `./plugins`, `./drivers/*`. `"sideEffects": false`. CLI binary: `oke`.
|
|
81
83
|
- `create-oke` — scaffold CLI (`bunx create-oke@latest <name>`). Lives in `packages/create-oke` and ships Notes starters from `packages/create-oke/templates/{standard,advanced}`.
|
|
82
84
|
|
|
83
|
-
Engine: Bun `>=1.
|
|
85
|
+
Engine: Bun `>=1.4.0`.
|
|
84
86
|
|
|
85
87
|
## Documentation authority
|
|
86
88
|
|
package/README.md
CHANGED
|
@@ -2,11 +2,11 @@
|
|
|
2
2
|
<picture>
|
|
3
3
|
<source
|
|
4
4
|
media="(prefers-color-scheme: dark)"
|
|
5
|
-
srcset="https://shieldcn.dev/header/grid.svg?title=okengine&subtitle=One+law.+Eight+elements.+
|
|
5
|
+
srcset="https://shieldcn.dev/header/grid.svg?title=okengine&subtitle=One+law.+Eight+elements.+One+contract.&logo=https://raw.githubusercontent.com/omqkhafi/okengine/main/site/public/logo/OKE-W.svg&theme=zinc&size=banner&mode=dark&font=geist&align=left"
|
|
6
6
|
/>
|
|
7
7
|
<img
|
|
8
|
-
alt="okengine — One law. Eight elements.
|
|
9
|
-
src="https://shieldcn.dev/header/grid.svg?title=okengine&subtitle=One+law.+Eight+elements.+
|
|
8
|
+
alt="okengine — One law. Eight elements. One contract."
|
|
9
|
+
src="https://shieldcn.dev/header/grid.svg?title=okengine&subtitle=One+law.+Eight+elements.+One+contract.&logo=https://raw.githubusercontent.com/omqkhafi/okengine/main/site/public/logo/OKE-B.svg&theme=zinc&size=banner&mode=light&font=geist&align=left"
|
|
10
10
|
width="750"
|
|
11
11
|
/>
|
|
12
12
|
</picture>
|
|
@@ -16,13 +16,13 @@
|
|
|
16
16
|
<a href="https://www.npmjs.com/package/okengine"><img alt="npm" src="https://shieldcn.dev/npm/okengine.svg?size=sm&variant=outline" /></a>
|
|
17
17
|
<a href="https://jsr.io/@omqkhafi/okengine"><img alt="JSR" src="https://shieldcn.dev/jsr/@omqkhafi/okengine.svg?size=sm&variant=outline" /></a>
|
|
18
18
|
<a href="https://opensource.org/licenses/MIT"><img alt="MIT" src="https://shieldcn.dev/npm/license/okengine.svg?size=sm&variant=outline" /></a>
|
|
19
|
-
<a href="https://bun.sh"><img alt="Bun >=1.
|
|
19
|
+
<a href="https://bun.sh"><img alt="Bun >=1.4.0" src="https://shieldcn.dev/badge/Bun-%3E%3D1.4.0.svg?logo=bun&size=sm&variant=outline" /></a>
|
|
20
20
|
<a href="https://github.com/omqkhafi/okengine/actions"><img alt="CI" src="https://shieldcn.dev/github/ci/omqkhafi/okengine.svg?size=sm&variant=outline" /></a>
|
|
21
21
|
<a href="https://github.com/omqkhafi/okengine/commits"><img alt="last commit" src="https://shieldcn.dev/github/last-commit/omqkhafi/okengine.svg?size=sm&variant=outline" /></a>
|
|
22
22
|
</p>
|
|
23
23
|
|
|
24
24
|
<p align="center">
|
|
25
|
-
<em>
|
|
25
|
+
<em>Modern backends became a pile of disconnected systems. One law collapses them — client, Console, and infra derived from one contract. Yours to host.</em>
|
|
26
26
|
</p>
|
|
27
27
|
|
|
28
28
|
<p align="center">
|
|
@@ -39,7 +39,7 @@
|
|
|
39
39
|
|
|
40
40
|
## Install
|
|
41
41
|
|
|
42
|
-
Requires [Bun](https://bun.sh) `>=1.
|
|
42
|
+
Requires [Bun](https://bun.sh) `>=1.4.0`.
|
|
43
43
|
|
|
44
44
|
```bash
|
|
45
45
|
bunx create-oke@latest my-app # scaffold (recommended)
|
|
@@ -69,12 +69,13 @@ Mnemonic: **O·K·E = 6·5·3**.
|
|
|
69
69
|
The starter already exports a health Flow — change it and save; App and Console update from the same Manifest:
|
|
70
70
|
|
|
71
71
|
```typescript
|
|
72
|
-
|
|
72
|
+
// src/flows/main/health.ts — folders are the URL: `main/health.ts` → GET /health
|
|
73
|
+
import { on, flow, http } from "okengine";
|
|
73
74
|
import { z } from "zod";
|
|
74
75
|
|
|
75
76
|
export const health = on(
|
|
76
|
-
http.get(
|
|
77
|
-
flow(
|
|
77
|
+
http.get().public(),
|
|
78
|
+
flow({
|
|
78
79
|
out: z.object({ ok: z.literal(true) }),
|
|
79
80
|
do: () => ({ ok: true as const }),
|
|
80
81
|
}),
|
|
@@ -91,6 +92,8 @@ const api = createClient<App>("http://localhost:6530");
|
|
|
91
92
|
const { data, error } = await api.main.health({});
|
|
92
93
|
```
|
|
93
94
|
|
|
95
|
+
Native ids: import `okid` from `okengine/okid` — compact, URL-safe, cryptographically random (`okid()`, `okid(16)`, `okid({ sortable: true })`).
|
|
96
|
+
|
|
94
97
|
Full walkthrough: [Basic usage](https://oke.omqkhafi.dev/docs/get-started/basic-usage).
|
|
95
98
|
|
|
96
99
|
## One law
|
|
@@ -101,7 +104,7 @@ Every backend behavior is a Flow: `on(Trigger) → Effects`. Endpoints, jobs, co
|
|
|
101
104
|
import { on, flow, signal, store, clock, gate, vault, channel, ai, plugin } from "okengine";
|
|
102
105
|
```
|
|
103
106
|
|
|
104
|
-
That is the
|
|
107
|
+
That is the core programming vocabulary. World access goes through `fx` — effects are inferred, so the Manifest can derive the typed client, Console, and MCP without a second source of truth.
|
|
105
108
|
|
|
106
109
|
| Element | Essence |
|
|
107
110
|
| ----------- | ----------------------------- |
|
|
@@ -140,6 +143,7 @@ Store apps sync schema with `oke db push|generate|migrate` (local `oke dev` auto
|
|
|
140
143
|
| Agents index | [/llms.txt](https://oke.omqkhafi.dev/llms.txt) |
|
|
141
144
|
| Manifest | [`manifest.v1.schema.json`](manifest.v1.schema.json) |
|
|
142
145
|
| Budgets | [`BUDGETS.md`](BUDGETS.md) |
|
|
146
|
+
| Security | [`SECURITY.md`](SECURITY.md) |
|
|
143
147
|
| Contributing | [`CONTRIBUTING.md`](CONTRIBUTING.md) |
|
|
144
148
|
|
|
145
149
|
## License
|
package/manifest.v1.schema.json
CHANGED
|
@@ -219,7 +219,17 @@
|
|
|
219
219
|
"signal": { "type": "string", "minLength": 1 },
|
|
220
220
|
"cron": { "type": "string", "minLength": 1 },
|
|
221
221
|
"every": { "type": "string", "minLength": 1 },
|
|
222
|
-
"cdc": { "$ref": "#/$defs/CdcTrigger" }
|
|
222
|
+
"cdc": { "$ref": "#/$defs/CdcTrigger" },
|
|
223
|
+
"mcp": { "$ref": "#/$defs/McpTrigger" }
|
|
224
|
+
}
|
|
225
|
+
},
|
|
226
|
+
"McpTrigger": {
|
|
227
|
+
"description": "Explicit MCP tool exposure. Presence means the flow is listed over MCP for OAuth user-plane clients; absence means not an MCP tool (deny-by-default).",
|
|
228
|
+
"type": "object",
|
|
229
|
+
"required": ["name"],
|
|
230
|
+
"additionalProperties": false,
|
|
231
|
+
"properties": {
|
|
232
|
+
"name": { "type": "string", "minLength": 1 }
|
|
223
233
|
}
|
|
224
234
|
},
|
|
225
235
|
"Slo": {
|
|
@@ -378,7 +388,38 @@
|
|
|
378
388
|
"type": "object",
|
|
379
389
|
"additionalProperties": false,
|
|
380
390
|
"properties": {
|
|
381
|
-
"type": {
|
|
391
|
+
"type": {
|
|
392
|
+
"type": "string",
|
|
393
|
+
"enum": [
|
|
394
|
+
"text",
|
|
395
|
+
"varchar",
|
|
396
|
+
"char",
|
|
397
|
+
"boolean",
|
|
398
|
+
"smallint",
|
|
399
|
+
"integer",
|
|
400
|
+
"bigint",
|
|
401
|
+
"serial",
|
|
402
|
+
"smallserial",
|
|
403
|
+
"bigserial",
|
|
404
|
+
"numeric",
|
|
405
|
+
"real",
|
|
406
|
+
"doublePrecision",
|
|
407
|
+
"json",
|
|
408
|
+
"jsonb",
|
|
409
|
+
"uuid",
|
|
410
|
+
"time",
|
|
411
|
+
"timestamp",
|
|
412
|
+
"date",
|
|
413
|
+
"interval",
|
|
414
|
+
"point",
|
|
415
|
+
"line",
|
|
416
|
+
"bytea",
|
|
417
|
+
"inet",
|
|
418
|
+
"cidr",
|
|
419
|
+
"macaddr",
|
|
420
|
+
"macaddr8"
|
|
421
|
+
]
|
|
422
|
+
},
|
|
382
423
|
"nullable": { "type": "boolean" },
|
|
383
424
|
"primaryKey": { "type": "boolean" },
|
|
384
425
|
"unique": { "type": "boolean" },
|
|
@@ -390,6 +431,24 @@
|
|
|
390
431
|
{ "type": "null" }
|
|
391
432
|
]
|
|
392
433
|
},
|
|
434
|
+
"enumValues": {
|
|
435
|
+
"description": "Allowed string values for enum columns (text/varchar/char).",
|
|
436
|
+
"type": "array",
|
|
437
|
+
"items": { "type": "string" },
|
|
438
|
+
"minItems": 1
|
|
439
|
+
},
|
|
440
|
+
"length": { "description": "varchar/char max length.", "type": "integer", "minimum": 1 },
|
|
441
|
+
"precision": {
|
|
442
|
+
"description": "Fractional-second digits (time/timestamp, 0-6) or interval precision.",
|
|
443
|
+
"type": "integer"
|
|
444
|
+
},
|
|
445
|
+
"scale": { "description": "numeric(p, s) scale digits.", "type": "integer" },
|
|
446
|
+
"withTimezone": { "description": "time/timestamp timezone flavor.", "type": "boolean" },
|
|
447
|
+
"mode": {
|
|
448
|
+
"description": "JS mapping selector for temporal/numeric/point/line/bigint columns.",
|
|
449
|
+
"type": "string"
|
|
450
|
+
},
|
|
451
|
+
"fields": { "description": "interval field qualifier.", "type": "string" },
|
|
393
452
|
"sqlName": { "type": "string", "minLength": 1 },
|
|
394
453
|
"description": {
|
|
395
454
|
"description": "Optional human description; consumers fall back to the column map key.",
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "okengine",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "One law. Eight elements.
|
|
3
|
+
"version": "0.18.4",
|
|
4
|
+
"description": "One law. Eight elements. One contract. The backend model stays small; operational surfaces are derived from it instead of maintained separately.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
7
7
|
"type": "git",
|
|
@@ -72,6 +72,12 @@
|
|
|
72
72
|
"./client/auth": "./src/client/auth.ts",
|
|
73
73
|
"./client-react": "./src/client-react/index.ts",
|
|
74
74
|
"./test": "./src/test/index.ts",
|
|
75
|
+
"./testing": {
|
|
76
|
+
"types": "./src/testing.ts",
|
|
77
|
+
"bun": "./src/testing.ts",
|
|
78
|
+
"import": "./dist/testing.js",
|
|
79
|
+
"default": "./dist/testing.js"
|
|
80
|
+
},
|
|
75
81
|
"./config": "./src/config/index.ts",
|
|
76
82
|
"./auth": "./src/auth/index.ts",
|
|
77
83
|
"./console": "./src/console/index.ts",
|
|
@@ -86,7 +92,13 @@
|
|
|
86
92
|
"./ai": "./src/elements/ai.ts",
|
|
87
93
|
"./runs": "./src/runs/index.ts",
|
|
88
94
|
"./drivers": "./src/drivers/index.ts",
|
|
89
|
-
"./drivers/*": "./src/drivers/*"
|
|
95
|
+
"./drivers/*": "./src/drivers/*",
|
|
96
|
+
"./okid": {
|
|
97
|
+
"types": "./src/okid.ts",
|
|
98
|
+
"bun": "./src/okid.ts",
|
|
99
|
+
"import": "./dist/okid.js",
|
|
100
|
+
"default": "./dist/okid.js"
|
|
101
|
+
}
|
|
90
102
|
},
|
|
91
103
|
"scripts": {
|
|
92
104
|
"typecheck": "tsc --noEmit && tsc --noEmit -p tests/console/tsconfig.ui-next.json && tsc --noEmit -p src/console/ui-next && bun run --cwd packages/create-oke typecheck && bun run --cwd examples/keel typecheck",
|
|
@@ -112,7 +124,8 @@
|
|
|
112
124
|
"test:keel:docker": "OKE_TEST_DOCKER=1 bun run --cwd examples/keel test",
|
|
113
125
|
"build:lib": "bun src/release/build-lib.ts",
|
|
114
126
|
"prepack": "bun run build && bun run build:lib",
|
|
115
|
-
"bench": "bun test ./src/runtime/cold-start.bench.ts src/client/budget.test.ts src/console/budget.test.ts src/kernel/budget.test.ts src/kernel/routing-budget.test.ts src/runs/bench.test.ts",
|
|
127
|
+
"bench": "bun test ./src/runtime/cold-start.bench.ts src/client/budget.test.ts src/console/budget.test.ts src/kernel/budget.test.ts src/kernel/routing-budget.test.ts src/runs/bench.test.ts src/okid.bench.test.ts",
|
|
128
|
+
"bench:load": "OKE_BENCH=1 bun test ./src/bench/*.bench.ts --timeout 600000 --pass-with-no-tests",
|
|
116
129
|
"budgets": "bun src/release/publish.ts",
|
|
117
130
|
"gate": "PUBLISH_GATE=1 bun test src/cli/doc-staleness.test.ts src/cli/competitor-mention-removal.test.ts src/drivers/vault-driver-removal.test.ts src/kernel/errors.registry.test.ts src/upgrade/codemods.test.ts scripts/publish.gate.test.ts",
|
|
118
131
|
"dev": "bun run --cwd site dev",
|
|
@@ -121,7 +134,8 @@
|
|
|
121
134
|
"ci": "bun scripts/ci.ts",
|
|
122
135
|
"bump": "bun run scripts/bump-version.ts",
|
|
123
136
|
"release": "bun run scripts/publish.ts",
|
|
124
|
-
"g": "gflows"
|
|
137
|
+
"g": "gflows",
|
|
138
|
+
"postinstall": "bun run --cwd examples/keel prepare"
|
|
125
139
|
},
|
|
126
140
|
"dependencies": {
|
|
127
141
|
"@clack/prompts": "^1.7.0",
|
|
@@ -5,7 +5,7 @@ icon: "Bot"
|
|
|
5
5
|
source: "docs/spec/unified-theory.md"
|
|
6
6
|
---
|
|
7
7
|
|
|
8
|
-
Resources for AI agents that read or operate an OKE app — not the `ai` element itself.
|
|
8
|
+
Resources for AI agents that read or operate an OKE app — not the `ai` element itself. In OKE, **MCP is a surface of the model, not the model itself**. Gate governs agents calling in; the AI element governs apps calling out.
|
|
9
9
|
|
|
10
10
|
## Pages
|
|
11
11
|
|
|
@@ -5,7 +5,16 @@ icon: "Plug"
|
|
|
5
5
|
source: "docs/spec/unified-theory.md"
|
|
6
6
|
---
|
|
7
7
|
|
|
8
|
-
Two directions, same
|
|
8
|
+
## Two directions, same execution model
|
|
9
|
+
|
|
10
|
+
> **MCP is a surface of the model, not the model itself.**
|
|
11
|
+
|
|
12
|
+
Two genuinely distinct things share the protocol in OKE:
|
|
13
|
+
|
|
14
|
+
1. **Gate Element (MCP Provider role):** Your app exposes Flows as MCP tools on port **6535** (or via `mcp.tool()` + OAuth 2.1 Authorization Server) so external AI agents (Claude, ChatGPT) can read the Manifest and call declared Flows.
|
|
15
|
+
2. **AI Element (MCP Client role):** Your app consumes _external_ MCP tool servers via `ai.mcpServer(...)`, routing tool calls through `fx.call` inside prompts and agents.
|
|
16
|
+
|
|
17
|
+
OKE does not create separate security models for users, operators, and agents. They enter the same execution model through different triggers and planes.
|
|
9
18
|
|
|
10
19
|
The server on **6535** speaks JSON-RPC over HTTP (MCP protocol `2024-11-05`), requires a Bearer token **even on localhost**, and never forwards that token upstream — adapters receive structured operator ids instead.
|
|
11
20
|
|
|
@@ -9,18 +9,18 @@ Tools alone don't make a good operator — an agent also needs to know the _voca
|
|
|
9
9
|
|
|
10
10
|
## The layers
|
|
11
11
|
|
|
12
|
-
| Layer | Path | Loaded when | Teaches
|
|
13
|
-
| ------------------ | ---------------------------- | ------------------------------------------------- |
|
|
14
|
-
| **Agent contract** | `AGENTS.md` (repo root) | Every agent session, automatically | The one law, eight elements,
|
|
15
|
-
| **Element skill** | `.agents/skills/oke/` | Building or changing an okengine app | The element contract in depth — declaration patterns per element
|
|
16
|
-
| **Docs skill** | `.agents/skills/oke-docs/` | Writing or editing docs under `site/content/docs` | The documentation information-architecture standard and its gates
|
|
17
|
-
| **Ship skill** | `.agents/skills/oke-ship/` | After any implementation, before claiming done | Changelog under `## Unreleased` + docs sync via `oke-docs`
|
|
18
|
-
| **Deps skill** | `.agents/skills/oke-deps/` | Updating `package.json` dependencies | Scoped bumps, Bun install, pins (Drizzle RC, fumadocs alias, …)
|
|
19
|
-
| **Images skill** | `.agents/skills/oke-images/` | Updating Compose image pins | Registry probe, pin style, catalog + recipes + Keel + docs lockstep
|
|
12
|
+
| Layer | Path | Loaded when | Teaches |
|
|
13
|
+
| ------------------ | ---------------------------- | ------------------------------------------------- | ---------------------------------------------------------------------- |
|
|
14
|
+
| **Agent contract** | `AGENTS.md` (repo root) | Every agent session, automatically | The one law, eight elements, one contract, the fx rule, ports, budgets |
|
|
15
|
+
| **Element skill** | `.agents/skills/oke/` | Building or changing an okengine app | The element contract in depth — declaration patterns per element |
|
|
16
|
+
| **Docs skill** | `.agents/skills/oke-docs/` | Writing or editing docs under `site/content/docs` | The documentation information-architecture standard and its gates |
|
|
17
|
+
| **Ship skill** | `.agents/skills/oke-ship/` | After any implementation, before claiming done | Changelog under `## Unreleased` + docs sync via `oke-docs` |
|
|
18
|
+
| **Deps skill** | `.agents/skills/oke-deps/` | Updating `package.json` dependencies | Scoped bumps, Bun install, pins (Drizzle RC, fumadocs alias, …) |
|
|
19
|
+
| **Images skill** | `.agents/skills/oke-images/` | Updating Compose image pins | Registry probe, pin style, catalog + recipes + Keel + docs lockstep |
|
|
20
20
|
|
|
21
21
|
## AGENTS.md — the root contract
|
|
22
22
|
|
|
23
|
-
Every OKE app's repo carries an `AGENTS.md` that agents (Cursor, Claude Code, and peers) read at session start. It is deliberately short and absolute: every backend behavior is a Flow (`on(Trigger) → Effects`), there are eight elements
|
|
23
|
+
Every OKE app's repo carries an `AGENTS.md` that agents (Cursor, Claude Code, and peers) read at session start. It is deliberately short and absolute: every backend behavior is a Flow (`on(Trigger) → Effects`), there are eight elements bound to one contract, all world access goes through `fx`, drivers are named after protocols, and the ports/budgets are fixed. Its closing rule is the one that keeps agents honest: **if the documentation is silent, stop and ask** — never invent the API.
|
|
24
24
|
|
|
25
25
|
## Skills — installable know-how
|
|
26
26
|
|
|
@@ -129,7 +129,7 @@ const result = await fx.ask(triage, input, {
|
|
|
129
129
|
});
|
|
130
130
|
```
|
|
131
131
|
|
|
132
|
-
External MCP tools take the same path. Declare a server with a **required** allowlist, then pass `server.tool("…")` — never whatever `tools/list` happens to expose:
|
|
132
|
+
External MCP tools take the same path. In OKE, **MCP is a surface of the model, not the model itself** — `ai.mcpServer` models the client role (consuming external tools), while `mcp.tool()` + Gate models the provider role (exposing your flows to agents). Declare a server with a **required** allowlist, then pass `server.tool("…")` — never whatever `tools/list` happens to expose:
|
|
133
133
|
|
|
134
134
|
```typescript
|
|
135
135
|
export const github = ai.mcpServer("github", {
|
|
@@ -141,7 +141,7 @@ reclaimed after its lease expires and continues at the next unfinished step.
|
|
|
141
141
|
| Guarantee | What it means |
|
|
142
142
|
| ------------------ | -------------------------------------------------------------------------------------------------- |
|
|
143
143
|
| Leader election | Instances that share one CronStore fire a given tick once (lease TTL, default 30s) |
|
|
144
|
-
| Process identity | Boot mints one `instanceId` (`inst-<
|
|
144
|
+
| Process identity | Boot mints one `instanceId` (`inst-<okid>`) for Clock, Journal, and the fleet registry |
|
|
145
145
|
| Catch-up `"one"` | Health counts every missed slot; the runtime still fires **once** when overdue — not once per miss |
|
|
146
146
|
| Reconciled at boot | Named clocks land in `oke_crons`; the scheduler reads the Store, not the source |
|
|
147
147
|
| DST detection | Ambiguous local times get a Console warning — schedules are not rewritten or blocked |
|
|
@@ -111,7 +111,7 @@ Built-in codes attach a localized `message` ([Errors](/docs/reference/errors));
|
|
|
111
111
|
— that is the `as never` trap. See [fx](/docs/reference/fx).
|
|
112
112
|
</Callout>
|
|
113
113
|
|
|
114
|
-
## The
|
|
114
|
+
## The triggers
|
|
115
115
|
|
|
116
116
|
<FlowTriggers />
|
|
117
117
|
|
|
@@ -201,6 +201,30 @@ export const getOrder = flow("orders.get", {
|
|
|
201
201
|
const order = await fx.call(getOrder, { id: orderId }); // from any other flow
|
|
202
202
|
```
|
|
203
203
|
|
|
204
|
+
### mcp — an agent calls a tool
|
|
205
|
+
|
|
206
|
+
`mcp.tool(name)` marks a flow for **OAuth-protected user-plane** exposure over MCP. Deny-by-default: a flow without this trigger is never listed over `tools/list`. A gate is required, exactly like a sensitive HTTP route:
|
|
207
|
+
|
|
208
|
+
```typescript
|
|
209
|
+
export const createBooking = on(
|
|
210
|
+
mcp.tool("bookings.create").gate(member), // gates required — deny-by-default
|
|
211
|
+
flow("bookings.create", {
|
|
212
|
+
plane: "user",
|
|
213
|
+
in: BookingRef,
|
|
214
|
+
out: Booking,
|
|
215
|
+
do: async ({ id }, fx) => {
|
|
216
|
+
/* … */
|
|
217
|
+
},
|
|
218
|
+
}),
|
|
219
|
+
);
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
- The tool name is namespaced (`bookings.create`) and appears in the Manifest under `trigger.mcp.name` with its gates.
|
|
223
|
+
- Binding the **same tool name** twice fails boot with **OKE1018** (`MCP tool "{tool}" is bound twice`).
|
|
224
|
+
- Ungated `mcp.tool(...)` fails gate posture at boot (`GateBootError`) — the trigger never exposes an unauthenticated tool.
|
|
225
|
+
|
|
226
|
+
This is one direction of [MCP](/docs/ai/mcp): exposing your flows as tools. The other is consuming external servers as `ai.mcpServer` tools via `fx.ask` / `ai.agent`.
|
|
227
|
+
|
|
204
228
|
## fx — the only door
|
|
205
229
|
|
|
206
230
|
Everything a flow may touch, on one object:
|
|
@@ -9,6 +9,8 @@ Gate answers **"may this happen?"** before it happens: is this a verified member
|
|
|
9
9
|
burned its minute quota? Attach gates to the HTTP trigger — the pipeline checks them before a
|
|
10
10
|
store write, emit, or channel send runs.
|
|
11
11
|
|
|
12
|
+
> **Same Semantics Across Planes:** OKE does not create separate security models for users, operators, and agents. They enter the same execution model through different triggers and planes: users via sessions, operators via Console policies, and agents via `mcp.tool()` + OAuth 2.1 AS.
|
|
13
|
+
|
|
12
14
|
<Callout title="The one rule">
|
|
13
15
|
Every HTTP trigger declares posture: attach a real gate, or attach `.public()`. Omitting both
|
|
14
16
|
fails boot. Denial is a typed error value — never a thrown exception mid-`do`.
|
|
@@ -63,8 +65,7 @@ import { member, canBook, fair } from "../../gates";
|
|
|
63
65
|
export const health = on(
|
|
64
66
|
http.get("/health").public(),
|
|
65
67
|
flow("health.check", {
|
|
66
|
-
|
|
67
|
-
do: () => ({ ok: true as const }),
|
|
68
|
+
do: () => ({ ok: true }),
|
|
68
69
|
}),
|
|
69
70
|
);
|
|
70
71
|
|