@duckmind/dm-linux-x64 0.65.5 → 0.65.7

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 (1208) hide show
  1. package/README.md +0 -8
  2. package/dm +2 -2
  3. package/extensions/.dm-extensions.json +677 -44
  4. package/extensions/dm-lens/clients/actionable-warnings-logger.js +0 -6
  5. package/extensions/dm-lens/clients/actionable-warnings.js +42 -13
  6. package/extensions/dm-lens/clients/advisory-provenance.js +129 -41
  7. package/extensions/dm-lens/clients/agent-behavior-client.js +1 -0
  8. package/extensions/dm-lens/clients/analysed-root.js +0 -0
  9. package/extensions/dm-lens/clients/ast-grep-client.js +38 -3
  10. package/extensions/dm-lens/clients/ast-grep-rule-manager.js +37 -5
  11. package/extensions/dm-lens/clients/ast-grep-tool-logger.js +1 -7
  12. package/extensions/dm-lens/clients/bash-file-access.js +138 -1
  13. package/extensions/dm-lens/clients/biome-client.js +9 -2
  14. package/extensions/dm-lens/clients/blocker-freshness.js +171 -21
  15. package/extensions/dm-lens/clients/bootstrap.js +9 -5
  16. package/extensions/dm-lens/clients/bounded-pid-file-lock.js +1 -1
  17. package/extensions/dm-lens/clients/bounded-telemetry.js +1 -4
  18. package/extensions/dm-lens/clients/bundled-resource-health.js +43 -0
  19. package/extensions/dm-lens/clients/bus-events-logger.js +0 -6
  20. package/extensions/dm-lens/clients/cache/rule-cache.js +11 -3
  21. package/extensions/dm-lens/clients/cache-manager.js +29 -5
  22. package/extensions/dm-lens/clients/cache-observability.js +104 -4
  23. package/extensions/dm-lens/clients/cargo-manifest.js +6 -3
  24. package/extensions/dm-lens/clients/cascade-format.js +87 -5
  25. package/extensions/dm-lens/clients/cascade-logger.js +0 -6
  26. package/extensions/dm-lens/clients/child-unref.js +5 -9
  27. package/extensions/dm-lens/clients/code-quality-warnings.js +4 -2
  28. package/extensions/dm-lens/clients/complexity-client.js +5 -1
  29. package/extensions/dm-lens/clients/config-core/index.js +2 -68
  30. package/extensions/dm-lens/clients/config-core/process-spec.js +1 -1
  31. package/extensions/dm-lens/clients/config-core/provenance.js +1 -2
  32. package/extensions/dm-lens/clients/config-core/records.js +1 -1
  33. package/extensions/dm-lens/clients/config-core/schema.js +3 -6
  34. package/extensions/dm-lens/clients/config-diagnostic-codes.js +5 -3
  35. package/extensions/dm-lens/clients/config-locations.js +125 -5
  36. package/extensions/dm-lens/clients/config-resolve.js +12 -6
  37. package/extensions/dm-lens/clients/config-schema.js +56 -3
  38. package/extensions/dm-lens/clients/config-warn.js +3 -2
  39. package/extensions/dm-lens/clients/dead-code-client.js +4 -1
  40. package/extensions/dm-lens/clients/dead-code-logger.js +0 -3
  41. package/extensions/dm-lens/clients/degradation-ledger.js +29 -4
  42. package/extensions/dm-lens/clients/dependency-checker.js +29 -50
  43. package/extensions/dm-lens/clients/diagnostic-dispositions.js +23 -4
  44. package/extensions/dm-lens/clients/diagnostic-logger.js +1 -1
  45. package/extensions/dm-lens/clients/dispatch/ast-grep-catalog.js +19 -0
  46. package/extensions/dm-lens/clients/dispatch/auxiliary-lsp.js +9 -0
  47. package/extensions/dm-lens/clients/dispatch/collect-later-tier.js +0 -3
  48. package/extensions/dm-lens/clients/dispatch/dispatcher.js +30 -27
  49. package/extensions/dm-lens/clients/dispatch/facts/function-facts.js +1 -1
  50. package/extensions/dm-lens/clients/dispatch/facts/import-facts.js +4 -1
  51. package/extensions/dm-lens/clients/dispatch/finding-policy.js +163 -0
  52. package/extensions/dm-lens/clients/dispatch/indent-detect.js +213 -13
  53. package/extensions/dm-lens/clients/dispatch/inline-suppressions.js +20 -1
  54. package/extensions/dm-lens/clients/dispatch/integration.js +77 -13
  55. package/extensions/dm-lens/clients/dispatch/lazy.js +0 -3
  56. package/extensions/dm-lens/clients/dispatch/pending-runner-findings.js +1 -1
  57. package/extensions/dm-lens/clients/dispatch/plan.js +0 -3
  58. package/extensions/dm-lens/clients/dispatch/rule-ignores.js +21 -0
  59. package/extensions/dm-lens/clients/dispatch/rules/high-complexity.js +2 -2
  60. package/extensions/dm-lens/clients/dispatch/rules/high-fan-out.js +1 -1
  61. package/extensions/dm-lens/clients/dispatch/runners/actionlint.js +25 -29
  62. package/extensions/dm-lens/clients/dispatch/runners/ast-grep-napi.js +8 -32
  63. package/extensions/dm-lens/clients/dispatch/runners/biome-check.js +39 -23
  64. package/extensions/dm-lens/clients/dispatch/runners/cpp-check.js +29 -48
  65. package/extensions/dm-lens/clients/dispatch/runners/credo.js +17 -14
  66. package/extensions/dm-lens/clients/dispatch/runners/cue-vet.js +9 -7
  67. package/extensions/dm-lens/clients/dispatch/runners/dart-analyze.js +21 -43
  68. package/extensions/dm-lens/clients/dispatch/runners/detekt.js +11 -5
  69. package/extensions/dm-lens/clients/dispatch/runners/dotnet-build.js +27 -23
  70. package/extensions/dm-lens/clients/dispatch/runners/elixir-check.js +23 -38
  71. package/extensions/dm-lens/clients/dispatch/runners/eslint.js +22 -35
  72. package/extensions/dm-lens/clients/dispatch/runners/fish-indent.js +2 -1
  73. package/extensions/dm-lens/clients/dispatch/runners/gleam-check.js +35 -12
  74. package/extensions/dm-lens/clients/dispatch/runners/go-vet.js +5 -3
  75. package/extensions/dm-lens/clients/dispatch/runners/golangci-lint.js +21 -22
  76. package/extensions/dm-lens/clients/dispatch/runners/hadolint.js +26 -16
  77. package/extensions/dm-lens/clients/dispatch/runners/helm-lint.js +3 -1
  78. package/extensions/dm-lens/clients/dispatch/runners/helm-render.js +3 -2
  79. package/extensions/dm-lens/clients/dispatch/runners/htmlhint.js +18 -9
  80. package/extensions/dm-lens/clients/dispatch/runners/javac.js +24 -23
  81. package/extensions/dm-lens/clients/dispatch/runners/ktlint.js +23 -54
  82. package/extensions/dm-lens/clients/dispatch/runners/lsp.js +17 -7
  83. package/extensions/dm-lens/clients/dispatch/runners/markdownlint.js +12 -6
  84. package/extensions/dm-lens/clients/dispatch/runners/mypy.js +2 -1
  85. package/extensions/dm-lens/clients/dispatch/runners/oxlint.js +24 -7
  86. package/extensions/dm-lens/clients/dispatch/runners/php-lint.js +26 -17
  87. package/extensions/dm-lens/clients/dispatch/runners/phpstan.js +2 -1
  88. package/extensions/dm-lens/clients/dispatch/runners/prisma-validate.js +2 -1
  89. package/extensions/dm-lens/clients/dispatch/runners/psscriptanalyzer.js +10 -11
  90. package/extensions/dm-lens/clients/dispatch/runners/pyright.js +2 -1
  91. package/extensions/dm-lens/clients/dispatch/runners/rubocop.js +22 -18
  92. package/extensions/dm-lens/clients/dispatch/runners/ruff.js +17 -22
  93. package/extensions/dm-lens/clients/dispatch/runners/rust-clippy.js +8 -11
  94. package/extensions/dm-lens/clients/dispatch/runners/shellcheck.js +9 -4
  95. package/extensions/dm-lens/clients/dispatch/runners/shfmt.js +4 -13
  96. package/extensions/dm-lens/clients/dispatch/runners/spellcheck.js +15 -5
  97. package/extensions/dm-lens/clients/dispatch/runners/spotbugs.js +2 -1
  98. package/extensions/dm-lens/clients/dispatch/runners/sqlfluff.js +10 -4
  99. package/extensions/dm-lens/clients/dispatch/runners/stylelint.js +9 -4
  100. package/extensions/dm-lens/clients/dispatch/runners/swiftlint.js +11 -3
  101. package/extensions/dm-lens/clients/dispatch/runners/taplo.js +13 -7
  102. package/extensions/dm-lens/clients/dispatch/runners/terragrunt.js +2 -1
  103. package/extensions/dm-lens/clients/dispatch/runners/tflint.js +26 -16
  104. package/extensions/dm-lens/clients/dispatch/runners/tree-sitter.js +12 -13
  105. package/extensions/dm-lens/clients/dispatch/runners/trivy-config.js +9 -3
  106. package/extensions/dm-lens/clients/dispatch/runners/utils/availability-policy.js +5 -0
  107. package/extensions/dm-lens/clients/dispatch/runners/utils/candidate-probe.js +2 -2
  108. package/extensions/dm-lens/clients/dispatch/runners/utils/diagnostic-parsers.js +8 -52
  109. package/extensions/dm-lens/clients/dispatch/runners/utils/runner-helpers.js +35 -3
  110. package/extensions/dm-lens/clients/dispatch/runners/utils.js +0 -17
  111. package/extensions/dm-lens/clients/dispatch/runners/vale.js +12 -4
  112. package/extensions/dm-lens/clients/dispatch/runners/yaml-rule-parser.js +2 -20
  113. package/extensions/dm-lens/clients/dispatch/runners/yamllint.js +16 -4
  114. package/extensions/dm-lens/clients/dispatch/runners/zig-check.js +26 -38
  115. package/extensions/dm-lens/clients/dispatch/suppress-writer.js +13 -3
  116. package/extensions/dm-lens/clients/dispatch/types.js +4 -1
  117. package/extensions/dm-lens/clients/dispatch/utils/format-utils.js +2 -2
  118. package/extensions/dm-lens/clients/disposition-logger.js +0 -6
  119. package/extensions/dm-lens/clients/disposition-publish.js +2 -1
  120. package/extensions/dm-lens/clients/effective-config.js +14 -4
  121. package/extensions/dm-lens/clients/event-loop-hold.js +123 -0
  122. package/extensions/dm-lens/clients/event-loop-monitor.js +2 -2
  123. package/extensions/dm-lens/clients/extension-log.js +6 -1
  124. package/extensions/dm-lens/clients/feature-hints.js +2 -1
  125. package/extensions/dm-lens/clients/file-kinds.js +17 -21
  126. package/extensions/dm-lens/clients/file-role.js +11 -2
  127. package/extensions/dm-lens/clients/file-time.js +1 -1
  128. package/extensions/dm-lens/clients/file-utils.js +93 -6
  129. package/extensions/dm-lens/clients/finding-delivery-gate.js +22 -26
  130. package/extensions/dm-lens/clients/format-service.js +33 -16
  131. package/extensions/dm-lens/clients/formatters.js +129 -92
  132. package/extensions/dm-lens/clients/generated-artifacts.js +2 -2
  133. package/extensions/dm-lens/clients/generation-guard.js +4 -0
  134. package/extensions/dm-lens/clients/git-guard.js +80 -26
  135. package/extensions/dm-lens/clients/gitleaks-client.js +26 -0
  136. package/extensions/dm-lens/clients/govulncheck-client.js +34 -6
  137. package/extensions/dm-lens/clients/gradle-ktfmt-style.js +96 -13
  138. package/extensions/dm-lens/clients/grammar-source.js +3 -3
  139. package/extensions/dm-lens/clients/host-edit-normalize.js +1 -1
  140. package/extensions/dm-lens/clients/indent-retarget.js +35 -5
  141. package/extensions/dm-lens/clients/inline-blocker-dispositions.js +107 -0
  142. package/extensions/dm-lens/clients/install-diagnostics.js +8 -6
  143. package/extensions/dm-lens/clients/installer/index.js +695 -183
  144. package/extensions/dm-lens/clients/installer/managed-tool-refresh.js +85 -25
  145. package/extensions/dm-lens/clients/instance-reaper-state.js +3 -0
  146. package/extensions/dm-lens/clients/instance-reaper.js +23 -16
  147. package/extensions/dm-lens/clients/instance-registry.js +34 -2
  148. package/extensions/dm-lens/clients/jscpd-client.js +11 -1
  149. package/extensions/dm-lens/clients/knip-client.js +2 -1
  150. package/extensions/dm-lens/clients/language-profile.js +18 -12
  151. package/extensions/dm-lens/clients/language-registry.js +3 -1
  152. package/extensions/dm-lens/clients/latency-logger.js +14 -4
  153. package/extensions/dm-lens/clients/ledger-bounds.js +13 -1
  154. package/extensions/dm-lens/clients/lens-config.js +74 -7
  155. package/extensions/dm-lens/clients/lens-engine.js +9 -10
  156. package/extensions/dm-lens/clients/lens-events.js +1 -1
  157. package/extensions/dm-lens/clients/lens-flag-registry.js +47 -2
  158. package/extensions/dm-lens/clients/lens-map.js +1 -1
  159. package/extensions/dm-lens/clients/log-cleanup.js +0 -28
  160. package/extensions/dm-lens/clients/lsp/cascade-tier.js +2 -1
  161. package/extensions/dm-lens/clients/lsp/client.js +70 -30
  162. package/extensions/dm-lens/clients/lsp/config.js +41 -15
  163. package/extensions/dm-lens/clients/lsp/content-limits.js +21 -0
  164. package/extensions/dm-lens/clients/lsp/diagnostic-binding.js +8 -0
  165. package/extensions/dm-lens/clients/lsp/document-drift.js +72 -1
  166. package/extensions/dm-lens/clients/lsp/edits.js +3 -3
  167. package/extensions/dm-lens/clients/lsp/index.js +435 -62
  168. package/extensions/dm-lens/clients/lsp/inferred-project.js +1 -1
  169. package/extensions/dm-lens/clients/lsp/language.js +0 -3
  170. package/extensions/dm-lens/clients/lsp/launch.js +12 -5
  171. package/extensions/dm-lens/clients/lsp/path-utils.js +0 -2
  172. package/extensions/dm-lens/clients/lsp/pending-aux-coverage.js +0 -1
  173. package/extensions/dm-lens/clients/lsp/server.js +125 -60
  174. package/extensions/dm-lens/clients/lsp/session-roots.js +26 -5
  175. package/extensions/dm-lens/clients/lsp/sync-kind.js +14 -1
  176. package/extensions/dm-lens/clients/lsp/tsserver-sync.js +5 -7
  177. package/extensions/dm-lens/clients/lsp/wait-policy/classification.js +3 -0
  178. package/extensions/dm-lens/clients/lsp/wait-policy/strategies.js +31 -2
  179. package/extensions/dm-lens/clients/lsp/workspace-diagnostics-cache.js +26 -4
  180. package/extensions/dm-lens/clients/lsp-document-symbols.js +1 -1
  181. package/extensions/dm-lens/clients/map-with-concurrency.js +7 -3
  182. package/extensions/dm-lens/clients/mcp/analyze.js +1 -1
  183. package/extensions/dm-lens/clients/mcp/ipc.js +104 -40
  184. package/extensions/dm-lens/clients/mcp/review.js +39 -7
  185. package/extensions/dm-lens/clients/mcp/session.js +38 -4
  186. package/extensions/dm-lens/clients/metrics-history.js +19 -84
  187. package/extensions/dm-lens/clients/middle-man-analysis.js +2 -4
  188. package/extensions/dm-lens/clients/module-report.js +1 -1
  189. package/extensions/dm-lens/clients/mutating-tool.js +3 -3
  190. package/extensions/dm-lens/clients/mutation-attribution.js +3 -3
  191. package/extensions/dm-lens/clients/ndjson-logger.js +17 -9
  192. package/extensions/dm-lens/clients/observed-mutation.js +42 -11
  193. package/extensions/dm-lens/clients/opaque-mutation-scan.js +17 -7
  194. package/extensions/dm-lens/clients/opengrep-client.js +92 -10
  195. package/extensions/dm-lens/clients/opengrep-config.js +1 -1
  196. package/extensions/dm-lens/clients/package-manager.js +2 -1
  197. package/extensions/dm-lens/clients/path-utils.js +199 -3
  198. package/extensions/dm-lens/clients/performance-report.js +3 -3
  199. package/extensions/dm-lens/clients/persistent-reverify.js +167 -0
  200. package/extensions/dm-lens/clients/php-cs-fixer-config.js +9 -4
  201. package/extensions/dm-lens/clients/pipeline.js +124 -68
  202. package/extensions/dm-lens/clients/project-changes.js +1 -1
  203. package/extensions/dm-lens/clients/project-diagnostics/cache.js +19 -5
  204. package/extensions/dm-lens/clients/project-diagnostics/extractors.js +1 -1
  205. package/extensions/dm-lens/clients/project-diagnostics/fresh-fetch.js +150 -18
  206. package/extensions/dm-lens/clients/project-diagnostics/runner-adapters/dead-code.js +4 -1
  207. package/extensions/dm-lens/clients/project-diagnostics/runner-adapters/gitleaks.js +3 -3
  208. package/extensions/dm-lens/clients/project-diagnostics/runner-adapters/jscpd.js +1 -1
  209. package/extensions/dm-lens/clients/project-diagnostics/runner-adapters/knip.js +1 -1
  210. package/extensions/dm-lens/clients/project-diagnostics/runner-adapters/madge.js +1 -1
  211. package/extensions/dm-lens/clients/project-diagnostics/runner-adapters/opengrep.js +1 -1
  212. package/extensions/dm-lens/clients/project-diagnostics/runner-adapters/runner-findings.js +19 -2
  213. package/extensions/dm-lens/clients/project-diagnostics/scanner.js +35 -4
  214. package/extensions/dm-lens/clients/project-lens-config.js +58 -4
  215. package/extensions/dm-lens/clients/project-scan-policy.js +0 -46
  216. package/extensions/dm-lens/clients/python-environment.js +80 -4
  217. package/extensions/dm-lens/clients/python-provenance.js +551 -0
  218. package/extensions/dm-lens/clients/read-guard-logger.js +3 -1
  219. package/extensions/dm-lens/clients/read-guard.js +29 -6
  220. package/extensions/dm-lens/clients/recent-touches.js +2 -2
  221. package/extensions/dm-lens/clients/resource-sampler.js +59 -9
  222. package/extensions/dm-lens/clients/review-graph/builder.js +39 -34
  223. package/extensions/dm-lens/clients/review-graph/git-identity.js +11 -7
  224. package/extensions/dm-lens/clients/review-graph/import-resolvers.js +1 -1
  225. package/extensions/dm-lens/clients/review-graph-logger.js +3 -1
  226. package/extensions/dm-lens/clients/ruff-client.js +11 -10
  227. package/extensions/dm-lens/clients/runtime-agent-end.js +41 -5
  228. package/extensions/dm-lens/clients/runtime-context.js +5 -2
  229. package/extensions/dm-lens/clients/runtime-coordinator.js +60 -6
  230. package/extensions/dm-lens/clients/runtime-session.js +52 -8
  231. package/extensions/dm-lens/clients/runtime-tool-call.js +27 -15
  232. package/extensions/dm-lens/clients/runtime-tool-result.js +279 -63
  233. package/extensions/dm-lens/clients/runtime-turn.js +453 -185
  234. package/extensions/dm-lens/clients/safe-spawn.js +248 -62
  235. package/extensions/dm-lens/clients/sanitize.js +0 -4
  236. package/extensions/dm-lens/clients/scan-utils.js +1 -39
  237. package/extensions/dm-lens/clients/scratch-tree-policy.js +2 -3
  238. package/extensions/dm-lens/clients/security-scan-client.js +2 -2
  239. package/extensions/dm-lens/clients/session-event-guard.js +59 -2
  240. package/extensions/dm-lens/clients/session-summary.js +0 -25
  241. package/extensions/dm-lens/clients/sg-runner.js +24 -12
  242. package/extensions/dm-lens/clients/sgconfig.js +58 -6
  243. package/extensions/dm-lens/clients/shared-checkout-guard.js +1 -1
  244. package/extensions/dm-lens/clients/situational-tool-telemetry.js +85 -0
  245. package/extensions/dm-lens/clients/skills-resolver.js +42 -0
  246. package/extensions/dm-lens/clients/smells-rollup.js +2 -2
  247. package/extensions/dm-lens/clients/spawn-output-cap.js +29 -0
  248. package/extensions/dm-lens/clients/startup-scan.js +1 -2
  249. package/extensions/dm-lens/clients/string-utils.js +3 -0
  250. package/extensions/dm-lens/clients/test-runner-client.js +118 -57
  251. package/extensions/dm-lens/clients/test-runner-delivery.js +118 -66
  252. package/extensions/dm-lens/clients/tool-agreement.js +403 -0
  253. package/extensions/dm-lens/clients/tool-config.js +218 -0
  254. package/extensions/dm-lens/clients/tool-cwd.js +248 -0
  255. package/extensions/dm-lens/clients/tool-definition.js +18 -1
  256. package/extensions/dm-lens/clients/tool-policy.js +138 -10
  257. package/extensions/dm-lens/clients/tool-probe.js +5 -0
  258. package/extensions/dm-lens/clients/tool-set-policy.js +35 -0
  259. package/extensions/dm-lens/clients/tree-sitter-client.js +201 -80
  260. package/extensions/dm-lens/clients/tree-sitter-query-loader.js +78 -130
  261. package/extensions/dm-lens/clients/trivy-client.js +8 -1
  262. package/extensions/dm-lens/clients/tui-fit.js +0 -3
  263. package/extensions/dm-lens/clients/turn-context.js +48 -0
  264. package/extensions/dm-lens/clients/turn-end/lane.js +0 -0
  265. package/extensions/dm-lens/clients/turn-end/lanes/govulncheck.js +54 -0
  266. package/extensions/dm-lens/clients/turn-end/lanes/secrets.js +140 -0
  267. package/extensions/dm-lens/clients/user-notify.js +0 -3
  268. package/extensions/dm-lens/clients/warm-attach.js +25 -0
  269. package/extensions/dm-lens/clients/widget-state.js +203 -13
  270. package/extensions/dm-lens/clients/word-index-logger.js +0 -6
  271. package/extensions/dm-lens/clients/word-index-store.js +1 -4
  272. package/extensions/dm-lens/clients/word-index.js +9 -5
  273. package/extensions/dm-lens/clients/workspace-topology.js +20 -3
  274. package/extensions/dm-lens/clients/write-ordering-guard.js +6 -0
  275. package/extensions/dm-lens/clients/zizmor-config.js +15 -11
  276. package/extensions/dm-lens/config/dependency-cruiser-eager-allowlist.json +8 -2
  277. package/extensions/dm-lens/dist/clients/actionable-warnings-logger.js +24 -0
  278. package/extensions/dm-lens/dist/clients/actionable-warnings.js +1014 -0
  279. package/extensions/dm-lens/dist/clients/advisory-provenance.js +385 -0
  280. package/extensions/dm-lens/dist/clients/agent-behavior-client.js +94 -0
  281. package/extensions/dm-lens/dist/clients/agent-nudge.js +151 -0
  282. package/extensions/dm-lens/dist/clients/analysed-root.js +1 -0
  283. package/extensions/dm-lens/dist/clients/ast-grep-client.js +576 -0
  284. package/extensions/dm-lens/dist/clients/ast-grep-rule-manager.js +114 -0
  285. package/extensions/dm-lens/dist/clients/ast-grep-tool-logger.js +85 -0
  286. package/extensions/dm-lens/dist/clients/ast-grep-types.js +1 -0
  287. package/extensions/dm-lens/dist/clients/ast-grep-yaml-synth.js +109 -0
  288. package/extensions/dm-lens/dist/clients/atomic-write-staging.js +66 -0
  289. package/extensions/dm-lens/dist/clients/atomic-write.js +37 -0
  290. package/extensions/dm-lens/dist/clients/availability-probe-flight.js +11 -0
  291. package/extensions/dm-lens/dist/clients/bash-file-access.js +830 -0
  292. package/extensions/dm-lens/dist/clients/biome-client.js +221 -0
  293. package/extensions/dm-lens/dist/clients/blocker-freshness.js +385 -0
  294. package/extensions/dm-lens/dist/clients/blocker-past-eof.js +49 -0
  295. package/extensions/dm-lens/dist/clients/bootstrap.js +246 -0
  296. package/extensions/dm-lens/dist/clients/bounded-cache.js +105 -0
  297. package/extensions/dm-lens/dist/clients/bounded-pid-file-lock.js +173 -0
  298. package/extensions/dm-lens/dist/clients/bounded-telemetry.js +104 -0
  299. package/extensions/dm-lens/dist/clients/build-identity.js +45 -0
  300. package/extensions/dm-lens/dist/clients/bundled-resource-health.js +41 -0
  301. package/extensions/dm-lens/dist/clients/bus-events-logger.js +48 -0
  302. package/extensions/dm-lens/dist/clients/bus-publish.js +117 -0
  303. package/extensions/dm-lens/dist/clients/cache/rule-cache.js +103 -0
  304. package/extensions/dm-lens/dist/clients/cache-manager.js +340 -0
  305. package/extensions/dm-lens/dist/clients/cache-observability.js +847 -0
  306. package/extensions/dm-lens/dist/clients/call-graph.js +628 -0
  307. package/extensions/dm-lens/dist/clients/cargo-manifest.js +151 -0
  308. package/extensions/dm-lens/dist/clients/cascade-budget.js +52 -0
  309. package/extensions/dm-lens/dist/clients/cascade-format.js +160 -0
  310. package/extensions/dm-lens/dist/clients/cascade-logger.js +22 -0
  311. package/extensions/dm-lens/dist/clients/cascade-types.js +1 -0
  312. package/extensions/dm-lens/dist/clients/child-unref.js +59 -0
  313. package/extensions/dm-lens/dist/clients/code-quality-warnings.js +192 -0
  314. package/extensions/dm-lens/dist/clients/codebase-model.js +110 -0
  315. package/extensions/dm-lens/dist/clients/collateral-test-role.js +8 -0
  316. package/extensions/dm-lens/dist/clients/complexity-client.js +398 -0
  317. package/extensions/dm-lens/dist/clients/config-core/deny.js +117 -0
  318. package/extensions/dm-lens/dist/clients/config-core/index.js +2 -0
  319. package/extensions/dm-lens/dist/clients/config-core/merge.js +228 -0
  320. package/extensions/dm-lens/dist/clients/config-core/normalize.js +217 -0
  321. package/extensions/dm-lens/dist/clients/config-core/process-spec.js +147 -0
  322. package/extensions/dm-lens/dist/clients/config-core/provenance.js +54 -0
  323. package/extensions/dm-lens/dist/clients/config-core/records.js +79 -0
  324. package/extensions/dm-lens/dist/clients/config-core/resolve.js +48 -0
  325. package/extensions/dm-lens/dist/clients/config-core/safe-object.js +22 -0
  326. package/extensions/dm-lens/dist/clients/config-core/schema.js +90 -0
  327. package/extensions/dm-lens/dist/clients/config-diagnostic-codes.js +90 -0
  328. package/extensions/dm-lens/dist/clients/config-locations.js +175 -0
  329. package/extensions/dm-lens/dist/clients/config-resolve.js +359 -0
  330. package/extensions/dm-lens/dist/clients/config-schema.js +128 -0
  331. package/extensions/dm-lens/dist/clients/config-warn.js +146 -0
  332. package/extensions/dm-lens/dist/clients/console-guard-install.js +4 -0
  333. package/extensions/dm-lens/dist/clients/cooperative-budget.js +36 -0
  334. package/extensions/dm-lens/dist/clients/dead-code-client.js +342 -0
  335. package/extensions/dm-lens/dist/clients/dead-code-logger.js +18 -0
  336. package/extensions/dm-lens/dist/clients/deadline-utils.js +117 -0
  337. package/extensions/dm-lens/dist/clients/debug-handles.js +121 -0
  338. package/extensions/dm-lens/dist/clients/debug-heap.js +80 -0
  339. package/extensions/dm-lens/dist/clients/deferred-lsp-work.js +33 -0
  340. package/extensions/dm-lens/dist/clients/degradation-ledger.js +272 -0
  341. package/extensions/dm-lens/dist/clients/demoted-finding-render.js +61 -0
  342. package/extensions/dm-lens/dist/clients/dependency-checker.js +525 -0
  343. package/extensions/dm-lens/dist/clients/deps/ast-grep-napi.js +17 -0
  344. package/extensions/dm-lens/dist/clients/deps/dm-host-deps.js +10 -0
  345. package/extensions/dm-lens/dist/clients/deps/dm-tui-compat.js +58 -0
  346. package/extensions/dm-lens/dist/clients/deps/js-yaml.js +7 -0
  347. package/extensions/dm-lens/dist/clients/deps/minimatch.js +6 -0
  348. package/extensions/dm-lens/dist/clients/deps/pidusage.js +5 -0
  349. package/extensions/dm-lens/dist/clients/deps/typebox.js +5 -0
  350. package/extensions/dm-lens/dist/clients/deps/vscode-jsonrpc.js +8 -0
  351. package/extensions/dm-lens/dist/clients/deps/web-tree-sitter.js +11 -0
  352. package/extensions/dm-lens/dist/clients/diagnostic-dispositions.js +318 -0
  353. package/extensions/dm-lens/dist/clients/diagnostic-line-freshness.js +144 -0
  354. package/extensions/dm-lens/dist/clients/diagnostic-logger.js +60 -0
  355. package/extensions/dm-lens/dist/clients/diagnostic-tracker.js +89 -0
  356. package/extensions/dm-lens/dist/clients/diagnostics-publish.js +134 -0
  357. package/extensions/dm-lens/dist/clients/dispatch/ast-grep-catalog.js +16 -0
  358. package/extensions/dm-lens/dist/clients/dispatch/auxiliary-lsp.js +158 -0
  359. package/extensions/dm-lens/dist/clients/dispatch/collect-later-tier.js +25 -0
  360. package/extensions/dm-lens/dist/clients/dispatch/diagnostic-taxonomy.js +58 -0
  361. package/extensions/dm-lens/dist/clients/dispatch/dispatcher.js +953 -0
  362. package/extensions/dm-lens/dist/clients/dispatch/fact-provider-types.js +1 -0
  363. package/extensions/dm-lens/dist/clients/dispatch/fact-rule-runner.js +17 -0
  364. package/extensions/dm-lens/dist/clients/dispatch/fact-runner.js +18 -0
  365. package/extensions/dm-lens/dist/clients/dispatch/fact-scheduler.js +52 -0
  366. package/extensions/dm-lens/dist/clients/dispatch/fact-store.js +199 -0
  367. package/extensions/dm-lens/dist/clients/dispatch/facts/comment-facts.js +20 -0
  368. package/extensions/dm-lens/dist/clients/dispatch/facts/file-content.js +18 -0
  369. package/extensions/dm-lens/dist/clients/dispatch/facts/function-facts.js +281 -0
  370. package/extensions/dm-lens/dist/clients/dispatch/facts/import-facts.js +169 -0
  371. package/extensions/dm-lens/dist/clients/dispatch/facts/tree-sitter-facts.js +19 -0
  372. package/extensions/dm-lens/dist/clients/dispatch/facts/try-catch-facts.js +95 -0
  373. package/extensions/dm-lens/dist/clients/dispatch/finding-policy.js +159 -0
  374. package/extensions/dm-lens/dist/clients/dispatch/indent-detect.js +227 -0
  375. package/extensions/dm-lens/dist/clients/dispatch/inline-suppressions.js +52 -0
  376. package/extensions/dm-lens/dist/clients/dispatch/integration.js +1463 -0
  377. package/extensions/dm-lens/dist/clients/dispatch/lazy.js +8 -0
  378. package/extensions/dm-lens/dist/clients/dispatch/pending-runner-findings.js +75 -0
  379. package/extensions/dm-lens/dist/clients/dispatch/plan.js +278 -0
  380. package/extensions/dm-lens/dist/clients/dispatch/priorities.js +14 -0
  381. package/extensions/dm-lens/dist/clients/dispatch/rule-id-normalize.js +42 -0
  382. package/extensions/dm-lens/dist/clients/dispatch/rule-ignores.js +21 -0
  383. package/extensions/dm-lens/dist/clients/dispatch/rule-policy.js +73 -0
  384. package/extensions/dm-lens/dist/clients/dispatch/rules/async-noise.js +31 -0
  385. package/extensions/dm-lens/dist/clients/dispatch/rules/async-unnecessary-wrapper.js +27 -0
  386. package/extensions/dm-lens/dist/clients/dispatch/rules/cors-wildcard.js +35 -0
  387. package/extensions/dm-lens/dist/clients/dispatch/rules/error-obscuring.js +29 -0
  388. package/extensions/dm-lens/dist/clients/dispatch/rules/error-swallowing.js +29 -0
  389. package/extensions/dm-lens/dist/clients/dispatch/rules/framework-call-noise.js +31 -0
  390. package/extensions/dm-lens/dist/clients/dispatch/rules/high-complexity.js +56 -0
  391. package/extensions/dm-lens/dist/clients/dispatch/rules/high-fan-out.js +45 -0
  392. package/extensions/dm-lens/dist/clients/dispatch/rules/high-import-coupling.js +31 -0
  393. package/extensions/dm-lens/dist/clients/dispatch/rules/missing-error-propagation.js +45 -0
  394. package/extensions/dm-lens/dist/clients/dispatch/rules/no-commented-credentials.js +46 -0
  395. package/extensions/dm-lens/dist/clients/dispatch/rules/pass-through-wrappers.js +38 -0
  396. package/extensions/dm-lens/dist/clients/dispatch/rules/placeholder-comments.js +40 -0
  397. package/extensions/dm-lens/dist/clients/dispatch/rules/unsafe-boundary.js +101 -0
  398. package/extensions/dm-lens/dist/clients/dispatch/runner-context.js +46 -0
  399. package/extensions/dm-lens/dist/clients/dispatch/runners/actionlint.js +98 -0
  400. package/extensions/dm-lens/dist/clients/dispatch/runners/ast-grep-napi.js +690 -0
  401. package/extensions/dm-lens/dist/clients/dispatch/runners/biome-check.js +202 -0
  402. package/extensions/dm-lens/dist/clients/dispatch/runners/cpp-check.js +190 -0
  403. package/extensions/dm-lens/dist/clients/dispatch/runners/credo.js +66 -0
  404. package/extensions/dm-lens/dist/clients/dispatch/runners/cue-vet.js +167 -0
  405. package/extensions/dm-lens/dist/clients/dispatch/runners/dart-analyze.js +151 -0
  406. package/extensions/dm-lens/dist/clients/dispatch/runners/detekt.js +157 -0
  407. package/extensions/dm-lens/dist/clients/dispatch/runners/dotnet-build.js +157 -0
  408. package/extensions/dm-lens/dist/clients/dispatch/runners/elixir-check.js +153 -0
  409. package/extensions/dm-lens/dist/clients/dispatch/runners/eslint.js +99 -0
  410. package/extensions/dm-lens/dist/clients/dispatch/runners/fact-rules.js +20 -0
  411. package/extensions/dm-lens/dist/clients/dispatch/runners/fish-indent.js +65 -0
  412. package/extensions/dm-lens/dist/clients/dispatch/runners/gleam-check.js +107 -0
  413. package/extensions/dm-lens/dist/clients/dispatch/runners/go-vet.js +51 -0
  414. package/extensions/dm-lens/dist/clients/dispatch/runners/golangci-lint.js +89 -0
  415. package/extensions/dm-lens/dist/clients/dispatch/runners/hadolint.js +83 -0
  416. package/extensions/dm-lens/dist/clients/dispatch/runners/helm-lint.js +144 -0
  417. package/extensions/dm-lens/dist/clients/dispatch/runners/helm-render.js +593 -0
  418. package/extensions/dm-lens/dist/clients/dispatch/runners/htmlhint.js +103 -0
  419. package/extensions/dm-lens/dist/clients/dispatch/runners/index.js +100 -0
  420. package/extensions/dm-lens/dist/clients/dispatch/runners/javac.js +82 -0
  421. package/extensions/dm-lens/dist/clients/dispatch/runners/ktlint.js +93 -0
  422. package/extensions/dm-lens/dist/clients/dispatch/runners/lsp.js +206 -0
  423. package/extensions/dm-lens/dist/clients/dispatch/runners/markdownlint.js +129 -0
  424. package/extensions/dm-lens/dist/clients/dispatch/runners/mypy.js +70 -0
  425. package/extensions/dm-lens/dist/clients/dispatch/runners/oxlint.js +305 -0
  426. package/extensions/dm-lens/dist/clients/dispatch/runners/php-lint.js +70 -0
  427. package/extensions/dm-lens/dist/clients/dispatch/runners/phpstan.js +90 -0
  428. package/extensions/dm-lens/dist/clients/dispatch/runners/prisma-validate.js +56 -0
  429. package/extensions/dm-lens/dist/clients/dispatch/runners/psscriptanalyzer.js +307 -0
  430. package/extensions/dm-lens/dist/clients/dispatch/runners/pyright.js +118 -0
  431. package/extensions/dm-lens/dist/clients/dispatch/runners/rubocop.js +79 -0
  432. package/extensions/dm-lens/dist/clients/dispatch/runners/ruff.js +69 -0
  433. package/extensions/dm-lens/dist/clients/dispatch/runners/rust-clippy.js +147 -0
  434. package/extensions/dm-lens/dist/clients/dispatch/runners/shellcheck.js +111 -0
  435. package/extensions/dm-lens/dist/clients/dispatch/runners/shfmt.js +81 -0
  436. package/extensions/dm-lens/dist/clients/dispatch/runners/spellcheck.js +74 -0
  437. package/extensions/dm-lens/dist/clients/dispatch/runners/spotbugs.js +208 -0
  438. package/extensions/dm-lens/dist/clients/dispatch/runners/sqlfluff.js +136 -0
  439. package/extensions/dm-lens/dist/clients/dispatch/runners/stylelint.js +118 -0
  440. package/extensions/dm-lens/dist/clients/dispatch/runners/swiftlint.js +143 -0
  441. package/extensions/dm-lens/dist/clients/dispatch/runners/taplo.js +97 -0
  442. package/extensions/dm-lens/dist/clients/dispatch/runners/terragrunt.js +110 -0
  443. package/extensions/dm-lens/dist/clients/dispatch/runners/tflint.js +104 -0
  444. package/extensions/dm-lens/dist/clients/dispatch/runners/tree-sitter.js +516 -0
  445. package/extensions/dm-lens/dist/clients/dispatch/runners/trivy-config.js +155 -0
  446. package/extensions/dm-lens/dist/clients/dispatch/runners/utils/availability-policy.js +285 -0
  447. package/extensions/dm-lens/dist/clients/dispatch/runners/utils/candidate-probe.js +61 -0
  448. package/extensions/dm-lens/dist/clients/dispatch/runners/utils/diagnostic-parsers.js +61 -0
  449. package/extensions/dm-lens/dist/clients/dispatch/runners/utils/lazy-installer.js +130 -0
  450. package/extensions/dm-lens/dist/clients/dispatch/runners/utils/runner-helpers.js +1067 -0
  451. package/extensions/dm-lens/dist/clients/dispatch/runners/utils/spawn-outcome.js +40 -0
  452. package/extensions/dm-lens/dist/clients/dispatch/runners/utils/tool-failure.js +117 -0
  453. package/extensions/dm-lens/dist/clients/dispatch/runners/utils/toolchain-availability.js +88 -0
  454. package/extensions/dm-lens/dist/clients/dispatch/runners/utils.js +8 -0
  455. package/extensions/dm-lens/dist/clients/dispatch/runners/vale.js +106 -0
  456. package/extensions/dm-lens/dist/clients/dispatch/runners/yaml-rule-parser.js +163 -0
  457. package/extensions/dm-lens/dist/clients/dispatch/runners/yamllint.js +83 -0
  458. package/extensions/dm-lens/dist/clients/dispatch/runners/zig-check.js +72 -0
  459. package/extensions/dm-lens/dist/clients/dispatch/suppress-writer.js +57 -0
  460. package/extensions/dm-lens/dist/clients/dispatch/tool-profile.js +30 -0
  461. package/extensions/dm-lens/dist/clients/dispatch/types.js +7 -0
  462. package/extensions/dm-lens/dist/clients/dispatch/utils/format-utils.js +45 -0
  463. package/extensions/dm-lens/dist/clients/dispatch/utils/lsp-diagnostics.js +31 -0
  464. package/extensions/dm-lens/dist/clients/disposition-logger.js +19 -0
  465. package/extensions/dm-lens/dist/clients/disposition-publish.js +88 -0
  466. package/extensions/dm-lens/dist/clients/durable-store.js +77 -0
  467. package/extensions/dm-lens/dist/clients/effective-config.js +160 -0
  468. package/extensions/dm-lens/dist/clients/env-utils.js +26 -0
  469. package/extensions/dm-lens/dist/clients/error-class.js +3 -0
  470. package/extensions/dm-lens/dist/clients/eval-timestamp.js +2 -0
  471. package/extensions/dm-lens/dist/clients/event-loop-hold.js +119 -0
  472. package/extensions/dm-lens/dist/clients/event-loop-monitor.js +84 -0
  473. package/extensions/dm-lens/dist/clients/extension-log.js +230 -0
  474. package/extensions/dm-lens/dist/clients/extension-mode.js +20 -0
  475. package/extensions/dm-lens/dist/clients/feature-hints.js +88 -0
  476. package/extensions/dm-lens/dist/clients/file-kinds.js +304 -0
  477. package/extensions/dm-lens/dist/clients/file-role.js +50 -0
  478. package/extensions/dm-lens/dist/clients/file-time.js +112 -0
  479. package/extensions/dm-lens/dist/clients/file-utils.js +630 -0
  480. package/extensions/dm-lens/dist/clients/finding-delivery-gate.js +129 -0
  481. package/extensions/dm-lens/dist/clients/finding-identity.js +23 -0
  482. package/extensions/dm-lens/dist/clients/fix-worklog.js +75 -0
  483. package/extensions/dm-lens/dist/clients/format-events-publish.js +230 -0
  484. package/extensions/dm-lens/dist/clients/format-service.js +154 -0
  485. package/extensions/dm-lens/dist/clients/formatters-lazy.js +8 -0
  486. package/extensions/dm-lens/dist/clients/formatters.js +1351 -0
  487. package/extensions/dm-lens/dist/clients/freshness-cadence.js +1 -0
  488. package/extensions/dm-lens/dist/clients/freshness.js +8 -0
  489. package/extensions/dm-lens/dist/clients/generated-artifacts.js +209 -0
  490. package/extensions/dm-lens/dist/clients/generation-guard.js +105 -0
  491. package/extensions/dm-lens/dist/clients/git-guard.js +770 -0
  492. package/extensions/dm-lens/dist/clients/git-tracked-ignore.js +120 -0
  493. package/extensions/dm-lens/dist/clients/gitleaks-client.js +282 -0
  494. package/extensions/dm-lens/dist/clients/go-client.js +47 -0
  495. package/extensions/dm-lens/dist/clients/govulncheck-client.js +411 -0
  496. package/extensions/dm-lens/dist/clients/gradle-ktfmt-style.js +177 -0
  497. package/extensions/dm-lens/dist/clients/grammar-source.js +224 -0
  498. package/extensions/dm-lens/dist/clients/gzip-stage-write.js +85 -0
  499. package/extensions/dm-lens/dist/clients/hashline-anchor.js +222 -0
  500. package/extensions/dm-lens/dist/clients/hook-budgets.js +16 -0
  501. package/extensions/dm-lens/dist/clients/host-edit-normalize.js +87 -0
  502. package/extensions/dm-lens/dist/clients/host-ports.js +35 -0
  503. package/extensions/dm-lens/dist/clients/indent-retarget.js +102 -0
  504. package/extensions/dm-lens/dist/clients/inline-blocker-dispositions.js +103 -0
  505. package/extensions/dm-lens/dist/clients/install-diagnostics.js +123 -0
  506. package/extensions/dm-lens/dist/clients/installer/index.js +3770 -0
  507. package/extensions/dm-lens/dist/clients/installer/managed-tool-refresh-session.js +17 -0
  508. package/extensions/dm-lens/dist/clients/installer/managed-tool-refresh.js +522 -0
  509. package/extensions/dm-lens/dist/clients/instance-reaper-state.js +3 -0
  510. package/extensions/dm-lens/dist/clients/instance-reaper.js +577 -0
  511. package/extensions/dm-lens/dist/clients/instance-registry-lock.js +131 -0
  512. package/extensions/dm-lens/dist/clients/instance-registry.js +452 -0
  513. package/extensions/dm-lens/dist/clients/jscpd-client.js +252 -0
  514. package/extensions/dm-lens/dist/clients/json-cache-read.js +25 -0
  515. package/extensions/dm-lens/dist/clients/knip-client.js +472 -0
  516. package/extensions/dm-lens/dist/clients/language-policy.js +242 -0
  517. package/extensions/dm-lens/dist/clients/language-profile.js +261 -0
  518. package/extensions/dm-lens/dist/clients/language-registry.js +424 -0
  519. package/extensions/dm-lens/dist/clients/latency-logger.js +192 -0
  520. package/extensions/dm-lens/dist/clients/lazy-import.js +14 -0
  521. package/extensions/dm-lens/dist/clients/ledger-bounds.js +21 -0
  522. package/extensions/dm-lens/dist/clients/lens-config.js +237 -0
  523. package/extensions/dm-lens/dist/clients/lens-engine.js +181 -0
  524. package/extensions/dm-lens/dist/clients/lens-events.js +105 -0
  525. package/extensions/dm-lens/dist/clients/lens-flag-registry.js +302 -0
  526. package/extensions/dm-lens/dist/clients/lens-map.js +980 -0
  527. package/extensions/dm-lens/dist/clients/live-bus-emitter.js +53 -0
  528. package/extensions/dm-lens/dist/clients/log-cleanup.js +138 -0
  529. package/extensions/dm-lens/dist/clients/lsp/aggregation.js +88 -0
  530. package/extensions/dm-lens/dist/clients/lsp/cascade-tier.js +203 -0
  531. package/extensions/dm-lens/dist/clients/lsp/client.js +2709 -0
  532. package/extensions/dm-lens/dist/clients/lsp/config.js +252 -0
  533. package/extensions/dm-lens/dist/clients/lsp/content-limits.js +21 -0
  534. package/extensions/dm-lens/dist/clients/lsp/diagnostic-binding.js +79 -0
  535. package/extensions/dm-lens/dist/clients/lsp/document-drift.js +312 -0
  536. package/extensions/dm-lens/dist/clients/lsp/edits.js +930 -0
  537. package/extensions/dm-lens/dist/clients/lsp/index.js +4448 -0
  538. package/extensions/dm-lens/dist/clients/lsp/inferred-project.js +121 -0
  539. package/extensions/dm-lens/dist/clients/lsp/jvm-runtime.js +194 -0
  540. package/extensions/dm-lens/dist/clients/lsp/language.js +23 -0
  541. package/extensions/dm-lens/dist/clients/lsp/launch.js +468 -0
  542. package/extensions/dm-lens/dist/clients/lsp/lombok.js +146 -0
  543. package/extensions/dm-lens/dist/clients/lsp/path-utils.js +1 -0
  544. package/extensions/dm-lens/dist/clients/lsp/pending-aux-coverage.js +90 -0
  545. package/extensions/dm-lens/dist/clients/lsp/position-encoding.js +28 -0
  546. package/extensions/dm-lens/dist/clients/lsp/ruby-drive-dirs.js +42 -0
  547. package/extensions/dm-lens/dist/clients/lsp/server.js +2422 -0
  548. package/extensions/dm-lens/dist/clients/lsp/session-roots.js +52 -0
  549. package/extensions/dm-lens/dist/clients/lsp/spawn-history.js +15 -0
  550. package/extensions/dm-lens/dist/clients/lsp/sync-kind.js +30 -0
  551. package/extensions/dm-lens/dist/clients/lsp/tsserver-sync.js +156 -0
  552. package/extensions/dm-lens/dist/clients/lsp/wait-policy/capability-snapshot.js +1 -0
  553. package/extensions/dm-lens/dist/clients/lsp/wait-policy/classification.js +36 -0
  554. package/extensions/dm-lens/dist/clients/lsp/wait-policy/index.js +3 -0
  555. package/extensions/dm-lens/dist/clients/lsp/wait-policy/strategies.js +175 -0
  556. package/extensions/dm-lens/dist/clients/lsp/watch-queue.js +40 -0
  557. package/extensions/dm-lens/dist/clients/lsp/workspace-diagnostics-cache.js +267 -0
  558. package/extensions/dm-lens/dist/clients/lsp/workspace-diagnostics-session.js +7 -0
  559. package/extensions/dm-lens/dist/clients/lsp/workspace-sweep-hold.js +93 -0
  560. package/extensions/dm-lens/dist/clients/lsp-budget.js +83 -0
  561. package/extensions/dm-lens/dist/clients/lsp-document-symbols.js +93 -0
  562. package/extensions/dm-lens/dist/clients/lsp-lazy.js +8 -0
  563. package/extensions/dm-lens/dist/clients/lsp-mutation.js +273 -0
  564. package/extensions/dm-lens/dist/clients/lsp-status.js +37 -0
  565. package/extensions/dm-lens/dist/clients/map-with-concurrency.js +20 -0
  566. package/extensions/dm-lens/dist/clients/mcp/analyze.js +251 -0
  567. package/extensions/dm-lens/dist/clients/mcp/host-shim.js +14 -0
  568. package/extensions/dm-lens/dist/clients/mcp/ipc.js +302 -0
  569. package/extensions/dm-lens/dist/clients/mcp/review.js +137 -0
  570. package/extensions/dm-lens/dist/clients/mcp/session.js +305 -0
  571. package/extensions/dm-lens/dist/clients/memory-sampler.js +107 -0
  572. package/extensions/dm-lens/dist/clients/message-end-attribution.js +18 -0
  573. package/extensions/dm-lens/dist/clients/metrics-client.js +80 -0
  574. package/extensions/dm-lens/dist/clients/metrics-history.js +255 -0
  575. package/extensions/dm-lens/dist/clients/middle-man-analysis.js +161 -0
  576. package/extensions/dm-lens/dist/clients/model-provider.js +31 -0
  577. package/extensions/dm-lens/dist/clients/module-report-lsp.js +140 -0
  578. package/extensions/dm-lens/dist/clients/module-report.js +1642 -0
  579. package/extensions/dm-lens/dist/clients/mutating-tool.js +377 -0
  580. package/extensions/dm-lens/dist/clients/mutation-attribution.js +168 -0
  581. package/extensions/dm-lens/dist/clients/mutation-bridge.js +102 -0
  582. package/extensions/dm-lens/dist/clients/ndjson-logger.js +471 -0
  583. package/extensions/dm-lens/dist/clients/observed-mutation-sources.js +43 -0
  584. package/extensions/dm-lens/dist/clients/observed-mutation.js +709 -0
  585. package/extensions/dm-lens/dist/clients/oldtext-autopatch.js +100 -0
  586. package/extensions/dm-lens/dist/clients/opaque-mutation-scan.js +313 -0
  587. package/extensions/dm-lens/dist/clients/opengrep-client.js +216 -0
  588. package/extensions/dm-lens/dist/clients/opengrep-config.js +52 -0
  589. package/extensions/dm-lens/dist/clients/package-manager.js +303 -0
  590. package/extensions/dm-lens/dist/clients/package-root.js +25 -0
  591. package/extensions/dm-lens/dist/clients/partial-edit-apply.js +337 -0
  592. package/extensions/dm-lens/dist/clients/path-attribution-telemetry.js +31 -0
  593. package/extensions/dm-lens/dist/clients/path-keyed-map.js +57 -0
  594. package/extensions/dm-lens/dist/clients/path-utils.js +476 -0
  595. package/extensions/dm-lens/dist/clients/performance-report.js +291 -0
  596. package/extensions/dm-lens/dist/clients/persist-debounce.js +37 -0
  597. package/extensions/dm-lens/dist/clients/persistent-reverify.js +165 -0
  598. package/extensions/dm-lens/dist/clients/php-cs-fixer-config.js +15 -0
  599. package/extensions/dm-lens/dist/clients/pipeline.js +1091 -0
  600. package/extensions/dm-lens/dist/clients/post-autofix-notice.js +19 -0
  601. package/extensions/dm-lens/dist/clients/print-mode.js +3 -0
  602. package/extensions/dm-lens/dist/clients/probe-home-state.js +62 -0
  603. package/extensions/dm-lens/dist/clients/process-bridge.js +20 -0
  604. package/extensions/dm-lens/dist/clients/process-singletons.js +69 -0
  605. package/extensions/dm-lens/dist/clients/process-snapshot.js +22 -0
  606. package/extensions/dm-lens/dist/clients/project-changes.js +112 -0
  607. package/extensions/dm-lens/dist/clients/project-conventions.js +152 -0
  608. package/extensions/dm-lens/dist/clients/project-diagnostics/cache.js +91 -0
  609. package/extensions/dm-lens/dist/clients/project-diagnostics/extractors.js +53 -0
  610. package/extensions/dm-lens/dist/clients/project-diagnostics/fresh-fetch.js +408 -0
  611. package/extensions/dm-lens/dist/clients/project-diagnostics/runner-adapters/call-graph-impact.js +64 -0
  612. package/extensions/dm-lens/dist/clients/project-diagnostics/runner-adapters/dead-code.js +38 -0
  613. package/extensions/dm-lens/dist/clients/project-diagnostics/runner-adapters/gitleaks.js +21 -0
  614. package/extensions/dm-lens/dist/clients/project-diagnostics/runner-adapters/govulncheck.js +23 -0
  615. package/extensions/dm-lens/dist/clients/project-diagnostics/runner-adapters/jscpd.js +28 -0
  616. package/extensions/dm-lens/dist/clients/project-diagnostics/runner-adapters/knip.js +45 -0
  617. package/extensions/dm-lens/dist/clients/project-diagnostics/runner-adapters/madge.js +34 -0
  618. package/extensions/dm-lens/dist/clients/project-diagnostics/runner-adapters/opengrep.js +32 -0
  619. package/extensions/dm-lens/dist/clients/project-diagnostics/runner-adapters/runner-findings.js +79 -0
  620. package/extensions/dm-lens/dist/clients/project-diagnostics/runner-adapters/trivy.js +41 -0
  621. package/extensions/dm-lens/dist/clients/project-diagnostics/scanner.js +349 -0
  622. package/extensions/dm-lens/dist/clients/project-diagnostics/types.js +1 -0
  623. package/extensions/dm-lens/dist/clients/project-lens-config.js +437 -0
  624. package/extensions/dm-lens/dist/clients/project-report.js +527 -0
  625. package/extensions/dm-lens/dist/clients/project-scale.js +60 -0
  626. package/extensions/dm-lens/dist/clients/project-scan-policy.js +4 -0
  627. package/extensions/dm-lens/dist/clients/project-snapshot-fingerprint.js +39 -0
  628. package/extensions/dm-lens/dist/clients/project-snapshot-persist-worker.js +14 -0
  629. package/extensions/dm-lens/dist/clients/project-snapshot.js +1178 -0
  630. package/extensions/dm-lens/dist/clients/project-trust.js +104 -0
  631. package/extensions/dm-lens/dist/clients/python-environment.js +120 -0
  632. package/extensions/dm-lens/dist/clients/python-provenance.js +551 -0
  633. package/extensions/dm-lens/dist/clients/quiet-window-config.js +16 -0
  634. package/extensions/dm-lens/dist/clients/quiet-window.js +126 -0
  635. package/extensions/dm-lens/dist/clients/read-bridge.js +46 -0
  636. package/extensions/dm-lens/dist/clients/read-expansion.js +218 -0
  637. package/extensions/dm-lens/dist/clients/read-guard-logger.js +178 -0
  638. package/extensions/dm-lens/dist/clients/read-guard-tool-lines.js +1042 -0
  639. package/extensions/dm-lens/dist/clients/read-guard.js +1096 -0
  640. package/extensions/dm-lens/dist/clients/recent-touches.js +126 -0
  641. package/extensions/dm-lens/dist/clients/redact/secrets.js +386 -0
  642. package/extensions/dm-lens/dist/clients/resource-sampler.js +344 -0
  643. package/extensions/dm-lens/dist/clients/reverse-deps.js +227 -0
  644. package/extensions/dm-lens/dist/clients/review-graph/builder.js +3635 -0
  645. package/extensions/dm-lens/dist/clients/review-graph/format.js +30 -0
  646. package/extensions/dm-lens/dist/clients/review-graph/git-identity.js +115 -0
  647. package/extensions/dm-lens/dist/clients/review-graph/import-resolvers.js +325 -0
  648. package/extensions/dm-lens/dist/clients/review-graph/persist-worker.js +8 -0
  649. package/extensions/dm-lens/dist/clients/review-graph/query.js +195 -0
  650. package/extensions/dm-lens/dist/clients/review-graph/revision-drift.js +3 -0
  651. package/extensions/dm-lens/dist/clients/review-graph/service.js +60 -0
  652. package/extensions/dm-lens/dist/clients/review-graph/shared-extraction-ir.js +54 -0
  653. package/extensions/dm-lens/dist/clients/review-graph/symbol-id.js +29 -0
  654. package/extensions/dm-lens/dist/clients/review-graph/tsconfig-paths.js +253 -0
  655. package/extensions/dm-lens/dist/clients/review-graph/types.js +1 -0
  656. package/extensions/dm-lens/dist/clients/review-graph/workspace-modules.js +374 -0
  657. package/extensions/dm-lens/dist/clients/review-graph-logger.js +51 -0
  658. package/extensions/dm-lens/dist/clients/ruff-client.js +109 -0
  659. package/extensions/dm-lens/dist/clients/rules-scanner.js +113 -0
  660. package/extensions/dm-lens/dist/clients/run-duration.js +9 -0
  661. package/extensions/dm-lens/dist/clients/runtime-agent-end.js +608 -0
  662. package/extensions/dm-lens/dist/clients/runtime-config.js +39 -0
  663. package/extensions/dm-lens/dist/clients/runtime-context.js +155 -0
  664. package/extensions/dm-lens/dist/clients/runtime-coordinator.js +817 -0
  665. package/extensions/dm-lens/dist/clients/runtime-session.js +1625 -0
  666. package/extensions/dm-lens/dist/clients/runtime-tool-call.js +868 -0
  667. package/extensions/dm-lens/dist/clients/runtime-tool-result.js +1317 -0
  668. package/extensions/dm-lens/dist/clients/runtime-turn.js +2333 -0
  669. package/extensions/dm-lens/dist/clients/rust-client.js +48 -0
  670. package/extensions/dm-lens/dist/clients/safe-spawn.js +1267 -0
  671. package/extensions/dm-lens/dist/clients/sanitize.js +174 -0
  672. package/extensions/dm-lens/dist/clients/scan-utils.js +7 -0
  673. package/extensions/dm-lens/dist/clients/scratch-tree-policy.js +57 -0
  674. package/extensions/dm-lens/dist/clients/search-read-registration.js +59 -0
  675. package/extensions/dm-lens/dist/clients/secret-findings.js +69 -0
  676. package/extensions/dm-lens/dist/clients/security-scan-client.js +208 -0
  677. package/extensions/dm-lens/dist/clients/session-event-guard.js +111 -0
  678. package/extensions/dm-lens/dist/clients/session-lifecycle.js +173 -0
  679. package/extensions/dm-lens/dist/clients/session-start-observability.js +47 -0
  680. package/extensions/dm-lens/dist/clients/session-state-store.js +63 -0
  681. package/extensions/dm-lens/dist/clients/session-summary.js +8 -0
  682. package/extensions/dm-lens/dist/clients/sessionstart-logger.js +22 -0
  683. package/extensions/dm-lens/dist/clients/sg-runner.js +627 -0
  684. package/extensions/dm-lens/dist/clients/sgconfig.js +280 -0
  685. package/extensions/dm-lens/dist/clients/shared-checkout-guard.js +177 -0
  686. package/extensions/dm-lens/dist/clients/single-flight.js +52 -0
  687. package/extensions/dm-lens/dist/clients/situational-tool-telemetry.js +85 -0
  688. package/extensions/dm-lens/dist/clients/skills-resolver.js +38 -0
  689. package/extensions/dm-lens/dist/clients/slow-fs.js +77 -0
  690. package/extensions/dm-lens/dist/clients/smells-rollup.js +118 -0
  691. package/extensions/dm-lens/dist/clients/source-filter.js +320 -0
  692. package/extensions/dm-lens/dist/clients/source-walker.js +96 -0
  693. package/extensions/dm-lens/dist/clients/spawn-output-cap.js +35 -0
  694. package/extensions/dm-lens/dist/clients/spawn-timeout-cooldown.js +51 -0
  695. package/extensions/dm-lens/dist/clients/stale-marker.js +1 -0
  696. package/extensions/dm-lens/dist/clients/startup-scan.js +222 -0
  697. package/extensions/dm-lens/dist/clients/startup-timing.js +67 -0
  698. package/extensions/dm-lens/dist/clients/string-utils.js +6 -0
  699. package/extensions/dm-lens/dist/clients/subagent-mode.js +40 -0
  700. package/extensions/dm-lens/dist/clients/symbol-containment.js +16 -0
  701. package/extensions/dm-lens/dist/clients/symbol-types.js +1 -0
  702. package/extensions/dm-lens/dist/clients/test-runner-client.js +1504 -0
  703. package/extensions/dm-lens/dist/clients/test-runner-delivery.js +260 -0
  704. package/extensions/dm-lens/dist/clients/todo-scanner.js +164 -0
  705. package/extensions/dm-lens/dist/clients/tool-agreement.js +377 -0
  706. package/extensions/dm-lens/dist/clients/tool-config.js +218 -0
  707. package/extensions/dm-lens/dist/clients/tool-cwd.js +235 -0
  708. package/extensions/dm-lens/dist/clients/tool-definition.js +22 -0
  709. package/extensions/dm-lens/dist/clients/tool-event.js +18 -0
  710. package/extensions/dm-lens/dist/clients/tool-policy.js +2393 -0
  711. package/extensions/dm-lens/dist/clients/tool-probe.js +5 -0
  712. package/extensions/dm-lens/dist/clients/tool-render.js +79 -0
  713. package/extensions/dm-lens/dist/clients/tool-set-policy.js +70 -0
  714. package/extensions/dm-lens/dist/clients/tree-sitter-cache.js +206 -0
  715. package/extensions/dm-lens/dist/clients/tree-sitter-client.js +2787 -0
  716. package/extensions/dm-lens/dist/clients/tree-sitter-logger.js +77 -0
  717. package/extensions/dm-lens/dist/clients/tree-sitter-navigator.js +198 -0
  718. package/extensions/dm-lens/dist/clients/tree-sitter-query-loader.js +318 -0
  719. package/extensions/dm-lens/dist/clients/tree-sitter-shared.js +87 -0
  720. package/extensions/dm-lens/dist/clients/tree-sitter-symbol-extractor.js +957 -0
  721. package/extensions/dm-lens/dist/clients/trivy-client.js +305 -0
  722. package/extensions/dm-lens/dist/clients/tui-fit.js +26 -0
  723. package/extensions/dm-lens/dist/clients/turn-context.js +48 -0
  724. package/extensions/dm-lens/dist/clients/turn-end/lane.js +1 -0
  725. package/extensions/dm-lens/dist/clients/turn-end/lanes/govulncheck.js +54 -0
  726. package/extensions/dm-lens/dist/clients/turn-end/lanes/secrets.js +131 -0
  727. package/extensions/dm-lens/dist/clients/turn-summary-render.js +56 -0
  728. package/extensions/dm-lens/dist/clients/turn-summary.js +84 -0
  729. package/extensions/dm-lens/dist/clients/typos-config.js +9 -0
  730. package/extensions/dm-lens/dist/clients/user-notify.js +15 -0
  731. package/extensions/dm-lens/dist/clients/vanished-instance-marker.js +18 -0
  732. package/extensions/dm-lens/dist/clients/warm-attach.js +210 -0
  733. package/extensions/dm-lens/dist/clients/widget-state.js +963 -0
  734. package/extensions/dm-lens/dist/clients/word-index-logger.js +21 -0
  735. package/extensions/dm-lens/dist/clients/word-index-store.js +222 -0
  736. package/extensions/dm-lens/dist/clients/word-index.js +1426 -0
  737. package/extensions/dm-lens/dist/clients/workspace-topology.js +261 -0
  738. package/extensions/dm-lens/dist/clients/write-ordering-guard.js +24 -0
  739. package/extensions/dm-lens/dist/clients/zizmor-config.js +160 -0
  740. package/extensions/dm-lens/dist/i18n.js +67 -0
  741. package/extensions/dm-lens/dist/index.js +1782 -0
  742. package/extensions/dm-lens/dist/mcp/analyze-cli.js +178 -0
  743. package/extensions/dm-lens/dist/mcp/build-staleness.js +55 -0
  744. package/extensions/dm-lens/dist/mcp/cli.js +78 -0
  745. package/extensions/dm-lens/dist/mcp/server.js +1208 -0
  746. package/extensions/dm-lens/dist/mcp/worker.js +33 -0
  747. package/extensions/dm-lens/dist/scripts/lib/process-scan.mjs +256 -0
  748. package/extensions/dm-lens/dist/scripts/lib/skills-predicate.mjs +53 -0
  749. package/extensions/dm-lens/dist/scripts/lib/web-tree-sitter-dir.mjs +45 -0
  750. package/extensions/dm-lens/dist/tools/activate-tools.js +61 -0
  751. package/extensions/dm-lens/dist/tools/ast-grep-outline.js +127 -0
  752. package/extensions/dm-lens/dist/tools/ast-grep-replace.js +226 -0
  753. package/extensions/dm-lens/dist/tools/ast-grep-search.js +687 -0
  754. package/extensions/dm-lens/dist/tools/effective-config.js +59 -0
  755. package/extensions/dm-lens/dist/tools/lens-diagnostic-mark.js +240 -0
  756. package/extensions/dm-lens/dist/tools/lens-diagnostics.js +1484 -0
  757. package/extensions/dm-lens/dist/tools/lsp-diagnostics.js +1088 -0
  758. package/extensions/dm-lens/dist/tools/lsp-navigation.js +1194 -0
  759. package/extensions/dm-lens/dist/tools/lsp-structured-output.js +277 -0
  760. package/extensions/dm-lens/dist/tools/module-report.js +332 -0
  761. package/extensions/dm-lens/dist/tools/project-report.js +72 -0
  762. package/extensions/dm-lens/dist/tools/render-compact.js +272 -0
  763. package/extensions/dm-lens/dist/tools/scan-progress.js +31 -0
  764. package/extensions/dm-lens/dist/tools/shared.js +26 -0
  765. package/extensions/dm-lens/dist/tools/symbol-search.js +133 -0
  766. package/extensions/dm-lens/index.js +278 -101
  767. package/extensions/dm-lens/mcp/analyze-cli.js +3 -2
  768. package/extensions/dm-lens/mcp/build-staleness.js +1 -1
  769. package/extensions/dm-lens/mcp/server.js +144 -73
  770. package/extensions/dm-lens/package.json +4 -4
  771. package/extensions/dm-lens/rules/ast-grep-rules/rule-tests/no-assert-tuple-test.yml +13 -0
  772. package/extensions/dm-lens/rules/ast-grep-rules/rule-tests/no-boolean-in-except-test.yml +26 -0
  773. package/extensions/dm-lens/rules/ast-grep-rules/rule-tests/no-http-headers-bracket-access-test.yml +10 -0
  774. package/extensions/dm-lens/rules/ast-grep-rules/rule-tests/unchecked-numeric-parse-python-test.yml +18 -0
  775. package/extensions/dm-lens/rules/ast-grep-rules/rule-tests/unchecked-throwing-call-python-test.yml +4 -3
  776. package/extensions/dm-lens/rules/ast-grep-rules/rules/go-no-fmt-println.yml +2 -2
  777. package/extensions/dm-lens/rules/ast-grep-rules/rules/no-assert-tuple.yml +23 -13
  778. package/extensions/dm-lens/rules/ast-grep-rules/rules/no-boolean-in-except.yml +7 -3
  779. package/extensions/dm-lens/rules/ast-grep-rules/rules/no-console-except-error-js.yml +2 -2
  780. package/extensions/dm-lens/rules/ast-grep-rules/rules/no-console-except-error.yml +2 -2
  781. package/extensions/dm-lens/rules/ast-grep-rules/rules/no-http-headers-bracket-access.yml +12 -7
  782. package/extensions/dm-lens/rules/ast-grep-rules/rules/unchecked-numeric-parse-python.yml +44 -0
  783. package/extensions/dm-lens/rules/ast-grep-rules/rules/unchecked-throwing-call-python.yml +5 -3
  784. package/extensions/dm-lens/rules/tree-sitter-queries/python/python-cross-language-method.yml +3 -3
  785. package/extensions/dm-lens/rules/tree-sitter-queries/python/python-hallucinated-import.yml +2 -2
  786. package/extensions/dm-lens/rules/tree-sitter-queries/python/python-sql-injection.yml +12 -2
  787. package/extensions/dm-lens/rules/tree-sitter-queries/typescript/console-statement.yml +2 -2
  788. package/extensions/dm-lens/rules/tree-sitter-queries/typescript/sql-injection.yml +23 -7
  789. package/extensions/dm-lens/rules/typos/_typos.toml +4 -2
  790. package/extensions/dm-lens/scripts/lib/process-scan.mjs +1 -1
  791. package/extensions/dm-lens/scripts/lib/skills-predicate.mjs +53 -0
  792. package/extensions/dm-lens/scripts/lib/web-tree-sitter-dir.mjs +45 -0
  793. package/extensions/dm-lens/skills/pi-lens-ast-grep/SKILL.md +23 -6
  794. package/extensions/dm-lens/skills/pi-lens-lsp-navigation/SKILL.md +26 -9
  795. package/extensions/dm-lens/tools/activate-tools.js +10 -7
  796. package/extensions/dm-lens/tools/ast-grep-outline.js +2 -6
  797. package/extensions/dm-lens/tools/ast-grep-replace.js +5 -16
  798. package/extensions/dm-lens/tools/ast-grep-search.js +83 -38
  799. package/extensions/dm-lens/tools/effective-config.js +5 -4
  800. package/extensions/dm-lens/tools/lens-diagnostic-mark.js +5 -3
  801. package/extensions/dm-lens/tools/lens-diagnostics.js +478 -106
  802. package/extensions/dm-lens/tools/lsp-diagnostics.js +317 -172
  803. package/extensions/dm-lens/tools/lsp-navigation.js +26 -56
  804. package/extensions/dm-lens/tools/lsp-structured-output.js +3 -3
  805. package/extensions/dm-lens/tools/module-report.js +5 -5
  806. package/extensions/dm-lens/tools/project-report.js +9 -15
  807. package/extensions/dm-lens/tools/render-compact.js +220 -1
  808. package/extensions/dm-lens/tools/symbol-search.js +3 -5
  809. package/extensions/dm-mcp-adapter/OAUTH.md +368 -2
  810. package/extensions/dm-mcp-adapter/THIRD_PARTY_NOTICES.md +1 -1
  811. package/extensions/dm-mcp-adapter/agent-plugin-loader.js +73 -30
  812. package/extensions/dm-mcp-adapter/agent-plugin-provenance.js +26 -0
  813. package/extensions/dm-mcp-adapter/bearer-command-resolver.js +182 -0
  814. package/extensions/dm-mcp-adapter/claude-plugin-loader.js +350 -0
  815. package/extensions/dm-mcp-adapter/cli.js +82 -5
  816. package/extensions/dm-mcp-adapter/commands.js +89 -15
  817. package/extensions/dm-mcp-adapter/config.js +283 -33
  818. package/extensions/dm-mcp-adapter/consent-manager.js +32 -8
  819. package/extensions/dm-mcp-adapter/direct-tool-surface.js +223 -0
  820. package/extensions/dm-mcp-adapter/direct-tools.js +21 -216
  821. package/extensions/dm-mcp-adapter/dist/abort.js +35 -0
  822. package/extensions/dm-mcp-adapter/dist/agent-plugin-loader.js +73 -30
  823. package/extensions/dm-mcp-adapter/dist/agent-plugin-provenance.js +26 -0
  824. package/extensions/dm-mcp-adapter/dist/bearer-command-resolver.js +182 -0
  825. package/extensions/dm-mcp-adapter/dist/claude-plugin-loader.js +350 -0
  826. package/extensions/dm-mcp-adapter/dist/config.js +283 -33
  827. package/extensions/dm-mcp-adapter/dist/consent-manager.js +84 -0
  828. package/extensions/dm-mcp-adapter/dist/elicitation-handler.js +308 -0
  829. package/extensions/dm-mcp-adapter/dist/errors.js +225 -0
  830. package/extensions/dm-mcp-adapter/dist/http-ca.js +71 -0
  831. package/extensions/dm-mcp-adapter/dist/jev-client.js +359 -0
  832. package/extensions/dm-mcp-adapter/dist/jev-contracts.js +1 -0
  833. package/extensions/dm-mcp-adapter/dist/jev-key-store.js +176 -0
  834. package/extensions/dm-mcp-adapter/dist/json-schema-validator.js +70 -0
  835. package/extensions/dm-mcp-adapter/dist/lifecycle.js +387 -0
  836. package/extensions/dm-mcp-adapter/dist/logger.js +115 -0
  837. package/extensions/dm-mcp-adapter/dist/mcp-auth-fetch.js +86 -0
  838. package/extensions/dm-mcp-adapter/dist/mcp-auth-flow.js +949 -0
  839. package/extensions/dm-mcp-adapter/dist/mcp-auth.js +997 -0
  840. package/extensions/dm-mcp-adapter/dist/mcp-bearer-store.js +7 -136
  841. package/extensions/dm-mcp-adapter/dist/mcp-callback-server.js +381 -0
  842. package/extensions/dm-mcp-adapter/dist/mcp-oauth-provider.js +524 -0
  843. package/extensions/dm-mcp-adapter/dist/mcp-probe.js +151 -0
  844. package/extensions/dm-mcp-adapter/dist/mcp-tasks.js +300 -0
  845. package/extensions/dm-mcp-adapter/dist/mcp-trace.js +215 -0
  846. package/extensions/dm-mcp-adapter/dist/metadata-cache.js +10 -28
  847. package/extensions/dm-mcp-adapter/dist/npx-resolver.js +465 -0
  848. package/extensions/dm-mcp-adapter/dist/package-mcp-loader.js +5 -16
  849. package/extensions/dm-mcp-adapter/dist/request-headers-command.js +294 -0
  850. package/extensions/dm-mcp-adapter/dist/runtime-owner.js +94 -0
  851. package/extensions/dm-mcp-adapter/dist/sampling-handler.js +213 -0
  852. package/extensions/dm-mcp-adapter/dist/secure-keyring.js +191 -0
  853. package/extensions/dm-mcp-adapter/dist/server-manager.js +1514 -0
  854. package/extensions/dm-mcp-adapter/dist/session-approvals.js +127 -0
  855. package/extensions/dm-mcp-adapter/dist/session-recovery.js +82 -0
  856. package/extensions/dm-mcp-adapter/dist/state.js +1 -0
  857. package/extensions/dm-mcp-adapter/dist/types.js +39 -0
  858. package/extensions/dm-mcp-adapter/dist/ui-resource-handler.js +204 -0
  859. package/extensions/dm-mcp-adapter/dist/unix-socket-transport.js +83 -0
  860. package/extensions/dm-mcp-adapter/dist/utils.js +84 -9
  861. package/extensions/dm-mcp-adapter/elicitation-handler.js +27 -22
  862. package/extensions/dm-mcp-adapter/host-html-template.js +17 -18
  863. package/extensions/dm-mcp-adapter/http-ca.js +71 -0
  864. package/extensions/dm-mcp-adapter/index.js +904 -167
  865. package/extensions/dm-mcp-adapter/init.js +53 -42
  866. package/extensions/dm-mcp-adapter/jev-client.js +359 -0
  867. package/extensions/dm-mcp-adapter/jev-contracts.js +0 -0
  868. package/extensions/dm-mcp-adapter/jev-key-store.js +176 -0
  869. package/extensions/dm-mcp-adapter/json-schema-validator.js +19 -2
  870. package/extensions/dm-mcp-adapter/lazy-loader.js +7 -0
  871. package/extensions/dm-mcp-adapter/lifecycle.js +8 -3
  872. package/extensions/dm-mcp-adapter/mcp-auth-fetch.js +86 -0
  873. package/extensions/dm-mcp-adapter/mcp-auth-flow.js +228 -75
  874. package/extensions/dm-mcp-adapter/mcp-auth.js +312 -47
  875. package/extensions/dm-mcp-adapter/mcp-bearer-store.js +7 -136
  876. package/extensions/dm-mcp-adapter/mcp-code.js +151 -20
  877. package/extensions/dm-mcp-adapter/mcp-install.js +40 -0
  878. package/extensions/dm-mcp-adapter/mcp-oauth-provider.js +52 -8
  879. package/extensions/dm-mcp-adapter/mcp-output-guard.js +42 -43
  880. package/extensions/dm-mcp-adapter/mcp-panel-theme.js +79 -0
  881. package/extensions/dm-mcp-adapter/mcp-panel.js +294 -286
  882. package/extensions/dm-mcp-adapter/mcp-references.js +13 -18
  883. package/extensions/dm-mcp-adapter/mcp-script-worker.mjs +5 -1
  884. package/extensions/dm-mcp-adapter/mcp-setup-panel.js +317 -282
  885. package/extensions/dm-mcp-adapter/mcp-status.js +2 -0
  886. package/extensions/dm-mcp-adapter/mcp-tasks.js +309 -0
  887. package/extensions/dm-mcp-adapter/metadata-cache.js +11 -28
  888. package/extensions/dm-mcp-adapter/namespace-tools.js +43 -7
  889. package/extensions/dm-mcp-adapter/oauth.js +1 -1
  890. package/extensions/dm-mcp-adapter/package-mcp-loader.js +5 -16
  891. package/extensions/dm-mcp-adapter/package.json +4 -1
  892. package/extensions/dm-mcp-adapter/prompts.js +31 -4
  893. package/extensions/dm-mcp-adapter/proxy-modes.js +394 -199
  894. package/extensions/dm-mcp-adapter/request-headers-command.js +3 -2
  895. package/extensions/dm-mcp-adapter/runtime-owner.js +16 -1
  896. package/extensions/dm-mcp-adapter/sampling-handler.js +16 -25
  897. package/extensions/dm-mcp-adapter/sandbox-proxy-template.js +14 -90
  898. package/extensions/dm-mcp-adapter/search-ranking.js +31 -6
  899. package/extensions/dm-mcp-adapter/secure-keyring.js +191 -0
  900. package/extensions/dm-mcp-adapter/semantic-search.js +160 -0
  901. package/extensions/dm-mcp-adapter/server-manager.js +406 -117
  902. package/extensions/dm-mcp-adapter/session-approvals.js +127 -0
  903. package/extensions/dm-mcp-adapter/skills/mcp-scripting/SKILL.md +11 -1
  904. package/extensions/dm-mcp-adapter/test-runner.mjs +3 -4
  905. package/extensions/dm-mcp-adapter/tool-approval.js +32 -22
  906. package/extensions/dm-mcp-adapter/tool-metadata.js +18 -11
  907. package/extensions/dm-mcp-adapter/tool-registrar.js +7 -4
  908. package/extensions/dm-mcp-adapter/tool-result-renderer.js +4 -2
  909. package/extensions/dm-mcp-adapter/types.js +39 -0
  910. package/extensions/dm-mcp-adapter/ui-server.js +51 -36
  911. package/extensions/dm-mcp-adapter/ui-session.js +57 -25
  912. package/extensions/dm-mcp-adapter/utils.js +84 -9
  913. package/extensions/dm-ponytail/hooks/cursor-hooks.json +17 -0
  914. package/extensions/dm-ponytail/hooks/ponytail-activate.js +14 -2
  915. package/extensions/dm-ponytail/hooks/ponytail-mode-tracker.js +21 -2
  916. package/extensions/dm-ponytail/hooks/ponytail-runtime.js +23 -0
  917. package/extensions/dm-ponytail/package.json +1 -1
  918. package/extensions/dm-subagents/agents/claude-code-writer.md +1 -0
  919. package/extensions/dm-subagents/agents/codex-exec-writer.md +1 -0
  920. package/extensions/dm-subagents/agents/cursor-agent-writer.md +1 -0
  921. package/extensions/dm-subagents/agents/evidence-auditor.md +34 -0
  922. package/extensions/dm-subagents/agents/researcher.md +23 -13
  923. package/extensions/dm-subagents/agents/reviewer.md +6 -4
  924. package/extensions/dm-subagents/agents/scout.md +1 -1
  925. package/extensions/dm-subagents/agents/worker.md +3 -2
  926. package/extensions/dm-subagents/index.js +3 -2
  927. package/extensions/dm-subagents/inspector-runner.mjs +2 -2
  928. package/extensions/dm-subagents/install.mjs +1 -2
  929. package/extensions/dm-subagents/package.json +35 -1
  930. package/extensions/dm-subagents/prompts/council.md +6 -3
  931. package/extensions/dm-subagents/prompts/parallel-review.md +1 -1
  932. package/extensions/dm-subagents/runner-peer-loader.mjs +18 -0
  933. package/extensions/dm-subagents/runner-peer-preload.mjs +29 -0
  934. package/extensions/dm-subagents/skills/dm-subagents/SKILL.md +35 -22
  935. package/extensions/dm-subagents/skills/dm-subagents/references/constraints-and-recipes.md +9 -5
  936. package/extensions/dm-subagents/skills/dm-subagents/references/execution-controls.md +40 -19
  937. package/extensions/dm-subagents/skills/dm-subagents/references/management-authoring-rpc.md +6 -6
  938. package/extensions/dm-subagents/skills/dm-subagents/references/multi-lane-orchestration.md +11 -1
  939. package/extensions/dm-subagents/skills/dm-subagents/references/prompting-and-roles.md +35 -30
  940. package/extensions/dm-subagents/skills/dm-subagents/references/review-and-validation.md +3 -3
  941. package/extensions/dm-subagents/src/agents/advertised-agent-prompt.js +70 -0
  942. package/extensions/dm-subagents/src/agents/agent-management.js +276 -172
  943. package/extensions/dm-subagents/src/agents/agent-memory.js +92 -3
  944. package/extensions/dm-subagents/src/agents/agent-serializer.js +17 -8
  945. package/extensions/dm-subagents/src/agents/agents.js +389 -207
  946. package/extensions/dm-subagents/src/agents/builtin-names.js +1 -0
  947. package/extensions/dm-subagents/src/agents/chain-serializer.js +7 -0
  948. package/extensions/dm-subagents/src/agents/global-npm-root.js +47 -0
  949. package/extensions/dm-subagents/src/agents/proactive-skills.js +1 -1
  950. package/extensions/dm-subagents/src/agents/runtime-agent-registry.js +17 -13
  951. package/extensions/dm-subagents/src/agents/skills.js +36 -10
  952. package/extensions/dm-subagents/src/api/capability-ceiling.js +0 -1
  953. package/extensions/dm-subagents/src/api/child-tool-plan.js +3 -0
  954. package/extensions/dm-subagents/src/api/preflight.js +75 -64
  955. package/extensions/dm-subagents/src/api/required-child-extensions.js +3 -0
  956. package/extensions/dm-subagents/src/api/workflow-resources.js +1 -0
  957. package/extensions/dm-subagents/src/extension/config.js +27 -18
  958. package/extensions/dm-subagents/src/extension/doctor.js +10 -13
  959. package/extensions/dm-subagents/src/extension/fanout-child.js +91 -14
  960. package/extensions/dm-subagents/src/extension/herdr-dm-bridge.js +258 -0
  961. package/extensions/dm-subagents/src/extension/index.js +202 -66
  962. package/extensions/dm-subagents/src/extension/public-execution.js +55 -4
  963. package/extensions/dm-subagents/src/extension/rpc.js +18 -27
  964. package/extensions/dm-subagents/src/extension/schemas.js +99 -84
  965. package/extensions/dm-subagents/src/extension/subagent-guide.js +14 -3
  966. package/extensions/dm-subagents/src/extension/tool-activation.js +157 -0
  967. package/extensions/dm-subagents/src/extension/tool-description.js +30 -78
  968. package/extensions/dm-subagents/src/inspectors/actions.js +145 -0
  969. package/extensions/dm-subagents/src/inspectors/ghostty/actions.js +60 -0
  970. package/extensions/dm-subagents/src/inspectors/ghostty/plugin.js +17 -0
  971. package/extensions/dm-subagents/src/inspectors/herdr/actions.js +94 -179
  972. package/extensions/dm-subagents/src/inspectors/herdr/plugin.js +13 -0
  973. package/extensions/dm-subagents/src/inspectors/herdr/project-panes.js +1 -1
  974. package/extensions/dm-subagents/src/inspectors/{herdr/inspector-runner.js → inspector-runner.js} +31 -25
  975. package/extensions/dm-subagents/src/inspectors/plugins.js +5 -0
  976. package/extensions/dm-subagents/src/inspectors/{herdr/session-roots-codec.js → session-roots-codec.js} +1 -6
  977. package/extensions/dm-subagents/src/inspectors/types.js +1 -0
  978. package/extensions/dm-subagents/src/integrations/dm-web-session-liveness.js +50 -0
  979. package/extensions/dm-subagents/src/intercom/intercom-bridge.js +39 -5
  980. package/extensions/dm-subagents/src/intercom/native-supervisor-channel.js +256 -151
  981. package/extensions/dm-subagents/src/intercom/result-intercom.js +6 -0
  982. package/extensions/dm-subagents/src/intercom/supervisor-ui.js +199 -0
  983. package/extensions/dm-subagents/src/missions/workflow-state.js +30 -17
  984. package/extensions/dm-subagents/src/policy/authority.js +6 -2
  985. package/extensions/dm-subagents/src/profiles/profiles.js +10 -5
  986. package/extensions/dm-subagents/src/runs/background/active-async-capacity.js +28 -35
  987. package/extensions/dm-subagents/src/runs/background/active-run-index.js +17 -0
  988. package/extensions/dm-subagents/src/runs/background/async-execution.js +580 -389
  989. package/extensions/dm-subagents/src/runs/background/async-job-tracker.js +71 -47
  990. package/extensions/dm-subagents/src/runs/background/async-resume.js +61 -26
  991. package/extensions/dm-subagents/src/runs/background/async-retention.js +8 -0
  992. package/extensions/dm-subagents/src/runs/background/async-status-snapshot.js +3 -4
  993. package/extensions/dm-subagents/src/runs/background/async-status.js +90 -13
  994. package/extensions/dm-subagents/src/runs/background/auto-drain.js +57 -33
  995. package/extensions/dm-subagents/src/runs/background/binary-bootstrap.js +54 -0
  996. package/extensions/dm-subagents/src/runs/background/chain-append.js +1 -1
  997. package/extensions/dm-subagents/src/runs/background/chain-root-attachment.js +11 -27
  998. package/extensions/dm-subagents/src/runs/background/control-channel.js +105 -256
  999. package/extensions/dm-subagents/src/runs/background/fleet-view.js +67 -10
  1000. package/extensions/dm-subagents/src/runs/background/notify.js +252 -17
  1001. package/extensions/dm-subagents/src/runs/background/owned-process-tree.js +33 -2
  1002. package/extensions/dm-subagents/src/runs/background/process-terminal-candidate.js +88 -0
  1003. package/extensions/dm-subagents/src/runs/background/process-terminal.js +29 -87
  1004. package/extensions/dm-subagents/src/runs/background/result-files.js +8 -4
  1005. package/extensions/dm-subagents/src/runs/background/result-watcher.js +15 -3
  1006. package/extensions/dm-subagents/src/runs/background/retained-children.js +3 -2
  1007. package/extensions/dm-subagents/src/runs/background/retained-nested-route-tracker.js +86 -0
  1008. package/extensions/dm-subagents/src/runs/background/run-child-session.js +574 -0
  1009. package/extensions/dm-subagents/src/runs/background/run-id-resolver.js +9 -5
  1010. package/extensions/dm-subagents/src/runs/background/run-status.js +114 -11
  1011. package/extensions/dm-subagents/src/runs/background/runner-aliases.js +129 -0
  1012. package/extensions/dm-subagents/src/runs/background/runner-child-launch.js +62 -0
  1013. package/extensions/dm-subagents/src/runs/background/runner-child-sessions.js +16 -0
  1014. package/extensions/dm-subagents/src/runs/background/runner-http-dispatcher.js +84 -0
  1015. package/extensions/dm-subagents/src/runs/background/runner-startup-failure.js +43 -0
  1016. package/extensions/dm-subagents/src/runs/background/scheduled-runs.js +119 -20
  1017. package/extensions/dm-subagents/src/runs/background/stale-run-reconciler.js +33 -10
  1018. package/extensions/dm-subagents/src/runs/background/steering.js +24 -3
  1019. package/extensions/dm-subagents/src/runs/background/subagent-runner-bootstrap.js +238 -0
  1020. package/extensions/dm-subagents/src/runs/background/subagent-runner.js +1008 -1344
  1021. package/extensions/dm-subagents/src/runs/background/subagent-wait.js +156 -26
  1022. package/extensions/dm-subagents/src/runs/background/wait-completions.js +91 -23
  1023. package/extensions/dm-subagents/src/runs/background/wait-subscriptions.js +10 -3
  1024. package/extensions/dm-subagents/src/runs/background/wait-tool.js +8 -12
  1025. package/extensions/dm-subagents/src/runs/background/workflow-terminal-proof.js +60 -0
  1026. package/extensions/dm-subagents/src/runs/foreground/async-steering-action.js +29 -26
  1027. package/extensions/dm-subagents/src/runs/foreground/async-stop-action.js +94 -2
  1028. package/extensions/dm-subagents/src/runs/foreground/execution.js +446 -648
  1029. package/extensions/dm-subagents/src/runs/foreground/foreground-control.js +4 -0
  1030. package/extensions/dm-subagents/src/runs/foreground/foreground-history.js +5 -2
  1031. package/extensions/dm-subagents/src/runs/foreground/prompt-audit.js +8 -4
  1032. package/extensions/dm-subagents/src/runs/foreground/subagent-executor.js +1337 -445
  1033. package/extensions/dm-subagents/src/runs/foreground/workflow-detach-reconcile.js +10 -5
  1034. package/extensions/dm-subagents/src/runs/foreground/workflow-foreground-steering.js +65 -90
  1035. package/extensions/dm-subagents/src/runs/shared/acceptance.js +265 -68
  1036. package/extensions/dm-subagents/src/runs/shared/agent-contract.js +1 -1
  1037. package/extensions/dm-subagents/src/runs/shared/async-status-projection.js +133 -76
  1038. package/extensions/dm-subagents/src/runs/shared/capability-ceiling.js +4 -2
  1039. package/extensions/dm-subagents/src/runs/shared/child-hooks.js +166 -0
  1040. package/extensions/dm-subagents/src/runs/shared/child-identity.js +10 -2
  1041. package/extensions/dm-subagents/src/runs/shared/child-launch-plan.js +19 -2
  1042. package/extensions/dm-subagents/src/runs/shared/child-launch.js +212 -0
  1043. package/extensions/dm-subagents/src/runs/shared/child-lifecycle.js +22 -0
  1044. package/extensions/dm-subagents/src/runs/shared/child-runtime-config.js +31 -0
  1045. package/extensions/dm-subagents/src/runs/shared/child-session.js +378 -0
  1046. package/extensions/dm-subagents/src/runs/shared/child-tool-plan.js +299 -0
  1047. package/extensions/dm-subagents/src/runs/shared/claude-code-adapter.js +1 -1
  1048. package/extensions/dm-subagents/src/runs/shared/dm-spawn.js +148 -32
  1049. package/extensions/dm-subagents/src/runs/shared/dynamic-fanout.js +6 -4
  1050. package/extensions/dm-subagents/src/runs/shared/effective-system-prompt.js +19 -0
  1051. package/extensions/dm-subagents/src/runs/shared/external-cli-contract.js +6 -1
  1052. package/extensions/dm-subagents/src/runs/shared/external-cli-preflight.js +14 -2
  1053. package/extensions/dm-subagents/src/runs/shared/external-cli-runner.js +6 -7
  1054. package/extensions/dm-subagents/src/runs/shared/external-job-bridge.js +60 -0
  1055. package/extensions/dm-subagents/src/runs/shared/git-environment.js +25 -0
  1056. package/extensions/dm-subagents/src/runs/shared/herdr-connection.js +341 -0
  1057. package/extensions/dm-subagents/src/runs/shared/herdr-dm-protocol.js +60 -0
  1058. package/extensions/dm-subagents/src/runs/shared/herdr-external-adapters.js +555 -0
  1059. package/extensions/dm-subagents/src/runs/shared/herdr-machine.js +239 -0
  1060. package/extensions/dm-subagents/src/runs/shared/herdr-placed-run.js +987 -0
  1061. package/extensions/dm-subagents/src/runs/shared/host-step-status.js +2 -0
  1062. package/extensions/dm-subagents/src/runs/shared/lane-metadata.js +23 -3
  1063. package/extensions/dm-subagents/src/runs/shared/mcp-direct-tool-allowlist.js +4 -3
  1064. package/extensions/dm-subagents/src/runs/shared/mcp-direct-tool-grant.js +15 -5
  1065. package/extensions/dm-subagents/src/runs/shared/model-resolution-diagnostic.js +43 -0
  1066. package/extensions/dm-subagents/src/runs/shared/{model-fallback.js → model-resolution.js} +44 -128
  1067. package/extensions/dm-subagents/src/runs/shared/nested-events.js +39 -49
  1068. package/extensions/dm-subagents/src/runs/shared/nested-path.js +0 -13
  1069. package/extensions/dm-subagents/src/runs/shared/orca-progress-tabs.js +22 -12
  1070. package/extensions/dm-subagents/src/runs/shared/parallel-handoff.js +78 -2
  1071. package/extensions/dm-subagents/src/runs/shared/permissions.js +1 -16
  1072. package/extensions/dm-subagents/src/runs/shared/process-signal.js +3 -0
  1073. package/extensions/dm-subagents/src/runs/shared/readonly-drain-observation.js +51 -0
  1074. package/extensions/dm-subagents/src/runs/shared/run-fanout-budget.js +0 -13
  1075. package/extensions/dm-subagents/src/runs/shared/runtime-acknowledged-extensions.js +0 -26
  1076. package/extensions/dm-subagents/src/runs/shared/single-output.js +20 -2
  1077. package/extensions/dm-subagents/src/runs/shared/structured-output.js +263 -10
  1078. package/extensions/dm-subagents/src/runs/shared/subagent-control.js +6 -14
  1079. package/extensions/dm-subagents/src/runs/shared/subagent-prompt-runtime.js +117 -370
  1080. package/extensions/dm-subagents/src/runs/shared/tool-availability.js +12 -50
  1081. package/extensions/dm-subagents/src/runs/shared/tool-budget.js +10 -13
  1082. package/extensions/dm-subagents/src/runs/shared/tool-timeout.js +1 -1
  1083. package/extensions/dm-subagents/src/runs/shared/usage-reconciliation.js +69 -0
  1084. package/extensions/dm-subagents/src/runs/shared/workflow-async-child-guidance.js +11 -0
  1085. package/extensions/dm-subagents/src/runs/shared/worktree-cleanup-plan.js +30 -10
  1086. package/extensions/dm-subagents/src/runs/shared/worktree-setup-command.js +195 -0
  1087. package/extensions/dm-subagents/src/runs/shared/worktree.js +814 -141
  1088. package/extensions/dm-subagents/src/shared/atomic-json.js +2 -1
  1089. package/extensions/dm-subagents/src/shared/child-cache-retention.js +19 -0
  1090. package/extensions/dm-subagents/src/shared/fork-context.js +40 -77
  1091. package/extensions/dm-subagents/src/shared/fork-session-cwd.js +24 -0
  1092. package/extensions/dm-subagents/src/shared/jsonl-writer.js +8 -0
  1093. package/extensions/dm-subagents/src/shared/launch-contract.js +37 -6
  1094. package/extensions/dm-subagents/src/shared/model-response-aliases.js +15 -0
  1095. package/extensions/dm-subagents/src/shared/opencode-session-headers.js +15 -0
  1096. package/extensions/dm-subagents/src/shared/pruned-fork.js +83 -76
  1097. package/extensions/dm-subagents/src/shared/required-child-extensions.js +72 -0
  1098. package/extensions/dm-subagents/src/shared/shortcuts.js +0 -2
  1099. package/extensions/dm-subagents/src/shared/thinking-ceiling.js +0 -6
  1100. package/extensions/dm-subagents/src/shared/types.js +16 -12
  1101. package/extensions/dm-subagents/src/shared/utils.js +22 -7
  1102. package/extensions/dm-subagents/src/shared/watch-strategy.js +2 -0
  1103. package/extensions/dm-subagents/src/shared/workflow-child-permit.js +70 -0
  1104. package/extensions/dm-subagents/src/slash/delegation-adapters.js +15 -1
  1105. package/extensions/dm-subagents/src/slash/delegation-request.js +13 -0
  1106. package/extensions/dm-subagents/src/slash/prompt-template-bridge.js +28 -1
  1107. package/extensions/dm-subagents/src/slash/prompt-workflows.js +15 -2
  1108. package/extensions/dm-subagents/src/slash/slash-commands.js +12 -269
  1109. package/extensions/dm-subagents/src/slash/subagent-cost.js +255 -0
  1110. package/extensions/dm-subagents/src/slash/subagents-admin.js +49 -25
  1111. package/extensions/dm-subagents/src/tui/fleet-status.js +224 -23
  1112. package/extensions/dm-subagents/src/tui/fleet.js +38 -25
  1113. package/extensions/dm-subagents/src/tui/render.js +636 -63
  1114. package/extensions/dm-subagents/src/watchdog/child-status.js +42 -23
  1115. package/extensions/dm-subagents/src/watchdog/diff-tool.js +86 -0
  1116. package/extensions/dm-subagents/src/watchdog/emission-guard.js +4 -3
  1117. package/extensions/dm-subagents/src/watchdog/guidance.js +19 -0
  1118. package/extensions/dm-subagents/src/watchdog/lsp-diagnostics.js +1 -1
  1119. package/extensions/dm-subagents/src/watchdog/model-selection.js +18 -1
  1120. package/extensions/dm-subagents/src/watchdog/permission-arbiter.js +16 -10
  1121. package/extensions/dm-subagents/src/watchdog/register-child.js +39 -26
  1122. package/extensions/dm-subagents/src/watchdog/register-main.js +51 -43
  1123. package/extensions/dm-subagents/src/watchdog/render.js +5 -7
  1124. package/extensions/dm-subagents/src/watchdog/review.js +142 -67
  1125. package/extensions/dm-subagents/src/watchdog/rules.js +55 -0
  1126. package/extensions/dm-subagents/src/watchdog/runtime.js +167 -109
  1127. package/extensions/dm-subagents/src/watchdog/scope.js +1 -9
  1128. package/extensions/dm-subagents/src/watchdog/settings.js +55 -99
  1129. package/extensions/dm-subagents/src/watchdog/tool-actions.js +11 -12
  1130. package/extensions/dm-subagents/src/watchdog/turn-delta.js +30 -5
  1131. package/extensions/dm-subagents/src/watchdog/types.js +2 -4
  1132. package/extensions/dm-subagents/src/watchdog/warning-format.js +2 -3
  1133. package/extensions/dm-subagents/src/workflows/chat-progress.js +4 -4
  1134. package/extensions/dm-subagents/src/workflows/scripted-workflow.js +482 -36
  1135. package/extensions/dm-subagents/src/workflows/workflow-checklist.js +303 -0
  1136. package/extensions/dm-subagents/src/workflows/workflow-child-summary.js +57 -5
  1137. package/extensions/dm-subagents/src/workflows/workflow-preflight.js +27 -1
  1138. package/extensions/dm-subagents/src/workflows/workflow-receipt.js +51 -3
  1139. package/extensions/dm-subagents/src/workflows/workflow-resources.js +226 -0
  1140. package/extensions/dm-subagents/src/workflows/workflow-settlement.js +5 -0
  1141. package/extensions/dm-web-access/abortable.js +19 -0
  1142. package/extensions/dm-web-access/anysearch.js +4 -13
  1143. package/extensions/dm-web-access/baizhi.js +123 -0
  1144. package/extensions/dm-web-access/bocha.js +3 -24
  1145. package/extensions/dm-web-access/brave.js +3 -23
  1146. package/extensions/dm-web-access/brightdata.js +5 -30
  1147. package/extensions/dm-web-access/content-find.js +181 -47
  1148. package/extensions/dm-web-access/crawl4ai.js +166 -0
  1149. package/extensions/dm-web-access/credential-source.js +1 -0
  1150. package/extensions/dm-web-access/curator-page.js +27 -2
  1151. package/extensions/dm-web-access/curator-run.js +36 -0
  1152. package/extensions/dm-web-access/curator-server.js +11 -2
  1153. package/extensions/dm-web-access/domain-filter-normalization.js +17 -0
  1154. package/extensions/dm-web-access/duckduckgo.js +4 -24
  1155. package/extensions/dm-web-access/extract.js +54 -12
  1156. package/extensions/dm-web-access/fetch-params.js +1 -1
  1157. package/extensions/dm-web-access/firecrawl.js +7 -45
  1158. package/extensions/dm-web-access/gemini-search.js +101 -46
  1159. package/extensions/dm-web-access/github-extract.js +2 -11
  1160. package/extensions/dm-web-access/index.js +382 -247
  1161. package/extensions/dm-web-access/jina-search.js +4 -13
  1162. package/extensions/dm-web-access/kagi.js +4 -13
  1163. package/extensions/dm-web-access/kimi-search.js +5 -30
  1164. package/extensions/dm-web-access/mistral-search.js +251 -0
  1165. package/extensions/dm-web-access/ollama.js +2 -7
  1166. package/extensions/dm-web-access/openai-search.js +204 -46
  1167. package/extensions/dm-web-access/opencode-session-headers.js +15 -0
  1168. package/extensions/dm-web-access/package.json +1 -1
  1169. package/extensions/dm-web-access/page-query.js +14 -4
  1170. package/extensions/dm-web-access/parallel.js +1 -17
  1171. package/extensions/dm-web-access/pdf-extract.js +1 -0
  1172. package/extensions/dm-web-access/perplexity.js +10 -1
  1173. package/extensions/dm-web-access/querit.js +5 -34
  1174. package/extensions/dm-web-access/query-rewrite.js +6 -2
  1175. package/extensions/dm-web-access/search-answer-formatting.js +6 -0
  1176. package/extensions/dm-web-access/search-result-count-normalization.js +5 -0
  1177. package/extensions/dm-web-access/search1api.js +5 -34
  1178. package/extensions/dm-web-access/searchinfinity.js +5 -34
  1179. package/extensions/dm-web-access/searxng.js +3 -23
  1180. package/extensions/dm-web-access/serpapi.js +183 -0
  1181. package/extensions/dm-web-access/serpbase.js +3 -24
  1182. package/extensions/dm-web-access/serpdive.js +3 -23
  1183. package/extensions/dm-web-access/serper.js +5 -30
  1184. package/extensions/dm-web-access/serply.js +184 -0
  1185. package/extensions/dm-web-access/source-check.js +10 -46
  1186. package/extensions/dm-web-access/ssrf-protection.js +3 -1
  1187. package/extensions/dm-web-access/storage.js +9 -0
  1188. package/extensions/dm-web-access/summary-review.js +36 -25
  1189. package/extensions/dm-web-access/tavily.js +3 -23
  1190. package/extensions/dm-web-access/tinyfish.js +5 -34
  1191. package/extensions/dm-web-access/tool-activation.js +112 -0
  1192. package/extensions/dm-web-access/utils.js +27 -10
  1193. package/extensions/dm-web-access/valyu.js +5 -30
  1194. package/extensions/dm-web-access/xai-search.js +78 -42
  1195. package/extensions/dm-web-access/xcrawl.js +5 -30
  1196. package/package.json +7 -4
  1197. package/extensions/dm-lens/tools/ast-dump.js +0 -101
  1198. package/extensions/dm-subagents/src/api/dm-args.js +0 -3
  1199. package/extensions/dm-subagents/src/runs/shared/child-protocol.js +0 -447
  1200. package/extensions/dm-subagents/src/runs/shared/completion-evidence.js +0 -40
  1201. package/extensions/dm-subagents/src/runs/shared/completion-guard.js +0 -173
  1202. package/extensions/dm-subagents/src/runs/shared/dm-args.js +0 -581
  1203. package/extensions/dm-subagents/src/runs/shared/llm-intent-arbiter.js +0 -190
  1204. package/extensions/dm-subagents/src/runs/shared/model-exclusions.js +0 -207
  1205. package/extensions/dm-subagents/src/runs/shared/subagent-startup-retry.js +0 -50
  1206. package/extensions/dm-subagents/src/runs/shared/task-intent.js +0 -130
  1207. package/extensions/dm-subagents/src/shared/post-exit-stdio-guard.js +0 -68
  1208. /package/extensions/dm-subagents/src/inspectors/{herdr/shell-command.js → shell-command.js} +0 -0
@@ -21,10 +21,13 @@ 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 } from "../../extension/public-execution.js";
24
+ import { normalizePublicSubagentExecution, validateWorkflowCapacityOverrides } from "../../extension/public-execution.js";
25
25
  import { runSync } from "./execution.js";
26
26
  import { handleWatchdogToolAction, WATCHDOG_TOOL_ACTIONS } from "../../watchdog/tool-actions.js";
27
- import { buildModelCandidates, inheritsParentModel, normalizeParentModel, resolveEffectiveSubagentModel } from "../shared/model-fallback.js";
27
+ import { applyWatchdogLaunchRules } from "../../watchdog/rules.js";
28
+ import { childWatchdogProgressForModel } from "../../watchdog/child-status.js";
29
+ import { normalizeParentModel, resolveEffectiveSubagentModel, resolveModelOrigin } from "../shared/model-resolution.js";
30
+ import { projectChainOutputSchemas, resolveEffectiveOutputSchema } from "../shared/child-launch-plan.js";
28
31
  import { formatRetainedChildren, listRetainedChildren } from "../background/retained-children.js";
29
32
  import { resolveModelScopesForAgent } from "../shared/model-scope.js";
30
33
  import { recordRun } from "../shared/run-history.js";
@@ -40,27 +43,30 @@ import { updateActiveRunIndex } from "../background/active-run-index.js";
40
43
  import { steeringReceipt } from "../background/steering.js";
41
44
  import { acquireActiveAsyncCapacity, ActiveAsyncCapacityError, getActiveAsyncCapacitySnapshot, resolveAbandonedSlotReleaseAfterMs, resolveMaxActiveAsyncRunsPerSession, transferActiveAsyncCapacity } from "../background/active-async-capacity.js";
42
45
  import { isScheduledRunAction } from "../background/scheduled-runs.js";
46
+ import { encodeIndexSegment } from "../background/index-segment.js";
43
47
  import { enqueueChainAppendRequest, readPendingChainAppendRequests, runnerStepOutputNames } from "../background/chain-append.js";
44
48
  import { ChainOutputValidationError, validateChainOutputBindingsWithContext } from "../shared/chain-outputs.js";
45
- import { normalizeGateAcceptance, validateExecutionAcceptance } from "../shared/acceptance.js";
46
- import { canPreferFork, createForkContextResolver, forkedChildRequiresThinkingOff, resolveSubagentLaunchContext } from "../../shared/fork-context.js";
49
+ import { acceptanceHasTypedVerify, normalizeGateAcceptance, resolveAcceptanceReportMode, TYPED_VERIFY_OUTPUT_SCHEMA_CONFLICT, validateAcceptanceInput, validateExecutionAcceptance, validateExecutionAcceptancePolicy } from "../shared/acceptance.js";
50
+ import { canPreferFork, createForkContextResolver, resolveSubagentLaunchContext } from "../../shared/fork-context.js";
47
51
  import { createPrunedForkSessionWriter } from "../../shared/pruned-fork.js";
48
52
  import { resolveCurrentSessionId } from "../../shared/session-identity.js";
49
53
  import { currentCompletionOwnerId } from "../../shared/completion-owner.js";
54
+ import { SUBAGENT_ASYNC_COMPLETE_EVENT } from "../../shared/types.js";
50
55
  import { applyIntercomBridgeToAgent, INTERCOM_BRIDGE_MARKER, resolveIntercomBridge, resolveIntercomSessionTarget, resolveSubagentIntercomTarget } from "../../intercom/intercom-bridge.js";
51
56
  import { formatControlIntercomMessage, formatControlNoticeMessage, resolveControlConfig, shouldNotifyControlEvent } from "../shared/subagent-control.js";
52
57
  import { formatSpawnBudget, getSpawnBudgetSnapshot, grantSpawnBudget, preflightSpawnBudget, preflightSpawnBudgetGrant, reserveSpawnBudget } from "../shared/spawn-budget.js";
53
- import { claimRunFanoutBatch, claimRunFanoutBatchWithCommit, createRunFanoutBudget, decodeRunFanoutBudgetDescriptor, formatRunFanoutBudget, getRunFanoutBudgetSnapshot, readRunFanoutBudgetDescriptor, RunFanoutLimitError, RUN_FANOUT_BUDGET_ENV, writeRunFanoutBudgetDescriptor } from "../shared/run-fanout-budget.js";
58
+ import { claimRunFanoutBatch, claimRunFanoutBatchWithCommit, createRunFanoutBudget, formatRunFanoutBudget, getRunFanoutBudgetSnapshot, readRunFanoutBudgetDescriptor, RunFanoutLimitError, writeRunFanoutBudgetDescriptor } from "../shared/run-fanout-budget.js";
59
+ import { retainLiveForegroundNestedRoute } from "../../integrations/dm-web-session-liveness.js";
54
60
  import { validateToolBudgetConfig } from "../shared/tool-budget.js";
55
61
  import { usageBudgetExceededMessage, usageBudgetState, validateUsageBudgetConfig } from "../shared/usage-budget.js";
56
62
  import { intersectSubagentCapabilityCeilings, resolveCurrentSubagentCapabilityCeiling } from "../shared/capability-ceiling.js";
57
- import { isAgentContractV1 } from "../shared/agent-contract.js";
63
+ import { isAgentContract } from "../shared/agent-contract.js";
58
64
  import { normalizeExtensionBindings } from "../shared/extension-bindings.js";
65
+ import { resolveRequiredChildExtensions } from "../../shared/required-child-extensions.js";
59
66
  import { finalizeSingleOutput, injectSingleOutputInstruction, normalizeSingleOutputOverride, outputPathMappingFromTask, resolveSingleOutputPath, validateFileOnlyOutputMode } from "../shared/single-output.js";
60
67
  import { assertJsonSchemaObject, cleanupStructuredOutputRuntime, createStructuredOutputRuntime } from "../shared/structured-output.js";
61
- import { compactForegroundDetails, getSingleResultOutput, readStatus, resolveChildCwd, sumResultsCost, sumResultsUsage } from "../../shared/utils.js";
62
- import { createTaskMutationArbiter } from "../shared/llm-intent-arbiter.js";
63
- import { discardPreservedWorktrees, formatParallelHandoffError, formatParallelHandoffReference, formatStoredParallelHandoffCleanup, parallelHandoffPath, readParallelHandoffManifest, recordParallelHandoffMerge, recordParallelHandoffSupersession, writeParallelHandoffGroup, writePendingParallelHandoff } from "../shared/parallel-handoff.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";
64
70
  import { summarizeContextModes } from "../shared/context-mode.js";
65
71
  import {
66
72
  attachNestedChildrenToResultChildren,
@@ -71,50 +77,60 @@ import {
71
77
  stripDetailsOutputsForIntercomReceipt
72
78
  } from "../../intercom/result-intercom.js";
73
79
  import { applySteeringRecoveryAgentConfig, asyncReviveRequiresRecoveryDescriptor, buildRevivedAsyncTask, readAsyncRecoveryDescriptor, resolveAsyncResumeTarget, resolveAsyncRunLocation } from "../background/async-resume.js";
74
- import { deliverInterruptRequest, readRevivalBriefs, requestAsyncSteer } from "../background/control-channel.js";
75
- import { updateSteeringTarget, waitForSteeringAction } from "../background/steering.js";
80
+ import { closeSteerInbox, consumeSteerRequests, deliverInterruptRequest, readRevivalBriefs, requestAsyncSteer, watchAsyncControlInbox } from "../background/control-channel.js";
81
+ import { createSteeringStatus, recordSteeringRequest, steeringStatus, updateSteeringTarget, waitForSteeringAction } from "../background/steering.js";
76
82
  import { canQueueRetainedAsyncFollowUp, steerAsyncRun } from "./async-steering-action.js";
77
83
  import {
78
- removeWorkflowForegroundSteeringRoute,
79
84
  resolveWorkflowForegroundSteeringTarget,
80
85
  steerWorkflowForegroundTarget,
81
- workflowForegroundSteeringDir,
82
- workflowForegroundSteeringLaunchOptions
86
+ steerWorkflowRun
83
87
  } from "./workflow-foreground-steering.js";
84
88
  import { stopAsyncRun } from "./async-stop-action.js";
85
89
  import { dismissRecoveredWorkflow } from "./async-dismiss-action.js";
86
90
  import { promotePausedWorkflowIfSettled, reconcileDetachedWorkflowChildCompletion } from "./workflow-detach-reconcile.js";
87
91
  import { reconcileAsyncRun } from "../background/stale-run-reconciler.js";
88
92
  import { resolveAsyncRootResultPath, waitForImportedAsyncRoot } from "../background/chain-root-attachment.js";
89
- import { resultFilePath, writeAsyncResultFile } from "../background/result-files.js";
90
- import { attachRootChildrenToSteps, createNestedRoute, findNestedControlResult, resolveInheritedNestedRouteFromEnv, resolveNestedAsyncDir, resolveNestedParentAddressFromEnv, snapshotNestedEventFiles, updateForegroundNestedProjection, writeNestedControlRequest, writeNestedEvent } from "../shared/nested-events.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";
91
95
  import { resolveSubagentRunId } from "../background/run-id-resolver.js";
92
96
  import { formatNestedRunStatusLines } from "../shared/nested-render.js";
93
- import { isStoppableAsyncStatusStep, resolveAsyncStatusChild } from "../shared/child-identity.js";
97
+ import { isStoppableAsyncStatusStep, resolveAsyncStatusChild, stopStoppableAsyncStatusChildren } from "../shared/child-identity.js";
94
98
  import { inspectSubagentStatus } from "../background/run-status.js";
95
99
  import { getExternalJobProvider } from "../../api/external-job-provider.js";
96
100
  import { externalJobFollowUpRequestDigest, externalJobFollowUpRequestId, externalJobFollowUpRunId, externalJobPromptDigest, externalJobStableJson } from "../shared/external-job-runner.js";
97
101
  import { externalCliReceiptMetadata, normalizeExternalCliRunnerStatus } from "../shared/external-cli-contract.js";
102
+ import { formatHerdrMachineRunnerUnsupported, resolveHerdrMachinePlacement } from "../shared/herdr-machine.js";
98
103
  import { applyForceTopLevelAsyncOverride } from "../background/top-level-async.js";
99
104
  import { handleMissionAction, MISSION_ACTIONS } from "../../missions/actions.js";
100
105
  import { attachMissionToLaunchResult, prepareMissionLaunch, writeMissionAsyncBinding } from "../../missions/lifecycle.js";
101
106
  import { MissionNotFoundError, updateMission } from "../../missions/store.js";
102
107
  import { createMissionWorkflowState } from "../../missions/workflow-state.js";
103
108
  import { resolveAuthorityDecision } from "../../policy/authority.js";
104
- import { handleHerdrInspectorAction, HERDR_INSPECTOR_ACTIONS } from "../../inspectors/herdr/actions.js";
109
+ import { handleInspectorAction, INSPECTOR_ACTIONS } from "../../inspectors/actions.js";
110
+ import { createBuiltinInspectorPlugins } from "../../inspectors/plugins.js";
105
111
  import { handleHerdrProjectPaneAction, HERDR_PROJECT_PANE_ACTIONS } from "../../inspectors/herdr/project-panes.js";
106
112
  import { previewSimpleWorkflowRun, runWorkflowScript, validateWorkflowScript, WorkflowScriptError } from "../../workflows/scripted-workflow.js";
113
+ import { formatIncrementalChildCompletion, incrementalChildCompletionTriggersTurn } from "../background/notify.js";
107
114
  import { executeWorkflowHostCommand, resolveWorkflowHostOutputClaimPath } from "../../workflows/host-command.js";
108
- import { buildWorkflowReceipt, resolveWorkflowReceiptResumeEntry, writeWorkflowReceipt } from "../../workflows/workflow-receipt.js";
115
+ import { buildWorkflowReceipt, readWorkflowReceipt, workflowReceiptPath, resolveWorkflowReceiptResumeEntry, writeWorkflowReceipt } from "../../workflows/workflow-receipt.js";
109
116
  import { upsertHostStep, validHostStepNodes } from "../shared/host-step-status.js";
110
117
  import { assertWorkflowLaneKey, normalizeWorkflowLaneMetadata } from "../shared/lane-metadata.js";
111
- import { parseWorkflowChildSummary, workflowChildSummary } from "../../workflows/workflow-child-summary.js";
118
+ import { parseWorkflowChildSummary, workflowChildProgress, workflowChildSummary } from "../../workflows/workflow-child-summary.js";
112
119
  import { resolveWorkflowChatProgress } from "../../workflows/chat-progress.js";
113
120
  import { annotateWorkflowPreflightTrace, formatWorkflowPreflight, formatWorkflowPreflightWarnings, normalizeWorkflowPreflight, workflowPreflightWarnings } from "../../workflows/workflow-preflight.js";
114
- import { claimWorkflowChildPermit, validateWorkflowChildPermitRoot } from "../../shared/workflow-child-permit.js";
121
+ import {
122
+ authorizeWorkflowResourceHost,
123
+ claimWorkflowChildPermit,
124
+ consumeWorkflowResourcePermit,
125
+ validateWorkflowChildPermitRoot
126
+ } from "../../shared/workflow-child-permit.js";
127
+ import { deepFreezeWorkflowArgs, normalizeWorkflowArgs, resolveWorkflowResource } from "../../workflows/workflow-resources.js";
128
+ import { stableJsonDigest } from "../../shared/launch-contract.js";
115
129
  import {
116
130
  cleanupWorktrees,
117
131
  createWorktrees,
132
+ preflightWorktreeSource,
133
+ withWorktreeTransaction,
118
134
  diffWorktrees,
119
135
  formatWorktreeDiffSummary
120
136
  } from "../shared/worktree.js";
@@ -124,9 +140,12 @@ import {
124
140
  DEFAULT_ARTIFACT_CONFIG,
125
141
  DEFAULT_FORK_PREAMBLE,
126
142
  SUBAGENT_ACTIONS,
143
+ SUBAGENT_ASYNC_STARTED_EVENT,
144
+ SUBAGENT_CHILD_STATUS_EVENT,
127
145
  SUBAGENT_CONTROL_EVENT,
128
146
  SUBAGENT_CONTROL_INTERCOM_EVENT,
129
147
  SUBAGENT_FOREGROUND_COMPLETE_EVENT,
148
+ SUBAGENT_LIFECYCLE_ARTIFACT_VERSION,
130
149
  checkSubagentDepth,
131
150
  resolveChildMaxSubagentDepth,
132
151
  resolveCurrentMaxSubagentDepth,
@@ -196,6 +215,15 @@ function rememberParentModel(state, sessionId, model) {
196
215
  state.lastParentModel = parentModel;
197
216
  return parentModel ?? state.lastParentModel;
198
217
  }
218
+ function inheritedNestedRoute(deps) {
219
+ return inheritedNestedRouteOf(deps.childRuntime);
220
+ }
221
+ function inheritedNestedParentAddress(deps) {
222
+ return inheritedNestedParentAddressOf(deps.childRuntime);
223
+ }
224
+ function inheritedRunFanoutBudget(deps) {
225
+ return deps.childRuntime?.runFanoutBudget;
226
+ }
199
227
  function resolveRequestedCwd(runtimeCwd, requestedCwd) {
200
228
  return requestedCwd ? path.resolve(runtimeCwd, requestedCwd) : runtimeCwd;
201
229
  }
@@ -214,12 +242,19 @@ function loadWorkflowScriptPath(params, runtimeCwd) {
214
242
  const { workflowScriptPath: _workflowScriptPath, ...rest } = params;
215
243
  return { params: { ...rest, workflowScript } };
216
244
  }
217
- function removeForegroundControlIfIdle(state, runId) {
245
+ export function removeForegroundControlIfIdle(state, runId, trackRetainedNestedRoute) {
218
246
  const control = state.foregroundControls.get(runId);
219
247
  if (control && (!foregroundSchedulingSettled(control) || (control.activeChildren?.size ?? 0) > 0))
220
248
  return false;
221
- if (control)
222
- removeWorkflowForegroundSteeringRoute(control);
249
+ if (control?.nestedRoute && trackRetainedNestedRoute) {
250
+ try {
251
+ if (retainLiveForegroundNestedRoute(state, control.nestedRoute))
252
+ trackRetainedNestedRoute(runId);
253
+ } catch (error) {
254
+ console.error(`Failed to retain live nested descendants for foreground run '${runId}':`, error);
255
+ }
256
+ }
257
+ retainNestedLookupRoute(state, control?.nestedRoute, control?.sessionId);
223
258
  state.foregroundControls.delete(runId);
224
259
  if (state.lastForegroundControlId === runId)
225
260
  state.lastForegroundControlId = null;
@@ -285,8 +320,8 @@ function formatForegroundActivity(control) {
285
320
  function nestedResolutionScopeForExecutor(deps) {
286
321
  if (deps.allowMutatingManagementActions !== false)
287
322
  return;
288
- const route = resolveInheritedNestedRouteFromEnv();
289
- const address = route ? resolveNestedParentAddressFromEnv() : undefined;
323
+ const route = inheritedNestedRoute(deps);
324
+ const address = route ? inheritedNestedParentAddress(deps) : undefined;
290
325
  return {
291
326
  routes: route ? [route] : [],
292
327
  ...address ? { descendantOf: { parentRunId: address.parentRunId, ...address.parentStepIndex !== undefined ? { parentStepIndex: address.parentStepIndex } : {} } } : {}
@@ -428,6 +463,7 @@ function rememberForegroundRun(state, input) {
428
463
  updatedAt,
429
464
  children: input.results.map((result, index) => {
430
465
  const resumeContract = omitUndefinedProperties({
466
+ modelResponseAliases: input.modelResponseAliases,
431
467
  outputSchema: input.params.outputSchema,
432
468
  agentContract: input.params.agentContract,
433
469
  acceptance: input.params.acceptance,
@@ -468,6 +504,7 @@ function rememberForegroundRun(state, input) {
468
504
  ...Object.keys(resumeContract).length ? { resumeContract } : {},
469
505
  ...result.launchContractDigest ? { launchContractDigest: result.launchContractDigest } : {},
470
506
  ...input.extensionBindings ? { extensionBindings: input.extensionBindings } : {},
507
+ ...input.requiredExtensions?.length ? { requiredExtensions: input.requiredExtensions } : {},
471
508
  ...result.launchResolvedExtensions ? { launchResolvedExtensions: result.launchResolvedExtensions } : {},
472
509
  ...result.runtimeAcknowledgedExtensions ? { runtimeAcknowledgedExtensions: result.runtimeAcknowledgedExtensions } : {},
473
510
  ...result.capabilityCeiling ? { capabilityCeiling: result.capabilityCeiling } : {},
@@ -627,6 +664,7 @@ function resolveForegroundResumeTarget(params, state, options = {}) {
627
664
  ...child.launchContractDigest ? { launchContractDigest: child.launchContractDigest } : {},
628
665
  ...child.resumeContract ? { resumeContract: child.resumeContract } : {},
629
666
  ...child.extensionBindings ? { extensionBindings: normalizeExtensionBindings(child.extensionBindings).value } : {},
667
+ ...child.requiredExtensions ? { requiredExtensions: child.requiredExtensions } : {},
630
668
  ...child.capabilityCeiling ? { capabilityCeiling: child.capabilityCeiling } : {}
631
669
  };
632
670
  }
@@ -868,10 +906,15 @@ function appendStepToAsyncChain(input) {
868
906
  };
869
907
  }
870
908
  const chain = [input.params.step];
871
- const acceptanceErrors = validateExecutionAcceptance({ ...input.params, chain });
872
- if (acceptanceErrors.length > 0) {
909
+ const validationParams = { ...input.params, chain };
910
+ const acceptancePolicyErrors = validateExecutionAcceptancePolicy(validationParams);
911
+ const outputSchemaError = validateLaunchOutputSchemaOverrides(validationParams);
912
+ const earlyErrors = [...acceptancePolicyErrors];
913
+ if (outputSchemaError)
914
+ earlyErrors.push(outputSchemaError);
915
+ if (earlyErrors.length > 0) {
873
916
  return {
874
- content: [{ type: "text", text: `Cannot append step: ${acceptanceErrors.join(" ")}` }],
917
+ content: [{ type: "text", text: `Cannot append step: ${earlyErrors.join(" ")}` }],
875
918
  isError: true,
876
919
  details: { mode: "management", results: [] }
877
920
  };
@@ -950,6 +993,14 @@ function appendStepToAsyncChain(input) {
950
993
  const scope = resolveExecutionAgentScope(input.params.agentScope);
951
994
  const discoveredForAppend = input.deps.discoverAgents(input.requestCwd, scope, input.parentModel?.provider);
952
995
  const agents = discoveredForAppend.agents;
996
+ const acceptanceErrors = validateExecutionAcceptance(projectEffectiveAcceptanceSchemas(validationParams, agents));
997
+ if (acceptanceErrors.length > 0) {
998
+ return {
999
+ content: [{ type: "text", text: `Cannot append step: ${acceptanceErrors.join(" ")}` }],
1000
+ isError: true,
1001
+ details: { mode: "management", results: [] }
1002
+ };
1003
+ }
953
1004
  const contextPolicy = resolveExplicitContextPolicy(input.params);
954
1005
  const chainSkillInput = normalizeSkillInput(input.params.skill);
955
1006
  const chainSkills = chainSkillInput === false ? [] : chainSkillInput ?? [];
@@ -962,8 +1013,10 @@ function appendStepToAsyncChain(input) {
962
1013
  currentModelProvider: parentModel?.provider,
963
1014
  currentModel: parentModel,
964
1015
  modelScope: discoveredForAppend.modelScope,
1016
+ modelResponseAliases: input.deps.config.modelResponseAliases,
965
1017
  interactive: input.ctx.hasUI,
966
- permissions: input.deps.config.permissions
1018
+ permissions: input.deps.config.permissions,
1019
+ childRuntime: input.deps.childRuntime
967
1020
  });
968
1021
  const built = buildAsyncRunnerSteps(resolved.id, compactOptional({
969
1022
  chain: wrapChainTasksForFork(chain, contextPolicy),
@@ -976,10 +1029,13 @@ function appendStepToAsyncChain(input) {
976
1029
  cwd: status.cwd ?? input.requestCwd,
977
1030
  chainSkills,
978
1031
  dynamicFanoutMaxItems: input.deps.config.chain?.dynamicFanout?.maxItems,
979
- maxSubagentDepth: resolveCurrentMaxSubagentDepth(input.deps.config.maxSubagentDepth),
1032
+ maxSubagentDepth: resolveCurrentMaxSubagentDepth(input.deps.config.maxSubagentDepth, input.deps.childRuntime),
980
1033
  waitToolEnabled: input.deps.waitToolEnabled,
981
1034
  waitToolDefaultTimeoutMs: input.deps.waitToolDefaultTimeoutMs,
982
1035
  contextForAgent: contextPolicy.contextForAgent,
1036
+ worktreeBaseDir: input.deps.config.worktreeBaseDir,
1037
+ worktreeProvider: input.deps.config.worktreeProvider,
1038
+ worktreeBranchPrefix: input.deps.config.worktreeBranchPrefix,
983
1039
  asyncDir: resolved.location.asyncDir,
984
1040
  validateOutputBindings: false,
985
1041
  capabilityCeiling: intersectSubagentCapabilityCeilings(status.capabilityCeiling, resolveCurrentSubagentCapabilityCeiling(asyncCtx.currentSessionId))
@@ -1118,6 +1174,49 @@ function resolveNestedResumeTarget(match, trustedSessionRoots) {
1118
1174
  ...recoveryDescriptor ? { recoveryDescriptor } : {}
1119
1175
  });
1120
1176
  }
1177
+ function resolveNestedExternalJobResumeTarget(match, params, deps) {
1178
+ const run = match.match.run;
1179
+ if (run.state === "stopped")
1180
+ return;
1181
+ const asyncDir = resolveNestedAsyncDir(match.match.rootRunId, run);
1182
+ if (!asyncDir)
1183
+ return;
1184
+ const status = readNestedRunStatus(asyncDir, run);
1185
+ const steps = status?.steps ?? [];
1186
+ const step = steps[params.index ?? 0];
1187
+ if (!step) {
1188
+ if (params.index === undefined || !steps.some((candidate) => candidate.runner?.type === "external-job"))
1189
+ return;
1190
+ } else if (!step.runner) {
1191
+ if (nestedRunSessionFile(run))
1192
+ return;
1193
+ const agent = deps.discoverAgents(status?.cwd ?? deps.state.baseCwd, resolveExecutionAgentScope(params.agentScope)).agents.find((candidate) => candidate.name === step.agent);
1194
+ if (agent?.runner?.type === "external-job")
1195
+ throw new Error(externalJobWithoutMetadataMessage(run.id));
1196
+ return;
1197
+ } else if (step.runner.type !== "external-job") {
1198
+ return;
1199
+ }
1200
+ const target = resolveAsyncResumeTarget(compactOptional({ dir: asyncDir, index: params.index }), nestedRunScope(match.match.rootRunId), { requireSessionFile: false });
1201
+ if (target.kind === "live")
1202
+ throw new Error(externalJobStillRunningMessage(target.runId));
1203
+ return { source: "async", ...target };
1204
+ }
1205
+ function readNestedRunStatus(asyncDir, run) {
1206
+ try {
1207
+ return readStatus(asyncDir);
1208
+ } catch (error) {
1209
+ if (nestedRunSessionFile(run))
1210
+ return null;
1211
+ throw error;
1212
+ }
1213
+ }
1214
+ function externalJobStillRunningMessage(runId) {
1215
+ return `External-job run '${runId}' is still running. Wait for completion, then use subagent({ action: "resume", id: "${runId}", message: "..." }).`;
1216
+ }
1217
+ function externalJobWithoutMetadataMessage(runId) {
1218
+ return `External-job run '${runId}' has no persisted provider metadata. Cannot follow up without the parent provider job id.`;
1219
+ }
1121
1220
  async function waitForNestedControlResult(target, requestId, ignoredFiles, timeoutMs = 1000) {
1122
1221
  const deadline = Date.now() + timeoutMs;
1123
1222
  while (Date.now() < deadline) {
@@ -1268,14 +1367,14 @@ function externalRunnerControlError(asyncDir, action) {
1268
1367
  }
1269
1368
  async function resumeExternalJobFollowUp(input) {
1270
1369
  if (input.target.kind === "live" || input.target.state === "running" || input.target.state === "queued") {
1271
- return { content: [{ type: "text", text: `External-job run '${input.target.runId}' is still running. Wait for completion, then use subagent({ action: "resume", id: "${input.target.runId}", message: "..." }).` }], isError: true, details: { mode: "management", results: [] } };
1370
+ return { content: [{ type: "text", text: externalJobStillRunningMessage(input.target.runId) }], isError: true, details: { mode: "management", results: [] } };
1272
1371
  }
1273
1372
  const runner = input.target.runner;
1274
1373
  const externalJob = input.target.externalJob;
1275
1374
  if (runner?.type !== "external-job")
1276
1375
  return { content: [{ type: "text", text: "Internal error: external-job follow-up was requested for a non-external-job runner." }], isError: true, details: { mode: "management", results: [] } };
1277
1376
  if (!externalJob)
1278
- return { content: [{ type: "text", text: `External-job run '${input.target.runId}' has no persisted provider metadata. Cannot follow up without the parent provider job id.` }], isError: true, details: { mode: "management", results: [] } };
1377
+ return { content: [{ type: "text", text: externalJobWithoutMetadataMessage(input.target.runId) }], isError: true, details: { mode: "management", results: [] } };
1279
1378
  if (externalJob.provider !== runner.provider)
1280
1379
  return { content: [{ type: "text", text: `External-job run '${input.target.runId}' has mismatched provider metadata. Refusing to follow up.` }], isError: true, details: { mode: "management", results: [] } };
1281
1380
  if (!externalJobOptionsEqual(externalJob.options, runner.options))
@@ -1291,18 +1390,20 @@ async function resumeExternalJobFollowUp(input) {
1291
1390
  const requestDigest = externalJobFollowUpRequestDigest({ provider: runner.provider, parentProviderJobId: externalJob.providerJobId, promptDigest, options: runner.options });
1292
1391
  const requestId = externalJobFollowUpRequestId(requestDigest);
1293
1392
  const runId = externalJobFollowUpRunId(requestDigest);
1294
- const asyncDir = path.join(DIRS.async, runId);
1393
+ const nestedRoute = inheritedNestedRoute(input.deps);
1394
+ const runRoots = nestedRoute ? nestedRunScope(nestedRoute.rootRunId) : { asyncDirRoot: DIRS.async, resultsDir: DIRS.results };
1395
+ const asyncDir = path.join(runRoots.asyncDirRoot, runId);
1295
1396
  const currentSessionId = input.deps.state.currentSessionId;
1296
1397
  if (!currentSessionId)
1297
1398
  return { content: [{ type: "text", text: "External-job follow-up requires an active parent session." }], isError: true, details: { mode: "management", results: [] } };
1298
- if (fs.existsSync(asyncDir) || fs.existsSync(resultFilePath(DIRS.results, runId))) {
1399
+ if (fs.existsSync(asyncDir) || fs.existsSync(resultFilePath(runRoots.resultsDir, runId))) {
1299
1400
  return externalJobFollowUpStarted({ sourceRunId: input.target.runId, runId, asyncDir, duplicate: true, interactive: input.ctx.hasUI });
1300
1401
  }
1301
- const depthState = checkSubagentDepth(input.deps.config.maxSubagentDepth);
1402
+ const depthState = checkSubagentDepth(input.deps.config.maxSubagentDepth, input.deps.childRuntime);
1302
1403
  if (depthState.blocked) {
1303
1404
  return { content: [{ type: "text", text: `Nested subagent resume blocked (depth=${depthState.depth}, max=${depthState.maxDepth}). Complete the follow-up directly instead.` }], isError: true, details: { mode: "management", results: [] } };
1304
1405
  }
1305
- const topLevelResume = depthState.depth === 0 && !resolveInheritedNestedRouteFromEnv() && !input.deps.state.workflowControllers?.has(input.target.runId);
1406
+ const topLevelResume = depthState.depth === 0 && !inheritedNestedRoute(input.deps) && !input.deps.state.workflowControllers?.has(input.target.runId);
1306
1407
  let activeAsyncCapacity;
1307
1408
  try {
1308
1409
  activeAsyncCapacity = topLevelResume ? acquireActiveAsyncCapacity({
@@ -1324,7 +1425,7 @@ async function resumeExternalJobFollowUp(input) {
1324
1425
  ...input.baseAgentConfig,
1325
1426
  runner: { type: "external-job", provider: runner.provider, options: runner.options }
1326
1427
  };
1327
- const result = executeAsyncSingle(runId, compactOptional({
1428
+ const result = await executeAsyncSingle(runId, compactOptional({
1328
1429
  agent: input.target.agent,
1329
1430
  task: input.followUp,
1330
1431
  goal: input.followUp,
@@ -1338,20 +1439,24 @@ async function resumeExternalJobFollowUp(input) {
1338
1439
  currentModelProvider: parentModel?.provider,
1339
1440
  currentModel: parentModel,
1340
1441
  modelScope: input.modelScope,
1442
+ modelResponseAliases: input.deps.config.modelResponseAliases,
1341
1443
  interactive: input.ctx.hasUI,
1342
- permissions: input.deps.config.permissions
1444
+ permissions: input.deps.config.permissions,
1445
+ childRuntime: input.deps.childRuntime
1343
1446
  }),
1344
1447
  cwd: input.effectiveCwd,
1345
1448
  artifactsDir,
1346
1449
  artifactConfig,
1347
1450
  shareEnabled: false,
1348
1451
  ...input.parentSessionFile ? { sessionRoot: input.deps.getSubagentSessionRoot(input.parentSessionFile) } : {},
1349
- maxSubagentDepth: resolveCurrentMaxSubagentDepth(input.deps.config.maxSubagentDepth),
1452
+ maxSubagentDepth: resolveCurrentMaxSubagentDepth(input.deps.config.maxSubagentDepth, input.deps.childRuntime),
1350
1453
  waitToolEnabled: input.deps.waitToolEnabled,
1351
1454
  waitToolDefaultTimeoutMs: input.deps.waitToolDefaultTimeoutMs,
1352
1455
  worktreeSetupHook: input.deps.config.worktreeSetupHook,
1353
1456
  worktreeSetupHookTimeoutMs: input.deps.config.worktreeSetupHookTimeoutMs,
1354
1457
  worktreeBaseDir: input.deps.config.worktreeBaseDir,
1458
+ worktreeProvider: input.deps.config.worktreeProvider,
1459
+ worktreeBranchPrefix: input.deps.config.worktreeBranchPrefix,
1355
1460
  controlConfig: resolveControlConfig(input.deps.config.control, undefined),
1356
1461
  controlIntercomTarget: input.intercomBridge.active ? input.intercomBridge.orchestratorTarget : undefined,
1357
1462
  childIntercomTarget: input.intercomBridge.active ? (agent, index) => resolveSubagentIntercomTarget(runId, agent, index) : undefined,
@@ -1369,6 +1474,33 @@ async function resumeExternalJobFollowUp(input) {
1369
1474
  }
1370
1475
  return externalJobFollowUpStarted({ sourceRunId: input.target.runId, runId: result.details.asyncId ?? runId, asyncDir: result.details.asyncDir ?? asyncDir, interactive: input.ctx.hasUI });
1371
1476
  }
1477
+ function resolveRequestedResumeTarget(params, deps, parentSessionFile) {
1478
+ const requestedId = params.id ?? params.runId;
1479
+ let resolved;
1480
+ try {
1481
+ resolved = requestedId ? resolveSubagentRunId(requestedId, omitUndefinedProperties({ state: deps.state, nested: nestedResolutionScopeForExecutor(deps) })) : undefined;
1482
+ } catch (error) {
1483
+ const message = error instanceof Error ? error.message : "";
1484
+ const asyncMatches = message.match(/async:/g)?.length ?? 0;
1485
+ if (!isResumeAmbiguity(error) || !message.includes("foreground:") || asyncMatches !== 1)
1486
+ throw error;
1487
+ }
1488
+ if (resolved?.kind === "nested") {
1489
+ if (params.chain?.length)
1490
+ throw new Error("Attaching a running subagent as a chain root is currently available for top-level async runs only.");
1491
+ if (resolved.match.run.state === "running" || resolved.match.run.state === "queued")
1492
+ return { kind: "live-nested", target: resolved };
1493
+ const externalJobTarget = resolveNestedExternalJobResumeTarget(resolved, params, deps);
1494
+ if (externalJobTarget)
1495
+ return externalJobTarget;
1496
+ const trustedSessionRoots = [
1497
+ ...deps.config.defaultSessionDir ? [path.resolve(deps.expandTilde(deps.config.defaultSessionDir))] : [],
1498
+ ...parentSessionFile ? [deps.getSubagentSessionRoot(parentSessionFile)] : []
1499
+ ];
1500
+ return resolveNestedResumeTarget(resolved, trustedSessionRoots);
1501
+ }
1502
+ return resolveResumeTarget(params, deps.state, { asyncRequireSessionFile: false });
1503
+ }
1372
1504
  async function resumeAsyncRun(input) {
1373
1505
  const followUp = (input.params.message ?? input.params.task ?? "").trim();
1374
1506
  const attachChain = (input.params.chain?.length ?? 0) > 0 ? input.params.chain : undefined;
@@ -1386,47 +1518,22 @@ async function resumeAsyncRun(input) {
1386
1518
  details: { mode: "management", results: [] }
1387
1519
  };
1388
1520
  }
1389
- const acceptanceErrors = validateExecutionAcceptance(input.params);
1390
- if (acceptanceErrors.length > 0) {
1391
- return {
1392
- content: [{ type: "text", text: `Cannot resume: ${acceptanceErrors.join(" ")}` }],
1393
- isError: true,
1394
- details: { mode: "management", results: [] }
1395
- };
1521
+ const acceptancePolicyErrors = validateExecutionAcceptancePolicy(input.params);
1522
+ if (acceptancePolicyErrors.length > 0) {
1523
+ return { content: [{ type: "text", text: `Cannot resume: ${acceptancePolicyErrors.join(" ")}` }], isError: true, details: { mode: "management", results: [] } };
1524
+ }
1525
+ const outputSchemaError = validateLaunchOutputSchemaOverrides(input.params);
1526
+ if (outputSchemaError) {
1527
+ return { content: [{ type: "text", text: `Cannot resume: ${outputSchemaError}` }], isError: true, details: { mode: "management", results: [] } };
1396
1528
  }
1397
1529
  input.deps.state.currentSessionId = resolveCurrentSessionId(input.ctx.sessionManager);
1398
1530
  let target;
1399
1531
  const parentSessionFile = input.ctx.sessionManager.getSessionFile() ?? null;
1400
1532
  try {
1401
- const requestedId = input.params.id ?? input.params.runId;
1402
- let resolved;
1403
- try {
1404
- resolved = requestedId ? resolveSubagentRunId(requestedId, omitUndefinedProperties({ state: input.deps.state, nested: nestedResolutionScopeForExecutor(input.deps) })) : undefined;
1405
- } catch (error) {
1406
- const message = error instanceof Error ? error.message : "";
1407
- const asyncMatches = message.match(/async:/g)?.length ?? 0;
1408
- if (!isResumeAmbiguity(error) || !message.includes("foreground:") || asyncMatches !== 1)
1409
- throw error;
1410
- }
1411
- if (resolved?.kind === "nested") {
1412
- if (attachChain) {
1413
- return {
1414
- content: [{ type: "text", text: "Attaching a running subagent as a chain root is currently available for top-level async runs only." }],
1415
- isError: true,
1416
- details: { mode: "management", results: [] }
1417
- };
1418
- }
1419
- if (resolved.match.run.state === "running" || resolved.match.run.state === "queued") {
1420
- return resumeLiveNestedRun({ target: resolved, message: followUp });
1421
- }
1422
- const trustedSessionRoots = [
1423
- ...input.deps.config.defaultSessionDir ? [path.resolve(input.deps.expandTilde(input.deps.config.defaultSessionDir))] : [],
1424
- ...parentSessionFile ? [input.deps.getSubagentSessionRoot(parentSessionFile)] : []
1425
- ];
1426
- target = resolveNestedResumeTarget(resolved, trustedSessionRoots);
1427
- } else {
1428
- target = resolveResumeTarget(input.params, input.deps.state, { asyncRequireSessionFile: false });
1429
- }
1533
+ const resolved = resolveRequestedResumeTarget(input.params, input.deps, parentSessionFile);
1534
+ if (resolved.kind === "live-nested")
1535
+ return resumeLiveNestedRun({ target: resolved.target, message: followUp });
1536
+ target = resolved;
1430
1537
  } catch (error) {
1431
1538
  const message = error instanceof Error ? error.message : String(error);
1432
1539
  return { content: [{ type: "text", text: message }], isError: true, details: { mode: "management", results: [] } };
@@ -1445,7 +1552,7 @@ async function resumeAsyncRun(input) {
1445
1552
  details: { mode: "management", results: [] }
1446
1553
  };
1447
1554
  }
1448
- const { blocked, depth, maxDepth } = checkSubagentDepth(input.deps.config.maxSubagentDepth);
1555
+ const { blocked, depth, maxDepth } = checkSubagentDepth(input.deps.config.maxSubagentDepth, input.deps.childRuntime);
1449
1556
  if (blocked) {
1450
1557
  return {
1451
1558
  content: [{ type: "text", text: `Nested subagent resume blocked (depth=${depth}, max=${maxDepth}). Complete the follow-up directly instead.` }],
@@ -1460,7 +1567,7 @@ async function resumeAsyncRun(input) {
1460
1567
  const discoveredAgents = discovered.agents;
1461
1568
  const unknownAgentDiagnosticContext = diagnosticContextFromDiscovery(discovered, effectiveCwd, scope);
1462
1569
  const modelScope = discovered.modelScope;
1463
- const sessionName = resolveIntercomSessionTarget(input.deps.dm.getSessionName(), input.ctx.sessionManager.getSessionId());
1570
+ const sessionName = resolveIntercomSessionTarget(input.deps.childRuntime?.intercomSessionName ?? input.deps.dm.getSessionName(), input.ctx.sessionManager.getSessionId());
1464
1571
  const recoveryDescriptor = "recoveryDescriptor" in target ? target.recoveryDescriptor : undefined;
1465
1572
  const recoveryContext = recoveryDescriptor?.context ?? (input.params.context === "profile" ? undefined : input.params.context);
1466
1573
  const intercomBridge = resolveIntercomBridge({
@@ -1498,7 +1605,7 @@ async function resumeAsyncRun(input) {
1498
1605
  if (target.source === "async" && target.runner?.type === "external-job") {
1499
1606
  if (attachChain)
1500
1607
  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: [] } };
1501
- return resumeExternalJobFollowUp({
1608
+ const resumed = await resumeExternalJobFollowUp({
1502
1609
  target,
1503
1610
  followUp,
1504
1611
  baseAgentConfig,
@@ -1512,6 +1619,10 @@ async function resumeAsyncRun(input) {
1512
1619
  parentSessionFile,
1513
1620
  absoluteDeadlineAt: input.absoluteDeadlineAt
1514
1621
  });
1622
+ const resumedRunId = resumed.details.runId ?? resumed.details.asyncId;
1623
+ if (!resumed.isError && resumedRunId)
1624
+ input.onLaunch?.({ agent: target.agent, async: true, runId: resumedRunId });
1625
+ return resumed;
1515
1626
  }
1516
1627
  if (attachChain) {
1517
1628
  if (target.source !== "async") {
@@ -1528,8 +1639,12 @@ async function resumeAsyncRun(input) {
1528
1639
  details: { mode: "chain", results: [] }
1529
1640
  };
1530
1641
  }
1642
+ const acceptanceErrors = validateExecutionAcceptance(projectEffectiveAcceptanceSchemas(input.params, agents));
1643
+ if (acceptanceErrors.length > 0) {
1644
+ return { content: [{ type: "text", text: `Cannot resume: ${acceptanceErrors.join(" ")}` }], isError: true, details: { mode: "chain", results: [] } };
1645
+ }
1531
1646
  const runId = randomUUID();
1532
- const topLevelResume = depth === 0 && !resolveInheritedNestedRouteFromEnv() && !input.params.workflowParentRunId;
1647
+ const topLevelResume = depth === 0 && !inheritedNestedRoute(input.deps) && !input.params.workflowParentRunId;
1533
1648
  let activeAsyncCapacity;
1534
1649
  try {
1535
1650
  activeAsyncCapacity = topLevelResume ? acquireActiveAsyncCapacity({
@@ -1574,8 +1689,10 @@ async function resumeAsyncRun(input) {
1574
1689
  currentModelProvider: parentModel?.provider,
1575
1690
  currentModel: parentModel,
1576
1691
  modelScope,
1692
+ modelResponseAliases: input.deps.config.modelResponseAliases,
1577
1693
  interactive: input.ctx.hasUI,
1578
- permissions: input.deps.config.permissions
1694
+ permissions: input.deps.config.permissions,
1695
+ childRuntime: input.deps.childRuntime
1579
1696
  }),
1580
1697
  availableModels,
1581
1698
  cwd: effectiveCwd,
@@ -1588,12 +1705,16 @@ async function resumeAsyncRun(input) {
1588
1705
  agentContract: input.params.agentContract,
1589
1706
  fast: input.params.fast,
1590
1707
  dynamicFanoutMaxItems: input.deps.config.chain?.dynamicFanout?.maxItems,
1591
- maxSubagentDepth: resolveCurrentMaxSubagentDepth(input.deps.config.maxSubagentDepth),
1708
+ maxSubagentDepth: resolveCurrentMaxSubagentDepth(input.deps.config.maxSubagentDepth, input.deps.childRuntime),
1592
1709
  waitToolEnabled: input.deps.waitToolEnabled,
1593
1710
  waitToolDefaultTimeoutMs: input.deps.waitToolDefaultTimeoutMs,
1594
1711
  worktreeSetupHook: input.deps.config.worktreeSetupHook,
1595
1712
  worktreeSetupHookTimeoutMs: input.deps.config.worktreeSetupHookTimeoutMs,
1596
1713
  worktreeBaseDir: input.deps.config.worktreeBaseDir,
1714
+ baseRef: input.params.baseRef ?? target.recoveryDescriptor?.baseRef,
1715
+ ...recoveryDescriptor?.requiredExtensions ? { requiredExtensions: recoveryDescriptor.requiredExtensions } : {},
1716
+ worktreeProvider: input.deps.config.worktreeProvider,
1717
+ worktreeBranchPrefix: input.deps.config.worktreeBranchPrefix,
1597
1718
  controlConfig: resolveControlConfig(input.deps.config.control, input.params.control),
1598
1719
  controlIntercomTarget: intercomBridge.active ? intercomBridge.orchestratorTarget : undefined,
1599
1720
  childIntercomTarget: intercomBridge.active ? (agent, index) => resolveSubagentIntercomTarget(runId, agent, index) : undefined,
@@ -1608,6 +1729,7 @@ async function resumeAsyncRun(input) {
1608
1729
  return result;
1609
1730
  }
1610
1731
  const attachedId = result.details.asyncId ?? runId;
1732
+ input.onLaunch?.({ agent: target.agent, ...target.sessionFile ? { sessionFile: target.sessionFile } : {}, async: true, runId: attachedId });
1611
1733
  const lines = [
1612
1734
  `Attached async subagent ${target.runId} as the first step of a new chain.`,
1613
1735
  `Chain run: ${attachedId}`,
@@ -1627,11 +1749,26 @@ async function resumeAsyncRun(input) {
1627
1749
  if (!revivalSessionFile) {
1628
1750
  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: [] } };
1629
1751
  }
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
+ }
1630
1755
  if (target.source === "async" && asyncReviveRequiresRecoveryDescriptor(target)) {
1631
1756
  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: [] } };
1632
1757
  }
1758
+ if (target.source === "nested" && !target.recoveryDescriptor) {
1759
+ 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
+ }
1761
+ const recoveryAgentConfig = recoveryDescriptor ? applySteeringRecoveryAgentConfig(baseAgentConfig, recoveryDescriptor) : baseAgentConfig;
1762
+ const agentConfig = intercomBridge.active ? applyIntercomBridgeToAgent(recoveryAgentConfig, intercomBridge) : recoveryAgentConfig;
1763
+ const foregroundContract = target.source === "foreground" ? target.resumeContract : undefined;
1764
+ const outputSchema = Object.hasOwn(input.params, "outputSchema") ? input.params.outputSchema : Object.hasOwn(foregroundContract ?? {}, "outputSchema") ? foregroundContract?.outputSchema : recoveryDescriptor?.structuredOutputSchema;
1765
+ const acceptance = input.params.acceptance !== undefined ? input.params.acceptance : foregroundContract?.acceptance !== undefined ? foregroundContract.acceptance : recoveryDescriptor?.acceptance;
1766
+ const acceptanceErrors = validateExecutionAcceptance({ ...input.params, acceptance, outputSchema });
1767
+ if (acceptanceErrors.length > 0) {
1768
+ return { content: [{ type: "text", text: `Cannot resume: ${acceptanceErrors.join(" ")}` }], isError: true, details: { mode: "management", results: [] } };
1769
+ }
1633
1770
  const runId = randomUUID();
1634
- const topLevelResume = depth === 0 && !resolveInheritedNestedRouteFromEnv() && !input.params.workflowParentRunId;
1771
+ const topLevelResume = depth === 0 && !inheritedNestedRoute(input.deps) && !input.params.workflowParentRunId;
1635
1772
  let activeAsyncCapacity;
1636
1773
  try {
1637
1774
  activeAsyncCapacity = !topLevelResume ? undefined : target.source === "async" ? transferActiveAsyncCapacity({
@@ -1652,17 +1789,13 @@ async function resumeAsyncRun(input) {
1652
1789
  return { content: [{ type: "text", text: error.message }], isError: true, details: { mode: "single", results: [], activeAsyncCapacity: error.snapshot } };
1653
1790
  return { content: [{ type: "text", text: error instanceof Error ? error.message : String(error) }], isError: true, details: { mode: "single", results: [] } };
1654
1791
  }
1655
- const recoveryAgentConfig = recoveryDescriptor ? applySteeringRecoveryAgentConfig(baseAgentConfig, recoveryDescriptor) : baseAgentConfig;
1656
- const agentConfig = intercomBridge.active ? applyIntercomBridgeToAgent(recoveryAgentConfig, intercomBridge) : recoveryAgentConfig;
1657
- const foregroundContract = target.source === "foreground" ? target.resumeContract : undefined;
1658
- const outputSchema = input.params.outputSchema ?? foregroundContract?.outputSchema ?? recoveryDescriptor?.structuredOutputSchema;
1659
1792
  const agentContract = input.params.agentContract ?? foregroundContract?.agentContract ?? recoveryDescriptor?.agentContract;
1660
1793
  const artifactConfig = recoveryDescriptor?.artifactConfig ?? omitUndefinedProperties({ ...DEFAULT_ARTIFACT_CONFIG, enabled: input.params.artifacts !== false, dir: input.deps.config.artifactDir ?? DEFAULT_ARTIFACT_CONFIG.dir });
1661
1794
  const artifactsDir = recoveryDescriptor?.artifactsDir ?? getArtifactsDir(parentSessionFile, effectiveCwd, artifactConfig.dir);
1662
1795
  const availableModels = input.ctx.modelRegistry.getAvailable().map(toModelInfo);
1663
1796
  const parentModel = input.parentModel;
1664
1797
  const revivalAsyncDir = path.join(DIRS.async, runId);
1665
- const result = executeAsyncSingle(runId, compactOptional({
1798
+ const result = await executeAsyncSingle(runId, compactOptional({
1666
1799
  agent: target.agent,
1667
1800
  task: buildRevivedAsyncTask(target, effectiveFollowUp),
1668
1801
  goal: effectiveFollowUp,
@@ -1676,8 +1809,10 @@ async function resumeAsyncRun(input) {
1676
1809
  currentModelProvider: parentModel?.provider,
1677
1810
  currentModel: parentModel,
1678
1811
  modelScope,
1812
+ modelResponseAliases: recoveryDescriptor ? recoveryDescriptor.modelResponseAliases : foregroundContract?.modelResponseAliases,
1679
1813
  interactive: input.ctx.hasUI,
1680
- permissions: input.deps.config.permissions
1814
+ permissions: input.deps.config.permissions,
1815
+ childRuntime: input.deps.childRuntime
1681
1816
  }),
1682
1817
  cwd: effectiveCwd,
1683
1818
  maxOutput: input.params.maxOutput ?? recoveryDescriptor?.maxOutput,
@@ -1697,41 +1832,49 @@ async function resumeAsyncRun(input) {
1697
1832
  modelOverride: recoveryDescriptor?.model ?? target.model,
1698
1833
  fast: recoveryDescriptor?.fast,
1699
1834
  modelOverrideFromParent: recoveryDescriptor?.modelOverrideFromParent,
1835
+ modelOrigin: recoveryDescriptor?.modelOrigin ?? (recoveryDescriptor?.modelOverrideFromParent ? "inherited" : undefined),
1700
1836
  thinkingOverride: recoveryDescriptor?.thinking ?? target.thinking,
1701
1837
  thinkingCeiling: recoveryDescriptor?.thinkingCeiling ?? ("thinkingCeiling" in target ? target.thinkingCeiling : undefined),
1702
1838
  extensionBindings: recoveryDescriptor?.extensionBindings ?? ("extensionBindings" in target ? target.extensionBindings : undefined),
1839
+ requiredExtensions: recoveryDescriptor?.requiredExtensions ?? target.requiredExtensions,
1703
1840
  outputBaseDir: resolveSingleRunOutputBaseDir(input.deps, artifactsDir, runId),
1704
- maxSubagentDepth: recoveryDescriptor?.maxSubagentDepth ?? resolveCurrentMaxSubagentDepth(input.deps.config.maxSubagentDepth),
1841
+ maxSubagentDepth: recoveryDescriptor?.maxSubagentDepth ?? resolveCurrentMaxSubagentDepth(input.deps.config.maxSubagentDepth, input.deps.childRuntime),
1705
1842
  waitToolEnabled: input.deps.waitToolEnabled,
1706
1843
  waitToolDefaultTimeoutMs: input.deps.waitToolDefaultTimeoutMs,
1707
1844
  worktreeSetupHook: input.deps.config.worktreeSetupHook,
1708
1845
  worktreeSetupHookTimeoutMs: input.deps.config.worktreeSetupHookTimeoutMs,
1709
1846
  worktreeBaseDir: input.deps.config.worktreeBaseDir,
1710
- worktree: input.params.worktree === true,
1847
+ baseRef: input.params.baseRef ?? recoveryDescriptor?.baseRef,
1848
+ worktreeProvider: input.deps.config.worktreeProvider,
1849
+ worktreeBranchPrefix: input.deps.config.worktreeBranchPrefix,
1850
+ worktree: input.params.worktree === true && !(("managedWorktree" in target) && target.managedWorktree === true),
1711
1851
  lane: input.params.lane ?? recoveryDescriptor?.lane,
1712
- controlConfig: recoveryDescriptor?.controlConfig ?? resolveControlConfig(input.deps.config.control, input.params.control),
1852
+ controlConfig: resolveRevivalControlConfig({ globalConfig: input.deps.config.control, requestedControl: input.params.control, recoveryControlConfig: recoveryDescriptor?.controlConfig }),
1713
1853
  intercomBridge: input.params.intercomBridge ?? recoveryDescriptor?.intercomBridge,
1714
1854
  controlIntercomTarget: intercomBridge.active ? intercomBridge.orchestratorTarget : undefined,
1715
1855
  childIntercomTarget: intercomBridge.active ? (agent, index) => resolveSubagentIntercomTarget(runId, agent, index) : undefined,
1716
1856
  availableModels,
1717
1857
  output: input.params.output !== undefined ? input.params.output : foregroundContract?.output ?? recoveryDescriptor?.outputPath,
1718
1858
  outputMode: input.params.outputMode ?? foregroundContract?.outputMode ?? recoveryDescriptor?.outputMode,
1859
+ outputClaimPath: input.params.workflowOutputClaimPath,
1719
1860
  ...agentContract ? { agentContract } : {},
1720
1861
  ...outputSchema ? { structuredOutputSchema: outputSchema } : {},
1721
1862
  ...recoveryDescriptor?.skills ? { skills: [...recoveryDescriptor.skills] } : {},
1722
- ...input.params.acceptance !== undefined ? { acceptance: input.params.acceptance } : foregroundContract?.acceptance !== undefined ? { acceptance: foregroundContract.acceptance } : recoveryDescriptor?.acceptance !== undefined ? { acceptance: recoveryDescriptor.acceptance } : {},
1863
+ ...acceptance !== undefined ? { acceptance } : {},
1723
1864
  ...input.params.timeoutMs !== undefined ? { timeoutMs: input.params.timeoutMs } : {},
1724
1865
  ...input.absoluteDeadlineAt !== undefined ? { absoluteDeadlineAt: input.absoluteDeadlineAt } : {},
1725
1866
  ...input.params.toolBudget !== undefined ? { toolBudget: input.params.toolBudget } : {},
1726
- capabilityCeiling: intersectSubagentCapabilityCeilings("capabilityCeiling" in target ? target.capabilityCeiling : undefined, recoveryDescriptor?.capabilityCeiling, resolveCurrentSubagentCapabilityCeiling(input.deps.state.currentSessionId)),
1867
+ capabilityCeiling: intersectSubagentCapabilityCeilings(recoveryDescriptor?.capabilityCeiling ?? (target.source === "foreground" || target.source === "async" && target.mode === "workflow" ? target.capabilityCeiling : undefined), resolveCurrentSubagentCapabilityCeiling(input.deps.state.currentSessionId)),
1727
1868
  runFanoutBudget: input.params.runFanoutBudget ?? recoveryDescriptor?.runFanoutBudget ?? createRunFanoutBudget(runId, resolveMaxSubagentSpawnsPerRun(input.deps.config.maxSubagentSpawnsPerRun)),
1728
1869
  parentWorkflowRunId: input.params.workflowParentRunId,
1729
1870
  workflowKey: input.params.workflowKey,
1730
1871
  activeAsyncCapacity
1731
1872
  }));
1873
+ const notifyLaunch = () => input.onLaunch?.({ agent: target.agent, sessionFile: revivalSessionFile, async: true, runId });
1732
1874
  if (result.isError) {
1733
1875
  const startedStatus = readStatus(revivalAsyncDir);
1734
1876
  if (input.params.workflowParentRunId !== undefined && startedStatus?.runId === runId && startedStatus.processTerminal?.runnerProcessInstanceId) {
1877
+ notifyLaunch();
1735
1878
  return {
1736
1879
  ...result,
1737
1880
  details: {
@@ -1746,6 +1889,7 @@ async function resumeAsyncRun(input) {
1746
1889
  activeAsyncCapacity?.rollback();
1747
1890
  return result;
1748
1891
  }
1892
+ notifyLaunch();
1749
1893
  for (const brief of queuedBriefs)
1750
1894
  fs.rmSync(brief.path, { force: true });
1751
1895
  if (queuedBriefs.length > 0 && sourceAsyncDir) {
@@ -1773,7 +1917,9 @@ async function resumeAsyncRun(input) {
1773
1917
  } finally {
1774
1918
  input.signal?.removeEventListener("abort", stopOnAbort);
1775
1919
  }
1776
- fs.rmSync(resultPath, { force: true });
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);
1777
1923
  const usage = importedAsyncRootUsage(completed);
1778
1924
  const childResult = {
1779
1925
  index: 0,
@@ -1789,14 +1935,14 @@ async function resumeAsyncRun(input) {
1789
1935
  ...completed.stopped ? { stopped: true } : {},
1790
1936
  ...completed.sessionFile ? { sessionFile: completed.sessionFile } : {},
1791
1937
  ...completed.model ? { model: completed.model } : {},
1792
- ...completed.attemptedModels ? { attemptedModels: completed.attemptedModels } : {},
1793
- ...completed.modelAttempts ? { modelAttempts: completed.modelAttempts } : {},
1938
+ ...completed.requestedModel ? { requestedModel: completed.requestedModel } : {},
1794
1939
  ...completed.contextOverflow ? { contextOverflow: true } : {},
1795
1940
  ...completed.structuredOutput !== undefined ? { structuredOutput: completed.structuredOutput } : {},
1796
1941
  ...completed.structuredOutputPath ? { structuredOutputPath: completed.structuredOutputPath } : {},
1797
1942
  ...completed.structuredOutputSchemaPath ? { structuredOutputSchemaPath: completed.structuredOutputSchemaPath } : {},
1798
1943
  ...completed.acceptance ? { acceptance: completed.acceptance } : {},
1799
1944
  ...completed.artifactPaths ? { artifactPaths: completed.artifactPaths } : {},
1945
+ ...completed.savedOutputPath ? { savedOutputPath: completed.savedOutputPath } : {},
1800
1946
  ...completed.outputSaveError ? { outputSaveError: completed.outputSaveError } : {},
1801
1947
  ...completed.transcriptPath ? { transcriptPath: completed.transcriptPath } : {},
1802
1948
  ...completed.transcriptError ? { transcriptError: completed.transcriptError } : {}
@@ -1974,6 +2120,9 @@ function canonicalizeExecutionParams(params, agents, diagnostics, context) {
1974
2120
  const agent = agents.find((candidate) => candidate.name === result.name);
1975
2121
  if (params.extensionBindings !== undefined && (agent?.runner?.type === "external-cli" || agent?.runner?.type === "external-job"))
1976
2122
  return { error: `extensionBindings is not supported for runner.type='${agent.runner.type}'.` };
2123
+ const machineError = agent ? formatHerdrMachineRunnerUnsupported({ machine: params.machine ?? agent.machine, agentName: agent.name, runnerType: agent.runner?.type, adapter: agent.runner?.type === "external-cli" ? agent.runner.adapter : undefined, worktree: params.worktree }) : undefined;
2124
+ if (machineError)
2125
+ return { error: machineError };
1977
2126
  }
1978
2127
  if (params.extensionBindings !== undefined) {
1979
2128
  try {
@@ -2029,20 +2178,33 @@ function canonicalizeExecutionParams(params, agents, diagnostics, context) {
2029
2178
  }
2030
2179
  return { params };
2031
2180
  }
2181
+ function projectEffectiveAcceptanceSchemas(params, agents) {
2182
+ const withEffectiveSchema = (step) => {
2183
+ const agent = agents.find((candidate) => candidate.name === step.agent);
2184
+ return agent ? { ...step, outputSchema: resolveEffectiveOutputSchema(agent, step.outputSchema) } : step;
2185
+ };
2186
+ return {
2187
+ ...params,
2188
+ ...params.tasks ? { tasks: params.tasks.map(withEffectiveSchema) } : {},
2189
+ ...params.chain ? { chain: projectChainOutputSchemas(params.chain, agents) } : {}
2190
+ };
2191
+ }
2032
2192
  function validateExecutionInput(params, agents, hasChain, hasTasks, hasSingle, allowClarifyTaskPrompt, context) {
2033
2193
  if (Number(hasChain) + Number(hasTasks) + Number(hasSingle) !== 1) {
2194
+ const agentList = agents.map((a) => a.name).join(", ") || "none";
2195
+ const noMode = !hasChain && !hasTasks && !hasSingle;
2034
2196
  return {
2035
2197
  content: [
2036
2198
  {
2037
2199
  type: "text",
2038
- text: `Provide exactly one mode. Agents: ${agents.map((a) => a.name).join(", ") || "none"}`
2200
+ text: noMode && typeof params.workflowKey === "string" ? `Workflow child '${params.workflowKey}' has no agent. Pass { key, agent, task }. Agents: ${agentList}` : `Provide exactly one mode. Agents: ${agentList}`
2039
2201
  }
2040
2202
  ],
2041
2203
  isError: true,
2042
2204
  details: { mode: "single", results: [] }
2043
2205
  };
2044
2206
  }
2045
- const acceptanceErrors = validateExecutionAcceptance(params);
2207
+ const acceptanceErrors = validateExecutionAcceptance(projectEffectiveAcceptanceSchemas(params, agents));
2046
2208
  if (acceptanceErrors.length > 0) {
2047
2209
  return {
2048
2210
  content: [{ type: "text", text: acceptanceErrors.join(" ") }],
@@ -2263,6 +2425,14 @@ function buildRequestedModeError(params, message) {
2263
2425
  details: { mode: getRequestedModeLabel(params), results: [] }
2264
2426
  }, params.context === "profile" ? undefined : params.context);
2265
2427
  }
2428
+ function buildWorkflowValidationResult(validation, mode, preflight) {
2429
+ const payload = preflight ? { ...validation, preflight } : validation;
2430
+ return {
2431
+ content: [{ type: "text", text: JSON.stringify(payload) }],
2432
+ ...validation.ok ? {} : { isError: true },
2433
+ details: { mode, results: [] }
2434
+ };
2435
+ }
2266
2436
  function applySingleAgentLaunchDefaults(params, agents) {
2267
2437
  if ((params.chain?.length ?? 0) > 0 || (params.tasks?.length ?? 0) > 0 || !params.agent)
2268
2438
  return params;
@@ -2270,14 +2440,37 @@ function applySingleAgentLaunchDefaults(params, agents) {
2270
2440
  if (!agent)
2271
2441
  return params;
2272
2442
  const parentTimeoutMs = params.timeoutMs === undefined && params.maxRuntimeMs === undefined && agent.defaultTimeoutMs === undefined && params.workflowParentDeadlineAt !== undefined ? Math.max(1, params.workflowParentDeadlineAt - Date.now()) : undefined;
2443
+ const outputSchema = params.outputSchema === false ? false : resolveEffectiveOutputSchema(agent, params.outputSchema);
2273
2444
  return {
2274
2445
  ...params,
2275
2446
  ...params.async === undefined && agent.defaultAsync !== undefined ? { async: agent.defaultAsync } : {},
2276
2447
  ...params.timeoutMs === undefined && params.maxRuntimeMs === undefined && agent.defaultTimeoutMs !== undefined ? { timeoutMs: agent.defaultTimeoutMs } : {},
2277
2448
  ...parentTimeoutMs !== undefined ? { timeoutMs: parentTimeoutMs } : {},
2278
- ...params.acceptance === undefined && agent.defaultAcceptance !== undefined ? { acceptance: agent.defaultAcceptance } : {}
2449
+ ...params.acceptance === undefined && agent.defaultAcceptance !== undefined ? { acceptance: agent.defaultAcceptance } : {},
2450
+ ...outputSchema !== undefined ? { outputSchema } : {}
2279
2451
  };
2280
2452
  }
2453
+ function validateLaunchOutputSchemaOverrides(params) {
2454
+ const values = [params.outputSchema, ...(params.tasks ?? []).map((task) => task.outputSchema)];
2455
+ for (const step of params.chain ?? []) {
2456
+ if (isParallelStep(step))
2457
+ values.push(...step.parallel.map((task) => task.outputSchema));
2458
+ else if (isDynamicParallelStep(step))
2459
+ values.push(step.parallel.outputSchema);
2460
+ else
2461
+ values.push(step.outputSchema);
2462
+ }
2463
+ for (const value of values) {
2464
+ if (value === undefined || value === false)
2465
+ continue;
2466
+ try {
2467
+ assertJsonSchemaObject(value, "outputSchema");
2468
+ } catch (error) {
2469
+ return error instanceof Error ? error.message : String(error);
2470
+ }
2471
+ }
2472
+ return;
2473
+ }
2281
2474
  export const DEFAULT_FOREGROUND_TIMEOUT_MS = 30 * 60 * 1000;
2282
2475
 
2283
2476
  export { DEFAULT_ASYNC_TIMEOUT_MS };
@@ -2397,17 +2590,22 @@ function withResolvedContext(result, fallback) {
2397
2590
  };
2398
2591
  }
2399
2592
  function withAggregatedToolUsage(result) {
2400
- if (result.details.results.length === 0)
2401
- return result;
2402
- const usage = sumResultsUsage(result.details.results);
2403
- return usage.input !== 0 || usage.output !== 0 || usage.cacheRead !== 0 || usage.cacheWrite !== 0 || usage.cost !== 0 || usage.turns !== 0 ? { ...result, details: { ...result.details, totalChildUsage: usage } } : result;
2404
- }
2405
- function withForkThinkingNotes(result, downgrades) {
2406
- if (downgrades.size === 0)
2407
- return result;
2408
- const children = [...downgrades.entries()].sort(([a], [b]) => a - b).map(([index, agent]) => `${agent} (child ${index})`).join(", ");
2409
- const note = `Note: fork context forced thinking off for ${children}. The forked transcript contained signed Anthropic thinking blocks that were sanitized, and Anthropic children cannot resume such a transcript with thinking enabled. Use context: "fresh" when an Anthropic child needs thinking.`;
2410
- return { ...result, content: [...result.content, { type: "text", text: note }] };
2593
+ const highWarnings = result.details.results.flatMap((child) => child.watchdog?.warnings?.filter((warning) => warning.importance === "high") ?? []);
2594
+ const projected = {
2595
+ ...result,
2596
+ ...highWarnings.length ? { content: [...result.content, { type: "text", text: ["High-importance watchdog findings:", ...highWarnings.map((warning) => `- ${warning.severity}: ${warning.summary}
2597
+ Evidence: ${warning.evidence}
2598
+ Recommended action: ${warning.recommendedAction}`)].join(`
2599
+ `) }] } : {},
2600
+ details: {
2601
+ ...result.details,
2602
+ results: result.details.results.map((child) => ({ ...child, ...child.watchdog ? { watchdog: childWatchdogProgressForModel(child.watchdog) } : {} }))
2603
+ }
2604
+ };
2605
+ if (projected.details.results.length === 0)
2606
+ return projected;
2607
+ 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;
2411
2609
  }
2412
2610
  function toExecutionErrorResult(params, error, contextSummary) {
2413
2611
  const message = error instanceof Error ? error.message : String(error);
@@ -2422,7 +2620,7 @@ function resolveStaticLaunchSummary(input) {
2422
2620
  const externalRunner = agentConfig?.runner?.type === "external-cli" || agentConfig?.runner?.type === "external-job";
2423
2621
  const modelScopes = resolveModelScopesForAgent(input.modelScope, input.agent, input.parentModel);
2424
2622
  const model = externalRunner ? undefined : resolveEffectiveSubagentModel(input.explicitModel, agentConfig?.model, input.parentModel, input.availableModels, agentConfig?.modelProvider ?? input.currentProvider, modelScopes.length === 0 ? {} : { scope: modelScopes });
2425
- const thinkingOverride = externalRunner ? undefined : input.thinkingOverrideForTask(input.agent, input.index, model);
2623
+ const thinkingOverride = externalRunner ? undefined : input.thinkingOverrideForTask();
2426
2624
  const thinking = externalRunner ? undefined : resolveEffectiveThinking(model, thinkingOverride ?? agentConfig?.thinking);
2427
2625
  return {
2428
2626
  agent: input.agent,
@@ -2524,8 +2722,9 @@ async function preflightForkSessionsForStaticTasks(params, contextPolicy, prepar
2524
2722
  if (!contextPolicy.usesFork)
2525
2723
  return;
2526
2724
  if (params.agent) {
2527
- if (shouldForkAgent(contextPolicy, params.agent))
2528
- await prepareSessionForTask(params.agent, 0, params.model);
2725
+ if (shouldForkAgent(contextPolicy, params.agent)) {
2726
+ await prepareSessionForTask(params.agent, 0, params.model, params.modelOrigin === "inherited", params.modelOrigin);
2727
+ }
2529
2728
  return;
2530
2729
  }
2531
2730
  if (params.tasks) {
@@ -2573,6 +2772,35 @@ function importedAsyncRootUsage(completed) {
2573
2772
  turns: 0
2574
2773
  };
2575
2774
  }
2775
+ function removeWorkflowAwaitedResult(asyncDir, resultPath, runId, publication) {
2776
+ try {
2777
+ fs.rmSync(resultPath, { force: true });
2778
+ } catch {}
2779
+ removeResultIndex(asyncDir, publication.sessionId, runId, publication.toolCallId);
2780
+ }
2781
+ function emitWorkflowAwaitedChildComplete(dm, state, runId, asyncDir, parentWorkflowRunId, completed) {
2782
+ let status;
2783
+ try {
2784
+ status = readStatus(asyncDir);
2785
+ } catch (error) {
2786
+ console.error(`Failed to read awaited workflow child status for ${runId}; emitting completion with fallback metadata:`, error);
2787
+ }
2788
+ dm.events.emit(SUBAGENT_ASYNC_COMPLETE_EVENT, {
2789
+ id: runId,
2790
+ runId,
2791
+ sessionId: status?.sessionId ?? completed.importedPublication?.sessionId ?? state.currentSessionId,
2792
+ completionOwnerId: status?.completionOwnerId ?? state.completionOwnerId ?? currentCompletionOwnerId(),
2793
+ asyncDir,
2794
+ agent: completed.agent,
2795
+ mode: "single",
2796
+ state: completed.stopped ? "stopped" : completed.success ? "complete" : "failed",
2797
+ success: completed.success,
2798
+ timestamp: Date.now(),
2799
+ triggerTurn: false,
2800
+ awaitedByWorkflow: true,
2801
+ parentWorkflowRunId
2802
+ });
2803
+ }
2576
2804
  async function waitForWorkflowAsyncSingleResult(params, launchResult, options) {
2577
2805
  if (params.workflowAwaitAsync !== true || !launchResult.details.asyncDir)
2578
2806
  return launchResult;
@@ -2594,7 +2822,9 @@ async function waitForWorkflowAsyncSingleResult(params, launchResult, options) {
2594
2822
  } finally {
2595
2823
  options.signal?.removeEventListener("abort", stopOnAbort);
2596
2824
  }
2597
- fs.rmSync(resultPath, { force: true });
2825
+ if (completed.importedPublication)
2826
+ removeWorkflowAwaitedResult(asyncDir, resultPath, options.runId, completed.importedPublication);
2827
+ emitWorkflowAwaitedChildComplete(options.dm, options.state, options.runId, asyncDir, params.workflowParentRunId, completed);
2598
2828
  const usage = importedAsyncRootUsage(completed);
2599
2829
  const childResult = omitUndefinedProperties({
2600
2830
  index: 0,
@@ -2610,14 +2840,14 @@ async function waitForWorkflowAsyncSingleResult(params, launchResult, options) {
2610
2840
  ...completed.stopped ? { stopped: true } : {},
2611
2841
  ...completed.sessionFile ? { sessionFile: completed.sessionFile } : {},
2612
2842
  ...completed.model ? { model: completed.model } : {},
2613
- ...completed.attemptedModels ? { attemptedModels: completed.attemptedModels } : {},
2614
- ...completed.modelAttempts ? { modelAttempts: completed.modelAttempts } : {},
2843
+ ...completed.requestedModel ? { requestedModel: completed.requestedModel } : {},
2615
2844
  ...completed.contextOverflow ? { contextOverflow: true } : {},
2616
2845
  ...completed.structuredOutput !== undefined ? { structuredOutput: completed.structuredOutput } : {},
2617
2846
  ...completed.structuredOutputPath ? { structuredOutputPath: completed.structuredOutputPath } : {},
2618
2847
  ...completed.structuredOutputSchemaPath ? { structuredOutputSchemaPath: completed.structuredOutputSchemaPath } : {},
2619
2848
  ...completed.acceptance ? { acceptance: completed.acceptance } : {},
2620
2849
  ...completed.artifactPaths ? { artifactPaths: completed.artifactPaths } : {},
2850
+ ...completed.savedOutputPath ? { savedOutputPath: completed.savedOutputPath } : {},
2621
2851
  ...completed.outputSaveError ? { outputSaveError: completed.outputSaveError } : {},
2622
2852
  ...completed.transcriptPath ? { transcriptPath: completed.transcriptPath } : {},
2623
2853
  ...completed.transcriptError ? { transcriptError: completed.transcriptError } : {}
@@ -2673,11 +2903,13 @@ async function runAsyncPath(data, deps) {
2673
2903
  currentModelProvider: parentModel?.provider,
2674
2904
  currentModel: parentModel,
2675
2905
  modelScope: data.modelScope,
2906
+ modelResponseAliases: deps.config.modelResponseAliases,
2676
2907
  interactive: ctx.hasUI,
2677
- permissions: deps.config.permissions
2908
+ permissions: deps.config.permissions,
2909
+ childRuntime: deps.childRuntime
2678
2910
  });
2679
2911
  const availableModels = ctx.modelRegistry.getAvailable().map(toModelInfo);
2680
- const currentMaxSubagentDepth = resolveCurrentMaxSubagentDepth(deps.config.maxSubagentDepth);
2912
+ const currentMaxSubagentDepth = resolveCurrentMaxSubagentDepth(deps.config.maxSubagentDepth, deps.childRuntime);
2681
2913
  const currentProvider = parentModel?.provider;
2682
2914
  const controlIntercomTarget = resolveRunLevelIntercomTarget(intercomBridge, contextPolicy);
2683
2915
  const childIntercomTarget = resolveChildIntercomTargetFactory(intercomBridge, contextPolicy, id);
@@ -2701,9 +2933,21 @@ async function runAsyncPath(data, deps) {
2701
2933
  return buildRequestedModeError(params, `Agent '${a.name}' uses runner.type='${a.runner.type}' and does not support fast mode.`);
2702
2934
  }
2703
2935
  const modelScopes = resolveModelScopesForAgent(data.modelScope, a.name, parentModel);
2704
- const modelOverride = a.runner?.type === "external-cli" || a.runner?.type === "external-job" ? params.model ?? (externalRunnerWithoutExplicitModel ? undefined : a.model) : resolveEffectiveSubagentModel(params.model, a.model, parentModel, availableModels, a.modelProvider ?? currentProvider, modelScopes.length === 0 ? {} : { scope: modelScopes });
2705
- const modelOverrideFromParent = inheritsParentModel(params.model, a.model, parentModel);
2706
- const asyncResult = executeAsyncSingle(id, compactOptional({
2936
+ const modelOrigin = resolveModelOrigin({
2937
+ storedOrigin: params.modelOrigin,
2938
+ explicitModel: params.model,
2939
+ agentModel: a.model,
2940
+ parentModel
2941
+ });
2942
+ const modelOverride = a.runner?.type === "external-cli" || a.runner?.type === "external-job" ? params.model ?? (externalRunnerWithoutExplicitModel ? undefined : a.model) : resolveEffectiveSubagentModel(params.model, a.model, parentModel, availableModels, a.modelProvider ?? currentProvider, {
2943
+ ...modelScopes.length === 0 ? {} : { scope: modelScopes },
2944
+ source: modelOrigin === "explicit" ? "explicit" : "inherited"
2945
+ });
2946
+ const modelOverrideFromParent = modelOrigin === "inherited";
2947
+ const launchRuleError = applyWatchdogLaunchRules({ cwd: effectiveCwd, agent: a.name, model: modelOverride ?? (parentModel && `${parentModel.provider}/${parentModel.id}`), warn: (violation) => deps.watchdog?.displayRuleWarning(violation) });
2948
+ if (launchRuleError)
2949
+ return toExecutionErrorResult(params, new Error(launchRuleError), data.contextPolicy.contextSummary);
2950
+ const asyncResult = await executeAsyncSingle(id, compactOptional({
2707
2951
  agent: params.agent,
2708
2952
  task: shouldForkAgent(contextPolicy, params.agent) ? wrapForkTask(params.task ?? "") : params.task ?? "",
2709
2953
  goal: params.task ?? "",
@@ -2713,13 +2957,15 @@ async function runAsyncPath(data, deps) {
2713
2957
  availableModels,
2714
2958
  cwd: effectiveCwd,
2715
2959
  requestedCwd: data.requestedCwd,
2960
+ machine: params.machine,
2961
+ machineCwd: params.machineCwd,
2716
2962
  maxOutput: params.maxOutput,
2717
2963
  artifactsDir: artifactConfig.enabled ? artifactsDir : undefined,
2718
2964
  artifactConfig,
2719
2965
  shareEnabled,
2720
2966
  activeAsyncCapacity: data.activeAsyncCapacity,
2721
2967
  sessionRoot,
2722
- sessionFile: sessionFileForTask(params.agent, 0, modelOverride, modelOverrideFromParent),
2968
+ sessionFile: sessionFileForTask(params.agent, 0, modelOverride, modelOverrideFromParent, modelOrigin),
2723
2969
  context: contextPolicy.contextForAgent(params.agent),
2724
2970
  skills,
2725
2971
  output: effectiveOutput,
@@ -2730,7 +2976,8 @@ async function runAsyncPath(data, deps) {
2730
2976
  modelOverride,
2731
2977
  fast: params.fast,
2732
2978
  modelOverrideFromParent,
2733
- thinkingOverride: externalRunnerWithoutExplicitModel ? undefined : thinkingOverrideForTask(params.agent, 0, modelOverride, modelOverrideFromParent),
2979
+ modelOrigin,
2980
+ thinkingOverride: externalRunnerWithoutExplicitModel ? undefined : thinkingOverrideForTask(),
2734
2981
  thinkingCeiling: a.maxThinking,
2735
2982
  maxSubagentDepth,
2736
2983
  waitToolEnabled: deps.waitToolEnabled,
@@ -2739,13 +2986,16 @@ async function runAsyncPath(data, deps) {
2739
2986
  worktreeSetupHook: deps.config.worktreeSetupHook,
2740
2987
  worktreeSetupHookTimeoutMs: deps.config.worktreeSetupHookTimeoutMs,
2741
2988
  worktreeBaseDir: deps.config.worktreeBaseDir,
2989
+ baseRef: params.baseRef,
2990
+ worktreeProvider: deps.config.worktreeProvider,
2991
+ worktreeBranchPrefix: deps.config.worktreeBranchPrefix,
2742
2992
  controlConfig,
2743
2993
  intercomBridge: params.intercomBridge,
2744
2994
  controlIntercomTarget,
2745
2995
  childIntercomTarget: childIntercomTarget ? (agent, index) => childIntercomTarget(agent, index) : undefined,
2746
2996
  nestedRoute,
2747
2997
  agentContract: params.agentContract,
2748
- structuredOutputSchema: params.outputSchema,
2998
+ structuredOutputSchema: params.outputSchema || undefined,
2749
2999
  extensionBindings: params.extensionBindings,
2750
3000
  acceptance: params.acceptance,
2751
3001
  timeoutMs: data.timeoutMs,
@@ -2753,6 +3003,7 @@ async function runAsyncPath(data, deps) {
2753
3003
  usageBudget: data.usageBudget,
2754
3004
  configToolBudget: data.configToolBudget,
2755
3005
  toolTimeoutMs: data.params?.toolTimeoutMs,
3006
+ checkpointBeforeDeadlineMs: data.params?.checkpointBeforeDeadlineMs ?? deps.config.checkpointBeforeDeadlineMs,
2756
3007
  configToolTimeoutMs: data.configToolTimeoutMs,
2757
3008
  capabilityCeiling: data.capabilityCeiling,
2758
3009
  runFanoutBudget: data.runFanoutBudget,
@@ -2761,20 +3012,25 @@ async function runAsyncPath(data, deps) {
2761
3012
  lane: params.lane,
2762
3013
  workflowAwaitAsync: params.workflowAwaitAsync
2763
3014
  }));
2764
- return waitForWorkflowAsyncSingleResult(params, asyncResult, { runId: id, task: params.task ?? "", signal: data.signal, state: deps.state, kill: deps.kill });
3015
+ return waitForWorkflowAsyncSingleResult(params, asyncResult, { runId: id, task: params.task ?? "", signal: data.signal, state: deps.state, dm: deps.dm, kill: deps.kill });
2765
3016
  }
2766
3017
  return null;
2767
3018
  }
2768
- function createSingleWorktreeSetup(enabled, cwd, runId, agent, setupHook, setupHookTimeoutMs, baseDir, beforeCreate) {
2769
- if (!enabled)
2770
- return {};
3019
+ async function createSingleWorktreeSetup(cwd, runId, agent, setupHook, setupHookTimeoutMs, baseDir, baseRef, provider, branchPrefix, label, task, onProgress, signal, deadlineAt) {
2771
3020
  try {
2772
3021
  return {
2773
- setup: createWorktrees(cwd, runId, 1, omitUndefinedProperties({
3022
+ setup: await createWorktrees(cwd, runId, 1, omitUndefinedProperties({
2774
3023
  agents: [agent],
2775
3024
  setupHook: setupHook ? { hookPath: setupHook, ...setupHookTimeoutMs === undefined ? {} : { timeoutMs: setupHookTimeoutMs } } : undefined,
2776
3025
  baseDir,
2777
- beforeCreate
3026
+ baseRef,
3027
+ provider,
3028
+ branchPrefix,
3029
+ labels: [label],
3030
+ tasks: [task],
3031
+ onProgress,
3032
+ signal,
3033
+ deadlineAt
2778
3034
  }))
2779
3035
  };
2780
3036
  } catch (error) {
@@ -2796,9 +3052,6 @@ export function sanitizeRunPathSegment(value, maxBytes = 120) {
2796
3052
  function resolveSingleRunOutputBaseDir(deps, artifactsDir, runId) {
2797
3053
  return resolveConfiguredSingleRunOutputBaseDir(deps) ?? path.join(artifactsDir, "outputs", sanitizeRunPathSegment(runId));
2798
3054
  }
2799
- function resolveWorkflowAggregateOutputPath(output, ctxCwd, workflowCwd, outputBaseDir) {
2800
- return resolveSingleOutputPath(output, ctxCwd, workflowCwd, outputBaseDir);
2801
- }
2802
3055
  function workflowChildDefaultOutput(aggregateOutputPath, artifactsDir, workflowRunId, workflowKey) {
2803
3056
  if (aggregateOutputPath) {
2804
3057
  const parsed = path.parse(aggregateOutputPath);
@@ -2808,6 +3061,9 @@ function workflowChildDefaultOutput(aggregateOutputPath, artifactsDir, workflowR
2808
3061
  }
2809
3062
  function workflowHostCommandRunner(input) {
2810
3063
  return async (key, params, signal) => {
3064
+ const authorizationError = input.authorize?.(key, params);
3065
+ if (authorizationError)
3066
+ throw new Error(authorizationError);
2811
3067
  const defaultOutputPath = path.join(input.artifactsDir, "outputs", sanitizeRunPathSegment(input.workflowRunId), "host", `${sanitizeRunPathSegment(key)}.log`);
2812
3068
  const outputPath = params.output ? path.resolve(input.workflowCwd, params.output) : defaultOutputPath;
2813
3069
  const claimPath = resolveWorkflowHostOutputClaimPath(outputPath);
@@ -2839,8 +3095,22 @@ function appendWorkflowOutputWarning(text, warning) {
2839
3095
 
2840
3096
  ${warning}` : text;
2841
3097
  }
3098
+ export function resolveWorkflowChildLocalCwd(input) {
3099
+ if (input.params.machine !== undefined)
3100
+ return input.workflowCwd;
3101
+ if (typeof input.params.agent === "string") {
3102
+ const agentScope = resolveExecutionAgentScope(input.params.agentScope ?? input.workflowAgentScope);
3103
+ const workflowAgents = input.discoverAgents(input.workflowCwd, agentScope).agents;
3104
+ const agent = resolveAgentName(input.params.agent, workflowAgents).agent ?? resolveAgentName(input.params.agent, input.agents).agent;
3105
+ if (agent?.machine !== undefined)
3106
+ return input.workflowCwd;
3107
+ }
3108
+ return typeof input.params.cwd === "string" ? resolveChildCwd(input.workflowCwd, input.params.cwd) : input.workflowCwd;
3109
+ }
2842
3110
  function resolveWorkflowChildOutputPath(input) {
2843
- if (typeof input.params.resume === "string") {
3111
+ const rawOutput = input.params.output;
3112
+ const hasExplicitOutput = typeof rawOutput === "string" || typeof rawOutput === "boolean";
3113
+ if (typeof input.params.resume === "string" && (!hasExplicitOutput || rawOutput === true || rawOutput === "true")) {
2844
3114
  if (!input.state)
2845
3115
  return { path: undefined, inherited: false };
2846
3116
  const index = input.params.index;
@@ -2850,13 +3120,14 @@ function resolveWorkflowChildOutputPath(input) {
2850
3120
  }, input.state);
2851
3121
  return { path: "recoveryDescriptor" in target ? target.recoveryDescriptor?.outputPath : undefined, inherited: false };
2852
3122
  }
2853
- const rawOutput = input.params.output;
2854
- const hasExplicitOutput = typeof rawOutput === "string" || typeof rawOutput === "boolean";
2855
- const childCwd = typeof input.params.cwd === "string" ? resolveChildCwd(input.workflowCwd, input.params.cwd) : input.workflowCwd;
2856
- const agentScope = resolveExecutionAgentScope(input.params.agentScope ?? input.workflowAgentScope);
2857
- const discoveredAgents = input.discoverAgents(childCwd, agentScope).agents;
2858
- const agent = typeof input.params.agent === "string" ? resolveAgentName(input.params.agent, discoveredAgents).agent ?? resolveAgentName(input.params.agent, input.agents).agent : undefined;
2859
- const agentOutput = typeof agent?.output === "string" ? agent.output : undefined;
3123
+ const childCwd = resolveWorkflowChildLocalCwd(input);
3124
+ let agentOutput;
3125
+ if (rawOutput === true || rawOutput === "true" || !hasExplicitOutput && !input.aggregateOutputPath) {
3126
+ const agentScope = resolveExecutionAgentScope(input.params.agentScope ?? input.workflowAgentScope);
3127
+ const discoveredAgents = input.discoverAgents(childCwd, agentScope).agents;
3128
+ const agent = typeof input.params.agent === "string" ? resolveAgentName(input.params.agent, discoveredAgents).agent ?? resolveAgentName(input.params.agent, input.agents).agent : undefined;
3129
+ agentOutput = typeof agent?.output === "string" ? agent.output : undefined;
3130
+ }
2860
3131
  const output = rawOutput === true || rawOutput === "true" ? agentOutput : hasExplicitOutput ? rawOutput : input.aggregateOutputPath ? workflowChildDefaultOutput(input.aggregateOutputPath, input.artifactsDir, input.workflowRunId, input.key) : agentOutput;
2861
3132
  return {
2862
3133
  path: resolveSingleOutputPath(output, input.ctxCwd, childCwd, input.configuredOutputBaseDir ?? path.join(input.artifactsDir, "outputs", sanitizeRunPathSegment(input.workflowRunId))),
@@ -2911,25 +3182,89 @@ function prepareWorkflowChildLaunchParams(input) {
2911
3182
  childParams = { ...input.childParams, output: input.outputOverride };
2912
3183
  } else if (usesDefaultOutput && input.aggregateOutputPath !== undefined) {
2913
3184
  childParams = { ...input.childParams, output: workflowChildDefaultOutput(input.aggregateOutputPath, input.artifactsDir, input.parentWorkflowRunId, input.workflowKey) };
2914
- } else if (input.childParams.resume === undefined) {
3185
+ } else if (input.childParams.resume === undefined || input.childParams.output !== undefined) {
2915
3186
  const resolvedOutput = resolveWorkflowChildOutputPath({ ctxCwd: input.ctxCwd, workflowCwd: input.workflowCwd, artifactsDir: input.artifactsDir, workflowRunId: input.parentWorkflowRunId, aggregateOutputPath: input.aggregateOutputPath, configuredOutputBaseDir: input.configuredOutputBaseDir, discoverAgents: input.discoverAgents, agents: input.agents, workflowAgentScope: input.workflowAgentScope, key: input.workflowKey, params: input.childParams });
2916
3187
  if (resolvedOutput.path)
2917
3188
  childParams = { ...input.childParams, output: resolvedOutput.path };
2918
3189
  }
2919
- const childCwd = typeof childParams.cwd === "string" ? resolveChildCwd(input.workflowCwd, childParams.cwd) : input.workflowCwd;
3190
+ const childCwd = resolveWorkflowChildLocalCwd({ ...input, params: childParams });
2920
3191
  const agentScope = resolveExecutionAgentScope(childParams.agentScope ?? input.workflowAgentScope);
2921
3192
  const discoveredAgents = input.discoverAgents(childCwd, agentScope).agents;
2922
3193
  const agent = typeof childParams.agent === "string" ? resolveAgentName(childParams.agent, discoveredAgents).agent ?? resolveAgentName(childParams.agent, input.agents).agent : undefined;
2923
3194
  const externalAsyncRequired = agent?.runner?.type === "external-cli" || agent?.runner?.type === "external-job";
2924
3195
  return prepareWorkflowLaunchParams(input.workflowDefaults, childParams, input.parentWorkflowRunId, input.workflowKey, { ...input.options, externalAsyncRequired, outputClaimPath: input.outputClaimPath });
2925
3196
  }
2926
- function finalizeSingleWorktreeHandoff(input) {
2927
- const diffsDir = path.join(input.artifactsDir, "worktree-diffs", input.runId);
2928
- const diffs = diffWorktrees(input.worktreeSetup, [input.agent], diffsDir);
2929
- const diffSummary = formatWorktreeDiffSummary(diffs);
2930
- const manifestPath = parallelHandoffPath(input.artifactsDir, input.runId);
2931
- const handoff = {
2932
- manifestPath,
3197
+ async function finalizeSingleWorktreeHandoff(input) {
3198
+ let admitted = false;
3199
+ try {
3200
+ return await withWorktreeTransaction(() => {
3201
+ admitted = true;
3202
+ const diffsDir = path.join(input.artifactsDir, "worktree-diffs", input.runId);
3203
+ const diffs = diffWorktrees(input.worktreeSetup, [input.agent], diffsDir);
3204
+ const diffSummary = formatWorktreeDiffSummary(diffs);
3205
+ const manifestPath = parallelHandoffPath(input.artifactsDir, input.runId);
3206
+ const handoff = {
3207
+ manifestPath,
3208
+ runId: input.runId,
3209
+ mode: "single",
3210
+ source: "foreground",
3211
+ cwd: input.cwd,
3212
+ stepIndex: 0,
3213
+ flatStartIndex: 0,
3214
+ setup: input.worktreeSetup,
3215
+ laneBindings: input.workflowKey || input.lane ? [{ index: 0, taskIndex: 0, ...input.workflowKey ? { workflowKey: input.workflowKey } : {}, runId: input.workflowKey ? input.runId : undefined, ...input.lane ? { lane: input.lane } : {} }] : undefined,
3216
+ diffs,
3217
+ results: [{
3218
+ agent: input.result.agent,
3219
+ ...input.workflowKey ? { workflowKey: input.workflowKey } : {},
3220
+ ...input.workflowKey ? { runId: input.runId } : {},
3221
+ ...input.lane ? { lane: input.lane } : {},
3222
+ status: resolveSubagentResultStatus(omitUndefinedProperties({
3223
+ exitCode: input.result.exitCode,
3224
+ interrupted: input.result.interrupted,
3225
+ detached: input.result.detached,
3226
+ state: input.result.stopped ? "stopped" : undefined,
3227
+ processSignal: input.result.processSignal,
3228
+ timedOut: input.result.timedOut,
3229
+ stopped: input.result.stopped,
3230
+ turnBudgetExceeded: input.result.turnBudgetExceeded
3231
+ })),
3232
+ summary: resultSummaryForIntercom(input.result),
3233
+ ...input.result.artifactPaths?.outputPath ? { outputPath: input.result.artifactPaths.outputPath } : {},
3234
+ ...input.result.structuredOutput !== undefined ? { structuredOutput: input.result.structuredOutput } : {},
3235
+ ...input.result.structuredOutputPath ? { structuredOutputPath: input.result.structuredOutputPath } : {},
3236
+ ...input.result.sessionFile ? { sessionPath: input.result.sessionFile } : {}
3237
+ }]
3238
+ };
3239
+ try {
3240
+ writeParallelHandoffGroup(handoff);
3241
+ const cleanup = cleanupWorktrees(input.worktreeSetup, { kind: "preserve", capturedDiffs: diffs, handoffManifestPath: manifestPath });
3242
+ const reference = writeParallelHandoffGroup({ ...handoff, cleanup });
3243
+ return {
3244
+ suffix: [diffSummary, formatParallelHandoffReference(reference)].filter(Boolean).join(`
3245
+
3246
+ `),
3247
+ reference
3248
+ };
3249
+ } catch (error) {
3250
+ return { suffix: [diffSummary, formatParallelHandoffError(error)].filter(Boolean).join(`
3251
+
3252
+ `) };
3253
+ }
3254
+ });
3255
+ } catch (error) {
3256
+ if (admitted)
3257
+ throw error;
3258
+ const reference = retainSingleWorktreeHandoff(input, error);
3259
+ return { suffix: `${formatParallelHandoffError(error)}
3260
+
3261
+ ${formatParallelHandoffReference(reference)}`, reference };
3262
+ }
3263
+ }
3264
+ function retainSingleWorktreeHandoff(input, error) {
3265
+ const reason = `Worktree finalization retained; manual reconciliation required: ${error instanceof Error ? error.message : String(error)}`;
3266
+ return writeParallelHandoffGroup({
3267
+ manifestPath: parallelHandoffPath(input.artifactsDir, input.runId),
2933
3268
  runId: input.runId,
2934
3269
  mode: "single",
2935
3270
  source: "foreground",
@@ -2937,45 +3272,20 @@ function finalizeSingleWorktreeHandoff(input) {
2937
3272
  stepIndex: 0,
2938
3273
  flatStartIndex: 0,
2939
3274
  setup: input.worktreeSetup,
2940
- laneBindings: input.workflowKey || input.lane ? [{ index: 0, taskIndex: 0, ...input.workflowKey ? { workflowKey: input.workflowKey } : {}, runId: input.workflowKey ? input.runId : undefined, ...input.lane ? { lane: input.lane } : {} }] : undefined,
2941
- diffs,
2942
- results: [{
2943
- agent: input.result.agent,
2944
- ...input.workflowKey ? { workflowKey: input.workflowKey } : {},
2945
- ...input.workflowKey ? { runId: input.runId } : {},
2946
- ...input.lane ? { lane: input.lane } : {},
2947
- status: resolveSubagentResultStatus(omitUndefinedProperties({
2948
- exitCode: input.result.exitCode,
2949
- interrupted: input.result.interrupted,
2950
- detached: input.result.detached,
2951
- state: input.result.stopped ? "stopped" : undefined,
2952
- processSignal: input.result.processSignal,
2953
- timedOut: input.result.timedOut,
2954
- stopped: input.result.stopped,
2955
- turnBudgetExceeded: input.result.turnBudgetExceeded
2956
- })),
2957
- summary: resultSummaryForIntercom(input.result),
2958
- ...input.result.artifactPaths?.outputPath ? { outputPath: input.result.artifactPaths.outputPath } : {},
2959
- ...input.result.structuredOutput !== undefined ? { structuredOutput: input.result.structuredOutput } : {},
2960
- ...input.result.structuredOutputPath ? { structuredOutputPath: input.result.structuredOutputPath } : {},
2961
- ...input.result.sessionFile ? { sessionPath: input.result.sessionFile } : {}
2962
- }]
2963
- };
2964
- try {
2965
- writeParallelHandoffGroup(handoff);
2966
- const cleanup = cleanupWorktrees(input.worktreeSetup, { kind: "preserve", capturedDiffs: diffs, handoffManifestPath: manifestPath });
2967
- const reference = writeParallelHandoffGroup({ ...handoff, cleanup });
2968
- return {
2969
- suffix: [diffSummary, formatParallelHandoffReference(reference)].filter(Boolean).join(`
2970
-
2971
- `),
2972
- reference
2973
- };
2974
- } catch (error) {
2975
- return { suffix: [diffSummary, formatParallelHandoffError(error)].filter(Boolean).join(`
2976
-
2977
- `) };
2978
- }
3275
+ diffs: [],
3276
+ results: [],
3277
+ cleanup: { state: "partial", pruned: false, errors: [reason], tasks: input.worktreeSetup.worktrees.map((worktree) => ({
3278
+ index: worktree.index,
3279
+ path: worktree.path,
3280
+ branch: worktree.branch,
3281
+ provider: worktree.provider,
3282
+ naming: worktree.naming,
3283
+ worktreeRemoved: false,
3284
+ branchRemoved: false,
3285
+ preserved: true,
3286
+ reason
3287
+ })) }
3288
+ });
2979
3289
  }
2980
3290
  async function runSinglePath(data, deps) {
2981
3291
  const {
@@ -2993,7 +3303,8 @@ async function runSinglePath(data, deps) {
2993
3303
  artifactsDir,
2994
3304
  onUpdate,
2995
3305
  controlConfig,
2996
- contextPolicy
3306
+ contextPolicy,
3307
+ suppressUnchangedDelegationUpdates
2997
3308
  } = data;
2998
3309
  let lane;
2999
3310
  try {
@@ -3015,6 +3326,15 @@ async function runSinglePath(data, deps) {
3015
3326
  details: { mode: "single", results: [] }
3016
3327
  };
3017
3328
  }
3329
+ let foregroundMachine;
3330
+ const requestedMachine = params.machine ?? agentConfig.machine;
3331
+ if (requestedMachine) {
3332
+ try {
3333
+ foregroundMachine = resolveHerdrMachinePlacement({ machine: requestedMachine, cwd: ctx.cwd, stepCwd: params.machineCwd }).machine;
3334
+ } catch (error) {
3335
+ return toExecutionErrorResult(params, error instanceof Error ? error : new Error(String(error)), data.contextPolicy.contextSummary);
3336
+ }
3337
+ }
3018
3338
  const effectiveToolBudget = resolveEffectiveToolBudget(omitUndefinedProperties({ runBudget: data.toolBudget, agentBudget: agentConfig.toolBudget, configBudget: data.configToolBudget }));
3019
3339
  if (effectiveToolBudget.error)
3020
3340
  return toExecutionErrorResult(params, new Error(effectiveToolBudget.error), data.contextPolicy.contextSummary);
@@ -3023,19 +3343,31 @@ async function runSinglePath(data, deps) {
3023
3343
  const availableModels = ctx.modelRegistry.getAvailable().map(toModelInfo);
3024
3344
  const modelScopes = resolveModelScopesForAgent(data.modelScope, agentConfig.name, parentModel);
3025
3345
  let task = typeof params.task === "string" ? params.task : "";
3026
- let modelOverride = resolveEffectiveSubagentModel(params.model, agentConfig.model, parentModel, availableModels, agentConfig.modelProvider ?? currentProvider, modelScopes.length === 0 ? {} : { scope: modelScopes });
3027
- const modelOverrideFromParent = inheritsParentModel(params.model, agentConfig.model, parentModel);
3346
+ const modelOrigin = resolveModelOrigin({
3347
+ storedOrigin: params.modelOrigin,
3348
+ explicitModel: params.model,
3349
+ agentModel: agentConfig.model,
3350
+ parentModel
3351
+ });
3352
+ let modelOverride = resolveEffectiveSubagentModel(params.model, agentConfig.model, parentModel, availableModels, agentConfig.modelProvider ?? currentProvider, {
3353
+ ...modelScopes.length === 0 ? {} : { scope: modelScopes },
3354
+ source: modelOrigin === "explicit" ? "explicit" : "inherited"
3355
+ });
3356
+ const modelOverrideFromParent = modelOrigin === "inherited";
3357
+ const launchRuleError = applyWatchdogLaunchRules({ cwd: effectiveCwd, agent: agentConfig.name, model: modelOverride ?? (parentModel && `${parentModel.provider}/${parentModel.id}`), warn: (violation) => deps.watchdog?.displayRuleWarning(violation) });
3358
+ if (launchRuleError)
3359
+ return toExecutionErrorResult(params, new Error(launchRuleError), data.contextPolicy.contextSummary);
3028
3360
  let skillOverride = normalizeSkillInput(params.skill);
3029
3361
  let readsOverride = params.reads;
3030
3362
  const rawOutput = params.output !== undefined ? params.output : agentConfig.output;
3031
3363
  let effectiveOutput = normalizeSingleOutputOverride(rawOutput, agentConfig.output);
3032
3364
  const effectiveOutputMode = params.outputMode ?? agentConfig.outputMode ?? "inline";
3033
- const currentMaxSubagentDepth = resolveCurrentMaxSubagentDepth(deps.config.maxSubagentDepth);
3365
+ const currentMaxSubagentDepth = resolveCurrentMaxSubagentDepth(deps.config.maxSubagentDepth, deps.childRuntime);
3034
3366
  const maxSubagentDepth = resolveChildMaxSubagentDepth(currentMaxSubagentDepth, agentConfig.maxSubagentDepth);
3035
- const sourceCwd = effectiveCwd;
3367
+ const sourceCwd = foregroundMachine?.cwd ?? effectiveCwd;
3036
3368
  let pendingHandoff;
3037
- const { setup: worktreeSetup, errorResult: worktreeSetupError } = createSingleWorktreeSetup(params.worktree, sourceCwd, runId, params.agent, deps.config.worktreeSetupHook, deps.config.worktreeSetupHookTimeoutMs, deps.config.worktreeBaseDir, (plannedSetup) => {
3038
- pendingHandoff = writePendingParallelHandoff({
3369
+ const { setup: worktreeSetup, errorResult: worktreeSetupError } = params.worktree ? await createSingleWorktreeSetup(sourceCwd, runId, params.agent, deps.config.worktreeSetupHook, deps.config.worktreeSetupHookTimeoutMs, deps.config.worktreeBaseDir, params.baseRef, deps.config.worktreeProvider, deps.config.worktreeBranchPrefix, params.lane?.key ?? params.workflowKey, task, (progress) => {
3370
+ pendingHandoff = writeWorktreeSetupHandoff({
3039
3371
  manifestPath: parallelHandoffPath(artifactsDir, runId),
3040
3372
  runId,
3041
3373
  mode: "single",
@@ -3043,13 +3375,52 @@ async function runSinglePath(data, deps) {
3043
3375
  cwd: sourceCwd,
3044
3376
  stepIndex: 0,
3045
3377
  flatStartIndex: 0,
3046
- setup: plannedSetup,
3378
+ progress,
3047
3379
  laneBindings: params.workflowKey || lane ? [{ index: 0, taskIndex: 0, ...params.workflowKey ? { workflowKey: params.workflowKey, runId } : {}, ...lane ? { lane } : {} }] : undefined
3048
3380
  });
3049
- });
3050
- if (worktreeSetupError)
3381
+ }, signal, data.deadlineAt) : {};
3382
+ if (worktreeSetupError) {
3383
+ if (pendingHandoff) {
3384
+ worktreeSetupError.details.parallelHandoff = pendingHandoff;
3385
+ worktreeSetupError.content.push({ type: "text", text: formatParallelHandoffReference(pendingHandoff) });
3386
+ }
3051
3387
  return worktreeSetupError;
3388
+ }
3052
3389
  const singleCwd = worktreeSetup?.worktrees[0]?.agentCwd ?? sourceCwd;
3390
+ const cleanupSingleWorktree = async () => {
3391
+ if (!worktreeSetup)
3392
+ return;
3393
+ let admitted = false;
3394
+ try {
3395
+ await withWorktreeTransaction(() => {
3396
+ if (data.deadlineAt !== undefined && Date.now() >= data.deadlineAt)
3397
+ throw new Error("Run deadline expired before unlaunched worktree cleanup");
3398
+ admitted = true;
3399
+ const cleanup = cleanupWorktrees(worktreeSetup);
3400
+ pendingHandoff = writeParallelHandoffGroup({
3401
+ manifestPath: parallelHandoffPath(artifactsDir, runId),
3402
+ runId,
3403
+ mode: "single",
3404
+ source: "foreground",
3405
+ cwd: sourceCwd,
3406
+ stepIndex: 0,
3407
+ flatStartIndex: 0,
3408
+ setup: worktreeSetup,
3409
+ diffs: [],
3410
+ results: [],
3411
+ cleanup
3412
+ });
3413
+ });
3414
+ } catch (error) {
3415
+ if (admitted)
3416
+ throw error;
3417
+ pendingHandoff = retainSingleWorktreeHandoff({ worktreeSetup, artifactsDir, runId, cwd: sourceCwd }, error);
3418
+ }
3419
+ };
3420
+ if (worktreeSetup && (signal?.aborted || data.deadlineAt !== undefined && Date.now() >= data.deadlineAt)) {
3421
+ await cleanupSingleWorktree();
3422
+ return { content: [{ type: "text", text: "Subagent setup canceled before child launch." }], isError: true, details: { mode: "single", results: [], parallelHandoff: pendingHandoff } };
3423
+ }
3053
3424
  const authoredTask = task;
3054
3425
  if (shouldForkAgent(contextPolicy, params.agent)) {
3055
3426
  task = wrapForkTask(task);
@@ -3058,13 +3429,12 @@ async function runSinglePath(data, deps) {
3058
3429
  const outputPath = resolveSingleOutputPath(effectiveOutput, ctx.cwd, singleCwd, resolveSingleRunOutputBaseDir(deps, artifactsDir, runId));
3059
3430
  const validationError = validateFileOnlyOutputMode(effectiveOutputMode, outputPath, `Single run (${params.agent})`);
3060
3431
  if (validationError) {
3061
- if (worktreeSetup)
3062
- cleanupWorktrees(worktreeSetup);
3063
- return { content: [{ type: "text", text: validationError }], isError: true, details: { mode: "single", results: [] } };
3432
+ await cleanupSingleWorktree();
3433
+ return { content: [{ type: "text", text: validationError }], isError: true, details: { mode: "single", results: [], parallelHandoff: pendingHandoff } };
3064
3434
  }
3065
- const structuredRuntime = params.outputSchema ? createStructuredOutputRuntime(params.outputSchema, artifactConfig.enabled ? path.join(artifactsDir, "structured-output", runId) : undefined, { captureAcceptanceReport: params.acceptance !== false }) : undefined;
3435
+ const structuredRuntime = params.outputSchema ? createStructuredOutputRuntime(params.outputSchema, artifactConfig.enabled ? path.join(artifactsDir, "structured-output", runId) : undefined, { acceptanceReport: resolveAcceptanceReportMode(params.acceptance) }) : undefined;
3066
3436
  const reads = readsOverride !== undefined ? readsOverride : agentConfig.defaultReads ?? false;
3067
- const readPaths = Array.isArray(reads) ? resolveExistingReadPaths(reads, singleCwd) : [];
3437
+ const readPaths = !foregroundMachine && Array.isArray(reads) ? resolveExistingReadPaths(reads, singleCwd) : [];
3068
3438
  const readsInstruction = readPaths.length > 0 ? `[Read from: ${readPaths.join(", ")}]
3069
3439
 
3070
3440
  ` : "";
@@ -3078,9 +3448,10 @@ async function runSinglePath(data, deps) {
3078
3448
  }
3079
3449
  const interruptController = new AbortController;
3080
3450
  let detachForeground;
3451
+ let childSessionControls;
3081
3452
  const foregroundControl = deps.state.foregroundControls.get(runId);
3082
3453
  if (foregroundControl) {
3083
- const thinking = resolveEffectiveThinking(modelOverride, thinkingOverrideForTask(params.agent, 0, modelOverride, modelOverrideFromParent));
3454
+ const thinking = resolveEffectiveThinking(modelOverride, thinkingOverrideForTask());
3084
3455
  beginForegroundChild(foregroundControl, omitUndefinedProperties({
3085
3456
  index: 0,
3086
3457
  agent: params.agent,
@@ -3098,15 +3469,33 @@ async function runSinglePath(data, deps) {
3098
3469
  interruptController.abort();
3099
3470
  return true;
3100
3471
  },
3101
- detach: () => detachForeground?.("user request") === true
3472
+ detach: () => detachForeground?.("user request") === true,
3473
+ steer: async (input) => {
3474
+ if (!childSessionControls)
3475
+ return { state: "failed", reason: CHILD_SESSION_NOT_RUNNING_YET };
3476
+ try {
3477
+ if (input.mode === "follow_up") {
3478
+ await childSessionControls.followUp(input.message);
3479
+ return { state: "queued" };
3480
+ }
3481
+ await childSessionControls.steer(input.message);
3482
+ return { state: "delivered" };
3483
+ } catch (error) {
3484
+ return { state: "failed", reason: error instanceof Error ? error.message : String(error) };
3485
+ }
3486
+ }
3102
3487
  }));
3488
+ if (deps.childRuntime?.fanoutChild)
3489
+ deps.activateSupervisorTransport?.();
3103
3490
  }
3491
+ const modelResponseAliases = deps.config.modelResponseAliases === undefined ? undefined : structuredClone(deps.config.modelResponseAliases);
3104
3492
  const forwardSingleUpdate = onUpdate ? (update) => {
3105
3493
  if (foregroundControl)
3106
3494
  updateForegroundChild(foregroundControl, 0, update.details?.progress?.[0]);
3107
3495
  onUpdate(update);
3108
3496
  } : undefined;
3109
3497
  const deadlineAt = data.deadlineAt ?? (data.timeoutMs !== undefined ? Date.now() + data.timeoutMs : undefined);
3498
+ const requiredExtensions = deps.childRuntime?.requiredExtensions ?? resolveRequiredChildExtensions(data.parentPiSessionId);
3110
3499
  let r;
3111
3500
  let resolveDetachedWorkflowChild;
3112
3501
  const detachedWorkflowChild = params.workflowAwaitDetached === true ? new Promise((resolve) => {
@@ -3114,11 +3503,17 @@ async function runSinglePath(data, deps) {
3114
3503
  }) : undefined;
3115
3504
  try {
3116
3505
  const launched = await runSync(ctx.cwd, agents, params.agent, task, compactOptional({
3506
+ machine: foregroundMachine,
3507
+ parentProviderRegistry: ctx.modelRegistry,
3508
+ remoteReads: foregroundMachine ? readsOverride : undefined,
3117
3509
  permissions: deps.config.permissions,
3118
3510
  runtimeSnapshotHost: deps.dm,
3119
3511
  parentSessionId: ctx.sessionManager.getSessionId() ?? undefined,
3120
- llmIntentArbiter: createTaskMutationArbiter(ctx),
3121
- ...workflowForegroundSteeringLaunchOptions(foregroundControl, 0),
3512
+ requiredExtensions,
3513
+ childRuntime: deps.childRuntime,
3514
+ onChildSession: (controls) => {
3515
+ childSessionControls = controls;
3516
+ },
3122
3517
  context: data.contextPolicy.contextForAgent(params.agent),
3123
3518
  unknownAgentDiagnosticContext: data.unknownAgentDiagnosticContext,
3124
3519
  runFanoutBudget: params.runFanoutAdmitted ? data.runFanoutBudget : { ...data.runFanoutBudget, parentPath: `${data.runFanoutBudget.parentPath ? `${data.runFanoutBudget.parentPath}/` : ""}single` },
@@ -3130,7 +3525,7 @@ async function runSinglePath(data, deps) {
3130
3525
  intercomEvents: deps.dm.events,
3131
3526
  runId,
3132
3527
  sessionDir: sessionDirForIndex(0),
3133
- sessionFile: sessionFileForTask(params.agent, 0, modelOverride, modelOverrideFromParent),
3528
+ sessionFile: sessionFileForTask(params.agent, 0, modelOverride, modelOverrideFromParent, modelOrigin),
3134
3529
  share: shareEnabled,
3135
3530
  artifactsDir: artifactConfig.enabled ? artifactsDir : undefined,
3136
3531
  artifactConfig,
@@ -3142,6 +3537,7 @@ async function runSinglePath(data, deps) {
3142
3537
  waitToolEnabled: deps.waitToolEnabled,
3143
3538
  waitToolDefaultTimeoutMs: deps.waitToolDefaultTimeoutMs,
3144
3539
  onUpdate: forwardSingleUpdate,
3540
+ suppressUnchangedDelegationUpdates,
3145
3541
  controlConfig,
3146
3542
  onControlEvent,
3147
3543
  intercomSessionName: childIntercomTarget,
@@ -3151,10 +3547,12 @@ async function runSinglePath(data, deps) {
3151
3547
  modelOverride,
3152
3548
  fast: params.fast,
3153
3549
  modelOverrideFromParent,
3154
- thinkingOverride: thinkingOverrideForTask(params.agent, 0, modelOverride, modelOverrideFromParent),
3550
+ modelOrigin,
3551
+ thinkingOverride: thinkingOverrideForTask(),
3155
3552
  thinkingCeiling: agentConfig.maxThinking,
3156
3553
  extensionBindings: params.extensionBindings,
3157
3554
  availableModels,
3555
+ modelResponseAliases,
3158
3556
  preferredModelProvider: currentProvider,
3159
3557
  modelScope: modelScopes,
3160
3558
  skills: effectiveSkills,
@@ -3167,14 +3565,14 @@ async function runSinglePath(data, deps) {
3167
3565
  onDetachReady: (detach) => {
3168
3566
  detachForeground = detach;
3169
3567
  },
3170
- onDetachedExit: (result) => {
3568
+ onDetachedExit: async (result) => {
3171
3569
  if (resolveDetachedWorkflowChild) {
3172
3570
  resolveDetachedWorkflowChild(result);
3173
3571
  return;
3174
3572
  }
3175
3573
  try {
3176
3574
  if (worktreeSetup) {
3177
- finalizeSingleWorktreeHandoff({ worktreeSetup, artifactsDir, runId, cwd: sourceCwd, agent: params.agent, result, workflowKey: params.workflowKey, lane });
3575
+ await finalizeSingleWorktreeHandoff({ worktreeSetup, artifactsDir, runId, cwd: sourceCwd, agent: params.agent, result, workflowKey: params.workflowKey, lane });
3178
3576
  }
3179
3577
  try {
3180
3578
  updateRememberedForegroundChild(deps.state, { runId, mode: "single", cwd: singleCwd, sessionId: data.parentSessionId, index: 0, result, events: deps.dm.events, notify: true });
@@ -3199,7 +3597,7 @@ async function runSinglePath(data, deps) {
3199
3597
  if (foregroundControl)
3200
3598
  finishForegroundChild(foregroundControl, 0);
3201
3599
  } finally {
3202
- removeForegroundControlIfIdle(deps.state, runId);
3600
+ removeForegroundControlIfIdle(deps.state, runId, deps.trackRetainedNestedRoute);
3203
3601
  }
3204
3602
  }
3205
3603
  }
@@ -3210,13 +3608,13 @@ async function runSinglePath(data, deps) {
3210
3608
  toolTimeoutMs: params.toolTimeoutMs,
3211
3609
  configToolTimeoutMs: data.configToolTimeoutMs,
3212
3610
  toolBudget: effectiveToolBudget.toolBudget,
3611
+ usageBudget: data.usageBudget ?? data.inheritedUsageBudget,
3213
3612
  capabilityCeiling: data.capabilityCeiling,
3214
3613
  allowZeroToolBudget: data.allowZeroToolBudget && effectiveToolBudget.toolBudget === data.toolBudget
3215
3614
  }));
3216
3615
  r = launched.detached && detachedWorkflowChild ? await detachedWorkflowChild : launched;
3217
3616
  } catch (error) {
3218
- if (worktreeSetup)
3219
- cleanupWorktrees(worktreeSetup);
3617
+ await cleanupSingleWorktree();
3220
3618
  throw error;
3221
3619
  } finally {
3222
3620
  if (!r?.detached) {
@@ -3231,7 +3629,7 @@ async function runSinglePath(data, deps) {
3231
3629
  }
3232
3630
  let worktreeHandoff;
3233
3631
  if (worktreeSetup) {
3234
- worktreeHandoff = r.detached ? { suffix: pendingHandoff ? formatParallelHandoffReference(pendingHandoff) : "", reference: pendingHandoff } : finalizeSingleWorktreeHandoff({ worktreeSetup, artifactsDir, runId, cwd: sourceCwd, agent: params.agent, result: r, workflowKey: params.workflowKey, lane });
3632
+ worktreeHandoff = r.detached ? { suffix: pendingHandoff ? formatParallelHandoffReference(pendingHandoff) : "", reference: pendingHandoff } : await finalizeSingleWorktreeHandoff({ worktreeSetup, artifactsDir, runId, cwd: sourceCwd, agent: params.agent, result: r, workflowKey: params.workflowKey, lane });
3235
3633
  }
3236
3634
  if (r.progress)
3237
3635
  allProgress.push(r.progress);
@@ -3269,7 +3667,7 @@ async function runSinglePath(data, deps) {
3269
3667
  usageBudget: usageBudgetState(data.usageBudget, totalCost),
3270
3668
  ...worktreeHandoff?.reference ? { parallelHandoff: worktreeHandoff.reference } : {}
3271
3669
  }));
3272
- rememberForegroundRun(deps.state, { runId, mode: "single", cwd: singleCwd, sessionId: data.parentSessionId, results: details.results, params, effectiveOutput, effectiveOutputMode, extensionBindings: params.extensionBindings });
3670
+ rememberForegroundRun(deps.state, { modelResponseAliases, runId, mode: "single", cwd: singleCwd, sessionId: data.parentSessionId, results: details.results, params, effectiveOutput, effectiveOutputMode, extensionBindings: params.extensionBindings, requiredExtensions });
3273
3671
  const suppressRoutineResultIntercom = shouldSuppressRoutineResultIntercom({ suppressRoutineResultIntercom: params.suppressRoutineResultIntercom, results: [r] });
3274
3672
  if (!r.detached && !r.interrupted && !suppressRoutineResultIntercom) {
3275
3673
  if (foregroundControl)
@@ -3340,6 +3738,7 @@ function duplicateSubagentCallResult(params) {
3340
3738
  };
3341
3739
  }
3342
3740
  const workflowLaunchObservers = new WeakMap;
3741
+ const workflowOwnedUsageBudgets = new WeakMap;
3343
3742
  const missionsMissingFromStore = new Set;
3344
3743
  function recordMissionWorkflowChild(binding, workflowRunId, key, update) {
3345
3744
  if (!binding || missionsMissingFromStore.has(binding.missionId))
@@ -3378,30 +3777,34 @@ export async function runMissionWorkflowChild(binding, workflowRunId, key, phase
3378
3777
  throw error;
3379
3778
  }
3380
3779
  }
3381
- export function bindMissionWorkflowChildAsyncLaunch(params, binding, asyncByDefault, asyncId = randomUUID()) {
3780
+ export function bindMissionWorkflowChildAsyncLaunch(params, binding, asyncByDefault, asyncId = randomUUID(), nestedRootRunId) {
3382
3781
  const requestedAsync = params.async ?? asyncByDefault;
3383
3782
  if (!binding || !requestedAsync || params.clarify === true)
3384
3783
  return params;
3385
3784
  const id = asyncId.trim();
3386
3785
  if (!id || path.basename(id) !== id)
3387
3786
  throw new Error("workflow child async id must be a single path segment");
3388
- writeMissionAsyncBinding(path.join(DIRS.async, id), binding);
3787
+ writeMissionAsyncBinding(path.join(nestedRootRunId ? nestedRunScope(nestedRootRunId).asyncDirRoot : DIRS.async, id), binding);
3389
3788
  return { ...params, workflowChildAsyncId: id };
3390
3789
  }
3391
3790
  function workflowChildResult(key, result, childParams = {}, resumeState, forcedTerminalOutcome) {
3791
+ const running = missionWorkflowChildStatus(result) === "running";
3392
3792
  const receiptOutput = result.content.map((part) => part.type === "text" ? part.text : "").filter(Boolean).join(`
3393
3793
  `);
3394
- const output = result.details.results.length === 1 && result.details.results[0]?.finalOutput !== undefined ? result.details.results[0].finalOutput : receiptOutput;
3794
+ const output = running ? "" : result.details.results.length === 1 && result.details.results[0]?.finalOutput !== undefined ? result.details.results[0].finalOutput : receiptOutput;
3395
3795
  const childError = result.details.results.map((child) => child.error).find((error) => Boolean(error));
3396
- const failureError = childError && receiptOutput && receiptOutput !== childError ? `${childError}
3796
+ const failureErrorBase = childError && receiptOutput ? receiptOutput.includes(childError) ? receiptOutput : `${childError}
3397
3797
 
3398
3798
  ${receiptOutput}` : childError || receiptOutput || output || "Child run failed.";
3799
+ 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}`);
3800
+ const failureError = [failureErrorBase, ...savedOutputEvidence].join(`
3801
+ `);
3399
3802
  const detached = result.details.results.some((child) => child.detached);
3400
3803
  const interrupted = result.details.results.some((child) => child.interrupted);
3401
3804
  const stopped = result.details.results.some((child) => child.stopped);
3402
3805
  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);
3403
3806
  const acceptanceRecovery = result.details.results.find((child) => child.acceptance?.recovery)?.acceptance?.recovery;
3404
- const ok = result.isError !== true && !detached && !interrupted && !stopped && acceptanceRecovery === undefined;
3807
+ const ok = result.isError !== true && !running && !detached && !interrupted && !stopped && acceptanceRecovery === undefined;
3405
3808
  const artifactPaths = new Set;
3406
3809
  if (result.details.asyncDir)
3407
3810
  artifactPaths.add(result.details.asyncDir);
@@ -3432,9 +3835,8 @@ ${receiptOutput}` : childError || receiptOutput || output || "Child run failed."
3432
3835
  }
3433
3836
  const requestedContext = childParams.context === "fresh" || childParams.context === "fork" ? childParams.context : undefined;
3434
3837
  const resolvedContext = result.details.context ?? (resolvedContexts.length === 1 ? resolvedContexts[0] : resolvedContexts.length > 1 ? "mixed" : undefined);
3435
- const resumeSourceRunId = typeof childParams.resume === "string" && childParams.resume.trim() ? childParams.resume.trim() : undefined;
3436
- const continuationRunIds = [...new Set([resumeSourceRunId, runId].filter((value) => Boolean(value)))];
3437
3838
  const outputReference = result.details.results.find((child) => child.savedOutputPath)?.savedOutputPath ?? result.details.results.find((child) => child.outputReference?.path)?.outputReference?.path;
3839
+ const outputArtifactPath = running ? undefined : result.details.parallelHandoff?.path ?? result.details.results.find((child) => child.artifactPaths?.outputPath)?.artifactPaths?.outputPath;
3438
3840
  const outputPathMapping = typeof childParams.task === "string" ? outputPathMappingFromTask(childParams.task, outputReference) : undefined;
3439
3841
  const externalResult = result.details.results.length === 1 && result.details.results[0]?.runner?.type === "external-cli" ? result.details.results[0] : undefined;
3440
3842
  const externalStatus = result.details.asyncDir ? readStatus(result.details.asyncDir) : undefined;
@@ -3449,12 +3851,14 @@ ${receiptOutput}` : childError || receiptOutput || output || "Child run failed."
3449
3851
  return {
3450
3852
  key,
3451
3853
  ok,
3854
+ ...running ? { state: "running" } : {},
3855
+ ...result.details.asyncDir ? { asyncDir: result.details.asyncDir } : {},
3452
3856
  ...lane ? { lane } : {},
3453
3857
  ...terminalOutcome ? { terminalOutcome } : {},
3454
3858
  ...resolvedAgents.length === 1 ? { agent: resolvedAgents[0] } : {},
3455
3859
  ...runId ? { runId } : {},
3456
3860
  output,
3457
- ...!ok ? { error: failureError } : {},
3861
+ ...!ok && !running ? { error: failureError } : {},
3458
3862
  ...detached ? { detached: true } : {},
3459
3863
  ...interrupted ? { interrupted: true } : {},
3460
3864
  ...stopped ? { stopped: true } : {},
@@ -3462,11 +3866,12 @@ ${receiptOutput}` : childError || receiptOutput || output || "Child run failed."
3462
3866
  ...requestedContext ? { requestedContext } : {},
3463
3867
  ...resolvedContext ? { resolvedContext } : {},
3464
3868
  ...outputReference ? { outputReference } : {},
3869
+ ...outputArtifactPath ? { outputArtifactPath } : {},
3465
3870
  ...acceptanceRecovery ? { recovery: acceptanceRecovery } : {},
3466
3871
  ...outputPathMapping ? { outputPathMapping } : {},
3467
3872
  ...externalAdapter ? { externalAdapter } : {},
3468
3873
  resumability,
3469
- continuation: { runIds: continuationRunIds },
3874
+ continuation: { runIds: runId ? [runId] : [] },
3470
3875
  artifactPaths: [...artifactPaths],
3471
3876
  results: result.details.results
3472
3877
  };
@@ -3482,10 +3887,23 @@ function workflowChildAccountingFields(child) {
3482
3887
  ...child.recovery ? { recovery: child.recovery } : {}
3483
3888
  };
3484
3889
  }
3890
+ function workflowRunningChildrenSummary(children) {
3891
+ const running = children.filter((child) => child.state === "running");
3892
+ 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
+ }
3894
+ function workflowResultChildren(children, status, includeFailureFields) {
3895
+ return children.map((child) => {
3896
+ 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 } } : {} };
3898
+ });
3899
+ }
3485
3900
  function workflowOutputPathMappingSummary(children) {
3486
3901
  const mappings = children.flatMap((child) => child.outputPathMapping ? [`'${child.key}': requested ${child.outputPathMapping.requestedPath} -> saved ${child.outputPathMapping.savedPath}`] : []);
3487
3902
  return mappings.length > 0 ? ` Output path mappings: ${mappings.join("; ")}.` : "";
3488
3903
  }
3904
+ function workflowDetailsResults(children) {
3905
+ return children.flatMap((child) => (child.results ?? []).map((result) => result.workflowKey ? result : { ...result, workflowKey: child.key }));
3906
+ }
3489
3907
  function workflowSteerReceipt(key, result) {
3490
3908
  const steering = result.details.steering;
3491
3909
  const error = result.content.map((part) => part.type === "text" ? part.text : "").filter(Boolean).join(`
@@ -3502,6 +3920,7 @@ function workflowSteerReceipt(key, result) {
3502
3920
  ...state === "failed" && error ? { error } : {}
3503
3921
  };
3504
3922
  }
3923
+ const CHILD_SESSION_NOT_RUNNING_YET = "Child session is not running yet.";
3505
3924
  const MAX_WORKFLOW_RESUME_HINT_BYTES = 1024;
3506
3925
  const MAX_WORKFLOW_CHILD_RUN_ID_BYTES = 256;
3507
3926
  const WORKFLOW_RESUME_HINT_PARENT_STATES = new Set(["complete", "failed", "partial"]);
@@ -3553,7 +3972,29 @@ function missingWorkflowReceiptResumeHint(reference, state) {
3553
3972
  return;
3554
3973
  }
3555
3974
  }
3556
- function resolveKeyedWorkflowResume(reference, state) {
3975
+ function resolveWorkflowResume(reference, deps, parentSessionFile, index) {
3976
+ const state = deps.state;
3977
+ if (typeof reference === "string") {
3978
+ const target = resolveRequestedResumeTarget({ id: reference.trim(), ...index !== undefined ? { index } : {} }, deps, parentSessionFile);
3979
+ if (target.kind !== "revive")
3980
+ return reference.trim();
3981
+ const runId = target.runId;
3982
+ const status = target.source === "async" && target.asyncDir ? readStatus(target.asyncDir) : undefined;
3983
+ if (status?.runId === runId && status.parentWorkflowRunId && status.workflowKey) {
3984
+ const receiptPath = workflowReceiptPath(DIRS.async, status.parentWorkflowRunId);
3985
+ try {
3986
+ fs.statSync(receiptPath);
3987
+ } catch (error) {
3988
+ if (error.code === "ENOENT")
3989
+ return { runId, runIds: [runId] };
3990
+ throw error;
3991
+ }
3992
+ const entry = readWorkflowReceipt(DIRS.async, status.parentWorkflowRunId).entries[status.workflowKey];
3993
+ if (entry?.latestRunId === runId)
3994
+ return { runId, runIds: entry.continuation.runIds };
3995
+ }
3996
+ return { runId, runIds: [runId] };
3997
+ }
3557
3998
  try {
3558
3999
  const entry = resolveWorkflowReceiptResumeEntry({
3559
4000
  reference,
@@ -3564,10 +4005,7 @@ function resolveKeyedWorkflowResume(reference, state) {
3564
4005
  throw new Error(`Workflow receipt child '${reference.key}' latest run '${runId}' is still running.`);
3565
4006
  }
3566
4007
  });
3567
- const runId = entry.latestRunId;
3568
- if (!runId)
3569
- throw new Error(`Workflow receipt child '${reference.key}' has no retained run id.`);
3570
- return { runId, runIds: entry.continuation.runIds };
4008
+ return { runId: entry.latestRunId, runIds: entry.continuation.runIds };
3571
4009
  } catch (error) {
3572
4010
  const workflowRunId = reference.workflowRunId.trim();
3573
4011
  if (isMissingWorkflowReceiptDiagnostic(error, workflowRunId)) {
@@ -3578,8 +4016,8 @@ function resolveKeyedWorkflowResume(reference, state) {
3578
4016
  throw error;
3579
4017
  }
3580
4018
  }
3581
- function terminalWorkflowReceipt(workflowRunId, state, children, workflowChildren, terminalOutcome, hostSteps) {
3582
- return buildWorkflowReceipt({ workflowRunId, state, children, workflowChildren, terminalOutcome, hostSteps });
4019
+ function terminalWorkflowReceipt(workflowRunId, state, children, workflowChildren, terminalOutcome, hostSteps, resource, argsDigest) {
4020
+ return buildWorkflowReceipt({ workflowRunId, state, children, workflowChildren, terminalOutcome, hostSteps, resource, ...argsDigest ? { argsDigest } : {} });
3583
4021
  }
3584
4022
  function workflowFailureTerminalOutcome(error, _children, usageBudget) {
3585
4023
  if (usageBudget?.exhausted)
@@ -3592,24 +4030,23 @@ function workflowFailureMessage(error, workflowRunId, children) {
3592
4030
  if (children.length === 0 && text.includes(validationPrefix)) {
3593
4031
  return `Workflow '${workflowRunId}' validation failed before child launch; no children launched.${text.slice(text.indexOf(validationPrefix) + validationPrefix.length)}`;
3594
4032
  }
3595
- return text;
4033
+ return [text, workflowRunningChildrenSummary(children)].filter(Boolean).join(" ");
3596
4034
  }
3597
4035
  export async function steerWorkflowChildByKey(input) {
3598
4036
  const asyncDirRoot = input.asyncDirRoot ?? DIRS.async;
3599
4037
  const ackTimeoutMs = input.options.ackTimeoutMs ?? 3000;
3600
4038
  const deadline = Date.now() + ackTimeoutMs;
3601
4039
  while (true) {
3602
- const control = [...input.state.foregroundControls.values()].find((candidate) => candidate.parentWorkflowRunId === input.workflowRunId && candidate.workflowKey === input.key && Boolean(candidate.workflowSteeringDir) && (candidate.activeChildren?.size ?? 0) > 0);
4040
+ const control = [...input.state.foregroundControls.values()].find((candidate) => candidate.parentWorkflowRunId === input.workflowRunId && candidate.workflowKey === input.key && (candidate.activeChildren?.size ?? 0) > 0);
3603
4041
  if (control) {
3604
4042
  const result = await steerWorkflowForegroundTarget({
3605
4043
  target: { control, workflowRunId: input.workflowRunId, sourceRunId: control.runId },
3606
4044
  message: input.message,
3607
4045
  mode: input.options.mode,
3608
- index: input.options.index,
3609
- ackTimeoutMs: Math.max(1, deadline - Date.now()),
3610
- signal: input.signal
4046
+ index: input.options.index
3611
4047
  });
3612
- return workflowSteerReceipt(input.key, result);
4048
+ if (!result.details.steering?.targets.some((target) => target.reason === CHILD_SESSION_NOT_RUNNING_YET) || Date.now() >= deadline)
4049
+ return workflowSteerReceipt(input.key, result);
3613
4050
  }
3614
4051
  const workflowStatus = readStatus(path.join(asyncDirRoot, input.workflowRunId));
3615
4052
  const step = workflowStatus?.steps?.find((candidate) => candidate.workflowKey === input.key);
@@ -3649,7 +4086,33 @@ export async function steerWorkflowChildByKey(input) {
3649
4086
  await new Promise((resolve) => setTimeout(resolve, Math.min(10, Math.max(1, deadline - Date.now()))));
3650
4087
  }
3651
4088
  }
4089
+ export async function preflightWorkflowWorktrees(input) {
4090
+ const sources = new Map;
4091
+ for (const { key, params } of input.calls) {
4092
+ if (params.resume !== undefined)
4093
+ continue;
4094
+ const effective = prepareWorkflowLaunchParams(input.workflowDefaults, params, "preflight", key);
4095
+ if ((effective.worktree ?? input.defaultWorktree) !== true)
4096
+ continue;
4097
+ const cwd = resolveRequestedCwd(input.ctxCwd, effective.cwd);
4098
+ const keys = sources.get(cwd) ?? [];
4099
+ keys.push(key);
4100
+ sources.set(cwd, keys);
4101
+ }
4102
+ for (const [cwd, keys] of sources) {
4103
+ try {
4104
+ await preflightWorktreeSource(cwd, { signal: input.signal, deadlineAt: input.deadlineAt });
4105
+ } catch (error) {
4106
+ throw new Error(`Worktree admission failed for ${keys.map((key) => `'${key}'`).join(", ")} at ${cwd}: ${error instanceof Error ? error.message : String(error)} Select the correct cwd or arrange an operator-approved commit/stash.`, { cause: error });
4107
+ }
4108
+ }
4109
+ input.signal.throwIfAborted();
4110
+ }
3652
4111
  export function prepareWorkflowLaunchParams(workflowDefaults, childParams, parentWorkflowRunId, workflowKey, options = {}) {
4112
+ const { globalConcurrencyLimit: _globalConcurrencyLimit, maxSubagentSpawnsPerRun: _maxSubagentSpawnsPerRun, ...workflowDefaultsWithoutCapacity } = workflowDefaults;
4113
+ const { globalConcurrencyLimit: _childGlobalConcurrencyLimit, maxSubagentSpawnsPerRun: _childMaxSubagentSpawnsPerRun, ...childParamsWithoutCapacity } = childParams;
4114
+ workflowDefaults = workflowDefaultsWithoutCapacity;
4115
+ childParams = childParamsWithoutCapacity;
3653
4116
  const capabilityCeiling = intersectSubagentCapabilityCeilings(workflowDefaults.capabilityCeiling, options.capabilityCeiling);
3654
4117
  const lane = normalizeWorkflowLaneMetadata(Object.hasOwn(childParams, "lane") ? childParams.lane : workflowDefaults.lane, `workflow child '${workflowKey}'.lane`);
3655
4118
  assertWorkflowLaneKey(lane, workflowKey, `workflow child '${workflowKey}'.lane`);
@@ -3665,11 +4128,12 @@ export function prepareWorkflowLaunchParams(workflowDefaults, childParams, paren
3665
4128
  const toolBudget = childParams.toolBudget ?? workflowDefaults.toolBudget;
3666
4129
  const intercomBridge = childParams.intercomBridge ?? workflowDefaults.intercomBridge;
3667
4130
  const worktree = childParams.worktree ?? workflowDefaults.worktree;
4131
+ const baseRef = Object.hasOwn(childParams, "baseRef") ? childParams.baseRef : undefined;
3668
4132
  const outputSchema = Object.hasOwn(childParams, "outputSchema") ? childParams.outputSchema : workflowDefaults.outputSchema;
3669
- if (outputSchema !== undefined)
4133
+ if (outputSchema !== undefined && outputSchema !== false)
3670
4134
  assertJsonSchemaObject(outputSchema, "outputSchema");
3671
4135
  const agentContract = Object.hasOwn(childParams, "agentContract") ? childParams.agentContract : workflowDefaults.agentContract;
3672
- if (agentContract !== undefined && !isAgentContractV1(agentContract))
4136
+ if (agentContract !== undefined && !isAgentContract(agentContract))
3673
4137
  throw new Error("agentContract must be { version: 1 }.");
3674
4138
  const acceptance = Object.hasOwn(childParams, "acceptance") ? childParams.acceptance : workflowDefaults.acceptance;
3675
4139
  const output = Object.hasOwn(childParams, "output") ? childParams.output : workflowDefaults.output;
@@ -3678,6 +4142,7 @@ export function prepareWorkflowLaunchParams(workflowDefaults, childParams, paren
3678
4142
  const outputMode = Object.hasOwn(childParams, "outputMode") ? childParams.outputMode : workflowDefaults.outputMode;
3679
4143
  if (outputMode !== undefined && outputMode !== "inline" && outputMode !== "file-only")
3680
4144
  throw new Error("outputMode must be 'inline' or 'file-only'.");
4145
+ const control = mergeWorkflowControlOverrides(workflowDefaults.control, childParams.control);
3681
4146
  return {
3682
4147
  action: "resume",
3683
4148
  id: childParams.resume.trim(),
@@ -3685,8 +4150,10 @@ export function prepareWorkflowLaunchParams(workflowDefaults, childParams, paren
3685
4150
  message: typeof childParams.task === "string" ? childParams.task.trim() : "",
3686
4151
  workflowParentRunId: parentWorkflowRunId,
3687
4152
  workflowKey,
4153
+ ...options.outputClaimPath ? { workflowOutputClaimPath: options.outputClaimPath } : {},
3688
4154
  ...lane ? { lane } : {},
3689
4155
  ...worktree !== undefined ? { worktree } : {},
4156
+ ...baseRef !== undefined ? { baseRef } : {},
3690
4157
  ...outputSchema !== undefined ? { outputSchema } : {},
3691
4158
  ...agentContract !== undefined ? { agentContract } : {},
3692
4159
  ...acceptance !== undefined ? { acceptance } : {},
@@ -3696,15 +4163,19 @@ export function prepareWorkflowLaunchParams(workflowDefaults, childParams, paren
3696
4163
  ...options.missionDetached ? { mission: false } : {},
3697
4164
  ...timeoutMs !== undefined ? { timeoutMs } : {},
3698
4165
  ...toolBudget !== undefined ? { toolBudget } : {},
4166
+ ...control !== undefined ? { control } : {},
3699
4167
  ...intercomBridge !== undefined ? { intercomBridge } : {},
3700
4168
  ...capabilityCeiling ? { capabilityCeiling } : {}
3701
4169
  };
3702
4170
  }
4171
+ const control = mergeWorkflowControlOverrides(workflowDefaults.control, childParams.control);
4172
+ const asyncOmitted = childParams.async === undefined && workflowDefaults.async === undefined;
3703
4173
  const launchParams = {
3704
4174
  ...workflowDefaults,
3705
- async: options.externalAsyncRequired === true && childParams.async === undefined && workflowDefaults.async === undefined ? true : false,
4175
+ ...options.externalAsyncRequired === true && asyncOmitted ? { async: true } : {},
3706
4176
  ...childParams,
3707
- ...options.externalAsyncRequired === true && childParams.async === undefined && workflowDefaults.async === undefined ? { workflowAwaitAsync: true } : {},
4177
+ ...control !== undefined ? { control } : {},
4178
+ ...asyncOmitted ? { workflowAwaitAsync: true } : {},
3708
4179
  ...options.missionDetached ? { mission: false } : {},
3709
4180
  workflowParentRunId: parentWorkflowRunId,
3710
4181
  workflowKey,
@@ -3723,6 +4194,18 @@ export function prepareWorkflowLaunchParams(workflowDefaults, childParams, paren
3723
4194
  throw new Error(normalizedGate.error);
3724
4195
  return normalizedGate.params;
3725
4196
  }
4197
+ function mergeWorkflowControlOverrides(workflowControl, childControl) {
4198
+ if (childControl === undefined)
4199
+ return workflowControl;
4200
+ if (workflowControl === undefined)
4201
+ return childControl;
4202
+ return { ...workflowControl, ...childControl };
4203
+ }
4204
+ export function resolveRevivalControlConfig(input) {
4205
+ if (input.requestedControl === undefined)
4206
+ return input.recoveryControlConfig ?? resolveControlConfig(input.globalConfig, undefined);
4207
+ return resolveControlConfig(input.recoveryControlConfig ?? input.globalConfig, input.requestedControl);
4208
+ }
3726
4209
  function normalizeGateParams(params) {
3727
4210
  if (params.gate !== undefined && params.action === "resume") {
3728
4211
  return { ok: false, error: "gate is not supported with action='resume'; resume uses the retained child contract." };
@@ -3735,6 +4218,16 @@ function normalizeGateParams(params) {
3735
4218
  const { gate: _gate, ...rest } = params;
3736
4219
  return { ok: true, params: { ...rest, ...normalized.acceptance !== undefined ? { acceptance: normalized.acceptance } : {} } };
3737
4220
  }
4221
+ function describeTypedVerifyOutputSchemaConflict(effective, requested) {
4222
+ if (!acceptanceHasTypedVerify(effective.acceptance))
4223
+ return;
4224
+ if (effective.outputSchema === undefined || effective.outputSchema === false)
4225
+ return;
4226
+ const agent = effective.agent ?? "?";
4227
+ const schemaSource = requested.outputSchema !== undefined && requested.outputSchema !== false ? "outputSchema" : `agent '${agent}' outputSchema`;
4228
+ const verifySource = requested.gate !== undefined ? "gate.output" : requested.acceptance !== undefined ? "acceptance.verify" : `agent '${agent}' defaultAcceptance`;
4229
+ return `${verifySource}: ${TYPED_VERIFY_OUTPUT_SCHEMA_CONFLICT.replace("with outputSchema", `with ${schemaSource}`)}`;
4230
+ }
3738
4231
  function formatWorkflowValue(value) {
3739
4232
  if (value === undefined)
3740
4233
  return "(undefined)";
@@ -3842,9 +4335,7 @@ function applyWorkflowLaneTrace(graph, trace) {
3842
4335
  else
3843
4336
  delete graph.currentNodeId;
3844
4337
  }
3845
- function workflowChatProgressUpdate(runId, chatProgress, workflow, workflowChildren, preflight) {
3846
- if (chatProgress.mode !== "live-card")
3847
- return;
4338
+ function workflowProgressUpdate(runId, chatProgress, workflow, workflowChildren, preflight) {
3848
4339
  return {
3849
4340
  content: [{ type: "text", text: "Workflow running." }],
3850
4341
  details: { mode: "workflow", runId, results: [], workflow, ...preflight ? { preflight } : {}, ...workflowChildren ? { workflowChildren } : {}, chatProgress }
@@ -3885,14 +4376,19 @@ export function createSubagentExecutor(deps) {
3885
4376
  const delegatedThinkingOverrides = new WeakMap;
3886
4377
  const delegatedZeroToolBudgets = new WeakSet;
3887
4378
  const delegatedExecutions = new WeakSet;
4379
+ const publicExecutions = new WeakSet;
4380
+ const workflowResourcePermits = new WeakMap;
3888
4381
  const workflowPermitContexts = new WeakMap;
3889
4382
  const warnedArtifactPackageDirs = new Set;
3890
4383
  const scheduledOwnerExecutors = new Map;
3891
4384
  const execute = async (_id, params, signal, onUpdate, ctx, preserveActiveSession = false, parentModelOverride) => {
3892
4385
  const workflowLaunchObserver = workflowLaunchObservers.get(params);
4386
+ const inheritedUsageBudget = workflowOwnedUsageBudgets.get(params);
3893
4387
  const delegatedThinkingOverride = delegatedThinkingOverrides.get(params);
3894
4388
  const allowZeroToolBudget = delegatedZeroToolBudgets.has(params);
3895
4389
  const delegatedExecution = delegatedExecutions.has(params);
4390
+ const publicExecution = publicExecutions.has(params);
4391
+ const workflowResourcePermit = workflowResourcePermits.get(params);
3896
4392
  const workflowPermitContext = workflowPermitContexts.get(params);
3897
4393
  const delegatedWorkflowPermit = workflowPermitContext && "root" in workflowPermitContext ? workflowPermitContext.root : undefined;
3898
4394
  const workflowChildPermitLaunch = workflowPermitContext && "child" in workflowPermitContext ? workflowPermitContext.child : undefined;
@@ -3905,6 +4401,9 @@ export function createSubagentExecutor(deps) {
3905
4401
  if (!normalizedGate.ok)
3906
4402
  return buildRequestedModeError(params, normalizedGate.error);
3907
4403
  let requestParams = normalizedGate.params;
4404
+ const capacityOverrideError = validateWorkflowCapacityOverrides(requestParams);
4405
+ if (capacityOverrideError)
4406
+ return buildRequestedModeError(requestParams, capacityOverrideError);
3908
4407
  let workflowPreflight;
3909
4408
  try {
3910
4409
  if (requestParams.preflight !== undefined && requestParams.workflowScript === undefined && requestParams.workflowScriptPath === undefined) {
@@ -3916,7 +4415,9 @@ export function createSubagentExecutor(deps) {
3916
4415
  } catch (error) {
3917
4416
  const message = error instanceof Error ? error.message : String(error);
3918
4417
  if (requestParams.action?.trim() === "validate") {
3919
- const validation = validateWorkflowScript(requestParams.workflowScript ?? "");
4418
+ const validation = validateWorkflowScript(requestParams.workflowScript ?? "", {
4419
+ maxSubagentSpawnsPerRun: requestParams.maxSubagentSpawnsPerRun ?? resolveMaxSubagentSpawnsPerRun(deps.config.maxSubagentSpawnsPerRun)
4420
+ });
3920
4421
  const invalidValidation = { ...validation, ok: false, errors: [...validation.errors, { message }] };
3921
4422
  return {
3922
4423
  content: [{ type: "text", text: JSON.stringify(invalidValidation) }],
@@ -3927,20 +4428,44 @@ export function createSubagentExecutor(deps) {
3927
4428
  return buildRequestedModeError(requestParams, message);
3928
4429
  }
3929
4430
  if (requestParams.action?.trim() === "validate") {
3930
- const validation = validateWorkflowScript(requestParams.workflowScript ?? "");
3931
- const payload = workflowPreflight ? { ...validation, preflight: workflowPreflight } : validation;
3932
- return {
3933
- content: [{ type: "text", text: JSON.stringify(payload) }],
3934
- ...validation.ok ? {} : { isError: true },
3935
- details: { mode: "management", results: [] }
3936
- };
4431
+ const validation = validateWorkflowScript(requestParams.workflowScript ?? "", {
4432
+ maxSubagentSpawnsPerRun: requestParams.maxSubagentSpawnsPerRun ?? resolveMaxSubagentSpawnsPerRun(deps.config.maxSubagentSpawnsPerRun)
4433
+ });
4434
+ return buildWorkflowValidationResult(validation, "management", workflowPreflight);
3937
4435
  }
3938
4436
  const normalizedAction = typeof requestParams.action === "string" ? requestParams.action.trim() : requestParams.action;
3939
4437
  if (normalizedAction === "resume" && requestParams.extensionBindings !== undefined)
3940
4438
  return buildRequestedModeError(requestParams, "extensionBindings is not supported with action='resume'; resume uses the original retained child binding.");
4439
+ let workflowResource;
4440
+ if (workflowResourcePermit) {
4441
+ if (typeof requestParams.workflowScript !== "string")
4442
+ return buildRequestedModeError(requestParams, "Resolved workflow resource is missing its workflow script.");
4443
+ const consumed = consumeWorkflowResourcePermit(workflowResourcePermit, requestParams.workflowScript);
4444
+ if (typeof consumed === "string")
4445
+ return buildRequestedModeError(requestParams, consumed);
4446
+ workflowResource = { permit: workflowResourcePermit, ...consumed };
4447
+ }
3941
4448
  if (requestParams.workflowScript !== undefined && normalizedAction === undefined) {
4449
+ const workflowArgsEvidence = requestParams.args === undefined ? undefined : { args: requestParams.args, argsDigest: stableJsonDigest(requestParams.args) };
4450
+ const workflowArgs = workflowArgsEvidence?.args;
4451
+ const workflowArgsDigest = workflowArgsEvidence?.argsDigest;
4452
+ const workflowValidation = validateWorkflowScript(requestParams.workflowScript, {
4453
+ maxSubagentSpawnsPerRun: requestParams.maxSubagentSpawnsPerRun ?? resolveMaxSubagentSpawnsPerRun(deps.config.maxSubagentSpawnsPerRun)
4454
+ });
4455
+ if (!workflowValidation.ok && publicExecution)
4456
+ 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(" ")}`);
4460
+ }
4461
+ for (const warning of workflowValidation.warnings ?? [])
4462
+ console.warn(`[dm-subagents] ${warning.message}`);
4463
+ const acceptanceErrors = validateAcceptanceInput(requestParams.acceptance);
4464
+ if (acceptanceErrors.length > 0)
4465
+ return buildRequestedModeError(requestParams, acceptanceErrors.join(" "));
4466
+ const foregroundWorkflowRunId = encodeIndexSegment(_id);
3942
4467
  if (delegatedWorkflowPermit) {
3943
- const permitError = validateWorkflowChildPermitRoot(delegatedWorkflowPermit, _id);
4468
+ const permitError = validateWorkflowChildPermitRoot(delegatedWorkflowPermit, foregroundWorkflowRunId);
3944
4469
  if (permitError)
3945
4470
  return buildRequestedModeError(requestParams, permitError);
3946
4471
  if (requestParams.async !== false)
@@ -3988,9 +4513,9 @@ export function createSubagentExecutor(deps) {
3988
4513
  const scriptFirstLine = requestParams.workflowScript.split(/\r?\n/).map((line) => line.trim()).find(Boolean) || "Workflow";
3989
4514
  const boundedScriptPreview = scriptFirstLine.length > 100 ? `${scriptFirstLine.slice(0, 97)}...` : scriptFirstLine;
3990
4515
  const derivedObjective = previewAgent ? `Workflow: ${previewAgent}` : boundedScriptPreview;
3991
- const workflowDepth = checkSubagentDepth(deps.config.maxSubagentDepth).depth;
4516
+ const workflowDepth = checkSubagentDepth(deps.config.maxSubagentDepth, deps.childRuntime).depth;
3992
4517
  const asyncWorkflow = requestParams.async !== false;
3993
- const topLevelAsyncWorkflow = asyncWorkflow && workflowDepth === 0 && !resolveInheritedNestedRouteFromEnv() && !requestParams.workflowParentRunId;
4518
+ const topLevelAsyncWorkflow = asyncWorkflow && workflowDepth === 0 && !inheritedNestedRoute(deps) && !requestParams.workflowParentRunId;
3994
4519
  const workflowRunId = asyncWorkflow ? randomUUID() : undefined;
3995
4520
  let workflowCapacity;
3996
4521
  if (workflowRunId && topLevelAsyncWorkflow) {
@@ -4013,7 +4538,7 @@ export function createSubagentExecutor(deps) {
4013
4538
  }
4014
4539
  let workflowFanoutBudget;
4015
4540
  try {
4016
- workflowFanoutBudget = requestParams.runFanoutBudget ?? decodeRunFanoutBudgetDescriptor(process.env[RUN_FANOUT_BUDGET_ENV]) ?? createRunFanoutBudget(_id, resolveMaxSubagentSpawnsPerRun(deps.config.maxSubagentSpawnsPerRun));
4541
+ workflowFanoutBudget = requestParams.runFanoutBudget ?? inheritedRunFanoutBudget(deps) ?? createRunFanoutBudget(_id, requestParams.maxSubagentSpawnsPerRun ?? resolveMaxSubagentSpawnsPerRun(deps.config.maxSubagentSpawnsPerRun));
4017
4542
  } catch (error) {
4018
4543
  workflowCapacity?.rollback();
4019
4544
  return { content: [{ type: "text", text: error instanceof Error ? error.message : String(error) }], isError: true, details: { mode: "workflow", results: [] } };
@@ -4087,9 +4612,10 @@ export function createSubagentExecutor(deps) {
4087
4612
  ...workflowSessionRoot ? { sessionRoot: workflowSessionRoot } : {},
4088
4613
  ...requestParams.scheduleOrigin ? { scheduleOrigin: requestParams.scheduleOrigin } : {},
4089
4614
  pid: process.pid,
4615
+ ...workflowCapabilityCeiling ? { admissionCapabilityCeiling: workflowCapabilityCeiling } : {},
4090
4616
  steps: [],
4091
4617
  ...workflowPreflight ? { preflight: workflowPreflight } : {},
4092
- workflow: { trace: [], emits: [], console: [] },
4618
+ workflow: { trace: [], emits: [], console: [], ...workflowArgsEvidence ?? {}, ...workflowResource ? { resource: workflowResource.provenance } : {} },
4093
4619
  workflowChildren: workflowChildSummary({ parentToolCallId: toolCallId, workflowRunId, workflowState: "running", inventoryComplete: false }),
4094
4620
  runFanoutBudget: getRunFanoutBudgetSnapshot(workflowFanoutBudget)
4095
4621
  };
@@ -4109,22 +4635,63 @@ export function createSubagentExecutor(deps) {
4109
4635
  },
4110
4636
  onError: (error, filePath) => console.error(`Failed to update async workflow index '${filePath}':`, error)
4111
4637
  });
4112
- const queueActiveRunIndex = () => {
4113
- const state = status.state;
4638
+ const queueActiveRunIndex = (snapshot = status) => {
4639
+ const state = snapshot.state;
4114
4640
  if (indexedState === state && indexPersistence.pendingCount() === 0)
4115
4641
  return;
4116
- indexPersistence.write(asyncDir, { state, toolCallId: status.toolCallId }, (_filePath, payload) => {
4642
+ indexPersistence.write(asyncDir, { state, toolCallId: snapshot.toolCallId }, (_filePath, payload) => {
4117
4643
  const indexPayload = payload;
4118
4644
  updateActiveRunIndex(asyncDir, indexPayload.state, indexPayload.toolCallId, { retryCapacityErrors: true });
4119
4645
  });
4120
4646
  };
4647
+ let pendingResultPublication;
4648
+ let settleResultPublication;
4649
+ let resultWriteFailureWakeDelivered = false;
4650
+ const reportResultWriteFailure = (error) => {
4651
+ const message = `Failed to write async workflow result ${resultPath}: ${error instanceof Error ? error.message : String(error)}`;
4652
+ console.error(message, error);
4653
+ try {
4654
+ if (currentSessionId && fallbackResultPayloadPathForSessionRun(path.dirname(resultPath), currentSessionId, workflowRunId))
4655
+ return true;
4656
+ } catch (pendingError) {
4657
+ console.error(`Failed to verify pending async workflow result '${workflowRunId}':`, pendingError);
4658
+ }
4659
+ appendWorkflowEvent({ type: "subagent.workflow.result_write_failed", error: message });
4660
+ if (resultWriteFailureWakeDelivered)
4661
+ return false;
4662
+ if (deps.state.currentSessionId !== currentSessionId || deps.state.completionOwnerId !== completionOwnerId)
4663
+ return false;
4664
+ try {
4665
+ deps.dm.sendMessage({
4666
+ customType: "subagent-workflow-result-write-failed",
4667
+ content: message,
4668
+ display: true
4669
+ }, { triggerTurn: true });
4670
+ resultWriteFailureWakeDelivered = true;
4671
+ } catch (sendError) {
4672
+ console.error(`Failed to send workflow result write failure notification for '${workflowRunId}':`, sendError);
4673
+ }
4674
+ deps.refreshResultDelivery?.();
4675
+ return false;
4676
+ };
4677
+ const pendingWorkflowChildAnnouncements = new Map;
4678
+ let announcePersistedWorkflowChildren = () => {};
4121
4679
  const runPersistence = createCapacityResilientJsonWriter({
4122
4680
  keepAlive: true,
4123
- onSuccess: (filePath) => {
4124
- if (filePath === statusPath)
4125
- queueActiveRunIndex();
4681
+ onSuccess: (filePath, payload) => {
4682
+ if (filePath === statusPath) {
4683
+ announcePersistedWorkflowChildren();
4684
+ queueActiveRunIndex(payload);
4685
+ }
4686
+ if (filePath === resultPath)
4687
+ settleResultPublication?.(true);
4688
+ },
4689
+ onError: (error, filePath) => {
4690
+ if (filePath === resultPath)
4691
+ settleResultPublication?.(reportResultWriteFailure(error));
4692
+ else
4693
+ console.error(`Failed to persist async workflow state '${filePath}':`, error);
4126
4694
  },
4127
- onError: (error, filePath) => console.error(`Failed to persist async workflow state '${filePath}':`, error),
4128
4695
  write: (filePath, payload) => filePath === resultPath ? writeAsyncResultFile(filePath, payload) : writeAtomicJson(filePath, payload)
4129
4696
  });
4130
4697
  let initialPersistenceComplete = false;
@@ -4145,8 +4712,9 @@ export function createSubagentExecutor(deps) {
4145
4712
  queueActiveRunIndex();
4146
4713
  } else if (options.tolerateStatusWriteFailure) {
4147
4714
  try {
4148
- runPersistence.write(statusPath, status);
4149
- statusPersistenceDegraded = false;
4715
+ runPersistence.write(statusPath, { ...status });
4716
+ if (runPersistence.pendingCount() === 0)
4717
+ statusPersistenceDegraded = false;
4150
4718
  } catch (error) {
4151
4719
  const message = `Failed to persist async workflow state ${statusPath}: ${error instanceof Error ? error.message : String(error)}`;
4152
4720
  console.error(message, error);
@@ -4160,7 +4728,7 @@ export function createSubagentExecutor(deps) {
4160
4728
  }
4161
4729
  }
4162
4730
  } else {
4163
- runPersistence.write(statusPath, status);
4731
+ runPersistence.write(statusPath, { ...status });
4164
4732
  }
4165
4733
  if (liveJob) {
4166
4734
  liveJob.status = status.state;
@@ -4188,13 +4756,19 @@ export function createSubagentExecutor(deps) {
4188
4756
  };
4189
4757
  const writeWorkflowResult = (payload) => {
4190
4758
  try {
4759
+ let resultPublished = false;
4760
+ settleResultPublication = (published) => {
4761
+ resultPublished = published;
4762
+ };
4763
+ pendingResultPublication = undefined;
4191
4764
  runPersistence.write(resultPath, payload);
4765
+ if (!resultPublished)
4766
+ pendingResultPublication = new Promise((resolve) => {
4767
+ settleResultPublication = resolve;
4768
+ });
4192
4769
  return true;
4193
4770
  } catch (error) {
4194
- const message = `Failed to write async workflow result ${resultPath}: ${error instanceof Error ? error.message : String(error)}`;
4195
- console.error(message, error);
4196
- appendWorkflowEvent({ type: "subagent.workflow.result_write_failed", error: message });
4197
- return false;
4771
+ return reportResultWriteFailure(error);
4198
4772
  }
4199
4773
  };
4200
4774
  const projectWorkflowActivity = () => {
@@ -4227,22 +4801,221 @@ export function createSubagentExecutor(deps) {
4227
4801
  indexPersistence.dispose();
4228
4802
  return { content: [{ type: "text", text: `Failed to create async workflow storage: ${error instanceof Error ? error.message : String(error)}` }], isError: true, details: { mode: "workflow", results: [] } };
4229
4803
  }
4230
- appendWorkflowEvent({ type: "subagent.workflow.started" });
4804
+ appendWorkflowEvent({ type: "subagent.workflow.started", ...workflowArgsDigest ? { argsDigest: workflowArgsDigest } : {} });
4805
+ try {
4806
+ deps.dm.events.emit(SUBAGENT_ASYNC_STARTED_EVENT, {
4807
+ lifecycleArtifactVersion: SUBAGENT_LIFECYCLE_ARTIFACT_VERSION,
4808
+ id: workflowRunId,
4809
+ asyncDir,
4810
+ cwd: workflowCwd,
4811
+ ...workflowSessionRoot ? { sessionRoot: workflowSessionRoot } : {},
4812
+ pid: process.pid,
4813
+ sessionId: currentSessionId ?? undefined,
4814
+ completionOwnerId,
4815
+ mode: "workflow",
4816
+ agent: "workflow",
4817
+ goal: derivedObjective.trim() ? PROMPT_REDACTED : undefined,
4818
+ ...timeout !== undefined ? { timeoutMs: timeout, deadlineAt: startedAt + timeout } : {}
4819
+ });
4820
+ } catch (error) {
4821
+ console.error("Failed to emit async workflow start event:", error);
4822
+ }
4823
+ const emitWorkflowSteerEvent = (type, requestId, index, extra = {}) => {
4824
+ appendWorkflowEvent({ type, requestId, ...index !== undefined ? { index } : {}, ...extra });
4825
+ };
4826
+ const recordWorkflowSteerTargets = (request, targets) => {
4827
+ status.steering ??= createSteeringStatus();
4828
+ recordSteeringRequest(steeringStatus(status), {
4829
+ id: request.id,
4830
+ requestedAt: request.ts,
4831
+ ...request.source ? { source: request.source } : {},
4832
+ message: request.message,
4833
+ targets
4834
+ });
4835
+ };
4836
+ const explicitWorkflowSteerIndexes = (request) => request.targetIndex !== undefined ? [request.targetIndex] : request.targetIndexes;
4837
+ const failWorkflowSteer = (request, indexes, reason) => {
4838
+ const targets = indexes.map((index) => ({ index, state: "failed", reason }));
4839
+ recordWorkflowSteerTargets(request, targets);
4840
+ emitWorkflowSteerEvent("subagent.steer.requested", request.id, undefined, { targets });
4841
+ for (const index of indexes)
4842
+ emitWorkflowSteerEvent("subagent.steer.failed", request.id, index, { reason });
4843
+ persist({ tolerateStatusWriteFailure: true });
4844
+ };
4845
+ const pendingWorkflowSteers = new Set;
4846
+ const deliverWorkflowSteerRequest = (request) => {
4847
+ let indexes = explicitWorkflowSteerIndexes(request);
4848
+ if (status.state !== "running") {
4849
+ failWorkflowSteer(request, indexes ?? [0], `run became ${status.state} before steering request was consumed`);
4850
+ return;
4851
+ }
4852
+ const liveControls = [...deps.state.foregroundControls.values()].filter((candidate) => candidate.parentWorkflowRunId === workflowRunId && (candidate.activeChildren?.size ?? 0) > 0);
4853
+ if (indexes === undefined) {
4854
+ if (liveControls.length !== 1) {
4855
+ failWorkflowSteer(request, [0], liveControls.length > 1 ? `workflow has ${liveControls.length} live children; steer a child run id instead` : "workflow child is not live in this process");
4856
+ return;
4857
+ }
4858
+ const index = status.steps?.findIndex((step) => !!step.workflowKey && step.workflowKey === liveControls[0].workflowKey) ?? -1;
4859
+ if (index < 0) {
4860
+ failWorkflowSteer(request, [0], "live workflow child has no projected step");
4861
+ return;
4862
+ }
4863
+ indexes = [index];
4864
+ }
4865
+ const resolved = indexes.map((index) => {
4866
+ const step = status.steps?.[index];
4867
+ const control = step?.workflowKey ? liveControls.find((candidate) => candidate.workflowKey === step.workflowKey) : undefined;
4868
+ return { index, control, reason: !step ? "child index out of range" : !control ? "workflow child is not live in this process" : undefined };
4869
+ });
4870
+ const targets = resolved.map(({ index, reason }) => ({ index, state: reason ? "failed" : "routed", ...reason ? { reason } : {} }));
4871
+ recordWorkflowSteerTargets(request, targets);
4872
+ emitWorkflowSteerEvent("subagent.steer.requested", request.id, undefined, { targets });
4873
+ persist({ tolerateStatusWriteFailure: true });
4874
+ for (const { index, control, reason } of resolved) {
4875
+ if (!control) {
4876
+ emitWorkflowSteerEvent("subagent.steer.failed", request.id, index, { reason });
4877
+ continue;
4878
+ }
4879
+ emitWorkflowSteerEvent("subagent.steer.routed", request.id, index);
4880
+ const applyWorkflowSteerDelivery = (state, reason) => {
4881
+ if (!pendingWorkflowSteers.has(applyWorkflowSteerDelivery))
4882
+ return;
4883
+ if (state !== "queued")
4884
+ pendingWorkflowSteers.delete(applyWorkflowSteerDelivery);
4885
+ const now = Date.now();
4886
+ const steering = steeringStatus(status);
4887
+ if (state !== "queued")
4888
+ steering.pending = Math.max(0, steering.pending - 1);
4889
+ if (state === "delivered") {
4890
+ steering.delivered++;
4891
+ steering.lastDeliveredAt = now;
4892
+ } else if (state === "failed")
4893
+ steering.failed++;
4894
+ const receipt = steering.recent.find((candidate) => candidate.id === request.id)?.targets.find((target) => target.index === index);
4895
+ if (receipt) {
4896
+ receipt.state = state;
4897
+ if (state === "delivered")
4898
+ receipt.deliveredAt = now;
4899
+ if (state === "failed")
4900
+ receipt.failedAt = now;
4901
+ if (reason)
4902
+ receipt.reason = reason;
4903
+ }
4904
+ if (state === "failed") {
4905
+ const failedStep = status.steps?.[index];
4906
+ if (failedStep)
4907
+ failedStep.activityState = "needs_attention";
4908
+ status.activityState = "needs_attention";
4909
+ }
4910
+ emitWorkflowSteerEvent(`subagent.steer.${state}`, request.id, index, state === "failed" ? { reason } : { deliveryStatus: state, message: request.message });
4911
+ persist({ tolerateStatusWriteFailure: true });
4912
+ };
4913
+ pendingWorkflowSteers.add(applyWorkflowSteerDelivery);
4914
+ steerWorkflowForegroundTarget({
4915
+ target: { control, workflowRunId, sourceRunId: workflowRunId },
4916
+ message: request.message,
4917
+ ...request.mode ? { mode: request.mode } : {}
4918
+ }).then((result) => {
4919
+ const target = result.details.steering?.targets[0];
4920
+ applyWorkflowSteerDelivery(target?.state === "delivered" ? "delivered" : target?.state === "queued" ? "queued" : "failed", target?.reason ?? (target ? undefined : "steering produced no target receipt"));
4921
+ }, (error) => applyWorkflowSteerDelivery("failed", error instanceof Error ? error.message : String(error)));
4922
+ }
4923
+ };
4924
+ let disposeWorkflowSteerInbox;
4925
+ try {
4926
+ disposeWorkflowSteerInbox = watchAsyncControlInbox(asyncDir, {
4927
+ onSteer: deliverWorkflowSteerRequest,
4928
+ onError: (error, phase, request) => {
4929
+ const reason = error instanceof Error ? error.message : String(error);
4930
+ appendWorkflowEvent({ type: "subagent.workflow.steer_inbox_unavailable", phase, error: reason });
4931
+ if (request)
4932
+ failWorkflowSteer(request, explicitWorkflowSteerIndexes(request) ?? [0], `steer consumer failed: ${reason}`);
4933
+ }
4934
+ });
4935
+ } catch (error) {
4936
+ appendWorkflowEvent({ type: "subagent.workflow.steer_inbox_unavailable", error: error instanceof Error ? error.message : String(error) });
4937
+ }
4938
+ deps.activateSupervisorTransport?.();
4231
4939
  const { workflowScript, async: _workflowAsync, chatProgress: _chatProgress, ...workflowRequest } = requestParams;
4940
+ let workflowSteerInboxClosed = false;
4941
+ const settleWorkflowSteerInbox = (outcome = status.state) => {
4942
+ if (workflowSteerInboxClosed)
4943
+ return;
4944
+ workflowSteerInboxClosed = true;
4945
+ disposeWorkflowSteerInbox?.();
4946
+ for (const settle of pendingWorkflowSteers)
4947
+ settle("failed", `run became ${outcome} before steering delivery settled; delivery unconfirmed`);
4948
+ try {
4949
+ closeSteerInbox(asyncDir, outcome);
4950
+ const undelivered = consumeSteerRequests(asyncDir, undefined, (error) => {
4951
+ appendWorkflowEvent({ type: "subagent.workflow.steer_inbox_unavailable", phase: "drain", error: error instanceof Error ? error.message : String(error) });
4952
+ });
4953
+ for (const request of undelivered)
4954
+ failWorkflowSteer(request, explicitWorkflowSteerIndexes(request) ?? [0], `run became ${outcome} before steering request was consumed`);
4955
+ } catch (error) {
4956
+ appendWorkflowEvent({ type: "subagent.workflow.steer_inbox_unavailable", phase: "close", error: error instanceof Error ? error.message : String(error) });
4957
+ }
4958
+ persist();
4959
+ };
4232
4960
  Promise.resolve().then(async () => {
4233
4961
  const workflowDeadlineAt = timeout === undefined ? undefined : Date.now() + timeout;
4234
4962
  const workflowResults = [];
4235
4963
  const workflowChildRunIds = new Map;
4236
- const { action: _action, agent: _agent, task: _task, resume: _resume, tasks: _tasks, chain: _chain, concurrency: _concurrency, foregroundOnly: _foregroundOnly, clarify: _clarify, timeoutMs: _timeoutMs, maxRuntimeMs: _maxRuntimeMs, usageBudget: _usageBudget, missionId: _missionId, mission: _mission, preflight: _preflight, ...workflowChildDefaults } = workflowRequest;
4964
+ const { args: _args, action: _action, agent: _agent, task: _task, resume: _resume, tasks: _tasks, chain: _chain, concurrency: _concurrency, foregroundOnly: _foregroundOnly, clarify: _clarify, timeoutMs: _timeoutMs, maxRuntimeMs: _maxRuntimeMs, usageBudget: _usageBudget, missionId: _missionId, mission: _mission, preflight: _preflight, globalConcurrencyLimit: _globalConcurrencyLimit, maxSubagentSpawnsPerRun: _maxSubagentSpawnsPerRun, ...workflowChildDefaults } = workflowRequest;
4237
4965
  const workflowOutput = typeof workflowChildDefaults.output === "string" || typeof workflowChildDefaults.output === "boolean" ? workflowChildDefaults.output : undefined;
4238
4966
  const configuredOutputBaseDir = resolveConfiguredSingleRunOutputBaseDir(deps);
4239
- const workflowAggregateOutputPath = resolveWorkflowAggregateOutputPath(workflowOutput, parentCwd, workflowCwd, resolveSingleRunOutputBaseDir(deps, workflowArtifactsDir, workflowRunId));
4967
+ const workflowAggregateOutputPath = resolveSingleOutputPath(workflowOutput, parentCwd, workflowCwd, resolveSingleRunOutputBaseDir(deps, workflowArtifactsDir, workflowRunId));
4240
4968
  const claimedOutputPaths = new Map;
4241
4969
  const childOutputOverrides = new Map;
4242
4970
  const childOutputClaimPaths = new Map;
4243
4971
  const producedChildOutputPaths = new Set;
4244
4972
  const workflowSteps = new Map;
4245
- const runHostCommand = workflowHostCommandRunner({ workflowCwd, artifactsDir: workflowArtifactsDir, workflowRunId, claimedOutputPaths, producedOutputPaths: producedChildOutputPaths });
4973
+ const announcedWorkflowChildren = new Set;
4974
+ const announceWorkflowChild = (key, step) => {
4975
+ if (announcedWorkflowChildren.has(key))
4976
+ return;
4977
+ announcedWorkflowChildren.add(key);
4978
+ const stepIndex = status.steps?.indexOf(step);
4979
+ const childEvent = {
4980
+ type: "subagent.child-status",
4981
+ version: 1,
4982
+ runId: workflowRunId,
4983
+ childId: key,
4984
+ status: "started",
4985
+ ts: Date.now(),
4986
+ source: "async",
4987
+ asyncDir,
4988
+ ...stepIndex !== undefined ? { stepIndex } : {},
4989
+ agent: step.agent,
4990
+ ...step.runId ? { childRunId: step.runId } : {},
4991
+ workflowKey: key,
4992
+ ...step.phase ? { phase: step.phase } : {},
4993
+ ...step.label ? { label: step.label } : {}
4994
+ };
4995
+ appendWorkflowEvent({ ...childEvent });
4996
+ try {
4997
+ deps.dm.events.emit(SUBAGENT_CHILD_STATUS_EVENT, childEvent);
4998
+ } catch (error) {
4999
+ console.error("Failed to emit workflow child status event:", error);
5000
+ }
5001
+ };
5002
+ announcePersistedWorkflowChildren = () => {
5003
+ for (const [key, step] of pendingWorkflowChildAnnouncements) {
5004
+ if (!step.runId)
5005
+ continue;
5006
+ announceWorkflowChild(key, step);
5007
+ pendingWorkflowChildAnnouncements.delete(key);
5008
+ }
5009
+ };
5010
+ const runHostCommand = workflowHostCommandRunner({
5011
+ workflowCwd,
5012
+ artifactsDir: workflowArtifactsDir,
5013
+ workflowRunId,
5014
+ claimedOutputPaths,
5015
+ producedOutputPaths: producedChildOutputPaths,
5016
+ ...workflowResource ? { authorize: (key, params) => authorizeWorkflowResourceHost(workflowResource.permit, key, params.command) } : {}
5017
+ });
5018
+ const workflowHost = workflowResource ? workflowResource.authority.host ? runHostCommand : undefined : publicExecution ? undefined : runHostCommand;
4246
5019
  let projectedTraceLength = 0;
4247
5020
  let projectedTraceTail;
4248
5021
  const updateTrace = (trace) => {
@@ -4352,9 +5125,19 @@ export function createSubagentExecutor(deps) {
4352
5125
  try {
4353
5126
  const workflow = await runWorkflowScript({
4354
5127
  script: workflowScript,
4355
- globalConcurrencyLimit: deps.config.globalConcurrencyLimit,
5128
+ ...workflowArgs ? { args: workflowArgs } : {},
5129
+ workflowRunId,
5130
+ processCwd: ctx.cwd,
5131
+ globalConcurrencyLimit: requestParams.globalConcurrencyLimit ?? deps.config.globalConcurrencyLimit,
4356
5132
  timeoutMs: timeout,
4357
5133
  signal: controller.signal,
5134
+ continueAfterAbortWhenChildrenSettled: (abortError) => {
5135
+ if (abortError.message !== "Workflow stopped because the extension session was replaced or reloaded.")
5136
+ return false;
5137
+ const activeAsyncChild = [...deps.state.asyncJobs?.values() ?? []].some((job) => job.parentWorkflowRunId === workflowRunId && (job.status === "queued" || job.status === "running"));
5138
+ const activeForegroundChild = [...deps.state.foregroundControls.values()].some((control) => control.parentWorkflowRunId === workflowRunId && (control.activeChildren?.size ?? 0) > 0);
5139
+ return !activeAsyncChild && !activeForegroundChild;
5140
+ },
4358
5141
  registerStopChild: (stop) => {
4359
5142
  if (stop)
4360
5143
  deps.state.workflowChildStops?.set(workflowRunId, stop);
@@ -4363,19 +5146,39 @@ export function createSubagentExecutor(deps) {
4363
5146
  },
4364
5147
  ...workflowState ? { state: workflowState } : {},
4365
5148
  onTrace: updateTrace,
5149
+ onChildSettled: (notification) => {
5150
+ appendWorkflowEvent({
5151
+ type: "subagent.workflow.child_settled",
5152
+ childKey: notification.childKey,
5153
+ ...notification.childRunId ? { childRunId: notification.childRunId } : {},
5154
+ outcome: notification.outcome,
5155
+ workflowRunning: notification.workflowRunning
5156
+ });
5157
+ try {
5158
+ deps.dm.sendMessage({
5159
+ customType: "subagent-incremental-child-notify",
5160
+ content: formatIncrementalChildCompletion(notification),
5161
+ display: notification.outcome !== "completed"
5162
+ }, { triggerTurn: incrementalChildCompletionTriggersTurn(notification, requestParams.scheduleOrigin) });
5163
+ } catch (sendError) {
5164
+ console.error(`Failed to send incremental child completion notification for '${notification.childKey}':`, sendError);
5165
+ }
5166
+ deps.refreshResultDelivery?.();
5167
+ },
4366
5168
  onLanePlan: (lanes) => {
4367
5169
  status.workflowGraph = buildWorkflowLaneGraph(workflowRunId, lanes, status.workflowGraph);
4368
5170
  applyWorkflowLaneTrace(status.workflowGraph, status.workflow?.trace ?? []);
4369
5171
  persist({ tolerateStatusWriteFailure: true });
4370
5172
  },
4371
- host: runHostCommand,
5173
+ ...workflowHost ? { host: workflowHost } : {},
4372
5174
  onHostStep: (hostStep) => {
4373
5175
  status = upsertHostStep({ status, hostStep, persist: (nextStatus) => {
4374
5176
  status = nextStatus;
4375
5177
  persist({ tolerateStatusWriteFailure: true });
4376
5178
  } });
4377
5179
  },
4378
- admit: (calls) => {
5180
+ admit: async (calls, admissionSignal) => {
5181
+ await preflightWorkflowWorktrees({ workflowDefaults: workflowChildDefaults, defaultWorktree: deps.config.worktree, calls, ctxCwd: parentCwd, signal: admissionSignal, deadlineAt: workflowDeadlineAt });
4379
5182
  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 });
4380
5183
  if (outputClaims.error)
4381
5184
  throw new Error(outputClaims.error);
@@ -4412,8 +5215,10 @@ export function createSubagentExecutor(deps) {
4412
5215
  });
4413
5216
  let preparedChildParams;
4414
5217
  const result = await runMissionWorkflowChild(missionBinding, workflowRunId, key, childPhase, () => {
4415
- const childRequest = bindMissionWorkflowChildAsyncLaunch({ ...prepareWorkflowChildLaunchParams({ workflowDefaults: workflowChildDefaults, childParams, parentWorkflowRunId: workflowRunId, workflowKey: key, ctxCwd: parentCwd, workflowCwd, artifactsDir: workflowArtifactsDir, aggregateOutputPath: workflowAggregateOutputPath, configuredOutputBaseDir, discoverAgents: discoverWorkflowAgents, agents: workflowAgents, workflowAgentScope: workflowChildDefaults.agentScope, outputOverride: childOutputOverrides.get(key), outputClaimPath: childOutputClaimPaths.get(key), options: { missionDetached: detachWorkflowChildMissions, awaitDetachedChild: true, runFanoutBudget: workflowFanoutBudget, parentDeadlineAt: workflowDeadlineAt, capabilityCeiling: workflowCapabilityCeiling } }), runFanoutAdmitted: admission.admitted }, missionBinding, deps.asyncByDefault);
5218
+ const childRequest = bindMissionWorkflowChildAsyncLaunch({ ...prepareWorkflowChildLaunchParams({ workflowDefaults: workflowChildDefaults, childParams, parentWorkflowRunId: workflowRunId, workflowKey: key, ctxCwd: parentCwd, workflowCwd, artifactsDir: workflowArtifactsDir, aggregateOutputPath: workflowAggregateOutputPath, configuredOutputBaseDir, discoverAgents: discoverWorkflowAgents, agents: workflowAgents, workflowAgentScope: workflowChildDefaults.agentScope, outputOverride: childOutputOverrides.get(key), outputClaimPath: childOutputClaimPaths.get(key), options: { missionDetached: detachWorkflowChildMissions, awaitDetachedChild: true, runFanoutBudget: workflowFanoutBudget, parentDeadlineAt: workflowDeadlineAt, capabilityCeiling: workflowCapabilityCeiling } }), runFanoutAdmitted: admission.admitted }, missionBinding, deps.asyncByDefault, undefined, inheritedNestedRoute(deps)?.rootRunId);
4416
5219
  preparedChildParams = childRequest;
5220
+ if (workflowUsageBudget.budget)
5221
+ workflowOwnedUsageBudgets.set(childRequest, workflowUsageBudget.budget);
4417
5222
  workflowLaunchObservers.set(childRequest, (launch) => {
4418
5223
  const step = status.steps?.find((candidate) => candidate.workflowKey === key);
4419
5224
  if (step) {
@@ -4426,6 +5231,8 @@ export function createSubagentExecutor(deps) {
4426
5231
  step.runId = launch.runId;
4427
5232
  if (childRequest.lane)
4428
5233
  step.lane = childRequest.lane;
5234
+ if (step.runId)
5235
+ pendingWorkflowChildAnnouncements.set(key, step);
4429
5236
  persist({ tolerateStatusWriteFailure: true });
4430
5237
  }
4431
5238
  recordMissionWorkflowChild(missionBinding, workflowRunId, key, { status: "running", agent: launch.agent, ...launch.sessionFile ? { sessionPath: launch.sessionFile } : {} });
@@ -4469,7 +5276,7 @@ export function createSubagentExecutor(deps) {
4469
5276
  workflowChildRunIds.set(key, child.runId);
4470
5277
  const step = status.steps?.find((candidate) => candidate.workflowKey === key);
4471
5278
  if (step) {
4472
- step.async = Boolean(result.details.asyncId || result.details.asyncDir);
5279
+ step.async = step.async === true || Boolean(result.details.asyncId || result.details.asyncDir);
4473
5280
  if (child.runId)
4474
5281
  step.runId = child.runId;
4475
5282
  if (child.lane)
@@ -4497,37 +5304,43 @@ export function createSubagentExecutor(deps) {
4497
5304
  return child;
4498
5305
  },
4499
5306
  status: async (keyOrRunId, workflowSignal) => workflowChildResult(keyOrRunId, await execute(randomUUID(), { action: "status", id: keyOrRunId }, workflowSignal, undefined, ctx, preserveActiveSession, workflowParentModel)),
4500
- resolveResume: (reference) => resolveKeyedWorkflowResume(reference, deps.state),
5307
+ resolveResume: (reference, _signal, index) => resolveWorkflowResume(reference, deps, ctx.sessionManager.getSessionFile() ?? null, index),
4501
5308
  steer: (key, message, options, workflowSignal) => steerWorkflowChildByKey({ state: deps.state, workflowRunId, key, message, options, signal: workflowSignal, resolveRunId: () => workflowChildRunIds.get(key) })
4502
5309
  });
4503
5310
  const finalPreflightWarnings = workflowPreflightWarnings(workflowPreflight, workflow.trace, { settled: true });
4504
5311
  const finalPreflightTrace = annotateWorkflowPreflightTrace(workflow.trace, workflowPreflight);
4505
5312
  const returnPreview = formatWorkflowValue(workflow.value).slice(0, 1000);
4506
5313
  const emitPreview = workflow.emits.length > 0 ? ` Emitted: ${workflow.emits.map(formatWorkflowValue).join(", ").slice(0, 1000)}` : "";
4507
- const summary = `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(" ")}` : ""}`;
5314
+ 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(" ")}` : ""}`;
4508
5316
  const outputWarning = writeWorkflowAggregateOutput(workflowAggregateOutputPath, summary, producedChildOutputPaths);
4509
5317
  const resultSummary = appendWorkflowOutputWarning(summary, outputWarning);
4510
5318
  const workflowUsage = sumResultsUsage(workflowResults);
5319
+ settleWorkflowSteerInbox("complete");
4511
5320
  const workflowChildren = workflowChildSummary({ parentToolCallId: toolCallId, workflowRunId, workflowState: "completed", inventoryComplete: true, trace: workflow.trace, children: workflow.children, steps: status.steps });
4512
- status = { ...status, state: "complete", endedAt: Date.now(), workflow: { value: workflow.value, trace: finalPreflightTrace, emits: workflow.emits, console: workflow.console, ...finalPreflightWarnings.length ? { preflightWarnings: finalPreflightWarnings } : {} }, workflowChildren, totalTokens: { input: workflowUsage.input, output: workflowUsage.output, total: workflowUsage.input + workflowUsage.output }, totalCost: sumResultsCost(workflowResults) };
4513
- const receipt = terminalWorkflowReceipt(workflowRunId, "complete", workflow.children, workflowChildren, undefined, validHostStepNodes(status.workflowGraph));
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) };
5322
+ const receipt = terminalWorkflowReceipt(workflowRunId, "complete", workflow.children, workflowChildren, undefined, validHostStepNodes(status.workflowGraph), workflowResource?.provenance, workflowArgsDigest);
5323
+ delete status.workflowReceiptPath;
4514
5324
  let workflowReceipt;
4515
5325
  try {
4516
5326
  workflowReceipt = { path: writeWorkflowReceipt(asyncDir, receipt), receipt };
5327
+ status.workflowReceiptPath = workflowReceipt.path;
4517
5328
  } catch (receiptError) {
4518
5329
  appendWorkflowEvent({ type: "subagent.workflow.receipt_write_failed", error: `Failed to persist async workflow receipt: ${receiptError instanceof Error ? receiptError.message : String(receiptError)}` });
4519
5330
  }
4520
- if (!writeWorkflowResult({ id: workflowRunId, runId: workflowRunId, toolCallId, agent: "workflow", mode: "workflow", success: true, state: "complete", summary: resultSummary, output: resultSummary, workflowChildren, results: workflow.children.map((child) => ({ workflowKey: child.key, ...child.agent ? { agent: child.agent } : {}, ...child.runId ? { runId: child.runId } : {}, ...status.steps?.find((step) => step.workflowKey === child.key)?.sessionName ? { sessionName: status.steps?.find((step) => step.workflowKey === child.key)?.sessionName } : {}, ...workflowChildAccountingFields(child), output: child.output, outputState: child.output.trim() || child.structuredOutput !== undefined ? "present" : "absent", structuredOutput: child.structuredOutput, success: child.ok, ...child.outputReference ? { outputReference: child.outputReference } : {}, ...child.outputPathMapping ? { outputPathMapping: child.outputPathMapping } : {}, ...child.stopped ? { stopped: true } : {}, ...child.interrupted ? { interrupted: true } : {}, ...child.artifactPaths[0] ? { artifactPaths: { outputPath: child.artifactPaths[0] } } : {} })), workflow: status.workflow, ...workflowReceipt ? { workflowReceipt } : {}, asyncDir, cwd: workflowCwd, sessionId: currentSessionId, completionOwnerId, ...requestParams.scheduleOrigin ? { scheduleOrigin: requestParams.scheduleOrigin } : {}, timestamp: Date.now(), durationMs: Date.now() - startedAt }))
5331
+ if (!writeWorkflowResult({ id: workflowRunId, runId: workflowRunId, toolCallId, agent: "workflow", mode: "workflow", success: true, state: "complete", summary: resultSummary, output: resultSummary, workflowChildren, results: workflowResultChildren(workflow.children, status, false), workflow: status.workflow, ...workflowCapabilityCeiling ? { admissionCapabilityCeiling: workflowCapabilityCeiling } : {}, ...workflowReceipt ? { workflowReceipt } : {}, asyncDir, cwd: workflowCwd, sessionId: currentSessionId, completionOwnerId, ...requestParams.scheduleOrigin ? { scheduleOrigin: requestParams.scheduleOrigin } : {}, timestamp: Date.now(), durationMs: Date.now() - startedAt }))
5332
+ return;
5333
+ if (pendingResultPublication && !await pendingResultPublication)
4521
5334
  return;
4522
5335
  persist();
4523
5336
  deps.refreshResultDelivery?.();
4524
5337
  persistClosed = true;
4525
- appendWorkflowEvent({ type: "subagent.workflow.completed", state: status.state, ...status.error ? { error: status.error } : {} });
5338
+ appendWorkflowEvent({ type: "subagent.workflow.completed", state: status.state, ...workflowArgsDigest ? { argsDigest: workflowArgsDigest } : {}, ...status.error ? { error: status.error } : {} });
4526
5339
  } catch (error) {
4527
5340
  const partial = error instanceof WorkflowScriptError ? error.partial : { trace: [], emits: [], console: [], children: [] };
4528
5341
  const stopped = controller.signal.aborted;
4529
5342
  const detachedChildKeys = new Set(partial.children.filter((child) => child.detached).map((child) => child.key));
4530
- const hasRealFailedChild = partial.children.some((child) => !child.ok && !child.detached);
5343
+ const hasRealFailedChild = partial.children.some((child) => !child.ok && child.state !== "running" && !child.detached);
4531
5344
  const pauseForDetached = !stopped && error instanceof WorkflowScriptError && error.errorKind === "detached-child" && detachedChildKeys.size > 0 && !hasRealFailedChild;
4532
5345
  const state = stopped ? "stopped" : pauseForDetached ? "paused" : "failed";
4533
5346
  for (const step of status.steps ?? []) {
@@ -4543,10 +5356,11 @@ export function createSubagentExecutor(deps) {
4543
5356
  }
4544
5357
  }
4545
5358
  const workflowState = state === "paused" ? "paused" : state === "stopped" ? "stopped" : "failed";
5359
+ settleWorkflowSteerInbox(state);
4546
5360
  const workflowChildren = workflowChildSummary({ parentToolCallId: toolCallId, workflowRunId, workflowState, inventoryComplete: true, trace: partial.trace, children: partial.children, steps: status.steps });
4547
5361
  const finalPreflightWarnings = workflowPreflightWarnings(workflowPreflight, partial.trace, { settled: true });
4548
5362
  const finalPreflightTrace = annotateWorkflowPreflightTrace(partial.trace, workflowPreflight);
4549
- status = compactOptional({ ...status, state, stopped: stopped || undefined, activityState: pauseForDetached ? "needs_attention" : undefined, error: workflowFailureMessage(error, workflowRunId, partial.children), endedAt: Date.now(), workflow: { trace: finalPreflightTrace, emits: partial.emits, console: partial.console, ...finalPreflightWarnings.length ? { preflightWarnings: finalPreflightWarnings } : {} }, workflowChildren });
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 });
4550
5364
  if (pauseForDetached) {
4551
5365
  const promoted = promotePausedWorkflowIfSettled(status);
4552
5366
  if (promoted)
@@ -4557,20 +5371,29 @@ export function createSubagentExecutor(deps) {
4557
5371
  const resultSummary = appendWorkflowOutputWarning(terminalSummary, outputWarning);
4558
5372
  const receiptState = status.state === "complete" ? "complete" : status.state === "paused" ? "paused" : status.state === "stopped" ? "stopped" : "failed";
4559
5373
  const terminalOutcome = workflowFailureTerminalOutcome(error, partial.children, usageBudgetState(workflowUsageBudget.budget, sumResultsCost(workflowResults)));
4560
- const receipt = terminalWorkflowReceipt(workflowRunId, receiptState, partial.children, workflowChildren, terminalOutcome, validHostStepNodes(status.workflowGraph));
5374
+ const receipt = terminalWorkflowReceipt(workflowRunId, receiptState, partial.children, workflowChildren, terminalOutcome, validHostStepNodes(status.workflowGraph), workflowResource?.provenance, workflowArgsDigest);
5375
+ delete status.workflowReceiptPath;
4561
5376
  let workflowReceipt;
4562
5377
  try {
4563
5378
  workflowReceipt = { path: writeWorkflowReceipt(asyncDir, receipt), receipt };
5379
+ status.workflowReceiptPath = workflowReceipt.path;
4564
5380
  } catch (receiptError) {
4565
5381
  appendWorkflowEvent({ type: "subagent.workflow.receipt_write_failed", error: `Failed to persist async workflow receipt: ${receiptError instanceof Error ? receiptError.message : String(receiptError)}` });
4566
5382
  }
4567
- if (!writeWorkflowResult({ id: workflowRunId, runId: workflowRunId, toolCallId, agent: "workflow", mode: "workflow", success: status.state === "complete", state: status.state, summary: resultSummary, error: status.state === "complete" ? undefined : status.error, stopped: status.stopped, activityState: status.activityState, workflowChildren, ...terminalOutcome ? { terminalOutcome } : {}, results: partial.children.map((child) => ({ workflowKey: child.key, ...child.agent ? { agent: child.agent } : {}, ...child.runId ? { runId: child.runId } : {}, ...status.steps?.find((step) => step.workflowKey === child.key)?.sessionName ? { sessionName: status.steps?.find((step) => step.workflowKey === child.key)?.sessionName } : {}, ...workflowChildAccountingFields(child), output: child.output, outputState: child.output.trim() || child.structuredOutput !== undefined ? "present" : "absent", structuredOutput: child.structuredOutput, success: child.ok, ...child.outputReference ? { outputReference: child.outputReference } : {}, ...child.terminalOutcome ? { terminalOutcome: child.terminalOutcome } : {}, ...child.outputPathMapping ? { outputPathMapping: child.outputPathMapping } : {}, ...child.stopped ? { stopped: true } : {}, ...child.interrupted ? { interrupted: true } : {}, ...child.detached && status.state !== "complete" ? { detached: true } : {}, ...child.artifactPaths[0] ? { artifactPaths: { outputPath: child.artifactPaths[0] } } : {} })), workflow: status.workflow, ...workflowReceipt ? { workflowReceipt } : {}, asyncDir, cwd: workflowCwd, sessionId: currentSessionId, completionOwnerId, ...requestParams.scheduleOrigin ? { scheduleOrigin: requestParams.scheduleOrigin } : {}, timestamp: Date.now(), durationMs: Date.now() - startedAt }))
5383
+ if (!writeWorkflowResult({ id: workflowRunId, runId: workflowRunId, toolCallId, agent: "workflow", mode: "workflow", success: status.state === "complete", state: status.state, summary: resultSummary, error: status.state === "complete" ? undefined : status.error, stopped: status.stopped, activityState: status.activityState, workflowChildren, ...terminalOutcome ? { terminalOutcome } : {}, results: workflowResultChildren(partial.children, status, true), workflow: status.workflow, ...workflowCapabilityCeiling ? { admissionCapabilityCeiling: workflowCapabilityCeiling } : {}, ...workflowReceipt ? { workflowReceipt } : {}, asyncDir, cwd: workflowCwd, sessionId: currentSessionId, completionOwnerId, ...requestParams.scheduleOrigin ? { scheduleOrigin: requestParams.scheduleOrigin } : {}, timestamp: Date.now(), durationMs: Date.now() - startedAt }))
5384
+ return;
5385
+ if (pendingResultPublication && !await pendingResultPublication)
4568
5386
  return;
4569
5387
  persist();
4570
5388
  deps.refreshResultDelivery?.();
4571
5389
  persistClosed = true;
4572
- appendWorkflowEvent({ type: "subagent.workflow.completed", state: status.state, ...terminalOutcome ? { terminalOutcome } : {}, ...status.error ? { error: status.error } : {}, ...status.activityState ? { activityState: status.activityState } : {} });
5390
+ appendWorkflowEvent({ type: "subagent.workflow.completed", state: status.state, ...workflowArgsDigest ? { argsDigest: workflowArgsDigest } : {}, ...terminalOutcome ? { terminalOutcome } : {}, ...status.error ? { error: status.error } : {}, ...status.activityState ? { activityState: status.activityState } : {} });
4573
5391
  } finally {
5392
+ try {
5393
+ settleWorkflowSteerInbox();
5394
+ } catch (error) {
5395
+ console.error(`Failed to close async workflow steer inbox '${asyncDir}':`, error);
5396
+ }
4574
5397
  persistClosed = true;
4575
5398
  deps.state.workflowControllers?.delete(workflowRunId);
4576
5399
  deps.state.workflowChildStops?.delete(workflowRunId);
@@ -4581,39 +5404,58 @@ export function createSubagentExecutor(deps) {
4581
5404
  content: [{ type: "text", text: `${workflowPreflight ? `${formatWorkflowPreflight(workflowPreflight)}
4582
5405
 
4583
5406
  ` : ""}${formatAsyncStartedMessage(`Async workflow [${workflowRunId}]`, ctx.hasUI === true)}` }],
4584
- details: { mode: "workflow", runId: workflowRunId, toolCallId, asyncId: workflowRunId, asyncDir, results: [], ...workflowPreflight ? { preflight: workflowPreflight } : {}, workflowChildren: status.workflowChildren, chatProgress, ...deps.state.activeAsyncCapacity ? { activeAsyncCapacity: deps.state.activeAsyncCapacity } : {} }
5407
+ details: { mode: "workflow", runId: workflowRunId, toolCallId, asyncId: workflowRunId, asyncDir, results: [], ...workflowPreflight ? { preflight: workflowPreflight } : {}, workflow: status.workflow, workflowChildren: status.workflowChildren, chatProgress, ...deps.state.activeAsyncCapacity ? { activeAsyncCapacity: deps.state.activeAsyncCapacity } : {} }
4585
5408
  }, workflowFanoutBudget));
4586
5409
  }
4587
- const { workflowScript: _workflowScript, action: _action, agent: _agent, task: _task, resume: _resume, tasks: _tasks, chain: _chain, concurrency: _concurrency, async: _async, foregroundOnly: _foregroundOnly, clarify: _clarify, timeoutMs: _timeoutMs, maxRuntimeMs: _maxRuntimeMs, usageBudget: _usageBudget, chatProgress: _chatProgress, missionId: _missionId, mission: _mission, preflight: _preflight, ...workflowChildDefaults } = requestParams;
5410
+ const { workflowScript: _workflowScript, args: _args, action: _action, agent: _agent, task: _task, resume: _resume, tasks: _tasks, chain: _chain, concurrency: _concurrency, async: _async, foregroundOnly: _foregroundOnly, clarify: _clarify, timeoutMs: _timeoutMs, maxRuntimeMs: _maxRuntimeMs, usageBudget: _usageBudget, chatProgress: _chatProgress, missionId: _missionId, mission: _mission, preflight: _preflight, globalConcurrencyLimit: _globalConcurrencyLimit, maxSubagentSpawnsPerRun: _maxSubagentSpawnsPerRun, ...workflowChildDefaults } = requestParams;
4588
5411
  const workflowOutput = typeof workflowChildDefaults.output === "string" || typeof workflowChildDefaults.output === "boolean" ? workflowChildDefaults.output : undefined;
4589
5412
  const configuredOutputBaseDir = resolveConfiguredSingleRunOutputBaseDir(deps);
4590
- const workflowAggregateOutputPath = resolveWorkflowAggregateOutputPath(workflowOutput, ctx.cwd, workflowCwd, resolveSingleRunOutputBaseDir(deps, workflowArtifactsDir, _id));
5413
+ const workflowAggregateOutputPath = resolveSingleOutputPath(workflowOutput, ctx.cwd, workflowCwd, resolveSingleRunOutputBaseDir(deps, workflowArtifactsDir, foregroundWorkflowRunId));
4591
5414
  const claimedOutputPaths = new Map;
4592
5415
  const childOutputOverrides = new Map;
4593
5416
  const childOutputClaimPaths = new Map;
4594
5417
  const producedChildOutputPaths = new Set;
4595
5418
  const workflowResults = [];
4596
5419
  const workflowChildRunIds = new Map;
4597
- const runHostCommand = workflowHostCommandRunner({ workflowCwd, artifactsDir: workflowArtifactsDir, workflowRunId: _id, claimedOutputPaths, producedOutputPaths: producedChildOutputPaths });
5420
+ const runHostCommand = workflowHostCommandRunner({
5421
+ workflowCwd,
5422
+ artifactsDir: workflowArtifactsDir,
5423
+ workflowRunId: foregroundWorkflowRunId,
5424
+ claimedOutputPaths,
5425
+ producedOutputPaths: producedChildOutputPaths,
5426
+ ...workflowResource ? { authorize: (key, params) => authorizeWorkflowResourceHost(workflowResource.permit, key, params.command) } : {}
5427
+ });
5428
+ const workflowHost = delegatedWorkflowPermit ? undefined : workflowResource ? workflowResource.authority.host ? runHostCommand : undefined : publicExecution ? undefined : runHostCommand;
4598
5429
  const workflowHostSteps = new Map;
4599
- let liveWorkflow = { trace: [], emits: [], console: [] };
4600
- let liveWorkflowChildren = workflowChildSummary({ parentToolCallId: _id, workflowRunId: _id, workflowState: "running", inventoryComplete: false });
5430
+ let liveWorkflow = { trace: [], emits: [], console: [], ...workflowResource ? { resource: workflowResource.provenance } : {} };
5431
+ const childProgress = new Map;
5432
+ let activityTimer;
5433
+ let lastProgressAt = 0;
5434
+ let workflowProgressClosed = false;
4601
5435
  const workflowDeadlineAt = timeout === undefined ? undefined : Date.now() + timeout;
4602
5436
  const workflowCapabilityCeiling = intersectSubagentCapabilityCeilings(requestParams.capabilityCeiling, resolveCurrentSubagentCapabilityCeiling(resolveCurrentSessionId(ctx.sessionManager)));
4603
5437
  const sendWorkflowProgress = () => {
4604
- const update = workflowChatProgressUpdate(_id, chatProgress, liveWorkflow, liveWorkflowChildren, workflowPreflight);
4605
- if (update)
4606
- onUpdate?.(update);
5438
+ if (workflowProgressClosed)
5439
+ return;
5440
+ if (activityTimer)
5441
+ clearTimeout(activityTimer);
5442
+ activityTimer = undefined;
5443
+ lastProgressAt = Date.now();
5444
+ const liveWorkflowChildren = workflowChildSummary({ parentToolCallId: _id, workflowRunId: foregroundWorkflowRunId, workflowState: "running", inventoryComplete: false, trace: liveWorkflow.trace, progress: childProgress });
5445
+ onUpdate?.(workflowProgressUpdate(foregroundWorkflowRunId, chatProgress, liveWorkflow, liveWorkflowChildren, workflowPreflight));
4607
5446
  };
4608
5447
  try {
4609
5448
  const workflow = await runWorkflowScript({
4610
5449
  script: requestParams.workflowScript,
4611
- ...delegatedWorkflowPermit ? { oneUsePermit: { claim: (key) => claimWorkflowChildPermit(delegatedWorkflowPermit, _id, key) } } : {},
4612
- globalConcurrencyLimit: deps.config.globalConcurrencyLimit,
5450
+ ...workflowArgs ? { args: workflowArgs } : {},
5451
+ workflowRunId: foregroundWorkflowRunId,
5452
+ processCwd: ctx.cwd,
5453
+ ...delegatedWorkflowPermit ? { oneUsePermit: { claim: (key) => claimWorkflowChildPermit(delegatedWorkflowPermit, foregroundWorkflowRunId, key) } } : {},
5454
+ globalConcurrencyLimit: requestParams.globalConcurrencyLimit ?? deps.config.globalConcurrencyLimit,
4613
5455
  timeoutMs: timeout,
4614
5456
  signal,
4615
5457
  ...workflowState ? { state: workflowState } : {},
4616
- ...!delegatedWorkflowPermit ? { host: runHostCommand } : {},
5458
+ ...workflowHost ? { host: workflowHost } : {},
4617
5459
  onHostStep: (hostStep) => {
4618
5460
  workflowHostSteps.set(hostStep.id, { ...hostStep, ...hostStep.freshness ? { freshness: { ...hostStep.freshness } } : {} });
4619
5461
  },
@@ -4621,11 +5463,15 @@ export function createSubagentExecutor(deps) {
4621
5463
  const projectedTrace = annotateWorkflowPreflightTrace(trace, workflowPreflight);
4622
5464
  const preflightWarnings = workflowPreflightWarnings(workflowPreflight, trace);
4623
5465
  liveWorkflow = { ...liveWorkflow, trace: projectedTrace, ...preflightWarnings.length ? { preflightWarnings } : {} };
4624
- liveWorkflowChildren = workflowChildSummary({ parentToolCallId: _id, workflowRunId: _id, workflowState: "running", inventoryComplete: false, trace });
5466
+ for (const entry of trace) {
5467
+ if (entry.operation === "run" && ["completed", "failed", "stopped", "detached"].includes(entry.state))
5468
+ childProgress.delete(entry.key);
5469
+ }
4625
5470
  sendWorkflowProgress();
4626
5471
  },
4627
- admit: (calls) => {
4628
- const outputClaims = workflowChildOutputClaims({ ctxCwd: ctx.cwd, workflowCwd, artifactsDir: workflowArtifactsDir, workflowRunId: _id, aggregateOutputPath: workflowAggregateOutputPath, configuredOutputBaseDir, discoverAgents: discoverWorkflowAgents, agents: workflowAgents, workflowAgentScope: workflowChildDefaults.agentScope, state: deps.state, claimedOutputPaths, entries: calls });
5472
+ admit: async (calls, admissionSignal) => {
5473
+ await preflightWorkflowWorktrees({ workflowDefaults: workflowChildDefaults, defaultWorktree: deps.config.worktree, calls, ctxCwd: ctx.cwd, signal: admissionSignal, deadlineAt: workflowDeadlineAt });
5474
+ 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 });
4629
5475
  if (outputClaims.error)
4630
5476
  throw new Error(outputClaims.error);
4631
5477
  claimRunFanoutBatch(workflowFanoutBudget, calls.map(({ key }) => `workflow[${key}]`));
@@ -4656,7 +5502,7 @@ export function createSubagentExecutor(deps) {
4656
5502
  return workflowChildResult(key, buildRequestedModeError(childParams, usageBudgetExceededMessage(budgetState)), childParams, deps.state, { state: "partial", reason: "budget_exhausted" });
4657
5503
  const childPhase = typeof childParams.phase === "string" && childParams.phase.trim() ? childParams.phase.trim() : undefined;
4658
5504
  const childLabel = typeof childParams.label === "string" && childParams.label.trim() ? childParams.label.trim() : undefined;
4659
- recordMissionWorkflowChild(missionBinding, _id, key, {
5505
+ recordMissionWorkflowChild(missionBinding, foregroundWorkflowRunId, key, {
4660
5506
  status: "running",
4661
5507
  ...typeof childParams.agent === "string" && childParams.agent.trim() ? { agent: childParams.agent.trim() } : {},
4662
5508
  ...childLabel ? { label: childLabel } : {},
@@ -4664,9 +5510,11 @@ export function createSubagentExecutor(deps) {
4664
5510
  heartbeat: { status: "running", ...childPhase ? { phase: childPhase } : {} }
4665
5511
  });
4666
5512
  let preparedChildParams;
4667
- const result = await runMissionWorkflowChild(missionBinding, _id, key, childPhase, () => {
4668
- const childRequest = bindMissionWorkflowChildAsyncLaunch({ ...prepareWorkflowChildLaunchParams({ workflowDefaults: workflowChildDefaults, childParams, parentWorkflowRunId: _id, workflowKey: key, ctxCwd: ctx.cwd, workflowCwd, artifactsDir: workflowArtifactsDir, aggregateOutputPath: workflowAggregateOutputPath, configuredOutputBaseDir, discoverAgents: discoverWorkflowAgents, agents: workflowAgents, workflowAgentScope: workflowChildDefaults.agentScope, outputOverride: childOutputOverrides.get(key), outputClaimPath: childOutputClaimPaths.get(key), options: { missionDetached: detachWorkflowChildMissions, suppressRoutineResultIntercom: chatProgress.mode === "live-card", runFanoutBudget: workflowFanoutBudget, parentDeadlineAt: workflowDeadlineAt, capabilityCeiling: workflowCapabilityCeiling } }), runFanoutAdmitted: admission.admitted }, missionBinding, deps.asyncByDefault);
5513
+ const result = await runMissionWorkflowChild(missionBinding, foregroundWorkflowRunId, key, childPhase, () => {
5514
+ const childRequest = bindMissionWorkflowChildAsyncLaunch({ ...prepareWorkflowChildLaunchParams({ workflowDefaults: workflowChildDefaults, childParams: delegatedWorkflowPermit ? { ...childParams, async: false } : childParams, parentWorkflowRunId: foregroundWorkflowRunId, workflowKey: key, ctxCwd: ctx.cwd, workflowCwd, artifactsDir: workflowArtifactsDir, aggregateOutputPath: workflowAggregateOutputPath, configuredOutputBaseDir, discoverAgents: discoverWorkflowAgents, agents: workflowAgents, workflowAgentScope: workflowChildDefaults.agentScope, outputOverride: childOutputOverrides.get(key), outputClaimPath: childOutputClaimPaths.get(key), options: { missionDetached: detachWorkflowChildMissions, suppressRoutineResultIntercom: chatProgress.mode === "live-card", runFanoutBudget: workflowFanoutBudget, parentDeadlineAt: workflowDeadlineAt, capabilityCeiling: workflowCapabilityCeiling } }), runFanoutAdmitted: admission.admitted }, missionBinding, deps.asyncByDefault, undefined, inheritedNestedRoute(deps)?.rootRunId);
4669
5515
  preparedChildParams = childRequest;
5516
+ if (workflowUsageBudget.budget)
5517
+ workflowOwnedUsageBudgets.set(childRequest, workflowUsageBudget.budget);
4670
5518
  if (delegatedWorkflowPermit) {
4671
5519
  if (childRequest.async !== false)
4672
5520
  throw new Error("Workflow child permit supports one foreground child only.");
@@ -4674,9 +5522,9 @@ export function createSubagentExecutor(deps) {
4674
5522
  const childAgent = typeof childRequest.agent === "string" ? resolveAgentName(childRequest.agent, discoverWorkflowAgents(childCwd, resolveExecutionAgentScope(childRequest.agentScope)).agents).agent : undefined;
4675
5523
  if (childAgent?.runner?.type === "external-cli" || childAgent?.runner?.type === "external-job")
4676
5524
  throw new Error("Workflow child permit supports native DM children only.");
4677
- workflowPermitContexts.set(childRequest, { child: { permit: delegatedWorkflowPermit, workflowRunId: _id, childKey: key } });
5525
+ workflowPermitContexts.set(childRequest, { child: { permit: delegatedWorkflowPermit, workflowRunId: foregroundWorkflowRunId, childKey: key } });
4678
5526
  }
4679
- workflowLaunchObservers.set(childRequest, (launch) => recordMissionWorkflowChild(missionBinding, _id, key, {
5527
+ workflowLaunchObservers.set(childRequest, (launch) => recordMissionWorkflowChild(missionBinding, foregroundWorkflowRunId, key, {
4680
5528
  status: "running",
4681
5529
  agent: launch.agent,
4682
5530
  ...launch.sessionFile ? { sessionPath: launch.sessionFile } : {}
@@ -4685,8 +5533,21 @@ export function createSubagentExecutor(deps) {
4685
5533
  const progress = update.details.progress?.[0];
4686
5534
  if (!progress)
4687
5535
  return;
5536
+ if (onUpdate && !workflowProgressClosed) {
5537
+ if (progress.status === "running")
5538
+ childProgress.set(key, workflowChildProgress(progress));
5539
+ else
5540
+ childProgress.delete(key);
5541
+ if (!activityTimer) {
5542
+ const delay = 100 - (Date.now() - lastProgressAt);
5543
+ if (delay <= 0)
5544
+ sendWorkflowProgress();
5545
+ else
5546
+ activityTimer = setTimeout(sendWorkflowProgress, delay);
5547
+ }
5548
+ }
4688
5549
  const progressStatus = progress.status === "completed" ? "completed" : progress.status === "failed" ? "failed" : "running";
4689
- recordMissionWorkflowChild(missionBinding, _id, key, {
5550
+ recordMissionWorkflowChild(missionBinding, foregroundWorkflowRunId, key, {
4690
5551
  status: progressStatus,
4691
5552
  heartbeat: { status: progressStatus, ...childPhase ? { phase: childPhase } : {} }
4692
5553
  });
@@ -4703,7 +5564,7 @@ export function createSubagentExecutor(deps) {
4703
5564
  if (child.runId)
4704
5565
  workflowChildRunIds.set(key, child.runId);
4705
5566
  const childStatus = missionWorkflowChildStatus(result);
4706
- recordMissionWorkflowChild(missionBinding, _id, key, {
5567
+ recordMissionWorkflowChild(missionBinding, foregroundWorkflowRunId, key, {
4707
5568
  status: childStatus,
4708
5569
  ...child.runId ? { runId: child.runId } : {},
4709
5570
  ...result.details.results[0]?.agent ? { agent: result.details.results[0].agent } : {},
@@ -4715,17 +5576,18 @@ export function createSubagentExecutor(deps) {
4715
5576
  return child;
4716
5577
  },
4717
5578
  status: async (keyOrRunId, workflowSignal) => workflowChildResult(keyOrRunId, await execute(randomUUID(), { action: "status", id: keyOrRunId }, workflowSignal, undefined, ctx, preserveActiveSession, workflowParentModel)),
4718
- resolveResume: (reference) => resolveKeyedWorkflowResume(reference, deps.state),
4719
- steer: (key, message, options, workflowSignal) => steerWorkflowChildByKey({ state: deps.state, workflowRunId: _id, key, message, options, signal: workflowSignal, resolveRunId: () => workflowChildRunIds.get(key) })
5579
+ resolveResume: (reference, _signal, index) => resolveWorkflowResume(reference, deps, ctx.sessionManager.getSessionFile() ?? null, index),
5580
+ steer: (key, message, options, workflowSignal) => steerWorkflowChildByKey({ state: deps.state, workflowRunId: foregroundWorkflowRunId, key, message, options, signal: workflowSignal, resolveRunId: () => workflowChildRunIds.get(key) })
4720
5581
  });
4721
5582
  const finalPreflightWarnings = workflowPreflightWarnings(workflowPreflight, workflow.trace, { settled: true });
4722
5583
  const finalPreflightTrace = annotateWorkflowPreflightTrace(workflow.trace, workflowPreflight);
4723
- const workflowChildren = workflowChildSummary({ parentToolCallId: _id, workflowRunId: _id, workflowState: "completed", inventoryComplete: true, trace: workflow.trace, children: workflow.children });
4724
- const receipt = terminalWorkflowReceipt(_id, "complete", workflow.children, workflowChildren, undefined, [...workflowHostSteps.values()]);
5584
+ const workflowChildren = workflowChildSummary({ parentToolCallId: _id, workflowRunId: foregroundWorkflowRunId, workflowState: "completed", inventoryComplete: true, trace: workflow.trace, children: workflow.children });
5585
+ const receipt = terminalWorkflowReceipt(foregroundWorkflowRunId, "complete", workflow.children, workflowChildren, undefined, [...workflowHostSteps.values()], workflowResource?.provenance, workflowArgsDigest);
4725
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}` : ""}`);
5587
+ const runningSummary = workflowRunningChildrenSummary(workflow.children);
4726
5588
  const sections = [
4727
5589
  ...workflowPreflight ? [formatWorkflowPreflight(workflowPreflight)] : [],
4728
- "Workflow completed.",
5590
+ runningSummary ? `Workflow dispatch completed; ${runningSummary}` : "Workflow completed.",
4729
5591
  `Return:
4730
5592
  ${formatWorkflowValue(workflow.value)}`
4731
5593
  ];
@@ -4753,11 +5615,11 @@ ${traceLines.join(`
4753
5615
  const displayText = appendWorkflowOutputWarning(workflowText, outputWarning);
4754
5616
  return attachWorkflowMission(withRunFanoutBudget({
4755
5617
  content: [{ type: "text", text: displayText }],
4756
- details: compactOptional({ mode: "workflow", runId: _id, results: workflow.children.flatMap((child) => child.results ?? []), ...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, ...finalPreflightWarnings.length ? { preflightWarnings: finalPreflightWarnings } : {}, receipt }, chatProgress })
5618
+ 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 })
4757
5619
  }, workflowFanoutBudget));
4758
5620
  } catch (error) {
4759
5621
  const partial = error instanceof WorkflowScriptError ? error.partial : { trace: [], emits: [], console: [], children: [] };
4760
- const text = workflowFailureMessage(error, _id, partial.children);
5622
+ const text = workflowFailureMessage(error, foregroundWorkflowRunId, partial.children);
4761
5623
  const finalPreflightWarnings = workflowPreflightWarnings(workflowPreflight, partial.trace, { settled: true });
4762
5624
  const finalPreflightTrace = annotateWorkflowPreflightTrace(partial.trace, workflowPreflight);
4763
5625
  const traceLines = finalPreflightTrace.map((entry) => `- ${entry.operation} ${entry.key}: ${entry.state}${entry.runId ? ` (${entry.runId})` : ""}${entry.warning ? ` — ${entry.warning}` : ""}${entry.error ? ` — ${entry.error}` : ""}`);
@@ -4787,20 +5649,35 @@ ${traceLines.join(`
4787
5649
  `);
4788
5650
  const outputWarning = writeWorkflowAggregateOutput(workflowAggregateOutputPath, workflowText, producedChildOutputPaths);
4789
5651
  const displayText = appendWorkflowOutputWarning(workflowText, outputWarning);
4790
- const workflowChildren = workflowChildSummary({ parentToolCallId: _id, workflowRunId: _id, workflowState: "failed", inventoryComplete: true, trace: partial.trace, children: partial.children });
5652
+ const workflowChildren = workflowChildSummary({ parentToolCallId: _id, workflowRunId: foregroundWorkflowRunId, workflowState: "failed", inventoryComplete: true, trace: partial.trace, children: partial.children });
4791
5653
  const terminalOutcome = workflowFailureTerminalOutcome(error, partial.children, usageBudgetState(workflowUsageBudget.budget, sumResultsCost(workflowResults)));
4792
- const receipt = terminalWorkflowReceipt(_id, "failed", partial.children, workflowChildren, terminalOutcome, [...workflowHostSteps.values()]);
5654
+ const receipt = terminalWorkflowReceipt(foregroundWorkflowRunId, "failed", partial.children, workflowChildren, terminalOutcome, [...workflowHostSteps.values()], workflowResource?.provenance, workflowArgsDigest);
4793
5655
  return attachWorkflowMission(withRunFanoutBudget({
4794
5656
  content: [{ type: "text", text: displayText }],
4795
5657
  isError: true,
4796
- details: compactOptional({ mode: "workflow", runId: _id, results: partial.children.flatMap((child) => child.results ?? []), ...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, ...finalPreflightWarnings.length ? { preflightWarnings: finalPreflightWarnings } : {}, receipt }, chatProgress })
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 })
4797
5659
  }, workflowFanoutBudget));
5660
+ } finally {
5661
+ workflowProgressClosed = true;
5662
+ if (activityTimer)
5663
+ clearTimeout(activityTimer);
5664
+ childProgress.clear();
4798
5665
  }
4799
5666
  }
4800
5667
  const directParams = requestParams;
4801
- const requestedCwd = directParams.cwd;
4802
- const requestCwd = resolveRequestedCwd(ctx.cwd, directParams.cwd);
4803
- const paramsWithResolvedCwd = directParams.cwd === undefined ? directParams : { ...directParams, cwd: requestCwd };
5668
+ const placedByAgent = () => {
5669
+ if (directParams.machine !== undefined || directParams.cwd === undefined || typeof directParams.agent !== "string")
5670
+ return false;
5671
+ try {
5672
+ return resolveAgentName(directParams.agent, deps.discoverAgents(ctx.cwd, resolveExecutionAgentScope(directParams.agentScope)).agents).agent?.machine !== undefined;
5673
+ } catch {
5674
+ return false;
5675
+ }
5676
+ };
5677
+ const remotePlacement = directParams.action === undefined && (directParams.machine !== undefined || placedByAgent());
5678
+ const requestedCwd = remotePlacement ? undefined : directParams.cwd;
5679
+ const requestCwd = remotePlacement ? ctx.cwd : resolveRequestedCwd(ctx.cwd, directParams.cwd);
5680
+ const paramsWithResolvedCwd = directParams.cwd === undefined ? directParams : remotePlacement ? omitUndefinedProperties({ ...directParams, cwd: undefined, machineCwd: directParams.cwd }) : { ...directParams, cwd: requestCwd };
4804
5681
  const action = paramsWithResolvedCwd.action;
4805
5682
  let requestSessionId = "";
4806
5683
  let requestPiSessionId;
@@ -4865,7 +5742,8 @@ ${paramsWithResolvedCwd.handoffPath}`);
4865
5742
  if (!confirmed)
4866
5743
  return { content: [{ type: "text", text: "Worktree discard canceled; preserved worktrees were not changed." }], details: { mode: "management", results: [] } };
4867
5744
  try {
4868
- const discarded = discardPreservedWorktrees(path.isAbsolute(paramsWithResolvedCwd.handoffPath) ? paramsWithResolvedCwd.handoffPath : path.resolve(requestCwd, paramsWithResolvedCwd.handoffPath), { kind: decision === "confirm" ? "confirmed" : "policy", ...deps.config.authorityPolicy ? { policy: deps.config.authorityPolicy } : {} });
5745
+ const manifestPath = path.isAbsolute(paramsWithResolvedCwd.handoffPath) ? paramsWithResolvedCwd.handoffPath : path.resolve(requestCwd, paramsWithResolvedCwd.handoffPath);
5746
+ const discarded = await withWorktreeTransaction(() => discardPreservedWorktrees(manifestPath, { kind: decision === "confirm" ? "confirmed" : "policy", ...deps.config.authorityPolicy ? { policy: deps.config.authorityPolicy } : {} }));
4869
5747
  return { content: [{ type: "text", text: discarded.text }], details: { mode: "management", results: [] } };
4870
5748
  } catch (error) {
4871
5749
  return { content: [{ type: "text", text: error instanceof Error ? error.message : String(error) }], isError: true, details: { mode: "management", results: [] } };
@@ -4900,6 +5778,23 @@ ${paramsWithResolvedCwd.handoffPath}`);
4900
5778
  return { content: [{ type: "text", text: error instanceof Error ? error.message : String(error) }], isError: true, details: { mode: "management", results: [] } };
4901
5779
  }
4902
5780
  }
5781
+ const policyAction = action === "stop" ? "stopRun" : action === "steer" ? "steerRun" : action === "schedule.create" ? "scheduleCreate" : action === "inspector.open" ? "inspectorOpen" : action === "project.open" ? "projectOpen" : undefined;
5782
+ if (policyAction) {
5783
+ if (deps.allowMutatingManagementActions === false && MUTATING_MANAGEMENT_ACTIONS.has(action)) {
5784
+ return { content: [{ type: "text", text: `Action '${action}' is not available from child-safe subagent fanout mode.` }], isError: true, details: { mode: "management", results: [] } };
5785
+ }
5786
+ const decision = resolveAuthorityDecision({ action: policyAction, ...deps.config.authorityPolicy === undefined ? {} : { policy: deps.config.authorityPolicy } });
5787
+ if (decision === "forbid") {
5788
+ return { content: [{ type: "text", text: `Authority policy forbids action '${action}'.` }], isError: true, details: { mode: "management", results: [] } };
5789
+ }
5790
+ if (decision === "confirm") {
5791
+ if (!ctx.hasUI)
5792
+ return { content: [{ type: "text", text: `Authority policy requires user confirmation for action '${action}', but this session has no interactive UI.` }], isError: true, details: { mode: "management", results: [] } };
5793
+ const confirmed = await ctx.ui.confirm(`Authorize subagent ${action}?`, `Authority policy requires confirmation before '${action}'.`);
5794
+ if (!confirmed)
5795
+ return { content: [{ type: "text", text: `Action '${action}' canceled; authority was not granted.` }], details: { mode: "management", results: [] } };
5796
+ }
5797
+ }
4903
5798
  if (HERDR_PROJECT_PANE_ACTIONS.includes(action)) {
4904
5799
  if (deps.allowMutatingManagementActions === false && MUTATING_MANAGEMENT_ACTIONS.has(action)) {
4905
5800
  return { content: [{ type: "text", text: `Action '${action}' is not available from child-safe subagent fanout mode.` }], isError: true, details: { mode: "management", results: [] } };
@@ -4907,16 +5802,17 @@ ${paramsWithResolvedCwd.handoffPath}`);
4907
5802
  deps.state.currentSessionId = resolveCurrentSessionId(ctx.sessionManager);
4908
5803
  return handleHerdrProjectPaneAction(action, paramsWithResolvedCwd, { cwd: requestCwd, state: deps.state, signal });
4909
5804
  }
4910
- if (HERDR_INSPECTOR_ACTIONS.includes(action)) {
5805
+ if (INSPECTOR_ACTIONS.includes(action)) {
4911
5806
  if (deps.allowMutatingManagementActions === false && MUTATING_MANAGEMENT_ACTIONS.has(action)) {
4912
5807
  return { content: [{ type: "text", text: `Action '${action}' is not available from child-safe subagent fanout mode.` }], isError: true, details: { mode: "management", results: [] } };
4913
5808
  }
4914
5809
  deps.state.currentSessionId = resolveCurrentSessionId(ctx.sessionManager);
4915
- return handleHerdrInspectorAction(action, paramsWithResolvedCwd, {
5810
+ return handleInspectorAction(action, paramsWithResolvedCwd, {
4916
5811
  state: deps.state,
4917
5812
  cwd: requestCwd,
4918
5813
  ...deps.config.missions ? { missions: deps.config.missions } : {},
4919
5814
  ...deps.config.authorityPolicy ? { authorityPolicy: deps.config.authorityPolicy } : {},
5815
+ plugins: createBuiltinInspectorPlugins(),
4920
5816
  signal
4921
5817
  });
4922
5818
  }
@@ -4935,20 +5831,6 @@ ${paramsWithResolvedCwd.handoffPath}`);
4935
5831
  ...currentSessionId ? { currentSessionId } : {}
4936
5832
  });
4937
5833
  }
4938
- const policyAction = action === "stop" ? "stopRun" : action === "steer" ? "steerRun" : action === "schedule.create" ? "scheduleCreate" : undefined;
4939
- if (policyAction) {
4940
- const decision = resolveAuthorityDecision({ action: policyAction, ...deps.config.authorityPolicy === undefined ? {} : { policy: deps.config.authorityPolicy } });
4941
- if (decision === "forbid") {
4942
- return { content: [{ type: "text", text: `Authority policy forbids action '${action}'.` }], isError: true, details: { mode: "management", results: [] } };
4943
- }
4944
- if (decision === "confirm") {
4945
- if (!ctx.hasUI)
4946
- return { content: [{ type: "text", text: `Authority policy requires user confirmation for action '${action}', but this session has no interactive UI.` }], isError: true, details: { mode: "management", results: [] } };
4947
- const confirmed = await ctx.ui.confirm(`Authorize subagent ${action}?`, `Authority policy requires confirmation before '${action}'.`);
4948
- if (!confirmed)
4949
- return { content: [{ type: "text", text: `Action '${action}' canceled; authority was not granted.` }], details: { mode: "management", results: [] } };
4950
- }
4951
- }
4952
5834
  if (WATCHDOG_TOOL_ACTIONS.includes(action)) {
4953
5835
  if (deps.allowMutatingManagementActions === false && MUTATING_MANAGEMENT_ACTIONS.has(action)) {
4954
5836
  return {
@@ -5084,7 +5966,7 @@ Usage is not reset. Compaction keeps the same budget; a new parent session start
5084
5966
  }
5085
5967
  let orchestratorTarget;
5086
5968
  try {
5087
- orchestratorTarget = resolveIntercomSessionTarget(deps.dm.getSessionName(), ctx.sessionManager.getSessionId());
5969
+ orchestratorTarget = resolveIntercomSessionTarget(deps.childRuntime?.intercomSessionName ?? deps.dm.getSessionName(), ctx.sessionManager.getSessionId());
5088
5970
  } catch (error) {
5089
5971
  if (!sessionError)
5090
5972
  sessionError = error instanceof Error ? `${error.name}: ${error.message}` : String(error);
@@ -5136,7 +6018,7 @@ ${item.text}` } : item)
5136
6018
  }
5137
6019
  return withBudget(inspectSubagentStatus(paramsWithResolvedCwd, omitUndefinedProperties({ state: deps.state, nested: nestedScope, sessionRoots, abandonedSlotReleaseAfterMs: resolveAbandonedSlotReleaseAfterMs(deps.config.capacity?.abandonedSlotReleaseAfterMs) })));
5138
6020
  }
5139
- if (paramsWithResolvedCwd.view === "fleet") {
6021
+ if (paramsWithResolvedCwd.view === "fleet" || paramsWithResolvedCwd.view === "transcript") {
5140
6022
  return withBudget(inspectSubagentStatus(paramsWithResolvedCwd, omitUndefinedProperties({ state: deps.state, nested: nestedScope, sessionRoots, abandonedSlotReleaseAfterMs: resolveAbandonedSlotReleaseAfterMs(deps.config.capacity?.abandonedSlotReleaseAfterMs) })));
5141
6023
  }
5142
6024
  if (targetRunId) {
@@ -5145,12 +6027,6 @@ ${item.text}` } : item)
5145
6027
  if (resolved?.kind === "foreground") {
5146
6028
  const foreground = getForegroundControl(deps.state, resolved.id);
5147
6029
  if (foreground) {
5148
- if (paramsWithResolvedCwd.view === "transcript") {
5149
- return withBudget({
5150
- content: [{ type: "text", text: "Live foreground transcript is already visible in the expanded running subagent result. Persisted session transcript becomes inspectable after the foreground run completes when sessions are enabled." }],
5151
- details: { mode: "management", results: [] }
5152
- });
5153
- }
5154
6030
  return withBudget(foregroundStatusResult(foreground));
5155
6031
  }
5156
6032
  }
@@ -5160,19 +6036,24 @@ ${item.text}` } : item)
5160
6036
  }
5161
6037
  } else if (!hasDirectoryTarget) {
5162
6038
  const foreground = getForegroundControl(deps.state, undefined);
5163
- if (foreground && paramsWithResolvedCwd.view !== "transcript")
6039
+ if (foreground)
5164
6040
  return withBudget(foregroundStatusResult(foreground));
5165
- if (foreground && paramsWithResolvedCwd.view === "transcript") {
5166
- return withBudget({
5167
- content: [{ type: "text", text: "Live foreground transcript is already visible in the expanded running subagent result. Pass an async run id to inspect a background transcript." }],
5168
- details: { mode: "management", results: [] }
5169
- });
5170
- }
5171
6041
  }
5172
6042
  return withBudget(inspectSubagentStatus(paramsWithResolvedCwd, omitUndefinedProperties({ state: deps.state, nested: nestedScope, sessionRoots, abandonedSlotReleaseAfterMs: resolveAbandonedSlotReleaseAfterMs(deps.config.capacity?.abandonedSlotReleaseAfterMs) })));
5173
6043
  }
5174
6044
  if (action === "resume") {
5175
- return resumeAsyncRun(omitUndefinedProperties({ params: paramsWithResolvedCwd, requestCwd, ctx, deps, parentModel: requestParentModel, signal }));
6045
+ return resumeAsyncRun(omitUndefinedProperties({
6046
+ params: paramsWithResolvedCwd,
6047
+ requestCwd,
6048
+ ctx,
6049
+ deps,
6050
+ parentModel: requestParentModel,
6051
+ signal,
6052
+ ...workflowLaunchObserver ? { onLaunch: (launch) => {
6053
+ workflowLaunchObservers.delete(params);
6054
+ workflowLaunchObserver(launch);
6055
+ } } : {}
6056
+ }));
5176
6057
  }
5177
6058
  if (action === "steer") {
5178
6059
  if (paramsWithResolvedCwd.mode !== undefined && resolveSteerDeliveryMode(paramsWithResolvedCwd.mode) === undefined) {
@@ -5189,10 +6070,7 @@ ${item.text}` } : item)
5189
6070
  const runId = location.resolvedId ?? targetRunId ?? path.basename(location.asyncDir ?? paramsWithResolvedCwd.dir);
5190
6071
  const directoryStatus = location.asyncDir ? readStatus(location.asyncDir) : null;
5191
6072
  if (directoryStatus?.mode === "workflow") {
5192
- const route = resolveWorkflowForegroundSteeringTarget({ state: deps.state, workflowRunId: directoryStatus.runId || runId, asyncDirRoot: DIRS.async });
5193
- if (!route.ok)
5194
- return { content: [{ type: "text", text: route.message }], isError: true, details: { mode: "management", results: [] } };
5195
- return steerWorkflowForegroundTarget({ target: route.target, message, mode: resolveSteerDeliveryMode(paramsWithResolvedCwd.mode), index: paramsWithResolvedCwd.index, signal });
6073
+ return steerWorkflowRun({ state: deps.state, runId, asyncDir: location.asyncDir, message, mode: resolveSteerDeliveryMode(paramsWithResolvedCwd.mode), index: paramsWithResolvedCwd.index, signal });
5196
6074
  }
5197
6075
  if (location.asyncDir) {
5198
6076
  const unsupported = externalRunnerControlError(location.asyncDir, "steer");
@@ -5201,6 +6079,7 @@ ${item.text}` } : item)
5201
6079
  }
5202
6080
  return steerAsyncRun(compactOptional({
5203
6081
  state: deps.state,
6082
+ findPendingAsks: deps.findPendingAsks,
5204
6083
  runId,
5205
6084
  message,
5206
6085
  mode: resolveSteerDeliveryMode(paramsWithResolvedCwd.mode),
@@ -5232,16 +6111,13 @@ ${item.text}` } : item)
5232
6111
  const route = resolveWorkflowForegroundSteeringTarget({ state: deps.state, childRunId: resolved.id, asyncDirRoot: DIRS.async });
5233
6112
  if (!route.ok)
5234
6113
  return { content: [{ type: "text", text: route.message }], isError: true, details: { mode: "management", results: [] } };
5235
- return steerWorkflowForegroundTarget({ target: route.target, message, mode: resolveSteerDeliveryMode(paramsWithResolvedCwd.mode), index: paramsWithResolvedCwd.index, signal });
6114
+ return steerWorkflowForegroundTarget({ target: route.target, message, mode: resolveSteerDeliveryMode(paramsWithResolvedCwd.mode), index: paramsWithResolvedCwd.index });
5236
6115
  }
5237
6116
  if (resolved?.kind !== "async")
5238
6117
  return { content: [{ type: "text", text: `No async run found for '${targetRunId}'.` }], isError: true, details: { mode: "management", results: [] } };
5239
6118
  const resolvedStatus = resolved.location.asyncDir ? readStatus(resolved.location.asyncDir) : null;
5240
6119
  if (resolvedStatus?.mode === "workflow") {
5241
- const route = resolveWorkflowForegroundSteeringTarget({ state: deps.state, workflowRunId: resolvedStatus.runId || resolved.id, asyncDirRoot: DIRS.async });
5242
- if (!route.ok)
5243
- return { content: [{ type: "text", text: route.message }], isError: true, details: { mode: "management", results: [] } };
5244
- return steerWorkflowForegroundTarget({ target: route.target, message, mode: resolveSteerDeliveryMode(paramsWithResolvedCwd.mode), index: paramsWithResolvedCwd.index, signal });
6120
+ return steerWorkflowRun({ state: deps.state, runId: resolved.id, asyncDir: resolved.location.asyncDir, message, mode: resolveSteerDeliveryMode(paramsWithResolvedCwd.mode), index: paramsWithResolvedCwd.index, signal });
5245
6121
  }
5246
6122
  if (resolved.location.asyncDir) {
5247
6123
  const unsupported = externalRunnerControlError(resolved.location.asyncDir, "steer");
@@ -5250,6 +6126,7 @@ ${item.text}` } : item)
5250
6126
  }
5251
6127
  return steerAsyncRun(compactOptional({
5252
6128
  state: deps.state,
6129
+ findPendingAsks: deps.findPendingAsks,
5253
6130
  runId: resolved.id,
5254
6131
  message,
5255
6132
  mode: resolveSteerDeliveryMode(paramsWithResolvedCwd.mode),
@@ -5318,7 +6195,8 @@ ${item.text}` } : item)
5318
6195
  if (action === "stop") {
5319
6196
  const targetRunId = paramsWithResolvedCwd.runId ?? paramsWithResolvedCwd.id;
5320
6197
  const workflowController = targetRunId ? deps.state.workflowControllers?.get(targetRunId) : undefined;
5321
- if (workflowController) {
6198
+ if (workflowController && targetRunId) {
6199
+ const stopChild = deps.state.workflowChildStops?.get(targetRunId);
5322
6200
  if (paramsWithResolvedCwd.childId !== undefined) {
5323
6201
  const workflowRunId = targetRunId;
5324
6202
  const asyncJob = deps.state.asyncJobs.get(workflowRunId);
@@ -5332,7 +6210,6 @@ ${item.text}` } : item)
5332
6210
  return { content: [{ type: "text", text: resolution.message }], isError: true, details: { mode: "management", results: [] } };
5333
6211
  if (!isStoppableAsyncStatusStep(resolution.child.step))
5334
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: [] } };
5335
- const stopChild = deps.state.workflowChildStops?.get(targetRunId);
5336
6213
  if (!stopChild)
5337
6214
  return { content: [{ type: "text", text: `Workflow ${targetRunId} child stop is unavailable in this extension runtime.` }], isError: true, details: { mode: "management", results: [] } };
5338
6215
  if (!stopChild(resolution.child.id, `Workflow child '${resolution.child.id}' stopped.`))
@@ -5360,6 +6237,10 @@ ${item.text}` } : item)
5360
6237
  }
5361
6238
  return { content: [{ type: "text", text: `Stop requested for child ${resolution.child.id} in async workflow ${workflowRunId}.` }], details: { mode: "management", results: [] } };
5362
6239
  }
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.");
5363
6244
  workflowController.abort(new Error("Workflow stopped."));
5364
6245
  return { content: [{ type: "text", text: `Stop requested for async workflow ${targetRunId}.` }], details: { mode: "management", results: [] } };
5365
6246
  }
@@ -5446,10 +6327,12 @@ ${item.text}` } : item)
5446
6327
  cwd: requestCwd,
5447
6328
  config: deps.config,
5448
6329
  currentSessionId: deps.state.currentSessionId ?? ctx.sessionManager.getSessionId() ?? undefined,
5449
- runtimeAgentOwner: deps.dm
6330
+ discoverAgentsAll: deps.discoverAgentsAll,
6331
+ runtimeAgentOwner: deps.dm,
6332
+ onAgentsChanged: deps.onAgentsChanged
5450
6333
  });
5451
6334
  }
5452
- const { blocked, depth, maxDepth } = checkSubagentDepth(deps.config.maxSubagentDepth);
6335
+ const { blocked, depth, maxDepth } = checkSubagentDepth(deps.config.maxSubagentDepth, deps.childRuntime);
5453
6336
  if (blocked) {
5454
6337
  return {
5455
6338
  content: [
@@ -5466,6 +6349,9 @@ ${item.text}` } : item)
5466
6349
  if (normalized.error)
5467
6350
  return normalized.error;
5468
6351
  const normalizedParams = normalized.params;
6352
+ const outputSchemaError = validateLaunchOutputSchemaOverrides(normalizedParams);
6353
+ if (outputSchemaError)
6354
+ return buildRequestedModeError(normalizedParams, outputSchemaError);
5469
6355
  let effectiveParams = applyForceTopLevelAsyncOverride(normalizedParams, depth, deps.config.forceTopLevelAsync === true);
5470
6356
  const runToolBudget = resolveToolBudget(effectiveParams.toolBudget, "toolBudget", allowZeroToolBudget ? { minimumHard: 0 } : undefined);
5471
6357
  if (runToolBudget.error)
@@ -5486,14 +6372,20 @@ ${item.text}` } : item)
5486
6372
  if (canonicalParams.error)
5487
6373
  return buildRequestedModeError(effectiveParams, canonicalParams.error);
5488
6374
  effectiveParams = canonicalParams.params;
6375
+ if (effectiveParams.worktree === undefined && deps.config.worktree !== undefined) {
6376
+ effectiveParams = { ...effectiveParams, worktree: deps.config.worktree };
6377
+ }
5489
6378
  const modelScope = discovered.modelScope;
5490
6379
  effectiveParams = applySingleAgentLaunchDefaults(effectiveParams, discoveredAgents);
6380
+ const typedVerifyConflict = describeTypedVerifyOutputSchemaConflict(effectiveParams, params);
6381
+ if (typedVerifyConflict)
6382
+ return buildRequestedModeError(effectiveParams, typedVerifyConflict);
5491
6383
  const contextPolicyResult = resolveAgentDefaultContextPolicy(effectiveParams, discoveredAgents, deps.config.defaultSubagentContext, canPreferFork(ctx.sessionManager));
5492
6384
  if ("error" in contextPolicyResult)
5493
6385
  return buildRequestedModeError(effectiveParams, contextPolicyResult.error);
5494
6386
  const contextPolicy = contextPolicyResult;
5495
6387
  effectiveParams = contextPolicy.params;
5496
- const sessionName = resolveIntercomSessionTarget(deps.dm.getSessionName(), ctx.sessionManager.getSessionId());
6388
+ const sessionName = resolveIntercomSessionTarget(deps.childRuntime?.intercomSessionName ?? deps.dm.getSessionName(), ctx.sessionManager.getSessionId());
5497
6389
  const intercomBridge = resolveIntercomBridge({
5498
6390
  config: deps.config.intercomBridge,
5499
6391
  override: effectiveParams.intercomBridge,
@@ -5501,9 +6393,8 @@ ${item.text}` } : item)
5501
6393
  orchestratorTarget: sessionName
5502
6394
  });
5503
6395
  const agents = applyScopedIntercomBridgeToAgents(discoveredAgents, intercomBridge, contextPolicy);
5504
- const runId = randomUUID();
5505
- const inheritedNestedRoute = resolveInheritedNestedRouteFromEnv();
5506
- const nestedParentAddress = inheritedNestedRoute ? resolveNestedParentAddressFromEnv() : undefined;
6396
+ const inheritedNestedRouteValue = inheritedNestedRoute(deps);
6397
+ const nestedParentAddress = inheritedNestedRouteValue ? inheritedNestedParentAddress(deps) : undefined;
5507
6398
  const shareEnabled = effectiveParams.share === true;
5508
6399
  const hasChain = (effectiveParams.chain?.length ?? 0) > 0;
5509
6400
  const hasTasks = (effectiveParams.tasks?.length ?? 0) > 0;
@@ -5521,33 +6412,11 @@ ${item.text}` } : item)
5521
6412
  return;
5522
6413
  };
5523
6414
  let prepareForkSessionForIndex = async () => {};
5524
- let forkThinkingOverrideForIndex = () => {
5525
- return;
5526
- };
5527
- let prepareForkThinking = (_agentName, _index, _modelOverride, _modelOverrideFromParent) => {};
5528
- const forkThinkingRequirements = new Map;
5529
- const forkThinkingDowngrades = new Map;
5530
6415
  try {
5531
- const forkAvailableModels = contextPolicy.usesFork ? ctx.modelRegistry.getAvailable().map(toModelInfo) : [];
5532
- const parentModel = requestParentModel;
5533
- prepareForkThinking = (agentName, index, modelOverride, modelOverrideFromParent) => {
5534
- const agentConfig = agents.find((agent) => agent.name === agentName);
5535
- if (agentConfig?.runner?.type === "external-cli" || agentConfig?.runner?.type === "external-job") {
5536
- forkThinkingRequirements.set(index, true);
5537
- return;
5538
- }
5539
- const primaryModel = modelOverrideFromParent ? modelOverride : resolveEffectiveSubagentModel(modelOverride, agentConfig?.model, parentModel, forkAvailableModels, agentConfig?.modelProvider ?? parentModel?.provider, { source: "inherited" });
5540
- const candidates = buildModelCandidates(primaryModel, agentConfig?.fallbackModels, forkAvailableModels, agentConfig?.modelProvider ?? parentModel?.provider, { primaryModelFromParent: modelOverrideFromParent ?? inheritsParentModel(modelOverride, agentConfig?.model, parentModel) });
5541
- forkThinkingRequirements.set(index, candidates.length === 0 || candidates.some((candidate) => forkedChildRequiresThinkingOff(candidate, forkAvailableModels, parentModel?.provider)));
5542
- };
5543
6416
  const pruneSession = contextPolicy.usesFork && deps.config.forkContext?.mode === "pruned" ? await createPrunedForkSessionWriter(ctx, deps.config.forkContext, signal) : undefined;
5544
- const forkContextResolver = createForkContextResolver(ctx.sessionManager, contextPolicy.usesFork ? "fork" : undefined, {
5545
- forceThinkingOffForIndex: (index) => forkThinkingRequirements.get(index) ?? true,
5546
- ...pruneSession ? { pruneSession } : {}
5547
- });
6417
+ const forkContextResolver = createForkContextResolver(ctx.sessionManager, contextPolicy.usesFork ? "fork" : undefined, pruneSession ? { pruneSession } : {});
5548
6418
  prepareForkSessionForIndex = forkContextResolver.prepareSessionForIndex;
5549
6419
  forkSessionFileForIndex = forkContextResolver.sessionFileForIndex;
5550
- forkThinkingOverrideForIndex = forkContextResolver.thinkingOverrideForIndex;
5551
6420
  } catch (error) {
5552
6421
  return toExecutionErrorResult(effectiveParams, error, contextPolicy.contextSummary);
5553
6422
  }
@@ -5560,13 +6429,21 @@ ${item.text}` } : item)
5560
6429
  if (externalAgent && (!effectiveAsync || effectiveParams.foregroundOnly === true)) {
5561
6430
  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.`);
5562
6431
  }
6432
+ if (effectiveAsync && hasSingle && effectiveParams.resume === undefined && effectiveParams.worktree === true) {
6433
+ try {
6434
+ await preflightWorktreeSource(effectiveCwd, { signal });
6435
+ } catch (error) {
6436
+ return toExecutionErrorResult(effectiveParams, error, contextPolicy.contextSummary);
6437
+ }
6438
+ }
6439
+ const runId = randomUUID();
5563
6440
  const foregroundTimeout = resolveSingleAgentLaunchTimeout(effectiveParams, effectiveAsync, resolveConfigDefaultTimeoutMs(deps.config.timeoutMs));
5564
6441
  if (foregroundTimeout.error)
5565
6442
  return buildRequestedModeError(effectiveParams, foregroundTimeout.error);
5566
6443
  const controlConfig = resolveControlConfig(deps.config.control, effectiveParams.control);
5567
6444
  const requestedWorkflowChildAsyncId = typeof effectiveParams.workflowChildAsyncId === "string" ? effectiveParams.workflowChildAsyncId.trim() : "";
5568
6445
  const asyncRunId = requestedWorkflowChildAsyncId && path.basename(requestedWorkflowChildAsyncId) === requestedWorkflowChildAsyncId ? requestedWorkflowChildAsyncId : randomUUID();
5569
- const topLevelAsyncCapacityEligible = depth === 0 && !inheritedNestedRoute && !effectiveParams.workflowParentRunId;
6446
+ const topLevelAsyncCapacityEligible = depth === 0 && !inheritedNestedRouteValue && !effectiveParams.workflowParentRunId;
5570
6447
  const topLevelAsync = effectiveAsync && topLevelAsyncCapacityEligible;
5571
6448
  let activeAsyncCapacity;
5572
6449
  if (topLevelAsync) {
@@ -5590,8 +6467,8 @@ ${item.text}` } : item)
5590
6467
  }
5591
6468
  let runFanoutBudget;
5592
6469
  try {
5593
- const inheritedRunFanoutBudget = effectiveParams.runFanoutBudget ? undefined : decodeRunFanoutBudgetDescriptor(process.env[RUN_FANOUT_BUDGET_ENV]);
5594
- runFanoutBudget = effectiveParams.runFanoutBudget ?? (inheritedRunFanoutBudget ? { ...inheritedRunFanoutBudget, parentPath: `${inheritedRunFanoutBudget.parentPath ? `${inheritedRunFanoutBudget.parentPath}/` : ""}${runId}` } : undefined) ?? createRunFanoutBudget(runId, resolveMaxSubagentSpawnsPerRun(deps.config.maxSubagentSpawnsPerRun));
6470
+ const inheritedRunFanoutBudgetValue = effectiveParams.runFanoutBudget ? undefined : inheritedRunFanoutBudget(deps);
6471
+ runFanoutBudget = effectiveParams.runFanoutBudget ?? (inheritedRunFanoutBudgetValue ? { ...inheritedRunFanoutBudgetValue, parentPath: `${inheritedRunFanoutBudgetValue.parentPath ? `${inheritedRunFanoutBudgetValue.parentPath}/` : ""}${runId}` } : undefined) ?? createRunFanoutBudget(runId, resolveMaxSubagentSpawnsPerRun(deps.config.maxSubagentSpawnsPerRun));
5595
6472
  if (!effectiveParams.runFanoutAdmitted)
5596
6473
  claimRunFanoutBatch(runFanoutBudget, staticRunFanoutPaths(effectiveParams));
5597
6474
  } catch (error) {
@@ -5600,7 +6477,7 @@ ${item.text}` } : item)
5600
6477
  return runFanoutErrorResult(error, foregroundMode);
5601
6478
  return buildRequestedModeError(effectiveParams, error instanceof Error ? error.message : String(error));
5602
6479
  }
5603
- const nestedRoute = inheritedNestedRoute ?? createNestedRoute(runId);
6480
+ const nestedRoute = inheritedNestedRouteValue ?? createNestedRoute(runId);
5604
6481
  const artifactConfig = omitUndefinedProperties({
5605
6482
  ...DEFAULT_ARTIFACT_CONFIG,
5606
6483
  enabled: effectiveParams.artifacts !== false,
@@ -5615,7 +6492,7 @@ ${item.text}` } : item)
5615
6492
  }
5616
6493
  let sessionRoot;
5617
6494
  if (effectiveParams.sessionDir) {
5618
- sessionRoot = path.resolve(deps.expandTilde(effectiveParams.sessionDir));
6495
+ sessionRoot = path.join(path.resolve(deps.expandTilde(effectiveParams.sessionDir)), runId);
5619
6496
  } else {
5620
6497
  const baseSessionRoot = deps.config.defaultSessionDir ? path.resolve(deps.expandTilde(deps.config.defaultSessionDir)) : deps.getSubagentSessionRoot(parentSessionFile);
5621
6498
  sessionRoot = path.join(baseSessionRoot, runId);
@@ -5628,28 +6505,18 @@ ${item.text}` } : item)
5628
6505
  return toExecutionErrorResult(effectiveParams, new Error(`Failed to create session directory '${sessionRoot}': ${message}`), contextPolicy.contextSummary);
5629
6506
  }
5630
6507
  const sessionDirForIndex = (idx) => path.join(sessionRoot, `run-${idx ?? 0}`);
5631
- const forkSessionFileForTask = (agentName, idx = 0, modelOverride, modelOverrideFromParent) => {
6508
+ const forkSessionFileForTask = (agentName, idx = 0) => {
5632
6509
  if (!shouldForkAgent(contextPolicy, agentName))
5633
6510
  return;
5634
- prepareForkThinking(agentName, idx, modelOverride, modelOverrideFromParent);
5635
6511
  return forkSessionFileForIndex(idx);
5636
6512
  };
5637
- const prepareForkSessionForTask = async (agentName, idx = 0, modelOverride, modelOverrideFromParent) => {
6513
+ const prepareForkSessionForTask = async (agentName, idx = 0) => {
5638
6514
  if (!shouldForkAgent(contextPolicy, agentName))
5639
6515
  return;
5640
- prepareForkThinking(agentName, idx, modelOverride, modelOverrideFromParent);
5641
6516
  await prepareForkSessionForIndex(idx);
5642
6517
  };
5643
- const forkThinkingOverrideForTask = (agentName, idx = 0, modelOverride, modelOverrideFromParent) => {
5644
- if (!shouldForkAgent(contextPolicy, agentName))
5645
- return delegatedThinkingOverride;
5646
- prepareForkThinking(agentName, idx, modelOverride, modelOverrideFromParent);
5647
- const override = forkThinkingOverrideForIndex(idx);
5648
- if (override === "off")
5649
- forkThinkingDowngrades.set(idx, agentName);
5650
- return override ?? delegatedThinkingOverride;
5651
- };
5652
- const childSessionFileForTask = (agentName, idx, modelOverride, modelOverrideFromParent) => forkSessionFileForTask(agentName, idx, modelOverride, modelOverrideFromParent) ?? path.join(sessionDirForIndex(idx), "session.jsonl");
6518
+ const thinkingOverrideForTask = () => delegatedThinkingOverride;
6519
+ const childSessionFileForTask = (agentName, idx, modelOverride, modelOverrideFromParent, modelOrigin) => forkSessionFileForTask(agentName, idx, modelOverride, modelOverrideFromParent, modelOrigin) ?? path.join(sessionDirForIndex(idx), "session.jsonl");
5653
6520
  const childSessionFileForIndex = (idx) => path.join(sessionDirForIndex(idx), "session.jsonl");
5654
6521
  try {
5655
6522
  if (!(effectiveParams.clarify === true && ctx.hasUI) || deps.config.forkContext?.mode === "pruned") {
@@ -5724,18 +6591,20 @@ ${item.text}` } : item)
5724
6591
  sessionDirForIndex,
5725
6592
  sessionFileForIndex: childSessionFileForIndex,
5726
6593
  sessionFileForTask: childSessionFileForTask,
5727
- thinkingOverrideForTask: forkThinkingOverrideForTask,
6594
+ thinkingOverrideForTask,
5728
6595
  artifactConfig,
5729
6596
  artifactsDir,
5730
6597
  backgroundRequestedWhileClarifying,
5731
6598
  effectiveAsync,
5732
6599
  asyncRunId,
5733
6600
  controlConfig,
6601
+ ...delegatedExecution ? { suppressUnchangedDelegationUpdates: true } : {},
5734
6602
  intercomBridge,
5735
6603
  nestedRoute,
5736
6604
  timeoutMs: foregroundTimeout.timeoutMs,
5737
6605
  toolBudget: runToolBudget.toolBudget,
5738
6606
  usageBudget: usageBudget.budget,
6607
+ inheritedUsageBudget,
5739
6608
  allowZeroToolBudget,
5740
6609
  configToolBudget: configToolBudget.toolBudget,
5741
6610
  configToolTimeoutMs: deps.config.toolTimeoutMs,
@@ -5751,15 +6620,12 @@ ${item.text}` } : item)
5751
6620
  workflowChildPermitLaunch
5752
6621
  });
5753
6622
  const foregroundDescription = selectedAgentNames.length === 1 ? `${selectedAgentNames[0]} child` : `${selectedAgentNames.length} live children`;
5754
- const parentWorkflowStatus = effectiveParams.workflowParentRunId ? readStatus(path.join(DIRS.async, effectiveParams.workflowParentRunId)) : null;
5755
- const workflowSteeringDir = effectiveParams.workflowParentRunId && requestSessionId && deps.state.workflowControllers?.has(effectiveParams.workflowParentRunId) && parentWorkflowStatus?.mode === "workflow" && (parentWorkflowStatus.state === "running" || parentWorkflowStatus.state === "queued") && parentWorkflowStatus.sessionId === requestSessionId ? workflowForegroundSteeringDir(DIRS.async, effectiveParams.workflowParentRunId, runId) : undefined;
5756
6623
  const foregroundControl = effectiveAsync ? undefined : compactOptional({
5757
6624
  runId,
5758
6625
  sessionId: requestSessionId,
5759
6626
  mode: foregroundMode,
5760
6627
  ...effectiveParams.workflowParentRunId ? { parentWorkflowRunId: effectiveParams.workflowParentRunId } : {},
5761
6628
  ...effectiveParams.workflowKey ? { workflowKey: effectiveParams.workflowKey } : {},
5762
- workflowSteeringDir,
5763
6629
  startedAt: Date.now(),
5764
6630
  updatedAt: Date.now(),
5765
6631
  cwd: effectiveCwd,
@@ -5811,7 +6677,7 @@ ${item.text}` } : item)
5811
6677
  deps.refreshResultDelivery?.();
5812
6678
  }
5813
6679
  const writeNestedForegroundEvent = (type, result) => {
5814
- if (!inheritedNestedRoute || !nestedParentAddress)
6680
+ if (!inheritedNestedRouteValue || !nestedParentAddress)
5815
6681
  return;
5816
6682
  const now = Date.now();
5817
6683
  const details = result?.details;
@@ -5826,7 +6692,7 @@ ${item.text}` } : item)
5826
6692
  availableModels: ctx.modelRegistry.getAvailable().map(toModelInfo),
5827
6693
  currentProvider: requestParentModel?.provider,
5828
6694
  modelScope,
5829
- thinkingOverrideForTask: forkThinkingOverrideForTask,
6695
+ thinkingOverrideForTask,
5830
6696
  dynamicFanoutMaxItems: deps.config.chain?.dynamicFanout?.maxItems
5831
6697
  });
5832
6698
  } catch (error) {
@@ -5836,7 +6702,7 @@ ${item.text}` } : item)
5836
6702
  const agentsForSummary = startedLaunches.map((launch) => launch.agent);
5837
6703
  const leafIntercomTarget = agentsForSummary[0] && intercomBridgeAppliesToAgent(intercomBridge, contextPolicy, agentsForSummary[0]) ? resolveSubagentIntercomTarget(runId, agentsForSummary[0], 0) : undefined;
5838
6704
  try {
5839
- writeNestedEvent(inheritedNestedRoute, compactOptional({
6705
+ writeNestedEvent(inheritedNestedRouteValue, compactOptional({
5840
6706
  type,
5841
6707
  ts: now,
5842
6708
  parentRunId: nestedParentAddress.parentRunId,
@@ -5847,7 +6713,7 @@ ${item.text}` } : item)
5847
6713
  parentStepIndex: nestedParentAddress.parentStepIndex,
5848
6714
  depth: nestedParentAddress.depth,
5849
6715
  path: nestedParentAddress.path,
5850
- ownerIntercomTarget: process.env.DM_SUBAGENT_INTERCOM_SESSION_NAME,
6716
+ ownerIntercomTarget: deps.childRuntime?.intercomSessionName,
5851
6717
  leafIntercomTarget,
5852
6718
  intercomTarget: leafIntercomTarget,
5853
6719
  ownerState: state === "running" ? "live" : "gone",
@@ -5902,7 +6768,7 @@ ${item.text}` } : item)
5902
6768
  const asyncResult = await runAsyncPath(execData, deps);
5903
6769
  if (asyncResult) {
5904
6770
  asyncLaunchFailed = asyncResult.isError === true;
5905
- return attachMission(withRunFanoutBudget(withResolvedContext(withForkThinkingNotes(asyncResult, forkThinkingDowngrades), contextPolicy.contextSummary), runFanoutBudget));
6771
+ return attachMission(withRunFanoutBudget(withResolvedContext(asyncResult, contextPolicy.contextSummary), runFanoutBudget));
5906
6772
  }
5907
6773
  if (foregroundControl) {
5908
6774
  writeNestedForegroundEvent("subagent.nested.started");
@@ -5912,11 +6778,11 @@ ${item.text}` } : item)
5912
6778
  if (hasSingle) {
5913
6779
  const result = await runSinglePath(execData, deps);
5914
6780
  writeNestedForegroundEvent("subagent.nested.completed", result);
5915
- return attachMission(withRunFanoutBudget(withResolvedContext(withForkThinkingNotes(result, forkThinkingDowngrades), contextPolicy.contextSummary), runFanoutBudget, { annotateContent: runFanoutAnnotateContent }));
6781
+ return attachMission(withRunFanoutBudget(withResolvedContext(result, contextPolicy.contextSummary), runFanoutBudget, { annotateContent: runFanoutAnnotateContent }));
5916
6782
  }
5917
6783
  } catch (error) {
5918
6784
  asyncLaunchFailed = effectiveAsync;
5919
- const errorResult = withForkThinkingNotes(toExecutionErrorResult(effectiveParams, error, contextPolicy.contextSummary), forkThinkingDowngrades);
6785
+ const errorResult = toExecutionErrorResult(effectiveParams, error, contextPolicy.contextSummary);
5920
6786
  if (nestedForegroundStarted)
5921
6787
  writeNestedForegroundEvent("subagent.nested.completed", errorResult);
5922
6788
  return attachMission(errorResult);
@@ -5927,7 +6793,7 @@ ${item.text}` } : item)
5927
6793
  activeAsyncCapacity.rollback();
5928
6794
  if (foregroundControl) {
5929
6795
  settleForegroundSchedulingOwner(foregroundControl);
5930
- removeForegroundControlIfIdle(deps.state, runId);
6796
+ removeForegroundControlIfIdle(deps.state, runId, deps.trackRetainedNestedRoute);
5931
6797
  }
5932
6798
  }
5933
6799
  return withResolvedContext({
@@ -5941,7 +6807,7 @@ ${item.text}` } : item)
5941
6807
  const requestParams = normalizedAction ? { ...params, action: normalizedAction } : params;
5942
6808
  if (normalizedAction)
5943
6809
  return execute(id, requestParams, signal, onUpdate, ctx).then(withAggregatedToolUsage);
5944
- const { depth } = checkSubagentDepth(deps.config.maxSubagentDepth);
6810
+ const { depth } = checkSubagentDepth(deps.config.maxSubagentDepth, deps.childRuntime);
5945
6811
  const dispatchParams = applyForceTopLevelAsyncOverride(requestParams, depth, deps.config.forceTopLevelAsync === true);
5946
6812
  const runsForeground = dispatchParams.clarify === true || (dispatchParams.async ?? deps.asyncByDefault) !== true;
5947
6813
  if (!runsForeground)
@@ -5960,10 +6826,25 @@ ${item.text}` } : item)
5960
6826
  if (!normalized.ok) {
5961
6827
  return Promise.resolve({ content: [{ type: "text", text: normalized.error }], isError: true, details: { mode: normalized.mode, results: [] } });
5962
6828
  }
5963
- const loaded = loadWorkflowScriptPath(normalized.params, ctx.cwd);
6829
+ let publicParams = normalized.params;
6830
+ if (publicParams.workflow !== undefined) {
6831
+ const resolved = resolveWorkflowResource(publicParams.workflow, publicParams.args, ctx.sessionManager.getSessionId() ?? undefined);
6832
+ if (!resolved.ok)
6833
+ return Promise.resolve({ content: [{ type: "text", text: resolved.error }], isError: true, details: { mode: "workflow", results: [] } });
6834
+ const { workflow: _workflow, args: _args, ...withoutResourceInput } = publicParams;
6835
+ publicParams = { ...withoutResourceInput, workflowScript: resolved.resource.script };
6836
+ workflowResourcePermits.set(publicParams, resolved.resource.permit);
6837
+ } else if (publicParams.workflowScript !== undefined || publicParams.workflowScriptPath !== undefined) {
6838
+ 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);
5964
6844
  if (loaded.error) {
5965
- return Promise.resolve({ content: [{ type: "text", text: loaded.error }], isError: true, details: { mode: normalized.params.action ? "management" : "workflow", results: [] } });
6845
+ return Promise.resolve({ content: [{ type: "text", text: loaded.error }], isError: true, details: { mode: publicParams.action ? "management" : "workflow", results: [] } });
5966
6846
  }
6847
+ publicExecutions.add(loaded.params);
5967
6848
  return executeWithSingleDispatchGuard(id, loaded.params, signal, onUpdate, ctx);
5968
6849
  };
5969
6850
  const executeDelegated = async (id, params, signal, onUpdate, ctx) => {
@@ -5986,15 +6867,26 @@ ${item.text}` } : item)
5986
6867
  };
5987
6868
  const executeScheduled = (id, params, signal, ctx) => {
5988
6869
  const ownerSessionId = resolveCurrentSessionId(ctx.sessionManager);
5989
- let ownerExecutor = scheduledOwnerExecutors.get(ownerSessionId);
5990
- if (!ownerExecutor) {
5991
- ownerExecutor = createSubagentExecutor({
5992
- ...deps,
5993
- state: createScheduledOwnerState(deps.state, ownerSessionId, ctx)
5994
- });
5995
- scheduledOwnerExecutors.set(ownerSessionId, ownerExecutor);
6870
+ const runtimeOwnerId = ctx.sessionManager.getSessionId() || null;
6871
+ let ownerExecutors = scheduledOwnerExecutors.get(runtimeOwnerId);
6872
+ if (!ownerExecutors) {
6873
+ ownerExecutors = new Map;
6874
+ scheduledOwnerExecutors.set(runtimeOwnerId, ownerExecutors);
6875
+ }
6876
+ let owner = ownerExecutors.get(ownerSessionId);
6877
+ if (!owner) {
6878
+ const state = createScheduledOwnerState(deps.state, ownerSessionId, ctx);
6879
+ owner = { state, executor: createSubagentExecutor({ ...deps, state }) };
6880
+ ownerExecutors.set(ownerSessionId, owner);
5996
6881
  }
5997
- return ownerExecutor.execute(id, params, signal, undefined, ctx);
6882
+ return owner.executor.executePublic(id, params, signal, undefined, ctx);
5998
6883
  };
5999
- return { execute: executeWithSingleDispatchGuard, executePublic, executeDelegated, executeScheduled };
6884
+ function* getCurrentSupervisorOwnerStates() {
6885
+ const ownerId = deps.state.supervisorOwnerSessionId;
6886
+ if (!ownerId)
6887
+ return;
6888
+ for (const owner of scheduledOwnerExecutors.get(ownerId)?.values() ?? [])
6889
+ yield owner.state;
6890
+ }
6891
+ return { execute: executeWithSingleDispatchGuard, executePublic, executeDelegated, executeScheduled, getCurrentSupervisorOwnerStates };
6000
6892
  }