okengine 0.9.0 → 0.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (175) hide show
  1. package/AGENTS.md +1 -1
  2. package/manifest.v1.schema.json +9 -1
  3. package/package.json +3 -3
  4. package/site/content/docs/console/runs.mdx +10 -0
  5. package/site/content/docs/console/traces.mdx +4 -0
  6. package/site/content/docs/elements/ai.mdx +54 -32
  7. package/site/content/docs/elements/channel.mdx +105 -14
  8. package/site/content/docs/elements/clock.mdx +1 -0
  9. package/site/content/docs/elements/flow.mdx +42 -8
  10. package/site/content/docs/get-started/basic-usage.mdx +5 -1
  11. package/site/content/docs/get-started/installation.mdx +9 -5
  12. package/site/content/docs/meta.json +2 -0
  13. package/site/content/docs/plugins/otp.mdx +58 -46
  14. package/site/content/docs/providers/azure-redis.mdx +85 -0
  15. package/site/content/docs/providers/cockroachdb.mdx +86 -0
  16. package/site/content/docs/providers/digitalocean-caching.mdx +88 -0
  17. package/site/content/docs/providers/dragonfly-cloud.mdx +82 -0
  18. package/site/content/docs/providers/elasticache.mdx +92 -0
  19. package/site/content/docs/providers/index.mdx +101 -0
  20. package/site/content/docs/providers/memorystore.mdx +89 -0
  21. package/site/content/docs/providers/meta.json +20 -0
  22. package/site/content/docs/providers/neon.mdx +115 -0
  23. package/site/content/docs/providers/redis-cloud.mdx +93 -0
  24. package/site/content/docs/providers/supabase.mdx +117 -0
  25. package/site/content/docs/providers/upstash.mdx +91 -0
  26. package/site/content/docs/providers/yugabytedb.mdx +95 -0
  27. package/site/content/docs/recipes/caddy.mdx +128 -0
  28. package/site/content/docs/recipes/cockroachdb.mdx +127 -0
  29. package/site/content/docs/recipes/dragonfly.mdx +125 -0
  30. package/site/content/docs/recipes/index.mdx +146 -0
  31. package/site/content/docs/recipes/llama-cpp.mdx +153 -0
  32. package/site/content/docs/recipes/mailpit.mdx +136 -0
  33. package/site/content/docs/recipes/meilisearch.mdx +139 -0
  34. package/site/content/docs/recipes/meta.json +31 -0
  35. package/site/content/docs/recipes/ollama.mdx +142 -0
  36. package/site/content/docs/recipes/openbao.mdx +141 -0
  37. package/site/content/docs/recipes/pgdog.mdx +137 -0
  38. package/site/content/docs/recipes/postgres.mdx +136 -0
  39. package/site/content/docs/recipes/redis.mdx +130 -0
  40. package/site/content/docs/recipes/rustfs.mdx +148 -0
  41. package/site/content/docs/recipes/sglang.mdx +105 -0
  42. package/site/content/docs/recipes/supabase-docker.mdx +145 -0
  43. package/site/content/docs/recipes/timescale.mdx +129 -0
  44. package/site/content/docs/recipes/traefik.mdx +136 -0
  45. package/site/content/docs/recipes/valkey.mdx +121 -0
  46. package/site/content/docs/recipes/vllm.mdx +106 -0
  47. package/site/content/docs/recipes/yugabytedb.mdx +135 -0
  48. package/site/content/docs/reference/cli.md +42 -6
  49. package/site/content/docs/reference/configuration.mdx +5 -3
  50. package/site/content/docs/reference/environment-variables.mdx +12 -12
  51. package/site/content/docs/reference/fx.mdx +38 -4
  52. package/src/auth/otp-capability.ts +14 -14
  53. package/src/cli/ai-setup/ai-setup.test.ts +32 -12
  54. package/src/cli/ai-setup/apply.ts +65 -23
  55. package/src/cli/ai-setup/catalog.ts +1316 -35
  56. package/src/cli/ai-setup/detect-ollama.ts +47 -0
  57. package/src/cli/ai-setup/index.ts +44 -7
  58. package/src/cli/ai-setup/prompts.ts +430 -486
  59. package/src/cli/ai-setup/recommend.test.ts +150 -50
  60. package/src/cli/ai-setup/recommend.ts +118 -101
  61. package/src/cli/ask-seed.test.ts +68 -0
  62. package/src/cli/ask-seed.ts +79 -0
  63. package/src/cli/db-seed-redact.test.ts +25 -0
  64. package/src/cli/db-seed.ts +36 -7
  65. package/src/cli/db.test.ts +1 -1
  66. package/src/cli/db.ts +2 -2
  67. package/src/cli/dev-controls.test.ts +107 -0
  68. package/src/cli/dev-controls.ts +354 -0
  69. package/src/cli/dev-schema-sync.ts +12 -4
  70. package/src/cli/dev.test.ts +50 -30
  71. package/src/cli/dev.ts +607 -66
  72. package/src/cli/drizzle-env.test.ts +40 -6
  73. package/src/cli/drizzle-env.ts +22 -1
  74. package/src/cli/ensure-drizzle-config.ts +6 -4
  75. package/src/cli/hero-meta.test.ts +13 -1
  76. package/src/cli/hero-meta.ts +28 -6
  77. package/src/cli/index.ts +5 -0
  78. package/src/cli/registry.ts +24 -0
  79. package/src/cli/replay.test.ts +105 -0
  80. package/src/cli/replay.ts +206 -0
  81. package/src/compiler/extract.ts +3 -3
  82. package/src/config/index.ts +3 -3
  83. package/src/console/server/claim.ts +3 -1
  84. package/src/console/ui/dist/assets/{index-ClX0ZCe5.js → index-D-9KFce5.js} +2 -2
  85. package/src/console/ui/dist/assets/panel-overview-CW0CQEc2.js +1 -0
  86. package/src/console/ui/dist/assets/panel-runs-BxuyDI3x.js +1 -0
  87. package/src/console/ui/dist/assets/{panel-signals-Dsxdu_AR.js → panel-signals-BXofbj7v.js} +1 -1
  88. package/src/console/ui/dist/assets/{panel-store-hy7O8HOs.js → panel-store-B8mH-arU.js} +1 -1
  89. package/src/console/ui/dist/assets/{panel-traces-CBiAe5go.js → panel-traces-DSA-ZWnf.js} +1 -1
  90. package/src/console/ui/dist/index.html +1 -1
  91. package/src/console/ui/overview/slo.ts +31 -3
  92. package/src/console/ui/overview/types.ts +6 -0
  93. package/src/console/ui/runs/errors.test.ts +53 -0
  94. package/src/console/ui/runs/errors.ts +88 -0
  95. package/src/console/ui/runs/index.ts +8 -0
  96. package/src/console/ui/runs/search.ts +16 -0
  97. package/src/console/ui/shell/panels/runs/RunsPanel.tsx +72 -1
  98. package/src/docker/ai-model-status.test.ts +101 -0
  99. package/src/docker/ai-model-status.ts +276 -0
  100. package/src/docker/compose-health.test.ts +115 -0
  101. package/src/docker/compose-health.ts +234 -0
  102. package/src/docker/compose.ts +24 -8
  103. package/src/docker/derive.ts +35 -9
  104. package/src/docker/docker.test.ts +304 -12
  105. package/src/docker/helpers.ts +56 -0
  106. package/src/docker/index.ts +52 -0
  107. package/src/docker/ollama-pull.ts +232 -0
  108. package/src/docker/recipes/cockroach.ts +24 -0
  109. package/src/docker/recipes/index.ts +32 -0
  110. package/src/docker/recipes/llama-cpp.ts +273 -0
  111. package/src/docker/recipes/ollama.ts +19 -23
  112. package/src/docker/recipes/pgdog.ts +4 -1
  113. package/src/docker/recipes/postgres.ts +5 -18
  114. package/src/docker/recipes/sglang.ts +55 -0
  115. package/src/docker/recipes/supabase.ts +21 -0
  116. package/src/docker/recipes/timescale.ts +18 -0
  117. package/src/docker/recipes/vllm.ts +44 -0
  118. package/src/docker/recipes/yugabyte.ts +23 -0
  119. package/src/docker/stack-id.test.ts +22 -0
  120. package/src/docker/stack-id.ts +38 -4
  121. package/src/docker/types.ts +15 -0
  122. package/src/drivers/ai-ollama.integration.test.ts +7 -4
  123. package/src/drivers/signal-engine.ts +10 -0
  124. package/src/drivers/signal-postgres.ts +24 -2
  125. package/src/drivers/signal-types.ts +10 -0
  126. package/src/elements/channel/fallback.test.ts +91 -0
  127. package/src/elements/channel/hard-bounce.test.ts +82 -0
  128. package/src/elements/channel/injection.test.ts +153 -0
  129. package/src/elements/channel/locale-ar.test.ts +102 -0
  130. package/src/elements/channel/otp-delivery.ts +5 -2
  131. package/src/elements/channel/receipts-ledger.test.ts +100 -0
  132. package/src/elements/channel/runtime.ts +24 -1
  133. package/src/elements/channel/test-helpers.ts +60 -0
  134. package/src/elements/channel/whatsapp-compliance.test.ts +124 -0
  135. package/src/elements/store/cache.ts +1 -1
  136. package/src/elements/store/emit-drizzle.ts +43 -9
  137. package/src/elements/store/runtime.ts +1 -1
  138. package/src/elements/store/schema-decl.test.ts +2 -0
  139. package/src/elements/store/schema-decl.ts +15 -0
  140. package/src/elements/store/seed.ts +1 -1
  141. package/src/index.ts +1 -0
  142. package/src/kernel/app.ts +118 -11
  143. package/src/kernel/boot-bind/signal.ts +6 -2
  144. package/src/kernel/boot-bind/store.ts +2 -1
  145. package/src/kernel/boot.test.ts +6 -5
  146. package/src/kernel/boot.ts +8 -3
  147. package/src/kernel/compensate.test.ts +131 -0
  148. package/src/kernel/correlation.test.ts +108 -0
  149. package/src/kernel/effect-timing.test.ts +82 -0
  150. package/src/kernel/flow.ts +38 -0
  151. package/src/kernel/fx-runs.test.ts +49 -0
  152. package/src/kernel/fx.test.ts +14 -0
  153. package/src/kernel/fx.ts +111 -1
  154. package/src/manifest/types.ts +8 -2
  155. package/src/plugins/auth-delivery.mailpit.integration.test.ts +1 -1
  156. package/src/plugins/auth-methods.security.test.ts +3 -3
  157. package/src/plugins/auth-methods.test.ts +1 -1
  158. package/src/plugins/index.ts +2 -2
  159. package/src/plugins/otp.test.ts +21 -19
  160. package/src/plugins/otp.ts +36 -34
  161. package/src/plugins/taqnyat.live.test.ts +3 -3
  162. package/src/runs/collect.ts +3 -0
  163. package/src/runs/export-otlp.ts +64 -0
  164. package/src/runs/index.ts +16 -0
  165. package/src/runs/parquet.ts +9 -0
  166. package/src/runs/types.ts +5 -0
  167. package/src/runs/window.test.ts +68 -0
  168. package/src/runs/window.ts +148 -0
  169. package/src/runtime/boot-warn.test.ts +45 -0
  170. package/src/runtime/boot-warn.ts +17 -0
  171. package/src/runtime/dev-request-log.ts +5 -5
  172. package/src/term.test.ts +95 -10
  173. package/src/term.ts +369 -14
  174. package/src/console/ui/dist/assets/panel-overview-DONDzBd2.js +0 -1
  175. package/src/console/ui/dist/assets/panel-runs-D5zf-D9c.js +0 -1
package/src/term.ts CHANGED
@@ -60,10 +60,56 @@ export function termStyle(color: boolean = termColorEnabled()): TermStyle {
60
60
  };
61
61
  }
62
62
 
63
+ /**
64
+ * Readiness for hero / Docker status dots.
65
+ *
66
+ * - `ready` — green ●
67
+ * - `pending` — yellow ● (starting / loading)
68
+ * - `error` — red ●
69
+ * - `idle` — dim ● (unbound)
70
+ */
71
+ export type DevStatus = "ready" | "pending" | "error" | "idle";
72
+
73
+ /**
74
+ * Colored ● for {@link DevStatus}.
75
+ *
76
+ * @param status - Readiness
77
+ * @param color - Color on/off
78
+ */
79
+ export function formatStatusDot(status: DevStatus, color: boolean = termColorEnabled()): string {
80
+ const s = termStyle(color);
81
+ switch (status) {
82
+ case "ready":
83
+ return `${s.green}●${s.reset}`;
84
+ case "pending":
85
+ return `${s.yellow}●${s.reset}`;
86
+ case "error":
87
+ return `${s.red}●${s.reset}`;
88
+ case "idle":
89
+ return `${s.dim}●${s.reset}`;
90
+ }
91
+ }
92
+
93
+ /**
94
+ * Map AI model phase → {@link DevStatus}.
95
+ *
96
+ * @param phase - Probe phase string
97
+ */
98
+ export function devStatusFromAiPhase(
99
+ phase: "unreachable" | "starting" | "loading" | "ready" | "error" | string,
100
+ ): DevStatus {
101
+ if (phase === "ready") return "ready";
102
+ if (phase === "error") return "error";
103
+ if (phase === "unreachable" || phase === "starting" || phase === "loading") return "pending";
104
+ return "pending";
105
+ }
106
+
63
107
  /** One eight-element row in the hero. */
64
108
  export type DevHeroElement = {
65
109
  readonly element: string;
66
110
  readonly detail: string;
111
+ /** Status dot (default: idle when detail is `—`, else ready). */
112
+ readonly status?: DevStatus;
67
113
  };
68
114
 
69
115
  /** Shared options for the `oke dev` hero / banner. */
@@ -124,10 +170,18 @@ export function formatDevHeroDetails(options: DevHeroMeta = {}): string {
124
170
  const elements = options.elements ?? [];
125
171
  if (elements.length > 0) {
126
172
  lines.push(`${bar} ${s.dim}elements${s.reset}`);
173
+ const color = options.color ?? termColorEnabled();
127
174
  for (const row of elements) {
128
- const idle = row.detail === "—";
129
- const detail = idle ? `${s.dim}—${s.reset}` : `${s.cyan}${row.detail}${s.reset}`;
130
- lines.push(`${bar} ${s.dim}${row.element.padEnd(9)}${s.reset} ${detail}`);
175
+ const idle = row.detail === "—" || row.detail === "";
176
+ const status = row.status ?? (idle ? "idle" : "ready");
177
+ const dot = formatStatusDot(status, color);
178
+ const detail = idle
179
+ ? row.detail === ""
180
+ ? ""
181
+ : `${s.dim}—${s.reset}`
182
+ : `${s.cyan}${row.detail}${s.reset}`;
183
+ const detailPart = detail ? ` ${detail}` : "";
184
+ lines.push(`${bar} ${dot} ${s.dim}${row.element.padEnd(9)}${s.reset}${detailPart}`);
131
185
  }
132
186
  }
133
187
  return lines.length > 0 ? `${lines.join("\n")}\n` : "";
@@ -152,11 +206,220 @@ export function formatDevBanner(options: DevHeroMeta = {}): string {
152
206
  if (options.watching !== false) {
153
207
  lines.push(`${bar} ${s.dim}watching — client types regenerate on save${s.reset}`);
154
208
  }
155
- lines.push(formatDevHeroDetails(options).trimEnd());
209
+ const details = formatDevHeroDetails(options).trimEnd();
210
+ if (details) lines.push(details);
156
211
  lines.push(bar);
157
212
  return `${lines.join("\n")}\n`;
158
213
  }
159
214
 
215
+ /**
216
+ * Count visual lines in a terminal string (trailing newline optional).
217
+ *
218
+ * @param text - Block text
219
+ */
220
+ export function countTermLines(text: string): number {
221
+ if (text.length === 0) return 0;
222
+ const normalized = text.endsWith("\n") ? text.slice(0, -1) : text;
223
+ if (normalized.length === 0) return 0;
224
+ return normalized.split("\n").length;
225
+ }
226
+
227
+ /** Handle for a bottom-of-TTY block that can be repainted until frozen. */
228
+ export type RewritableBlock = {
229
+ /** Paint / repaint the block (must still be the last output). */
230
+ readonly paint: (text: string) => void;
231
+ /** Erase the block in place (no-op when frozen or non-TTY). */
232
+ readonly clear: () => void;
233
+ /** Stop rewriting — further {@link paint} calls append instead. */
234
+ readonly freeze: () => void;
235
+ readonly frozen: () => boolean;
236
+ };
237
+
238
+ /**
239
+ * Erase `lineCount` lines above the cursor (cursor ends on the first cleared row).
240
+ *
241
+ * @param write - stdout writer
242
+ * @param lineCount - Rows to clear
243
+ */
244
+ function eraseTermLines(write: (text: string) => void, lineCount: number): void {
245
+ if (lineCount <= 0) return;
246
+ write(`\x1b[${lineCount}A`);
247
+ for (let i = 0; i < lineCount; i++) {
248
+ write("\x1b[2K");
249
+ if (i < lineCount - 1) write("\x1b[1B");
250
+ }
251
+ if (lineCount > 1) write(`\x1b[${lineCount - 1}A`);
252
+ }
253
+
254
+ /**
255
+ * Bottom-anchored live block for hero elements / Docker summary.
256
+ *
257
+ * Repaints in place with ANSI cursor moves while at the bottom of the TTY.
258
+ * Call {@link RewritableBlock.freeze} before printing anything below it.
259
+ *
260
+ * @param write - stdout writer
261
+ * @param enabled - When false (non-TTY / tests), every paint appends
262
+ */
263
+ export function createRewritableBlock(
264
+ write: (text: string) => void,
265
+ enabled: boolean = termColorEnabled() && process.stdout.isTTY === true,
266
+ ): RewritableBlock {
267
+ let lineCount = 0;
268
+ let frozen = false;
269
+ return {
270
+ paint(text: string) {
271
+ if (text.length === 0) {
272
+ this.clear();
273
+ return;
274
+ }
275
+ const body = text.endsWith("\n") ? text : `${text}\n`;
276
+ const nextLines = countTermLines(body);
277
+ if (!frozen && enabled && lineCount > 0) {
278
+ eraseTermLines(write, lineCount);
279
+ }
280
+ write(body);
281
+ if (!frozen && enabled) lineCount = nextLines;
282
+ else lineCount = 0;
283
+ },
284
+ clear() {
285
+ if (frozen) return;
286
+ if (enabled && lineCount > 0) eraseTermLines(write, lineCount);
287
+ lineCount = 0;
288
+ },
289
+ freeze() {
290
+ frozen = true;
291
+ lineCount = 0;
292
+ },
293
+ frozen: () => frozen,
294
+ };
295
+ }
296
+
297
+ /** Keyed ephemeral boot-progress lines (compose / vault / health / AI). */
298
+ export type BootProgress = {
299
+ /** Set or replace a progress row by key, then repaint. */
300
+ readonly set: (key: string, line: string) => void;
301
+ /** Erase all progress rows (TTY) before the final board. */
302
+ readonly clear: () => void;
303
+ };
304
+
305
+ /**
306
+ * Live boot-progress pane — keyed rows replace in place, then {@link BootProgress.clear}.
307
+ *
308
+ * @param write - stdout writer
309
+ * @param enabled - TTY rewrite on/off
310
+ */
311
+ export function createBootProgress(
312
+ write: (text: string) => void,
313
+ enabled: boolean = termColorEnabled() && process.stdout.isTTY === true,
314
+ ): BootProgress {
315
+ const block = createRewritableBlock(write, enabled);
316
+ const order: string[] = [];
317
+ const lines = new Map<string, string>();
318
+ const repaint = (): void => {
319
+ if (order.length === 0) {
320
+ block.clear();
321
+ return;
322
+ }
323
+ block.paint(order.map((key) => lines.get(key) ?? "").join(""));
324
+ };
325
+ return {
326
+ set(key: string, line: string) {
327
+ const body = line.endsWith("\n") ? line : `${line}\n`;
328
+ if (!lines.has(key)) order.push(key);
329
+ lines.set(key, body);
330
+ if (!enabled) {
331
+ write(body);
332
+ return;
333
+ }
334
+ repaint();
335
+ },
336
+ clear() {
337
+ order.length = 0;
338
+ lines.clear();
339
+ block.clear();
340
+ },
341
+ };
342
+ }
343
+
344
+ /** Live elements/Docker board that can rewrite after content is printed below. */
345
+ export type AnchoredBoard = {
346
+ /** Paint or rewrite the board (same height preferred). */
347
+ readonly paint: (text: string) => void;
348
+ /** Wrap a writer so post-board output is tracked for cursor math. */
349
+ readonly wrapWrite: (inner: (text: string) => void) => (text: string) => void;
350
+ /**
351
+ * Forget board geometry (after a full-screen clear) so the next
352
+ * {@link paint} writes fresh at the cursor.
353
+ */
354
+ readonly reset: () => void;
355
+ /** Disable further in-place rewrites (session end). */
356
+ readonly stop: () => void;
357
+ };
358
+
359
+ /**
360
+ * Anchored status board — rewrites in place even after Backend / Logs lines.
361
+ *
362
+ * Uses saved cursor + line offsets. Soft-reload full-screen clears can desync;
363
+ * later paints then append instead.
364
+ *
365
+ * @param write - stdout writer
366
+ * @param enabled - TTY rewrite on/off
367
+ */
368
+ export function createAnchoredBoard(
369
+ write: (text: string) => void,
370
+ enabled: boolean = termColorEnabled() && process.stdout.isTTY === true,
371
+ ): AnchoredBoard {
372
+ let boardLines = 0;
373
+ let belowLines = 0;
374
+ let stopped = false;
375
+ let lastBody = "";
376
+
377
+ return {
378
+ paint(text: string) {
379
+ if (stopped) return;
380
+ const body = text.endsWith("\n") ? text : `${text}\n`;
381
+ const nextLines = countTermLines(body);
382
+ if (!enabled) {
383
+ if (boardLines === 0) write(body);
384
+ boardLines = nextLines;
385
+ lastBody = body;
386
+ return;
387
+ }
388
+ if (boardLines === 0) {
389
+ write(body);
390
+ boardLines = nextLines;
391
+ lastBody = body;
392
+ return;
393
+ }
394
+ if (body === lastBody) return;
395
+ // Move to board start, replace rows, restore cursor.
396
+ write("\x1b[s");
397
+ write(`\x1b[${belowLines + boardLines}A`);
398
+ eraseTermLines(write, boardLines);
399
+ write(body);
400
+ boardLines = nextLines;
401
+ lastBody = body;
402
+ write("\x1b[u");
403
+ },
404
+ wrapWrite(inner: (text: string) => void) {
405
+ return (text: string) => {
406
+ if (!stopped && enabled && boardLines > 0) {
407
+ belowLines += countTermLines(text);
408
+ }
409
+ inner(text);
410
+ };
411
+ },
412
+ reset() {
413
+ boardLines = 0;
414
+ belowLines = 0;
415
+ lastBody = "";
416
+ },
417
+ stop() {
418
+ stopped = true;
419
+ },
420
+ };
421
+ }
422
+
160
423
  /**
161
424
  * One service URL line (Console / MCP after bind).
162
425
  *
@@ -175,14 +438,14 @@ export function formatServiceLine(
175
438
  }
176
439
 
177
440
  /**
178
- * App child ready line (`bun --hot` soft reload).
441
+ * Backend child ready line (`bun --hot` soft reload).
179
442
  *
180
- * @param url - App base URL
443
+ * @param url - Backend base URL
181
444
  * @param color - Color on/off
182
445
  */
183
446
  export function formatAppReadyLine(url: string, color: boolean = termColorEnabled()): string {
184
447
  const s = termStyle(color);
185
- return `${s.green}●${s.reset} ${s.dim}App${s.reset} ${s.cyan}${url}${s.reset}\n`;
448
+ return `${s.green}●${s.reset} ${s.dim}${"Backend".padEnd(7)}${s.reset} ${s.cyan}${url}${s.reset}\n`;
186
449
  }
187
450
 
188
451
  /**
@@ -241,10 +504,87 @@ export function formatDevLogSeparator(color: boolean = termColorEnabled()): stri
241
504
  *
242
505
  * @param message - Status text
243
506
  * @param color - Color on/off
507
+ * @param status - Optional colored ● prefix
508
+ */
509
+ export function formatStatusLine(
510
+ message: string,
511
+ color: boolean = termColorEnabled(),
512
+ status?: DevStatus,
513
+ ): string {
514
+ const s = termStyle(color);
515
+ const dot = status ? `${formatStatusDot(status, color)} ` : "";
516
+ return `${s.dim}│${s.reset} ${dot}${s.dim}${message}${s.reset}\n`;
517
+ }
518
+
519
+ /**
520
+ * Wrap a long message to `width` columns (word-aware).
521
+ *
522
+ * @param text - Source text
523
+ * @param width - Max columns per line
524
+ */
525
+ function wrapWords(text: string, width: number): string[] {
526
+ const words = text.split(/\s+/).filter((w) => w.length > 0);
527
+ if (words.length === 0) return [];
528
+ const lines: string[] = [];
529
+ let cur = "";
530
+ for (const word of words) {
531
+ if (cur.length === 0) {
532
+ cur = word;
533
+ continue;
534
+ }
535
+ if (`${cur} ${word}`.length <= width) {
536
+ cur = `${cur} ${word}`;
537
+ continue;
538
+ }
539
+ lines.push(cur);
540
+ cur = word;
541
+ }
542
+ if (cur.length > 0) lines.push(cur);
543
+ return lines;
544
+ }
545
+
546
+ /**
547
+ * Boot honesty notice — Clack-like column under the `oke dev` hero.
548
+ *
549
+ * @param message - Body (with or without `oke boot:` prefix)
550
+ * @param color - Color on/off
244
551
  */
245
- export function formatStatusLine(message: string, color: boolean = termColorEnabled()): string {
552
+ export function formatBootWarn(message: string, color: boolean = termColorEnabled()): string {
246
553
  const s = termStyle(color);
247
- return `${s.dim}│${s.reset} ${s.dim}${message}${s.reset}\n`;
554
+ const bar = `${s.dim}│${s.reset}`;
555
+ const body = message.replace(/^oke boot:\s*/i, "").trim();
556
+ const width = Math.max(40, Math.min(72, (process.stdout.columns ?? 80) - 6));
557
+ const wrapped = wrapWords(body, width);
558
+ const lines = [`${s.yellow}◇${s.reset} ${s.dim}Notice${s.reset}`];
559
+ for (const line of wrapped) {
560
+ lines.push(`${bar} ${s.dim}${line}${s.reset}`);
561
+ }
562
+ lines.push(bar);
563
+ return `${lines.join("\n")}\n`;
564
+ }
565
+
566
+ /**
567
+ * Route raw CLI / boot lines into hero chrome (`│ …` or Notice boxes).
568
+ *
569
+ * @param text - Chunk that may contain newlines
570
+ * @param color - Color on/off
571
+ */
572
+ export function formatCliChrome(text: string, color: boolean = termColorEnabled()): string {
573
+ const parts = text.split("\n");
574
+ const out: string[] = [];
575
+ for (let i = 0; i < parts.length; i++) {
576
+ const line = parts[i]!;
577
+ const isLastEmpty = i === parts.length - 1 && line.length === 0;
578
+ if (isLastEmpty) continue;
579
+ const trimmed = line.trimEnd();
580
+ if (trimmed.length === 0) continue;
581
+ if (/^oke boot:/i.test(trimmed)) {
582
+ out.push(formatBootWarn(trimmed, color));
583
+ continue;
584
+ }
585
+ out.push(formatStatusLine(trimmed, color));
586
+ }
587
+ return out.join("");
248
588
  }
249
589
 
250
590
  /** One infra service row for {@link formatStackSummary}. */
@@ -253,10 +593,16 @@ export type StackSummaryService = {
253
593
  readonly label: string;
254
594
  /** Published host port. */
255
595
  readonly hostPort: number;
596
+ /** Optional trailing detail (e.g. AI model id). */
597
+ readonly detail?: string;
598
+ /** Status dot (default `pending` until probed). */
599
+ readonly status?: DevStatus;
600
+ /** Compose service name for health lookup (`ai`, `store-sql`). */
601
+ readonly serviceName?: string;
256
602
  };
257
603
 
258
604
  /** Surfaces that emit request lines during `oke dev`. */
259
- export type DevLogSurface = "App" | "Console" | "MCP";
605
+ export type DevLogSurface = "Backend" | "Console" | "MCP";
260
606
 
261
607
  /**
262
608
  * Local calendar date `YYYY-MM-DD` (no time).
@@ -286,7 +632,7 @@ export function formatDevLogTime(at: Date = new Date()): string {
286
632
  * One HTTP/RPC request line for the `oke dev` TTY.
287
633
  *
288
634
  * @example
289
- * `● App GET /health main.health 12ms 200 2026-07-26 03:11:42`
635
+ * `● Backend GET /health main.health 12ms 200 2026-07-26 03:11:42`
290
636
  *
291
637
  * @param options - Surface, method, path, flow, timing, status
292
638
  */
@@ -308,7 +654,7 @@ export function formatRequestLine(options: {
308
654
  const date = formatDevLogDate(at);
309
655
  const time = formatDevLogTime(at);
310
656
  const surfaceColor =
311
- options.surface === "App" ? s.green : options.surface === "Console" ? s.magenta : s.cyan;
657
+ options.surface === "Backend" ? s.green : options.surface === "Console" ? s.magenta : s.cyan;
312
658
  const statusColor = options.status >= 500 ? s.red : options.status >= 400 ? s.yellow : s.green;
313
659
  const methodRaw = options.method.toUpperCase();
314
660
  const methodColor =
@@ -356,15 +702,24 @@ export function formatStackSummary(options: {
356
702
  const s = termStyle(options.color ?? termColorEnabled());
357
703
  const bar = `${s.dim}│${s.reset}`;
358
704
  const pad = (label: string) => label.padEnd(8);
705
+ const color = options.color ?? termColorEnabled();
359
706
  const lines: string[] = [
707
+ `${s.dim}│${s.reset}`,
360
708
  `${s.green}◇${s.reset} ${s.bold}Docker${s.reset} ${s.cyan}${options.project}${s.reset}`,
361
709
  ];
362
710
  for (const svc of options.services) {
363
- lines.push(`${bar} ${s.dim}${pad(svc.label)}${s.reset} ${s.cyan}:${svc.hostPort}${s.reset}`);
711
+ const detail = svc.detail?.trim();
712
+ const status = svc.status ?? "pending";
713
+ const dot = formatStatusDot(status, color);
714
+ lines.push(
715
+ `${bar} ${dot} ${s.dim}${pad(svc.label)}${s.reset} ${s.cyan}:${svc.hostPort}${s.reset}` +
716
+ (detail ? ` ${s.dim}${detail}${s.reset}` : ""),
717
+ );
364
718
  }
365
719
  const drivers = options.appDrivers ?? [];
366
720
  const appDetail = drivers.length > 0 ? `host Bun · ${drivers.join(" + ")}` : "host Bun";
367
- lines.push(`${bar} ${s.dim}${pad("app")}${s.reset} ${s.dim}${appDetail}${s.reset}`);
721
+ const appDot = formatStatusDot("ready", color);
722
+ lines.push(`${bar} ${appDot} ${s.dim}${pad("app")}${s.reset} ${s.dim}${appDetail}${s.reset}`);
368
723
  lines.push(bar);
369
724
  return `${lines.join("\n")}\n`;
370
725
  }
@@ -1 +0,0 @@
1
- import{a as e,r as t}from"./rolldown-runtime-B0Z9INg1.js";import{Q as n,d as r,n as i,nt as a,tt as o,u as s}from"./panel-access-ri1X9Otj.js";import{n as c}from"./panel-diff-CFuWxiXy.js";import{n as l}from"./panel-ai-DLHjRoJk.js";import{c as u,n as d,u as f}from"./panel-architecture-DI3bQF3J.js";import{r as p}from"./panel-channels-BDYWX29p.js";import{n as m}from"./panel-clock-i-JpTjVB.js";import{n as h}from"./panel-gates-CfkBgco7.js";var g=[`!=`,`>=`,`<=`,`=`,`>`,`<`];function _(e){if(!e||!e.trim())return{clauses:[]};let t=e.split(/\s+AND\s+/i).map(e=>e.trim()).filter(Boolean),n=[];for(let e of t){let t=re(e);t&&n.push(t)}return{clauses:n}}function v(e){return e.clauses.map(te).join(` AND `)}function y(e,t){return{clauses:[...e.clauses.filter(e=>e.dimension!==t.dimension),t]}}function b(e,t){return{clauses:e.clauses.filter(e=>e.dimension!==t)}}function x(e,t){for(let n of t.clauses)if(!S(e,n))return!1;return!0}function ee(e,t){return t.clauses.length===0?[...e]:e.filter(e=>x(e,t))}function te(e){let t=oe(e.dimension,e.value);return`${e.dimension} ${e.op} ${t}`}var ne=[`flow`,`unit`,`trigger`,`plane`,`tenant`,`principal`,`cache`,`replica`,`error`,`buildVersion`,`promptVersion`,`duration`];function re(e){let t=null,n=-1;for(let r of g){let i=e.indexOf(` ${r} `);if(i!==-1){t=r,n=i;break}}if(t===null||n<0)return null;let r=e.slice(0,n).trim(),i=e.slice(n+t.length+2).trim();if(!r||!i)return null;let a=ie(r,i);return a===void 0?null:{dimension:r,op:t,value:a}}function ie(e,t){return e===`duration`||e===`duration_ms`?ae(t):t===`true`?!0:t===`false`?!1:t.startsWith(`"`)&&t.endsWith(`"`)||t.startsWith(`'`)&&t.endsWith(`'`)?t.slice(1,-1):/^-?\d+(\.\d+)?$/.test(t)?Number(t):t}function ae(e){let t=/^(-?\d+(?:\.\d+)?)\s*(ms|s|m)?$/i.exec(e.trim());if(!t)return;let n=Number(t[1]),r=(t[2]??`ms`).toLowerCase();if(r===`ms`)return n;if(r===`s`)return n*1e3;if(r===`m`)return n*6e4}function oe(e,t){if(e===`duration`||e===`duration_ms`){let e=typeof t==`number`?t:Number(t);return Number.isFinite(e)?e>=6e4&&e%6e4==0?`${e/6e4}m`:e>=1e3&&e%1e3==0?`${e/1e3}s`:`${e}ms`:String(t)}return typeof t==`string`&&/\s/.test(t)?`"${t}"`:String(t)}function S(e,t){let n=C(e,t.dimension);if(n==null)return t.op===`!=`;let r=t.value;if(t.op===`=`)return w(n,r);if(t.op===`!=`)return!w(n,r);let i=T(n),a=T(r);return i===void 0||a===void 0?!1:t.op===`>`?i>a:t.op===`<`?i<a:t.op===`>=`?i>=a:t.op===`<=`&&i<=a}function C(e,t){switch(t){case`flow`:return e.flow;case`unit`:return e.unit??null;case`trigger`:return e.trigger;case`plane`:return e.plane;case`tenant`:return e.tenant??null;case`principal`:return e.principal??null;case`cache`:return e.cache;case`replica`:return e.replica??null;case`replicaLagMs`:case`replica_lag_ms`:return e.replicaLagMs??null;case`error`:case`error_code`:return e.error??null;case`buildVersion`:case`build_version`:return e.buildVersion??null;case`promptVersion`:case`prompt_version`:return e.promptVersion??null;case`cost`:return e.cost??null;case`duration`:case`duration_ms`:return e.durationMs;case`gates`:return e.gates.join(`,`);default:return e.dimensions[t]}}function w(e,t){if(typeof e==`number`||typeof t==`number`){let n=T(e),r=T(t);if(n!==void 0&&r!==void 0)return n===r}return String(e)===String(t)}function T(e){if(typeof e==`number`&&Number.isFinite(e))return e;if(typeof e==`boolean`)return;let t=Number(e);return Number.isFinite(t)?t:void 0}function E(e,t){let n=new Map;for(let r of e){let e=C(r,t),i=e==null||e===``?`(empty)`:String(e),a=n.get(i)??[];a.push(r),n.set(i,a)}let r=[];for(let[e,t]of n){let n=t.map(e=>e.durationMs).sort((e,t)=>e-t),i=n.reduce((e,t)=>e+t,0),a=t.reduce((e,t)=>e+(t.cost??0),0);r.push({key:e,count:t.length,avgDurationMs:t.length===0?0:i/t.length,p50DurationMs:D(n,.5),p99DurationMs:D(n,.99),sumCost:a})}return r.sort((e,t)=>t.count-e.count||e.key.localeCompare(t.key)),r}function se(e){let t=new Set([`flow`,`unit`,`trigger`,`plane`,`tenant`,`principal`,`cache`,`replica`,`error`,`buildVersion`,`promptVersion`]);for(let n of e)for(let e of Object.keys(n.dimensions))e!==`duration_ms`&&t.add(e);return[...t].sort((e,t)=>e.localeCompare(t))}function D(e,t){return e.length===0?0:e.length===1?e[0]:e[Math.min(e.length-1,Math.max(0,Math.ceil(t*e.length)-1))]}function ce(e){if(e.length===0)return null;let t=E(e,`flow`)[0];return!t||t.key===`(empty)`?null:{busiestFlow:t.key,runCount:t.count,href:`/flows?flow=${encodeURIComponent(t.key)}`}}var O=6048e5;function le(e){let{manifest:t,ai:n,runs:r,now:i}=e,a=i-O,o=[];for(let[e,n]of Object.entries(t?.flows??{})){let t=n.cost?.budget;if(t==null||t<=0)continue;let s=ue(r.filter(t=>t.flow===e&&t.startedAt>=a&&t.startedAt<=i));o.push(k({id:`flow:${e}`,name:e,kind:`flow`,declaredBudget:t,spent:s,windowMs:O}))}if(n){for(let e of n.prompts){let t=e.budgetMaxCostPerCall;if(t==null||t<=0)continue;let r=n.versions.find(t=>t.prompt===e.name&&t.version===e.version)??n.versions.filter(t=>t.prompt===e.name).sort((e,t)=>t.version-e.version)[0];if(!r||r.sampleCount===0)continue;let i=t*r.sampleCount,a=r.cost.mean*r.sampleCount;o.push(k({id:`ai-prompt:${e.name}@${r.version}`,name:`${e.name}@${r.version}`,kind:`ai-prompt`,declaredBudget:i,spent:a,windowMs:O}))}for(let e of n.agents){let t=e.budgetMaxCostPerRun;if(t==null||t<=0)continue;let r=n.agentRuns.filter(t=>t.agent===e.name);if(r.length===0)continue;let i=t*r.length,a=r.reduce((e,t)=>e+t.cost,0);o.push(k({id:`ai-agent:${e.name}`,name:e.name,kind:`ai-agent`,declaredBudget:i,spent:a,windowMs:O}))}}return o.sort((e,t)=>t.burnRate-e.burnRate||e.name.localeCompare(t.name))}function k(e){let{declaredBudget:t,spent:n,windowMs:r}=e,i=t<=0?0:n/t,a=Math.max(0,1-(t<=0?0:n/t)),o=null;if(n>0&&i>0&&a>0){let e=n/r;e>0&&(o=(t-n)/e)}else i>=1&&a<=0&&(o=0);return{id:e.id,name:e.name,kind:e.kind,declaredBudget:t,spent:n,burnRate:i,remainingFraction:a,timeToExhaustionMs:o,windowMs:r}}function ue(e){return e.reduce((e,t)=>e+(t.cost??0),0)}var A=36e5;function j(e,t){let n=t-A,r=e.filter(e=>e.startedAt>=n&&e.startedAt<=t),i=r.length,a=r.filter(e=>!!e.error).length,o=r.map(e=>e.durationMs).sort((e,t)=>e-t),s=r.filter(e=>e.replicaLagMs!=null&&e.replicaLagMs>200||e.cache===`miss`).length;return{latencyP99Ms:M(o,.99),trafficPerMin:i===0?0:i/(A/6e4),errorRate:i===0?0:a/i,saturation:i===0?0:s/i,sampleCount:i,windowMs:A}}function M(e,t){return e.length===0?0:e.length===1?e[0]:e[Math.min(e.length-1,Math.max(0,Math.ceil(t*e.length)-1))]}function N(e){return e.filter(e=>e.dead>0).map(e=>({signal:e.name,dead:e.dead,delivery:e.delivery})).sort((e,t)=>t.dead-e.dead||e.signal.localeCompare(t.signal))}var P=7776e6;function F(e,t){return e.filter(e=>e.kind===`secret`?e.lastReadAt==null||t-e.lastReadAt>=P:!1)}function I(e){return e.filter(e=>e.category===`permission-widening`&&(e.path.startsWith(`/plugins/`)||e.path.startsWith(`/plugins`)||e.summary.toLowerCase().includes(`plugin`))).map(e=>({path:e.path,summary:e.summary,kind:e.kind})).sort((e,t)=>e.path.localeCompare(t.path))}function L(e){return[...z(e.gatesAudit),...B(e.signals),...V(e.crons),...H(e.vaultSecrets,e.now),...U(e.channelOutcomes),...de(e.architectureGraph),...fe(e.diffChanges),...pe(e.aiVersions),...me(e.accessHygiene)].sort(R)}function R(e,t){return t.userHarm===e.userHarm?t.irreversibility===e.irreversibility?t.trend===e.trend?e.id.localeCompare(t.id):t.trend-e.trend:t.irreversibility-e.irreversibility:t.userHarm-e.userHarm}function z(e){return h(e).map(e=>({id:`gates:unguarded`,source:`gates`,title:`Unguarded flows`,detail:e.message,href:`/gates`,userHarm:90,irreversibility:80,trend:e.count}))}function B(e){return N(e).map(e=>({id:`signals:dlq:${e.signal}`,source:`signals`,title:`Dead letters`,detail:`${e.signal}: ${e.dead} dead letter${e.dead===1?``:`s`} (${e.delivery})`,href:`/signals?signal=${encodeURIComponent(e.signal)}`,userHarm:70,irreversibility:40,trend:e.dead}))}function V(e){return m(e).map(e=>({id:`clock:overdue:${e.name}`,source:`clock`,title:`Overdue cron`,detail:`${e.name} is overdue${e.missedRuns>0?` · ${e.missedRuns} missed`:``}`,href:`/clock?cron=${encodeURIComponent(e.name)}`,userHarm:60,irreversibility:30,trend:e.missedRuns}))}function H(e,t){let n=F(e,t);return n.length===0?[]:[{id:`vault:dormant`,source:`vault`,title:`Dormant secrets`,detail:`${n.length} secret${n.length===1?``:`s`} unread for 90+ days (or never): ${n.map(e=>e.name).join(`, `)}`,href:`/vault`,userHarm:50,irreversibility:70,trend:n.length}]}function U(e){return p(e).map(e=>({id:`channels:spam`,source:`channels`,title:`Spam complaints`,detail:`${e.count} delivered-then-complained — burns sender reputation`,href:`/channels`,userHarm:100,irreversibility:95,trend:e.count}))}function de(e){return e?f(e).map(e=>({id:`architecture:cycle:${e.nodeIds.join(`>`)}`,source:`architecture`,title:e.title,detail:e.detail,href:`/architecture`,userHarm:65,irreversibility:55,trend:e.severity===`critical`?2:1})):[]}function fe(e){return I(e).map(e=>({id:`plugins:widen:${e.path}`,source:`plugins`,title:`Plugin capability widening`,detail:e.summary,href:`/diff?path=${encodeURIComponent(e.path)}`,userHarm:55,irreversibility:90,trend:1}))}function pe(e){return l(e).map(e=>({id:`ai:budget:${e.prompt}@${e.version}`,source:`ai`,title:`Model budget overrun`,detail:`${e.prompt}@${e.version}: ${(e.overBudgetRate*100).toFixed(1)}% over budget (p95 $${e.p95Cost.toFixed(3)})`,href:`/ai?prompt=${encodeURIComponent(e.prompt)}&version=${e.version}`,userHarm:45,irreversibility:50,trend:Math.round(e.overBudgetRate*100)}))}function me(e){return i(e).map(t=>({id:`access:hygiene:${t.code}`,source:`access`,title:`Access hygiene`,detail:t.message,href:`/access`,userHarm:40,irreversibility:35,trend:t.code===`unused-keys`?e.unusedKeys.length:t.code===`never-signed-in`?e.neverSignedInOperators.length:e.expiredInvitations.length}))}var W=36e5,he=2592e6,ge=7776e6,G=36e5;function K(e){let t=e.trim(),n=/^(\d+(?:\.\d+)?)\s*%?$/.exec(t);if(!n)return null;let r=Number(n[1]);return!Number.isFinite(r)||r<0||r>100?null:Math.max(0,1-r/100)}function q(e){if(!e)return[];let t=[];for(let[n,r]of Object.entries(e.flows??{})){let e=r.slo?.availability;if(!e)continue;let i=K(e);i!=null&&t.push({id:`flow:${n}`,kind:`flow`,name:n,availability:e,tolerableErrorRate:i,flowIds:[n]})}for(let[n,r]of Object.entries(e.journeys??{})){let e=r.slo?.availability;if(!e)continue;let i=K(e);i!=null&&t.push({id:`journey:${n}`,kind:`journey`,name:n,availability:e,tolerableErrorRate:i,flowIds:xe(r)})}return t.sort((e,t)=>e.id.localeCompare(t.id))}function _e(e){return q(e.manifest).map(t=>ye(t,e.runs,e.now))}function ve(e){return q(e).length>0}function ye(e,t,n){let r=J(t,e.flowIds,n-W,n),i=J(t,e.flowIds,n-he,n),a=r.errorRate,o=e.tolerableErrorRate<=0?a>0?1/0:0:a/e.tolerableErrorRate,s=i.total*e.tolerableErrorRate,c=Math.max(0,s-i.errors),l=s<=0?i.errors>0?0:1:c/s,u=a-e.tolerableErrorRate,d=null;if(u>0&&r.total>0){let e=u*(r.total/W);e>0&&(d=c/e)}let f=be(t,e.flowIds,e.tolerableErrorRate,n),p=f==null||n-f>=7776e6;return{id:e.id,kind:e.kind,name:e.name,availability:e.availability,tolerableErrorRate:e.tolerableErrorRate,currentErrorRate:a,burnRate:o,remainingBudgetFraction:l,timeToExhaustionMs:d,ceremonial:p,lastBurnAt:f,sampleCount:r.total,errorCount:r.errors}}function J(e,t,n,r){let i=new Set(t),a=0,o=0;for(let t of e)t.startedAt<n||t.startedAt>r||i.size>0&&!i.has(t.flow)||(a+=1,t.error&&(o+=1));return{total:a,errors:o,errorRate:a===0?0:o/a}}function be(e,t,n,r){if(n<=0)return null;let i=r-ge,a=null;for(let o=i;o<r;o+=G){let i=Math.min(r,o+G),s=J(e,t,o,i);s.total!==0&&s.errorRate/n>=1&&(a=i)}return a}function xe(e){return(e.flows??[]).map(e=>typeof e==`string`?e:String(e))}function Se(e){let{hasDeclaredSlos:t,slos:n,costBudgets:r,findings:i}=e,a=n.filter(e=>e.burnRate>=1&&!e.ceremonial).sort((e,t)=>t.burnRate-e.burnRate||(e.timeToExhaustionMs??1/0)-(t.timeToExhaustionMs??1/0));if(a.length>0){let e=a[0],t=Y(e.timeToExhaustionMs),n=a.length===1?`one objective is burning fast`:`${a.length} objectives are burning`;return{tone:e.burnRate>=6?`critical`:`warn`,line:`${n} — ${e.name} will exhaust its budget ${t}`}}let o=r.filter(e=>e.burnRate>=1).sort((e,t)=>t.burnRate-e.burnRate||(e.timeToExhaustionMs??1/0)-(t.timeToExhaustionMs??1/0));if(o.length>0){let e=o[0];return{tone:`warn`,line:`cost budget burning — ${e.name} will exhaust ${Y(e.timeToExhaustionMs)}`}}if(i.length>0){let e=i[0];return{tone:e.userHarm>=90?`critical`:`warn`,line:`${e.title.toLowerCase()}: ${e.detail}`}}if(!t)return{tone:`empty`,line:`no objectives declared yet — findings and golden signals below; declare a first SLO on your busiest flow`};let s=n.filter(e=>e.ceremonial);return s.length===n.length&&n.length>0?{tone:`ok`,line:`all ${n.length} objective${n.length===1?``:`s`} within budget — ${s.length} marked ceremonial (no burn in 90 days)`}:{tone:`ok`,line:`all objectives within budget — no burning SLOs`}}function Y(e){if(e==null)return`if the current burn continues`;if(e<=0)return`now`;let t=e/864e5;if(t>=2)return`in ${Math.round(t)} days`;if(t>=1)return`in 1 day`;let n=e/36e5;if(n>=2)return`in ${Math.round(n)} hours`;if(n>=1)return`in 1 hour`;let r=Math.max(1,Math.round(e/6e4));return`in ${r} minute${r===1?``:`s`}`}function Ce(e){return Number.isFinite(e)?e>=10?`${e.toFixed(0)}×`:e>=1?`${e.toFixed(1)}×`:`${e.toFixed(2)}×`:`∞×`}function X(e){return e==null?`—`:e<=0?`exhausted`:Y(e).replace(/^in /,``)}function we(e){let{manifest:t,runs:n,gates:r,signals:i,clock:a,vault:o,channels:s,ai:l,diff:u,access:f,now:p}=e,m=e.architectureGraph===void 0?t?d(t):null:e.architectureGraph,h=ve(t),g=_e({manifest:t,runs:n,now:p}),_=le({manifest:t,ai:l,runs:n,now:p}),v=L({gatesAudit:r?.audit??{unguardedFlows:[],orphanPermissions:[],emptyRoles:[],unattachedGates:[]},signals:i,crons:a?.crons??[],vaultSecrets:o?.secrets??[],channelOutcomes:s?.outcomes??[],architectureGraph:m,diffChanges:u?.changes??[],aiVersions:l?.versions??[],accessHygiene:f?.hygiene??{unusedKeys:[],neverSignedInOperators:[],expiredInvitations:[]},now:p}),y=u?(()=>{let e=c(u);return{hasBaseline:e.hasBaseline,severity:e.severity,changeCount:e.changeCount,line:e.line,href:e.href}})():{hasBaseline:!1,severity:null,changeCount:0,line:`Manifest Diff unavailable`,href:`/diff`},b=j(n,p),x=h?null:ce(n);return{verdict:Se({hasDeclaredSlos:h,slos:g,costBudgets:_,findings:v}),slos:g,costBudgets:_,whatChanged:y,findings:v,golden:b,firstSloInvite:x,hasDeclaredSlos:h}}var Te=e(a(),1),Z=o();function Q(){let e=n({queryKey:[`console.manifest.get`],queryFn:async()=>{let e=await r.manifestGet();if(e.error)throw Error(e.error.code);return e.data.manifest}}),t=n({queryKey:[`console.runs.list`],queryFn:async()=>{let e=await r.runsList();if(e.error)throw Error(e.error.code);return e.data.runs.map(u)},refetchInterval:1e4}),i=n({queryKey:[`console.gates.list`],queryFn:async()=>{let e=await r.gatesList();if(e.error)throw Error(e.error.code);return e.data},refetchInterval:15e3}),a=n({queryKey:[`console.signals.list`],queryFn:async()=>{let e=await r.signalsList();if(e.error)throw Error(e.error.code);return e.data.signals},refetchInterval:1e4}),o=n({queryKey:[`console.clock.list`],queryFn:async()=>{let e=await r.clockList();if(e.error)throw Error(e.error.code);return e.data},refetchInterval:1e4}),c=n({queryKey:[`console.vault.list`],queryFn:async()=>{let e=await r.vaultList();if(e.error)throw Error(e.error.code);return e.data},refetchInterval:3e4}),l=n({queryKey:[`console.channel.list`],queryFn:async()=>{let e=await r.channelsList();if(e.error)throw Error(e.error.code);return e.data},refetchInterval:15e3}),d=n({queryKey:[`console.ai.list`],queryFn:async()=>{let e=await r.aiList();if(e.error)throw Error(e.error.code);return e.data},refetchInterval:15e3}),f=n({queryKey:[`console.diff.list`],queryFn:async()=>{let e=await r.diffList();if(e.error)throw Error(e.error.code);return e.data},refetchInterval:15e3}),p=n({queryKey:[`console.access.list`],queryFn:async()=>{let e=await r.accessList();if(e.error)throw Error(e.error.code);return e.data},refetchInterval:3e4}),m=(0,Te.useMemo)(()=>{let n=o.data?.now??Date.now();return we({manifest:e.data??null,runs:t.data??[],gates:i.data??null,signals:a.data??[],clock:o.data??null,vault:c.data??null,channels:l.data??null,ai:d.data??null,diff:f.data??null,access:p.data??null,now:n})},[e.data,t.data,i.data,a.data,o.data,c.data,l.data,d.data,f.data,p.data]),h=e.isLoading||t.isLoading||i.isLoading;return(0,Z.jsxs)(`div`,{className:`flex h-full min-h-0 flex-col overflow-y-auto`,children:[(0,Z.jsxs)(`header`,{className:`shrink-0 border-b border-[var(--oke-line)] px-6 py-5`,children:[(0,Z.jsx)(`p`,{className:`text-xs uppercase tracking-[0.2em] text-[var(--oke-muted)]`,children:`Overview`}),(0,Z.jsx)(`h1`,{className:`mt-1 text-xl font-semibold tracking-tight text-[var(--oke-fg)]`,children:`Is the system healthy right now?`}),(0,Z.jsx)(`p`,{role:`status`,"aria-live":`polite`,className:s(`mt-3 text-base leading-snug`,m.verdict.tone===`critical`&&`text-red-700`,m.verdict.tone===`warn`&&`text-amber-800`,m.verdict.tone===`ok`&&`text-[var(--oke-fg)]`,m.verdict.tone===`empty`&&`text-[var(--oke-muted)]`),children:h?`Loading panel projections…`:m.verdict.line})]}),(0,Z.jsxs)(`main`,{id:`overview-main`,className:`flex flex-col gap-8 px-6 py-6`,children:[!h&&!e.data?(0,Z.jsxs)(`p`,{className:`text-sm text-[var(--oke-muted)]`,children:[`No Manifest yet — save a Flow under`,` `,(0,Z.jsx)(`code`,{className:`font-mono text-[var(--oke-fg)]`,children:`src/`}),` and the Console will refresh.`]}):null,m.hasDeclaredSlos?(0,Z.jsx)($,{label:`Error budgets`,ariaLabel:`Error budgets`,items:m.slos.map(e=>({id:e.id,title:`${e.kind}:${e.name}`,meta:e.availability,burn:e.burnRate,exhaust:e.timeToExhaustionMs,badge:e.ceremonial?`CEREMONIAL`:null,remaining:e.remainingBudgetFraction}))}):null,(0,Z.jsx)($,{label:`Cost budgets`,ariaLabel:`Cost budgets`,empty:`No cost budgets declared.`,items:m.costBudgets.map(e=>({id:e.id,title:e.name,meta:`$${e.spent.toFixed(2)} / $${e.declaredBudget.toFixed(2)}`,burn:e.burnRate,exhaust:e.timeToExhaustionMs,badge:null,remaining:e.remainingFraction}))}),(0,Z.jsxs)(`section`,{"aria-label":`What changed`,className:`flex flex-col gap-2`,children:[(0,Z.jsx)(`h2`,{className:`text-sm font-medium text-[var(--oke-fg)]`,children:`What changed`}),(0,Z.jsx)(`p`,{className:`text-sm text-[var(--oke-muted)]`,children:(0,Z.jsx)(`a`,{href:m.whatChanged.href,className:`underline decoration-[var(--oke-line)] underline-offset-2 hover:text-[var(--oke-fg)]`,children:m.whatChanged.line})})]}),(0,Z.jsx)(Ee,{view:m}),(0,Z.jsx)(De,{view:m}),m.firstSloInvite?(0,Z.jsxs)(`section`,{"aria-label":`Declare first SLO`,className:`flex flex-col gap-2 border border-[var(--oke-line)] px-4 py-3`,children:[(0,Z.jsx)(`h2`,{className:`text-sm font-medium text-[var(--oke-fg)]`,children:`Declare a first objective`}),(0,Z.jsxs)(`p`,{className:`text-sm text-[var(--oke-muted)]`,children:[`Your busiest flow is`,` `,(0,Z.jsx)(`a`,{href:m.firstSloInvite.href,className:`font-mono text-[var(--oke-fg)] underline decoration-[var(--oke-line)] underline-offset-2`,children:m.firstSloInvite.busiestFlow}),` `,`(`,m.firstSloInvite.runCount.toLocaleString(`en-US`),` runs). Add`,` `,(0,Z.jsx)(`code`,{className:`font-mono text-[13px] text-[var(--oke-fg)]`,children:`slo: { availability: "99.9%" }`}),` `,`on that flow.`]})]}):null]})]})}function $(e){return(0,Z.jsxs)(`section`,{"aria-label":e.ariaLabel,className:`flex flex-col gap-3`,children:[(0,Z.jsx)(`h2`,{className:`text-sm font-medium text-[var(--oke-fg)]`,children:e.label}),e.items.length===0?(0,Z.jsx)(`p`,{className:`text-sm text-[var(--oke-muted)]`,children:e.empty??`None.`}):(0,Z.jsx)(`ul`,{className:`divide-y divide-[var(--oke-line)] border-y border-[var(--oke-line)]`,children:e.items.map(e=>(0,Z.jsxs)(`li`,{className:`flex min-h-10 flex-wrap items-center justify-between gap-3 py-2 text-sm`,children:[(0,Z.jsxs)(`div`,{className:`flex min-w-0 flex-col gap-0.5`,children:[(0,Z.jsx)(`span`,{className:`font-mono text-[13px] text-[var(--oke-fg)]`,children:e.title}),(0,Z.jsx)(`span`,{className:`text-[var(--oke-muted)]`,children:e.meta})]}),(0,Z.jsxs)(`div`,{className:`flex flex-wrap items-center gap-3 text-[var(--oke-muted)]`,children:[(0,Z.jsxs)(`span`,{children:[`burn `,(0,Z.jsx)(`span`,{className:`text-[var(--oke-fg)]`,children:Ce(e.burn)})]}),(0,Z.jsxs)(`span`,{children:[`exhausts`,` `,(0,Z.jsx)(`span`,{className:`text-[var(--oke-fg)]`,children:X(e.exhaust)})]}),(0,Z.jsx)(`span`,{"aria-hidden":!0,className:`inline-block h-1.5 w-16 overflow-hidden bg-[var(--oke-line)]`,title:`${Math.round(e.remaining*100)}% remaining`,children:(0,Z.jsx)(`span`,{className:`block h-full bg-[var(--oke-fg)]`,style:{width:`${Math.max(0,Math.min(100,e.remaining*100))}%`}})}),e.badge?(0,Z.jsx)(`span`,{role:`status`,className:`text-xs uppercase tracking-wider text-[var(--oke-muted)]`,children:e.badge}):null]})]},e.id))})]})}function Ee({view:e}){return(0,Z.jsxs)(`section`,{"aria-label":`Findings`,"aria-live":`polite`,className:`flex flex-col gap-3`,children:[(0,Z.jsx)(`h2`,{className:`text-sm font-medium text-[var(--oke-fg)]`,children:`Findings`}),e.findings.length===0?(0,Z.jsx)(`p`,{className:`text-sm text-[var(--oke-muted)]`,children:`No findings from other panels.`}):(0,Z.jsx)(`ol`,{className:`divide-y divide-[var(--oke-line)] border-y border-[var(--oke-line)]`,children:e.findings.map((e,t)=>(0,Z.jsx)(`li`,{className:`py-2 text-sm`,children:(0,Z.jsxs)(`a`,{href:e.href,className:`flex min-h-8 items-start gap-3 hover:text-[var(--oke-fg)]`,children:[(0,Z.jsxs)(`span`,{className:`w-5 shrink-0 text-[var(--oke-muted)]`,children:[t+1,`.`]}),(0,Z.jsxs)(`span`,{children:[(0,Z.jsx)(`span`,{className:`text-[var(--oke-fg)]`,children:e.title}),(0,Z.jsxs)(`span`,{className:`text-[var(--oke-muted)]`,children:[` · `,e.detail]}),(0,Z.jsx)(`span`,{className:`ml-2 text-xs uppercase tracking-wider text-[var(--oke-muted)]`,children:e.source})]})]})},e.id))})]})}function De({view:e}){return(0,Z.jsxs)(`section`,{"aria-label":`Golden signals`,className:`flex flex-col gap-3`,children:[(0,Z.jsx)(`h2`,{className:`text-sm font-medium text-[var(--oke-fg)]`,children:`Golden signals`}),(0,Z.jsxs)(`dl`,{className:`grid grid-cols-2 gap-4 sm:grid-cols-4`,children:[(0,Z.jsxs)(`div`,{children:[(0,Z.jsx)(`dt`,{className:`text-xs uppercase tracking-wider text-[var(--oke-muted)]`,children:`Latency p99`}),(0,Z.jsxs)(`dd`,{className:`mt-1 text-sm text-[var(--oke-fg)]`,children:[Math.round(e.golden.latencyP99Ms),` ms`]})]}),(0,Z.jsxs)(`div`,{children:[(0,Z.jsx)(`dt`,{className:`text-xs uppercase tracking-wider text-[var(--oke-muted)]`,children:`Traffic`}),(0,Z.jsxs)(`dd`,{className:`mt-1 text-sm text-[var(--oke-fg)]`,children:[e.golden.trafficPerMin.toFixed(1),` / min`]})]}),(0,Z.jsxs)(`div`,{children:[(0,Z.jsx)(`dt`,{className:`text-xs uppercase tracking-wider text-[var(--oke-muted)]`,children:`Errors`}),(0,Z.jsxs)(`dd`,{className:`mt-1 text-sm text-[var(--oke-fg)]`,children:[(e.golden.errorRate*100).toFixed(2),`%`]})]}),(0,Z.jsxs)(`div`,{children:[(0,Z.jsx)(`dt`,{className:`text-xs uppercase tracking-wider text-[var(--oke-muted)]`,children:`Saturation`}),(0,Z.jsxs)(`dd`,{className:`mt-1 text-sm text-[var(--oke-fg)]`,children:[(e.golden.saturation*100).toFixed(1),`%`]})]})]})]})}var Oe=t({OverviewPanel:()=>Q,default:()=>Q});export{ee as a,v as c,ne as i,y as l,se as n,_ as o,E as r,b as s,Oe as t};
@@ -1 +0,0 @@
1
- import{a as e,r as t,t as n}from"./rolldown-runtime-B0Z9INg1.js";import{B as r,C as i,D as a,I as o,J as s,Q as c,R as l,U as u,b as d,d as f,j as p,k as m,nt as h,o as g,q as _,tt as v,u as y,w as b,y as ee}from"./panel-access-ri1X9Otj.js";import{i as te}from"./panel-ai-DLHjRoJk.js";import{c as ne,l as x}from"./panel-architecture-DI3bQF3J.js";import{a as S,c as C,i as re,l as ie,n as ae,o as w,r as T,s as E}from"./panel-overview-DONDzBd2.js";function D(e){let t=new Map,n,r,i=e=>{e.next&&(e.prev?(e.prev.next=e.next,e.next.prev=e.prev,e.next=void 0,r&&(r.next=e,e.prev=r)):(e.next.prev=void 0,n=e.next,e.next=void 0,r&&(e.prev=r,r.next=e)),r=e)};return{get(e){let n=t.get(e);if(n)return i(n),n.value},set(a,o){if(t.size>=e&&n){let e=n;t.delete(e.key),e.next&&(n=e.next,e.next.prev=void 0),e===r&&(r=void 0)}let s=t.get(a);if(s)s.value=o,i(s);else{let e={key:a,value:o,prev:r};r&&(r.next=e),r=e,n||=e,t.set(a,e)}},clear(){t.clear(),n=void 0,r=void 0}}}var O=4,oe=5;function se(e){let t=e.indexOf(`{`);if(t===-1)return null;let n=e.indexOf(`}`,t);return n===-1||t+1>=e.length?null:[t,n]}function ce(e,t,n=new Uint16Array(6)){let r=e.indexOf(`/`,t),i=r===-1?e.length:r,a=e.substring(t,i);if(!a||!a.includes(`$`))return n[0]=0,n[1]=t,n[2]=t,n[3]=i,n[4]=i,n[5]=i,n;if(a===`$`){let r=e.length;return n[0]=2,n[1]=t,n[2]=t,n[3]=r,n[4]=r,n[5]=r,n}if(a.charCodeAt(0)===36)return n[0]=1,n[1]=t,n[2]=t+1,n[3]=i,n[4]=i,n[5]=i,n;let o=se(a);if(o){let[r,s]=o,c=a.charCodeAt(r+1);if(c===45){if(r+2<a.length&&a.charCodeAt(r+2)===36){let e=r+3,a=s;if(e<a)return n[0]=3,n[1]=t+r,n[2]=t+e,n[3]=t+a,n[4]=t+s+1,n[5]=i,n}}else if(c===36){let a=r+1,o=r+2;return o===s?(n[0]=2,n[1]=t+r,n[2]=t+a,n[3]=t+o,n[4]=t+s+1,n[5]=e.length,n):(n[0]=1,n[1]=t+r,n[2]=t+o,n[3]=t+s,n[4]=t+s+1,n[5]=i,n)}}return n[0]=0,n[1]=t,n[2]=t,n[3]=i,n[4]=i,n[5]=i,n}function k(e,t,n,r,i,a,o){o?.(n);let s=r;{let r=n.fullPath??n.from,o=r.length,c=n.options?.caseSensitive??e,l=n.options?.params?.parse??n.options?.parseParams;for(;s<o;){let e=ce(r,s,t),o,u=s,d=e[5];switch(s=d+1,a++,e[0]){case 0:{let t=r.substring(e[2],e[3]);if(c){let e=i.static?.get(t);if(e)o=e;else{i.static??=new Map;let e=j(n.fullPath??n.from);e.parent=i,e.depth=a,o=e,i.static.set(t,e)}}else{let e=t.toLowerCase(),r=i.staticInsensitive?.get(e);if(r)o=r;else{i.staticInsensitive??=new Map;let t=j(n.fullPath??n.from);t.parent=i,t.depth=a,o=t,i.staticInsensitive.set(e,t)}}break}case 1:{let t=r.substring(u,e[1]),s=r.substring(e[4],d),f=c&&!!(t||s),p=t?f?t:t.toLowerCase():void 0,m=s?f?s:s.toLowerCase():void 0,h=!l&&i.dynamic?.find(e=>!e.parse&&e.caseSensitive===f&&e.prefix===p&&e.suffix===m);if(h)o=h;else{let e=ue(1,n.fullPath??n.from,f,p,m);o=e,e.depth=a,e.parent=i,i.dynamic??=[],i.dynamic.push(e)}break}case 3:{let t=r.substring(u,e[1]),s=r.substring(e[4],d),f=c&&!!(t||s),p=t?f?t:t.toLowerCase():void 0,m=s?f?s:s.toLowerCase():void 0,h=!l&&i.optional?.find(e=>!e.parse&&e.caseSensitive===f&&e.prefix===p&&e.suffix===m);if(h)o=h;else{let e=ue(3,n.fullPath??n.from,f,p,m);o=e,e.parent=i,e.depth=a,i.optional??=[],i.optional.push(e)}break}case 2:{let t=r.substring(u,e[1]),s=r.substring(e[4],d),l=c&&!!(t||s),f=t?l?t:t.toLowerCase():void 0,p=s?l?s:s.toLowerCase():void 0,m=ue(2,n.fullPath??n.from,l,f,p);o=m,m.parent=i,m.depth=a,i.wildcard??=[],i.wildcard.push(m)}}i=o}if(l&&n.children&&!n.isRoot&&n.id&&n.id.charCodeAt(n.id.lastIndexOf(`/`)+1)===95){let e=j(n.fullPath??n.from);e.kind=oe,e.parent=i,a++,e.depth=a,i.pathless??=[],i.pathless.push(e),i=e}let u=(n.path||!n.children)&&!n.isRoot;if(u&&r.endsWith(`/`)){let e=j(n.fullPath??n.from);e.kind=O,e.parent=i,a++,e.depth=a,i.index=e,i=e}i.parse=l??null,i.priority=n.options?.params?.priority??0,u&&!i.route&&(i.route=n,i.fullPath=n.fullPath??n.from)}if(n.children)for(let r of n.children)k(e,t,r,s,i,a,o)}function le(e,t){if(e.parse&&!t.parse)return-1;if(!e.parse&&t.parse)return 1;if(e.parse&&t.parse&&(e.priority||t.priority))return t.priority-e.priority;if(e.prefix&&t.prefix&&e.prefix!==t.prefix){if(e.prefix.startsWith(t.prefix))return-1;if(t.prefix.startsWith(e.prefix))return 1}if(e.suffix&&t.suffix&&e.suffix!==t.suffix){if(e.suffix.endsWith(t.suffix))return-1;if(t.suffix.endsWith(e.suffix))return 1}return e.prefix&&!t.prefix?-1:!e.prefix&&t.prefix?1:e.suffix&&!t.suffix?-1:!e.suffix&&t.suffix?1:e.caseSensitive&&!t.caseSensitive?-1:!e.caseSensitive&&t.caseSensitive?1:0}function A(e){if(e.pathless)for(let t of e.pathless)A(t);if(e.static)for(let t of e.static.values())A(t);if(e.staticInsensitive)for(let t of e.staticInsensitive.values())A(t);if(e.dynamic?.length){e.dynamic.sort(le);for(let t of e.dynamic)A(t)}if(e.optional?.length){e.optional.sort(le);for(let t of e.optional)A(t)}if(e.wildcard?.length){e.wildcard.sort(le);for(let t of e.wildcard)A(t)}}function j(e){return{kind:0,depth:0,pathless:null,index:null,static:null,staticInsensitive:null,dynamic:null,optional:null,wildcard:null,route:null,fullPath:e,parent:null,parse:null,priority:0}}function ue(e,t,n,r,i){return{kind:e,depth:0,pathless:null,index:null,static:null,staticInsensitive:null,dynamic:null,optional:null,wildcard:null,route:null,fullPath:t,parent:null,parse:null,priority:0,caseSensitive:n,prefix:r,suffix:i}}function de(e,t){let n=j(`/`),r=new Uint16Array(6);for(let t of e)k(!1,r,t,1,n,0);A(n),t.masksTree=n,t.flatCache=D(1e3)}function fe(e,t){e||=`/`;let n=t.flatCache.get(e);if(n)return n;let r=F(e,t.masksTree);return t.flatCache.set(e,r),r}function pe(e,t,n,r,i){e||=`/`,r||=`/`;let a=t?`case\0${e}`:e,o=i.singleCache.get(a);return o||(o=j(`/`),k(t,new Uint16Array(6),{from:e},1,o,0),i.singleCache.set(a,o)),F(r,o,n)}function M(e,t,n=!1){let r=n?e:`nofuzz\0${e}`,i=t.matchCache.get(r);if(i!==void 0)return i;e||=`/`;let a;try{a=F(e,t.segmentTree,n)}catch(e){if(e instanceof URIError)a=null;else throw e}return a&&(a.branch=L(a.route)),t.matchCache.set(r,a),a}function N(e){return e===`/`?e:e.replace(/\/{1,}$/,``)}function P(e,t=!1,n){let r=j(e.fullPath),i=new Uint16Array(6),a={},o={},s=0;return k(t,i,e,1,r,0,e=>{if(n?.(e,s),e.id in a&&p(),a[e.id]=e,s!==0&&e.path){let t=N(e.fullPath);(!o[t]||e.fullPath.endsWith(`/`))&&(o[t]=e)}s++}),A(r),{processedTree:{segmentTree:r,singleCache:D(1e3),matchCache:D(1e3),flatCache:null,masksTree:null},routesById:a,routesByPath:o}}function F(e,t,n=!1){let r=e.split(`/`),i=z(e,r,t,n);if(!i)return null;let[a]=I(e,r,i);return{route:i.node.route,rawParams:a}}function I(e,t,n){let r=R(n.node),i=null,a=Object.create(null),o=n.extract?.part??0,s=n.extract?.node??0,c=n.extract?.path??0,l=n.extract?.segment??0;for(;s<r.length;o++,s++,c++,l++){let u=r[s];if(u.kind===O)break;if(u.kind===oe){l--,o--,c--;continue}let d=t[o],f=c;if(d&&(c+=d.length),u.kind===1){i??=n.node.fullPath.split(`/`);let e=i[l],t=u.prefix?.length??0;if(e.charCodeAt(t)===123){let n=u.suffix?.length??0,r=e.substring(t+2,e.length-n-1),i=d.substring(t,d.length-n);a[r]=decodeURIComponent(i)}else{let t=e.substring(1);a[t]=decodeURIComponent(d)}}else if(u.kind===3){if(n.skipped&1<<s){o--,c=f-1;continue}i??=n.node.fullPath.split(`/`);let e=i[l],t=u.prefix?.length??0,r=u.suffix?.length??0,p=e.substring(t+3,e.length-r-1),m=u.suffix||u.prefix?d.substring(t,d.length-r):d;m&&(a[p]=decodeURIComponent(m))}else if(u.kind===2){let t=u,n=e.substring(f+(t.prefix?.length??0),e.length-(t.suffix?.length??0)),r=decodeURIComponent(n);a[`*`]=r,a._splat=r;break}}return n.rawParams&&Object.assign(a,n.rawParams),[a,{part:o,node:s,path:c,segment:l}]}function L(e){let t=[e];for(;e.parentRoute;)e=e.parentRoute,t.push(e);return t.reverse(),t}function R(e){let t=Array(e.depth+1);do t[e.depth]=e,e=e.parent;while(e);return t}function z(e,t,n,r){if(e===`/`&&n.index)return{node:n.index,skipped:0};let i=!u(t),a=i&&e!==`/`,o=t.length-+!!i,s=[{node:n,index:1,skipped:0,depth:1,statics:0,dynamics:0,optionals:0}],c=null,l=null;for(;s.length;){let n=s.pop(),{node:i,index:u,skipped:d,depth:f,statics:p,dynamics:m,optionals:h}=n,{extract:g,rawParams:_}=n;if(i.kind===2&&i.route&&!U(l,n))continue;if(i.parse){if(!H(e,t,n))continue;_=n.rawParams,g=n.extract}r&&i.route&&i.kind!==O&&U(c,n)&&(c=n);let v=u===o;if(v&&(i.route&&(!a||i.kind===O||i.kind===2)&&U(l,n)&&(l=n),!i.optional&&!i.wildcard&&!i.index&&!i.pathless))continue;let y=v?void 0:t[u],b;if(v&&i.index){let n={node:i.index,index:u,skipped:d,depth:f+1,statics:p,dynamics:m,optionals:h,extract:g,rawParams:_},r=!0;if(i.index.parse&&(H(e,t,n)||(r=!1)),r){if(!m&&!h&&!d&&V(p,o))return n;U(l,n)&&(l=n)}}if(i.wildcard)for(let e=i.wildcard.length-1;e>=0;e--){let n=i.wildcard[e],{prefix:r,suffix:a}=n;if(!(r&&(v||!(n.caseSensitive?y:b??=y.toLowerCase()).startsWith(r)))){if(a){if(v)continue;let e=t.slice(u).join(`/`).slice(-a.length);if((n.caseSensitive?e:e.toLowerCase())!==a)continue}s.push({node:n,index:o,skipped:d,depth:f+1,statics:p,dynamics:m,optionals:h,extract:g,rawParams:_})}}if(i.optional){let e=d|1<<f,t=f+1;for(let n=i.optional.length-1;n>=0;n--){let r=i.optional[n];s.push({node:r,index:u,skipped:e,depth:t,statics:p,dynamics:m,optionals:h,extract:g,rawParams:_})}if(!v)for(let e=i.optional.length-1;e>=0;e--){let n=i.optional[e],{prefix:r,suffix:a}=n;if(r||a){let e=n.caseSensitive?y:b??=y.toLowerCase();if(r&&!e.startsWith(r)||a&&!e.endsWith(a))continue}s.push({node:n,index:u+1,skipped:d,depth:t,statics:p,dynamics:m,optionals:h+B(o,u),extract:g,rawParams:_})}}if(!v&&i.dynamic&&y)for(let e=i.dynamic.length-1;e>=0;e--){let t=i.dynamic[e],{prefix:n,suffix:r}=t;if(n||r){let e=t.caseSensitive?y:b??=y.toLowerCase();if(n&&!e.startsWith(n)||r&&!e.endsWith(r))continue}s.push({node:t,index:u+1,skipped:d,depth:f+1,statics:p,dynamics:m+B(o,u),optionals:h,extract:g,rawParams:_})}if(!v&&i.staticInsensitive){let e=i.staticInsensitive.get(b??=y.toLowerCase());e&&s.push({node:e,index:u+1,skipped:d,depth:f+1,statics:p+B(o,u),dynamics:m,optionals:h,extract:g,rawParams:_})}if(!v&&i.static){let e=i.static.get(y);e&&s.push({node:e,index:u+1,skipped:d,depth:f+1,statics:p+B(o,u),dynamics:m,optionals:h,extract:g,rawParams:_})}if(i.pathless){let e=f+1;for(let t=i.pathless.length-1;t>=0;t--){let n=i.pathless[t];s.push({node:n,index:u,skipped:d,depth:e,statics:p,dynamics:m,optionals:h,extract:g,rawParams:_})}}}if(l)return l;if(r&&c){let n=c.index;for(let e=0;e<c.index;e++)n+=t[e].length;let r=n===e.length?`/`:e.slice(n);return c.rawParams??=Object.create(null),c.rawParams[`**`]=decodeURIComponent(r),c}return null}function B(e,t){return 2**(e-t-1)}function V(e,t){return e===2**(t-1)-1}function H(e,t,n){let r,i;try{[r,i]=I(e,t,n)}catch{return null}if(n.rawParams=r,n.extract=i,!n.node.parse)return!0;try{if(n.node.parse(r)===!1)return null}catch{}return!0}function U(e,t){return!e||t.statics>e.statics||t.statics===e.statics&&(t.dynamics>e.dynamics||t.dynamics===e.dynamics&&(t.optionals>e.optionals||t.optionals===e.optionals&&((t.node.kind===O)>(e.node.kind===O)||t.node.kind===O==(e.node.kind===O)&&t.depth>e.depth)))}function me(e){return W(e.filter(e=>e!==void 0).join(`/`))}function W(e){return e.replace(/\/{2,}/g,`/`)}function G(e){return e===`/`?e:e.replace(/^\/{1,}/,``)}function K(e){let t=e.length;return t>1&&e[t-1]===`/`?e.replace(/\/{1,}$/,``):e}function he(e){return K(G(e))}function ge(e,t){return e?.endsWith(`/`)&&e!==`/`&&e!==`${t}/`?e.slice(0,-1):e}function _e(e,t,n){return ge(e,n)===ge(t,n)}function q({base:e,to:t,trailingSlash:n=`never`,cache:r}){let i=t.startsWith(`/`),a=!i&&t===`.`,o;if(r){o=i?t:a?e:e+`\0`+t;let n=r.get(o);if(n)return n}let s;if(a)s=e.split(`/`);else if(i)s=t.split(`/`);else{for(s=e.split(`/`);s.length>1&&u(s)===``;)s.pop();let n=t.split(`/`);for(let e=0,t=n.length;e<t;e++){let r=n[e];r===``?e?e===t-1&&s.push(r):s=[r]:r===`..`?s.pop():r===`.`||s.push(r)}}s.length>1&&(u(s)===``?n===`never`&&s.pop():n===`always`&&s.push(``));let c=W(s.join(`/`))||`/`;return o&&r&&r.set(o,c),c}function ve(e){let t=new Map(e.map(e=>[encodeURIComponent(e),e])),n=Array.from(t.keys()).map(e=>e.replace(/[.*+?^${}()|[\]\\]/g,`\\$&`)).join(`|`),r=new RegExp(n,`g`);return e=>e.replace(r,e=>t.get(e)??e)}function J(e,t,n){let r=t[e];return typeof r==`string`?e===`_splat`?/^[a-zA-Z0-9\-._~!/]*$/.test(r)?r:r.split(`/`).map(e=>be(e,n)).join(`/`):be(r,n):r}function ye({path:e,params:t,decoder:n,...r}){let i=!1,a=Object.create(null);if(!e||e===`/`)return{interpolatedPath:`/`,usedParams:a,isMissingParams:i};if(!e.includes(`$`))return{interpolatedPath:e,usedParams:a,isMissingParams:i};let o=e.length,s=0,c,l=``;for(;s<o;){let r=s;c=ce(e,r,c);let o=c[5];if(s=o+1,r===o)continue;let u=c[0];if(u===0){l+=`/`+e.substring(r,o);continue}if(u===2){let s=t._splat;a._splat=s,a[`*`]=s;let u=e.substring(r,c[1]),d=e.substring(c[4],o);if(!s){i=!0,(u||d)&&(l+=`/`+u+d);continue}let f=J(`_splat`,t,n);l+=`/`+u+f+d;continue}if(u===1){let s=e.substring(c[2],c[3]);!i&&!(s in t)&&(i=!0),a[s]=t[s];let u=e.substring(r,c[1]),d=e.substring(c[4],o),f=J(s,t,n)??`undefined`;l+=`/`+u+f+d;continue}if(u===3){let i=e.substring(c[2],c[3]),s=t[i];if(s==null)continue;a[i]=s;let u=e.substring(r,c[1]),d=e.substring(c[4],o),f=J(i,t,n)??``;l+=`/`+u+f+d;continue}}return e.endsWith(`/`)&&(l+=`/`),{usedParams:a,interpolatedPath:l||`/`,isMissingParams:i}}function be(e,t){let n=encodeURIComponent(e);return t?.(n)??n}var xe=`Error preloading route! ☝️`,Y=e(h(),1),X=v();function Se({children:e,fallback:t=null}){return Ce()?(0,X.jsx)(Y.Fragment,{children:e}):(0,X.jsx)(Y.Fragment,{children:t})}function Ce(){return Y.useSyncExternalStore(we,()=>!0,()=>!1)}function we(){return()=>{}}var Te=n((e=>{var t=h();function n(e){var t=`https://react.dev/errors/`+e;if(1<arguments.length){t+=`?args[]=`+encodeURIComponent(arguments[1]);for(var n=2;n<arguments.length;n++)t+=`&args[]=`+encodeURIComponent(arguments[n])}return`Minified React error #`+e+`; visit `+t+` for the full message or use the non-minified dev environment for full errors and additional helpful warnings.`}function r(){}var i={d:{f:r,r:function(){throw Error(n(522))},D:r,C:r,L:r,m:r,X:r,S:r,M:r},p:0,findDOMNode:null},a=Symbol.for(`react.portal`);function o(e,t,n){var r=3<arguments.length&&arguments[3]!==void 0?arguments[3]:null;return{$$typeof:a,key:r==null?null:``+r,children:e,containerInfo:t,implementation:n}}var s=t.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE;function c(e,t){if(e===`font`)return``;if(typeof t==`string`)return t===`use-credentials`?t:``}e.__DOM_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE=i,e.createPortal=function(e,t){var r=2<arguments.length&&arguments[2]!==void 0?arguments[2]:null;if(!t||t.nodeType!==1&&t.nodeType!==9&&t.nodeType!==11)throw Error(n(299));return o(e,t,null,r)},e.flushSync=function(e){var t=s.T,n=i.p;try{if(s.T=null,i.p=2,e)return e()}finally{s.T=t,i.p=n,i.d.f()}},e.preconnect=function(e,t){typeof e==`string`&&(t?(t=t.crossOrigin,t=typeof t==`string`?t===`use-credentials`?t:``:void 0):t=null,i.d.C(e,t))},e.prefetchDNS=function(e){typeof e==`string`&&i.d.D(e)},e.preinit=function(e,t){if(typeof e==`string`&&t&&typeof t.as==`string`){var n=t.as,r=c(n,t.crossOrigin),a=typeof t.integrity==`string`?t.integrity:void 0,o=typeof t.fetchPriority==`string`?t.fetchPriority:void 0;n===`style`?i.d.S(e,typeof t.precedence==`string`?t.precedence:void 0,{crossOrigin:r,integrity:a,fetchPriority:o}):n===`script`&&i.d.X(e,{crossOrigin:r,integrity:a,fetchPriority:o,nonce:typeof t.nonce==`string`?t.nonce:void 0})}},e.preinitModule=function(e,t){if(typeof e==`string`)if(typeof t==`object`&&t){if(t.as==null||t.as===`script`){var n=c(t.as,t.crossOrigin);i.d.M(e,{crossOrigin:n,integrity:typeof t.integrity==`string`?t.integrity:void 0,nonce:typeof t.nonce==`string`?t.nonce:void 0})}}else t??i.d.M(e)},e.preload=function(e,t){if(typeof e==`string`&&typeof t==`object`&&t&&typeof t.as==`string`){var n=t.as,r=c(n,t.crossOrigin);i.d.L(e,n,{crossOrigin:r,integrity:typeof t.integrity==`string`?t.integrity:void 0,nonce:typeof t.nonce==`string`?t.nonce:void 0,type:typeof t.type==`string`?t.type:void 0,fetchPriority:typeof t.fetchPriority==`string`?t.fetchPriority:void 0,referrerPolicy:typeof t.referrerPolicy==`string`?t.referrerPolicy:void 0,imageSrcSet:typeof t.imageSrcSet==`string`?t.imageSrcSet:void 0,imageSizes:typeof t.imageSizes==`string`?t.imageSizes:void 0,media:typeof t.media==`string`?t.media:void 0})}},e.preloadModule=function(e,t){if(typeof e==`string`)if(t){var n=c(t.as,t.crossOrigin);i.d.m(e,{as:typeof t.as==`string`&&t.as!==`script`?t.as:void 0,crossOrigin:n,integrity:typeof t.integrity==`string`?t.integrity:void 0})}else i.d.m(e)},e.requestFormReset=function(e){i.d.r(e)},e.unstable_batchedUpdates=function(e,t){return e(t)},e.useFormState=function(e,t,n){return s.H.useFormState(e,t,n)},e.useFormStatus=function(){return s.H.useHostTransitionStatus()},e.version=`19.2.8`})),Ee=n(((e,t)=>{function n(){if(!(typeof __REACT_DEVTOOLS_GLOBAL_HOOK__>`u`||typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE!=`function`))try{__REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE(n)}catch(e){console.error(e)}}n(),t.exports=Te()})),De=e(Ee(),1);function Oe(e,t){let n=m(),i=_(t),{activeProps:c,inactiveProps:u,activeOptions:d,to:f,preload:p,preloadDelay:h,preloadIntentProximity:g,hashScrollIntoView:v,replace:y,startTransition:b,resetScroll:ee,viewTransition:te,children:ne,target:x,disabled:S,style:C,className:re,onClick:ie,onBlur:ae,onFocus:w,onMouseEnter:T,onMouseLeave:E,onTouchStart:D,ignoreBlocker:O,params:oe,search:se,hash:ce,state:k,mask:le,reloadDocument:A,unsafeRelative:j,from:ue,_fromLocation:de,...fe}=e,pe=Ce(),M=Y.useMemo(()=>e,[n,e.from,e._fromLocation,e.hash,e.to,e.search,e.params,e.state,e.mask,e.unsafeRelative]),N=a(n.stores.location,e=>e,(e,t)=>e.href===t.href),P=Y.useMemo(()=>{let e={_fromLocation:N,...M};return n.buildLocation(e)},[n,N,M]),F=P.maskedLocation?P.maskedLocation.publicHref:P.publicHref,I=P.maskedLocation?P.maskedLocation.external:P.external,L=Y.useMemo(()=>Fe(F,I,n.history,S),[S,I,F,n.history]),R=Y.useMemo(()=>{if(L?.external)return r(L.href,n.protocolAllowlist)?void 0:L.href;if(!Ie(f)&&typeof f==`string`&&f.indexOf(`:`)!==-1)try{return new URL(f),r(f,n.protocolAllowlist)?void 0:f}catch{}},[f,L,n.protocolAllowlist]),z=Y.useMemo(()=>{if(R)return!1;if(d?.exact){if(!_e(N.pathname,P.pathname,n.basepath))return!1}else{let e=ge(N.pathname,n.basepath),t=ge(P.pathname,n.basepath);if(!(e.startsWith(t)&&(e.length===t.length||e[t.length]===`/`)))return!1}return(d?.includeSearch??!0)&&!o(N.search,P.search,{partial:!d?.exact,ignoreUndefined:!d?.explicitUndefined})?!1:!d?.includeHash||pe&&N.hash===P.hash},[d?.exact,d?.explicitUndefined,d?.includeHash,d?.includeSearch,N,R,pe,P.hash,P.pathname,P.search,n.basepath]),B=z?l(c,{})??Ae:ke,V=z?ke:l(u,{})??ke,H=[re,B.className,V.className].filter(Boolean).join(` `),U=(C||B.style||V.style)&&{...C,...B.style,...V.style},[me,W]=Y.useState(!1),G=Y.useRef(!1),K=e.reloadDocument||R?!1:p??n.options.defaultPreload,he=h??n.options.defaultPreloadDelay??0,q=Y.useCallback(()=>{n.preloadRoute({...M,_builtLocation:P}).catch(e=>{console.warn(e),console.warn(xe)})},[n,M,P]);s(i,Y.useCallback(e=>{e?.isIntersecting&&q()},[q]),Pe,{disabled:!!S||K!==`viewport`}),Y.useEffect(()=>{G.current||!S&&K===`render`&&(q(),G.current=!0)},[S,q,K]);let ve=e=>{let t=e.currentTarget.getAttribute(`target`),r=x===void 0?t:x;if(!S&&!Re(e)&&!e.defaultPrevented&&(!r||r===`_self`)&&e.button===0){e.preventDefault(),(0,De.flushSync)(()=>{W(!0)});let t=n.subscribe(`onResolved`,()=>{t(),W(!1)});n.navigate({...M,replace:y,resetScroll:ee,hashScrollIntoView:v,startTransition:b,viewTransition:te,ignoreBlocker:O})}};if(R)return{...fe,ref:i,href:R,...ne&&{children:ne},...x&&{target:x},...S&&{disabled:S},...C&&{style:C},...re&&{className:re},...ie&&{onClick:ie},...ae&&{onBlur:ae},...w&&{onFocus:w},...T&&{onMouseEnter:T},...E&&{onMouseLeave:E},...D&&{onTouchStart:D}};let J=e=>{if(S||K!==`intent`)return;if(!he){q();return}let t=e.currentTarget;if(Z.has(t))return;let n=setTimeout(()=>{Z.delete(t),q()},he);Z.set(t,n)},ye=e=>{S||K!==`intent`||q()},be=e=>{if(S||!K||!he)return;let t=e.currentTarget,n=Z.get(t);n&&(clearTimeout(n),Z.delete(t))};return{...fe,...B,...V,href:L?.href,ref:i,onClick:Q([ie,ve]),onBlur:Q([ae,be]),onFocus:Q([w,J]),onMouseEnter:Q([T,J]),onMouseLeave:Q([E,be]),onTouchStart:Q([D,ye]),disabled:!!S,target:x,...U&&{style:U},...H&&{className:H},...S&&je,...z&&Me,...pe&&me&&Ne}}var ke={},Ae={className:`active`},je={role:`link`,"aria-disabled":!0},Me={"data-status":`active`,"aria-current":`page`},Ne={"data-transitioning":`transitioning`},Z=new WeakMap,Pe={rootMargin:`100px`},Q=e=>t=>{for(let n of e)if(n){if(t.defaultPrevented)return;n(t)}};function Fe(e,t,n,r){if(!r)return t?{href:e,external:!0}:{href:n.createHref(e)||`/`,external:!1}}function Ie(e){if(typeof e!=`string`)return!1;let t=e.charCodeAt(0);return t===47?e.charCodeAt(1)!==47:t===46}var Le=Y.forwardRef((e,t)=>{let{_asChild:n,...r}=e,{type:i,...a}=Oe(r,t),o=typeof r.children==`function`?r.children({isActive:a[`data-status`]===`active`}):r.children;if(!n){let{disabled:e,...t}=a;return Y.createElement(`a`,t,o)}return Y.createElement(n,a,o)});function Re(e){return!!(e.metaKey||e.altKey||e.ctrlKey||e.shiftKey)}var ze=ee({where:d().optional(),group:d().optional(),run:d().optional(),durMin:te().optional(),durMax:te().optional()});function Be(e){let t=ze.safeParse(e??{});return t.success?t.data:ze.parse({})}function Ve(e){let t={};return e.where&&(t.where=e.where),e.group&&(t.group=e.group),e.run&&(t.run=e.run),e.durMin!==void 0&&(t.durMin=e.durMin),e.durMax!==void 0&&(t.durMax=e.durMax),t}function He(e){return w(e.where)}function Ue(e){return e.durMin===void 0||e.durMax===void 0?null:{minMs:Math.min(e.durMin,e.durMax),maxMs:Math.max(e.durMin,e.durMax)}}function We(e,t){let n=C(t);return{...e,where:n||void 0}}function Ge(e,t){return{...e,group:t??void 0}}function Ke(e,t){return{...e,run:t}}function qe(e){return{...e,run:void 0}}function Je(e,t){return t?{...e,durMin:t.minMs,durMax:t.maxMs}:{...e,durMin:void 0,durMax:void 0}}function Ye(e,t){let n=e.filter(t.select),r=e.filter(e=>!t.select(e));if(n.length===0||r.length===0)return[];let i=new Set(t.ignore??[`duration_ms`,`flow`]),a=t.minLift??.15,o=t.limit??10,s=new Set;for(let t of e)for(let e of Object.keys(t.dimensions))i.has(e)||s.add(e);let c=[];for(let e of s){let t=Xe(n,e),i=Xe(r,e),o=new Set([...t.keys(),...i.keys()]);for(let s of o){let o=(t.get(s)??0)/n.length,l=(i.get(s)??0)/r.length,u=o-l;u<a||c.push({dimension:e,value:s,outlierShare:o,baselineShare:l,lift:u,explanation:Ze(e,s,o,l)})}}return c.sort((e,t)=>t.lift-e.lift),c.slice(0,o)}function Xe(e,t){let n=new Map;for(let r of e){let e=r.dimensions[t];if(e==null)continue;let i=String(e);n.set(i,(n.get(i)??0)+1)}return n}function Ze(e,t,n,r){return`${Math.round(n*100)}% ${e}=${t} vs ${Math.round(r*100)}%`}function Qe(e,t){return Ye(e.map(x),{select:e=>e.durationMs>=t.minMs&&e.durationMs<=t.maxMs,minLift:.15,ignore:[`duration_ms`,`duration`,`flow`]})}function $e(e,t=20){if(e.length===0||t<1)return[];let n=1/0,r=-1/0;for(let t of e)n=Math.min(n,t.durationMs),r=Math.max(r,t.durationMs);if(!Number.isFinite(n)||!Number.isFinite(r))return[];if(n===r)return[{minMs:n,maxMs:r+1,count:e.length}];let i=(r-n)/t,a=[];for(let e=0;e<t;e++){let o=n+e*i,s=e===t-1?r+2**-52:n+(e+1)*i;a.push({minMs:o,maxMs:s,count:0})}for(let r of e){let e=Math.floor((r.durationMs-n)/i);e<0&&(e=0),e>=t&&(e=t-1);let o=a[e];a[e]={...o,count:o.count+1}}return a}function et(e,t){return e<=t?{minMs:e,maxMs:t}:{minMs:t,maxMs:e}}function $(e){return Number.isFinite(e)?e>=6e4?`${(e/6e4).toFixed(e%6e4==0?0:1)}m`:e>=1e3?`${(e/1e3).toFixed(e%1e3==0?0:2)}s`:`${Math.round(e)}ms`:`—`}function tt(e,t){let n=new Map(e.map(e=>[e.id,e])),r=n.get(t);if(!r)return t;let i=new Set;for(;r.parentId&&n.has(r.parentId)&&!i.has(r.id);)i.add(r.id),r=n.get(r.parentId);return r.id}function nt(e,t){let n=new Map(e.map(e=>[e.id,e]));if(!n.has(t))return 0;let r=new Map;for(let t of e){if(!t.parentId||!n.has(t.parentId))continue;let e=r.get(t.parentId)??[];e.push(t.id),r.set(t.parentId,e)}let i=0,a=[t],o=new Set;for(;a.length>0;){let e=a.pop();if(!o.has(e)){o.add(e),i+=1;for(let t of r.get(e)??[])a.push(t)}}return i}function rt(e,t){return nt(e,tt(e,t))>1}function it(){let e=b({from:`/runs`}),t=i({from:`/runs`}),n=e=>{t({search:Ve(e),replace:!0})},r=c({queryKey:[`console.runs.list`],queryFn:async()=>{let e=await f.runsList();if(e.error)throw Error(e.error.code);return e.data.runs.map(ne)},refetchInterval:5e3}),a=r.data??[],o=He(e),s=(0,Y.useMemo)(()=>S(a,o),[a,o]),l=Ue(e),u=(0,Y.useMemo)(()=>$e(s),[s]),d=Math.max(1,...u.map(e=>e.count)),p=(0,Y.useMemo)(()=>e.group?T(s,e.group):[],[s,e.group]),m=(0,Y.useMemo)(()=>l?Qe(s,l):[],[s,l]),h=(0,Y.useMemo)(()=>ae(a),[a]),_=a.find(t=>t.id===e.run);return(0,X.jsxs)(`div`,{className:`flex h-full min-h-0 flex-col`,children:[(0,X.jsxs)(`header`,{className:`flex shrink-0 flex-wrap items-end gap-4 border-b border-[var(--oke-line)] px-6 py-4`,children:[(0,X.jsxs)(`div`,{className:`flex flex-col gap-1`,children:[(0,X.jsx)(`p`,{className:`text-xs uppercase tracking-[0.2em] text-[var(--oke-muted)]`,children:`Runs`}),(0,X.jsx)(`h1`,{className:`text-xl font-semibold tracking-tight`,children:`Population analysis`}),(0,X.jsxs)(`p`,{className:`text-xs text-[var(--oke-muted)]`,children:[s.length,` of `,a.length,` runs · wide events, not log lines`]})]}),(0,X.jsx)(at,{search:e,dimensions:h,onChange:n}),(0,X.jsxs)(`label`,{className:`flex flex-col gap-1 text-sm`,children:[(0,X.jsx)(`span`,{className:`text-[var(--oke-muted)]`,children:`Group by`}),(0,X.jsxs)(`select`,{"aria-label":`Group by dimension`,className:`min-h-8 border border-[var(--oke-line)] bg-transparent px-2 text-sm`,value:e.group??``,onChange:t=>{let r=t.target.value;n(Ge(e,r||null))},children:[(0,X.jsx)(`option`,{value:``,children:`None`}),h.map(e=>(0,X.jsx)(`option`,{value:e,children:e},e))]})]})]}),(0,X.jsxs)(`div`,{className:`grid min-h-0 flex-1 grid-cols-1 lg:grid-cols-[minmax(0,1.2fr)_minmax(0,1fr)]`,children:[(0,X.jsxs)(`div`,{className:`min-h-0 overflow-auto border-r border-[var(--oke-line)] px-6 py-6`,children:[(0,X.jsxs)(`section`,{"aria-label":`Duration distribution`,className:`mb-8`,children:[(0,X.jsx)(`h2`,{className:`mb-2 text-sm font-medium`,children:`Duration distribution`}),(0,X.jsx)(`p`,{className:`mb-3 text-xs text-[var(--oke-muted)]`,children:`Range-select a region to explain outliers against the rest.`}),r.isLoading?(0,X.jsx)(`p`,{className:`text-sm text-[var(--oke-muted)]`,children:`Loading runs…`}):u.length===0?(0,X.jsx)(`p`,{className:`text-sm text-[var(--oke-muted)]`,children:`No runs match the current query.`}):(0,X.jsx)(ot,{buckets:u,maxBucket:d,range:l,onSelect:t=>n(Je(e,t))}),l?(0,X.jsxs)(`div`,{className:`mt-3 flex flex-wrap items-center gap-2`,children:[(0,X.jsxs)(`p`,{className:`text-xs text-[var(--oke-muted)]`,children:[`Selected `,$(l.minMs),` – `,$(l.maxMs)]}),(0,X.jsx)(g,{type:`button`,variant:`ghost`,onClick:()=>n(Je(e,null)),children:`Clear selection`})]}):null]}),l?(0,X.jsxs)(`section`,{"aria-label":`Outlier explanation`,className:`mb-8`,children:[(0,X.jsx)(`h2`,{className:`mb-2 text-sm font-medium`,children:`Outlier explanation`}),m.length===0?(0,X.jsx)(`p`,{className:`text-sm text-[var(--oke-muted)]`,children:`No dimension separates this region strongly enough.`}):(0,X.jsx)(`ol`,{className:`flex list-decimal flex-col gap-1 pl-5 text-sm`,children:m.map(e=>(0,X.jsx)(`li`,{children:e.explanation},`${e.dimension}:${e.value}`))})]}):null,e.group?(0,X.jsxs)(`section`,{"aria-label":`Group aggregates`,className:`mb-8`,children:[(0,X.jsxs)(`h2`,{className:`mb-2 text-sm font-medium`,children:[`Group by `,e.group]}),(0,X.jsxs)(`table`,{className:`w-full border-collapse text-left text-sm`,children:[(0,X.jsx)(`thead`,{children:(0,X.jsxs)(`tr`,{className:`border-b border-[var(--oke-line)] text-[var(--oke-muted)]`,children:[(0,X.jsx)(`th`,{scope:`col`,className:`py-2 pr-3 font-medium`,children:e.group}),(0,X.jsx)(`th`,{scope:`col`,className:`py-2 pr-3 font-medium`,children:`Count`}),(0,X.jsx)(`th`,{scope:`col`,className:`py-2 pr-3 font-medium`,children:`Avg`}),(0,X.jsx)(`th`,{scope:`col`,className:`py-2 pr-3 font-medium`,children:`p50`}),(0,X.jsx)(`th`,{scope:`col`,className:`py-2 pr-3 font-medium`,children:`p99`}),(0,X.jsx)(`th`,{scope:`col`,className:`py-2 font-medium`,children:`Cost`})]})}),(0,X.jsx)(`tbody`,{className:`divide-y divide-[var(--oke-line)]`,children:p.map(e=>(0,X.jsxs)(`tr`,{children:[(0,X.jsx)(`td`,{className:`py-2 pr-3 font-mono text-xs`,children:e.key}),(0,X.jsx)(`td`,{className:`py-2 pr-3`,children:e.count}),(0,X.jsx)(`td`,{className:`py-2 pr-3`,children:$(e.avgDurationMs)}),(0,X.jsx)(`td`,{className:`py-2 pr-3`,children:$(e.p50DurationMs)}),(0,X.jsx)(`td`,{className:`py-2 pr-3`,children:$(e.p99DurationMs)}),(0,X.jsx)(`td`,{className:`py-2`,children:e.sumCost>0?`$${e.sumCost.toFixed(3)}`:`—`})]},e.key))})]})]}):null,(0,X.jsxs)(`section`,{"aria-label":`Run list`,children:[(0,X.jsx)(`h2`,{className:`mb-2 text-sm font-medium`,children:`Runs`}),s.length===0?(0,X.jsx)(`p`,{className:`text-sm text-[var(--oke-muted)]`,children:`No runs yet. Invoke a flow or widen the query.`}):(0,X.jsx)(`ul`,{className:`divide-y divide-[var(--oke-line)]`,children:s.slice(0,200).map(t=>{let r=t.id===e.run;return(0,X.jsx)(`li`,{children:(0,X.jsxs)(`button`,{type:`button`,"aria-pressed":r,className:y(`flex w-full min-h-10 items-center justify-between gap-3 px-2 py-2 text-left text-sm`,r?`bg-[color-mix(in_oklab,var(--oke-fg)_6%,transparent)]`:`hover:bg-[color-mix(in_oklab,var(--oke-fg)_3%,transparent)]`),onClick:()=>n(Ke(e,t.id)),children:[(0,X.jsx)(`span`,{className:`font-medium`,children:t.flow}),(0,X.jsxs)(`span`,{className:`flex items-center gap-3 font-mono text-xs text-[var(--oke-muted)]`,children:[(0,X.jsx)(`span`,{children:t.cache}),t.error?(0,X.jsx)(`span`,{role:`status`,className:`text-[var(--oke-danger)]`,children:t.error}):(0,X.jsx)(`span`,{children:$(t.durationMs)})]})]})},t.id)})})]})]}),(0,X.jsx)(`section`,{"aria-label":`Run detail`,className:`min-h-0 overflow-auto px-6 py-6`,"aria-live":`polite`,children:_?(0,X.jsx)(st,{run:_,allRuns:a,onClose:()=>n(qe(e))}):(0,X.jsx)(`p`,{className:`text-sm text-[var(--oke-muted)]`,children:`Select a run to see its flat dimension record.`})})]})]})}function at({search:e,dimensions:t,onChange:n}){let r=He(e),i=[...new Set([...re,...t])].sort(),[a,o]=(0,Y.useState)(`cache`),[s,c]=(0,Y.useState)(`=`),[l,u]=(0,Y.useState)(`miss`),[d,f]=(0,Y.useState)(e.where??``);return(0,Y.useEffect)(()=>{f(e.where??``)},[e.where]),(0,X.jsxs)(`div`,{className:`flex min-w-[16rem] flex-1 flex-col gap-2`,children:[(0,X.jsxs)(`div`,{className:`flex flex-wrap items-end gap-2`,children:[(0,X.jsxs)(`label`,{className:`flex flex-col gap-1 text-sm`,children:[(0,X.jsx)(`span`,{className:`text-[var(--oke-muted)]`,children:`Dimension`}),(0,X.jsx)(`select`,{"aria-label":`Query dimension`,className:`min-h-8 border border-[var(--oke-line)] bg-transparent px-2 text-sm`,value:a,onChange:e=>o(e.target.value),children:i.map(e=>(0,X.jsx)(`option`,{value:e,children:e},e))})]}),(0,X.jsxs)(`label`,{className:`flex flex-col gap-1 text-sm`,children:[(0,X.jsx)(`span`,{className:`text-[var(--oke-muted)]`,children:`Op`}),(0,X.jsx)(`select`,{"aria-label":`Query operator`,className:`min-h-8 border border-[var(--oke-line)] bg-transparent px-2 text-sm`,value:s,onChange:e=>c(e.target.value),children:[`=`,`!=`,`>`,`<`,`>=`,`<=`].map(e=>(0,X.jsx)(`option`,{value:e,children:e},e))})]}),(0,X.jsxs)(`label`,{className:`flex min-w-[8rem] flex-1 flex-col gap-1 text-sm`,children:[(0,X.jsx)(`span`,{className:`text-[var(--oke-muted)]`,children:`Value`}),(0,X.jsx)(`input`,{"aria-label":`Query value`,className:`min-h-8 border border-[var(--oke-line)] bg-transparent px-2 text-sm`,value:l,onChange:e=>u(e.target.value)})]}),(0,X.jsx)(g,{type:`button`,variant:`ghost`,onClick:()=>{let t=w(`${a} ${s} ${l}`).clauses[0];if(!t)return;let i=We(e,ie(r,t));f(i.where??``),n(i)},children:`Add`})]}),r.clauses.length>0?(0,X.jsx)(`ul`,{"aria-label":`Active query clauses`,className:`flex flex-wrap gap-2`,children:r.clauses.map(t=>(0,X.jsx)(`li`,{children:(0,X.jsxs)(`button`,{type:`button`,className:`min-h-8 border border-[var(--oke-line)] px-2 font-mono text-xs`,onClick:()=>{let i=We(e,E(r,t.dimension));f(i.where??``),n(i)},children:[t.dimension,` `,t.op,` `,String(t.value),` ×`]})},t.dimension))}):null,(0,X.jsxs)(`label`,{className:`flex flex-col gap-1 text-sm`,children:[(0,X.jsx)(`span`,{className:`text-[var(--oke-muted)]`,children:`Dimension query expression`}),(0,X.jsx)(`input`,{"aria-label":`Dimension query expression`,className:`min-h-8 border border-[var(--oke-line)] bg-transparent px-2 font-mono text-sm`,placeholder:`flow = X AND cache = miss AND duration > 1s`,value:d,onChange:e=>f(e.target.value),onBlur:()=>{n(We(e,w(d)))},onKeyDown:t=>{t.key===`Enter`&&n(We(e,w(d)))}})]})]})}function ot({buckets:e,maxBucket:t,range:n,onSelect:r}){let[i,a]=(0,Y.useState)(null);return(0,X.jsx)(`div`,{role:`group`,"aria-label":`Duration histogram`,className:`flex h-40 items-end gap-px border border-[var(--oke-line)] bg-[color-mix(in_oklab,var(--oke-fg)_3%,transparent)] p-2`,onMouseLeave:()=>a(null),children:e.map((e,o)=>{let s=n!==null&&e.minMs<=n.maxMs&&e.maxMs>=n.minMs,c=Math.max(4,e.count/t*100);return(0,X.jsx)(`button`,{type:`button`,title:`${$(e.minMs)}–${$(e.maxMs)}: ${e.count}`,"aria-label":`Duration ${$(e.minMs)} to ${$(e.maxMs)}, ${e.count} runs`,"aria-pressed":s,className:y(`min-h-2 min-w-2 flex-1`,s?`bg-[var(--oke-accent)]`:`bg-[color-mix(in_oklab,var(--oke-fg)_35%,transparent)]`),style:{height:`${c}%`},onMouseDown:()=>a(e.minMs),onMouseEnter:()=>{i!==null&&r(et(i,e.maxMs))},onMouseUp:()=>{r(et(i===null?e.minMs:i,e.maxMs)),a(null)},onClick:()=>{i===null&&r(et(e.minMs,e.maxMs))}},o)})})}function st({run:e,allRuns:t,onClose:n}){let r=rt(t,e.id),i=[{label:`flow`,value:e.flow},{label:`unit`,value:e.unit??`—`},{label:`trigger`,value:e.trigger},{label:`plane`,value:e.plane},{label:`tenant`,value:e.tenant??`—`},{label:`principal`,value:e.principal??`—`},{label:`gates`,value:e.gates.length?e.gates.join(`, `):`—`},{label:`cache`,value:e.cache},{label:`replica`,value:e.replica==null?`—`:`${e.replica}${e.replicaLagMs==null?``:` · lag ${e.replicaLagMs}ms`}`},{label:`cost`,value:e.cost==null?`—`:`$${e.cost.toFixed(4)}`},{label:`promptVersion`,value:e.promptVersion==null?`—`:String(e.promptVersion)},{label:`buildVersion`,value:e.buildVersion??`—`},{label:`duration`,value:$(e.durationMs)},{label:`error`,value:e.error??`—`}];return(0,X.jsxs)(`div`,{className:`flex flex-col gap-6`,children:[(0,X.jsxs)(`div`,{className:`flex flex-wrap items-start justify-between gap-3`,children:[(0,X.jsxs)(`div`,{children:[(0,X.jsx)(`h2`,{className:`text-lg font-semibold`,children:e.flow}),(0,X.jsx)(`p`,{className:`font-mono text-xs text-[var(--oke-muted)]`,children:e.id})]}),(0,X.jsxs)(`div`,{className:`flex flex-wrap gap-2`,children:[r?(0,X.jsx)(Le,{to:`/traces`,search:{trace:tt(t,e.id),span:e.id},className:`inline-flex min-h-8 items-center border border-[var(--oke-line)] px-3 text-sm`,children:`Open in Traces`}):null,(0,X.jsx)(g,{type:`button`,variant:`ghost`,onClick:n,children:`Close`})]})]}),(0,X.jsx)(`dl`,{className:`grid grid-cols-[minmax(0,8rem)_1fr] gap-x-4 gap-y-2 text-sm`,children:i.map(t=>(0,X.jsxs)(`div`,{className:`contents`,children:[(0,X.jsx)(`dt`,{className:`text-[var(--oke-muted)]`,children:t.label}),(0,X.jsx)(`dd`,{className:y(`font-mono text-xs`,t.label===`error`&&e.error?`text-[var(--oke-danger)]`:``),children:t.value})]},t.label))}),(0,X.jsxs)(`div`,{children:[(0,X.jsx)(`h3`,{className:`mb-2 text-sm font-medium`,children:`Effects`}),e.effects.length===0?(0,X.jsx)(`p`,{className:`text-sm text-[var(--oke-muted)]`,children:`None`}):(0,X.jsx)(`ul`,{className:`divide-y divide-[var(--oke-line)] text-sm`,children:e.effects.map((e,t)=>(0,X.jsxs)(`li`,{className:`flex min-h-8 items-center justify-between gap-3 py-1`,children:[(0,X.jsxs)(`span`,{children:[e.kind,` `,(0,X.jsx)(`span`,{className:`font-mono text-xs`,children:e.resource})]}),(0,X.jsxs)(`span`,{className:`font-mono text-xs text-[var(--oke-muted)]`,children:[e.duration,`ms · `,e.reversibility]})]},`${e.kind}:${e.resource}:${t}`))})]}),(0,X.jsxs)(`details`,{className:`group`,children:[(0,X.jsxs)(`summary`,{className:`cursor-pointer text-sm font-medium`,children:[`fx.log (`,e.logs.length,`)`]}),e.logs.length===0?(0,X.jsx)(`p`,{className:`mt-2 text-sm text-[var(--oke-muted)]`,children:`No log lines`}):(0,X.jsx)(`ul`,{className:`mt-2 divide-y divide-[var(--oke-line)] font-mono text-xs`,children:e.logs.map((e,t)=>(0,X.jsxs)(`li`,{className:`py-2`,children:[(0,X.jsxs)(`span`,{className:`text-[var(--oke-muted)]`,children:[`[`,e.level,`]`]}),` `,e.message,e.data?(0,X.jsx)(`pre`,{className:`mt-1 whitespace-pre-wrap text-[var(--oke-muted)]`,children:JSON.stringify(e.data,null,2)}):null]},t))})]})]})}var ct=t({default:()=>it});export{pe as _,Se as a,D as b,ye as c,he as d,G as f,M as g,fe as h,Ee as i,me as l,L as m,Be as n,W as o,K as p,Le as r,ve as s,ct as t,q as u,de as v,P as y};