@duckmind/dm-windows-x64 0.61.4 → 0.61.9

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 (279) hide show
  1. package/dm.exe +0 -0
  2. package/extensions/.dm-extensions.json +211 -67
  3. package/extensions/dm-subagents/agents/claude-code-writer.md +15 -0
  4. package/extensions/dm-subagents/agents/claude-code.md +15 -0
  5. package/extensions/dm-subagents/agents/codex-exec-writer.md +15 -0
  6. package/extensions/dm-subagents/agents/codex-exec.md +15 -0
  7. package/extensions/dm-subagents/agents/cursor-agent-writer.md +14 -0
  8. package/extensions/dm-subagents/agents/cursor-agent.md +14 -0
  9. package/extensions/dm-subagents/agents/delegate.md +3 -2
  10. package/extensions/dm-subagents/agents/oracle.md +10 -5
  11. package/extensions/dm-subagents/agents/researcher.md +2 -2
  12. package/extensions/dm-subagents/agents/reviewer.md +17 -7
  13. package/extensions/dm-subagents/agents/scout.md +5 -5
  14. package/extensions/dm-subagents/agents/worker.md +6 -2
  15. package/extensions/dm-subagents/async-retention-discovery-worker.mjs +167 -0
  16. package/extensions/dm-subagents/index.js +4 -0
  17. package/extensions/dm-subagents/inspector-runner.mjs +10 -0
  18. package/extensions/dm-subagents/install.mjs +3 -2
  19. package/extensions/dm-subagents/package.json +2 -2
  20. package/extensions/dm-subagents/prompts/council.md +60 -0
  21. package/extensions/dm-subagents/prompts/parallel-review.md +5 -1
  22. package/extensions/dm-subagents/prompts/review-loop.md +13 -7
  23. package/extensions/dm-subagents/skills/council-mode/SKILL.md +59 -0
  24. package/extensions/dm-subagents/skills/council-mode/references/pass-contracts.md +150 -0
  25. package/extensions/dm-subagents/skills/dm-subagents/SKILL.md +96 -911
  26. package/extensions/dm-subagents/skills/dm-subagents/references/constraints-and-recipes.md +70 -0
  27. package/extensions/dm-subagents/skills/dm-subagents/references/execution-controls.md +539 -0
  28. package/extensions/dm-subagents/skills/dm-subagents/references/management-authoring-rpc.md +161 -0
  29. package/extensions/dm-subagents/skills/dm-subagents/references/multi-lane-orchestration.md +51 -0
  30. package/extensions/dm-subagents/skills/dm-subagents/references/prompting-and-roles.md +295 -0
  31. package/extensions/dm-subagents/skills/dm-subagents/references/review-and-validation.md +73 -0
  32. package/extensions/dm-subagents/src/agents/agent-management.js +716 -484
  33. package/extensions/dm-subagents/src/agents/agent-refinements.js +563 -0
  34. package/extensions/dm-subagents/src/agents/agent-serializer.js +70 -5
  35. package/extensions/dm-subagents/src/agents/agents.js +1447 -299
  36. package/extensions/dm-subagents/src/agents/builtin-names.js +15 -0
  37. package/extensions/dm-subagents/src/agents/chain-serializer.js +12 -7
  38. package/extensions/dm-subagents/src/agents/frontmatter.js +64 -14
  39. package/extensions/dm-subagents/src/agents/identity.js +1 -1
  40. package/extensions/dm-subagents/src/agents/proactive-skills.js +14 -11
  41. package/extensions/dm-subagents/src/agents/runtime-agent-events.js +49 -0
  42. package/extensions/dm-subagents/src/agents/runtime-agent-registry.js +412 -0
  43. package/extensions/dm-subagents/src/agents/skills.js +52 -35
  44. package/extensions/dm-subagents/src/api/agents.js +6 -0
  45. package/extensions/dm-subagents/src/api/background-work.js +151 -0
  46. package/extensions/dm-subagents/src/api/capability-ceiling.js +12 -0
  47. package/extensions/dm-subagents/src/api/control-channel.js +3 -0
  48. package/extensions/dm-subagents/src/api/delegation.js +5 -0
  49. package/extensions/dm-subagents/src/api/dm-args.js +3 -0
  50. package/extensions/dm-subagents/src/api/external-job-provider.js +137 -0
  51. package/extensions/dm-subagents/src/api/external-runs.js +233 -0
  52. package/extensions/dm-subagents/src/api/intercom-bridge.js +3 -0
  53. package/extensions/dm-subagents/src/api/preflight.js +322 -0
  54. package/extensions/dm-subagents/src/api/project-panes.js +11 -0
  55. package/extensions/dm-subagents/src/api/shared-types.js +4 -0
  56. package/extensions/dm-subagents/src/extension/config.js +175 -0
  57. package/extensions/dm-subagents/src/extension/control-notices.js +4 -43
  58. package/extensions/dm-subagents/src/extension/doctor.js +71 -17
  59. package/extensions/dm-subagents/src/extension/fanout-child.js +49 -32
  60. package/extensions/dm-subagents/src/extension/index.js +711 -265
  61. package/extensions/dm-subagents/src/extension/public-execution.js +114 -0
  62. package/extensions/dm-subagents/src/extension/rpc.js +427 -22
  63. package/extensions/dm-subagents/src/extension/schemas.js +158 -65
  64. package/extensions/dm-subagents/src/extension/steering-notices.js +23 -0
  65. package/extensions/dm-subagents/src/extension/subagent-guide.js +31 -0
  66. package/extensions/dm-subagents/src/extension/tool-description.js +92 -74
  67. package/extensions/dm-subagents/src/extension/tool-result.js +7 -0
  68. package/extensions/dm-subagents/src/inspectors/herdr/actions.js +218 -0
  69. package/extensions/dm-subagents/src/inspectors/herdr/client.js +123 -0
  70. package/extensions/dm-subagents/src/inspectors/herdr/focus.js +47 -0
  71. package/extensions/dm-subagents/src/inspectors/herdr/inspector-runner.js +160 -0
  72. package/extensions/dm-subagents/src/inspectors/herdr/project-panes.js +618 -0
  73. package/extensions/dm-subagents/src/inspectors/herdr/session-roots-codec.js +21 -0
  74. package/extensions/dm-subagents/src/inspectors/herdr/shell-command.js +15 -0
  75. package/extensions/dm-subagents/src/integrations/herdr-status.js +377 -0
  76. package/extensions/dm-subagents/src/intercom/intercom-bridge.js +17 -13
  77. package/extensions/dm-subagents/src/intercom/native-supervisor-channel.js +371 -79
  78. package/extensions/dm-subagents/src/intercom/result-intercom.js +47 -7
  79. package/extensions/dm-subagents/src/missions/actions.js +394 -0
  80. package/extensions/dm-subagents/src/missions/goal-driver.js +149 -0
  81. package/extensions/dm-subagents/src/missions/lifecycle.js +331 -0
  82. package/extensions/dm-subagents/src/missions/store.js +548 -0
  83. package/extensions/dm-subagents/src/missions/types.js +9 -0
  84. package/extensions/dm-subagents/src/missions/workflow-state.js +245 -0
  85. package/extensions/dm-subagents/src/policy/authority.js +37 -0
  86. package/extensions/dm-subagents/src/profiles/profiles.js +36 -18
  87. package/extensions/dm-subagents/src/runs/background/active-async-capacity.js +427 -0
  88. package/extensions/dm-subagents/src/runs/background/active-run-index.js +122 -0
  89. package/extensions/dm-subagents/src/runs/background/async-execution.js +925 -137
  90. package/extensions/dm-subagents/src/runs/background/async-job-tracker.js +515 -148
  91. package/extensions/dm-subagents/src/runs/background/async-resume.js +378 -51
  92. package/extensions/dm-subagents/src/runs/background/async-retention.js +828 -0
  93. package/extensions/dm-subagents/src/runs/background/async-status-snapshot.js +31 -0
  94. package/extensions/dm-subagents/src/runs/background/async-status.js +259 -22
  95. package/extensions/dm-subagents/src/runs/background/auto-drain.js +46 -0
  96. package/extensions/dm-subagents/src/runs/background/chain-append.js +50 -15
  97. package/extensions/dm-subagents/src/runs/background/chain-root-attachment.js +67 -12
  98. package/extensions/dm-subagents/src/runs/background/completion-batcher.js +5 -1
  99. package/extensions/dm-subagents/src/runs/background/completion-dedupe.js +3 -11
  100. package/extensions/dm-subagents/src/runs/background/completion-replay.js +245 -0
  101. package/extensions/dm-subagents/src/runs/background/control-channel.js +423 -36
  102. package/extensions/dm-subagents/src/runs/background/fleet-view.js +132 -59
  103. package/extensions/dm-subagents/src/runs/background/index-segment.js +38 -0
  104. package/extensions/dm-subagents/src/runs/background/inspect-rpc.js +373 -0
  105. package/extensions/dm-subagents/src/runs/background/notify.js +357 -57
  106. package/extensions/dm-subagents/src/runs/background/owned-process-tree.js +86 -0
  107. package/extensions/dm-subagents/src/runs/background/process-terminal.js +269 -0
  108. package/extensions/dm-subagents/src/runs/background/result-delivery-ownership.js +34 -0
  109. package/extensions/dm-subagents/src/runs/background/result-files.js +469 -0
  110. package/extensions/dm-subagents/src/runs/background/result-watcher.js +540 -75
  111. package/extensions/dm-subagents/src/runs/background/resume-guidance.js +44 -0
  112. package/extensions/dm-subagents/src/runs/background/retained-children.js +119 -0
  113. package/extensions/dm-subagents/src/runs/background/run-id-query.js +5 -0
  114. package/extensions/dm-subagents/src/runs/background/run-id-resolver.js +93 -9
  115. package/extensions/dm-subagents/src/runs/background/run-status.js +303 -32
  116. package/extensions/dm-subagents/src/runs/background/scheduled-runs.js +784 -376
  117. package/extensions/dm-subagents/src/runs/background/stale-run-reconciler.js +75 -34
  118. package/extensions/dm-subagents/src/runs/background/steering.js +221 -0
  119. package/extensions/dm-subagents/src/runs/background/subagent-runner.js +3106 -844
  120. package/extensions/dm-subagents/src/runs/background/subagent-wait.js +529 -0
  121. package/extensions/dm-subagents/src/runs/background/terminal-run-index.js +106 -0
  122. package/extensions/dm-subagents/src/runs/background/top-level-async.js +1 -1
  123. package/extensions/dm-subagents/src/runs/background/wait-completions.js +155 -0
  124. package/extensions/dm-subagents/src/runs/background/wait-config.js +46 -0
  125. package/extensions/dm-subagents/src/runs/background/wait-subscriptions.js +278 -0
  126. package/extensions/dm-subagents/src/runs/background/wait-tool.js +47 -0
  127. package/extensions/dm-subagents/src/runs/foreground/async-dismiss-action.js +81 -0
  128. package/extensions/dm-subagents/src/runs/foreground/async-steering-action.js +245 -0
  129. package/extensions/dm-subagents/src/runs/foreground/async-stop-action.js +74 -0
  130. package/extensions/dm-subagents/src/runs/foreground/execution.js +1401 -342
  131. package/extensions/dm-subagents/src/runs/foreground/foreground-control.js +133 -0
  132. package/extensions/dm-subagents/src/runs/foreground/foreground-history.js +148 -0
  133. package/extensions/dm-subagents/src/runs/foreground/prompt-audit.js +139 -0
  134. package/extensions/dm-subagents/src/runs/foreground/subagent-executor.js +4278 -1441
  135. package/extensions/dm-subagents/src/runs/foreground/workflow-detach-reconcile.js +278 -0
  136. package/extensions/dm-subagents/src/runs/foreground/workflow-foreground-steering.js +155 -0
  137. package/extensions/dm-subagents/src/runs/shared/abort-recovery.js +97 -0
  138. package/extensions/dm-subagents/src/runs/shared/acceptance.js +597 -148
  139. package/extensions/dm-subagents/src/runs/shared/agent-contract.js +35 -0
  140. package/extensions/dm-subagents/src/runs/shared/async-status-projection.js +472 -0
  141. package/extensions/dm-subagents/src/runs/shared/background-process-options.js +6 -0
  142. package/extensions/dm-subagents/src/runs/shared/capability-ceiling.js +175 -0
  143. package/extensions/dm-subagents/src/runs/shared/child-identity.js +32 -0
  144. package/extensions/dm-subagents/src/runs/shared/child-launch-plan.js +65 -0
  145. package/extensions/dm-subagents/src/runs/shared/child-protocol.js +447 -0
  146. package/extensions/dm-subagents/src/runs/shared/claude-code-adapter.js +120 -0
  147. package/extensions/dm-subagents/src/runs/shared/codex-exec-adapter.js +129 -0
  148. package/extensions/dm-subagents/src/runs/shared/completion-evidence.js +40 -0
  149. package/extensions/dm-subagents/src/runs/shared/completion-guard.js +140 -83
  150. package/extensions/dm-subagents/src/runs/shared/context-mode.js +38 -0
  151. package/extensions/dm-subagents/src/runs/shared/cursor-agent-adapter.js +101 -0
  152. package/extensions/dm-subagents/src/runs/shared/dm-args.js +445 -72
  153. package/extensions/dm-subagents/src/runs/shared/dm-spawn.js +27 -16
  154. package/extensions/dm-subagents/src/runs/shared/dynamic-fanout.js +19 -6
  155. package/extensions/dm-subagents/src/runs/shared/extension-bindings.js +81 -0
  156. package/extensions/dm-subagents/src/runs/shared/external-cli-contract.js +134 -0
  157. package/extensions/dm-subagents/src/runs/shared/external-cli-preflight.js +98 -0
  158. package/extensions/dm-subagents/src/runs/shared/external-cli-runner.js +419 -0
  159. package/extensions/dm-subagents/src/runs/shared/external-job-bridge.js +404 -0
  160. package/extensions/dm-subagents/src/runs/shared/external-job-runner.js +334 -0
  161. package/extensions/dm-subagents/src/runs/shared/fast-mode-extension.js +8 -0
  162. package/extensions/dm-subagents/src/runs/shared/host-step-status.js +228 -0
  163. package/extensions/dm-subagents/src/runs/shared/lane-metadata.js +104 -0
  164. package/extensions/dm-subagents/src/runs/shared/launch-cwd.js +17 -0
  165. package/extensions/dm-subagents/src/runs/shared/llm-intent-arbiter.js +190 -0
  166. package/extensions/dm-subagents/src/runs/shared/long-running-guard.js +48 -3
  167. package/extensions/dm-subagents/src/runs/shared/mcp-config-sources.js +387 -0
  168. package/extensions/dm-subagents/src/runs/shared/mcp-direct-tool-allowlist.js +212 -137
  169. package/extensions/dm-subagents/src/runs/shared/mcp-direct-tool-grant.js +131 -0
  170. package/extensions/dm-subagents/src/runs/shared/model-exclusions.js +207 -0
  171. package/extensions/dm-subagents/src/runs/shared/model-fallback.js +225 -55
  172. package/extensions/dm-subagents/src/runs/shared/model-scope.js +85 -28
  173. package/extensions/dm-subagents/src/runs/shared/mutation-evidence.js +182 -0
  174. package/extensions/dm-subagents/src/runs/shared/nested-events.js +264 -102
  175. package/extensions/dm-subagents/src/runs/shared/nested-render.js +15 -5
  176. package/extensions/dm-subagents/src/runs/shared/orca-progress-tabs.js +505 -0
  177. package/extensions/dm-subagents/src/runs/shared/parallel-handoff.js +653 -0
  178. package/extensions/dm-subagents/src/runs/shared/parallel-utils.js +29 -12
  179. package/extensions/dm-subagents/src/runs/shared/permissions.js +108 -0
  180. package/extensions/dm-subagents/src/runs/shared/process-signal.js +13 -0
  181. package/extensions/dm-subagents/src/runs/shared/run-fanout-budget.js +257 -0
  182. package/extensions/dm-subagents/src/runs/shared/run-history.js +133 -13
  183. package/extensions/dm-subagents/src/runs/shared/runtime-acknowledged-extensions.js +62 -0
  184. package/extensions/dm-subagents/src/runs/shared/session-lease.js +225 -0
  185. package/extensions/dm-subagents/src/runs/shared/single-output.js +129 -27
  186. package/extensions/dm-subagents/src/runs/shared/spawn-budget.js +95 -0
  187. package/extensions/dm-subagents/src/runs/shared/structured-output.js +129 -10
  188. package/extensions/dm-subagents/src/runs/shared/subagent-control.js +66 -11
  189. package/extensions/dm-subagents/src/runs/shared/subagent-prompt-runtime.js +548 -70
  190. package/extensions/dm-subagents/src/runs/shared/subagent-startup-retry.js +50 -0
  191. package/extensions/dm-subagents/src/runs/shared/task-intent.js +130 -0
  192. package/extensions/dm-subagents/src/runs/shared/tool-availability.js +59 -0
  193. package/extensions/dm-subagents/src/runs/shared/tool-budget.js +7 -5
  194. package/extensions/dm-subagents/src/runs/shared/tool-timeout.js +64 -0
  195. package/extensions/dm-subagents/src/runs/shared/usage-budget.js +74 -0
  196. package/extensions/dm-subagents/src/runs/shared/workflow-graph.js +22 -0
  197. package/extensions/dm-subagents/src/runs/shared/worktree-cleanup-plan.js +721 -0
  198. package/extensions/dm-subagents/src/runs/shared/worktree.js +168 -19
  199. package/extensions/dm-subagents/src/shared/accessible-dir.js +35 -0
  200. package/extensions/dm-subagents/src/shared/agent-stream-options.js +3 -0
  201. package/extensions/dm-subagents/src/shared/artifacts.js +170 -11
  202. package/extensions/dm-subagents/src/shared/atomic-json.js +36 -38
  203. package/extensions/dm-subagents/src/shared/capacity-resilient-json.js +77 -0
  204. package/extensions/dm-subagents/src/shared/child-session-name.js +15 -0
  205. package/extensions/dm-subagents/src/shared/child-transcript.js +57 -2
  206. package/extensions/dm-subagents/src/shared/completion-owner.js +7 -0
  207. package/extensions/dm-subagents/src/shared/display-text.js +142 -0
  208. package/extensions/dm-subagents/src/shared/extension-context.js +17 -0
  209. package/extensions/dm-subagents/src/shared/file-coalescer.js +9 -0
  210. package/extensions/dm-subagents/src/shared/file-system-retry.js +56 -0
  211. package/extensions/dm-subagents/src/shared/fork-context.js +96 -33
  212. package/extensions/dm-subagents/src/shared/formatters.js +21 -7
  213. package/extensions/dm-subagents/src/shared/launch-contract.js +94 -0
  214. package/extensions/dm-subagents/src/shared/model-info.js +10 -5
  215. package/extensions/dm-subagents/src/shared/node-executable.js +19 -0
  216. package/extensions/dm-subagents/src/shared/prompt-resources.js +10 -0
  217. package/extensions/dm-subagents/src/shared/pruned-fork.js +427 -0
  218. package/extensions/dm-subagents/src/shared/session-file-trust.js +19 -0
  219. package/extensions/dm-subagents/src/shared/session-tokens.js +14 -3
  220. package/extensions/dm-subagents/src/shared/settings.js +39 -47
  221. package/extensions/dm-subagents/src/shared/shortcuts.js +16 -0
  222. package/extensions/dm-subagents/src/shared/status-format.js +9 -2
  223. package/extensions/dm-subagents/src/shared/thinking-ceiling.js +41 -0
  224. package/extensions/dm-subagents/src/shared/types.js +47 -7
  225. package/extensions/dm-subagents/src/shared/utf8.js +12 -0
  226. package/extensions/dm-subagents/src/shared/utils.js +151 -131
  227. package/extensions/dm-subagents/src/shared/watch-strategy.js +3 -0
  228. package/extensions/dm-subagents/src/shared/workflow-child-permit.js +84 -0
  229. package/extensions/dm-subagents/src/slash/delegation-adapters.js +274 -0
  230. package/extensions/dm-subagents/src/slash/delegation-json.js +113 -0
  231. package/extensions/dm-subagents/src/slash/delegation-request.js +152 -0
  232. package/extensions/dm-subagents/src/slash/prompt-template-bridge.js +294 -243
  233. package/extensions/dm-subagents/src/slash/prompt-workflows.js +35 -73
  234. package/extensions/dm-subagents/src/slash/selector.js +101 -0
  235. package/extensions/dm-subagents/src/slash/slash-bridge.js +17 -1
  236. package/extensions/dm-subagents/src/slash/slash-commands.js +722 -732
  237. package/extensions/dm-subagents/src/slash/slash-live-state.js +37 -19
  238. package/extensions/dm-subagents/src/slash/subagents-admin.js +410 -0
  239. package/extensions/dm-subagents/src/tui/fleet-status.js +824 -0
  240. package/extensions/dm-subagents/src/tui/fleet-transcript.js +479 -0
  241. package/extensions/dm-subagents/src/tui/fleet.js +1326 -0
  242. package/extensions/dm-subagents/src/tui/render-helpers.js +22 -0
  243. package/extensions/dm-subagents/src/tui/render.js +1511 -261
  244. package/extensions/dm-subagents/src/watchdog/change-signature.js +220 -0
  245. package/extensions/dm-subagents/src/watchdog/child-status.js +151 -0
  246. package/extensions/dm-subagents/src/watchdog/emission-guard.js +90 -0
  247. package/extensions/dm-subagents/src/watchdog/lsp-diagnostics.js +484 -0
  248. package/extensions/dm-subagents/src/watchdog/model-selection.js +154 -0
  249. package/extensions/dm-subagents/src/watchdog/permission-arbiter.js +138 -0
  250. package/extensions/dm-subagents/src/watchdog/register-child.js +112 -0
  251. package/extensions/dm-subagents/src/watchdog/register-main.js +419 -0
  252. package/extensions/dm-subagents/src/watchdog/render.js +54 -0
  253. package/extensions/dm-subagents/src/watchdog/review.js +251 -0
  254. package/extensions/dm-subagents/src/watchdog/runtime.js +803 -0
  255. package/extensions/dm-subagents/src/watchdog/scope.js +56 -0
  256. package/extensions/dm-subagents/src/watchdog/settings.js +515 -0
  257. package/extensions/dm-subagents/src/watchdog/tool-actions.js +151 -0
  258. package/extensions/dm-subagents/src/watchdog/turn-delta.js +169 -0
  259. package/extensions/dm-subagents/src/watchdog/types.js +29 -0
  260. package/extensions/dm-subagents/src/watchdog/warning-format.js +58 -0
  261. package/extensions/dm-subagents/src/workflows/chat-progress.js +116 -0
  262. package/extensions/dm-subagents/src/workflows/host-command.js +227 -0
  263. package/extensions/dm-subagents/src/workflows/scripted-workflow.js +2011 -0
  264. package/extensions/dm-subagents/src/workflows/workflow-child-summary.js +116 -0
  265. package/extensions/dm-subagents/src/workflows/workflow-preflight.js +243 -0
  266. package/extensions/dm-subagents/src/workflows/workflow-receipt.js +387 -0
  267. package/extensions/dm-subagents/src/workflows/workflow-settlement.js +189 -0
  268. package/package.json +4 -3
  269. package/extensions/dm-fff/package.json +0 -21
  270. package/extensions/dm-fff/src/index.js +0 -691
  271. package/extensions/dm-fff/src/query.js +0 -60
  272. package/extensions/dm-subagents/agents/context-builder.md +0 -46
  273. package/extensions/dm-subagents/agents/planner.md +0 -55
  274. package/extensions/dm-subagents/prompts/parallel-context-build.md +0 -55
  275. package/extensions/dm-subagents/prompts/parallel-handoff-plan.md +0 -61
  276. package/extensions/dm-subagents/src/runs/background/wait.js +0 -206
  277. package/extensions/dm-subagents/src/runs/foreground/chain-clarify.js +0 -1013
  278. package/extensions/dm-subagents/src/runs/foreground/chain-execution.js +0 -981
  279. package/extensions/dm-subagents/src/runs/shared/turn-budget.js +0 -50
@@ -2,8 +2,7 @@ import { randomUUID } from "node:crypto";
2
2
  import * as fs from "node:fs";
3
3
  import * as path from "node:path";
4
4
  import {
5
- ASYNC_DIR,
6
- RESULTS_DIR,
5
+ DIRS,
7
6
  TEMP_ROOT_DIR
8
7
  } from "../../shared/types.js";
9
8
  import { isSafeNestedPathId, parseNestedPathEnv, sanitizeNestedPath } from "./nested-path.js";
@@ -18,9 +17,12 @@ import {
18
17
  SUBAGENT_PARENT_RUN_ID_ENV
19
18
  } from "./dm-args.js";
20
19
  import { writeAtomicJson } from "../../shared/atomic-json.js";
20
+ import { sanitizeProcessTerminal } from "../background/process-terminal.js";
21
+ import { THINKING_LEVELS } from "../../shared/model-info.js";
21
22
  export const NESTED_EVENTS_DIR = path.join(TEMP_ROOT_DIR, "nested-subagent-events");
22
23
  const ROUTE_FILE = "route.json";
23
24
  const REGISTRY_FILE = "registry.json";
25
+ const ROUTE_INDEX_DIR = ".route-index";
24
26
  const MAX_EVENT_BYTES = 64 * 1024;
25
27
  const MAX_STEPS = 12;
26
28
  const MAX_CHILDREN = 16;
@@ -43,6 +45,15 @@ function containedPath(base, candidate) {
43
45
  function commonRouteRoot(route) {
44
46
  return path.dirname(path.resolve(route.eventSink));
45
47
  }
48
+ function routeIndexRoot() {
49
+ return path.join(NESTED_EVENTS_DIR, ROUTE_INDEX_DIR, "roots");
50
+ }
51
+ function routeIndexDir(rootRunId) {
52
+ return path.join(routeIndexRoot(), encodeURIComponent(rootRunId));
53
+ }
54
+ function routeIndexPath(rootRunId, capabilityToken) {
55
+ return path.join(routeIndexDir(rootRunId), `${encodeURIComponent(capabilityToken)}.json`);
56
+ }
46
57
  function validateRouteShape(route) {
47
58
  assertSafeId("rootRunId", route.rootRunId);
48
59
  assertSafeId("capabilityToken", route.capabilityToken);
@@ -61,8 +72,10 @@ export function createNestedRoute(rootRunId) {
61
72
  const controlInbox = path.join(routeRoot, "controls");
62
73
  fs.mkdirSync(eventSink, { recursive: true, mode: 448 });
63
74
  fs.mkdirSync(controlInbox, { recursive: true, mode: 448 });
64
- fs.writeFileSync(path.join(routeRoot, ROUTE_FILE), `${JSON.stringify({ rootRunId, capabilityToken, createdAt: Date.now() })}
65
- `, { mode: 384 });
75
+ const createdAt = Date.now();
76
+ fs.mkdirSync(routeIndexDir(rootRunId), { recursive: true, mode: 448 });
77
+ writeAtomicJson(routeIndexPath(rootRunId, capabilityToken), { rootRunId, capabilityToken, routeRoot: path.basename(routeRoot), createdAt });
78
+ writeAtomicJson(path.join(routeRoot, ROUTE_FILE), { rootRunId, capabilityToken, createdAt });
66
79
  return { rootRunId, eventSink, controlInbox, capabilityToken };
67
80
  }
68
81
  export function resolveNestedRouteFromEnv(env = process.env) {
@@ -121,7 +134,9 @@ function sanitizeTokenUsage(value) {
121
134
  const input = clampNumber(raw.input);
122
135
  const output = clampNumber(raw.output);
123
136
  const total = clampNumber(raw.total);
124
- return input !== undefined && output !== undefined && total !== undefined ? { input, output, total } : undefined;
137
+ const window = clampNumber(raw.window);
138
+ const windowPeak = clampNumber(raw.windowPeak);
139
+ return input !== undefined && output !== undefined && total !== undefined ? { input, output, total, ...window !== undefined ? { window } : {}, ...windowPeak !== undefined ? { windowPeak } : {} } : undefined;
125
140
  }
126
141
  function sanitizeCost(value) {
127
142
  if (!value || typeof value !== "object")
@@ -132,6 +147,56 @@ function sanitizeCost(value) {
132
147
  const costUsd = clampNumber(raw.costUsd);
133
148
  return inputTokens !== undefined && outputTokens !== undefined && costUsd !== undefined ? { inputTokens, outputTokens, costUsd } : undefined;
134
149
  }
150
+ function sanitizeLaunchResolvedExtensions(value) {
151
+ if (!value || typeof value !== "object")
152
+ return;
153
+ const raw = value;
154
+ if (raw.version !== 1 || raw.source !== "launch-resolved" || typeof raw.disableAmbientExtensions !== "boolean")
155
+ return;
156
+ const stringList = (input) => Array.isArray(input) ? input.filter((item) => typeof item === "string" && /^sha256:[a-f0-9]{16}$/.test(item)).slice(0, 32) : [];
157
+ const omitted = raw.omitted && typeof raw.omitted === "object" ? raw.omitted : {};
158
+ const omittedCount = (key) => Math.max(0, Math.floor(clampNumber(omitted[key]) ?? 0));
159
+ return {
160
+ version: 1,
161
+ source: "launch-resolved",
162
+ disableAmbientExtensions: raw.disableAmbientExtensions,
163
+ runtime: stringList(raw.runtime),
164
+ configured: stringList(raw.configured),
165
+ effective: stringList(raw.effective),
166
+ omitted: {
167
+ runtime: omittedCount("runtime"),
168
+ configured: omittedCount("configured"),
169
+ effective: omittedCount("effective")
170
+ }
171
+ };
172
+ }
173
+ function sanitizeRuntimeAcknowledgedExtensions(value) {
174
+ if (!value || typeof value !== "object")
175
+ return;
176
+ const raw = value;
177
+ if (raw.version !== 1 || raw.source !== "child-runtime" || !Array.isArray(raw.ids))
178
+ return;
179
+ const ids = [];
180
+ const seen = new Set;
181
+ for (const item of raw.ids) {
182
+ if (typeof item !== "string" || item.length === 0 || item.length > 128 || !/^[A-Za-z0-9._:@+-]+$/.test(item) || item.includes("..") || item.includes("/") || item.includes("\\") || seen.has(item))
183
+ continue;
184
+ seen.add(item);
185
+ ids.push(item);
186
+ }
187
+ if (ids.length === 0)
188
+ return;
189
+ return {
190
+ version: 1,
191
+ source: "child-runtime",
192
+ ids: ids.slice(0, 32),
193
+ omitted: Math.max(0, ids.length - 32) + Math.max(0, Math.floor(clampNumber(raw.omitted) ?? 0))
194
+ };
195
+ }
196
+ function runtimeAcknowledgedEntry(value) {
197
+ const sanitized = sanitizeRuntimeAcknowledgedExtensions(value);
198
+ return sanitized ? { runtimeAcknowledgedExtensions: sanitized } : {};
199
+ }
135
200
  function sanitizeTurnBudget(value) {
136
201
  if (!value || typeof value !== "object")
137
202
  return;
@@ -139,7 +204,7 @@ function sanitizeTurnBudget(value) {
139
204
  const maxTurns = clampNumber(raw.maxTurns);
140
205
  const graceTurns = clampNumber(raw.graceTurns);
141
206
  const turnCount = clampNumber(raw.turnCount);
142
- const outcome = raw.outcome === "within-budget" || raw.outcome === "wrap-up-requested" || raw.outcome === "exceeded" ? raw.outcome : undefined;
207
+ const outcome = raw.outcome === "within-budget" || raw.outcome === "wrap-up-requested" || raw.outcome === "termination-deferred" || raw.outcome === "exceeded" ? raw.outcome : undefined;
143
208
  if (maxTurns === undefined || graceTurns === undefined || turnCount === undefined || !outcome)
144
209
  return;
145
210
  return {
@@ -148,11 +213,12 @@ function sanitizeTurnBudget(value) {
148
213
  turnCount,
149
214
  outcome,
150
215
  ...clampNumber(raw.wrapUpRequestedAtTurn) !== undefined ? { wrapUpRequestedAtTurn: clampNumber(raw.wrapUpRequestedAtTurn) } : {},
216
+ ...clampNumber(raw.terminationDeferredAtTurn) !== undefined ? { terminationDeferredAtTurn: clampNumber(raw.terminationDeferredAtTurn) } : {},
151
217
  ...clampNumber(raw.exceededAtTurn) !== undefined ? { exceededAtTurn: clampNumber(raw.exceededAtTurn) } : {}
152
218
  };
153
219
  }
154
220
  function sanitizeState(value, fallback) {
155
- return value === "queued" || value === "running" || value === "complete" || value === "failed" || value === "paused" ? value : fallback;
221
+ return value === "queued" || value === "running" || value === "complete" || value === "failed" || value === "partial" || value === "paused" || value === "stopped" ? value : fallback;
156
222
  }
157
223
  function sanitizeStep(input, depth) {
158
224
  if (!input || typeof input !== "object")
@@ -161,10 +227,15 @@ function sanitizeStep(input, depth) {
161
227
  const agent = stringValue(raw.agent, 128);
162
228
  if (!agent)
163
229
  return;
164
- const status = raw.status === "pending" || raw.status === "running" || raw.status === "complete" || raw.status === "completed" || raw.status === "failed" || raw.status === "paused" ? raw.status : "pending";
230
+ const status = raw.status === "pending" || raw.status === "running" || raw.status === "complete" || raw.status === "completed" || raw.status === "failed" || raw.status === "paused" || raw.status === "stopped" ? raw.status : "pending";
231
+ const model = stringValue(raw.model);
232
+ const thinking = THINKING_LEVELS.find((level) => level === raw.thinking);
165
233
  return {
166
234
  agent,
167
235
  status,
236
+ ...model ? { model } : {},
237
+ ...thinking ? { thinking } : {},
238
+ ...stringValue(raw.sessionName, 256) ? { sessionName: stringValue(raw.sessionName, 256) } : {},
168
239
  ...stringValue(raw.sessionFile, 2048) ? { sessionFile: stringValue(raw.sessionFile, 2048) } : {},
169
240
  ...raw.activityState === "active_long_running" || raw.activityState === "needs_attention" ? { activityState: raw.activityState } : {},
170
241
  ...clampNumber(raw.lastActivityAt) !== undefined ? { lastActivityAt: clampNumber(raw.lastActivityAt) } : {},
@@ -177,9 +248,12 @@ function sanitizeStep(input, depth) {
177
248
  ...clampNumber(raw.endedAt) !== undefined ? { endedAt: clampNumber(raw.endedAt) } : {},
178
249
  ...stringValue(raw.error, 1024) ? { error: stringValue(raw.error, 1024) } : {},
179
250
  ...raw.timedOut === true ? { timedOut: true } : {},
251
+ ...raw.stopped === true ? { stopped: true } : {},
180
252
  ...sanitizeTurnBudget(raw.turnBudget) ? { turnBudget: sanitizeTurnBudget(raw.turnBudget) } : {},
181
253
  ...raw.turnBudgetExceeded === true ? { turnBudgetExceeded: true } : {},
182
254
  ...raw.wrapUpRequested === true ? { wrapUpRequested: true } : {},
255
+ ...sanitizeLaunchResolvedExtensions(raw.launchResolvedExtensions) ? { launchResolvedExtensions: sanitizeLaunchResolvedExtensions(raw.launchResolvedExtensions) } : {},
256
+ ...sanitizeRuntimeAcknowledgedExtensions(raw.runtimeAcknowledgedExtensions) ? { runtimeAcknowledgedExtensions: sanitizeRuntimeAcknowledgedExtensions(raw.runtimeAcknowledgedExtensions) } : {},
183
257
  ...depth < MAX_DEPTH && Array.isArray(raw.children) ? { children: raw.children.map((child) => sanitizeSummary(child, depth + 1)).filter((child) => Boolean(child)).slice(0, MAX_CHILDREN) } : {}
184
258
  };
185
259
  }
@@ -201,6 +275,9 @@ export function sanitizeSummary(input, depth = 0) {
201
275
  depth: Math.min(Math.max(0, clampNumber(raw.depth) ?? 0), MAX_DEPTH),
202
276
  path: pathParts,
203
277
  state: sanitizeState(raw.state, "running"),
278
+ ...stringValue(raw.sessionName, 256) ? { sessionName: stringValue(raw.sessionName, 256) } : {},
279
+ ...stringValue(raw.model) ? { model: stringValue(raw.model) } : {},
280
+ ...THINKING_LEVELS.find((level) => level === raw.thinking) ? { thinking: THINKING_LEVELS.find((level) => level === raw.thinking) } : {},
204
281
  ...stringValue(raw.asyncDir, 2048) ? { asyncDir: stringValue(raw.asyncDir, 2048) } : {},
205
282
  ...clampNumber(raw.pid) !== undefined && clampNumber(raw.pid) > 0 && Number.isInteger(clampNumber(raw.pid)) ? { pid: clampNumber(raw.pid) } : {},
206
283
  ...stringValue(raw.sessionId, 256) ? { sessionId: stringValue(raw.sessionId, 256) } : {},
@@ -231,10 +308,13 @@ export function sanitizeSummary(input, depth = 0) {
231
308
  ...clampNumber(raw.timeoutMs) !== undefined ? { timeoutMs: clampNumber(raw.timeoutMs) } : {},
232
309
  ...clampNumber(raw.deadlineAt) !== undefined ? { deadlineAt: clampNumber(raw.deadlineAt) } : {},
233
310
  ...raw.timedOut === true ? { timedOut: true } : {},
311
+ ...raw.stopped === true ? { stopped: true } : {},
234
312
  ...sanitizeTurnBudget(raw.turnBudget) ? { turnBudget: sanitizeTurnBudget(raw.turnBudget) } : {},
235
313
  ...raw.turnBudgetExceeded === true ? { turnBudgetExceeded: true } : {},
236
314
  ...raw.wrapUpRequested === true ? { wrapUpRequested: true } : {},
237
315
  ...stringValue(raw.error, 1024) ? { error: stringValue(raw.error, 1024) } : {},
316
+ ...sanitizeLaunchResolvedExtensions(raw.launchResolvedExtensions) ? { launchResolvedExtensions: sanitizeLaunchResolvedExtensions(raw.launchResolvedExtensions) } : {},
317
+ ...sanitizeRuntimeAcknowledgedExtensions(raw.runtimeAcknowledgedExtensions) ? { runtimeAcknowledgedExtensions: sanitizeRuntimeAcknowledgedExtensions(raw.runtimeAcknowledgedExtensions) } : {},
238
318
  ...steps && steps.length > 0 ? { steps } : {},
239
319
  ...depth < MAX_DEPTH && Array.isArray(raw.children) ? { children: raw.children.map((child) => sanitizeSummary(child, depth + 1)).filter((child) => Boolean(child)).slice(0, MAX_CHILDREN) } : {}
240
320
  };
@@ -290,7 +370,38 @@ export function parseNestedEventRecords(content, route) {
290
370
  `) ? undefined : -1).map((line) => line.trim() ? parseRecord(line, route) : undefined).filter((event) => Boolean(event));
291
371
  }
292
372
  function terminal(state) {
293
- return state === "complete" || state === "failed" || state === "paused";
373
+ return state === "complete" || state === "failed" || state === "partial" || state === "paused" || state === "stopped";
374
+ }
375
+ function mergeBoundedChildren(existing, incoming) {
376
+ if (incoming === undefined)
377
+ return existing?.slice(0, MAX_CHILDREN);
378
+ const incomingById = new Map(incoming.map((child) => [child.id, child]));
379
+ const merged = (existing ?? []).map((child) => incomingById.get(child.id) ?? child);
380
+ for (const child of incoming) {
381
+ if (!existing?.some((prior) => prior.id === child.id))
382
+ merged.push(child);
383
+ }
384
+ return merged.slice(0, MAX_CHILDREN);
385
+ }
386
+ function mergeStepSummary(existing, incoming) {
387
+ if (!existing || existing.agent !== incoming.agent)
388
+ return { ...incoming, ...incoming.children ? { children: incoming.children.slice(0, MAX_CHILDREN) } : {} };
389
+ const metadata = { ...existing };
390
+ delete metadata.status;
391
+ delete metadata.activityState;
392
+ delete metadata.lastActivityAt;
393
+ delete metadata.currentTool;
394
+ delete metadata.currentToolStartedAt;
395
+ delete metadata.currentPath;
396
+ delete metadata.turnCount;
397
+ delete metadata.toolCount;
398
+ delete metadata.children;
399
+ const children = mergeBoundedChildren(existing.children, incoming.children);
400
+ return {
401
+ ...metadata,
402
+ ...incoming,
403
+ ...children ? { children } : {}
404
+ };
294
405
  }
295
406
  function mergeSummary(existing, event) {
296
407
  const incomingState = event.type === "subagent.nested.completed" && event.child.state === "running" ? "complete" : event.child.state;
@@ -305,7 +416,18 @@ function mergeSummary(existing, event) {
305
416
  return existing;
306
417
  if (terminal(existing.state) && terminal(incoming.state) && incomingUpdate === existingUpdate)
307
418
  return existing;
308
- return { ...existing, ...incoming, state: incoming.state, lastUpdate: Math.max(existingUpdate, incomingUpdate) };
419
+ const existingSteps = existing.steps ?? [];
420
+ const incomingSteps = incoming.steps;
421
+ const steps = incomingSteps === undefined ? existing.steps : Array.from({ length: Math.min(MAX_STEPS, Math.max(existingSteps.length, incomingSteps.length)) }, (_, index) => incomingSteps[index] ? mergeStepSummary(existingSteps[index], incomingSteps[index]) : existingSteps[index]).filter((step) => Boolean(step));
422
+ const children = mergeBoundedChildren(existing.children, incoming.children);
423
+ return {
424
+ ...existing,
425
+ ...incoming,
426
+ ...steps ? { steps } : {},
427
+ ...children ? { children } : {},
428
+ state: incoming.state,
429
+ lastUpdate: Math.max(existingUpdate, incomingUpdate)
430
+ };
309
431
  }
310
432
  function attachChild(children, event) {
311
433
  let updated = false;
@@ -340,67 +462,60 @@ export function applyNestedEvent(registry, event) {
340
462
  function registryPath(route) {
341
463
  return path.join(commonRouteRoot(route), REGISTRY_FILE);
342
464
  }
465
+ function routeFromIndexEntry(rootRunId, filePath) {
466
+ try {
467
+ const metadata = JSON.parse(fs.readFileSync(filePath, "utf-8"));
468
+ if (metadata.rootRunId !== rootRunId || typeof metadata.capabilityToken !== "string" || typeof metadata.routeRoot !== "string")
469
+ return;
470
+ const routeRoot = path.join(NESTED_EVENTS_DIR, path.basename(metadata.routeRoot));
471
+ const route = {
472
+ rootRunId,
473
+ eventSink: path.join(routeRoot, "events"),
474
+ controlInbox: path.join(routeRoot, "controls"),
475
+ capabilityToken: metadata.capabilityToken
476
+ };
477
+ validateRouteShape(route);
478
+ if (!fs.statSync(route.eventSink).isDirectory() || !fs.statSync(route.controlInbox).isDirectory())
479
+ return;
480
+ const routeFilePath = path.join(routeRoot, ROUTE_FILE);
481
+ try {
482
+ const routeFile = JSON.parse(fs.readFileSync(routeFilePath, "utf-8"));
483
+ if (routeFile.rootRunId !== rootRunId || routeFile.capabilityToken !== metadata.capabilityToken)
484
+ return;
485
+ } catch (error) {
486
+ if (error.code !== "ENOENT")
487
+ return;
488
+ try {
489
+ writeAtomicJson(routeFilePath, { rootRunId, capabilityToken: metadata.capabilityToken, createdAt: typeof metadata.createdAt === "number" ? metadata.createdAt : Date.now() });
490
+ } catch {}
491
+ }
492
+ return route;
493
+ } catch {
494
+ return;
495
+ }
496
+ }
343
497
  export function findNestedRouteForRootId(rootRunId) {
344
498
  assertSafeId("rootRunId", rootRunId);
345
499
  let entries;
346
500
  try {
347
- entries = fs.readdirSync(NESTED_EVENTS_DIR);
501
+ entries = fs.readdirSync(routeIndexDir(rootRunId));
348
502
  } catch (error) {
349
503
  if (error.code === "ENOENT")
350
504
  return;
351
505
  throw error;
352
506
  }
353
507
  for (const entry of entries) {
354
- if (!entry.startsWith(`${rootRunId}-`))
355
- continue;
356
- const routeRoot = path.join(NESTED_EVENTS_DIR, entry);
357
- try {
358
- const metadata = JSON.parse(fs.readFileSync(path.join(routeRoot, ROUTE_FILE), "utf-8"));
359
- if (metadata.rootRunId !== rootRunId || typeof metadata.capabilityToken !== "string")
360
- continue;
361
- const route = {
362
- rootRunId,
363
- eventSink: path.join(routeRoot, "events"),
364
- controlInbox: path.join(routeRoot, "controls"),
365
- capabilityToken: metadata.capabilityToken
366
- };
367
- validateRouteShape(route);
508
+ const route = routeFromIndexEntry(rootRunId, path.join(routeIndexDir(rootRunId), entry));
509
+ if (route)
368
510
  return route;
369
- } catch {
370
- continue;
371
- }
372
511
  }
373
512
  return;
374
513
  }
375
514
  export function buildNestedRouteIndex() {
376
- let entries;
377
- try {
378
- entries = fs.readdirSync(NESTED_EVENTS_DIR);
379
- } catch (error) {
380
- if (error.code === "ENOENT")
381
- return new Map;
382
- throw error;
383
- }
384
515
  const index = new Map;
385
- for (const entry of entries) {
386
- const routeRoot = path.join(NESTED_EVENTS_DIR, entry);
387
- try {
388
- const metadata = JSON.parse(fs.readFileSync(path.join(routeRoot, ROUTE_FILE), "utf-8"));
389
- if (typeof metadata.rootRunId !== "string" || typeof metadata.capabilityToken !== "string")
390
- continue;
391
- if (index.has(metadata.rootRunId))
392
- continue;
393
- const route = {
394
- rootRunId: metadata.rootRunId,
395
- eventSink: path.join(routeRoot, "events"),
396
- controlInbox: path.join(routeRoot, "controls"),
397
- capabilityToken: metadata.capabilityToken
398
- };
399
- validateRouteShape(route);
400
- index.set(metadata.rootRunId, route);
401
- } catch {
402
- continue;
403
- }
516
+ for (const route of listNestedRoutes()) {
517
+ if (!index.has(route.rootRunId))
518
+ index.set(route.rootRunId, route);
404
519
  }
405
520
  return index;
406
521
  }
@@ -442,29 +557,28 @@ function collectScopedNestedRuns(children, scope, output = []) {
442
557
  return output;
443
558
  }
444
559
  function listNestedRoutes() {
445
- let entries;
560
+ let rootEntries;
446
561
  try {
447
- entries = fs.readdirSync(NESTED_EVENTS_DIR);
562
+ rootEntries = fs.readdirSync(routeIndexRoot());
448
563
  } catch (error) {
449
564
  if (error.code === "ENOENT")
450
565
  return [];
451
566
  throw error;
452
567
  }
453
568
  const routes = [];
454
- for (const entry of entries) {
455
- const routeRoot = path.join(NESTED_EVENTS_DIR, entry);
569
+ for (const rootEntry of rootEntries) {
570
+ let rootRunId;
456
571
  try {
457
- const metadata = JSON.parse(fs.readFileSync(path.join(routeRoot, ROUTE_FILE), "utf-8"));
458
- if (typeof metadata.rootRunId !== "string" || typeof metadata.capabilityToken !== "string")
459
- continue;
460
- const route = {
461
- rootRunId: metadata.rootRunId,
462
- eventSink: path.join(routeRoot, "events"),
463
- controlInbox: path.join(routeRoot, "controls"),
464
- capabilityToken: metadata.capabilityToken
465
- };
466
- validateRouteShape(route);
467
- routes.push(route);
572
+ rootRunId = decodeURIComponent(rootEntry);
573
+ } catch {
574
+ continue;
575
+ }
576
+ try {
577
+ for (const entry of fs.readdirSync(path.join(routeIndexRoot(), rootEntry))) {
578
+ const route = routeFromIndexEntry(rootRunId, path.join(routeIndexRoot(), rootEntry, entry));
579
+ if (route)
580
+ routes.push(route);
581
+ }
468
582
  } catch {
469
583
  continue;
470
584
  }
@@ -534,7 +648,10 @@ export function projectNestedEvents(route) {
534
648
  } catch {
535
649
  continue;
536
650
  }
537
- for (const event of parseNestedEventRecords(content, route)) {
651
+ const records = parseNestedEventRecords(content, route);
652
+ if (records.length === 0)
653
+ continue;
654
+ for (const event of records) {
538
655
  registry = applyNestedEvent(registry, event);
539
656
  changed = true;
540
657
  }
@@ -542,8 +659,27 @@ export function projectNestedEvents(route) {
542
659
  changed = true;
543
660
  }
544
661
  if (changed) {
545
- registry = { ...registry, processedEvents: [...seen].slice(-1000) };
662
+ const processedEvents = [...seen];
663
+ const retainedEvents = processedEvents.slice(-1000);
664
+ const evictedEvents = processedEvents.slice(0, -1000);
665
+ registry = { ...registry, processedEvents: retainedEvents };
546
666
  writeAtomicJson(registryPath(route), registry);
667
+ for (const entry of evictedEvents) {
668
+ const eventPath = path.join(route.eventSink, entry);
669
+ if (!containedPath(route.eventSink, eventPath))
670
+ continue;
671
+ try {
672
+ const stat = fs.statSync(eventPath);
673
+ if (!stat.isFile() || stat.size > MAX_EVENT_BYTES)
674
+ continue;
675
+ const content = fs.readFileSync(eventPath, "utf-8");
676
+ const hasStatusRecord = parseNestedEventRecords(content, route).length > 0;
677
+ const hasControlResult = content.split(`
678
+ `).some((line) => line.trim() && parseControlResult(line.trim(), route));
679
+ if (hasStatusRecord && !hasControlResult)
680
+ fs.unlinkSync(eventPath);
681
+ } catch {}
682
+ }
547
683
  }
548
684
  return registry;
549
685
  }
@@ -695,38 +831,46 @@ export function writeNestedControlResult(route, result) {
695
831
  throw new Error("Nested control result failed validation.");
696
832
  writeRouteRecord(route.eventSink, sanitized.ts, sanitized);
697
833
  }
698
- export function readNestedControlResults(route) {
834
+ function readControlResultsFromFile(route, eventPath) {
835
+ if (!containedPath(route.eventSink, eventPath))
836
+ return [];
837
+ try {
838
+ const stat = fs.statSync(eventPath);
839
+ if (!stat.isFile() || stat.size > MAX_EVENT_BYTES)
840
+ return [];
841
+ const content = fs.readFileSync(eventPath, "utf-8");
842
+ const lines = content.includes(`
843
+ `) ? content.split(`
844
+ `).filter((line) => line.trim()) : [content];
845
+ return lines.map((line) => parseControlResult(line, route)).filter((result) => Boolean(result));
846
+ } catch {
847
+ return [];
848
+ }
849
+ }
850
+ function listNestedEventFiles(route) {
699
851
  validateRouteShape(route);
700
- let entries = [];
701
852
  try {
702
- entries = fs.readdirSync(route.eventSink).filter((entry) => entry.endsWith(".json") || entry.endsWith(".jsonl")).sort();
853
+ return fs.readdirSync(route.eventSink).filter((entry) => entry.endsWith(".json") || entry.endsWith(".jsonl"));
703
854
  } catch (error) {
704
- if (error.code !== "ENOENT")
705
- throw error;
855
+ if (error.code === "ENOENT")
856
+ return [];
857
+ throw error;
706
858
  }
707
- const results = [];
859
+ }
860
+ export function snapshotNestedEventFiles(route) {
861
+ return new Set(listNestedEventFiles(route));
862
+ }
863
+ export function findNestedControlResult(route, requestId, targetRunId, ignoredFiles) {
864
+ const entries = listNestedEventFiles(route).filter((entry) => !ignoredFiles.has(entry)).sort().reverse();
708
865
  for (const entry of entries) {
709
- const eventPath = path.join(route.eventSink, entry);
710
- if (!containedPath(route.eventSink, eventPath))
711
- continue;
712
- try {
713
- const stat = fs.statSync(eventPath);
714
- if (!stat.isFile() || stat.size > MAX_EVENT_BYTES)
715
- continue;
716
- const content = fs.readFileSync(eventPath, "utf-8");
717
- const lines = content.includes(`
718
- `) ? content.split(`
719
- `).filter((line) => line.trim()) : [content];
720
- for (const line of lines) {
721
- const result = parseControlResult(line, route);
722
- if (result)
723
- results.push(result);
724
- }
725
- } catch {
726
- continue;
727
- }
866
+ const result = readControlResultsFromFile(route, path.join(route.eventSink, entry)).find((candidate) => candidate.requestId === requestId && candidate.targetRunId === targetRunId);
867
+ if (result)
868
+ return result;
728
869
  }
729
- return results;
870
+ return;
871
+ }
872
+ export function readNestedControlResults(route) {
873
+ return listNestedEventFiles(route).sort().flatMap((entry) => readControlResultsFromFile(route, path.join(route.eventSink, entry)));
730
874
  }
731
875
  export function nestedRouteEnv(route) {
732
876
  return {
@@ -791,6 +935,14 @@ export function nestedSummaryFromAsyncStatus(status, asyncDir, fallback) {
791
935
  ...status.pid ? { pid: status.pid } : {},
792
936
  ...status.sessionId ? { sessionId: status.sessionId } : {},
793
937
  mode: status.mode ?? fallback.mode,
938
+ ...status.steps?.length === 1 && status.steps[0]?.model ? { model: status.steps[0].model } : {},
939
+ ...status.steps?.length === 1 && status.steps[0]?.thinking ? { thinking: status.steps[0].thinking } : {},
940
+ ...status.steps?.length === 1 && status.steps[0]?.sessionName ? { sessionName: status.steps[0].sessionName } : {},
941
+ ...status.processTerminal ? { processTerminal: sanitizeProcessTerminal(status.processTerminal, { runId: status.runId || fallback.id, runnerProcessInstanceId: status.processTerminal.runnerProcessInstanceId }, `${asyncDir}/status.json`) } : {},
942
+ ...status.launchResolvedExtensions ? { launchResolvedExtensions: status.launchResolvedExtensions } : {},
943
+ ...runtimeAcknowledgedEntry(status.runtimeAcknowledgedExtensions),
944
+ ...status.capabilityCeiling ? { capabilityCeiling: status.capabilityCeiling } : {},
945
+ ...status.capabilityAudit ? { capabilityAudit: status.capabilityAudit } : {},
794
946
  state: status.state,
795
947
  ...status.currentStep !== undefined ? { currentStep: status.currentStep } : {},
796
948
  ...status.chainStepCount !== undefined ? { chainStepCount: status.chainStepCount } : {},
@@ -805,6 +957,7 @@ export function nestedSummaryFromAsyncStatus(status, asyncDir, fallback) {
805
957
  ...status.timeoutMs !== undefined ? { timeoutMs: status.timeoutMs } : {},
806
958
  ...status.deadlineAt !== undefined ? { deadlineAt: status.deadlineAt } : {},
807
959
  ...status.timedOut !== undefined ? { timedOut: status.timedOut } : {},
960
+ ...status.stopped !== undefined ? { stopped: status.stopped } : {},
808
961
  ...status.turnBudget ? { turnBudget: status.turnBudget } : {},
809
962
  ...status.turnBudgetExceeded !== undefined ? { turnBudgetExceeded: status.turnBudgetExceeded } : {},
810
963
  ...status.wrapUpRequested !== undefined ? { wrapUpRequested: status.wrapUpRequested } : {},
@@ -813,9 +966,12 @@ export function nestedSummaryFromAsyncStatus(status, asyncDir, fallback) {
813
966
  ...status.endedAt !== undefined ? { endedAt: status.endedAt } : {},
814
967
  lastUpdate: status.lastUpdate ?? fallback.ts,
815
968
  ...status.sessionFile ? { sessionFile: status.sessionFile } : {},
816
- ...status.steps?.length ? { steps: status.steps.map((step) => ({
969
+ ...status.steps?.length ? { steps: status.steps.map((step, index) => ({
817
970
  agent: step.agent,
971
+ ...step.sessionName ? { sessionName: step.sessionName } : {},
818
972
  status: step.status,
973
+ ...step.model ? { model: step.model } : {},
974
+ ...step.thinking ? { thinking: step.thinking } : {},
819
975
  ...step.sessionFile ? { sessionFile: step.sessionFile } : {},
820
976
  ...step.activityState ? { activityState: step.activityState } : {},
821
977
  ...step.lastActivityAt !== undefined ? { lastActivityAt: step.lastActivityAt } : {},
@@ -827,10 +983,16 @@ export function nestedSummaryFromAsyncStatus(status, asyncDir, fallback) {
827
983
  ...step.startedAt !== undefined ? { startedAt: step.startedAt } : {},
828
984
  ...step.endedAt !== undefined ? { endedAt: step.endedAt } : {},
829
985
  ...step.error ? { error: step.error } : {},
986
+ ...step.launchResolvedExtensions ? { launchResolvedExtensions: step.launchResolvedExtensions } : {},
987
+ ...runtimeAcknowledgedEntry(step.runtimeAcknowledgedExtensions),
830
988
  ...step.timedOut !== undefined ? { timedOut: step.timedOut } : {},
989
+ ...step.stopped !== undefined ? { stopped: step.stopped } : {},
831
990
  ...step.turnBudget ? { turnBudget: step.turnBudget } : {},
832
991
  ...step.turnBudgetExceeded !== undefined ? { turnBudgetExceeded: step.turnBudgetExceeded } : {},
833
- ...step.wrapUpRequested !== undefined ? { wrapUpRequested: step.wrapUpRequested } : {}
992
+ ...step.wrapUpRequested !== undefined ? { wrapUpRequested: step.wrapUpRequested } : {},
993
+ ...step.processTerminal ? { processTerminal: sanitizeProcessTerminal(step.processTerminal, { runId: status.runId || fallback.id, runnerProcessInstanceId: step.processTerminal.runnerProcessInstanceId }, `${asyncDir}/status.json step ${index}`) } : {},
994
+ ...step.capabilityCeiling ? { capabilityCeiling: step.capabilityCeiling } : {},
995
+ ...step.capabilityAudit ? { capabilityAudit: step.capabilityAudit } : {}
834
996
  })).slice(0, MAX_STEPS) } : {}
835
997
  };
836
998
  }
@@ -842,10 +1004,10 @@ export function nestedArtifactEnv(rootRunId, parentRunId) {
842
1004
  }
843
1005
  export function isTopLevelAsyncDir(asyncDir) {
844
1006
  const resolved = path.resolve(asyncDir);
845
- return containedPath(ASYNC_DIR, resolved) && !containedPath(path.join(TEMP_ROOT_DIR, "nested-subagent-runs"), resolved);
1007
+ return containedPath(DIRS.async, resolved) && !containedPath(path.join(TEMP_ROOT_DIR, "nested-subagent-runs"), resolved);
846
1008
  }
847
1009
  export function nestedResultsPath(rootRunId, id) {
848
1010
  assertSafeId("rootRunId", rootRunId);
849
1011
  assertSafeId("id", id);
850
- return path.join(RESULTS_DIR, "nested", rootRunId, `${id}.json`);
1012
+ return path.join(DIRS.results, "nested", rootRunId, `${id}.json`);
851
1013
  }
@@ -1,7 +1,7 @@
1
- import { formatDuration, formatTokens, shortenPath } from "../../shared/formatters.js";
1
+ import { formatDuration, formatModelThinking, formatTokenUsage, shortenPath } from "../../shared/formatters.js";
2
2
  import { formatActivityLabel } from "../../shared/status-format.js";
3
3
  export function countNestedRuns(children) {
4
- const counts = { total: 0, running: 0, paused: 0, complete: 0, failed: 0, queued: 0 };
4
+ const counts = { total: 0, running: 0, paused: 0, complete: 0, failed: 0, partial: 0, rejected: 0, stopped: 0, queued: 0 };
5
5
  for (const child of children ?? []) {
6
6
  counts.total++;
7
7
  counts[child.state]++;
@@ -11,6 +11,9 @@ export function countNestedRuns(children) {
11
11
  counts.paused += nested.paused;
12
12
  counts.complete += nested.complete;
13
13
  counts.failed += nested.failed;
14
+ counts.partial += nested.partial;
15
+ counts.rejected += nested.rejected;
16
+ counts.stopped += nested.stopped;
14
17
  counts.queued += nested.queued;
15
18
  }
16
19
  return counts;
@@ -23,12 +26,17 @@ export function formatNestedAggregate(children) {
23
26
  counts.running > 0 ? `${counts.running} running` : "",
24
27
  counts.paused > 0 ? `${counts.paused} paused` : "",
25
28
  counts.failed > 0 ? `${counts.failed} failed` : "",
29
+ counts.partial > 0 ? `${counts.partial} partial` : "",
30
+ counts.rejected > 0 ? `${counts.rejected} rejected` : "",
31
+ counts.stopped > 0 ? `${counts.stopped} stopped` : "",
26
32
  counts.complete > 0 ? `${counts.complete} complete` : "",
27
33
  counts.queued > 0 ? `${counts.queued} queued` : ""
28
34
  ].filter(Boolean);
29
35
  return `+${counts.total} nested run${counts.total === 1 ? "" : "s"}${parts.length ? ` (${parts.join(", ")})` : ""}`;
30
36
  }
31
37
  function nestedRunLabel(run) {
38
+ if (run.sessionName?.trim())
39
+ return run.sessionName.trim();
32
40
  if (run.agent)
33
41
  return run.agent;
34
42
  if (run.agents?.length)
@@ -48,7 +56,7 @@ function formatNestedActivity(input) {
48
56
  if (input.toolCount !== undefined)
49
57
  facts.push(`${input.toolCount} tools`);
50
58
  if (input.totalTokens)
51
- facts.push(`${formatTokens(input.totalTokens.total)} tok`);
59
+ facts.push(formatTokenUsage(input.totalTokens));
52
60
  const activity = formatActivityLabel(input.lastActivityAt, input.activityState);
53
61
  return activity || facts.length ? [activity, ...facts].filter(Boolean).join(" | ") : undefined;
54
62
  }
@@ -73,7 +81,8 @@ function formatNestedRunLines(children, options) {
73
81
  }
74
82
  const activity = child.state === "running" ? formatNestedActivity(child) : undefined;
75
83
  const error = child.error ? ` | error: ${child.error}` : "";
76
- lines.push(`${indent}↳ ${nestedRunLabel(child)} [${child.id}] ${child.state}${activity ? ` | ${activity}` : ""}${error}`);
84
+ const modelThinking = formatModelThinking(child.model, child.thinking);
85
+ lines.push(`${indent}↳ ${nestedRunLabel(child)} [${child.id}] ${child.state}${modelThinking ? ` | ${modelThinking}` : ""}${activity ? ` | ${activity}` : ""}${error}`);
77
86
  if (options.commandHints && lines.length < options.maxLines)
78
87
  lines.push(`${indent} Status: subagent({ action: "status", id: "${child.id}" })`);
79
88
  if (depth === options.maxDepth) {
@@ -86,7 +95,8 @@ function formatNestedRunLines(children, options) {
86
95
  if (lines.length >= options.maxLines)
87
96
  return;
88
97
  const stepActivity = step.status === "running" ? formatNestedActivity(step) : undefined;
89
- lines.push(`${indent} ${stepIndex + 1}. ${step.agent} ${step.status}${stepActivity ? ` | ${stepActivity}` : ""}${step.error ? ` | error: ${step.error}` : ""}`);
98
+ const stepModelThinking = formatModelThinking(step.model, step.thinking);
99
+ lines.push(`${indent} ${stepIndex + 1}. ${step.sessionName?.trim() || step.agent} ${step.status}${stepModelThinking ? ` | ${stepModelThinking}` : ""}${stepActivity ? ` | ${stepActivity}` : ""}${step.error ? ` | error: ${step.error}` : ""}`);
90
100
  append(step.children, depth + 1, `${indent} `);
91
101
  }
92
102
  append(child.children, depth + 1, `${indent} `);