@herbertgao/pi-extensions 2026.8.6 → 2026.8.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +5 -5
- package/node_modules/@herbertgao/pi-cc-extensions/README.en.md +1 -1
- package/node_modules/@herbertgao/pi-cc-extensions/README.md +1 -1
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/config/config.ts +19 -7
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/config/panel.ts +30 -9
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/feature/compact-thinking.ts +272 -22
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/compact-mode.ts +94 -77
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/message-display.ts +1 -1
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/mouse/hover.ts +14 -0
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/mouse/interaction.ts +55 -17
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/mouse/layout.ts +41 -2
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/tool/diff/diff-renderer.ts +75 -6
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/tool/diff/types.ts +7 -3
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/tool/grouping.ts +64 -1
- package/node_modules/@herbertgao/pi-cc-extensions/package.json +3 -3
- package/node_modules/@herbertgao/pi-subagents/CHANGELOG.md +6 -0
- package/node_modules/@herbertgao/pi-subagents/README.md +30 -22
- package/node_modules/@herbertgao/pi-subagents/examples/agent-tool-description.md +5 -5
- package/node_modules/@herbertgao/pi-subagents/package.json +7 -7
- package/node_modules/@herbertgao/pi-subagents/src/agent-file-toggle.ts +7 -1
- package/node_modules/@herbertgao/pi-subagents/src/agent-manager.ts +48 -19
- package/node_modules/@herbertgao/pi-subagents/src/agent-runner.ts +17 -13
- package/node_modules/@herbertgao/pi-subagents/src/custom-agents.ts +26 -2
- package/node_modules/@herbertgao/pi-subagents/src/index.ts +219 -40
- package/node_modules/@herbertgao/pi-subagents/src/invocation-config.ts +101 -3
- package/node_modules/@herbertgao/pi-subagents/src/nested-tools.ts +18 -4
- package/node_modules/@herbertgao/pi-subagents/src/settings.ts +99 -0
- package/node_modules/@herbertgao/pi-subagents/src/types.ts +22 -3
- package/node_modules/@herbertgao/pi-subagents/src/ui/agent-widget.ts +51 -3
- package/node_modules/@herbertgao/pi-subagents/src/ui/conversation-viewer.ts +20 -2
- package/node_modules/@herbertgao/pi-subagents/src/ui/fleet-list.ts +21 -6
- package/node_modules/@herbertgao/pi-subagents/src/usage.ts +129 -1
- package/node_modules/@herbertgao/pi-subagents/src/worktree.ts +20 -0
- package/node_modules/@juicesharp/rpiv-ask-user-question/README.md +1 -0
- package/node_modules/@juicesharp/rpiv-ask-user-question/ask-user-question.ts +26 -10
- package/node_modules/@juicesharp/rpiv-ask-user-question/config.ts +25 -0
- package/node_modules/@juicesharp/rpiv-ask-user-question/docs/configuration.md +13 -4
- package/node_modules/@juicesharp/rpiv-ask-user-question/docs/hosts.md +2 -1
- package/node_modules/@juicesharp/rpiv-ask-user-question/docs/localization.md +3 -1
- package/node_modules/@juicesharp/rpiv-ask-user-question/locales/en.json +2 -2
- package/node_modules/@juicesharp/rpiv-ask-user-question/locales/zh.json +2 -2
- package/node_modules/@juicesharp/rpiv-ask-user-question/package.json +3 -2
- package/node_modules/@juicesharp/rpiv-ask-user-question/state/build-questionnaire.ts +10 -0
- package/node_modules/@juicesharp/rpiv-ask-user-question/state/key-router.ts +3 -1
- package/node_modules/@juicesharp/rpiv-ask-user-question/state/questionnaire-session.ts +30 -7
- package/node_modules/@juicesharp/rpiv-ask-user-question/state/state.ts +14 -6
- package/node_modules/@juicesharp/rpiv-ask-user-question/view/dialog-builder.ts +30 -4
- package/node_modules/@juicesharp/rpiv-ask-user-question/view/tab-content-strategy.ts +26 -5
- package/node_modules/@narumitw/pi-btw/README.md +120 -111
- package/node_modules/@narumitw/pi-btw/dist/index.ts +2898 -0
- package/node_modules/@narumitw/pi-btw/dist/index.ts.map +7 -0
- package/node_modules/@narumitw/pi-btw/package.json +10 -6
- package/node_modules/@narumitw/pi-btw/src/btw.ts +36 -40
- package/node_modules/@narumitw/pi-btw/src/fullscreen-ui.ts +55 -10
- package/node_modules/@narumitw/pi-btw/src/main-tree-picker.ts +390 -0
- package/node_modules/@narumitw/pi-btw/src/menu.ts +45 -2
- package/node_modules/@narumitw/pi-btw/src/transcript-pager.ts +136 -45
- package/node_modules/pi-lens/CHANGELOG.md +909 -0
- package/node_modules/pi-lens/README.md +11 -3
- package/node_modules/pi-lens/config/ruff/core.toml +42 -0
- package/node_modules/pi-lens/dist/clients/actionable-warnings.js +130 -27
- package/node_modules/pi-lens/dist/clients/advisory-provenance.js +126 -13
- package/node_modules/pi-lens/dist/clients/agent-nudge.js +67 -11
- package/node_modules/pi-lens/dist/clients/ast-grep-client.js +9 -3
- package/node_modules/pi-lens/dist/clients/atomic-write.js +9 -3
- package/node_modules/pi-lens/dist/clients/bash-file-access.js +285 -8
- package/node_modules/pi-lens/dist/clients/biome-client.js +61 -30
- package/node_modules/pi-lens/dist/clients/blocker-freshness.js +428 -0
- package/node_modules/pi-lens/dist/clients/blocker-past-eof.js +119 -0
- package/node_modules/pi-lens/dist/clients/bootstrap.js +12 -1
- package/node_modules/pi-lens/dist/clients/bounded-pid-file-lock.js +12 -3
- package/node_modules/pi-lens/dist/clients/bounded-telemetry.js +192 -0
- package/node_modules/pi-lens/dist/clients/cascade-budget.js +196 -0
- package/node_modules/pi-lens/dist/clients/cascade-format.js +20 -1
- package/node_modules/pi-lens/dist/clients/cascade-types.js +9 -1
- package/node_modules/pi-lens/dist/clients/child-unref.js +54 -6
- package/node_modules/pi-lens/dist/clients/code-quality-warnings.js +76 -24
- package/node_modules/pi-lens/dist/clients/dead-code-client.js +123 -31
- package/node_modules/pi-lens/dist/clients/deadline-utils.js +8 -1
- package/node_modules/pi-lens/dist/clients/debug-handles.js +5 -0
- package/node_modules/pi-lens/dist/clients/degradation-ledger.js +62 -13
- package/node_modules/pi-lens/dist/clients/dependency-checker.js +25 -3
- package/node_modules/pi-lens/dist/clients/diagnostic-dispositions.js +147 -33
- package/node_modules/pi-lens/dist/clients/diagnostic-line-freshness.js +298 -0
- package/node_modules/pi-lens/dist/clients/dispatch/dispatcher.js +52 -2
- package/node_modules/pi-lens/dist/clients/dispatch/integration.js +256 -88
- package/node_modules/pi-lens/dist/clients/dispatch/lazy.js +7 -4
- package/node_modules/pi-lens/dist/clients/dispatch/plan.js +5 -0
- package/node_modules/pi-lens/dist/clients/dispatch/runners/ast-grep-napi.js +234 -18
- package/node_modules/pi-lens/dist/clients/dispatch/runners/biome-check.js +187 -19
- package/node_modules/pi-lens/dist/clients/dispatch/runners/cpp-check.js +6 -3
- package/node_modules/pi-lens/dist/clients/dispatch/runners/credo.js +11 -9
- package/node_modules/pi-lens/dist/clients/dispatch/runners/cue-vet.js +398 -0
- package/node_modules/pi-lens/dist/clients/dispatch/runners/elixir-check.js +11 -3
- package/node_modules/pi-lens/dist/clients/dispatch/runners/eslint.js +12 -7
- package/node_modules/pi-lens/dist/clients/dispatch/runners/go-vet.js +18 -0
- package/node_modules/pi-lens/dist/clients/dispatch/runners/helm-render.js +895 -0
- package/node_modules/pi-lens/dist/clients/dispatch/runners/index.js +4 -0
- package/node_modules/pi-lens/dist/clients/dispatch/runners/javac.js +16 -3
- package/node_modules/pi-lens/dist/clients/dispatch/runners/lsp.js +60 -53
- package/node_modules/pi-lens/dist/clients/dispatch/runners/markdownlint.js +16 -0
- package/node_modules/pi-lens/dist/clients/dispatch/runners/mypy.js +23 -0
- package/node_modules/pi-lens/dist/clients/dispatch/runners/psscriptanalyzer.js +331 -55
- package/node_modules/pi-lens/dist/clients/dispatch/runners/pyright.js +38 -5
- package/node_modules/pi-lens/dist/clients/dispatch/runners/rust-clippy.js +97 -19
- package/node_modules/pi-lens/dist/clients/dispatch/runners/spellcheck.js +14 -0
- package/node_modules/pi-lens/dist/clients/dispatch/runners/sqlfluff.js +20 -0
- package/node_modules/pi-lens/dist/clients/dispatch/runners/stylelint.js +22 -0
- package/node_modules/pi-lens/dist/clients/dispatch/runners/swiftlint.js +10 -0
- package/node_modules/pi-lens/dist/clients/dispatch/runners/taplo.js +18 -6
- package/node_modules/pi-lens/dist/clients/dispatch/runners/trivy-config.js +73 -12
- package/node_modules/pi-lens/dist/clients/dispatch/runners/utils/availability-policy.js +275 -13
- package/node_modules/pi-lens/dist/clients/dispatch/runners/utils/candidate-probe.js +21 -6
- package/node_modules/pi-lens/dist/clients/dispatch/runners/utils/lazy-installer.js +260 -27
- package/node_modules/pi-lens/dist/clients/dispatch/runners/utils/runner-helpers.js +734 -64
- package/node_modules/pi-lens/dist/clients/dispatch/runners/utils/spawn-outcome.js +86 -11
- package/node_modules/pi-lens/dist/clients/dispatch/runners/utils/tool-failure.js +72 -0
- package/node_modules/pi-lens/dist/clients/dispatch/runners/utils/toolchain-availability.js +9 -0
- package/node_modules/pi-lens/dist/clients/dispatch/runners/vale.js +9 -0
- package/node_modules/pi-lens/dist/clients/dispatch/runners/yamllint.js +18 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/zig-check.js +4 -2
- package/node_modules/pi-lens/dist/clients/event-loop-monitor.js +28 -5
- package/node_modules/pi-lens/dist/clients/extension-log.js +22 -1
- package/node_modules/pi-lens/dist/clients/file-kinds.js +8 -2
- package/node_modules/pi-lens/dist/clients/finding-delivery-gate.js +294 -0
- package/node_modules/pi-lens/dist/clients/finding-identity.js +88 -0
- package/node_modules/pi-lens/dist/clients/formatters-lazy.js +3 -2
- package/node_modules/pi-lens/dist/clients/formatters.js +500 -115
- package/node_modules/pi-lens/dist/clients/generation-guard.js +216 -0
- package/node_modules/pi-lens/dist/clients/git-guard.js +31 -0
- package/node_modules/pi-lens/dist/clients/gitleaks-client.js +181 -8
- package/node_modules/pi-lens/dist/clients/govulncheck-client.js +109 -9
- package/node_modules/pi-lens/dist/clients/grammar-source.js +333 -10
- package/node_modules/pi-lens/dist/clients/host-ports.js +8 -0
- package/node_modules/pi-lens/dist/clients/installer/index.js +1114 -100
- package/node_modules/pi-lens/dist/clients/installer/managed-tool-refresh-session.js +58 -0
- package/node_modules/pi-lens/dist/clients/installer/managed-tool-refresh.js +715 -0
- package/node_modules/pi-lens/dist/clients/instance-reaper.js +643 -97
- package/node_modules/pi-lens/dist/clients/instance-registry.js +87 -17
- package/node_modules/pi-lens/dist/clients/jscpd-client.js +82 -6
- package/node_modules/pi-lens/dist/clients/knip-client.js +310 -10
- package/node_modules/pi-lens/dist/clients/language-policy.js +8 -2
- package/node_modules/pi-lens/dist/clients/language-profile.js +2 -0
- package/node_modules/pi-lens/dist/clients/latency-logger.js +440 -11
- package/node_modules/pi-lens/dist/clients/lazy-import.js +21 -0
- package/node_modules/pi-lens/dist/clients/ledger-bounds.js +21 -0
- package/node_modules/pi-lens/dist/clients/lens-flag-registry.js +8 -0
- package/node_modules/pi-lens/dist/clients/lsp/cascade-tier.js +102 -7
- package/node_modules/pi-lens/dist/clients/lsp/client.js +1516 -159
- package/node_modules/pi-lens/dist/clients/lsp/diagnostic-binding.js +83 -1
- package/node_modules/pi-lens/dist/clients/lsp/document-drift.js +389 -0
- package/node_modules/pi-lens/dist/clients/lsp/index.js +2274 -147
- package/node_modules/pi-lens/dist/clients/lsp/inferred-project.js +215 -0
- package/node_modules/pi-lens/dist/clients/lsp/jvm-runtime.js +146 -14
- package/node_modules/pi-lens/dist/clients/lsp/language.js +48 -4
- package/node_modules/pi-lens/dist/clients/lsp/server.js +277 -16
- package/node_modules/pi-lens/dist/clients/lsp/spawn-history.js +22 -0
- package/node_modules/pi-lens/dist/clients/lsp/sync-kind.js +43 -0
- package/node_modules/pi-lens/dist/clients/lsp/tsserver-sync.js +79 -3
- package/node_modules/pi-lens/dist/clients/lsp/wait-policy/strategies.js +43 -0
- package/node_modules/pi-lens/dist/clients/lsp/workspace-diagnostics-cache.js +422 -28
- package/node_modules/pi-lens/dist/clients/lsp/workspace-diagnostics-session.js +30 -0
- package/node_modules/pi-lens/dist/clients/lsp/workspace-sweep-hold.js +175 -0
- package/node_modules/pi-lens/dist/clients/lsp-lazy.js +3 -2
- package/node_modules/pi-lens/dist/clients/mcp/session.js +10 -2
- package/node_modules/pi-lens/dist/clients/module-report.js +8 -0
- package/node_modules/pi-lens/dist/clients/opengrep-client.js +15 -1
- package/node_modules/pi-lens/dist/clients/package-manager.js +170 -14
- package/node_modules/pi-lens/dist/clients/path-attribution-telemetry.js +27 -0
- package/node_modules/pi-lens/dist/clients/path-utils.js +160 -0
- package/node_modules/pi-lens/dist/clients/pipeline.js +154 -33
- package/node_modules/pi-lens/dist/clients/post-autofix-notice.js +37 -0
- package/node_modules/pi-lens/dist/clients/project-diagnostics/cache.js +17 -3
- package/node_modules/pi-lens/dist/clients/project-diagnostics/extractors.js +89 -22
- package/node_modules/pi-lens/dist/clients/project-diagnostics/fresh-fetch.js +84 -14
- package/node_modules/pi-lens/dist/clients/project-diagnostics/runner-adapters/gitleaks.js +15 -3
- package/node_modules/pi-lens/dist/clients/project-diagnostics/runner-adapters/trivy.js +50 -2
- package/node_modules/pi-lens/dist/clients/project-diagnostics/scanner.js +5 -0
- package/node_modules/pi-lens/dist/clients/project-lens-config.js +3 -0
- package/node_modules/pi-lens/dist/clients/project-snapshot.js +299 -0
- package/node_modules/pi-lens/dist/clients/quiet-window-config.js +47 -0
- package/node_modules/pi-lens/dist/clients/quiet-window.js +11 -25
- package/node_modules/pi-lens/dist/clients/read-guard-logger.js +1 -1
- package/node_modules/pi-lens/dist/clients/read-guard.js +184 -10
- package/node_modules/pi-lens/dist/clients/resource-sampler.js +49 -17
- package/node_modules/pi-lens/dist/clients/reverse-deps.js +50 -11
- package/node_modules/pi-lens/dist/clients/review-graph/query.js +52 -4
- package/node_modules/pi-lens/dist/clients/runtime-agent-end.js +96 -7
- package/node_modules/pi-lens/dist/clients/runtime-context.js +8 -1
- package/node_modules/pi-lens/dist/clients/runtime-coordinator.js +308 -45
- package/node_modules/pi-lens/dist/clients/runtime-session.js +332 -9
- package/node_modules/pi-lens/dist/clients/runtime-tool-call.js +217 -22
- package/node_modules/pi-lens/dist/clients/runtime-tool-result.js +212 -79
- package/node_modules/pi-lens/dist/clients/runtime-turn.js +575 -67
- package/node_modules/pi-lens/dist/clients/safe-spawn.js +220 -7
- package/node_modules/pi-lens/dist/clients/scratch-tree-policy.js +161 -0
- package/node_modules/pi-lens/dist/clients/search-read-registration.js +34 -6
- package/node_modules/pi-lens/dist/clients/security-scan-client.js +157 -24
- package/node_modules/pi-lens/dist/clients/sg-runner.js +116 -22
- package/node_modules/pi-lens/dist/clients/single-flight.js +158 -0
- package/node_modules/pi-lens/dist/clients/stale-marker.js +17 -0
- package/node_modules/pi-lens/dist/clients/startup-timing.js +19 -1
- package/node_modules/pi-lens/dist/clients/test-runner-client.js +151 -16
- package/node_modules/pi-lens/dist/clients/tool-event.js +56 -5
- package/node_modules/pi-lens/dist/clients/tool-policy.js +125 -20
- package/node_modules/pi-lens/dist/clients/tree-sitter-cache.js +75 -1
- package/node_modules/pi-lens/dist/clients/tree-sitter-client.js +769 -64
- package/node_modules/pi-lens/dist/clients/tree-sitter-shared.js +11 -0
- package/node_modules/pi-lens/dist/clients/tree-sitter-symbol-extractor.js +90 -0
- package/node_modules/pi-lens/dist/clients/trivy-client.js +19 -1
- package/node_modules/pi-lens/dist/clients/widget-state.js +336 -36
- package/node_modules/pi-lens/dist/clients/zizmor-config.js +214 -14
- package/node_modules/pi-lens/dist/index.js +67738 -55739
- package/node_modules/pi-lens/dist/tools/lens-diagnostics.js +466 -54
- package/node_modules/pi-lens/dist/tools/lsp-diagnostics.js +132 -43
- package/node_modules/pi-lens/dist/tools/lsp-navigation.js +46 -7
- package/node_modules/pi-lens/docs/agent-guide.md +6 -1
- package/node_modules/pi-lens/docs/ast-grep_rules_catalog.md +515 -506
- package/node_modules/pi-lens/docs/dispositions.md +21 -0
- package/node_modules/pi-lens/docs/features.md +19 -5
- package/node_modules/pi-lens/docs/globalconfig.md +3 -0
- package/node_modules/pi-lens/docs/language-coverage.md +71 -5
- package/node_modules/pi-lens/docs/mcp.md +2 -2
- package/node_modules/pi-lens/docs/servercapabilities.md +4 -1
- package/node_modules/pi-lens/docs/settings.md +19 -1
- package/node_modules/pi-lens/docs/usage.md +1 -0
- package/node_modules/pi-lens/package.json +10 -6
- package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/__snapshots__/no-reflect-get-js-snapshot.yml +23 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/__snapshots__/no-reflect-get-snapshot.yml +23 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/__snapshots__/ts-void-zero-snapshot.yml +23 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-bare-object-param-test.yml +16 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-chained-type-assertions-test.yml +15 -1
- package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-compile-call-test.yml +29 -1
- package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-dupe-class-members-test.yml +33 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-inner-html-js-test.yml +7 -1
- package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-inner-html-test.yml +7 -1
- package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-known-value-widening-test.yml +9 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-non-null-assertion-test.yml +216 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-reflect-apply-js-test.yml +2 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-reflect-apply-test.yml +2 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-reflect-get-js-test.yml +2 -1
- package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-reflect-get-test.yml +2 -1
- package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-return-value-in-generator-test.yml +12 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-runtime-typeof-test.yml +33 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-server-bind-wildcard-test.yml +9 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-shape-in-symbol-names-test.yml +13 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-sql-in-code-js-test.yml +5 -1
- package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-sql-in-code-test.yml +5 -1
- package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-unknown-parameters-test.yml +12 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-unknown-returns-test.yml +16 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-unsafe-dictionary-any-test.yml +10 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-unsafe-dictionary-unknown-test.yml +8 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/redundant-unsafe-function-test.yml +35 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/require-safety-comment-for-as-unknown-as-test.yml +177 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/ts-void-zero-test.yml +1 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-await-expression-member-js.yml +13 -2
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-await-expression-member.yml +13 -2
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-bare-host-path-in-win32-branch.yml +2 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-bare-object-param.yml +60 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-chained-type-assertions.yml +57 -12
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-compile-call.yml +63 -5
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-dupe-class-members.yml +52 -8
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-inner-html-js.yml +27 -2
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-inner-html.yml +27 -2
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-known-value-widening.yml +71 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-non-null-assertion.yml +316 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-raw-json-store-write.yml +7 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-reflect-apply-js.yml +22 -2
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-reflect-apply.yml +23 -2
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-reflect-get-js.yml +33 -5
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-reflect-get.yml +34 -8
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-return-value-in-generator.yml +22 -5
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-runtime-typeof.yml +121 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-server-bind-wildcard.yml +23 -7
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-shape-in-symbol-names.yml +68 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-sql-in-code-js.yml +41 -2
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-sql-in-code.yml +41 -2
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-unknown-laundering.yml +6 -1
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-unknown-parameters.yml +67 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-unknown-returns.yml +106 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-unsafe-dictionary-any.yml +50 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-unsafe-dictionary-unknown.yml +56 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-win32-isabsolute-for-qualification.yml +2 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/redundant-unsafe-function.yml +32 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/require-safety-comment-for-as-unknown-as.yml +184 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/ts-void-zero.yml +5 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/self-scan-baseline.json +5 -0
- package/node_modules/pi-lens/scripts/analyze-pi-lens-logs.mjs +53 -1
- package/node_modules/pi-lens/scripts/download-grammars.js +25 -0
- package/node_modules/pi-lens/scripts/grammars.lock.json +9 -0
- package/node_modules/pi-lens/skills/pi-lens-ast-grep/SKILL.md +2 -0
- package/node_modules/pi-lens/skills/pi-lens-write-ast-grep-rule/SKILL.md +80 -3
- package/node_modules/pi-lens/skills/pi-lens-write-ast-grep-rule/reference.md +41 -0
- package/node_modules/pi-lens/vendor/grammars/tree-sitter-cue.wasm +0 -0
- package/node_modules/pi-mcp-adapter/CHANGELOG.md +36 -0
- package/node_modules/pi-mcp-adapter/README.md +47 -5
- package/node_modules/pi-mcp-adapter/cli.js +163 -1
- package/node_modules/pi-mcp-adapter/commands.ts +128 -22
- package/node_modules/pi-mcp-adapter/config.ts +25 -7
- package/node_modules/pi-mcp-adapter/direct-tools.ts +5 -4
- package/node_modules/pi-mcp-adapter/index.ts +219 -32
- package/node_modules/pi-mcp-adapter/init.ts +36 -4
- package/node_modules/pi-mcp-adapter/lifecycle.ts +315 -24
- package/node_modules/pi-mcp-adapter/mcp-auth-flow.ts +39 -6
- package/node_modules/pi-mcp-adapter/mcp-bearer-store.ts +387 -0
- package/node_modules/pi-mcp-adapter/mcp-callback-server.ts +27 -3
- package/node_modules/pi-mcp-adapter/mcp-code.ts +4 -0
- package/node_modules/pi-mcp-adapter/mcp-panel.ts +42 -13
- package/node_modules/pi-mcp-adapter/metadata-cache.ts +32 -21
- package/node_modules/pi-mcp-adapter/package-mcp-loader.ts +168 -0
- package/node_modules/pi-mcp-adapter/package.json +3 -1
- package/node_modules/pi-mcp-adapter/proxy-modes.ts +5 -4
- package/node_modules/pi-mcp-adapter/request-headers-command.ts +31 -37
- package/node_modules/pi-mcp-adapter/search-ranking.ts +92 -22
- package/node_modules/pi-mcp-adapter/server-manager.ts +140 -2
- package/node_modules/pi-mcp-adapter/session-recovery.ts +7 -0
- package/node_modules/pi-mcp-adapter/tool-approval.ts +15 -2
- package/node_modules/pi-mcp-adapter/tool-result-renderer.ts +44 -4
- package/node_modules/pi-mcp-adapter/types.ts +2 -0
- package/node_modules/pi-mcp-adapter/ui-server.ts +18 -16
- package/node_modules/pi-mcp-adapter/utils.ts +70 -0
- package/node_modules/pi-web-access/CHANGELOG.md +23 -0
- package/node_modules/pi-web-access/README.md +27 -9
- package/node_modules/pi-web-access/anysearch.ts +4 -2
- package/node_modules/pi-web-access/brave.ts +16 -4
- package/node_modules/pi-web-access/curator-page.ts +6 -3
- package/node_modules/pi-web-access/curator-server.ts +4 -1
- package/node_modules/pi-web-access/exa.ts +18 -7
- package/node_modules/pi-web-access/extract.ts +28 -3
- package/node_modules/pi-web-access/gemini-search.ts +16 -4
- package/node_modules/pi-web-access/index.ts +41 -57
- package/node_modules/pi-web-access/package.json +1 -1
- package/node_modules/pi-web-access/page-query.ts +4 -2
- package/node_modules/pi-web-access/parallel-mcp.ts +249 -0
- package/node_modules/pi-web-access/parallel.ts +2 -2
- package/node_modules/pi-web-access/query-rewrite.ts +51 -0
- package/node_modules/pi-web-access/serper.ts +211 -0
- package/node_modules/pi-web-access/summary-model-scope.ts +12 -4
- package/node_modules/pi-web-access/summary-review.ts +44 -22
- package/node_modules/pi-web-access/tavily.ts +16 -4
- package/node_modules/pi-web-access/utils.ts +87 -0
- package/node_modules/pi-web-access/valyu.ts +199 -0
- package/package.json +13 -13
|
@@ -10,7 +10,7 @@ import { Type } from "../clients/deps/typebox.js";
|
|
|
10
10
|
import { getProjectIgnoreMatcher, isExcludedDirName, } from "../clients/file-utils.js";
|
|
11
11
|
import { getLSPService, groupFilesByPrimaryServer, runPerServerGroups, } from "../clients/lsp/index.js";
|
|
12
12
|
import { buildScopeKey, createWorkspaceDiagnosticsCacheContext, } from "../clients/lsp/workspace-diagnostics-cache.js";
|
|
13
|
-
import { primaryServerId } from "../clients/lsp/config.js";
|
|
13
|
+
import { getServersForFileWithConfig, primaryServerId, } from "../clients/lsp/config.js";
|
|
14
14
|
import { combineAbortSignals, withDeadline } from "../clients/deadline-utils.js";
|
|
15
15
|
import { applyAuxiliarySuppressions, retagAuxiliaryDiagnostics, } from "../clients/dispatch/auxiliary-lsp.js";
|
|
16
16
|
import { detectFileRole } from "../clients/file-role.js";
|
|
@@ -18,7 +18,8 @@ import { hashDiagnosticContent, touchCompletedConfirmationPolicy, touchCoverageG
|
|
|
18
18
|
import { classifyCascadeWaitTier } from "../clients/lsp/wait-policy/index.js";
|
|
19
19
|
import { attemptTsserverSyncDiagnostics, } from "../clients/lsp/tsserver-sync.js";
|
|
20
20
|
import { convertLspDiagnostics } from "../clients/dispatch/utils/lsp-diagnostics.js";
|
|
21
|
-
import {
|
|
21
|
+
import { demoteInferredProjectDiagnostics } from "../clients/lsp/inferred-project.js";
|
|
22
|
+
import { isBlocking, reconcileScanDiagnostics } from "../clients/widget-state.js";
|
|
22
23
|
import { baseName, compactRenderResult } from "./render-compact.js";
|
|
23
24
|
import { makeProgressReporter, scanningSummaryLine } from "./scan-progress.js";
|
|
24
25
|
import { isWarmAttached, tryWarmAttachedDiagnostics, } from "../clients/warm-attach.js";
|
|
@@ -239,7 +240,14 @@ export function createLspDiagnosticsTool(
|
|
|
239
240
|
// confirmed result reconciled into the footer reserves its token when the
|
|
240
241
|
// per-file check starts, so settlement order cannot make an older result look
|
|
241
242
|
// newer. Optional/undefined in tests.
|
|
242
|
-
nextWriteIndex
|
|
243
|
+
nextWriteIndex,
|
|
244
|
+
// #1561: #571 wired this tool's confirmed result into the widget footer and
|
|
245
|
+
// stopped there. The inline-blocker map is a SECOND agent-facing store fed by
|
|
246
|
+
// the same dispatch verdict, and nothing retired it — so pi-lens kept
|
|
247
|
+
// injecting "Unresolved from this turn" for three more turns after answering
|
|
248
|
+
// "confirmed clean" for the same file. index.ts injects
|
|
249
|
+
// `runtime.retireInlineBlockerOnConfirmedClean`. Optional/undefined in tests.
|
|
250
|
+
onConfirmedNoBlockers) {
|
|
243
251
|
return {
|
|
244
252
|
name: "lsp_diagnostics",
|
|
245
253
|
label: "LSP Diagnostics",
|
|
@@ -387,6 +395,7 @@ nextWriteIndex) {
|
|
|
387
395
|
nextWriteIndex,
|
|
388
396
|
serverScope,
|
|
389
397
|
cwd,
|
|
398
|
+
onConfirmedNoBlockers,
|
|
390
399
|
});
|
|
391
400
|
}
|
|
392
401
|
const rawPath = typedParams.path;
|
|
@@ -427,9 +436,10 @@ nextWriteIndex) {
|
|
|
427
436
|
nextWriteIndex,
|
|
428
437
|
serverScope,
|
|
429
438
|
cwd,
|
|
439
|
+
onConfirmedNoBlockers,
|
|
430
440
|
});
|
|
431
441
|
}
|
|
432
|
-
return runFileDiagnostics(absPath, severity, lspService, waitMs, nextWriteIndex, serverScope, cwd);
|
|
442
|
+
return runFileDiagnostics(absPath, severity, lspService, waitMs, nextWriteIndex, serverScope, cwd, onConfirmedNoBlockers);
|
|
433
443
|
},
|
|
434
444
|
};
|
|
435
445
|
}
|
|
@@ -632,35 +642,66 @@ function canTrustTouchConfirmation(file, serverScope, confirmedByTouch) {
|
|
|
632
642
|
(serverScope === "primary" || primaryServerId(file) !== "typescript"));
|
|
633
643
|
}
|
|
634
644
|
/**
|
|
635
|
-
* #
|
|
636
|
-
* (`widget-state.ts`'s `allDiagnostics`) — same shared choke point
|
|
637
|
-
* `lens_diagnostics` mode=full uses (`clients/widget-state.ts`'s
|
|
638
|
-
* `reconcileScanDiagnostics`). A manual `lsp_diagnostics` check that proves a
|
|
639
|
-
* stale footer error is actually gone (the real-world case that surfaced
|
|
640
|
-
* #571) is exactly the kind of confirmed result that should correct it.
|
|
641
|
-
* Direct `lsp_diagnostics` deliberately does not perform a second disk read at
|
|
642
|
-
* this reconciliation seam: its collecting touch already read the content and
|
|
643
|
-
* supplies the binding verdict. `false` is unconfirmed and is never written;
|
|
644
|
-
* `true` is trusted, while an absent/`unknown` verdict preserves the legacy
|
|
645
|
-
* fail-open policy for servers that cannot bind their diagnostics to content.
|
|
645
|
+
* #1561 F1: what this check is entitled to speak for.
|
|
646
646
|
*
|
|
647
|
-
*
|
|
648
|
-
*
|
|
649
|
-
*
|
|
650
|
-
*
|
|
651
|
-
* `
|
|
652
|
-
*
|
|
653
|
-
*
|
|
647
|
+
* Inline blockers are raised by the whole dispatch — eslint, biome-check,
|
|
648
|
+
* actionlint, ast-grep security rules — while this tool only ever consults
|
|
649
|
+
* language servers. Retiring one therefore needs an explicit coverage claim,
|
|
650
|
+
* and the honest claim is exactly the servers this check consulted and got an
|
|
651
|
+
* answer from. `serverScope: "primary"` consults only the primary, so its claim
|
|
652
|
+
* is `"lsp"` alone; an all-scope check adds each auxiliary server by id, which
|
|
653
|
+
* is the same vocabulary `retagAuxiliaryDiagnostics` tags their findings with.
|
|
654
654
|
*
|
|
655
|
-
*
|
|
656
|
-
*
|
|
657
|
-
*
|
|
658
|
-
*
|
|
659
|
-
* is the file content `collectDiagnosticsForFile`/the cache already read (or
|
|
660
|
-
* undefined for a cache-hit branch, whose `rawDiags` were already suppression-
|
|
661
|
-
* /skipTestFiles-filtered at write time — an empty string here is then a safe
|
|
662
|
-
* no-op re-check, not a behavior gap).
|
|
655
|
+
* A server named in `unconfirmedServerIds` is dropped: it produced no evidence
|
|
656
|
+
* for this content, so claiming coverage for it would be the #1470/#1493 lie one
|
|
657
|
+
* layer up. (Today an aux gap also demotes the whole verdict to "unconfirmed",
|
|
658
|
+
* so the hook does not fire at all — this stays correct if that ever narrows.)
|
|
663
659
|
*/
|
|
660
|
+
function coveredSourcesForCheck(file, serverScope, unconfirmedServerIds) {
|
|
661
|
+
const unconfirmed = new Set(unconfirmedServerIds);
|
|
662
|
+
const covered = new Set();
|
|
663
|
+
let servers = [];
|
|
664
|
+
try {
|
|
665
|
+
servers = (getServersForFileWithConfig(file) ?? []);
|
|
666
|
+
}
|
|
667
|
+
catch {
|
|
668
|
+
// A registry we cannot read is not a coverage claim. Returning an empty
|
|
669
|
+
// set makes every retire fail closed, which is the safe direction for a
|
|
670
|
+
// commit gate.
|
|
671
|
+
return [];
|
|
672
|
+
}
|
|
673
|
+
for (const server of servers) {
|
|
674
|
+
const auxiliary = server.role === "auxiliary";
|
|
675
|
+
if (auxiliary && serverScope === "primary")
|
|
676
|
+
continue;
|
|
677
|
+
if (unconfirmed.has(server.id))
|
|
678
|
+
continue;
|
|
679
|
+
// The dispatch runner tags the primary language server's findings `lsp`;
|
|
680
|
+
// auxiliaries keep their own tool id.
|
|
681
|
+
covered.add(auxiliary ? server.id : "lsp");
|
|
682
|
+
}
|
|
683
|
+
return [...covered];
|
|
684
|
+
}
|
|
685
|
+
/**
|
|
686
|
+
* #1645 review F3: `lsp_diagnostics` writes into the SAME widget store as
|
|
687
|
+
* `lens_diagnostics mode=full`. Two tools writing one store must apply ONE rule
|
|
688
|
+
* for "is this file's diagnostics demoted" — otherwise an orphan file blocks or
|
|
689
|
+
* does not depending purely on which tool ran last, which is the #1633-V1
|
|
690
|
+
* lesson. Every path in this file that reaches `reconcileWidgetFromLspResult`
|
|
691
|
+
* or the rendered output routes its raw diagnostics through here first, so the
|
|
692
|
+
* store, the counts, and the text all agree.
|
|
693
|
+
*
|
|
694
|
+
* Applied AFTER the confirmation verdict is computed, never before: confirmation
|
|
695
|
+
* asks "did the server answer for this content", which the demotion must not
|
|
696
|
+
* influence.
|
|
697
|
+
*/
|
|
698
|
+
function demoteInferredForFile(file, diagnostics, cwd, lspService) {
|
|
699
|
+
return demoteInferredProjectDiagnostics(diagnostics, {
|
|
700
|
+
filePath: file,
|
|
701
|
+
cwd,
|
|
702
|
+
service: lspService,
|
|
703
|
+
});
|
|
704
|
+
}
|
|
664
705
|
function reconcileWidgetFromLspResult(file, rawDiags, confirmation, writeIndex, cwd, content,
|
|
665
706
|
// #1095: true when the result's content binding demonstrably mismatches disk
|
|
666
707
|
// (boundToCurrentDisk === false). Such a result — even a NON-EMPTY one, which
|
|
@@ -678,7 +719,7 @@ boundMismatch = false,
|
|
|
678
719
|
observedAt) {
|
|
679
720
|
const confirmed = (rawDiags.length > 0 || confirmation !== "unconfirmed") && !boundMismatch;
|
|
680
721
|
if (!confirmed)
|
|
681
|
-
return;
|
|
722
|
+
return { confirmed: false, blocking: true };
|
|
682
723
|
try {
|
|
683
724
|
// #692: provenance label ONLY — must never affect `rule`/identity (see
|
|
684
725
|
// `ConvertLspDiagnosticsOptions.scanOrigin`'s doc comment).
|
|
@@ -687,9 +728,16 @@ observedAt) {
|
|
|
687
728
|
});
|
|
688
729
|
const retagged = retagAuxiliaryDiagnostics(diagnostics, rawDiags, content ?? "", { cwd, fileRole: detectFileRole(file, content) });
|
|
689
730
|
reconcileScanDiagnostics(file, retagged, true, writeIndex, observedAt);
|
|
731
|
+
// #1561: the blocking tally comes from the SAME `isBlocking` predicate the
|
|
732
|
+
// footer counts with — no second severity rule for the blocker-retire
|
|
733
|
+
// decision to drift away from.
|
|
734
|
+
return { confirmed: true, blocking: retagged.some(isBlocking) };
|
|
690
735
|
}
|
|
691
736
|
catch {
|
|
692
737
|
// Never let a footer-reconciliation hiccup fail the diagnostics check.
|
|
738
|
+
// A verdict we could not compute is NOT evidence of clean: report it as
|
|
739
|
+
// still-blocking so no caller retires a blocker off a failed reconcile.
|
|
740
|
+
return { confirmed: false, blocking: true };
|
|
693
741
|
}
|
|
694
742
|
}
|
|
695
743
|
async function collectFileDiagnosticResult(file, severity, lspService, waitMs, nextWriteIndex, serverScope = "all",
|
|
@@ -703,7 +751,11 @@ cacheCtx, scopeKey,
|
|
|
703
751
|
// `allowBlocking(cwd)` for a scan-reconciled aux finding — defaults to
|
|
704
752
|
// `process.cwd()` for any call site that predates this (there are none
|
|
705
753
|
// today besides the two below, both of which now pass it explicitly).
|
|
706
|
-
cwd = process.cwd()
|
|
754
|
+
cwd = process.cwd(),
|
|
755
|
+
// #1561: see `createLspDiagnosticsTool`'s parameter doc. Called only for a
|
|
756
|
+
// FRESH observation — never on the cache-hit replay below, whose `rawDiags`
|
|
757
|
+
// are an OLD observation (#1093) and therefore no evidence about now.
|
|
758
|
+
onConfirmedNoBlockers) {
|
|
707
759
|
// Reserve the ordering token when this diagnostic operation starts, not when
|
|
708
760
|
// its LSP promise settles. A slower old result must not receive a newer token
|
|
709
761
|
// merely because it completed later (#1198).
|
|
@@ -725,8 +777,13 @@ cwd = process.cwd()) {
|
|
|
725
777
|
// NOT served — fall through to a fresh touch instead of replaying a stale
|
|
726
778
|
// cached result. "unknown"/true bindings serve as before.
|
|
727
779
|
if (cached && cached.binding.boundToCurrentDisk !== false) {
|
|
728
|
-
const filteredDiags = applySeverityFilter(cached.diagnostics, severity);
|
|
729
780
|
const confirmation = cached.diagnostics.length === 0 ? "clean" : undefined;
|
|
781
|
+
// #1645 review F3: a cache REPLAY writes the widget store exactly like a
|
|
782
|
+
// fresh touch does, so it gets the same demotion. Without this, replaying
|
|
783
|
+
// yesterday's cached blocker would re-cement an orphan file as blocking
|
|
784
|
+
// after mode=full had demoted it.
|
|
785
|
+
const cachedDiags = await demoteInferredForFile(file, cached.diagnostics, cwd, lspService);
|
|
786
|
+
const filteredDiags = applySeverityFilter(cachedDiags, severity);
|
|
730
787
|
// #692: cached.diagnostics were already suppression-/skipTestFiles-
|
|
731
788
|
// filtered at write time (this same code path); no file content was
|
|
732
789
|
// cached alongside them, so `undefined` here is a safe re-check, not
|
|
@@ -736,7 +793,7 @@ cwd = process.cwd()) {
|
|
|
736
793
|
// now(), or a repeat check that only re-serves the cache would keep
|
|
737
794
|
// re-arming the mtime-staleness gate and a resolved finding would render
|
|
738
795
|
// forever (the #1092 defect).
|
|
739
|
-
reconcileWidgetFromLspResult(file,
|
|
796
|
+
reconcileWidgetFromLspResult(file, cachedDiags, confirmation, writeIndex, cwd, undefined,
|
|
740
797
|
// This branch only runs when the cache binding is not a mismatch
|
|
741
798
|
// (guarded above), so boundMismatch is false; #1093's observedAt is
|
|
742
799
|
// the cache entry's original scan time.
|
|
@@ -789,7 +846,8 @@ cwd = process.cwd()) {
|
|
|
789
846
|
const boundMismatch = binding?.boundToCurrentDisk === false;
|
|
790
847
|
if (boundMismatch)
|
|
791
848
|
confirmation = "unconfirmed";
|
|
792
|
-
// #1470: an auxiliary cut off by the aux grace timer
|
|
849
|
+
// #1470/#1493: an auxiliary that never reported — cut off by the aux grace timer,
|
|
850
|
+
// or silent with nothing published for this content — contributed no evidence
|
|
793
851
|
// about this file, so a "clean" verdict computed from the merged result would
|
|
794
852
|
// be claiming coverage this batch does not have. Demote it — that also keeps
|
|
795
853
|
// the entry out of the workspace cache below, which would otherwise replay the
|
|
@@ -797,8 +855,18 @@ cwd = process.cwd()) {
|
|
|
797
855
|
if (unconfirmedServerIds.length > 0 && confirmation === "clean") {
|
|
798
856
|
confirmation = "unconfirmed";
|
|
799
857
|
}
|
|
858
|
+
// #1645 review F3: one demotion rule for every writer of the widget store.
|
|
859
|
+
effectiveRawDiags = await demoteInferredForFile(file, effectiveRawDiags, cwd, lspService);
|
|
800
860
|
const filteredDiags = applySeverityFilter(effectiveRawDiags, severity);
|
|
801
|
-
reconcileWidgetFromLspResult(file, effectiveRawDiags, confirmation, writeIndex, cwd, collectedContent, boundMismatch);
|
|
861
|
+
const verdict = reconcileWidgetFromLspResult(file, effectiveRawDiags, confirmation, writeIndex, cwd, collectedContent, boundMismatch);
|
|
862
|
+
if (verdict.confirmed && !verdict.blocking) {
|
|
863
|
+
onConfirmedNoBlockers?.({
|
|
864
|
+
filePath: file,
|
|
865
|
+
writeIndex,
|
|
866
|
+
coveredSources: coveredSourcesForCheck(file, serverScope, unconfirmedServerIds),
|
|
867
|
+
cwd,
|
|
868
|
+
});
|
|
869
|
+
}
|
|
802
870
|
// #671: only a CONFIRMED outcome ("clean", or a non-empty result — either
|
|
803
871
|
// is definitionally confirmed per this function's own doctrine above) is
|
|
804
872
|
// safe to cache; "unconfirmed" (timeout OR a silent-tier server's
|
|
@@ -806,7 +874,10 @@ cwd = process.cwd()) {
|
|
|
806
874
|
// result — same false-clean bug class `runWorkspaceDiagnostics`'s cache
|
|
807
875
|
// wiring guards against. #1095: the entry carries the content fingerprint so a
|
|
808
876
|
// later lookup can verify it against disk beyond the mtime proxy.
|
|
809
|
-
if (cacheCtx &&
|
|
877
|
+
if (cacheCtx &&
|
|
878
|
+
scopeKey !== undefined &&
|
|
879
|
+
confirmation !== "unconfirmed" &&
|
|
880
|
+
unconfirmedServerIds.length === 0) {
|
|
810
881
|
cacheCtx.record(file, scopeKey, effectiveRawDiags, stat.mtimeMs, collectedContent !== undefined
|
|
811
882
|
? hashDiagnosticContent(collectedContent)
|
|
812
883
|
: undefined);
|
|
@@ -820,7 +891,10 @@ cwd = process.cwd()) {
|
|
|
820
891
|
primaryServerId: primaryServerId(file),
|
|
821
892
|
};
|
|
822
893
|
}
|
|
823
|
-
async function runFileDiagnostics(absPath, severity, lspService, waitMs, nextWriteIndex, serverScope = "all", cwd = process.cwd()
|
|
894
|
+
async function runFileDiagnostics(absPath, severity, lspService, waitMs, nextWriteIndex, serverScope = "all", cwd = process.cwd(),
|
|
895
|
+
// #1561: see `createLspDiagnosticsTool`'s parameter doc. This is the path the
|
|
896
|
+
// live incident took (`mode: "file"`).
|
|
897
|
+
onConfirmedNoBlockers) {
|
|
824
898
|
// Reserve the token before awaiting this file's LSP result. The direct-file
|
|
825
899
|
// path performs its own confirmation/reconciliation below (#1198).
|
|
826
900
|
const writeIndex = nextWriteIndex?.();
|
|
@@ -866,21 +940,36 @@ async function runFileDiagnostics(absPath, severity, lspService, waitMs, nextWri
|
|
|
866
940
|
const boundMismatch = binding?.boundToCurrentDisk === false;
|
|
867
941
|
if (boundMismatch)
|
|
868
942
|
confirmation = "unconfirmed";
|
|
869
|
-
// #1470: NARROWED, not collapsed. An auxiliary
|
|
870
|
-
//
|
|
871
|
-
//
|
|
943
|
+
// #1470/#1493: NARROWED, not collapsed. An auxiliary that never reported — the aux
|
|
944
|
+
// grace timer cut it off, or it stayed silent with nothing published for this
|
|
945
|
+
// content — makes the FILE-level verdict unconfirmed. The merged result is missing
|
|
946
|
+
// whatever that scanner would have said, and this tool is the security lane's read surface. The
|
|
872
947
|
// PRIMARY's own verdict is untouched (`primaryCoverageGapOnly` below), so a
|
|
873
948
|
// TypeScript answer stays "confirmed clean" on its own line while an explicit
|
|
874
949
|
// line names the scanner whose coverage is absent.
|
|
875
950
|
const primaryCoverageGapOnly = unconfirmedServerIds.length > 0 && confirmation === "clean";
|
|
876
951
|
if (primaryCoverageGapOnly)
|
|
877
952
|
confirmation = "unconfirmed";
|
|
953
|
+
// #1645 review F3: one demotion rule for every writer of the widget store.
|
|
954
|
+
effectiveRawDiags = await demoteInferredForFile(absPath, effectiveRawDiags, cwd, lspService);
|
|
878
955
|
const filtered = applySeverityFilter(effectiveRawDiags, severity);
|
|
879
956
|
const total = filtered.length;
|
|
880
957
|
const truncated = total > MAX_DIAGNOSTICS;
|
|
881
958
|
const limited = truncated ? filtered.slice(0, MAX_DIAGNOSTICS) : filtered;
|
|
882
959
|
const unconfirmed = confirmation === "unconfirmed";
|
|
883
|
-
reconcileWidgetFromLspResult(absPath, effectiveRawDiags, confirmation, writeIndex, cwd, collectedContent, boundMismatch);
|
|
960
|
+
const verdict = reconcileWidgetFromLspResult(absPath, effectiveRawDiags, confirmation, writeIndex, cwd, collectedContent, boundMismatch);
|
|
961
|
+
// #1561: a confirmed current view with nothing at the blocking tier retires
|
|
962
|
+
// this file's stale inline blocker — the store #571 corrected the footer for
|
|
963
|
+
// but never reached, which is how a resolved cross-file finding kept being
|
|
964
|
+
// injected as "Unresolved from this turn" for the rest of the session.
|
|
965
|
+
if (verdict.confirmed && !verdict.blocking) {
|
|
966
|
+
onConfirmedNoBlockers?.({
|
|
967
|
+
filePath: absPath,
|
|
968
|
+
writeIndex,
|
|
969
|
+
coveredSources: coveredSourcesForCheck(absPath, serverScope, unconfirmedServerIds),
|
|
970
|
+
cwd,
|
|
971
|
+
});
|
|
972
|
+
}
|
|
884
973
|
const primaryId = primaryServerId(absPath);
|
|
885
974
|
const primaryDiags = limited.filter((d) => d.source === primaryId);
|
|
886
975
|
const auxiliaryDiags = limited.filter((d) => d.source !== primaryId);
|
|
@@ -1078,7 +1167,7 @@ async function collectBatchDiagnostics(files, severity, lspService, options) {
|
|
|
1078
1167
|
const cacheCtx = createWorkspaceDiagnosticsCacheContext(resolvedCwd);
|
|
1079
1168
|
const scopeKey = buildScopeKey(options.serverScope ?? "all");
|
|
1080
1169
|
const results = await mapWithConcurrency(files, options.concurrency, async (file) => {
|
|
1081
|
-
const work = collectFileDiagnosticResult(file, severity, lspService, options.waitMs, options.nextWriteIndex, options.serverScope, cacheCtx, scopeKey, resolvedCwd);
|
|
1170
|
+
const work = collectFileDiagnosticResult(file, severity, lspService, options.waitMs, options.nextWriteIndex, options.serverScope, cacheCtx, scopeKey, resolvedCwd, options.onConfirmedNoBlockers);
|
|
1082
1171
|
const bounded = withDeadline(work, {
|
|
1083
1172
|
ms: batchFileDeadlineMs(),
|
|
1084
1173
|
onTimeout: "undefined",
|
|
@@ -9,9 +9,10 @@ import { fileURLToPath, pathToFileURL } from "node:url";
|
|
|
9
9
|
import { Type } from "../clients/deps/typebox.js";
|
|
10
10
|
import { logLatency } from "../clients/latency-logger.js";
|
|
11
11
|
import { newLspMutationCorrelationId, recordLspMutationOutcome, } from "../clients/lsp-mutation.js";
|
|
12
|
+
import { uriToPath } from "../clients/path-utils.js";
|
|
12
13
|
import { compactRenderResult } from "./render-compact.js";
|
|
13
14
|
import { applyWorkspaceEdit, summarizeWorkspaceEdit, } from "../clients/lsp/edits.js";
|
|
14
|
-
import { getLSPService } from "../clients/lsp/index.js";
|
|
15
|
+
import { getLSPService, } from "../clients/lsp/index.js";
|
|
15
16
|
import { buildLspNavigationEnvelope } from "./lsp-structured-output.js";
|
|
16
17
|
import { SYMBOL_KIND_NAMES } from "../clients/lsp-document-symbols.js";
|
|
17
18
|
const VALID_OPERATIONS = [
|
|
@@ -678,6 +679,7 @@ getFlag, mutationDeps) {
|
|
|
678
679
|
let columnResolution;
|
|
679
680
|
let mutationContext;
|
|
680
681
|
let requestedApply = false;
|
|
682
|
+
const workspaceScopeAttribution = {};
|
|
681
683
|
const finalize = (payload, meta) => {
|
|
682
684
|
if (payload.isError &&
|
|
683
685
|
requestedApply &&
|
|
@@ -698,6 +700,9 @@ getFlag, mutationDeps) {
|
|
|
698
700
|
supported,
|
|
699
701
|
diagnosticsMode,
|
|
700
702
|
columnResolution,
|
|
703
|
+
...(Object.keys(workspaceScopeAttribution).length > 0
|
|
704
|
+
? { workspaceScopeAttribution }
|
|
705
|
+
: {}),
|
|
701
706
|
},
|
|
702
707
|
});
|
|
703
708
|
const text = payload.content[0]?.text ?? "";
|
|
@@ -821,7 +826,9 @@ getFlag, mutationDeps) {
|
|
|
821
826
|
}
|
|
822
827
|
const lspService = getLSPService();
|
|
823
828
|
if (operation === "capabilities") {
|
|
824
|
-
const snapshots =
|
|
829
|
+
const snapshots = rawPath
|
|
830
|
+
? await lspService.getCapabilitySnapshots(filePath)
|
|
831
|
+
: await lspService.getCapabilitySnapshots(undefined, workspaceScopeAttribution);
|
|
825
832
|
const output = formatCapabilities(snapshots, rawPath ? filePath : undefined);
|
|
826
833
|
return finalize({
|
|
827
834
|
content: [{ type: "text", text: output }],
|
|
@@ -838,7 +845,9 @@ getFlag, mutationDeps) {
|
|
|
838
845
|
});
|
|
839
846
|
}
|
|
840
847
|
if (operation === "workspaceDiagnostics") {
|
|
841
|
-
const wsDiagSupport =
|
|
848
|
+
const wsDiagSupport = rawPath
|
|
849
|
+
? await lspService.getWorkspaceDiagnosticsSupport(filePath)
|
|
850
|
+
: await lspService.getWorkspaceDiagnosticsSupport(undefined, workspaceScopeAttribution);
|
|
842
851
|
diagnosticsMode = wsDiagSupport?.mode ?? "unknown";
|
|
843
852
|
if (rawPath && !filePathIsDirectory) {
|
|
844
853
|
const hasLSP = lspService.supportsLSP(filePath);
|
|
@@ -1007,7 +1016,10 @@ getFlag, mutationDeps) {
|
|
|
1007
1016
|
const lspEndLine = (endLine ?? line ?? 1) - 1;
|
|
1008
1017
|
const lspEndChar = (endCharacter ?? resolvedCharacter.character) - 1;
|
|
1009
1018
|
const runWorkspaceSymbolOperation = async () => {
|
|
1010
|
-
|
|
1019
|
+
const support = rawPath
|
|
1020
|
+
? await lspService.getOperationSupport(filePath)
|
|
1021
|
+
: await lspService.getOperationSupport(undefined, workspaceScopeAttribution);
|
|
1022
|
+
supported = operationSupportStatus(operation, support);
|
|
1011
1023
|
if (supported === false) {
|
|
1012
1024
|
throw new Error("__UNSUPPORTED__ Active LSP server does not advertise support for workspaceSymbol");
|
|
1013
1025
|
}
|
|
@@ -1018,7 +1030,9 @@ getFlag, mutationDeps) {
|
|
|
1018
1030
|
await openFileBestEffort(lspService, filePath);
|
|
1019
1031
|
}
|
|
1020
1032
|
try {
|
|
1021
|
-
const raw =
|
|
1033
|
+
const raw = rawPath
|
|
1034
|
+
? await lspService.workspaceSymbol(query ?? "", filePath)
|
|
1035
|
+
: await lspService.workspaceSymbol(query ?? "", undefined, workspaceScopeAttribution);
|
|
1022
1036
|
const filtered = (Array.isArray(raw) ? raw : [raw]).filter((s) => typeof s === "object" &&
|
|
1023
1037
|
s !== null &&
|
|
1024
1038
|
(!s.kind || NAVIGABLE_SYMBOL_KINDS.has(s.kind)));
|
|
@@ -1127,7 +1141,9 @@ getFlag, mutationDeps) {
|
|
|
1127
1141
|
if (!command || command.trim().length === 0) {
|
|
1128
1142
|
throw new Error("__BADINPUT__ command parameter required for executeCommand");
|
|
1129
1143
|
}
|
|
1130
|
-
const advertised =
|
|
1144
|
+
const advertised = rawPath
|
|
1145
|
+
? await lspService.getAdvertisedCommands(filePath)
|
|
1146
|
+
: await lspService.getAdvertisedCommands(undefined, workspaceScopeAttribution);
|
|
1131
1147
|
const isAdvertised = advertised.includes(command);
|
|
1132
1148
|
// Dry-run by default: report advertisement status without running.
|
|
1133
1149
|
// Mutation only on explicit apply:true (and the client re-checks
|
|
@@ -1147,18 +1163,41 @@ getFlag, mutationDeps) {
|
|
|
1147
1163
|
if (!isAdvertised) {
|
|
1148
1164
|
throw new Error(`__UNSUPPORTED__ command "${command}" is not advertised by the active LSP server (advertised: ${advertised.join(", ") || "none"})`);
|
|
1149
1165
|
}
|
|
1150
|
-
return
|
|
1166
|
+
return rawPath
|
|
1167
|
+
? lspService.executeCommand(filePath, command, commandArguments, mutationContext)
|
|
1168
|
+
: lspService.executeCommand(undefined, command, commandArguments, mutationContext, workspaceScopeAttribution);
|
|
1151
1169
|
}
|
|
1152
1170
|
case "incomingCalls": {
|
|
1153
1171
|
if (!callHierarchyItem) {
|
|
1154
1172
|
throw new Error("__BADINPUT__ callHierarchyItem parameter required for incomingCalls");
|
|
1155
1173
|
}
|
|
1174
|
+
// #1803 fix-round F1: needsFilePath is false for call-hierarchy
|
|
1175
|
+
// traversal (the operand is callHierarchyItem, not path), so the
|
|
1176
|
+
// shared needsFilePath pre-check at line ~1319 never runs for
|
|
1177
|
+
// this operation — LSPService.incomingCalls' own capability gate
|
|
1178
|
+
// (clients/lsp/index.ts) returns a bare [], which this tool layer
|
|
1179
|
+
// cannot distinguish from "supported server, zero callers found".
|
|
1180
|
+
// Pre-check here, keyed off the item's own uri (the file the
|
|
1181
|
+
// resolved server is scoped to), mirrors
|
|
1182
|
+
// runWorkspaceSymbolOperation's supported-check above: throwing
|
|
1183
|
+
// __UNSUPPORTED__ routes through the catch block below into the
|
|
1184
|
+
// same discriminated isError:true/emptyReason:"unsupported" shape
|
|
1185
|
+
// every other capability-gated operation already reports.
|
|
1186
|
+
supported = operationSupportStatus(operation, await lspService.getOperationSupport(uriToPath(callHierarchyItem.uri)));
|
|
1187
|
+
if (supported === false) {
|
|
1188
|
+
throw new Error("__UNSUPPORTED__ Active LSP server does not advertise support for incomingCalls");
|
|
1189
|
+
}
|
|
1156
1190
|
return lspService.incomingCalls(callHierarchyItem);
|
|
1157
1191
|
}
|
|
1158
1192
|
case "outgoingCalls": {
|
|
1159
1193
|
if (!callHierarchyItem) {
|
|
1160
1194
|
throw new Error("__BADINPUT__ callHierarchyItem parameter required for outgoingCalls");
|
|
1161
1195
|
}
|
|
1196
|
+
// #1803 fix-round F1: same pre-check as incomingCalls above.
|
|
1197
|
+
supported = operationSupportStatus(operation, await lspService.getOperationSupport(uriToPath(callHierarchyItem.uri)));
|
|
1198
|
+
if (supported === false) {
|
|
1199
|
+
throw new Error("__UNSUPPORTED__ Active LSP server does not advertise support for outgoingCalls");
|
|
1200
|
+
}
|
|
1162
1201
|
return lspService.outgoingCalls(callHierarchyItem);
|
|
1163
1202
|
}
|
|
1164
1203
|
default:
|
|
@@ -95,7 +95,7 @@ not clean**:
|
|
|
95
95
|
| **`unconfirmed`** | A push-only/silent-on-clean LSP server returned empty; emptiness could not be *proven* clean. | Don't report the file as clean. |
|
|
96
96
|
| **`cold` (not applicable / unavailable this run)** | A heavyweight analyzer (knip/jscpd/madge/gitleaks/govulncheck/trivy/dead-code) didn't contribute. | Don't fold its silence into "no issues." |
|
|
97
97
|
| **`partial` / `truncated` / file-cap** | A walk/scan hit a file cap or coverage limit; results are a partial view. | Don't treat as whole-project coverage. |
|
|
98
|
-
| **`stale`** | A cached diagnostic's file changed on disk since the scan. | Don't trust the stale value. |
|
|
98
|
+
| **`stale`** | A cached diagnostic's file changed on disk since the scan. Secrets findings demote to `🔑 ACTION NEEDED` advisory with the line number withheld, never silently dropped; govulncheck keeps the CVE and drops only the cached line. | Don't trust the stale value or its line number. Re-scan to confirm. |
|
|
99
99
|
| **cold-LSP `0` (e.g. MCP `fresh` mode)** | LSP cold-spawned and under-reported; a `0` carries an explicit `lsp` signal. | Don't read the `0` as "clean." |
|
|
100
100
|
| **unsafe root** | cwd resolved at/above `$HOME`, so scanners were skipped. | Re-run from inside the project. |
|
|
101
101
|
|
|
@@ -113,6 +113,11 @@ is blocking when `semantic === "blocking"`, else it falls back to severity):
|
|
|
113
113
|
|
|
114
114
|
- **🔴 Blocking** — a hard stop. Secrets, CRITICAL CVEs, unresolved errors, etc.
|
|
115
115
|
**Resolve every blocker before you consider the work complete.**
|
|
116
|
+
- **🔑 ACTION NEEDED** — a third tier, distinct from both: a secrets finding
|
|
117
|
+
whose cached file changed since the scan. It does not gate commit-guard like
|
|
118
|
+
a blocker does, but it is not "no action required" like an advisory either —
|
|
119
|
+
the finding is unverified, not dismissed. Re-run a secrets scan to confirm
|
|
120
|
+
or clear it.
|
|
116
121
|
- **Advisory** — informational (🟡 warnings, 📜 license notes, style/hygiene).
|
|
117
122
|
Address when relevant; they do not gate completion.
|
|
118
123
|
|