@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
|
@@ -22,13 +22,23 @@ import {
|
|
|
22
22
|
import { cascadeSettleWaitMs } from "./cascade-budget.js";
|
|
23
23
|
import { logCascade } from "./cascade-logger.js";
|
|
24
24
|
import { normalizeMapKey } from "./path-utils.js";
|
|
25
|
+
import {
|
|
26
|
+
boundDeferredTargets,
|
|
27
|
+
mergeDeferredTargets,
|
|
28
|
+
TEST_RUNNER_MAX_PERSISTED_TARGETS
|
|
29
|
+
} from "./deferred-test-targets.js";
|
|
25
30
|
import { compareOrdinal } from "./string-utils.js";
|
|
31
|
+
|
|
32
|
+
export { TEST_RUNNER_MAX_PERSISTED_TARGETS };
|
|
26
33
|
import {
|
|
27
34
|
resolveRunnerPath,
|
|
28
35
|
toRunnerDisplayPath
|
|
29
36
|
} from "./dispatch/runner-context.js";
|
|
30
37
|
import { getKnipIgnorePatterns } from "./file-utils.js";
|
|
31
|
-
import {
|
|
38
|
+
import {
|
|
39
|
+
admitsProjectWideFindings,
|
|
40
|
+
formatCacheAgeLabel
|
|
41
|
+
} from "./finding-delivery-gate.js";
|
|
32
42
|
import {
|
|
33
43
|
getFullScanWallClockMs,
|
|
34
44
|
isWorkspaceSweepActive,
|
|
@@ -40,12 +50,23 @@ import { isSecretWarning, secretLocationKey } from "./secret-findings.js";
|
|
|
40
50
|
import { govulncheckLane } from "./turn-end/lanes/govulncheck.js";
|
|
41
51
|
import { secretsLane } from "./turn-end/lanes/secrets.js";
|
|
42
52
|
import {
|
|
53
|
+
planDeliveryHolds,
|
|
54
|
+
stillReportedParked
|
|
55
|
+
} from "./turn-end/delivery-holds.js";
|
|
56
|
+
import { isHardFailureSummary } from "./hard-failure-summary.js";
|
|
57
|
+
import {
|
|
58
|
+
MAX_KNIP_ROOTS_PER_TURN,
|
|
59
|
+
resolveKnipScanRoots
|
|
60
|
+
} from "./knip-scan-roots.js";
|
|
61
|
+
import {
|
|
62
|
+
DEAD_CODE_DELTA_MAX_SHOWN,
|
|
43
63
|
deadCodeIssueKey,
|
|
44
64
|
deadCodeIssues,
|
|
45
65
|
formatDeadCodeDelta,
|
|
46
66
|
stableFindingKey
|
|
47
67
|
} from "./dead-code-client.js";
|
|
48
68
|
import { logDeadCodeScan } from "./dead-code-logger.js";
|
|
69
|
+
import { scopeCell } from "./session-scope.js";
|
|
49
70
|
import {
|
|
50
71
|
PROJECT_DIAGNOSTICS_CACHE_VERSION,
|
|
51
72
|
writeProjectDiagnosticsDeltaReport
|
|
@@ -53,6 +74,7 @@ import {
|
|
|
53
74
|
import { deadCodeIssueToProjectDiagnostic } from "./project-diagnostics/runner-adapters/dead-code.js";
|
|
54
75
|
import { trivyFindingToProjectDiagnostic } from "./project-diagnostics/runner-adapters/trivy.js";
|
|
55
76
|
import { knipIssuesToProjectDiagnostics } from "./project-diagnostics/runner-adapters/knip.js";
|
|
77
|
+
import { hasAmbientPythonEnvironment } from "./python-environment.js";
|
|
56
78
|
import { logLatency } from "./latency-logger.js";
|
|
57
79
|
import {
|
|
58
80
|
getLspBudgetIdleTimeoutMs,
|
|
@@ -68,6 +90,7 @@ import {
|
|
|
68
90
|
isRunnerErrorResult,
|
|
69
91
|
RUNNERS
|
|
70
92
|
} from "./test-runner-client.js";
|
|
93
|
+
import { createTurnEndTestRoots } from "./test-target-roots.js";
|
|
71
94
|
import {
|
|
72
95
|
MAX_ADVISORY_AFFECTED_FILES,
|
|
73
96
|
gateFindingsByPathFreshness,
|
|
@@ -78,17 +101,20 @@ import {
|
|
|
78
101
|
sweepInlineBlockerFreshness
|
|
79
102
|
} from "./blocker-freshness.js";
|
|
80
103
|
import { sweepInlineBlockerPastEof } from "./blocker-past-eof.js";
|
|
81
|
-
import { getLSPService } from "./lsp/
|
|
104
|
+
import { getLSPService } from "./lsp/capabilities.js";
|
|
82
105
|
import {
|
|
83
106
|
drainPendingAuxCapEvictedCount,
|
|
84
107
|
drainPendingAuxiliaryCoverage,
|
|
108
|
+
isAuxBacklogPublished,
|
|
85
109
|
isPendingAuxiliaryPastRearmTtl,
|
|
86
110
|
rearmPendingAuxiliaryCoverage,
|
|
87
111
|
MAX_LATE_AUX_REARMS,
|
|
88
|
-
pendingAuxiliaryCoverageSize
|
|
112
|
+
pendingAuxiliaryCoverageSize,
|
|
113
|
+
canRearmPendingAuxiliary
|
|
89
114
|
} from "./lsp/pending-aux-coverage.js";
|
|
90
115
|
import { convertLspDiagnostics } from "./dispatch/utils/lsp-diagnostics.js";
|
|
91
116
|
import { retagAuxiliaryDiagnostics } from "./dispatch/auxiliary-lsp.js";
|
|
117
|
+
import { findingsResult, hasUsableResult } from "./dispatch/types.js";
|
|
92
118
|
import {
|
|
93
119
|
runPersistentReverify
|
|
94
120
|
} from "./persistent-reverify.js";
|
|
@@ -98,6 +124,10 @@ import {
|
|
|
98
124
|
filterFindingsByDisposition
|
|
99
125
|
} from "./dispatch/finding-policy.js";
|
|
100
126
|
import { detectFileRole } from "./file-role.js";
|
|
127
|
+
import {
|
|
128
|
+
judgeDeferredRunnerFindings,
|
|
129
|
+
recordDeferredRunnerBlockers
|
|
130
|
+
} from "./deferred-runner-blockers.js";
|
|
101
131
|
import {
|
|
102
132
|
applyInlineBlockerPolicy,
|
|
103
133
|
summarizeInlineBlockerPolicy
|
|
@@ -105,7 +135,8 @@ import {
|
|
|
105
135
|
import {
|
|
106
136
|
drainPendingRunnerFindings,
|
|
107
137
|
dropStaleRunnerFindings,
|
|
108
|
-
pendingRunnerFindingsSize
|
|
138
|
+
pendingRunnerFindingsSize,
|
|
139
|
+
requeueRunnerFindings
|
|
109
140
|
} from "./dispatch/pending-runner-findings.js";
|
|
110
141
|
import {
|
|
111
142
|
incrementDegradationCount,
|
|
@@ -134,23 +165,9 @@ import {
|
|
|
134
165
|
const LATE_AUX_COVERAGE_GAP_DETAIL_CAP_PER_TURN = 20;
|
|
135
166
|
export const TEST_RUNNER_BATCH_CONCURRENCY = 4;
|
|
136
167
|
export const TEST_RUNNER_MAX_TARGETS = 12;
|
|
168
|
+
const TURN_END_SELECTION_ROOT_ROWS = 8;
|
|
137
169
|
export const TEST_RUNNER_BATCH_BUDGET_MS = 20000;
|
|
138
170
|
export const TEST_RUNNER_MAX_DEFERRALS = 2;
|
|
139
|
-
export const TEST_RUNNER_MAX_PERSISTED_TARGETS = 64;
|
|
140
|
-
function deferralEntryKey(entry) {
|
|
141
|
-
return `${entry.sessionId ?? ""}\x00${normalizeMapKey(path.resolve(entry.testFile))}`;
|
|
142
|
-
}
|
|
143
|
-
function mergeDeferredTargets(existing, incoming) {
|
|
144
|
-
const byKey = new Map;
|
|
145
|
-
for (const entry of [...existing, ...incoming]) {
|
|
146
|
-
const key = deferralEntryKey(entry);
|
|
147
|
-
const prior = byKey.get(key);
|
|
148
|
-
if (prior && (prior.attempts ?? 0) >= (entry.attempts ?? 0))
|
|
149
|
-
continue;
|
|
150
|
-
byKey.set(key, entry);
|
|
151
|
-
}
|
|
152
|
-
return [...byKey.values()];
|
|
153
|
-
}
|
|
154
171
|
export async function runTestTargetsBounded(args) {
|
|
155
172
|
const results = [];
|
|
156
173
|
if (args.targets.length === 0)
|
|
@@ -224,6 +241,79 @@ export async function runTestTargetsBounded(args) {
|
|
|
224
241
|
function wouldPoisonCache(prev, next) {
|
|
225
242
|
return !next.success && prev?.data.success === true;
|
|
226
243
|
}
|
|
244
|
+
const LATE_DEAD_CODE_SCANS = "dead-code-late-scans";
|
|
245
|
+
function lateDeadCodeScansOf(scope) {
|
|
246
|
+
return scopeCell(scope, LATE_DEAD_CODE_SCANS, () => new Map);
|
|
247
|
+
}
|
|
248
|
+
function joinedEarlierScan(result, askedAt) {
|
|
249
|
+
return result.scannedAt !== undefined && Date.parse(result.scannedAt) < askedAt;
|
|
250
|
+
}
|
|
251
|
+
function withRowForFailureWrite(scan, cacheManager, cacheKey, cwd, startRow) {
|
|
252
|
+
return scan.then((result) => result.success || startRow?.data.success === true ? { result, row: startRow } : cacheManager.readCacheAsync(cacheKey, cwd).then((row) => ({ result, row })));
|
|
253
|
+
}
|
|
254
|
+
function lateDeadCodeScanKey(client, cwd) {
|
|
255
|
+
return `${client.id}\x00${cwd}`;
|
|
256
|
+
}
|
|
257
|
+
function deadCodeScanEvent(client, cwd, result, durationMs) {
|
|
258
|
+
return {
|
|
259
|
+
language: client.language,
|
|
260
|
+
root: cwd,
|
|
261
|
+
success: result.success,
|
|
262
|
+
cached: false,
|
|
263
|
+
unusedExports: result.unusedExports.length,
|
|
264
|
+
unusedFiles: result.unusedFiles.length,
|
|
265
|
+
unusedDeps: result.unusedDeps.length,
|
|
266
|
+
unlistedDeps: result.unlistedDeps.length,
|
|
267
|
+
durationMs: result.durationMs ?? durationMs,
|
|
268
|
+
...result.excludedWorktrees !== undefined && {
|
|
269
|
+
excludedWorktrees: result.excludedWorktrees
|
|
270
|
+
},
|
|
271
|
+
...!result.success && { reason: result.summary }
|
|
272
|
+
};
|
|
273
|
+
}
|
|
274
|
+
function dropLateDeadCodeScan(scans, key, client, reason) {
|
|
275
|
+
scans.delete(key);
|
|
276
|
+
incrementDegradationCount({
|
|
277
|
+
kind: "dead-code-late-scan-dropped",
|
|
278
|
+
subject: client.id,
|
|
279
|
+
reason
|
|
280
|
+
});
|
|
281
|
+
}
|
|
282
|
+
function parkLateDeadCodeScan(args) {
|
|
283
|
+
const { scope, cacheManager, client, cwd, cacheKey, startedAt } = args;
|
|
284
|
+
const scans = lateDeadCodeScansOf(scope);
|
|
285
|
+
const key = lateDeadCodeScanKey(client, cwd);
|
|
286
|
+
const entry = {
|
|
287
|
+
files: args.files,
|
|
288
|
+
previousScan: args.previousScan,
|
|
289
|
+
carry: new Set,
|
|
290
|
+
settled: null,
|
|
291
|
+
askedAt: startedAt
|
|
292
|
+
};
|
|
293
|
+
scans.set(key, entry);
|
|
294
|
+
withRowForFailureWrite(args.scan, cacheManager, cacheKey, cwd, entry.previousScan ? { data: entry.previousScan } : null).then(({ result, row }) => {
|
|
295
|
+
if (!scope.isLive()) {
|
|
296
|
+
dropLateDeadCodeScan(scans, key, client, "session-ended");
|
|
297
|
+
return;
|
|
298
|
+
}
|
|
299
|
+
const durationMs = Date.now() - startedAt;
|
|
300
|
+
const cacheKept = wouldPoisonCache(row, result);
|
|
301
|
+
if (!cacheKept) {
|
|
302
|
+
cacheManager.writeCache(cacheKey, result, cwd, {
|
|
303
|
+
scanDurationMs: durationMs
|
|
304
|
+
});
|
|
305
|
+
}
|
|
306
|
+
logDeadCodeScan({
|
|
307
|
+
...deadCodeScanEvent(client, cwd, result, durationMs),
|
|
308
|
+
...cacheKept && { cacheKept }
|
|
309
|
+
});
|
|
310
|
+
if (!result.success) {
|
|
311
|
+
dropLateDeadCodeScan(scans, key, client, `scan-failed: ${result.summary}`);
|
|
312
|
+
return;
|
|
313
|
+
}
|
|
314
|
+
entry.settled = result;
|
|
315
|
+
}, (err) => dropLateDeadCodeScan(scans, key, client, `scan-threw: ${err}`));
|
|
316
|
+
}
|
|
227
317
|
let lspIdleResetTimeout = null;
|
|
228
318
|
let pendingSweepRearm = null;
|
|
229
319
|
function emitIdleResetReporterWarning(reportErr) {
|
|
@@ -297,22 +387,66 @@ export function cancelLSPIdleReset() {
|
|
|
297
387
|
pendingSweepRearm = null;
|
|
298
388
|
}
|
|
299
389
|
}
|
|
300
|
-
function capTurnEndMessage(content) {
|
|
390
|
+
function capTurnEndMessage(content, held = 0) {
|
|
301
391
|
const maxLines = RUNTIME_CONFIG.turnEnd.maxLines;
|
|
302
392
|
const maxChars = RUNTIME_CONFIG.turnEnd.maxChars;
|
|
303
|
-
|
|
304
|
-
|
|
393
|
+
const marker = held > 0 ? `... (truncated; ${held} held for the next turn)` : "... (truncated)";
|
|
394
|
+
let kept = content;
|
|
395
|
+
let cut = false;
|
|
396
|
+
const lines = kept.split(`
|
|
305
397
|
`);
|
|
306
398
|
if (lines.length > maxLines) {
|
|
307
|
-
|
|
308
|
-
`)
|
|
309
|
-
|
|
399
|
+
kept = lines.slice(0, maxLines).join(`
|
|
400
|
+
`);
|
|
401
|
+
cut = true;
|
|
402
|
+
}
|
|
403
|
+
if (kept.length > maxChars) {
|
|
404
|
+
kept = sliceAtCodePointBoundaries(kept, 0, maxChars);
|
|
405
|
+
cut = true;
|
|
310
406
|
}
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
407
|
+
return cut ? `${kept}
|
|
408
|
+
${marker}` : content;
|
|
409
|
+
}
|
|
410
|
+
function turnEndKeptChars(content) {
|
|
411
|
+
const maxLines = RUNTIME_CONFIG.turnEnd.maxLines;
|
|
412
|
+
const maxChars = RUNTIME_CONFIG.turnEnd.maxChars;
|
|
413
|
+
const lines = content.split(`
|
|
414
|
+
`);
|
|
415
|
+
const kept = lines.length > maxLines ? lines.slice(0, maxLines).join(`
|
|
416
|
+
`).length : content.length;
|
|
417
|
+
return Math.min(kept, sliceAtCodePointBoundaries(content, 0, maxChars).length);
|
|
418
|
+
}
|
|
419
|
+
function sliceAtCodePointBoundaries(value, start, end) {
|
|
420
|
+
if (start > 0 && start < value.length && isLowSurrogate(value.charCodeAt(start)) && isHighSurrogate(value.charCodeAt(start - 1))) {
|
|
421
|
+
start += 1;
|
|
422
|
+
}
|
|
423
|
+
if (end > 0 && end < value.length && isLowSurrogate(value.charCodeAt(end)) && isHighSurrogate(value.charCodeAt(end - 1))) {
|
|
424
|
+
end -= 1;
|
|
425
|
+
}
|
|
426
|
+
return value.slice(start, end);
|
|
427
|
+
}
|
|
428
|
+
function isHighSurrogate(codeUnit) {
|
|
429
|
+
return codeUnit >= 55296 && codeUnit <= 56319;
|
|
430
|
+
}
|
|
431
|
+
function isLowSurrogate(codeUnit) {
|
|
432
|
+
return codeUnit >= 56320 && codeUnit <= 57343;
|
|
433
|
+
}
|
|
434
|
+
const RESOLVED_SHARE_OF_CHARS = 0.4;
|
|
435
|
+
const RESOLVED_MAX_LINES = 5;
|
|
436
|
+
function formatWriteOrdinal(n) {
|
|
437
|
+
const mod100 = n % 100;
|
|
438
|
+
if (mod100 >= 11 && mod100 <= 13)
|
|
439
|
+
return `${n}th`;
|
|
440
|
+
switch (n % 10) {
|
|
441
|
+
case 1:
|
|
442
|
+
return `${n}st`;
|
|
443
|
+
case 2:
|
|
444
|
+
return `${n}nd`;
|
|
445
|
+
case 3:
|
|
446
|
+
return `${n}rd`;
|
|
447
|
+
default:
|
|
448
|
+
return `${n}th`;
|
|
314
449
|
}
|
|
315
|
-
return out;
|
|
316
450
|
}
|
|
317
451
|
export async function handleTurnEnd(deps) {
|
|
318
452
|
const {
|
|
@@ -337,21 +471,25 @@ export async function handleTurnEnd(deps) {
|
|
|
337
471
|
dbg(`turn_end: retaining newer turn state (dispatch=${turnIndexAtDispatch}, current=${runtime.turnIndex})`);
|
|
338
472
|
return;
|
|
339
473
|
}
|
|
340
|
-
cacheManager.clearTurnState(cwd, currentOwner);
|
|
474
|
+
cacheManager.clearTurnState(cwd, currentOwner, isSecondarySession ? sessionId : undefined);
|
|
341
475
|
};
|
|
342
476
|
updateHeartbeat().catch(() => {});
|
|
343
477
|
const cwd = ctxCwd ?? process.cwd();
|
|
344
|
-
|
|
478
|
+
const isSecondarySession = deps.sessionScope?.role === "secondary";
|
|
479
|
+
const sessionRole = isSecondarySession ? "secondary" : "primary";
|
|
480
|
+
const allowProjectWideFindings = admitsProjectWideFindings(sessionRole);
|
|
481
|
+
const turnStateSessionId = isSecondarySession ? sessionId : undefined;
|
|
482
|
+
let turnState = cacheManager.readTurnState(cwd, turnStateSessionId);
|
|
345
483
|
const currentOwner = {
|
|
346
484
|
...owner ?? {
|
|
347
485
|
kind: "pi",
|
|
348
|
-
id: runtime.telemetrySessionId,
|
|
486
|
+
id: sessionId ?? runtime.telemetrySessionId,
|
|
349
487
|
pid: process.pid,
|
|
350
488
|
lastSeen: new Date().toISOString()
|
|
351
489
|
},
|
|
352
490
|
sessionStartedAt: owner?.sessionStartedAt ?? runtime.sessionStartedAt
|
|
353
491
|
};
|
|
354
|
-
const access = cacheManager.getTurnStateAccess(cwd, currentOwner);
|
|
492
|
+
const access = isSecondarySession ? "owned" : cacheManager.getTurnStateAccess(cwd, currentOwner);
|
|
355
493
|
const gateOwnerLabel = turnState.owner ? `${turnState.owner.kind}:${turnState.owner.id}` : turnState.sessionId ? `legacy:${turnState.sessionId}` : "none";
|
|
356
494
|
const sameProcessPiSessionHandoff = access === "foreign-live" && currentOwner.kind === "pi" && turnState.owner?.kind === "pi" && turnState.owner.pid === process.pid && turnState.owner.id !== currentOwner.id;
|
|
357
495
|
if (access === "foreign-live" && !sameProcessPiSessionHandoff) {
|
|
@@ -361,9 +499,10 @@ export async function handleTurnEnd(deps) {
|
|
|
361
499
|
if (access === "available" && (turnState.files || turnState.owner || turnState.sessionId)) {
|
|
362
500
|
dbg("turn_end: evicting stale turn-state owner");
|
|
363
501
|
clearOwnedTurnState();
|
|
364
|
-
turnState = cacheManager.readTurnState(cwd);
|
|
502
|
+
turnState = cacheManager.readTurnState(cwd, turnStateSessionId);
|
|
365
503
|
}
|
|
366
|
-
const
|
|
504
|
+
const ownFiles = Object.keys(turnState.files);
|
|
505
|
+
const files = ownFiles;
|
|
367
506
|
let widgetDemotedFindingsRetired = 0;
|
|
368
507
|
for (const wPath of drainRenderedDependencyDriftFilePaths()) {
|
|
369
508
|
const deliveryCount = incrementWidgetDependencyDriftDelivery(wPath);
|
|
@@ -379,7 +518,7 @@ export async function handleTurnEnd(deps) {
|
|
|
379
518
|
}
|
|
380
519
|
}
|
|
381
520
|
}
|
|
382
|
-
if (files.length === 0 && !runtime.hasCascadeRuns()) {
|
|
521
|
+
if (files.length === 0 && !runtime.hasCascadeRuns() && !isSecondarySession) {
|
|
383
522
|
if (getFlag("lens-guard") && !runtime.gitGuardHasBlockers) {
|
|
384
523
|
const guardRecord = cacheManager.readCache("turn-end-findings", cwd)?.data;
|
|
385
524
|
if (guardRecord?.sessionId === runtime.telemetrySessionId && guardRecord.testFailures !== true) {
|
|
@@ -400,7 +539,7 @@ export async function handleTurnEnd(deps) {
|
|
|
400
539
|
});
|
|
401
540
|
}
|
|
402
541
|
resetFormatService();
|
|
403
|
-
if (pendingRunnerFindingsSize() === 0)
|
|
542
|
+
if (pendingRunnerFindingsSize() === 0 && !runtime.hasResolvedBlockerFiles())
|
|
404
543
|
return;
|
|
405
544
|
}
|
|
406
545
|
if (files.length > 0 && (lspIdleResetTimeout || pendingSweepRearm)) {
|
|
@@ -408,7 +547,7 @@ export async function handleTurnEnd(deps) {
|
|
|
408
547
|
dbg("turn_end: cancelled pending LSP idle reset (active editing)");
|
|
409
548
|
}
|
|
410
549
|
dbg(`turn_end: ${files.length} file(s) modified, cycles: ${turnState.turnCycles}/${turnState.maxCycles}, access: ${access}, owner: ${gateOwnerLabel}`);
|
|
411
|
-
if (cacheManager.isMaxCyclesExceeded(cwd)) {
|
|
550
|
+
if (cacheManager.isMaxCyclesExceeded(cwd, turnStateSessionId)) {
|
|
412
551
|
dbg("turn_end: max cycles exceeded, clearing state and forcing through");
|
|
413
552
|
clearOwnedTurnState();
|
|
414
553
|
runtime.fixedThisTurn.clear();
|
|
@@ -419,8 +558,131 @@ export async function handleTurnEnd(deps) {
|
|
|
419
558
|
const blockerParts = [];
|
|
420
559
|
const staleSecretParts = [];
|
|
421
560
|
const advisoryParts = [];
|
|
561
|
+
const deliveryHolds = [];
|
|
562
|
+
const turnScope = deps.sessionScope ?? runtime.sessionScope;
|
|
563
|
+
const holdScope = runtime.captureSessionGeneration();
|
|
564
|
+
const carryScope = sessionId ?? runtime.telemetrySessionId;
|
|
565
|
+
const carryLane = (...parts) => [carryScope, ...parts].join(":");
|
|
566
|
+
const takeParked = (lane) => holdScope.guardedWrite(`turn-end:${lane}`, () => runtime.takeCutAdvisoryItems(lane)) ?? [];
|
|
567
|
+
const cutAdvisoryHold = (family, lane, part, shown, isReOffer) => {
|
|
568
|
+
const fresh = shown.filter((item) => !isReOffer(item));
|
|
569
|
+
const recordDropped = (reason) => {
|
|
570
|
+
incrementDegradationCount({
|
|
571
|
+
kind: "turn-end-advisory-carry-dropped",
|
|
572
|
+
subject: family,
|
|
573
|
+
reason
|
|
574
|
+
});
|
|
575
|
+
};
|
|
576
|
+
return {
|
|
577
|
+
part,
|
|
578
|
+
canHold: () => fresh.length > 0,
|
|
579
|
+
onHeld: () => {
|
|
580
|
+
for (const evicted of runtime.parkCutAdvisoryItems(lane, fresh)) {
|
|
581
|
+
recordDropped(`${evicted} evicted: more lanes had cut items parked than the carry bound keeps`);
|
|
582
|
+
}
|
|
583
|
+
if (fresh.length < shown.length) {
|
|
584
|
+
recordDropped("the cap cut items this lane had already re-offered once");
|
|
585
|
+
}
|
|
586
|
+
},
|
|
587
|
+
onDropped: () => recordDropped("the cap cut a part that showed only items it had already re-offered once")
|
|
588
|
+
};
|
|
589
|
+
};
|
|
422
590
|
const projectDiagnosticsDelta = [];
|
|
423
591
|
const projectDiagnosticsSources = new Set;
|
|
592
|
+
const runnerFindingsStart = Date.now();
|
|
593
|
+
const runnerDrainSignal = deps.signal;
|
|
594
|
+
const deliverySessionId = sessionId ?? runtime.telemetrySessionId;
|
|
595
|
+
const pendingRunnerFindings = await bounded(drainPendingRunnerFindings(0, runtime.sessionScope.capture(), deliverySessionId), {
|
|
596
|
+
ms: HOOK_WALL_BUDGET_MS.turn_end,
|
|
597
|
+
signal: runnerDrainSignal,
|
|
598
|
+
hook: "turn_end",
|
|
599
|
+
label: "drainPendingRunnerFindings"
|
|
600
|
+
}) ?? [];
|
|
601
|
+
let runnerFindingsDelivered = 0;
|
|
602
|
+
let runnerFindingsStale = 0;
|
|
603
|
+
let runnerFindingsFailed = 0;
|
|
604
|
+
let runnerFindingsDropped = 0;
|
|
605
|
+
let runnerBlockersRecorded = 0;
|
|
606
|
+
let runnerFindingsDispositionSuppressed = 0;
|
|
607
|
+
const runnerFindingsDeliveredIds = [];
|
|
608
|
+
for (const pending of pendingRunnerFindings) {
|
|
609
|
+
const result = pending.result;
|
|
610
|
+
if (!result)
|
|
611
|
+
continue;
|
|
612
|
+
recordRunner(pending.filePath, pending.runnerId, result.status, result.diagnostics.length, Date.now() - pending.markedAtMs, pending.writeIndex);
|
|
613
|
+
if (result.status === "failed" && !hasUsableResult(result)) {
|
|
614
|
+
runnerFindingsFailed += 1;
|
|
615
|
+
const detail = result.failureMessage ? `: ${result.failureMessage}` : "";
|
|
616
|
+
const failedNote = `❌ Deferred runner ${pending.runnerId} failed (${result.failureKind ?? "unknown"})${detail}`;
|
|
617
|
+
deliveryHolds.push({
|
|
618
|
+
part: failedNote,
|
|
619
|
+
onHeld: () => requeueRunnerFindings({
|
|
620
|
+
...pending,
|
|
621
|
+
result: { ...result, diagnostics: [] }
|
|
622
|
+
})
|
|
623
|
+
});
|
|
624
|
+
advisoryParts.push(failedNote);
|
|
625
|
+
}
|
|
626
|
+
const verdict = judgeDeferredRunnerFindings(pending, cwd);
|
|
627
|
+
runnerFindingsStale += verdict.stale;
|
|
628
|
+
if (verdict.stale > 0) {
|
|
629
|
+
dropStaleRunnerFindings(pending);
|
|
630
|
+
runnerFindingsDropped += 1;
|
|
631
|
+
}
|
|
632
|
+
if (verdict.live === 0)
|
|
633
|
+
continue;
|
|
634
|
+
const displayPath = toRunnerDisplayPath(cwd, pending.filePath);
|
|
635
|
+
const runnerKept = verdict.kept;
|
|
636
|
+
runnerFindingsDispositionSuppressed += verdict.suppressed;
|
|
637
|
+
if (runnerKept.length === 0) {
|
|
638
|
+
continue;
|
|
639
|
+
}
|
|
640
|
+
runnerFindingsDelivered += runnerKept.length;
|
|
641
|
+
runnerBlockersRecorded += recordDeferredRunnerBlockers(runtime, pending, runnerKept, verdict.bytes);
|
|
642
|
+
for (const finding of runnerKept) {
|
|
643
|
+
if (runnerFindingsDeliveredIds.length < 50) {
|
|
644
|
+
runnerFindingsDeliveredIds.push(finding.id);
|
|
645
|
+
}
|
|
646
|
+
}
|
|
647
|
+
const advisoryKept = runnerKept.flatMap((finding) => finding.semantic === "blocking" ? [] : [finding]);
|
|
648
|
+
if (advisoryKept.length === 0)
|
|
649
|
+
continue;
|
|
650
|
+
const lines = advisoryKept.map((finding) => ` ${displayPath}:${finding.line ?? 1}:${finding.column ?? 1} [${finding.rule ?? finding.id}] ${finding.message}`);
|
|
651
|
+
const runnerSuppressedNote = verdict.suppressed > 0 ? `; suppressed by disposition: ${verdict.suppressed} finding(s)` : "";
|
|
652
|
+
const lateRunnerPart = `⏱️ Late runner diagnostics (${pending.runnerId} completed after the edit${runnerSuppressedNote}):
|
|
653
|
+
${lines.join(`
|
|
654
|
+
`)}`;
|
|
655
|
+
const {
|
|
656
|
+
failureKind: _kind,
|
|
657
|
+
failureMessage: _message,
|
|
658
|
+
...findingsOnly
|
|
659
|
+
} = result;
|
|
660
|
+
deliveryHolds.push({
|
|
661
|
+
part: lateRunnerPart,
|
|
662
|
+
onHeld: () => requeueRunnerFindings({
|
|
663
|
+
...pending,
|
|
664
|
+
result: findingsResult(advisoryKept, findingsOnly)
|
|
665
|
+
})
|
|
666
|
+
});
|
|
667
|
+
advisoryParts.push(lateRunnerPart);
|
|
668
|
+
}
|
|
669
|
+
logLatency({
|
|
670
|
+
type: "phase",
|
|
671
|
+
toolName: "turn_end",
|
|
672
|
+
filePath: cwd,
|
|
673
|
+
phase: "late_runner_findings",
|
|
674
|
+
durationMs: Date.now() - runnerFindingsStart,
|
|
675
|
+
metadata: {
|
|
676
|
+
pending: pendingRunnerFindings.length,
|
|
677
|
+
delivered: runnerFindingsDelivered,
|
|
678
|
+
stale: runnerFindingsStale,
|
|
679
|
+
failed: runnerFindingsFailed,
|
|
680
|
+
dropped: runnerFindingsDropped,
|
|
681
|
+
blockersRecorded: runnerBlockersRecorded,
|
|
682
|
+
dispositionSuppressed: runnerFindingsDispositionSuppressed,
|
|
683
|
+
deliveredIds: runnerFindingsDeliveredIds
|
|
684
|
+
}
|
|
685
|
+
});
|
|
424
686
|
const blockerPastEofStart = Date.now();
|
|
425
687
|
const blockerPastEof = sweepInlineBlockerPastEof(runtime, cwd);
|
|
426
688
|
logLatency({
|
|
@@ -435,6 +697,32 @@ export async function handleTurnEnd(deps) {
|
|
|
435
697
|
demoted: blockerPastEof.demoted
|
|
436
698
|
}
|
|
437
699
|
});
|
|
700
|
+
let demotedFindingsRetired = 0;
|
|
701
|
+
const retirePastEofOnDelivery = (bPath, deadLines, displayPath) => () => {
|
|
702
|
+
if (!runtime.retireDemotedPastEofBlocker(bPath, deadLines))
|
|
703
|
+
return;
|
|
704
|
+
runtime.updateGitGuardStatus(false, "");
|
|
705
|
+
demotedFindingsRetired += 1;
|
|
706
|
+
incrementDegradationCount({
|
|
707
|
+
kind: "demoted-finding-retired",
|
|
708
|
+
subject: `inline-blocker:${displayPath}`,
|
|
709
|
+
reason: `file shrank past cited line(s) ${deadLines.join(", ")}; retired after one degraded delivery`
|
|
710
|
+
});
|
|
711
|
+
};
|
|
712
|
+
const countDriftDeliveryOnDelivery = (bPath, displayPath) => () => {
|
|
713
|
+
const deliveryCount = runtime.incrementInlineBlockerStaleDelivery(bPath);
|
|
714
|
+
if (deliveryCount < DEPENDENCY_DRIFT_MAX_DELIVERIES)
|
|
715
|
+
return;
|
|
716
|
+
if (!runtime.retireDemotedDependencyDriftBlocker(bPath))
|
|
717
|
+
return;
|
|
718
|
+
runtime.updateGitGuardStatus(false, "");
|
|
719
|
+
demotedFindingsRetired += 1;
|
|
720
|
+
incrementDegradationCount({
|
|
721
|
+
kind: "demoted-finding-retired",
|
|
722
|
+
subject: `inline-blocker:${displayPath}`,
|
|
723
|
+
reason: `capped after ${deliveryCount} deliveries with no re-run; re-run can still confirm`
|
|
724
|
+
});
|
|
725
|
+
};
|
|
438
726
|
const blockerFreshnessStart = Date.now();
|
|
439
727
|
const blockerFreshness = await sweepInlineBlockerFreshness(runtime, cwd, {
|
|
440
728
|
...deps.signal === undefined ? {} : { signal: deps.signal },
|
|
@@ -462,8 +750,6 @@ export async function handleTurnEnd(deps) {
|
|
|
462
750
|
}
|
|
463
751
|
});
|
|
464
752
|
const unresolvedBlockers = runtime.getInlineBlockersSnapshot();
|
|
465
|
-
let demotedFindingsRetired = 0;
|
|
466
|
-
const pendingDependencyDriftDeliveries = [];
|
|
467
753
|
const inlinePolicyEntries = [];
|
|
468
754
|
const policySuppressedPaths = [];
|
|
469
755
|
const inlinePolicyStart = Date.now();
|
|
@@ -475,39 +761,32 @@ export async function handleTurnEnd(deps) {
|
|
|
475
761
|
inlinePolicyEntries.push({ ...tally, stale: true });
|
|
476
762
|
const deadLines = blockerPastEof.deadLinesByPath.get(bPath) ?? [];
|
|
477
763
|
const degraded = degradeDemotedFindingBody(summary, { deadLines });
|
|
478
|
-
const
|
|
764
|
+
const retires = runtime.wouldRetireDemotedPastEofBlocker(bPath, deadLines);
|
|
479
765
|
let retirementNote;
|
|
480
|
-
if (
|
|
481
|
-
demotedFindingsRetired += 1;
|
|
482
|
-
incrementDegradationCount({
|
|
483
|
-
kind: "demoted-finding-retired",
|
|
484
|
-
subject: `inline-blocker:${displayPath}`,
|
|
485
|
-
reason: `file shrank past cited line(s) ${deadLines.join(", ")}; retired after one degraded delivery`
|
|
486
|
-
});
|
|
766
|
+
if (retires) {
|
|
487
767
|
retirementNote = formatRetirementNote(deadLines);
|
|
488
768
|
} else if (staleReason === "dependency-drift") {
|
|
489
769
|
const tentativeCount = runtime.peekInlineBlockerStaleDeliveryCount(bPath) + 1;
|
|
490
770
|
if (tentativeCount >= DEPENDENCY_DRIFT_MAX_DELIVERIES) {
|
|
491
771
|
retirementNote = formatDeliveryCapNote(tentativeCount);
|
|
492
772
|
}
|
|
493
|
-
pendingDependencyDriftDeliveries.push(() => {
|
|
494
|
-
const deliveryCount = runtime.incrementInlineBlockerStaleDelivery(bPath);
|
|
495
|
-
if (deliveryCount >= DEPENDENCY_DRIFT_MAX_DELIVERIES) {
|
|
496
|
-
const capRetired = runtime.retireDemotedDependencyDriftBlocker(bPath);
|
|
497
|
-
if (capRetired) {
|
|
498
|
-
demotedFindingsRetired += 1;
|
|
499
|
-
incrementDegradationCount({
|
|
500
|
-
kind: "demoted-finding-retired",
|
|
501
|
-
subject: `inline-blocker:${displayPath}`,
|
|
502
|
-
reason: `capped after ${deliveryCount} deliveries with no re-run; re-run can still confirm`
|
|
503
|
-
});
|
|
504
|
-
}
|
|
505
|
-
}
|
|
506
|
-
});
|
|
507
773
|
}
|
|
508
|
-
|
|
774
|
+
const advisoryPart = `${STALE_LINE_MARKER} ${displayPath}:
|
|
509
775
|
${degraded.body}` + (retirementNote ? `
|
|
510
|
-
${retirementNote}` : "")
|
|
776
|
+
${retirementNote}` : "");
|
|
777
|
+
advisoryParts.push(advisoryPart);
|
|
778
|
+
if (retires) {
|
|
779
|
+
deliveryHolds.push({
|
|
780
|
+
part: advisoryPart,
|
|
781
|
+
onDelivered: retirePastEofOnDelivery(bPath, deadLines, displayPath)
|
|
782
|
+
});
|
|
783
|
+
} else if (staleReason === "dependency-drift") {
|
|
784
|
+
deliveryHolds.push({
|
|
785
|
+
part: advisoryPart,
|
|
786
|
+
onDelivered: countDriftDeliveryOnDelivery(bPath, displayPath),
|
|
787
|
+
skipOnSuppressed: true
|
|
788
|
+
});
|
|
789
|
+
}
|
|
511
790
|
} else {
|
|
512
791
|
const policy = applyInlineBlockerPolicy(record, cwd);
|
|
513
792
|
inlinePolicyEntries.push({ ...tally, stale: false, outcome: policy });
|
|
@@ -540,7 +819,16 @@ ${policy.body}`);
|
|
|
540
819
|
});
|
|
541
820
|
}
|
|
542
821
|
const cascadeSettleStart = Date.now();
|
|
543
|
-
const
|
|
822
|
+
const cascadeSettleSignal = deps.signal;
|
|
823
|
+
const { settled, timedOut } = await bounded(runtime.settleCascadeRuns(cascadeSettleWaitMs(), {
|
|
824
|
+
trackTurnEndClock: true,
|
|
825
|
+
generation: holdScope
|
|
826
|
+
}), {
|
|
827
|
+
ms: HOOK_WALL_BUDGET_MS.turn_end,
|
|
828
|
+
signal: cascadeSettleSignal,
|
|
829
|
+
hook: "turn_end",
|
|
830
|
+
label: "settleCascadeRuns"
|
|
831
|
+
}) ?? { settled: 0, timedOut: 0 };
|
|
544
832
|
logLatency({
|
|
545
833
|
type: "phase",
|
|
546
834
|
toolName: "turn_end",
|
|
@@ -550,7 +838,7 @@ ${policy.body}`);
|
|
|
550
838
|
metadata: { settled, timedOut }
|
|
551
839
|
});
|
|
552
840
|
const t0 = Date.now();
|
|
553
|
-
const cascadeRuns = runtime.consumeCascadeRuns().filter((run) => {
|
|
841
|
+
const cascadeRuns = (holdScope.guardedWrite("turn-end:cascade-runs", () => runtime.consumeCascadeRuns()) ?? []).filter((run) => {
|
|
554
842
|
const originSeq = run.origin?.projectSeq;
|
|
555
843
|
const originTurn = run.origin?.turnSeq;
|
|
556
844
|
if (originSeq !== undefined) {
|
|
@@ -589,7 +877,10 @@ ${policy.body}`);
|
|
|
589
877
|
let carriedRunsRendered = 0;
|
|
590
878
|
let labeledAdvisories = 0;
|
|
591
879
|
const carriedMetaByResult = new Map;
|
|
880
|
+
const runByResult = new Map;
|
|
592
881
|
for (const r of cascadeRuns) {
|
|
882
|
+
if (r.result)
|
|
883
|
+
runByResult.set(r.result, r);
|
|
593
884
|
if (r.result && (r.carriedTurns ?? 0) > 0 && r.carriedTurns !== undefined) {
|
|
594
885
|
carriedMetaByResult.set(r.result, {
|
|
595
886
|
carriedTurns: r.carriedTurns,
|
|
@@ -613,6 +904,7 @@ ${policy.body}`);
|
|
|
613
904
|
}
|
|
614
905
|
}
|
|
615
906
|
const parts = [];
|
|
907
|
+
const sectionRuns = [];
|
|
616
908
|
let injectedNeighborCount = 0;
|
|
617
909
|
let injectedDiagnosticCount = 0;
|
|
618
910
|
let suppressedByOwnership = 0;
|
|
@@ -626,6 +918,9 @@ ${policy.body}`);
|
|
|
626
918
|
${carrySuffix}` : result.formatted);
|
|
627
919
|
if (carrySuffix)
|
|
628
920
|
carriedRunsRendered += 1;
|
|
921
|
+
const sectionRun = runByResult.get(result);
|
|
922
|
+
if (sectionRun)
|
|
923
|
+
sectionRuns.push(sectionRun);
|
|
629
924
|
injectedNeighborCount += result.neighbors.length;
|
|
630
925
|
injectedDiagnosticCount += result.neighbors.reduce((s, n) => s + n.diagnostics.length, 0);
|
|
631
926
|
} else if (!ownsAny && result.formatted) {
|
|
@@ -667,6 +962,13 @@ ${testLines.join(`
|
|
|
667
962
|
|
|
668
963
|
`);
|
|
669
964
|
blockerParts.push(section);
|
|
965
|
+
deliveryHolds.push({
|
|
966
|
+
part: section,
|
|
967
|
+
onHeld: () => {
|
|
968
|
+
for (const run of sectionRuns)
|
|
969
|
+
runtime.appendCascadeRun(run);
|
|
970
|
+
}
|
|
971
|
+
});
|
|
670
972
|
logCascade({
|
|
671
973
|
phase: "cascade_injected",
|
|
672
974
|
filePath: cascadeLogFilePath,
|
|
@@ -734,18 +1036,31 @@ ${lines.join(`
|
|
|
734
1036
|
return `${advisory}
|
|
735
1037
|
${suffix}`;
|
|
736
1038
|
};
|
|
1039
|
+
const holdAdvisory = (advisory, runs) => {
|
|
1040
|
+
if (advisory === undefined)
|
|
1041
|
+
return;
|
|
1042
|
+
deliveryHolds.push({
|
|
1043
|
+
part: advisory,
|
|
1044
|
+
onHeld: () => {
|
|
1045
|
+
for (const run of runs)
|
|
1046
|
+
runtime.appendCascadeRun({ ...run, result: undefined });
|
|
1047
|
+
}
|
|
1048
|
+
});
|
|
1049
|
+
};
|
|
737
1050
|
const graphAdvisory = withCarryLabel(buildAdvisory(graphRuns, {
|
|
738
1051
|
lead: (fileCount, reasons) => `Cascade could not compute downstream impact for ${fileCount} edited file(s) this turn — ` + `the review graph was unavailable (${reasons}), so their dependents were not ` + `cascade-checked and a clean cascade result does not cover them.`,
|
|
739
1052
|
fallbackDetail: (r) => r.indeterminate?.reason === "missing_node" ? "changed file not in the review graph" : "review graph unavailable"
|
|
740
1053
|
}), graphRuns);
|
|
741
1054
|
if (graphAdvisory)
|
|
742
1055
|
advisoryParts.push(graphAdvisory);
|
|
1056
|
+
holdAdvisory(graphAdvisory, graphRuns);
|
|
743
1057
|
const bindingAdvisory = withCarryLabel(buildAdvisory(bindingRuns, {
|
|
744
1058
|
lead: (fileCount, reasons) => `Cascade identified dependents for ${fileCount} edited file(s) this turn, but their ` + `diagnostics could not be freshly confirmed (${reasons}) and were withheld — a clean ` + `cascade result does not cover them.`,
|
|
745
1059
|
fallbackDetail: () => "cascade diagnostics withheld (binding rejected)"
|
|
746
1060
|
}), bindingRuns);
|
|
747
1061
|
if (bindingAdvisory)
|
|
748
1062
|
advisoryParts.push(bindingAdvisory);
|
|
1063
|
+
holdAdvisory(bindingAdvisory, bindingRuns);
|
|
749
1064
|
const budgetAdvisory = withCarryLabel(buildAdvisory(budgetRuns, {
|
|
750
1065
|
lead: (fileCount, reasons) => `Cascade checked the selected neighbors for ${fileCount} edited file(s) this turn, ` + `but some eligible dependents were not checked because the cascade budget ` + `was exhausted (${reasons}); a clean cascade result does not cover them.`,
|
|
751
1066
|
fallbackDetail: (r) => {
|
|
@@ -758,6 +1073,7 @@ ${suffix}`;
|
|
|
758
1073
|
}), budgetRuns);
|
|
759
1074
|
if (budgetAdvisory)
|
|
760
1075
|
advisoryParts.push(budgetAdvisory);
|
|
1076
|
+
holdAdvisory(budgetAdvisory, budgetRuns);
|
|
761
1077
|
const fileCount = new Set(indeterminateRuns.map((r) => normalizeMapKey(r.filePath))).size;
|
|
762
1078
|
const byFile = indeterminateRuns.map((r) => ({
|
|
763
1079
|
file: toRunnerDisplayPath(cwd, r.filePath),
|
|
@@ -812,106 +1128,182 @@ ${suffix}`;
|
|
|
812
1128
|
skipped: cascadeSkipped
|
|
813
1129
|
}
|
|
814
1130
|
});
|
|
815
|
-
const
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
1131
|
+
const knipScan = resolveKnipScanRoots(cwd, files);
|
|
1132
|
+
for (const root of knipScan.overCap) {
|
|
1133
|
+
incrementDegradationCount({
|
|
1134
|
+
kind: "turn-end-knip-root-skipped",
|
|
1135
|
+
subject: "root-cap",
|
|
1136
|
+
reason: `${toRunnerDisplayPath(cwd, root)} not scanned: more than ${MAX_KNIP_ROOTS_PER_TURN} checkouts edited this turn`
|
|
1137
|
+
});
|
|
1138
|
+
}
|
|
1139
|
+
const KNOWN_SLOW_KNIP_GRACE_MS = 1;
|
|
1140
|
+
const KNIP_MAX_SHOWN = 5;
|
|
1141
|
+
const applyKnipResult = (scanRoot, prevKnip, knipResult, rowNow) => {
|
|
1142
|
+
const knipWouldPoison = wouldPoisonCache(rowNow, knipResult);
|
|
1143
|
+
if (knipWouldPoison) {
|
|
1144
|
+
dbg(`turn_end: keeping last good knip cache; this run failed: ${knipResult.summary}`);
|
|
826
1145
|
} else {
|
|
827
|
-
|
|
828
|
-
|
|
1146
|
+
cacheManager.writeCache("knip", knipResult, scanRoot);
|
|
1147
|
+
}
|
|
1148
|
+
const knipMeta = {
|
|
1149
|
+
execution: knipResult.execution ?? "executed",
|
|
1150
|
+
success: knipResult.success,
|
|
1151
|
+
totalIssues: knipResult.issues.length,
|
|
1152
|
+
newIssues: 0,
|
|
1153
|
+
blockerIssues: 0,
|
|
1154
|
+
dispositionSuppressed: 0,
|
|
1155
|
+
...!knipResult.success && { reason: knipResult.summary },
|
|
1156
|
+
...knipResult.failureKind && { failureKind: knipResult.failureKind },
|
|
1157
|
+
...knipResult.nestedWorktrees !== undefined && {
|
|
1158
|
+
nestedWorktrees: knipResult.nestedWorktrees,
|
|
1159
|
+
nestedFilesDropped: knipResult.nestedFilesDropped
|
|
1160
|
+
},
|
|
1161
|
+
...knipWouldPoison && { cacheKept: true }
|
|
1162
|
+
};
|
|
1163
|
+
const knipBlockerLane = carryLane("knip", scanRoot, "blocker");
|
|
1164
|
+
const knipAdvisoryLane = carryLane("knip", scanRoot, "advisory");
|
|
1165
|
+
const parkedKnip = knipResult.success ? [
|
|
1166
|
+
...takeParked(knipBlockerLane),
|
|
1167
|
+
...takeParked(knipAdvisoryLane)
|
|
1168
|
+
] : [];
|
|
1169
|
+
if (knipResult.success && knipResult.issues.length > 0) {
|
|
1170
|
+
const issueKey = (i) => stableFindingKey(i.type, i.file, i.name, i.package);
|
|
1171
|
+
const prevKeys = new Set((prevKnip?.data?.issues ?? []).map(issueKey));
|
|
1172
|
+
const modifiedSet = new Set(files.map((f) => resolveRunnerPath(cwd, f)));
|
|
1173
|
+
const newIssues = knipResult.issues.filter((issue) => {
|
|
1174
|
+
if (prevKeys.has(issueKey(issue)))
|
|
1175
|
+
return false;
|
|
1176
|
+
if (!issue.file)
|
|
1177
|
+
return false;
|
|
1178
|
+
const abs = resolveRunnerPath(scanRoot, issue.file);
|
|
1179
|
+
return modifiedSet.has(abs);
|
|
829
1180
|
});
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
1181
|
+
knipMeta.newIssues = newIssues.length;
|
|
1182
|
+
const reOffered = stillReportedParked(parkedKnip, knipResult.issues, issueKey, new Set(newIssues.map(issueKey)));
|
|
1183
|
+
const reOfferedKeys = new Set(reOffered.map(issueKey));
|
|
1184
|
+
if (reOffered.length > 0)
|
|
1185
|
+
knipMeta.reOffered = reOffered.length;
|
|
1186
|
+
if (newIssues.length > 0) {
|
|
1187
|
+
projectDiagnosticsDelta.push(...knipIssuesToProjectDiagnostics(scanRoot, newIssues));
|
|
1188
|
+
projectDiagnosticsSources.add("knip");
|
|
835
1189
|
}
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
...knipResult.failureKind && { failureKind: knipResult.failureKind },
|
|
845
|
-
...knipWouldPoison && { cacheKept: true }
|
|
1190
|
+
const knipPaired = [...newIssues, ...reOffered].flatMap((issue) => knipIssuesToProjectDiagnostics(scanRoot, [issue]).map((diagnostic) => ({
|
|
1191
|
+
issue,
|
|
1192
|
+
diagnostic
|
|
1193
|
+
})));
|
|
1194
|
+
const knipFiltered = filterFindingsByDisposition(knipPaired, cwd, (pair) => pair.diagnostic);
|
|
1195
|
+
const knipDeliverable = {
|
|
1196
|
+
kept: knipFiltered.kept.map((pair) => pair.issue),
|
|
1197
|
+
suppressed: knipFiltered.suppressed
|
|
846
1198
|
};
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
return false;
|
|
854
|
-
if (!issue.file)
|
|
855
|
-
return false;
|
|
856
|
-
const abs = resolveRunnerPath(cwd, issue.file);
|
|
857
|
-
return modifiedSet.has(abs);
|
|
858
|
-
});
|
|
859
|
-
knipMeta.newIssues = newIssues.length;
|
|
860
|
-
if (newIssues.length > 0) {
|
|
861
|
-
projectDiagnosticsDelta.push(...knipIssuesToProjectDiagnostics(cwd, newIssues));
|
|
862
|
-
projectDiagnosticsSources.add("knip");
|
|
863
|
-
}
|
|
864
|
-
const knipPaired = newIssues.flatMap((issue) => knipIssuesToProjectDiagnostics(cwd, [issue]).map((diagnostic) => ({
|
|
865
|
-
issue,
|
|
866
|
-
diagnostic
|
|
867
|
-
})));
|
|
868
|
-
const knipFiltered = filterFindingsByDisposition(knipPaired, cwd, (pair) => pair.diagnostic);
|
|
869
|
-
const knipDeliverable = {
|
|
870
|
-
kept: knipFiltered.kept.map((pair) => pair.issue),
|
|
871
|
-
suppressed: knipFiltered.suppressed
|
|
872
|
-
};
|
|
873
|
-
knipMeta.dispositionSuppressed = knipDeliverable.suppressed;
|
|
874
|
-
const blockerIssues = knipDeliverable.kept.filter((i) => i.type === "unlisted" || i.type === "bin");
|
|
875
|
-
knipMeta.blockerIssues = blockerIssues.length;
|
|
876
|
-
if (blockerIssues.length > 0) {
|
|
877
|
-
let report = `\uD83D\uDD34 New unresolved imports/deps in modified code (Knip):
|
|
1199
|
+
knipMeta.dispositionSuppressed = knipDeliverable.suppressed;
|
|
1200
|
+
const displayPath = (issue) => issue.file ? toRunnerDisplayPath(cwd, resolveRunnerPath(scanRoot, issue.file)) : "(unknown)";
|
|
1201
|
+
const blockerIssues = knipDeliverable.kept.filter((i) => i.type === "unlisted" || i.type === "bin");
|
|
1202
|
+
knipMeta.blockerIssues = blockerIssues.length;
|
|
1203
|
+
if (blockerIssues.length > 0) {
|
|
1204
|
+
let report = `\uD83D\uDD34 New unresolved imports/deps in modified code (Knip):
|
|
878
1205
|
`;
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
1206
|
+
let firstPath = null;
|
|
1207
|
+
for (const issue of blockerIssues.slice(0, KNIP_MAX_SHOWN)) {
|
|
1208
|
+
const display = displayPath(issue);
|
|
1209
|
+
if (!firstPath && display !== "(unknown)")
|
|
1210
|
+
firstPath = display;
|
|
1211
|
+
report += ` ${display}${issue.line ? `:${issue.line}` : ""} — ${issue.type}: ${issue.name}
|
|
885
1212
|
`;
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
1213
|
+
}
|
|
1214
|
+
if (firstPath) {
|
|
1215
|
+
report += ` First location: ${firstPath}
|
|
889
1216
|
`;
|
|
890
|
-
}
|
|
891
|
-
blockerParts.push(report);
|
|
892
1217
|
}
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
1218
|
+
blockerParts.push(report);
|
|
1219
|
+
deliveryHolds.push(cutAdvisoryHold("knip", knipBlockerLane, report, blockerIssues.slice(0, KNIP_MAX_SHOWN), (issue) => reOfferedKeys.has(issueKey(issue))));
|
|
1220
|
+
}
|
|
1221
|
+
const unusedExportDelta = knipDeliverable.kept.filter((i) => i.type === "export" || i.type === "enumMember");
|
|
1222
|
+
if (unusedExportDelta.length > 0) {
|
|
1223
|
+
let report = `⚠️ Newly unused exports in files you edited — check if callers need updating (Knip):
|
|
896
1224
|
`;
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
1225
|
+
for (const issue of unusedExportDelta.slice(0, KNIP_MAX_SHOWN)) {
|
|
1226
|
+
const display = displayPath(issue);
|
|
1227
|
+
report += ` ${display}${issue.line ? `:${issue.line}` : ""} — ${issue.name}
|
|
900
1228
|
`;
|
|
901
|
-
}
|
|
902
|
-
advisoryParts.push(report);
|
|
903
1229
|
}
|
|
1230
|
+
advisoryParts.push(report);
|
|
1231
|
+
deliveryHolds.push(cutAdvisoryHold("knip", knipAdvisoryLane, report, unusedExportDelta.slice(0, KNIP_MAX_SHOWN), (issue) => reOfferedKeys.has(issueKey(issue))));
|
|
904
1232
|
}
|
|
905
1233
|
}
|
|
906
|
-
|
|
907
|
-
|
|
1234
|
+
return knipMeta;
|
|
1235
|
+
};
|
|
1236
|
+
const logKnipRow = (root, startedAt, metadata) => logLatency({
|
|
908
1237
|
type: "phase",
|
|
909
1238
|
toolName: "turn_end",
|
|
910
|
-
filePath:
|
|
1239
|
+
filePath: root,
|
|
911
1240
|
phase: "knip",
|
|
912
|
-
durationMs: Date.now() -
|
|
913
|
-
metadata
|
|
1241
|
+
durationMs: Date.now() - startedAt,
|
|
1242
|
+
metadata
|
|
914
1243
|
});
|
|
1244
|
+
if (runtime.isStartupScanInFlight("knip")) {
|
|
1245
|
+
dbg("turn_end: skipping knip (startup scan still in flight)");
|
|
1246
|
+
logKnipRow(cwd, Date.now(), { skipped: true });
|
|
1247
|
+
} else {
|
|
1248
|
+
let budgetSpent = false;
|
|
1249
|
+
for (const scanRoot of knipScan.roots) {
|
|
1250
|
+
if (budgetSpent) {
|
|
1251
|
+
incrementDegradationCount({
|
|
1252
|
+
kind: "turn-end-knip-root-skipped",
|
|
1253
|
+
subject: "budget",
|
|
1254
|
+
reason: `${toRunnerDisplayPath(cwd, scanRoot)} not scanned: an earlier knip scan spent the turn_end budget`
|
|
1255
|
+
});
|
|
1256
|
+
continue;
|
|
1257
|
+
}
|
|
1258
|
+
const startedAt = Date.now();
|
|
1259
|
+
const prevKnip = cacheManager.readCache("knip", scanRoot);
|
|
1260
|
+
const previousFailedHard = prevKnip && !prevKnip.data.success && !prevKnip.data.failureKind && isHardFailureSummary(prevKnip.data.summary);
|
|
1261
|
+
const abandonedFailure = previousFailedHard ? null : knipClient.recentHardFailure?.(scanRoot) ?? null;
|
|
1262
|
+
let metadata;
|
|
1263
|
+
if (previousFailedHard || abandonedFailure !== null) {
|
|
1264
|
+
const reason = previousFailedHard ? prevKnip.data.summary : abandonedFailure ?? "";
|
|
1265
|
+
dbg(`turn_end: skipping knip after recent failure: ${reason}`);
|
|
1266
|
+
metadata = { skipped: true, reason };
|
|
1267
|
+
} else {
|
|
1268
|
+
const remainingMs = Math.max(0, HOOK_WALL_BUDGET_MS.turn_end - (Date.now() - turnEndStart));
|
|
1269
|
+
const scanFloorMs = knipClient.scanFloorMs?.(scanRoot);
|
|
1270
|
+
const knownSlow = scanFloorMs !== undefined && scanFloorMs > remainingMs;
|
|
1271
|
+
const scanned = await bounded(withRowForFailureWrite(knipClient.analyze(scanRoot, getKnipIgnorePatterns(), {
|
|
1272
|
+
projectSeq: runtime.projectSeq
|
|
1273
|
+
}), cacheManager, "knip", scanRoot, prevKnip), {
|
|
1274
|
+
ms: knownSlow ? KNOWN_SLOW_KNIP_GRACE_MS : remainingMs,
|
|
1275
|
+
signal: deps.signal,
|
|
1276
|
+
hook: "turn_end",
|
|
1277
|
+
label: "knip"
|
|
1278
|
+
});
|
|
1279
|
+
if (scanned === undefined) {
|
|
1280
|
+
dbg(`turn_end: knip for ${scanRoot} outlived the turn_end budget`);
|
|
1281
|
+
const aborted = deps.signal?.aborted === true;
|
|
1282
|
+
const nestedWorktrees = knipClient.nestedWorktrees?.(scanRoot) ?? 0;
|
|
1283
|
+
metadata = {
|
|
1284
|
+
execution: "deferred",
|
|
1285
|
+
aborted,
|
|
1286
|
+
...knownSlow && {
|
|
1287
|
+
reason: "scan-exceeds-budget",
|
|
1288
|
+
scanFloorMs
|
|
1289
|
+
},
|
|
1290
|
+
...nestedWorktrees > 0 && { nestedWorktrees }
|
|
1291
|
+
};
|
|
1292
|
+
if (nestedWorktrees > 0 && !aborted) {
|
|
1293
|
+
incrementDegradationCount({
|
|
1294
|
+
kind: "turn-end-knip-nested-worktrees",
|
|
1295
|
+
subject: toRunnerDisplayPath(cwd, scanRoot),
|
|
1296
|
+
reason: `${nestedWorktrees} linked worktree(s) nested under the scan root: knip walks them as project files and the scan did not fit the turn_end budget; add their directory (for example /.worktrees/) to .gitignore to drop the cost`
|
|
1297
|
+
});
|
|
1298
|
+
}
|
|
1299
|
+
} else {
|
|
1300
|
+
metadata = applyKnipResult(scanRoot, prevKnip, scanned.result, scanned.row);
|
|
1301
|
+
}
|
|
1302
|
+
}
|
|
1303
|
+
budgetSpent = metadata.execution === "deferred" && (metadata.scanFloorMs === undefined || metadata.aborted === true);
|
|
1304
|
+
logKnipRow(scanRoot, startedAt, metadata);
|
|
1305
|
+
}
|
|
1306
|
+
}
|
|
915
1307
|
const tDeadCode = Date.now();
|
|
916
1308
|
const deadCodeMeta = {};
|
|
917
1309
|
if (runtime.isStartupScanInFlight("dead-code")) {
|
|
@@ -926,29 +1318,136 @@ ${suffix}`;
|
|
|
926
1318
|
let newIssueTotal = 0;
|
|
927
1319
|
let deadCodeDispositionSuppressed = 0;
|
|
928
1320
|
const reasons = [];
|
|
1321
|
+
const deliverDeadCodeDelta = (client, sources) => {
|
|
1322
|
+
const latest = sources.at(-1);
|
|
1323
|
+
if (latest === undefined)
|
|
1324
|
+
return;
|
|
1325
|
+
const result = latest.result;
|
|
1326
|
+
const deadCodeLane = carryLane("dead-code", client.id);
|
|
1327
|
+
const parkedDeadCode = takeParked(deadCodeLane);
|
|
1328
|
+
deadCodeMeta.totalIssues = (deadCodeMeta.totalIssues ?? 0) + deadCodeIssues(result).length;
|
|
1329
|
+
if (!sources.some((source) => source.previousScan?.success)) {
|
|
1330
|
+
reasons.push(`${client.id}:no_previous_scan`);
|
|
1331
|
+
return;
|
|
1332
|
+
}
|
|
1333
|
+
const newIssues = [];
|
|
1334
|
+
for (const source of sources) {
|
|
1335
|
+
if (!source.previousScan?.success)
|
|
1336
|
+
continue;
|
|
1337
|
+
const prevKeys = new Set(deadCodeIssues(source.previousScan).map(deadCodeIssueKey));
|
|
1338
|
+
for (const issue of deadCodeIssues(source.result)) {
|
|
1339
|
+
if (prevKeys.has(deadCodeIssueKey(issue)) || !issue.file)
|
|
1340
|
+
continue;
|
|
1341
|
+
if (source.modified.has(resolveRunnerPath(cwd, issue.file))) {
|
|
1342
|
+
newIssues.push(issue);
|
|
1343
|
+
}
|
|
1344
|
+
}
|
|
1345
|
+
}
|
|
1346
|
+
const reOffered = stillReportedParked(parkedDeadCode, deadCodeIssues(result), deadCodeIssueKey, new Set(newIssues.map(deadCodeIssueKey)));
|
|
1347
|
+
if (newIssues.length === 0 && reOffered.length === 0) {
|
|
1348
|
+
reasons.push(`${client.id}:clean`);
|
|
1349
|
+
return;
|
|
1350
|
+
}
|
|
1351
|
+
newIssueTotal += newIssues.length;
|
|
1352
|
+
if (newIssues.length > 0) {
|
|
1353
|
+
projectDiagnosticsDelta.push(...newIssues.map((issue) => deadCodeIssueToProjectDiagnostic(cwd, issue, result.language)));
|
|
1354
|
+
projectDiagnosticsSources.add("dead-code");
|
|
1355
|
+
}
|
|
1356
|
+
const deadCodeDeliverable = filterFindingsByDisposition([...newIssues, ...reOffered], cwd, (issue) => deadCodeIssueToProjectDiagnostic(cwd, issue, result.language));
|
|
1357
|
+
deadCodeDispositionSuppressed += deadCodeDeliverable.suppressed;
|
|
1358
|
+
if (deadCodeDeliverable.kept.length === 0) {
|
|
1359
|
+
reasons.push(`${client.id}:all_disposed`);
|
|
1360
|
+
return;
|
|
1361
|
+
}
|
|
1362
|
+
const deadCodePart = formatDeadCodeDelta(deadCodeDeliverable.kept, result.language);
|
|
1363
|
+
advisoryParts.push(deadCodePart);
|
|
1364
|
+
const reOfferedKeys = new Set(reOffered.map(deadCodeIssueKey));
|
|
1365
|
+
deliveryHolds.push(cutAdvisoryHold("dead-code", deadCodeLane, deadCodePart, deadCodeDeliverable.kept.slice(0, DEAD_CODE_DELTA_MAX_SHOWN), (issue) => reOfferedKeys.has(deadCodeIssueKey(issue))));
|
|
1366
|
+
};
|
|
929
1367
|
try {
|
|
1368
|
+
const lateScans = lateDeadCodeScansOf(turnScope);
|
|
930
1369
|
for (const client of deadCodeClients) {
|
|
931
1370
|
if (!client.detect(cwd)) {
|
|
932
1371
|
reasons.push(`${client.id}:not_detected`);
|
|
933
1372
|
continue;
|
|
934
1373
|
}
|
|
935
|
-
if (![...modifiedFiles()].some((f) => client.owns(f))) {
|
|
936
|
-
reasons.push(`${client.id}:no_owned_files`);
|
|
937
|
-
continue;
|
|
938
|
-
}
|
|
939
1374
|
const cacheKey = `dead-code-${client.id}`;
|
|
940
|
-
const
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
1375
|
+
const lateKey = lateDeadCodeScanKey(client, cwd);
|
|
1376
|
+
const sources = [];
|
|
1377
|
+
const late = lateScans.get(lateKey);
|
|
1378
|
+
let carried = new Set;
|
|
1379
|
+
if (late?.settled) {
|
|
1380
|
+
lateScans.delete(lateKey);
|
|
1381
|
+
sources.push({
|
|
1382
|
+
result: late.settled,
|
|
1383
|
+
previousScan: late.previousScan,
|
|
1384
|
+
modified: late.files
|
|
1385
|
+
});
|
|
1386
|
+
carried = late.carry;
|
|
1387
|
+
reasons.push(`${client.id}:late_scan`);
|
|
1388
|
+
if (joinedEarlierScan(late.settled, late.askedAt)) {
|
|
1389
|
+
carried = new Set([...late.carry, ...late.files]);
|
|
1390
|
+
reasons.push(`${client.id}:joined`);
|
|
1391
|
+
}
|
|
946
1392
|
}
|
|
947
|
-
const startMs = Date.now();
|
|
948
1393
|
try {
|
|
949
|
-
|
|
1394
|
+
if (late && !late.settled) {
|
|
1395
|
+
for (const file of modifiedFiles())
|
|
1396
|
+
late.carry.add(file);
|
|
1397
|
+
reasons.push(`${client.id}:in_flight`);
|
|
1398
|
+
continue;
|
|
1399
|
+
}
|
|
1400
|
+
const scanFiles = new Set([...modifiedFiles(), ...carried]);
|
|
1401
|
+
if (![...scanFiles].some((f) => client.owns(f))) {
|
|
1402
|
+
reasons.push(`${client.id}:no_owned_files`);
|
|
1403
|
+
continue;
|
|
1404
|
+
}
|
|
1405
|
+
const prev = cacheManager.readCache(cacheKey, cwd);
|
|
1406
|
+
const previousFailedHard = prev && !prev.data.success && isHardFailureSummary(prev.data.summary);
|
|
1407
|
+
const abandonedFailure = previousFailedHard ? null : client.recentHardFailure?.(cwd) ?? null;
|
|
1408
|
+
if (previousFailedHard || abandonedFailure !== null) {
|
|
1409
|
+
const failure = previousFailedHard ? prev.data.summary : abandonedFailure ?? "";
|
|
1410
|
+
dbg(`turn_end: skipping dead-code after failure: ${failure}`);
|
|
1411
|
+
deadCodeMeta.skipped = true;
|
|
1412
|
+
reasons.push(`${client.id}:backoff:${failure}`);
|
|
1413
|
+
continue;
|
|
1414
|
+
}
|
|
1415
|
+
const startMs = Date.now();
|
|
1416
|
+
const scan = client.analyze(cwd);
|
|
1417
|
+
const settled = await bounded(withRowForFailureWrite(scan, cacheManager, cacheKey, cwd, prev), {
|
|
1418
|
+
signal: deps.signal,
|
|
1419
|
+
hook: "turn_end",
|
|
1420
|
+
label: "dead-code",
|
|
1421
|
+
ms: Math.max(0, HOOK_WALL_BUDGET_MS.turn_end - (Date.now() - turnEndStart))
|
|
1422
|
+
});
|
|
1423
|
+
const joined = settled !== undefined && joinedEarlierScan(settled.result, startMs);
|
|
1424
|
+
if (settled === undefined || joined) {
|
|
1425
|
+
if (joined) {
|
|
1426
|
+
reasons.push(`${client.id}:joined`);
|
|
1427
|
+
} else {
|
|
1428
|
+
dbg(`turn_end: dead-code(${client.id}) outlived the budget`);
|
|
1429
|
+
deadCodeMeta.execution = "deferred";
|
|
1430
|
+
deadCodeMeta.aborted = deps.signal?.aborted === true;
|
|
1431
|
+
reasons.push(`${client.id}:deferred`);
|
|
1432
|
+
}
|
|
1433
|
+
parkLateDeadCodeScan({
|
|
1434
|
+
scope: turnScope,
|
|
1435
|
+
cacheManager,
|
|
1436
|
+
client,
|
|
1437
|
+
cwd,
|
|
1438
|
+
cacheKey,
|
|
1439
|
+
scan,
|
|
1440
|
+
startedAt: startMs,
|
|
1441
|
+
files: scanFiles,
|
|
1442
|
+
previousScan: prev?.data
|
|
1443
|
+
});
|
|
1444
|
+
if (joined)
|
|
1445
|
+
continue;
|
|
1446
|
+
break;
|
|
1447
|
+
}
|
|
1448
|
+
const { result } = settled;
|
|
950
1449
|
const durationMs = Date.now() - startMs;
|
|
951
|
-
if (wouldPoisonCache(
|
|
1450
|
+
if (wouldPoisonCache(settled.row, result)) {
|
|
952
1451
|
dbg(`turn_end: keeping last good dead-code(${client.id}) cache; this run failed: ${result.summary}`);
|
|
953
1452
|
deadCodeMeta.cacheKept = true;
|
|
954
1453
|
} else {
|
|
@@ -956,53 +1455,30 @@ ${suffix}`;
|
|
|
956
1455
|
scanDurationMs: durationMs
|
|
957
1456
|
});
|
|
958
1457
|
}
|
|
959
|
-
logDeadCodeScan(
|
|
960
|
-
language: client.language,
|
|
961
|
-
success: result.success,
|
|
962
|
-
cached: false,
|
|
963
|
-
unusedExports: result.unusedExports.length,
|
|
964
|
-
unusedFiles: result.unusedFiles.length,
|
|
965
|
-
unusedDeps: result.unusedDeps.length,
|
|
966
|
-
unlistedDeps: result.unlistedDeps.length,
|
|
967
|
-
durationMs: result.durationMs ?? durationMs,
|
|
968
|
-
...!result.success && { reason: result.summary }
|
|
969
|
-
});
|
|
1458
|
+
logDeadCodeScan(deadCodeScanEvent(client, cwd, result, durationMs));
|
|
970
1459
|
deadCodeMeta.success = result.success;
|
|
1460
|
+
if (result.excludedWorktrees !== undefined) {
|
|
1461
|
+
deadCodeMeta.excludedWorktrees = (deadCodeMeta.excludedWorktrees ?? 0) + result.excludedWorktrees;
|
|
1462
|
+
}
|
|
971
1463
|
if (!result.success) {
|
|
972
1464
|
reasons.push(`${client.id}:scan_failed:${result.summary}`);
|
|
973
1465
|
continue;
|
|
974
1466
|
}
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
}
|
|
980
|
-
const prevKeys = new Set(deadCodeIssues(prev.data).map(deadCodeIssueKey));
|
|
981
|
-
const modified = modifiedFiles();
|
|
982
|
-
const newIssues = deadCodeIssues(result).filter((issue) => {
|
|
983
|
-
if (prevKeys.has(deadCodeIssueKey(issue)))
|
|
984
|
-
return false;
|
|
985
|
-
if (!issue.file)
|
|
986
|
-
return false;
|
|
987
|
-
return modified.has(resolveRunnerPath(cwd, issue.file));
|
|
1467
|
+
sources.push({
|
|
1468
|
+
result,
|
|
1469
|
+
previousScan: prev?.data,
|
|
1470
|
+
modified: scanFiles
|
|
988
1471
|
});
|
|
989
|
-
if (newIssues.length === 0) {
|
|
990
|
-
reasons.push(`${client.id}:clean`);
|
|
991
|
-
continue;
|
|
992
|
-
}
|
|
993
|
-
newIssueTotal += newIssues.length;
|
|
994
|
-
projectDiagnosticsDelta.push(...newIssues.map((issue) => deadCodeIssueToProjectDiagnostic(cwd, issue, result.language)));
|
|
995
|
-
projectDiagnosticsSources.add("dead-code");
|
|
996
|
-
const deadCodeDeliverable = filterFindingsByDisposition(newIssues, cwd, (issue) => deadCodeIssueToProjectDiagnostic(cwd, issue, result.language));
|
|
997
|
-
deadCodeDispositionSuppressed += deadCodeDeliverable.suppressed;
|
|
998
|
-
if (deadCodeDeliverable.kept.length === 0) {
|
|
999
|
-
reasons.push(`${client.id}:all_disposed`);
|
|
1000
|
-
continue;
|
|
1001
|
-
}
|
|
1002
|
-
advisoryParts.push(formatDeadCodeDelta(deadCodeDeliverable.kept, result.language));
|
|
1003
1472
|
} catch (err) {
|
|
1004
1473
|
dbg(`turn_end: dead-code(${client.id}) failed: ${err}`);
|
|
1005
1474
|
reasons.push(`${client.id}:threw`);
|
|
1475
|
+
} finally {
|
|
1476
|
+
try {
|
|
1477
|
+
deliverDeadCodeDelta(client, sources);
|
|
1478
|
+
} catch (err) {
|
|
1479
|
+
dbg(`turn_end: dead-code(${client.id}) delivery failed: ${err}`);
|
|
1480
|
+
reasons.push(`${client.id}:threw`);
|
|
1481
|
+
}
|
|
1006
1482
|
}
|
|
1007
1483
|
}
|
|
1008
1484
|
} catch (err) {
|
|
@@ -1053,7 +1529,7 @@ ${suffix}`;
|
|
|
1053
1529
|
cwd,
|
|
1054
1530
|
signal: deps.signal,
|
|
1055
1531
|
readScannerCache,
|
|
1056
|
-
peekActionableWarnings: () => runtime.peekActionableWarnings()
|
|
1532
|
+
peekActionableWarnings: () => runtime.peekActionableWarnings(sessionId)
|
|
1057
1533
|
};
|
|
1058
1534
|
const govSources = await govulncheckLane.collect(laneCtx);
|
|
1059
1535
|
const trivyCacheEntry = await readScannerCache("trivy");
|
|
@@ -1081,15 +1557,15 @@ ${suffix}`;
|
|
|
1081
1557
|
const govGate = scannerGates.govulncheck;
|
|
1082
1558
|
const gitleaksGate = scannerGates.gitleaks;
|
|
1083
1559
|
const trivySecretsGate = scannerGates["trivy-secrets"];
|
|
1084
|
-
const govDelivery = govulncheckLane.render(govulncheckLane.gate({ govulncheck: govGate }, laneCtx), laneCtx);
|
|
1560
|
+
const govDelivery = allowProjectWideFindings ? govulncheckLane.render(govulncheckLane.gate({ govulncheck: govGate }, laneCtx), laneCtx) : {};
|
|
1085
1561
|
for (const [store, count] of Object.entries(govDelivery.dispositionSuppressed ?? {})) {
|
|
1086
1562
|
recordDispositionSuppressed(store, count);
|
|
1087
1563
|
}
|
|
1088
1564
|
advisoryParts.push(...govDelivery.advisoryParts ?? []);
|
|
1089
|
-
const secretsDelivery = secretsLane.render(secretsLane.gate({
|
|
1565
|
+
const secretsDelivery = allowProjectWideFindings ? secretsLane.render(secretsLane.gate({
|
|
1090
1566
|
gitleaks: gitleaksGate,
|
|
1091
1567
|
"trivy-secrets": trivySecretsGate
|
|
1092
|
-
}, laneCtx), laneCtx);
|
|
1568
|
+
}, laneCtx), laneCtx) : {};
|
|
1093
1569
|
for (const [store, count] of Object.entries(secretsDelivery.dispositionSuppressed ?? {})) {
|
|
1094
1570
|
recordDispositionSuppressed(store, count);
|
|
1095
1571
|
}
|
|
@@ -1156,8 +1632,14 @@ ${suffix}`;
|
|
|
1156
1632
|
}
|
|
1157
1633
|
const t3 = Date.now();
|
|
1158
1634
|
let madgeStats;
|
|
1159
|
-
|
|
1160
|
-
|
|
1635
|
+
const madgeAvailabilitySignal = deps.signal;
|
|
1636
|
+
if (getFlag("lens-turn-end-madge") && await bounded(depChecker.ensureAvailable(), {
|
|
1637
|
+
ms: HOOK_WALL_BUDGET_MS.turn_end,
|
|
1638
|
+
signal: madgeAvailabilitySignal,
|
|
1639
|
+
hook: "turn_end",
|
|
1640
|
+
label: "madge.ensureAvailable"
|
|
1641
|
+
})) {
|
|
1642
|
+
const madgeFiles = cacheManager.getFilesForMadge(cwd, turnStateSessionId);
|
|
1161
1643
|
if (madgeFiles.length > 0) {
|
|
1162
1644
|
dbg(`turn_end: madge checking ${madgeFiles.length} file(s) for circular deps`);
|
|
1163
1645
|
const absFiles = madgeFiles.map((file) => path.resolve(cwd, file));
|
|
@@ -1186,6 +1668,7 @@ ${suffix}`;
|
|
|
1186
1668
|
if (!getFlag("no-tests") && files.length > 0) {
|
|
1187
1669
|
const seen = new Set;
|
|
1188
1670
|
const targets = [];
|
|
1671
|
+
const testRootFor = createTurnEndTestRoots(cwd);
|
|
1189
1672
|
const candidates = [];
|
|
1190
1673
|
const seenCandidateKeys = new Set;
|
|
1191
1674
|
for (const file of files) {
|
|
@@ -1216,14 +1699,11 @@ ${suffix}`;
|
|
|
1216
1699
|
const resolvedDeferralKeys = new Set;
|
|
1217
1700
|
const heldDeferred = [];
|
|
1218
1701
|
const boundPersisted = (entries, label) => {
|
|
1219
|
-
const
|
|
1220
|
-
|
|
1221
|
-
|
|
1222
|
-
|
|
1223
|
-
|
|
1224
|
-
return ordered;
|
|
1225
|
-
dbg(`turn_end: ${label} test target list held ${ordered.length} entries, bounded to the newest ${TEST_RUNNER_MAX_PERSISTED_TARGETS} (oldest foreign-session rows dropped)`);
|
|
1226
|
-
return ordered.slice(-TEST_RUNNER_MAX_PERSISTED_TARGETS);
|
|
1702
|
+
const bounded = boundDeferredTargets(entries, TEST_RUNNER_MAX_PERSISTED_TARGETS, isThisSession);
|
|
1703
|
+
if (bounded.length !== entries.length) {
|
|
1704
|
+
dbg(`turn_end: ${label} test target list held ${entries.length} entries, bounded to the newest ${TEST_RUNNER_MAX_PERSISTED_TARGETS} (oldest foreign-session rows dropped)`);
|
|
1705
|
+
}
|
|
1706
|
+
return bounded;
|
|
1227
1707
|
};
|
|
1228
1708
|
const writeTestFindings = (record, ownDeferred) => {
|
|
1229
1709
|
const live = cacheManager.readCache("test-runner-findings", cwd)?.data;
|
|
@@ -1272,14 +1752,15 @@ ${suffix}`;
|
|
|
1272
1752
|
incrementDegradationCount({
|
|
1273
1753
|
kind: "test-runner-batch-capped",
|
|
1274
1754
|
subject: `${cwd}:deferral-exhausted`,
|
|
1275
|
-
reason: `test target
|
|
1755
|
+
reason: `test target was cut after ${attempts} turn(s) at the turn-end budget and is retired for this session — too slow for a per-turn batch; run it explicitly (target: ${path.relative(cwd, testFile)})`
|
|
1276
1756
|
});
|
|
1277
1757
|
dbg(`turn_end: retiring deferred test target ${path.relative(cwd, testFile)} after ${attempts} cut batch(es) — too slow for the turn-end budget, run it explicitly`);
|
|
1278
1758
|
}
|
|
1279
1759
|
continue;
|
|
1280
1760
|
}
|
|
1281
1761
|
const config = RUNNERS[carried.runner];
|
|
1282
|
-
|
|
1762
|
+
const carriedRoot = testRootFor(testFile);
|
|
1763
|
+
if (!config || isExcludedTestTarget(testFile, carriedRoot) || !fs.existsSync(testFile)) {
|
|
1283
1764
|
resolvedDeferralKeys.add(carriedKey);
|
|
1284
1765
|
deadDeferred++;
|
|
1285
1766
|
continue;
|
|
@@ -1304,6 +1785,7 @@ ${suffix}`;
|
|
|
1304
1785
|
runner: carried.runner,
|
|
1305
1786
|
config,
|
|
1306
1787
|
strategy: "deferred",
|
|
1788
|
+
testRoot: carriedRoot,
|
|
1307
1789
|
deferralAttempts: attempts
|
|
1308
1790
|
});
|
|
1309
1791
|
dbg(`turn_end: re-running deferred test target ${path.relative(cwd, testFile)} (${carried.runner}) from the previous turn's cut batch`);
|
|
@@ -1339,8 +1821,12 @@ ${suffix}`;
|
|
|
1339
1821
|
let missingTargetFiles = 0;
|
|
1340
1822
|
let excludedTargets = 0;
|
|
1341
1823
|
let retiredSkips = 0;
|
|
1824
|
+
let noTestFile = 0;
|
|
1825
|
+
const candidatesByRoot = new Map;
|
|
1342
1826
|
for (const { display, abs, isNeighbor } of candidates) {
|
|
1343
|
-
const
|
|
1827
|
+
const testRoot = testRootFor(abs);
|
|
1828
|
+
candidatesByRoot.set(testRoot, (candidatesByRoot.get(testRoot) ?? 0) + 1);
|
|
1829
|
+
const target = testRunnerClient.getTestRunTarget(abs, testRoot, runtime.turnIndex);
|
|
1344
1830
|
const targetKey = target ? normalizeMapKey(target.testFile) : "";
|
|
1345
1831
|
if (target && !seen.has(targetKey)) {
|
|
1346
1832
|
seen.add(targetKey);
|
|
@@ -1349,9 +1835,9 @@ ${suffix}`;
|
|
|
1349
1835
|
dbg(`turn_end: ${display} → test target retired earlier this session (outran the turn-end batch budget), skipping spawn (${path.relative(cwd, target.testFile)})`);
|
|
1350
1836
|
continue;
|
|
1351
1837
|
}
|
|
1352
|
-
if (isExcludedTestTarget(target.testFile,
|
|
1838
|
+
if (isExcludedTestTarget(target.testFile, testRoot)) {
|
|
1353
1839
|
excludedTargets++;
|
|
1354
|
-
dbg(`turn_end: ${display} → test target excluded
|
|
1840
|
+
dbg(`turn_end: ${display} → test target excluded by the built-in turn-end policy, skipping spawn (${path.relative(cwd, target.testFile)})`);
|
|
1355
1841
|
continue;
|
|
1356
1842
|
}
|
|
1357
1843
|
if (!fs.existsSync(target.testFile)) {
|
|
@@ -1363,14 +1849,15 @@ ${suffix}`;
|
|
|
1363
1849
|
overCapTargets++;
|
|
1364
1850
|
continue;
|
|
1365
1851
|
}
|
|
1366
|
-
targets.push({ ...target, sourceFile: abs });
|
|
1852
|
+
targets.push({ ...target, sourceFile: abs, testRoot });
|
|
1367
1853
|
dbg(`turn_end: ${display} → test ${target.runner} ${path.relative(cwd, target.testFile)} (${target.strategy}${isNeighbor ? ", cascade-neighbor" : ""})`);
|
|
1368
1854
|
} else if (!target) {
|
|
1855
|
+
noTestFile++;
|
|
1369
1856
|
dbg(`turn_end: ${display} → no test file found${isNeighbor ? " (cascade-neighbor)" : ""}`);
|
|
1370
1857
|
}
|
|
1371
1858
|
}
|
|
1372
1859
|
if (excludedTargets > 0) {
|
|
1373
|
-
dbg(`turn_end: excluded ${excludedTargets} test target(s)
|
|
1860
|
+
dbg(`turn_end: excluded ${excludedTargets} test target(s) by the built-in turn-end policy`);
|
|
1374
1861
|
}
|
|
1375
1862
|
if (retiredSkips > 0) {
|
|
1376
1863
|
dbg(`turn_end: skipped ${retiredSkips} test target(s) retired earlier this session for outrunning the turn-end batch budget`);
|
|
@@ -1386,6 +1873,33 @@ ${suffix}`;
|
|
|
1386
1873
|
});
|
|
1387
1874
|
dbg(`turn_end: test target count capped at ${TEST_RUNNER_MAX_TARGETS}, ${overCapTargets} skipped`);
|
|
1388
1875
|
}
|
|
1876
|
+
if (candidates.length > 0) {
|
|
1877
|
+
const selectedByRoot = new Map;
|
|
1878
|
+
for (const target of targets) {
|
|
1879
|
+
selectedByRoot.set(target.testRoot, (selectedByRoot.get(target.testRoot) ?? 0) + 1);
|
|
1880
|
+
}
|
|
1881
|
+
const roots = [...candidatesByRoot.entries()].map(([root, candidateCount]) => ({
|
|
1882
|
+
root: root === cwd ? "." : toRunnerDisplayPath(cwd, root),
|
|
1883
|
+
candidates: candidateCount,
|
|
1884
|
+
selected: selectedByRoot.get(root) ?? 0
|
|
1885
|
+
}));
|
|
1886
|
+
emitBounded("turn_end_test_selection", `${cwd}:turn:${runtime.turnIndex}`, {
|
|
1887
|
+
filePath: cwd,
|
|
1888
|
+
durationMs: 0,
|
|
1889
|
+
metadata: {
|
|
1890
|
+
sessionId: turnSessionId,
|
|
1891
|
+
candidates: candidates.length,
|
|
1892
|
+
selected: targets.length,
|
|
1893
|
+
noTestFile,
|
|
1894
|
+
excluded: excludedTargets,
|
|
1895
|
+
missing: missingTargetFiles,
|
|
1896
|
+
overCap: overCapTargets,
|
|
1897
|
+
retired: retiredSkips,
|
|
1898
|
+
roots: roots.slice(0, TURN_END_SELECTION_ROOT_ROWS),
|
|
1899
|
+
rootsOmitted: Math.max(0, roots.length - TURN_END_SELECTION_ROOT_ROWS)
|
|
1900
|
+
}
|
|
1901
|
+
});
|
|
1902
|
+
}
|
|
1389
1903
|
if (targets.length > 0) {
|
|
1390
1904
|
for (const target of targets) {
|
|
1391
1905
|
target.fileSeqAtRun = runtime.getFileSeq(target.sourceFile);
|
|
@@ -1419,15 +1933,32 @@ ${suffix}`;
|
|
|
1419
1933
|
concurrency: TEST_RUNNER_BATCH_CONCURRENCY,
|
|
1420
1934
|
budgetMs: TEST_RUNNER_BATCH_BUDGET_MS,
|
|
1421
1935
|
signal: getAmbientAbortSignal(),
|
|
1422
|
-
run: (t, batchSignal) => testRunnerClient.runTestFileAsync(t.testFile,
|
|
1936
|
+
run: (t, batchSignal) => testRunnerClient.runTestFileAsync(t.testFile, t.testRoot, {
|
|
1423
1937
|
runner: t.runner,
|
|
1424
1938
|
config: t.config,
|
|
1425
1939
|
turnIndex: firedAtTurn,
|
|
1426
|
-
signal: batchSignal
|
|
1940
|
+
signal: batchSignal,
|
|
1941
|
+
displayRoot: cwd,
|
|
1942
|
+
requireOwnInstall: t.testRoot !== cwd
|
|
1427
1943
|
})
|
|
1428
|
-
}).then(({ results, deferred, stopReason }) => {
|
|
1429
|
-
const settledResults =
|
|
1430
|
-
const
|
|
1944
|
+
}).then(({ results: batchResults, deferred, stopReason }) => {
|
|
1945
|
+
const settledResults = batchResults;
|
|
1946
|
+
const results = [];
|
|
1947
|
+
for (const result of settledResults) {
|
|
1948
|
+
if (!("value" in result) || !result.value.notRun) {
|
|
1949
|
+
results.push(result);
|
|
1950
|
+
continue;
|
|
1951
|
+
}
|
|
1952
|
+
const skippedRoot = targets.find((candidate) => candidate.testFile === result.value.file)?.testRoot ?? cwd;
|
|
1953
|
+
const ambientNote = result.value.runner === "pytest" && hasAmbientPythonEnvironment() ? "; ambient Python environments outside this checkout were not borrowed" : "";
|
|
1954
|
+
incrementDegradationCount({
|
|
1955
|
+
kind: "turn-end-test-root-skipped",
|
|
1956
|
+
subject: result.value.notRun,
|
|
1957
|
+
reason: `${toRunnerDisplayPath(cwd, skippedRoot)} has no ${result.value.runner} install of its own${ambientNote}; its tests were skipped rather than fetched through npx or run in another environment`
|
|
1958
|
+
});
|
|
1959
|
+
dbg(`turn_end: skipped ${toRunnerDisplayPath(cwd, result.value.file)}: ${result.value.notRun} in ${toRunnerDisplayPath(cwd, skippedRoot)}`);
|
|
1960
|
+
}
|
|
1961
|
+
const verdicts = results.flatMap((result) => {
|
|
1431
1962
|
if (result.status === "rejected")
|
|
1432
1963
|
return [];
|
|
1433
1964
|
const target = targets.find((candidate) => candidate.testFile === result.value.file);
|
|
@@ -1435,6 +1966,7 @@ ${suffix}`;
|
|
|
1435
1966
|
{
|
|
1436
1967
|
file: result.value.file,
|
|
1437
1968
|
sourceFile: target.sourceFile,
|
|
1969
|
+
runner: target.runner,
|
|
1438
1970
|
fileSeq: target.fileSeqAtRun === undefined ? {
|
|
1439
1971
|
state: "unknown",
|
|
1440
1972
|
reason: "sequence-unavailable"
|
|
@@ -1672,7 +2204,12 @@ ${suffix}`;
|
|
|
1672
2204
|
const impactLines = [];
|
|
1673
2205
|
let callGraphDispositionSuppressed = 0;
|
|
1674
2206
|
const impactFindings = [];
|
|
1675
|
-
|
|
2207
|
+
const impactFiles = files.slice(0, 5);
|
|
2208
|
+
const impactFileKeys = new Set(impactFiles.map((file) => normalizeMapKey(resolveRunnerPath(cwd, file))));
|
|
2209
|
+
const reOfferedImpactFiles = takeParked(carryLane("call-graph")).filter((file) => !impactFileKeys.has(normalizeMapKey(resolveRunnerPath(cwd, file))));
|
|
2210
|
+
const shownImpactFiles = [];
|
|
2211
|
+
for (const filePath of [...impactFiles, ...reOfferedImpactFiles]) {
|
|
2212
|
+
const linesBefore = impactLines.length;
|
|
1676
2213
|
const changedFileKey = normalizeMapKey(resolveRunnerPath(cwd, filePath));
|
|
1677
2214
|
const fileCallerKeys = [...runtime.callGraph.callers.keys()].filter((k) => {
|
|
1678
2215
|
const graphFilePath = parseSymbolKey(k).filePath;
|
|
@@ -1698,11 +2235,15 @@ ${suffix}`;
|
|
|
1698
2235
|
impactLines.push(` ${parseSymbolKey(calleeKey).symbolName ?? calleeKey}: ${summary}`);
|
|
1699
2236
|
}
|
|
1700
2237
|
}
|
|
2238
|
+
if (impactLines.length > linesBefore)
|
|
2239
|
+
shownImpactFiles.push(filePath);
|
|
1701
2240
|
}
|
|
1702
2241
|
if (impactLines.length > 0) {
|
|
1703
|
-
|
|
2242
|
+
const impactPart = `\uD83D\uDCCA Call-graph impact (changed symbols have callers):
|
|
1704
2243
|
${impactLines.join(`
|
|
1705
|
-
`)}
|
|
2244
|
+
`)}`;
|
|
2245
|
+
advisoryParts.push(impactPart);
|
|
2246
|
+
deliveryHolds.push(cutAdvisoryHold("call-graph", carryLane("call-graph"), impactPart, shownImpactFiles, (file) => !impactFiles.includes(file)));
|
|
1706
2247
|
}
|
|
1707
2248
|
if (impactFindings.length > 0) {
|
|
1708
2249
|
const impactDiagnostics = callGraphImpactToProjectDiagnostics(cwd, impactFindings);
|
|
@@ -1780,10 +2321,12 @@ ${impactLines.join(`
|
|
|
1780
2321
|
turnIndex: runtime.turnIndex,
|
|
1781
2322
|
files,
|
|
1782
2323
|
modifiedRangesByFile,
|
|
1783
|
-
dispatchWarnings: runtime.peekActionableWarnings(),
|
|
2324
|
+
dispatchWarnings: runtime.peekActionableWarnings(sessionId),
|
|
1784
2325
|
includeLspCodeActions: !!getFlag("lens-actionable-warning-actions"),
|
|
1785
2326
|
projectSeqStart: runtime.turnStartProjectSeq,
|
|
1786
2327
|
projectSeqEnd: runtime.projectSeq,
|
|
2328
|
+
branchEpoch: runtime.readGuard.currentBranchEpoch,
|
|
2329
|
+
branchScope: runtime.readGuard.lineageKey,
|
|
1787
2330
|
fileSeqByPath,
|
|
1788
2331
|
deltaOnly: !getFlag("lens-actionable-warning-all"),
|
|
1789
2332
|
dbg,
|
|
@@ -1882,7 +2425,7 @@ ${impactLines.join(`
|
|
|
1882
2425
|
const t5 = Date.now();
|
|
1883
2426
|
try {
|
|
1884
2427
|
const qualityWarningsByFile = new Map;
|
|
1885
|
-
for (const warning of runtime.peekCodeQualityWarnings()) {
|
|
2428
|
+
for (const warning of runtime.peekCodeQualityWarnings(sessionId)) {
|
|
1886
2429
|
const group = qualityWarningsByFile.get(warning.filePath);
|
|
1887
2430
|
if (group)
|
|
1888
2431
|
group.push(warning);
|
|
@@ -1946,97 +2489,25 @@ ${impactLines.join(`
|
|
|
1946
2489
|
}
|
|
1947
2490
|
});
|
|
1948
2491
|
}
|
|
1949
|
-
cacheManager.incrementTurnCycle(cwd, currentOwner);
|
|
1950
|
-
const runnerFindingsStart = Date.now();
|
|
1951
|
-
const pendingRunnerFindings = await drainPendingRunnerFindings(0);
|
|
1952
|
-
let runnerFindingsDelivered = 0;
|
|
1953
|
-
let runnerFindingsStale = 0;
|
|
1954
|
-
let runnerFindingsFailed = 0;
|
|
1955
|
-
let runnerFindingsDropped = 0;
|
|
1956
|
-
let runnerFindingsDispositionSuppressed = 0;
|
|
1957
|
-
const runnerFindingsDeliveredIds = [];
|
|
1958
|
-
for (const pending of pendingRunnerFindings) {
|
|
1959
|
-
const result = pending.result;
|
|
1960
|
-
if (!result)
|
|
1961
|
-
continue;
|
|
1962
|
-
recordRunner(pending.filePath, pending.runnerId, result.status, result.diagnostics.length, Date.now() - pending.markedAtMs, pending.writeIndex);
|
|
1963
|
-
if (result.status === "failed") {
|
|
1964
|
-
runnerFindingsFailed += 1;
|
|
1965
|
-
const detail = result.failureMessage ? `: ${result.failureMessage}` : "";
|
|
1966
|
-
advisoryParts.push(`❌ Deferred runner ${pending.runnerId} failed (${result.failureKind ?? "unknown"})${detail}`);
|
|
1967
|
-
continue;
|
|
1968
|
-
}
|
|
1969
|
-
const findings = result.diagnostics;
|
|
1970
|
-
if (findings.length === 0)
|
|
1971
|
-
continue;
|
|
1972
|
-
const { "late-runner-findings": gate } = gateFindingsByPathFreshness({
|
|
1973
|
-
cwd,
|
|
1974
|
-
sources: {
|
|
1975
|
-
"late-runner-findings": {
|
|
1976
|
-
findings,
|
|
1977
|
-
scannedAt: pending.markedAtMs,
|
|
1978
|
-
citedPath: (finding) => finding.filePath
|
|
1979
|
-
}
|
|
1980
|
-
}
|
|
1981
|
-
});
|
|
1982
|
-
runnerFindingsStale += gate.stale.length;
|
|
1983
|
-
if (gate.stale.length > 0) {
|
|
1984
|
-
dropStaleRunnerFindings(pending);
|
|
1985
|
-
runnerFindingsDropped += 1;
|
|
1986
|
-
}
|
|
1987
|
-
if (gate.live.length === 0)
|
|
1988
|
-
continue;
|
|
1989
|
-
const displayPath = toRunnerDisplayPath(cwd, pending.filePath);
|
|
1990
|
-
let runnerContent;
|
|
1991
|
-
try {
|
|
1992
|
-
runnerContent = fs.readFileSync(pending.filePath, "utf-8");
|
|
1993
|
-
} catch {
|
|
1994
|
-
runnerContent = undefined;
|
|
1995
|
-
}
|
|
1996
|
-
const { kept: runnerKept, suppressed: runnerSuppressedHere } = applyPushedFindingPolicy(gate.live, {
|
|
1997
|
-
cwd,
|
|
1998
|
-
filePath: pending.filePath,
|
|
1999
|
-
content: runnerContent
|
|
2000
|
-
});
|
|
2001
|
-
runnerFindingsDispositionSuppressed += runnerSuppressedHere;
|
|
2002
|
-
if (runnerKept.length === 0) {
|
|
2003
|
-
continue;
|
|
2004
|
-
}
|
|
2005
|
-
const lines = runnerKept.map((finding) => ` ${displayPath}:${finding.line ?? 1}:${finding.column ?? 1} [${finding.rule ?? finding.id}] ${finding.message}`);
|
|
2006
|
-
runnerFindingsDelivered += runnerKept.length;
|
|
2007
|
-
for (const finding of runnerKept) {
|
|
2008
|
-
if (runnerFindingsDeliveredIds.length < 50) {
|
|
2009
|
-
runnerFindingsDeliveredIds.push(finding.id);
|
|
2010
|
-
}
|
|
2011
|
-
}
|
|
2012
|
-
const runnerSuppressedNote = runnerSuppressedHere > 0 ? `; suppressed by disposition: ${runnerSuppressedHere} finding(s)` : "";
|
|
2013
|
-
advisoryParts.push(`⏱️ Late runner diagnostics (${pending.runnerId} completed after the edit${runnerSuppressedNote}):
|
|
2014
|
-
${lines.join(`
|
|
2015
|
-
`)}`);
|
|
2016
|
-
}
|
|
2017
|
-
logLatency({
|
|
2018
|
-
type: "phase",
|
|
2019
|
-
toolName: "turn_end",
|
|
2020
|
-
filePath: cwd,
|
|
2021
|
-
phase: "late_runner_findings",
|
|
2022
|
-
durationMs: Date.now() - runnerFindingsStart,
|
|
2023
|
-
metadata: {
|
|
2024
|
-
pending: pendingRunnerFindings.length,
|
|
2025
|
-
delivered: runnerFindingsDelivered,
|
|
2026
|
-
stale: runnerFindingsStale,
|
|
2027
|
-
failed: runnerFindingsFailed,
|
|
2028
|
-
dropped: runnerFindingsDropped,
|
|
2029
|
-
dispositionSuppressed: runnerFindingsDispositionSuppressed,
|
|
2030
|
-
deliveredIds: runnerFindingsDeliveredIds
|
|
2031
|
-
}
|
|
2032
|
-
});
|
|
2492
|
+
cacheManager.incrementTurnCycle(cwd, currentOwner, turnStateSessionId);
|
|
2033
2493
|
const lateAuxStart = Date.now();
|
|
2034
|
-
const
|
|
2035
|
-
|
|
2494
|
+
const lateAuxDrain = isSecondarySession ? {
|
|
2495
|
+
drainedPairs: drainPendingAuxiliaryCoverage(),
|
|
2496
|
+
lateAuxCapEvicted: drainPendingAuxCapEvictedCount()
|
|
2497
|
+
} : holdScope.guardedWrite("turn-end:late-aux", () => ({
|
|
2498
|
+
drainedPairs: drainPendingAuxiliaryCoverage(),
|
|
2499
|
+
lateAuxCapEvicted: drainPendingAuxCapEvictedCount()
|
|
2500
|
+
})) ?? { drainedPairs: [], lateAuxCapEvicted: 0 };
|
|
2501
|
+
const { drainedPairs, lateAuxCapEvicted } = lateAuxDrain;
|
|
2502
|
+
const rearmLateAux = (pair) => isSecondarySession ? (rearmPendingAuxiliaryCoverage(pair), true) : holdScope.guardedWrite("turn-end:late-aux-rearm", () => {
|
|
2503
|
+
rearmPendingAuxiliaryCoverage(pair);
|
|
2504
|
+
return true;
|
|
2505
|
+
}) === true;
|
|
2036
2506
|
let lateAuxDelivered = 0;
|
|
2037
2507
|
let lateAuxStale = 0;
|
|
2038
2508
|
let lateAuxMissing = 0;
|
|
2039
2509
|
let lateAuxRearmed = 0;
|
|
2510
|
+
let lateAuxBacklogPending = 0;
|
|
2040
2511
|
let lateAuxClientGone = 0;
|
|
2041
2512
|
let lateAuxProbeFailed = 0;
|
|
2042
2513
|
let lateAuxCleanConfirmed = 0;
|
|
@@ -2044,6 +2515,9 @@ ${lines.join(`
|
|
|
2044
2515
|
let lateAuxCeilingExhausted = 0;
|
|
2045
2516
|
let lateAuxAnswered = 0;
|
|
2046
2517
|
let lateAuxNotifyStallDemoted = 0;
|
|
2518
|
+
let lateAuxHoldRearmed = 0;
|
|
2519
|
+
let lateAuxHoldExpired = 0;
|
|
2520
|
+
let lateAuxHoldCeiling = 0;
|
|
2047
2521
|
let lateAuxDispositionSuppressed = 0;
|
|
2048
2522
|
let lateAuxAuxSuppressed = 0;
|
|
2049
2523
|
const lateAuxCoverageGapPairs = [];
|
|
@@ -2069,9 +2543,9 @@ ${lines.join(`
|
|
|
2069
2543
|
} catch {
|
|
2070
2544
|
lateAuxProbeFailed += pairs.length;
|
|
2071
2545
|
for (const pair of pairs) {
|
|
2072
|
-
if (
|
|
2073
|
-
|
|
2074
|
-
|
|
2546
|
+
if (canRearmPendingAuxiliary(pair)) {
|
|
2547
|
+
if (rearmLateAux(pair))
|
|
2548
|
+
lateAuxRearmed += 1;
|
|
2075
2549
|
} else if (isPendingAuxiliaryPastRearmTtl(pair)) {
|
|
2076
2550
|
lateAuxExpired += 1;
|
|
2077
2551
|
} else {
|
|
@@ -2109,13 +2583,14 @@ ${lines.join(`
|
|
|
2109
2583
|
const pastTtl = isPendingAuxiliaryPastRearmTtl(pair);
|
|
2110
2584
|
const atCeiling = (pair.rearmCount ?? 0) >= MAX_LATE_AUX_REARMS;
|
|
2111
2585
|
if (!pastTtl && !atCeiling) {
|
|
2112
|
-
|
|
2113
|
-
|
|
2114
|
-
|
|
2115
|
-
|
|
2116
|
-
|
|
2117
|
-
|
|
2118
|
-
|
|
2586
|
+
if (rearmLateAux(pair)) {
|
|
2587
|
+
lateAuxRearmed += 1;
|
|
2588
|
+
if (lateAuxStuckPairs.length < 20)
|
|
2589
|
+
lateAuxStuckPairs.push({
|
|
2590
|
+
filePath: pair.filePath,
|
|
2591
|
+
serverId: pair.serverId
|
|
2592
|
+
});
|
|
2593
|
+
}
|
|
2119
2594
|
} else {
|
|
2120
2595
|
if (pastTtl)
|
|
2121
2596
|
lateAuxExpired += 1;
|
|
@@ -2129,15 +2604,19 @@ ${lines.join(`
|
|
|
2129
2604
|
continue;
|
|
2130
2605
|
}
|
|
2131
2606
|
const rawDiags = cachedEntry.diags;
|
|
2132
|
-
|
|
2133
|
-
|
|
2134
|
-
|
|
2135
|
-
|
|
2136
|
-
|
|
2137
|
-
|
|
2138
|
-
|
|
2139
|
-
|
|
2140
|
-
|
|
2607
|
+
const backlogPending = !isAuxBacklogPublished(pair);
|
|
2608
|
+
if (backlogPending)
|
|
2609
|
+
lateAuxBacklogPending += 1;
|
|
2610
|
+
if (cachedEntry.publishedAt === undefined || cachedEntry.publishedAt <= pair.markedAtMs || backlogPending) {
|
|
2611
|
+
if (canRearmPendingAuxiliary(pair)) {
|
|
2612
|
+
if (rearmLateAux(pair)) {
|
|
2613
|
+
lateAuxRearmed += 1;
|
|
2614
|
+
if (lateAuxStuckPairs.length < 20)
|
|
2615
|
+
lateAuxStuckPairs.push({
|
|
2616
|
+
filePath: pair.filePath,
|
|
2617
|
+
serverId: pair.serverId
|
|
2618
|
+
});
|
|
2619
|
+
}
|
|
2141
2620
|
} else {
|
|
2142
2621
|
if (isPendingAuxiliaryPastRearmTtl(pair))
|
|
2143
2622
|
lateAuxExpired += 1;
|
|
@@ -2186,9 +2665,9 @@ ${lines.join(`
|
|
|
2186
2665
|
lateAuxMissing += retained.length - gate.live.length - gate.stale.length;
|
|
2187
2666
|
if (gate.live.length === 0) {
|
|
2188
2667
|
if (gate.stale.length > 0) {
|
|
2189
|
-
if (
|
|
2190
|
-
|
|
2191
|
-
|
|
2668
|
+
if (canRearmPendingAuxiliary(pair)) {
|
|
2669
|
+
if (rearmLateAux(pair))
|
|
2670
|
+
lateAuxRearmed += 1;
|
|
2192
2671
|
} else if (isPendingAuxiliaryPastRearmTtl(pair)) {
|
|
2193
2672
|
lateAuxExpired += 1;
|
|
2194
2673
|
} else {
|
|
@@ -2213,9 +2692,29 @@ ${lines.join(`
|
|
|
2213
2692
|
lateAuxDelivered += lateAuxKept.length;
|
|
2214
2693
|
lateAuxAnswered += 1;
|
|
2215
2694
|
const lateAuxSuppressedNote = lateAuxSuppressedHere > 0 ? `; suppressed by disposition: ${lateAuxSuppressedHere} finding(s)` : "";
|
|
2216
|
-
|
|
2695
|
+
const lateAuxPart = `\uD83D\uDD50 Late auxiliary diagnostics (${pair.serverId} answered after its grace window${lateAuxSuppressedNote}):
|
|
2217
2696
|
${lines.join(`
|
|
2218
|
-
`)}
|
|
2697
|
+
`)}`;
|
|
2698
|
+
advisoryParts.push(lateAuxPart);
|
|
2699
|
+
deliveryHolds.push({
|
|
2700
|
+
part: lateAuxPart,
|
|
2701
|
+
canHold: () => canRearmPendingAuxiliary(pair),
|
|
2702
|
+
onHeld: () => {
|
|
2703
|
+
rearmPendingAuxiliaryCoverage(pair);
|
|
2704
|
+
lateAuxHoldRearmed += 1;
|
|
2705
|
+
},
|
|
2706
|
+
onDropped: () => {
|
|
2707
|
+
if (isPendingAuxiliaryPastRearmTtl(pair))
|
|
2708
|
+
lateAuxHoldExpired += 1;
|
|
2709
|
+
else
|
|
2710
|
+
lateAuxHoldCeiling += 1;
|
|
2711
|
+
incrementDegradationCount({
|
|
2712
|
+
kind: "late-auxiliary-held-dropped",
|
|
2713
|
+
subject: `late-auxiliary:${pair.serverId}`,
|
|
2714
|
+
reason: "cut by the turn-end cap and past its re-arm bound, so not re-armed"
|
|
2715
|
+
});
|
|
2716
|
+
}
|
|
2717
|
+
});
|
|
2219
2718
|
}
|
|
2220
2719
|
}
|
|
2221
2720
|
} catch (err) {
|
|
@@ -2259,6 +2758,7 @@ ${lines.join(`
|
|
|
2259
2758
|
stale: lateAuxStale,
|
|
2260
2759
|
missing: lateAuxMissing,
|
|
2261
2760
|
rearmed: lateAuxRearmed,
|
|
2761
|
+
backlogPending: lateAuxBacklogPending,
|
|
2262
2762
|
clientGone: lateAuxClientGone,
|
|
2263
2763
|
probeFailed: lateAuxProbeFailed,
|
|
2264
2764
|
cleanConfirmed: lateAuxCleanConfirmed,
|
|
@@ -2276,21 +2776,112 @@ ${lines.join(`
|
|
|
2276
2776
|
}
|
|
2277
2777
|
});
|
|
2278
2778
|
}
|
|
2279
|
-
const
|
|
2280
|
-
${
|
|
2281
|
-
const
|
|
2282
|
-
|
|
2283
|
-
|
|
2284
|
-
|
|
2779
|
+
const unresolvedKeys = new Set(unresolvedBlockers.map((record) => normalizeMapKey(path.resolve(record.filePath))));
|
|
2780
|
+
const formatResolvedTail = (dropped) => `… and ${dropped} more`;
|
|
2781
|
+
const resolvedTailMax = formatResolvedTail(Number.MAX_SAFE_INTEGER).length;
|
|
2782
|
+
const resolvedShareChars = Math.floor(RUNTIME_CONFIG.turnEnd.maxChars * RESOLVED_SHARE_OF_CHARS) - resolvedTailMax;
|
|
2783
|
+
const formatResolvedLine = (entry) => {
|
|
2784
|
+
const clause = entry.confirmedClean ? " confirmed clean" : entry.writeIndex === undefined ? "" : ` cleared by the ${formatWriteOrdinal(entry.writeIndex)} write`;
|
|
2785
|
+
const label = entry.turnIndex === runtime.turnIndex ? "Resolved this turn" : "Resolved since the last report";
|
|
2786
|
+
const head = `${label}: `;
|
|
2787
|
+
const tail = ` (${entry.blockerCount} blocker(s)${clause})`;
|
|
2788
|
+
let display = toRunnerDisplayPath(cwd, entry.filePath);
|
|
2789
|
+
const room = resolvedShareChars - 1 - head.length - tail.length;
|
|
2790
|
+
if (display.length > room) {
|
|
2791
|
+
const keepHead = Math.ceil((room - 1) / 2);
|
|
2792
|
+
display = `${sliceAtCodePointBoundaries(display, 0, keepHead)}…${sliceAtCodePointBoundaries(display, display.length - (room - 1 - keepHead), display.length)}`;
|
|
2793
|
+
}
|
|
2794
|
+
return `${head}${display}${tail}`;
|
|
2795
|
+
};
|
|
2796
|
+
const blockerText = blockerParts.join(`
|
|
2797
|
+
|
|
2798
|
+
`);
|
|
2799
|
+
const blockerChars = blockerParts.length > 0 ? blockerText.length + 2 : 0;
|
|
2800
|
+
const blockerLines = blockerParts.length > 0 ? blockerText.split(`
|
|
2801
|
+
`).length + 1 : 0;
|
|
2802
|
+
const resolvedCharBudget = Math.min(resolvedShareChars, RUNTIME_CONFIG.turnEnd.maxChars - blockerChars - resolvedTailMax);
|
|
2803
|
+
const resolvedLineBudget = Math.min(RESOLVED_MAX_LINES, RUNTIME_CONFIG.turnEnd.maxLines - blockerLines) - 1;
|
|
2804
|
+
let resolvedChars = 0;
|
|
2805
|
+
let resolvedCount = 0;
|
|
2806
|
+
const {
|
|
2807
|
+
files: resolvedBlockerFileList,
|
|
2808
|
+
dropped: resolvedBlockerFilesDropped
|
|
2809
|
+
} = runtime.consumeResolvedBlockerFiles((entry) => {
|
|
2810
|
+
if (unresolvedKeys.has(normalizeMapKey(path.resolve(entry.filePath))))
|
|
2811
|
+
return true;
|
|
2812
|
+
const cost = formatResolvedLine(entry).length + 1;
|
|
2813
|
+
if (resolvedCount > 0 && (resolvedCount >= resolvedLineBudget || resolvedChars + cost > resolvedCharBudget))
|
|
2814
|
+
return true;
|
|
2815
|
+
resolvedChars += cost;
|
|
2816
|
+
resolvedCount += 1;
|
|
2817
|
+
return false;
|
|
2818
|
+
});
|
|
2819
|
+
const resolvedLines = resolvedBlockerFileList.map(formatResolvedLine);
|
|
2820
|
+
if (resolvedBlockerFilesDropped > 0) {
|
|
2821
|
+
resolvedLines.push(formatResolvedTail(resolvedBlockerFilesDropped));
|
|
2822
|
+
}
|
|
2823
|
+
const resolvedParts = resolvedLines.length > 0 ? [resolvedLines.join(`
|
|
2824
|
+
`)] : [];
|
|
2825
|
+
const asIs = (raw) => ({ raw, text: raw });
|
|
2826
|
+
const composedParts = [
|
|
2827
|
+
...resolvedParts.map(asIs),
|
|
2828
|
+
...blockerParts.map(asIs),
|
|
2829
|
+
...staleSecretParts.map(asIs),
|
|
2830
|
+
...advisoryParts.map((raw) => ({
|
|
2831
|
+
raw,
|
|
2832
|
+
text: `ℹ️ Advisory — no action required this turn:
|
|
2833
|
+
${raw}`
|
|
2834
|
+
}))
|
|
2285
2835
|
];
|
|
2836
|
+
const findingParts = composedParts.map((part) => part.text);
|
|
2837
|
+
let heldSections = 0;
|
|
2286
2838
|
if (findingParts.length > 0) {
|
|
2287
2839
|
dbg(`turn_end: ${blockerParts.length} blocker section(s), ${advisoryParts.length} advisory section(s) found, persisting for next context`);
|
|
2288
|
-
const
|
|
2840
|
+
const joined = findingParts.join(`
|
|
2841
|
+
|
|
2842
|
+
`);
|
|
2843
|
+
const holdPlan = planDeliveryHolds({
|
|
2844
|
+
holds: deliveryHolds,
|
|
2845
|
+
parts: composedParts,
|
|
2846
|
+
keptChars: turnEndKeptChars(joined),
|
|
2847
|
+
separatorLength: `
|
|
2289
2848
|
|
|
2290
|
-
|
|
2849
|
+
`.length
|
|
2850
|
+
});
|
|
2851
|
+
const settleHolds = (suppressed) => {
|
|
2852
|
+
const outcome = holdPlan.settle({
|
|
2853
|
+
suppressed,
|
|
2854
|
+
isCurrentSession: () => holdScope.isCurrent(),
|
|
2855
|
+
onFault: (cause) => dbg(`turn_end: delivery hold failed: ${cause}`)
|
|
2856
|
+
});
|
|
2857
|
+
heldSections = outcome.held;
|
|
2858
|
+
if (lateAuxHoldRearmed + lateAuxHoldExpired + lateAuxHoldCeiling > 0) {
|
|
2859
|
+
logLatency({
|
|
2860
|
+
type: "phase",
|
|
2861
|
+
toolName: "turn_end",
|
|
2862
|
+
filePath: cwd,
|
|
2863
|
+
phase: "late_auxiliary_holds",
|
|
2864
|
+
durationMs: 0,
|
|
2865
|
+
metadata: {
|
|
2866
|
+
rearmed: lateAuxHoldRearmed,
|
|
2867
|
+
expired: lateAuxHoldExpired,
|
|
2868
|
+
ceilingExhausted: lateAuxHoldCeiling,
|
|
2869
|
+
pendingAfter: pendingAuxiliaryCoverageSize()
|
|
2870
|
+
}
|
|
2871
|
+
});
|
|
2872
|
+
}
|
|
2873
|
+
if (outcome.held > 0) {
|
|
2874
|
+
incrementDegradationCount({
|
|
2875
|
+
kind: "turn-end-sections-held",
|
|
2876
|
+
subject: "turn-end",
|
|
2877
|
+
reason: `${outcome.held} one-shot section(s) cut by the turn-end cap, kept pending for the next turn`
|
|
2878
|
+
});
|
|
2879
|
+
}
|
|
2880
|
+
};
|
|
2881
|
+
const content = capTurnEndMessage(joined, holdPlan.heldCount);
|
|
2291
2882
|
const signature = `${files.slice().sort((a, b) => compareOrdinal(a, b)).join("|")}::${content}`;
|
|
2292
2883
|
const last = cacheManager.readCache("turn-end-findings-last", cwd);
|
|
2293
|
-
if (last?.data?.signature === signature && last?.data?.sessionId === runtime.telemetrySessionId) {
|
|
2884
|
+
if (last?.data?.signature === signature && last?.data?.sessionId === runtime.telemetrySessionId && resolvedBlockerFileList.length === 0) {
|
|
2294
2885
|
dbg("turn_end: duplicate findings detected (same session), suppressing re-prompt");
|
|
2295
2886
|
if (getFlag("lens-guard")) {
|
|
2296
2887
|
const existingGuard = cacheManager.readCache("turn-end-findings", cwd)?.data;
|
|
@@ -2314,13 +2905,13 @@ ${p}`);
|
|
|
2314
2905
|
});
|
|
2315
2906
|
}
|
|
2316
2907
|
}
|
|
2908
|
+
settleHolds(true);
|
|
2317
2909
|
clearOwnedTurnState();
|
|
2318
2910
|
runtime.fixedThisTurn.clear();
|
|
2319
2911
|
resetFormatService();
|
|
2320
2912
|
return;
|
|
2321
2913
|
}
|
|
2322
|
-
|
|
2323
|
-
commit();
|
|
2914
|
+
settleHolds(false);
|
|
2324
2915
|
const fileSeqByPath = {};
|
|
2325
2916
|
for (const [filePath, seq] of runtime.getFileSeqEntries()) {
|
|
2326
2917
|
fileSeqByPath[normalizeMapKey(path.resolve(filePath))] = seq;
|
|
@@ -2394,7 +2985,7 @@ ${p}`);
|
|
|
2394
2985
|
}
|
|
2395
2986
|
if (blockerParts.length === 0) {
|
|
2396
2987
|
clearOwnedTurnState();
|
|
2397
|
-
if (getFlag("lens-guard") && advisoryParts.length === 0 && staleSecretParts.length === 0 && !runtime.gitGuardHasBlockers) {
|
|
2988
|
+
if (getFlag("lens-guard") && advisoryParts.length === 0 && staleSecretParts.length === 0 && resolvedParts.length === 0 && !runtime.gitGuardHasBlockers) {
|
|
2398
2989
|
const guardRecord = cacheManager.readCache("turn-end-findings", cwd)?.data;
|
|
2399
2990
|
if (guardRecord?.sessionId === runtime.telemetrySessionId && guardRecord.testFailures !== true) {
|
|
2400
2991
|
cacheManager.clearCache("turn-end-findings", cwd);
|
|
@@ -2402,8 +2993,8 @@ ${p}`);
|
|
|
2402
2993
|
}
|
|
2403
2994
|
}
|
|
2404
2995
|
runtime.fixedThisTurn.clear();
|
|
2405
|
-
runtime.clearActionableWarnings();
|
|
2406
|
-
runtime.clearCodeQualityWarnings();
|
|
2996
|
+
runtime.clearActionableWarnings(sessionId);
|
|
2997
|
+
runtime.clearCodeQualityWarnings(sessionId);
|
|
2407
2998
|
if (demotedFindingsRetired > 0) {
|
|
2408
2999
|
cacheManager.clearCache("turn-end-findings-last", cwd);
|
|
2409
3000
|
}
|
|
@@ -2418,6 +3009,9 @@ ${p}`);
|
|
|
2418
3009
|
blockerSections: blockerParts.length,
|
|
2419
3010
|
staleSecretSections: staleSecretParts.length,
|
|
2420
3011
|
advisorySections: advisoryParts.length,
|
|
3012
|
+
resolvedBlockerFiles: resolvedBlockerFileList.length,
|
|
3013
|
+
resolvedBlockerFilesDropped,
|
|
3014
|
+
heldSections,
|
|
2421
3015
|
demotedFindingsRetired,
|
|
2422
3016
|
widgetDemotedFindingsRetired
|
|
2423
3017
|
}
|