@herbertgao/pi-extensions 2026.8.4 → 2026.8.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 +5 -5
- package/node_modules/@herbertgao/pi-cc-extensions/README.en.md +11 -3
- package/node_modules/@herbertgao/pi-cc-extensions/README.md +11 -3
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/config/config.ts +24 -0
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/config/panel.ts +91 -1
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/feature/compact-thinking.ts +7 -3
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/feature/context.ts +74 -5
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/index.ts +7 -6
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/compact-mode.ts +21 -12
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/default-mode.ts +4 -5
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/markdown-enhance.ts +53 -14
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/tool/grouping.ts +22 -12
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/tool/result.ts +2 -4
- package/node_modules/@herbertgao/pi-cc-extensions/package.json +3 -3
- package/node_modules/@herbertgao/pi-subagents/CHANGELOG.md +18 -0
- package/node_modules/@herbertgao/pi-subagents/package.json +8 -4
- package/node_modules/@herbertgao/pi-subagents/src/agent-color.ts +72 -67
- package/node_modules/@herbertgao/pi-subagents/src/agent-file-toggle.ts +255 -0
- package/node_modules/@herbertgao/pi-subagents/src/agent-manager.ts +191 -3
- package/node_modules/@herbertgao/pi-subagents/src/agent-runner.ts +20 -4
- package/node_modules/@herbertgao/pi-subagents/src/index.ts +289 -113
- package/node_modules/@herbertgao/pi-subagents/src/output-file.ts +24 -1
- package/node_modules/@herbertgao/pi-subagents/src/ui/agent-widget.ts +24 -2
- package/node_modules/@herbertgao/pi-subagents/src/ui/fleet-list.ts +15 -6
- package/node_modules/@herbertgao/pi-subagents/src/ui/schedule-menu.ts +9 -8
- package/node_modules/@herbertgao/pi-subagents/src/ui/select-item.ts +48 -0
- package/node_modules/@herbertgao/pi-subagents/src/worktree.ts +9 -5
- package/node_modules/@juicesharp/rpiv-ask-user-question/README.md +2 -0
- package/node_modules/@juicesharp/rpiv-ask-user-question/ask-user-question.ts +20 -0
- package/node_modules/@juicesharp/rpiv-ask-user-question/docs/hosts.md +6 -0
- package/node_modules/@juicesharp/rpiv-ask-user-question/docs/keyboard.md +7 -0
- package/node_modules/@juicesharp/rpiv-ask-user-question/package.json +2 -2
- package/node_modules/@juicesharp/rpiv-ask-user-question/state/build-questionnaire.ts +7 -0
- package/node_modules/@juicesharp/rpiv-ask-user-question/state/key-router.ts +16 -5
- package/node_modules/@juicesharp/rpiv-ask-user-question/state/questionnaire-session.ts +4 -2
- package/node_modules/@narumitw/pi-btw/README.md +32 -24
- package/node_modules/@narumitw/pi-btw/package.json +6 -6
- package/node_modules/@narumitw/pi-btw/src/btw.ts +4 -2
- package/node_modules/@narumitw/pi-btw/src/menu.ts +34 -13
- package/node_modules/@narumitw/pi-btw/src/settings.ts +22 -2
- package/node_modules/pi-lens/CHANGELOG.md +2535 -954
- package/node_modules/pi-lens/README.md +13 -0
- package/node_modules/pi-lens/dist/clients/actionable-warnings.js +73 -18
- package/node_modules/pi-lens/dist/clients/advisory-provenance.js +314 -0
- package/node_modules/pi-lens/dist/clients/agent-behavior-client.js +21 -4
- package/node_modules/pi-lens/dist/clients/agent-nudge.js +14 -7
- package/node_modules/pi-lens/dist/clients/ast-grep-client.js +68 -16
- package/node_modules/pi-lens/dist/clients/ast-grep-types.js +0 -1
- package/node_modules/pi-lens/dist/clients/ast-grep-yaml-synth.js +37 -10
- package/node_modules/pi-lens/dist/clients/atomic-write-staging.js +63 -0
- package/node_modules/pi-lens/dist/clients/atomic-write.js +114 -14
- package/node_modules/pi-lens/dist/clients/bash-file-access.js +193 -23
- package/node_modules/pi-lens/dist/clients/biome-client.js +136 -24
- package/node_modules/pi-lens/dist/clients/bootstrap.js +11 -2
- package/node_modules/pi-lens/dist/clients/bounded-cache.js +34 -0
- package/node_modules/pi-lens/dist/clients/bounded-pid-file-lock.js +192 -0
- package/node_modules/pi-lens/dist/clients/bus-events-logger.js +62 -6
- package/node_modules/pi-lens/dist/clients/bus-publish.js +19 -4
- package/node_modules/pi-lens/dist/clients/cache/rule-cache.js +47 -5
- package/node_modules/pi-lens/dist/clients/cache-manager.js +97 -9
- package/node_modules/pi-lens/dist/clients/cache-observability.js +301 -14
- package/node_modules/pi-lens/dist/clients/call-graph.js +449 -117
- package/node_modules/pi-lens/dist/clients/cascade-format.js +57 -2
- package/node_modules/pi-lens/dist/clients/child-unref.js +85 -0
- package/node_modules/pi-lens/dist/clients/codebase-model.js +52 -23
- package/node_modules/pi-lens/dist/clients/collateral-test-role.js +40 -0
- package/node_modules/pi-lens/dist/clients/complexity-client.js +2 -1
- package/node_modules/pi-lens/dist/clients/console-guard-install.js +26 -0
- package/node_modules/pi-lens/dist/clients/cooperative-budget.js +42 -0
- package/node_modules/pi-lens/dist/clients/dead-code-client.js +137 -31
- package/node_modules/pi-lens/dist/clients/debug-handles.js +206 -0
- package/node_modules/pi-lens/dist/clients/debug-heap.js +167 -0
- package/node_modules/pi-lens/dist/clients/degradation-ledger.js +153 -0
- package/node_modules/pi-lens/dist/clients/dependency-checker.js +361 -77
- package/node_modules/pi-lens/dist/clients/diagnostic-dispositions.js +65 -13
- package/node_modules/pi-lens/dist/clients/diagnostics-publish.js +18 -4
- package/node_modules/pi-lens/dist/clients/dispatch/dispatcher.js +176 -29
- package/node_modules/pi-lens/dist/clients/dispatch/facts/function-facts.js +23 -7
- package/node_modules/pi-lens/dist/clients/dispatch/facts/import-facts.js +8 -18
- package/node_modules/pi-lens/dist/clients/dispatch/facts/tree-sitter-facts.js +8 -5
- package/node_modules/pi-lens/dist/clients/dispatch/indent-detect.js +35 -0
- package/node_modules/pi-lens/dist/clients/dispatch/inline-suppressions.js +17 -8
- package/node_modules/pi-lens/dist/clients/dispatch/integration.js +1172 -683
- package/node_modules/pi-lens/dist/clients/dispatch/lazy.js +14 -0
- package/node_modules/pi-lens/dist/clients/dispatch/plan.js +11 -1
- package/node_modules/pi-lens/dist/clients/dispatch/rule-id-normalize.js +50 -0
- package/node_modules/pi-lens/dist/clients/dispatch/rule-policy.js +135 -0
- package/node_modules/pi-lens/dist/clients/dispatch/runners/ast-grep-napi.js +23 -5
- package/node_modules/pi-lens/dist/clients/dispatch/runners/biome-check.js +5 -9
- package/node_modules/pi-lens/dist/clients/dispatch/runners/detekt.js +3 -2
- package/node_modules/pi-lens/dist/clients/dispatch/runners/hadolint.js +2 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/helm-lint.js +154 -0
- package/node_modules/pi-lens/dist/clients/dispatch/runners/htmlhint.js +3 -2
- package/node_modules/pi-lens/dist/clients/dispatch/runners/index.js +5 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/lsp.js +47 -6
- package/node_modules/pi-lens/dist/clients/dispatch/runners/markdownlint.js +4 -9
- package/node_modules/pi-lens/dist/clients/dispatch/runners/pyright.js +9 -5
- package/node_modules/pi-lens/dist/clients/dispatch/runners/ruff.js +4 -8
- package/node_modules/pi-lens/dist/clients/dispatch/runners/shellcheck.js +2 -3
- package/node_modules/pi-lens/dist/clients/dispatch/runners/shfmt.js +2 -3
- package/node_modules/pi-lens/dist/clients/dispatch/runners/spotbugs.js +2 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/taplo.js +2 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/terragrunt.js +163 -0
- package/node_modules/pi-lens/dist/clients/dispatch/runners/tflint.js +37 -5
- package/node_modules/pi-lens/dist/clients/dispatch/runners/tree-sitter.js +3 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/trivy-config.js +13 -7
- package/node_modules/pi-lens/dist/clients/dispatch/runners/utils/availability-policy.js +226 -0
- package/node_modules/pi-lens/dist/clients/dispatch/runners/utils/candidate-probe.js +69 -0
- package/node_modules/pi-lens/dist/clients/dispatch/runners/utils/lazy-installer.js +3 -0
- package/node_modules/pi-lens/dist/clients/dispatch/runners/utils/runner-helpers.js +473 -42
- package/node_modules/pi-lens/dist/clients/dispatch/runners/utils/spawn-outcome.js +22 -0
- package/node_modules/pi-lens/dist/clients/dispatch/runners/utils/toolchain-availability.js +97 -0
- package/node_modules/pi-lens/dist/clients/dispatch/runners/yaml-rule-parser.js +5 -4
- package/node_modules/pi-lens/dist/clients/disposition-publish.js +18 -4
- package/node_modules/pi-lens/dist/clients/durable-store.js +97 -0
- package/node_modules/pi-lens/dist/clients/eval-timestamp.js +17 -0
- package/node_modules/pi-lens/dist/clients/event-loop-monitor.js +94 -3
- package/node_modules/pi-lens/dist/clients/extension-log.js +432 -0
- package/node_modules/pi-lens/dist/clients/extension-mode.js +73 -0
- package/node_modules/pi-lens/dist/clients/file-kinds.js +57 -0
- package/node_modules/pi-lens/dist/clients/file-role.js +18 -3
- package/node_modules/pi-lens/dist/clients/file-utils.js +56 -34
- package/node_modules/pi-lens/dist/clients/fix-worklog.js +5 -1
- package/node_modules/pi-lens/dist/clients/format-events-publish.js +51 -7
- package/node_modules/pi-lens/dist/clients/format-service.js +24 -8
- package/node_modules/pi-lens/dist/clients/formatters-lazy.js +8 -0
- package/node_modules/pi-lens/dist/clients/formatters.js +358 -61
- package/node_modules/pi-lens/dist/clients/generated-artifacts.js +148 -15
- package/node_modules/pi-lens/dist/clients/git-guard.js +678 -11
- package/node_modules/pi-lens/dist/clients/git-tracked-ignore.js +4 -0
- package/node_modules/pi-lens/dist/clients/go-client.js +23 -40
- package/node_modules/pi-lens/dist/clients/govulncheck-client.js +124 -7
- package/node_modules/pi-lens/dist/clients/grammar-source.js +12 -4
- package/node_modules/pi-lens/dist/clients/gzip-stage-write.js +21 -3
- package/node_modules/pi-lens/dist/clients/host-ports.js +31 -0
- package/node_modules/pi-lens/dist/clients/installer/index.js +395 -100
- package/node_modules/pi-lens/dist/clients/instance-reaper.js +142 -172
- package/node_modules/pi-lens/dist/clients/jscpd-client.js +27 -55
- package/node_modules/pi-lens/dist/clients/knip-client.js +58 -42
- package/node_modules/pi-lens/dist/clients/language-policy.js +14 -2
- package/node_modules/pi-lens/dist/clients/language-profile.js +13 -7
- package/node_modules/pi-lens/dist/clients/latency-logger.js +72 -1
- package/node_modules/pi-lens/dist/clients/lens-config.js +12 -1
- package/node_modules/pi-lens/dist/clients/lens-engine.js +86 -17
- package/node_modules/pi-lens/dist/clients/lens-events.js +63 -9
- package/node_modules/pi-lens/dist/clients/lens-flag-registry.js +16 -0
- package/node_modules/pi-lens/dist/clients/lens-map.js +94 -19
- package/node_modules/pi-lens/dist/clients/live-bus-emitter.js +73 -0
- package/node_modules/pi-lens/dist/clients/log-cleanup.js +2 -1
- package/node_modules/pi-lens/dist/clients/lsp/aggregation.js +30 -4
- package/node_modules/pi-lens/dist/clients/lsp/cascade-tier.js +59 -14
- package/node_modules/pi-lens/dist/clients/lsp/client.js +662 -56
- package/node_modules/pi-lens/dist/clients/lsp/config.js +13 -2
- package/node_modules/pi-lens/dist/clients/lsp/diagnostic-binding.js +115 -0
- package/node_modules/pi-lens/dist/clients/lsp/edits.js +1012 -121
- package/node_modules/pi-lens/dist/clients/lsp/index.js +2025 -800
- package/node_modules/pi-lens/dist/clients/lsp/launch.js +32 -26
- package/node_modules/pi-lens/dist/clients/lsp/path-utils.js +1 -1
- package/node_modules/pi-lens/dist/clients/lsp/ruby-drive-dirs.js +83 -0
- package/node_modules/pi-lens/dist/clients/lsp/server.js +437 -86
- package/node_modules/pi-lens/dist/clients/lsp/tsserver-sync.js +96 -0
- package/node_modules/pi-lens/dist/clients/lsp/wait-policy/classification.js +21 -5
- package/node_modules/pi-lens/dist/clients/lsp/wait-policy/strategies.js +18 -3
- package/node_modules/pi-lens/dist/clients/lsp/workspace-diagnostics-cache.js +28 -4
- package/node_modules/pi-lens/dist/clients/lsp-lazy.js +8 -0
- package/node_modules/pi-lens/dist/clients/lsp-mutation.js +248 -0
- package/node_modules/pi-lens/dist/clients/mcp/analyze.js +127 -32
- package/node_modules/pi-lens/dist/clients/mcp/ipc.js +157 -24
- package/node_modules/pi-lens/dist/clients/mcp/session.js +235 -14
- package/node_modules/pi-lens/dist/clients/memory-sampler.js +115 -0
- package/node_modules/pi-lens/dist/clients/metrics-client.js +2 -1
- package/node_modules/pi-lens/dist/clients/metrics-history.js +2 -1
- package/node_modules/pi-lens/dist/clients/model-provider.js +53 -0
- package/node_modules/pi-lens/dist/clients/module-report-lsp.js +5 -0
- package/node_modules/pi-lens/dist/clients/module-report.js +168 -3
- package/node_modules/pi-lens/dist/clients/ndjson-logger.js +319 -118
- package/node_modules/pi-lens/dist/clients/opengrep-client.js +1 -1
- package/node_modules/pi-lens/dist/clients/partial-edit-apply.js +120 -5
- package/node_modules/pi-lens/dist/clients/path-utils.js +110 -9
- package/node_modules/pi-lens/dist/clients/pipeline.js +76 -15
- package/node_modules/pi-lens/dist/clients/print-mode.js +21 -0
- package/node_modules/pi-lens/dist/clients/project-changes.js +40 -0
- package/node_modules/pi-lens/dist/clients/project-diagnostics/cache.js +3 -2
- package/node_modules/pi-lens/dist/clients/project-diagnostics/fresh-fetch.js +1 -1
- package/node_modules/pi-lens/dist/clients/project-diagnostics/runner-adapters/call-graph-impact.js +8 -0
- package/node_modules/pi-lens/dist/clients/project-diagnostics/runner-adapters/runner-findings.js +23 -2
- package/node_modules/pi-lens/dist/clients/project-diagnostics/scanner.js +21 -1
- package/node_modules/pi-lens/dist/clients/project-lens-config.js +86 -9
- package/node_modules/pi-lens/dist/clients/project-report.js +27 -13
- package/node_modules/pi-lens/dist/clients/project-snapshot.js +175 -20
- package/node_modules/pi-lens/dist/clients/project-trust.js +181 -0
- package/node_modules/pi-lens/dist/clients/quiet-window.js +18 -4
- package/node_modules/pi-lens/dist/clients/read-bridge.js +147 -0
- package/node_modules/pi-lens/dist/clients/read-guard-logger.js +159 -1
- package/node_modules/pi-lens/dist/clients/read-guard-tool-lines.js +150 -29
- package/node_modules/pi-lens/dist/clients/read-guard.js +185 -4
- package/node_modules/pi-lens/dist/clients/resource-sampler.js +70 -84
- package/node_modules/pi-lens/dist/clients/review-graph/builder.js +1122 -221
- package/node_modules/pi-lens/dist/clients/review-graph/git-identity.js +2 -1
- package/node_modules/pi-lens/dist/clients/review-graph/import-resolvers.js +21 -10
- package/node_modules/pi-lens/dist/clients/review-graph/query.js +24 -0
- package/node_modules/pi-lens/dist/clients/review-graph/symbol-id.js +46 -0
- package/node_modules/pi-lens/dist/clients/review-graph/tsconfig-paths.js +57 -6
- package/node_modules/pi-lens/dist/clients/review-graph/workspace-modules.js +51 -3
- package/node_modules/pi-lens/dist/clients/review-graph-logger.js +30 -1
- package/node_modules/pi-lens/dist/clients/ruff-client.js +27 -44
- package/node_modules/pi-lens/dist/clients/run-duration.js +55 -0
- package/node_modules/pi-lens/dist/clients/runtime-agent-end.js +257 -77
- package/node_modules/pi-lens/dist/clients/runtime-context.js +129 -12
- package/node_modules/pi-lens/dist/clients/runtime-coordinator.js +242 -26
- package/node_modules/pi-lens/dist/clients/runtime-session.js +428 -117
- package/node_modules/pi-lens/dist/clients/runtime-tool-call.js +71 -48
- package/node_modules/pi-lens/dist/clients/runtime-tool-result.js +342 -33
- package/node_modules/pi-lens/dist/clients/runtime-turn.js +619 -93
- package/node_modules/pi-lens/dist/clients/rust-client.js +23 -38
- package/node_modules/pi-lens/dist/clients/safe-spawn.js +777 -62
- package/node_modules/pi-lens/dist/clients/security-scan-client.js +90 -6
- package/node_modules/pi-lens/dist/clients/session-state-store.js +3 -2
- package/node_modules/pi-lens/dist/clients/sg-runner.js +424 -196
- package/node_modules/pi-lens/dist/clients/slow-fs.js +2 -1
- package/node_modules/pi-lens/dist/clients/smells-rollup.js +231 -0
- package/node_modules/pi-lens/dist/clients/source-filter.js +184 -20
- package/node_modules/pi-lens/dist/clients/source-walker.js +66 -10
- package/node_modules/pi-lens/dist/clients/startup-scan.js +15 -16
- package/node_modules/pi-lens/dist/clients/startup-timing.js +7 -1
- package/node_modules/pi-lens/dist/clients/test-runner-client.js +469 -32
- package/node_modules/pi-lens/dist/clients/tool-event.js +35 -0
- package/node_modules/pi-lens/dist/clients/tool-policy.js +390 -39
- package/node_modules/pi-lens/dist/clients/tool-render.js +155 -0
- package/node_modules/pi-lens/dist/clients/tool-set-policy.js +76 -0
- package/node_modules/pi-lens/dist/clients/tree-sitter-cache.js +6 -1
- package/node_modules/pi-lens/dist/clients/tree-sitter-client.js +419 -50
- package/node_modules/pi-lens/dist/clients/tree-sitter-logger.js +21 -0
- package/node_modules/pi-lens/dist/clients/tree-sitter-query-loader.js +7 -1
- package/node_modules/pi-lens/dist/clients/tree-sitter-shared.js +7 -2
- package/node_modules/pi-lens/dist/clients/tree-sitter-symbol-extractor.js +44 -7
- package/node_modules/pi-lens/dist/clients/user-notify.js +51 -0
- package/node_modules/pi-lens/dist/clients/vanished-instance-marker.js +57 -0
- package/node_modules/pi-lens/dist/clients/warm-attach.js +50 -13
- package/node_modules/pi-lens/dist/clients/widget-state.js +300 -43
- package/node_modules/pi-lens/dist/clients/word-index.js +680 -81
- package/node_modules/pi-lens/dist/clients/workspace-topology.js +89 -6
- package/node_modules/pi-lens/dist/index.js +51785 -36118
- package/node_modules/pi-lens/dist/mcp/analyze-cli.js +182 -29
- package/node_modules/pi-lens/dist/mcp/server.js +219 -46
- package/node_modules/pi-lens/dist/tools/activate-tools.js +17 -5
- package/node_modules/pi-lens/dist/tools/ast-grep-replace.js +9 -4
- package/node_modules/pi-lens/dist/tools/ast-grep-search.js +93 -27
- package/node_modules/pi-lens/dist/tools/lens-diagnostic-mark.js +5 -2
- package/node_modules/pi-lens/dist/tools/lens-diagnostics.js +203 -38
- package/node_modules/pi-lens/dist/tools/lsp-diagnostics.js +210 -42
- package/node_modules/pi-lens/dist/tools/lsp-navigation.js +46 -3
- package/node_modules/pi-lens/dist/tools/module-report.js +9 -0
- package/node_modules/pi-lens/dist/tools/symbol-search.js +1 -1
- package/node_modules/pi-lens/docs/agent-guide.md +40 -15
- package/node_modules/pi-lens/docs/agent-tools.md +21 -10
- package/node_modules/pi-lens/docs/analysisall.md +192 -0
- package/node_modules/pi-lens/docs/api-ports-inventory.md +165 -0
- package/node_modules/pi-lens/docs/ast-grep_rules_catalog.md +14 -3
- package/node_modules/pi-lens/docs/durable-store-audit-1202.md +32 -0
- package/node_modules/pi-lens/docs/environment-variables.md +44 -0
- package/node_modules/pi-lens/docs/fable.md +27 -0
- package/node_modules/pi-lens/docs/features.md +45 -3
- package/node_modules/pi-lens/docs/globalconfig.md +56 -1
- package/node_modules/pi-lens/docs/language-coverage.md +4 -3
- package/node_modules/pi-lens/docs/lsp-capability-matrix.md +2 -2
- package/node_modules/pi-lens/docs/mcp.md +37 -4
- package/node_modules/pi-lens/docs/servercapabilities.md +3 -3
- package/node_modules/pi-lens/docs/settings.md +18 -1
- package/node_modules/pi-lens/docs/tools.md +4 -1
- package/node_modules/pi-lens/docs/usage.md +41 -5
- package/node_modules/pi-lens/docs/word-index.md +35 -0
- package/node_modules/pi-lens/package.json +10 -10
- package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-bare-except-test.yml +49 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-bare-host-path-in-win32-branch-test.yml +87 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-chained-type-assertions-test.yml +8 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-conditional-empty-object-spread-js-test.yml +9 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-conditional-empty-object-spread-test.yml +9 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-nested-links-test.yml +11 -1
- package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-raw-json-store-write-test.yml +17 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-reflect-apply-js-test.yml +7 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-reflect-apply-test.yml +7 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-reflect-get-js-test.yml +8 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-reflect-get-test.yml +8 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-unknown-laundering-test.yml +11 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-win32-isabsolute-for-qualification-test.yml +16 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-bare-except.yml +3 -15
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-bare-host-path-in-win32-branch.yml +25 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-chained-type-assertions.yml +21 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-conditional-empty-object-spread-js.yml +21 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-conditional-empty-object-spread.yml +29 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-nested-links.yml +7 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-raw-json-store-write.yml +30 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-reflect-apply-js.yml +9 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-reflect-apply.yml +9 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-reflect-get-js.yml +13 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-reflect-get.yml +16 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-unknown-laundering.yml +27 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-win32-isabsolute-for-qualification.yml +23 -0
- package/node_modules/pi-lens/rules/tree-sitter-queries/tsx/no-nested-links.yml +4 -6
- package/node_modules/pi-lens/rules/tree-sitter-queries/typescript/duplicate-function-arg.yml +2 -2
- package/node_modules/pi-lens/scripts/analyze-pi-lens-logs.mjs +134 -2
- package/node_modules/pi-lens/skills/pi-lens-ast-grep/SKILL.md +10 -11
- package/node_modules/pi-lens/skills/pi-lens-lsp-navigation/SKILL.md +22 -22
- package/node_modules/pi-lens/skills/pi-lens-write-ast-grep-rule/SKILL.md +8 -114
- package/node_modules/pi-lens/skills/pi-lens-write-ast-grep-rule/reference.md +129 -0
- package/node_modules/pi-lens/skills/pi-lens-write-tree-sitter-rule/SKILL.md +3 -1
- package/node_modules/pi-mcp-adapter/CHANGELOG.md +38 -0
- package/node_modules/pi-mcp-adapter/README.md +38 -4
- package/node_modules/pi-mcp-adapter/agent-dir.ts +12 -4
- package/node_modules/pi-mcp-adapter/agent-plugin-loader.ts +1 -1
- package/node_modules/pi-mcp-adapter/cli.js +25 -4
- package/node_modules/pi-mcp-adapter/commands.ts +15 -7
- package/node_modules/pi-mcp-adapter/config.ts +4 -4
- package/node_modules/pi-mcp-adapter/direct-tools.ts +58 -8
- package/node_modules/pi-mcp-adapter/host-html-template.ts +0 -8
- package/node_modules/pi-mcp-adapter/index.ts +8 -3
- package/node_modules/pi-mcp-adapter/init.ts +29 -5
- package/node_modules/pi-mcp-adapter/lifecycle.ts +0 -4
- package/node_modules/pi-mcp-adapter/mcp-auth-flow.ts +1 -2
- package/node_modules/pi-mcp-adapter/mcp-auth.ts +60 -2
- package/node_modules/pi-mcp-adapter/mcp-panel.ts +45 -9
- package/node_modules/pi-mcp-adapter/mcp-script-worker.mjs +22 -20
- package/node_modules/pi-mcp-adapter/mcp-setup-panel.ts +2 -1
- package/node_modules/pi-mcp-adapter/metadata-cache.ts +37 -4
- package/node_modules/pi-mcp-adapter/npx-resolver.ts +81 -26
- package/node_modules/pi-mcp-adapter/package.json +4 -3
- package/node_modules/pi-mcp-adapter/proxy-modes.ts +108 -26
- package/node_modules/pi-mcp-adapter/request-headers-command.ts +336 -0
- package/node_modules/pi-mcp-adapter/search-ranking.ts +86 -7
- package/node_modules/pi-mcp-adapter/server-manager.ts +41 -7
- package/node_modules/pi-mcp-adapter/session-recovery.ts +8 -2
- package/node_modules/pi-mcp-adapter/tool-approval.ts +48 -7
- package/node_modules/pi-mcp-adapter/tool-metadata.ts +62 -4
- package/node_modules/pi-mcp-adapter/tool-result-renderer.ts +138 -12
- package/node_modules/pi-mcp-adapter/types.ts +176 -27
- package/node_modules/pi-mcp-adapter/ui-server.ts +20 -1
- package/node_modules/pi-web-access/CHANGELOG.md +14 -0
- package/node_modules/pi-web-access/README.md +18 -12
- package/node_modules/pi-web-access/auth-fetch.ts +148 -0
- package/node_modules/pi-web-access/chrome-cookies.ts +110 -23
- package/node_modules/pi-web-access/curator-page.ts +5 -3
- package/node_modules/pi-web-access/curator-server.ts +2 -1
- package/node_modules/pi-web-access/extract.ts +106 -34
- package/node_modules/pi-web-access/fetch-params.ts +17 -3
- package/node_modules/pi-web-access/firecrawl.ts +172 -12
- package/node_modules/pi-web-access/gemini-search.ts +18 -4
- package/node_modules/pi-web-access/index.ts +120 -48
- package/node_modules/pi-web-access/package.json +2 -2
- package/node_modules/pi-web-access/summary-review.ts +11 -5
- package/node_modules/pi-web-access/youtube-extract.ts +2 -2
- package/package.json +12 -13
- package/node_modules/pi-lens/dist/clients/ast-grep-parser.js +0 -86
- package/node_modules/pi-lens/dist/clients/lsp/interactive-install.js +0 -367
- package/node_modules/pi-lens/dist/clients/lsp/lsp-index.js +0 -10
- package/node_modules/pi-lens/dist/clients/lsp/server-strategies.js +0 -5
- package/node_modules/pi-lens/dist/clients/project-metadata.js +0 -690
- package/node_modules/pi-lens/dist/clients/source-groups.js +0 -96
- package/node_modules/pi-lens/dist/clients/startup-marker.js +0 -6
- package/node_modules/pi-lens/dist/clients/types.js +0 -11
|
@@ -13,14 +13,63 @@
|
|
|
13
13
|
import { existsSync, realpathSync } from "node:fs";
|
|
14
14
|
import * as os from "node:os";
|
|
15
15
|
import * as path from "node:path";
|
|
16
|
-
import {
|
|
16
|
+
import { win32 } from "node:path";
|
|
17
17
|
import { fileURLToPath, pathToFileURL } from "node:url";
|
|
18
18
|
import { minimatch } from "./deps/minimatch.js";
|
|
19
19
|
/**
|
|
20
|
-
* Detect
|
|
20
|
+
* Detect a positively Windows-shaped path, regardless of the host OS.
|
|
21
|
+
*
|
|
22
|
+
* A backslash anywhere in a path is not enough: it is a legal character in a
|
|
23
|
+
* POSIX filename. Only a drive-letter prefix (`X:`), a UNC root (`\\`), or a
|
|
24
|
+
* rooted backslash at position zero (`\`) selects Windows parsing.
|
|
25
|
+
*/
|
|
26
|
+
export function isWindowsPath(filePath) {
|
|
27
|
+
return /^[A-Za-z]:/.test(filePath) || filePath.startsWith("\\");
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Canonical backslash→forward-slash fold — the single sanctioned form of the
|
|
31
|
+
* `p.replace(/\\/g, "/")` idiom otherwise hand-rolled across the codebase
|
|
32
|
+
* (~138 sites, #1193). PURE separator normalization: it does NOT resolve,
|
|
33
|
+
* canonicalize, lowercase, or collapse repeated slashes — reach for
|
|
34
|
+
* `normalizeFilePath`/`normalizeMapKey`/`normalizeEphemeralMapKey` when a
|
|
35
|
+
* canonical map *key* (case-fold / realpath) is what you need. Consolidating on
|
|
36
|
+
* this funnels the scattered transform and makes a shape-2 lint/ast-grep rule
|
|
37
|
+
* possible for the first time: today a bare inline `.replace(/\\/g, "/")` is
|
|
38
|
+
* byte-identical to the sanctioned use so it can't be ruled (#1158); once
|
|
39
|
+
* everything routes through `toPosix`, an *un-migrated* inline `.replace`
|
|
40
|
+
* becomes detectable.
|
|
41
|
+
*/
|
|
42
|
+
export function toPosix(filePath) {
|
|
43
|
+
return filePath.replace(/\\/g, "/");
|
|
44
|
+
}
|
|
45
|
+
/** Return whether `filePath` is fully qualified under Windows semantics. */
|
|
46
|
+
export function isFullyQualifiedWin32(filePath) {
|
|
47
|
+
return win32.isAbsolute(filePath) && win32.parse(filePath).root.length > 1;
|
|
48
|
+
}
|
|
49
|
+
/** Return whether `filePath` is fully qualified under POSIX semantics. */
|
|
50
|
+
export function isFullyQualifiedPosix(filePath) {
|
|
51
|
+
return path.posix.isAbsolute(filePath) && !isWindowsPath(filePath);
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Return whether `filePath` is fully qualified under the host's semantics.
|
|
55
|
+
*
|
|
56
|
+
* In particular, `/foo` is rooted-relative under Win32 (ambient-drive
|
|
57
|
+
* dependent) but fully qualified under POSIX.
|
|
58
|
+
*/
|
|
59
|
+
export function isFullyQualified(filePath) {
|
|
60
|
+
return process.platform === "win32"
|
|
61
|
+
? isFullyQualifiedWin32(filePath)
|
|
62
|
+
: isFullyQualifiedPosix(filePath);
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Split a path into its non-empty segments on EITHER separator (`\` or `/`),
|
|
66
|
+
* regardless of the running OS — the shape-safe form of `p.split(path.sep)` /
|
|
67
|
+
* an inline `p.split(/[\\/]+/)`, which #1161/#1163 showed must not assume the
|
|
68
|
+
* host separator for a possibly-cross-shaped path. Drops empty segments
|
|
69
|
+
* (leading slash, drive-root, doubled separators).
|
|
21
70
|
*/
|
|
22
|
-
function
|
|
23
|
-
return
|
|
71
|
+
export function splitPathSegments(filePath) {
|
|
72
|
+
return filePath.split(/[\\/]+/).filter(Boolean);
|
|
24
73
|
}
|
|
25
74
|
/**
|
|
26
75
|
* Normalize a file path for consistent Map key usage.
|
|
@@ -87,7 +136,15 @@ function resolveNonExisting(filePath) {
|
|
|
87
136
|
const base = canonical.replace(/\\/g, "/");
|
|
88
137
|
return base.endsWith("/") ? base + tail : `${base}/${tail}`;
|
|
89
138
|
}
|
|
90
|
-
|
|
139
|
+
// Use win32.dirname (not the platform-default dirname) so a
|
|
140
|
+
// Windows-shaped path is parsed with win32 semantics regardless of the
|
|
141
|
+
// running OS — consistent with the win32.resolve/win32.normalize this
|
|
142
|
+
// branch already commits to. The platform-default POSIX dirname would
|
|
143
|
+
// find no separator in a win32-resolved "C:\repo\..." path (its only
|
|
144
|
+
// separators are backslashes), collapse to ".", stop the upward walk at
|
|
145
|
+
// cwd, and mangle the key on Linux CI (refs #1150, the #1024
|
|
146
|
+
// OS-divergence class).
|
|
147
|
+
const parent = win32.dirname(current);
|
|
91
148
|
if (parent === current) {
|
|
92
149
|
// Reached filesystem root without finding existing dir
|
|
93
150
|
// Fall back to full lowercase
|
|
@@ -111,6 +168,29 @@ export function uriToPath(uri) {
|
|
|
111
168
|
return normalizeFilePath(uri);
|
|
112
169
|
}
|
|
113
170
|
}
|
|
171
|
+
/**
|
|
172
|
+
* Decode a file:// URI to an on-disk path WITHOUT map-key normalization.
|
|
173
|
+
*
|
|
174
|
+
* `uriToPath` runs its result through `normalizeFilePath`, which on win32
|
|
175
|
+
* lowercases the nonexistent tail of a path (see `resolveNonExisting`) and
|
|
176
|
+
* canonicalizes an existing path to its real casing. That is correct for Map
|
|
177
|
+
* keys, but DESTRUCTIVE for a real create/rename target: creating `NewFile.txt`
|
|
178
|
+
* would write `newfile.txt`, and a legitimate case-only rename would collapse
|
|
179
|
+
* to a no-op ("source and destination must differ"). Disk mutations must honor
|
|
180
|
+
* the caller's intended casing, so they resolve their target through this
|
|
181
|
+
* decode-only path while confinement/validation keep using the normalized
|
|
182
|
+
* `uriToPath`. Non-win32 is unaffected either way (normalizeFilePath is a
|
|
183
|
+
* near-identity there).
|
|
184
|
+
*/
|
|
185
|
+
export function uriToDiskPath(uri) {
|
|
186
|
+
try {
|
|
187
|
+
return fileURLToPath(uri);
|
|
188
|
+
}
|
|
189
|
+
catch {
|
|
190
|
+
// Not a valid file:// URI — treat as a plain path (matches uriToPath).
|
|
191
|
+
return uri;
|
|
192
|
+
}
|
|
193
|
+
}
|
|
114
194
|
/**
|
|
115
195
|
* Convert a path to a file:// URI.
|
|
116
196
|
* Does NOT normalize the path - URIs preserve original casing.
|
|
@@ -125,12 +205,28 @@ export function pathToUri(filePath) {
|
|
|
125
205
|
export function normalizeMapKey(filePath) {
|
|
126
206
|
return normalizeFilePath(filePath);
|
|
127
207
|
}
|
|
128
|
-
/**
|
|
208
|
+
/**
|
|
209
|
+
* Human-facing path relative to a project root when the file is inside it.
|
|
210
|
+
*
|
|
211
|
+
* Parses by path SHAPE, not host OS (refs #1150/#1152, shape-2 class #1163):
|
|
212
|
+
* a Windows-shaped `filePath` (drive-letter/UNC — e.g. a persisted call-graph
|
|
213
|
+
* symbol-key path `C:\repo\src\x.ts` rehydrated on a Linux CI run) is split
|
|
214
|
+
* with `win32.*` regardless of `process.platform`. The host-default
|
|
215
|
+
* `isAbsolute`/`relative` find no drive-letter anchor in a win32 path on POSIX:
|
|
216
|
+
* `path.isAbsolute("C:\\repo\\x.ts")` returns FALSE on Linux, short-circuiting
|
|
217
|
+
* to the raw absolute path instead of ever relativizing it — so a file that IS
|
|
218
|
+
* under the project root renders as a full absolute path on Linux but the
|
|
219
|
+
* expected `src/x.ts` on Windows (green-locally / wrong-on-CI, the #1024
|
|
220
|
+
* divergence class). `win32.*` on a native POSIX path (Windows never sees one;
|
|
221
|
+
* Linux native paths aren't Windows-shaped) is never selected, so same-OS
|
|
222
|
+
* native paths are unchanged either way.
|
|
223
|
+
*/
|
|
129
224
|
export function toProjectRelativePath(filePath, projectRoot) {
|
|
130
|
-
|
|
225
|
+
const p = isWindowsPath(filePath) ? win32 : path;
|
|
226
|
+
if (!p.isAbsolute(filePath))
|
|
131
227
|
return filePath.replace(/\\/g, "/");
|
|
132
|
-
const relative =
|
|
133
|
-
return relative && !relative.startsWith("..") && !
|
|
228
|
+
const relative = p.relative(p.resolve(projectRoot), filePath);
|
|
229
|
+
return relative && !relative.startsWith("..") && !p.isAbsolute(relative)
|
|
134
230
|
? relative.replace(/\\/g, "/")
|
|
135
231
|
: filePath.replace(/\\/g, "/");
|
|
136
232
|
}
|
|
@@ -156,6 +252,11 @@ export function toProjectRelativePath(filePath, projectRoot) {
|
|
|
156
252
|
* real-casing resolution actually matters.
|
|
157
253
|
*/
|
|
158
254
|
export function normalizeEphemeralMapKey(filePath) {
|
|
255
|
+
// Most hot-path keys on POSIX are already canonical slash-separated strings.
|
|
256
|
+
// Preserve that identity instead of allocating a replacement string for each
|
|
257
|
+
// file in a large diagnostics reconciliation.
|
|
258
|
+
if (process.platform !== "win32" && !filePath.includes("\\"))
|
|
259
|
+
return filePath;
|
|
159
260
|
const slashed = filePath.replace(/\\/g, "/");
|
|
160
261
|
return process.platform === "win32" ? slashed.toLowerCase() : slashed;
|
|
161
262
|
}
|
|
@@ -19,7 +19,7 @@ import { recordFromCodeQualityDiagnostic, } from "./code-quality-warnings.js";
|
|
|
19
19
|
import { recordDiagnostics } from "./widget-state.js";
|
|
20
20
|
import { getDiagnosticLogger } from "./diagnostic-logger.js";
|
|
21
21
|
import { getDiagnosticTracker } from "./diagnostic-tracker.js";
|
|
22
|
-
import {
|
|
22
|
+
import { loadDispatchIntegration } from "./dispatch/lazy.js";
|
|
23
23
|
import { toRunnerDisplayPath } from "./dispatch/runner-context.js";
|
|
24
24
|
import { createAvailabilityChecker, resolveAvailableOrInstall, resolveCommandArgsWithInstallFallback, resolveToolCommand, resolveToolCommandWithInstallFallback, } from "./dispatch/runners/utils/runner-helpers.js";
|
|
25
25
|
import { findDetektConfig } from "./dispatch/runners/detekt.js";
|
|
@@ -29,12 +29,14 @@ import { logLatency } from "./latency-logger.js";
|
|
|
29
29
|
import { emitLensAnalysisComplete } from "./lens-events.js";
|
|
30
30
|
import { publishFilesTouched } from "./bus-publish.js";
|
|
31
31
|
import { publishDiagnostics, wasPreviouslyReportedDirty, } from "./diagnostics-publish.js";
|
|
32
|
-
import {
|
|
32
|
+
import { loadLspService } from "./lsp-lazy.js";
|
|
33
33
|
import { clearGraphCache } from "./review-graph/builder.js";
|
|
34
|
+
import { BoundedLruCache } from "./bounded-cache.js";
|
|
34
35
|
import { RUNTIME_CONFIG } from "./runtime-config.js";
|
|
35
36
|
import { getAmbientAbortSignal, safeSpawnAsync } from "./safe-spawn.js";
|
|
36
37
|
import { combineAbortSignals } from "./deadline-utils.js";
|
|
37
|
-
import {
|
|
38
|
+
import { recordDegradationOnce } from "./degradation-ledger.js";
|
|
39
|
+
import { getAutofixPolicyForFile, getPreferredAutofixTools, getRubocopCommand, hasBiomeConfig, hasDetektConfig, hasEslintConfig, hasGolangciConfig, hasKtfmtConfig, hasKtlintConfig, hasOxlintConfig, hasRubocopConfig, hasSqlfluffConfig, hasStylelintConfig, markdownlintConfigArgs, } from "./tool-policy.js";
|
|
38
40
|
const LSP_MAX_FILE_BYTES = RUNTIME_CONFIG.pipeline.lspMaxFileBytes;
|
|
39
41
|
const LSP_MAX_FILE_LINES = RUNTIME_CONFIG.pipeline.lspMaxFileLines;
|
|
40
42
|
const LSP_SPAWN_BUDGET_MS = RUNTIME_CONFIG.pipeline.lspSpawnBudgetMs;
|
|
@@ -66,7 +68,10 @@ const SNAPSHOT_YIELD_EVERY = 500;
|
|
|
66
68
|
async function snapshotDirInto(dir, ignoreMatcher, stack, snapshot, counter) {
|
|
67
69
|
let entries;
|
|
68
70
|
try {
|
|
69
|
-
|
|
71
|
+
// Async (#1137): a synchronous per-directory read blocks the loop for the
|
|
72
|
+
// whole stall on a slow cloud-backed (OneDrive) directory; fs.promises
|
|
73
|
+
// keeps this tool_result-path walk off the event loop.
|
|
74
|
+
entries = await nodeFs.promises.readdir(dir, { withFileTypes: true });
|
|
70
75
|
}
|
|
71
76
|
catch {
|
|
72
77
|
return;
|
|
@@ -85,7 +90,7 @@ async function snapshotDirInto(dir, ignoreMatcher, stack, snapshot, counter) {
|
|
|
85
90
|
if (ignoreMatcher.isIgnored(fullPath, false))
|
|
86
91
|
continue;
|
|
87
92
|
try {
|
|
88
|
-
const stat = nodeFs.
|
|
93
|
+
const stat = await nodeFs.promises.stat(fullPath);
|
|
89
94
|
snapshot.set(path.resolve(fullPath), {
|
|
90
95
|
mtimeMs: stat.mtimeMs,
|
|
91
96
|
size: stat.size,
|
|
@@ -173,7 +178,7 @@ function createPhaseTracker(toolName, filePath) {
|
|
|
173
178
|
}
|
|
174
179
|
// --- ESLint autofix helpers ---
|
|
175
180
|
export { hasEslintConfig, hasRubocopConfig, hasSqlfluffConfig, hasStylelintConfig, };
|
|
176
|
-
const _eslintCache = new
|
|
181
|
+
const _eslintCache = new BoundedLruCache(32);
|
|
177
182
|
/**
|
|
178
183
|
* Run eslint --fix on a file. Runs a single spawn and diffs the file before/after,
|
|
179
184
|
* same idiom as the other autofix helpers below. Exit code 1 (unfixable problems
|
|
@@ -186,7 +191,9 @@ async function tryEslintFix(filePath, cwd) {
|
|
|
186
191
|
const userHasConfig = hasEslintConfig(cwd);
|
|
187
192
|
if (!userHasConfig)
|
|
188
193
|
return 0;
|
|
189
|
-
|
|
194
|
+
// PATH is part of command resolution; include it so an install or PATH
|
|
195
|
+
// refresh cannot leave a negative eslint result live for the session.
|
|
196
|
+
const cacheKey = `${path.resolve(cwd)}|${process.env.PATH ?? ""}`;
|
|
190
197
|
let cached = _eslintCache.get(cacheKey);
|
|
191
198
|
if (!cached) {
|
|
192
199
|
const candidate = resolveToolCommand(cwd, "eslint") ?? "eslint";
|
|
@@ -274,8 +281,12 @@ async function tryMarkdownlintFix(filePath, cwd) {
|
|
|
274
281
|
const cmd = await resolveToolCommandWithInstallFallback(cwd, "markdownlint");
|
|
275
282
|
if (!cmd)
|
|
276
283
|
return 0;
|
|
284
|
+
// Shared config-args seam (#1247): the lint runner consumes the same
|
|
285
|
+
// builder, so the bare --fix here can never fall back to markdownlint's
|
|
286
|
+
// default all-rules-on config again (the whole-file CHANGELOG/AGENTS
|
|
287
|
+
// reformat + `#946` → `# 946` corruption).
|
|
277
288
|
// markdownlint-cli2 --fix exits non-zero when unfixable violations remain.
|
|
278
|
-
return detectFileChangedAfterCommand(filePath, cmd, ["--fix", filePath], cwd, [1]);
|
|
289
|
+
return detectFileChangedAfterCommand(filePath, cmd, [...markdownlintConfigArgs(cwd), "--fix", filePath], cwd, [1]);
|
|
279
290
|
}
|
|
280
291
|
async function tryOxlintFix(filePath, cwd) {
|
|
281
292
|
const cmd = await resolveToolCommandWithInstallFallback(cwd, "oxlint");
|
|
@@ -356,6 +367,7 @@ export async function runAutofix(filePath, cwd, getFlag, dbg, deps, getFlagSourc
|
|
|
356
367
|
hasGolangciConfig: hasGolangciConfig(cwd),
|
|
357
368
|
hasDetektConfig: hasDetektConfig(cwd),
|
|
358
369
|
hasKtfmtConfig: hasKtfmtConfig(cwd),
|
|
370
|
+
hasKtlintConfig: hasKtlintConfig(cwd),
|
|
359
371
|
hasOxlintConfig: hasOxlintConfig(cwd),
|
|
360
372
|
};
|
|
361
373
|
const autofixPolicy = getAutofixPolicyForFile(filePath, autofixContext);
|
|
@@ -396,7 +408,7 @@ export async function runAutofix(filePath, cwd, getFlag, dbg, deps, getFlagSourc
|
|
|
396
408
|
dbg(`autofix: ruff unavailable for ${filePath}`);
|
|
397
409
|
continue;
|
|
398
410
|
}
|
|
399
|
-
const result = await ruffClient.fixFileAsync(filePath);
|
|
411
|
+
const result = await ruffClient.fixFileAsync(filePath, cwd);
|
|
400
412
|
if (result.success && result.fixed > 0) {
|
|
401
413
|
fixedCount += result.fixed;
|
|
402
414
|
autofixTools.push(`ruff:${result.fixed}`);
|
|
@@ -415,7 +427,7 @@ export async function runAutofix(filePath, cwd, getFlag, dbg, deps, getFlagSourc
|
|
|
415
427
|
dbg(`autofix: biome unavailable or unsupported for ${filePath}`);
|
|
416
428
|
continue;
|
|
417
429
|
}
|
|
418
|
-
const result = await biomeClient.fixFileAsync(filePath);
|
|
430
|
+
const result = await biomeClient.fixFileAsync(filePath, cwd);
|
|
419
431
|
if (result.success && result.fixed > 0) {
|
|
420
432
|
fixedCount += result.fixed;
|
|
421
433
|
autofixTools.push(`biome:${result.fixed}`);
|
|
@@ -570,7 +582,6 @@ export async function runAutofix(filePath, cwd, getFlag, dbg, deps, getFlagSourc
|
|
|
570
582
|
dbg(`autofix: oxlint --fix fixed ${filePath}`);
|
|
571
583
|
needsContentRefresh = true;
|
|
572
584
|
}
|
|
573
|
-
continue;
|
|
574
585
|
}
|
|
575
586
|
}
|
|
576
587
|
if (attemptedTools.length > 0 && autofixTools.length === 0) {
|
|
@@ -593,7 +604,7 @@ export async function resyncLspFile(filePath, fileContent, needsContentRefresh,
|
|
|
593
604
|
if (limitCheck.tooLarge)
|
|
594
605
|
return;
|
|
595
606
|
try {
|
|
596
|
-
const lspService = getLSPService();
|
|
607
|
+
const lspService = (await loadLspService()).getLSPService();
|
|
597
608
|
if (lspService.supportsLSP(filePath)) {
|
|
598
609
|
// Push the final post-format/post-fix content through touchFile (not the
|
|
599
610
|
// bare openFile) so it registers in the touch-debounce map via
|
|
@@ -704,6 +715,13 @@ export async function runFormatPhase(filePath, getFormatService, dbg) {
|
|
|
704
715
|
}
|
|
705
716
|
if (!result.allSucceeded) {
|
|
706
717
|
const failures = result.formatters.filter((f) => !f.success);
|
|
718
|
+
for (const failure of failures) {
|
|
719
|
+
recordDegradationOnce({
|
|
720
|
+
kind: "formatter-failure",
|
|
721
|
+
subject: `${failure.name}:${path.basename(filePath)}`,
|
|
722
|
+
reason: failure.error ?? "unknown error",
|
|
723
|
+
});
|
|
724
|
+
}
|
|
707
725
|
formatFailures.push(...failures.map((f) => `${f.name}: ${f.error ?? "unknown error"}`));
|
|
708
726
|
dbg("autoformat: " +
|
|
709
727
|
failures
|
|
@@ -713,6 +731,11 @@ export async function runFormatPhase(filePath, getFormatService, dbg) {
|
|
|
713
731
|
}
|
|
714
732
|
catch (err) {
|
|
715
733
|
const message = err instanceof Error ? err.message : String(err);
|
|
734
|
+
recordDegradationOnce({
|
|
735
|
+
kind: "formatter-failure",
|
|
736
|
+
subject: `format-service:${path.basename(filePath)}`,
|
|
737
|
+
reason: message,
|
|
738
|
+
});
|
|
716
739
|
formatFailures.push(message);
|
|
717
740
|
dbg(`autoformat error: ${err}`);
|
|
718
741
|
}
|
|
@@ -820,7 +843,25 @@ export async function runPipeline(ctx, deps) {
|
|
|
820
843
|
});
|
|
821
844
|
// --- 3. Auto-fix ---
|
|
822
845
|
phase.start("autofix");
|
|
823
|
-
|
|
846
|
+
let fixedCount = 0;
|
|
847
|
+
let autofixTools = [];
|
|
848
|
+
let attemptedTools = [];
|
|
849
|
+
let autofixChangedFiles = [];
|
|
850
|
+
let fixRefresh = false;
|
|
851
|
+
let autofixSkipReason;
|
|
852
|
+
if (ctx.autofixMode === "deferred") {
|
|
853
|
+
autofixSkipReason = "deferred_to_agent_end";
|
|
854
|
+
dbg(`autofix: deferred until agent_end for ${filePath}`);
|
|
855
|
+
}
|
|
856
|
+
else
|
|
857
|
+
({
|
|
858
|
+
fixedCount,
|
|
859
|
+
autofixTools,
|
|
860
|
+
attemptedTools,
|
|
861
|
+
changedFiles: autofixChangedFiles,
|
|
862
|
+
needsContentRefresh: fixRefresh,
|
|
863
|
+
skipReason: autofixSkipReason,
|
|
864
|
+
} = await runAutofix(filePath, cwd, getFlag, dbg, deps, getFlagSource));
|
|
824
865
|
for (const changedFile of autofixChangedFiles) {
|
|
825
866
|
piChangedFiles.add(path.resolve(changedFile));
|
|
826
867
|
}
|
|
@@ -871,11 +912,17 @@ export async function runPipeline(ctx, deps) {
|
|
|
871
912
|
const piApi = {
|
|
872
913
|
getFlag: getFlag,
|
|
873
914
|
};
|
|
915
|
+
const { dispatchLintWithResult, computeCascadeForFile } = await loadDispatchIntegration();
|
|
874
916
|
const dispatchResult = await dispatchLintWithResult(filePath, cwd, piApi, ctx.modifiedRanges, {
|
|
875
917
|
model: ctx.telemetry?.model ?? "unknown",
|
|
876
918
|
sessionId: ctx.telemetry?.sessionId ?? "unknown",
|
|
877
919
|
turnIndex: ctx.telemetry?.turnIndex ?? 0,
|
|
878
920
|
writeIndex: ctx.telemetry?.writeIndex ?? 0,
|
|
921
|
+
}, {
|
|
922
|
+
projectRoot: ctx.projectRoot,
|
|
923
|
+
writeIndex: ctx.telemetry?.writeIndex,
|
|
924
|
+
telemetryModel: ctx.telemetry?.modelId,
|
|
925
|
+
telemetryProvider: ctx.telemetry?.provider,
|
|
879
926
|
});
|
|
880
927
|
recordDiagnostics(filePath, dispatchResult.diagnostics, ctx.telemetry?.writeIndex);
|
|
881
928
|
// #502: emit the write batch's FINAL diagnostic state immediately after
|
|
@@ -972,7 +1019,11 @@ export async function runPipeline(ctx, deps) {
|
|
|
972
1019
|
const fileList = changedList.length
|
|
973
1020
|
? "\nModified files:\n" + topFiles + overflow
|
|
974
1021
|
: "";
|
|
975
|
-
|
|
1022
|
+
const targetHasAuthoritativeAttachment = ctx.autofixMode !== "deferred" &&
|
|
1023
|
+
autofixChangedFiles.some((changedFile) => path.resolve(changedFile) === path.resolve(filePath));
|
|
1024
|
+
output += targetHasAuthoritativeAttachment
|
|
1025
|
+
? `\n\n⚠️ **The attached full content for ${toRunnerDisplayPath(cwd, filePath)} is authoritative after autofix. You MUST re-read any other modified side-effect files before editing them.**${fileList}`
|
|
1026
|
+
: `\n\n⚠️ **File was modified by auto-format/fix. You MUST re-read modified file(s) before making any further edits — the content on disk has changed (whitespace, indentation, quotes, or code). Editing from memory will produce mismatches.**${fileList}`;
|
|
976
1027
|
}
|
|
977
1028
|
phase.end("dispatch_lint", {
|
|
978
1029
|
hasOutput: !!dispatchResult.output,
|
|
@@ -984,6 +1035,11 @@ export async function runPipeline(ctx, deps) {
|
|
|
984
1035
|
// result is never shown inline — settled (bounded) and surfaced at turn_end.
|
|
985
1036
|
// The stored promise must never reject: an unhandled rejection is fatal, so a
|
|
986
1037
|
// failing compute resolves to an "error" skip-run instead.
|
|
1038
|
+
const cascadeOrigin = {
|
|
1039
|
+
turnSeq: ctx.telemetry?.turnIndex,
|
|
1040
|
+
writeSeq: ctx.telemetry?.writeIndex,
|
|
1041
|
+
projectSeq: ctx.seqState?.projectSeq(),
|
|
1042
|
+
};
|
|
987
1043
|
const cascadePromise = getFlag("no-lsp")
|
|
988
1044
|
? undefined
|
|
989
1045
|
: computeCascadeForFile(filePath, cwd, {
|
|
@@ -995,10 +1051,12 @@ export async function runPipeline(ctx, deps) {
|
|
|
995
1051
|
fileContent,
|
|
996
1052
|
wordIndex: ctx.wordIndex,
|
|
997
1053
|
onWordIndexUpdated: ctx.onWordIndexUpdated,
|
|
998
|
-
}).
|
|
1054
|
+
}).then((run) => ({ ...run, origin: cascadeOrigin }))
|
|
1055
|
+
.catch((err) => {
|
|
999
1056
|
dbg(`cascade compute failed for ${filePath}: ${err}`);
|
|
1000
1057
|
return {
|
|
1001
1058
|
filePath,
|
|
1059
|
+
origin: cascadeOrigin,
|
|
1002
1060
|
result: undefined,
|
|
1003
1061
|
neighborCount: 0,
|
|
1004
1062
|
diagnosticCount: 0,
|
|
@@ -1054,5 +1112,8 @@ export async function runPipeline(ctx, deps) {
|
|
|
1054
1112
|
formattersUsed,
|
|
1055
1113
|
fixedCount,
|
|
1056
1114
|
autofixTools,
|
|
1115
|
+
postMutation: ctx.autofixMode !== "deferred" && autofixChangedFiles.some((f) => path.resolve(f) === path.resolve(filePath)) && fileContent !== undefined
|
|
1116
|
+
? { filePath: path.resolve(filePath), content: fileContent, source: "autofix" }
|
|
1117
|
+
: undefined,
|
|
1057
1118
|
};
|
|
1058
1119
|
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* One-shot invocation detection, shared across the session_start-scheduled
|
|
3
|
+
* background work that must NOT run — or retain the process — in print mode
|
|
4
|
+
* (#1154 quick-mode warmup, #1153 orphan-reaper).
|
|
5
|
+
*
|
|
6
|
+
* `pi -p` / `pi --print` is a one-shot: the host computes a single turn and
|
|
7
|
+
* exits. Work scheduled to warm caches / clean up state for a *future* session
|
|
8
|
+
* in the same process is pure waste in this mode AND — when it arms a
|
|
9
|
+
* referenced libuv handle (a non-`unref`'d timer, an LSP child, an fs walk)
|
|
10
|
+
* with no session_shutdown teardown — keeps the already-settled one-shot
|
|
11
|
+
* process alive. That is the referenced-handle retention class of
|
|
12
|
+
* #1097/#1110/#1148/#1149 and the located #1122 hypothesis-A concern.
|
|
13
|
+
*
|
|
14
|
+
* argv is read live (not captured at module load) so tests can drive it; the
|
|
15
|
+
* flag never changes within a real process, and there is no hot-path caller,
|
|
16
|
+
* so recomputing is free. This mirrors the print detection in
|
|
17
|
+
* `runtime-session.ts`'s `resolveStartupMode` — keep them a single source.
|
|
18
|
+
*/
|
|
19
|
+
export function isPrintMode(argv = process.argv) {
|
|
20
|
+
return argv.includes("--print") || argv.includes("-p");
|
|
21
|
+
}
|
|
@@ -44,6 +44,31 @@ export function readProjectChanges(cwd) {
|
|
|
44
44
|
return [];
|
|
45
45
|
}
|
|
46
46
|
}
|
|
47
|
+
/**
|
|
48
|
+
* Async twin of `readProjectChanges` (#1162). `fs.promises.readFile` — unlike
|
|
49
|
+
* the sync `readFileSync` above — YIELDS to the event loop, which is what lets
|
|
50
|
+
* a caller bound it with a `Promise.race` timeout: a `setTimeout` can never
|
|
51
|
+
* preempt a synchronous blocking read (the thread doesn't return to the event
|
|
52
|
+
* loop until the OS does), so a bounded read on the session_start hot path
|
|
53
|
+
* requires the async form. Same parse/error-swallow semantics as the sync
|
|
54
|
+
* version — a missing/corrupt log is the normal cold-start case, not a
|
|
55
|
+
* caller-visible error.
|
|
56
|
+
*/
|
|
57
|
+
export async function readProjectChangesAsync(cwd) {
|
|
58
|
+
const logPath = getProjectChangeLogPath(cwd);
|
|
59
|
+
try {
|
|
60
|
+
const content = await fs.promises.readFile(logPath, "utf-8");
|
|
61
|
+
return content
|
|
62
|
+
.split(/\r?\n/)
|
|
63
|
+
.map((line) => line.trim())
|
|
64
|
+
.filter(Boolean)
|
|
65
|
+
.map(parseChangeLine)
|
|
66
|
+
.filter((entry) => Boolean(entry));
|
|
67
|
+
}
|
|
68
|
+
catch {
|
|
69
|
+
return [];
|
|
70
|
+
}
|
|
71
|
+
}
|
|
47
72
|
export function readChangesSince(cwd, seq, maxEntries = 200) {
|
|
48
73
|
const limit = Math.max(1, maxEntries);
|
|
49
74
|
return readProjectChanges(cwd)
|
|
@@ -134,6 +159,21 @@ export function readLatestProjectSequence(cwd, base) {
|
|
|
134
159
|
}
|
|
135
160
|
return fullReplay(entries);
|
|
136
161
|
}
|
|
162
|
+
/**
|
|
163
|
+
* Async twin of `readLatestProjectSequence` (#1162) — same fold logic, but
|
|
164
|
+
* reads the log via `readProjectChangesAsync` so a caller can bound the wait
|
|
165
|
+
* with a `Promise.race` timeout (see that function's doc comment for why the
|
|
166
|
+
* sync form can't be bounded at all).
|
|
167
|
+
*/
|
|
168
|
+
export async function readLatestProjectSequenceAsync(cwd, base) {
|
|
169
|
+
const entries = await readProjectChangesAsync(cwd);
|
|
170
|
+
if (base) {
|
|
171
|
+
const partial = partialReplay(entries, base);
|
|
172
|
+
if (partial)
|
|
173
|
+
return partial;
|
|
174
|
+
}
|
|
175
|
+
return fullReplay(entries);
|
|
176
|
+
}
|
|
137
177
|
export function appendProjectChange(cwd, entry) {
|
|
138
178
|
const logPath = getProjectChangeLogPath(cwd);
|
|
139
179
|
fs.mkdirSync(path.dirname(logPath), { recursive: true });
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import * as fs from "node:fs";
|
|
2
2
|
import * as path from "node:path";
|
|
3
3
|
import { getProjectDataDir } from "../file-utils.js";
|
|
4
|
+
import { writeFileAtomic } from "../atomic-write.js";
|
|
4
5
|
import { readJsonCache } from "../json-cache-read.js";
|
|
5
6
|
// v2: cheap-tier scan now also runs ast-grep-napi (#308); invalidate older
|
|
6
7
|
// snapshots so a pre-ast-grep cache isn't served as complete via refreshRunners=cached.
|
|
@@ -25,7 +26,7 @@ export function loadProjectDiagnosticsSnapshot(cwd) {
|
|
|
25
26
|
export function saveProjectDiagnosticsSnapshot(cwd, snapshot) {
|
|
26
27
|
const filePath = cachePath(cwd, SNAPSHOT_CACHE_FILE);
|
|
27
28
|
fs.mkdirSync(path.dirname(filePath), { recursive: true });
|
|
28
|
-
|
|
29
|
+
writeFileAtomic(filePath, JSON.stringify(snapshot, null, 2));
|
|
29
30
|
}
|
|
30
31
|
export function loadProjectDiagnosticsDeltaReport(cwd) {
|
|
31
32
|
return readJsonCache(cachePath(cwd, DELTA_CACHE_FILE), (parsed) => {
|
|
@@ -42,7 +43,7 @@ export function loadProjectDiagnosticsDeltaReport(cwd) {
|
|
|
42
43
|
export function writeProjectDiagnosticsDeltaReport(cwd, report) {
|
|
43
44
|
const filePath = cachePath(cwd, DELTA_CACHE_FILE);
|
|
44
45
|
fs.mkdirSync(path.dirname(filePath), { recursive: true });
|
|
45
|
-
|
|
46
|
+
writeFileAtomic(filePath, JSON.stringify(report, null, 2));
|
|
46
47
|
}
|
|
47
48
|
/**
|
|
48
49
|
* Drop diagnostics whose underlying file changed on disk after the snapshot was
|
|
@@ -383,7 +383,7 @@ export async function fetchFreshProjectDiagnostics(cacheManager, cwd, clients, s
|
|
|
383
383
|
cold.push("test-runner");
|
|
384
384
|
return;
|
|
385
385
|
}
|
|
386
|
-
record("test-runner", testRunnerFindingsToProjectDiagnostics(cached.data), Date.now() - startMs);
|
|
386
|
+
record("test-runner", testRunnerFindingsToProjectDiagnostics(cached.data, analysisRoot, options.runtime), Date.now() - startMs);
|
|
387
387
|
}),
|
|
388
388
|
];
|
|
389
389
|
// Swallow any later rejection so an aborted-and-abandoned task can never
|
package/node_modules/pi-lens/dist/clients/project-diagnostics/runner-adapters/call-graph-impact.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import * as path from "node:path";
|
|
2
2
|
import { parseSymbolKey, } from "../../call-graph.js";
|
|
3
|
+
import { isTestRoleCollateral } from "../../collateral-test-role.js";
|
|
3
4
|
function resolveImpactFile(cwd, filePath) {
|
|
4
5
|
return path.isAbsolute(filePath) ? filePath : path.resolve(cwd, filePath);
|
|
5
6
|
}
|
|
@@ -87,6 +88,13 @@ export function callGraphImpactToProjectDiagnostics(cwd, findings) {
|
|
|
87
88
|
if (!filePath)
|
|
88
89
|
continue; // Nothing real to attribute this to.
|
|
89
90
|
const resolvedFile = resolveImpactFile(cwd, filePath);
|
|
91
|
+
// #1080: the call graph is derived from the tests-free review graph and is
|
|
92
|
+
// normally tests-free, but this adapter accepts arbitrary caller
|
|
93
|
+
// symbol keys — an old/fixture/expanded graph could supply a test-file
|
|
94
|
+
// caller. A KNOWN test-role caller must not be persisted as collateral
|
|
95
|
+
// call-graph impact. Fail-open: a classifier error retains the finding.
|
|
96
|
+
if (isTestRoleCollateral(resolvedFile))
|
|
97
|
+
continue;
|
|
90
98
|
const dedupeKey = `${resolvedFile}:${result.symbolKey}`;
|
|
91
99
|
const existing = byKey.get(dedupeKey);
|
|
92
100
|
if (existing && SEVERITY_RANK[existing.severity] >= SEVERITY_RANK[mapped.severity]) {
|
package/node_modules/pi-lens/dist/clients/project-diagnostics/runner-adapters/runner-findings.js
CHANGED
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
import * as fs from "node:fs";
|
|
2
|
+
import * as path from "node:path";
|
|
3
|
+
import { advisoryPathKey, validateAdvisoryProvenance, } from "../../advisory-provenance.js";
|
|
1
4
|
function failureMessage(failure) {
|
|
2
5
|
const firstLine = failure.message.split("\n")[0]?.slice(0, 300) ?? "";
|
|
3
6
|
return firstLine ? `${failure.name}: ${firstLine}` : failure.name;
|
|
@@ -71,8 +74,26 @@ export function testResultToProjectDiagnostics(result, stale = false) {
|
|
|
71
74
|
},
|
|
72
75
|
];
|
|
73
76
|
}
|
|
74
|
-
export function testRunnerFindingsToProjectDiagnostics(cache) {
|
|
77
|
+
export function testRunnerFindingsToProjectDiagnostics(cache, cwd, runtime) {
|
|
75
78
|
if (!cache.results || cache.results.length === 0)
|
|
76
79
|
return [];
|
|
77
|
-
|
|
80
|
+
const validation = cwd
|
|
81
|
+
? validateAdvisoryProvenance(cache, cwd, runtime)
|
|
82
|
+
: { status: "unknown", reasons: ["validation-context-missing"] };
|
|
83
|
+
const root = cwd ?? process.cwd();
|
|
84
|
+
const missingKeys = new Set((cache.provenance?.files ?? [])
|
|
85
|
+
.filter((file) => !fs.existsSync(path.resolve(root, file.path)))
|
|
86
|
+
.map((file) => advisoryPathKey(file.path, root)));
|
|
87
|
+
const historical = cache.superseded === true || cache.stale === true || validation.status !== "current";
|
|
88
|
+
return cache.results
|
|
89
|
+
.filter((result) => !missingKeys.has(advisoryPathKey(result.file, root)))
|
|
90
|
+
.flatMap((result) => testResultToProjectDiagnostics(result, historical))
|
|
91
|
+
.map((diagnostic) => historical ? {
|
|
92
|
+
...diagnostic,
|
|
93
|
+
severity: "info",
|
|
94
|
+
semantic: "none",
|
|
95
|
+
message: diagnostic.message.startsWith("[stale")
|
|
96
|
+
? diagnostic.message
|
|
97
|
+
: `[historical — re-run to confirm] ${diagnostic.message}`,
|
|
98
|
+
} : diagnostic);
|
|
78
99
|
}
|
|
@@ -10,7 +10,7 @@ import { isAtOrAboveHomeDir } from "../path-utils.js";
|
|
|
10
10
|
import { getProjectDiagnosticsScannerMaxFiles } from "../project-scale.js";
|
|
11
11
|
import { captureReviewGraphStructuralIr } from "../review-graph/builder.js";
|
|
12
12
|
import { publishReviewGraphFileIr, reviewGraphIrContentHash, } from "../review-graph/shared-extraction-ir.js";
|
|
13
|
-
import { collectSourceFilesWithBudgetAsync } from "../source-filter.js";
|
|
13
|
+
import { collectSourceFilesWithBudgetAsync, } from "../source-filter.js";
|
|
14
14
|
import { logTreeSitter, logTreeSitterCacheStats, } from "../tree-sitter-logger.js";
|
|
15
15
|
import { queriesForLanguage, queryLoader, } from "../tree-sitter-query-loader.js";
|
|
16
16
|
import { EXT_TO_LANG, getSharedTreeSitterClient, isTreeSitterWasmAborted, } from "../tree-sitter-shared.js";
|
|
@@ -322,11 +322,19 @@ export async function scanProjectDiagnostics(options) {
|
|
|
322
322
|
// trips `maxFiles`. Unlike `unsafeRoot` this is not a refusal: when the
|
|
323
323
|
// budget trips we scan the truncated best-effort list and flag the snapshot
|
|
324
324
|
// so callers don't read the partial result as a complete sweep.
|
|
325
|
+
// #1107 phase 2: typed as the full `SourceCollectionResult` (not just its
|
|
326
|
+
// `{files, entryBudgetExceeded}` shape) so the generated-skip counters
|
|
327
|
+
// below are readable through the ternary — the `options.files` branch
|
|
328
|
+
// legitimately never walked, so it leaves them `undefined`, same
|
|
329
|
+
// convention as `entryBudgetExceeded: false` above it.
|
|
325
330
|
const collected = options.files
|
|
326
331
|
? { files: options.files.slice(0, maxFiles), entryBudgetExceeded: false }
|
|
327
332
|
: await collectSourceFilesWithBudgetAsync(cwd, {
|
|
328
333
|
maxFiles,
|
|
329
334
|
maxScanEntries: options.maxScanEntries,
|
|
335
|
+
// #1107 phase 2 review: the actionable opt-out generatedSkipNotice
|
|
336
|
+
// points a user at.
|
|
337
|
+
includeGenerated: options.includeGenerated === true,
|
|
330
338
|
});
|
|
331
339
|
const files = collected.files;
|
|
332
340
|
// Check cancellation before and during the file-major pass so a full-mode
|
|
@@ -361,6 +369,18 @@ export async function scanProjectDiagnostics(options) {
|
|
|
361
369
|
// byte-identical for the untruncated (normal) case.
|
|
362
370
|
if (collected.entryBudgetExceeded)
|
|
363
371
|
snapshot.scanTruncated = true;
|
|
372
|
+
// #1107 phase 2: only present when nonzero, same convention as the
|
|
373
|
+
// truncation flag above — a healthy scan with no generated-name skips
|
|
374
|
+
// produces a byte-identical snapshot to before this change.
|
|
375
|
+
if (collected.generatedOrArtifactSkips) {
|
|
376
|
+
snapshot.generatedFileSkips = collected.generatedOrArtifactSkips;
|
|
377
|
+
}
|
|
378
|
+
if (collected.generatedNameOnlySkips) {
|
|
379
|
+
snapshot.generatedNameOnlySkips = collected.generatedNameOnlySkips;
|
|
380
|
+
}
|
|
381
|
+
if (collected.generatedDirSkips) {
|
|
382
|
+
snapshot.generatedDirSkips = collected.generatedDirSkips;
|
|
383
|
+
}
|
|
364
384
|
if (wasmAborted) {
|
|
365
385
|
snapshot.scanTruncated = true;
|
|
366
386
|
snapshot.treeSitterStatus = "wasm_aborted_restart_required";
|