@tangle-network/agent-runtime 0.350.2 → 0.353.2

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 (95) hide show
  1. package/dist/{activation-CfJMyzEs.js → activation-BkRaG5t0.js} +4 -4
  2. package/dist/{activation-CfJMyzEs.js.map → activation-BkRaG5t0.js.map} +1 -1
  3. package/dist/{activation-DyiHrTlS.d.ts → activation-CFS31SWI.d.ts} +2 -2
  4. package/dist/agent.d.ts +1 -1
  5. package/dist/agent.js +3 -3
  6. package/dist/{bundle-Ze8pd07a.js → bundle-DeDkJbsr.js} +2 -2
  7. package/dist/{bundle-Ze8pd07a.js.map → bundle-DeDkJbsr.js.map} +1 -1
  8. package/dist/candidate-execution/index.js +4 -4
  9. package/dist/chat-turn.d.ts +2 -0
  10. package/dist/chat-turn.js +1 -0
  11. package/dist/{coordination-manager-BkVfWlMz.js → coordination-manager-BrRkc55z.js} +4 -4
  12. package/dist/{coordination-manager-BkVfWlMz.js.map → coordination-manager-BrRkc55z.js.map} +1 -1
  13. package/dist/{delegate-DgEie4ad.js → delegate-CAdajnf8.js} +3 -3
  14. package/dist/{delegate-DgEie4ad.js.map → delegate-CAdajnf8.js.map} +1 -1
  15. package/dist/durable.d.ts +7 -130
  16. package/dist/durable.js +24 -952
  17. package/dist/durable.js.map +1 -1
  18. package/dist/{errors-wuhGvpE3.js → errors-AzSuGI23.js} +4 -1
  19. package/dist/errors-AzSuGI23.js.map +1 -0
  20. package/dist/execution-handle-Bd2_nUB6.js +167 -0
  21. package/dist/execution-handle-Bd2_nUB6.js.map +1 -0
  22. package/dist/execution-handle-CujvqgCn.d.ts +130 -0
  23. package/dist/{graph-Cx0FhKSE.js → graph-CyaIHVGR.js} +7 -6
  24. package/dist/{graph-Cx0FhKSE.js.map → graph-CyaIHVGR.js.map} +1 -1
  25. package/dist/{improve-i0HU1-aa.js → improve-DwG-yioQ.js} +10 -9
  26. package/dist/{improve-i0HU1-aa.js.map → improve-DwG-yioQ.js.map} +1 -1
  27. package/dist/index.d.ts +4 -3
  28. package/dist/index.js +14 -11
  29. package/dist/index.js.map +1 -1
  30. package/dist/intelligence.d.ts +2 -2
  31. package/dist/intelligence.js +12 -10
  32. package/dist/intelligence.js.map +1 -1
  33. package/dist/journal-store-BJPMUydp.js +3925 -0
  34. package/dist/journal-store-BJPMUydp.js.map +1 -0
  35. package/dist/kernel.d.ts +1 -1
  36. package/dist/kernel.js +11 -10
  37. package/dist/{loop-runner-DvfOXVx9.d.ts → loop-runner-D9rcTNf2.d.ts} +2 -2
  38. package/dist/{loop-runner-BwN9MhdP.js → loop-runner-DwS3jARE.js} +3 -3
  39. package/dist/{loop-runner-BwN9MhdP.js.map → loop-runner-DwS3jARE.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 +4 -4
  43. package/dist/mcp/index.d.ts +1 -1
  44. package/dist/mcp/index.js +8 -8
  45. package/dist/mcp/memory-bin.js +2 -2
  46. package/dist/{model-policy-GSxWwP-b.js → model-policy-C-RGAUW4.js} +2 -2
  47. package/dist/{model-policy-GSxWwP-b.js.map → model-policy-C-RGAUW4.js.map} +1 -1
  48. package/dist/{prepare-DE8TQnLu.js → prepare-XWwsOh8O.js} +4 -3
  49. package/dist/{prepare-DE8TQnLu.js.map → prepare-XWwsOh8O.js.map} +1 -1
  50. package/dist/{profile-CAhZDW2T.js → profile-C01SQZKa.js} +3 -3
  51. package/dist/{profile-CAhZDW2T.js.map → profile-C01SQZKa.js.map} +1 -1
  52. package/dist/profiles.d.ts +1 -1
  53. package/dist/profiles.js +2 -2
  54. package/dist/{provision-supervisor-Bde_FF0R.js → provision-supervisor-AEnei2Jq.js} +7 -7
  55. package/dist/{provision-supervisor-Bde_FF0R.js.map → provision-supervisor-AEnei2Jq.js.map} +1 -1
  56. package/dist/{run-cancellation-BLy_Zz-w.js → run-cancellation-CoJRKvih.js} +2 -2
  57. package/dist/{run-cancellation-BLy_Zz-w.js.map → run-cancellation-CoJRKvih.js.map} +1 -1
  58. package/dist/{runtime-6Ec9sHRe.js → runtime-DCYSaYHW.js} +42 -39
  59. package/dist/{runtime-6Ec9sHRe.js.map → runtime-DCYSaYHW.js.map} +1 -1
  60. package/dist/{sandbox-profile-compat-BxMQ1VXv.js → sandbox-profile-compat-CXjozdWL.js} +4 -623
  61. package/dist/{sandbox-profile-compat-BxMQ1VXv.js.map → sandbox-profile-compat-CXjozdWL.js.map} +1 -1
  62. package/dist/{search-executor-B7g_5Wjl.js → search-executor-B2jc63hZ.js} +14 -11
  63. package/dist/{search-executor-B7g_5Wjl.js.map → search-executor-B2jc63hZ.js.map} +1 -1
  64. package/dist/{server-fvEMwGMQ.js → server-CKBTwWM8.js} +6 -6
  65. package/dist/{server-fvEMwGMQ.js.map → server-CKBTwWM8.js.map} +1 -1
  66. package/dist/{structural-rollout-B86bSixU.js → structural-rollout-rRT3ypqz.js} +7 -5
  67. package/dist/{structural-rollout-B86bSixU.js.map → structural-rollout-rRT3ypqz.js.map} +1 -1
  68. package/dist/{supervise-CaeZcgAW.js → supervise-B3_wtgHS.js} +18 -21
  69. package/dist/supervise-B3_wtgHS.js.map +1 -0
  70. package/dist/supervision-discovery-CewADdEs.js +772 -0
  71. package/dist/supervision-discovery-CewADdEs.js.map +1 -0
  72. package/dist/{supervisor-C1OePYE-.js → supervisor-C_sDmX5H.js} +156 -3984
  73. package/dist/supervisor-C_sDmX5H.js.map +1 -0
  74. package/dist/testing.d.ts +1 -1
  75. package/dist/testing.js +13 -13
  76. package/dist/{tool-server-CwuYeW_Z.js → tool-server-CZWd_Opp.js} +2 -2
  77. package/dist/{tool-server-CwuYeW_Z.js.map → tool-server-CZWd_Opp.js.map} +1 -1
  78. package/dist/{top-snapshot-ChwpTr7A.js → top-snapshot-DcV7VG4m.js} +178 -161
  79. package/dist/top-snapshot-DcV7VG4m.js.map +1 -0
  80. package/dist/tui/bin.js +45 -74
  81. package/dist/tui/bin.js.map +1 -1
  82. package/dist/tui/index.d.ts +25 -54
  83. package/dist/tui/index.js +2 -2
  84. package/dist/{types-Fowuwdz2.d.ts → types-DTHxh4X9.d.ts} +47 -63
  85. package/dist/util-ebWMWzY0.js +624 -0
  86. package/dist/util-ebWMWzY0.js.map +1 -0
  87. package/dist/workspace-store/index.js +9 -3
  88. package/dist/workspace-store/index.js.map +1 -1
  89. package/package.json +18 -13
  90. package/dist/errors-wuhGvpE3.js.map +0 -1
  91. package/dist/record-events-B2GUgYdz.js +0 -261
  92. package/dist/record-events-B2GUgYdz.js.map +0 -1
  93. package/dist/supervise-CaeZcgAW.js.map +0 -1
  94. package/dist/supervisor-C1OePYE-.js.map +0 -1
  95. package/dist/top-snapshot-ChwpTr7A.js.map +0 -1
package/dist/testing.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { Ch as ToolLoopCallContext, Ct as SuperviseProfileEntry, Dh as ToolLoopMessageRecord, Eh as ToolLoopCompactionOptions, Fv as CoordinationEvent, Gy as BusRecord, Hv as DecideGate, Hy as McpToolDescriptor, Ip as PriorCoordination, Kv as RouteFlow, M as Budget, Nd as superviseWithTestBrain, Np as CoordinationDeliveryEvidence, Oh as ToolLoopToolCall, Om as Inbox, Qf as ManagerWakePolicy, Rd as SuperviseTestOptions, Rf as supervisorAgentWithTestBrain, Sp as SupervisorFinalizer, Vv as WorkerWatchOptions, Vx as HarnessTranscriptCapture, Xv as ChildQuestionInbox, Yg as DeliverableSpec, Zi as ResultBlobStore, Zv as EscalateQuestion, _t as PeerAuditAccess, ab as AnalyzeOnSettleRoute, ap as StopRule, bt as SpawnPreflightContext, fd as runGraphWithTestBrain, ft as CoordinationTools, fy as ContinuityMode, gt as MakeWorkerAgent, ht as GraphSubtasks, ld as RunGraphTestOptions, ly as AuthorizeDownMessage, mt as GraphSubtaskPreparation, qf as SupervisorAgentTestDeps, rb as AnalystRegistry, tm as SpawnResourceReader, ua as Agent, up as RunCancelRequest, wh as ToolLoopChat, xt as SpawnRefusal, yh as RouterResponseReceipt, yt as SpawnPreflight, yy as MapOnSettleRoute } from "./types-Fowuwdz2.js";
1
+ import { Bv as DecideGate, By as McpToolDescriptor, Ch as ToolLoopCallContext, Ct as SuperviseProfileEntry, Dh as ToolLoopMessageRecord, Eh as ToolLoopCompactionOptions, Ip as PriorCoordination, Jv as ChildQuestionInbox, M as Budget, Nd as superviseWithTestBrain, Np as CoordinationDeliveryEvidence, Nv as CoordinationEvent, Oh as ToolLoopToolCall, Om as Inbox, Qf as ManagerWakePolicy, Rd as SuperviseTestOptions, Rf as supervisorAgentWithTestBrain, Sp as SupervisorFinalizer, Uy as BusRecord, Wv as RouteFlow, Yg as DeliverableSpec, Yv as EscalateQuestion, Zi as ResultBlobStore, _t as PeerAuditAccess, _y as MapOnSettleRoute, ap as StopRule, bt as SpawnPreflightContext, fd as runGraphWithTestBrain, ft as CoordinationTools, gt as MakeWorkerAgent, ht as GraphSubtasks, ld as RunGraphTestOptions, mt as GraphSubtaskPreparation, qf as SupervisorAgentTestDeps, rb as AnalyzeOnSettleRoute, sy as AuthorizeDownMessage, tb as AnalystRegistry, tm as SpawnResourceReader, ua as Agent, up as RunCancelRequest, uy as ContinuityMode, wh as ToolLoopChat, xt as SpawnRefusal, yh as RouterResponseReceipt, yt as SpawnPreflight, zv as WorkerWatchOptions, zx as HarnessTranscriptCapture } from "./types-DTHxh4X9.js";
2
2
  import { AgentImprovementProposal, AgentProfile, AgentProfileImprovementMeasuredComparison, SandboxSizePreset } from "@tangle-network/agent-interface";
3
3
  /** What the brain returned for one turn, as the recorder keeps it. */
4
4
  interface RouterTranscriptReply {
package/dist/testing.js CHANGED
@@ -1,13 +1,13 @@
1
- import { P as canonicalCandidateDigest$1, R as immutableCandidateValue } from "./sandbox-profile-compat-BxMQ1VXv.js";
2
- import { c as verifyAgentImprovementProposal } from "./activation-CfJMyzEs.js";
3
- import { a as applyExactAgentProfileDiff, v as parseExactAgentProfile } from "./profile-CAhZDW2T.js";
4
- import { N as supervisorAgentWithTestBrain, R as driverAgent, r as superviseWithTestBrain } from "./supervise-CaeZcgAW.js";
5
- import { r as runGraphWithTestBrain } from "./graph-Cx0FhKSE.js";
1
+ import { P as canonicalCandidateDigest$1, R as immutableCandidateValue } from "./sandbox-profile-compat-CXjozdWL.js";
2
+ import { c as verifyAgentImprovementProposal } from "./activation-BkRaG5t0.js";
3
+ import { a as applyExactAgentProfileDiff, v as parseExactAgentProfile } from "./profile-C01SQZKa.js";
4
+ import { N as supervisorAgentWithTestBrain, R as driverAgent, r as superviseWithTestBrain } from "./supervise-B3_wtgHS.js";
5
+ import { r as runGraphWithTestBrain } from "./graph-CyaIHVGR.js";
6
6
  import { SANDBOX_SIZE_PRESET_NAMES, canonicalAgentProfileDigest } from "@tangle-network/agent-interface";
7
7
  // src/testing/fixtures/agent-improvement-proposal.json
8
8
  var agent_improvement_proposal_default = {
9
9
  changedSurfaces: ["prompt"],
10
- digest: "sha256:30d8982b8f89ecd3ad0409e4bc41a5dc6e7555dc40b2868d78c5c67d5b5c8f0d",
10
+ digest: "sha256:c8b21629cf36d183e5a87df5ba9fd9900dc32d436fffb8c26adaf403b411a29f",
11
11
  evaluation: {
12
12
  "decision": {
13
13
  "contributingChecks": [
@@ -4578,7 +4578,7 @@ var agent_improvement_proposal_default = {
4578
4578
  ],
4579
4579
  "metadata": {
4580
4580
  "fixture": "agent-improvement-proposal",
4581
- "runtimeVersion": "0.350.2"
4581
+ "runtimeVersion": "0.353.2"
4582
4582
  },
4583
4583
  "objectives": [
4584
4584
  {
@@ -4689,8 +4689,8 @@ var agent_improvement_proposal_default = {
4689
4689
  "baselineContentHash": "sha256:5c21ee53e513fc604cb09754e21c392b24a424da0ef37dbf8f1ee4a8a0b08f09",
4690
4690
  "candidateContentHash": "sha256:60fcbb1c728194bd51d7d19cb732d1c3f1881dce7e0a6266b41c8b98cfd65693",
4691
4691
  "kind": "agent-eval-loop",
4692
- "recordDigest": "sha256:3b648a763934829b428ffcfcd8d6d3f04f4cd9b24d39cbf887c82df904a4edd9",
4693
- "runId": "agent-runtime-0.350.2-proposal-fixture",
4692
+ "recordDigest": "sha256:96c004afe5a00721ff7de3a937d553a8be80d93394cbd31014e64be148f11279",
4693
+ "runId": "agent-runtime-0.353.2-proposal-fixture",
4694
4694
  "schema": "agent-candidate-experiment"
4695
4695
  }
4696
4696
  },
@@ -4713,12 +4713,12 @@ var agent_improvement_proposal_default = {
4713
4713
  }],
4714
4714
  kind: "agent-improvement-proposal",
4715
4715
  proposedAt: "2026-07-10T01:00:00.000Z",
4716
- runId: "agent-runtime-0.350.2-proposal-fixture"
4716
+ runId: "agent-runtime-0.353.2-proposal-fixture"
4717
4717
  };
4718
4718
  // src/testing/fixtures/agent-profile-improvement-proposal.json
4719
4719
  var agent_profile_improvement_proposal_default = {
4720
4720
  changedSurfaces: ["prompt", "skills"],
4721
- digest: "sha256:cdde5076bfb9f541dcd6d0a08729f857a6558e249cfeed71d67999a6addacfd9",
4721
+ digest: "sha256:80586cfb745b31a31848f647728629712e4617fd47ae4fd6426fb85d685ca25c",
4722
4722
  evaluation: {
4723
4723
  "decision": {
4724
4724
  "contributingChecks": [
@@ -6352,7 +6352,7 @@ var agent_profile_improvement_proposal_default = {
6352
6352
  ],
6353
6353
  "metadata": {
6354
6354
  "fixture": "agent-profile-improvement-proposal",
6355
- "runtimeVersion": "0.350.2"
6355
+ "runtimeVersion": "0.353.2"
6356
6356
  },
6357
6357
  "objectives": [
6358
6358
  {
@@ -6463,7 +6463,7 @@ var agent_profile_improvement_proposal_default = {
6463
6463
  "baselineContentHash": "sha256:21c495a37c418c10bde64fbaa188beddeed31f1f051ea60a6a6582a9ee0db704",
6464
6464
  "candidateContentHash": "sha256:103f77bc8481601eef1ad5fe6ba84a40dffabc3a44f421f8c8559121edab84e9",
6465
6465
  "kind": "agent-eval-loop",
6466
- "recordDigest": "sha256:5ed8dee478a1231deb8d4b9c7e0df19ac0056f9ab988413c065af8db3efe76b3",
6466
+ "recordDigest": "sha256:0f90ddd5895d4c0e4f153decddec714d8db3b41ee25a604f6a33df28f12ec243",
6467
6467
  "runId": "profile-improvement-1",
6468
6468
  "schema": "agent-profile-improvement-experiment"
6469
6469
  }
@@ -1,4 +1,4 @@
1
- import { m as ValidationError } from "./errors-wuhGvpE3.js";
1
+ import { m as ValidationError } from "./errors-AzSuGI23.js";
2
2
  import { createInterface } from "node:readline";
3
3
  // src/mcp/tool-server.ts
4
4
  /**
@@ -168,4 +168,4 @@ function writeResponse(output, response) {
168
168
  }
169
169
  export { createStdioToolServer as n, PROTOCOL_VERSION as t };
170
170
 
171
- //# sourceMappingURL=tool-server-CwuYeW_Z.js.map
171
+ //# sourceMappingURL=tool-server-CZWd_Opp.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"tool-server-CwuYeW_Z.js","names":[],"sources":["../src/mcp/tool-server.ts"],"sourcesContent":["/**\n * `createStdioToolServer` — the generic newline-delimited JSON-RPC 2.0 MCP\n * server core: `initialize` / `notifications/initialized` / `tools/list` /\n * `ping` / `tools/call` over a stdio-shaped transport. It answers the\n * client's protocol version when listed in `SUPPORTED_PROTOCOL_VERSIONS`,\n * else 2024-11-05, and publishes tool annotations when a tool declares them.\n *\n * Extracted from `createMcpServer` (server.ts) so every in-repo MCP server —\n * the delegation server, the memory server — serves the ONE wire protocol the\n * same-host client (`connectStdioMcp`, runtime/stdio-mcp-client.ts) speaks.\n * A second hand-rolled serve loop could drift from what the client expects;\n * this core makes that impossible by construction.\n *\n * @experimental\n */\n\nimport { createInterface, type Interface as ReadlineInterface } from 'node:readline'\nimport { ValidationError } from '../errors'\nimport type { JsonRpcMessage, JsonRpcResponse, McpToolDescriptor, McpTransport } from './protocol'\n\nexport type { JsonRpcMessage, JsonRpcResponse, McpToolDescriptor, McpTransport } from './protocol'\n\nexport const PROTOCOL_VERSION = '2024-11-05'\n\n/**\n * Protocol versions this server speaks, newest first. `initialize` answers with\n * the client's requested version when it is listed here, and otherwise with\n * `PROTOCOL_VERSION` (2024-11-05), which every client that speaks 2024-11-05 accepts.\n */\nconst SUPPORTED_PROTOCOL_VERSIONS: readonly string[] = [\n '2025-11-25',\n '2025-06-18',\n '2025-03-26',\n PROTOCOL_VERSION,\n]\n\n/** @experimental */\nexport interface StdioToolServerOptions {\n /** Server display name surfaced via `initialize`. */\n serverName: string\n /** Server version surfaced via `initialize`. */\n serverVersion: string\n /** The tools to serve. Duplicate names throw — a silent shadow would hide a tool. */\n tools: readonly McpToolDescriptor[]\n}\n\n/** @experimental */\nexport interface StdioToolServer {\n /** Tools currently registered, keyed by name. */\n readonly tools: ReadonlyMap<string, McpToolDescriptor>\n /** Handle a single parsed JSON-RPC message. Returns the response object (or `null` for notifications). */\n handle(message: JsonRpcMessage): Promise<JsonRpcResponse | null>\n /** Drive the server on a stdio-shaped transport until `stop()` is called. */\n serve(transport?: McpTransport): Promise<void>\n /** Stop a `serve` call. Subsequent requests are rejected. */\n stop(): void\n}\n\n/** Build the generic stdio JSON-RPC tool server. */\nexport function createStdioToolServer(options: StdioToolServerOptions): StdioToolServer {\n const tools = new Map<string, McpToolDescriptor>()\n for (const tool of options.tools) {\n if (tools.has(tool.name)) {\n throw new ValidationError(`createStdioToolServer: duplicate tool name \"${tool.name}\"`)\n }\n tools.set(tool.name, tool)\n }\n\n let stopped = false\n let activeReadline: ReadlineInterface | undefined\n\n async function handle(message: JsonRpcMessage): Promise<JsonRpcResponse | null> {\n if (stopped) {\n return rpcError(message.id ?? null, -32099, 'server stopped')\n }\n if (message.method === 'initialize') {\n const requested = (message.params as { protocolVersion?: unknown } | undefined)\n ?.protocolVersion\n return rpcResult(message.id ?? null, {\n protocolVersion:\n typeof requested === 'string' && SUPPORTED_PROTOCOL_VERSIONS.includes(requested)\n ? requested\n : PROTOCOL_VERSION,\n capabilities: { tools: {} },\n serverInfo: { name: options.serverName, version: options.serverVersion },\n })\n }\n if (message.method === 'notifications/initialized') {\n // MCP clients send this after the handshake; it has no id and expects\n // no response.\n return null\n }\n if (message.method === 'ping') {\n return rpcResult(message.id ?? null, {})\n }\n if (message.method === 'tools/list') {\n return rpcResult(message.id ?? null, {\n tools: [...tools.values()].map((tool) => ({\n name: tool.name,\n description: tool.description,\n inputSchema: tool.inputSchema,\n ...(tool.annotations ? { annotations: tool.annotations } : {}),\n })),\n })\n }\n if (message.method === 'tools/call') {\n const params = (message.params ?? {}) as { name?: unknown; arguments?: unknown }\n const name = typeof params.name === 'string' ? params.name : ''\n const tool = tools.get(name)\n if (!tool) {\n return rpcError(message.id ?? null, -32601, `unknown tool: ${name}`)\n }\n try {\n const output = await tool.handler(params.arguments ?? {})\n return rpcResult(message.id ?? null, toolCallResult(output))\n } catch (err) {\n const reason = err instanceof Error ? err.message : String(err)\n const code = err instanceof TypeError || err instanceof RangeError ? -32602 : -32000\n return rpcError(message.id ?? null, code, reason)\n }\n }\n if (message.id === undefined || message.id === null) return null\n return rpcError(message.id, -32601, `unknown method: ${message.method}`)\n }\n\n async function serve(transport?: McpTransport): Promise<void> {\n const input = transport?.input ?? process.stdin\n const output = transport?.output ?? process.stdout\n const rl = createInterface({ input, crlfDelay: Number.POSITIVE_INFINITY })\n activeReadline = rl\n return new Promise<void>((resolve, reject) => {\n rl.on('line', (line) => {\n const trimmed = line.trim()\n if (!trimmed) return\n let parsed: JsonRpcMessage | undefined\n try {\n parsed = JSON.parse(trimmed) as JsonRpcMessage\n } catch (err) {\n writeResponse(output, rpcError(null, -32700, `parse error: ${(err as Error).message}`))\n return\n }\n if (parsed?.jsonrpc !== '2.0' || typeof parsed.method !== 'string') {\n writeResponse(output, rpcError(parsed?.id ?? null, -32600, 'invalid request'))\n return\n }\n void handle(parsed).then((response) => {\n if (response) writeResponse(output, response)\n })\n })\n rl.on('close', () => resolve())\n rl.on('error', (err) => reject(err))\n if (stopped) {\n rl.close()\n resolve()\n }\n })\n }\n\n function stop(): void {\n stopped = true\n activeReadline?.close()\n activeReadline = undefined\n }\n\n return { tools, handle, serve, stop }\n}\n\nfunction toolCallResult(output: unknown): {\n content: [{ type: 'text'; text: string }]\n structuredContent?: Record<string, unknown>\n isError: false\n} {\n let json: string | undefined\n try {\n json = JSON.stringify(output)\n } catch (err) {\n const reason = err instanceof Error ? `: ${err.message}` : ''\n throw new TypeError(`MCP tool result must be JSON-serializable${reason}`, { cause: err })\n }\n if (json === undefined) {\n throw new TypeError('MCP tool result must be JSON-serializable')\n }\n\n const serialized = JSON.parse(json) as unknown\n // Preserve string content verbatim. MCP clients pass this text directly to the calling agent.\n const result: {\n content: [{ type: 'text'; text: string }]\n structuredContent?: Record<string, unknown>\n isError: false\n } = {\n content: [{ type: 'text', text: typeof serialized === 'string' ? serialized : json }],\n isError: false,\n }\n if (serialized !== null && typeof serialized === 'object' && !Array.isArray(serialized)) {\n result.structuredContent = serialized as Record<string, unknown>\n }\n return result\n}\n\nfunction rpcResult(id: number | string | null, result: unknown): JsonRpcResponse {\n return { jsonrpc: '2.0', id, result }\n}\n\nfunction rpcError(\n id: number | string | null,\n code: number,\n message: string,\n data?: unknown,\n): JsonRpcResponse {\n return {\n jsonrpc: '2.0',\n id,\n error: data === undefined ? { code, message } : { code, message, data },\n }\n}\n\nfunction writeResponse(output: NodeJS.WritableStream, response: JsonRpcResponse): void {\n output.write(`${JSON.stringify(response)}\\n`)\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"tool-server-CZWd_Opp.js","names":[],"sources":["../src/mcp/tool-server.ts"],"sourcesContent":["/**\n * `createStdioToolServer` — the generic newline-delimited JSON-RPC 2.0 MCP\n * server core: `initialize` / `notifications/initialized` / `tools/list` /\n * `ping` / `tools/call` over a stdio-shaped transport. It answers the\n * client's protocol version when listed in `SUPPORTED_PROTOCOL_VERSIONS`,\n * else 2024-11-05, and publishes tool annotations when a tool declares them.\n *\n * Extracted from `createMcpServer` (server.ts) so every in-repo MCP server —\n * the delegation server, the memory server — serves the ONE wire protocol the\n * same-host client (`connectStdioMcp`, runtime/stdio-mcp-client.ts) speaks.\n * A second hand-rolled serve loop could drift from what the client expects;\n * this core makes that impossible by construction.\n *\n * @experimental\n */\n\nimport { createInterface, type Interface as ReadlineInterface } from 'node:readline'\nimport { ValidationError } from '../errors'\nimport type { JsonRpcMessage, JsonRpcResponse, McpToolDescriptor, McpTransport } from './protocol'\n\nexport type { JsonRpcMessage, JsonRpcResponse, McpToolDescriptor, McpTransport } from './protocol'\n\nexport const PROTOCOL_VERSION = '2024-11-05'\n\n/**\n * Protocol versions this server speaks, newest first. `initialize` answers with\n * the client's requested version when it is listed here, and otherwise with\n * `PROTOCOL_VERSION` (2024-11-05), which every client that speaks 2024-11-05 accepts.\n */\nconst SUPPORTED_PROTOCOL_VERSIONS: readonly string[] = [\n '2025-11-25',\n '2025-06-18',\n '2025-03-26',\n PROTOCOL_VERSION,\n]\n\n/** @experimental */\nexport interface StdioToolServerOptions {\n /** Server display name surfaced via `initialize`. */\n serverName: string\n /** Server version surfaced via `initialize`. */\n serverVersion: string\n /** The tools to serve. Duplicate names throw — a silent shadow would hide a tool. */\n tools: readonly McpToolDescriptor[]\n}\n\n/** @experimental */\nexport interface StdioToolServer {\n /** Tools currently registered, keyed by name. */\n readonly tools: ReadonlyMap<string, McpToolDescriptor>\n /** Handle a single parsed JSON-RPC message. Returns the response object (or `null` for notifications). */\n handle(message: JsonRpcMessage): Promise<JsonRpcResponse | null>\n /** Drive the server on a stdio-shaped transport until `stop()` is called. */\n serve(transport?: McpTransport): Promise<void>\n /** Stop a `serve` call. Subsequent requests are rejected. */\n stop(): void\n}\n\n/** Build the generic stdio JSON-RPC tool server. */\nexport function createStdioToolServer(options: StdioToolServerOptions): StdioToolServer {\n const tools = new Map<string, McpToolDescriptor>()\n for (const tool of options.tools) {\n if (tools.has(tool.name)) {\n throw new ValidationError(`createStdioToolServer: duplicate tool name \"${tool.name}\"`)\n }\n tools.set(tool.name, tool)\n }\n\n let stopped = false\n let activeReadline: ReadlineInterface | undefined\n\n async function handle(message: JsonRpcMessage): Promise<JsonRpcResponse | null> {\n if (stopped) {\n return rpcError(message.id ?? null, -32099, 'server stopped')\n }\n if (message.method === 'initialize') {\n const requested = (message.params as { protocolVersion?: unknown } | undefined)\n ?.protocolVersion\n return rpcResult(message.id ?? null, {\n protocolVersion:\n typeof requested === 'string' && SUPPORTED_PROTOCOL_VERSIONS.includes(requested)\n ? requested\n : PROTOCOL_VERSION,\n capabilities: { tools: {} },\n serverInfo: { name: options.serverName, version: options.serverVersion },\n })\n }\n if (message.method === 'notifications/initialized') {\n // MCP clients send this after the handshake; it has no id and expects\n // no response.\n return null\n }\n if (message.method === 'ping') {\n return rpcResult(message.id ?? null, {})\n }\n if (message.method === 'tools/list') {\n return rpcResult(message.id ?? null, {\n tools: [...tools.values()].map((tool) => ({\n name: tool.name,\n description: tool.description,\n inputSchema: tool.inputSchema,\n ...(tool.annotations ? { annotations: tool.annotations } : {}),\n })),\n })\n }\n if (message.method === 'tools/call') {\n const params = (message.params ?? {}) as { name?: unknown; arguments?: unknown }\n const name = typeof params.name === 'string' ? params.name : ''\n const tool = tools.get(name)\n if (!tool) {\n return rpcError(message.id ?? null, -32601, `unknown tool: ${name}`)\n }\n try {\n const output = await tool.handler(params.arguments ?? {})\n return rpcResult(message.id ?? null, toolCallResult(output))\n } catch (err) {\n const reason = err instanceof Error ? err.message : String(err)\n const code = err instanceof TypeError || err instanceof RangeError ? -32602 : -32000\n return rpcError(message.id ?? null, code, reason)\n }\n }\n if (message.id === undefined || message.id === null) return null\n return rpcError(message.id, -32601, `unknown method: ${message.method}`)\n }\n\n async function serve(transport?: McpTransport): Promise<void> {\n const input = transport?.input ?? process.stdin\n const output = transport?.output ?? process.stdout\n const rl = createInterface({ input, crlfDelay: Number.POSITIVE_INFINITY })\n activeReadline = rl\n return new Promise<void>((resolve, reject) => {\n rl.on('line', (line) => {\n const trimmed = line.trim()\n if (!trimmed) return\n let parsed: JsonRpcMessage | undefined\n try {\n parsed = JSON.parse(trimmed) as JsonRpcMessage\n } catch (err) {\n writeResponse(output, rpcError(null, -32700, `parse error: ${(err as Error).message}`))\n return\n }\n if (parsed?.jsonrpc !== '2.0' || typeof parsed.method !== 'string') {\n writeResponse(output, rpcError(parsed?.id ?? null, -32600, 'invalid request'))\n return\n }\n void handle(parsed).then((response) => {\n if (response) writeResponse(output, response)\n })\n })\n rl.on('close', () => resolve())\n rl.on('error', (err) => reject(err))\n if (stopped) {\n rl.close()\n resolve()\n }\n })\n }\n\n function stop(): void {\n stopped = true\n activeReadline?.close()\n activeReadline = undefined\n }\n\n return { tools, handle, serve, stop }\n}\n\nfunction toolCallResult(output: unknown): {\n content: [{ type: 'text'; text: string }]\n structuredContent?: Record<string, unknown>\n isError: false\n} {\n let json: string | undefined\n try {\n json = JSON.stringify(output)\n } catch (err) {\n const reason = err instanceof Error ? `: ${err.message}` : ''\n throw new TypeError(`MCP tool result must be JSON-serializable${reason}`, { cause: err })\n }\n if (json === undefined) {\n throw new TypeError('MCP tool result must be JSON-serializable')\n }\n\n const serialized = JSON.parse(json) as unknown\n // Preserve string content verbatim. MCP clients pass this text directly to the calling agent.\n const result: {\n content: [{ type: 'text'; text: string }]\n structuredContent?: Record<string, unknown>\n isError: false\n } = {\n content: [{ type: 'text', text: typeof serialized === 'string' ? serialized : json }],\n isError: false,\n }\n if (serialized !== null && typeof serialized === 'object' && !Array.isArray(serialized)) {\n result.structuredContent = serialized as Record<string, unknown>\n }\n return result\n}\n\nfunction rpcResult(id: number | string | null, result: unknown): JsonRpcResponse {\n return { jsonrpc: '2.0', id, result }\n}\n\nfunction rpcError(\n id: number | string | null,\n code: number,\n message: string,\n data?: unknown,\n): JsonRpcResponse {\n return {\n jsonrpc: '2.0',\n id,\n error: data === undefined ? { code, message } : { code, message, data },\n }\n}\n\nfunction writeResponse(output: NodeJS.WritableStream, response: JsonRpcResponse): void {\n output.write(`${JSON.stringify(response)}\\n`)\n}\n"],"mappings":"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"}
@@ -1,23 +1,14 @@
1
- import { t as spawnJournalRecordEvents } from "./record-events-B2GUgYdz.js";
2
- import { _ as safeWorkerFile, b as supervisorWorkersDir, f as legacySupervisorRunsRoot, y as supervisorRunsRoot } from "./run-cancellation-BLy_Zz-w.js";
1
+ import { r as spawnJournalRecordEvents, t as FileSpawnJournal } from "./journal-store-BJPMUydp.js";
2
+ import { _ as safeWorkerFile, b as supervisorWorkersDir, f as legacySupervisorRunsRoot, y as supervisorRunsRoot } from "./run-cancellation-CoJRKvih.js";
3
+ import { n as projectPursuit, r as FileObserverJournal, t as discoverDurableSupervisionRun } from "./supervision-discovery-CewADdEs.js";
3
4
  import { existsSync, readFileSync, readdirSync, statSync } from "node:fs";
4
5
  import { basename, join, resolve } from "node:path";
5
6
  // src/tui/top-snapshot.ts
6
7
  /**
7
- * The snapshot reader for the supervisor-run TUI: turn the on-disk run layout into a `TopSnapshot`.
8
- * ANSI frame presentation lives in `./top-frame`; this module owns reading and projection.
9
- *
10
- * This module never derives a run path itself. Every directory and per-worker file it reads comes
11
- * from `../runtime/supervise/run-layout` — the same module the writers use — so the reader cannot
12
- * drift from the layout the way an independently-versioned copy of the contract would.
13
- *
14
- * Extracted from the `loops` repo (`src/top-model.ts`), which held a hand-joined copy of the
15
- * layout. Rendering is deliberately unchanged: raw ANSI, zero dependencies.
16
- *
17
- * This is the OPERATOR view: what is on disk right now, for a human watching a workspace. It
18
- * carries no model-call identity, so its per-supervisor totals cannot be joined with root stream
19
- * events without double counting. A client that needs one execution's totals reads
20
- * `projectPursuit` from `../durable` instead.
8
+ * Read-only operator snapshots over the writer-owned supervisor layout and explicit durable runs.
9
+ * Workspace reads preserve legacy files; durable reads use discovery, journals and the canonical
10
+ * pursuit projection for model identity, failure and accounting evidence. Run totals count once.
11
+ * ANSI presentation lives in `./top-frame`.
21
12
  *
22
13
  * @experimental
23
14
  */
@@ -28,16 +19,9 @@ const emptySpend = {
28
19
  usd: 0,
29
20
  ms: 0
30
21
  };
31
- /**
32
- * Read every supervisor run under one workspace into a single point-in-time snapshot.
33
- *
34
- * Pure with respect to the process: it only reads, and it never throws for a writer mid-append.
35
- * An unreadable or half-written source is still skipped — an operator view must survive a live
36
- * writer — but every skip is reported as one bounded `TopSnapshotDiagnostic`, so a client can
37
- * tell a removed run from a partial read. `now` is injectable so elapsed time is deterministic
38
- * under test.
39
- */
40
- function loadTopSnapshot(rootDir, now = Date.now()) {
22
+ function loadTopSnapshot(rootDir, input = Date.now()) {
23
+ if (typeof input !== "number") return loadDurableTopSnapshot(rootDir, input.runDir, input.now ?? Date.now());
24
+ const now = input;
41
25
  const root = resolve(rootDir);
42
26
  const supervisors = [];
43
27
  const diagnostics = [];
@@ -58,25 +42,83 @@ function loadTopSnapshot(rootDir, now = Date.now()) {
58
42
  report(entry, state.diagnostics);
59
43
  if (!state.value) continue;
60
44
  const journal = readJournal(dir);
61
- const progress = readProgressTail(dir, 8);
45
+ const progress = readSourceFile(join(dir, "progress.ndjson"), "progress", "progress.ndjson");
62
46
  const workerEvents = readWorkerEventTails(supervisorWorkersDir(dir), 8);
63
47
  report(entry, [
64
48
  ...journal.diagnostics,
65
49
  ...progress.diagnostics,
66
50
  ...workerEvents.diagnostics
67
51
  ]);
68
- supervisors.push(buildSupervisorView(state.value, dir, journal.value, progress.value, now, workerEvents.value));
52
+ supervisors.push(buildSupervisorView(state.value, dir, journal.value, tailLines(progress.value, 8), now, workerEvents.value));
69
53
  }
70
54
  }
71
55
  supervisors.sort((a, b) => String(b.startedAt ?? "").localeCompare(String(a.startedAt ?? "")));
56
+ return topSnapshot(root, now, supervisors, diagnostics, discovered);
57
+ }
58
+ function topSnapshot(root, now, supervisors, diagnostics = [], discovered = 1, pursuit) {
72
59
  return {
73
60
  root,
74
61
  generatedAt: now,
75
62
  supervisors,
76
- completeness: diagnostics.length === 0 ? "complete" : "partial",
63
+ completeness: diagnostics.length ? "partial" : "complete",
77
64
  diagnostics,
78
65
  discovered,
79
- loaded: supervisors.length
66
+ loaded: supervisors.length,
67
+ ...pursuit ? { pursuit } : {}
68
+ };
69
+ }
70
+ async function loadDurableTopSnapshot(rootDir, runDir, now) {
71
+ const root = resolve(rootDir);
72
+ let pursuit;
73
+ let source = "observer-journal";
74
+ let path = "observer.jsonl";
75
+ try {
76
+ if (typeof runDir !== "string" || !runDir.trim()) throw new TypeError("runDir must be non-empty");
77
+ const journal = await FileObserverJournal.open(join(resolve(runDir), path));
78
+ if (!journal) return topSnapshot(root, now, [], [{
79
+ source,
80
+ path,
81
+ reason: "missing"
82
+ }]);
83
+ pursuit = projectPursuit(await journal.read());
84
+ source = "journal";
85
+ path = ".";
86
+ const discovery = await discoverDurableSupervisionRun(runDir);
87
+ const latest = new Map(pursuit.runs.map((run) => [run.runId, run]));
88
+ path = "spawn-journal.jsonl";
89
+ const spawnJournal = new FileSpawnJournal(discovery.spawnJournalPath);
90
+ return topSnapshot(root, now, await Promise.all([...latest.values()].map(async (run) => {
91
+ const binding = discovery.roots.find((id) => id === run.runId);
92
+ if (!binding) throw new Error("observer run has no discovered spawn root");
93
+ const events = await spawnJournal.loadTree(binding) ?? [];
94
+ const rootSpawn = events.find((event) => event.kind === "spawned" && event.id === binding);
95
+ const budget = rootSpawn?.kind === "spawned" ? rootSpawn.budget?.maxTokens : void 0;
96
+ return buildSupervisorView({
97
+ id: run.runId,
98
+ status: run.status,
99
+ task: run.runId,
100
+ workspaceDir: root,
101
+ budget: budget ?? 0,
102
+ budgetKnown: budget !== void 0,
103
+ startedAt: new Date(run.firstObservedAt).toISOString(),
104
+ ...run.settledAt === void 0 ? {} : { completedAt: new Date(run.settledAt).toISOString() }
105
+ }, discovery.runDir, events.filter(isSpawnEvent), run.error ? [run.error] : [], now, void 0, run);
106
+ })), [], 1, pursuit);
107
+ } catch (error) {
108
+ const reason = isRecord(error) && typeof error.code === "string" ? "unreadable" : "invalid-state";
109
+ return topSnapshot(root, now, [], [{
110
+ source,
111
+ path,
112
+ reason
113
+ }], 1, pursuit);
114
+ }
115
+ }
116
+ function observerSpend(spend, gaps = []) {
117
+ const parsed = parseSpend(spend);
118
+ return {
119
+ ...parsed,
120
+ usdKnown: spend !== void 0 && parsed.usdKnown !== false && !gaps.includes("usd"),
121
+ tokensKnown: spend !== void 0 && parsed.tokensKnown !== false && !gaps.includes("tokens")
80
122
  };
81
123
  }
82
124
  /**
@@ -119,15 +161,18 @@ function readJournal(eventDir) {
119
161
  }] : []
120
162
  };
121
163
  }
122
- function buildSupervisorView(state, stateDir, events, progressTail, now, workerEventTails = /* @__PURE__ */ new Map()) {
164
+ function buildSupervisorView(state, stateDir, events, progressTail, now, workerEventTails = /* @__PURE__ */ new Map(), accounting) {
123
165
  const workers = /* @__PURE__ */ new Map();
124
166
  let driverSpend = emptySpend;
125
167
  const journalRootId = events.find((event) => event.kind === "spawned" && !event.parent && event.label === "root")?.id;
126
168
  const isRoot = (id) => id === state.id || id === journalRootId;
127
169
  for (const event of events) {
170
+ if (isRoot(event.id) || event.kind === "spawned" && !event.parent && event.label === "root") {
171
+ if (event.kind === "metered" && event.accountingOnly !== true) driverSpend = addSpend(driverSpend, parseSpend(event.spend));
172
+ continue;
173
+ }
174
+ const worker = ensureWorker(workers, event.id);
128
175
  if (event.kind === "spawned") {
129
- if (isRoot(event.id) || !event.parent && event.label === "root") continue;
130
- const worker = ensureWorker(workers, event.id, event.label ?? event.id);
131
176
  worker.label = event.label ?? worker.label;
132
177
  if (event.parent) worker.parent = event.parent;
133
178
  if (event.runtime) worker.runtime = event.runtime;
@@ -135,47 +180,30 @@ function buildSupervisorView(state, stateDir, events, progressTail, now, workerE
135
180
  if (event.at) worker.startedAt = event.at;
136
181
  const budget = parseBudget(event.budget);
137
182
  if (budget) worker.budget = budget;
138
- continue;
139
- }
140
- if (event.kind === "settled") {
141
- if (isRoot(event.id)) continue;
142
- const worker = ensureWorker(workers, event.id, event.id);
143
- worker.status = event.status === "down" ? "down" : "done";
144
- if (event.at) worker.endedAt = event.at;
145
- if (event.outRef) worker.outRef = event.outRef;
146
- if (event.infra !== void 0) worker.infra = event.infra;
147
- const verdict = describeVerdict(event.verdict);
148
- if (verdict) worker.verdict = verdict;
149
- worker.spend = addSpend(worker.spend, parseSpend(event.spent));
150
- worker.metered = emptySpend;
151
- continue;
152
- }
153
- if (event.kind === "cancelled") {
154
- if (isRoot(event.id)) continue;
155
- const worker = ensureWorker(workers, event.id, event.id);
156
- worker.status = "cancelled";
183
+ } else if (event.kind === "settled" || event.kind === "cancelled") {
157
184
  if (event.at) worker.endedAt = event.at;
158
- if (event.reason) worker.reason = event.reason;
159
- if (event.spent !== void 0) {
185
+ if (event.kind === "settled") {
186
+ worker.status = event.status === "down" ? "down" : "done";
187
+ if (event.outRef) worker.outRef = event.outRef;
188
+ if (event.infra !== void 0) worker.infra = event.infra;
189
+ const verdict = describeVerdict(event.verdict);
190
+ if (verdict) worker.verdict = verdict;
191
+ } else {
192
+ worker.status = "cancelled";
193
+ if (event.reason) worker.reason = event.reason;
194
+ }
195
+ if (event.kind === "settled" || event.spent !== void 0) {
160
196
  worker.spend = addSpend(worker.spend, parseSpend(event.spent));
161
197
  worker.metered = emptySpend;
162
198
  }
163
- continue;
164
- }
165
- if (event.kind === "metered") {
166
- const spend = parseSpend(event.spend);
167
- if (isRoot(event.id)) {
168
- if (event.accountingOnly !== true) driverSpend = addSpend(driverSpend, spend);
169
- } else {
170
- const worker = ensureWorker(workers, event.id, event.id);
171
- if (event.accountingOnly !== true) worker.metered = addSpend(worker.metered, spend);
172
- }
173
- continue;
174
- }
175
- if (event.kind === "progress") {
176
- if (isRoot(event.id)) continue;
177
- const worker = ensureWorker(workers, event.id, event.id);
178
- worker.metered = parseSpend(event.spend);
199
+ } else if (event.kind === "progress") worker.metered = parseSpend(event.spend);
200
+ else if (event.accountingOnly !== true) worker.metered = addSpend(worker.metered, parseSpend(event.spend));
201
+ }
202
+ if (accounting) {
203
+ driverSpend = observerSpend(accounting.totals.exclusiveByNode[accounting.runId]);
204
+ for (const worker of workers.values()) {
205
+ worker.spend = observerSpend(accounting.totals.exclusiveByNode[worker.id], accounting.spendGaps?.find((gap) => gap.id === worker.id)?.channels);
206
+ worker.metered = emptySpend;
179
207
  }
180
208
  }
181
209
  const workerViews = [...workers.values()].map((worker) => {
@@ -185,6 +213,10 @@ function buildSupervisorView(state, stateDir, events, progressTail, now, workerE
185
213
  return finalizeWorker(worker, now);
186
214
  }).sort((a, b) => compareWorker(a, b));
187
215
  const totals = supervisorTotals(state, workerViews, driverSpend, now);
216
+ if (accounting) {
217
+ const spend = observerSpend(accounting.totals.inclusive, accounting.spendGaps?.flatMap((gap) => gap.channels));
218
+ Object.assign(totals, spend, { tokensTotal: spend.tokensInput + spend.tokensOutput });
219
+ }
188
220
  return {
189
221
  id: state.id,
190
222
  stateDir,
@@ -192,18 +224,23 @@ function buildSupervisorView(state, stateDir, events, progressTail, now, workerE
192
224
  task: state.task,
193
225
  workspaceDir: state.workspaceDir,
194
226
  budget: state.budget,
195
- ...state.verifyCmd ? { verifyCmd: state.verifyCmd } : {},
196
- ...state.workerModel ? { workerModel: state.workerModel } : {},
197
- ...state.driverModel ? { driverModel: state.driverModel } : {},
198
- ...state.verdict ? { verdict: state.verdict } : {},
199
- ...state.progress ? { progress: state.progress } : {},
200
- ...state.startedAt ? { startedAt: state.startedAt } : {},
201
- ...state.completedAt ? { completedAt: state.completedAt } : {},
202
- ...state.maxSandboxes !== void 0 ? { maxSandboxes: state.maxSandboxes } : {},
203
- ...state.maxLifetimeSeconds !== void 0 ? { maxLifetimeSeconds: state.maxLifetimeSeconds } : {},
204
- ...state.idleTimeoutSeconds !== void 0 ? { idleTimeoutSeconds: state.idleTimeoutSeconds } : {},
205
- ...state.maxUsd !== void 0 ? { maxUsd: state.maxUsd } : {},
206
- ...state.maxDepth !== void 0 ? { maxDepth: state.maxDepth } : {},
227
+ ...state.budgetKnown === void 0 ? {} : { budgetKnown: state.budgetKnown },
228
+ ...selectFields(state, [
229
+ "verifyCmd",
230
+ "workerModel",
231
+ "driverModel",
232
+ "verdict",
233
+ "progress",
234
+ "startedAt",
235
+ "completedAt"
236
+ ], Boolean),
237
+ ...selectFields(state, [
238
+ "maxSandboxes",
239
+ "maxLifetimeSeconds",
240
+ "idleTimeoutSeconds",
241
+ "maxUsd",
242
+ "maxDepth"
243
+ ], (value) => value !== void 0),
207
244
  ...state.result?.spentUsd !== void 0 ? { resultSpentUsd: state.result.spentUsd } : {},
208
245
  ...state.result?.spentTokens !== void 0 ? { resultSpentTokens: state.result.spentTokens } : {},
209
246
  workers: workerViews,
@@ -213,12 +250,17 @@ function buildSupervisorView(state, stateDir, events, progressTail, now, workerE
213
250
  totals
214
251
  };
215
252
  }
216
- function ensureWorker(workers, id, label) {
253
+ function selectFields(value, keys, include) {
254
+ const selected = {};
255
+ for (const key of keys) if (include(value[key])) selected[key] = value[key];
256
+ return selected;
257
+ }
258
+ function ensureWorker(workers, id) {
217
259
  const existing = workers.get(id);
218
260
  if (existing) return existing;
219
261
  const created = {
220
262
  id,
221
- label,
263
+ label: id,
222
264
  status: "running",
223
265
  spend: emptySpend,
224
266
  metered: emptySpend,
@@ -232,53 +274,43 @@ function finalizeWorker(worker, now) {
232
274
  const endMs = parseTime(worker.endedAt) ?? (worker.status === "running" ? now : startMs);
233
275
  const latencyMs = startMs !== void 0 && endMs !== void 0 ? Math.max(0, endMs - startMs) : 0;
234
276
  return {
235
- id: worker.id,
236
- label: worker.label,
237
- ...worker.eventFile ? { eventFile: worker.eventFile } : {},
238
- ...worker.parent ? { parent: worker.parent } : {},
239
- ...worker.runtime ? { runtime: worker.runtime } : {},
240
- status: worker.status,
241
- ...worker.verdict ? { verdict: worker.verdict } : {},
242
- ...worker.infra !== void 0 ? { infra: worker.infra } : {},
243
- ...worker.startedAt ? { startedAt: worker.startedAt } : {},
244
- ...worker.endedAt ? { endedAt: worker.endedAt } : {},
245
- latencyMs,
246
- ...worker.budget ? { budget: worker.budget } : {},
247
- spend: worker.spend,
248
- metered: worker.metered,
249
- liveTail: worker.liveTail,
250
- ...worker.outRef ? { outRef: worker.outRef } : {},
251
- ...worker.reason ? { reason: worker.reason } : {}
277
+ ...worker,
278
+ latencyMs
252
279
  };
253
280
  }
254
281
  function supervisorTotals(state, workers, driverSpend, now) {
255
- const workerSpends = workers.map(totalSpend);
256
- const tokenInput = sum(workerSpends.map((spend) => spend.tokensInput)) + driverSpend.tokensInput;
257
- const tokenOutput = sum(workerSpends.map((spend) => spend.tokensOutput)) + driverSpend.tokensOutput;
258
- const computedUsd = sum(workerSpends.map((spend) => spend.usd)) + driverSpend.usd;
259
- const usd = computedUsd > 0 ? computedUsd : state.result?.spentUsd ?? 0;
282
+ const spend = workers.map(totalSpend).reduce(addSpend, driverSpend);
283
+ const counts = {
284
+ running: 0,
285
+ done: 0,
286
+ down: 0,
287
+ cancelled: 0
288
+ };
289
+ for (const worker of workers) counts[worker.status] += 1;
260
290
  const started = parseTime(state.startedAt);
261
291
  const completed = parseTime(state.completedAt);
262
292
  const latencyMs = started !== void 0 ? Math.max(0, (completed ?? now) - started) : 0;
263
293
  const latencies = workers.map((worker) => worker.latencyMs).filter((ms) => ms > 0);
264
294
  return {
265
295
  workers: workers.length,
266
- running: workers.filter((worker) => worker.status === "running").length,
267
- done: workers.filter((worker) => worker.status === "done").length,
268
- down: workers.filter((worker) => worker.status === "down").length,
269
- cancelled: workers.filter((worker) => worker.status === "cancelled").length,
270
- inFlight: workers.filter((worker) => worker.status === "running").length,
271
- settled: workers.filter((worker) => worker.status !== "running").length,
272
- tokensInput: tokenInput,
273
- tokensOutput: tokenOutput,
274
- tokensTotal: tokenInput + tokenOutput,
275
- usd,
296
+ ...counts,
297
+ ...spend.usdKnown === false ? { usdKnown: false } : {},
298
+ ...spend.tokensKnown === false ? { tokensKnown: false } : {},
299
+ inFlight: counts.running,
300
+ settled: workers.length - counts.running,
301
+ tokensInput: spend.tokensInput,
302
+ tokensOutput: spend.tokensOutput,
303
+ tokensTotal: spend.tokensInput + spend.tokensOutput,
304
+ usd: spend.usd > 0 ? spend.usd : state.result?.spentUsd ?? 0,
276
305
  latencyMs,
277
306
  workerLatency: distribution(latencies)
278
307
  };
279
308
  }
280
309
  function aggregateSnapshot(snapshot) {
310
+ const complete = snapshot.completeness === "complete";
281
311
  return {
312
+ usdKnown: complete && snapshot.supervisors.every((row) => row.totals.usdKnown !== false),
313
+ tokensKnown: complete && snapshot.supervisors.every((row) => row.totals.tokensKnown !== false),
282
314
  supervisors: snapshot.supervisors.length,
283
315
  workers: sum(snapshot.supervisors.map((supervisor) => supervisor.totals.workers)),
284
316
  running: sum(snapshot.supervisors.map((supervisor) => supervisor.totals.running)),
@@ -305,13 +337,17 @@ function addSpend(a, b) {
305
337
  tokensInput: a.tokensInput + b.tokensInput,
306
338
  tokensOutput: a.tokensOutput + b.tokensOutput,
307
339
  usd: a.usd + b.usd,
308
- ms: a.ms + b.ms
340
+ ms: a.ms + b.ms,
341
+ ...a.usdKnown === false || b.usdKnown === false ? { usdKnown: false } : {},
342
+ ...a.tokensKnown === false || b.tokensKnown === false ? { tokensKnown: false } : {}
309
343
  };
310
344
  }
311
345
  function parseSpend(value) {
312
346
  if (!isRecord(value)) return emptySpend;
313
347
  const tokens = isRecord(value.tokens) ? value.tokens : {};
314
348
  return {
349
+ ...value.usdKnown === false ? { usdKnown: false } : {},
350
+ ...value.tokensKnown === false || tokens.tokensKnown === false ? { tokensKnown: false } : {},
315
351
  iterations: numberValue(value.iterations),
316
352
  tokensInput: numberValue(tokens.input),
317
353
  tokensOutput: numberValue(tokens.output),
@@ -334,13 +370,6 @@ function describeVerdict(value) {
334
370
  if (typeof value.score === "number") return `score ${value.score.toFixed(2)}`;
335
371
  }
336
372
  function distribution(values) {
337
- if (values.length === 0) return {
338
- n: 0,
339
- min: 0,
340
- median: 0,
341
- p90: 0,
342
- max: 0
343
- };
344
373
  const sorted = [...values].sort((a, b) => a - b);
345
374
  return {
346
375
  n: sorted.length,
@@ -384,14 +413,6 @@ function tailLines(raw, maxLines) {
384
413
  if (raw === void 0) return [];
385
414
  return raw.trim().split("\n").filter(Boolean).slice(-maxLines);
386
415
  }
387
- function readProgressTail(dir, maxLines) {
388
- const path = "progress.ndjson";
389
- const read = readSourceFile(join(dir, path), "progress", path);
390
- return {
391
- value: tailLines(read.value, maxLines),
392
- diagnostics: read.diagnostics
393
- };
394
- }
395
416
  function readWorkerEventTails(dir, maxLines) {
396
417
  const out = /* @__PURE__ */ new Map();
397
418
  if (!existsSync(dir)) return {
@@ -436,46 +457,42 @@ function readSupervisorState(dir) {
436
457
  value: void 0,
437
458
  diagnostics: read.diagnostics
438
459
  };
439
- if (read.value === void 0) return {
460
+ const failed = (reason) => ({
440
461
  value: void 0,
441
462
  diagnostics: [{
442
463
  source: "supervisor-state",
443
464
  path,
444
- reason: "missing"
465
+ reason
445
466
  }]
446
- };
447
- let parsed;
467
+ });
468
+ if (read.value === void 0) return failed("missing");
448
469
  try {
449
- parsed = JSON.parse(read.value);
470
+ const parsed = JSON.parse(read.value);
471
+ return isSupervisorState(parsed) ? {
472
+ value: parsed,
473
+ diagnostics: []
474
+ } : failed("invalid-state");
450
475
  } catch {
451
- return {
452
- value: void 0,
453
- diagnostics: [{
454
- source: "supervisor-state",
455
- path,
456
- reason: "partial-json"
457
- }]
458
- };
476
+ return failed("partial-json");
459
477
  }
460
- if (!isSupervisorState(parsed)) return {
461
- value: void 0,
462
- diagnostics: [{
463
- source: "supervisor-state",
464
- path,
465
- reason: "invalid-state"
466
- }]
467
- };
468
- return {
469
- value: parsed,
470
- diagnostics: []
471
- };
472
478
  }
473
479
  function isSupervisorState(value) {
474
- return value !== void 0 && typeof value.id === "string" && typeof value.status === "string" && typeof value.task === "string" && typeof value.workspaceDir === "string" && typeof value.budget === "number";
480
+ return isRecord(value) && Object.entries({
481
+ id: "string",
482
+ status: "string",
483
+ task: "string",
484
+ workspaceDir: "string",
485
+ budget: "number"
486
+ }).every(([key, type]) => typeof value[key] === type);
475
487
  }
476
488
  function isSpawnEvent(value) {
477
- if (!isRecord(value)) return false;
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";
489
+ return isRecord(value) && typeof value.id === "string" && typeof value.kind === "string" && [
490
+ "spawned",
491
+ "settled",
492
+ "cancelled",
493
+ "metered",
494
+ "progress"
495
+ ].includes(value.kind);
479
496
  }
480
497
  function isRecord(value) {
481
498
  return typeof value === "object" && value !== null;
@@ -500,4 +517,4 @@ function sum(values) {
500
517
  }
501
518
  export { parseTime as a, parseSpend as i, loadTopSnapshot as n, totalSpend as o, numberValue as r, aggregateSnapshot as t };
502
519
 
503
- //# sourceMappingURL=top-snapshot-ChwpTr7A.js.map
520
+ //# sourceMappingURL=top-snapshot-DcV7VG4m.js.map