@duckmind/dm-darwin-x64 0.66.5 → 0.66.6

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 (1115) hide show
  1. package/README.md +4 -0
  2. package/dm +2 -2
  3. package/extensions/.dm-extensions.json +755 -37
  4. package/extensions/dm-lens/clients/actionable-warnings.js +63 -11
  5. package/extensions/dm-lens/clients/advisory-provenance.js +5 -3
  6. package/extensions/dm-lens/clients/agent-nudge.js +106 -2
  7. package/extensions/dm-lens/clients/analysis-root.js +103 -0
  8. package/extensions/dm-lens/clients/ast-grep-client.js +18 -7
  9. package/extensions/dm-lens/clients/ast-grep-rule-manager.js +35 -12
  10. package/extensions/dm-lens/clients/biome-client.js +18 -12
  11. package/extensions/dm-lens/clients/blocker-freshness.js +1 -9
  12. package/extensions/dm-lens/clients/bounded-pid-file-lock.js +141 -30
  13. package/extensions/dm-lens/clients/bounded-telemetry.js +3 -0
  14. package/extensions/dm-lens/clients/cache/rule-cache.js +2 -17
  15. package/extensions/dm-lens/clients/cache-manager.js +105 -17
  16. package/extensions/dm-lens/clients/cargo-manifest.js +23 -3
  17. package/extensions/dm-lens/clients/complexity-client.js +1 -1
  18. package/extensions/dm-lens/clients/config-core/normalize.js +9 -0
  19. package/extensions/dm-lens/clients/config-core/schema.js +3 -0
  20. package/extensions/dm-lens/clients/config-schema.js +105 -2
  21. package/extensions/dm-lens/clients/confirmed-delete.js +11 -0
  22. package/extensions/dm-lens/clients/custom-rule-locations.js +28 -0
  23. package/extensions/dm-lens/clients/dead-code-client.js +81 -12
  24. package/extensions/dm-lens/clients/deferred-runner-blockers.js +108 -0
  25. package/extensions/dm-lens/clients/deferred-test-targets.js +31 -0
  26. package/extensions/dm-lens/clients/degradation-ledger.js +21 -3
  27. package/extensions/dm-lens/clients/demoted-finding-render.js +5 -2
  28. package/extensions/dm-lens/clients/dependency-checker.js +13 -4
  29. package/extensions/dm-lens/clients/diagnostic-line-freshness.js +3 -5
  30. package/extensions/dm-lens/clients/dispatch/adopted-root-runners.js +22 -0
  31. package/extensions/dm-lens/clients/dispatch/dispatcher.js +105 -27
  32. package/extensions/dm-lens/clients/dispatch/facts/comment-facts.js +5 -2
  33. package/extensions/dm-lens/clients/dispatch/facts/function-facts.js +1 -1
  34. package/extensions/dm-lens/clients/dispatch/facts/import-facts.js +2 -2
  35. package/extensions/dm-lens/clients/dispatch/facts/tree-sitter-facts.js +2 -2
  36. package/extensions/dm-lens/clients/dispatch/facts/try-catch-facts.js +1 -1
  37. package/extensions/dm-lens/clients/dispatch/finding-policy.js +12 -4
  38. package/extensions/dm-lens/clients/dispatch/integration.js +60 -15
  39. package/extensions/dm-lens/clients/dispatch/known-runner-ids.js +13 -0
  40. package/extensions/dm-lens/clients/dispatch/pending-runner-findings.js +66 -11
  41. package/extensions/dm-lens/clients/dispatch/plan.js +6 -0
  42. package/extensions/dm-lens/clients/dispatch/rule-id-normalize.js +9 -2
  43. package/extensions/dm-lens/clients/dispatch/rule-policy.js +33 -4
  44. package/extensions/dm-lens/clients/dispatch/runners/ast-grep-napi.js +9 -5
  45. package/extensions/dm-lens/clients/dispatch/runners/biome-check.js +5 -2
  46. package/extensions/dm-lens/clients/dispatch/runners/cue-vet.js +7 -3
  47. package/extensions/dm-lens/clients/dispatch/runners/detekt.js +3 -3
  48. package/extensions/dm-lens/clients/dispatch/runners/fact-rules.js +3 -3
  49. package/extensions/dm-lens/clients/dispatch/runners/fish-indent.js +10 -6
  50. package/extensions/dm-lens/clients/dispatch/runners/gleam-check.js +8 -5
  51. package/extensions/dm-lens/clients/dispatch/runners/go-vet.js +2 -1
  52. package/extensions/dm-lens/clients/dispatch/runners/lsp.js +28 -8
  53. package/extensions/dm-lens/clients/dispatch/runners/oxlint.js +2 -2
  54. package/extensions/dm-lens/clients/dispatch/runners/php-lint.js +6 -7
  55. package/extensions/dm-lens/clients/dispatch/runners/prisma-validate.js +18 -8
  56. package/extensions/dm-lens/clients/dispatch/runners/psscriptanalyzer.js +3 -3
  57. package/extensions/dm-lens/clients/dispatch/runners/pyright.js +1 -1
  58. package/extensions/dm-lens/clients/dispatch/runners/rust-clippy.js +25 -6
  59. package/extensions/dm-lens/clients/dispatch/runners/shellcheck.js +71 -4
  60. package/extensions/dm-lens/clients/dispatch/runners/shfmt.js +5 -1
  61. package/extensions/dm-lens/clients/dispatch/runners/spellcheck.js +3 -3
  62. package/extensions/dm-lens/clients/dispatch/runners/swiftlint.js +3 -3
  63. package/extensions/dm-lens/clients/dispatch/runners/taplo.js +17 -5
  64. package/extensions/dm-lens/clients/dispatch/runners/tree-sitter.js +12 -5
  65. package/extensions/dm-lens/clients/dispatch/runners/trivy-config.js +3 -3
  66. package/extensions/dm-lens/clients/dispatch/runners/utils/runner-helpers.js +127 -46
  67. package/extensions/dm-lens/clients/dispatch/runners/utils/tool-failure.js +11 -6
  68. package/extensions/dm-lens/clients/dispatch/runners/vale.js +3 -3
  69. package/extensions/dm-lens/clients/dispatch/runners/yaml-rule-parser.js +8 -1
  70. package/extensions/dm-lens/clients/dispatch/types.js +21 -1
  71. package/extensions/dm-lens/clients/dispatch/utils/format-utils.js +13 -0
  72. package/extensions/dm-lens/clients/effective-config.js +14 -3
  73. package/extensions/dm-lens/clients/ephemeral-root.js +71 -0
  74. package/extensions/dm-lens/clients/file-kinds.js +9 -0
  75. package/extensions/dm-lens/clients/file-mutation-queue.js +95 -0
  76. package/extensions/dm-lens/clients/file-utils.js +87 -8
  77. package/extensions/dm-lens/clients/finding-delivery-gate.js +5 -2
  78. package/extensions/dm-lens/clients/fix-run-restore.js +416 -0
  79. package/extensions/dm-lens/clients/format-events-publish.js +82 -2
  80. package/extensions/dm-lens/clients/format-service.js +10 -5
  81. package/extensions/dm-lens/clients/formatters.js +29 -12
  82. package/extensions/dm-lens/clients/generation-guard.js +50 -8
  83. package/extensions/dm-lens/clients/generation-lock.js +184 -0
  84. package/extensions/dm-lens/clients/git-guard.js +19 -1
  85. package/extensions/dm-lens/clients/gitleaks-client.js +13 -4
  86. package/extensions/dm-lens/clients/grammar-source.js +5 -0
  87. package/extensions/dm-lens/clients/grammar-wasm-imports.js +48 -0
  88. package/extensions/dm-lens/clients/gzip-stage-write.js +15 -7
  89. package/extensions/dm-lens/clients/hard-failure-summary.js +28 -0
  90. package/extensions/dm-lens/clients/hook-budgets.js +1 -0
  91. package/extensions/dm-lens/clients/inline-blocker-fields.js +8 -0
  92. package/extensions/dm-lens/clients/install-diagnostics.js +31 -16
  93. package/extensions/dm-lens/clients/installer/index.js +238 -58
  94. package/extensions/dm-lens/clients/instance-reaper.js +164 -52
  95. package/extensions/dm-lens/clients/instance-registry-lock.js +117 -76
  96. package/extensions/dm-lens/clients/instance-registry-tail.js +17 -0
  97. package/extensions/dm-lens/clients/instance-registry.js +248 -91
  98. package/extensions/dm-lens/clients/io-bridge-contract.js +7 -0
  99. package/extensions/dm-lens/clients/io-bridge.js +372 -0
  100. package/extensions/dm-lens/clients/jscpd-client.js +83 -35
  101. package/extensions/dm-lens/clients/knip-client.js +75 -6
  102. package/extensions/dm-lens/clients/knip-scan-roots.js +29 -0
  103. package/extensions/dm-lens/clients/language-policy.js +2 -0
  104. package/extensions/dm-lens/clients/language-profile.js +4 -1
  105. package/extensions/dm-lens/clients/language-registry.js +4 -1
  106. package/extensions/dm-lens/clients/latency-logger.js +11 -1
  107. package/extensions/dm-lens/clients/lens-config.js +10 -1
  108. package/extensions/dm-lens/clients/lens-engine.js +1 -1
  109. package/extensions/dm-lens/clients/lens-flag-registry.js +14 -24
  110. package/extensions/dm-lens/clients/lsp/aggregation.js +9 -8
  111. package/extensions/dm-lens/clients/lsp/auxiliary-lifecycle.js +23 -0
  112. package/extensions/dm-lens/clients/lsp/capabilities.js +98 -0
  113. package/extensions/dm-lens/clients/lsp/cascade-tier.js +8 -3
  114. package/extensions/dm-lens/clients/lsp/client.js +282 -48
  115. package/extensions/dm-lens/clients/lsp/config.js +247 -15
  116. package/extensions/dm-lens/clients/lsp/document-drift.js +23 -11
  117. package/extensions/dm-lens/clients/lsp/edits.js +137 -85
  118. package/extensions/dm-lens/clients/lsp/grouping.js +38 -0
  119. package/extensions/dm-lens/clients/lsp/index.js +484 -275
  120. package/extensions/dm-lens/clients/lsp/launch.js +106 -6
  121. package/extensions/dm-lens/clients/lsp/pending-aux-coverage.js +37 -7
  122. package/extensions/dm-lens/clients/lsp/resolved-config.js +188 -0
  123. package/extensions/dm-lens/clients/lsp/server-covers.js +8 -0
  124. package/extensions/dm-lens/clients/lsp/server-traits.js +39 -0
  125. package/extensions/dm-lens/clients/lsp/server.js +259 -34
  126. package/extensions/dm-lens/clients/lsp/service-singleton.js +59 -0
  127. package/extensions/dm-lens/clients/lsp/session-roots.js +1 -1
  128. package/extensions/dm-lens/clients/lsp/wait-policy/classification.js +2 -1
  129. package/extensions/dm-lens/clients/lsp/wait-policy/strategies.js +25 -4
  130. package/extensions/dm-lens/clients/lsp/workspace-diagnostics-cache.js +6 -3
  131. package/extensions/dm-lens/clients/lsp-budget.js +9 -5
  132. package/extensions/dm-lens/clients/lsp-document-symbols.js +1 -1
  133. package/extensions/dm-lens/clients/lsp-lazy.js +1 -1
  134. package/extensions/dm-lens/clients/lsp-mutation.js +44 -8
  135. package/extensions/dm-lens/clients/lsp-status.js +5 -7
  136. package/extensions/dm-lens/clients/mcp/analyze.js +24 -11
  137. package/extensions/dm-lens/clients/mcp/ipc.js +26 -7
  138. package/extensions/dm-lens/clients/mcp/session.js +1 -1
  139. package/extensions/dm-lens/clients/memory-sampler.js +48 -3
  140. package/extensions/dm-lens/clients/module-report-lsp.js +1 -1
  141. package/extensions/dm-lens/clients/module-report.js +9 -3
  142. package/extensions/dm-lens/clients/mutating-tool.js +12 -3
  143. package/extensions/dm-lens/clients/mutation-attribution.js +8 -0
  144. package/extensions/dm-lens/clients/mutation-bridge.js +181 -48
  145. package/extensions/dm-lens/clients/ndjson-logger.js +33 -0
  146. package/extensions/dm-lens/clients/observed-mutation-sources.js +1 -1
  147. package/extensions/dm-lens/clients/observed-mutation.js +40 -20
  148. package/extensions/dm-lens/clients/opaque-mutation-scan.js +40 -13
  149. package/extensions/dm-lens/clients/opengrep-client.js +6 -3
  150. package/extensions/dm-lens/clients/package-manager.js +61 -6
  151. package/extensions/dm-lens/clients/path-utils.js +77 -18
  152. package/extensions/dm-lens/clients/performance-report.js +1 -1
  153. package/extensions/dm-lens/clients/persist-worker-stats.js +8 -0
  154. package/extensions/dm-lens/clients/persistent-reverify.js +5 -1
  155. package/extensions/dm-lens/clients/pipeline.js +310 -114
  156. package/extensions/dm-lens/clients/probe-home-state.js +6 -1
  157. package/extensions/dm-lens/clients/process-bridge.js +28 -0
  158. package/extensions/dm-lens/clients/process-snapshot.js +115 -2
  159. package/extensions/dm-lens/clients/project-changes.js +81 -19
  160. package/extensions/dm-lens/clients/project-diagnostics/fresh-fetch.js +18 -13
  161. package/extensions/dm-lens/clients/project-lens-config.js +32 -5
  162. package/extensions/dm-lens/clients/project-scale.js +1 -1
  163. package/extensions/dm-lens/clients/project-snapshot-fingerprint.js +17 -12
  164. package/extensions/dm-lens/clients/project-snapshot-persist-worker.js +2 -3
  165. package/extensions/dm-lens/clients/project-snapshot.js +229 -64
  166. package/extensions/dm-lens/clients/python-environment.js +44 -2
  167. package/extensions/dm-lens/clients/quiet-window.js +6 -3
  168. package/extensions/dm-lens/clients/read-bridge.js +28 -20
  169. package/extensions/dm-lens/clients/read-expansion.js +1 -1
  170. package/extensions/dm-lens/clients/read-guard-branch.js +129 -0
  171. package/extensions/dm-lens/clients/read-guard-logger.js +11 -3
  172. package/extensions/dm-lens/clients/read-guard-tool-lines.js +16 -8
  173. package/extensions/dm-lens/clients/read-guard.js +516 -176
  174. package/extensions/dm-lens/clients/review-graph/builder.js +132 -54
  175. package/extensions/dm-lens/clients/review-graph/git-identity.js +59 -1
  176. package/extensions/dm-lens/clients/review-graph/import-resolvers.js +6 -8
  177. package/extensions/dm-lens/clients/runtime-agent-end.js +271 -68
  178. package/extensions/dm-lens/clients/runtime-coordinator.js +386 -74
  179. package/extensions/dm-lens/clients/runtime-session.js +174 -31
  180. package/extensions/dm-lens/clients/runtime-tool-call.js +92 -17
  181. package/extensions/dm-lens/clients/runtime-tool-result.js +477 -137
  182. package/extensions/dm-lens/clients/runtime-turn.js +949 -355
  183. package/extensions/dm-lens/clients/safe-spawn.js +12 -4
  184. package/extensions/dm-lens/clients/scanner-temp-root.js +8 -0
  185. package/extensions/dm-lens/clients/scratch-tree-policy.js +9 -0
  186. package/extensions/dm-lens/clients/search-read-registration.js +2 -1
  187. package/extensions/dm-lens/clients/session-lifecycle.js +120 -18
  188. package/extensions/dm-lens/clients/session-scope.js +456 -0
  189. package/extensions/dm-lens/clients/session-state-store.js +23 -20
  190. package/extensions/dm-lens/clients/sg-runner.js +24 -6
  191. package/extensions/dm-lens/clients/sgconfig.js +35 -5
  192. package/extensions/dm-lens/clients/startup-scan.js +10 -2
  193. package/extensions/dm-lens/clients/test-runner-client.js +258 -48
  194. package/extensions/dm-lens/clients/test-runner-delivery.js +46 -9
  195. package/extensions/dm-lens/clients/test-target-roots.js +20 -0
  196. package/extensions/dm-lens/clients/tool-agreement.js +282 -19
  197. package/extensions/dm-lens/clients/tool-config.js +1 -0
  198. package/extensions/dm-lens/clients/tool-event.js +6 -0
  199. package/extensions/dm-lens/clients/tool-probe.js +8 -0
  200. package/extensions/dm-lens/clients/tool-set-policy.js +36 -26
  201. package/extensions/dm-lens/clients/tree-sitter-client.js +304 -34
  202. package/extensions/dm-lens/clients/tree-sitter-query-loader.js +76 -2
  203. package/extensions/dm-lens/clients/tree-sitter-shared.js +2 -2
  204. package/extensions/dm-lens/clients/tree-sitter-symbol-extractor.js +3 -1
  205. package/extensions/dm-lens/clients/trivy-client.js +40 -7
  206. package/extensions/dm-lens/clients/turn-end/delivery-holds.js +59 -0
  207. package/extensions/dm-lens/clients/widget-state.js +36 -2
  208. package/extensions/dm-lens/clients/word-index.js +73 -5
  209. package/extensions/dm-lens/clients/workspace-topology.js +11 -4
  210. package/extensions/dm-lens/clients/write-ordering-guard.js +4 -0
  211. package/extensions/dm-lens/config/dependency-cruiser-eager-allowlist.json +9 -3
  212. package/extensions/dm-lens/dist/clients/actionable-warnings-logger.js +24 -0
  213. package/extensions/dm-lens/dist/clients/actionable-warnings.js +1062 -0
  214. package/extensions/dm-lens/dist/clients/advisory-provenance.js +387 -0
  215. package/extensions/dm-lens/dist/clients/agent-behavior-client.js +94 -0
  216. package/extensions/dm-lens/dist/clients/agent-nudge.js +253 -0
  217. package/extensions/dm-lens/dist/clients/analysed-root.js +1 -0
  218. package/extensions/dm-lens/dist/clients/analysis-root.js +100 -0
  219. package/extensions/dm-lens/dist/clients/ast-grep-client.js +587 -0
  220. package/extensions/dm-lens/dist/clients/ast-grep-rule-manager.js +137 -0
  221. package/extensions/dm-lens/dist/clients/ast-grep-tool-logger.js +85 -0
  222. package/extensions/dm-lens/dist/clients/ast-grep-types.js +1 -0
  223. package/extensions/dm-lens/dist/clients/ast-grep-yaml-synth.js +109 -0
  224. package/extensions/dm-lens/dist/clients/atomic-write-staging.js +66 -0
  225. package/extensions/dm-lens/dist/clients/atomic-write.js +37 -0
  226. package/extensions/dm-lens/dist/clients/availability-probe-flight.js +11 -0
  227. package/extensions/dm-lens/dist/clients/bash-file-access.js +830 -0
  228. package/extensions/dm-lens/dist/clients/biome-client.js +223 -0
  229. package/extensions/dm-lens/dist/clients/blocker-freshness.js +377 -0
  230. package/extensions/dm-lens/dist/clients/blocker-past-eof.js +49 -0
  231. package/extensions/dm-lens/dist/clients/bootstrap.js +246 -0
  232. package/extensions/dm-lens/dist/clients/bounded-cache.js +105 -0
  233. package/extensions/dm-lens/dist/clients/bounded-pid-file-lock.js +275 -0
  234. package/extensions/dm-lens/dist/clients/bounded-telemetry.js +107 -0
  235. package/extensions/dm-lens/dist/clients/build-identity.js +45 -0
  236. package/extensions/dm-lens/dist/clients/bundled-resource-health.js +41 -0
  237. package/extensions/dm-lens/dist/clients/bus-events-logger.js +48 -0
  238. package/extensions/dm-lens/dist/clients/bus-publish.js +117 -0
  239. package/extensions/dm-lens/dist/clients/cache/rule-cache.js +87 -0
  240. package/extensions/dm-lens/dist/clients/cache-manager.js +428 -0
  241. package/extensions/dm-lens/dist/clients/cache-observability.js +847 -0
  242. package/extensions/dm-lens/dist/clients/call-graph.js +628 -0
  243. package/extensions/dm-lens/dist/clients/cargo-manifest.js +171 -0
  244. package/extensions/dm-lens/dist/clients/cascade-budget.js +52 -0
  245. package/extensions/dm-lens/dist/clients/cascade-format.js +160 -0
  246. package/extensions/dm-lens/dist/clients/cascade-logger.js +22 -0
  247. package/extensions/dm-lens/dist/clients/cascade-types.js +1 -0
  248. package/extensions/dm-lens/dist/clients/child-unref.js +59 -0
  249. package/extensions/dm-lens/dist/clients/code-quality-warnings.js +192 -0
  250. package/extensions/dm-lens/dist/clients/codebase-model.js +110 -0
  251. package/extensions/dm-lens/dist/clients/collateral-test-role.js +8 -0
  252. package/extensions/dm-lens/dist/clients/complexity-client.js +398 -0
  253. package/extensions/dm-lens/dist/clients/config-core/deny.js +117 -0
  254. package/extensions/dm-lens/dist/clients/config-core/index.js +2 -0
  255. package/extensions/dm-lens/dist/clients/config-core/merge.js +228 -0
  256. package/extensions/dm-lens/dist/clients/config-core/normalize.js +226 -0
  257. package/extensions/dm-lens/dist/clients/config-core/process-spec.js +147 -0
  258. package/extensions/dm-lens/dist/clients/config-core/provenance.js +54 -0
  259. package/extensions/dm-lens/dist/clients/config-core/records.js +79 -0
  260. package/extensions/dm-lens/dist/clients/config-core/resolve.js +48 -0
  261. package/extensions/dm-lens/dist/clients/config-core/safe-object.js +22 -0
  262. package/extensions/dm-lens/dist/clients/config-core/schema.js +93 -0
  263. package/extensions/dm-lens/dist/clients/config-diagnostic-codes.js +90 -0
  264. package/extensions/dm-lens/dist/clients/config-locations.js +175 -0
  265. package/extensions/dm-lens/dist/clients/config-resolve.js +359 -0
  266. package/extensions/dm-lens/dist/clients/config-schema.js +230 -0
  267. package/extensions/dm-lens/dist/clients/config-warn.js +146 -0
  268. package/extensions/dm-lens/dist/clients/confirmed-delete.js +11 -0
  269. package/extensions/dm-lens/dist/clients/console-guard-install.js +4 -0
  270. package/extensions/dm-lens/dist/clients/cooperative-budget.js +36 -0
  271. package/extensions/dm-lens/dist/clients/custom-rule-locations.js +28 -0
  272. package/extensions/dm-lens/dist/clients/dead-code-client.js +408 -0
  273. package/extensions/dm-lens/dist/clients/dead-code-logger.js +18 -0
  274. package/extensions/dm-lens/dist/clients/deadline-utils.js +117 -0
  275. package/extensions/dm-lens/dist/clients/debug-handles.js +121 -0
  276. package/extensions/dm-lens/dist/clients/debug-heap.js +80 -0
  277. package/extensions/dm-lens/dist/clients/deferred-lsp-work.js +33 -0
  278. package/extensions/dm-lens/dist/clients/deferred-runner-blockers.js +106 -0
  279. package/extensions/dm-lens/dist/clients/deferred-test-targets.js +31 -0
  280. package/extensions/dm-lens/dist/clients/degradation-ledger.js +289 -0
  281. package/extensions/dm-lens/dist/clients/demoted-finding-render.js +64 -0
  282. package/extensions/dm-lens/dist/clients/dependency-checker.js +534 -0
  283. package/extensions/dm-lens/dist/clients/deps/ast-grep-napi.js +17 -0
  284. package/extensions/dm-lens/dist/clients/deps/dm-host-deps.js +10 -0
  285. package/extensions/dm-lens/dist/clients/deps/dm-tui-compat.js +58 -0
  286. package/extensions/dm-lens/dist/clients/deps/js-yaml.js +7 -0
  287. package/extensions/dm-lens/dist/clients/deps/minimatch.js +6 -0
  288. package/extensions/dm-lens/dist/clients/deps/pidusage.js +5 -0
  289. package/extensions/dm-lens/dist/clients/deps/typebox.js +5 -0
  290. package/extensions/dm-lens/dist/clients/deps/vscode-jsonrpc.js +8 -0
  291. package/extensions/dm-lens/dist/clients/deps/web-tree-sitter.js +11 -0
  292. package/extensions/dm-lens/dist/clients/diagnostic-dispositions.js +318 -0
  293. package/extensions/dm-lens/dist/clients/diagnostic-line-freshness.js +142 -0
  294. package/extensions/dm-lens/dist/clients/diagnostic-logger.js +60 -0
  295. package/extensions/dm-lens/dist/clients/diagnostic-tracker.js +89 -0
  296. package/extensions/dm-lens/dist/clients/diagnostics-publish.js +134 -0
  297. package/extensions/dm-lens/dist/clients/dispatch/adopted-root-runners.js +22 -0
  298. package/extensions/dm-lens/dist/clients/dispatch/ast-grep-catalog.js +16 -0
  299. package/extensions/dm-lens/dist/clients/dispatch/auxiliary-lsp.js +158 -0
  300. package/extensions/dm-lens/dist/clients/dispatch/collect-later-tier.js +25 -0
  301. package/extensions/dm-lens/dist/clients/dispatch/diagnostic-taxonomy.js +58 -0
  302. package/extensions/dm-lens/dist/clients/dispatch/dispatcher.js +1017 -0
  303. package/extensions/dm-lens/dist/clients/dispatch/fact-provider-types.js +1 -0
  304. package/extensions/dm-lens/dist/clients/dispatch/fact-rule-runner.js +17 -0
  305. package/extensions/dm-lens/dist/clients/dispatch/fact-runner.js +18 -0
  306. package/extensions/dm-lens/dist/clients/dispatch/fact-scheduler.js +52 -0
  307. package/extensions/dm-lens/dist/clients/dispatch/fact-store.js +199 -0
  308. package/extensions/dm-lens/dist/clients/dispatch/facts/comment-facts.js +23 -0
  309. package/extensions/dm-lens/dist/clients/dispatch/facts/file-content.js +18 -0
  310. package/extensions/dm-lens/dist/clients/dispatch/facts/function-facts.js +281 -0
  311. package/extensions/dm-lens/dist/clients/dispatch/facts/import-facts.js +169 -0
  312. package/extensions/dm-lens/dist/clients/dispatch/facts/tree-sitter-facts.js +19 -0
  313. package/extensions/dm-lens/dist/clients/dispatch/facts/try-catch-facts.js +95 -0
  314. package/extensions/dm-lens/dist/clients/dispatch/finding-policy.js +164 -0
  315. package/extensions/dm-lens/dist/clients/dispatch/indent-detect.js +227 -0
  316. package/extensions/dm-lens/dist/clients/dispatch/inline-suppressions.js +52 -0
  317. package/extensions/dm-lens/dist/clients/dispatch/integration.js +1502 -0
  318. package/extensions/dm-lens/dist/clients/dispatch/known-runner-ids.js +13 -0
  319. package/extensions/dm-lens/dist/clients/dispatch/lazy.js +8 -0
  320. package/extensions/dm-lens/dist/clients/dispatch/pending-runner-findings.js +130 -0
  321. package/extensions/dm-lens/dist/clients/dispatch/plan.js +284 -0
  322. package/extensions/dm-lens/dist/clients/dispatch/priorities.js +14 -0
  323. package/extensions/dm-lens/dist/clients/dispatch/rule-id-normalize.js +49 -0
  324. package/extensions/dm-lens/dist/clients/dispatch/rule-ignores.js +21 -0
  325. package/extensions/dm-lens/dist/clients/dispatch/rule-policy.js +102 -0
  326. package/extensions/dm-lens/dist/clients/dispatch/rules/async-noise.js +31 -0
  327. package/extensions/dm-lens/dist/clients/dispatch/rules/async-unnecessary-wrapper.js +27 -0
  328. package/extensions/dm-lens/dist/clients/dispatch/rules/cors-wildcard.js +35 -0
  329. package/extensions/dm-lens/dist/clients/dispatch/rules/error-obscuring.js +29 -0
  330. package/extensions/dm-lens/dist/clients/dispatch/rules/error-swallowing.js +29 -0
  331. package/extensions/dm-lens/dist/clients/dispatch/rules/framework-call-noise.js +31 -0
  332. package/extensions/dm-lens/dist/clients/dispatch/rules/high-complexity.js +56 -0
  333. package/extensions/dm-lens/dist/clients/dispatch/rules/high-fan-out.js +45 -0
  334. package/extensions/dm-lens/dist/clients/dispatch/rules/high-import-coupling.js +31 -0
  335. package/extensions/dm-lens/dist/clients/dispatch/rules/missing-error-propagation.js +45 -0
  336. package/extensions/dm-lens/dist/clients/dispatch/rules/no-commented-credentials.js +46 -0
  337. package/extensions/dm-lens/dist/clients/dispatch/rules/pass-through-wrappers.js +38 -0
  338. package/extensions/dm-lens/dist/clients/dispatch/rules/placeholder-comments.js +40 -0
  339. package/extensions/dm-lens/dist/clients/dispatch/rules/unsafe-boundary.js +101 -0
  340. package/extensions/dm-lens/dist/clients/dispatch/runner-context.js +46 -0
  341. package/extensions/dm-lens/dist/clients/dispatch/runners/actionlint.js +98 -0
  342. package/extensions/dm-lens/dist/clients/dispatch/runners/ast-grep-napi.js +694 -0
  343. package/extensions/dm-lens/dist/clients/dispatch/runners/biome-check.js +205 -0
  344. package/extensions/dm-lens/dist/clients/dispatch/runners/cpp-check.js +190 -0
  345. package/extensions/dm-lens/dist/clients/dispatch/runners/credo.js +66 -0
  346. package/extensions/dm-lens/dist/clients/dispatch/runners/cue-vet.js +171 -0
  347. package/extensions/dm-lens/dist/clients/dispatch/runners/dart-analyze.js +151 -0
  348. package/extensions/dm-lens/dist/clients/dispatch/runners/detekt.js +157 -0
  349. package/extensions/dm-lens/dist/clients/dispatch/runners/dotnet-build.js +157 -0
  350. package/extensions/dm-lens/dist/clients/dispatch/runners/elixir-check.js +153 -0
  351. package/extensions/dm-lens/dist/clients/dispatch/runners/eslint.js +99 -0
  352. package/extensions/dm-lens/dist/clients/dispatch/runners/fact-rules.js +20 -0
  353. package/extensions/dm-lens/dist/clients/dispatch/runners/fish-indent.js +66 -0
  354. package/extensions/dm-lens/dist/clients/dispatch/runners/gleam-check.js +110 -0
  355. package/extensions/dm-lens/dist/clients/dispatch/runners/go-vet.js +52 -0
  356. package/extensions/dm-lens/dist/clients/dispatch/runners/golangci-lint.js +89 -0
  357. package/extensions/dm-lens/dist/clients/dispatch/runners/hadolint.js +83 -0
  358. package/extensions/dm-lens/dist/clients/dispatch/runners/helm-lint.js +144 -0
  359. package/extensions/dm-lens/dist/clients/dispatch/runners/helm-render.js +593 -0
  360. package/extensions/dm-lens/dist/clients/dispatch/runners/htmlhint.js +103 -0
  361. package/extensions/dm-lens/dist/clients/dispatch/runners/index.js +100 -0
  362. package/extensions/dm-lens/dist/clients/dispatch/runners/javac.js +82 -0
  363. package/extensions/dm-lens/dist/clients/dispatch/runners/ktlint.js +93 -0
  364. package/extensions/dm-lens/dist/clients/dispatch/runners/lsp.js +226 -0
  365. package/extensions/dm-lens/dist/clients/dispatch/runners/markdownlint.js +129 -0
  366. package/extensions/dm-lens/dist/clients/dispatch/runners/mypy.js +70 -0
  367. package/extensions/dm-lens/dist/clients/dispatch/runners/oxlint.js +305 -0
  368. package/extensions/dm-lens/dist/clients/dispatch/runners/php-lint.js +66 -0
  369. package/extensions/dm-lens/dist/clients/dispatch/runners/phpstan.js +90 -0
  370. package/extensions/dm-lens/dist/clients/dispatch/runners/prisma-validate.js +66 -0
  371. package/extensions/dm-lens/dist/clients/dispatch/runners/psscriptanalyzer.js +307 -0
  372. package/extensions/dm-lens/dist/clients/dispatch/runners/pyright.js +118 -0
  373. package/extensions/dm-lens/dist/clients/dispatch/runners/rubocop.js +79 -0
  374. package/extensions/dm-lens/dist/clients/dispatch/runners/ruff.js +69 -0
  375. package/extensions/dm-lens/dist/clients/dispatch/runners/rust-clippy.js +166 -0
  376. package/extensions/dm-lens/dist/clients/dispatch/runners/shellcheck.js +177 -0
  377. package/extensions/dm-lens/dist/clients/dispatch/runners/shfmt.js +85 -0
  378. package/extensions/dm-lens/dist/clients/dispatch/runners/spellcheck.js +74 -0
  379. package/extensions/dm-lens/dist/clients/dispatch/runners/spotbugs.js +208 -0
  380. package/extensions/dm-lens/dist/clients/dispatch/runners/sqlfluff.js +136 -0
  381. package/extensions/dm-lens/dist/clients/dispatch/runners/stylelint.js +118 -0
  382. package/extensions/dm-lens/dist/clients/dispatch/runners/swiftlint.js +143 -0
  383. package/extensions/dm-lens/dist/clients/dispatch/runners/taplo.js +108 -0
  384. package/extensions/dm-lens/dist/clients/dispatch/runners/terragrunt.js +110 -0
  385. package/extensions/dm-lens/dist/clients/dispatch/runners/tflint.js +104 -0
  386. package/extensions/dm-lens/dist/clients/dispatch/runners/tree-sitter.js +521 -0
  387. package/extensions/dm-lens/dist/clients/dispatch/runners/trivy-config.js +155 -0
  388. package/extensions/dm-lens/dist/clients/dispatch/runners/utils/availability-policy.js +285 -0
  389. package/extensions/dm-lens/dist/clients/dispatch/runners/utils/candidate-probe.js +61 -0
  390. package/extensions/dm-lens/dist/clients/dispatch/runners/utils/diagnostic-parsers.js +61 -0
  391. package/extensions/dm-lens/dist/clients/dispatch/runners/utils/lazy-installer.js +130 -0
  392. package/extensions/dm-lens/dist/clients/dispatch/runners/utils/runner-helpers.js +1143 -0
  393. package/extensions/dm-lens/dist/clients/dispatch/runners/utils/spawn-outcome.js +40 -0
  394. package/extensions/dm-lens/dist/clients/dispatch/runners/utils/tool-failure.js +120 -0
  395. package/extensions/dm-lens/dist/clients/dispatch/runners/utils/toolchain-availability.js +88 -0
  396. package/extensions/dm-lens/dist/clients/dispatch/runners/utils.js +8 -0
  397. package/extensions/dm-lens/dist/clients/dispatch/runners/vale.js +106 -0
  398. package/extensions/dm-lens/dist/clients/dispatch/runners/yaml-rule-parser.js +170 -0
  399. package/extensions/dm-lens/dist/clients/dispatch/runners/yamllint.js +83 -0
  400. package/extensions/dm-lens/dist/clients/dispatch/runners/zig-check.js +72 -0
  401. package/extensions/dm-lens/dist/clients/dispatch/suppress-writer.js +57 -0
  402. package/extensions/dm-lens/dist/clients/dispatch/tool-profile.js +30 -0
  403. package/extensions/dm-lens/dist/clients/dispatch/types.js +27 -0
  404. package/extensions/dm-lens/dist/clients/dispatch/utils/format-utils.js +58 -0
  405. package/extensions/dm-lens/dist/clients/dispatch/utils/lsp-diagnostics.js +31 -0
  406. package/extensions/dm-lens/dist/clients/disposition-logger.js +19 -0
  407. package/extensions/dm-lens/dist/clients/disposition-publish.js +88 -0
  408. package/extensions/dm-lens/dist/clients/durable-store.js +77 -0
  409. package/extensions/dm-lens/dist/clients/effective-config.js +170 -0
  410. package/extensions/dm-lens/dist/clients/env-utils.js +26 -0
  411. package/extensions/dm-lens/dist/clients/ephemeral-root.js +67 -0
  412. package/extensions/dm-lens/dist/clients/error-class.js +3 -0
  413. package/extensions/dm-lens/dist/clients/eval-timestamp.js +2 -0
  414. package/extensions/dm-lens/dist/clients/event-loop-hold.js +119 -0
  415. package/extensions/dm-lens/dist/clients/event-loop-monitor.js +84 -0
  416. package/extensions/dm-lens/dist/clients/extension-log.js +230 -0
  417. package/extensions/dm-lens/dist/clients/extension-mode.js +20 -0
  418. package/extensions/dm-lens/dist/clients/feature-hints.js +88 -0
  419. package/extensions/dm-lens/dist/clients/file-kinds.js +313 -0
  420. package/extensions/dm-lens/dist/clients/file-mutation-queue.js +95 -0
  421. package/extensions/dm-lens/dist/clients/file-role.js +50 -0
  422. package/extensions/dm-lens/dist/clients/file-time.js +112 -0
  423. package/extensions/dm-lens/dist/clients/file-utils.js +706 -0
  424. package/extensions/dm-lens/dist/clients/finding-delivery-gate.js +132 -0
  425. package/extensions/dm-lens/dist/clients/finding-identity.js +23 -0
  426. package/extensions/dm-lens/dist/clients/fix-run-restore.js +413 -0
  427. package/extensions/dm-lens/dist/clients/fix-worklog.js +75 -0
  428. package/extensions/dm-lens/dist/clients/format-events-publish.js +310 -0
  429. package/extensions/dm-lens/dist/clients/format-service.js +159 -0
  430. package/extensions/dm-lens/dist/clients/formatters-lazy.js +8 -0
  431. package/extensions/dm-lens/dist/clients/formatters.js +1367 -0
  432. package/extensions/dm-lens/dist/clients/freshness-cadence.js +1 -0
  433. package/extensions/dm-lens/dist/clients/freshness.js +8 -0
  434. package/extensions/dm-lens/dist/clients/generated-artifacts.js +209 -0
  435. package/extensions/dm-lens/dist/clients/generation-guard.js +147 -0
  436. package/extensions/dm-lens/dist/clients/generation-lock.js +181 -0
  437. package/extensions/dm-lens/dist/clients/git-guard.js +786 -0
  438. package/extensions/dm-lens/dist/clients/git-tracked-ignore.js +120 -0
  439. package/extensions/dm-lens/dist/clients/gitleaks-client.js +290 -0
  440. package/extensions/dm-lens/dist/clients/go-client.js +47 -0
  441. package/extensions/dm-lens/dist/clients/govulncheck-client.js +411 -0
  442. package/extensions/dm-lens/dist/clients/gradle-ktfmt-style.js +177 -0
  443. package/extensions/dm-lens/dist/clients/grammar-source.js +229 -0
  444. package/extensions/dm-lens/dist/clients/grammar-wasm-imports.js +48 -0
  445. package/extensions/dm-lens/dist/clients/gzip-stage-write.js +93 -0
  446. package/extensions/dm-lens/dist/clients/hard-failure-summary.js +28 -0
  447. package/extensions/dm-lens/dist/clients/hashline-anchor.js +222 -0
  448. package/extensions/dm-lens/dist/clients/hook-budgets.js +17 -0
  449. package/extensions/dm-lens/dist/clients/host-edit-normalize.js +87 -0
  450. package/extensions/dm-lens/dist/clients/host-ports.js +35 -0
  451. package/extensions/dm-lens/dist/clients/indent-retarget.js +102 -0
  452. package/extensions/dm-lens/dist/clients/inline-blocker-dispositions.js +103 -0
  453. package/extensions/dm-lens/dist/clients/inline-blocker-fields.js +8 -0
  454. package/extensions/dm-lens/dist/clients/install-diagnostics.js +135 -0
  455. package/extensions/dm-lens/dist/clients/installer/index.js +3935 -0
  456. package/extensions/dm-lens/dist/clients/installer/managed-tool-refresh-session.js +17 -0
  457. package/extensions/dm-lens/dist/clients/installer/managed-tool-refresh.js +522 -0
  458. package/extensions/dm-lens/dist/clients/instance-reaper-state.js +3 -0
  459. package/extensions/dm-lens/dist/clients/instance-reaper.js +682 -0
  460. package/extensions/dm-lens/dist/clients/instance-registry-lock.js +166 -0
  461. package/extensions/dm-lens/dist/clients/instance-registry-tail.js +17 -0
  462. package/extensions/dm-lens/dist/clients/instance-registry.js +595 -0
  463. package/extensions/dm-lens/dist/clients/io-bridge-contract.js +7 -0
  464. package/extensions/dm-lens/dist/clients/io-bridge.js +357 -0
  465. package/extensions/dm-lens/dist/clients/jscpd-client.js +300 -0
  466. package/extensions/dm-lens/dist/clients/json-cache-read.js +25 -0
  467. package/extensions/dm-lens/dist/clients/knip-client.js +534 -0
  468. package/extensions/dm-lens/dist/clients/knip-scan-roots.js +26 -0
  469. package/extensions/dm-lens/dist/clients/language-policy.js +244 -0
  470. package/extensions/dm-lens/dist/clients/language-profile.js +263 -0
  471. package/extensions/dm-lens/dist/clients/language-registry.js +427 -0
  472. package/extensions/dm-lens/dist/clients/latency-logger.js +202 -0
  473. package/extensions/dm-lens/dist/clients/lazy-import.js +14 -0
  474. package/extensions/dm-lens/dist/clients/ledger-bounds.js +21 -0
  475. package/extensions/dm-lens/dist/clients/lens-config.js +246 -0
  476. package/extensions/dm-lens/dist/clients/lens-engine.js +181 -0
  477. package/extensions/dm-lens/dist/clients/lens-events.js +105 -0
  478. package/extensions/dm-lens/dist/clients/lens-flag-registry.js +292 -0
  479. package/extensions/dm-lens/dist/clients/lens-map.js +980 -0
  480. package/extensions/dm-lens/dist/clients/live-bus-emitter.js +53 -0
  481. package/extensions/dm-lens/dist/clients/log-cleanup.js +138 -0
  482. package/extensions/dm-lens/dist/clients/lsp/aggregation.js +89 -0
  483. package/extensions/dm-lens/dist/clients/lsp/auxiliary-lifecycle.js +23 -0
  484. package/extensions/dm-lens/dist/clients/lsp/capabilities.js +94 -0
  485. package/extensions/dm-lens/dist/clients/lsp/cascade-tier.js +208 -0
  486. package/extensions/dm-lens/dist/clients/lsp/client.js +2943 -0
  487. package/extensions/dm-lens/dist/clients/lsp/config.js +471 -0
  488. package/extensions/dm-lens/dist/clients/lsp/content-limits.js +21 -0
  489. package/extensions/dm-lens/dist/clients/lsp/diagnostic-binding.js +79 -0
  490. package/extensions/dm-lens/dist/clients/lsp/document-drift.js +324 -0
  491. package/extensions/dm-lens/dist/clients/lsp/edits.js +982 -0
  492. package/extensions/dm-lens/dist/clients/lsp/grouping.js +38 -0
  493. package/extensions/dm-lens/dist/clients/lsp/index.js +4639 -0
  494. package/extensions/dm-lens/dist/clients/lsp/inferred-project.js +121 -0
  495. package/extensions/dm-lens/dist/clients/lsp/jvm-runtime.js +194 -0
  496. package/extensions/dm-lens/dist/clients/lsp/language.js +23 -0
  497. package/extensions/dm-lens/dist/clients/lsp/launch.js +564 -0
  498. package/extensions/dm-lens/dist/clients/lsp/lombok.js +146 -0
  499. package/extensions/dm-lens/dist/clients/lsp/path-utils.js +1 -0
  500. package/extensions/dm-lens/dist/clients/lsp/pending-aux-coverage.js +120 -0
  501. package/extensions/dm-lens/dist/clients/lsp/position-encoding.js +28 -0
  502. package/extensions/dm-lens/dist/clients/lsp/resolved-config.js +183 -0
  503. package/extensions/dm-lens/dist/clients/lsp/ruby-drive-dirs.js +42 -0
  504. package/extensions/dm-lens/dist/clients/lsp/server-covers.js +8 -0
  505. package/extensions/dm-lens/dist/clients/lsp/server-traits.js +39 -0
  506. package/extensions/dm-lens/dist/clients/lsp/server.js +2640 -0
  507. package/extensions/dm-lens/dist/clients/lsp/service-singleton.js +59 -0
  508. package/extensions/dm-lens/dist/clients/lsp/session-roots.js +52 -0
  509. package/extensions/dm-lens/dist/clients/lsp/spawn-history.js +15 -0
  510. package/extensions/dm-lens/dist/clients/lsp/sync-kind.js +30 -0
  511. package/extensions/dm-lens/dist/clients/lsp/tsserver-sync.js +156 -0
  512. package/extensions/dm-lens/dist/clients/lsp/wait-policy/capability-snapshot.js +1 -0
  513. package/extensions/dm-lens/dist/clients/lsp/wait-policy/classification.js +37 -0
  514. package/extensions/dm-lens/dist/clients/lsp/wait-policy/index.js +3 -0
  515. package/extensions/dm-lens/dist/clients/lsp/wait-policy/strategies.js +196 -0
  516. package/extensions/dm-lens/dist/clients/lsp/watch-queue.js +40 -0
  517. package/extensions/dm-lens/dist/clients/lsp/workspace-diagnostics-cache.js +270 -0
  518. package/extensions/dm-lens/dist/clients/lsp/workspace-diagnostics-session.js +7 -0
  519. package/extensions/dm-lens/dist/clients/lsp/workspace-sweep-hold.js +93 -0
  520. package/extensions/dm-lens/dist/clients/lsp-budget.js +87 -0
  521. package/extensions/dm-lens/dist/clients/lsp-document-symbols.js +93 -0
  522. package/extensions/dm-lens/dist/clients/lsp-lazy.js +8 -0
  523. package/extensions/dm-lens/dist/clients/lsp-mutation.js +309 -0
  524. package/extensions/dm-lens/dist/clients/lsp-status.js +35 -0
  525. package/extensions/dm-lens/dist/clients/map-with-concurrency.js +20 -0
  526. package/extensions/dm-lens/dist/clients/mcp/analyze.js +265 -0
  527. package/extensions/dm-lens/dist/clients/mcp/host-shim.js +14 -0
  528. package/extensions/dm-lens/dist/clients/mcp/ipc.js +321 -0
  529. package/extensions/dm-lens/dist/clients/mcp/review.js +137 -0
  530. package/extensions/dm-lens/dist/clients/mcp/session.js +305 -0
  531. package/extensions/dm-lens/dist/clients/memory-sampler.js +145 -0
  532. package/extensions/dm-lens/dist/clients/message-end-attribution.js +18 -0
  533. package/extensions/dm-lens/dist/clients/metrics-client.js +80 -0
  534. package/extensions/dm-lens/dist/clients/metrics-history.js +255 -0
  535. package/extensions/dm-lens/dist/clients/middle-man-analysis.js +161 -0
  536. package/extensions/dm-lens/dist/clients/model-provider.js +31 -0
  537. package/extensions/dm-lens/dist/clients/module-report-lsp.js +140 -0
  538. package/extensions/dm-lens/dist/clients/module-report.js +1648 -0
  539. package/extensions/dm-lens/dist/clients/mutating-tool.js +386 -0
  540. package/extensions/dm-lens/dist/clients/mutation-attribution.js +176 -0
  541. package/extensions/dm-lens/dist/clients/mutation-bridge.js +231 -0
  542. package/extensions/dm-lens/dist/clients/ndjson-logger.js +504 -0
  543. package/extensions/dm-lens/dist/clients/observed-mutation-sources.js +43 -0
  544. package/extensions/dm-lens/dist/clients/observed-mutation.js +729 -0
  545. package/extensions/dm-lens/dist/clients/oldtext-autopatch.js +100 -0
  546. package/extensions/dm-lens/dist/clients/opaque-mutation-scan.js +340 -0
  547. package/extensions/dm-lens/dist/clients/opengrep-client.js +219 -0
  548. package/extensions/dm-lens/dist/clients/opengrep-config.js +52 -0
  549. package/extensions/dm-lens/dist/clients/package-manager.js +358 -0
  550. package/extensions/dm-lens/dist/clients/package-root.js +25 -0
  551. package/extensions/dm-lens/dist/clients/partial-edit-apply.js +337 -0
  552. package/extensions/dm-lens/dist/clients/path-attribution-telemetry.js +31 -0
  553. package/extensions/dm-lens/dist/clients/path-keyed-map.js +57 -0
  554. package/extensions/dm-lens/dist/clients/path-utils.js +535 -0
  555. package/extensions/dm-lens/dist/clients/performance-report.js +291 -0
  556. package/extensions/dm-lens/dist/clients/persist-debounce.js +37 -0
  557. package/extensions/dm-lens/dist/clients/persist-worker-stats.js +8 -0
  558. package/extensions/dm-lens/dist/clients/persistent-reverify.js +166 -0
  559. package/extensions/dm-lens/dist/clients/php-cs-fixer-config.js +15 -0
  560. package/extensions/dm-lens/dist/clients/pipeline.js +1279 -0
  561. package/extensions/dm-lens/dist/clients/post-autofix-notice.js +19 -0
  562. package/extensions/dm-lens/dist/clients/print-mode.js +3 -0
  563. package/extensions/dm-lens/dist/clients/probe-home-state.js +67 -0
  564. package/extensions/dm-lens/dist/clients/process-bridge.js +48 -0
  565. package/extensions/dm-lens/dist/clients/process-singletons.js +69 -0
  566. package/extensions/dm-lens/dist/clients/process-snapshot.js +130 -0
  567. package/extensions/dm-lens/dist/clients/project-changes.js +174 -0
  568. package/extensions/dm-lens/dist/clients/project-conventions.js +152 -0
  569. package/extensions/dm-lens/dist/clients/project-diagnostics/cache.js +91 -0
  570. package/extensions/dm-lens/dist/clients/project-diagnostics/extractors.js +53 -0
  571. package/extensions/dm-lens/dist/clients/project-diagnostics/fresh-fetch.js +413 -0
  572. package/extensions/dm-lens/dist/clients/project-diagnostics/runner-adapters/call-graph-impact.js +64 -0
  573. package/extensions/dm-lens/dist/clients/project-diagnostics/runner-adapters/dead-code.js +38 -0
  574. package/extensions/dm-lens/dist/clients/project-diagnostics/runner-adapters/gitleaks.js +21 -0
  575. package/extensions/dm-lens/dist/clients/project-diagnostics/runner-adapters/govulncheck.js +23 -0
  576. package/extensions/dm-lens/dist/clients/project-diagnostics/runner-adapters/jscpd.js +28 -0
  577. package/extensions/dm-lens/dist/clients/project-diagnostics/runner-adapters/knip.js +45 -0
  578. package/extensions/dm-lens/dist/clients/project-diagnostics/runner-adapters/madge.js +34 -0
  579. package/extensions/dm-lens/dist/clients/project-diagnostics/runner-adapters/opengrep.js +32 -0
  580. package/extensions/dm-lens/dist/clients/project-diagnostics/runner-adapters/runner-findings.js +79 -0
  581. package/extensions/dm-lens/dist/clients/project-diagnostics/runner-adapters/trivy.js +41 -0
  582. package/extensions/dm-lens/dist/clients/project-diagnostics/scanner.js +349 -0
  583. package/extensions/dm-lens/dist/clients/project-diagnostics/types.js +1 -0
  584. package/extensions/dm-lens/dist/clients/project-lens-config.js +464 -0
  585. package/extensions/dm-lens/dist/clients/project-report.js +527 -0
  586. package/extensions/dm-lens/dist/clients/project-scale.js +60 -0
  587. package/extensions/dm-lens/dist/clients/project-scan-policy.js +4 -0
  588. package/extensions/dm-lens/dist/clients/project-snapshot-fingerprint.js +44 -0
  589. package/extensions/dm-lens/dist/clients/project-snapshot-persist-worker.js +13 -0
  590. package/extensions/dm-lens/dist/clients/project-snapshot.js +1333 -0
  591. package/extensions/dm-lens/dist/clients/project-trust.js +104 -0
  592. package/extensions/dm-lens/dist/clients/python-environment.js +162 -0
  593. package/extensions/dm-lens/dist/clients/python-provenance.js +551 -0
  594. package/extensions/dm-lens/dist/clients/quiet-window-config.js +16 -0
  595. package/extensions/dm-lens/dist/clients/quiet-window.js +129 -0
  596. package/extensions/dm-lens/dist/clients/read-bridge.js +53 -0
  597. package/extensions/dm-lens/dist/clients/read-expansion.js +218 -0
  598. package/extensions/dm-lens/dist/clients/read-guard-branch.js +126 -0
  599. package/extensions/dm-lens/dist/clients/read-guard-logger.js +186 -0
  600. package/extensions/dm-lens/dist/clients/read-guard-tool-lines.js +1050 -0
  601. package/extensions/dm-lens/dist/clients/read-guard.js +1429 -0
  602. package/extensions/dm-lens/dist/clients/recent-touches.js +126 -0
  603. package/extensions/dm-lens/dist/clients/redact/secrets.js +386 -0
  604. package/extensions/dm-lens/dist/clients/resource-sampler.js +344 -0
  605. package/extensions/dm-lens/dist/clients/reverse-deps.js +227 -0
  606. package/extensions/dm-lens/dist/clients/review-graph/builder.js +3708 -0
  607. package/extensions/dm-lens/dist/clients/review-graph/format.js +30 -0
  608. package/extensions/dm-lens/dist/clients/review-graph/git-identity.js +168 -0
  609. package/extensions/dm-lens/dist/clients/review-graph/import-resolvers.js +323 -0
  610. package/extensions/dm-lens/dist/clients/review-graph/persist-worker.js +8 -0
  611. package/extensions/dm-lens/dist/clients/review-graph/query.js +195 -0
  612. package/extensions/dm-lens/dist/clients/review-graph/revision-drift.js +3 -0
  613. package/extensions/dm-lens/dist/clients/review-graph/service.js +60 -0
  614. package/extensions/dm-lens/dist/clients/review-graph/shared-extraction-ir.js +54 -0
  615. package/extensions/dm-lens/dist/clients/review-graph/symbol-id.js +29 -0
  616. package/extensions/dm-lens/dist/clients/review-graph/tsconfig-paths.js +253 -0
  617. package/extensions/dm-lens/dist/clients/review-graph/types.js +1 -0
  618. package/extensions/dm-lens/dist/clients/review-graph/workspace-modules.js +374 -0
  619. package/extensions/dm-lens/dist/clients/review-graph-logger.js +51 -0
  620. package/extensions/dm-lens/dist/clients/ruff-client.js +109 -0
  621. package/extensions/dm-lens/dist/clients/rules-scanner.js +113 -0
  622. package/extensions/dm-lens/dist/clients/run-duration.js +9 -0
  623. package/extensions/dm-lens/dist/clients/runtime-agent-end.js +800 -0
  624. package/extensions/dm-lens/dist/clients/runtime-config.js +39 -0
  625. package/extensions/dm-lens/dist/clients/runtime-context.js +155 -0
  626. package/extensions/dm-lens/dist/clients/runtime-coordinator.js +1117 -0
  627. package/extensions/dm-lens/dist/clients/runtime-session.js +1768 -0
  628. package/extensions/dm-lens/dist/clients/runtime-tool-call.js +935 -0
  629. package/extensions/dm-lens/dist/clients/runtime-tool-result.js +1630 -0
  630. package/extensions/dm-lens/dist/clients/runtime-turn.js +2900 -0
  631. package/extensions/dm-lens/dist/clients/rust-client.js +48 -0
  632. package/extensions/dm-lens/dist/clients/safe-spawn.js +1275 -0
  633. package/extensions/dm-lens/dist/clients/sanitize.js +174 -0
  634. package/extensions/dm-lens/dist/clients/scan-utils.js +7 -0
  635. package/extensions/dm-lens/dist/clients/scanner-temp-root.js +8 -0
  636. package/extensions/dm-lens/dist/clients/scratch-tree-policy.js +63 -0
  637. package/extensions/dm-lens/dist/clients/search-read-registration.js +60 -0
  638. package/extensions/dm-lens/dist/clients/secret-findings.js +69 -0
  639. package/extensions/dm-lens/dist/clients/security-scan-client.js +208 -0
  640. package/extensions/dm-lens/dist/clients/session-event-guard.js +111 -0
  641. package/extensions/dm-lens/dist/clients/session-lifecycle.js +269 -0
  642. package/extensions/dm-lens/dist/clients/session-scope.js +451 -0
  643. package/extensions/dm-lens/dist/clients/session-start-observability.js +47 -0
  644. package/extensions/dm-lens/dist/clients/session-state-store.js +66 -0
  645. package/extensions/dm-lens/dist/clients/session-summary.js +8 -0
  646. package/extensions/dm-lens/dist/clients/sessionstart-logger.js +22 -0
  647. package/extensions/dm-lens/dist/clients/sg-runner.js +645 -0
  648. package/extensions/dm-lens/dist/clients/sgconfig.js +306 -0
  649. package/extensions/dm-lens/dist/clients/shared-checkout-guard.js +177 -0
  650. package/extensions/dm-lens/dist/clients/single-flight.js +52 -0
  651. package/extensions/dm-lens/dist/clients/situational-tool-telemetry.js +85 -0
  652. package/extensions/dm-lens/dist/clients/skills-resolver.js +38 -0
  653. package/extensions/dm-lens/dist/clients/slow-fs.js +77 -0
  654. package/extensions/dm-lens/dist/clients/smells-rollup.js +118 -0
  655. package/extensions/dm-lens/dist/clients/source-filter.js +320 -0
  656. package/extensions/dm-lens/dist/clients/source-walker.js +96 -0
  657. package/extensions/dm-lens/dist/clients/spawn-output-cap.js +35 -0
  658. package/extensions/dm-lens/dist/clients/spawn-timeout-cooldown.js +51 -0
  659. package/extensions/dm-lens/dist/clients/stale-marker.js +1 -0
  660. package/extensions/dm-lens/dist/clients/startup-scan.js +230 -0
  661. package/extensions/dm-lens/dist/clients/startup-timing.js +67 -0
  662. package/extensions/dm-lens/dist/clients/string-utils.js +6 -0
  663. package/extensions/dm-lens/dist/clients/subagent-mode.js +40 -0
  664. package/extensions/dm-lens/dist/clients/symbol-containment.js +16 -0
  665. package/extensions/dm-lens/dist/clients/symbol-types.js +1 -0
  666. package/extensions/dm-lens/dist/clients/test-runner-client.js +1697 -0
  667. package/extensions/dm-lens/dist/clients/test-runner-delivery.js +293 -0
  668. package/extensions/dm-lens/dist/clients/test-target-roots.js +17 -0
  669. package/extensions/dm-lens/dist/clients/todo-scanner.js +164 -0
  670. package/extensions/dm-lens/dist/clients/tool-agreement.js +640 -0
  671. package/extensions/dm-lens/dist/clients/tool-config.js +219 -0
  672. package/extensions/dm-lens/dist/clients/tool-cwd.js +235 -0
  673. package/extensions/dm-lens/dist/clients/tool-definition.js +22 -0
  674. package/extensions/dm-lens/dist/clients/tool-event.js +24 -0
  675. package/extensions/dm-lens/dist/clients/tool-policy.js +2393 -0
  676. package/extensions/dm-lens/dist/clients/tool-probe.js +13 -0
  677. package/extensions/dm-lens/dist/clients/tool-render.js +79 -0
  678. package/extensions/dm-lens/dist/clients/tool-set-policy.js +77 -0
  679. package/extensions/dm-lens/dist/clients/tree-sitter-cache.js +206 -0
  680. package/extensions/dm-lens/dist/clients/tree-sitter-client.js +3057 -0
  681. package/extensions/dm-lens/dist/clients/tree-sitter-logger.js +77 -0
  682. package/extensions/dm-lens/dist/clients/tree-sitter-navigator.js +198 -0
  683. package/extensions/dm-lens/dist/clients/tree-sitter-query-loader.js +389 -0
  684. package/extensions/dm-lens/dist/clients/tree-sitter-shared.js +87 -0
  685. package/extensions/dm-lens/dist/clients/tree-sitter-symbol-extractor.js +959 -0
  686. package/extensions/dm-lens/dist/clients/trivy-client.js +335 -0
  687. package/extensions/dm-lens/dist/clients/tui-fit.js +26 -0
  688. package/extensions/dm-lens/dist/clients/turn-context.js +48 -0
  689. package/extensions/dm-lens/dist/clients/turn-end/delivery-holds.js +59 -0
  690. package/extensions/dm-lens/dist/clients/turn-end/lane.js +1 -0
  691. package/extensions/dm-lens/dist/clients/turn-end/lanes/govulncheck.js +54 -0
  692. package/extensions/dm-lens/dist/clients/turn-end/lanes/secrets.js +131 -0
  693. package/extensions/dm-lens/dist/clients/turn-summary-render.js +56 -0
  694. package/extensions/dm-lens/dist/clients/turn-summary.js +84 -0
  695. package/extensions/dm-lens/dist/clients/typos-config.js +9 -0
  696. package/extensions/dm-lens/dist/clients/user-notify.js +15 -0
  697. package/extensions/dm-lens/dist/clients/vanished-instance-marker.js +18 -0
  698. package/extensions/dm-lens/dist/clients/warm-attach.js +210 -0
  699. package/extensions/dm-lens/dist/clients/widget-state.js +997 -0
  700. package/extensions/dm-lens/dist/clients/word-index-logger.js +21 -0
  701. package/extensions/dm-lens/dist/clients/word-index-store.js +222 -0
  702. package/extensions/dm-lens/dist/clients/word-index.js +1494 -0
  703. package/extensions/dm-lens/dist/clients/workspace-topology.js +268 -0
  704. package/extensions/dm-lens/dist/clients/write-ordering-guard.js +28 -0
  705. package/extensions/dm-lens/dist/clients/zizmor-config.js +160 -0
  706. package/extensions/dm-lens/dist/i18n.js +67 -0
  707. package/extensions/dm-lens/dist/index.js +1973 -0
  708. package/extensions/dm-lens/dist/mcp/analyze-cli.js +205 -0
  709. package/extensions/dm-lens/dist/mcp/build-staleness.js +55 -0
  710. package/extensions/dm-lens/dist/mcp/cli.js +96 -0
  711. package/extensions/dm-lens/dist/mcp/server.js +1239 -0
  712. package/extensions/dm-lens/dist/mcp/tool-arguments.js +134 -0
  713. package/extensions/dm-lens/dist/mcp/worker.js +41 -0
  714. package/extensions/dm-lens/dist/scripts/lib/process-scan.mjs +375 -0
  715. package/extensions/dm-lens/dist/scripts/lib/skills-predicate.mjs +53 -0
  716. package/extensions/dm-lens/dist/scripts/lib/web-tree-sitter-dir.mjs +51 -0
  717. package/extensions/dm-lens/dist/tools/activate-tools.js +62 -0
  718. package/extensions/dm-lens/dist/tools/ast-grep-outline.js +126 -0
  719. package/extensions/dm-lens/dist/tools/ast-grep-replace.js +227 -0
  720. package/extensions/dm-lens/dist/tools/ast-grep-search.js +687 -0
  721. package/extensions/dm-lens/dist/tools/effective-config.js +59 -0
  722. package/extensions/dm-lens/dist/tools/lens-diagnostic-mark.js +251 -0
  723. package/extensions/dm-lens/dist/tools/lens-diagnostics.js +1518 -0
  724. package/extensions/dm-lens/dist/tools/lsp-diagnostics.js +1198 -0
  725. package/extensions/dm-lens/dist/tools/lsp-navigation.js +1249 -0
  726. package/extensions/dm-lens/dist/tools/lsp-structured-output.js +277 -0
  727. package/extensions/dm-lens/dist/tools/module-report.js +332 -0
  728. package/extensions/dm-lens/dist/tools/project-report.js +72 -0
  729. package/extensions/dm-lens/dist/tools/render-compact.js +272 -0
  730. package/extensions/dm-lens/dist/tools/scan-progress.js +31 -0
  731. package/extensions/dm-lens/dist/tools/shared.js +32 -0
  732. package/extensions/dm-lens/dist/tools/symbol-search.js +133 -0
  733. package/extensions/dm-lens/i18n.js +3 -3
  734. package/extensions/dm-lens/index.js +431 -214
  735. package/extensions/dm-lens/mcp/analyze-cli.js +63 -36
  736. package/extensions/dm-lens/mcp/cli.js +20 -0
  737. package/extensions/dm-lens/mcp/server.js +40 -3
  738. package/extensions/dm-lens/mcp/tool-arguments.js +134 -0
  739. package/extensions/dm-lens/mcp/worker.js +8 -0
  740. package/extensions/dm-lens/package.json +1 -1
  741. package/extensions/dm-lens/rules/ast-grep-rules/rule-tests/advisory-registry-subset-test.yml +41 -0
  742. package/extensions/dm-lens/rules/ast-grep-rules/rule-tests/no-identity-operator-on-literals-test.yml +12 -2
  743. package/extensions/dm-lens/rules/ast-grep-rules/rule-tests/throw-new-error-js-test.yml +2 -0
  744. package/extensions/dm-lens/rules/ast-grep-rules/rule-tests/throw-new-error-test.yml +2 -0
  745. package/extensions/dm-lens/rules/ast-grep-rules/rules/advisory-registry-subset.yml +50 -0
  746. package/extensions/dm-lens/rules/ast-grep-rules/rules/no-identity-operator-on-literals.yml +20 -12
  747. package/extensions/dm-lens/rules/ast-grep-rules/rules/throw-new-error-js.yml +2 -2
  748. package/extensions/dm-lens/rules/ast-grep-rules/rules/throw-new-error.yml +2 -2
  749. package/extensions/dm-lens/scripts/lib/process-scan.mjs +126 -7
  750. package/extensions/dm-lens/scripts/lib/web-tree-sitter-dir.mjs +6 -0
  751. package/extensions/dm-lens/tools/activate-tools.js +3 -2
  752. package/extensions/dm-lens/tools/ast-grep-outline.js +2 -3
  753. package/extensions/dm-lens/tools/ast-grep-replace.js +6 -5
  754. package/extensions/dm-lens/tools/ast-grep-search.js +2 -2
  755. package/extensions/dm-lens/tools/lens-diagnostic-mark.js +12 -1
  756. package/extensions/dm-lens/tools/lens-diagnostics.js +74 -37
  757. package/extensions/dm-lens/tools/lsp-diagnostics.js +140 -25
  758. package/extensions/dm-lens/tools/lsp-navigation.js +64 -7
  759. package/extensions/dm-lens/tools/module-report.js +6 -6
  760. package/extensions/dm-lens/tools/shared.js +6 -0
  761. package/extensions/dm-mcp-adapter/THIRD_PARTY_NOTICES.md +1 -1
  762. package/extensions/dm-mcp-adapter/cli.js +265 -23
  763. package/extensions/dm-mcp-adapter/commands.js +83 -17
  764. package/extensions/dm-mcp-adapter/config.js +517 -92
  765. package/extensions/dm-mcp-adapter/direct-tool-surface.js +10 -8
  766. package/extensions/dm-mcp-adapter/direct-tools.js +54 -36
  767. package/extensions/dm-mcp-adapter/dist/abort.js +35 -0
  768. package/extensions/dm-mcp-adapter/dist/agent-dir.js +45 -0
  769. package/extensions/dm-mcp-adapter/dist/agent-plugin-loader.js +392 -0
  770. package/extensions/dm-mcp-adapter/dist/agent-plugin-provenance.js +26 -0
  771. package/extensions/dm-mcp-adapter/dist/bearer-command-resolver.js +182 -0
  772. package/extensions/dm-mcp-adapter/dist/claude-plugin-loader.js +350 -0
  773. package/extensions/dm-mcp-adapter/dist/config.js +1735 -0
  774. package/extensions/dm-mcp-adapter/dist/consent-manager.js +84 -0
  775. package/extensions/dm-mcp-adapter/dist/elicitation-handler.js +370 -0
  776. package/extensions/dm-mcp-adapter/dist/errors.js +225 -0
  777. package/extensions/dm-mcp-adapter/dist/http-ca.js +75 -0
  778. package/extensions/dm-mcp-adapter/dist/jev-client.js +359 -0
  779. package/extensions/dm-mcp-adapter/dist/jev-contracts.js +1 -0
  780. package/extensions/dm-mcp-adapter/dist/jev-key-store.js +189 -0
  781. package/extensions/dm-mcp-adapter/dist/json-schema-validator.js +70 -0
  782. package/extensions/dm-mcp-adapter/dist/lifecycle.js +387 -0
  783. package/extensions/dm-mcp-adapter/dist/logger.js +115 -0
  784. package/extensions/dm-mcp-adapter/dist/mcp-auth-fetch.js +86 -0
  785. package/extensions/dm-mcp-adapter/dist/mcp-auth-flow.js +956 -0
  786. package/extensions/dm-mcp-adapter/dist/mcp-auth.js +998 -0
  787. package/extensions/dm-mcp-adapter/dist/mcp-bearer-store.js +182 -0
  788. package/extensions/dm-mcp-adapter/dist/mcp-callback-server.js +380 -0
  789. package/extensions/dm-mcp-adapter/dist/mcp-oauth-provider.js +525 -0
  790. package/extensions/dm-mcp-adapter/dist/mcp-probe.js +151 -0
  791. package/extensions/dm-mcp-adapter/dist/mcp-tasks.js +300 -0
  792. package/extensions/dm-mcp-adapter/dist/mcp-trace.js +220 -0
  793. package/extensions/dm-mcp-adapter/dist/metadata-cache.js +323 -0
  794. package/extensions/dm-mcp-adapter/dist/npx-resolver.js +465 -0
  795. package/extensions/dm-mcp-adapter/dist/output-shape.js +312 -0
  796. package/extensions/dm-mcp-adapter/dist/package-mcp-loader.js +144 -0
  797. package/extensions/dm-mcp-adapter/dist/project-server-trust.js +186 -0
  798. package/extensions/dm-mcp-adapter/dist/request-headers-command.js +294 -0
  799. package/extensions/dm-mcp-adapter/dist/resource-tools.js +7 -0
  800. package/extensions/dm-mcp-adapter/dist/runtime-owner.js +94 -0
  801. package/extensions/dm-mcp-adapter/dist/sampling-handler.js +213 -0
  802. package/extensions/dm-mcp-adapter/dist/secure-keyring.js +191 -0
  803. package/extensions/dm-mcp-adapter/dist/server-manager.js +1594 -0
  804. package/extensions/dm-mcp-adapter/dist/session-approvals.js +127 -0
  805. package/extensions/dm-mcp-adapter/dist/session-recovery.js +83 -0
  806. package/extensions/dm-mcp-adapter/dist/state.js +1 -0
  807. package/extensions/dm-mcp-adapter/dist/ts-shape.js +157 -0
  808. package/extensions/dm-mcp-adapter/dist/types.js +286 -0
  809. package/extensions/dm-mcp-adapter/dist/ui-app-bridge-helpers.js +36 -0
  810. package/extensions/dm-mcp-adapter/dist/ui-resource-handler.js +204 -0
  811. package/extensions/dm-mcp-adapter/dist/ui-stream-types.js +58 -0
  812. package/extensions/dm-mcp-adapter/dist/ui-tool-visibility.js +26 -0
  813. package/extensions/dm-mcp-adapter/dist/unix-socket-transport.js +83 -0
  814. package/extensions/dm-mcp-adapter/dist/utils.js +418 -0
  815. package/extensions/dm-mcp-adapter/elicitation-handler.js +67 -2
  816. package/extensions/dm-mcp-adapter/failure-backoff.js +9 -0
  817. package/extensions/dm-mcp-adapter/host-managed.js +400 -0
  818. package/extensions/dm-mcp-adapter/http-ca.js +4 -0
  819. package/extensions/dm-mcp-adapter/index.js +347 -57
  820. package/extensions/dm-mcp-adapter/init.js +92 -44
  821. package/extensions/dm-mcp-adapter/jev-client.js +5 -5
  822. package/extensions/dm-mcp-adapter/jev-key-store.js +15 -2
  823. package/extensions/dm-mcp-adapter/mcp-auth-flow.js +10 -2
  824. package/extensions/dm-mcp-adapter/mcp-auth.js +2 -1
  825. package/extensions/dm-mcp-adapter/mcp-callback-server.js +1 -1
  826. package/extensions/dm-mcp-adapter/mcp-code.js +174 -87
  827. package/extensions/dm-mcp-adapter/mcp-keyring-helper.cjs +1 -1
  828. package/extensions/dm-mcp-adapter/mcp-oauth-provider.js +3 -2
  829. package/extensions/dm-mcp-adapter/mcp-output-guard.js +19 -5
  830. package/extensions/dm-mcp-adapter/mcp-panel.js +59 -12
  831. package/extensions/dm-mcp-adapter/mcp-script-wasm.js +22 -0
  832. package/extensions/dm-mcp-adapter/mcp-script-worker.mjs +227 -111
  833. package/extensions/dm-mcp-adapter/mcp-setup-panel.js +500 -258
  834. package/extensions/dm-mcp-adapter/mcp-status.js +9 -2
  835. package/extensions/dm-mcp-adapter/mcp-trace.js +5 -0
  836. package/extensions/dm-mcp-adapter/metadata-cache.js +68 -11
  837. package/extensions/dm-mcp-adapter/namespace-tools.js +20 -5
  838. package/extensions/dm-mcp-adapter/onboarding-state.js +11 -1
  839. package/extensions/dm-mcp-adapter/output-shape.js +312 -0
  840. package/extensions/dm-mcp-adapter/package-mcp-loader.js +15 -6
  841. package/extensions/dm-mcp-adapter/package.json +6 -15
  842. package/extensions/dm-mcp-adapter/panel-keys.js +13 -0
  843. package/extensions/dm-mcp-adapter/pi-builtin-mcp.js +26 -0
  844. package/extensions/dm-mcp-adapter/pi-signin-import.js +121 -0
  845. package/extensions/dm-mcp-adapter/project-server-trust.js +186 -0
  846. package/extensions/dm-mcp-adapter/prompts.js +80 -7
  847. package/extensions/dm-mcp-adapter/proxy-modes.js +219 -158
  848. package/extensions/dm-mcp-adapter/runtime-protocol.js +342 -0
  849. package/extensions/dm-mcp-adapter/search-ranking.js +8 -6
  850. package/extensions/dm-mcp-adapter/semantic-search.js +5 -4
  851. package/extensions/dm-mcp-adapter/server-manager.js +108 -26
  852. package/extensions/dm-mcp-adapter/session-recovery.js +3 -2
  853. package/extensions/dm-mcp-adapter/skills/mcp-scripting/SKILL.md +24 -28
  854. package/extensions/dm-mcp-adapter/skills/mcp-scripting/references/jev.md +3 -0
  855. package/extensions/dm-mcp-adapter/test-runner.mjs +1 -1
  856. package/extensions/dm-mcp-adapter/tool-approval.js +17 -7
  857. package/extensions/dm-mcp-adapter/tool-metadata.js +4 -2
  858. package/extensions/dm-mcp-adapter/tool-parameters.js +4 -0
  859. package/extensions/dm-mcp-adapter/tool-result-renderer.js +68 -7
  860. package/extensions/dm-mcp-adapter/ts-shape.js +1 -1
  861. package/extensions/dm-mcp-adapter/ui-server.js +24 -20
  862. package/extensions/dm-mcp-adapter/unix-socket-transport.js +1 -1
  863. package/extensions/dm-mcp-adapter/utils.js +37 -1
  864. package/extensions/dm-ponytail/extensions/ponytail.mjs +37 -17
  865. package/extensions/dm-ponytail/hooks/claude-codex-hooks.json +3 -3
  866. package/extensions/dm-ponytail/hooks/copilot-hooks.json +4 -4
  867. package/extensions/dm-ponytail/hooks/ponytail-activate.js +46 -13
  868. package/extensions/dm-ponytail/hooks/ponytail-config.js +6 -5
  869. package/extensions/dm-ponytail/hooks/ponytail-instructions.js +29 -33
  870. package/extensions/dm-ponytail/hooks/ponytail-map.js +116 -0
  871. package/extensions/dm-ponytail/hooks/ponytail-mode-tracker.js +26 -13
  872. package/extensions/dm-ponytail/hooks/ponytail-runtime.js +23 -9
  873. package/extensions/dm-ponytail/hooks/ponytail-subagent.js +15 -3
  874. package/extensions/dm-ponytail/hooks/qoder-hooks.json +3 -3
  875. package/extensions/dm-ponytail/package.json +1 -1
  876. package/extensions/dm-ponytail/pi-extension/index.js +37 -17
  877. package/extensions/dm-ponytail/pi-extension/package.json +1 -1
  878. package/extensions/dm-ponytail/skills/plugin.json +5 -0
  879. package/extensions/dm-ponytail/skills/ponytail/SKILL.md +33 -101
  880. package/extensions/dm-ponytail/skills/ponytail-audit/SKILL.md +89 -27
  881. package/extensions/dm-ponytail/skills/ponytail-debt/SKILL.md +13 -12
  882. package/extensions/dm-ponytail/skills/ponytail-gain/SKILL.md +21 -18
  883. package/extensions/dm-ponytail/skills/ponytail-help/SKILL.md +13 -14
  884. package/extensions/dm-ponytail/skills/ponytail-review/SKILL.md +96 -52
  885. package/extensions/dm-subagents/agents/oracle.md +8 -19
  886. package/extensions/dm-subagents/agents/researcher.md +0 -3
  887. package/extensions/dm-subagents/agents/reviewer.md +17 -61
  888. package/extensions/dm-subagents/agents/scout.md +1 -4
  889. package/extensions/dm-subagents/agents/worker.md +8 -25
  890. package/extensions/dm-subagents/index.js +5 -0
  891. package/extensions/dm-subagents/install.mjs +47 -62
  892. package/extensions/dm-subagents/package.json +6 -5
  893. package/extensions/dm-subagents/prompts/council.md +1 -1
  894. package/extensions/dm-subagents/prompts/review-loop.md +1 -1
  895. package/extensions/dm-subagents/skills/council-mode/SKILL.md +1 -1
  896. package/extensions/dm-subagents/skills/dm-subagents/SKILL.md +13 -6
  897. package/extensions/dm-subagents/skills/dm-subagents/references/constraints-and-recipes.md +3 -3
  898. package/extensions/dm-subagents/skills/dm-subagents/references/execution-controls.md +79 -78
  899. package/extensions/dm-subagents/skills/dm-subagents/references/management-authoring-rpc.md +18 -14
  900. package/extensions/dm-subagents/skills/dm-subagents/references/multi-lane-orchestration.md +1 -1
  901. package/extensions/dm-subagents/skills/dm-subagents/references/prompting-and-roles.md +46 -49
  902. package/extensions/dm-subagents/src/agents/advertised-agent-prompt.js +18 -32
  903. package/extensions/dm-subagents/src/agents/agent-management.js +7 -2
  904. package/extensions/dm-subagents/src/agents/agent-memory.js +3 -3
  905. package/extensions/dm-subagents/src/agents/agent-scope.js +3 -0
  906. package/extensions/dm-subagents/src/agents/agent-serializer.js +12 -1
  907. package/extensions/dm-subagents/src/agents/agents.js +217 -120
  908. package/extensions/dm-subagents/src/api/inspectors.js +10 -0
  909. package/extensions/dm-subagents/src/api/preflight.js +43 -6
  910. package/extensions/dm-subagents/src/extension/config.js +35 -2
  911. package/extensions/dm-subagents/src/extension/control-notices.js +3 -7
  912. package/extensions/dm-subagents/src/extension/declaration-pinning.js +127 -0
  913. package/extensions/dm-subagents/src/extension/doctor.js +4 -7
  914. package/extensions/dm-subagents/src/extension/fanout-child.js +15 -7
  915. package/extensions/dm-subagents/src/extension/herdr-dm-bridge.js +2 -0
  916. package/extensions/dm-subagents/src/extension/index.js +231 -332
  917. package/extensions/dm-subagents/src/extension/public-execution.js +63 -33
  918. package/extensions/dm-subagents/src/extension/reply-workflow-script.js +65 -0
  919. package/extensions/dm-subagents/src/extension/rpc.js +42 -16
  920. package/extensions/dm-subagents/src/extension/schemas.js +73 -152
  921. package/extensions/dm-subagents/src/extension/subagent-guide.js +92 -7
  922. package/extensions/dm-subagents/src/extension/subagent-options.js +47 -0
  923. package/extensions/dm-subagents/src/extension/tool-activation.js +57 -89
  924. package/extensions/dm-subagents/src/extension/tool-description.js +56 -47
  925. package/extensions/dm-subagents/src/extension/upgrade-notice.js +36 -0
  926. package/extensions/dm-subagents/src/inspectors/actions.js +34 -11
  927. package/extensions/dm-subagents/src/inspectors/plugins.js +71 -2
  928. package/extensions/dm-subagents/src/inspectors/tmux/actions.js +173 -0
  929. package/extensions/dm-subagents/src/inspectors/tmux/client.js +63 -0
  930. package/extensions/dm-subagents/src/inspectors/tmux/plugin.js +14 -0
  931. package/extensions/dm-subagents/src/integrations/herdr-status.js +26 -49
  932. package/extensions/dm-subagents/src/integrations/program-status.js +179 -0
  933. package/extensions/dm-subagents/src/intercom/native-supervisor-channel.js +77 -4
  934. package/extensions/dm-subagents/src/intercom/result-intercom.js +3 -2
  935. package/extensions/dm-subagents/src/intercom/supervisor-ui.js +2 -152
  936. package/extensions/dm-subagents/src/missions/goal-driver.js +47 -34
  937. package/extensions/dm-subagents/src/missions/store.js +33 -4
  938. package/extensions/dm-subagents/src/profiles/profiles.js +22 -15
  939. package/extensions/dm-subagents/src/runs/background/active-async-capacity.js +49 -6
  940. package/extensions/dm-subagents/src/runs/background/async-execution.js +301 -139
  941. package/extensions/dm-subagents/src/runs/background/async-job-tracker.js +65 -24
  942. package/extensions/dm-subagents/src/runs/background/async-resume.js +9 -3
  943. package/extensions/dm-subagents/src/runs/background/async-retention.js +40 -15
  944. package/extensions/dm-subagents/src/runs/background/await-async-run.js +68 -0
  945. package/extensions/dm-subagents/src/runs/background/binary-bootstrap.js +2 -1
  946. package/extensions/dm-subagents/src/runs/background/calendar-schedule.js +90 -0
  947. package/extensions/dm-subagents/src/runs/background/chain-root-attachment.js +11 -8
  948. package/extensions/dm-subagents/src/runs/background/control-channel.js +89 -5
  949. package/extensions/dm-subagents/src/runs/background/fleet-view.js +5 -5
  950. package/extensions/dm-subagents/src/runs/background/notify.js +170 -11
  951. package/extensions/dm-subagents/src/runs/background/pid-namespace.js +17 -0
  952. package/extensions/dm-subagents/src/runs/background/result-files.js +80 -6
  953. package/extensions/dm-subagents/src/runs/background/result-watcher.js +92 -65
  954. package/extensions/dm-subagents/src/runs/background/resume-guidance.js +2 -2
  955. package/extensions/dm-subagents/src/runs/background/run-child-session.js +34 -10
  956. package/extensions/dm-subagents/src/runs/background/run-id-resolver.js +8 -6
  957. package/extensions/dm-subagents/src/runs/background/run-status.js +25 -15
  958. package/extensions/dm-subagents/src/runs/background/runner-aliases.js +4 -2
  959. package/extensions/dm-subagents/src/runs/background/runner-child-launch.js +3 -0
  960. package/extensions/dm-subagents/src/runs/background/runner-http-dispatcher.js +2 -1
  961. package/extensions/dm-subagents/src/runs/background/scheduled-runs.js +270 -79
  962. package/extensions/dm-subagents/src/runs/background/stale-run-reconciler.js +18 -3
  963. package/extensions/dm-subagents/src/runs/background/subagent-runner-bootstrap.js +4 -1
  964. package/extensions/dm-subagents/src/runs/background/subagent-runner.js +123 -33
  965. package/extensions/dm-subagents/src/runs/background/subagent-wait.js +33 -20
  966. package/extensions/dm-subagents/src/runs/background/terminal-run-index.js +42 -1
  967. package/extensions/dm-subagents/src/runs/background/wait-completions.js +1 -0
  968. package/extensions/dm-subagents/src/runs/background/wait-tool.js +36 -26
  969. package/extensions/dm-subagents/src/runs/background/workflow-terminal-proof.js +39 -26
  970. package/extensions/dm-subagents/src/runs/foreground/async-stop-action.js +58 -26
  971. package/extensions/dm-subagents/src/runs/foreground/command-action.js +37 -0
  972. package/extensions/dm-subagents/src/runs/foreground/execution.js +132 -32
  973. package/extensions/dm-subagents/src/runs/foreground/foreground-history.js +1 -0
  974. package/extensions/dm-subagents/src/runs/foreground/prompt-audit.js +5 -5
  975. package/extensions/dm-subagents/src/runs/foreground/subagent-executor.js +683 -325
  976. package/extensions/dm-subagents/src/runs/shared/async-status-projection.js +3 -0
  977. package/extensions/dm-subagents/src/runs/shared/child-commands.js +252 -0
  978. package/extensions/dm-subagents/src/runs/shared/child-hooks.js +6 -5
  979. package/extensions/dm-subagents/src/runs/shared/child-launch.js +13 -1
  980. package/extensions/dm-subagents/src/runs/shared/child-session.js +183 -34
  981. package/extensions/dm-subagents/src/runs/shared/child-tool-plan.js +17 -14
  982. package/extensions/dm-subagents/src/runs/shared/claude-code-adapter.js +87 -1
  983. package/extensions/dm-subagents/src/runs/shared/dm-spawn.js +11 -85
  984. package/extensions/dm-subagents/src/runs/shared/dynamic-fanout.js +3 -0
  985. package/extensions/dm-subagents/src/runs/shared/effective-system-prompt.js +1 -2
  986. package/extensions/dm-subagents/src/runs/shared/external-cli-preflight.js +57 -6
  987. package/extensions/dm-subagents/src/runs/shared/external-cli-runner.js +6 -3
  988. package/extensions/dm-subagents/src/runs/shared/herdr-placed-run.js +13 -6
  989. package/extensions/dm-subagents/src/runs/shared/mcp-config-sources.js +1 -1
  990. package/extensions/dm-subagents/src/runs/shared/mcp-direct-tool-allowlist.js +66 -14
  991. package/extensions/dm-subagents/src/runs/shared/model-resolution-diagnostic.js +25 -5
  992. package/extensions/dm-subagents/src/runs/shared/model-resolution.js +55 -11
  993. package/extensions/dm-subagents/src/runs/shared/model-scope.js +23 -10
  994. package/extensions/dm-subagents/src/runs/shared/nested-events.js +3 -0
  995. package/extensions/dm-subagents/src/runs/shared/parallel-handoff.js +55 -7
  996. package/extensions/dm-subagents/src/runs/shared/partial-output.js +26 -0
  997. package/extensions/dm-subagents/src/runs/shared/run-history.js +41 -0
  998. package/extensions/dm-subagents/src/runs/shared/runner-launcher.js +21 -0
  999. package/extensions/dm-subagents/src/runs/shared/single-output.js +67 -26
  1000. package/extensions/dm-subagents/src/runs/shared/structured-output.js +24 -7
  1001. package/extensions/dm-subagents/src/runs/shared/subagent-control.js +32 -20
  1002. package/extensions/dm-subagents/src/runs/shared/subagent-prompt-runtime.js +68 -29
  1003. package/extensions/dm-subagents/src/runs/shared/tool-availability.js +1 -1
  1004. package/extensions/dm-subagents/src/runs/shared/workflow-async-child-guidance.js +1 -1
  1005. package/extensions/dm-subagents/src/runs/shared/worktree-cleanup-apply.js +169 -0
  1006. package/extensions/dm-subagents/src/runs/shared/worktree-cleanup-plan.js +41 -20
  1007. package/extensions/dm-subagents/src/runs/shared/worktree-lock.js +38 -0
  1008. package/extensions/dm-subagents/src/runs/shared/worktree.js +10 -1
  1009. package/extensions/dm-subagents/src/shared/atomic-json.js +2 -1
  1010. package/extensions/dm-subagents/src/shared/disabled-features.js +101 -0
  1011. package/extensions/dm-subagents/src/shared/dm-declarations.js +14 -0
  1012. package/extensions/dm-subagents/src/shared/dm-safeguards.js +41 -0
  1013. package/extensions/dm-subagents/src/shared/dm-settlement.js +48 -0
  1014. package/extensions/dm-subagents/src/shared/edit-distance.js +23 -0
  1015. package/extensions/dm-subagents/src/shared/extension-context.js +4 -0
  1016. package/extensions/dm-subagents/src/shared/file-lease.js +89 -0
  1017. package/extensions/dm-subagents/src/shared/fork-context.js +0 -1
  1018. package/extensions/dm-subagents/src/shared/formatters.js +1 -6
  1019. package/extensions/dm-subagents/src/shared/model-info.js +23 -0
  1020. package/extensions/dm-subagents/src/shared/package-version.js +12 -0
  1021. package/extensions/dm-subagents/src/shared/parent-wake.js +67 -0
  1022. package/extensions/dm-subagents/src/shared/pruned-fork.js +6 -2
  1023. package/extensions/dm-subagents/src/shared/required-child-extensions.js +35 -5
  1024. package/extensions/dm-subagents/src/shared/runtime-module-path.js +9 -0
  1025. package/extensions/dm-subagents/src/shared/settings-file-lease.js +31 -0
  1026. package/extensions/dm-subagents/src/shared/types.js +3 -1
  1027. package/extensions/dm-subagents/src/shared/utils.js +7 -7
  1028. package/extensions/dm-subagents/src/slash/prompt-template-bridge.js +2 -2
  1029. package/extensions/dm-subagents/src/slash/slash-commands.js +25 -15
  1030. package/extensions/dm-subagents/src/slash/subagent-cost.js +38 -7
  1031. package/extensions/dm-subagents/src/slash/subagents-admin.js +1 -1
  1032. package/extensions/dm-subagents/src/tui/dm-mouse-region.js +12 -0
  1033. package/extensions/dm-subagents/src/tui/fleet-status.js +12 -6
  1034. package/extensions/dm-subagents/src/tui/fleet-transcript.js +6 -2
  1035. package/extensions/dm-subagents/src/tui/fleet.js +20 -6
  1036. package/extensions/dm-subagents/src/tui/render.js +126 -72
  1037. package/extensions/dm-subagents/src/tui/running-tone.js +20 -0
  1038. package/extensions/dm-subagents/src/tui/subagent-messages.js +249 -0
  1039. package/extensions/dm-subagents/src/watchdog/diff-tool.js +19 -11
  1040. package/extensions/dm-subagents/src/watchdog/permission-arbiter.js +2 -2
  1041. package/extensions/dm-subagents/src/watchdog/register-child.js +2 -2
  1042. package/extensions/dm-subagents/src/watchdog/register-main.js +4 -24
  1043. package/extensions/dm-subagents/src/watchdog/render.js +1 -19
  1044. package/extensions/dm-subagents/src/watchdog/review.js +3 -3
  1045. package/extensions/dm-subagents/src/watchdog/runtime.js +6 -2
  1046. package/extensions/dm-subagents/src/watchdog/settings.js +22 -17
  1047. package/extensions/dm-subagents/src/watchdog/tool-actions.js +2 -2
  1048. package/extensions/dm-subagents/src/watchdog/turn-delta.js +1 -1
  1049. package/extensions/dm-subagents/src/workflows/chat-progress.js +2 -2
  1050. package/extensions/dm-subagents/src/workflows/scripted-workflow.js +116 -45
  1051. package/extensions/dm-subagents/src/workflows/structured-workflow-scripts.js +154 -0
  1052. package/extensions/dm-subagents/src/workflows/workflow-checklist.js +3 -0
  1053. package/extensions/dm-subagents/src/workflows/workflow-receipt.js +7 -4
  1054. package/extensions/dm-subagents/src/workflows/workflow-resources.js +52 -17
  1055. package/extensions/dm-subagents/src/workflows/workflow-reuse.js +87 -0
  1056. package/extensions/dm-subagents/src/workflows/workflow-revival.js +80 -0
  1057. package/extensions/dm-tty/control.js +150 -0
  1058. package/extensions/dm-tty/index.js +122 -0
  1059. package/extensions/dm-tty/package.json +20 -0
  1060. package/extensions/dm-tty/pty.js +213 -0
  1061. package/extensions/dm-tty/pty_bridge.py +266 -0
  1062. package/extensions/dm-tty/server.js +438 -0
  1063. package/extensions/dm-tty/sessions.js +97 -0
  1064. package/extensions/dm-tty/standalone.js +75 -0
  1065. package/extensions/dm-tty/web/client.js +1141 -0
  1066. package/extensions/dm-tty/web/index.html +117 -0
  1067. package/extensions/dm-tty/web/style.css +73 -0
  1068. package/extensions/dm-web-access/brave-rate-limit.js +160 -0
  1069. package/extensions/dm-web-access/brave.js +62 -11
  1070. package/extensions/dm-web-access/ceramic.js +197 -0
  1071. package/extensions/dm-web-access/chrome-cookies.js +69 -21
  1072. package/extensions/dm-web-access/curator-page.js +12 -2
  1073. package/extensions/dm-web-access/curator-server.js +10 -0
  1074. package/extensions/dm-web-access/declared-web-links.js +1 -1
  1075. package/extensions/dm-web-access/degoog.js +288 -0
  1076. package/extensions/dm-web-access/dist/index.js +28404 -0
  1077. package/extensions/dm-web-access/dist/mcp-cli.js +28186 -0
  1078. package/extensions/dm-web-access/duckduckgo.js +6 -3
  1079. package/extensions/dm-web-access/endpoint-pdf-extract.js +210 -0
  1080. package/extensions/dm-web-access/exa.js +17 -35
  1081. package/extensions/dm-web-access/extract.js +63 -10
  1082. package/extensions/dm-web-access/firecrawl.js +30 -4
  1083. package/extensions/dm-web-access/gemini-search.js +117 -37
  1084. package/extensions/dm-web-access/gemini-web.js +7 -7
  1085. package/extensions/dm-web-access/github-extract.js +28 -2
  1086. package/extensions/dm-web-access/github-issue-pr.js +88 -73
  1087. package/extensions/dm-web-access/index.js +230 -1161
  1088. package/extensions/dm-web-access/keenable.js +197 -0
  1089. package/extensions/dm-web-access/mcp-cli.js +30 -0
  1090. package/extensions/dm-web-access/mcp-server.js +51 -0
  1091. package/extensions/dm-web-access/mcp-tool-definitions.js +93 -0
  1092. package/extensions/dm-web-access/openai-search.js +70 -20
  1093. package/extensions/dm-web-access/opencode-session-headers.js +1 -1
  1094. package/extensions/dm-web-access/package.json +4 -1
  1095. package/extensions/dm-web-access/page-query.js +5 -10
  1096. package/extensions/dm-web-access/parallel-mcp.js +2 -1
  1097. package/extensions/dm-web-access/pdf-extract.js +34 -1
  1098. package/extensions/dm-web-access/perplexity.js +68 -51
  1099. package/extensions/dm-web-access/query-rewrite.js +3 -4
  1100. package/extensions/dm-web-access/scripts/build.js +8 -0
  1101. package/extensions/dm-web-access/ssrf-protection.js +10 -8
  1102. package/extensions/dm-web-access/storage.js +79 -76
  1103. package/extensions/dm-web-access/summary-model-scope.js +5 -64
  1104. package/extensions/dm-web-access/summary-review.js +35 -9
  1105. package/extensions/dm-web-access/tavily.js +69 -22
  1106. package/extensions/dm-web-access/tool-activation.js +44 -26
  1107. package/extensions/dm-web-access/tool-arguments.js +21 -0
  1108. package/extensions/dm-web-access/utils.js +17 -7
  1109. package/extensions/dm-web-access/video-extract.js +1 -1
  1110. package/extensions/dm-web-access/web-tool-contract.js +0 -0
  1111. package/extensions/dm-web-access/web-tool-core.js +1312 -0
  1112. package/extensions/dm-web-access/you.js +155 -0
  1113. package/extensions/dm-web-access/youtube-extract.js +2 -2
  1114. package/extensions/dm-web-access/zai.js +159 -0
  1115. package/package.json +13 -9
@@ -1,7 +1,7 @@
1
1
  import { randomUUID } from "node:crypto";
2
2
  import * as fs from "node:fs";
3
3
  import * as path from "node:path";
4
- import { discoverAgents, findBlockingAgentDiagnostic, formatUnknownAgentError, resolveAgentName, unknownAgentDiagnosticContext } from "../../agents/agents.js";
4
+ import { discoverAgents, findBlockingAgentDiagnostic, formatAvailableAgentLines, formatUnknownAgentError, resolveAgentName, suggestAgentName, unknownAgentDiagnosticContext } from "../../agents/agents.js";
5
5
  import { getArtifactsDir, getProjectArtifactPackagingWarning, getProjectSubagentsDir } from "../../shared/artifacts.js";
6
6
  import { writeAtomicJson } from "../../shared/atomic-json.js";
7
7
  import { createCapacityResilientJsonWriter } from "../../shared/capacity-resilient-json.js";
@@ -16,17 +16,20 @@ import {
16
16
  } from "./foreground-control.js";
17
17
  import { getLivePromptAudit, rewritePromptWithGuidance, updateLiveEffectivePrompt } from "./prompt-audit.js";
18
18
  import { persistForegroundRunHistory, MAX_REMEMBERED_FOREGROUND_RUNS } from "./foreground-history.js";
19
- import { resolveExecutionAgentScope } from "../../agents/agent-scope.js";
19
+ import { projectScopeRequiresTrustMessage, resolveExecutionAgentScope } from "../../agents/agent-scope.js";
20
20
  import { handleManagementAction } from "../../agents/agent-management.js";
21
21
  import { handleRefinementAction } from "../../agents/agent-refinements.js";
22
22
  import { buildDoctorReport } from "../../extension/doctor.js";
23
23
  import { readSubagentGuide } from "../../extension/subagent-guide.js";
24
- import { normalizePublicSubagentExecution, validateWorkflowCapacityOverrides } from "../../extension/public-execution.js";
24
+ import { isWorkflowScriptPath, normalizePublicSubagentExecution, validateWorkflowCapacityOverrides } from "../../extension/public-execution.js";
25
+ import { readReplyWorkflowScript } from "../../extension/reply-workflow-script.js";
26
+ import { disabledFeatureNotice, disabledFeatureUseError, resolveDisabledFeatureSurface } from "../../shared/disabled-features.js";
25
27
  import { runSync } from "./execution.js";
28
+ import { commandAction } from "./command-action.js";
26
29
  import { handleWatchdogToolAction, WATCHDOG_TOOL_ACTIONS } from "../../watchdog/tool-actions.js";
27
30
  import { applyWatchdogLaunchRules } from "../../watchdog/rules.js";
28
31
  import { childWatchdogProgressForModel } from "../../watchdog/child-status.js";
29
- import { normalizeParentModel, resolveEffectiveSubagentModel, resolveModelOrigin } from "../shared/model-resolution.js";
32
+ import { normalizeParentModel, resolveEffectiveSubagentModel, resolveModelOrigin, scopedModelIdsFromContext } from "../shared/model-resolution.js";
30
33
  import { projectChainOutputSchemas, resolveEffectiveOutputSchema } from "../shared/child-launch-plan.js";
31
34
  import { formatRetainedChildren, listRetainedChildren } from "../background/retained-children.js";
32
35
  import { resolveModelScopesForAgent } from "../shared/model-scope.js";
@@ -57,16 +60,17 @@ import { formatControlIntercomMessage, formatControlNoticeMessage, resolveContro
57
60
  import { formatSpawnBudget, getSpawnBudgetSnapshot, grantSpawnBudget, preflightSpawnBudget, preflightSpawnBudgetGrant, reserveSpawnBudget } from "../shared/spawn-budget.js";
58
61
  import { claimRunFanoutBatch, claimRunFanoutBatchWithCommit, createRunFanoutBudget, formatRunFanoutBudget, getRunFanoutBudgetSnapshot, readRunFanoutBudgetDescriptor, RunFanoutLimitError, writeRunFanoutBudgetDescriptor } from "../shared/run-fanout-budget.js";
59
62
  import { retainLiveForegroundNestedRoute } from "../../integrations/dm-web-session-liveness.js";
63
+ import { HERDR_FOREGROUND_CONTROL_CHANGED_EVENT } from "../../integrations/herdr-status.js";
60
64
  import { validateToolBudgetConfig } from "../shared/tool-budget.js";
61
65
  import { usageBudgetExceededMessage, usageBudgetState, validateUsageBudgetConfig } from "../shared/usage-budget.js";
62
- import { intersectSubagentCapabilityCeilings, resolveCurrentSubagentCapabilityCeiling } from "../shared/capability-ceiling.js";
66
+ import { assertAgentAllowedByCapabilityCeiling, intersectSubagentCapabilityCeilings, resolveCurrentSubagentCapabilityCeiling } from "../shared/capability-ceiling.js";
63
67
  import { isAgentContract } from "../shared/agent-contract.js";
64
68
  import { normalizeExtensionBindings } from "../shared/extension-bindings.js";
65
- import { resolveRequiredChildExtensions } from "../../shared/required-child-extensions.js";
66
- import { finalizeSingleOutput, injectSingleOutputInstruction, normalizeSingleOutputOverride, outputPathMappingFromTask, resolveSingleOutputPath, validateFileOnlyOutputMode } from "../shared/single-output.js";
69
+ import { assertRequiredChildExtensionsAdmitted, hasMandatoryRequiredChildExtensions, readRetainedRequiredChildExtensions, resolveRequiredChildExtensions } from "../../shared/required-child-extensions.js";
70
+ import { capInlineOutput, finalizeSingleOutput, injectSingleOutputInstruction, normalizeSingleOutputOverride, outputPathMappingFromTask, resolveSingleOutputPath, validateFileOnlyOutputMode } from "../shared/single-output.js";
67
71
  import { assertJsonSchemaObject, cleanupStructuredOutputRuntime, createStructuredOutputRuntime } from "../shared/structured-output.js";
68
- import { compactForegroundDetails, getSingleResultOutput, PROMPT_REDACTED, readStatus, resolveChildCwd, sumResultsCost, sumResultsUsage } from "../../shared/utils.js";
69
- import { discardPreservedWorktrees, formatParallelHandoffError, formatParallelHandoffReference, formatStoredParallelHandoffCleanup, parallelHandoffPath, readParallelHandoffManifest, recordParallelHandoffMerge, recordParallelHandoffSupersession, writeParallelHandoffGroup, writeWorktreeSetupHandoff } from "../shared/parallel-handoff.js";
72
+ import { compactForegroundDetails, getSingleResultOutput, PROMPT_REDACTED, readStatus, resolveChildCwd, sumResultsCost, sumResultsUsage, toAgentToolUsage } from "../../shared/utils.js";
73
+ import { discardPreservedWorktrees, formatParallelHandoffError, formatParallelHandoffReference, protectRetainedWorktreeForResume, formatStoredParallelHandoffCleanup, parallelHandoffPath, readParallelHandoffManifest, recordParallelHandoffMerge, recordParallelHandoffSupersession, writeParallelHandoffGroup, writeWorktreeSetupHandoff } from "../shared/parallel-handoff.js";
70
74
  import { summarizeContextModes } from "../shared/context-mode.js";
71
75
  import {
72
76
  attachNestedChildrenToResultChildren,
@@ -90,16 +94,18 @@ import { dismissRecoveredWorkflow } from "./async-dismiss-action.js";
90
94
  import { promotePausedWorkflowIfSettled, reconcileDetachedWorkflowChildCompletion } from "./workflow-detach-reconcile.js";
91
95
  import { reconcileAsyncRun } from "../background/stale-run-reconciler.js";
92
96
  import { resolveAsyncRootResultPath, waitForImportedAsyncRoot } from "../background/chain-root-attachment.js";
93
- import { fallbackResultPayloadPathForSessionRun, removeResultIndex, resultFilePath, writeAsyncResultFile } from "../background/result-files.js";
94
- import { attachRootChildrenToSteps, createNestedRoute, findNestedControlResult, inheritedNestedParentAddressOf, inheritedNestedRouteOf, nestedRunScope, resolveNestedAsyncDir, retainNestedLookupRoute, snapshotNestedEventFiles, updateForegroundNestedProjection, writeNestedControlRequest, writeNestedEvent } from "../shared/nested-events.js";
97
+ import { awaitExistingAsyncRun, claimWorkflowAwaitedResult } from "../background/await-async-run.js";
98
+ import { fallbackResultPayloadPathForSessionRun, resultFilePath, retireResultSnapshot, writeAsyncResultFile } from "../background/result-files.js";
99
+ import { attachRootChildrenToSteps, createNestedRoute, findNestedControlResult, inheritedNestedParentAddressOf, inheritedNestedRouteOf, nestedRunNotActiveMessage, nestedRunScope, resolveNestedAsyncDir, retainNestedLookupRoute, snapshotNestedEventFiles, updateForegroundNestedProjection, writeNestedControlRequest, writeNestedEvent } from "../shared/nested-events.js";
95
100
  import { resolveSubagentRunId } from "../background/run-id-resolver.js";
96
101
  import { formatNestedRunStatusLines } from "../shared/nested-render.js";
97
- import { isStoppableAsyncStatusStep, resolveAsyncStatusChild, stopStoppableAsyncStatusChildren } from "../shared/child-identity.js";
102
+ import { isStoppableAsyncStatusStep, resolveAsyncStatusChild } from "../shared/child-identity.js";
98
103
  import { inspectSubagentStatus } from "../background/run-status.js";
99
104
  import { getExternalJobProvider } from "../../api/external-job-provider.js";
100
105
  import { externalJobFollowUpRequestDigest, externalJobFollowUpRequestId, externalJobFollowUpRunId, externalJobPromptDigest, externalJobStableJson } from "../shared/external-job-runner.js";
101
106
  import { externalCliReceiptMetadata, normalizeExternalCliRunnerStatus } from "../shared/external-cli-contract.js";
102
107
  import { formatHerdrMachineRunnerUnsupported, resolveHerdrMachinePlacement } from "../shared/herdr-machine.js";
108
+ import { lookupRunnerLauncher, resolveAgentRunnerLauncher } from "../shared/runner-launcher.js";
103
109
  import { applyForceTopLevelAsyncOverride } from "../background/top-level-async.js";
104
110
  import { handleMissionAction, MISSION_ACTIONS } from "../../missions/actions.js";
105
111
  import { attachMissionToLaunchResult, prepareMissionLaunch, writeMissionAsyncBinding } from "../../missions/lifecycle.js";
@@ -107,12 +113,14 @@ import { MissionNotFoundError, updateMission } from "../../missions/store.js";
107
113
  import { createMissionWorkflowState } from "../../missions/workflow-state.js";
108
114
  import { resolveAuthorityDecision } from "../../policy/authority.js";
109
115
  import { handleInspectorAction, INSPECTOR_ACTIONS } from "../../inspectors/actions.js";
110
- import { createBuiltinInspectorPlugins } from "../../inspectors/plugins.js";
116
+ import { getInspectorPlugins } from "../../inspectors/plugins.js";
111
117
  import { handleHerdrProjectPaneAction, HERDR_PROJECT_PANE_ACTIONS } from "../../inspectors/herdr/project-panes.js";
112
118
  import { previewSimpleWorkflowRun, runWorkflowScript, validateWorkflowScript, WorkflowScriptError } from "../../workflows/scripted-workflow.js";
113
119
  import { formatIncrementalChildCompletion, incrementalChildCompletionTriggersTurn } from "../background/notify.js";
120
+ import { appendWorkflowChildJournal, findWorkflowReuseSource, matchWorkflowReuse, workflowChildFingerprint, workflowScriptDigest, workflowStopCause, WORKFLOW_RUNTIME_REPLACED_RELAUNCH_NOTICE } from "../../workflows/workflow-reuse.js";
114
121
  import { executeWorkflowHostCommand, resolveWorkflowHostOutputClaimPath } from "../../workflows/host-command.js";
115
122
  import { buildWorkflowReceipt, readWorkflowReceipt, workflowReceiptPath, resolveWorkflowReceiptResumeEntry, writeWorkflowReceipt } from "../../workflows/workflow-receipt.js";
123
+ import { formatWorkflowKeyRevival, recordWorkflowRevival, withWorkflowRevivals } from "../../workflows/workflow-revival.js";
116
124
  import { upsertHostStep, validHostStepNodes } from "../shared/host-step-status.js";
117
125
  import { assertWorkflowLaneKey, normalizeWorkflowLaneMetadata } from "../shared/lane-metadata.js";
118
126
  import { parseWorkflowChildSummary, workflowChildProgress, workflowChildSummary } from "../../workflows/workflow-child-summary.js";
@@ -124,7 +132,7 @@ import {
124
132
  consumeWorkflowResourcePermit,
125
133
  validateWorkflowChildPermitRoot
126
134
  } from "../../shared/workflow-child-permit.js";
127
- import { deepFreezeWorkflowArgs, normalizeWorkflowArgs, resolveWorkflowResource } from "../../workflows/workflow-resources.js";
135
+ import { deepFreezeWorkflowArgs, normalizeWorkflowArgs, resolveStructuredWorkflowResource, resolveWorkflowResource } from "../../workflows/workflow-resources.js";
128
136
  import { stableJsonDigest } from "../../shared/launch-contract.js";
129
137
  import {
130
138
  cleanupWorktrees,
@@ -134,10 +142,12 @@ import {
134
142
  diffWorktrees,
135
143
  formatWorktreeDiffSummary
136
144
  } from "../shared/worktree.js";
145
+ import { applyReviewedCleanupPlan, formatCleanupReceipt, loadReviewedCleanupPlan } from "../shared/worktree-cleanup-apply.js";
137
146
  import { createWorktreeCleanupPlan, formatWorktreeCleanupPlan } from "../shared/worktree-cleanup-plan.js";
138
147
  import {
139
148
  DIRS,
140
149
  DEFAULT_ARTIFACT_CONFIG,
150
+ DEFAULT_MAX_OUTPUT,
141
151
  DEFAULT_FORK_PREAMBLE,
142
152
  SUBAGENT_ACTIONS,
143
153
  SUBAGENT_ASYNC_STARTED_EVENT,
@@ -150,36 +160,20 @@ import {
150
160
  resolveChildMaxSubagentDepth,
151
161
  resolveCurrentMaxSubagentDepth,
152
162
  resolveMaxSubagentSpawnsPerRun,
163
+ truncateOutput,
153
164
  wrapForkTask
154
165
  } from "../../shared/types.js";
155
166
  import { deriveChildSessionName } from "../../shared/child-session-name.js";
156
- const MUTATING_MANAGEMENT_ACTIONS = new Set(["create", "update", "delete", "eject", "disable", "enable", "reset", "grant-spawn-budget", "watchdog.configure", "mission.create", "mission.update", "mission.resolve-decision", "mission.attach-run", "mission.close", "inspector.open", "inspector.close", "project.open", "project.close", "worktree.discard", "worktree.cleanup", "lane.recordMerge", "lane.recordSupersession", "refine", "refine.rollback", "dismiss", "schedule.create", "schedule.pause", "schedule.resume", "schedule.run", "schedule.run-due", "schedule.delete"]);
157
- const DESTRUCTIVE_MANAGEMENT_ACTIONS = new Set(["delete", "eject", "disable", "reset", "mission.close", "worktree.discard", "refine.rollback", "inspector.close", "project.close", "stop", "interrupt", "schedule.delete"]);
167
+ import { editDistance, hasSingleAdjacentTransposition } from "../../shared/edit-distance.js";
168
+ const MUTATING_MANAGEMENT_ACTIONS = new Set(["command.yield", "command.cancel", "create", "update", "delete", "eject", "disable", "enable", "reset", "grant-spawn-budget", "watchdog.configure", "mission.create", "mission.update", "mission.resolve-decision", "mission.attach-run", "mission.close", "inspector.open", "inspector.close", "project.open", "project.close", "worktree.discard", "worktree.cleanup", "lane.recordMerge", "lane.recordSupersession", "refine", "refine.rollback", "dismiss", "schedule.create", "schedule.pause", "schedule.resume", "schedule.run", "schedule.run-due", "schedule.delete"]);
169
+ const DESTRUCTIVE_MANAGEMENT_ACTIONS = new Set(["command.cancel", "delete", "eject", "disable", "reset", "mission.close", "worktree.discard", "refine.rollback", "inspector.close", "project.close", "stop", "interrupt", "schedule.delete"]);
158
170
  function resolveSteerDeliveryMode(mode) {
159
171
  return mode === "steer" || mode === "follow_up" || mode === "auto" ? mode : undefined;
160
172
  }
161
- function editDistance(left, right) {
162
- const previous = Array.from({ length: right.length + 1 }, (_, index) => index);
163
- for (let leftIndex = 1;leftIndex <= left.length; leftIndex += 1) {
164
- let diagonal = previous[0];
165
- previous[0] = leftIndex;
166
- for (let rightIndex = 1;rightIndex <= right.length; rightIndex += 1) {
167
- const above = previous[rightIndex];
168
- previous[rightIndex] = left[leftIndex - 1] === right[rightIndex - 1] ? diagonal : Math.min(diagonal, above, previous[rightIndex - 1]) + 1;
169
- diagonal = above;
170
- }
171
- }
172
- return previous[right.length];
173
- }
174
- function hasSingleAdjacentTransposition(left, right) {
175
- if (left.length !== right.length)
176
- return false;
177
- const mismatch = [...left].findIndex((character, index) => character !== right[index]);
178
- return mismatch >= 0 && left[mismatch] === right[mismatch + 1] && left[mismatch + 1] === right[mismatch] && left.slice(mismatch + 2) === right.slice(mismatch + 2);
179
- }
180
- export function unknownSubagentActionMessage(action) {
173
+ export function unknownSubagentActionMessage(action, disabled) {
181
174
  const requested = action.toLowerCase();
182
- const suggestion = SUBAGENT_ACTIONS.find((candidate) => {
175
+ const enabledActions = SUBAGENT_ACTIONS.filter((candidate) => !disabled?.actions.has(candidate));
176
+ const suggestion = enabledActions.find((candidate) => {
183
177
  const distance = editDistance(requested, candidate);
184
178
  const closeMatch = distance <= Math.max(1, Math.floor(candidate.length / 4)) || hasSingleAdjacentTransposition(requested, candidate);
185
179
  if (DESTRUCTIVE_MANAGEMENT_ACTIONS.has(candidate))
@@ -187,7 +181,7 @@ export function unknownSubagentActionMessage(action) {
187
181
  return closeMatch;
188
182
  });
189
183
  const nextStep = 'Use subagent({ action: "status" }) to inspect runs or subagent({ action: "list" }) to inspect agents.';
190
- const validActions = `Valid: ${SUBAGENT_ACTIONS.join(", ")}.`;
184
+ const validActions = `Valid: ${enabledActions.join(", ")}.`;
191
185
  return suggestion ? `Unknown action: ${action}. Did you mean ${suggestion}? ${nextStep} ${validActions}` : `Unknown action: ${action}. ${nextStep} ${validActions}`;
192
186
  }
193
187
  function omitUndefinedProperties(value) {
@@ -227,20 +221,17 @@ function inheritedRunFanoutBudget(deps) {
227
221
  function resolveRequestedCwd(runtimeCwd, requestedCwd) {
228
222
  return requestedCwd ? path.resolve(runtimeCwd, requestedCwd) : runtimeCwd;
229
223
  }
230
- function loadWorkflowScriptPath(params, runtimeCwd) {
231
- if (params.workflowScriptPath === undefined)
232
- return { params };
233
- const scriptPath = path.resolve(resolveRequestedCwd(runtimeCwd, params.cwd), params.workflowScriptPath);
234
- let workflowScript;
224
+ function readWorkflowScriptFile(requestedPath, requestedCwd, runtimeCwd) {
225
+ const scriptPath = path.resolve(resolveRequestedCwd(runtimeCwd, requestedCwd), requestedPath);
226
+ let script;
235
227
  try {
236
- workflowScript = fs.readFileSync(scriptPath, "utf8");
228
+ script = fs.readFileSync(scriptPath, "utf8");
237
229
  } catch (error) {
238
- return { error: `Failed to read workflowScriptPath '${scriptPath}': ${error instanceof Error ? error.message : String(error)}` };
230
+ return { error: `Failed to read workflow script '${scriptPath}': ${error instanceof Error ? error.message : String(error)}` };
239
231
  }
240
- if (!workflowScript.trim())
241
- return { error: `workflowScriptPath file '${scriptPath}' is empty.` };
242
- const { workflowScriptPath: _workflowScriptPath, ...rest } = params;
243
- return { params: { ...rest, workflowScript } };
232
+ if (!script.trim())
233
+ return { error: `Workflow script file '${scriptPath}' is empty.` };
234
+ return { script };
244
235
  }
245
236
  export function removeForegroundControlIfIdle(state, runId, trackRetainedNestedRoute) {
246
237
  const control = state.foregroundControls.get(runId);
@@ -334,6 +325,22 @@ function trustedSessionRootsForStatus(ctx, deps) {
334
325
  roots.push(deps.getSubagentSessionRoot(parentSessionFile));
335
326
  return [...new Set(roots)];
336
327
  }
328
+ function sessionProjectTrust(ctx) {
329
+ return typeof ctx.isProjectTrusted === "function" ? ctx.isProjectTrusted() : undefined;
330
+ }
331
+ function withSessionProjectTrust(deps, ctx) {
332
+ if (sessionProjectTrust(ctx) !== false)
333
+ return deps;
334
+ return { ...deps, discoverAgents: (cwd, scope, preferredModelProvider) => deps.discoverAgents(cwd, scope, preferredModelProvider, { projectTrusted: false }) };
335
+ }
336
+ function projectScopeTrustError(params, ctx) {
337
+ if (sessionProjectTrust(ctx) !== false || resolveExecutionAgentScope(params.agentScope) !== "project")
338
+ return;
339
+ const action = typeof params.action === "string" ? params.action.trim() : undefined;
340
+ if (action !== undefined && action !== "resume" && action !== "validate" && action !== "append-step")
341
+ return;
342
+ return buildRequestedModeError(params, projectScopeRequiresTrustMessage(resolveRequestedCwd(ctx.cwd, params.cwd)));
343
+ }
337
344
  function spawnBudgetErrorResult(message, mode) {
338
345
  return {
339
346
  content: [{ type: "text", text: message }],
@@ -490,6 +497,7 @@ function rememberForegroundRun(state, input) {
490
497
  ...result.error ? { error: result.error } : {},
491
498
  ...result.finalOutput ? { finalOutput: result.finalOutput } : {},
492
499
  ...result.outputState ? { outputState: result.outputState } : {},
500
+ ...result.outputPartial ? { outputPartial: true } : {},
493
501
  ...result.outputMode ? { outputMode: result.outputMode } : {},
494
502
  ...result.savedOutputPath ? { savedOutputPath: result.savedOutputPath } : {},
495
503
  ...result.outputSaveError ? { outputSaveError: result.outputSaveError } : {},
@@ -574,6 +582,7 @@ function updateRememberedForegroundChild(state, input) {
574
582
  ...input.result.error ? { error: input.result.error } : {},
575
583
  ...input.result.finalOutput ? { finalOutput: input.result.finalOutput } : {},
576
584
  outputState: input.result.outputState,
585
+ outputPartial: input.result.outputPartial,
577
586
  outputMode: input.result.outputMode,
578
587
  savedOutputPath: input.result.savedOutputPath,
579
588
  outputSaveError: input.result.outputSaveError,
@@ -832,7 +841,7 @@ function emitControlNotification(input) {
832
841
  }
833
842
  }
834
843
  function interruptAsyncRun(state, runId, kill, location) {
835
- const target = getAsyncInterruptTarget(state, runId, location);
844
+ const target = getAsyncInterruptTarget(state, runId, location, { fallbackToNewest: runId === undefined });
836
845
  if (!target)
837
846
  return null;
838
847
  const status = reconcileAsyncRun(target.asyncDir, omitUndefinedProperties({ kill })).status;
@@ -970,6 +979,16 @@ function appendStepToAsyncChain(input) {
970
979
  details: { mode: "management", results: [] }
971
980
  };
972
981
  }
982
+ let retainedRequiredExtensions;
983
+ try {
984
+ retainedRequiredExtensions = readRetainedRequiredChildExtensions(resolved.location.asyncDir);
985
+ } catch (error) {
986
+ return {
987
+ content: [{ type: "text", text: `Cannot append step to run '${resolved.id}': ${error instanceof Error ? error.message : String(error)}` }],
988
+ isError: true,
989
+ details: { mode: "management", results: [] }
990
+ };
991
+ }
973
992
  const pendingAppendRequests = readPendingChainAppendRequests(resolved.location.asyncDir);
974
993
  const reservedOutputNames = new Set([
975
994
  ...Object.keys(status.outputs ?? {}),
@@ -1010,14 +1029,25 @@ function appendStepToAsyncChain(input) {
1010
1029
  cwd: input.ctx.cwd,
1011
1030
  currentSessionId: resolveCurrentSessionId(input.ctx.sessionManager),
1012
1031
  parentSessionId: input.ctx.sessionManager.getSessionId() ?? undefined,
1032
+ parentSessionFile: input.ctx.sessionManager.getSessionFile() ?? undefined,
1013
1033
  currentModelProvider: parentModel?.provider,
1014
1034
  currentModel: parentModel,
1035
+ scopedModelIds: scopedModelIdsFromContext(input.ctx),
1015
1036
  modelScope: discoveredForAppend.modelScope,
1016
1037
  modelResponseAliases: input.deps.config.modelResponseAliases,
1017
1038
  interactive: input.ctx.hasUI,
1018
1039
  permissions: input.deps.config.permissions,
1019
1040
  childRuntime: input.deps.childRuntime
1020
1041
  });
1042
+ const appendedLaunchers = new Set(chain.flatMap(getStepAgents).map((name) => agents.find((agent) => agent.name === name)?.launcher));
1043
+ const appendedLauncher = [...appendedLaunchers][0];
1044
+ if (appendedLaunchers.size === 1 && appendedLauncher !== status.launcher?.name) {
1045
+ return {
1046
+ content: [{ type: "text", text: `Cannot append step to run '${resolved.id}': its runner uses ${status.launcher ? `launcher '${status.launcher.name}'` : "no launcher"}, but the appended agents use ${appendedLauncher ? `launcher '${appendedLauncher}'` : "no launcher"}.` }],
1047
+ isError: true,
1048
+ details: { mode: "management", results: [] }
1049
+ };
1050
+ }
1021
1051
  const built = buildAsyncRunnerSteps(resolved.id, compactOptional({
1022
1052
  chain: wrapChainTasksForFork(chain, contextPolicy),
1023
1053
  task: input.params.task,
@@ -1038,7 +1068,8 @@ function appendStepToAsyncChain(input) {
1038
1068
  worktreeBranchPrefix: input.deps.config.worktreeBranchPrefix,
1039
1069
  asyncDir: resolved.location.asyncDir,
1040
1070
  validateOutputBindings: false,
1041
- capabilityCeiling: intersectSubagentCapabilityCeilings(status.capabilityCeiling, resolveCurrentSubagentCapabilityCeiling(asyncCtx.currentSessionId))
1071
+ capabilityCeiling: intersectSubagentCapabilityCeilings(status.capabilityCeiling, resolveCurrentSubagentCapabilityCeiling(asyncCtx.currentSessionId)),
1072
+ requiredExtensions: retainedRequiredExtensions
1042
1073
  }));
1043
1074
  if ("error" in built) {
1044
1075
  return {
@@ -1309,11 +1340,14 @@ async function interruptNestedRun(target) {
1309
1340
  if (run.state === "paused")
1310
1341
  return { content: [{ type: "text", text: `Nested run ${run.id} is already paused.` }], isError: true, details: { mode: "management", results: [] } };
1311
1342
  const result = await sendNestedControlRequest(target, "interrupt");
1312
- if (result)
1343
+ const missingForegroundRoute = result?.ok === false && result.message === nestedRunNotActiveMessage(run.id);
1344
+ if (result && !missingForegroundRoute)
1313
1345
  return { content: [{ type: "text", text: result.message }], ...result.ok ? {} : { isError: true }, details: { mode: "management", results: [] } };
1314
1346
  const direct = directNestedAsyncInterrupt(target);
1315
1347
  if (direct)
1316
1348
  return direct;
1349
+ if (result)
1350
+ return { content: [{ type: "text", text: result.message }], isError: true, details: { mode: "management", results: [] } };
1317
1351
  return { content: [{ type: "text", text: `Nested run ${run.id} owner is not reachable and no safe direct async interrupt fallback is available.` }], isError: true, details: { mode: "management", results: [] } };
1318
1352
  }
1319
1353
  async function resumeLiveNestedRun(input) {
@@ -1436,13 +1470,16 @@ async function resumeExternalJobFollowUp(input) {
1436
1470
  cwd: input.requestCwd,
1437
1471
  currentSessionId,
1438
1472
  parentSessionId: input.ctx.sessionManager.getSessionId() ?? undefined,
1473
+ parentSessionFile: input.ctx.sessionManager.getSessionFile() ?? undefined,
1439
1474
  currentModelProvider: parentModel?.provider,
1440
1475
  currentModel: parentModel,
1476
+ scopedModelIds: scopedModelIdsFromContext(input.ctx),
1441
1477
  modelScope: input.modelScope,
1442
1478
  modelResponseAliases: input.deps.config.modelResponseAliases,
1443
1479
  interactive: input.ctx.hasUI,
1444
1480
  permissions: input.deps.config.permissions,
1445
- childRuntime: input.deps.childRuntime
1481
+ childRuntime: input.deps.childRuntime,
1482
+ projectTrusted: sessionProjectTrust(input.ctx)
1446
1483
  }),
1447
1484
  cwd: input.effectiveCwd,
1448
1485
  artifactsDir,
@@ -1511,6 +1548,14 @@ async function resumeAsyncRun(input) {
1511
1548
  details: { mode: "management", results: [] }
1512
1549
  };
1513
1550
  }
1551
+ const timeoutOverflowError = timerDelayOverflowError("timeoutMs", input.params.timeoutMs);
1552
+ if (timeoutOverflowError) {
1553
+ return {
1554
+ content: [{ type: "text", text: timeoutOverflowError }],
1555
+ isError: true,
1556
+ details: { mode: "management", results: [] }
1557
+ };
1558
+ }
1514
1559
  if (input.params.model !== undefined) {
1515
1560
  return {
1516
1561
  content: [{ type: "text", text: "action='resume' reuses the persisted child model and does not accept a model override." }],
@@ -1544,7 +1589,7 @@ async function resumeAsyncRun(input) {
1544
1589
  type: "text",
1545
1590
  text: [
1546
1591
  `Async child '${target.runId}' index ${target.index} is still running. action='resume' only revives paused, completed, or failed children.`,
1547
- `Send live input with subagent({ action: "steer", id: "${target.runId}", index: ${target.index}, message: "..." }).`
1592
+ `Send live input with subagent({ action: "steer", id: "${target.runId}", message: "...", options: { index: ${target.index} } }).`
1548
1593
  ].join(`
1549
1594
  `)
1550
1595
  }],
@@ -1602,6 +1647,18 @@ async function resumeAsyncRun(input) {
1602
1647
  const message = runner ? `External adapter '${runner.adapter.id}' cannot resume: ${runner.nonResumableReason}` : "External runners do not persist DM sessions and cannot be resumed.";
1603
1648
  return { content: [{ type: "text", text: message }], isError: true, details: { mode: "management", results: [] } };
1604
1649
  }
1650
+ if (input.params.baseRef !== undefined && "managedWorktree" in target && target.managedWorktree === true) {
1651
+ return { content: [{ type: "text", text: "Cannot resume with baseRef: retained managed-worktree children continue in their existing worktree. Start a new worktree run from that base ref instead." }], isError: true, details: { mode: "management", results: [] } };
1652
+ }
1653
+ if (target.source === "async" && target.managedWorktree && target.asyncDir) {
1654
+ try {
1655
+ const protectedCwd = await protectRetainedWorktreeForResume(parallelHandoffPath(target.asyncDir), target.runId, target.index, input.signal);
1656
+ if (path.resolve(protectedCwd) !== path.resolve(effectiveCwd))
1657
+ throw new Error("Retained worktree cwd changed during resume admission.");
1658
+ } catch (error) {
1659
+ return { content: [{ type: "text", text: error instanceof Error ? error.message : String(error) }], isError: true, details: { mode: "management", results: [] } };
1660
+ }
1661
+ }
1605
1662
  if (target.source === "async" && target.runner?.type === "external-job") {
1606
1663
  if (attachChain)
1607
1664
  return { content: [{ type: "text", text: "External-job follow-up does not support chain attachment. Use action='resume' with message instead." }], isError: true, details: { mode: "management", results: [] } };
@@ -1667,7 +1724,7 @@ async function resumeAsyncRun(input) {
1667
1724
  const chain = wrapChainTasksForFork(attachChain, contextPolicy);
1668
1725
  const normalized = normalizeSkillInput(input.params.skill);
1669
1726
  const parentModel = input.parentModel;
1670
- const result = executeAsyncChain(runId, compactOptional({
1727
+ const result = await executeAsyncChain(runId, compactOptional({
1671
1728
  chain,
1672
1729
  task: workflowTask,
1673
1730
  goal,
@@ -1686,13 +1743,17 @@ async function resumeAsyncRun(input) {
1686
1743
  cwd: input.requestCwd,
1687
1744
  currentSessionId: input.deps.state.currentSessionId,
1688
1745
  parentSessionId: input.ctx.sessionManager.getSessionId() ?? undefined,
1746
+ parentSessionFile: input.ctx.sessionManager.getSessionFile() ?? undefined,
1689
1747
  currentModelProvider: parentModel?.provider,
1690
1748
  currentModel: parentModel,
1749
+ scopedModelIds: scopedModelIdsFromContext(input.ctx),
1691
1750
  modelScope,
1692
1751
  modelResponseAliases: input.deps.config.modelResponseAliases,
1752
+ runnerLaunchers: input.deps.config.runnerLaunchers,
1693
1753
  interactive: input.ctx.hasUI,
1694
1754
  permissions: input.deps.config.permissions,
1695
- childRuntime: input.deps.childRuntime
1755
+ childRuntime: input.deps.childRuntime,
1756
+ projectTrusted: sessionProjectTrust(input.ctx)
1696
1757
  }),
1697
1758
  availableModels,
1698
1759
  cwd: effectiveCwd,
@@ -1749,16 +1810,13 @@ async function resumeAsyncRun(input) {
1749
1810
  if (!revivalSessionFile) {
1750
1811
  return { content: [{ type: "text", text: `Async run '${target.runId}' child ${target.index} does not have a persisted session file to resume from.` }], isError: true, details: { mode: "management", results: [] } };
1751
1812
  }
1752
- if (input.params.baseRef !== undefined && "managedWorktree" in target && target.managedWorktree === true) {
1753
- return { content: [{ type: "text", text: "Cannot resume with baseRef: retained managed-worktree children continue in their existing worktree. Start a new worktree run from that base ref instead." }], isError: true, details: { mode: "management", results: [] } };
1754
- }
1755
1813
  if (target.source === "async" && asyncReviveRequiresRecoveryDescriptor(target)) {
1756
1814
  return { content: [{ type: "text", text: `Async child '${target.runId}' is missing its required run fan-out recovery identity. Start a new run instead.` }], isError: true, details: { mode: "management", results: [] } };
1757
1815
  }
1758
1816
  if (target.source === "nested" && !target.recoveryDescriptor) {
1759
1817
  return { content: [{ type: "text", text: `Nested child '${target.runId}' is missing its required recovery identity. Start a new run instead.` }], isError: true, details: { mode: "management", results: [] } };
1760
1818
  }
1761
- const recoveryAgentConfig = recoveryDescriptor ? applySteeringRecoveryAgentConfig(baseAgentConfig, recoveryDescriptor) : baseAgentConfig;
1819
+ const recoveryAgentConfig = recoveryDescriptor ? applySteeringRecoveryAgentConfig(baseAgentConfig, recoveryDescriptor) : { ...baseAgentConfig, launcher: undefined };
1762
1820
  const agentConfig = intercomBridge.active ? applyIntercomBridgeToAgent(recoveryAgentConfig, intercomBridge) : recoveryAgentConfig;
1763
1821
  const foregroundContract = target.source === "foreground" ? target.resumeContract : undefined;
1764
1822
  const outputSchema = Object.hasOwn(input.params, "outputSchema") ? input.params.outputSchema : Object.hasOwn(foregroundContract ?? {}, "outputSchema") ? foregroundContract?.outputSchema : recoveryDescriptor?.structuredOutputSchema;
@@ -1767,6 +1825,9 @@ async function resumeAsyncRun(input) {
1767
1825
  if (acceptanceErrors.length > 0) {
1768
1826
  return { content: [{ type: "text", text: `Cannot resume: ${acceptanceErrors.join(" ")}` }], isError: true, details: { mode: "management", results: [] } };
1769
1827
  }
1828
+ if (agentConfig.launcher !== undefined && !lookupRunnerLauncher(input.deps.config.runnerLaunchers, agentConfig.launcher)) {
1829
+ return { content: [{ type: "text", text: `Cannot resume: run '${target.runId}' was launched with launcher '${agentConfig.launcher}', which is no longer defined in runnerLaunchers in the user subagent config.` }], isError: true, details: { mode: "management", results: [] } };
1830
+ }
1770
1831
  const runId = randomUUID();
1771
1832
  const topLevelResume = depth === 0 && !inheritedNestedRoute(input.deps) && !input.params.workflowParentRunId;
1772
1833
  let activeAsyncCapacity;
@@ -1806,13 +1867,17 @@ async function resumeAsyncRun(input) {
1806
1867
  cwd: input.requestCwd,
1807
1868
  currentSessionId: input.deps.state.currentSessionId,
1808
1869
  parentSessionId: input.ctx.sessionManager.getSessionId() ?? undefined,
1870
+ parentSessionFile: input.ctx.sessionManager.getSessionFile() ?? undefined,
1809
1871
  currentModelProvider: parentModel?.provider,
1810
1872
  currentModel: parentModel,
1873
+ scopedModelIds: scopedModelIdsFromContext(input.ctx),
1811
1874
  modelScope,
1812
1875
  modelResponseAliases: recoveryDescriptor ? recoveryDescriptor.modelResponseAliases : foregroundContract?.modelResponseAliases,
1876
+ runnerLaunchers: input.deps.config.runnerLaunchers,
1813
1877
  interactive: input.ctx.hasUI,
1814
1878
  permissions: input.deps.config.permissions,
1815
- childRuntime: input.deps.childRuntime
1879
+ childRuntime: input.deps.childRuntime,
1880
+ projectTrusted: sessionProjectTrust(input.ctx)
1816
1881
  }),
1817
1882
  cwd: effectiveCwd,
1818
1883
  maxOutput: input.params.maxOutput ?? recoveryDescriptor?.maxOutput,
@@ -1904,68 +1969,33 @@ async function resumeAsyncRun(input) {
1904
1969
  if (input.params.workflowParentRunId !== undefined && result.details.asyncDir) {
1905
1970
  const asyncDir = result.details.asyncDir;
1906
1971
  const resultPath = workflowAwaitedAsyncResultPath(asyncDir);
1907
- const stopOnAbort = () => {
1908
- stopAsyncRun(input.deps.state, revivedId, input.deps.kill, { asyncDir, resolvedId: revivedId });
1909
- };
1910
- if (input.signal?.aborted)
1911
- stopOnAbort();
1912
- else
1913
- input.signal?.addEventListener("abort", stopOnAbort, { once: true });
1914
- let completed;
1915
- try {
1916
- completed = await waitForImportedAsyncRoot({ runId: revivedId, asyncDir, resultPath, index: 0 });
1917
- } finally {
1918
- input.signal?.removeEventListener("abort", stopOnAbort);
1919
- }
1920
- if (completed.importedPublication)
1921
- removeWorkflowAwaitedResult(asyncDir, resultPath, revivedId, completed.importedPublication);
1922
- emitWorkflowAwaitedChildComplete(input.deps.dm, input.deps.state, revivedId, asyncDir, input.params.workflowParentRunId, completed);
1923
- const usage = importedAsyncRootUsage(completed);
1924
- const childResult = {
1925
- index: 0,
1926
- agent: completed.agent,
1927
- ...completed.sessionName ? { sessionName: completed.sessionName } : {},
1928
- task: effectiveFollowUp,
1929
- exitCode: completed.exitCode,
1930
- usage,
1931
- finalOutput: completed.output,
1932
- outputState: completed.output.trim() ? "present" : "absent",
1933
- ...completed.error ? { error: completed.error } : {},
1934
- ...completed.timedOut ? { timedOut: true } : {},
1935
- ...completed.stopped ? { stopped: true } : {},
1936
- ...completed.sessionFile ? { sessionFile: completed.sessionFile } : {},
1937
- ...completed.model ? { model: completed.model } : {},
1938
- ...completed.requestedModel ? { requestedModel: completed.requestedModel } : {},
1939
- ...completed.contextOverflow ? { contextOverflow: true } : {},
1940
- ...completed.structuredOutput !== undefined ? { structuredOutput: completed.structuredOutput } : {},
1941
- ...completed.structuredOutputPath ? { structuredOutputPath: completed.structuredOutputPath } : {},
1942
- ...completed.structuredOutputSchemaPath ? { structuredOutputSchemaPath: completed.structuredOutputSchemaPath } : {},
1943
- ...completed.acceptance ? { acceptance: completed.acceptance } : {},
1944
- ...completed.artifactPaths ? { artifactPaths: completed.artifactPaths } : {},
1945
- ...completed.savedOutputPath ? { savedOutputPath: completed.savedOutputPath } : {},
1946
- ...completed.outputSaveError ? { outputSaveError: completed.outputSaveError } : {},
1947
- ...completed.transcriptPath ? { transcriptPath: completed.transcriptPath } : {},
1948
- ...completed.transcriptError ? { transcriptError: completed.transcriptError } : {}
1949
- };
1950
- return {
1951
- content: [{ type: "text", text: completed.success ? completed.output || completed.error || `Revived ${target.source} subagent ${revivedId} completed without output.` : completed.error || completed.output || `Revived ${target.source} subagent ${revivedId} completed without output.` }],
1952
- ...completed.success ? {} : { isError: true },
1953
- details: {
1954
- ...result.details,
1955
- runId: revivedId,
1956
- results: [childResult],
1957
- ...target.launchContractDigest ? { sourceLaunchContractDigest: target.launchContractDigest } : {}
1958
- }
1959
- };
1972
+ const stopListener = stopAwaitedAsyncChildOnAbort(input.signal, input.deps.state, revivedId, asyncDir, input.deps.kill);
1973
+ const completed = await waitForImportedAsyncRoot({ runId: revivedId, asyncDir, resultPath, index: 0 }, {
1974
+ shouldAbort: () => input.signal?.aborted === true,
1975
+ timeoutMessage: "Workflow stopped before async child completed.",
1976
+ abortedAsStopped: true
1977
+ }).finally(stopListener.remove);
1978
+ const details = { ...result.details };
1979
+ if (target.launchContractDigest)
1980
+ details.sourceLaunchContractDigest = target.launchContractDigest;
1981
+ return importWorkflowAwaitedChildResult(completed, { runId: revivedId, asyncDir, resultPath, task: effectiveFollowUp, parentWorkflowRunId: input.params.workflowParentRunId, details, emptyOutputText: `Revived ${target.source} subagent ${revivedId} completed without output.`, state: input.deps.state, dm: input.deps.dm });
1960
1982
  }
1961
1983
  const revivedTarget = intercomBridge.active ? resolveSubagentIntercomTarget(revivedId, target.agent, 0) : undefined;
1962
1984
  const sourceLabel = target.source;
1985
+ let workflowRevivalWarning;
1986
+ try {
1987
+ if (target.source === "async")
1988
+ recordWorkflowRevival(DIRS.async, target.runId, revivedId);
1989
+ } catch (error) {
1990
+ workflowRevivalWarning = `Warning: workflow key link not recorded: ${error instanceof Error ? error.message : String(error)}`;
1991
+ }
1963
1992
  const lines = [
1964
1993
  `Revived ${sourceLabel} subagent from ${target.runId}.`,
1965
1994
  `Revived run: ${revivedId}`,
1966
1995
  `Agent: ${target.agent}`,
1967
1996
  `Session: ${target.sessionFile}`,
1968
1997
  result.details.asyncDir ? `Async dir: ${result.details.asyncDir}` : undefined,
1998
+ workflowRevivalWarning,
1969
1999
  revivedTarget ? `Intercom target: ${revivedTarget} (if registered)` : undefined,
1970
2000
  `Status if needed: subagent({ action: "status", id: "${revivedId}" })`
1971
2001
  ].filter((line) => Boolean(line));
@@ -1992,10 +2022,12 @@ function formatFailedSingleRunOutput(result, displayOutput) {
1992
2022
  const error = result.error || "Failed";
1993
2023
  const output = displayOutput.trim();
1994
2024
  const lines = [error];
2025
+ let cappedOutput = output;
1995
2026
  if (output && output !== error.trim()) {
1996
- lines.push("", "Output:", output);
2027
+ cappedOutput = capInlineOutput(output, { artifactPath: result.artifactPaths?.outputPath, savedPath: result.savedOutputPath });
2028
+ lines.push("", "Output:", cappedOutput);
1997
2029
  }
1998
- if (result.artifactPaths?.outputPath && fs.existsSync(result.artifactPaths.outputPath)) {
2030
+ if (cappedOutput === output && result.artifactPaths?.outputPath && fs.existsSync(result.artifactPaths.outputPath)) {
1999
2031
  lines.push("", `Output artifact: ${result.artifactPaths.outputPath}`);
2000
2032
  }
2001
2033
  return lines.join(`
@@ -2050,6 +2082,7 @@ async function emitForegroundResultIntercom(input) {
2050
2082
  ...result.sessionName ? { sessionName: result.sessionName } : {},
2051
2083
  status: foregroundResultIntercomStatus(result),
2052
2084
  outputState: result.outputState ?? "unknown",
2085
+ ...result.outputPartial ? { outputPartial: true } : {},
2053
2086
  summary: resultSummaryForIntercom(result),
2054
2087
  index,
2055
2088
  artifactPath: result.artifactPaths?.outputPath,
@@ -2107,6 +2140,30 @@ function canonicalizeAgentName(name, agents, diagnostics, context) {
2107
2140
  return { error: formatUnknownAgentError(name, context) };
2108
2141
  return { name: resolved.agent.name };
2109
2142
  }
2143
+ function workflowValidationOptions(deps, params, runtimeCwd, parentModelProvider) {
2144
+ const cwd = resolveRequestedCwd(runtimeCwd, params.cwd);
2145
+ const scope = resolveExecutionAgentScope(params.agentScope);
2146
+ let discovered;
2147
+ let listedAgents = false;
2148
+ return {
2149
+ maxSubagentSpawnsPerRun: params.maxSubagentSpawnsPerRun ?? resolveMaxSubagentSpawnsPerRun(deps.config.maxSubagentSpawnsPerRun),
2150
+ agentNameError: (name) => {
2151
+ discovered ??= deps.discoverAgents(cwd, scope, parentModelProvider());
2152
+ const { agents } = discovered;
2153
+ const resolved = resolveAgentName(name, agents);
2154
+ if (resolved.agent || resolved.error)
2155
+ return canonicalizeAgentName(name, agents, discovered.agentDiagnostics, diagnosticContextFromDiscovery(discovered, cwd, scope)).error;
2156
+ const disabled = discovered.disabledAgents?.includes(name.trim()) === true;
2157
+ const suggestion = disabled ? undefined : suggestAgentName(name, agents);
2158
+ const problem = disabled ? `Agent '${name}' is disabled by a settings override.` : `Unknown agent '${name}'.${suggestion ? ` Did you mean '${suggestion}'?` : ""}`;
2159
+ if (listedAgents)
2160
+ return problem;
2161
+ listedAgents = true;
2162
+ return [`${problem} Available agents:`, ...formatAvailableAgentLines(agents)].join(`
2163
+ `);
2164
+ }
2165
+ };
2166
+ }
2110
2167
  function canonicalizeExecutionParams(params, agents, diagnostics, context) {
2111
2168
  const resolve = (name, location) => {
2112
2169
  const result = canonicalizeAgentName(name, agents, diagnostics, context);
@@ -2475,6 +2532,9 @@ export const DEFAULT_FOREGROUND_TIMEOUT_MS = 30 * 60 * 1000;
2475
2532
 
2476
2533
  export { DEFAULT_ASYNC_TIMEOUT_MS };
2477
2534
  const MAX_TIMER_DELAY_MS = 2147483647;
2535
+ function timerDelayOverflowError(name, value) {
2536
+ return typeof value === "number" && value > MAX_TIMER_DELAY_MS ? `${name} must be a positive integer no larger than ${MAX_TIMER_DELAY_MS}.` : undefined;
2537
+ }
2478
2538
  export function resolveConfigDefaultTimeoutMs(raw) {
2479
2539
  if (typeof raw !== "number" || !Number.isInteger(raw) || raw <= 0 || raw > MAX_TIMER_DELAY_MS)
2480
2540
  return;
@@ -2492,6 +2552,9 @@ export function resolveForegroundTimeout(params, defaultTimeoutMs) {
2492
2552
  if (typeof value !== "number" || !Number.isInteger(value) || value <= 0) {
2493
2553
  return { error: `${name} must be a positive integer.` };
2494
2554
  }
2555
+ const overflowError = timerDelayOverflowError(name, value);
2556
+ if (overflowError)
2557
+ return { error: overflowError };
2495
2558
  }
2496
2559
  if (rawTimeout !== undefined && rawMaxRuntime !== undefined && rawTimeout !== rawMaxRuntime) {
2497
2560
  return { error: "timeoutMs and maxRuntimeMs are aliases; provide only one value or use the same value for both." };
@@ -2605,7 +2668,7 @@ function withAggregatedToolUsage(result) {
2605
2668
  if (projected.details.results.length === 0)
2606
2669
  return projected;
2607
2670
  const usage = sumResultsUsage(projected.details.results);
2608
- return usage.input !== 0 || usage.output !== 0 || usage.cacheRead !== 0 || usage.cacheWrite !== 0 || usage.cost !== 0 || usage.turns !== 0 ? { ...projected, details: { ...projected.details, totalChildUsage: usage } } : projected;
2671
+ return usage.input !== 0 || usage.output !== 0 || usage.cacheRead !== 0 || usage.cacheWrite !== 0 || usage.cost !== 0 || usage.turns !== 0 ? { ...projected, usage: toAgentToolUsage(usage) } : projected;
2609
2672
  }
2610
2673
  function toExecutionErrorResult(params, error, contextSummary) {
2611
2674
  const message = error instanceof Error ? error.message : String(error);
@@ -2618,7 +2681,7 @@ function toExecutionErrorResult(params, error, contextSummary) {
2618
2681
  function resolveStaticLaunchSummary(input) {
2619
2682
  const agentConfig = input.agents.find((agent) => agent.name === input.agent);
2620
2683
  const externalRunner = agentConfig?.runner?.type === "external-cli" || agentConfig?.runner?.type === "external-job";
2621
- const modelScopes = resolveModelScopesForAgent(input.modelScope, input.agent, input.parentModel);
2684
+ const modelScopes = resolveModelScopesForAgent(input.modelScope, input.agent, input.parentModel, input.scopedModelIds);
2622
2685
  const model = externalRunner ? undefined : resolveEffectiveSubagentModel(input.explicitModel, agentConfig?.model, input.parentModel, input.availableModels, agentConfig?.modelProvider ?? input.currentProvider, modelScopes.length === 0 ? {} : { scope: modelScopes });
2623
2686
  const thinkingOverride = externalRunner ? undefined : input.thinkingOverrideForTask();
2624
2687
  const thinking = externalRunner ? undefined : resolveEffectiveThinking(model, thinkingOverride ?? agentConfig?.thinking);
@@ -2635,6 +2698,7 @@ function collectStaticLaunchSummaries(input) {
2635
2698
  explicitModel,
2636
2699
  agents: input.agents,
2637
2700
  parentModel: input.parentModel,
2701
+ scopedModelIds: input.scopedModelIds,
2638
2702
  availableModels: input.availableModels,
2639
2703
  currentProvider: input.currentProvider,
2640
2704
  modelScope: input.modelScope,
@@ -2774,9 +2838,10 @@ function importedAsyncRootUsage(completed) {
2774
2838
  }
2775
2839
  function removeWorkflowAwaitedResult(asyncDir, resultPath, runId, publication) {
2776
2840
  try {
2777
- fs.rmSync(resultPath, { force: true });
2778
- } catch {}
2779
- removeResultIndex(asyncDir, publication.sessionId, runId, publication.toolCallId);
2841
+ retireResultSnapshot(workflowAwaitedAsyncResultPath(asyncDir), { ...publication, runId }, resultPath);
2842
+ } catch (error) {
2843
+ console.error(`Failed to remove imported workflow child result '${resultPath}'; leaving it in place:`, error);
2844
+ }
2780
2845
  }
2781
2846
  function emitWorkflowAwaitedChildComplete(dm, state, runId, asyncDir, parentWorkflowRunId, completed) {
2782
2847
  let status;
@@ -2801,30 +2866,10 @@ function emitWorkflowAwaitedChildComplete(dm, state, runId, asyncDir, parentWork
2801
2866
  parentWorkflowRunId
2802
2867
  });
2803
2868
  }
2804
- async function waitForWorkflowAsyncSingleResult(params, launchResult, options) {
2805
- if (params.workflowAwaitAsync !== true || !launchResult.details.asyncDir)
2806
- return launchResult;
2807
- const asyncDir = launchResult.details.asyncDir;
2808
- const resultPath = workflowAwaitedAsyncResultPath(asyncDir);
2809
- const stopOnAbort = () => {
2810
- stopAsyncRun(options.state, options.runId, options.kill, { asyncDir, resolvedId: options.runId });
2811
- };
2812
- if (options.signal?.aborted)
2813
- stopOnAbort();
2814
- else
2815
- options.signal?.addEventListener("abort", stopOnAbort, { once: true });
2816
- let completed;
2817
- try {
2818
- completed = await waitForImportedAsyncRoot({ runId: options.runId, asyncDir, resultPath, index: 0 }, omitUndefinedProperties({
2819
- shouldAbort: () => options.signal?.aborted === true,
2820
- timeoutMessage: "Workflow stopped before async child completed."
2821
- }));
2822
- } finally {
2823
- options.signal?.removeEventListener("abort", stopOnAbort);
2824
- }
2869
+ function importWorkflowAwaitedChildResult(completed, options) {
2825
2870
  if (completed.importedPublication)
2826
- removeWorkflowAwaitedResult(asyncDir, resultPath, options.runId, completed.importedPublication);
2827
- emitWorkflowAwaitedChildComplete(options.dm, options.state, options.runId, asyncDir, params.workflowParentRunId, completed);
2871
+ removeWorkflowAwaitedResult(options.asyncDir, options.resultPath, options.runId, completed.importedPublication);
2872
+ emitWorkflowAwaitedChildComplete(options.dm, options.state, options.runId, options.asyncDir, options.parentWorkflowRunId, completed);
2828
2873
  const usage = importedAsyncRootUsage(completed);
2829
2874
  const childResult = omitUndefinedProperties({
2830
2875
  index: 0,
@@ -2853,15 +2898,52 @@ async function waitForWorkflowAsyncSingleResult(params, launchResult, options) {
2853
2898
  ...completed.transcriptError ? { transcriptError: completed.transcriptError } : {}
2854
2899
  });
2855
2900
  return {
2856
- content: [{ type: "text", text: completed.success ? completed.output || completed.error || `Async workflow child ${options.runId} completed without output.` : completed.error || completed.output || `Async workflow child ${options.runId} completed without output.` }],
2901
+ content: [{ type: "text", text: (completed.success ? completed.output || completed.error : completed.error || completed.output) || (options.emptyOutputText ?? `Async workflow child ${options.runId} completed without output.`) }],
2857
2902
  ...completed.success ? {} : { isError: true },
2858
2903
  details: {
2859
- ...launchResult.details,
2904
+ ...options.details,
2860
2905
  runId: options.runId,
2861
2906
  results: [childResult]
2862
2907
  }
2863
2908
  };
2864
2909
  }
2910
+ function stopAwaitedAsyncChildOnAbort(signal, state, runId, asyncDir, kill) {
2911
+ const stopOnAbort = () => {
2912
+ if (!workflowStopCause(signal?.reason))
2913
+ stopAsyncRun(state, runId, kill, { asyncDir, resolvedId: runId });
2914
+ };
2915
+ if (signal?.aborted)
2916
+ stopOnAbort();
2917
+ else
2918
+ signal?.addEventListener("abort", stopOnAbort, { once: true });
2919
+ return { remove: () => signal?.removeEventListener("abort", stopOnAbort) };
2920
+ }
2921
+ function resolveLiveWorkflowRunId(deps, id) {
2922
+ const controllers = deps.state.workflowControllers;
2923
+ if (!controllers?.size)
2924
+ return;
2925
+ if (controllers.has(id))
2926
+ return id;
2927
+ try {
2928
+ const resolved = resolveSubagentRunId(id, omitUndefinedProperties({ state: deps.state, nested: nestedResolutionScopeForExecutor(deps) }));
2929
+ return resolved?.kind === "async" && controllers.has(resolved.id) ? resolved.id : undefined;
2930
+ } catch {
2931
+ return;
2932
+ }
2933
+ }
2934
+ async function waitForWorkflowAsyncSingleResult(params, launchResult, options) {
2935
+ if (params.workflowAwaitAsync !== true || !launchResult.details.asyncDir)
2936
+ return launchResult;
2937
+ const asyncDir = launchResult.details.asyncDir;
2938
+ const resultPath = workflowAwaitedAsyncResultPath(asyncDir);
2939
+ const stopListener = stopAwaitedAsyncChildOnAbort(options.signal, options.state, options.runId, asyncDir, options.kill);
2940
+ const completed = await waitForImportedAsyncRoot({ runId: options.runId, asyncDir, resultPath, index: 0 }, omitUndefinedProperties({
2941
+ shouldAbort: () => options.signal?.aborted === true,
2942
+ timeoutMessage: "Workflow stopped before async child completed.",
2943
+ abortedAsStopped: true
2944
+ })).finally(stopListener.remove);
2945
+ return importWorkflowAwaitedChildResult(completed, { runId: options.runId, asyncDir, resultPath, task: options.task, parentWorkflowRunId: params.workflowParentRunId, details: launchResult.details, state: options.state, dm: options.dm });
2946
+ }
2865
2947
  async function runAsyncPath(data, deps) {
2866
2948
  const {
2867
2949
  params,
@@ -2900,13 +2982,17 @@ async function runAsyncPath(data, deps) {
2900
2982
  cwd: ctx.cwd,
2901
2983
  currentSessionId: data.parentSessionId,
2902
2984
  parentSessionId: data.parentPiSessionId,
2985
+ parentSessionFile: ctx.sessionManager.getSessionFile() ?? undefined,
2903
2986
  currentModelProvider: parentModel?.provider,
2904
2987
  currentModel: parentModel,
2988
+ scopedModelIds: data.scopedModelIds,
2905
2989
  modelScope: data.modelScope,
2906
2990
  modelResponseAliases: deps.config.modelResponseAliases,
2991
+ runnerLaunchers: deps.config.runnerLaunchers,
2907
2992
  interactive: ctx.hasUI,
2908
2993
  permissions: deps.config.permissions,
2909
- childRuntime: deps.childRuntime
2994
+ childRuntime: deps.childRuntime,
2995
+ projectTrusted: sessionProjectTrust(ctx)
2910
2996
  });
2911
2997
  const availableModels = ctx.modelRegistry.getAvailable().map(toModelInfo);
2912
2998
  const currentMaxSubagentDepth = resolveCurrentMaxSubagentDepth(deps.config.maxSubagentDepth, deps.childRuntime);
@@ -2932,7 +3018,7 @@ async function runAsyncPath(data, deps) {
2932
3018
  if ((a.runner?.type === "external-cli" || a.runner?.type === "external-job") && (params.fast ?? a.fast) === true) {
2933
3019
  return buildRequestedModeError(params, `Agent '${a.name}' uses runner.type='${a.runner.type}' and does not support fast mode.`);
2934
3020
  }
2935
- const modelScopes = resolveModelScopesForAgent(data.modelScope, a.name, parentModel);
3021
+ const modelScopes = resolveModelScopesForAgent(data.modelScope, a.name, parentModel, data.scopedModelIds);
2936
3022
  const modelOrigin = resolveModelOrigin({
2937
3023
  storedOrigin: params.modelOrigin,
2938
3024
  explicitModel: params.model,
@@ -2948,11 +3034,13 @@ async function runAsyncPath(data, deps) {
2948
3034
  if (launchRuleError)
2949
3035
  return toExecutionErrorResult(params, new Error(launchRuleError), data.contextPolicy.contextSummary);
2950
3036
  const asyncResult = await executeAsyncSingle(id, compactOptional({
3037
+ toolCallId: data.toolCallId,
2951
3038
  agent: params.agent,
2952
3039
  task: shouldForkAgent(contextPolicy, params.agent) ? wrapForkTask(params.task ?? "") : params.task ?? "",
2953
3040
  goal: params.task ?? "",
2954
3041
  agentConfig: a,
2955
3042
  recoveryAgentConfig: data.recoveryAgents.find((agent) => agent.name === params.agent),
3043
+ requiredExtensions: data.requiredExtensions,
2956
3044
  ctx: asyncCtx,
2957
3045
  availableModels,
2958
3046
  cwd: effectiveCwd,
@@ -3095,6 +3183,39 @@ function appendWorkflowOutputWarning(text, warning) {
3095
3183
 
3096
3184
  ${warning}` : text;
3097
3185
  }
3186
+ const WORKFLOW_TRACE_ERROR_MAX_CHARS = 500;
3187
+ function formatWorkflowResultText(input) {
3188
+ const traceSection = (error) => input.trace.length > 0 ? [`Call trace:
3189
+ ${input.trace.map((entry) => `${entry.line}${entry.error ? ` — ${error(entry.error)}` : ""}`).join(`
3190
+ `)}`] : [];
3191
+ const fullText = [...input.head, ...input.script, ...traceSection((error) => error), ...input.tail].join(`
3192
+
3193
+ `);
3194
+ const outputWarning = writeWorkflowAggregateOutput(input.aggregateOutputPath, fullText, input.producedChildOutputPaths);
3195
+ const scriptText = input.script.join(`
3196
+
3197
+ `);
3198
+ const config = { ...DEFAULT_MAX_OUTPUT, ...input.maxOutput };
3199
+ const scriptCut = truncateOutput(scriptText, config).truncated;
3200
+ const traceCut = input.trace.some((entry) => (entry.error?.length ?? 0) > WORKFLOW_TRACE_ERROR_MAX_CHARS);
3201
+ let shownScriptText = scriptText;
3202
+ let saveWarning;
3203
+ let savedPath;
3204
+ if (scriptCut || traceCut) {
3205
+ const aggregateHoldsFullText = input.aggregateOutputPath !== undefined && !outputWarning && !input.producedChildOutputPaths.has(resolveWorkflowHostOutputClaimPath(input.aggregateOutputPath));
3206
+ if (!aggregateHoldsFullText)
3207
+ saveWarning = writeWorkflowAggregateOutput(input.fullResultPath, fullText, new Set);
3208
+ savedPath = aggregateHoldsFullText ? input.aggregateOutputPath : saveWarning ? undefined : input.fullResultPath;
3209
+ if (scriptCut)
3210
+ shownScriptText = truncateOutput(scriptText, config, savedPath).text;
3211
+ }
3212
+ const shownTrace = traceSection((error) => error.length > WORKFLOW_TRACE_ERROR_MAX_CHARS ? `${error.slice(0, WORKFLOW_TRACE_ERROR_MAX_CHARS)}… (+${error.length - WORKFLOW_TRACE_ERROR_MAX_CHARS} chars)` : error);
3213
+ const traceNote = traceCut && !scriptCut && savedPath ? [`[TRUNCATED: trace errors shortened - full output at ${savedPath}]`] : [];
3214
+ const text = [...input.head, ...shownScriptText ? [shownScriptText] : [], ...shownTrace, ...input.tail, ...traceNote].join(`
3215
+
3216
+ `);
3217
+ return appendWorkflowOutputWarning(appendWorkflowOutputWarning(text, outputWarning), saveWarning);
3218
+ }
3098
3219
  export function resolveWorkflowChildLocalCwd(input) {
3099
3220
  if (input.params.machine !== undefined)
3100
3221
  return input.workflowCwd;
@@ -3118,7 +3239,11 @@ function resolveWorkflowChildOutputPath(input) {
3118
3239
  id: input.params.resume.trim(),
3119
3240
  ...typeof index === "number" && Number.isInteger(index) ? { index } : {}
3120
3241
  }, input.state);
3121
- return { path: "recoveryDescriptor" in target ? target.recoveryDescriptor?.outputPath : undefined, inherited: false };
3242
+ const recoveryOutput = "recoveryDescriptor" in target ? target.recoveryDescriptor?.outputPath : undefined;
3243
+ if (hasExplicitOutput)
3244
+ return { path: recoveryOutput, inherited: false };
3245
+ const foregroundOutput = target.source === "foreground" ? target.resumeContract?.output : undefined;
3246
+ return { path: recoveryOutput, inherited: false, resumedOutput: recoveryOutput ?? (typeof foregroundOutput === "string" && path.isAbsolute(foregroundOutput) ? foregroundOutput : undefined) };
3122
3247
  }
3123
3248
  const childCwd = resolveWorkflowChildLocalCwd(input);
3124
3249
  let agentOutput;
@@ -3150,7 +3275,8 @@ function workflowChildOutputClaims(input) {
3150
3275
  }
3151
3276
  const overrides = new Map;
3152
3277
  for (const entry of resolvedEntries) {
3153
- if (entry.inherited && entry.path && (paths.get(resolveWorkflowHostOutputClaimPath(entry.path)) ?? 0) > 1) {
3278
+ const resumeCollides = entry.resumedOutput !== undefined && input.claimedOutputPaths.has(resolveWorkflowHostOutputClaimPath(entry.resumedOutput));
3279
+ if (resumeCollides || entry.inherited && entry.path && (paths.get(resolveWorkflowHostOutputClaimPath(entry.path)) ?? 0) > 1) {
3154
3280
  const output = workflowChildDefaultOutput(input.aggregateOutputPath, input.artifactsDir, input.workflowRunId, entry.key);
3155
3281
  overrides.set(entry.key, output);
3156
3282
  entry.path = output;
@@ -3168,6 +3294,15 @@ function workflowChildOutputClaims(input) {
3168
3294
  claims.set(claimPath, key);
3169
3295
  childClaims.set(key, claimPath);
3170
3296
  }
3297
+ for (const { key, path: resolved, resumedOutput } of resolvedEntries) {
3298
+ if (resolved || !resumedOutput)
3299
+ continue;
3300
+ const claimPath = resolveWorkflowHostOutputClaimPath(resumedOutput);
3301
+ if (claims.has(claimPath))
3302
+ continue;
3303
+ claims.set(claimPath, key);
3304
+ childClaims.set(key, claimPath);
3305
+ }
3171
3306
  return { claims, childClaims, overrides };
3172
3307
  }
3173
3308
  function applyWorkflowChildOutputClaims(target, claims) {
@@ -3178,7 +3313,7 @@ function applyWorkflowChildOutputClaims(target, claims) {
3178
3313
  function prepareWorkflowChildLaunchParams(input) {
3179
3314
  let childParams = input.childParams;
3180
3315
  const usesDefaultOutput = input.childParams.output === undefined && input.childParams.resume === undefined;
3181
- if (usesDefaultOutput && input.outputOverride !== undefined) {
3316
+ if (input.childParams.output === undefined && input.outputOverride !== undefined) {
3182
3317
  childParams = { ...input.childParams, output: input.outputOverride };
3183
3318
  } else if (usesDefaultOutput && input.aggregateOutputPath !== undefined) {
3184
3319
  childParams = { ...input.childParams, output: workflowChildDefaultOutput(input.aggregateOutputPath, input.artifactsDir, input.parentWorkflowRunId, input.workflowKey) };
@@ -3191,7 +3326,7 @@ function prepareWorkflowChildLaunchParams(input) {
3191
3326
  const agentScope = resolveExecutionAgentScope(childParams.agentScope ?? input.workflowAgentScope);
3192
3327
  const discoveredAgents = input.discoverAgents(childCwd, agentScope).agents;
3193
3328
  const agent = typeof childParams.agent === "string" ? resolveAgentName(childParams.agent, discoveredAgents).agent ?? resolveAgentName(childParams.agent, input.agents).agent : undefined;
3194
- const externalAsyncRequired = agent?.runner?.type === "external-cli" || agent?.runner?.type === "external-job";
3329
+ const externalAsyncRequired = agent?.runner?.type === "external-cli" || agent?.runner?.type === "external-job" || agent?.launcher !== undefined;
3195
3330
  return prepareWorkflowLaunchParams(input.workflowDefaults, childParams, input.parentWorkflowRunId, input.workflowKey, { ...input.options, externalAsyncRequired, outputClaimPath: input.outputClaimPath });
3196
3331
  }
3197
3332
  async function finalizeSingleWorktreeHandoff(input) {
@@ -3328,8 +3463,10 @@ async function runSinglePath(data, deps) {
3328
3463
  }
3329
3464
  let foregroundMachine;
3330
3465
  const requestedMachine = params.machine ?? agentConfig.machine;
3466
+ const requiredExtensions = data.requiredExtensions ?? deps.childRuntime?.requiredExtensions ?? resolveRequiredChildExtensions(data.parentPiSessionId);
3331
3467
  if (requestedMachine) {
3332
3468
  try {
3469
+ assertRequiredChildExtensionsAdmitted([requiredExtensions], { agent: agentConfig.name, runnerType: agentConfig.runner?.type, machine: requestedMachine });
3333
3470
  foregroundMachine = resolveHerdrMachinePlacement({ machine: requestedMachine, cwd: ctx.cwd, stepCwd: params.machineCwd }).machine;
3334
3471
  } catch (error) {
3335
3472
  return toExecutionErrorResult(params, error instanceof Error ? error : new Error(String(error)), data.contextPolicy.contextSummary);
@@ -3341,7 +3478,7 @@ async function runSinglePath(data, deps) {
3341
3478
  const parentModel = data.parentModel;
3342
3479
  const currentProvider = parentModel?.provider;
3343
3480
  const availableModels = ctx.modelRegistry.getAvailable().map(toModelInfo);
3344
- const modelScopes = resolveModelScopesForAgent(data.modelScope, agentConfig.name, parentModel);
3481
+ const modelScopes = resolveModelScopesForAgent(data.modelScope, agentConfig.name, parentModel, data.scopedModelIds);
3345
3482
  let task = typeof params.task === "string" ? params.task : "";
3346
3483
  const modelOrigin = resolveModelOrigin({
3347
3484
  storedOrigin: params.modelOrigin,
@@ -3449,7 +3586,25 @@ async function runSinglePath(data, deps) {
3449
3586
  const interruptController = new AbortController;
3450
3587
  let detachForeground;
3451
3588
  let childSessionControls;
3589
+ let pendingRuntimeStop;
3452
3590
  const foregroundControl = deps.state.foregroundControls.get(runId);
3591
+ const syncHerdrForegroundChild = () => {
3592
+ if (!foregroundControl?.parentWorkflowRunId)
3593
+ return;
3594
+ try {
3595
+ deps.dm.events.emit(HERDR_FOREGROUND_CONTROL_CHANGED_EVENT, { runId: foregroundControl.parentWorkflowRunId });
3596
+ } catch (error) {
3597
+ console.error("Failed to sync Herdr foreground child:", error);
3598
+ }
3599
+ };
3600
+ const finishTrackedForegroundChild = () => {
3601
+ if (!foregroundControl)
3602
+ return;
3603
+ const wasActive = foregroundControl.activeChildren?.has(0) === true;
3604
+ finishForegroundChild(foregroundControl, 0);
3605
+ if (wasActive)
3606
+ syncHerdrForegroundChild();
3607
+ };
3453
3608
  if (foregroundControl) {
3454
3609
  const thinking = resolveEffectiveThinking(modelOverride, thinkingOverrideForTask());
3455
3610
  beginForegroundChild(foregroundControl, omitUndefinedProperties({
@@ -3487,6 +3642,7 @@ async function runSinglePath(data, deps) {
3487
3642
  }));
3488
3643
  if (deps.childRuntime?.fanoutChild)
3489
3644
  deps.activateSupervisorTransport?.();
3645
+ syncHerdrForegroundChild();
3490
3646
  }
3491
3647
  const modelResponseAliases = deps.config.modelResponseAliases === undefined ? undefined : structuredClone(deps.config.modelResponseAliases);
3492
3648
  const forwardSingleUpdate = onUpdate ? (update) => {
@@ -3495,24 +3651,28 @@ async function runSinglePath(data, deps) {
3495
3651
  onUpdate(update);
3496
3652
  } : undefined;
3497
3653
  const deadlineAt = data.deadlineAt ?? (data.timeoutMs !== undefined ? Date.now() + data.timeoutMs : undefined);
3498
- const requiredExtensions = deps.childRuntime?.requiredExtensions ?? resolveRequiredChildExtensions(data.parentPiSessionId);
3499
3654
  let r;
3500
3655
  let resolveDetachedWorkflowChild;
3501
3656
  const detachedWorkflowChild = params.workflowAwaitDetached === true ? new Promise((resolve) => {
3502
3657
  resolveDetachedWorkflowChild = resolve;
3503
3658
  }) : undefined;
3504
3659
  try {
3660
+ const childSessionFile = sessionFileForTask(params.agent, 0, modelOverride, modelOverrideFromParent, modelOrigin);
3505
3661
  const launched = await runSync(ctx.cwd, agents, params.agent, task, compactOptional({
3506
3662
  machine: foregroundMachine,
3507
3663
  parentProviderRegistry: ctx.modelRegistry,
3664
+ projectTrusted: sessionProjectTrust(ctx),
3508
3665
  remoteReads: foregroundMachine ? readsOverride : undefined,
3509
3666
  permissions: deps.config.permissions,
3510
3667
  runtimeSnapshotHost: deps.dm,
3511
3668
  parentSessionId: ctx.sessionManager.getSessionId() ?? undefined,
3669
+ parentSessionFile: ctx.sessionManager.getSessionFile() ?? undefined,
3512
3670
  requiredExtensions,
3513
3671
  childRuntime: deps.childRuntime,
3514
3672
  onChildSession: (controls) => {
3515
3673
  childSessionControls = controls;
3674
+ if (pendingRuntimeStop)
3675
+ controls.stop(pendingRuntimeStop);
3516
3676
  },
3517
3677
  context: data.contextPolicy.contextForAgent(params.agent),
3518
3678
  unknownAgentDiagnosticContext: data.unknownAgentDiagnosticContext,
@@ -3520,12 +3680,13 @@ async function runSinglePath(data, deps) {
3520
3680
  cwd: singleCwd,
3521
3681
  requestedCwd: data.requestedCwd,
3522
3682
  signal,
3683
+ abortedAsStopped: params.workflowParentRunId !== undefined,
3523
3684
  interruptSignal: interruptController.signal,
3524
3685
  allowIntercomDetach: agentConfig.systemPrompt?.includes(INTERCOM_BRIDGE_MARKER) === true,
3525
3686
  intercomEvents: deps.dm.events,
3526
3687
  runId,
3527
3688
  sessionDir: sessionDirForIndex(0),
3528
- sessionFile: sessionFileForTask(params.agent, 0, modelOverride, modelOverrideFromParent, modelOrigin),
3689
+ sessionFile: childSessionFile,
3529
3690
  share: shareEnabled,
3530
3691
  artifactsDir: artifactConfig.enabled ? artifactsDir : undefined,
3531
3692
  artifactConfig,
@@ -3566,6 +3727,8 @@ async function runSinglePath(data, deps) {
3566
3727
  detachForeground = detach;
3567
3728
  },
3568
3729
  onDetachedExit: async (result) => {
3730
+ if (foregroundControl)
3731
+ foregroundControl.stopForRuntimeReplacement = undefined;
3569
3732
  if (resolveDetachedWorkflowChild) {
3570
3733
  resolveDetachedWorkflowChild(result);
3571
3734
  return;
@@ -3594,8 +3757,7 @@ async function runSinglePath(data, deps) {
3594
3757
  cleanupStructuredOutputRuntime(structuredRuntime);
3595
3758
  } finally {
3596
3759
  try {
3597
- if (foregroundControl)
3598
- finishForegroundChild(foregroundControl, 0);
3760
+ finishTrackedForegroundChild();
3599
3761
  } finally {
3600
3762
  removeForegroundControlIfIdle(deps.state, runId, deps.trackRetainedNestedRoute);
3601
3763
  }
@@ -3612,6 +3774,17 @@ async function runSinglePath(data, deps) {
3612
3774
  capabilityCeiling: data.capabilityCeiling,
3613
3775
  allowZeroToolBudget: data.allowZeroToolBudget && effectiveToolBudget.toolBudget === data.toolBudget
3614
3776
  }));
3777
+ if (launched.detached && foregroundControl) {
3778
+ foregroundControl.stopForRuntimeReplacement = () => {
3779
+ const sessionFile = childSessionFile && fs.existsSync(childSessionFile) ? childSessionFile : undefined;
3780
+ const stopped = { ...launched, detached: undefined, stopped: true, exitCode: 1, error: RUNTIME_REPLACED_STOP_ERROR, finalOutput: RUNTIME_REPLACED_STOP_ERROR, sessionFile };
3781
+ rememberForegroundRun(deps.state, { modelResponseAliases, runId, mode: "single", cwd: singleCwd, sessionId: data.parentSessionId, results: [stopped], params, effectiveOutput, effectiveOutputMode, extensionBindings: params.extensionBindings, requiredExtensions });
3782
+ if (childSessionControls)
3783
+ childSessionControls.stop(RUNTIME_REPLACED_STOP_ERROR);
3784
+ else
3785
+ pendingRuntimeStop = RUNTIME_REPLACED_STOP_ERROR;
3786
+ };
3787
+ }
3615
3788
  r = launched.detached && detachedWorkflowChild ? await detachedWorkflowChild : launched;
3616
3789
  } catch (error) {
3617
3790
  await cleanupSingleWorktree();
@@ -3620,8 +3793,7 @@ async function runSinglePath(data, deps) {
3620
3793
  if (!r?.detached) {
3621
3794
  if (!artifactConfig.enabled)
3622
3795
  cleanupStructuredOutputRuntime(structuredRuntime);
3623
- if (foregroundControl)
3624
- finishForegroundChild(foregroundControl, 0);
3796
+ finishTrackedForegroundChild();
3625
3797
  }
3626
3798
  }
3627
3799
  if (!r.detached) {
@@ -3714,12 +3886,12 @@ ${worktreeHandoff.suffix}` : "";
3714
3886
  isError: true
3715
3887
  };
3716
3888
  return {
3717
- content: [{ type: "text", text: `${finalizedOutput.displayOutput || "(no output)"}${worktreeSuffix}` }],
3889
+ content: [{ type: "text", text: `${capInlineOutput(finalizedOutput.displayOutput, { artifactPath: r.artifactPaths?.outputPath, savedPath: finalizedOutput.savedPath }) || "(no output)"}${worktreeSuffix}` }],
3718
3890
  details
3719
3891
  };
3720
3892
  }
3721
3893
  function inferExecutionMode(params) {
3722
- if (params.workflowScript !== undefined)
3894
+ if (params.workflowScript !== undefined || params.workflow !== undefined)
3723
3895
  return "workflow";
3724
3896
  if ((params.chain?.length ?? 0) > 0)
3725
3897
  return "chain";
@@ -3739,6 +3911,7 @@ function duplicateSubagentCallResult(params) {
3739
3911
  }
3740
3912
  const workflowLaunchObservers = new WeakMap;
3741
3913
  const workflowOwnedUsageBudgets = new WeakMap;
3914
+ const workflowRetainedRequiredExtensions = new WeakMap;
3742
3915
  const missionsMissingFromStore = new Set;
3743
3916
  function recordMissionWorkflowChild(binding, workflowRunId, key, update) {
3744
3917
  if (!binding || missionsMissingFromStore.has(binding.missionId))
@@ -3793,7 +3966,8 @@ function workflowChildResult(key, result, childParams = {}, resumeState, forcedT
3793
3966
  `);
3794
3967
  const output = running ? "" : result.details.results.length === 1 && result.details.results[0]?.finalOutput !== undefined ? result.details.results[0].finalOutput : receiptOutput;
3795
3968
  const childError = result.details.results.map((child) => child.error).find((error) => Boolean(error));
3796
- const failureErrorBase = childError && receiptOutput ? receiptOutput.includes(childError) ? receiptOutput : `${childError}
3969
+ const stopped = result.details.results.some((child) => child.stopped);
3970
+ const failureErrorBase = stopped && childError ? childError : childError && receiptOutput ? receiptOutput.includes(childError) ? receiptOutput : `${childError}
3797
3971
 
3798
3972
  ${receiptOutput}` : childError || receiptOutput || output || "Child run failed.";
3799
3973
  const savedOutputEvidence = [...new Set(result.details.results.map((child) => child.savedOutputPath).filter((value) => Boolean(value)))].filter((savedOutputPath) => !failureErrorBase.includes(savedOutputPath)).map((savedOutputPath) => `Saved output: ${savedOutputPath}`);
@@ -3801,7 +3975,6 @@ ${receiptOutput}` : childError || receiptOutput || output || "Child run failed."
3801
3975
  `);
3802
3976
  const detached = result.details.results.some((child) => child.detached);
3803
3977
  const interrupted = result.details.results.some((child) => child.interrupted);
3804
- const stopped = result.details.results.some((child) => child.stopped);
3805
3978
  const terminalOutcome = forcedTerminalOutcome ?? (result.details.results.some((child) => child.timedOut) ? { state: "partial", reason: "timeout" } : result.details.usageBudget?.exhausted || result.details.results.some((child) => child.turnBudgetExceeded || child.toolBudgetBlocked) ? { state: "partial", reason: "budget_exhausted" } : undefined);
3806
3979
  const acceptanceRecovery = result.details.results.find((child) => child.acceptance?.recovery)?.acceptance?.recovery;
3807
3980
  const ok = result.isError !== true && !running && !detached && !interrupted && !stopped && acceptanceRecovery === undefined;
@@ -3892,9 +4065,9 @@ function workflowRunningChildrenSummary(children) {
3892
4065
  return running.length ? `${running.length} child ${running.length === 1 ? "run remains" : "runs remain"} running or uncollected: ${running.map((child) => `${child.key}=${child.runId}`).join(", ")}. These launch receipts contain no final child results.` : "";
3893
4066
  }
3894
4067
  function workflowResultChildren(children, status, includeFailureFields) {
3895
- return children.map((child) => {
4068
+ return withWorkflowRevivals(DIRS.async, status.runId, children).map((child) => {
3896
4069
  const sessionName = status.steps?.find((step) => step.workflowKey === child.key)?.sessionName;
3897
- return { workflowKey: child.key, ...child.agent ? { agent: child.agent } : {}, ...child.runId ? { runId: child.runId } : {}, ...sessionName ? { sessionName } : {}, ...workflowChildAccountingFields(child), output: child.output, outputState: child.output.trim() || child.structuredOutput !== undefined ? "present" : "absent", structuredOutput: child.structuredOutput, ...child.state === "running" ? { state: "running" } : { success: child.ok }, ...child.asyncDir ? { asyncDir: child.asyncDir } : {}, ...child.outputReference ? { outputReference: child.outputReference } : {}, ...includeFailureFields && child.terminalOutcome ? { terminalOutcome: child.terminalOutcome } : {}, ...child.outputPathMapping ? { outputPathMapping: child.outputPathMapping } : {}, ...child.stopped ? { stopped: true } : {}, ...child.interrupted ? { interrupted: true } : {}, ...includeFailureFields && child.detached && status.state !== "complete" ? { detached: true } : {}, ...child.outputArtifactPath || child.outputReference ? { artifactPaths: { outputPath: child.outputArtifactPath ?? child.outputReference } } : {} };
4070
+ return { workflowKey: child.key, ...child.agent ? { agent: child.agent } : {}, ...child.runId ? { runId: child.runId } : {}, ...child.revival ? { revival: formatWorkflowKeyRevival(child.revival) } : {}, ...sessionName ? { sessionName } : {}, ...workflowChildAccountingFields(child), output: child.output, outputState: child.output.trim() || child.structuredOutput !== undefined ? "present" : "absent", structuredOutput: child.structuredOutput, ...child.state === "running" ? { state: "running" } : { success: child.ok }, ...!child.ok && child.error ? { error: child.error } : {}, ...child.asyncDir ? { asyncDir: child.asyncDir } : {}, ...child.outputReference ? { outputReference: child.outputReference } : {}, ...includeFailureFields && child.terminalOutcome ? { terminalOutcome: child.terminalOutcome } : {}, ...child.outputPathMapping ? { outputPathMapping: child.outputPathMapping } : {}, ...child.stopped ? { stopped: true } : {}, ...child.interrupted ? { interrupted: true } : {}, ...includeFailureFields && child.detached && status.state !== "complete" ? { detached: true } : {}, ...child.outputArtifactPath || child.outputReference ? { artifactPaths: { outputPath: child.outputArtifactPath ?? child.outputReference } } : {} };
3898
4071
  });
3899
4072
  }
3900
4073
  function workflowOutputPathMappingSummary(children) {
@@ -3902,7 +4075,11 @@ function workflowOutputPathMappingSummary(children) {
3902
4075
  return mappings.length > 0 ? ` Output path mappings: ${mappings.join("; ")}.` : "";
3903
4076
  }
3904
4077
  function workflowDetailsResults(children) {
3905
- return children.flatMap((child) => (child.results ?? []).map((result) => result.workflowKey ? result : { ...result, workflowKey: child.key }));
4078
+ return children.flatMap((child) => (child.results ?? []).map((result) => ({
4079
+ ...result,
4080
+ workflowKey: result.workflowKey ?? child.key,
4081
+ ...child.runId && !result.runId ? { runId: child.runId } : {}
4082
+ })));
3906
4083
  }
3907
4084
  function workflowSteerReceipt(key, result) {
3908
4085
  const steering = result.details.steering;
@@ -3921,6 +4098,7 @@ function workflowSteerReceipt(key, result) {
3921
4098
  };
3922
4099
  }
3923
4100
  const CHILD_SESSION_NOT_RUNNING_YET = "Child session is not running yet.";
4101
+ const RUNTIME_REPLACED_STOP_ERROR = "Subagent stopped because the dm-subagents runtime that ran it was replaced (reload or session switch).";
3924
4102
  const MAX_WORKFLOW_RESUME_HINT_BYTES = 1024;
3925
4103
  const MAX_WORKFLOW_CHILD_RUN_ID_BYTES = 256;
3926
4104
  const WORKFLOW_RESUME_HINT_PARENT_STATES = new Set(["complete", "failed", "partial"]);
@@ -4017,7 +4195,7 @@ function resolveWorkflowResume(reference, deps, parentSessionFile, index) {
4017
4195
  }
4018
4196
  }
4019
4197
  function terminalWorkflowReceipt(workflowRunId, state, children, workflowChildren, terminalOutcome, hostSteps, resource, argsDigest) {
4020
- return buildWorkflowReceipt({ workflowRunId, state, children, workflowChildren, terminalOutcome, hostSteps, resource, ...argsDigest ? { argsDigest } : {} });
4198
+ return buildWorkflowReceipt({ workflowRunId, state, children: withWorkflowRevivals(DIRS.async, workflowRunId, children), workflowChildren, terminalOutcome, hostSteps, resource, ...argsDigest ? { argsDigest } : {} });
4021
4199
  }
4022
4200
  function workflowFailureTerminalOutcome(error, _children, usageBudget) {
4023
4201
  if (usageBudget?.exhausted)
@@ -4373,6 +4551,7 @@ function createScheduledOwnerState(source, ownerSessionId, ctx) {
4373
4551
  };
4374
4552
  }
4375
4553
  export function createSubagentExecutor(deps) {
4554
+ const executorDeps = deps;
4376
4555
  const delegatedThinkingOverrides = new WeakMap;
4377
4556
  const delegatedZeroToolBudgets = new WeakSet;
4378
4557
  const delegatedExecutions = new WeakSet;
@@ -4381,9 +4560,28 @@ export function createSubagentExecutor(deps) {
4381
4560
  const workflowPermitContexts = new WeakMap;
4382
4561
  const warnedArtifactPackageDirs = new Set;
4383
4562
  const scheduledOwnerExecutors = new Map;
4563
+ const disabledFeatures = resolveDisabledFeatureSurface(deps.config);
4564
+ const disabledFeatureResult = (params) => {
4565
+ const error = disabledFeatureUseError(params, disabledFeatures);
4566
+ if (!error)
4567
+ return;
4568
+ return { content: [{ type: "text", text: error }], isError: true, details: { mode: params.action === undefined ? inferExecutionMode(params) : "management", results: [] } };
4569
+ };
4570
+ const admitEnabledWorkflowChildren = (calls) => {
4571
+ for (const call of calls) {
4572
+ const error = disabledFeatureUseError(call.params, disabledFeatures, `workflow child '${call.key}'`);
4573
+ if (error)
4574
+ throw new Error(error);
4575
+ }
4576
+ };
4384
4577
  const execute = async (_id, params, signal, onUpdate, ctx, preserveActiveSession = false, parentModelOverride) => {
4578
+ const projectScopeError = projectScopeTrustError(params, ctx);
4579
+ if (projectScopeError)
4580
+ return projectScopeError;
4581
+ const deps = withSessionProjectTrust(executorDeps, ctx);
4385
4582
  const workflowLaunchObserver = workflowLaunchObservers.get(params);
4386
4583
  const inheritedUsageBudget = workflowOwnedUsageBudgets.get(params);
4584
+ const retainedRequiredExtensions = workflowRetainedRequiredExtensions.get(params);
4387
4585
  const delegatedThinkingOverride = delegatedThinkingOverrides.get(params);
4388
4586
  const allowZeroToolBudget = delegatedZeroToolBudgets.has(params);
4389
4587
  const delegatedExecution = delegatedExecutions.has(params);
@@ -4405,9 +4603,18 @@ export function createSubagentExecutor(deps) {
4405
4603
  if (capacityOverrideError)
4406
4604
  return buildRequestedModeError(requestParams, capacityOverrideError);
4407
4605
  let workflowPreflight;
4606
+ const resolveWorkflowParentModel = () => parentModelOverride !== undefined ? parentModelOverride : (() => {
4607
+ const currentParentModel = normalizeParentModel(ctx.model);
4608
+ return (preserveActiveSession ? currentParentModel : rememberParentModel(deps.state, resolveCurrentSessionId(ctx.sessionManager), currentParentModel)) ?? null;
4609
+ })();
4610
+ const validateWorkflowRequest = () => {
4611
+ const validation = validateWorkflowScript(requestParams.workflowScript ?? "", workflowValidationOptions(deps, requestParams, ctx.cwd, () => resolveWorkflowParentModel()?.provider));
4612
+ const normalizedArgs = normalizeWorkflowArgs(requestParams.args);
4613
+ return "error" in normalizedArgs ? { ...validation, ok: false, errors: [...validation.errors, { message: normalizedArgs.error }] } : validation;
4614
+ };
4408
4615
  try {
4409
- if (requestParams.preflight !== undefined && requestParams.workflowScript === undefined && requestParams.workflowScriptPath === undefined) {
4410
- throw new Error("preflight requires workflowScript or workflowScriptPath.");
4616
+ if (requestParams.preflight !== undefined && requestParams.workflowScript === undefined) {
4617
+ throw new Error("preflight requires workflow: true or a workflow script path.");
4411
4618
  }
4412
4619
  workflowPreflight = normalizeWorkflowPreflight(requestParams.preflight);
4413
4620
  if (workflowPreflight)
@@ -4415,9 +4622,7 @@ export function createSubagentExecutor(deps) {
4415
4622
  } catch (error) {
4416
4623
  const message = error instanceof Error ? error.message : String(error);
4417
4624
  if (requestParams.action?.trim() === "validate") {
4418
- const validation = validateWorkflowScript(requestParams.workflowScript ?? "", {
4419
- maxSubagentSpawnsPerRun: requestParams.maxSubagentSpawnsPerRun ?? resolveMaxSubagentSpawnsPerRun(deps.config.maxSubagentSpawnsPerRun)
4420
- });
4625
+ const validation = validateWorkflowRequest();
4421
4626
  const invalidValidation = { ...validation, ok: false, errors: [...validation.errors, { message }] };
4422
4627
  return {
4423
4628
  content: [{ type: "text", text: JSON.stringify(invalidValidation) }],
@@ -4428,10 +4633,7 @@ export function createSubagentExecutor(deps) {
4428
4633
  return buildRequestedModeError(requestParams, message);
4429
4634
  }
4430
4635
  if (requestParams.action?.trim() === "validate") {
4431
- const validation = validateWorkflowScript(requestParams.workflowScript ?? "", {
4432
- maxSubagentSpawnsPerRun: requestParams.maxSubagentSpawnsPerRun ?? resolveMaxSubagentSpawnsPerRun(deps.config.maxSubagentSpawnsPerRun)
4433
- });
4434
- return buildWorkflowValidationResult(validation, "management", workflowPreflight);
4636
+ return buildWorkflowValidationResult(validateWorkflowRequest(), "management", workflowPreflight);
4435
4637
  }
4436
4638
  const normalizedAction = typeof requestParams.action === "string" ? requestParams.action.trim() : requestParams.action;
4437
4639
  if (normalizedAction === "resume" && requestParams.extensionBindings !== undefined)
@@ -4449,20 +4651,24 @@ export function createSubagentExecutor(deps) {
4449
4651
  const workflowArgsEvidence = requestParams.args === undefined ? undefined : { args: requestParams.args, argsDigest: stableJsonDigest(requestParams.args) };
4450
4652
  const workflowArgs = workflowArgsEvidence?.args;
4451
4653
  const workflowArgsDigest = workflowArgsEvidence?.argsDigest;
4452
- const workflowValidation = validateWorkflowScript(requestParams.workflowScript, {
4453
- maxSubagentSpawnsPerRun: requestParams.maxSubagentSpawnsPerRun ?? resolveMaxSubagentSpawnsPerRun(deps.config.maxSubagentSpawnsPerRun)
4454
- });
4654
+ const workflowParentModel = resolveWorkflowParentModel();
4655
+ const workflowValidation = validateWorkflowScript(requestParams.workflowScript, workflowValidationOptions(deps, requestParams, ctx.cwd, () => workflowParentModel?.provider));
4455
4656
  if (!workflowValidation.ok && publicExecution)
4456
4657
  return buildWorkflowValidationResult(workflowValidation, "workflow", workflowPreflight);
4457
- const spawnBudgetErrors = workflowValidation.errors.filter((error) => error.kind === "spawn-budget");
4458
- if (spawnBudgetErrors.length > 0) {
4459
- return buildRequestedModeError(requestParams, `Workflow '${_id}' validation failed before child launch; no children launched. ${spawnBudgetErrors.map((error) => error.message).join(" ")}`);
4658
+ const launchBlockingErrors = workflowValidation.errors.filter((error) => error.kind === "spawn-budget" || error.kind === "agent");
4659
+ if (launchBlockingErrors.length > 0) {
4660
+ return buildRequestedModeError(requestParams, `Workflow '${_id}' validation failed before child launch; no children launched. ${launchBlockingErrors.map((error) => error.message).join(" ")}`);
4661
+ }
4662
+ const structuredResource = workflowResource?.provenance.name === "chain" || workflowResource?.provenance.name === "tasks";
4663
+ for (const warning of workflowValidation.warnings ?? []) {
4664
+ if (!(structuredResource && warning.kind === "dynamic-spawn-count"))
4665
+ console.warn(`[dm-subagents] ${warning.message}`);
4460
4666
  }
4461
- for (const warning of workflowValidation.warnings ?? [])
4462
- console.warn(`[dm-subagents] ${warning.message}`);
4463
4667
  const acceptanceErrors = validateAcceptanceInput(requestParams.acceptance);
4464
4668
  if (acceptanceErrors.length > 0)
4465
4669
  return buildRequestedModeError(requestParams, acceptanceErrors.join(" "));
4670
+ const admittedRequiredExtensions = retainedRequiredExtensions ?? deps.childRuntime?.requiredExtensions ?? resolveRequiredChildExtensions(ctx.sessionManager.getSessionId() ?? undefined);
4671
+ const workflowRequiredExtensions = hasMandatoryRequiredChildExtensions(admittedRequiredExtensions) ? admittedRequiredExtensions : undefined;
4466
4672
  const foregroundWorkflowRunId = encodeIndexSegment(_id);
4467
4673
  if (delegatedWorkflowPermit) {
4468
4674
  const permitError = validateWorkflowChildPermitRoot(delegatedWorkflowPermit, foregroundWorkflowRunId);
@@ -4471,10 +4677,6 @@ export function createSubagentExecutor(deps) {
4471
4677
  if (requestParams.async !== false)
4472
4678
  return buildRequestedModeError(requestParams, "Workflow child permit supports foreground workflow roots only; set async:false.");
4473
4679
  }
4474
- const workflowParentModel = parentModelOverride !== undefined ? parentModelOverride : (() => {
4475
- const currentParentModel = normalizeParentModel(ctx.model);
4476
- return (preserveActiveSession ? currentParentModel : rememberParentModel(deps.state, resolveCurrentSessionId(ctx.sessionManager), currentParentModel)) ?? null;
4477
- })();
4478
4680
  if (requestParams.extensionBindings !== undefined) {
4479
4681
  try {
4480
4682
  requestParams.extensionBindings = normalizeExtensionBindings(requestParams.extensionBindings).value;
@@ -4483,6 +4685,13 @@ export function createSubagentExecutor(deps) {
4483
4685
  }
4484
4686
  }
4485
4687
  const parentCwd = ctx.cwd;
4688
+ for (const [name, value] of [["timeoutMs", requestParams.timeoutMs], ["maxRuntimeMs", requestParams.maxRuntimeMs]]) {
4689
+ if (value === undefined)
4690
+ continue;
4691
+ const overflowError = timerDelayOverflowError(name, value);
4692
+ if (overflowError)
4693
+ return buildRequestedModeError(requestParams, overflowError);
4694
+ }
4486
4695
  const timeout = requestParams.timeoutMs ?? requestParams.maxRuntimeMs ?? (requestParams.async === false ? resolveConfigDefaultTimeoutMs(deps.config.timeoutMs) ?? DEFAULT_FOREGROUND_TIMEOUT_MS : undefined);
4487
4696
  const workflowUsageBudget = validateUsageBudgetConfig(requestParams.usageBudget ?? deps.config.usageBudget, requestParams.usageBudget ? "usageBudget" : "config.usageBudget");
4488
4697
  if (workflowUsageBudget.error)
@@ -4583,6 +4792,12 @@ export function createSubagentExecutor(deps) {
4583
4792
  const workflowCapabilityCeiling = intersectSubagentCapabilityCeilings(requestParams.capabilityCeiling, resolveCurrentSubagentCapabilityCeiling(currentSessionId));
4584
4793
  const completionOwnerId = deps.state.completionOwnerId ?? currentCompletionOwnerId();
4585
4794
  deps.state.completionOwnerId = completionOwnerId;
4795
+ const workflowScriptSourceDigest = workflowScriptDigest(requestParams.workflowScript);
4796
+ const workflowReuseSource = findWorkflowReuseSource(DIRS.async, currentSessionId, workflowScriptSourceDigest, workflowArgsDigest);
4797
+ const workflowRunEvidence = { ...workflowArgsEvidence, scriptDigest: workflowScriptSourceDigest };
4798
+ if (workflowReuseSource)
4799
+ workflowRunEvidence.reusedFrom = workflowReuseSource.runId;
4800
+ const workflowJournalFingerprints = new Map;
4586
4801
  try {
4587
4802
  fs.mkdirSync(asyncDir, { recursive: true });
4588
4803
  writeRunFanoutBudgetDescriptor(asyncDir, workflowFanoutBudget);
@@ -4615,7 +4830,7 @@ export function createSubagentExecutor(deps) {
4615
4830
  ...workflowCapabilityCeiling ? { admissionCapabilityCeiling: workflowCapabilityCeiling } : {},
4616
4831
  steps: [],
4617
4832
  ...workflowPreflight ? { preflight: workflowPreflight } : {},
4618
- workflow: { trace: [], emits: [], console: [], ...workflowArgsEvidence ?? {}, ...workflowResource ? { resource: workflowResource.provenance } : {} },
4833
+ workflow: { trace: [], emits: [], console: [], ...workflowRunEvidence, ...workflowResource ? { resource: workflowResource.provenance } : {} },
4619
4834
  workflowChildren: workflowChildSummary({ parentToolCallId: toolCallId, workflowRunId, workflowState: "running", inventoryComplete: false }),
4620
4835
  runFanoutBudget: getRunFanoutBudgetSnapshot(workflowFanoutBudget)
4621
4836
  };
@@ -4662,7 +4877,7 @@ export function createSubagentExecutor(deps) {
4662
4877
  if (deps.state.currentSessionId !== currentSessionId || deps.state.completionOwnerId !== completionOwnerId)
4663
4878
  return false;
4664
4879
  try {
4665
- deps.dm.sendMessage({
4880
+ (deps.parentWake ?? deps.dm).sendMessage({
4666
4881
  customType: "subagent-workflow-result-write-failed",
4667
4882
  content: message,
4668
4883
  display: true
@@ -5099,6 +5314,8 @@ export function createSubagentExecutor(deps) {
5099
5314
  workflowSteps.set(entry.key, step);
5100
5315
  }
5101
5316
  const projectedStep = workflowSteps.get(entry.key);
5317
+ if (entry.reused && projectedStep)
5318
+ projectedStep.reused = true;
5102
5319
  if (entry.state === "stopped" && projectedStep) {
5103
5320
  appendWorkflowEvent({
5104
5321
  type: "subagent.child-status",
@@ -5132,7 +5349,7 @@ export function createSubagentExecutor(deps) {
5132
5349
  timeoutMs: timeout,
5133
5350
  signal: controller.signal,
5134
5351
  continueAfterAbortWhenChildrenSettled: (abortError) => {
5135
- if (abortError.message !== "Workflow stopped because the extension session was replaced or reloaded.")
5352
+ if (!workflowStopCause(abortError))
5136
5353
  return false;
5137
5354
  const activeAsyncChild = [...deps.state.asyncJobs?.values() ?? []].some((job) => job.parentWorkflowRunId === workflowRunId && (job.status === "queued" || job.status === "running"));
5138
5355
  const activeForegroundChild = [...deps.state.foregroundControls.values()].some((control) => control.parentWorkflowRunId === workflowRunId && (control.activeChildren?.size ?? 0) > 0);
@@ -5147,6 +5364,18 @@ export function createSubagentExecutor(deps) {
5147
5364
  ...workflowState ? { state: workflowState } : {},
5148
5365
  onTrace: updateTrace,
5149
5366
  onChildSettled: (notification) => {
5367
+ const journalFingerprint = workflowJournalFingerprints.get(notification.childKey);
5368
+ if (journalFingerprint)
5369
+ appendWorkflowChildJournal(asyncDir, { type: "settle", key: notification.childKey, fingerprint: journalFingerprint, result: notification.result });
5370
+ const settledResults = notification.result.results ?? [];
5371
+ const settledStep = settledResults.length ? status.steps?.find((candidate) => candidate.workflowKey === notification.childKey) : undefined;
5372
+ if (settledStep) {
5373
+ const usage = sumResultsUsage(settledResults);
5374
+ settledStep.tokens = { input: usage.input, output: usage.output, total: usage.input + usage.output };
5375
+ if (usage.turns > 0)
5376
+ settledStep.turnCount = usage.turns;
5377
+ persist({ tolerateStatusWriteFailure: true });
5378
+ }
5150
5379
  appendWorkflowEvent({
5151
5380
  type: "subagent.workflow.child_settled",
5152
5381
  childKey: notification.childKey,
@@ -5155,10 +5384,11 @@ export function createSubagentExecutor(deps) {
5155
5384
  workflowRunning: notification.workflowRunning
5156
5385
  });
5157
5386
  try {
5158
- deps.dm.sendMessage({
5387
+ (deps.parentWake ?? deps.dm).sendMessage({
5159
5388
  customType: "subagent-incremental-child-notify",
5160
5389
  content: formatIncrementalChildCompletion(notification),
5161
- display: notification.outcome !== "completed"
5390
+ display: notification.outcome !== "completed",
5391
+ details: { childKey: notification.childKey, outcome: notification.outcome }
5162
5392
  }, { triggerTurn: incrementalChildCompletionTriggersTurn(notification, requestParams.scheduleOrigin) });
5163
5393
  } catch (sendError) {
5164
5394
  console.error(`Failed to send incremental child completion notification for '${notification.childKey}':`, sendError);
@@ -5178,6 +5408,7 @@ export function createSubagentExecutor(deps) {
5178
5408
  } });
5179
5409
  },
5180
5410
  admit: async (calls, admissionSignal) => {
5411
+ admitEnabledWorkflowChildren(calls);
5181
5412
  await preflightWorkflowWorktrees({ workflowDefaults: workflowChildDefaults, defaultWorktree: deps.config.worktree, calls, ctxCwd: parentCwd, signal: admissionSignal, deadlineAt: workflowDeadlineAt });
5182
5413
  const outputClaims = workflowChildOutputClaims({ ctxCwd: parentCwd, workflowCwd, artifactsDir: workflowArtifactsDir, workflowRunId, aggregateOutputPath: workflowAggregateOutputPath, configuredOutputBaseDir, discoverAgents: discoverWorkflowAgents, agents: workflowAgents, workflowAgentScope: workflowChildDefaults.agentScope, state: deps.state, claimedOutputPaths, entries: calls });
5183
5414
  if (outputClaims.error)
@@ -5199,6 +5430,30 @@ export function createSubagentExecutor(deps) {
5199
5430
  appendWorkflowEvent({ type: "subagent.workflow.emit", value: emits.at(-1) });
5200
5431
  },
5201
5432
  launch: async (key, childParams, workflowSignal, admission) => {
5433
+ const journalFingerprint = workflowJournalFingerprints.get(key) ?? workflowChildFingerprint(childParams);
5434
+ workflowJournalFingerprints.set(key, journalFingerprint);
5435
+ const priorChild = workflowReuseSource ? matchWorkflowReuse(workflowReuseSource, key, journalFingerprint) : undefined;
5436
+ if (priorChild?.kind === "settled") {
5437
+ if (priorChild.result.runId)
5438
+ workflowChildRunIds.set(key, priorChild.result.runId);
5439
+ return { ...priorChild.result, reused: true };
5440
+ }
5441
+ if (priorChild?.kind === "started") {
5442
+ const priorRunId = priorChild.runId;
5443
+ const priorAsyncDir = path.join(DIRS.async, priorRunId);
5444
+ appendWorkflowChildJournal(asyncDir, { type: "start", key, fingerprint: journalFingerprint, runId: priorRunId });
5445
+ const stopListener = stopAwaitedAsyncChildOnAbort(workflowSignal, deps.state, priorRunId, priorAsyncDir, deps.kill);
5446
+ const reattached = await awaitExistingAsyncRun(priorAsyncDir, priorRunId, workflowSignal).finally(stopListener.remove);
5447
+ const claimedPath = reattached.status === "settled" ? claimWorkflowAwaitedResult(priorAsyncDir, workflowRunId, { ...reattached.result.importedPublication, runId: priorRunId }) : undefined;
5448
+ if (reattached.status === "settled" && claimedPath) {
5449
+ const imported = importWorkflowAwaitedChildResult(reattached.result, { runId: priorRunId, asyncDir: priorAsyncDir, resultPath: claimedPath, task: typeof childParams.task === "string" ? childParams.task : "", parentWorkflowRunId: workflowReuseSource?.runId, details: { mode: "single", asyncId: priorRunId, asyncDir: priorAsyncDir, results: [] }, state: deps.state, dm: deps.dm });
5450
+ const reattachedResult = workflowChildResult(key, imported, childParams, deps.state);
5451
+ if (reattachedResult.ok) {
5452
+ workflowChildRunIds.set(key, priorRunId);
5453
+ return { ...reattachedResult, reused: true };
5454
+ }
5455
+ }
5456
+ }
5202
5457
  if (workflowUsageBudget.budget && childParams.async === true)
5203
5458
  return workflowChildResult(key, buildRequestedModeError(childParams, "workflow usageBudget does not support async runs.run launches."), childParams, deps.state);
5204
5459
  const budgetState = usageBudgetState(workflowUsageBudget.budget, sumResultsCost(workflowResults));
@@ -5219,7 +5474,11 @@ export function createSubagentExecutor(deps) {
5219
5474
  preparedChildParams = childRequest;
5220
5475
  if (workflowUsageBudget.budget)
5221
5476
  workflowOwnedUsageBudgets.set(childRequest, workflowUsageBudget.budget);
5477
+ if (workflowRequiredExtensions)
5478
+ workflowRetainedRequiredExtensions.set(childRequest, workflowRequiredExtensions);
5222
5479
  workflowLaunchObservers.set(childRequest, (launch) => {
5480
+ if (launch.runId)
5481
+ appendWorkflowChildJournal(asyncDir, { type: "start", key, fingerprint: journalFingerprint, runId: launch.runId });
5223
5482
  const step = status.steps?.find((candidate) => candidate.workflowKey === key);
5224
5483
  if (step) {
5225
5484
  step.agent = launch.agent;
@@ -5309,16 +5568,19 @@ export function createSubagentExecutor(deps) {
5309
5568
  });
5310
5569
  const finalPreflightWarnings = workflowPreflightWarnings(workflowPreflight, workflow.trace, { settled: true });
5311
5570
  const finalPreflightTrace = annotateWorkflowPreflightTrace(workflow.trace, workflowPreflight);
5312
- const returnPreview = formatWorkflowValue(workflow.value).slice(0, 1000);
5313
- const emitPreview = workflow.emits.length > 0 ? ` Emitted: ${workflow.emits.map(formatWorkflowValue).join(", ").slice(0, 1000)}` : "";
5571
+ const returnText = formatWorkflowValue(workflow.value);
5572
+ const emitText = workflow.emits.map(formatWorkflowValue).join(", ");
5573
+ const returnPreview = returnText.length > 1000 ? `${returnText.slice(0, 1000)}…` : returnText;
5574
+ const emitPreview = workflow.emits.length > 0 ? ` Emitted: ${emitText.length > 1000 ? `${emitText.slice(0, 1000)}…` : emitText}` : "";
5575
+ const previewNote = returnText.length > 1000 || emitText.length > 1000 ? ` (truncated; full return value and emits: ${statusPath} (workflow.value, workflow.emits))` : "";
5314
5576
  const runningSummary = workflowRunningChildrenSummary(workflow.children);
5315
- const summary = `${runningSummary ? `Workflow dispatch completed; ${runningSummary}` : `Workflow completed with ${workflow.children.length} child run(s).`} Return: ${returnPreview}${emitPreview} Trace: ${workflow.trace.length} event(s).${workflowOutputPathMappingSummary(workflow.children)}${finalPreflightWarnings.length ? ` ${finalPreflightWarnings.join(" ")}` : ""}`;
5577
+ const summary = `${runningSummary ? `Workflow dispatch completed; ${runningSummary}` : `Workflow completed with ${workflow.children.length} child run(s).`} Return: ${returnPreview}${emitPreview}${previewNote} Trace: ${workflow.trace.length} event(s).${workflowOutputPathMappingSummary(workflow.children)}${finalPreflightWarnings.length ? ` ${finalPreflightWarnings.join(" ")}` : ""}`;
5316
5578
  const outputWarning = writeWorkflowAggregateOutput(workflowAggregateOutputPath, summary, producedChildOutputPaths);
5317
5579
  const resultSummary = appendWorkflowOutputWarning(summary, outputWarning);
5318
5580
  const workflowUsage = sumResultsUsage(workflowResults);
5319
5581
  settleWorkflowSteerInbox("complete");
5320
5582
  const workflowChildren = workflowChildSummary({ parentToolCallId: toolCallId, workflowRunId, workflowState: "completed", inventoryComplete: true, trace: workflow.trace, children: workflow.children, steps: status.steps });
5321
- status = { ...status, state: "complete", endedAt: Date.now(), workflow: { value: workflow.value, trace: finalPreflightTrace, emits: workflow.emits, console: workflow.console, ...workflowArgsEvidence ?? {}, ...workflowResource ? { resource: workflowResource.provenance } : {}, ...finalPreflightWarnings.length ? { preflightWarnings: finalPreflightWarnings } : {} }, workflowChildren, totalTokens: { input: workflowUsage.input, output: workflowUsage.output, total: workflowUsage.input + workflowUsage.output }, totalCost: sumResultsCost(workflowResults) };
5583
+ status = { ...status, state: "complete", endedAt: Date.now(), workflow: { value: workflow.value, trace: finalPreflightTrace, emits: workflow.emits, console: workflow.console, ...workflowRunEvidence, ...workflowResource ? { resource: workflowResource.provenance } : {}, ...finalPreflightWarnings.length ? { preflightWarnings: finalPreflightWarnings } : {} }, workflowChildren, totalTokens: { input: workflowUsage.input, output: workflowUsage.output, total: workflowUsage.input + workflowUsage.output }, totalCost: sumResultsCost(workflowResults) };
5322
5584
  const receipt = terminalWorkflowReceipt(workflowRunId, "complete", workflow.children, workflowChildren, undefined, validHostStepNodes(status.workflowGraph), workflowResource?.provenance, workflowArgsDigest);
5323
5585
  delete status.workflowReceiptPath;
5324
5586
  let workflowReceipt;
@@ -5339,6 +5601,9 @@ export function createSubagentExecutor(deps) {
5339
5601
  } catch (error) {
5340
5602
  const partial = error instanceof WorkflowScriptError ? error.partial : { trace: [], emits: [], console: [], children: [] };
5341
5603
  const stopped = controller.signal.aborted;
5604
+ const stopCause = stopped ? workflowStopCause(controller.signal.reason) : undefined;
5605
+ if (stopCause)
5606
+ workflowRunEvidence.stopCause = stopCause;
5342
5607
  const detachedChildKeys = new Set(partial.children.filter((child) => child.detached).map((child) => child.key));
5343
5608
  const hasRealFailedChild = partial.children.some((child) => !child.ok && child.state !== "running" && !child.detached);
5344
5609
  const pauseForDetached = !stopped && error instanceof WorkflowScriptError && error.errorKind === "detached-child" && detachedChildKeys.size > 0 && !hasRealFailedChild;
@@ -5360,13 +5625,14 @@ export function createSubagentExecutor(deps) {
5360
5625
  const workflowChildren = workflowChildSummary({ parentToolCallId: toolCallId, workflowRunId, workflowState, inventoryComplete: true, trace: partial.trace, children: partial.children, steps: status.steps });
5361
5626
  const finalPreflightWarnings = workflowPreflightWarnings(workflowPreflight, partial.trace, { settled: true });
5362
5627
  const finalPreflightTrace = annotateWorkflowPreflightTrace(partial.trace, workflowPreflight);
5363
- status = compactOptional({ ...status, state, stopped: stopped || undefined, activityState: pauseForDetached || status.activityState === "needs_attention" ? "needs_attention" : undefined, error: workflowFailureMessage(error, workflowRunId, partial.children), endedAt: Date.now(), workflow: { trace: finalPreflightTrace, emits: partial.emits, console: partial.console, ...workflowArgsEvidence ?? {}, ...workflowResource ? { resource: workflowResource.provenance } : {}, ...finalPreflightWarnings.length ? { preflightWarnings: finalPreflightWarnings } : {} }, workflowChildren });
5628
+ status = compactOptional({ ...status, state, stopped: stopped || undefined, activityState: pauseForDetached || status.activityState === "needs_attention" ? "needs_attention" : undefined, error: workflowFailureMessage(error, workflowRunId, partial.children), endedAt: Date.now(), workflow: { trace: finalPreflightTrace, emits: partial.emits, console: partial.console, ...error instanceof WorkflowScriptError && error.errorKind ? { failureKind: error.errorKind } : {}, ...workflowRunEvidence, ...workflowResource ? { resource: workflowResource.provenance } : {}, ...finalPreflightWarnings.length ? { preflightWarnings: finalPreflightWarnings } : {} }, workflowChildren });
5364
5629
  if (pauseForDetached) {
5365
5630
  const promoted = promotePausedWorkflowIfSettled(status);
5366
5631
  if (promoted)
5367
5632
  status = promoted;
5368
5633
  }
5369
- const terminalSummary = `${status.state === "complete" ? "Workflow completed after detached child finished." : status.error ?? (pauseForDetached ? "Workflow paused." : "Workflow failed.")}${workflowOutputPathMappingSummary(partial.children)}${finalPreflightWarnings.length ? ` ${finalPreflightWarnings.join(" ")}` : ""}`;
5634
+ const errorPreview = status.error && status.error.length > 1000 ? `${status.error.slice(0, 1000)}… (truncated; full error: ${statusPath} (error))` : status.error;
5635
+ const terminalSummary = `${status.state === "complete" ? "Workflow completed after detached child finished." : errorPreview ?? (pauseForDetached ? "Workflow paused." : "Workflow failed.")}${stopCause ? ` ${WORKFLOW_RUNTIME_REPLACED_RELAUNCH_NOTICE}` : ""}${workflowOutputPathMappingSummary(partial.children)}${finalPreflightWarnings.length ? ` ${finalPreflightWarnings.join(" ")}` : ""}`;
5370
5636
  const outputWarning = writeWorkflowAggregateOutput(workflowAggregateOutputPath, terminalSummary, producedChildOutputPaths);
5371
5637
  const resultSummary = appendWorkflowOutputWarning(terminalSummary, outputWarning);
5372
5638
  const receiptState = status.state === "complete" ? "complete" : status.state === "paused" ? "paused" : status.state === "stopped" ? "stopped" : "failed";
@@ -5411,6 +5677,7 @@ export function createSubagentExecutor(deps) {
5411
5677
  const workflowOutput = typeof workflowChildDefaults.output === "string" || typeof workflowChildDefaults.output === "boolean" ? workflowChildDefaults.output : undefined;
5412
5678
  const configuredOutputBaseDir = resolveConfiguredSingleRunOutputBaseDir(deps);
5413
5679
  const workflowAggregateOutputPath = resolveSingleOutputPath(workflowOutput, ctx.cwd, workflowCwd, resolveSingleRunOutputBaseDir(deps, workflowArtifactsDir, foregroundWorkflowRunId));
5680
+ const workflowFullResultPath = path.join(workflowArtifactsDir, `${sanitizeRunPathSegment(foregroundWorkflowRunId)}_workflow-result.md`);
5414
5681
  const claimedOutputPaths = new Map;
5415
5682
  const childOutputOverrides = new Map;
5416
5683
  const childOutputClaimPaths = new Map;
@@ -5470,6 +5737,7 @@ export function createSubagentExecutor(deps) {
5470
5737
  sendWorkflowProgress();
5471
5738
  },
5472
5739
  admit: async (calls, admissionSignal) => {
5740
+ admitEnabledWorkflowChildren(calls);
5473
5741
  await preflightWorkflowWorktrees({ workflowDefaults: workflowChildDefaults, defaultWorktree: deps.config.worktree, calls, ctxCwd: ctx.cwd, signal: admissionSignal, deadlineAt: workflowDeadlineAt });
5474
5742
  const outputClaims = workflowChildOutputClaims({ ctxCwd: ctx.cwd, workflowCwd, artifactsDir: workflowArtifactsDir, workflowRunId: foregroundWorkflowRunId, aggregateOutputPath: workflowAggregateOutputPath, configuredOutputBaseDir, discoverAgents: discoverWorkflowAgents, agents: workflowAgents, workflowAgentScope: workflowChildDefaults.agentScope, state: deps.state, claimedOutputPaths, entries: calls });
5475
5743
  if (outputClaims.error)
@@ -5515,6 +5783,8 @@ export function createSubagentExecutor(deps) {
5515
5783
  preparedChildParams = childRequest;
5516
5784
  if (workflowUsageBudget.budget)
5517
5785
  workflowOwnedUsageBudgets.set(childRequest, workflowUsageBudget.budget);
5786
+ if (workflowRequiredExtensions)
5787
+ workflowRetainedRequiredExtensions.set(childRequest, workflowRequiredExtensions);
5518
5788
  if (delegatedWorkflowPermit) {
5519
5789
  if (childRequest.async !== false)
5520
5790
  throw new Error("Workflow child permit supports one foreground child only.");
@@ -5583,36 +5853,31 @@ export function createSubagentExecutor(deps) {
5583
5853
  const finalPreflightTrace = annotateWorkflowPreflightTrace(workflow.trace, workflowPreflight);
5584
5854
  const workflowChildren = workflowChildSummary({ parentToolCallId: _id, workflowRunId: foregroundWorkflowRunId, workflowState: "completed", inventoryComplete: true, trace: workflow.trace, children: workflow.children });
5585
5855
  const receipt = terminalWorkflowReceipt(foregroundWorkflowRunId, "complete", workflow.children, workflowChildren, undefined, [...workflowHostSteps.values()], workflowResource?.provenance, workflowArgsDigest);
5586
- const traceLines = finalPreflightTrace.map((entry) => `- ${entry.operation} ${entry.key}: ${entry.state}${entry.runId ? ` (${entry.runId})` : ""}${entry.durationMs !== undefined ? ` in ${entry.durationMs}ms` : ""}${entry.warning ? ` — ${entry.warning}` : ""}${entry.error ? ` — ${entry.error}` : ""}`);
5856
+ const trace = finalPreflightTrace.map((entry) => ({ line: `- ${entry.operation} ${entry.key}: ${entry.state}${entry.runId ? ` (${entry.runId})` : ""}${entry.durationMs !== undefined ? ` in ${entry.durationMs}ms` : ""}${entry.warning ? ` — ${entry.warning}` : ""}`, error: entry.error }));
5587
5857
  const runningSummary = workflowRunningChildrenSummary(workflow.children);
5588
- const sections = [
5589
- ...workflowPreflight ? [formatWorkflowPreflight(workflowPreflight)] : [],
5590
- runningSummary ? `Workflow dispatch completed; ${runningSummary}` : "Workflow completed.",
5591
- `Return:
5592
- ${formatWorkflowValue(workflow.value)}`
5593
- ];
5594
- if (workflow.emits.length > 0)
5595
- sections.push(`Emitted:
5858
+ const outputMappings = workflowOutputPathMappingSummary(workflow.children).trim();
5859
+ const displayText = formatWorkflowResultText({
5860
+ head: [...workflowPreflight ? [formatWorkflowPreflight(workflowPreflight)] : [], runningSummary ? `Workflow dispatch completed; ${runningSummary}` : "Workflow completed."],
5861
+ script: [
5862
+ `Return:
5863
+ ${formatWorkflowValue(workflow.value)}`,
5864
+ ...workflow.emits.length > 0 ? [`Emitted:
5596
5865
  ${workflow.emits.map(formatWorkflowValue).join(`
5597
- `)}`);
5598
- if (workflow.console.length > 0)
5599
- sections.push(`Console:
5866
+ `)}`] : [],
5867
+ ...workflow.console.length > 0 ? [`Console:
5600
5868
  ${workflow.console.map((entry) => `[${entry.level}] ${entry.text}`).join(`
5601
- `)}`);
5602
- if (traceLines.length > 0)
5603
- sections.push(`Call trace:
5604
- ${traceLines.join(`
5605
- `)}`);
5606
- if (finalPreflightWarnings.length > 0)
5607
- sections.push(formatWorkflowPreflightWarnings(finalPreflightWarnings));
5608
- const outputMappings = workflowOutputPathMappingSummary(workflow.children).trim();
5609
- if (outputMappings)
5610
- sections.push(outputMappings);
5611
- const workflowText = sections.join(`
5612
-
5613
- `);
5614
- const outputWarning = writeWorkflowAggregateOutput(workflowAggregateOutputPath, workflowText, producedChildOutputPaths);
5615
- const displayText = appendWorkflowOutputWarning(workflowText, outputWarning);
5869
+ `)}`] : []
5870
+ ],
5871
+ trace,
5872
+ tail: [
5873
+ ...finalPreflightWarnings.length > 0 ? [formatWorkflowPreflightWarnings(finalPreflightWarnings)] : [],
5874
+ ...outputMappings ? [outputMappings] : []
5875
+ ],
5876
+ maxOutput: requestParams.maxOutput,
5877
+ aggregateOutputPath: workflowAggregateOutputPath,
5878
+ fullResultPath: workflowFullResultPath,
5879
+ producedChildOutputPaths
5880
+ });
5616
5881
  return attachWorkflowMission(withRunFanoutBudget({
5617
5882
  content: [{ type: "text", text: displayText }],
5618
5883
  details: compactOptional({ mode: "workflow", runId: foregroundWorkflowRunId, results: workflowDetailsResults(workflow.children), ...workflowPreflight ? { preflight: workflowPreflight } : {}, workflowChildren, totalChildUsage: sumResultsUsage(workflowResults), totalCost: sumResultsCost(workflowResults), usageBudget: usageBudgetState(workflowUsageBudget.budget, sumResultsCost(workflowResults)), workflow: { value: workflow.value, trace: finalPreflightTrace, emits: workflow.emits, console: workflow.console, ...workflowArgsEvidence ?? {}, ...workflowResource ? { resource: workflowResource.provenance } : {}, ...finalPreflightWarnings.length ? { preflightWarnings: finalPreflightWarnings } : {}, receipt }, chatProgress })
@@ -5622,40 +5887,36 @@ ${traceLines.join(`
5622
5887
  const text = workflowFailureMessage(error, foregroundWorkflowRunId, partial.children);
5623
5888
  const finalPreflightWarnings = workflowPreflightWarnings(workflowPreflight, partial.trace, { settled: true });
5624
5889
  const finalPreflightTrace = annotateWorkflowPreflightTrace(partial.trace, workflowPreflight);
5625
- const traceLines = finalPreflightTrace.map((entry) => `- ${entry.operation} ${entry.key}: ${entry.state}${entry.runId ? ` (${entry.runId})` : ""}${entry.warning ? ` — ${entry.warning}` : ""}${entry.error ? ` — ${entry.error}` : ""}`);
5626
- const sections = [
5627
- ...workflowPreflight ? [formatWorkflowPreflight(workflowPreflight)] : [],
5628
- `Workflow failed: ${text}`
5629
- ];
5630
- if (partial.emits.length > 0)
5631
- sections.push(`Emitted:
5890
+ const trace = finalPreflightTrace.map((entry) => ({ line: `- ${entry.operation} ${entry.key}: ${entry.state}${entry.runId ? ` (${entry.runId})` : ""}${entry.warning ? ` — ${entry.warning}` : ""}`, error: entry.error }));
5891
+ const outputMappings = workflowOutputPathMappingSummary(partial.children).trim();
5892
+ const displayText = formatWorkflowResultText({
5893
+ head: workflowPreflight ? [formatWorkflowPreflight(workflowPreflight)] : [],
5894
+ script: [
5895
+ `Workflow failed: ${text}`,
5896
+ ...partial.emits.length > 0 ? [`Emitted:
5632
5897
  ${partial.emits.map(formatWorkflowValue).join(`
5633
- `)}`);
5634
- if (partial.console.length > 0)
5635
- sections.push(`Console:
5898
+ `)}`] : [],
5899
+ ...partial.console.length > 0 ? [`Console:
5636
5900
  ${partial.console.map((entry) => `[${entry.level}] ${entry.text}`).join(`
5637
- `)}`);
5638
- if (traceLines.length > 0)
5639
- sections.push(`Call trace:
5640
- ${traceLines.join(`
5641
- `)}`);
5642
- if (finalPreflightWarnings.length > 0)
5643
- sections.push(formatWorkflowPreflightWarnings(finalPreflightWarnings));
5644
- const outputMappings = workflowOutputPathMappingSummary(partial.children).trim();
5645
- if (outputMappings)
5646
- sections.push(outputMappings);
5647
- const workflowText = sections.join(`
5648
-
5649
- `);
5650
- const outputWarning = writeWorkflowAggregateOutput(workflowAggregateOutputPath, workflowText, producedChildOutputPaths);
5651
- const displayText = appendWorkflowOutputWarning(workflowText, outputWarning);
5901
+ `)}`] : []
5902
+ ],
5903
+ trace,
5904
+ tail: [
5905
+ ...finalPreflightWarnings.length > 0 ? [formatWorkflowPreflightWarnings(finalPreflightWarnings)] : [],
5906
+ ...outputMappings ? [outputMappings] : []
5907
+ ],
5908
+ maxOutput: requestParams.maxOutput,
5909
+ aggregateOutputPath: workflowAggregateOutputPath,
5910
+ fullResultPath: workflowFullResultPath,
5911
+ producedChildOutputPaths
5912
+ });
5652
5913
  const workflowChildren = workflowChildSummary({ parentToolCallId: _id, workflowRunId: foregroundWorkflowRunId, workflowState: "failed", inventoryComplete: true, trace: partial.trace, children: partial.children });
5653
5914
  const terminalOutcome = workflowFailureTerminalOutcome(error, partial.children, usageBudgetState(workflowUsageBudget.budget, sumResultsCost(workflowResults)));
5654
5915
  const receipt = terminalWorkflowReceipt(foregroundWorkflowRunId, "failed", partial.children, workflowChildren, terminalOutcome, [...workflowHostSteps.values()], workflowResource?.provenance, workflowArgsDigest);
5655
5916
  return attachWorkflowMission(withRunFanoutBudget({
5656
5917
  content: [{ type: "text", text: displayText }],
5657
5918
  isError: true,
5658
- details: compactOptional({ mode: "workflow", runId: foregroundWorkflowRunId, results: workflowDetailsResults(partial.children), ...workflowPreflight ? { preflight: workflowPreflight } : {}, workflowChildren, totalChildUsage: sumResultsUsage(workflowResults), totalCost: sumResultsCost(workflowResults), usageBudget: usageBudgetState(workflowUsageBudget.budget, sumResultsCost(workflowResults)), workflow: { trace: finalPreflightTrace, emits: partial.emits, console: partial.console, ...workflowArgsEvidence ?? {}, ...workflowResource ? { resource: workflowResource.provenance } : {}, ...finalPreflightWarnings.length ? { preflightWarnings: finalPreflightWarnings } : {}, receipt }, chatProgress })
5919
+ details: compactOptional({ mode: "workflow", runId: foregroundWorkflowRunId, results: workflowDetailsResults(partial.children), ...workflowPreflight ? { preflight: workflowPreflight } : {}, workflowChildren, totalChildUsage: sumResultsUsage(workflowResults), totalCost: sumResultsCost(workflowResults), usageBudget: usageBudgetState(workflowUsageBudget.budget, sumResultsCost(workflowResults)), workflow: { trace: finalPreflightTrace, emits: partial.emits, console: partial.console, ...error instanceof WorkflowScriptError && error.errorKind ? { failureKind: error.errorKind } : {}, ...workflowArgsEvidence ?? {}, ...workflowResource ? { resource: workflowResource.provenance } : {}, ...finalPreflightWarnings.length ? { preflightWarnings: finalPreflightWarnings } : {}, receipt }, chatProgress })
5659
5920
  }, workflowFanoutBudget));
5660
5921
  } finally {
5661
5922
  workflowProgressClosed = true;
@@ -5696,11 +5957,40 @@ ${traceLines.join(`
5696
5957
  if (deps.allowMutatingManagementActions === false) {
5697
5958
  return { content: [{ type: "text", text: "Action 'worktree.cleanup' is not available from child-safe subagent fanout mode." }], isError: true, details: { mode: "management", results: [] } };
5698
5959
  }
5960
+ if (paramsWithResolvedCwd.mode === "apply") {
5961
+ try {
5962
+ if (!paramsWithResolvedCwd.repo?.trim() || !paramsWithResolvedCwd.planId?.trim() || paramsWithResolvedCwd.handoffPath !== undefined)
5963
+ throw new Error("worktree.cleanup apply requires explicit repo and planId, without handoffPath.");
5964
+ const repo = path.resolve(requestCwd, paramsWithResolvedCwd.repo);
5965
+ const plan = loadReviewedCleanupPlan(repo, paramsWithResolvedCwd.planId);
5966
+ const decision = resolveAuthorityDecision({ action: "discardWorktree", ...deps.config.authorityPolicy === undefined ? {} : { policy: deps.config.authorityPolicy } });
5967
+ if (decision === "forbid")
5968
+ throw new Error("Authority policy forbids worktree cleanup.");
5969
+ if (decision === "confirm") {
5970
+ if (!ctx.hasUI)
5971
+ throw new Error("Authority policy requires interactive confirmation for worktree cleanup.");
5972
+ if (!await ctx.ui.confirm("Apply reviewed worktree cleanup?", `Repository: ${plan.repoRoot}
5973
+ Plan: ${plan.planId}
5974
+ Remove up to ${plan.entries.filter((entry) => entry.decision === "remove").length} eligible worktrees. All local branches are retained.`))
5975
+ return { content: [{ type: "text", text: "Worktree cleanup canceled." }], details: { mode: "management", results: [] } };
5976
+ }
5977
+ const applied = await applyReviewedCleanupPlan({
5978
+ repo: plan.repoRoot,
5979
+ planId: plan.planId,
5980
+ authorized: true,
5981
+ signal,
5982
+ foregroundRunOwnership: (runId) => deps.state.foregroundControls.has(runId) ? "active" : deps.state.foregroundRuns?.get(runId)?.children.length && deps.state.foregroundRuns.get(runId).children.every((child) => child.status !== "detached") ? "terminal" : "unknown"
5983
+ });
5984
+ return { content: [{ type: "text", text: formatCleanupReceipt(applied) }], details: { mode: "management", results: [] } };
5985
+ } catch (error) {
5986
+ return { content: [{ type: "text", text: error instanceof Error ? error.message : String(error) }], isError: true, details: { mode: "management", results: [] } };
5987
+ }
5988
+ }
5699
5989
  if (paramsWithResolvedCwd.mode !== "plan") {
5700
- return { content: [{ type: "text", text: "worktree.cleanup currently supports mode='plan' only; apply/removal is not available yet." }], isError: true, details: { mode: "management", results: [] } };
5990
+ return { content: [{ type: "text", text: "worktree.cleanup requires mode='plan' or mode='apply'." }], isError: true, details: { mode: "management", results: [] } };
5701
5991
  }
5702
5992
  if (paramsWithResolvedCwd.planId !== undefined) {
5703
- return { content: [{ type: "text", text: "worktree.cleanup plan mode does not accept planId; apply is not available yet." }], isError: true, details: { mode: "management", results: [] } };
5993
+ return { content: [{ type: "text", text: "worktree.cleanup plan mode does not accept planId." }], isError: true, details: { mode: "management", results: [] } };
5704
5994
  }
5705
5995
  try {
5706
5996
  const created = createWorktreeCleanupPlan({
@@ -5778,7 +6068,7 @@ ${paramsWithResolvedCwd.handoffPath}`);
5778
6068
  return { content: [{ type: "text", text: error instanceof Error ? error.message : String(error) }], isError: true, details: { mode: "management", results: [] } };
5779
6069
  }
5780
6070
  }
5781
- const policyAction = action === "stop" ? "stopRun" : action === "steer" ? "steerRun" : action === "schedule.create" ? "scheduleCreate" : action === "inspector.open" ? "inspectorOpen" : action === "project.open" ? "projectOpen" : undefined;
6071
+ const policyAction = action === "stop" || action === "command.cancel" ? "stopRun" : action === "steer" || action === "command.yield" ? "steerRun" : action === "schedule.create" ? "scheduleCreate" : action === "inspector.open" ? "inspectorOpen" : action === "project.open" ? "projectOpen" : undefined;
5782
6072
  if (policyAction) {
5783
6073
  if (deps.allowMutatingManagementActions === false && MUTATING_MANAGEMENT_ACTIONS.has(action)) {
5784
6074
  return { content: [{ type: "text", text: `Action '${action}' is not available from child-safe subagent fanout mode.` }], isError: true, details: { mode: "management", results: [] } };
@@ -5812,7 +6102,7 @@ ${paramsWithResolvedCwd.handoffPath}`);
5812
6102
  cwd: requestCwd,
5813
6103
  ...deps.config.missions ? { missions: deps.config.missions } : {},
5814
6104
  ...deps.config.authorityPolicy ? { authorityPolicy: deps.config.authorityPolicy } : {},
5815
- plugins: createBuiltinInspectorPlugins(),
6105
+ plugins: getInspectorPlugins(deps.dm),
5816
6106
  signal
5817
6107
  });
5818
6108
  }
@@ -5934,8 +6224,14 @@ Usage is not reset. Compaction keeps the same budget; a new parent session start
5934
6224
  }
5935
6225
  if (action === "guide") {
5936
6226
  try {
6227
+ const guide = readSubagentGuide(paramsWithResolvedCwd.topic);
6228
+ const [topic, section] = paramsWithResolvedCwd.topic?.split("/") ?? [];
6229
+ const fullNotice = topic === "tool-reference" ? disabledFeatureNotice(disabledFeatures) : undefined;
6230
+ const notice = fullNotice && section !== undefined ? "Some options and actions documented here are disabled by config in this session; guide topic tool-reference lists them." : fullNotice;
5937
6231
  return {
5938
- content: [{ type: "text", text: readSubagentGuide(paramsWithResolvedCwd.topic) }],
6232
+ content: [{ type: "text", text: notice ? `${notice}
6233
+
6234
+ ${guide}` : guide }],
5939
6235
  details: { mode: "management", results: [] }
5940
6236
  };
5941
6237
  } catch (error) {
@@ -5957,10 +6253,12 @@ Usage is not reset. Compaction keeps the same budget; a new parent session start
5957
6253
  if (action === "doctor") {
5958
6254
  let currentSessionFile = null;
5959
6255
  let currentSessionId = deps.state.currentSessionId;
6256
+ let budgetSessionId = deps.state.currentSessionId;
5960
6257
  let sessionError;
5961
6258
  try {
5962
6259
  currentSessionFile = ctx.sessionManager.getSessionFile() ?? null;
5963
6260
  currentSessionId = ctx.sessionManager.getSessionId();
6261
+ budgetSessionId = currentSessionFile ?? currentSessionId;
5964
6262
  } catch (error) {
5965
6263
  sessionError = error instanceof Error ? `${error.name}: ${error.message}` : String(error);
5966
6264
  }
@@ -5971,8 +6269,8 @@ Usage is not reset. Compaction keeps the same budget; a new parent session start
5971
6269
  if (!sessionError)
5972
6270
  sessionError = error instanceof Error ? `${error.name}: ${error.message}` : String(error);
5973
6271
  }
5974
- const spawnBudget = getSpawnBudgetSnapshot(deps.state, deps.config, currentSessionId);
5975
- const activeAsyncCapacity = currentSessionId ? getActiveAsyncCapacitySnapshot(currentSessionId, resolveMaxActiveAsyncRunsPerSession(deps.config.maxActiveAsyncRunsPerSession), { liveWorkflowRunIds: new Set(deps.state.workflowControllers?.keys() ?? []), abandonedSlotReleaseAfterMs: resolveAbandonedSlotReleaseAfterMs(deps.config.capacity?.abandonedSlotReleaseAfterMs) }) : { used: 0, limit: resolveMaxActiveAsyncRunsPerSession(deps.config.maxActiveAsyncRunsPerSession) ?? 0 };
6272
+ const spawnBudget = getSpawnBudgetSnapshot(deps.state, deps.config, budgetSessionId);
6273
+ const activeAsyncCapacity = budgetSessionId ? getActiveAsyncCapacitySnapshot(budgetSessionId, resolveMaxActiveAsyncRunsPerSession(deps.config.maxActiveAsyncRunsPerSession), { liveWorkflowRunIds: new Set(deps.state.workflowControllers?.keys() ?? []), abandonedSlotReleaseAfterMs: resolveAbandonedSlotReleaseAfterMs(deps.config.capacity?.abandonedSlotReleaseAfterMs) }) : { used: 0, limit: resolveMaxActiveAsyncRunsPerSession(deps.config.maxActiveAsyncRunsPerSession) ?? 0 };
5976
6274
  deps.state.activeAsyncCapacity = activeAsyncCapacity;
5977
6275
  return {
5978
6276
  content: [{
@@ -5985,6 +6283,8 @@ Usage is not reset. Compaction keeps the same budget; a new parent session start
5985
6283
  requestedSessionDir: paramsWithResolvedCwd.sessionDir,
5986
6284
  currentSessionFile,
5987
6285
  currentSessionId,
6286
+ spawnBudget,
6287
+ activeAsyncCapacity,
5988
6288
  orchestratorTarget,
5989
6289
  sessionError,
5990
6290
  expandTilde: deps.expandTilde
@@ -5993,6 +6293,22 @@ Usage is not reset. Compaction keeps the same budget; a new parent session start
5993
6293
  details: { mode: "management", results: [], spawnBudget, activeAsyncCapacity }
5994
6294
  };
5995
6295
  }
6296
+ if (["command.status", "command.yield", "command.cancel"].includes(action)) {
6297
+ try {
6298
+ if (deps.allowMutatingManagementActions === false && action !== "command.status")
6299
+ throw new Error(`Action '${action}' is not available from child-safe subagent fanout mode.`);
6300
+ const targetRunId = paramsWithResolvedCwd.id ?? paramsWithResolvedCwd.runId;
6301
+ if (!targetRunId || paramsWithResolvedCwd.dir)
6302
+ throw new Error(`${action} requires id or runId; directory targets are not supported.`);
6303
+ deps.state.currentSessionId = resolveCurrentSessionId(ctx.sessionManager);
6304
+ const target = resolveSubagentRunId(targetRunId, { state: deps.state, nested: nestedResolutionScopeForExecutor(deps) });
6305
+ if (!target)
6306
+ throw new Error(`No run found for '${targetRunId}'.`);
6307
+ return await commandAction({ state: deps.state, target, operation: action.slice("command.".length), index: paramsWithResolvedCwd.index, toolCallId: paramsWithResolvedCwd.toolCallId, signal });
6308
+ } catch (error) {
6309
+ return { content: [{ type: "text", text: error instanceof Error ? error.message : String(error) }], isError: true, details: { mode: "management", results: [] } };
6310
+ }
6311
+ }
5996
6312
  if (action === "status" || action === "debug.run") {
5997
6313
  if (!preserveActiveSession)
5998
6314
  deps.state.currentSessionId = resolveCurrentSessionId(ctx.sessionManager);
@@ -6151,7 +6467,7 @@ ${item.text}` } : item)
6151
6467
  }
6152
6468
  if (action.startsWith("schedule.")) {
6153
6469
  if (!isScheduledRunAction(action)) {
6154
- return { content: [{ type: "text", text: unknownSubagentActionMessage(action) }], isError: true, details: { mode: "management", results: [] } };
6470
+ return { content: [{ type: "text", text: unknownSubagentActionMessage(action, disabledFeatures) }], isError: true, details: { mode: "management", results: [] } };
6155
6471
  }
6156
6472
  if (deps.allowMutatingManagementActions === false && MUTATING_MANAGEMENT_ACTIONS.has(action)) {
6157
6473
  return {
@@ -6194,55 +6510,46 @@ ${item.text}` } : item)
6194
6510
  }
6195
6511
  if (action === "stop") {
6196
6512
  const targetRunId = paramsWithResolvedCwd.runId ?? paramsWithResolvedCwd.id;
6197
- const workflowController = targetRunId ? deps.state.workflowControllers?.get(targetRunId) : undefined;
6198
- if (workflowController && targetRunId) {
6199
- const stopChild = deps.state.workflowChildStops?.get(targetRunId);
6200
- if (paramsWithResolvedCwd.childId !== undefined) {
6201
- const workflowRunId = targetRunId;
6202
- const asyncJob = deps.state.asyncJobs.get(workflowRunId);
6203
- if (!asyncJob?.asyncDir)
6204
- return { content: [{ type: "text", text: `Status file not found for async workflow '${workflowRunId}'.` }], isError: true, details: { mode: "management", results: [] } };
6205
- const status = readStatus(asyncJob.asyncDir);
6206
- if (!status)
6207
- return { content: [{ type: "text", text: `Status file not found for async workflow '${workflowRunId}'.` }], isError: true, details: { mode: "management", results: [] } };
6208
- const resolution = resolveAsyncStatusChild(status, paramsWithResolvedCwd.childId);
6209
- if (!resolution.ok)
6210
- return { content: [{ type: "text", text: resolution.message }], isError: true, details: { mode: "management", results: [] } };
6211
- if (!isStoppableAsyncStatusStep(resolution.child.step))
6212
- return { content: [{ type: "text", text: `Child '${paramsWithResolvedCwd.childId}' in async run '${targetRunId}' is ${resolution.child.step.status}; stop only supports pending or running children.` }], isError: true, details: { mode: "management", results: [] } };
6213
- if (!stopChild)
6214
- return { content: [{ type: "text", text: `Workflow ${targetRunId} child stop is unavailable in this extension runtime.` }], isError: true, details: { mode: "management", results: [] } };
6215
- if (!stopChild(resolution.child.id, `Workflow child '${resolution.child.id}' stopped.`))
6216
- return { content: [{ type: "text", text: `Child '${paramsWithResolvedCwd.childId}' in workflow ${workflowRunId} is not available to stop.` }], isError: true, details: { mode: "management", results: [] } };
6217
- try {
6218
- fs.appendFileSync(path.join(asyncJob.asyncDir, "events.jsonl"), `${JSON.stringify({
6219
- type: "subagent.child-status",
6220
- version: 1,
6221
- runId: workflowRunId,
6222
- childId: resolution.child.id,
6223
- status: "stopping",
6224
- ts: Date.now(),
6225
- reason: "subagent-action",
6226
- source: "async",
6227
- stepIndex: resolution.child.index,
6228
- agent: resolution.child.step.agent,
6229
- ...resolution.child.step.runId ? { childRunId: resolution.child.step.runId } : {},
6230
- ...resolution.child.step.workflowKey ? { workflowKey: resolution.child.step.workflowKey } : {},
6231
- ...resolution.child.step.phase ? { phase: resolution.child.step.phase } : {},
6232
- ...resolution.child.step.label ? { label: resolution.child.step.label } : {}
6233
- })}
6513
+ const workflowRunId = targetRunId && paramsWithResolvedCwd.childId !== undefined ? resolveLiveWorkflowRunId(deps, targetRunId) : undefined;
6514
+ if (workflowRunId && paramsWithResolvedCwd.childId !== undefined) {
6515
+ const stopChild = deps.state.workflowChildStops?.get(workflowRunId);
6516
+ const asyncJob = deps.state.asyncJobs.get(workflowRunId);
6517
+ if (!asyncJob?.asyncDir)
6518
+ return { content: [{ type: "text", text: `Status file not found for async workflow '${workflowRunId}'.` }], isError: true, details: { mode: "management", results: [] } };
6519
+ const status = readStatus(asyncJob.asyncDir);
6520
+ if (!status)
6521
+ return { content: [{ type: "text", text: `Status file not found for async workflow '${workflowRunId}'.` }], isError: true, details: { mode: "management", results: [] } };
6522
+ const resolution = resolveAsyncStatusChild(status, paramsWithResolvedCwd.childId);
6523
+ if (!resolution.ok)
6524
+ return { content: [{ type: "text", text: resolution.message }], isError: true, details: { mode: "management", results: [] } };
6525
+ if (!isStoppableAsyncStatusStep(resolution.child.step))
6526
+ return { content: [{ type: "text", text: `Child '${paramsWithResolvedCwd.childId}' in async run '${workflowRunId}' is ${resolution.child.step.status}; stop only supports pending or running children.` }], isError: true, details: { mode: "management", results: [] } };
6527
+ if (!stopChild)
6528
+ return { content: [{ type: "text", text: `Workflow ${workflowRunId} child stop is unavailable in this extension runtime.` }], isError: true, details: { mode: "management", results: [] } };
6529
+ if (!stopChild(resolution.child.id, `Workflow child '${resolution.child.id}' stopped.`))
6530
+ return { content: [{ type: "text", text: `Child '${paramsWithResolvedCwd.childId}' in workflow ${workflowRunId} is not available to stop.` }], isError: true, details: { mode: "management", results: [] } };
6531
+ try {
6532
+ fs.appendFileSync(path.join(asyncJob.asyncDir, "events.jsonl"), `${JSON.stringify({
6533
+ type: "subagent.child-status",
6534
+ version: 1,
6535
+ runId: workflowRunId,
6536
+ childId: resolution.child.id,
6537
+ status: "stopping",
6538
+ ts: Date.now(),
6539
+ reason: "subagent-action",
6540
+ source: "async",
6541
+ stepIndex: resolution.child.index,
6542
+ agent: resolution.child.step.agent,
6543
+ ...resolution.child.step.runId ? { childRunId: resolution.child.step.runId } : {},
6544
+ ...resolution.child.step.workflowKey ? { workflowKey: resolution.child.step.workflowKey } : {},
6545
+ ...resolution.child.step.phase ? { phase: resolution.child.step.phase } : {},
6546
+ ...resolution.child.step.label ? { label: resolution.child.step.label } : {}
6547
+ })}
6234
6548
  `, "utf-8");
6235
- } catch (error) {
6236
- console.error(`Failed to append child status event for workflow ${workflowRunId}:`, error);
6237
- }
6238
- return { content: [{ type: "text", text: `Stop requested for child ${resolution.child.id} in async workflow ${workflowRunId}.` }], details: { mode: "management", results: [] } };
6549
+ } catch (error) {
6550
+ console.error(`Failed to append child status event for workflow ${workflowRunId}:`, error);
6239
6551
  }
6240
- const asyncJob = deps.state.asyncJobs.get(targetRunId);
6241
- const status = asyncJob?.asyncDir ? readStatus(asyncJob.asyncDir) : undefined;
6242
- if (status)
6243
- stopStoppableAsyncStatusChildren(status, stopChild, "Workflow stopped.");
6244
- workflowController.abort(new Error("Workflow stopped."));
6245
- return { content: [{ type: "text", text: `Stop requested for async workflow ${targetRunId}.` }], details: { mode: "management", results: [] } };
6552
+ return { content: [{ type: "text", text: `Stop requested for child ${resolution.child.id} in async workflow ${workflowRunId}.` }], details: { mode: "management", results: [] } };
6246
6553
  }
6247
6554
  let resolved;
6248
6555
  if (paramsWithResolvedCwd.dir) {
@@ -6317,7 +6624,7 @@ ${item.text}` } : item)
6317
6624
  }
6318
6625
  if (!SUBAGENT_ACTIONS.includes(action)) {
6319
6626
  return {
6320
- content: [{ type: "text", text: unknownSubagentActionMessage(action) }],
6627
+ content: [{ type: "text", text: unknownSubagentActionMessage(action, disabledFeatures) }],
6321
6628
  isError: true,
6322
6629
  details: { mode: "management", results: [] }
6323
6630
  };
@@ -6412,7 +6719,17 @@ ${item.text}` } : item)
6412
6719
  return;
6413
6720
  };
6414
6721
  let prepareForkSessionForIndex = async () => {};
6722
+ const launchCapabilityCeiling = () => intersectSubagentCapabilityCeilings(intersectSubagentCapabilityCeilings(effectiveParams.capabilityCeiling, resolveCurrentSubagentCapabilityCeiling(requestSessionId)), deps.childRuntime?.capabilityCeiling);
6723
+ const assertLaunchableAgentsAllowedBeforeFork = () => {
6724
+ if (!contextPolicy.usesFork)
6725
+ return;
6726
+ const ceiling = launchCapabilityCeiling();
6727
+ const launchable = hasSingle ? [effectiveParams.agent] : hasTasks ? (effectiveParams.tasks ?? []).map((task) => task.agent) : (effectiveParams.chain ?? []).flatMap((step) => isDynamicParallelStep(step) && (step.expand.maxItems ?? deps.config.chain?.dynamicFanout?.maxItems ?? 0) === 0 ? [] : getStepAgents(step));
6728
+ for (const agent of launchable)
6729
+ assertAgentAllowedByCapabilityCeiling(agent, ceiling);
6730
+ };
6415
6731
  try {
6732
+ assertLaunchableAgentsAllowedBeforeFork();
6416
6733
  const pruneSession = contextPolicy.usesFork && deps.config.forkContext?.mode === "pruned" ? await createPrunedForkSessionWriter(ctx, deps.config.forkContext, signal) : undefined;
6417
6734
  const forkContextResolver = createForkContextResolver(ctx.sessionManager, contextPolicy.usesFork ? "fork" : undefined, pruneSession ? { pruneSession } : {});
6418
6735
  prepareForkSessionForIndex = forkContextResolver.prepareSessionForIndex;
@@ -6421,14 +6738,24 @@ ${item.text}` } : item)
6421
6738
  return toExecutionErrorResult(effectiveParams, error, contextPolicy.contextSummary);
6422
6739
  }
6423
6740
  const selectedAgentNames = hasSingle ? [effectiveParams.agent] : hasTasks ? (effectiveParams.tasks ?? []).map((task) => task.agent) : (effectiveParams.chain ?? []).flatMap((step) => getStepAgents(step));
6424
- const externalAgent = selectedAgentNames.map((name) => agents.find((agent) => agent.name === name)).find((agent) => agent?.runner?.type === "external-cli" || agent?.runner?.type === "external-job");
6425
- const externalAsyncRequired = Boolean(externalAgent) && effectiveParams.async === undefined && effectiveParams.clarify !== true && effectiveParams.foregroundOnly !== true;
6741
+ const selectedAgents = selectedAgentNames.map((name) => agents.find((agent) => agent.name === name));
6742
+ const externalAgent = selectedAgents.find((agent) => agent?.runner?.type === "external-cli" || agent?.runner?.type === "external-job");
6743
+ const launcherAgent = selectedAgents.find((agent) => agent?.launcher !== undefined);
6744
+ const externalAsyncRequired = effectiveParams.foregroundOnly !== true && (Boolean(externalAgent) && effectiveParams.async === undefined && effectiveParams.clarify !== true || Boolean(launcherAgent) && normalizedParams.async === undefined && normalizedParams.clarify !== true);
6426
6745
  const requestedAsync = externalAsyncRequired ? true : effectiveParams.async ?? deps.asyncByDefault;
6427
6746
  const backgroundRequestedWhileClarifying = (hasChain || hasTasks) && requestedAsync && effectiveParams.clarify === true;
6428
6747
  const effectiveAsync = requestedAsync && effectiveParams.clarify !== true;
6429
6748
  if (externalAgent && (!effectiveAsync || effectiveParams.foregroundOnly === true)) {
6430
6749
  return buildRequestedModeError(effectiveParams, `Agent '${externalAgent.name}' uses runner.type='${externalAgent.runner?.type}', which currently supports async/background execution only. Omit async or pass async:true; clarify and foregroundOnly are unsupported.`);
6431
6750
  }
6751
+ if (launcherAgent && (!effectiveAsync || normalizedParams.async === false || normalizedParams.clarify === true || effectiveParams.foregroundOnly === true)) {
6752
+ return buildRequestedModeError(effectiveParams, `Agent '${launcherAgent.name}' uses launcher '${launcherAgent.launcher}', which wraps the background runner only. Foreground children run inside the parent process, so a launcher cannot wrap them. Omit async or pass async:true; clarify and foregroundOnly are unsupported.`);
6753
+ }
6754
+ for (const agent of selectedAgents) {
6755
+ const launcherError = agent ? resolveAgentRunnerLauncher(agent, deps.config.runnerLaunchers, effectiveParams.machine ?? agent.machine).error : undefined;
6756
+ if (launcherError)
6757
+ return buildRequestedModeError(effectiveParams, launcherError);
6758
+ }
6432
6759
  if (effectiveAsync && hasSingle && effectiveParams.resume === undefined && effectiveParams.worktree === true) {
6433
6760
  try {
6434
6761
  await preflightWorktreeSource(effectiveCwd, { signal });
@@ -6519,8 +6846,13 @@ ${item.text}` } : item)
6519
6846
  const childSessionFileForTask = (agentName, idx, modelOverride, modelOverrideFromParent, modelOrigin) => forkSessionFileForTask(agentName, idx, modelOverride, modelOverrideFromParent, modelOrigin) ?? path.join(sessionDirForIndex(idx), "session.jsonl");
6520
6847
  const childSessionFileForIndex = (idx) => path.join(sessionDirForIndex(idx), "session.jsonl");
6521
6848
  try {
6849
+ assertLaunchableAgentsAllowedBeforeFork();
6522
6850
  if (!(effectiveParams.clarify === true && ctx.hasUI) || deps.config.forkContext?.mode === "pruned") {
6523
- await preflightForkSessionsForStaticTasks(effectiveParams, contextPolicy, prepareForkSessionForTask, deps.config.chain?.dynamicFanout?.maxItems);
6851
+ const prepareAllowedForkSession = async (agent, ...rest) => {
6852
+ assertAgentAllowedByCapabilityCeiling(agent, launchCapabilityCeiling());
6853
+ await prepareForkSessionForTask(agent, ...rest);
6854
+ };
6855
+ await preflightForkSessionsForStaticTasks(effectiveParams, contextPolicy, prepareAllowedForkSession, deps.config.chain?.dynamicFanout?.maxItems);
6524
6856
  }
6525
6857
  } catch (error) {
6526
6858
  activeAsyncCapacity?.rollback();
@@ -6597,6 +6929,7 @@ ${item.text}` } : item)
6597
6929
  backgroundRequestedWhileClarifying,
6598
6930
  effectiveAsync,
6599
6931
  asyncRunId,
6932
+ toolCallId: _id,
6600
6933
  controlConfig,
6601
6934
  ...delegatedExecution ? { suppressUnchangedDelegationUpdates: true } : {},
6602
6935
  intercomBridge,
@@ -6605,12 +6938,14 @@ ${item.text}` } : item)
6605
6938
  toolBudget: runToolBudget.toolBudget,
6606
6939
  usageBudget: usageBudget.budget,
6607
6940
  inheritedUsageBudget,
6941
+ requiredExtensions: retainedRequiredExtensions,
6608
6942
  allowZeroToolBudget,
6609
6943
  configToolBudget: configToolBudget.toolBudget,
6610
6944
  configToolTimeoutMs: deps.config.toolTimeoutMs,
6611
6945
  contextPolicy,
6612
6946
  modelScope,
6613
6947
  parentModel: requestParentModel,
6948
+ scopedModelIds: scopedModelIdsFromContext(ctx),
6614
6949
  parentSessionId: requestSessionId,
6615
6950
  parentPiSessionId: requestPiSessionId,
6616
6951
  capabilityCeiling: intersectSubagentCapabilityCeilings(effectiveParams.capabilityCeiling, resolveCurrentSubagentCapabilityCeiling(requestSessionId)),
@@ -6689,6 +7024,7 @@ ${item.text}` } : item)
6689
7024
  params: effectiveParams,
6690
7025
  agents,
6691
7026
  parentModel: requestParentModel,
7027
+ scopedModelIds: scopedModelIdsFromContext(ctx),
6692
7028
  availableModels: ctx.modelRegistry.getAvailable().map(toModelInfo),
6693
7029
  currentProvider: requestParentModel?.provider,
6694
7030
  modelScope,
@@ -6822,32 +7158,54 @@ ${item.text}` } : item)
6822
7158
  }
6823
7159
  };
6824
7160
  const executePublic = (id, params, signal, onUpdate, ctx) => {
6825
- const normalized = normalizePublicSubagentExecution(params);
7161
+ const disabledFeatureError = disabledFeatureResult(params);
7162
+ if (disabledFeatureError)
7163
+ return Promise.resolve(disabledFeatureError);
7164
+ const normalized = normalizePublicSubagentExecution(params, { structuredWorkflows: disabledFeatures.features.has("workflow-scripts") });
6826
7165
  if (!normalized.ok) {
6827
7166
  return Promise.resolve({ content: [{ type: "text", text: normalized.error }], isError: true, details: { mode: normalized.mode, results: [] } });
6828
7167
  }
6829
7168
  let publicParams = normalized.params;
6830
- if (publicParams.workflow !== undefined) {
6831
- const resolved = resolveWorkflowResource(publicParams.workflow, publicParams.args, ctx.sessionManager.getSessionId() ?? undefined);
7169
+ const workflow = publicParams.workflow;
7170
+ const errorResult = (text) => Promise.resolve({ content: [{ type: "text", text }], isError: true, details: { mode: publicParams.action ? "management" : "workflow", results: [] } });
7171
+ const scriptTextHint = " A workflow string is a named workflow resource or a script file path. To run script text, write it in one ```js workflow block in the same reply and call subagent({ workflow: true }).";
7172
+ if (publicParams.tasks !== undefined || publicParams.chain !== undefined) {
7173
+ const kind = publicParams.tasks !== undefined ? "tasks" : "chain";
7174
+ const resolved = resolveStructuredWorkflowResource({ kind, steps: publicParams[kind], task: publicParams.task });
7175
+ if (!resolved.ok)
7176
+ return errorResult(resolved.error);
7177
+ const { tasks: _tasks, chain: _chain, task: _task, ...withoutStructuredInput } = publicParams;
7178
+ publicParams = { ...withoutStructuredInput, workflowScript: resolved.resource.script };
7179
+ workflowResourcePermits.set(publicParams, resolved.resource.permit);
7180
+ } else if (typeof workflow === "string" && !isWorkflowScriptPath(workflow)) {
7181
+ const resolved = resolveWorkflowResource(workflow, publicParams.args, ctx.sessionManager.getSessionId() ?? undefined);
6832
7182
  if (!resolved.ok)
6833
- return Promise.resolve({ content: [{ type: "text", text: resolved.error }], isError: true, details: { mode: "workflow", results: [] } });
7183
+ return Promise.resolve({ content: [{ type: "text", text: resolved.error + scriptTextHint }], isError: true, details: { mode: "workflow", results: [] } });
6834
7184
  const { workflow: _workflow, args: _args, ...withoutResourceInput } = publicParams;
6835
7185
  publicParams = { ...withoutResourceInput, workflowScript: resolved.resource.script };
6836
7186
  workflowResourcePermits.set(publicParams, resolved.resource.permit);
6837
- } else if (publicParams.workflowScript !== undefined || publicParams.workflowScriptPath !== undefined) {
7187
+ } else if (workflow !== undefined || publicParams.workflowScript !== undefined) {
6838
7188
  const normalizedArgs = normalizeWorkflowArgs(publicParams.args);
6839
- if ("error" in normalizedArgs)
6840
- return Promise.resolve({ content: [{ type: "text", text: normalizedArgs.error }], isError: true, details: { mode: publicParams.action ? "management" : "workflow", results: [] } });
6841
- publicParams = { ...publicParams, args: deepFreezeWorkflowArgs(normalizedArgs.args) };
6842
- }
6843
- const loaded = loadWorkflowScriptPath(publicParams, ctx.cwd);
6844
- if (loaded.error) {
6845
- return Promise.resolve({ content: [{ type: "text", text: loaded.error }], isError: true, details: { mode: publicParams.action ? "management" : "workflow", results: [] } });
7189
+ const validateOnly = publicParams.action === "validate";
7190
+ if ("error" in normalizedArgs && !validateOnly)
7191
+ return errorResult(normalizedArgs.error);
7192
+ let workflowScript = publicParams.workflowScript;
7193
+ if (workflow !== undefined) {
7194
+ const source = workflow === true ? readReplyWorkflowScript(ctx.sessionManager, id) : readWorkflowScriptFile(workflow, publicParams.cwd, ctx.cwd);
7195
+ if ("error" in source)
7196
+ return errorResult(workflow === true ? source.error : source.error + scriptTextHint);
7197
+ workflowScript = source.script;
7198
+ }
7199
+ const { workflow: _workflow, ...withoutWorkflowSource } = publicParams;
7200
+ publicParams = { ...withoutWorkflowSource, workflowScript, args: "error" in normalizedArgs ? publicParams.args : deepFreezeWorkflowArgs(normalizedArgs.args) };
6846
7201
  }
6847
- publicExecutions.add(loaded.params);
6848
- return executeWithSingleDispatchGuard(id, loaded.params, signal, onUpdate, ctx);
7202
+ publicExecutions.add(publicParams);
7203
+ return executeWithSingleDispatchGuard(id, publicParams, signal, onUpdate, ctx);
6849
7204
  };
6850
7205
  const executeDelegated = async (id, params, signal, onUpdate, ctx) => {
7206
+ const disabledFeatureError = disabledFeatureResult(params);
7207
+ if (disabledFeatureError)
7208
+ return disabledFeatureError;
6851
7209
  const delegatedParams = { ...params };
6852
7210
  const privateParams = delegatedParams;
6853
7211
  const thinkingOverride = privateParams.delegatedThinkingOverride;