okengine 0.1.4 → 0.2.1
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 +1 -1
- package/README.md +48 -15
- package/docs/spec/{complete-example.md → example.md} +0 -1
- package/docs/spec/unified-theory.md +1 -1
- package/package.json +21 -8
- package/src/auth/index.ts +1 -0
- package/src/cli/dev.ts +3 -1
- package/src/cli/doc-drift.ts +54 -21
- package/src/client/index.ts +1 -0
- package/src/config/index.ts +1 -0
- package/src/console/index.ts +26 -13
- package/src/console/server/app.ts +44 -7
- package/src/console/server/flows.ts +2 -6
- package/src/console/server/index.ts +2 -1
- package/src/console/server/lazy-panels.test.ts +27 -0
- package/src/console/server/panel-load.ts +28 -0
- package/src/console/server/plugin.ts +1 -1
- package/src/console/server/plugins.ts +7 -6
- package/src/console/server/public-flows.ts +12 -0
- package/src/console/server/state.ts +159 -122
- package/src/console/server/store.ts +13 -10
- package/src/drivers/index.ts +2 -6
- package/src/drivers/vault-sops.ts +20 -1
- package/src/elements/ai.ts +1 -0
- package/src/elements/channel.ts +1 -0
- package/src/elements/clock.ts +1 -0
- package/src/elements/gate.ts +1 -0
- package/src/elements/signal.ts +1 -0
- package/src/elements/store.ts +1 -0
- package/src/elements/vault.ts +1 -0
- package/src/index.ts +9 -0
- package/src/kernel/app.ts +1 -1
- package/src/kernel/boot-bind/ai.ts +31 -0
- package/src/kernel/boot-bind/channel.ts +27 -0
- package/src/kernel/boot-bind/clock.ts +74 -0
- package/src/kernel/boot-bind/gate.ts +28 -0
- package/src/kernel/boot-bind/runs.ts +28 -0
- package/src/kernel/boot-bind/signal.ts +68 -0
- package/src/kernel/boot-bind/store.ts +47 -0
- package/src/kernel/boot-bind/vault.ts +36 -0
- package/src/kernel/boot.test.ts +85 -1
- package/src/kernel/boot.ts +250 -212
- package/src/kernel/index.ts +2 -0
- package/src/mcp/data.ts +1 -0
- package/src/mcp/docs-index.ts +252 -0
- package/src/mcp/docs-mcp.test.ts +176 -0
- package/src/mcp/docs-server.ts +233 -0
- package/src/mcp/docs-tools.ts +143 -0
- package/src/mcp/index.ts +30 -5
- package/src/mcp/protocol.ts +2 -1
- package/src/release/exports.test.ts +71 -0
- package/src/release/exports.ts +156 -0
- package/src/release/index.ts +21 -0
- package/src/release/limits.ts +9 -0
- package/src/release/measure.exports.test.ts +82 -0
- package/src/release/measure.ts +297 -14
- package/src/release/publish.ts +14 -3
- package/src/release/readme.test.ts +61 -0
- package/src/release/readme.ts +13 -0
- package/src/runs/index.ts +1 -0
- package/src/runtime/index.ts +1 -0
- package/src/runtime/security.test.ts +6 -1
- package/src/runtime/types.ts +6 -0
- package/src/test/create-test-app.ts +2 -0
- package/src/test/index.ts +1 -0
- package/src/console/ui/dist/assets/index-B71Yl_SS.js +0 -10
- package/src/console/ui/dist/assets/panel-access-Dd37LU2c.js +0 -64
- package/src/console/ui/dist/assets/panel-ai-CC7LR6-J.js +0 -1
- package/src/console/ui/dist/assets/panel-architecture-B5b3iKCz.js +0 -1
- package/src/console/ui/dist/assets/panel-channels-CeNjTKXp.js +0 -1
- package/src/console/ui/dist/assets/panel-clock-DgFTLoHV.js +0 -1
- package/src/console/ui/dist/assets/panel-diff-DxehccqB.js +0 -1
- package/src/console/ui/dist/assets/panel-flows-BtrVn-Eg.js +0 -45
- package/src/console/ui/dist/assets/panel-gates-Z9MKRGdH.js +0 -1
- package/src/console/ui/dist/assets/panel-overview-Bd48d9km.js +0 -1
- package/src/console/ui/dist/assets/panel-plugins-DWd0TowH.js +0 -1
- package/src/console/ui/dist/assets/panel-runs-BwsWqKeB.js +0 -1
- package/src/console/ui/dist/assets/panel-signals-9najbZY2.js +0 -1
- package/src/console/ui/dist/assets/panel-store-OHkP2pDp.js +0 -1
- package/src/console/ui/dist/assets/panel-traces-tn2JoY8U.js +0 -1
- package/src/console/ui/dist/assets/panel-vault-BbfWdox0.js +0 -1
- package/src/console/ui/dist/assets/rolldown-runtime-CNC7AqOf.js +0 -1
- package/src/console/ui/dist/assets/style-Cnl7WLya.css +0 -3
- package/src/console/ui/dist/index.html +0 -14
package/AGENTS.md
CHANGED
|
@@ -76,7 +76,7 @@ A regression fails the build. Claims we cannot measure, we do not make.
|
|
|
76
76
|
|
|
77
77
|
Published packages:
|
|
78
78
|
- `okengine` — framework. Subpath exports: `.`, `./client`, `./test`, `./config`, `./auth`, `./drivers/*`. `"sideEffects": false`. CLI binary: `oke`.
|
|
79
|
-
- `create-oke` — scaffold CLI (`bunx create-oke@latest <name>`). Lives in `packages/create-oke`;
|
|
79
|
+
- `create-oke` — scaffold CLI (`bunx create-oke@latest <name>`). Lives in `packages/create-oke`; clean starters are `templates/*`, teaching apps stay in `examples/*` (`--from-example`).
|
|
80
80
|
|
|
81
81
|
Engine: Bun `>=1.3`.
|
|
82
82
|
|
package/README.md
CHANGED
|
@@ -2,13 +2,21 @@
|
|
|
2
2
|
|
|
3
3
|
*"Encore's batteries and dashboard, Elysia's speed and DX, Hono's portability — without the Rust lock-in, the cloud gravity, or the source-available license."*
|
|
4
4
|
|
|
5
|
+
[](https://www.npmjs.com/package/okengine)
|
|
6
|
+
[](https://jsr.io/@omqkhafi/okengine)
|
|
7
|
+
[](https://www.npmjs.com/package/create-oke)
|
|
5
8
|
[](https://opensource.org/licenses/MIT)
|
|
6
9
|
[](https://bun.sh)
|
|
7
10
|
|
|
8
|
-
**
|
|
11
|
+
**Framework:** [`okengine`](https://www.npmjs.com/package/okengine) · **CLI:** `oke` · **Scaffold:** [`create-oke`](https://www.npmjs.com/package/create-oke) · **Docs:** [oke.dev](https://oke.dev) · **License:** MIT
|
|
9
12
|
|
|
10
|
-
|
|
13
|
+
### Install
|
|
11
14
|
|
|
15
|
+
```bash
|
|
16
|
+
bun add okengine # npm (recommended — ships the `oke` CLI)
|
|
17
|
+
bunx jsr add @omqkhafi/okengine # JSR — library API only
|
|
18
|
+
bunx create-oke@latest my-app --template hello # scaffold from npm
|
|
19
|
+
```
|
|
12
20
|
---
|
|
13
21
|
|
|
14
22
|
## Start here
|
|
@@ -27,14 +35,14 @@ Eight elements cover what a backend needs. Ten exports are the whole public voca
|
|
|
27
35
|
import { on, flow, signal, store, clock, gate, vault, channel, ai, plugin } from "okengine";
|
|
28
36
|
```
|
|
29
37
|
|
|
30
|
-
Batteries included for the Bun era: contract-first APIs, typed client, infrastructure primitives, Console, auth — pure TypeScript, MIT, self-hostable, no cloud lock-in.
|
|
38
|
+
Batteries included for the Bun era: contract-first APIs, typed client, infrastructure primitives, Console, auth — pure TypeScript, MIT, self-hostable, no cloud lock-in. Handbook: [oke.dev/docs](https://oke.dev/docs). Spec depth: [`docs/spec/unified-theory.md`](https://github.com/omqkhafi/okengine/blob/main/docs/spec/unified-theory.md).
|
|
31
39
|
|
|
32
40
|
---
|
|
33
41
|
|
|
34
42
|
## Run something in two minutes
|
|
35
43
|
|
|
36
44
|
```bash
|
|
37
|
-
bunx create-oke@latest my-app
|
|
45
|
+
bunx create-oke@latest my-app --template hello
|
|
38
46
|
cd my-app
|
|
39
47
|
oke dev
|
|
40
48
|
```
|
|
@@ -43,9 +51,13 @@ oke dev
|
|
|
43
51
|
|---|---|
|
|
44
52
|
| `:6530` | your app |
|
|
45
53
|
| `:6533` | Console |
|
|
46
|
-
| `:6535` | MCP |
|
|
54
|
+
| `:6535` | MCP (your live Manifest, for agents) |
|
|
55
|
+
|
|
56
|
+
Mnemonic: **O·K·E = 6·5·3**. Docs MCP for the handbook is a separate surface on `:6536` (search/fetch only — see [Documentation](#documentation)).
|
|
57
|
+
|
|
58
|
+
That scaffolds the **hello** starter — one flow, no Store, the fastest true "it works" moment. Default without `--template` is **standard** (full recommended file layout, empty scaffolding). Open the Console — flows, contracts, effects, and an architecture diagram are already there. Derived, not configured.
|
|
47
59
|
|
|
48
|
-
|
|
60
|
+
Prefer a worked teaching app (business logic + comments)? Use `--from-example notes|linkly|provisions|skyport` instead.
|
|
49
61
|
|
|
50
62
|
### The idea, in one file
|
|
51
63
|
|
|
@@ -119,7 +131,9 @@ The rest of the scaffold is small and ordinary: `oke.config.ts` (drivers by prot
|
|
|
119
131
|
|
|
120
132
|
## How to learn (read in order)
|
|
121
133
|
|
|
122
|
-
|
|
134
|
+
Start on the site if you want the handbook path: [Introduction](https://oke.dev/docs/get-started/introduction) → [Installation](https://oke.dev/docs/get-started/installation) → [Basic usage](https://oke.dev/docs/get-started/basic-usage).
|
|
135
|
+
|
|
136
|
+
Each teaching app adds the smallest next set of ideas. Do not skip ahead.
|
|
123
137
|
|
|
124
138
|
1. **Notes** — `oke`, `on`, `flow`, `http`, `store.sql`, `fx`, typed errors, typed client
|
|
125
139
|
→ [`examples/notes`](examples/notes)
|
|
@@ -133,7 +147,17 @@ Each app adds the smallest next set of ideas. Do not skip ahead.
|
|
|
133
147
|
4. **Skyport** — `ai`, multi-tenancy, SLOs, distributed topology, scaling axes
|
|
134
148
|
→ [`examples/skyport`](examples/skyport)
|
|
135
149
|
|
|
136
|
-
|
|
150
|
+
Same path in the spec: [`docs/spec/four-applications.md`](docs/spec/four-applications.md).
|
|
151
|
+
|
|
152
|
+
---
|
|
153
|
+
|
|
154
|
+
## Documentation
|
|
155
|
+
|
|
156
|
+
- **Site** — [oke.dev](https://oke.dev) (landing) · [oke.dev/docs](https://oke.dev/docs) (handbook) · [changelog](https://oke.dev/changelog)
|
|
157
|
+
- **Agents on the site** — [`/llms.txt`](https://oke.dev/llms.txt) index · [`/llms-full.txt`](https://oke.dev/llms-full.txt) full text · `/llms.mdx/docs/...` per-page markdown
|
|
158
|
+
- **Docs MCP** — `:6536` · tools `oke.docs.search` / `oke.docs.get` (read-only; Host/Origin validated like the other surfaces)
|
|
159
|
+
- **App MCP** — `:6535` · live Manifest, schemas, effects, traces, Console-safe actions (Bearer + confirmation for writes)
|
|
160
|
+
- **Canonical specs in-repo** — [`docs/spec/`](docs/spec) (unified theory, four applications, Console)
|
|
137
161
|
|
|
138
162
|
---
|
|
139
163
|
|
|
@@ -180,7 +204,7 @@ flowchart TD
|
|
|
180
204
|
|
|
181
205
|
Seventeen panels on `:6533` (app `:6530`, MCP `:6535`): Overview, Flows, Signals, Store, Clock, Gates, Vault, Channels, AI, Architecture, Traces, Runs, Manifest Diff, Access, Plugins — plus Privacy and Tenancy when those plugins are plugged.
|
|
182
206
|
|
|
183
|
-
Operator and user planes stay separate. Every Console action is a real flow through `fx`, so the audit log is the trace.
|
|
207
|
+
Operator and user planes stay separate. Every Console action is a real flow through `fx`, so the audit log is the trace. Spec: [`docs/spec/console.md`](docs/spec/console.md) · handbook: [oke.dev/docs/console](https://oke.dev/docs/console/overview).
|
|
184
208
|
|
|
185
209
|
---
|
|
186
210
|
|
|
@@ -302,7 +326,7 @@ Long form is canonical in docs; short form is convenience only. Shared letters f
|
|
|
302
326
|
|
|
303
327
|
`.plug()` attaches a plugin. Scope is the attachment point: `app.plug()` app-wide, `unit.plug()` one unit, `flow.plug()` one flow. No `global: true`, no inheritance rule — [unified theory §14](docs/spec/unified-theory.md#14-plugins--the-extensibility-law).
|
|
304
328
|
|
|
305
|
-
The Console is treated as internet-facing even on localhost. Host header validation, Origin validation, and authentication are mandatory on `:6530`, `:6533`, and `:6535` ([console.md §10](docs/spec/console.md#10-security-posture)): two-plane auth (operator vs user), capability-scoped tokens.
|
|
329
|
+
The Console is treated as internet-facing even on localhost. Host header validation, Origin validation, and authentication are mandatory on `:6530`, `:6533`, and `:6535` ([console.md §10](docs/spec/console.md#10-security-posture)): two-plane auth (operator vs user), capability-scoped tokens. Docs MCP `:6536` uses the same Host/Origin checks and stays read-only (no Bearer writes).
|
|
306
330
|
|
|
307
331
|
---
|
|
308
332
|
|
|
@@ -316,12 +340,21 @@ The Console is treated as internet-facing even on localhost. Host header validat
|
|
|
316
340
|
|
|
317
341
|
---
|
|
318
342
|
|
|
343
|
+
## Budgets
|
|
344
|
+
|
|
345
|
+
Measured size and latency caps — see [`BUDGETS.md`](BUDGETS.md). Refresh with `bun run budgets`.
|
|
346
|
+
|
|
347
|
+
---
|
|
348
|
+
|
|
319
349
|
## Status
|
|
320
350
|
|
|
321
|
-
Pre-1.0. MIT. No `CONTRIBUTING` yet — issues and PRs welcome.
|
|
351
|
+
Pre-1.0. Published on [npm](https://www.npmjs.com/package/okengine) and [JSR](https://jsr.io/@omqkhafi/okengine) (`okengine` + `create-oke`, lockstep). Docs at [oke.dev](https://oke.dev). MIT. No `CONTRIBUTING` yet — issues and PRs welcome.
|
|
322
352
|
|
|
323
|
-
|
|
|
353
|
+
| Resource | Path |
|
|
324
354
|
|---|---|
|
|
325
|
-
|
|
|
326
|
-
|
|
|
327
|
-
|
|
|
355
|
+
| Docs site | [oke.dev](https://oke.dev) · [handbook](https://oke.dev/docs) · [changelog](https://oke.dev/changelog) |
|
|
356
|
+
| Unified theory | [`docs/spec/unified-theory.md`](https://github.com/omqkhafi/okengine/blob/main/docs/spec/unified-theory.md) |
|
|
357
|
+
| Four applications | [`docs/spec/four-applications.md`](https://github.com/omqkhafi/okengine/blob/main/docs/spec/four-applications.md) |
|
|
358
|
+
| Console | [`docs/spec/console.md`](https://github.com/omqkhafi/okengine/blob/main/docs/spec/console.md) |
|
|
359
|
+
| Scaffold | [`packages/create-oke`](https://github.com/omqkhafi/okengine/tree/main/packages/create-oke) |
|
|
360
|
+
| Changelog source | [`docs/changelog.md`](docs/changelog.md) |
|
|
@@ -1149,7 +1149,6 @@ oke images pin # tags → digests in oke.images.lock
|
|
|
1149
1149
|
|
|
1150
1150
|
oke build --target edge # < 15 kB kernel profile
|
|
1151
1151
|
oke eval # run prompt eval sets; fails CI on regression
|
|
1152
|
-
oke ai cost --since 7d # cost per flow, per tenant, per prompt version
|
|
1153
1152
|
oke branch prod --at "yesterday" # fork journaled state into a sandbox
|
|
1154
1153
|
oke privacy erase --subject <id> # crypto-shredding: deletes the key, not the terabytes
|
|
1155
1154
|
oke upgrade # run codemods for a breaking change, print the diff
|
|
@@ -416,7 +416,7 @@ Plus `oke import express|hono|elysia` codemods for the mechanical parts. Migrati
|
|
|
416
416
|
|---|---|
|
|
417
417
|
| Kernel (edge profile) | < 15 kB |
|
|
418
418
|
| Client runtime | < 3 kB |
|
|
419
|
-
| Cold start on Bun | < 75 ms |
|
|
419
|
+
| Cold start on Bun | < 75 ms in CI (GitHub Actions runners are less predictable than a dev machine); measured ~25–30 ms on real hardware |
|
|
420
420
|
| p99 routing overhead | < 1 ms |
|
|
421
421
|
|
|
422
422
|
A regression fails OKE's own build. Claims we cannot measure, we do not make.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "okengine",
|
|
3
|
-
"version": "0.1
|
|
3
|
+
"version": "0.2.1",
|
|
4
4
|
"description": "One law. Eight elements. Ten exports. One package. One manifest. Every backend need is derived, never added.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -10,7 +10,9 @@
|
|
|
10
10
|
"url": "git+https://github.com/omqkhafi/okengine.git"
|
|
11
11
|
},
|
|
12
12
|
"workspaces": [
|
|
13
|
-
"
|
|
13
|
+
"packages/*",
|
|
14
|
+
"examples/*",
|
|
15
|
+
"site"
|
|
14
16
|
],
|
|
15
17
|
"scripts": {
|
|
16
18
|
"typecheck": "tsc --noEmit",
|
|
@@ -44,10 +46,13 @@
|
|
|
44
46
|
"gate:errors": "bun test src/kernel/errors.registry.test.ts",
|
|
45
47
|
"gate:codemods": "bun test src/upgrade/codemods.test.ts",
|
|
46
48
|
"test:examples": "bun test examples/notes && bun test examples/linkly && bun test examples/provisions && bun test examples/skyport",
|
|
47
|
-
"test:create-oke": "bun run --cwd packages/create-oke typecheck && bun test packages/create-oke/src && CREATE_OKE_INTEGRATION=1 bun test packages/create-oke/tests/scaffold.integration.test.ts packages/create-oke/tests/dev.integration.test.ts",
|
|
49
|
+
"test:create-oke": "bun run --cwd packages/create-oke typecheck && bun test packages/create-oke/src && CREATE_OKE_INTEGRATION=1 bun test --timeout 180000 packages/create-oke/tests/scaffold.integration.test.ts packages/create-oke/tests/dev.integration.test.ts",
|
|
48
50
|
"test:doc-drift": "bun src/cli/doc-drift.ts",
|
|
51
|
+
"site:sync": "bun run --cwd site sync",
|
|
52
|
+
"site:dev": "bun run --cwd site dev",
|
|
53
|
+
"site:build": "bun run --cwd site build",
|
|
49
54
|
"test:skyport-docker": "bun test examples/skyport/tests/docker.test.ts",
|
|
50
|
-
"ci": "bun run bench:cold-start && bun run typecheck && bun run test && bun run budgets && bun run gate:doctor-diff && bun run gate:errors && bun run gate:codemods && bun run test:doc-drift && bun run test:examples && bun run test:skyport-docker && bun run test:create-oke",
|
|
55
|
+
"ci": "bun run bench:cold-start && bun run typecheck && bun run test && bun run budgets && bun run gate:doctor-diff && bun run gate:errors && bun run gate:codemods && bun run test:doc-drift && bun run site:build && bun run test:examples && bun run test:skyport-docker && bun run test:create-oke",
|
|
51
56
|
"gate:publish": "bun test scripts/publish.gate.test.ts",
|
|
52
57
|
"bump": "bun run scripts/bump-version.ts",
|
|
53
58
|
"publish:all": "bun run scripts/publish.ts",
|
|
@@ -60,13 +65,13 @@
|
|
|
60
65
|
},
|
|
61
66
|
"dependencies": {
|
|
62
67
|
"@duckdb/node-api": "^1.5.5-r.1",
|
|
63
|
-
"age-encryption": "^0.3.0",
|
|
64
68
|
"ajv": "^8.20.0",
|
|
65
69
|
"ajv-formats": "^3.0.1",
|
|
66
70
|
"oxc-parser": "^0.141.0",
|
|
67
71
|
"sently": "^0.8.0"
|
|
68
72
|
},
|
|
69
73
|
"devDependencies": {
|
|
74
|
+
"age-encryption": "^0.3.0",
|
|
70
75
|
"@base-ui/react": "^1.6.0",
|
|
71
76
|
"@codemirror/commands": "^6.10.4",
|
|
72
77
|
"@codemirror/lang-json": "^6.0.2",
|
|
@@ -103,11 +108,16 @@
|
|
|
103
108
|
"zod": "^4.4.3"
|
|
104
109
|
},
|
|
105
110
|
"peerDependencies": {
|
|
111
|
+
"age-encryption": "^0.3.0",
|
|
106
112
|
"drizzle-kit": ">=1.0.0-rc.0",
|
|
107
113
|
"drizzle-orm": ">=1.0.0-rc.0",
|
|
108
|
-
"drizzle-seed": ">=0.3.0"
|
|
114
|
+
"drizzle-seed": ">=0.3.0",
|
|
115
|
+
"zod": ">=3.23.0"
|
|
109
116
|
},
|
|
110
117
|
"peerDependenciesMeta": {
|
|
118
|
+
"age-encryption": {
|
|
119
|
+
"optional": true
|
|
120
|
+
},
|
|
111
121
|
"drizzle-kit": {
|
|
112
122
|
"optional": true
|
|
113
123
|
},
|
|
@@ -116,13 +126,16 @@
|
|
|
116
126
|
},
|
|
117
127
|
"drizzle-seed": {
|
|
118
128
|
"optional": true
|
|
129
|
+
},
|
|
130
|
+
"zod": {
|
|
131
|
+
"optional": true
|
|
119
132
|
}
|
|
120
133
|
},
|
|
121
134
|
"engines": {
|
|
122
135
|
"bun": ">=1.3"
|
|
123
136
|
},
|
|
124
137
|
"bin": {
|
|
125
|
-
"oke": "
|
|
138
|
+
"oke": "src/cli/index.ts"
|
|
126
139
|
},
|
|
127
140
|
"exports": {
|
|
128
141
|
".": "./src/index.ts",
|
|
@@ -149,4 +162,4 @@
|
|
|
149
162
|
"AGENTS.md",
|
|
150
163
|
"docs/spec"
|
|
151
164
|
]
|
|
152
|
-
}
|
|
165
|
+
}
|
package/src/auth/index.ts
CHANGED
package/src/cli/dev.ts
CHANGED
|
@@ -500,7 +500,9 @@ async function startAppHot(
|
|
|
500
500
|
if (stopped) return;
|
|
501
501
|
stopped = true;
|
|
502
502
|
try {
|
|
503
|
-
|
|
503
|
+
// SIGKILL so `bun --hot` cannot linger and hold the project directory
|
|
504
|
+
// open (create-oke afterEach `rmSync` otherwise races the child exit).
|
|
505
|
+
proc.kill("SIGKILL");
|
|
504
506
|
} catch {
|
|
505
507
|
// already exited
|
|
506
508
|
}
|
package/src/cli/doc-drift.ts
CHANGED
|
@@ -14,6 +14,10 @@
|
|
|
14
14
|
* Usage:
|
|
15
15
|
* bun src/cli/doc-drift.ts
|
|
16
16
|
* bun src/cli/doc-drift.ts docs/spec/four-applications.md README.md
|
|
17
|
+
* bun src/cli/doc-drift.ts site/content/docs/learn/notes.md
|
|
18
|
+
*
|
|
19
|
+
* Default paths: four-applications.md, README.md, and every markdown/MDX file
|
|
20
|
+
* under site/content/docs (claimed fences only — prose-only pages skip).
|
|
17
21
|
*/
|
|
18
22
|
|
|
19
23
|
import { resolve } from "node:path";
|
|
@@ -21,8 +25,27 @@ import { Window } from "happy-dom";
|
|
|
21
25
|
|
|
22
26
|
const ROOT = resolve(import.meta.dir, "../..");
|
|
23
27
|
|
|
24
|
-
/**
|
|
25
|
-
|
|
28
|
+
/**
|
|
29
|
+
* Discover site content markdown that may contain claimed fences.
|
|
30
|
+
*
|
|
31
|
+
* @param root - Repo root
|
|
32
|
+
*/
|
|
33
|
+
async function discoverSiteDocs(root: string): Promise<string[]> {
|
|
34
|
+
const docsDir = resolve(root, "site/content/docs");
|
|
35
|
+
const out: string[] = [];
|
|
36
|
+
try {
|
|
37
|
+
const glob = new Bun.Glob("**/*.{md,mdx}");
|
|
38
|
+
for await (const rel of glob.scan({ cwd: docsDir, onlyFiles: true })) {
|
|
39
|
+
out.push(resolve(docsDir, rel));
|
|
40
|
+
}
|
|
41
|
+
} catch {
|
|
42
|
+
// site/ not present yet — skip
|
|
43
|
+
}
|
|
44
|
+
return out.sort();
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/** Core docs that must contain claimed fences. */
|
|
48
|
+
const REQUIRED_DOCS: readonly string[] = [
|
|
26
49
|
resolve(ROOT, "docs/spec/four-applications.md"),
|
|
27
50
|
resolve(ROOT, "README.md"),
|
|
28
51
|
];
|
|
@@ -315,6 +338,9 @@ export async function checkDocDrift(
|
|
|
315
338
|
/**
|
|
316
339
|
* Run doc-drift over one or more markdown files.
|
|
317
340
|
*
|
|
341
|
+
* Site content under `site/` may have zero claimed fences (prose-only pages);
|
|
342
|
+
* only `docs/spec/four-applications.md` and `README.md` require at least one.
|
|
343
|
+
*
|
|
318
344
|
* @param paths - Absolute or repo-relative markdown paths
|
|
319
345
|
*/
|
|
320
346
|
export async function runDocDrift(
|
|
@@ -324,32 +350,36 @@ export async function runDocDrift(
|
|
|
324
350
|
let ok = true;
|
|
325
351
|
let total = 0;
|
|
326
352
|
let mermaidTotal = 0;
|
|
353
|
+
let checkedFiles = 0;
|
|
327
354
|
|
|
328
355
|
for (const path of paths) {
|
|
329
356
|
const abs = resolve(ROOT, path);
|
|
330
357
|
const label = abs.startsWith(ROOT + "/")
|
|
331
358
|
? abs.slice(ROOT.length + 1)
|
|
332
359
|
: abs;
|
|
360
|
+
const requireClaimed = !label.startsWith("site/");
|
|
333
361
|
const markdown = await Bun.file(abs).text();
|
|
334
362
|
const fences = parseClaimedFences(markdown);
|
|
335
363
|
if (fences.length === 0) {
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
const result = await checkDocDrift(fences);
|
|
342
|
-
total += fences.length;
|
|
343
|
-
if (!result.ok) {
|
|
344
|
-
ok = false;
|
|
345
|
-
messages.push(
|
|
346
|
-
`doc-drift: ${result.failures.length} failure(s) in ${label}`,
|
|
347
|
-
);
|
|
348
|
-
for (const f of result.failures) messages.push(` · ${f}`);
|
|
364
|
+
if (requireClaimed) {
|
|
365
|
+
messages.push(`doc-drift: no claimed fences found in ${label}`);
|
|
366
|
+
ok = false;
|
|
367
|
+
}
|
|
349
368
|
} else {
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
369
|
+
checkedFiles++;
|
|
370
|
+
const result = await checkDocDrift(fences);
|
|
371
|
+
total += fences.length;
|
|
372
|
+
if (!result.ok) {
|
|
373
|
+
ok = false;
|
|
374
|
+
messages.push(
|
|
375
|
+
`doc-drift: ${result.failures.length} failure(s) in ${label}`,
|
|
376
|
+
);
|
|
377
|
+
for (const f of result.failures) messages.push(` · ${f}`);
|
|
378
|
+
} else {
|
|
379
|
+
messages.push(
|
|
380
|
+
`doc-drift: ok — ${fences.length} claimed fence(s) in ${label}`,
|
|
381
|
+
);
|
|
382
|
+
}
|
|
353
383
|
}
|
|
354
384
|
|
|
355
385
|
const mermaidFences = parseMermaidFences(markdown);
|
|
@@ -370,11 +400,11 @@ export async function runDocDrift(
|
|
|
370
400
|
}
|
|
371
401
|
}
|
|
372
402
|
|
|
373
|
-
if (ok &&
|
|
403
|
+
if (ok && checkedFiles > 1) {
|
|
374
404
|
const mermaidNote =
|
|
375
405
|
mermaidTotal > 0 ? ` · ${mermaidTotal} mermaid fence(s)` : "";
|
|
376
406
|
messages.push(
|
|
377
|
-
`doc-drift: ok — ${total} claimed fence(s) across ${
|
|
407
|
+
`doc-drift: ok — ${total} claimed fence(s) across ${checkedFiles} file(s)${mermaidNote}`,
|
|
378
408
|
);
|
|
379
409
|
}
|
|
380
410
|
|
|
@@ -383,7 +413,10 @@ export async function runDocDrift(
|
|
|
383
413
|
|
|
384
414
|
async function main(): Promise<number> {
|
|
385
415
|
const args = process.argv.slice(2);
|
|
386
|
-
const paths =
|
|
416
|
+
const paths =
|
|
417
|
+
args.length > 0
|
|
418
|
+
? args
|
|
419
|
+
: [...REQUIRED_DOCS, ...(await discoverSiteDocs(ROOT))];
|
|
387
420
|
const { ok, messages } = await runDocDrift(paths);
|
|
388
421
|
for (const m of messages) {
|
|
389
422
|
if (ok) console.log(m);
|
package/src/client/index.ts
CHANGED
package/src/config/index.ts
CHANGED
package/src/console/index.ts
CHANGED
|
@@ -3,28 +3,41 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Built on `createClient<ConsoleApp>`. Every action is a real flow through `fx`;
|
|
5
5
|
* the audit log is the trace (docs/spec/console.md).
|
|
6
|
+
*
|
|
7
|
+
* Imports leaf modules (not `server/index`) so unused panel projectors stay out
|
|
8
|
+
* of the `okengine/console` graph when tree-shaken.
|
|
9
|
+
*
|
|
10
|
+
* @module
|
|
6
11
|
*/
|
|
7
12
|
|
|
8
13
|
export {
|
|
9
14
|
bootConsoleApp,
|
|
15
|
+
createConsoleApp,
|
|
16
|
+
type ConsoleApp,
|
|
17
|
+
type ConsoleAppHandle,
|
|
18
|
+
type CreateConsoleAppOptions,
|
|
19
|
+
} from "./server/app.ts";
|
|
20
|
+
export {
|
|
10
21
|
CLAIM_TTL_MS,
|
|
22
|
+
mintClaimCode,
|
|
23
|
+
printClaimCodeOnce,
|
|
24
|
+
verifyClaimCode,
|
|
25
|
+
} from "./server/claim.ts";
|
|
26
|
+
export { feedManifest } from "./server/live.ts";
|
|
27
|
+
export { consolePlugin } from "./server/plugin.ts";
|
|
28
|
+
export {
|
|
11
29
|
CONSOLE_COOKIES,
|
|
12
30
|
CONSOLE_CSP,
|
|
13
31
|
PLUGIN_IFRAME_SANDBOX,
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
feedManifest,
|
|
18
|
-
mintClaimCode,
|
|
19
|
-
printClaimCodeOnce,
|
|
32
|
+
withConsoleSecurityHeaders,
|
|
33
|
+
} from "./server/security-headers.ts";
|
|
34
|
+
export {
|
|
20
35
|
serveConsole,
|
|
21
36
|
startConsoleApp,
|
|
22
|
-
verifyClaimCode,
|
|
23
|
-
withConsoleSecurityHeaders,
|
|
24
|
-
type ConsoleApp,
|
|
25
|
-
type ConsoleAppHandle,
|
|
26
37
|
type ConsoleServerHandle,
|
|
27
|
-
type ConsoleState,
|
|
28
|
-
type CreateConsoleAppOptions,
|
|
29
38
|
type ServeConsoleOptions,
|
|
30
|
-
} from "./server/
|
|
39
|
+
} from "./server/serve.ts";
|
|
40
|
+
export {
|
|
41
|
+
createConsoleState,
|
|
42
|
+
type ConsoleState,
|
|
43
|
+
} from "./server/state.ts";
|
|
@@ -140,16 +140,53 @@ export async function bootConsoleApp(
|
|
|
140
140
|
if (!runs) return [];
|
|
141
141
|
return runs.all();
|
|
142
142
|
};
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
await bindManifestVaultRuntime(handle.state);
|
|
146
|
-
await bindManifestGateRuntime(handle.state);
|
|
147
|
-
await bindManifestClockRuntime(handle.state);
|
|
148
|
-
bindManifestAiRuntime(handle.state);
|
|
149
|
-
bindManifestChannelRuntime(handle.state);
|
|
143
|
+
// Element runtimes bind lazily on first panel access (see ensure* below
|
|
144
|
+
// via list* methods / bindManifest* callers) — not all seventeen at boot.
|
|
150
145
|
return handle.app;
|
|
151
146
|
}
|
|
152
147
|
|
|
148
|
+
/**
|
|
149
|
+
* Ensure Manifest-backed element runtimes for a panel are bound (idempotent).
|
|
150
|
+
*
|
|
151
|
+
* @param state - Console state
|
|
152
|
+
* @param panel - Panel id that was visited
|
|
153
|
+
*/
|
|
154
|
+
export async function ensureConsolePanelRuntimes(
|
|
155
|
+
state: ConsoleState,
|
|
156
|
+
panel:
|
|
157
|
+
| "signals"
|
|
158
|
+
| "store"
|
|
159
|
+
| "vault"
|
|
160
|
+
| "gates"
|
|
161
|
+
| "clock"
|
|
162
|
+
| "ai"
|
|
163
|
+
| "channels",
|
|
164
|
+
): Promise<void> {
|
|
165
|
+
switch (panel) {
|
|
166
|
+
case "signals":
|
|
167
|
+
await bindManifestSignalBus(state);
|
|
168
|
+
break;
|
|
169
|
+
case "store":
|
|
170
|
+
await bindManifestStoreRuntime(state);
|
|
171
|
+
break;
|
|
172
|
+
case "vault":
|
|
173
|
+
await bindManifestVaultRuntime(state);
|
|
174
|
+
break;
|
|
175
|
+
case "gates":
|
|
176
|
+
await bindManifestGateRuntime(state);
|
|
177
|
+
break;
|
|
178
|
+
case "clock":
|
|
179
|
+
await bindManifestClockRuntime(state);
|
|
180
|
+
break;
|
|
181
|
+
case "ai":
|
|
182
|
+
bindManifestAiRuntime(state);
|
|
183
|
+
break;
|
|
184
|
+
case "channels":
|
|
185
|
+
bindManifestChannelRuntime(state);
|
|
186
|
+
break;
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
|
|
153
190
|
/**
|
|
154
191
|
* Bind a ChannelRuntime + console inbox from the Manifest when no host
|
|
155
192
|
* runtime is attached — Console surfaces real receipts / inbox, not mocks.
|
|
@@ -30,14 +30,10 @@ import {
|
|
|
30
30
|
} from "./clock.ts";
|
|
31
31
|
import { createFileDiff, emitStructuralDiff } from "./structural.ts";
|
|
32
32
|
import type { ConsoleState } from "./state.ts";
|
|
33
|
+
import { PUBLIC_CONSOLE_FLOWS } from "./public-flows.ts";
|
|
33
34
|
import { tenancyDeclared } from "./store.ts";
|
|
34
35
|
|
|
35
|
-
|
|
36
|
-
export const PUBLIC_CONSOLE_FLOWS = new Set([
|
|
37
|
-
"console.setup.status",
|
|
38
|
-
"console.setup.claim",
|
|
39
|
-
"console.session.login",
|
|
40
|
-
]);
|
|
36
|
+
export { PUBLIC_CONSOLE_FLOWS };
|
|
41
37
|
|
|
42
38
|
const SetupStatusOut = z.object({
|
|
43
39
|
setupClosed: z.boolean(),
|
|
@@ -30,6 +30,7 @@ export {
|
|
|
30
30
|
bindManifestVaultRuntime,
|
|
31
31
|
bootConsoleApp,
|
|
32
32
|
createConsoleApp,
|
|
33
|
+
ensureConsolePanelRuntimes,
|
|
33
34
|
type ConsoleApp,
|
|
34
35
|
type ConsoleAppHandle,
|
|
35
36
|
type CreateConsoleAppOptions,
|
|
@@ -72,8 +73,8 @@ export {
|
|
|
72
73
|
} from "./claim.ts";
|
|
73
74
|
export {
|
|
74
75
|
createConsoleBindings,
|
|
75
|
-
PUBLIC_CONSOLE_FLOWS,
|
|
76
76
|
} from "./flows.ts";
|
|
77
|
+
export { PUBLIC_CONSOLE_FLOWS } from "./public-flows.ts";
|
|
77
78
|
export {
|
|
78
79
|
createLiveWebsocket,
|
|
79
80
|
feedManifest,
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Console per-panel backends construct lazily on first access.
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import { describe, expect, test } from "bun:test";
|
|
6
|
+
import { createConsoleState } from "./state.ts";
|
|
7
|
+
|
|
8
|
+
describe("console — lazy panel construction", () => {
|
|
9
|
+
test("createConsoleState constructs no panel backends", () => {
|
|
10
|
+
const state = createConsoleState({ silentClaim: true, secret: "x" });
|
|
11
|
+
expect([...state.constructedPanels]).toEqual([]);
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
test("only the visited panel is constructed", async () => {
|
|
15
|
+
const state = createConsoleState({ silentClaim: true, secret: "x" });
|
|
16
|
+
expect([...state.constructedPanels]).toEqual([]);
|
|
17
|
+
|
|
18
|
+
await state.listVault();
|
|
19
|
+
expect([...state.constructedPanels]).toEqual(["vault"]);
|
|
20
|
+
|
|
21
|
+
await state.listStores();
|
|
22
|
+
expect([...state.constructedPanels].sort()).toEqual(["store", "vault"]);
|
|
23
|
+
|
|
24
|
+
await state.listVault();
|
|
25
|
+
expect([...state.constructedPanels].sort()).toEqual(["store", "vault"]);
|
|
26
|
+
});
|
|
27
|
+
});
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Lazy Console panel module loader — expression `new URL` keeps panel
|
|
3
|
+
* backends out of the createConsoleState / createConsoleApp graph until
|
|
4
|
+
* first access (mirrors kernel boot-bind).
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
/** Panel ids that own server-side projection / mutation modules. */
|
|
8
|
+
export type ConsolePanelId =
|
|
9
|
+
| "access"
|
|
10
|
+
| "gates"
|
|
11
|
+
| "signals"
|
|
12
|
+
| "store"
|
|
13
|
+
| "clock"
|
|
14
|
+
| "vault"
|
|
15
|
+
| "ai"
|
|
16
|
+
| "channels"
|
|
17
|
+
| "plugins"
|
|
18
|
+
| "diff";
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Load a Console panel module by id without bundling it into the parent.
|
|
22
|
+
*
|
|
23
|
+
* @param id - Panel module stem (`store`, `vault`, …)
|
|
24
|
+
*/
|
|
25
|
+
export async function loadConsolePanel<T>(id: ConsolePanelId): Promise<T> {
|
|
26
|
+
const url = new URL(`./${id}.ts`, import.meta.url);
|
|
27
|
+
return import(url.href) as Promise<T>;
|
|
28
|
+
}
|