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