@tangle-network/agent-runtime 0.337.1 → 0.338.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 (112) hide show
  1. package/dist/{activation-DMehb166.d.ts → activation-CsbNax2X.d.ts} +92 -4
  2. package/dist/activation-kbkAuSmY.js +889 -0
  3. package/dist/activation-kbkAuSmY.js.map +1 -0
  4. package/dist/agent.d.ts +1 -1
  5. package/dist/agent.js +3 -6
  6. package/dist/agent.js.map +1 -1
  7. package/dist/{bundle-BPGjESee.js → bundle-DM60AI2B.js} +2 -2
  8. package/dist/{bundle-BPGjESee.js.map → bundle-DM60AI2B.js.map} +1 -1
  9. package/dist/candidate-execution/index.d.ts +2 -2
  10. package/dist/candidate-execution/index.js +4 -5
  11. package/dist/candidate-execution/index.js.map +1 -1
  12. package/dist/content-digest-sBTLujlK.js +9 -0
  13. package/dist/content-digest-sBTLujlK.js.map +1 -0
  14. package/dist/{delegate-aC14Cww3.js → delegate-Se1YZKMb.js} +2 -2
  15. package/dist/{delegate-aC14Cww3.js.map → delegate-Se1YZKMb.js.map} +1 -1
  16. package/dist/{coordination-driver-Dg9a6qsm.js → driver-control-acknowledgers-T2a1Ouay.js} +4514 -4440
  17. package/dist/driver-control-acknowledgers-T2a1Ouay.js.map +1 -0
  18. package/dist/durable.d.ts +1 -1
  19. package/dist/durable.js +223 -227
  20. package/dist/durable.js.map +1 -1
  21. package/dist/{graph-Cfx711ES.js → graph-CY0wH838.js} +65 -18
  22. package/dist/graph-CY0wH838.js.map +1 -0
  23. package/dist/{graph-registry-DAI6KNXB.js → graph-registry-By0tUj4S.js} +16 -15
  24. package/dist/graph-registry-By0tUj4S.js.map +1 -0
  25. package/dist/{improvement-cycle-DHKcb_YW.js → improve-CWGBT13K.js} +75 -1220
  26. package/dist/improve-CWGBT13K.js.map +1 -0
  27. package/dist/index.d.ts +6 -6
  28. package/dist/index.js +10 -13
  29. package/dist/index.js.map +1 -1
  30. package/dist/{integrations-DopfCC2a.d.ts → integrations-6xttbPi9.d.ts} +3 -3
  31. package/dist/integrations-dFi-ALk7.js.map +1 -1
  32. package/dist/intelligence.d.ts +7 -94
  33. package/dist/intelligence.js +505 -13
  34. package/dist/intelligence.js.map +1 -1
  35. package/dist/kernel.d.ts +2 -2
  36. package/dist/kernel.js +13 -12
  37. package/dist/{loop-runner-bin-B86AiPBf.d.ts → loop-runner-bin-CFnrAHpl.d.ts} +2 -2
  38. package/dist/{loop-runner-bin-BSKBNC38.js → loop-runner-bin-CdPlhy9g.js} +3 -3
  39. package/dist/{loop-runner-bin-BSKBNC38.js.map → loop-runner-bin-CdPlhy9g.js.map} +1 -1
  40. package/dist/loop-runner-bin.d.ts +1 -1
  41. package/dist/loop-runner-bin.js +1 -1
  42. package/dist/mcp/bin.js +3 -3
  43. package/dist/mcp/bin.js.map +1 -1
  44. package/dist/mcp/index.d.ts +7 -3
  45. package/dist/mcp/index.js +6 -8
  46. package/dist/mcp/index.js.map +1 -1
  47. package/dist/{openai-tools-DHO2QS1q.d.ts → openai-tools-zh2I_uD7.d.ts} +2 -2
  48. package/dist/platform.d.ts +7 -2
  49. package/dist/platform.js +16 -8
  50. package/dist/platform.js.map +1 -1
  51. package/dist/{prepare-CER-ZkPp.js → prepare-Bt0IouPq.js} +1241 -586
  52. package/dist/prepare-Bt0IouPq.js.map +1 -0
  53. package/dist/{profile-gNUsHNIJ.js → profile-Do-5xO_D.js} +89 -3
  54. package/dist/profile-Do-5xO_D.js.map +1 -0
  55. package/dist/profiles.d.ts +1 -1
  56. package/dist/profiles.js +1 -3
  57. package/dist/profiles.js.map +1 -1
  58. package/dist/{protected-model-port-BhpQRTw-.d.ts → protected-model-port-DGxQ8_YM.d.ts} +3 -3
  59. package/dist/{provision-supervisor-72YFf-i_.js → provision-supervisor-0jMufp4h.js} +12 -9
  60. package/dist/provision-supervisor-0jMufp4h.js.map +1 -0
  61. package/dist/record-value-B6bwJxLa.js +12 -0
  62. package/dist/record-value-B6bwJxLa.js.map +1 -0
  63. package/dist/{run-layout-Cu8H7aeh.js → run-cancellation-BoW5Sg9Y.js} +174 -95
  64. package/dist/run-cancellation-BoW5Sg9Y.js.map +1 -0
  65. package/dist/{runtime-qFLOq1R9.js → runtime-D37zRSs7.js} +432 -684
  66. package/dist/runtime-D37zRSs7.js.map +1 -0
  67. package/dist/{sandbox-profile-compat-QTkLe1Z6.js → sandbox-profile-compat-xSoVtdWw.js} +690 -697
  68. package/dist/sandbox-profile-compat-xSoVtdWw.js.map +1 -0
  69. package/dist/search-executor-DmgUm5p7.js +1916 -0
  70. package/dist/search-executor-DmgUm5p7.js.map +1 -0
  71. package/dist/{server-_FldJ9Cl.js → server-DQHJszfk.js} +4 -4
  72. package/dist/server-DQHJszfk.js.map +1 -0
  73. package/dist/{search-executor-CGxvizHh.js → structural-rollout-DAvIE8mw.js} +2262 -3984
  74. package/dist/structural-rollout-DAvIE8mw.js.map +1 -0
  75. package/dist/{supervise-H4BTN6uA.js → supervise-WuPAwfPh.js} +7793 -5338
  76. package/dist/supervise-WuPAwfPh.js.map +1 -0
  77. package/dist/{supervisor-C27ne4yv.js → supervisor-CPG1I9UN.js} +27379 -27899
  78. package/dist/supervisor-CPG1I9UN.js.map +1 -0
  79. package/dist/testing.d.ts +226 -1
  80. package/dist/testing.js +13 -14
  81. package/dist/testing.js.map +1 -1
  82. package/dist/{top-app-BaMw1W2z.js → top-app-C55Wa7uy.js} +339 -337
  83. package/dist/top-app-C55Wa7uy.js.map +1 -0
  84. package/dist/tui/bin.js +1 -1
  85. package/dist/tui/index.d.ts +17 -15
  86. package/dist/tui/index.js +2 -2
  87. package/dist/{types-CupCBY-j.d.ts → types-CrNWif8-.d.ts} +17655 -17406
  88. package/dist/{workspace-streams-JLjh5DC6.d.ts → workspace-streams-BZZds1Fw.d.ts} +18 -16
  89. package/package.json +4 -4
  90. package/skills/agent-graphs/SKILL.md +10 -3
  91. package/skills/agent-graphs/references/authoring.md +17 -0
  92. package/skills/profile-authoring/SKILL.md +3 -3
  93. package/skills/supervise/SKILL.md +2 -2
  94. package/dist/activation-BgWVlVu2.js +0 -234
  95. package/dist/activation-BgWVlVu2.js.map +0 -1
  96. package/dist/coordination-driver-Dg9a6qsm.js.map +0 -1
  97. package/dist/graph-Cfx711ES.js.map +0 -1
  98. package/dist/graph-registry-DAI6KNXB.js.map +0 -1
  99. package/dist/improvement-cycle-DHKcb_YW.js.map +0 -1
  100. package/dist/prepare-CER-ZkPp.js.map +0 -1
  101. package/dist/profile-gNUsHNIJ.js.map +0 -1
  102. package/dist/protected-model-port-BuRsviSL.js +0 -766
  103. package/dist/protected-model-port-BuRsviSL.js.map +0 -1
  104. package/dist/provision-supervisor-72YFf-i_.js.map +0 -1
  105. package/dist/run-layout-Cu8H7aeh.js.map +0 -1
  106. package/dist/runtime-qFLOq1R9.js.map +0 -1
  107. package/dist/sandbox-profile-compat-QTkLe1Z6.js.map +0 -1
  108. package/dist/search-executor-CGxvizHh.js.map +0 -1
  109. package/dist/server-_FldJ9Cl.js.map +0 -1
  110. package/dist/supervise-H4BTN6uA.js.map +0 -1
  111. package/dist/supervisor-C27ne4yv.js.map +0 -1
  112. package/dist/top-app-BaMw1W2z.js.map +0 -1
@@ -1,12 +1,12 @@
1
- import { _ as supervisorWorkersDir, a as legacySupervisorRunsRoot, g as supervisorRunsRoot, j as writeWorkerSteer, m as safeWorkerFile, n as cancelWorker, t as cancelRun } from "./run-layout-Cu8H7aeh.js";
1
+ import { N as writeWorkerSteer, _ as safeWorkerFile, b as supervisorWorkersDir, f as legacySupervisorRunsRoot, l as cancelWorker, n as cancelRun, y as supervisorRunsRoot } from "./run-cancellation-BoW5Sg9Y.js";
2
2
  import { randomUUID } from "node:crypto";
3
3
  import { existsSync, readFileSync, readdirSync, statSync } from "node:fs";
4
4
  import { basename, join, resolve } from "node:path";
5
5
  import { emitKeypressEvents } from "node:readline";
6
- //#region src/tui/top-model.ts
6
+ //#region src/tui/top-snapshot.ts
7
7
  /**
8
- * The read side of the supervisor-run TUI: turn the on-disk run layout into one `TopSnapshot`, and
9
- * render that snapshot to an ANSI frame.
8
+ * The snapshot reader for the supervisor-run TUI: turn the on-disk run layout into a `TopSnapshot`.
9
+ * ANSI frame presentation lives in `./top-frame`; this module owns reading and projection.
10
10
  *
11
11
  * This module never derives a run path itself. Every directory and per-worker file it reads comes
12
12
  * from `../runtime/supervise/run-layout` — the same module the writers use — so the reader cannot
@@ -29,20 +29,6 @@ const emptySpend = {
29
29
  usd: 0,
30
30
  ms: 0
31
31
  };
32
- const ansiPattern = /\x1b\[[0-9;?]*[ -/]*[@-~]/g;
33
- const colors = {
34
- reset: "\x1B[0m",
35
- dim: "\x1B[2m",
36
- bold: "\x1B[1m",
37
- red: "\x1B[31m",
38
- green: "\x1B[32m",
39
- yellow: "\x1B[33m",
40
- blue: "\x1B[34m",
41
- magenta: "\x1B[35m",
42
- cyan: "\x1B[36m",
43
- white: "\x1B[37m",
44
- inverse: "\x1B[7m"
45
- };
46
32
  /**
47
33
  * Read every supervisor run under one workspace into a single point-in-time snapshot.
48
34
  *
@@ -228,113 +214,6 @@ function buildSupervisorView(state, stateDir, events, progressTail, now, workerE
228
214
  totals
229
215
  };
230
216
  }
231
- /** Render one snapshot to an ANSI frame. Use this when nothing needs to be clickable. */
232
- function renderTopFrame(snapshot, options = {}) {
233
- return renderTopFrameWithLayout(snapshot, options).frame;
234
- }
235
- /**
236
- * Render one snapshot, returning the frame together with the row→entity map a mouse click resolves
237
- * against. The layout is the only thing that knows which row is which run or worker, so emitting it
238
- * alongside the text is what keeps click handling out of the renderer.
239
- */
240
- function renderTopFrameWithLayout(snapshot, options = {}) {
241
- const width = Math.max(88, options.width ?? 128);
242
- const height = Math.max(24, options.height ?? 42);
243
- const color = options.color ?? false;
244
- const focus = options.focus ?? "supervisors";
245
- const mode = options.mode ?? "overview";
246
- const selectedSupervisor = selectSupervisor(snapshot, options.selectedSupervisorId);
247
- const selectedWorker = selectedSupervisor ? selectWorker(selectedSupervisor, options.selectedWorkerId) : void 0;
248
- const targets = [];
249
- const lines = [];
250
- const push = (line = "", target) => {
251
- if (lines.length >= height) return;
252
- if (target) targets.push({
253
- row: lines.length,
254
- ...target
255
- });
256
- lines.push(fitAnsi(line, width));
257
- };
258
- const aggregate = aggregateSnapshot(snapshot);
259
- push(`${paint("SUPERVISOR TOP", "bold", color)} ${paint(snapshot.root, "dim", color)} runs ${aggregate.supervisors} workers ${aggregate.workers} live ${aggregate.running} done ${aggregate.done} down ${aggregate.down} ${formatMoney(aggregate.usd)} tok ${formatTokens(aggregate.tokensInput)}/${formatTokens(aggregate.tokensOutput)}`);
260
- push(`${paint("keys", "dim", color)} up/down select left/right run tab focus enter detail o overview l log s steer c cancel mouse q quit`);
261
- if (options.notice) push(paint(options.notice, "yellow", color));
262
- if (snapshot.completeness === "partial") push(paint(`partial snapshot: ${snapshot.diagnostics.length} source${snapshot.diagnostics.length === 1 ? "" : "s"} skipped or truncated; runs loaded ${snapshot.loaded}/${snapshot.discovered}`, "yellow", color));
263
- if (options.steerInput?.active) push(renderSteerInput(options.steerInput, width, color));
264
- push(rule(width, color));
265
- if (snapshot.supervisors.length === 0) {
266
- if (snapshot.discovered > 0) {
267
- push(paint("NO READABLE SUPERVISORS", "yellow", color));
268
- push(`${snapshot.discovered} run director${snapshot.discovered === 1 ? "y" : "ies"} found under ${supervisorRunsRoot(snapshot.root)}, none readable`);
269
- } else {
270
- push(paint("NO SUPERVISORS", "yellow", color));
271
- push(`No run state under ${supervisorRunsRoot(snapshot.root)}`);
272
- }
273
- push(`A run appears here once its driver writes state.json; re-point with: agent-runtime-top <root>`);
274
- return {
275
- frame: `${lines.join("\n")}\n`,
276
- targets
277
- };
278
- }
279
- push(sectionTitle("SUPERVISORS", focus === "supervisors", color));
280
- push(` id status workers spend tok in/out latency task`);
281
- for (const supervisor of snapshot.supervisors.slice(0, 9)) {
282
- const selected = supervisor.id === selectedSupervisor?.id;
283
- const status = statusText(supervisor.status, color);
284
- const pointer = selected ? paint(">", "cyan", color) : " ";
285
- const rowFocus = selected && focus === "supervisors" ? "inverse" : void 0;
286
- const workerSummary = `${supervisor.totals.running}/${supervisor.totals.workers} live`;
287
- const task = compact(supervisor.task, 34);
288
- const line = `${pointer} ${pad(supervisor.id, 21)} ${pad(status, 12)} ${pad(workerSummary, 13)} ${pad(formatMoney(supervisor.totals.usd), 12)} ${pad(`${formatTokens(supervisor.totals.tokensInput)}/${formatTokens(supervisor.totals.tokensOutput)}`, 16)} ${pad(formatDuration(supervisor.totals.latencyMs), 12)} ${task}`;
289
- push(rowFocus ? paint(line, rowFocus, color) : line, {
290
- kind: "supervisor",
291
- id: supervisor.id
292
- });
293
- }
294
- if (!selectedSupervisor) return {
295
- frame: `${lines.join("\n")}\n`,
296
- targets
297
- };
298
- push();
299
- push(sectionTitle(`WORKERS ${selectedSupervisor.id}`, focus === "workers", color));
300
- push(` id state runtime latency cost tok in/out score detail`);
301
- for (const worker of selectedSupervisor.workers.slice(0, 12)) {
302
- const selected = worker.id === selectedWorker?.id;
303
- const pointer = selected ? paint(">", "cyan", color) : " ";
304
- const rowFocus = selected && focus === "workers" ? "inverse" : void 0;
305
- const score = worker.verdict ?? (worker.status === "done" ? "done" : worker.status);
306
- const detail = worker.reason ?? worker.outRef ?? worker.parent ?? "";
307
- const spend = totalSpend(worker);
308
- const line = `${pointer} ${pad(worker.label, 12)} ${pad(statusText(worker.status, color), 12)} ${pad(worker.runtime ?? "-", 10)} ${pad(formatDuration(worker.latencyMs), 12)} ${pad(formatMoney(spend.usd), 11)} ${pad(`${formatTokens(spend.tokensInput)}/${formatTokens(spend.tokensOutput)}`, 16)} ${pad(compact(score, 9), 10)} ${compact(detail, 30)}`;
309
- push(rowFocus ? paint(line, rowFocus, color) : line, {
310
- kind: "worker",
311
- id: worker.id,
312
- supervisorId: selectedSupervisor.id
313
- });
314
- }
315
- if (selectedSupervisor.workers.length === 0) push(" no workers spawned yet");
316
- push();
317
- push(sectionTitle("OBSERVABILITY", false, color));
318
- for (const line of renderStatusBars(selectedSupervisor, width, color)) push(line);
319
- push();
320
- for (const line of renderCostBars(selectedSupervisor, width, color)) push(line);
321
- push();
322
- for (const line of renderTokenBars(selectedSupervisor, width, color)) push(line);
323
- push();
324
- for (const line of renderLatencyHistogram(selectedSupervisor, width, color)) push(line);
325
- push();
326
- if (mode === "log") {
327
- push(sectionTitle("JOURNAL TAIL", false, color));
328
- for (const line of renderJournalTail(selectedSupervisor, width, color)) push(line);
329
- } else {
330
- push(sectionTitle(mode === "detail" ? "DETAIL" : "RUN SUMMARY", false, color));
331
- for (const line of renderDetail(selectedSupervisor, selectedWorker, mode, width, color)) push(line);
332
- }
333
- return {
334
- frame: `${lines.join("\n")}\n`,
335
- targets
336
- };
337
- }
338
217
  function ensureWorker(workers, id, label) {
339
218
  const existing = workers.get(id);
340
219
  if (existing) return existing;
@@ -476,78 +355,344 @@ function percentile(sorted, p) {
476
355
  if (sorted.length === 0) return 0;
477
356
  return sorted[Math.min(sorted.length - 1, Math.max(0, Math.ceil(sorted.length * p) - 1))] ?? 0;
478
357
  }
479
- function renderStatusBars(supervisor, width, color) {
480
- const total = Math.max(1, supervisor.totals.workers);
481
- const barWidth = Math.max(12, Math.min(28, width - 58));
482
- return [`status ${pad("running", 9)} ${bar(supervisor.totals.running, total, barWidth, "#", color, "yellow")} ${supervisor.totals.running} ${pad("done", 5)} ${bar(supervisor.totals.done, total, barWidth, "#", color, "green")} ${supervisor.totals.done} ${pad("down", 5)} ${bar(supervisor.totals.down, total, barWidth, "#", color, "red")} ${supervisor.totals.down}`];
358
+ /**
359
+ * Read one source file under a run directory. An absent file is not a defect on its own — the
360
+ * writer may not have reached it yet — so it reads as `undefined` with no diagnostic; only a
361
+ * failed read raises one. `path` stays run-relative and never carries file contents.
362
+ */
363
+ function readSourceFile(file, source, path) {
364
+ if (!existsSync(file)) return {
365
+ value: void 0,
366
+ diagnostics: []
367
+ };
368
+ try {
369
+ return {
370
+ value: readFileSync(file, "utf8"),
371
+ diagnostics: []
372
+ };
373
+ } catch {
374
+ return {
375
+ value: void 0,
376
+ diagnostics: [{
377
+ source,
378
+ path,
379
+ reason: "unreadable"
380
+ }]
381
+ };
382
+ }
483
383
  }
484
- function renderCostBars(supervisor, width, color) {
485
- const workers = supervisor.workers.map((worker) => ({
486
- worker,
487
- spend: totalSpend(worker)
488
- })).sort((a, b) => b.spend.usd - a.spend.usd).slice(0, 6);
489
- const maxUsd = Math.max(1e-6, ...workers.map((row) => row.spend.usd), supervisor.driverSpend.usd);
490
- const out = [`cost total ${formatMoney(supervisor.totals.usd)} driver ${formatMoney(supervisor.driverSpend.usd)}`];
491
- const barWidth = Math.max(18, Math.min(46, width - 38));
492
- for (const row of workers) out.push(` ${pad(row.worker.label, 12)} ${bar(row.spend.usd, maxUsd, barWidth, "$", color, "magenta")} ${formatMoney(row.spend.usd)}`);
493
- if (workers.length === 0) out.push(" no worker cost yet");
494
- return out;
384
+ function tailLines(raw, maxLines) {
385
+ if (raw === void 0) return [];
386
+ return raw.trim().split("\n").filter(Boolean).slice(-maxLines);
495
387
  }
496
- function renderTokenBars(supervisor, width, color) {
497
- const rows = supervisor.workers.map((worker) => ({
498
- worker,
499
- spend: totalSpend(worker),
500
- total: totalSpend(worker).tokensInput + totalSpend(worker).tokensOutput
501
- })).sort((a, b) => b.total - a.total).slice(0, 6);
502
- const maxTokens = Math.max(1, ...rows.map((row) => row.total), supervisor.driverSpend.tokensInput + supervisor.driverSpend.tokensOutput);
503
- const out = [`tokens total in ${formatTokens(supervisor.totals.tokensInput)} / out ${formatTokens(supervisor.totals.tokensOutput)} driver ${formatTokens(supervisor.driverSpend.tokensInput)}/${formatTokens(supervisor.driverSpend.tokensOutput)}`];
504
- const barWidth = Math.max(18, Math.min(46, width - 44));
505
- for (const row of rows) out.push(` ${pad(row.worker.label, 12)} ${stackedTokenBar(row.spend.tokensInput, row.spend.tokensOutput, maxTokens, barWidth, color)} ${formatTokens(row.spend.tokensInput)}/${formatTokens(row.spend.tokensOutput)}`);
506
- if (rows.length === 0) out.push(" no worker tokens yet");
507
- return out;
388
+ function readProgressTail(dir, maxLines) {
389
+ const path = "progress.ndjson";
390
+ const read = readSourceFile(join(dir, path), "progress", path);
391
+ return {
392
+ value: tailLines(read.value, maxLines),
393
+ diagnostics: read.diagnostics
394
+ };
508
395
  }
509
- function renderLatencyHistogram(supervisor, width, color) {
510
- const values = supervisor.workers.map((worker) => worker.latencyMs).filter((value) => value > 0);
511
- const summary = supervisor.totals.workerLatency;
512
- const out = [`latency n=${summary.n} min ${formatDuration(summary.min)} p50 ${formatDuration(summary.median)} p90 ${formatDuration(summary.p90)} max ${formatDuration(summary.max)}`];
513
- if (values.length === 0) {
514
- out.push(" no latency samples yet");
515
- return out;
396
+ function readWorkerEventTails(dir, maxLines) {
397
+ const out = /* @__PURE__ */ new Map();
398
+ if (!existsSync(dir)) return {
399
+ value: out,
400
+ diagnostics: []
401
+ };
402
+ const workersDir = basename(dir);
403
+ let entries;
404
+ try {
405
+ entries = readdirSync(dir);
406
+ } catch {
407
+ return {
408
+ value: out,
409
+ diagnostics: [{
410
+ source: "worker-tail",
411
+ path: workersDir,
412
+ reason: "unreadable"
413
+ }]
414
+ };
516
415
  }
517
- const bins = histogram(values, 6);
518
- const maxCount = Math.max(1, ...bins.map((bin) => bin.count));
519
- const barWidth = Math.max(18, Math.min(48, width - 34));
520
- for (const bin of bins) out.push(` ${pad(`${formatDuration(bin.min)}-${formatDuration(bin.max)}`, 15)} ${bar(bin.count, maxCount, barWidth, "#", color, "blue")} ${bin.count}`);
521
- return out;
522
- }
523
- function renderDetail(supervisor, worker, mode, width, color) {
524
- if (mode === "detail" && worker) {
525
- const spend = totalSpend(worker);
526
- return [
527
- `worker ${paint(worker.label, "bold", color)} (${worker.id}) ${statusText(worker.status, color)} latency ${formatDuration(worker.latencyMs)}`,
528
- `tokens in/out ${formatTokens(spend.tokensInput)}/${formatTokens(spend.tokensOutput)} cost ${formatMoney(spend.usd)} iterations ${spend.iterations}`,
529
- `parent ${worker.parent ?? "-"} runtime ${worker.runtime ?? "-"} out ${worker.outRef ?? "-"}${worker.infra ? " infra" : ""}`,
530
- `events ${compact(worker.eventFile ?? "-", width - 8)}`,
531
- ...worker.reason ? [`reason ${compact(worker.reason, width - 7)}`] : [],
532
- ...renderWorkerTail(worker, width, color)
533
- ];
416
+ const diagnostics = [];
417
+ for (const entry of entries) {
418
+ if (!entry.endsWith(".ndjson") || entry.endsWith(".inbox.ndjson")) continue;
419
+ const file = join(dir, entry);
420
+ const read = readSourceFile(file, "worker-tail", join(workersDir, entry));
421
+ diagnostics.push(...read.diagnostics);
422
+ const lines = tailLines(read.value, maxLines);
423
+ out.set(entry.slice(0, -7), {
424
+ file,
425
+ lines
426
+ });
534
427
  }
535
- const caps = [
536
- supervisor.maxSandboxes !== void 0 ? `boxes ${supervisor.maxSandboxes}` : void 0,
537
- supervisor.maxUsd !== void 0 ? `max ${formatMoney(supervisor.maxUsd)}` : void 0,
538
- supervisor.maxDepth !== void 0 ? `depth ${supervisor.maxDepth}` : void 0,
539
- supervisor.maxLifetimeSeconds !== void 0 ? `ttl ${supervisor.maxLifetimeSeconds}s` : void 0
540
- ].filter((value) => value !== void 0);
541
- return [
542
- `task ${compact(supervisor.task, width - 7)}`,
543
- `workspace ${compact(supervisor.workspaceDir, width - 12)}`,
544
- `verify ${compact(supervisor.verifyCmd ?? "-", width - 9)}`,
545
- `models worker ${supervisor.workerModel ?? "-"} / driver ${supervisor.driverModel ?? "-"} caps ${caps.join(" | ") || "-"}`,
546
- `progress ${compact(supervisor.progress ?? supervisor.verdict ?? supervisor.status, width - 10)}`
547
- ];
428
+ return {
429
+ value: out,
430
+ diagnostics
431
+ };
548
432
  }
549
- function renderJournalTail(supervisor, width, color) {
550
- if (supervisor.journalTail.length === 0) return [" no journal events yet"];
433
+ function readSupervisorState(dir) {
434
+ const path = "state.json";
435
+ const read = readSourceFile(join(dir, path), "supervisor-state", path);
436
+ if (read.diagnostics.length > 0) return {
437
+ value: void 0,
438
+ diagnostics: read.diagnostics
439
+ };
440
+ if (read.value === void 0) return {
441
+ value: void 0,
442
+ diagnostics: [{
443
+ source: "supervisor-state",
444
+ path,
445
+ reason: "missing"
446
+ }]
447
+ };
448
+ let parsed;
449
+ try {
450
+ parsed = JSON.parse(read.value);
451
+ } catch {
452
+ return {
453
+ value: void 0,
454
+ diagnostics: [{
455
+ source: "supervisor-state",
456
+ path,
457
+ reason: "partial-json"
458
+ }]
459
+ };
460
+ }
461
+ if (!isSupervisorState(parsed)) return {
462
+ value: void 0,
463
+ diagnostics: [{
464
+ source: "supervisor-state",
465
+ path,
466
+ reason: "invalid-state"
467
+ }]
468
+ };
469
+ return {
470
+ value: parsed,
471
+ diagnostics: []
472
+ };
473
+ }
474
+ function isSupervisorState(value) {
475
+ return value !== void 0 && typeof value.id === "string" && typeof value.status === "string" && typeof value.task === "string" && typeof value.workspaceDir === "string" && typeof value.budget === "number";
476
+ }
477
+ function isSpawnEvent(value) {
478
+ return value.kind === "spawned" && typeof value.id === "string" || value.kind === "settled" && typeof value.id === "string" || value.kind === "cancelled" && typeof value.id === "string" || value.kind === "metered" && typeof value.id === "string" || value.kind === "progress" && typeof value.id === "string";
479
+ }
480
+ function isRecord(value) {
481
+ return typeof value === "object" && value !== null;
482
+ }
483
+ function isDirectory(path) {
484
+ try {
485
+ return statSync(path).isDirectory();
486
+ } catch {
487
+ return false;
488
+ }
489
+ }
490
+ function numberValue(value) {
491
+ return typeof value === "number" && Number.isFinite(value) ? value : 0;
492
+ }
493
+ function parseTime(value) {
494
+ if (!value) return void 0;
495
+ const parsed = Date.parse(value);
496
+ return Number.isFinite(parsed) ? parsed : void 0;
497
+ }
498
+ function sum(values) {
499
+ return values.reduce((total, value) => total + value, 0);
500
+ }
501
+ //#endregion
502
+ //#region src/tui/top-frame.ts
503
+ const ansiPattern = /\x1b\[[0-9;?]*[ -/]*[@-~]/g;
504
+ const colors = {
505
+ reset: "\x1B[0m",
506
+ dim: "\x1B[2m",
507
+ bold: "\x1B[1m",
508
+ red: "\x1B[31m",
509
+ green: "\x1B[32m",
510
+ yellow: "\x1B[33m",
511
+ blue: "\x1B[34m",
512
+ magenta: "\x1B[35m",
513
+ cyan: "\x1B[36m",
514
+ white: "\x1B[37m",
515
+ inverse: "\x1B[7m"
516
+ };
517
+ /** Render one snapshot to an ANSI frame. Use this when nothing needs to be clickable. */
518
+ function renderTopFrame(snapshot, options = {}) {
519
+ return renderTopFrameWithLayout(snapshot, options).frame;
520
+ }
521
+ /**
522
+ * Render one snapshot, returning the frame together with the row→entity map a mouse click resolves
523
+ * against. The layout is the only thing that knows which row is which run or worker, so emitting it
524
+ * alongside the text is what keeps click handling out of the renderer.
525
+ */
526
+ function renderTopFrameWithLayout(snapshot, options = {}) {
527
+ const width = Math.max(88, options.width ?? 128);
528
+ const height = Math.max(24, options.height ?? 42);
529
+ const color = options.color ?? false;
530
+ const focus = options.focus ?? "supervisors";
531
+ const mode = options.mode ?? "overview";
532
+ const selectedSupervisor = selectSupervisor(snapshot, options.selectedSupervisorId);
533
+ const selectedWorker = selectedSupervisor ? selectWorker(selectedSupervisor, options.selectedWorkerId) : void 0;
534
+ const targets = [];
535
+ const lines = [];
536
+ const push = (line = "", target) => {
537
+ if (lines.length >= height) return;
538
+ if (target) targets.push({
539
+ row: lines.length,
540
+ ...target
541
+ });
542
+ lines.push(fitAnsi(line, width));
543
+ };
544
+ const aggregate = aggregateSnapshot(snapshot);
545
+ push(`${paint("SUPERVISOR TOP", "bold", color)} ${paint(snapshot.root, "dim", color)} runs ${aggregate.supervisors} workers ${aggregate.workers} live ${aggregate.running} done ${aggregate.done} down ${aggregate.down} ${formatMoney(aggregate.usd)} tok ${formatTokens(aggregate.tokensInput)}/${formatTokens(aggregate.tokensOutput)}`);
546
+ push(`${paint("keys", "dim", color)} up/down select left/right run tab focus enter detail o overview l log s steer c cancel mouse q quit`);
547
+ if (options.notice) push(paint(options.notice, "yellow", color));
548
+ if (snapshot.completeness === "partial") push(paint(`partial snapshot: ${snapshot.diagnostics.length} source${snapshot.diagnostics.length === 1 ? "" : "s"} skipped or truncated; runs loaded ${snapshot.loaded}/${snapshot.discovered}`, "yellow", color));
549
+ if (options.steerInput?.active) push(renderSteerInput(options.steerInput, width, color));
550
+ push(rule(width, color));
551
+ if (snapshot.supervisors.length === 0) {
552
+ if (snapshot.discovered > 0) {
553
+ push(paint("NO READABLE SUPERVISORS", "yellow", color));
554
+ push(`${snapshot.discovered} run director${snapshot.discovered === 1 ? "y" : "ies"} found under ${supervisorRunsRoot(snapshot.root)}, none readable`);
555
+ } else {
556
+ push(paint("NO SUPERVISORS", "yellow", color));
557
+ push(`No run state under ${supervisorRunsRoot(snapshot.root)}`);
558
+ }
559
+ push(`A run appears here once its driver writes state.json; re-point with: agent-runtime-top <root>`);
560
+ return {
561
+ frame: `${lines.join("\n")}\n`,
562
+ targets
563
+ };
564
+ }
565
+ push(sectionTitle("SUPERVISORS", focus === "supervisors", color));
566
+ push(` id status workers spend tok in/out latency task`);
567
+ for (const supervisor of snapshot.supervisors.slice(0, 9)) {
568
+ const selected = supervisor.id === selectedSupervisor?.id;
569
+ const status = statusText(supervisor.status, color);
570
+ const pointer = selected ? paint(">", "cyan", color) : " ";
571
+ const rowFocus = selected && focus === "supervisors" ? "inverse" : void 0;
572
+ const workerSummary = `${supervisor.totals.running}/${supervisor.totals.workers} live`;
573
+ const task = compact(supervisor.task, 34);
574
+ const line = `${pointer} ${pad(supervisor.id, 21)} ${pad(status, 12)} ${pad(workerSummary, 13)} ${pad(formatMoney(supervisor.totals.usd), 12)} ${pad(`${formatTokens(supervisor.totals.tokensInput)}/${formatTokens(supervisor.totals.tokensOutput)}`, 16)} ${pad(formatDuration(supervisor.totals.latencyMs), 12)} ${task}`;
575
+ push(rowFocus ? paint(line, rowFocus, color) : line, {
576
+ kind: "supervisor",
577
+ id: supervisor.id
578
+ });
579
+ }
580
+ if (!selectedSupervisor) return {
581
+ frame: `${lines.join("\n")}\n`,
582
+ targets
583
+ };
584
+ push();
585
+ push(sectionTitle(`WORKERS ${selectedSupervisor.id}`, focus === "workers", color));
586
+ push(` id state runtime latency cost tok in/out score detail`);
587
+ for (const worker of selectedSupervisor.workers.slice(0, 12)) {
588
+ const selected = worker.id === selectedWorker?.id;
589
+ const pointer = selected ? paint(">", "cyan", color) : " ";
590
+ const rowFocus = selected && focus === "workers" ? "inverse" : void 0;
591
+ const score = worker.verdict ?? (worker.status === "done" ? "done" : worker.status);
592
+ const detail = worker.reason ?? worker.outRef ?? worker.parent ?? "";
593
+ const spend = totalSpend(worker);
594
+ const line = `${pointer} ${pad(worker.label, 12)} ${pad(statusText(worker.status, color), 12)} ${pad(worker.runtime ?? "-", 10)} ${pad(formatDuration(worker.latencyMs), 12)} ${pad(formatMoney(spend.usd), 11)} ${pad(`${formatTokens(spend.tokensInput)}/${formatTokens(spend.tokensOutput)}`, 16)} ${pad(compact(score, 9), 10)} ${compact(detail, 30)}`;
595
+ push(rowFocus ? paint(line, rowFocus, color) : line, {
596
+ kind: "worker",
597
+ id: worker.id,
598
+ supervisorId: selectedSupervisor.id
599
+ });
600
+ }
601
+ if (selectedSupervisor.workers.length === 0) push(" no workers spawned yet");
602
+ push();
603
+ push(sectionTitle("OBSERVABILITY", false, color));
604
+ for (const line of renderStatusBars(selectedSupervisor, width, color)) push(line);
605
+ push();
606
+ for (const line of renderCostBars(selectedSupervisor, width, color)) push(line);
607
+ push();
608
+ for (const line of renderTokenBars(selectedSupervisor, width, color)) push(line);
609
+ push();
610
+ for (const line of renderLatencyHistogram(selectedSupervisor, width, color)) push(line);
611
+ push();
612
+ if (mode === "log") {
613
+ push(sectionTitle("JOURNAL TAIL", false, color));
614
+ for (const line of renderJournalTail(selectedSupervisor, width, color)) push(line);
615
+ } else {
616
+ push(sectionTitle(mode === "detail" ? "DETAIL" : "RUN SUMMARY", false, color));
617
+ for (const line of renderDetail(selectedSupervisor, selectedWorker, mode, width, color)) push(line);
618
+ }
619
+ return {
620
+ frame: `${lines.join("\n")}\n`,
621
+ targets
622
+ };
623
+ }
624
+ function renderStatusBars(supervisor, width, color) {
625
+ const total = Math.max(1, supervisor.totals.workers);
626
+ const barWidth = Math.max(12, Math.min(28, width - 58));
627
+ return [`status ${pad("running", 9)} ${bar(supervisor.totals.running, total, barWidth, "#", color, "yellow")} ${supervisor.totals.running} ${pad("done", 5)} ${bar(supervisor.totals.done, total, barWidth, "#", color, "green")} ${supervisor.totals.done} ${pad("down", 5)} ${bar(supervisor.totals.down, total, barWidth, "#", color, "red")} ${supervisor.totals.down}`];
628
+ }
629
+ function renderCostBars(supervisor, width, color) {
630
+ const workers = supervisor.workers.map((worker) => ({
631
+ worker,
632
+ spend: totalSpend(worker)
633
+ })).sort((a, b) => b.spend.usd - a.spend.usd).slice(0, 6);
634
+ const maxUsd = Math.max(1e-6, ...workers.map((row) => row.spend.usd), supervisor.driverSpend.usd);
635
+ const out = [`cost total ${formatMoney(supervisor.totals.usd)} driver ${formatMoney(supervisor.driverSpend.usd)}`];
636
+ const barWidth = Math.max(18, Math.min(46, width - 38));
637
+ for (const row of workers) out.push(` ${pad(row.worker.label, 12)} ${bar(row.spend.usd, maxUsd, barWidth, "$", color, "magenta")} ${formatMoney(row.spend.usd)}`);
638
+ if (workers.length === 0) out.push(" no worker cost yet");
639
+ return out;
640
+ }
641
+ function renderTokenBars(supervisor, width, color) {
642
+ const rows = supervisor.workers.map((worker) => ({
643
+ worker,
644
+ spend: totalSpend(worker),
645
+ total: totalSpend(worker).tokensInput + totalSpend(worker).tokensOutput
646
+ })).sort((a, b) => b.total - a.total).slice(0, 6);
647
+ const maxTokens = Math.max(1, ...rows.map((row) => row.total), supervisor.driverSpend.tokensInput + supervisor.driverSpend.tokensOutput);
648
+ const out = [`tokens total in ${formatTokens(supervisor.totals.tokensInput)} / out ${formatTokens(supervisor.totals.tokensOutput)} driver ${formatTokens(supervisor.driverSpend.tokensInput)}/${formatTokens(supervisor.driverSpend.tokensOutput)}`];
649
+ const barWidth = Math.max(18, Math.min(46, width - 44));
650
+ for (const row of rows) out.push(` ${pad(row.worker.label, 12)} ${stackedTokenBar(row.spend.tokensInput, row.spend.tokensOutput, maxTokens, barWidth, color)} ${formatTokens(row.spend.tokensInput)}/${formatTokens(row.spend.tokensOutput)}`);
651
+ if (rows.length === 0) out.push(" no worker tokens yet");
652
+ return out;
653
+ }
654
+ function renderLatencyHistogram(supervisor, width, color) {
655
+ const values = supervisor.workers.map((worker) => worker.latencyMs).filter((value) => value > 0);
656
+ const summary = supervisor.totals.workerLatency;
657
+ const out = [`latency n=${summary.n} min ${formatDuration(summary.min)} p50 ${formatDuration(summary.median)} p90 ${formatDuration(summary.p90)} max ${formatDuration(summary.max)}`];
658
+ if (values.length === 0) {
659
+ out.push(" no latency samples yet");
660
+ return out;
661
+ }
662
+ const bins = histogram(values, 6);
663
+ const maxCount = Math.max(1, ...bins.map((bin) => bin.count));
664
+ const barWidth = Math.max(18, Math.min(48, width - 34));
665
+ for (const bin of bins) out.push(` ${pad(`${formatDuration(bin.min)}-${formatDuration(bin.max)}`, 15)} ${bar(bin.count, maxCount, barWidth, "#", color, "blue")} ${bin.count}`);
666
+ return out;
667
+ }
668
+ function renderDetail(supervisor, worker, mode, width, color) {
669
+ if (mode === "detail" && worker) {
670
+ const spend = totalSpend(worker);
671
+ return [
672
+ `worker ${paint(worker.label, "bold", color)} (${worker.id}) ${statusText(worker.status, color)} latency ${formatDuration(worker.latencyMs)}`,
673
+ `tokens in/out ${formatTokens(spend.tokensInput)}/${formatTokens(spend.tokensOutput)} cost ${formatMoney(spend.usd)} iterations ${spend.iterations}`,
674
+ `parent ${worker.parent ?? "-"} runtime ${worker.runtime ?? "-"} out ${worker.outRef ?? "-"}${worker.infra ? " infra" : ""}`,
675
+ `events ${compact(worker.eventFile ?? "-", width - 8)}`,
676
+ ...worker.reason ? [`reason ${compact(worker.reason, width - 7)}`] : [],
677
+ ...renderWorkerTail(worker, width, color)
678
+ ];
679
+ }
680
+ const caps = [
681
+ supervisor.maxSandboxes !== void 0 ? `boxes ${supervisor.maxSandboxes}` : void 0,
682
+ supervisor.maxUsd !== void 0 ? `max ${formatMoney(supervisor.maxUsd)}` : void 0,
683
+ supervisor.maxDepth !== void 0 ? `depth ${supervisor.maxDepth}` : void 0,
684
+ supervisor.maxLifetimeSeconds !== void 0 ? `ttl ${supervisor.maxLifetimeSeconds}s` : void 0
685
+ ].filter((value) => value !== void 0);
686
+ return [
687
+ `task ${compact(supervisor.task, width - 7)}`,
688
+ `workspace ${compact(supervisor.workspaceDir, width - 12)}`,
689
+ `verify ${compact(supervisor.verifyCmd ?? "-", width - 9)}`,
690
+ `models worker ${supervisor.workerModel ?? "-"} / driver ${supervisor.driverModel ?? "-"} caps ${caps.join(" | ") || "-"}`,
691
+ `progress ${compact(supervisor.progress ?? supervisor.verdict ?? supervisor.status, width - 10)}`
692
+ ];
693
+ }
694
+ function renderJournalTail(supervisor, width, color) {
695
+ if (supervisor.journalTail.length === 0) return [" no journal events yet"];
551
696
  return supervisor.journalTail.map((event) => {
552
697
  const at = event.at ? formatClock(event.at) : "--:--:--";
553
698
  if (event.kind === "spawned") return ` ${at} ${paint("spawn", "yellow", color)} ${pad(event.label ?? event.id, 16)} ${event.id}`;
@@ -676,149 +821,6 @@ function selectWorker(supervisor, requested) {
676
821
  }
677
822
  return supervisor.workers[0];
678
823
  }
679
- /**
680
- * Read one source file under a run directory. An absent file is not a defect on its own — the
681
- * writer may not have reached it yet — so it reads as `undefined` with no diagnostic; only a
682
- * failed read raises one. `path` stays run-relative and never carries file contents.
683
- */
684
- function readSourceFile(file, source, path) {
685
- if (!existsSync(file)) return {
686
- value: void 0,
687
- diagnostics: []
688
- };
689
- try {
690
- return {
691
- value: readFileSync(file, "utf8"),
692
- diagnostics: []
693
- };
694
- } catch {
695
- return {
696
- value: void 0,
697
- diagnostics: [{
698
- source,
699
- path,
700
- reason: "unreadable"
701
- }]
702
- };
703
- }
704
- }
705
- function tailLines(raw, maxLines) {
706
- if (raw === void 0) return [];
707
- return raw.trim().split("\n").filter(Boolean).slice(-maxLines);
708
- }
709
- function readProgressTail(dir, maxLines) {
710
- const path = "progress.ndjson";
711
- const read = readSourceFile(join(dir, path), "progress", path);
712
- return {
713
- value: tailLines(read.value, maxLines),
714
- diagnostics: read.diagnostics
715
- };
716
- }
717
- function readWorkerEventTails(dir, maxLines) {
718
- const out = /* @__PURE__ */ new Map();
719
- if (!existsSync(dir)) return {
720
- value: out,
721
- diagnostics: []
722
- };
723
- const workersDir = basename(dir);
724
- let entries;
725
- try {
726
- entries = readdirSync(dir);
727
- } catch {
728
- return {
729
- value: out,
730
- diagnostics: [{
731
- source: "worker-tail",
732
- path: workersDir,
733
- reason: "unreadable"
734
- }]
735
- };
736
- }
737
- const diagnostics = [];
738
- for (const entry of entries) {
739
- if (!entry.endsWith(".ndjson") || entry.endsWith(".inbox.ndjson")) continue;
740
- const file = join(dir, entry);
741
- const read = readSourceFile(file, "worker-tail", join(workersDir, entry));
742
- diagnostics.push(...read.diagnostics);
743
- const lines = tailLines(read.value, maxLines);
744
- out.set(entry.slice(0, -7), {
745
- file,
746
- lines
747
- });
748
- }
749
- return {
750
- value: out,
751
- diagnostics
752
- };
753
- }
754
- function readSupervisorState(dir) {
755
- const path = "state.json";
756
- const read = readSourceFile(join(dir, path), "supervisor-state", path);
757
- if (read.diagnostics.length > 0) return {
758
- value: void 0,
759
- diagnostics: read.diagnostics
760
- };
761
- if (read.value === void 0) return {
762
- value: void 0,
763
- diagnostics: [{
764
- source: "supervisor-state",
765
- path,
766
- reason: "missing"
767
- }]
768
- };
769
- let parsed;
770
- try {
771
- parsed = JSON.parse(read.value);
772
- } catch {
773
- return {
774
- value: void 0,
775
- diagnostics: [{
776
- source: "supervisor-state",
777
- path,
778
- reason: "partial-json"
779
- }]
780
- };
781
- }
782
- if (!isSupervisorState(parsed)) return {
783
- value: void 0,
784
- diagnostics: [{
785
- source: "supervisor-state",
786
- path,
787
- reason: "invalid-state"
788
- }]
789
- };
790
- return {
791
- value: parsed,
792
- diagnostics: []
793
- };
794
- }
795
- function isSupervisorState(value) {
796
- return value !== void 0 && typeof value.id === "string" && typeof value.status === "string" && typeof value.task === "string" && typeof value.workspaceDir === "string" && typeof value.budget === "number";
797
- }
798
- function isSpawnEvent(value) {
799
- return value.kind === "spawned" && typeof value.id === "string" || value.kind === "settled" && typeof value.id === "string" || value.kind === "cancelled" && typeof value.id === "string" || value.kind === "metered" && typeof value.id === "string" || value.kind === "progress" && typeof value.id === "string";
800
- }
801
- function isRecord(value) {
802
- return typeof value === "object" && value !== null;
803
- }
804
- function isDirectory(path) {
805
- try {
806
- return statSync(path).isDirectory();
807
- } catch {
808
- return false;
809
- }
810
- }
811
- function numberValue(value) {
812
- return typeof value === "number" && Number.isFinite(value) ? value : 0;
813
- }
814
- function parseTime(value) {
815
- if (!value) return void 0;
816
- const parsed = Date.parse(value);
817
- return Number.isFinite(parsed) ? parsed : void 0;
818
- }
819
- function sum(values) {
820
- return values.reduce((total, value) => total + value, 0);
821
- }
822
824
  function formatClock(value) {
823
825
  const parsed = parseTime(value);
824
826
  if (parsed === void 0) return "--:--:--";
@@ -895,7 +897,7 @@ function fitAnsi(value, width) {
895
897
  //#region src/tui/top-app.ts
896
898
  /**
897
899
  * The interactive side of the supervisor-run TUI: a keypress/mouse loop over the frames
898
- * `./top-model` renders, plus the operator controls that write back to the run — steer a live
900
+ * `./top-frame` renders, plus the operator controls that write back to the run — steer a live
899
901
  * worker, cancel one worker, and request cancellation of a whole run.
900
902
  *
901
903
  * The controls go through the owned run layout: steers via `writeWorkerSteer` (the durable inbox
@@ -1207,6 +1209,6 @@ function wrap(value, size) {
1207
1209
  return (value % size + size) % size;
1208
1210
  }
1209
1211
  //#endregion
1210
- export { renderTopFrameWithLayout as a, renderTopFrame as i, runTopApp as n, loadTopSnapshot as r, renderTopOnce as t };
1212
+ export { loadTopSnapshot as a, renderTopFrameWithLayout as i, runTopApp as n, renderTopFrame as r, renderTopOnce as t };
1211
1213
 
1212
- //# sourceMappingURL=top-app-BaMw1W2z.js.map
1214
+ //# sourceMappingURL=top-app-C55Wa7uy.js.map