okengine 0.18.4 → 0.19.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 +18 -10
- package/README.md +2 -2
- package/package.json +51 -50
- package/site/content/docs/ai/index.mdx +25 -6
- package/site/content/docs/ai/llms-txt.mdx +1 -1
- package/site/content/docs/ai/meta.json +1 -1
- package/site/content/docs/ai/skills.mdx +4 -1
- package/site/content/docs/ai/try-it.mdx +58 -0
- package/site/content/docs/client/auth.mdx +208 -0
- package/site/content/docs/client/calling.mdx +451 -0
- package/site/content/docs/client/index.mdx +209 -0
- package/site/content/docs/client/live.mdx +234 -0
- package/site/content/docs/client/meta.json +5 -0
- package/site/content/docs/client/react.mdx +249 -0
- package/site/content/docs/elements/ai/agents.mdx +232 -0
- package/site/content/docs/elements/ai/index.mdx +341 -0
- package/site/content/docs/elements/ai/mcp.mdx +275 -0
- package/site/content/docs/elements/ai/meta.json +5 -0
- package/site/content/docs/elements/ai/models.mdx +283 -0
- package/site/content/docs/elements/ai/prompts.mdx +256 -0
- package/site/content/docs/elements/channel/email.mdx +266 -0
- package/site/content/docs/elements/channel/index.mdx +344 -0
- package/site/content/docs/elements/channel/meta.json +5 -0
- package/site/content/docs/elements/channel/push.mdx +218 -0
- package/site/content/docs/elements/channel/receipts.mdx +206 -0
- package/site/content/docs/elements/channel/sms.mdx +264 -0
- package/site/content/docs/elements/channel/whatsapp.mdx +220 -0
- package/site/content/docs/elements/clock/index.mdx +300 -0
- package/site/content/docs/elements/clock/meta.json +5 -0
- package/site/content/docs/elements/clock/schedules.mdx +508 -0
- package/site/content/docs/elements/clock/sleep.mdx +445 -0
- package/site/content/docs/elements/flow/consumers.mdx +707 -0
- package/site/content/docs/elements/flow/http.mdx +1080 -0
- package/site/content/docs/elements/flow/index.mdx +618 -0
- package/site/content/docs/elements/flow/meta.json +5 -0
- package/site/content/docs/elements/flow/routing.mdx +559 -0
- package/site/content/docs/elements/flow/workflows.mdx +640 -0
- package/site/content/docs/elements/gate/auth.mdx +371 -0
- package/site/content/docs/elements/gate/authorization.mdx +298 -0
- package/site/content/docs/elements/gate/index.mdx +418 -0
- package/site/content/docs/elements/gate/meta.json +5 -0
- package/site/content/docs/elements/gate/rate-limits.mdx +365 -0
- package/site/content/docs/elements/gate/rls.mdx +303 -0
- package/site/content/docs/elements/gate/tenancy.mdx +372 -0
- package/site/content/docs/elements/index.mdx +52 -11
- package/site/content/docs/elements/signal/broadcast.mdx +517 -0
- package/site/content/docs/elements/signal/index.mdx +352 -0
- package/site/content/docs/elements/signal/live.mdx +590 -0
- package/site/content/docs/elements/signal/meta.json +5 -0
- package/site/content/docs/elements/signal/once.mdx +596 -0
- package/site/content/docs/elements/store/files.mdx +659 -0
- package/site/content/docs/elements/store/index.mdx +310 -0
- package/site/content/docs/elements/store/kv.mdx +629 -0
- package/site/content/docs/elements/store/meta.json +5 -0
- package/site/content/docs/elements/store/search.mdx +946 -0
- package/site/content/docs/elements/store/sql.mdx +937 -0
- package/site/content/docs/elements/vault/config.mdx +256 -0
- package/site/content/docs/elements/vault/index.mdx +356 -0
- package/site/content/docs/elements/vault/meta.json +5 -0
- package/site/content/docs/elements/vault/rotation.mdx +273 -0
- package/site/content/docs/elements/vault/secrets.mdx +285 -0
- package/site/content/docs/index.mdx +78 -30
- package/site/content/docs/meta.json +11 -8
- package/site/content/docs/plugins/cors.mdx +2 -1
- package/site/content/docs/plugins/csrf.mdx +4 -1
- package/site/content/docs/plugins/headers.mdx +2 -1
- package/site/content/docs/plugins/ip-allowlist.mdx +2 -1
- package/site/content/docs/plugins/magic-link.mdx +6 -0
- package/site/content/docs/plugins/maintenance-mode.mdx +2 -1
- package/site/content/docs/plugins/oauth.mdx +1 -1
- package/site/content/docs/plugins/otp.mdx +12 -1
- package/site/content/docs/plugins/passkey.mdx +39 -15
- package/site/content/docs/plugins/two-factor.mdx +91 -34
- package/site/content/docs/plugins/username.mdx +1 -1
- package/site/content/docs/recipes/caddy.mdx +3 -3
- package/site/content/docs/recipes/index.mdx +18 -28
- package/site/content/docs/recipes/mailpit.mdx +1 -1
- package/site/content/docs/recipes/meilisearch.mdx +3 -3
- package/site/content/docs/recipes/meta.json +1 -4
- package/site/content/docs/recipes/nginx.mdx +2 -2
- package/site/content/docs/recipes/openrouter.mdx +283 -0
- package/site/content/docs/recipes/pgdog.mdx +3 -3
- package/site/content/docs/recipes/postgres.mdx +1 -2
- package/site/content/docs/recipes/rustfs.mdx +2 -2
- package/site/content/docs/recipes/traefik.mdx +3 -3
- package/site/content/docs/reference/cli.mdx +231 -0
- package/site/content/docs/reference/configuration.mdx +30 -10
- package/site/content/docs/reference/environment-variables.mdx +93 -20
- package/site/content/docs/reference/errors.mdx +132 -29
- package/site/content/docs/reference/fx.mdx +137 -73
- package/site/content/docs/reference/index.mdx +13 -21
- package/site/content/docs/reference/meta.json +4 -5
- package/site/content/docs/reference/okid.mdx +42 -17
- package/site/content/docs/reference/plugins.mdx +4 -3
- package/site/content/docs/reference/security.mdx +197 -0
- package/site/content/docs/understand/meta.json +5 -0
- package/site/content/docs/understand/the-anatomy.mdx +132 -0
- package/site/content/docs/understand/the-model.mdx +32 -0
- package/site/content/docs/understand/the-problem.mdx +74 -0
- package/site/content/docs/understand/the-vocabulary.mdx +26 -0
- package/src/auth/api-keys.ts +2 -1
- package/src/auth/bindings.ts +64 -16
- package/src/auth/gate-auth.test.ts +6 -1
- package/src/auth/identity.ts +152 -5
- package/src/auth/index.ts +29 -0
- package/src/auth/invites.ts +2 -1
- package/src/auth/method-context.ts +41 -0
- package/src/auth/oauth-as/crypto.ts +2 -1
- package/src/auth/oauth-as/stores.ts +2 -1
- package/src/auth/operator.ts +2 -1
- package/src/auth/sessions-jwt.test.ts +77 -0
- package/src/auth/sessions.ts +20 -4
- package/src/auth/tenants.ts +3 -2
- package/src/auth/two-factor-challenge.test.ts +61 -0
- package/src/auth/two-factor-challenge.ts +284 -0
- package/src/auth/verification.ts +5 -0
- package/src/bench/REPORT.md +49 -0
- package/src/bench/g03-signal-once.bench.ts +1 -1
- package/src/bench/g10-observability-contention.bench.ts +1 -1
- package/src/bench/g17-hybrid-search.bench.ts +572 -0
- package/src/bench/load-app.ts +2 -10
- package/src/cli/ai-setup/ai-setup.test.ts +331 -42
- package/src/cli/ai-setup/apply.ts +294 -52
- package/src/cli/ai-setup/catalog.ts +238 -1342
- package/src/cli/ai-setup/index.ts +14 -99
- package/src/cli/ai-setup/prompts.ts +60 -443
- package/src/cli/ask-seed.test.ts +96 -0
- package/src/cli/ask-seed.ts +82 -0
- package/src/cli/ask-vault-gaps.test.ts +84 -0
- package/src/cli/ask-vault-gaps.ts +146 -0
- package/src/cli/build.ts +2 -2
- package/src/cli/client-add.test.ts +26 -1
- package/src/cli/client-add.ts +106 -27
- package/src/cli/competitor-mention-removal.test.ts +1 -1
- package/src/cli/db-seed.ts +2 -0
- package/src/cli/db.ts +150 -11
- package/src/cli/dev.ts +119 -211
- package/src/cli/docker-clean.ts +2 -2
- package/src/cli/docker-cli.test.ts +1 -1
- package/src/cli/doctor-diff.ts +4 -2
- package/src/cli/doctor-pii.test.ts +1 -1
- package/src/cli/doctor.ts +14 -1
- package/src/cli/hero-meta.test.ts +4 -2
- package/src/cli/load-config.images.test.ts +8 -10
- package/src/cli/load-config.ts +1 -1
- package/src/cli/registry.ts +22 -10
- package/src/cli/replay.ts +3 -1
- package/src/cli/start.ts +1 -1
- package/src/cli/tui/keys.ts +2 -3
- package/src/client/auth/cookies.ts +74 -0
- package/src/client/auth/create-auth-client.ts +636 -0
- package/src/client/auth/denials.ts +99 -0
- package/src/client/auth/session.ts +283 -0
- package/src/client/auth.test.ts +251 -0
- package/src/client/auth.ts +39 -114
- package/src/client/create-with-session.ts +245 -0
- package/src/client/create.ts +51 -5
- package/src/client/index.ts +11 -1
- package/src/client/live.ts +11 -79
- package/src/client/notes-contract.test.ts +5 -10
- package/src/client/sse.ts +137 -0
- package/src/client/stream.ts +147 -0
- package/src/client/transport.test.ts +32 -0
- package/src/client/transport.ts +123 -26
- package/src/client/types.ts +118 -14
- package/src/client-react/index.ts +185 -24
- package/src/client-react/use-live-query.ts +13 -3
- package/src/compiler/aot.test.ts +7 -4
- package/src/compiler/effects-embed.test.ts +56 -0
- package/src/compiler/effects-fetch.test.ts +43 -0
- package/src/compiler/effects-infer.ts +58 -2
- package/src/compiler/extract.test.ts +258 -44
- package/src/compiler/extract.ts +566 -48
- package/src/compiler/fixtures/skyport/src/flows/bookings/index.ts +7 -4
- package/src/compiler/fixtures/skyport/src/flows/bookings/signals.ts +2 -8
- package/src/compiler/fixtures/skyport.expected.json +4 -4
- package/src/compiler/fixtures/triggers/five-triggers.ts +14 -10
- package/src/compiler/response.ts +2 -2
- package/src/compiler/search-writer-isolation.test.ts +40 -0
- package/src/config/index.ts +11 -0
- package/src/console/server/app.ts +17 -23
- package/src/console/server/bind.ts +4 -0
- package/src/console/server/console.test.ts +2 -2
- package/src/console/server/flows-invoke.test.ts +50 -34
- package/src/console/server/flows.ts +436 -255
- package/src/console/server/runs-ingest.test.ts +6 -3
- package/src/console/server/serve.ts +1 -1
- package/src/console/server/signals.test.ts +1 -5
- package/src/console/server/signals.ts +8 -6
- package/src/console/server/state.ts +6 -1
- package/src/console/server/store.ts +1 -1
- package/src/console/ui-next/dist/assets/FileExportIcon-Ck-5od4R.js +1 -0
- package/src/console/ui-next/dist/assets/MoreHorizontalCircle01Icon-gMNGsE37.js +1 -0
- package/src/console/ui-next/dist/assets/PlusSignIcon-CwG3nxfu.js +1 -0
- package/src/console/ui-next/dist/assets/UnavailableIcon-D9cvHVPr.js +1 -0
- package/src/console/ui-next/dist/assets/UserIcon-DaE2PB5_.js +1 -0
- package/src/console/ui-next/dist/assets/access-page-DFeymU07.js +4 -0
- package/src/console/ui-next/dist/assets/agent-disclosure-U1rdfblp.js +1 -0
- package/src/console/ui-next/dist/assets/cache-glyph-BeFJeqBG.js +1 -0
- package/src/console/ui-next/dist/assets/call-pii-button-CVAONPii.js +1 -0
- package/src/console/ui-next/dist/assets/collapsible-D2A6NJ-3.js +1 -0
- package/src/console/ui-next/dist/assets/copy-inline-button-CAYD18cr.js +1 -0
- package/src/console/ui-next/dist/assets/dagre.esm-B1_XeuLP.js +1 -0
- package/src/console/ui-next/dist/assets/detail-header-DVWNjWjg.js +1 -0
- package/src/console/ui-next/dist/assets/dropdown-menu-4h2LOVXM.js +1 -0
- package/src/console/ui-next/dist/assets/duration-tone-Cgk_h5ja.js +9 -0
- package/src/console/ui-next/dist/assets/element-icons-BI8cJgdh.js +1 -0
- package/src/console/ui-next/dist/assets/explorer-empty-CJs5A-wm.js +1 -0
- package/src/console/ui-next/dist/assets/flows-page-Dss7941e.js +1 -0
- package/src/console/ui-next/dist/assets/highlighted-json-MYZQtRnw.js +154 -0
- package/src/console/ui-next/dist/assets/http-method-Jrh39p7A.js +1 -0
- package/src/console/ui-next/dist/assets/index-D0zS5rKO.css +2 -0
- package/src/console/ui-next/dist/assets/index-DXP2dBIF.js +63 -0
- package/src/console/ui-next/dist/assets/observability-page-HvolXxTI.js +4 -0
- package/src/console/ui-next/dist/assets/react-dom-Ddte4I-Q.js +9 -0
- package/src/console/ui-next/dist/assets/replica-lag-CSh2dzrb.js +18 -0
- package/src/console/ui-next/dist/assets/request-meta-BatF8KrK.js +1 -0
- package/src/console/ui-next/dist/assets/shortcut-keys-3ILd8oGn.js +1 -0
- package/src/console/ui-next/dist/assets/{sql-BskegiFM.js → sql-BsFa4tDR.js} +1 -1
- package/src/console/ui-next/dist/assets/store-page-eiKiHnNe.js +41 -0
- package/src/console/ui-next/dist/assets/trace-detail-sheet-CZkMeKS-.js +2 -0
- package/src/console/ui-next/dist/assets/tree-expand-toggle-CW8y5A2h.js +55 -0
- package/src/console/ui-next/dist/assets/units-page-B_RWJrEO.js +1 -0
- package/src/console/ui-next/dist/assets/{use-vault-list-uk4WVboC.js → use-vault-list-CT4-gajj.js} +1 -1
- package/src/console/ui-next/dist/assets/vault-page-CWrg-A68.js +2 -0
- package/src/console/ui-next/dist/assets/xyflow-CSyC6ryz.css +1 -0
- package/src/console/ui-next/dist/assets/xyflow-yApv7D4e.js +7 -0
- package/src/console/ui-next/dist/index.html +6 -13
- package/src/console/ui-next/seed-invoke-host.ts +21 -18
- package/src/console/ui-next/src/client.ts +7 -2
- package/src/console/ui-next/src/features/flows/graph/element-map.ts +2 -0
- package/src/console/ui-next/src/features/flows/traces/effect-kind.ts +12 -2
- package/src/console/ui-next/src/features/flows/traces/effect-summary.ts +4 -0
- package/src/console/ui-next/src/features/flows/traces/trace-detail-sheet.tsx +8 -0
- package/src/console/ui-next/src/features/flows/traces/waterfall-bars.ts +4 -0
- package/src/console/ui-next/src/features/flows/traces/waterfall-tooltip.ts +9 -3
- package/src/console/ui-next/src/features/store/detail/reveal-cell.tsx +7 -11
- package/src/console/ui-next/src/features/store/detail/store-row-detail-sheet.tsx +2 -2
- package/src/console/ui-next/src/features/store/lib/fields-from-table.ts +2 -0
- package/src/console/ui-next/src/features/store/lib/grid-model.test.ts +25 -1
- package/src/console/ui-next/src/features/store/lib/grid-model.ts +36 -1
- package/src/console/ui-next/src/features/store/query/query-results.tsx +3 -3
- package/src/console/ui-next/src/features/units/detail/effects-summary.tsx +2 -0
- package/src/console/ui-next/src/features/units/lib/call-read-safe.ts +3 -1
- package/src/console/ui-next/src/features/units/lib/fields-from-schema.ts +6 -0
- package/src/docker/ai-model-status.test.ts +1 -12
- package/src/docker/ai-model-status.ts +10 -38
- package/src/docker/compose-up.test.ts +100 -0
- package/src/docker/compose-up.ts +292 -0
- package/src/docker/compose.ts +4 -14
- package/src/docker/derive.ts +9 -34
- package/src/docker/docker.test.ts +16 -261
- package/src/docker/images-config.test.ts +13 -25
- package/src/docker/index.ts +1 -24
- package/src/docker/recipes/index.ts +0 -23
- package/src/docker/recipes/pgdog.ts +6 -4
- package/src/docker/stack-id.test.ts +2 -2
- package/src/docker/stack-id.ts +0 -1
- package/src/docker/types.ts +2 -2
- package/src/drivers/ai-anthropic.ts +10 -0
- package/src/drivers/ai-openai-compatible.ts +34 -7
- package/src/drivers/ai-providers.test.ts +0 -107
- package/src/drivers/ai-stream.test.ts +0 -34
- package/src/drivers/ai-types.ts +17 -8
- package/src/drivers/channel-fcm.ts +6 -1
- package/src/drivers/channel-msegat.ts +6 -1
- package/src/drivers/channel-resend.ts +5 -1
- package/src/drivers/channel-smtp.ts +5 -1
- package/src/drivers/channel-sndr.ts +10 -1
- package/src/drivers/channel-taqnyat-mail.ts +5 -1
- package/src/drivers/channel-taqnyat-whatsapp.ts +6 -1
- package/src/drivers/channel-taqnyat.ts +6 -1
- package/src/drivers/channel-types.ts +10 -0
- package/src/drivers/channel-unifonic.ts +6 -1
- package/src/drivers/channel-wa-cloud.ts +6 -1
- package/src/drivers/channel-webpush.ts +6 -1
- package/src/drivers/external.ts +33 -0
- package/src/drivers/index.ts +0 -10
- package/src/drivers/meilisearch.ts +6 -0
- package/src/drivers/oauth-types.ts +4 -0
- package/src/drivers/postgres.test.ts +74 -3
- package/src/drivers/postgres.ts +175 -6
- package/src/drivers/signal-types.ts +5 -5
- package/src/drivers/types.ts +7 -0
- package/src/drivers/vault-types.ts +5 -0
- package/src/elements/ai/declare.ts +17 -4
- package/src/elements/ai/eval.ts +1 -1
- package/src/elements/ai/mcp-http.ts +1 -1
- package/src/elements/ai/pii.ts +1 -1
- package/src/elements/ai/providers.test.ts +289 -0
- package/src/elements/ai/providers.ts +169 -0
- package/src/elements/ai/runtime.ts +68 -5
- package/src/elements/ai/schema.ts +2 -2
- package/src/elements/ai.test.ts +7 -7
- package/src/elements/ai.ts +17 -1
- package/src/elements/channel/runtime.ts +105 -12
- package/src/elements/clock/cron-fields.test.ts +144 -0
- package/src/elements/clock/cron-fields.ts +185 -0
- package/src/elements/clock/declare.ts +247 -3
- package/src/elements/clock.ts +21 -1
- package/src/elements/index.ts +15 -0
- package/src/elements/signal/chaos-child.ts +1 -2
- package/src/elements/signal/declare.ts +65 -37
- package/src/elements/signal/delivery-modes.test.ts +11 -31
- package/src/elements/signal/dry-run-replay.test.ts +1 -7
- package/src/elements/signal/dry-run-write-isolation.test.ts +1 -7
- package/src/elements/signal/key-ordering.test.ts +6 -26
- package/src/elements/signal/lease-reclaim.test.ts +2 -6
- package/src/elements/signal/optional-emit.test.ts +6 -9
- package/src/elements/signal/order-lifecycle.test.ts +4 -17
- package/src/elements/signal/orphan-messages.test.ts +4 -15
- package/src/elements/signal/reconcile.test.ts +2 -2
- package/src/elements/signal/runtime.ts +1 -1
- package/src/elements/signal/schema-emit.test.ts +4 -8
- package/src/elements/signal.test.ts +24 -49
- package/src/elements/signal.ts +9 -2
- package/src/elements/store/domain-ddl.test.ts +1 -1
- package/src/elements/store/live-http.test.ts +9 -4
- package/src/elements/store/prepare-row.test.ts +123 -0
- package/src/elements/store/resource.ts +43 -12
- package/src/elements/store/schema-decl.ts +117 -0
- package/src/elements/store/search-backfill.ts +205 -0
- package/src/elements/store/search-bind.ts +66 -0
- package/src/elements/store/search-bm25.ts +78 -0
- package/src/elements/store/search-ddl.ts +156 -0
- package/src/elements/store/search-embed-flow.ts +141 -0
- package/src/elements/store/search-errors.ts +34 -0
- package/src/elements/store/search-fusion.ts +112 -0
- package/src/elements/store/search-lsh.ts +179 -0
- package/src/elements/store/search-runtime.ts +300 -0
- package/src/elements/store/search.test.ts +144 -0
- package/src/elements/store/sql-session.test.ts +1 -0
- package/src/elements/store/sql-session.ts +83 -3
- package/src/elements/store/table.ts +23 -2
- package/src/elements/store/upsert-app.test.ts +1 -3
- package/src/elements/store.ts +50 -0
- package/src/full.ts +4 -2
- package/src/http.ts +4 -1
- package/src/i18n/catalogs/ar.ts +14 -6
- package/src/i18n/catalogs/en.ts +14 -6
- package/src/index.ts +6 -1
- package/src/kernel/adopt-barrel-fresh.test.ts +7 -7
- package/src/kernel/adopt-routes.ts +9 -1
- package/src/kernel/app-auth.ts +5 -0
- package/src/kernel/app.ts +102 -9
- package/src/kernel/auto-cache.test.ts +6 -12
- package/src/kernel/auto-registry.test.ts +3 -3
- package/src/kernel/boot-bind/ai.test.ts +22 -19
- package/src/kernel/boot-bind/ai.ts +5 -43
- package/src/kernel/boot-bind/clock.ts +23 -5
- package/src/kernel/boot-bind/honor-config.test.ts +4 -4
- package/src/kernel/boot.test.ts +11 -6
- package/src/kernel/boot.ts +66 -16
- package/src/kernel/boundary-contract.ts +93 -0
- package/src/kernel/budget.test.ts +1 -1
- package/src/kernel/call.ts +89 -0
- package/src/kernel/capability.ts +6 -0
- package/src/kernel/client-descriptor.ts +123 -0
- package/src/kernel/clock-timezone.test.ts +80 -0
- package/src/kernel/correlation.test.ts +1 -1
- package/src/kernel/dry-run.ts +11 -8
- package/src/kernel/effects-stamping.test.ts +42 -9
- package/src/kernel/effects.test.ts +4 -2
- package/src/kernel/effects.ts +51 -9
- package/src/kernel/errors-channel.ts +17 -0
- package/src/kernel/errors-live-resume.ts +3 -2
- package/src/kernel/errors-tenant.ts +7 -4
- package/src/kernel/errors.registry-helpers.ts +96 -0
- package/src/kernel/errors.registry.test.ts +139 -25
- package/src/kernel/errors.ts +102 -23
- package/src/kernel/external-effects.test.ts +196 -0
- package/src/kernel/flow.test.ts +13 -4
- package/src/kernel/flow.ts +69 -71
- package/src/kernel/fx-ask-telemetry.test.ts +2 -2
- package/src/kernel/fx-dead-letters.test.ts +3 -3
- package/src/kernel/fx-fetch.ts +55 -0
- package/src/kernel/fx-live-stream.ts +2 -2
- package/src/kernel/fx-live.test.ts +8 -8
- package/src/kernel/fx.test.ts +17 -11
- package/src/kernel/fx.ts +180 -57
- package/src/kernel/horizontal-child.ts +1 -1
- package/src/kernel/http-query.test.ts +3 -6
- package/src/kernel/index.ts +13 -3
- package/src/kernel/instance-id.ts +1 -1
- package/src/kernel/instances.test.ts +40 -0
- package/src/kernel/instances.ts +47 -9
- package/src/kernel/live-http.test.ts +6 -7
- package/src/kernel/live-http.ts +6 -2
- package/src/kernel/live-resume.test.ts +1 -1
- package/src/kernel/mcp-tool.test.ts +3 -3
- package/src/kernel/on.ts +98 -4
- package/src/kernel/pipeline.test.ts +12 -15
- package/src/kernel/plugin-elements.test.ts +1 -1
- package/src/kernel/stamp-http.test.ts +3 -3
- package/src/kernel/triggers.ts +210 -95
- package/src/kernel-entry.ts +0 -1
- package/src/manifest/diff.ts +11 -1
- package/src/manifest/fixtures/skyport.excerpt.json +1 -1
- package/src/manifest/types.ts +46 -2
- package/src/mcp/docs-index.ts +3 -3
- package/src/mcp/docs-mcp.test.ts +2 -2
- package/src/mcp/docs-tools.ts +1 -1
- package/src/okid.test.ts +56 -0
- package/src/okid.ts +55 -11
- package/src/plugins/anonymous.ts +8 -4
- package/src/plugins/auth/shared.ts +27 -3
- package/src/plugins/auth-delivery.mailpit.integration.test.ts +1 -1
- package/src/plugins/auth-methods.security.test.ts +561 -23
- package/src/plugins/config-source.ts +1 -1
- package/src/plugins/csrf.test.ts +65 -0
- package/src/plugins/index.ts +2 -0
- package/src/plugins/magic-link.ts +36 -16
- package/src/plugins/oauth/shared.ts +3 -1
- package/src/plugins/oauth.ts +22 -14
- package/src/plugins/otp.ts +37 -21
- package/src/plugins/passkey-webauthn.ts +9 -6
- package/src/plugins/passkey.ts +98 -26
- package/src/plugins/pre-account-hijack.test.ts +223 -0
- package/src/plugins/two-factor.ts +466 -37
- package/src/plugins/username.ts +19 -7
- package/src/release/build-lib.ts +1 -0
- package/src/release/limits.ts +2 -2
- package/src/release/measure.ts +1 -1
- package/src/runs/collect.test.ts +0 -2
- package/src/runtime/json-code-block.test.ts +250 -20
- package/src/runtime/json-code-block.ts +1261 -41
- package/src/term.test.ts +1 -1
- package/src/test/create-test-app.test.ts +12 -12
- package/src/test/live-signals.test.ts +6 -6
- package/src/test/provisions.integration.test.ts +10 -14
- package/src/test/reset-element-registries.ts +1 -1
- package/src/test/tenant-isolation.test.ts +12 -6
- package/site/content/docs/deployment/docker-swarm.mdx +0 -164
- package/site/content/docs/deployment/docker.mdx +0 -227
- package/site/content/docs/deployment/index.mdx +0 -83
- package/site/content/docs/deployment/kubernetes.mdx +0 -176
- package/site/content/docs/deployment/meta.json +0 -5
- package/site/content/docs/deployment/reverse-proxy.mdx +0 -234
- package/site/content/docs/elements/ai.mdx +0 -385
- package/site/content/docs/elements/channel.mdx +0 -346
- package/site/content/docs/elements/clock.mdx +0 -244
- package/site/content/docs/elements/flow.mdx +0 -420
- package/site/content/docs/elements/gate.mdx +0 -436
- package/site/content/docs/elements/signal.mdx +0 -380
- package/site/content/docs/elements/store.mdx +0 -1099
- package/site/content/docs/elements/vault.mdx +0 -405
- package/site/content/docs/get-started/basic-usage.mdx +0 -173
- package/site/content/docs/get-started/index.mdx +0 -43
- package/site/content/docs/get-started/installation.mdx +0 -220
- package/site/content/docs/get-started/introduction.mdx +0 -132
- package/site/content/docs/get-started/meta.json +0 -13
- package/site/content/docs/get-started/project-structure.mdx +0 -925
- package/site/content/docs/get-started/testing.mdx +0 -328
- package/site/content/docs/get-started/why.mdx +0 -162
- package/site/content/docs/recipes/llama-cpp.mdx +0 -151
- package/site/content/docs/recipes/ollama.mdx +0 -142
- package/site/content/docs/recipes/sglang.mdx +0 -105
- package/site/content/docs/recipes/vllm.mdx +0 -106
- package/site/content/docs/reference/cli.md +0 -232
- package/site/content/docs/reference/client.mdx +0 -469
- package/site/content/docs/reference/security.md +0 -74
- package/src/cli/ai-setup/detect-ollama.ts +0 -213
- package/src/cli/ai-setup/recommend.test.ts +0 -225
- package/src/cli/ai-setup/recommend.ts +0 -225
- package/src/cli/dev-controls.test.ts +0 -122
- package/src/cli/dev-controls.ts +0 -164
- package/src/cli/tui/DevLive.tsx +0 -126
- package/src/console/ui-next/dist/assets/access-page-De7Lc2JC.js +0 -4
- package/src/console/ui-next/dist/assets/agent-disclosure-BP0Y0Sux.js +0 -1
- package/src/console/ui-next/dist/assets/cache-glyph-B5X-NM0-.js +0 -1
- package/src/console/ui-next/dist/assets/call-pii-button-ChAUiLo9.js +0 -1
- package/src/console/ui-next/dist/assets/collapsible-DGnOM2ph.js +0 -1
- package/src/console/ui-next/dist/assets/copy-inline-button-DBHhgHKP.js +0 -1
- package/src/console/ui-next/dist/assets/dagre.esm-ZwcdTuZZ.js +0 -1
- package/src/console/ui-next/dist/assets/detail-header-DhHM1iaZ.js +0 -1
- package/src/console/ui-next/dist/assets/dropdown-menu-_NjTEo5_.js +0 -1
- package/src/console/ui-next/dist/assets/duration-tone-sC3lGABz.js +0 -9
- package/src/console/ui-next/dist/assets/element-icons-BVXtRyd3.js +0 -1
- package/src/console/ui-next/dist/assets/explorer-empty-2uIhBu0_.js +0 -1
- package/src/console/ui-next/dist/assets/flows-page-RGy7VEA_.js +0 -1
- package/src/console/ui-next/dist/assets/highlighted-json-Awq7gYdu.js +0 -154
- package/src/console/ui-next/dist/assets/http-method-_UHM2ODJ.js +0 -1
- package/src/console/ui-next/dist/assets/index-Ck88Jmv8.css +0 -2
- package/src/console/ui-next/dist/assets/index-_rgpdVzo.js +0 -66
- package/src/console/ui-next/dist/assets/link-BX6Vqztd.js +0 -1
- package/src/console/ui-next/dist/assets/observability-page-Ds6pcnh-.js +0 -4
- package/src/console/ui-next/dist/assets/preload-helper-oH4irX4C.js +0 -1
- package/src/console/ui-next/dist/assets/react-D8E3mtu1.js +0 -1
- package/src/console/ui-next/dist/assets/react-dom-Bph1y7z7.js +0 -9
- package/src/console/ui-next/dist/assets/replica-lag-DKRrbvdo.js +0 -18
- package/src/console/ui-next/dist/assets/request-meta-DV0ywz7t.js +0 -1
- package/src/console/ui-next/dist/assets/shortcut-JQIZlWfm.js +0 -1
- package/src/console/ui-next/dist/assets/shortcut-keys-DKxNTe_m.js +0 -1
- package/src/console/ui-next/dist/assets/skeleton-D-czQJT6.js +0 -1
- package/src/console/ui-next/dist/assets/store-page-02xOiqIK.js +0 -41
- package/src/console/ui-next/dist/assets/trace-detail-sheet-B09O8rA6.js +0 -2
- package/src/console/ui-next/dist/assets/tree-expand-toggle-BtyhmWb4.js +0 -55
- package/src/console/ui-next/dist/assets/units-page-4rHOePuE.js +0 -1
- package/src/console/ui-next/dist/assets/useMutation-B8EO02Ej.js +0 -1
- package/src/console/ui-next/dist/assets/useRender-BE2A9BWC.js +0 -1
- package/src/console/ui-next/dist/assets/vault-page-DISPgxLM.js +0 -2
- package/src/console/ui-next/dist/assets/xyflow-D7n4g6go.js +0 -7
- package/src/console/ui-next/dist/assets/xyflow-DZ0Ws1xk.css +0 -1
- package/src/docker/ollama-pull.ts +0 -232
- package/src/docker/recipes/llama-cpp.ts +0 -298
- package/src/docker/recipes/ollama.ts +0 -44
- package/src/docker/recipes/sglang.ts +0 -55
- package/src/docker/recipes/vllm.ts +0 -44
- package/src/drivers/ai-ollama-tools.integration.test.ts +0 -109
- package/src/drivers/ai-ollama.integration.test.ts +0 -184
- package/src/drivers/ai-ollama.ts +0 -389
- package/src/drivers/ollama.ts +0 -14
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* OKE1210 — kept off the Store-only `oke()` graph.
|
|
3
3
|
*
|
|
4
4
|
* Signal drivers throw this when a Last-Event-ID is missing from the tape.
|
|
5
5
|
* Loaded via computed `import.meta.require` from {@link lookupOkeError}.
|
|
@@ -9,7 +9,8 @@ import type { OkeErrorDefinition } from "./errors.ts";
|
|
|
9
9
|
|
|
10
10
|
/** Last-Event-ID is missing from the retained live tape. */
|
|
11
11
|
export const LIVE_RESUME_GAP: OkeErrorDefinition = {
|
|
12
|
-
code:
|
|
12
|
+
code: 1210,
|
|
13
|
+
domain: "signal",
|
|
13
14
|
cause: 'Cursor "{afterId}" missing on "{signal}".',
|
|
14
15
|
fix: "Reconnect without Last-Event-ID.",
|
|
15
16
|
};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* OKE1810–1830 — kept off the Store-only `oke()` graph.
|
|
3
3
|
*
|
|
4
4
|
* Tenant KV/vault and membership failures. Loaded via computed
|
|
5
5
|
* `import.meta.require` from {@link throwOke} / {@link lookupOkeError}.
|
|
@@ -9,21 +9,24 @@ import type { OkeErrorDefinition } from "./errors.ts";
|
|
|
9
9
|
|
|
10
10
|
/** Tenant-scoped op ran with no resolved `fx.tenant.id`. */
|
|
11
11
|
export const TENANT_REQUIRED: OkeErrorDefinition = {
|
|
12
|
-
code:
|
|
12
|
+
code: 1810,
|
|
13
|
+
domain: "mcp_tenancy",
|
|
13
14
|
cause: "This operation needs a tenant, but none is resolved for this request.",
|
|
14
15
|
fix: "Call fx.auth.switchTenant(id), send a signed tid claim, or pass the tenant header.",
|
|
15
16
|
};
|
|
16
17
|
|
|
17
18
|
/** Client-supplied tenant id is not a real membership. */
|
|
18
19
|
export const TENANT_NOT_MEMBER: OkeErrorDefinition = {
|
|
19
|
-
code:
|
|
20
|
+
code: 1820,
|
|
21
|
+
domain: "mcp_tenancy",
|
|
20
22
|
cause: 'The caller is not a member of tenant "{tenant}".',
|
|
21
23
|
fix: "Pick a tenant from fx.auth.listTenants() or add the user as a member.",
|
|
22
24
|
};
|
|
23
25
|
|
|
24
26
|
/** Tenant role mapped an invented or operator-plane scope. */
|
|
25
27
|
export const TENANT_UNKNOWN_SCOPE: OkeErrorDefinition = {
|
|
26
|
-
code:
|
|
28
|
+
code: 1830,
|
|
29
|
+
domain: "mcp_tenancy",
|
|
27
30
|
cause: 'Tenant role scope "{scope}" is not a declared application scope.',
|
|
28
31
|
fix: "Use a name from this app's Manifest catalog (never console:*).",
|
|
29
32
|
};
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Registry gate helpers — uniqueness, domain-range correctness, lazy discovery.
|
|
3
|
+
* Used only by `errors.registry.test.ts` (not a public runtime API).
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { readdir } from "node:fs/promises";
|
|
7
|
+
import { join } from "node:path";
|
|
8
|
+
import { OKE_ERROR_RANGES, type OkeErrorDefinition, type OkeErrorDomain } from "./errors.ts";
|
|
9
|
+
|
|
10
|
+
const LAZY_FILE_RE = /^errors-.+\.ts$/;
|
|
11
|
+
|
|
12
|
+
/** True when `value` looks like a full {@link OkeErrorDefinition}. */
|
|
13
|
+
export function isOkeErrorDefinition(value: unknown): value is OkeErrorDefinition {
|
|
14
|
+
if (value === null || typeof value !== "object") return false;
|
|
15
|
+
const v = value as Record<string, unknown>;
|
|
16
|
+
return (
|
|
17
|
+
typeof v.code === "number" &&
|
|
18
|
+
Number.isInteger(v.code) &&
|
|
19
|
+
typeof v.domain === "string" &&
|
|
20
|
+
typeof v.cause === "string" &&
|
|
21
|
+
typeof v.fix === "string"
|
|
22
|
+
);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/** Collect every `OkeErrorDefinition` export from a module namespace. */
|
|
26
|
+
export function collectDefsFromModule(mod: Record<string, unknown>): readonly OkeErrorDefinition[] {
|
|
27
|
+
const out: OkeErrorDefinition[] = [];
|
|
28
|
+
for (const value of Object.values(mod)) {
|
|
29
|
+
if (isOkeErrorDefinition(value)) out.push(value);
|
|
30
|
+
}
|
|
31
|
+
return out;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Discover lazy error chunks: every `errors-*.ts` file in `dir`
|
|
36
|
+
* (excludes `errors.ts` itself via the hyphen requirement).
|
|
37
|
+
*
|
|
38
|
+
* @param dir - Absolute directory to scan (typically `import.meta.dir`)
|
|
39
|
+
*/
|
|
40
|
+
export async function discoverLazyErrorDefs(dir: string): Promise<{
|
|
41
|
+
readonly files: readonly string[];
|
|
42
|
+
readonly defs: readonly OkeErrorDefinition[];
|
|
43
|
+
}> {
|
|
44
|
+
const names = (await readdir(dir)).filter((name) => LAZY_FILE_RE.test(name)).sort();
|
|
45
|
+
const defs: OkeErrorDefinition[] = [];
|
|
46
|
+
for (const name of names) {
|
|
47
|
+
const mod = (await import(join(dir, name))) as Record<string, unknown>;
|
|
48
|
+
defs.push(...collectDefsFromModule(mod));
|
|
49
|
+
}
|
|
50
|
+
return { files: names, defs };
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/** Return duplicate numeric codes, or an empty array if all unique. */
|
|
54
|
+
export function findDuplicateCodes(defs: readonly OkeErrorDefinition[]): readonly number[] {
|
|
55
|
+
const seen = new Set<number>();
|
|
56
|
+
const dupes: number[] = [];
|
|
57
|
+
for (const def of defs) {
|
|
58
|
+
if (seen.has(def.code)) dupes.push(def.code);
|
|
59
|
+
else seen.add(def.code);
|
|
60
|
+
}
|
|
61
|
+
return dupes;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/** Return defs whose code falls outside `OKE_ERROR_RANGES[domain]`. */
|
|
65
|
+
export function findOutOfRangeDefs(
|
|
66
|
+
defs: readonly OkeErrorDefinition[],
|
|
67
|
+
): readonly OkeErrorDefinition[] {
|
|
68
|
+
const bad: OkeErrorDefinition[] = [];
|
|
69
|
+
for (const def of defs) {
|
|
70
|
+
const range = OKE_ERROR_RANGES[def.domain as OkeErrorDomain];
|
|
71
|
+
if (!range) {
|
|
72
|
+
bad.push(def);
|
|
73
|
+
continue;
|
|
74
|
+
}
|
|
75
|
+
const [lo, hi] = range;
|
|
76
|
+
if (def.code < lo || def.code > hi) bad.push(def);
|
|
77
|
+
}
|
|
78
|
+
return bad;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/** Throw if any code is duplicated. */
|
|
82
|
+
export function assertUniqueCodes(defs: readonly OkeErrorDefinition[]): void {
|
|
83
|
+
const dupes = findDuplicateCodes(defs);
|
|
84
|
+
if (dupes.length > 0) {
|
|
85
|
+
throw new Error(`Duplicate OKE error codes: ${dupes.join(", ")}`);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
/** Throw if any code is outside its declared domain range. */
|
|
90
|
+
export function assertCodesInDomainRanges(defs: readonly OkeErrorDefinition[]): void {
|
|
91
|
+
const bad = findOutOfRangeDefs(defs);
|
|
92
|
+
if (bad.length > 0) {
|
|
93
|
+
const detail = bad.map((d) => `OKE${d.code} domain=${d.domain}`).join("; ");
|
|
94
|
+
throw new Error(`OKE error codes outside domain range: ${detail}`);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
@@ -1,48 +1,147 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Error-code registry gate — unique codes,
|
|
2
|
+
* Error-code registry gate — unique codes, domain ranges, lazy discovery (§21).
|
|
3
3
|
*
|
|
4
4
|
* Docs pages (docs/e/{code}.md) are deferred to a dedicated docs prompt;
|
|
5
5
|
* this gate enforces registry invariants only.
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
|
-
import { describe, expect, test } from "bun:test";
|
|
9
|
-
import {
|
|
8
|
+
import { afterAll, describe, expect, test } from "bun:test";
|
|
9
|
+
import { unlink, writeFile } from "node:fs/promises";
|
|
10
|
+
import { join } from "node:path";
|
|
11
|
+
import {
|
|
12
|
+
OKE_ERROR_RANGES,
|
|
13
|
+
OKE_ERRORS,
|
|
14
|
+
OkeError,
|
|
15
|
+
lookupOkeError,
|
|
16
|
+
type OkeErrorDefinition,
|
|
17
|
+
} from "./errors.ts";
|
|
10
18
|
import { LIVE_RESUME_GAP } from "./errors-live-resume.ts";
|
|
19
|
+
import { CHANNEL_SCHEMA } from "./errors-channel.ts";
|
|
11
20
|
import { TENANT_NOT_MEMBER, TENANT_REQUIRED, TENANT_UNKNOWN_SCOPE } from "./errors-tenant.ts";
|
|
21
|
+
import {
|
|
22
|
+
assertCodesInDomainRanges,
|
|
23
|
+
assertUniqueCodes,
|
|
24
|
+
discoverLazyErrorDefs,
|
|
25
|
+
findDuplicateCodes,
|
|
26
|
+
findOutOfRangeDefs,
|
|
27
|
+
} from "./errors.registry-helpers.ts";
|
|
12
28
|
|
|
13
|
-
const
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
TENANT_NOT_MEMBER,
|
|
17
|
-
TENANT_UNKNOWN_SCOPE,
|
|
18
|
-
];
|
|
29
|
+
const KERNEL_DIR = import.meta.dir;
|
|
30
|
+
const PROBE_FILE = "errors-__probe__.ts";
|
|
31
|
+
const PROBE_PATH = join(KERNEL_DIR, PROBE_FILE);
|
|
19
32
|
|
|
20
33
|
describe("OKE error-code registry", () => {
|
|
21
|
-
test("every code is unique", () => {
|
|
22
|
-
const
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
expect(new Set(codes).size).toBe(codes.length);
|
|
34
|
+
test("every code is unique across main + discovered lazy defs", async () => {
|
|
35
|
+
const { defs: lazy } = await discoverLazyErrorDefs(KERNEL_DIR);
|
|
36
|
+
const all = [...Object.values(OKE_ERRORS), ...lazy];
|
|
37
|
+
expect(findDuplicateCodes(all)).toEqual([]);
|
|
38
|
+
assertUniqueCodes(all);
|
|
27
39
|
});
|
|
28
40
|
|
|
29
|
-
test("every
|
|
41
|
+
test("every code falls within its declared domain range", async () => {
|
|
42
|
+
const { defs: lazy } = await discoverLazyErrorDefs(KERNEL_DIR);
|
|
43
|
+
const all = [...Object.values(OKE_ERRORS), ...lazy];
|
|
44
|
+
expect(findOutOfRangeDefs(all)).toEqual([]);
|
|
45
|
+
assertCodesInDomainRanges(all);
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
test("OKE_ERROR_RANGES matches the locked domain scheme", () => {
|
|
49
|
+
expect(OKE_ERROR_RANGES.kernel).toEqual([1000, 1099]);
|
|
50
|
+
expect(OKE_ERROR_RANGES.store).toEqual([1100, 1199]);
|
|
51
|
+
expect(OKE_ERROR_RANGES.signal).toEqual([1200, 1299]);
|
|
52
|
+
expect(OKE_ERROR_RANGES.clock).toEqual([1300, 1399]);
|
|
53
|
+
expect(OKE_ERROR_RANGES.gate).toEqual([1400, 1499]);
|
|
54
|
+
expect(OKE_ERROR_RANGES.vault).toEqual([1500, 1599]);
|
|
55
|
+
expect(OKE_ERROR_RANGES.channel).toEqual([1600, 1699]);
|
|
56
|
+
expect(OKE_ERROR_RANGES.ai).toEqual([1700, 1799]);
|
|
57
|
+
expect(OKE_ERROR_RANGES.mcp_tenancy).toEqual([1800, 1899]);
|
|
58
|
+
expect(OKE_ERROR_RANGES.compiler).toEqual([1900, 1999]);
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
test("lazy discovery finds live-resume, channel, and tenant modules without a hand list", async () => {
|
|
62
|
+
const { files, defs } = await discoverLazyErrorDefs(KERNEL_DIR);
|
|
63
|
+
expect(files).toContain("errors-live-resume.ts");
|
|
64
|
+
expect(files).toContain("errors-channel.ts");
|
|
65
|
+
expect(files).toContain("errors-tenant.ts");
|
|
66
|
+
const codes = defs.map((d) => d.code);
|
|
67
|
+
expect(codes).toContain(1210);
|
|
68
|
+
expect(codes).toContain(1605);
|
|
69
|
+
expect(codes).toContain(1810);
|
|
70
|
+
expect(codes).toContain(1820);
|
|
71
|
+
expect(codes).toContain(1830);
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
test("adversarial: out-of-range synthetic def fails range check", () => {
|
|
75
|
+
const bad: OkeErrorDefinition = {
|
|
76
|
+
code: 1999,
|
|
77
|
+
domain: "kernel",
|
|
78
|
+
cause: "probe",
|
|
79
|
+
fix: "probe",
|
|
80
|
+
};
|
|
81
|
+
expect(findOutOfRangeDefs([bad])).toEqual([bad]);
|
|
82
|
+
expect(() => assertCodesInDomainRanges([bad])).toThrow(/outside domain range/);
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
test("adversarial: duplicate synthetic def fails uniqueness check", () => {
|
|
86
|
+
const clone: OkeErrorDefinition = {
|
|
87
|
+
...OKE_ERRORS.UNDECLARED_READ,
|
|
88
|
+
cause: "dup",
|
|
89
|
+
fix: "dup",
|
|
90
|
+
};
|
|
91
|
+
expect(findDuplicateCodes([OKE_ERRORS.UNDECLARED_READ, clone])).toEqual([1001]);
|
|
92
|
+
expect(() => assertUniqueCodes([OKE_ERRORS.UNDECLARED_READ, clone])).toThrow(/Duplicate/);
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
test("adversarial: filesystem probe is discovered and fails range/uniqueness", async () => {
|
|
96
|
+
await writeFile(
|
|
97
|
+
PROBE_PATH,
|
|
98
|
+
[
|
|
99
|
+
'import type { OkeErrorDefinition } from "./errors.ts";',
|
|
100
|
+
"export const PROBE_OUT_OF_RANGE: OkeErrorDefinition = {",
|
|
101
|
+
" code: 1999,",
|
|
102
|
+
' domain: "kernel",',
|
|
103
|
+
' cause: "adversarial probe",',
|
|
104
|
+
' fix: "delete this file",',
|
|
105
|
+
"};",
|
|
106
|
+
"",
|
|
107
|
+
].join("\n"),
|
|
108
|
+
"utf8",
|
|
109
|
+
);
|
|
110
|
+
try {
|
|
111
|
+
const { files, defs } = await discoverLazyErrorDefs(KERNEL_DIR);
|
|
112
|
+
expect(files).toContain(PROBE_FILE);
|
|
113
|
+
const probe = defs.find((d) => d.code === 1999);
|
|
114
|
+
expect(probe).toBeDefined();
|
|
115
|
+
const all = [...Object.values(OKE_ERRORS), ...defs];
|
|
116
|
+
expect(findOutOfRangeDefs(all).some((d) => d.code === 1999)).toBe(true);
|
|
117
|
+
expect(() => assertCodesInDomainRanges(all)).toThrow(/OKE1999/);
|
|
118
|
+
} finally {
|
|
119
|
+
await unlink(PROBE_PATH).catch(() => undefined);
|
|
120
|
+
}
|
|
121
|
+
});
|
|
122
|
+
|
|
123
|
+
afterAll(async () => {
|
|
124
|
+
await unlink(PROBE_PATH).catch(() => undefined);
|
|
125
|
+
});
|
|
126
|
+
|
|
127
|
+
test("every entry has non-empty cause and fix templates", async () => {
|
|
128
|
+
const { defs: lazy } = await discoverLazyErrorDefs(KERNEL_DIR);
|
|
30
129
|
for (const [key, def] of Object.entries(OKE_ERRORS)) {
|
|
31
130
|
expect(def.cause.trim().length, `${key}.cause`).toBeGreaterThan(0);
|
|
32
131
|
expect(def.fix.trim().length, `${key}.fix`).toBeGreaterThan(0);
|
|
33
132
|
expect(Number.isInteger(def.code), `${key}.code`).toBe(true);
|
|
34
133
|
expect(def.code, `${key}.code`).toBeGreaterThan(0);
|
|
134
|
+
expect(def.domain, `${key}.domain`).toBeTruthy();
|
|
35
135
|
}
|
|
36
|
-
|
|
37
|
-
expect(LIVE_RESUME_GAP.fix.trim().length).toBeGreaterThan(0);
|
|
38
|
-
for (const def of LAZY_DEFS) {
|
|
136
|
+
for (const def of lazy) {
|
|
39
137
|
expect(def.cause.trim().length, `${def.code}.cause`).toBeGreaterThan(0);
|
|
40
138
|
expect(def.fix.trim().length, `${def.code}.fix`).toBeGreaterThan(0);
|
|
41
139
|
}
|
|
42
140
|
});
|
|
43
141
|
|
|
44
|
-
test("OkeError docsUrl matches docs origin /e/{code}", () => {
|
|
45
|
-
|
|
142
|
+
test("OkeError docsUrl matches docs origin /e/{code}", async () => {
|
|
143
|
+
const { defs: lazy } = await discoverLazyErrorDefs(KERNEL_DIR);
|
|
144
|
+
for (const def of [...Object.values(OKE_ERRORS), ...lazy] as OkeErrorDefinition[]) {
|
|
46
145
|
const err = new OkeError(def);
|
|
47
146
|
expect(err.docsUrl).toBe(`https://oke.omqkhafi.dev/e/${def.code}`);
|
|
48
147
|
expect(err.message).toContain(err.docsUrl);
|
|
@@ -52,12 +151,27 @@ describe("OKE error-code registry", () => {
|
|
|
52
151
|
});
|
|
53
152
|
|
|
54
153
|
test("lookupOkeError finds the lazy LIVE_RESUME_GAP entry", () => {
|
|
55
|
-
expect(lookupOkeError(
|
|
154
|
+
expect(lookupOkeError(1210)).toEqual(LIVE_RESUME_GAP);
|
|
155
|
+
});
|
|
156
|
+
|
|
157
|
+
test("lookupOkeError finds the lazy CHANNEL_SCHEMA entry", () => {
|
|
158
|
+
expect(lookupOkeError(1605)).toEqual(CHANNEL_SCHEMA);
|
|
56
159
|
});
|
|
57
160
|
|
|
58
161
|
test("lookupOkeError finds lazy tenant entries", () => {
|
|
59
|
-
expect(lookupOkeError(
|
|
60
|
-
expect(lookupOkeError(
|
|
61
|
-
expect(lookupOkeError(
|
|
162
|
+
expect(lookupOkeError(1810)).toEqual(TENANT_REQUIRED);
|
|
163
|
+
expect(lookupOkeError(1820)).toEqual(TENANT_NOT_MEMBER);
|
|
164
|
+
expect(lookupOkeError(1830)).toEqual(TENANT_UNKNOWN_SCOPE);
|
|
165
|
+
});
|
|
166
|
+
|
|
167
|
+
test("lookupOkeError finds UNDECLARED_EMBED at 1009 (not tenant)", () => {
|
|
168
|
+
expect(lookupOkeError(1009)).toEqual(OKE_ERRORS.UNDECLARED_EMBED);
|
|
169
|
+
expect(OKE_ERRORS.UNDECLARED_EMBED.code).toBe(1009);
|
|
170
|
+
expect(TENANT_REQUIRED.code).toBe(1810);
|
|
171
|
+
});
|
|
172
|
+
|
|
173
|
+
test("NO_EFFECTS_DECLARED owns 1020 after renumber (was UNDECLARED_EMBED)", () => {
|
|
174
|
+
expect(OKE_ERRORS.NO_EFFECTS_DECLARED.code).toBe(1020);
|
|
175
|
+
expect(OKE_ERRORS.UNDECLARED_EMBED.code).toBe(1009);
|
|
62
176
|
});
|
|
63
177
|
});
|
package/src/kernel/errors.ts
CHANGED
|
@@ -30,13 +30,46 @@ function loadFailureMessage(): typeof import("../i18n/failure-message.ts") {
|
|
|
30
30
|
}
|
|
31
31
|
}
|
|
32
32
|
|
|
33
|
-
/** Numeric OKE error code (
|
|
33
|
+
/** Numeric OKE error code (stable after the domain-range renumber). */
|
|
34
34
|
export type OkeErrorCode = number;
|
|
35
35
|
|
|
36
|
+
/**
|
|
37
|
+
* Error domain — each maps to a fixed numeric range in {@link OKE_ERROR_RANGES}.
|
|
38
|
+
* Kernel covers Flow/Trigger/Gate-posture (boot structural). Gate sessions/OAuth
|
|
39
|
+
* live in `gate`; MCP + tenancy share `mcp_tenancy`.
|
|
40
|
+
*/
|
|
41
|
+
export type OkeErrorDomain =
|
|
42
|
+
| "kernel"
|
|
43
|
+
| "store"
|
|
44
|
+
| "signal"
|
|
45
|
+
| "clock"
|
|
46
|
+
| "gate"
|
|
47
|
+
| "vault"
|
|
48
|
+
| "channel"
|
|
49
|
+
| "ai"
|
|
50
|
+
| "mcp_tenancy"
|
|
51
|
+
| "compiler";
|
|
52
|
+
|
|
53
|
+
/** Inclusive `[lo, hi]` band for each {@link OkeErrorDomain}. */
|
|
54
|
+
export const OKE_ERROR_RANGES = {
|
|
55
|
+
kernel: [1000, 1099],
|
|
56
|
+
store: [1100, 1199],
|
|
57
|
+
signal: [1200, 1299],
|
|
58
|
+
clock: [1300, 1399],
|
|
59
|
+
gate: [1400, 1499],
|
|
60
|
+
vault: [1500, 1599],
|
|
61
|
+
channel: [1600, 1699],
|
|
62
|
+
ai: [1700, 1799],
|
|
63
|
+
mcp_tenancy: [1800, 1899],
|
|
64
|
+
compiler: [1900, 1999],
|
|
65
|
+
} as const satisfies Record<OkeErrorDomain, readonly [number, number]>;
|
|
66
|
+
|
|
36
67
|
/** One registry entry — cause/fix may include `{name}` placeholders. */
|
|
37
68
|
export interface OkeErrorDefinition {
|
|
38
|
-
/** Permanent numeric code. */
|
|
69
|
+
/** Permanent numeric code (must fall in {@link OKE_ERROR_RANGES} for `domain`). */
|
|
39
70
|
readonly code: OkeErrorCode;
|
|
71
|
+
/** Domain that owns this code's numeric range. */
|
|
72
|
+
readonly domain: OkeErrorDomain;
|
|
40
73
|
/** One-line cause template. */
|
|
41
74
|
readonly cause: string;
|
|
42
75
|
/** Suggested fix template. */
|
|
@@ -112,65 +145,97 @@ export interface FailOptions {
|
|
|
112
145
|
}
|
|
113
146
|
|
|
114
147
|
/**
|
|
115
|
-
* Permanent error registry. Codes
|
|
148
|
+
* Permanent error registry. Codes are stable within their domain range after
|
|
149
|
+
* the domain-range renumber; each entry declares `domain` for range guards.
|
|
116
150
|
*
|
|
117
|
-
* Ranges
|
|
118
|
-
* - `1000–1099` —
|
|
119
|
-
* - `
|
|
151
|
+
* Ranges:
|
|
152
|
+
* - `1000–1099` — Kernel (Flow / Trigger / Gate-posture)
|
|
153
|
+
* - `1100–1199` — Store
|
|
154
|
+
* - `1200–1299` — Signal
|
|
155
|
+
* - `1300–1399` — Clock
|
|
156
|
+
* - `1400–1499` — Gate (sessions / OAuth / API keys)
|
|
157
|
+
* - `1500–1599` — Vault
|
|
158
|
+
* - `1600–1699` — Channel
|
|
159
|
+
* - `1700–1799` — AI
|
|
160
|
+
* - `1800–1899` — MCP + Tenancy
|
|
161
|
+
* - `1900–1999` — Compiler / Manifest
|
|
120
162
|
*/
|
|
121
163
|
export const OKE_ERRORS = {
|
|
122
164
|
/** Flow reads a store resource not listed in `effects.reads`. */
|
|
123
165
|
UNDECLARED_READ: {
|
|
124
166
|
code: 1001,
|
|
167
|
+
domain: "kernel",
|
|
125
168
|
cause: 'Flow "{flow}" reads "{resource}" without declaring it.',
|
|
126
169
|
fix: 'Add "{resource}" to this flow\'s effects.reads.',
|
|
127
170
|
},
|
|
128
171
|
/** Flow writes a store resource not listed in `effects.writes`. */
|
|
129
172
|
UNDECLARED_WRITE: {
|
|
130
173
|
code: 1002,
|
|
174
|
+
domain: "kernel",
|
|
131
175
|
cause: 'Flow "{flow}" writes "{resource}" without declaring it.',
|
|
132
176
|
fix: 'Add "{resource}" to this flow\'s effects.writes.',
|
|
133
177
|
},
|
|
134
178
|
/** Flow emits a signal not listed in `effects.emits`. */
|
|
135
179
|
UNDECLARED_EMIT: {
|
|
136
180
|
code: 1003,
|
|
181
|
+
domain: "kernel",
|
|
137
182
|
cause: 'Flow "{flow}" emits "{resource}" without declaring it.',
|
|
138
183
|
fix: 'Add "{resource}" to this flow\'s effects.emits.',
|
|
139
184
|
},
|
|
140
185
|
/** Flow sends a channel template not listed in `effects.sends`. */
|
|
141
186
|
UNDECLARED_SEND: {
|
|
142
187
|
code: 1004,
|
|
188
|
+
domain: "kernel",
|
|
143
189
|
cause: 'Flow "{flow}" sends "{resource}" without declaring it.',
|
|
144
190
|
fix: 'Add "{resource}" to this flow\'s effects.sends.',
|
|
145
191
|
},
|
|
146
192
|
/** Flow asks a prompt not listed in `effects.asks`. */
|
|
147
193
|
UNDECLARED_ASK: {
|
|
148
194
|
code: 1005,
|
|
195
|
+
domain: "kernel",
|
|
149
196
|
cause: 'Flow "{flow}" asks "{resource}" without declaring it.',
|
|
150
197
|
fix: 'Add "{resource}" to this flow\'s effects.asks.',
|
|
151
198
|
},
|
|
152
199
|
/** Flow reads a secret not listed in `effects.secrets`. */
|
|
153
200
|
UNDECLARED_SECRET: {
|
|
154
201
|
code: 1006,
|
|
202
|
+
domain: "kernel",
|
|
155
203
|
cause: 'Flow "{flow}" reads secret "{resource}" without declaring it.',
|
|
156
204
|
fix: 'Add "{resource}" to this flow\'s effects.secrets.',
|
|
157
205
|
},
|
|
158
206
|
/** Flow calls another flow not listed in `effects.calls`. */
|
|
159
207
|
UNDECLARED_CALL: {
|
|
160
208
|
code: 1007,
|
|
209
|
+
domain: "kernel",
|
|
161
210
|
cause: 'Flow "{flow}" calls "{resource}" without declaring it.',
|
|
162
211
|
fix: 'Add "{resource}" to this flow\'s effects.calls.',
|
|
163
212
|
},
|
|
213
|
+
/** Flow fetches a host not listed in `effects.fetches`. */
|
|
214
|
+
UNDECLARED_FETCH: {
|
|
215
|
+
code: 1008,
|
|
216
|
+
domain: "kernel",
|
|
217
|
+
cause: 'Flow "{flow}" fetches "{resource}" without declaring it.',
|
|
218
|
+
fix: 'Add "{resource}" to this flow\'s effects.fetches.',
|
|
219
|
+
},
|
|
220
|
+
/** Flow embeds via a model not listed in `effects.embeds`. */
|
|
221
|
+
UNDECLARED_EMBED: {
|
|
222
|
+
code: 1009,
|
|
223
|
+
domain: "kernel",
|
|
224
|
+
cause: 'Flow "{flow}" embeds with "{resource}" without declaring it.',
|
|
225
|
+
fix: 'Add "{resource}" to this flow\'s effects.embeds.',
|
|
226
|
+
},
|
|
164
227
|
/**
|
|
165
228
|
* Flow has no declared `effects` and no Manifest-derived effects were
|
|
166
229
|
* available to stamp at boot (dev+compose / prod — never a silent open token).
|
|
167
230
|
*/
|
|
168
231
|
NO_EFFECTS_DECLARED: {
|
|
169
|
-
code:
|
|
232
|
+
code: 1020,
|
|
233
|
+
domain: "kernel",
|
|
170
234
|
cause: 'Flow "{flow}" has no declared effects and no Manifest to derive them from.',
|
|
171
235
|
fix:
|
|
172
236
|
"Add explicit `effects` to this flow, or boot with a Manifest (`oke build`) / " +
|
|
173
|
-
"`rootDir` so effects can be derived.
|
|
237
|
+
"`rootDir` so effects can be derived. If extract failed, ensure `oxc-parser` is " +
|
|
238
|
+
"installed (okengine dependency). dev+compose/prod refuse an open capability token.",
|
|
174
239
|
},
|
|
175
240
|
/**
|
|
176
241
|
* A `src/flows/<unit>` folder exists on disk but no adopted flow carries
|
|
@@ -179,7 +244,8 @@ export const OKE_ERRORS = {
|
|
|
179
244
|
* route table in a deploy-shaped environment.
|
|
180
245
|
*/
|
|
181
246
|
ADOPT_BARREL_STALE: {
|
|
182
|
-
code:
|
|
247
|
+
code: 1030,
|
|
248
|
+
domain: "kernel",
|
|
183
249
|
cause: "src/flows/{unit} exists on disk but adopted no flows — the .adopt() barrel is stale.",
|
|
184
250
|
fix: "Run `oke dev` or `oke build` to regenerate `src/flows/generated.ts`.",
|
|
185
251
|
},
|
|
@@ -187,7 +253,8 @@ export const OKE_ERRORS = {
|
|
|
187
253
|
* `http.get()` was never stamped from the file tree — refuse a silent `/`.
|
|
188
254
|
*/
|
|
189
255
|
HTTP_PATH_UNRESOLVED: {
|
|
190
|
-
code:
|
|
256
|
+
code: 1040,
|
|
257
|
+
domain: "kernel",
|
|
191
258
|
cause: 'Flow "{flow}" bound {method} with no path — the file-tree stamp never ran.',
|
|
192
259
|
fix: 'Put the file under `src/flows/<unit>/` and import `@/flows/generated`, or pass an explicit path to `http.{method}("/…")`.',
|
|
193
260
|
},
|
|
@@ -195,7 +262,8 @@ export const OKE_ERRORS = {
|
|
|
195
262
|
* Two HTTP bindings share method + path — last-add-wins is the opposite of this DX.
|
|
196
263
|
*/
|
|
197
264
|
HTTP_ROUTE_DUPLICATE: {
|
|
198
|
-
code:
|
|
265
|
+
code: 1041,
|
|
266
|
+
domain: "kernel",
|
|
199
267
|
cause: '{method} {path} is bound twice (flow "{flow}").',
|
|
200
268
|
fix: "Give each HTTP flow a unique method + path.",
|
|
201
269
|
},
|
|
@@ -203,7 +271,8 @@ export const OKE_ERRORS = {
|
|
|
203
271
|
* Adopted HTTP flow still has no name (`flow({ do })` outside a unit).
|
|
204
272
|
*/
|
|
205
273
|
HTTP_FLOW_UNNAMED: {
|
|
206
|
-
code:
|
|
274
|
+
code: 1045,
|
|
275
|
+
domain: "kernel",
|
|
207
276
|
cause: "An HTTP flow on {method} {path} has no name.",
|
|
208
277
|
fix: 'Use `flow("unit.export", {…})` or export it from a `src/flows/<unit>/` file so the tree can stamp `unit.export`.',
|
|
209
278
|
},
|
|
@@ -211,7 +280,8 @@ export const OKE_ERRORS = {
|
|
|
211
280
|
* Two live HTTP exposures of the same signal share gates + match shape.
|
|
212
281
|
*/
|
|
213
282
|
LIVE_EXPOSURE_DUPLICATE: {
|
|
214
|
-
code:
|
|
283
|
+
code: 1050,
|
|
284
|
+
domain: "kernel",
|
|
215
285
|
cause:
|
|
216
286
|
'Live signal "{signal}" is exposed twice with the same gates ({gates}) and match ({match}).',
|
|
217
287
|
fix: "Use a different gate or path-param filter, or drop the extra route.",
|
|
@@ -220,7 +290,8 @@ export const OKE_ERRORS = {
|
|
|
220
290
|
* Two MCP tool bindings share the same exposed tool name.
|
|
221
291
|
*/
|
|
222
292
|
MCP_TOOL_DUPLICATE: {
|
|
223
|
-
code:
|
|
293
|
+
code: 1060,
|
|
294
|
+
domain: "kernel",
|
|
224
295
|
cause: 'MCP tool "{tool}" is bound twice (flow "{flow}").',
|
|
225
296
|
fix: "Give each MCP tool exposure a unique tool name.",
|
|
226
297
|
},
|
|
@@ -229,22 +300,24 @@ export const OKE_ERRORS = {
|
|
|
229
300
|
* Thrown at emit when `optional` is false and nobody is subscribed.
|
|
230
301
|
*/
|
|
231
302
|
ORPHAN_EMIT: {
|
|
232
|
-
code:
|
|
303
|
+
code: 1240,
|
|
304
|
+
domain: "signal",
|
|
233
305
|
cause: 'Flow "{flow}" emits signal "{resource}" with no subscriber.',
|
|
234
306
|
fix: "Add `on({resource}, …)` or mark the signal `{ optional: true }`.",
|
|
235
307
|
},
|
|
236
308
|
/** Emit payload failed the signal's declared Standard Schema. */
|
|
237
309
|
SIGNAL_SCHEMA: {
|
|
238
|
-
code:
|
|
310
|
+
code: 1250,
|
|
311
|
+
domain: "signal",
|
|
239
312
|
cause: '"{resource}": {detail}',
|
|
240
313
|
fix: "Fix schema payload.",
|
|
241
314
|
},
|
|
242
315
|
/**
|
|
243
316
|
* Domain table/column missing under docker/prod (migrations not applied).
|
|
244
|
-
* Store/DDL band starts at 1100.
|
|
245
317
|
*/
|
|
246
318
|
DOMAIN_SCHEMA_MISSING: {
|
|
247
|
-
code:
|
|
319
|
+
code: 1110,
|
|
320
|
+
domain: "store",
|
|
248
321
|
cause: "domain table not found — migrations have not been applied.",
|
|
249
322
|
fix: "run `oke db migrate` against this environment.",
|
|
250
323
|
},
|
|
@@ -260,7 +333,7 @@ type TenantErrorChunk = {
|
|
|
260
333
|
};
|
|
261
334
|
|
|
262
335
|
/**
|
|
263
|
-
* Load
|
|
336
|
+
* Load OKE1810–1830. Computed stem so Bun.build cannot inline the chunk.
|
|
264
337
|
*/
|
|
265
338
|
function loadTenantErrors(): TenantErrorChunk {
|
|
266
339
|
return lazyRequire(import.meta.dir, ["errors", "tenant"].join("-"));
|
|
@@ -289,15 +362,21 @@ export function throwOke(
|
|
|
289
362
|
* @param code - Permanent numeric code
|
|
290
363
|
*/
|
|
291
364
|
export function lookupOkeError(code: OkeErrorCode): OkeErrorDefinition | undefined {
|
|
292
|
-
if (code ===
|
|
365
|
+
if (code === 1210) {
|
|
293
366
|
return lazyRequire<typeof import("./errors-live-resume.ts")>(
|
|
294
367
|
import.meta.dir,
|
|
295
368
|
["errors", "live", "resume"].join("-"),
|
|
296
369
|
).LIVE_RESUME_GAP;
|
|
297
370
|
}
|
|
298
|
-
if (code ===
|
|
299
|
-
|
|
300
|
-
|
|
371
|
+
if (code === 1605) {
|
|
372
|
+
return lazyRequire<typeof import("./errors-channel.ts")>(
|
|
373
|
+
import.meta.dir,
|
|
374
|
+
["errors", "channel"].join("-"),
|
|
375
|
+
).CHANNEL_SCHEMA;
|
|
376
|
+
}
|
|
377
|
+
if (code === 1810) return loadTenantErrors().TENANT_REQUIRED;
|
|
378
|
+
if (code === 1820) return loadTenantErrors().TENANT_NOT_MEMBER;
|
|
379
|
+
if (code === 1830) return loadTenantErrors().TENANT_UNKNOWN_SCOPE;
|
|
301
380
|
for (const def of Object.values(OKE_ERRORS)) {
|
|
302
381
|
if (def.code === code) return def;
|
|
303
382
|
}
|