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.
Files changed (66) hide show
  1. package/README.md +30 -4
  2. package/docs/spec/example.md +12 -3
  3. package/docs/spec/four-applications.md +10 -3
  4. package/package.json +9 -40
  5. package/src/cli/dev-app-runner.ts +45 -6
  6. package/src/cli/dev.ts +204 -23
  7. package/src/cli/docker-cli.test.ts +10 -8
  8. package/src/cli/docker.ts +18 -7
  9. package/src/cli/doctor.ts +3 -18
  10. package/src/cli/hero-meta.test.ts +85 -0
  11. package/src/cli/hero-meta.ts +252 -0
  12. package/src/cli/index.ts +4 -1
  13. package/src/cli/json-out.test.ts +1 -1
  14. package/src/cli/load-config.images.test.ts +126 -0
  15. package/src/cli/load-config.ts +145 -2
  16. package/src/cli/ports.test.ts +51 -0
  17. package/src/cli/ports.ts +81 -0
  18. package/src/cli/registry.help.test.ts +18 -0
  19. package/src/cli/registry.ts +0 -4
  20. package/src/cli/safe-defaults.test.ts +3 -3
  21. package/src/config/define-config.test.ts +61 -0
  22. package/src/config/index.ts +89 -6
  23. package/src/config/resolve-driver.test.ts +30 -0
  24. package/src/console/server/app.ts +2 -1
  25. package/src/console/server/flows.ts +4 -1
  26. package/src/console/server/index.ts +5 -0
  27. package/src/console/server/operator-db.test.ts +213 -0
  28. package/src/console/server/operator-db.ts +470 -0
  29. package/src/console/server/plugin.ts +20 -0
  30. package/src/console/server/serve.ts +47 -1
  31. package/src/console/server/state.ts +25 -2
  32. package/src/console/ui/dist/assets/{index-B71Yl_SS.js → index-Dy4jht9P.js} +3 -3
  33. package/src/console/ui/dist/assets/{panel-overview-Bd48d9km.js → panel-overview-Dt_AeXgd.js} +1 -1
  34. package/src/console/ui/dist/assets/{panel-runs-BwsWqKeB.js → panel-runs-DGstFHeq.js} +1 -1
  35. package/src/console/ui/dist/assets/{panel-signals-9najbZY2.js → panel-signals-DzEa2Fnt.js} +1 -1
  36. package/src/console/ui/dist/assets/{panel-store-OHkP2pDp.js → panel-store-BJkbNgxx.js} +1 -1
  37. package/src/console/ui/dist/assets/{panel-traces-tn2JoY8U.js → panel-traces-BaRVO3gM.js} +1 -1
  38. package/src/console/ui/dist/assets/style-C8MxEWPd.css +3 -0
  39. package/src/console/ui/dist/favicon.svg +7 -0
  40. package/src/console/ui/dist/index.html +3 -2
  41. package/src/console/ui/shell/App.tsx +44 -4
  42. package/src/console/ui/shell/components/oke-logo.tsx +40 -0
  43. package/src/console/ui/shell/index.html +1 -0
  44. package/src/console/ui/shell/layout/Shell.tsx +2 -3
  45. package/src/console/ui/shell/panels/overview/OverviewPanel.tsx +8 -0
  46. package/src/console/ui/shell/public/favicon.svg +7 -0
  47. package/src/console/ui/shell/setup/Wizard.tsx +5 -2
  48. package/src/docker/compose.ts +45 -14
  49. package/src/docker/derive.ts +32 -10
  50. package/src/docker/docker.test.ts +28 -4
  51. package/src/docker/dockerfile.integration.test.ts +3 -1
  52. package/src/docker/index.ts +10 -0
  53. package/src/docker/stack-id.test.ts +86 -0
  54. package/src/docker/stack-id.ts +108 -0
  55. package/src/docker/stack.integration.test.ts +17 -8
  56. package/src/docker/types.ts +20 -1
  57. package/src/kernel/app.ts +39 -8
  58. package/src/kernel/boot-bind/store.test.ts +60 -0
  59. package/src/kernel/boot-bind/store.ts +142 -12
  60. package/src/kernel/boot.ts +28 -4
  61. package/src/mcp/server.ts +99 -57
  62. package/src/runtime/dev-request-log.test.ts +33 -0
  63. package/src/runtime/dev-request-log.ts +130 -0
  64. package/src/term.test.ts +98 -5
  65. package/src/term.ts +287 -6
  66. 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 handle.app.fetch(authed);
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 operators = createOperatorStore();
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;