okengine 0.2.2 → 0.2.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +30 -4
- package/docs/spec/example.md +12 -3
- package/docs/spec/four-applications.md +10 -3
- package/package.json +9 -40
- package/src/cli/dev-app-runner.ts +45 -6
- package/src/cli/dev.ts +204 -23
- package/src/cli/docker-cli.test.ts +10 -8
- package/src/cli/docker.ts +18 -7
- package/src/cli/doctor.ts +3 -18
- package/src/cli/hero-meta.test.ts +85 -0
- package/src/cli/hero-meta.ts +252 -0
- package/src/cli/index.ts +4 -1
- package/src/cli/json-out.test.ts +1 -1
- package/src/cli/load-config.images.test.ts +126 -0
- package/src/cli/load-config.ts +145 -2
- package/src/cli/ports.test.ts +51 -0
- package/src/cli/ports.ts +81 -0
- package/src/cli/registry.help.test.ts +18 -0
- package/src/cli/registry.ts +0 -4
- package/src/cli/safe-defaults.test.ts +3 -3
- package/src/config/define-config.test.ts +61 -0
- package/src/config/index.ts +89 -6
- package/src/config/resolve-driver.test.ts +30 -0
- package/src/console/server/app.ts +2 -1
- package/src/console/server/flows.ts +4 -1
- package/src/console/server/index.ts +5 -0
- package/src/console/server/operator-db.test.ts +213 -0
- package/src/console/server/operator-db.ts +470 -0
- package/src/console/server/plugin.ts +20 -0
- package/src/console/server/serve.ts +47 -1
- package/src/console/server/state.ts +25 -2
- package/src/console/ui/dist/assets/{index-B71Yl_SS.js → index-Dy4jht9P.js} +3 -3
- package/src/console/ui/dist/assets/{panel-overview-Bd48d9km.js → panel-overview-Dt_AeXgd.js} +1 -1
- package/src/console/ui/dist/assets/{panel-runs-BwsWqKeB.js → panel-runs-DGstFHeq.js} +1 -1
- package/src/console/ui/dist/assets/{panel-signals-9najbZY2.js → panel-signals-DzEa2Fnt.js} +1 -1
- package/src/console/ui/dist/assets/{panel-store-OHkP2pDp.js → panel-store-BJkbNgxx.js} +1 -1
- package/src/console/ui/dist/assets/{panel-traces-tn2JoY8U.js → panel-traces-BaRVO3gM.js} +1 -1
- package/src/console/ui/dist/assets/style-C8MxEWPd.css +3 -0
- package/src/console/ui/dist/favicon.svg +7 -0
- package/src/console/ui/dist/index.html +3 -2
- package/src/console/ui/shell/App.tsx +44 -4
- package/src/console/ui/shell/components/oke-logo.tsx +40 -0
- package/src/console/ui/shell/index.html +1 -0
- package/src/console/ui/shell/layout/Shell.tsx +2 -3
- package/src/console/ui/shell/panels/overview/OverviewPanel.tsx +8 -0
- package/src/console/ui/shell/public/favicon.svg +7 -0
- package/src/console/ui/shell/setup/Wizard.tsx +5 -2
- package/src/docker/compose.ts +45 -14
- package/src/docker/derive.ts +32 -10
- package/src/docker/docker.test.ts +28 -4
- package/src/docker/dockerfile.integration.test.ts +3 -1
- package/src/docker/index.ts +10 -0
- package/src/docker/stack-id.test.ts +86 -0
- package/src/docker/stack-id.ts +108 -0
- package/src/docker/stack.integration.test.ts +17 -8
- package/src/docker/types.ts +20 -1
- package/src/kernel/app.ts +39 -8
- package/src/kernel/boot-bind/store.test.ts +60 -0
- package/src/kernel/boot-bind/store.ts +142 -12
- package/src/kernel/boot.ts +28 -4
- package/src/mcp/server.ts +99 -57
- package/src/runtime/dev-request-log.test.ts +33 -0
- package/src/runtime/dev-request-log.ts +130 -0
- package/src/term.test.ts +98 -5
- package/src/term.ts +287 -6
- package/src/console/ui/dist/assets/style-Cnl7WLya.css +0 -3
|
@@ -11,6 +11,7 @@ import {
|
|
|
11
11
|
resolveAllowedHosts,
|
|
12
12
|
secureFetch,
|
|
13
13
|
} from "../../runtime/security.ts";
|
|
14
|
+
import { runWithDevSurface } from "../../runtime/dev-request-log.ts";
|
|
14
15
|
import { CONSOLE_PORT, type ServerHandle } from "../../runtime/types.ts";
|
|
15
16
|
import {
|
|
16
17
|
bindManifestSignalBus,
|
|
@@ -22,6 +23,7 @@ import {
|
|
|
22
23
|
type CreateConsoleAppOptions,
|
|
23
24
|
} from "./app.ts";
|
|
24
25
|
import { createLiveWebsocket, type ConsoleLiveData } from "./live.ts";
|
|
26
|
+
import { openConsolePersistence } from "./operator-db.ts";
|
|
25
27
|
import {
|
|
26
28
|
CONSOLE_COOKIES,
|
|
27
29
|
consoleSessionCookie,
|
|
@@ -37,6 +39,11 @@ export interface ServeConsoleOptions extends CreateConsoleAppOptions {
|
|
|
37
39
|
readonly staticDir?: string;
|
|
38
40
|
/** Boot environment — use `"dev"` / `"prod"` so Bearer auth is production-like. */
|
|
39
41
|
readonly env?: "dev" | "prod" | "test";
|
|
42
|
+
/**
|
|
43
|
+
* Persist operators + secret under `.oke/` (default true).
|
|
44
|
+
* Set false for ephemeral test servers.
|
|
45
|
+
*/
|
|
46
|
+
readonly persist?: boolean;
|
|
40
47
|
}
|
|
41
48
|
|
|
42
49
|
/** Running Console server handle. */
|
|
@@ -54,9 +61,26 @@ export async function serveConsole(
|
|
|
54
61
|
): Promise<ConsoleServerHandle> {
|
|
55
62
|
const hostname = options.hostname ?? "127.0.0.1";
|
|
56
63
|
const port = options.port ?? CONSOLE_PORT;
|
|
64
|
+
const cwd = options.cwd ?? process.cwd();
|
|
65
|
+
const wantPersist = options.persist !== false && options.operators === undefined;
|
|
66
|
+
const persistence = wantPersist
|
|
67
|
+
? await openConsolePersistence(cwd, {
|
|
68
|
+
envSecret: options.secret ?? process.env.OKE_CONSOLE_SECRET,
|
|
69
|
+
})
|
|
70
|
+
: null;
|
|
57
71
|
const handle = createConsoleApp({
|
|
58
72
|
...options,
|
|
73
|
+
cwd,
|
|
59
74
|
silentClaim: options.silentClaim ?? false,
|
|
75
|
+
...(persistence
|
|
76
|
+
? {
|
|
77
|
+
secret: options.secret ?? persistence.secret,
|
|
78
|
+
operators: persistence.operators,
|
|
79
|
+
sessions: persistence.sessions,
|
|
80
|
+
persistOperator: persistence.persistOperator,
|
|
81
|
+
persistSessions: persistence.persistSessions,
|
|
82
|
+
}
|
|
83
|
+
: {}),
|
|
60
84
|
});
|
|
61
85
|
|
|
62
86
|
const env = options.env ?? "dev";
|
|
@@ -88,7 +112,9 @@ export async function serveConsole(
|
|
|
88
112
|
const authed = withCookieAuth(request);
|
|
89
113
|
|
|
90
114
|
if (url.pathname.startsWith("/console/")) {
|
|
91
|
-
const response = await
|
|
115
|
+
const response = await runWithDevSurface("Console", () =>
|
|
116
|
+
handle.app.fetch(authed),
|
|
117
|
+
);
|
|
92
118
|
const withCookies = await attachSessionCookies(authed, response);
|
|
93
119
|
return withConsoleSecurityHeaders(withCookies);
|
|
94
120
|
}
|
|
@@ -160,6 +186,7 @@ export async function serveConsole(
|
|
|
160
186
|
stop(closeActive = false) {
|
|
161
187
|
server.stop(closeActive);
|
|
162
188
|
void handle.app.stop();
|
|
189
|
+
persistence?.close();
|
|
163
190
|
},
|
|
164
191
|
};
|
|
165
192
|
}
|
|
@@ -172,11 +199,30 @@ export async function serveConsole(
|
|
|
172
199
|
export async function startConsoleApp(
|
|
173
200
|
options: CreateConsoleAppOptions & {
|
|
174
201
|
readonly env?: "dev" | "prod" | "test";
|
|
202
|
+
/** Opt-in durable operators under `.oke/` (default false for unit tests). */
|
|
203
|
+
readonly persist?: boolean;
|
|
175
204
|
} = {},
|
|
176
205
|
): Promise<ConsoleAppHandle> {
|
|
206
|
+
const cwd = options.cwd ?? process.cwd();
|
|
207
|
+
const persistence =
|
|
208
|
+
options.persist === true && options.operators === undefined
|
|
209
|
+
? await openConsolePersistence(cwd, {
|
|
210
|
+
envSecret: options.secret ?? process.env.OKE_CONSOLE_SECRET,
|
|
211
|
+
})
|
|
212
|
+
: null;
|
|
177
213
|
const handle = createConsoleApp({
|
|
178
214
|
...options,
|
|
215
|
+
cwd,
|
|
179
216
|
silentClaim: options.silentClaim ?? true,
|
|
217
|
+
...(persistence
|
|
218
|
+
? {
|
|
219
|
+
secret: options.secret ?? persistence.secret,
|
|
220
|
+
operators: persistence.operators,
|
|
221
|
+
sessions: persistence.sessions,
|
|
222
|
+
persistOperator: persistence.persistOperator,
|
|
223
|
+
persistSessions: persistence.persistSessions,
|
|
224
|
+
}
|
|
225
|
+
: {}),
|
|
180
226
|
});
|
|
181
227
|
await bootConsoleApp(handle);
|
|
182
228
|
return handle;
|
|
@@ -345,6 +345,16 @@ export interface ConsoleState {
|
|
|
345
345
|
}>;
|
|
346
346
|
/** Whether first operator exists (wizard permanently closed). */
|
|
347
347
|
get setupClosed(): boolean;
|
|
348
|
+
/**
|
|
349
|
+
* Persist an operator after claim/create (SQLite under `.oke/`).
|
|
350
|
+
* No-op when persistence is disabled (tests / memory-only).
|
|
351
|
+
*/
|
|
352
|
+
persistOperator: (operatorId: string) => void;
|
|
353
|
+
/**
|
|
354
|
+
* Persist sessions after issue / revoke (SQLite under `.oke/`).
|
|
355
|
+
* No-op when persistence is disabled (tests / memory-only).
|
|
356
|
+
*/
|
|
357
|
+
persistSessions: () => void;
|
|
348
358
|
/**
|
|
349
359
|
* Per-email login attempt timestamps for credential-check rate limiting
|
|
350
360
|
* (console §10.4 — same 5/60s strategy as setup-claim).
|
|
@@ -398,6 +408,14 @@ export interface CreateConsoleStateOptions {
|
|
|
398
408
|
readonly okeConfig?: OkeConfig | null;
|
|
399
409
|
/** Host plugin registry for scopes / capabilities. */
|
|
400
410
|
readonly pluginRegistry?: PluginRegistry | null;
|
|
411
|
+
/** Pre-hydrated operator store (from `.oke/console.sqlite`). */
|
|
412
|
+
readonly operators?: OperatorStore;
|
|
413
|
+
/** Pre-hydrated session store (from `.oke/console.sqlite`). */
|
|
414
|
+
readonly sessions?: SessionStore;
|
|
415
|
+
/** Persist hook after claim/create. */
|
|
416
|
+
readonly persistOperator?: (operatorId: string) => void;
|
|
417
|
+
/** Persist hook after session issue / revoke. */
|
|
418
|
+
readonly persistSessions?: () => void;
|
|
401
419
|
}
|
|
402
420
|
|
|
403
421
|
/**
|
|
@@ -413,10 +431,13 @@ export function createConsoleState(
|
|
|
413
431
|
process.env.OKE_CONSOLE_SECRET ??
|
|
414
432
|
`oke-console-dev-${crypto.randomUUID()}`;
|
|
415
433
|
const now = options.now ?? (() => Date.now());
|
|
434
|
+
const operators = options.operators ?? createOperatorStore();
|
|
416
435
|
const claim = mintClaimCode(now);
|
|
417
|
-
const
|
|
418
|
-
const sessions = createSessionStore();
|
|
436
|
+
const sessions = options.sessions ?? createSessionStore();
|
|
419
437
|
const liveSubscribers = new Set<(msg: ConsoleLiveMessage) => void>();
|
|
438
|
+
const persistOperator =
|
|
439
|
+
options.persistOperator ?? ((_operatorId: string) => {});
|
|
440
|
+
const persistSessions = options.persistSessions ?? (() => {});
|
|
420
441
|
|
|
421
442
|
const signalConfig = createMemorySignalConfigStore();
|
|
422
443
|
const gateAuth = createDefaultGateAuthStores();
|
|
@@ -843,6 +864,8 @@ export function createConsoleState(
|
|
|
843
864
|
get setupClosed() {
|
|
844
865
|
return operators.operators.size > 0;
|
|
845
866
|
},
|
|
867
|
+
persistOperator,
|
|
868
|
+
persistSessions,
|
|
846
869
|
};
|
|
847
870
|
|
|
848
871
|
return state;
|