okengine 0.10.3 → 0.11.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +76 -10
- package/site/content/docs/deployment/docker-swarm.mdx +48 -111
- package/site/content/docs/deployment/docker.mdx +43 -36
- package/site/content/docs/deployment/index.mdx +9 -9
- package/site/content/docs/deployment/kubernetes.mdx +4 -4
- package/site/content/docs/elements/ai.mdx +7 -7
- package/site/content/docs/elements/channel.mdx +9 -7
- package/site/content/docs/elements/clock.mdx +8 -8
- package/site/content/docs/elements/flow.mdx +46 -47
- package/site/content/docs/elements/gate.mdx +6 -5
- package/site/content/docs/elements/signal.mdx +2 -2
- package/site/content/docs/elements/store.mdx +71 -78
- package/site/content/docs/elements/vault.mdx +89 -70
- package/site/content/docs/get-started/basic-usage.mdx +8 -8
- package/site/content/docs/get-started/installation.mdx +36 -36
- package/site/content/docs/get-started/introduction.mdx +11 -0
- package/site/content/docs/get-started/why.mdx +2 -2
- package/site/content/docs/plugins/anonymous.mdx +1 -1
- package/site/content/docs/plugins/magic-link.mdx +11 -11
- package/site/content/docs/plugins/otp.mdx +2 -2
- package/site/content/docs/plugins/passkey.mdx +1 -1
- package/site/content/docs/plugins/two-factor.mdx +1 -1
- package/site/content/docs/plugins/username.mdx +1 -1
- package/site/content/docs/recipes/caddy.mdx +1 -1
- package/site/content/docs/recipes/cockroachdb.mdx +2 -2
- package/site/content/docs/recipes/dragonfly.mdx +1 -1
- package/site/content/docs/recipes/index.mdx +1 -2
- package/site/content/docs/recipes/llama-cpp.mdx +21 -23
- package/site/content/docs/recipes/mailpit.mdx +11 -11
- package/site/content/docs/recipes/meilisearch.mdx +10 -10
- package/site/content/docs/recipes/meta.json +0 -1
- package/site/content/docs/recipes/ollama.mdx +1 -1
- package/site/content/docs/recipes/pgdog.mdx +12 -9
- package/site/content/docs/recipes/postgres.mdx +3 -3
- package/site/content/docs/recipes/redis.mdx +2 -2
- package/site/content/docs/recipes/rustfs.mdx +10 -7
- package/site/content/docs/recipes/sglang.mdx +1 -1
- package/site/content/docs/recipes/supabase-docker.mdx +1 -1
- package/site/content/docs/recipes/timescale.mdx +2 -2
- package/site/content/docs/recipes/valkey.mdx +1 -1
- package/site/content/docs/recipes/vllm.mdx +1 -1
- package/site/content/docs/recipes/yugabytedb.mdx +2 -2
- package/site/content/docs/reference/cli.md +61 -38
- package/site/content/docs/reference/configuration.mdx +145 -70
- package/site/content/docs/reference/environment-variables.mdx +36 -28
- package/site/content/docs/reference/errors.mdx +28 -29
- package/site/content/docs/reference/fx.mdx +11 -4
- package/site/content/docs/reference/i18n.mdx +17 -6
- package/site/content/docs/reference/index.mdx +5 -0
- package/site/content/docs/reference/meta.json +1 -0
- package/site/content/docs/reference/migrating-environments.mdx +158 -0
- package/site/content/docs/reference/plugins.mdx +2 -2
- package/src/auth/gate-auth.test.ts +12 -10
- package/src/cli/ai-setup/ai-setup.test.ts +27 -15
- package/src/cli/ai-setup/apply.ts +111 -15
- package/src/cli/ai-setup/catalog.ts +3 -3
- package/src/cli/ai-setup/index.ts +1 -1
- package/src/cli/ai-setup/prompts.ts +1 -1
- package/src/cli/ai-setup/recommend.test.ts +1 -1
- package/src/cli/ask-seed.test.ts +3 -3
- package/src/cli/build.ts +1 -1
- package/src/cli/db-auto-push.test.ts +6 -3
- package/src/cli/db-auto-push.ts +7 -5
- package/src/cli/db-seed.ts +7 -8
- package/src/cli/db.test.ts +70 -71
- package/src/cli/db.ts +86 -12
- package/src/cli/dev-controller.test.ts +35 -0
- package/src/cli/dev-controller.ts +298 -0
- package/src/cli/dev-controls.ts +11 -65
- package/src/cli/dev-db-push.test.ts +47 -15
- package/src/cli/dev-schema-sync.test.ts +11 -11
- package/src/cli/dev-schema-sync.ts +10 -10
- package/src/cli/dev-session-lock.test.ts +106 -0
- package/src/cli/dev-session-lock.ts +209 -0
- package/src/cli/dev.test.ts +166 -121
- package/src/cli/dev.ts +138 -192
- package/src/cli/doc-staleness.test.ts +3 -6
- package/src/cli/docker-clean.test.ts +33 -1
- package/src/cli/docker-clean.ts +28 -33
- package/src/cli/docker-cli.test.ts +12 -11
- package/src/cli/docker.ts +95 -20
- package/src/cli/doctor.test.ts +40 -0
- package/src/cli/doctor.ts +55 -15
- package/src/cli/drizzle-env.test.ts +11 -13
- package/src/cli/drizzle-env.ts +18 -11
- package/src/cli/ensure-drizzle-config.ts +11 -14
- package/src/cli/hero-meta.test.ts +15 -15
- package/src/cli/hero-meta.ts +10 -9
- package/src/cli/index.ts +36 -6
- package/src/cli/load-config.images.test.ts +16 -12
- package/src/cli/load-config.source.test.ts +50 -0
- package/src/cli/load-config.ts +34 -28
- package/src/cli/meilisearch-local.ts +1 -2
- package/src/cli/mode.ts +7 -58
- package/src/cli/registry.ts +175 -19
- package/src/cli/resolve-dev-sql-env.test.ts +8 -16
- package/src/cli/resolve-dev-sql-env.ts +13 -15
- package/src/cli/safe-defaults.test.ts +28 -10
- package/src/cli/schema.ts +65 -16
- package/src/cli/test.ts +58 -0
- package/src/cli/tui/App.tsx +252 -0
- package/src/cli/tui/DevLive.tsx +116 -0
- package/src/cli/tui/components/ConfirmDialog.tsx +48 -0
- package/src/cli/tui/components/HeaderBar.tsx +67 -0
- package/src/cli/tui/components/LogStream.tsx +47 -0
- package/src/cli/tui/components/PanelCard.tsx +39 -0
- package/src/cli/tui/components/SelectRow.tsx +37 -0
- package/src/cli/tui/components/SlashPalette.tsx +172 -0
- package/src/cli/tui/components/Spinner.tsx +32 -0
- package/src/cli/tui/components/StatusBar.tsx +51 -0
- package/src/cli/tui/components/StatusDot.tsx +37 -0
- package/src/cli/tui/components/TabBar.tsx +49 -0
- package/src/cli/tui/components/Wordmark.tsx +43 -0
- package/src/cli/tui/format.ts +38 -0
- package/src/cli/tui/keys.test.ts +18 -0
- package/src/cli/tui/keys.ts +26 -0
- package/src/cli/tui/launch.test.ts +18 -0
- package/src/cli/tui/launch.ts +57 -0
- package/src/cli/tui/panels/Dashboard.tsx +201 -0
- package/src/cli/tui/panels/Database.tsx +198 -0
- package/src/cli/tui/panels/Dev.tsx +257 -0
- package/src/cli/tui/panels/Docker.tsx +357 -0
- package/src/cli/tui/panels/Navigator.test.ts +22 -0
- package/src/cli/tui/panels/Navigator.tsx +213 -0
- package/src/cli/tui/slash-catalog.test.ts +31 -0
- package/src/cli/tui/slash-catalog.ts +184 -0
- package/src/cli/tui/slash-run.ts +54 -0
- package/src/cli/tui/state/ports.ts +95 -0
- package/src/cli/tui/theme.ts +24 -0
- package/src/cli/vault-cmd.test.ts +402 -0
- package/src/cli/vault-cmd.ts +727 -69
- package/src/cli/vault-secure-input.test.ts +56 -0
- package/src/cli/vault-secure-input.ts +124 -0
- package/src/compiler/effects-infer.ts +7 -0
- package/src/compiler/fixtures/skyport/oke.config.ts +3 -3
- package/src/compiler/fixtures/skyport/src/flows/payments/index.ts +1 -1
- package/src/compiler/fixtures/skyport.expected.json +1 -1
- package/src/compiler-entry.ts +7 -0
- package/src/config/define-config.test.ts +111 -47
- package/src/config/driver-defaults.test.ts +16 -23
- package/src/config/driver-defaults.ts +33 -63
- package/src/config/index.ts +169 -144
- package/src/config/resolve-driver.test.ts +14 -19
- package/src/console/server/app.ts +4 -2
- package/src/console/server/console.test.ts +58 -1
- package/src/console/server/flows.ts +22 -2
- package/src/console/server/index.ts +3 -0
- package/src/console/server/operator-db.test.ts +55 -13
- package/src/console/server/operator-db.ts +305 -263
- package/src/console/server/serve.ts +16 -7
- package/src/console/server/state.ts +31 -9
- package/src/console/server/vault.test.ts +120 -5
- package/src/console/server/vault.ts +208 -12
- package/src/console/ui/dist/assets/{index-D-9KFce5.js → index--Y0Uaz-m.js} +2 -2
- package/src/console/ui/dist/assets/panel-vault-BkZdJPX8.js +1 -0
- package/src/console/ui/dist/assets/style-C3L349iZ.css +3 -0
- package/src/console/ui/dist/index.html +2 -2
- package/src/console/ui/shell/client.ts +16 -0
- package/src/console/ui/shell/panels/vault/VaultPanel.tsx +54 -1
- package/src/console/ui/vault/VaultA11yView.tsx +33 -1
- package/src/console/ui/vault/backend.test.ts +75 -0
- package/src/console/ui/vault/backend.ts +117 -0
- package/src/console/ui/vault/fixture.ts +21 -2
- package/src/console/ui/vault/index.ts +11 -1
- package/src/console/ui/vault/types.ts +26 -0
- package/src/docker/compose.ts +164 -61
- package/src/docker/derive.ts +106 -12
- package/src/docker/docker.test.ts +156 -110
- package/src/docker/helpers.ts +98 -0
- package/src/docker/images-config.test.ts +3 -8
- package/src/docker/index.ts +30 -5
- package/src/docker/recipes/index.ts +0 -3
- package/src/docker/recipes/llama-cpp.ts +4 -4
- package/src/docker/recipes/pgdog.ts +9 -2
- package/src/docker/resources.test.ts +71 -0
- package/src/docker/resources.ts +176 -0
- package/src/docker/stack-id.test.ts +11 -4
- package/src/docker/stack-id.ts +42 -32
- package/src/docker/stack.integration.test.ts +4 -15
- package/src/docker/types.ts +35 -3
- package/src/drivers/ai-ollama.integration.test.ts +2 -2
- package/src/drivers/conformance.test.ts +11 -12
- package/src/drivers/drizzle-dialect.test.ts +0 -4
- package/src/drivers/drizzle-dialect.ts +7 -13
- package/src/drivers/index.ts +24 -7
- package/src/drivers/journal-postgres.test.ts +3 -1
- package/src/drivers/journal-postgres.ts +4 -2
- package/src/drivers/meilisearch.ts +1 -1
- package/src/drivers/pglite.ts +28 -5
- package/src/drivers/types.ts +9 -11
- package/src/drivers/vault-aws-secrets-manager.test.ts +159 -0
- package/src/drivers/vault-aws-secrets-manager.ts +333 -0
- package/src/drivers/vault-builtin.test.ts +110 -0
- package/src/drivers/vault-builtin.ts +184 -0
- package/src/drivers/vault-driver-removal.test.ts +13 -0
- package/src/drivers/vault-managed.test.ts +95 -0
- package/src/drivers/vault-managed.ts +101 -25
- package/src/drivers/vault-types.ts +25 -5
- package/src/elements/ai/runtime.ts +1 -1
- package/src/elements/clock/chaos.test.ts +4 -1
- package/src/elements/clock/durable.ts +57 -4
- package/src/elements/clock.test.ts +13 -14
- package/src/elements/gate/config.ts +13 -3
- package/src/elements/gate/constants.ts +18 -0
- package/src/elements/gate/declare.ts +1 -1
- package/src/elements/gate/strategies.ts +2 -12
- package/src/elements/gate.test.ts +1 -1
- package/src/elements/gate.ts +2 -2
- package/src/elements/store/domain-ddl.test.ts +5 -12
- package/src/elements/store/emit-drizzle.ts +44 -19
- package/src/elements/store/index-boot.test.ts +15 -116
- package/src/elements/store/load-plugin-tables.ts +1 -1
- package/src/elements/store/resource-list-docs.fixture.ts +12 -6
- package/src/elements/store/resource-list-docs.test.ts +64 -44
- package/src/elements/store/resource.test.ts +17 -10
- package/src/elements/store/runtime.ts +9 -12
- package/src/elements/store/schema-decl.test.ts +16 -32
- package/src/elements/store/seed.test.ts +1 -2
- package/src/elements/store/seed.ts +7 -8
- package/src/elements/store/sql-condition.test.ts +2 -2
- package/src/elements/store/sql-session.test.ts +8 -10
- package/src/elements/store/sql-session.ts +10 -2
- package/src/elements/store.test.ts +13 -13
- package/src/elements/vault/audit.ts +233 -0
- package/src/elements/vault/boot-chain.test.ts +78 -0
- package/src/elements/vault/boot-chain.ts +43 -39
- package/src/elements/vault/builtin-adapter.test.ts +479 -0
- package/src/elements/vault/builtin-adapter.ts +1184 -0
- package/src/elements/vault/crypto.test.ts +237 -0
- package/src/elements/vault/crypto.ts +431 -0
- package/src/elements/vault/declare.ts +164 -3
- package/src/elements/vault/errors.ts +56 -0
- package/src/elements/vault/kms-unseal.test.ts +76 -0
- package/src/elements/vault/kms-unseal.ts +181 -0
- package/src/elements/vault/path.ts +90 -0
- package/src/elements/vault/resilience.test.ts +102 -0
- package/src/elements/vault/resilience.ts +107 -0
- package/src/elements/vault/runtime.ts +36 -4
- package/src/elements/vault/security-checklist.test.ts +130 -0
- package/src/elements/vault/storage.ts +448 -0
- package/src/elements/vault/types.ts +288 -0
- package/src/elements/vault/unseal.ts +150 -0
- package/src/elements/vault.test.ts +72 -4
- package/src/elements/vault.ts +91 -2
- package/src/full.ts +248 -0
- package/src/http.ts +41 -0
- package/src/i18n/interpolate-simple.ts +37 -0
- package/src/i18n/messages.ts +51 -4
- package/src/i18n-entry.ts +7 -0
- package/src/index.ts +35 -145
- package/src/journal-entry.ts +20 -0
- package/src/kernel/adopt-barrel-fresh.test.ts +25 -10
- package/src/kernel/app-auth.ts +98 -0
- package/src/kernel/app.ts +77 -110
- package/src/kernel/auto-registry.test.ts +2 -2
- package/src/kernel/boot-bind/ai.test.ts +5 -5
- package/src/kernel/boot-bind/ai.ts +2 -1
- package/src/kernel/boot-bind/channel.test.ts +6 -6
- package/src/kernel/boot-bind/channel.ts +3 -10
- package/src/kernel/boot-bind/clock.ts +2 -2
- package/src/kernel/boot-bind/gate.ts +5 -9
- package/src/kernel/boot-bind/honor-config.test.ts +42 -42
- package/src/kernel/boot-bind/journal.ts +2 -2
- package/src/kernel/boot-bind/store.test.ts +43 -44
- package/src/kernel/boot-bind/store.ts +16 -41
- package/src/kernel/boot-bind/vault.ts +16 -1
- package/src/kernel/boot.test.ts +13 -19
- package/src/kernel/boot.ts +31 -19
- package/src/kernel/budget-entry.ts +1 -1
- package/src/kernel/compensate.test.ts +288 -1
- package/src/kernel/compensate.ts +126 -0
- package/src/kernel/concurrency.test.ts +10 -9
- package/src/kernel/effects-stamping.test.ts +27 -2
- package/src/kernel/element-registries.ts +5 -3
- package/src/kernel/flow.ts +4 -2
- package/src/kernel/fx.test.ts +119 -3
- package/src/kernel/fx.ts +215 -40
- package/src/kernel/index.ts +14 -0
- package/src/kernel/journal.ts +130 -7
- package/src/kernel/pipeline.test.ts +20 -6
- package/src/kernel/redacted.test.ts +35 -0
- package/src/kernel/redacted.ts +24 -2
- package/src/kernel/router/create-default.ts +16 -0
- package/src/kernel/router/create-edge.ts +18 -0
- package/src/kernel/router/create.ts +23 -0
- package/src/kernel/router/index.ts +23 -0
- package/src/kernel/router/linear.ts +88 -0
- package/src/kernel/router/regexp.ts +188 -0
- package/src/kernel/router/smart.ts +120 -0
- package/src/kernel/router/trie.ts +108 -0
- package/src/kernel/router/types.ts +56 -0
- package/src/kernel/router.ts +18 -532
- package/src/kernel-entry.ts +43 -0
- package/src/manifest/fixtures/skyport.excerpt.json +1 -1
- package/src/manifest/fixtures/skyport.manifest.json +1 -1
- package/src/plugins/config-source.test.ts +7 -7
- package/src/release/build-lib.ts +61 -0
- package/src/release/exports.test.ts +4 -2
- package/src/release/exports.ts +30 -4
- package/src/release/measure.ts +101 -22
- package/src/runs/duckdb.ts +7 -2
- package/src/shared/lazy-src.ts +79 -0
- package/src/shared/optional-peer.ts +41 -0
- package/src/term.test.ts +3 -44
- package/src/test/create-test-app.ts +12 -0
- package/src/test/provisions.integration.test.ts +1 -1
- package/src/test/reset-element-registries.ts +2 -0
- package/src/upgrade/codemods.test.ts +7 -20
- package/src/upgrade/codemods.ts +93 -60
- package/site/content/docs/recipes/openbao.mdx +0 -141
- package/src/cli/ask-dev-mode.ts +0 -40
- package/src/cli/dev-mode.test.ts +0 -45
- package/src/cli/dev-mode.ts +0 -78
- package/src/cli/openbao-bootstrap.test.ts +0 -150
- package/src/cli/openbao-bootstrap.ts +0 -321
- package/src/cli/openbao-restart.integration.test.ts +0 -145
- package/src/console/ui/dist/assets/panel-vault-Za1GyJfM.js +0 -1
- package/src/console/ui/dist/assets/style-C8MxEWPd.css +0 -3
- package/src/docker/recipes/openbao.ts +0 -47
- package/src/drivers/libsql.ts +0 -179
- package/src/drivers/sqlite.ts +0 -44
- package/src/drivers/vault-openbao.test.ts +0 -97
- package/src/drivers/vault-openbao.ts +0 -143
package/src/cli/dev.test.ts
CHANGED
|
@@ -20,7 +20,6 @@ import type { WideEvent } from "../runs/types.ts";
|
|
|
20
20
|
import { isDataEnvelope, MCP_DATA_KIND } from "../mcp/data.ts";
|
|
21
21
|
import { mintMcpSession } from "../mcp/session.ts";
|
|
22
22
|
import { runDev, type DevOptions, type DevSession } from "./dev.ts";
|
|
23
|
-
import { readDevMode, writeDevMode } from "./dev-mode.ts";
|
|
24
23
|
import { mcpContextFromConsole } from "./mcp-from-console.ts";
|
|
25
24
|
|
|
26
25
|
/** Repo public entry — absolute import so temp apps need no install. */
|
|
@@ -28,6 +27,45 @@ const OKE_INDEX = resolve(import.meta.dir, "../index.ts");
|
|
|
28
27
|
|
|
29
28
|
const SECRET = "oke-dev-mcp-integration-secret";
|
|
30
29
|
|
|
30
|
+
/** Minimal compose injectables — unit tests never shell out to Docker. */
|
|
31
|
+
const STUB_IMAGES = {
|
|
32
|
+
"store.sql": "postgres:16-alpine",
|
|
33
|
+
"store.kv": "redis:7-alpine",
|
|
34
|
+
} as const;
|
|
35
|
+
const STUB_CREDENTIALS = {
|
|
36
|
+
"store.sql": {
|
|
37
|
+
user: "oke",
|
|
38
|
+
password: "test-password-not-in-yaml",
|
|
39
|
+
database: "oke",
|
|
40
|
+
},
|
|
41
|
+
} as const;
|
|
42
|
+
|
|
43
|
+
function stubCompose(
|
|
44
|
+
overrides: Partial<
|
|
45
|
+
Pick<
|
|
46
|
+
DevOptions,
|
|
47
|
+
"images" | "credentials" | "composeUp" | "composeHealth" | "composeStop" | "noDbPush"
|
|
48
|
+
>
|
|
49
|
+
> = {},
|
|
50
|
+
): Pick<
|
|
51
|
+
DevOptions,
|
|
52
|
+
"images" | "credentials" | "composeUp" | "composeHealth" | "composeStop" | "noDbPush"
|
|
53
|
+
> {
|
|
54
|
+
return {
|
|
55
|
+
images: STUB_IMAGES,
|
|
56
|
+
credentials: STUB_CREDENTIALS,
|
|
57
|
+
composeUp: async () => {},
|
|
58
|
+
composeHealth: async () =>
|
|
59
|
+
new Map([
|
|
60
|
+
["store-sql", "ready"],
|
|
61
|
+
["store-kv", "ready"],
|
|
62
|
+
]),
|
|
63
|
+
composeStop: () => {},
|
|
64
|
+
noDbPush: true,
|
|
65
|
+
...overrides,
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
|
|
31
69
|
const LIVE_MANIFEST: Manifest = {
|
|
32
70
|
oke: "1.0",
|
|
33
71
|
app: "dev-live",
|
|
@@ -77,6 +115,52 @@ describe("mcpContextFromConsole", () => {
|
|
|
77
115
|
});
|
|
78
116
|
});
|
|
79
117
|
|
|
118
|
+
/**
|
|
119
|
+
* Console for MCP tests — boot with `docker: false` so host `OKE_DOCKER=1`
|
|
120
|
+
* from compose stubs does not force redis/smtp docker URLs.
|
|
121
|
+
*/
|
|
122
|
+
async function serveTestConsole(
|
|
123
|
+
port: number,
|
|
124
|
+
cwd: string,
|
|
125
|
+
manifest: Manifest = LIVE_MANIFEST,
|
|
126
|
+
): Promise<{
|
|
127
|
+
readonly console: import("../console/server/app.ts").ConsoleAppHandle;
|
|
128
|
+
readonly port: number;
|
|
129
|
+
readonly stop: () => void;
|
|
130
|
+
}> {
|
|
131
|
+
const { createConsoleApp } = await import("../console/server/app.ts");
|
|
132
|
+
const handle = createConsoleApp({
|
|
133
|
+
cwd,
|
|
134
|
+
secret: SECRET,
|
|
135
|
+
silentClaim: true,
|
|
136
|
+
manifest,
|
|
137
|
+
});
|
|
138
|
+
await handle.app.boot({ env: "test", docker: false });
|
|
139
|
+
handle.state.listRuns = async () => {
|
|
140
|
+
const runs = handle.app.bootResult?.runs;
|
|
141
|
+
if (!runs) return [];
|
|
142
|
+
return runs.all();
|
|
143
|
+
};
|
|
144
|
+
const server = Bun.serve({
|
|
145
|
+
port,
|
|
146
|
+
hostname: "127.0.0.1",
|
|
147
|
+
fetch: (req) => handle.app.fetch(req),
|
|
148
|
+
});
|
|
149
|
+
const boundPort = server.port;
|
|
150
|
+
if (boundPort === undefined) {
|
|
151
|
+
server.stop(true);
|
|
152
|
+
throw new Error("test console: Bun.serve did not bind a port");
|
|
153
|
+
}
|
|
154
|
+
return {
|
|
155
|
+
console: handle,
|
|
156
|
+
port: boundPort,
|
|
157
|
+
stop() {
|
|
158
|
+
server.stop(true);
|
|
159
|
+
void handle.app.stop();
|
|
160
|
+
},
|
|
161
|
+
};
|
|
162
|
+
}
|
|
163
|
+
|
|
80
164
|
describe("oke dev MCP live wiring", () => {
|
|
81
165
|
let session: DevSession | undefined;
|
|
82
166
|
|
|
@@ -99,9 +183,11 @@ describe("oke dev MCP live wiring", () => {
|
|
|
99
183
|
consolePort: 0,
|
|
100
184
|
mcpPort: 0,
|
|
101
185
|
appPort: 0,
|
|
186
|
+
...stubCompose(),
|
|
102
187
|
startApp: async () => ({ stop() {} }),
|
|
103
188
|
regenClient: async () => {},
|
|
104
189
|
write: () => {},
|
|
190
|
+
serveConsole: async (port) => serveTestConsole(port, dir),
|
|
105
191
|
});
|
|
106
192
|
|
|
107
193
|
expect(result.code).toBe(0);
|
|
@@ -228,26 +314,18 @@ describe("oke dev MCP live wiring", () => {
|
|
|
228
314
|
mcpPort: 0,
|
|
229
315
|
appPort: 0,
|
|
230
316
|
manifest: LIVE_MANIFEST,
|
|
317
|
+
...stubCompose(),
|
|
231
318
|
startApp: async () => ({ stop() {} }),
|
|
232
319
|
regenClient: async () => {},
|
|
233
320
|
write: () => {},
|
|
234
321
|
serveConsole: async (port) => {
|
|
235
|
-
const
|
|
236
|
-
const server = await serveConsole({
|
|
237
|
-
port,
|
|
238
|
-
hostname: "127.0.0.1",
|
|
239
|
-
cwd: dir,
|
|
240
|
-
secret: SECRET,
|
|
241
|
-
silentClaim: true,
|
|
242
|
-
env: "dev",
|
|
243
|
-
manifest: LIVE_MANIFEST,
|
|
244
|
-
});
|
|
322
|
+
const server = await serveTestConsole(port, dir);
|
|
245
323
|
return {
|
|
246
324
|
console: server.console,
|
|
247
325
|
port: server.port,
|
|
248
326
|
stop() {
|
|
249
327
|
consoleStopped = true;
|
|
250
|
-
server.stop(
|
|
328
|
+
server.stop();
|
|
251
329
|
},
|
|
252
330
|
};
|
|
253
331
|
},
|
|
@@ -298,6 +376,7 @@ describe("oke dev docs MCP", () => {
|
|
|
298
376
|
consolePort: 0,
|
|
299
377
|
mcpPort: 0,
|
|
300
378
|
docsMcpPort: 0,
|
|
379
|
+
...stubCompose(),
|
|
301
380
|
startApp: async () => ({ stop() {} }),
|
|
302
381
|
regenClient: async () => {},
|
|
303
382
|
write: () => {},
|
|
@@ -371,6 +450,7 @@ describe("oke dev docs MCP", () => {
|
|
|
371
450
|
consolePort: 0,
|
|
372
451
|
mcpPort: 0,
|
|
373
452
|
docsMcpPort: 0,
|
|
453
|
+
...stubCompose(),
|
|
374
454
|
startApp: async () => ({ stop() {} }),
|
|
375
455
|
regenClient: async () => {},
|
|
376
456
|
write: (t) => {
|
|
@@ -426,7 +506,7 @@ export const app = oke({ name: "dev-hot", env: "test" }).adopt({ ping });
|
|
|
426
506
|
);
|
|
427
507
|
}
|
|
428
508
|
|
|
429
|
-
/** Stub Console + MCP so boot/hot tests isolate the app child. */
|
|
509
|
+
/** Stub Console + MCP + compose so boot/hot tests isolate the app child. */
|
|
430
510
|
function stubSurfaces(): Pick<
|
|
431
511
|
DevOptions,
|
|
432
512
|
| "serveConsole"
|
|
@@ -436,6 +516,12 @@ function stubSurfaces(): Pick<
|
|
|
436
516
|
| "write"
|
|
437
517
|
| "silentClaim"
|
|
438
518
|
| "keepAlive"
|
|
519
|
+
| "images"
|
|
520
|
+
| "credentials"
|
|
521
|
+
| "composeUp"
|
|
522
|
+
| "composeHealth"
|
|
523
|
+
| "composeStop"
|
|
524
|
+
| "noDbPush"
|
|
439
525
|
> {
|
|
440
526
|
return {
|
|
441
527
|
silentClaim: true,
|
|
@@ -445,6 +531,7 @@ function stubSurfaces(): Pick<
|
|
|
445
531
|
serveConsole: async () => ({ stop() {} }),
|
|
446
532
|
serveMcp: async () => ({ stop() {} }),
|
|
447
533
|
serveDocsMcp: async () => ({ stop() {} }),
|
|
534
|
+
...stubCompose(),
|
|
448
535
|
};
|
|
449
536
|
}
|
|
450
537
|
|
|
@@ -561,6 +648,8 @@ describe("oke dev syncAdoptBarrel atomic write", () => {
|
|
|
561
648
|
cwd: dir,
|
|
562
649
|
dryRun: true,
|
|
563
650
|
stdinIsTTY: false,
|
|
651
|
+
images: STUB_IMAGES,
|
|
652
|
+
credentials: STUB_CREDENTIALS,
|
|
564
653
|
write: () => {},
|
|
565
654
|
});
|
|
566
655
|
expect(code).toBe(0);
|
|
@@ -631,109 +720,49 @@ describe("oke dev syncAdoptBarrel atomic write", () => {
|
|
|
631
720
|
});
|
|
632
721
|
});
|
|
633
722
|
|
|
634
|
-
describe("oke dev
|
|
635
|
-
test("
|
|
636
|
-
const dir = await mkdtemp(join(tmpdir(), "oke-dev-
|
|
723
|
+
describe("oke dev Docker-first", () => {
|
|
724
|
+
test("dryRun always plans compose (no mode ask)", async () => {
|
|
725
|
+
const dir = await mkdtemp(join(tmpdir(), "oke-dev-always-compose-"));
|
|
637
726
|
await Bun.write(join(dir, "src/app.ts"), "export {}\n");
|
|
638
|
-
let askCalls = 0;
|
|
639
727
|
let composeCalls = 0;
|
|
640
728
|
const { code, plan } = await runDev({
|
|
641
729
|
cwd: dir,
|
|
642
730
|
dryRun: true,
|
|
643
731
|
stdinIsTTY: false,
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
return "docker";
|
|
647
|
-
},
|
|
732
|
+
images: STUB_IMAGES,
|
|
733
|
+
credentials: STUB_CREDENTIALS,
|
|
648
734
|
composeUp: async () => {
|
|
649
735
|
composeCalls++;
|
|
650
736
|
},
|
|
651
737
|
write: () => {},
|
|
652
738
|
});
|
|
653
739
|
expect(code).toBe(0);
|
|
654
|
-
expect(askCalls).toBe(0);
|
|
655
740
|
expect(composeCalls).toBe(0);
|
|
656
|
-
expect(plan?.stackRoles).
|
|
657
|
-
expect(await readDevMode(dir)).toBeNull();
|
|
741
|
+
expect(plan?.stackRoles).toEqual(["store.sql", "store.kv"]);
|
|
658
742
|
});
|
|
659
743
|
|
|
660
|
-
test("
|
|
661
|
-
const dir = await mkdtemp(join(tmpdir(), "oke-dev-
|
|
744
|
+
test("role filter -d store.sql plans only that role", async () => {
|
|
745
|
+
const dir = await mkdtemp(join(tmpdir(), "oke-dev-roles-"));
|
|
662
746
|
await Bun.write(join(dir, "src/app.ts"), "export {}\n");
|
|
663
|
-
let askCalls = 0;
|
|
664
|
-
const { code } = await runDev({
|
|
665
|
-
cwd: dir,
|
|
666
|
-
dryRun: true,
|
|
667
|
-
stdinIsTTY: true,
|
|
668
|
-
ask: async () => {
|
|
669
|
-
askCalls++;
|
|
670
|
-
return "local";
|
|
671
|
-
},
|
|
672
|
-
write: () => {},
|
|
673
|
-
});
|
|
674
|
-
expect(code).toBe(0);
|
|
675
|
-
expect(askCalls).toBe(1);
|
|
676
|
-
expect(await readDevMode(dir)).toBe("local");
|
|
677
|
-
});
|
|
678
|
-
|
|
679
|
-
test("TTY + unset mode → docker choice saves and plans compose on dryRun", async () => {
|
|
680
|
-
const dir = await mkdtemp(join(tmpdir(), "oke-dev-mode-tty-d-"));
|
|
681
|
-
await Bun.write(join(dir, "src/app.ts"), "export {}\n");
|
|
682
|
-
let askCalls = 0;
|
|
683
|
-
let composeCalls = 0;
|
|
684
747
|
const { code, plan } = await runDev({
|
|
685
748
|
cwd: dir,
|
|
686
749
|
dryRun: true,
|
|
687
|
-
stdinIsTTY:
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
"store.sql":
|
|
691
|
-
|
|
692
|
-
password: "test-password-not-in-yaml",
|
|
693
|
-
database: "oke",
|
|
694
|
-
},
|
|
695
|
-
},
|
|
696
|
-
ask: async () => {
|
|
697
|
-
askCalls++;
|
|
698
|
-
return "docker";
|
|
699
|
-
},
|
|
700
|
-
composeUp: async () => {
|
|
701
|
-
composeCalls++;
|
|
750
|
+
stdinIsTTY: false,
|
|
751
|
+
docker: ["store.sql"],
|
|
752
|
+
images: {
|
|
753
|
+
"store.sql": "postgres:16-alpine",
|
|
754
|
+
"store.kv": "redis:7-alpine",
|
|
702
755
|
},
|
|
756
|
+
credentials: STUB_CREDENTIALS,
|
|
703
757
|
write: () => {},
|
|
704
758
|
});
|
|
705
759
|
expect(code).toBe(0);
|
|
706
|
-
expect(askCalls).toBe(1);
|
|
707
|
-
expect(composeCalls).toBe(0);
|
|
708
|
-
expect(await readDevMode(dir)).toBe("docker");
|
|
709
760
|
expect(plan?.stackRoles).toEqual(["store.sql"]);
|
|
710
761
|
});
|
|
711
762
|
|
|
712
|
-
test("session
|
|
713
|
-
const dir = await mkdtemp(join(tmpdir(), "oke-dev-mode-local-"));
|
|
714
|
-
await Bun.write(join(dir, "src/app.ts"), "export {}\n");
|
|
715
|
-
let askCalls = 0;
|
|
716
|
-
const { code, plan } = await runDev({
|
|
717
|
-
cwd: dir,
|
|
718
|
-
dryRun: true,
|
|
719
|
-
local: true,
|
|
720
|
-
stdinIsTTY: true,
|
|
721
|
-
ask: async () => {
|
|
722
|
-
askCalls++;
|
|
723
|
-
return "docker";
|
|
724
|
-
},
|
|
725
|
-
write: () => {},
|
|
726
|
-
});
|
|
727
|
-
expect(code).toBe(0);
|
|
728
|
-
expect(askCalls).toBe(0);
|
|
729
|
-
expect(plan?.stackRoles).toBeNull();
|
|
730
|
-
expect(await readDevMode(dir)).toBeNull();
|
|
731
|
-
});
|
|
732
|
-
|
|
733
|
-
test("session stop calls composeStop after a successful docker up", async () => {
|
|
763
|
+
test("session stop calls composeStop after a successful compose up", async () => {
|
|
734
764
|
const dir = await mkdtemp(join(tmpdir(), "oke-dev-compose-stop-"));
|
|
735
765
|
await Bun.write(join(dir, "src/app.ts"), "export {}\n");
|
|
736
|
-
await writeDevMode(dir, "docker");
|
|
737
766
|
let upCalls = 0;
|
|
738
767
|
let stopCalls = 0;
|
|
739
768
|
let stoppedFiles: readonly string[] | undefined;
|
|
@@ -746,26 +775,20 @@ describe("oke dev mode resolution", () => {
|
|
|
746
775
|
const result = await runDev({
|
|
747
776
|
cwd: dir,
|
|
748
777
|
stdinIsTTY: false,
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
password: "test-password-not-in-yaml",
|
|
754
|
-
database: "oke",
|
|
778
|
+
...stubCompose({
|
|
779
|
+
composeUp: async (files) => {
|
|
780
|
+
upCalls++;
|
|
781
|
+
expect(files.length).toBeGreaterThan(0);
|
|
755
782
|
},
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
},
|
|
765
|
-
composeStop: (files) => {
|
|
766
|
-
stopCalls++;
|
|
767
|
-
stoppedFiles = files;
|
|
768
|
-
},
|
|
783
|
+
composeHealth: async ({ onUpdate }) => {
|
|
784
|
+
onUpdate?.("store-sql", "ready");
|
|
785
|
+
return new Map([["store-sql", "ready"]]);
|
|
786
|
+
},
|
|
787
|
+
composeStop: (files) => {
|
|
788
|
+
stopCalls++;
|
|
789
|
+
stoppedFiles = files;
|
|
790
|
+
},
|
|
791
|
+
}),
|
|
769
792
|
startApp: async () => ({ stop() {} }),
|
|
770
793
|
serveConsole: async () => ({ stop() {} }),
|
|
771
794
|
regenClient: async () => {},
|
|
@@ -790,10 +813,9 @@ describe("oke dev mode resolution", () => {
|
|
|
790
813
|
}
|
|
791
814
|
});
|
|
792
815
|
|
|
793
|
-
test("
|
|
794
|
-
const dir = await mkdtemp(join(tmpdir(), "oke-dev-
|
|
816
|
+
test("compose failure exits loudly (no silent downgrade)", async () => {
|
|
817
|
+
const dir = await mkdtemp(join(tmpdir(), "oke-dev-compose-fail-"));
|
|
795
818
|
await Bun.write(join(dir, "src/app.ts"), "export {}\n");
|
|
796
|
-
await writeDevMode(dir, "docker");
|
|
797
819
|
const lines: string[] = [];
|
|
798
820
|
const origErr = console.error;
|
|
799
821
|
console.error = (...args: unknown[]) => {
|
|
@@ -803,17 +825,11 @@ describe("oke dev mode resolution", () => {
|
|
|
803
825
|
const { code } = await runDev({
|
|
804
826
|
cwd: dir,
|
|
805
827
|
stdinIsTTY: false,
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
user: "oke",
|
|
810
|
-
password: "test-password-not-in-yaml",
|
|
811
|
-
database: "oke",
|
|
828
|
+
...stubCompose({
|
|
829
|
+
composeUp: async () => {
|
|
830
|
+
throw new Error("compose boom");
|
|
812
831
|
},
|
|
813
|
-
},
|
|
814
|
-
composeUp: async () => {
|
|
815
|
-
throw new Error("compose boom");
|
|
816
|
-
},
|
|
832
|
+
}),
|
|
817
833
|
startApp: async () => ({ stop() {} }),
|
|
818
834
|
serveConsole: async () => ({ stop() {} }),
|
|
819
835
|
regenClient: async () => {},
|
|
@@ -821,7 +837,36 @@ describe("oke dev mode resolution", () => {
|
|
|
821
837
|
keepAlive: false,
|
|
822
838
|
});
|
|
823
839
|
expect(code).toBe(1);
|
|
824
|
-
expect(lines.some((l) => l.includes("
|
|
840
|
+
expect(lines.some((l) => l.includes("Docker Compose failed"))).toBe(true);
|
|
841
|
+
} finally {
|
|
842
|
+
console.error = origErr;
|
|
843
|
+
}
|
|
844
|
+
});
|
|
845
|
+
|
|
846
|
+
test("missing Docker daemon fails fast with a clear error", async () => {
|
|
847
|
+
const dir = await mkdtemp(join(tmpdir(), "oke-dev-no-daemon-"));
|
|
848
|
+
await Bun.write(join(dir, "src/app.ts"), "export {}\n");
|
|
849
|
+
const lines: string[] = [];
|
|
850
|
+
const origErr = console.error;
|
|
851
|
+
console.error = (...args: unknown[]) => {
|
|
852
|
+
lines.push(args.map(String).join(" "));
|
|
853
|
+
};
|
|
854
|
+
try {
|
|
855
|
+
const { code } = await runDev({
|
|
856
|
+
cwd: dir,
|
|
857
|
+
stdinIsTTY: false,
|
|
858
|
+
images: STUB_IMAGES,
|
|
859
|
+
credentials: STUB_CREDENTIALS,
|
|
860
|
+
assertDocker: async () => {
|
|
861
|
+
throw new Error(
|
|
862
|
+
"oke dev: Docker daemon unavailable — start Docker Desktop (or the Docker daemon) and retry",
|
|
863
|
+
);
|
|
864
|
+
},
|
|
865
|
+
write: () => {},
|
|
866
|
+
keepAlive: false,
|
|
867
|
+
});
|
|
868
|
+
expect(code).toBe(1);
|
|
869
|
+
expect(lines.some((l) => l.includes("Docker daemon unavailable"))).toBe(true);
|
|
825
870
|
} finally {
|
|
826
871
|
console.error = origErr;
|
|
827
872
|
}
|