okengine 0.13.0 → 0.15.2
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/manifest.v1.schema.json +7 -1
- package/package.json +4 -5
- package/site/content/docs/ai/mcp.mdx +27 -2
- package/site/content/docs/elements/ai.mdx +59 -11
- package/site/content/docs/elements/channel.mdx +1 -0
- package/site/content/docs/elements/clock.mdx +30 -12
- package/site/content/docs/elements/flow.mdx +9 -3
- package/site/content/docs/elements/gate.mdx +25 -22
- package/site/content/docs/elements/signal.mdx +71 -25
- package/site/content/docs/elements/store.mdx +87 -28
- package/site/content/docs/elements/vault.mdx +1 -0
- package/site/content/docs/get-started/basic-usage.mdx +22 -13
- package/site/content/docs/get-started/index.mdx +5 -0
- package/site/content/docs/get-started/installation.mdx +2 -2
- package/site/content/docs/get-started/introduction.mdx +11 -3
- package/site/content/docs/get-started/meta.json +1 -1
- package/site/content/docs/get-started/project-structure.mdx +932 -0
- package/site/content/docs/reference/cli.md +13 -10
- package/site/content/docs/reference/client.mdx +25 -21
- package/site/content/docs/reference/fx.mdx +27 -22
- package/site/content/docs/reference/security.md +1 -1
- package/src/auth/bindings.ts +14 -5
- package/src/auth/cross-plane.ts +10 -3
- package/src/cli/ai-setup/ai-setup.test.ts +62 -0
- package/src/cli/ai-setup/apply.ts +32 -1
- package/src/cli/ai-setup/recommend.test.ts +25 -0
- package/src/cli/ai-setup/recommend.ts +8 -3
- package/src/cli/attach-host-console.test.ts +3 -2
- package/src/cli/attach-host-console.ts +3 -0
- package/src/cli/build.test.ts +4 -2
- package/src/cli/db-seed.ts +48 -15
- package/src/cli/db.test.ts +104 -0
- package/src/cli/db.ts +122 -10
- package/src/cli/dev-controls.test.ts +20 -0
- package/src/cli/dev-controls.ts +13 -0
- package/src/cli/dev.test.ts +15 -4
- package/src/cli/dev.ts +102 -29
- package/src/cli/ensure-drizzle-config.ts +2 -1
- package/src/cli/tui/DevLive.tsx +12 -2
- package/src/cli/tui/keys.test.ts +2 -1
- package/src/cli/tui/keys.ts +3 -2
- package/src/compiler/aot.test.ts +1 -1
- package/src/compiler/effects-infer.ts +58 -3
- package/src/compiler/extract.test.ts +458 -29
- package/src/compiler/extract.ts +387 -69
- package/src/compiler/flow-path.test.ts +96 -0
- package/src/compiler/flow-path.ts +173 -0
- package/src/compiler/generate-adopt.test.ts +112 -3
- package/src/compiler/generate-adopt.ts +280 -26
- package/src/compiler/response.ts +45 -1
- package/src/compiler/schema-from-ast.ts +609 -0
- package/src/console/server/ai.ts +5 -2
- package/src/console/server/bind.ts +2 -2
- package/src/console/server/console.test.ts +3 -0
- package/src/console/server/flows.ts +121 -40
- package/src/console/server/invoke-user-flow.test.ts +3 -1
- package/src/console/server/invoke-user-flow.ts +17 -2
- package/src/console/server/iso-at.test.ts +9 -0
- package/src/console/server/iso-at.ts +11 -0
- package/src/console/server/security-headers.ts +6 -3
- package/src/console/server/serve.ts +17 -2
- package/src/console/server/spa-proxy.test.ts +1 -0
- package/src/console/server/sql-catalog.ts +147 -7
- package/src/console/server/sql-rls.test.ts +16 -0
- package/src/console/server/state.ts +8 -0
- package/src/console/server/store.test.ts +7 -4
- package/src/console/server/store.ts +142 -58
- package/src/console/ui-next/dist/assets/agent-disclosure-C0X1fbWF.js +1 -0
- package/src/console/ui-next/dist/assets/cache-glyph-F1FI122b.js +1 -0
- package/src/console/ui-next/dist/assets/{call-pii-button-bqkxMrJH.js → call-pii-button-DEDCl_j3.js} +1 -1
- package/src/console/ui-next/dist/assets/collapsible-LPqGvfoz.js +1 -0
- package/src/console/ui-next/dist/assets/{confirm-sheet-DDCRmG62.js → confirm-sheet-3ptDzXbz.js} +1 -1
- package/src/console/ui-next/dist/assets/{duration-tone-oiRxPVsZ.js → duration-tone-sC3lGABz.js} +1 -1
- package/src/console/ui-next/dist/assets/{explorer-empty-HjTnVQoR.js → explorer-empty-BvYrygyO.js} +1 -1
- package/src/console/ui-next/dist/assets/flows-page-Dluo1Bd7.js +1 -0
- package/src/console/ui-next/dist/assets/{highlighted-json-CvDPvveV.js → highlighted-json-CS_O8L-r.js} +1 -1
- package/src/console/ui-next/dist/assets/http-method--sWDdXSB.js +1 -0
- package/src/console/ui-next/dist/assets/index-Ca3HZMVq.js +66 -0
- package/src/console/ui-next/dist/assets/index-UtTDRQpS.css +2 -0
- package/src/console/ui-next/dist/assets/{link-DF7SZ9Ek.js → link-COeyggt-.js} +1 -1
- package/src/console/ui-next/dist/assets/observability-page-HK9-BO8z.js +4 -0
- package/src/console/ui-next/dist/assets/react-D8E3mtu1.js +1 -0
- package/src/console/ui-next/dist/assets/replica-lag-DBIFFf7d.js +18 -0
- package/src/console/ui-next/dist/assets/sheet-form-Dnwa5oOR.js +1 -0
- package/src/console/ui-next/dist/assets/shortcut-keys-CoqwEIi0.js +1 -0
- package/src/console/ui-next/dist/assets/skeleton-BHcfDYcb.js +1 -0
- package/src/console/ui-next/dist/assets/store-page-BSohH3wM.js +41 -0
- package/src/console/ui-next/dist/assets/trace-detail-sheet-CFIGRnnA.js +2 -0
- package/src/console/ui-next/dist/assets/tree-expand-toggle-BgLl34w7.js +54 -0
- package/src/console/ui-next/dist/assets/units-page-B0cFE76A.js +1 -0
- package/src/console/ui-next/dist/assets/{use-vault-list-Cl79j_ku.js → use-vault-list-BLbZhzyF.js} +1 -1
- package/src/console/ui-next/dist/assets/vault-page-B1SbYe10.js +2 -0
- package/src/console/ui-next/dist/index.html +6 -6
- package/src/console/ui-next/seed-invoke-host.ts +2 -0
- package/src/console/ui-next/src/client.ts +35 -7
- package/src/console/ui-next/src/components/motion/table/index.tsx +16 -0
- package/src/console/ui-next/src/components/motion/table/types.ts +4 -0
- package/src/console/ui-next/src/components/ui/kbd.tsx +2 -2
- package/src/console/ui-next/src/features/flows/graph/build-flow-graph.test.ts +18 -0
- package/src/console/ui-next/src/features/flows/graph/build-flow-graph.ts +14 -1
- package/src/console/ui-next/src/features/flows/graph/neighborhood.test.ts +17 -0
- package/src/console/ui-next/src/features/flows/graph/neighborhood.ts +16 -3
- package/src/console/ui-next/src/features/flows/traces/effect-kind.ts +3 -1
- package/src/console/ui-next/src/features/flows/traces/effect-summary.ts +24 -0
- package/src/console/ui-next/src/features/flows/traces/http-method.ts +19 -0
- package/src/console/ui-next/src/features/flows/traces/trace-detail-sheet.tsx +9 -3
- package/src/console/ui-next/src/features/flows/traces/trace-detail.test.ts +29 -2
- package/src/console/ui-next/src/features/flows/traces/traces-pane.tsx +10 -3
- package/src/console/ui-next/src/features/observability/lib/ask-count.test.ts +25 -0
- package/src/console/ui-next/src/features/observability/lib/ask-count.ts +4 -1
- package/src/console/ui-next/src/features/store/detail/browse-section.tsx +45 -1
- package/src/console/ui-next/src/features/store/detail/resource-panel.tsx +78 -16
- package/src/console/ui-next/src/features/store/detail/store-row-detail-sheet.tsx +155 -14
- package/src/console/ui-next/src/features/store/explorer/store-tree.tsx +33 -133
- package/src/console/ui-next/src/features/store/files/file-preview.tsx +4 -1
- package/src/console/ui-next/src/features/store/grid/rls-policy-sheet.tsx +326 -165
- package/src/console/ui-next/src/features/store/grid/sql-insert-sheet.tsx +6 -0
- package/src/console/ui-next/src/features/store/grid/store-data-grid.tsx +50 -3
- package/src/console/ui-next/src/features/store/lib/files-meta.test.ts +3 -0
- package/src/console/ui-next/src/features/store/lib/files-meta.ts +12 -0
- package/src/console/ui-next/src/features/store/lib/query-defaults.test.ts +25 -0
- package/src/console/ui-next/src/features/store/lib/query-defaults.ts +85 -3
- package/src/console/ui-next/src/features/store/lib/query-gate.ts +30 -4
- package/src/console/ui-next/src/features/store/lib/rls-policy.test.ts +139 -0
- package/src/console/ui-next/src/features/store/lib/rls-policy.ts +223 -21
- package/src/console/ui-next/src/features/store/lib/schema-graph.ts +4 -0
- package/src/console/ui-next/src/features/store/lib/sql-catalog.test.ts +24 -0
- package/src/console/ui-next/src/features/store/lib/sql-catalog.ts +19 -0
- package/src/console/ui-next/src/features/store/lib/store-tree.test.ts +6 -0
- package/src/console/ui-next/src/features/store/lib/store-tree.ts +13 -0
- package/src/console/ui-next/src/features/store/query/query-console.tsx +48 -14
- package/src/console/ui-next/src/features/store/query/query-gate-menu.tsx +19 -20
- package/src/console/ui-next/src/features/store/query/query-gate-parts.tsx +2 -1
- package/src/console/ui-next/src/features/store/query/query-results.tsx +110 -83
- package/src/console/ui-next/src/features/store/schema/schema-table-node.tsx +17 -0
- package/src/console/ui-next/src/features/units/call/call-api-panel.tsx +112 -72
- package/src/console/ui-next/src/features/units/detail/effects-summary.tsx +12 -4
- package/src/console/ui-next/src/features/units/lib/contract-input.test.ts +206 -1
- package/src/console/ui-next/src/features/units/lib/contract-input.ts +55 -0
- package/src/console/ui-next/src/features/vault/lib/types.ts +1 -1
- package/src/docker/compose-health.test.ts +27 -0
- package/src/docker/compose-health.ts +19 -3
- package/src/docker/docker.test.ts +4 -1
- package/src/docker/dockerfile.ts +1 -1
- package/src/docker/recipes/pgdog.ts +2 -0
- package/src/drivers/ai-anthropic.ts +5 -0
- package/src/drivers/ai-ollama.ts +49 -30
- package/src/drivers/ai-openai-compatible.ts +57 -46
- package/src/drivers/ai-providers.test.ts +3 -0
- package/src/drivers/bun-native-completeness.test.ts +7 -9
- package/src/drivers/clock-postgres.ts +13 -9
- package/src/drivers/instances-postgres.ts +4 -6
- package/src/drivers/journal-postgres.ts +13 -9
- package/src/drivers/pg-rls.test.ts +87 -0
- package/src/drivers/pg-rls.ts +233 -7
- package/src/drivers/pglite.ts +26 -3
- package/src/drivers/postgres.test.ts +23 -0
- package/src/drivers/postgres.ts +133 -9
- package/src/drivers/redis.ts +11 -4
- package/src/drivers/signal-redis.ts +24 -14
- package/src/drivers/signal-types.ts +2 -1
- package/src/drivers/types.ts +10 -0
- package/src/elements/ai/declare.ts +109 -0
- package/src/elements/ai/errors.test.ts +5 -1
- package/src/elements/ai/errors.ts +30 -2
- package/src/elements/ai/eval.ts +4 -6
- package/src/elements/ai/mcp-client.test.ts +206 -0
- package/src/elements/ai/mcp-client.ts +362 -0
- package/src/elements/ai/mcp-http.ts +159 -0
- package/src/elements/ai/mcp-mock.ts +134 -0
- package/src/elements/ai/mcp-protocol.ts +234 -0
- package/src/elements/ai/mcp-stdio.test.ts +50 -0
- package/src/elements/ai/mcp-stdio.ts +212 -0
- package/src/elements/ai/mcp-transport.ts +70 -0
- package/src/elements/ai/runtime.ts +159 -29
- package/src/elements/ai.test.ts +139 -0
- package/src/elements/ai.ts +16 -0
- package/src/elements/clock/declare.ts +26 -1
- package/src/elements/clock/health.test.ts +43 -0
- package/src/elements/clock/runtime.ts +55 -2
- package/src/elements/clock/schedule.ts +71 -142
- package/src/elements/clock.test.ts +9 -40
- package/src/elements/clock.ts +6 -1
- package/src/elements/gate/boot.ts +5 -5
- package/src/elements/gate/declare.ts +36 -4
- package/src/elements/gate/flatten.ts +1 -1
- package/src/elements/gate/runtime.ts +1 -1
- package/src/elements/index.ts +2 -0
- package/src/elements/signal/declare.ts +2 -1
- package/src/elements/signal/runtime.ts +16 -1
- package/src/elements/signal.ts +1 -0
- package/src/elements/store/cache.test.ts +2 -0
- package/src/elements/store/cache.ts +3 -3
- package/src/elements/store/declare.ts +9 -6
- package/src/elements/store/emit-drizzle.ts +44 -8
- package/src/elements/store/resource.test.ts +1 -1
- package/src/elements/store/rls-identity.test.ts +95 -0
- package/src/elements/store/rls-identity.ts +116 -0
- package/src/elements/store/runtime.ts +4 -0
- package/src/elements/store/schema-decl.test.ts +37 -0
- package/src/elements/store/schema-decl.ts +161 -0
- package/src/elements/store/seed.ts +1 -1
- package/src/elements/store/sql-condition.test.ts +12 -0
- package/src/elements/store/sql-condition.ts +26 -2
- package/src/elements/store/sql-rls-isolation.test.ts +165 -0
- package/src/elements/store/sql-rls-stamp.test.ts +117 -0
- package/src/elements/store/sql-session.ts +81 -3
- package/src/elements/store/upsert-app.test.ts +1 -1
- package/src/elements/store.ts +14 -0
- package/src/elements/vault/builtin-adapter.ts +17 -0
- package/src/full.ts +2 -0
- package/src/http.ts +20 -3
- package/src/index.ts +14 -1
- package/src/kernel/adopt-barrel-fresh.test.ts +1 -1
- package/src/kernel/adopt-routes.ts +30 -2
- package/src/kernel/app.ts +227 -77
- package/src/kernel/auto-cache.test.ts +8 -8
- package/src/kernel/auto-registry.test.ts +54 -9
- package/src/kernel/boot-bind/ai.ts +24 -0
- package/src/kernel/boot-bind/clock.ts +2 -0
- package/src/kernel/boot.test.ts +4 -4
- package/src/kernel/boot.ts +5 -3
- package/src/kernel/effects-stamping.test.ts +3 -3
- package/src/kernel/element-registries.ts +15 -5
- package/src/kernel/errors.ts +24 -0
- package/src/kernel/flow-units.ts +64 -0
- package/src/kernel/flow.ts +29 -17
- package/src/kernel/fx-dead-letters.test.ts +77 -0
- package/src/kernel/fx.test.ts +22 -0
- package/src/kernel/fx.ts +135 -6
- package/src/kernel/horizontal-child.ts +4 -4
- package/src/kernel/http-path-pending.ts +20 -0
- package/src/kernel/http-resource.ts +4 -0
- package/src/kernel/http-stream.test.ts +174 -0
- package/src/kernel/index.ts +2 -0
- package/src/kernel/pipeline.test.ts +2 -2
- package/src/kernel/plugin-elements.test.ts +1 -1
- package/src/kernel/plugin-needs.test.ts +1 -1
- package/src/kernel/ready.test.ts +2 -2
- package/src/kernel/resource-mount.test.ts +14 -0
- package/src/kernel/run-duration.test.ts +2 -2
- package/src/kernel/stamp-http.test.ts +79 -0
- package/src/kernel/stamp-http.ts +75 -0
- package/src/kernel/triggers.ts +52 -27
- package/src/manifest/mcp-ref.ts +88 -0
- package/src/manifest/types.ts +41 -2
- package/src/manifest/validate.test.ts +20 -0
- package/src/mcp/docs-server.ts +1 -1
- package/src/mcp/server.ts +1 -1
- package/src/plugins/compression.test.ts +21 -0
- package/src/plugins/compression.ts +1 -0
- package/src/release/measure.ts +2 -2
- package/src/runtime/bun.ts +41 -4
- package/src/runtime/json-code-block.test.ts +2 -2
- package/src/runtime/serve.test.ts +4 -4
- package/src/term.test.ts +52 -4
- package/src/term.ts +125 -17
- package/src/test/reset-element-registries.ts +10 -3
- package/src/cli/ask-seed.test.ts +0 -96
- package/src/cli/ask-seed.ts +0 -82
- package/src/console/ui-next/dist/assets/cache-glyph-CLPBqZeb.js +0 -1
- package/src/console/ui-next/dist/assets/collapsible-DYb0xU8C.js +0 -1
- package/src/console/ui-next/dist/assets/flows-page-Dg8CTE29.js +0 -1
- package/src/console/ui-next/dist/assets/http-method-BJ92Z_ke.js +0 -1
- package/src/console/ui-next/dist/assets/index-Bp-R7jtM.js +0 -66
- package/src/console/ui-next/dist/assets/index-D4Ldtj79.css +0 -2
- package/src/console/ui-next/dist/assets/observability-page-DAnpEaq1.js +0 -4
- package/src/console/ui-next/dist/assets/query-gate-parts-1m8m1iNp.js +0 -2
- package/src/console/ui-next/dist/assets/react-B1ML8gxg.js +0 -1
- package/src/console/ui-next/dist/assets/replica-lag-C8_BRt2x.js +0 -18
- package/src/console/ui-next/dist/assets/sheet-form-D-ata7jy.js +0 -1
- package/src/console/ui-next/dist/assets/shortcut-keys-DO4IsVqv.js +0 -1
- package/src/console/ui-next/dist/assets/skeleton-CL_X0GCj.js +0 -1
- package/src/console/ui-next/dist/assets/store-page-v3LXdYpr.js +0 -45
- package/src/console/ui-next/dist/assets/trace-detail-sheet-D16lWQMt.js +0 -2
- package/src/console/ui-next/dist/assets/units-page-BtQ0bqMe.js +0 -1
- package/src/console/ui-next/dist/assets/vault-page-Ca-MvcmJ.js +0 -2
package/src/term.test.ts
CHANGED
|
@@ -6,6 +6,7 @@ import { describe, expect, test } from "bun:test";
|
|
|
6
6
|
import {
|
|
7
7
|
formatAppReadyLine,
|
|
8
8
|
formatBootWarn,
|
|
9
|
+
formatBoundSurfaces,
|
|
9
10
|
formatClaimNote,
|
|
10
11
|
formatDevNote,
|
|
11
12
|
formatCliChrome,
|
|
@@ -14,6 +15,7 @@ import {
|
|
|
14
15
|
formatDevLogSeparator,
|
|
15
16
|
formatOkeWordmark,
|
|
16
17
|
formatServiceLine,
|
|
18
|
+
formatSurfaceBox,
|
|
17
19
|
formatRequestLine,
|
|
18
20
|
formatStackSummary,
|
|
19
21
|
countTermLines,
|
|
@@ -61,8 +63,8 @@ describe("term", () => {
|
|
|
61
63
|
expect(out).toContain("elements");
|
|
62
64
|
expect(out).toContain("store");
|
|
63
65
|
expect(out).toContain("postgres");
|
|
64
|
-
expect(out).toContain("●
|
|
65
|
-
expect(out).toContain("●
|
|
66
|
+
expect(out).toContain("● flow");
|
|
67
|
+
expect(out).toContain("● ai");
|
|
66
68
|
expect(out).toContain("Starting");
|
|
67
69
|
expect(out).not.toContain("Ready");
|
|
68
70
|
expect(out).not.toContain("on(Trigger)");
|
|
@@ -134,6 +136,7 @@ describe("term", () => {
|
|
|
134
136
|
appUrl: "http://127.0.0.1:6530",
|
|
135
137
|
consoleUrl: "http://127.0.0.1:6533",
|
|
136
138
|
mcpUrl: "http://127.0.0.1:6535",
|
|
139
|
+
docsMcpUrl: "http://127.0.0.1:6536",
|
|
137
140
|
profile: "local",
|
|
138
141
|
runtimeEnv: "local",
|
|
139
142
|
system: "darwin 25.4.0 · bun 1.3.14",
|
|
@@ -145,11 +148,38 @@ describe("term", () => {
|
|
|
145
148
|
expect(out).toContain("Backend");
|
|
146
149
|
expect(out).toContain("Console");
|
|
147
150
|
expect(out).toContain("MCP");
|
|
151
|
+
expect(out).toContain("Docs MCP");
|
|
148
152
|
expect(out).toContain("http://127.0.0.1:6530");
|
|
153
|
+
expect(out).toContain("Your flows, served from the Manifest.");
|
|
149
154
|
expect(out).toContain("└");
|
|
150
155
|
expect(out).toContain("Logs");
|
|
151
156
|
});
|
|
152
157
|
|
|
158
|
+
test("formatSurfaceBox prints url and purpose", () => {
|
|
159
|
+
const out = formatSurfaceBox({
|
|
160
|
+
label: "Backend",
|
|
161
|
+
url: "http://127.0.0.1:6530",
|
|
162
|
+
color: false,
|
|
163
|
+
});
|
|
164
|
+
expect(out).toContain("Backend");
|
|
165
|
+
expect(out).toContain("http://127.0.0.1:6530");
|
|
166
|
+
expect(out).toContain("Your flows, served from the Manifest.");
|
|
167
|
+
expect(out).toMatch(/● {2}Backend\n│ {2}http:\/\/127\.0\.0\.1:6530\n│ {2}Your flows/);
|
|
168
|
+
});
|
|
169
|
+
|
|
170
|
+
test("formatBoundSurfaces skips unbound MCP and Docs MCP", () => {
|
|
171
|
+
const out = formatBoundSurfaces({
|
|
172
|
+
appUrl: "http://127.0.0.1:6530",
|
|
173
|
+
consoleUrl: "http://127.0.0.1:6533",
|
|
174
|
+
color: false,
|
|
175
|
+
});
|
|
176
|
+
expect(out).toContain("Backend");
|
|
177
|
+
expect(out).toContain("Console");
|
|
178
|
+
expect(out).toContain("Panels, traces, and the effect graph.");
|
|
179
|
+
expect(out).not.toContain("Docs MCP");
|
|
180
|
+
expect(out).not.toContain("The same Manifest, for agents.");
|
|
181
|
+
});
|
|
182
|
+
|
|
153
183
|
test("formatDevLogSeparator closes hero and titles Logs", () => {
|
|
154
184
|
const out = formatDevLogSeparator(false);
|
|
155
185
|
expect(out).toContain("│");
|
|
@@ -280,10 +310,28 @@ describe("term", () => {
|
|
|
280
310
|
expect(out).toContain("Docker");
|
|
281
311
|
expect(out).toContain(":15975");
|
|
282
312
|
expect(out).toContain("gemma4:e4b-q4_K_M");
|
|
283
|
-
expect(out).toContain("●
|
|
284
|
-
expect(out).toContain("●
|
|
313
|
+
expect(out).toContain("● postgres");
|
|
314
|
+
expect(out).toContain("● ai");
|
|
285
315
|
// Blank │ row separates the Docker header from whatever sits above.
|
|
286
316
|
expect(out).toMatch(/│\n◇ {2}Docker/);
|
|
287
317
|
expect(out).not.toMatch(/\u001b\[/);
|
|
288
318
|
});
|
|
319
|
+
|
|
320
|
+
test("formatStackSummary aligns name and port columns", () => {
|
|
321
|
+
const out = formatStackSummary({
|
|
322
|
+
project: "oke-dev-a3f791",
|
|
323
|
+
services: [
|
|
324
|
+
{ label: "ai", hostPort: 23850, status: "ready" },
|
|
325
|
+
{ label: "store.index", hostPort: 8550, status: "ready" },
|
|
326
|
+
{ label: "postgres", hostPort: 15850, status: "ready" },
|
|
327
|
+
],
|
|
328
|
+
color: false,
|
|
329
|
+
});
|
|
330
|
+
const portCols = out
|
|
331
|
+
.split("\n")
|
|
332
|
+
.filter((line) => /●\s+\S/.test(line) && line.includes(":"))
|
|
333
|
+
.map((line) => line.search(/:\d/));
|
|
334
|
+
expect(portCols.length).toBe(3);
|
|
335
|
+
expect(new Set(portCols).size).toBe(1);
|
|
336
|
+
});
|
|
289
337
|
});
|
package/src/term.ts
CHANGED
|
@@ -112,6 +112,32 @@ export type DevHeroElement = {
|
|
|
112
112
|
readonly status?: DevStatus;
|
|
113
113
|
};
|
|
114
114
|
|
|
115
|
+
/** Name column for Ready / Docker / bind rows — fits `store.index`. */
|
|
116
|
+
const HERO_NAME_MIN = 12;
|
|
117
|
+
|
|
118
|
+
/**
|
|
119
|
+
* Widest name column that still fits every label (never below {@link HERO_NAME_MIN}).
|
|
120
|
+
*
|
|
121
|
+
* @param names - Row labels in the table
|
|
122
|
+
*/
|
|
123
|
+
function heroNameWidth(names: readonly string[]): number {
|
|
124
|
+
let width = HERO_NAME_MIN;
|
|
125
|
+
for (const name of names) {
|
|
126
|
+
if (name.length > width) width = name.length;
|
|
127
|
+
}
|
|
128
|
+
return width;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
/**
|
|
132
|
+
* Left-align a table cell.
|
|
133
|
+
*
|
|
134
|
+
* @param value - Cell text
|
|
135
|
+
* @param width - Column width
|
|
136
|
+
*/
|
|
137
|
+
function padHeroCol(value: string, width: number): string {
|
|
138
|
+
return value.padEnd(width);
|
|
139
|
+
}
|
|
140
|
+
|
|
115
141
|
/** Shared options for the `oke dev` hero / banner. */
|
|
116
142
|
export type DevHeroMeta = {
|
|
117
143
|
/** `local` · `docker` · `test` · `production` */
|
|
@@ -158,18 +184,24 @@ export function formatOkeWordmark(color: boolean = termColorEnabled()): string {
|
|
|
158
184
|
export function formatDevHeroDetails(options: DevHeroMeta = {}): string {
|
|
159
185
|
const s = termStyle(options.color ?? termColorEnabled());
|
|
160
186
|
const bar = `${s.dim}│${s.reset}`;
|
|
161
|
-
const
|
|
187
|
+
const elements = options.elements ?? [];
|
|
188
|
+
const nameWidth = heroNameWidth([
|
|
189
|
+
...(options.profile ? ["profile"] : []),
|
|
190
|
+
...(options.runtimeEnv ? ["env"] : []),
|
|
191
|
+
...(options.system ? ["system"] : []),
|
|
192
|
+
...elements.map((row) => row.element),
|
|
193
|
+
]);
|
|
194
|
+
const label = (name: string) => `${s.dim}${padHeroCol(name, nameWidth)}${s.reset}`;
|
|
162
195
|
const lines: string[] = [];
|
|
163
196
|
if (options.profile) {
|
|
164
|
-
lines.push(`${bar} ${label("profile")}
|
|
197
|
+
lines.push(`${bar} ${label("profile")} ${s.cyan}${options.profile}${s.reset}`);
|
|
165
198
|
}
|
|
166
199
|
if (options.runtimeEnv) {
|
|
167
|
-
lines.push(`${bar} ${label("env")}
|
|
200
|
+
lines.push(`${bar} ${label("env")} ${s.cyan}${options.runtimeEnv}${s.reset}`);
|
|
168
201
|
}
|
|
169
202
|
if (options.system) {
|
|
170
|
-
lines.push(`${bar} ${label("system")}
|
|
203
|
+
lines.push(`${bar} ${label("system")} ${s.dim}${options.system}${s.reset}`);
|
|
171
204
|
}
|
|
172
|
-
const elements = options.elements ?? [];
|
|
173
205
|
if (elements.length > 0) {
|
|
174
206
|
lines.push(`${bar} ${s.dim}elements${s.reset}`);
|
|
175
207
|
const color = options.color ?? termColorEnabled();
|
|
@@ -182,8 +214,10 @@ export function formatDevHeroDetails(options: DevHeroMeta = {}): string {
|
|
|
182
214
|
? ""
|
|
183
215
|
: `${s.dim}—${s.reset}`
|
|
184
216
|
: `${s.cyan}${row.detail}${s.reset}`;
|
|
185
|
-
const detailPart = detail ? `
|
|
186
|
-
lines.push(
|
|
217
|
+
const detailPart = detail ? ` ${detail}` : "";
|
|
218
|
+
lines.push(
|
|
219
|
+
`${bar} ${dot} ${s.dim}${padHeroCol(row.element, nameWidth)}${s.reset}${detailPart}`,
|
|
220
|
+
);
|
|
187
221
|
}
|
|
188
222
|
}
|
|
189
223
|
return lines.length > 0 ? `${lines.join("\n")}\n` : "";
|
|
@@ -454,7 +488,19 @@ export function createAnchoredBoard(
|
|
|
454
488
|
}
|
|
455
489
|
|
|
456
490
|
/**
|
|
457
|
-
* One
|
|
491
|
+
* One-line purpose for each `oke dev` bind surface.
|
|
492
|
+
*
|
|
493
|
+
* Same wording as the site PORTS mnemonic — keep them in lockstep.
|
|
494
|
+
*/
|
|
495
|
+
export const DEV_SURFACE_DETAILS: Readonly<Record<string, string>> = {
|
|
496
|
+
Backend: "Your flows, served from the Manifest.",
|
|
497
|
+
Console: "Panels, traces, and the effect graph.",
|
|
498
|
+
MCP: "The same Manifest, for agents.",
|
|
499
|
+
"Docs MCP": "Read-only docs search for agents.",
|
|
500
|
+
};
|
|
501
|
+
|
|
502
|
+
/**
|
|
503
|
+
* One service URL line (Console / MCP after bind, before the ready board).
|
|
458
504
|
*
|
|
459
505
|
* @param label - Surface name
|
|
460
506
|
* @param url - Absolute URL
|
|
@@ -466,19 +512,73 @@ export function formatServiceLine(
|
|
|
466
512
|
color: boolean = termColorEnabled(),
|
|
467
513
|
): string {
|
|
468
514
|
const s = termStyle(color);
|
|
469
|
-
const pad = label
|
|
515
|
+
const pad = padHeroCol(label, HERO_NAME_MIN);
|
|
470
516
|
return `${s.dim}│${s.reset} ${s.dim}${pad}${s.reset} ${s.cyan}${url}${s.reset}\n`;
|
|
471
517
|
}
|
|
472
518
|
|
|
473
519
|
/**
|
|
474
520
|
* Backend child ready line (`bun --hot` soft reload).
|
|
475
521
|
*
|
|
522
|
+
* Stays one line so Logs do not fill with surface boxes on every reload.
|
|
523
|
+
*
|
|
476
524
|
* @param url - Backend base URL
|
|
477
525
|
* @param color - Color on/off
|
|
478
526
|
*/
|
|
479
527
|
export function formatAppReadyLine(url: string, color: boolean = termColorEnabled()): string {
|
|
480
528
|
const s = termStyle(color);
|
|
481
|
-
return `${s.green}●${s.reset} ${s.dim}${"Backend"
|
|
529
|
+
return `${s.green}●${s.reset} ${s.dim}${padHeroCol("Backend", HERO_NAME_MIN)}${s.reset} ${s.cyan}${url}${s.reset}\n`;
|
|
530
|
+
}
|
|
531
|
+
|
|
532
|
+
/**
|
|
533
|
+
* One bound-surface box on the ready board — title, URL, purpose.
|
|
534
|
+
*
|
|
535
|
+
* @param options - Label, URL, optional detail override
|
|
536
|
+
*/
|
|
537
|
+
export function formatSurfaceBox(options: {
|
|
538
|
+
readonly label: string;
|
|
539
|
+
readonly url: string;
|
|
540
|
+
readonly detail?: string;
|
|
541
|
+
readonly color?: boolean;
|
|
542
|
+
}): string {
|
|
543
|
+
const s = termStyle(options.color ?? termColorEnabled());
|
|
544
|
+
const bar = `${s.dim}│${s.reset}`;
|
|
545
|
+
const detail = (options.detail ?? DEV_SURFACE_DETAILS[options.label] ?? "").trim();
|
|
546
|
+
const lines = [
|
|
547
|
+
`${s.green}●${s.reset} ${s.bold}${options.label}${s.reset}`,
|
|
548
|
+
`${bar} ${s.cyan}${options.url}${s.reset}`,
|
|
549
|
+
];
|
|
550
|
+
if (detail.length > 0) {
|
|
551
|
+
lines.push(`${bar} ${s.dim}${detail}${s.reset}`);
|
|
552
|
+
}
|
|
553
|
+
lines.push(bar);
|
|
554
|
+
return `${lines.join("\n")}\n`;
|
|
555
|
+
}
|
|
556
|
+
|
|
557
|
+
/**
|
|
558
|
+
* Backend · Console · MCP · Docs MCP boxes after bind.
|
|
559
|
+
*
|
|
560
|
+
* Pass `mcpUrl` / `docsMcpUrl` only when that surface came up — omitted
|
|
561
|
+
* URLs skip the box.
|
|
562
|
+
*
|
|
563
|
+
* @param options - Bound surface URLs
|
|
564
|
+
*/
|
|
565
|
+
export function formatBoundSurfaces(options: {
|
|
566
|
+
readonly appUrl: string;
|
|
567
|
+
readonly consoleUrl: string;
|
|
568
|
+
readonly mcpUrl?: string | null;
|
|
569
|
+
readonly docsMcpUrl?: string | null;
|
|
570
|
+
readonly color?: boolean;
|
|
571
|
+
}): string {
|
|
572
|
+
const color = options.color ?? termColorEnabled();
|
|
573
|
+
let out = formatSurfaceBox({ label: "Backend", url: options.appUrl, color });
|
|
574
|
+
out += formatSurfaceBox({ label: "Console", url: options.consoleUrl, color });
|
|
575
|
+
if (options.mcpUrl) {
|
|
576
|
+
out += formatSurfaceBox({ label: "MCP", url: options.mcpUrl, color });
|
|
577
|
+
}
|
|
578
|
+
if (options.docsMcpUrl) {
|
|
579
|
+
out += formatSurfaceBox({ label: "Docs MCP", url: options.docsMcpUrl, color });
|
|
580
|
+
}
|
|
581
|
+
return out;
|
|
482
582
|
}
|
|
483
583
|
|
|
484
584
|
/**
|
|
@@ -499,6 +599,7 @@ export function formatDevHero(
|
|
|
499
599
|
readonly appUrl: string;
|
|
500
600
|
readonly consoleUrl: string;
|
|
501
601
|
readonly mcpUrl: string;
|
|
602
|
+
readonly docsMcpUrl?: string;
|
|
502
603
|
},
|
|
503
604
|
): string {
|
|
504
605
|
const color = options.color ?? termColorEnabled();
|
|
@@ -511,9 +612,13 @@ export function formatDevHero(
|
|
|
511
612
|
`\n${bar}\n` +
|
|
512
613
|
formatDevHeroDetails({ ...options, color }) +
|
|
513
614
|
`${bar}\n` +
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
615
|
+
formatBoundSurfaces({
|
|
616
|
+
appUrl: options.appUrl,
|
|
617
|
+
consoleUrl: options.consoleUrl,
|
|
618
|
+
mcpUrl: options.mcpUrl,
|
|
619
|
+
docsMcpUrl: options.docsMcpUrl,
|
|
620
|
+
color,
|
|
621
|
+
}) +
|
|
517
622
|
formatDevLogSeparator(color)
|
|
518
623
|
);
|
|
519
624
|
}
|
|
@@ -767,25 +872,28 @@ export function formatStackSummary(options: {
|
|
|
767
872
|
}): string {
|
|
768
873
|
const s = termStyle(options.color ?? termColorEnabled());
|
|
769
874
|
const bar = `${s.dim}│${s.reset}`;
|
|
770
|
-
const
|
|
875
|
+
const nameWidth = heroNameWidth(["Docker", "app", ...options.services.map((svc) => svc.label)]);
|
|
876
|
+
const portWidth = Math.max(6, ...options.services.map((svc) => `:${svc.hostPort}`.length));
|
|
877
|
+
const pad = (label: string) => padHeroCol(label, nameWidth);
|
|
771
878
|
const color = options.color ?? termColorEnabled();
|
|
772
879
|
const lines: string[] = [
|
|
773
880
|
`${s.dim}│${s.reset}`,
|
|
774
|
-
`${s.green}◇${s.reset} ${s.bold}Docker${s.reset}
|
|
881
|
+
`${s.green}◇${s.reset} ${s.bold}${pad("Docker")}${s.reset} ${s.cyan}${options.project}${s.reset}`,
|
|
775
882
|
];
|
|
776
883
|
for (const svc of options.services) {
|
|
777
884
|
const detail = svc.detail?.trim();
|
|
778
885
|
const status = svc.status ?? "pending";
|
|
779
886
|
const dot = formatStatusDot(status, color);
|
|
887
|
+
const port = `:${svc.hostPort}`.padEnd(portWidth);
|
|
780
888
|
lines.push(
|
|
781
|
-
`${bar} ${dot}
|
|
889
|
+
`${bar} ${dot} ${s.dim}${pad(svc.label)}${s.reset} ${s.cyan}${port}${s.reset}` +
|
|
782
890
|
(detail ? ` ${s.dim}${detail}${s.reset}` : ""),
|
|
783
891
|
);
|
|
784
892
|
}
|
|
785
893
|
const drivers = options.appDrivers ?? [];
|
|
786
894
|
const appDetail = drivers.length > 0 ? `host Bun · ${drivers.join(" + ")}` : "host Bun";
|
|
787
895
|
const appDot = formatStatusDot("ready", color);
|
|
788
|
-
lines.push(`${bar} ${appDot}
|
|
896
|
+
lines.push(`${bar} ${appDot} ${s.dim}${pad("app")}${s.reset} ${s.dim}${appDetail}${s.reset}`);
|
|
789
897
|
lines.push(bar);
|
|
790
898
|
return `${lines.join("\n")}\n`;
|
|
791
899
|
}
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Global safety net for the `store
|
|
3
|
-
* `
|
|
4
|
-
* auto-registries
|
|
2
|
+
* Global safety net for the `store.*` / `vault.secret` / `signal()` /
|
|
3
|
+
* `clock()` / `gate.policy`·scope·rate / `channel.<medium>().template()` /
|
|
4
|
+
* `ai.model`·prompt·embed·agent auto-registries
|
|
5
|
+
* (`src/kernel/element-registries.ts`).
|
|
5
6
|
*
|
|
6
7
|
* Unlike `on()` bindings — created almost exclusively to wire a real app —
|
|
7
8
|
* these factories are called throughout the suite as bare value constructors,
|
|
@@ -19,9 +20,12 @@ import { afterEach } from "bun:test";
|
|
|
19
20
|
import {
|
|
20
21
|
aiAgentRegistry,
|
|
21
22
|
aiEmbedRegistry,
|
|
23
|
+
aiMcpServerRegistry,
|
|
22
24
|
aiModelRegistry,
|
|
23
25
|
aiPromptRegistry,
|
|
24
26
|
channelTemplateRegistry,
|
|
27
|
+
clockRegistry,
|
|
28
|
+
gateRegistry,
|
|
25
29
|
requiredEnvRegistry,
|
|
26
30
|
secretRegistry,
|
|
27
31
|
signalRegistry,
|
|
@@ -33,9 +37,12 @@ afterEach(() => {
|
|
|
33
37
|
secretRegistry.length = 0;
|
|
34
38
|
requiredEnvRegistry.length = 0;
|
|
35
39
|
signalRegistry.length = 0;
|
|
40
|
+
clockRegistry.length = 0;
|
|
41
|
+
gateRegistry.length = 0;
|
|
36
42
|
channelTemplateRegistry.length = 0;
|
|
37
43
|
aiModelRegistry.length = 0;
|
|
38
44
|
aiPromptRegistry.length = 0;
|
|
39
45
|
aiEmbedRegistry.length = 0;
|
|
40
46
|
aiAgentRegistry.length = 0;
|
|
47
|
+
aiMcpServerRegistry.length = 0;
|
|
41
48
|
});
|
package/src/cli/ask-seed.test.ts
DELETED
|
@@ -1,96 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Tests for the one-shot seed prompt after `oke db push`.
|
|
3
|
-
*/
|
|
4
|
-
|
|
5
|
-
import { mkdtempSync, mkdirSync, writeFileSync, rmSync, existsSync } from "node:fs";
|
|
6
|
-
import { tmpdir } from "node:os";
|
|
7
|
-
import { join } from "node:path";
|
|
8
|
-
import { describe, expect, test } from "bun:test";
|
|
9
|
-
import { maybeAskSeed } from "./ask-seed.ts";
|
|
10
|
-
import { PROJECT_STATE_REL } from "./project-state.ts";
|
|
11
|
-
|
|
12
|
-
describe("maybeAskSeed", () => {
|
|
13
|
-
test("skips when non-TTY", async () => {
|
|
14
|
-
const dir = mkdtempSync(join(tmpdir(), "ask-seed-"));
|
|
15
|
-
try {
|
|
16
|
-
mkdirSync(join(dir, "src", "db", "seed"), { recursive: true });
|
|
17
|
-
writeFileSync(join(dir, "src", "db", "seed", "index.ts"), "export default {};\n");
|
|
18
|
-
let seeded = false;
|
|
19
|
-
await maybeAskSeed({
|
|
20
|
-
cwd: dir,
|
|
21
|
-
env: "test",
|
|
22
|
-
stdinIsTTY: false,
|
|
23
|
-
confirmFn: async () => true,
|
|
24
|
-
seedFn: async () => {
|
|
25
|
-
seeded = true;
|
|
26
|
-
return 0;
|
|
27
|
-
},
|
|
28
|
-
});
|
|
29
|
-
expect(seeded).toBe(false);
|
|
30
|
-
} finally {
|
|
31
|
-
rmSync(dir, { recursive: true, force: true });
|
|
32
|
-
}
|
|
33
|
-
});
|
|
34
|
-
|
|
35
|
-
test("re-asks when the seed identity changes", async () => {
|
|
36
|
-
const dir = mkdtempSync(join(tmpdir(), "ask-seed-"));
|
|
37
|
-
try {
|
|
38
|
-
mkdirSync(join(dir, "src", "db", "seed"), { recursive: true });
|
|
39
|
-
writeFileSync(join(dir, "src", "db", "seed", "index.ts"), "export default {};\n");
|
|
40
|
-
mkdirSync(join(dir, ".oke"), { recursive: true });
|
|
41
|
-
writeFileSync(
|
|
42
|
-
join(dir, PROJECT_STATE_REL),
|
|
43
|
-
`${JSON.stringify({ seededAt: "2026-01-01T00:00:00.000Z", seed: "notes" }, null, 2)}\n`,
|
|
44
|
-
);
|
|
45
|
-
let calls = 0;
|
|
46
|
-
await maybeAskSeed({
|
|
47
|
-
cwd: dir,
|
|
48
|
-
env: "test",
|
|
49
|
-
stdinIsTTY: true,
|
|
50
|
-
confirmFn: async () => true,
|
|
51
|
-
seedFn: async () => {
|
|
52
|
-
calls += 1;
|
|
53
|
-
return 0;
|
|
54
|
-
},
|
|
55
|
-
});
|
|
56
|
-
expect(calls).toBe(1);
|
|
57
|
-
} finally {
|
|
58
|
-
rmSync(dir, { recursive: true, force: true });
|
|
59
|
-
}
|
|
60
|
-
});
|
|
61
|
-
|
|
62
|
-
test("asks once then writes .oke/state.json seededAt", async () => {
|
|
63
|
-
const dir = mkdtempSync(join(tmpdir(), "ask-seed-"));
|
|
64
|
-
try {
|
|
65
|
-
mkdirSync(join(dir, "src", "db", "seed"), { recursive: true });
|
|
66
|
-
writeFileSync(join(dir, "src", "db", "seed", "index.ts"), "export default {};\n");
|
|
67
|
-
let calls = 0;
|
|
68
|
-
await maybeAskSeed({
|
|
69
|
-
cwd: dir,
|
|
70
|
-
env: "test",
|
|
71
|
-
stdinIsTTY: true,
|
|
72
|
-
confirmFn: async () => true,
|
|
73
|
-
seedFn: async () => {
|
|
74
|
-
calls += 1;
|
|
75
|
-
return 0;
|
|
76
|
-
},
|
|
77
|
-
});
|
|
78
|
-
expect(calls).toBe(1);
|
|
79
|
-
expect(existsSync(join(dir, PROJECT_STATE_REL))).toBe(true);
|
|
80
|
-
|
|
81
|
-
await maybeAskSeed({
|
|
82
|
-
cwd: dir,
|
|
83
|
-
env: "test",
|
|
84
|
-
stdinIsTTY: true,
|
|
85
|
-
confirmFn: async () => true,
|
|
86
|
-
seedFn: async () => {
|
|
87
|
-
calls += 1;
|
|
88
|
-
return 0;
|
|
89
|
-
},
|
|
90
|
-
});
|
|
91
|
-
expect(calls).toBe(1);
|
|
92
|
-
} finally {
|
|
93
|
-
rmSync(dir, { recursive: true, force: true });
|
|
94
|
-
}
|
|
95
|
-
});
|
|
96
|
-
});
|
package/src/cli/ask-seed.ts
DELETED
|
@@ -1,82 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* One-time interactive prompt: run `oke db seed` after first successful push.
|
|
3
|
-
*/
|
|
4
|
-
|
|
5
|
-
import { confirm, isCancel } from "@clack/prompts";
|
|
6
|
-
import type { ConfigEnv } from "../config/index.ts";
|
|
7
|
-
import { resolveSeedIdentity, seedPromptMessage } from "../elements/store/seed.ts";
|
|
8
|
-
import { formatCliChrome } from "../term.ts";
|
|
9
|
-
import { loadSeedDef, resolveSeedModulePath, runSeed } from "./db-seed.ts";
|
|
10
|
-
import { isProjectSeeded, markProjectSeeded } from "./project-state.ts";
|
|
11
|
-
|
|
12
|
-
/** @deprecated Use `.oke/state.json` `seededAt` via {@link isProjectSeeded}. */
|
|
13
|
-
export { LEGACY_SEEDED_MARKER as SEEDED_MARKER } from "./project-state.ts";
|
|
14
|
-
|
|
15
|
-
/** Options for {@link maybeAskSeed}. */
|
|
16
|
-
export interface AskSeedOptions {
|
|
17
|
-
readonly cwd: string;
|
|
18
|
-
readonly env: ConfigEnv;
|
|
19
|
-
readonly write?: (text: string) => void;
|
|
20
|
-
readonly stdinIsTTY?: boolean;
|
|
21
|
-
/** Skip prompt (tests / `--yes` / non-interactive). */
|
|
22
|
-
readonly skip?: boolean;
|
|
23
|
-
/** Injectable confirm (tests). */
|
|
24
|
-
readonly confirmFn?: () => Promise<boolean>;
|
|
25
|
-
/** Injectable seed runner (tests). */
|
|
26
|
-
readonly seedFn?: (cwd: string, env: ConfigEnv) => Promise<number>;
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
/**
|
|
30
|
-
* After a successful `oke db push`, ask once whether to seed this app
|
|
31
|
-
* (`defineSeed({ name })` or the project folder). Skips when non-TTY,
|
|
32
|
-
* already seeded for that identity, or no seed module.
|
|
33
|
-
*
|
|
34
|
-
* @param options - Project / env / injectables
|
|
35
|
-
*/
|
|
36
|
-
export async function maybeAskSeed(options: AskSeedOptions): Promise<void> {
|
|
37
|
-
if (options.skip) return;
|
|
38
|
-
const tty = options.stdinIsTTY ?? Boolean(process.stdin.isTTY);
|
|
39
|
-
if (!tty) return;
|
|
40
|
-
|
|
41
|
-
const cwd = options.cwd;
|
|
42
|
-
const seedPath = await resolveSeedModulePath(cwd);
|
|
43
|
-
if (!(await Bun.file(seedPath).exists())) return;
|
|
44
|
-
|
|
45
|
-
const def = await loadSeedDef(cwd).catch(() => undefined);
|
|
46
|
-
const identity = resolveSeedIdentity(def, cwd);
|
|
47
|
-
if (await isProjectSeeded(cwd, identity.name)) return;
|
|
48
|
-
|
|
49
|
-
const write = options.write ?? ((t) => process.stdout.write(t));
|
|
50
|
-
const chromeWrite = (t: string) => write(formatCliChrome(t));
|
|
51
|
-
const ok =
|
|
52
|
-
options.confirmFn !== undefined
|
|
53
|
-
? await options.confirmFn()
|
|
54
|
-
: await (async () => {
|
|
55
|
-
const value = await confirm({
|
|
56
|
-
message: seedPromptMessage(identity),
|
|
57
|
-
initialValue: true,
|
|
58
|
-
});
|
|
59
|
-
if (isCancel(value)) return false;
|
|
60
|
-
return Boolean(value);
|
|
61
|
-
})();
|
|
62
|
-
|
|
63
|
-
if (!ok) {
|
|
64
|
-
chromeWrite("oke db seed: skipped (run `oke db seed` later)\n");
|
|
65
|
-
return;
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
const seed =
|
|
69
|
-
options.seedFn ??
|
|
70
|
-
((projectCwd, env) =>
|
|
71
|
-
runSeed({
|
|
72
|
-
cwd: projectCwd,
|
|
73
|
-
env,
|
|
74
|
-
write: chromeWrite,
|
|
75
|
-
force: true,
|
|
76
|
-
stdinIsTTY: false,
|
|
77
|
-
}));
|
|
78
|
-
const code = await seed(cwd, options.env);
|
|
79
|
-
if (code === 0) {
|
|
80
|
-
await markProjectSeeded(cwd, { seed: identity.name });
|
|
81
|
-
}
|
|
82
|
-
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{Cr as e,F as t,L as n,P as r,wr as i}from"./shortcut-keys-DO4IsVqv.js";import{A as a,f as o}from"./xyflow-D7n4g6go.js";import{t as s}from"./dagre.esm-ZwcdTuZZ.js";import{C as c,S as l,_ as u,o as d,v as f}from"./http-method-BJ92Z_ke.js";function p(e){let t=e.indexOf(`.`);return t===-1?e:e.slice(0,t)}function m(e){let t=e.indexOf(`.`);return t===-1?e:e.slice(t+1)}function h(e){let t=e?.flows??{},n=new Map;for(let e of Object.keys(t)){let r=t[e]?.effects?.calls??[];for(let t of r){let r=n.get(t)??[];r.push(e),n.set(t,r)}}for(let[e,t]of n)t.sort((e,t)=>e.localeCompare(t)),n.set(e,t);return n}function g(e,t){return h(e).get(t)??[]}function _(e){return e.startsWith(`sql:`)?{id:e,kind:`store`,label:e.slice(4),facet:`sql`}:e.startsWith(`kv:`)?{id:e,kind:`store`,label:e.slice(3),facet:`kv`}:e.startsWith(`files:`)?{id:e,kind:`store`,label:e.slice(6),facet:`files`}:e.startsWith(`index:`)?{id:e,kind:`store`,label:e.slice(6),facet:`index`}:e.startsWith(`signal:`)?{id:e,kind:`signal`,label:e.slice(7)}:e.startsWith(`ai:`)?{id:e,kind:`ai`,label:e.slice(3)}:e.startsWith(`vault:`)?{id:e,kind:`vault`,label:e.slice(6)}:e.startsWith(`channel:`)?{id:e,kind:`channel`,label:e.slice(8)}:e.startsWith(`gate:`)?{id:e,kind:`gate`,label:e.slice(5)}:e.startsWith(`clock:`)?{id:e,kind:`clock`,label:e.slice(6)}:null}function v(e,t,n,r,i=!1){let a=u[r];return{id:e,source:t,target:n,type:`smoothstep`,animated:i,data:{kind:r},style:{stroke:a,strokeWidth:r===`calls`?2.5:2.25},pathOptions:{borderRadius:28},zIndex:f.edge,markerEnd:{type:o.ArrowClosed,width:14,height:14,color:a}}}function y(e){let t=e?.flows??{},n=new Set(Object.keys(t)),r=[],i=new Map;for(let e of[...n].sort()){let t=p(e),n=i.get(t)??[];n.push(e),i.set(t,n)}let a=new Map,o=new Map;for(let e of n){let n=t[e];if(!n)continue;if(n.trigger?.signal){let t=`signal:${n.trigger.signal}`,i=_(t);i&&a.set(t,i),r.push(v(`e:${t}->flow:${e}`,t,`flow:${e}`,`trigger`))}if(n.trigger?.cron||n.trigger?.every){let t=`clock:${e}`,i=n.trigger.cron??n.trigger.every??e;a.set(t,{id:t,kind:`clock`,label:i,facet:n.trigger.cron?`cron`:`every`}),r.push(v(`e:${t}->flow:${e}`,t,`flow:${e}`,`trigger`))}for(let t of n.gates??[]){let n=`gate:${t}`;a.set(n,{id:n,kind:`gate`,label:t}),o.set(n,(o.get(n)??0)+1),r.push(v(`e:flow:${e}-gates->${n}`,`flow:${e}`,n,`gates`))}let i=n.effects;if(i){for(let t of i.reads??[]){let n=_(t);n&&(a.set(t,n),o.set(t,(o.get(t)??0)+1),r.push(v(`e:flow:${e}-reads->${t}`,`flow:${e}`,t,`reads`)))}for(let t of i.writes??[]){let n=_(t);n&&(a.set(t,n),o.set(t,(o.get(t)??0)+1),r.push(v(`e:flow:${e}-writes->${t}`,`flow:${e}`,t,`writes`)))}for(let t of i.emits??[]){let n=`signal:${t}`,i=_(n);i&&(a.set(n,i),o.set(n,(o.get(n)??0)+1),r.push(v(`e:flow:${e}->${n}`,`flow:${e}`,n,`emits`)))}for(let t of i.asks??[]){let n=`ai:${t}`,i=_(n);i&&(a.set(n,i),o.set(n,(o.get(n)??0)+1),r.push(v(`e:flow:${e}->${n}`,`flow:${e}`,n,`asks`)))}for(let t of i.sends??[]){let n=`channel:${t}`,i=_(n);i&&(a.set(n,i),o.set(n,(o.get(n)??0)+1),r.push(v(`e:flow:${e}->${n}`,`flow:${e}`,n,`sends`)))}for(let t of i.secrets??[]){let n=`vault:${t}`,i=_(n);i&&(a.set(n,i),o.set(n,(o.get(n)??0)+1),r.push(v(`e:flow:${e}->${n}`,`flow:${e}`,n,`secrets`)))}for(let t of i.calls??[])r.push(v(`e:flow:${e}->flow:${t}`,`flow:${e}`,`flow:${t}`,`calls`,!0))}}return{nodes:b(i,t,a,o),edges:r,flowIds:n}}function b(e,t,n,r){let i=new s.graphlib.Graph({compound:!0});i.setGraph({rankdir:`LR`,align:`UL`,nodesep:16,ranksep:88,edgesep:12,marginx:8,marginy:8}),i.setDefaultEdgeLabel(()=>({}));for(let[t,n]of[...e.entries()].sort()){i.setNode(`unit:${t}`,{});for(let e of n)i.setNode(`flow:${e}`,{...l.flow}),i.setParent(`flow:${e}`,`unit:${t}`)}for(let e of n.values())i.setNode(e.id,{...l[e.kind]});let a=new Set;for(let n of e.values())for(let e of n){let n=t[e];if(!n)continue;let r=(e,t)=>{let n=`${e}->${t}`;a.has(n)||!i.hasNode(e)||!i.hasNode(t)||(a.add(n),i.setEdge(e,t))};n.trigger?.signal&&r(`signal:${n.trigger.signal}`,`flow:${e}`),(n.trigger?.cron||n.trigger?.every)&&r(`clock:${e}`,`flow:${e}`);for(let t of n.gates??[])r(`flow:${e}`,`gate:${t}`);let o=n.effects;if(o){for(let t of o.reads??[])r(`flow:${e}`,t);for(let t of o.writes??[])r(`flow:${e}`,t);for(let t of o.emits??[])r(`flow:${e}`,`signal:${t}`);for(let t of o.asks??[])r(`flow:${e}`,`ai:${t}`);for(let t of o.sends??[])r(`flow:${e}`,`channel:${t}`);for(let t of o.secrets??[])r(`flow:${e}`,`vault:${t}`);for(let t of o.calls??[])r(`flow:${e}`,`flow:${t}`)}}s.layout(i);let o=[],{headerH:u,padX:d,padBottom:p}=c;for(let[n,r]of[...e.entries()].sort()){let e=`unit:${n}`,a=i.node(e);if(!a)continue;let s=a.x??0,c=a.y??0,h=r.length*l.flow.height+Math.max(0,r.length-1)*10,g=l.flow.width+d*2,_=u+h+p,v=s-g/2,y=c-_/2;o.push({id:e,type:`unit`,position:{x:v,y},data:{kind:`unit`,label:n,refId:e,badge:String(r.length)},selectable:!1,draggable:!1,zIndex:f.unit,width:g,height:_,style:{width:g,height:_}}),r.forEach((r,i)=>{let a=t[r];a&&o.push({id:`flow:${r}`,type:`flow`,position:{x:d,y:u+i*(l.flow.height+10)},parentId:e,extent:`parent`,zIndex:f.leaf,data:{kind:`flow`,label:m(r),refId:r,unit:n,plane:a.plane??`user`,badge:a.plane??`user`},draggable:!1,width:l.flow.width,height:l.flow.height,style:{width:l.flow.width,height:l.flow.height}})})}let h=[...n.values()].sort((e,t)=>e.kind.localeCompare(t.kind)||e.label.localeCompare(t.label));for(let e of h){let t=i.node(e.id),n=l[e.kind],a=r.get(e.id)??0;o.push({id:e.id,type:e.kind,position:{x:(t?.x??0)-n.width/2,y:(t?.y??0)-n.height/2},data:{kind:e.kind,label:e.label,refId:e.id,...e.facet===void 0?{}:{facet:e.facet},badge:e.facet??(a>0?String(a):e.kind)},draggable:!1,zIndex:f.leaf,width:n.width,height:n.height,style:{width:n.width,height:n.height}})}return o}function x(e,t,n,r={}){let i=t.size>0||n.size>0;return e.map(e=>{if(e.data.kind===`unit`||e.data.kind===`law`)return e;let a=e.data.kind===`flow`?t.has(e.data.refId):n.has(e.id);return{...e,data:{...e.data,highlighted:a,dimmed:i&&!a,active:r.activeNodeId!=null&&e.id===r.activeNodeId,focused:r.focusedNodeId!=null&&e.id===r.focusedNodeId}}})}function S(e,t){let n=new Map(t.map(e=>[e.id,e]));return t.some(e=>e.data.highlighted===!0)?e.map(e=>{let t=n.get(e.source),r=n.get(e.target),i=t?.data.highlighted===!0&&r?.data.highlighted===!0,a=u[e.data?.kind??`reads`];return{...e,animated:i?!0:e.animated,style:{...e.style,stroke:a,opacity:i?1:.32,strokeWidth:i?2.75:1.75},markerEnd:e.markerEnd&&typeof e.markerEnd==`object`?{...e.markerEnd,color:a}:e.markerEnd}}):e.map(e=>({...e,style:{...e.style,opacity:1}}))}var C=100;function w(e,t){return e.filter(e=>t.has(e.flow)).sort((e,t)=>t.startedAt-e.startedAt).slice(0,C)}var T=a();function E({cache:a,dataSlot:o}){let s=d(a);return(0,T.jsxs)(r,{children:[(0,T.jsx)(n,{render:t=>(0,T.jsx)(`span`,{...t,className:e(`flex w-4 shrink-0 items-center justify-center`,s.className),"data-slot":o,"data-cache":a,"aria-label":s.label,children:(0,T.jsx)(i,{icon:s.icon,className:`size-3`,"aria-hidden":!0})})}),(0,T.jsx)(t,{side:`top`,children:s.label})]})}export{S as a,p as c,x as i,w as n,y as o,m as r,g as s,E as t};
|