@herbertgao/pi-extensions 2026.8.6 → 2026.8.8
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 +8 -6
- package/node_modules/@herbertgao/pi-cc-extensions/README.en.md +2 -2
- package/node_modules/@herbertgao/pi-cc-extensions/README.md +2 -2
- 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 +320 -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 +79 -17
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/mouse/hover.ts +27 -0
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/mouse/interaction.ts +66 -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 +5 -4
- package/node_modules/@juicesharp/rpiv-ask-user-question/ask-user-question.ts +174 -100
- 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 +5 -1
- package/node_modules/@juicesharp/rpiv-ask-user-question/docs/keyboard.md +10 -2
- package/node_modules/@juicesharp/rpiv-ask-user-question/docs/localization.md +10 -6
- package/node_modules/@juicesharp/rpiv-ask-user-question/docs/tool-schema.md +11 -5
- package/node_modules/@juicesharp/rpiv-ask-user-question/locales/en.json +5 -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 +140 -97
- package/node_modules/@juicesharp/rpiv-ask-user-question/state/questionnaire-session.ts +63 -28
- package/node_modules/@juicesharp/rpiv-ask-user-question/state/selectors/projections.ts +22 -15
- package/node_modules/@juicesharp/rpiv-ask-user-question/state/state-reducer.ts +11 -1
- package/node_modules/@juicesharp/rpiv-ask-user-question/state/state.ts +14 -6
- package/node_modules/@juicesharp/rpiv-ask-user-question/tool/response-envelope.ts +11 -0
- package/node_modules/@juicesharp/rpiv-ask-user-question/tool/types.ts +11 -0
- package/node_modules/@juicesharp/rpiv-ask-user-question/view/components/multi-select-view.ts +31 -17
- package/node_modules/@juicesharp/rpiv-ask-user-question/view/components/preview/preview-block-renderer.ts +15 -6
- package/node_modules/@juicesharp/rpiv-ask-user-question/view/components/wrapping-select.ts +15 -6
- package/node_modules/@juicesharp/rpiv-ask-user-question/view/dialog-builder.ts +86 -38
- package/node_modules/@juicesharp/rpiv-ask-user-question/view/tab-content-strategy.ts +76 -9
- 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-plugins/fast-mode/dist/index.mjs +44 -1856
- package/node_modules/@pi-plugins/fast-mode/dist/index.mjs.map +1 -1
- package/node_modules/@pi-plugins/fast-mode/package.json +4 -6
- package/node_modules/pi-lens/CHANGELOG.md +999 -0
- package/node_modules/pi-lens/README.md +117 -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 +381 -13
- 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 +129 -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 +206 -0
- package/node_modules/pi-lens/dist/clients/cache-observability.js +353 -76
- 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 +84 -14
- package/node_modules/pi-lens/dist/clients/demoted-finding-render.js +155 -0
- package/node_modules/pi-lens/dist/clients/dependency-checker.js +25 -3
- package/node_modules/pi-lens/dist/clients/deps/pi-tui.js +8 -2
- package/node_modules/pi-lens/dist/clients/deps/typebox.js +8 -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/detekt.js +9 -6
- 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/hadolint.js +9 -7
- package/node_modules/pi-lens/dist/clients/dispatch/runners/helm-render.js +895 -0
- package/node_modules/pi-lens/dist/clients/dispatch/runners/htmlhint.js +8 -6
- 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 -2
- package/node_modules/pi-lens/dist/clients/dispatch/runners/mypy.js +25 -2
- package/node_modules/pi-lens/dist/clients/dispatch/runners/oxlint.js +20 -5
- package/node_modules/pi-lens/dist/clients/dispatch/runners/phpstan.js +44 -11
- 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 +17 -8
- package/node_modules/pi-lens/dist/clients/dispatch/runners/sqlfluff.js +32 -4
- package/node_modules/pi-lens/dist/clients/dispatch/runners/stylelint.js +47 -3
- package/node_modules/pi-lens/dist/clients/dispatch/runners/swiftlint.js +14 -4
- package/node_modules/pi-lens/dist/clients/dispatch/runners/taplo.js +127 -28
- package/node_modules/pi-lens/dist/clients/dispatch/runners/tflint.js +12 -7
- 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 +188 -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 +21 -10
- package/node_modules/pi-lens/dist/clients/dispatch/runners/yamllint.js +18 -2
- 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 +316 -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 +87 -8
- 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 +9 -2
- 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 +128 -8
- package/node_modules/pi-lens/dist/clients/lsp/client.js +1660 -164
- 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 +2423 -151
- 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 +22 -1
- package/node_modules/pi-lens/dist/clients/ndjson-logger.js +114 -23
- 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 +23 -9
- package/node_modules/pi-lens/dist/clients/project-lens-config.js +3 -0
- package/node_modules/pi-lens/dist/clients/project-report.js +62 -27
- 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 +8 -3
- package/node_modules/pi-lens/dist/clients/read-guard.js +253 -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/builder.js +194 -31
- package/node_modules/pi-lens/dist/clients/review-graph/query.js +52 -4
- package/node_modules/pi-lens/dist/clients/review-graph/revision-drift.js +21 -0
- package/node_modules/pi-lens/dist/clients/review-graph/workspace-modules.js +6 -3
- 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 +352 -45
- package/node_modules/pi-lens/dist/clients/runtime-session.js +373 -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 +620 -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/session-event-guard.js +184 -0
- 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/source-filter.js +6 -2
- package/node_modules/pi-lens/dist/clients/stale-marker.js +17 -0
- package/node_modules/pi-lens/dist/clients/startup-scan.js +5 -2
- 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-logger.js +1 -0
- 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 +61407 -48577
- package/node_modules/pi-lens/dist/tools/lens-diagnostics.js +476 -57
- 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 +27 -10
- 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/scripts/install-selftest.mjs +99 -11
- package/node_modules/pi-lens/scripts/lib/host-provided-deps.mjs +75 -0
- package/node_modules/pi-lens/scripts/lib/warm-loader-cache.mjs +285 -0
- package/node_modules/pi-lens/scripts/warm-loader-cache.mjs +233 -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 +37 -0
- package/node_modules/pi-web-access/README.md +32 -13
- 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/chrome-cookies.ts +86 -15
- 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/data-uri-sanitize.ts +406 -0
- package/node_modules/pi-web-access/exa.ts +18 -7
- package/node_modules/pi-web-access/extract.ts +40 -5
- package/node_modules/pi-web-access/firecrawl.ts +18 -2
- package/node_modules/pi-web-access/gemini-search.ts +16 -4
- package/node_modules/pi-web-access/github-extract.ts +65 -36
- package/node_modules/pi-web-access/index.ts +60 -61
- package/node_modules/pi-web-access/openai-search.ts +17 -6
- 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/pdf-extract.ts +18 -5
- 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/ssrf-protection.ts +12 -2
- 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 +14 -14
|
@@ -3,7 +3,7 @@ import { safeSpawnAsync } from "../../safe-spawn.js";
|
|
|
3
3
|
import { getLinterPolicyForCwd } from "../../tool-policy.js";
|
|
4
4
|
import { PRIORITY } from "../priorities.js";
|
|
5
5
|
import { createAvailabilityChecker, resolveToolCommandWithInstallFallback, } from "./utils/runner-helpers.js";
|
|
6
|
-
import {
|
|
6
|
+
import { parseToolRun } from "./utils/tool-failure.js";
|
|
7
7
|
const htmlhint = createAvailabilityChecker("htmlhint");
|
|
8
8
|
const HTMLHINT_RULES = {
|
|
9
9
|
"tag-pair": true,
|
|
@@ -55,7 +55,7 @@ const htmlhintRunner = {
|
|
|
55
55
|
return { status: "skipped", diagnostics: [], semantic: "none" };
|
|
56
56
|
}
|
|
57
57
|
let cmd = null;
|
|
58
|
-
if (await
|
|
58
|
+
if (await htmlhint.isAvailableAsync(cwd)) {
|
|
59
59
|
cmd = htmlhint.getCommand(cwd);
|
|
60
60
|
}
|
|
61
61
|
else {
|
|
@@ -72,11 +72,13 @@ const htmlhintRunner = {
|
|
|
72
72
|
"unix",
|
|
73
73
|
path.resolve(cwd, ctx.filePath),
|
|
74
74
|
], { cwd });
|
|
75
|
+
// #1948: htmlhint exits 1 when it finds errors and prints them in `unix`
|
|
76
|
+
// format on stdout. Zero parsed out of a nonzero exit is a parser break.
|
|
75
77
|
const output = result.stdout || result.stderr || "";
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
const diagnostics =
|
|
78
|
+
const run = parseToolRun("htmlhint", { result, output }, (out) => parseHtmlhintOutput(out, ctx.filePath));
|
|
79
|
+
if (run.skipped)
|
|
80
|
+
return run.skipped;
|
|
81
|
+
const diagnostics = run.diagnostics;
|
|
80
82
|
if (diagnostics.length === 0) {
|
|
81
83
|
return { status: "succeeded", diagnostics: [], semantic: "none" };
|
|
82
84
|
}
|
|
@@ -6,6 +6,7 @@ import astGrepNapiRunner from "./ast-grep-napi.js";
|
|
|
6
6
|
import biomeCheckJsonRunner from "./biome-check.js";
|
|
7
7
|
import cppCheckRunner from "./cpp-check.js";
|
|
8
8
|
import credoRunner from "./credo.js";
|
|
9
|
+
import cueVetRunner from "./cue-vet.js";
|
|
9
10
|
import dartAnalyzeRunner from "./dart-analyze.js";
|
|
10
11
|
import detektRunner from "./detekt.js";
|
|
11
12
|
import dotnetBuildRunner from "./dotnet-build.js";
|
|
@@ -17,6 +18,7 @@ import goVetRunner from "./go-vet.js";
|
|
|
17
18
|
import golangciRunner from "./golangci-lint.js";
|
|
18
19
|
import hadolintRunner from "./hadolint.js";
|
|
19
20
|
import helmLintRunner from "./helm-lint.js";
|
|
21
|
+
import helmRenderRunner from "./helm-render.js";
|
|
20
22
|
import htmlhintRunner from "./htmlhint.js";
|
|
21
23
|
import javacRunner from "./javac.js";
|
|
22
24
|
import ktlintRunner from "./ktlint.js";
|
|
@@ -84,6 +86,7 @@ export function registerDefaultRunners(registry) {
|
|
|
84
86
|
registry.register(htmlhintRunner); // HTML linting — tag pairs, attribute rules (priority 20)
|
|
85
87
|
registry.register(hadolintRunner); // Dockerfile linting — syntax, best practices (priority 20)
|
|
86
88
|
registry.register(helmLintRunner); // Helm chart linting (priority 20)
|
|
89
|
+
registry.register(helmRenderRunner); // Rendered-manifest validation (priority 20, helm.renderValidation.enabled-gated, off by default)
|
|
87
90
|
registry.register(valeRunner); // Prose/style linting for Markdown — config-gated (.vale.ini) (priority 30)
|
|
88
91
|
registry.register(phpLintRunner); // PHP syntax validation via php -l (priority 20)
|
|
89
92
|
registry.register(psScriptAnalyzerRunner); // PowerShell linting via PSScriptAnalyzer module (priority 20)
|
|
@@ -103,4 +106,5 @@ export function registerDefaultRunners(registry) {
|
|
|
103
106
|
registry.register(credoRunner); // Elixir static analysis via credo (priority 20, mix.exs-gated)
|
|
104
107
|
registry.register(elixirCheckRunner); // Elixir compile/syntax diagnostics via mix/elixirc (priority 20)
|
|
105
108
|
registry.register(phpstanRunner); // PHP static analysis via phpstan (priority 20, config-gated)
|
|
109
|
+
registry.register(cueVetRunner); // CUE evaluation-error validation via cue vet (priority 20) — covers the class cuelsp doesn't publish
|
|
106
110
|
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import * as path from "node:path";
|
|
2
2
|
import { safeSpawnAsync } from "../../safe-spawn.js";
|
|
3
|
+
import { hasJavaBuildDescriptor } from "../../tool-policy.js";
|
|
3
4
|
import { PRIORITY } from "../priorities.js";
|
|
4
5
|
import { createAvailabilityChecker } from "./utils/runner-helpers.js";
|
|
5
6
|
const javac = createAvailabilityChecker("javac", ".exe");
|
|
@@ -24,7 +25,9 @@ function parseJavacOutput(raw, filePath) {
|
|
|
24
25
|
line: lineNum,
|
|
25
26
|
column: 1,
|
|
26
27
|
severity,
|
|
27
|
-
|
|
28
|
+
// A standalone single-file javac run has no project classpath. It can
|
|
29
|
+
// report useful syntax/type evidence, but it cannot prove a blocker.
|
|
30
|
+
semantic: "warning",
|
|
28
31
|
tool: "javac",
|
|
29
32
|
rule: "compile",
|
|
30
33
|
fixable: false,
|
|
@@ -40,6 +43,17 @@ const javacRunner = {
|
|
|
40
43
|
skipTestFiles: false,
|
|
41
44
|
async run(ctx) {
|
|
42
45
|
const cwd = ctx.cwd || process.cwd();
|
|
46
|
+
const absPath = path.resolve(cwd, ctx.filePath);
|
|
47
|
+
// Inside a Maven/Gradle project a classpath-less single-file compile
|
|
48
|
+
// cannot produce a valid verdict: every non-JDK import becomes a
|
|
49
|
+
// "package does not exist" error, and the fallback turns those into
|
|
50
|
+
// false blocking diagnostics (#1877). jdtls owns those projects; this
|
|
51
|
+
// runner keeps its value for standalone files with no build descriptor.
|
|
52
|
+
// Same shared descriptor walk the SpotBugs gate uses.
|
|
53
|
+
if (hasJavaBuildDescriptor(path.dirname(absPath), ctx.projectRoot ?? ctx.cwd)) {
|
|
54
|
+
ctx.log?.("javac: skipped — file is inside a Maven/Gradle project; a classpath-less compile would emit false positives");
|
|
55
|
+
return { status: "skipped", diagnostics: [], semantic: "none" };
|
|
56
|
+
}
|
|
43
57
|
if (!(await (javac.isAvailableAsync(cwd)))) {
|
|
44
58
|
return { status: "skipped", diagnostics: [], semantic: "none" };
|
|
45
59
|
}
|
|
@@ -47,7 +61,6 @@ const javacRunner = {
|
|
|
47
61
|
if (!cmd) {
|
|
48
62
|
return { status: "skipped", diagnostics: [], semantic: "none" };
|
|
49
63
|
}
|
|
50
|
-
const absPath = path.resolve(cwd, ctx.filePath);
|
|
51
64
|
const result = await safeSpawnAsync(cmd, ["-Xlint:none", "-proc:none", absPath], {
|
|
52
65
|
cwd,
|
|
53
66
|
timeout: 30000,
|
|
@@ -69,7 +82,7 @@ const javacRunner = {
|
|
|
69
82
|
return {
|
|
70
83
|
status: hasErrors ? "failed" : "succeeded",
|
|
71
84
|
diagnostics,
|
|
72
|
-
semantic:
|
|
85
|
+
semantic: "warning",
|
|
73
86
|
};
|
|
74
87
|
},
|
|
75
88
|
};
|
|
@@ -12,12 +12,14 @@
|
|
|
12
12
|
* unified runner that delegates to the LSP service.
|
|
13
13
|
*/
|
|
14
14
|
import { logExtension } from "../../extension-log.js";
|
|
15
|
+
import { getLspCapableKinds } from "../../language-policy.js";
|
|
15
16
|
import { touchCoverageGap } from "../../lsp/diagnostic-binding.js";
|
|
16
17
|
import { getLSPService } from "../../lsp/index.js";
|
|
17
18
|
import { RUNTIME_CONFIG } from "../../runtime-config.js";
|
|
18
19
|
import { PRIORITY } from "../priorities.js";
|
|
19
20
|
import { resolveRunnerPath } from "../runner-context.js";
|
|
20
21
|
import { convertLspDiagnostics } from "../utils/lsp-diagnostics.js";
|
|
22
|
+
import { demoteInferredProjectDiagnostics } from "../../lsp/inferred-project.js";
|
|
21
23
|
import { enabledAuxiliaryLspServerIds, retagAuxiliaryDiagnostics, } from "../auxiliary-lsp.js";
|
|
22
24
|
import { readFileContent } from "./utils.js";
|
|
23
25
|
import { tryWarmAttachedCodeActions, tryWarmAttachedDiagnostics, } from "../../warm-attach.js";
|
|
@@ -50,41 +52,11 @@ function buildCodeActionSuggestion(actions) {
|
|
|
50
52
|
}
|
|
51
53
|
const lspRunner = {
|
|
52
54
|
id: "lsp",
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
"ruby",
|
|
59
|
-
"cxx",
|
|
60
|
-
"cmake",
|
|
61
|
-
"shell",
|
|
62
|
-
"json",
|
|
63
|
-
"markdown",
|
|
64
|
-
"css",
|
|
65
|
-
"yaml",
|
|
66
|
-
"html",
|
|
67
|
-
"docker",
|
|
68
|
-
"php",
|
|
69
|
-
"powershell",
|
|
70
|
-
"prisma",
|
|
71
|
-
"csharp",
|
|
72
|
-
"fsharp",
|
|
73
|
-
"java",
|
|
74
|
-
"kotlin",
|
|
75
|
-
"swift",
|
|
76
|
-
"dart",
|
|
77
|
-
"lua",
|
|
78
|
-
"zig",
|
|
79
|
-
"haskell",
|
|
80
|
-
"elixir",
|
|
81
|
-
"gleam",
|
|
82
|
-
"ocaml",
|
|
83
|
-
"clojure",
|
|
84
|
-
"terraform",
|
|
85
|
-
"nix",
|
|
86
|
-
"toml",
|
|
87
|
-
],
|
|
55
|
+
// Derived from LANGUAGE_POLICY, never hand-maintained: the copy this
|
|
56
|
+
// replaced had drifted (fish was lspCapable but absent, so getForKind
|
|
57
|
+
// answered that no LSP runs on fish). Registering a language as lspCapable
|
|
58
|
+
// is now the only step this seam needs (#1545).
|
|
59
|
+
appliesTo: getLspCapableKinds(),
|
|
88
60
|
priority: PRIORITY.LSP_PRIMARY,
|
|
89
61
|
enabledByDefault: true,
|
|
90
62
|
async run(ctx) {
|
|
@@ -112,10 +84,12 @@ const lspRunner = {
|
|
|
112
84
|
// one spawned server) — an empty `lspDiags` in that case is NOT a
|
|
113
85
|
// confirmed clean result and must not be reported as one (#570).
|
|
114
86
|
let diagnosticsInconclusive = false;
|
|
115
|
-
// #1470: server ids the touch carries no evidence for — an auxiliary
|
|
116
|
-
// push wait our aux grace timer cut off
|
|
117
|
-
//
|
|
118
|
-
//
|
|
87
|
+
// #1470/#1493: server ids the touch carries no evidence for — an auxiliary
|
|
88
|
+
// whose push wait our aux grace timer cut off (#1470), or one that stayed
|
|
89
|
+
// silent with no stored publication for this content (#1493). The touch is
|
|
90
|
+
// NOT inconclusive (the primary answered, and its findings below are real),
|
|
91
|
+
// so this is tracked separately: the only claim it invalidates is "0
|
|
92
|
+
// diagnostics means clean".
|
|
119
93
|
let unconfirmedServerIds = [];
|
|
120
94
|
let usedWarmAttach = false;
|
|
121
95
|
let failureReason = "";
|
|
@@ -138,8 +112,9 @@ const lspRunner = {
|
|
|
138
112
|
// #1179 (shape-5 structural fix): both branches normalize to the
|
|
139
113
|
// `touchFile` wrapper shape. The warm-attach IPC branch resolves a plain
|
|
140
114
|
// diagnostics array — `available` no longer implies a fully confirmed
|
|
141
|
-
// answer: a `partial` confirmation (an auxiliary
|
|
142
|
-
//
|
|
115
|
+
// answer: a `partial` confirmation (an auxiliary that never
|
|
116
|
+
// reported — cut off by the grace timer, or silent) is served as
|
|
117
|
+
// `available: true` too (the IPC gate at
|
|
143
118
|
// `clients/mcp/ipc.ts:248` rejects only `inconclusive`). Carry the
|
|
144
119
|
// incumbent's `unconfirmedServerIds` onto the wrapper so
|
|
145
120
|
// `touchCoverageGap` below sees it — dropping it here is the same
|
|
@@ -228,18 +203,22 @@ const lspRunner = {
|
|
|
228
203
|
}
|
|
229
204
|
if (lspDiags.length === 0) {
|
|
230
205
|
if (unconfirmedServerIds.length > 0) {
|
|
231
|
-
// #1470: an auxiliary
|
|
232
|
-
//
|
|
233
|
-
//
|
|
234
|
-
//
|
|
235
|
-
//
|
|
236
|
-
//
|
|
237
|
-
//
|
|
238
|
-
// away: the primary answered with zero findings, so there is nothing to
|
|
206
|
+
// #1470/#1493: an auxiliary never reported — cut off by the aux grace
|
|
207
|
+
// timer, or silent with nothing published for this content — so this
|
|
208
|
+
// empty merged result is missing whatever that scanner would have said.
|
|
209
|
+
// A hung OR silent opengrep must not read as a clean bill of health on
|
|
210
|
+
// the security lane. The empty result remains skipped, while the correlated
|
|
211
|
+
// server ids let the coverage notice name the missing scanners once. Nothing
|
|
212
|
+
// is thrown away: the primary answered with zero findings, so there is nothing to
|
|
239
213
|
// report; when it DOES have findings the branches below still report
|
|
240
214
|
// them (see the non-empty path), which is how a trustworthy primary
|
|
241
|
-
// stays trustworthy under
|
|
242
|
-
return {
|
|
215
|
+
// stays trustworthy under an auxiliary that never reported.
|
|
216
|
+
return {
|
|
217
|
+
status: "skipped",
|
|
218
|
+
diagnostics: [],
|
|
219
|
+
semantic: "none",
|
|
220
|
+
unconfirmedServerIds: [...unconfirmedServerIds],
|
|
221
|
+
};
|
|
243
222
|
}
|
|
244
223
|
return {
|
|
245
224
|
status: "succeeded",
|
|
@@ -250,9 +229,34 @@ const lspRunner = {
|
|
|
250
229
|
}
|
|
251
230
|
// Convert LSP diagnostics to our format
|
|
252
231
|
// Defensive: filter out malformed diagnostics that may lack range
|
|
253
|
-
const
|
|
232
|
+
const rawValidLspDiags = lspDiags.filter((d) => d.range?.start?.line !== undefined);
|
|
233
|
+
// #1640: the per-edit path renders the same authority as the mode=full
|
|
234
|
+
// sweep, so it applies the same demotion. Costs one bounded `projectInfo`
|
|
235
|
+
// request, and only when the file already has a TypeScript ERROR — an edit
|
|
236
|
+
// that type-checks clean pays nothing.
|
|
237
|
+
//
|
|
238
|
+
// #1645 review F2: NOT under warm attach. There, diagnostics came from an
|
|
239
|
+
// already-running remote session over IPC and no local client exists — so
|
|
240
|
+
// the probe would have to spawn a whole tsserver fleet to answer, breaking
|
|
241
|
+
// this branch's spawn-free contract (see the comment below), and the
|
|
242
|
+
// answer it spawned for would be the NEW server's project resolution, not
|
|
243
|
+
// the warm session's. A meaningless answer bought with a process is worse
|
|
244
|
+
// than no answer, so the warm-attach path keeps pre-#1640 rendering. This
|
|
245
|
+
// is a known gap, recorded on the issue rather than papered over with an
|
|
246
|
+
// "unverified" label that would fire on every warm-attach file including
|
|
247
|
+
// the properly configured majority.
|
|
248
|
+
const validLspDiags = usedWarmAttach
|
|
249
|
+
? rawValidLspDiags
|
|
250
|
+
: await demoteInferredProjectDiagnostics(rawValidLspDiags, {
|
|
251
|
+
filePath: diagnosticPath,
|
|
252
|
+
cwd: ctx.cwd,
|
|
253
|
+
service: lspService,
|
|
254
|
+
});
|
|
254
255
|
const fixSuggestionByIndex = new Map();
|
|
255
|
-
|
|
256
|
+
// #1640: read severity off the RAW list. A demoted diagnostic is still
|
|
257
|
+
// worth a quick-fix suggestion — the demotion changes its authority, not
|
|
258
|
+
// whether tsserver can offer a fix. Indexes align 1:1 with `validLspDiags`.
|
|
259
|
+
const blockingDiagIndexes = rawValidLspDiags
|
|
256
260
|
.map((d, idx) => ({ d, idx }))
|
|
257
261
|
.filter(({ d }) => d.severity === 1)
|
|
258
262
|
.slice(0, WARM_CODE_ACTION_LOOKUP_LIMIT);
|
|
@@ -312,6 +316,9 @@ const lspRunner = {
|
|
|
312
316
|
failureKind: hasErrors ? "blocking_diagnostics" : undefined,
|
|
313
317
|
diagnostics: keptDiagnostics,
|
|
314
318
|
semantic: resultSemantic,
|
|
319
|
+
...(unconfirmedServerIds.length > 0 && {
|
|
320
|
+
unconfirmedServerIds: [...unconfirmedServerIds],
|
|
321
|
+
}),
|
|
315
322
|
};
|
|
316
323
|
},
|
|
317
324
|
};
|
|
@@ -2,7 +2,12 @@ import { safeSpawnAsync } from "../../safe-spawn.js";
|
|
|
2
2
|
import { getLinterPolicyForCwd, markdownlintConfigArgs, } from "../../tool-policy.js";
|
|
3
3
|
import { PRIORITY } from "../priorities.js";
|
|
4
4
|
import { createAvailabilityChecker, resolveToolCommandWithInstallFallback, } from "./utils/runner-helpers.js";
|
|
5
|
+
import { parseToolRun } from "./utils/tool-failure.js";
|
|
5
6
|
const markdownlint = createAvailabilityChecker("markdownlint-cli2", ".cmd");
|
|
7
|
+
// markdownlint-cli2 exit codes (its README's "Exit Codes" section): 0 = no
|
|
8
|
+
// findings, 1 = lint findings, 2 = unexpected error (unreadable config, bad
|
|
9
|
+
// glob, crash). Only 2 is a rejected invocation.
|
|
10
|
+
const MARKDOWNLINT_EXIT_CODES = { ran: [1] };
|
|
6
11
|
// markdownlint-cli2 text output does not include per-violation fixability,
|
|
7
12
|
// so we keep a static allowlist of MD### rules whose --fix is deterministic.
|
|
8
13
|
// Sourced from the rule pages in
|
|
@@ -93,7 +98,7 @@ const markdownlintRunner = {
|
|
|
93
98
|
return { status: "skipped", diagnostics: [], semantic: "none" };
|
|
94
99
|
}
|
|
95
100
|
let cmd = null;
|
|
96
|
-
if (await
|
|
101
|
+
if (await markdownlint.isAvailableAsync(cwd)) {
|
|
97
102
|
cmd = markdownlint.getCommand(cwd);
|
|
98
103
|
}
|
|
99
104
|
else {
|
|
@@ -108,8 +113,17 @@ const markdownlintRunner = {
|
|
|
108
113
|
timeout: 15000,
|
|
109
114
|
cwd,
|
|
110
115
|
});
|
|
116
|
+
// #1816: this runner read `result.status` zero times, so an exit-2
|
|
117
|
+
// config error with an empty stdout parsed to zero diagnostics and was
|
|
118
|
+
// reported as a clean Markdown file. An empty result must distinguish
|
|
119
|
+
// clean from errored.
|
|
111
120
|
const raw = `${result.stdout ?? ""}${result.stderr ?? ""}`;
|
|
112
|
-
|
|
121
|
+
// #1948: one seam for both gates — the tool produced nothing, and the
|
|
122
|
+
// tool produced something the parser could not read.
|
|
123
|
+
const run = parseToolRun("markdownlint", { result, output: raw, exitCodes: MARKDOWNLINT_EXIT_CODES }, (out) => parseMarkdownlintOutput(out, ctx.filePath));
|
|
124
|
+
if (run.skipped)
|
|
125
|
+
return run.skipped;
|
|
126
|
+
const diagnostics = run.diagnostics;
|
|
113
127
|
if (diagnostics.length === 0) {
|
|
114
128
|
return { status: "succeeded", diagnostics: [], semantic: "none" };
|
|
115
129
|
}
|
|
@@ -3,7 +3,19 @@ import { safeSpawnAsync } from "../../safe-spawn.js";
|
|
|
3
3
|
import { hasMypyConfig } from "../../tool-policy.js";
|
|
4
4
|
import { PRIORITY } from "../priorities.js";
|
|
5
5
|
import { createAvailabilityChecker, resolveToolCommandWithInstallFallback, } from "./utils/runner-helpers.js";
|
|
6
|
+
import { parseToolRun } from "./utils/tool-failure.js";
|
|
6
7
|
const mypy = createAvailabilityChecker("mypy", "");
|
|
8
|
+
// mypy exit codes: 0 = no type errors, 1 = type errors found, 2 = a blocking
|
|
9
|
+
// error. 2 is NOT a rejected invocation on its own — mypy reports a source
|
|
10
|
+
// SYNTAX error under 2 and still writes a normal parsable diagnostic to stdout
|
|
11
|
+
// (verified live against mypy 2.3.1: `syn.py:1: error: Invalid syntax
|
|
12
|
+
// [syntax]`). A bad flag or unreadable config also exits 2, but writes its
|
|
13
|
+
// message to STDERR and leaves stdout empty.
|
|
14
|
+
//
|
|
15
|
+
// So the exit code cannot separate the two, and the STREAM does: the gate below
|
|
16
|
+
// judges "nothing to parse" on stdout alone, while the parser still reads both.
|
|
17
|
+
// The table's remaining job is to reject any OTHER nonzero status.
|
|
18
|
+
const MYPY_EXIT_CODES = { ran: [1, 2] };
|
|
7
19
|
// mypy output: file.py:10: error: Incompatible types [assignment]
|
|
8
20
|
//
|
|
9
21
|
// mypy follows imports and reports errors in OTHER modules, not just the file
|
|
@@ -55,7 +67,7 @@ const mypyRunner = {
|
|
|
55
67
|
return { status: "skipped", diagnostics: [], semantic: "none" };
|
|
56
68
|
}
|
|
57
69
|
let cmd = null;
|
|
58
|
-
if (await
|
|
70
|
+
if (await mypy.isAvailableAsync(cwd)) {
|
|
59
71
|
cmd = mypy.getCommand(cwd);
|
|
60
72
|
}
|
|
61
73
|
else {
|
|
@@ -64,8 +76,19 @@ const mypyRunner = {
|
|
|
64
76
|
if (!cmd)
|
|
65
77
|
return { status: "skipped", diagnostics: [], semantic: "none" };
|
|
66
78
|
const result = await safeSpawnAsync(cmd, ["--no-error-summary", "--show-column-numbers", ctx.filePath], { timeout: 30000, cwd });
|
|
79
|
+
// #1816: this runner read `result.status` zero times, so an exit-2
|
|
80
|
+
// config error reported the file as cleanly type-checked. The gate reads
|
|
81
|
+
// stdout only (see MYPY_EXIT_CODES) so an exit-2 SYNTAX error, which
|
|
82
|
+
// does write a diagnostic there, still reaches the parser.
|
|
67
83
|
const raw = `${result.stdout ?? ""}${result.stderr ?? ""}`;
|
|
68
|
-
|
|
84
|
+
// #1948: `parseOutput` keeps the split this runner already had — the gate
|
|
85
|
+
// judges "did it run" on stdout alone, the parser still reads both
|
|
86
|
+
// streams — so adding the parsed-nothing record does not widen the
|
|
87
|
+
// did-it-run verdict.
|
|
88
|
+
const run = parseToolRun("mypy", { result, output: result.stdout, exitCodes: MYPY_EXIT_CODES }, (out) => parseMypyOutput(out, ctx.filePath, cwd), { parseOutput: raw });
|
|
89
|
+
if (run.skipped)
|
|
90
|
+
return run.skipped;
|
|
91
|
+
const diagnostics = run.diagnostics;
|
|
69
92
|
if (diagnostics.length === 0) {
|
|
70
93
|
return { status: "succeeded", diagnostics: [], semantic: "none" };
|
|
71
94
|
}
|
|
@@ -76,10 +76,13 @@ const oxlintRunner = {
|
|
|
76
76
|
const result = await safeSpawnAsync(cmd, args, {
|
|
77
77
|
timeout: 30000,
|
|
78
78
|
});
|
|
79
|
-
// Oxlint
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
79
|
+
// Oxlint exits 0 whenever nothing at ERROR severity was found — that
|
|
80
|
+
// includes a run that found only warnings, its own default severity
|
|
81
|
+
// (#1947). A run that found nothing at all also exits 0, but still
|
|
82
|
+
// prints a report with an empty `diagnostics` array, so parsing
|
|
83
|
+
// unconditionally and branching on the parsed count (below) tells the
|
|
84
|
+
// two apart instead of the exit code discarding the warning case.
|
|
85
|
+
//
|
|
83
86
|
// Parse JSON output. Fall back to the unix-format parser if JSON parsing
|
|
84
87
|
// fails (older oxlint versions, malformed stderr noise, etc.) — keeps the
|
|
85
88
|
// runner producing diagnostics even when the structured-fix metadata is
|
|
@@ -94,8 +97,20 @@ const oxlintRunner = {
|
|
|
94
97
|
return { status: "succeeded", diagnostics: [], semantic: "none" };
|
|
95
98
|
}
|
|
96
99
|
const hasBlocking = diagnostics.some((d) => d.semantic === "blocking");
|
|
100
|
+
// A warning-only result on exit 0 is oxlint's normal outcome, not a
|
|
101
|
+
// failure: exit 0 means nothing hit ERROR severity. `status: "failed"`
|
|
102
|
+
// here would stop this arm from reporting "succeeded", which breaks two
|
|
103
|
+
// things downstream — plan.ts's ["eslint", "oxlint", "biome-check-json"]
|
|
104
|
+
// fallback group only stops at the first `status: "succeeded"` runner
|
|
105
|
+
// (dispatcher.ts's `runGroup`), so biome-check-json would run again on
|
|
106
|
+
// every warning-only save (extra spawns, a possible install, duplicate
|
|
107
|
+
// findings); and it would mismatch the sibling convention (biome-check,
|
|
108
|
+
// golangci-lint, rubocop) of keying `status` off blocking severity, not
|
|
109
|
+
// off the tool's raw exit code. The findings themselves still reach the
|
|
110
|
+
// delivery pipeline regardless of `status` — dispatcher.ts buckets by
|
|
111
|
+
// each diagnostic's own `semantic`, so a warning stays a warning.
|
|
97
112
|
return {
|
|
98
|
-
status: "failed",
|
|
113
|
+
status: !hasBlocking && result.status === 0 ? "succeeded" : "failed",
|
|
99
114
|
diagnostics,
|
|
100
115
|
semantic: hasBlocking ? "blocking" : "warning",
|
|
101
116
|
};
|
|
@@ -3,6 +3,11 @@ import { safeSpawnAsync } from "../../safe-spawn.js";
|
|
|
3
3
|
import { getLinterPolicyForCwd, hasPhpstanConfig } from "../../tool-policy.js";
|
|
4
4
|
import { PRIORITY } from "../priorities.js";
|
|
5
5
|
import { createAvailabilityChecker, resolveVendorToolCommand, } from "./utils/runner-helpers.js";
|
|
6
|
+
import { parseToolRun } from "./utils/tool-failure.js";
|
|
7
|
+
// phpstan's documented exit codes: 0 = no errors, 1 = errors found, 2 = a
|
|
8
|
+
// fatal/internal error that stopped the analysis. Only 1 is a run that carries
|
|
9
|
+
// findings.
|
|
10
|
+
const PHPSTAN_EXIT_CODES = { ran: [1] };
|
|
6
11
|
const phpstan = createAvailabilityChecker("phpstan", ".phar");
|
|
7
12
|
// phpstan analyses the target file PLUS its dependency closure and keys errors
|
|
8
13
|
// by the real file in `output.files`. Attribute each diagnostic to that key
|
|
@@ -19,7 +24,7 @@ export function parsePhpstanJson(raw, fallbackPath, cwd) {
|
|
|
19
24
|
? file
|
|
20
25
|
: path.resolve(cwd, file)
|
|
21
26
|
: fallbackPath;
|
|
22
|
-
for (const err of fileErrors
|
|
27
|
+
for (const err of fileErrors?.messages ?? []) {
|
|
23
28
|
diagnostics.push({
|
|
24
29
|
id: `phpstan:${err.line ?? 1}:${err.message.slice(0, 40)}`,
|
|
25
30
|
message: err.message,
|
|
@@ -29,11 +34,38 @@ export function parsePhpstanJson(raw, fallbackPath, cwd) {
|
|
|
29
34
|
severity: "error",
|
|
30
35
|
semantic: "blocking",
|
|
31
36
|
tool: "phpstan",
|
|
32
|
-
rule: "phpstan",
|
|
37
|
+
rule: err.identifier || "phpstan",
|
|
33
38
|
fixable: false,
|
|
34
39
|
});
|
|
35
40
|
}
|
|
36
41
|
}
|
|
42
|
+
// #1937 round 2: the top-level `errors[]` array carries phpstan's
|
|
43
|
+
// FILE-INDEPENDENT findings — internal errors, and ignore patterns that
|
|
44
|
+
// matched nothing. A run can report `totals.errors: 1` with `files: {}`
|
|
45
|
+
// and exit 1, and reading only `files` turned that into zero
|
|
46
|
+
// diagnostics: the same defect class as the `errors`-vs-`messages` bug
|
|
47
|
+
// above, one level up. Pinned by
|
|
48
|
+
// tests/fixtures/runner-output/phpstan/top-level-errors.captured.json.
|
|
49
|
+
//
|
|
50
|
+
// These have no file or line, so they attach to the edited file at line
|
|
51
|
+
// 1. That is the honest placement: the reader needs to see them, and
|
|
52
|
+
// there is nowhere truer to put them.
|
|
53
|
+
for (const message of output.errors ?? []) {
|
|
54
|
+
if (typeof message !== "string" || !message.trim())
|
|
55
|
+
continue;
|
|
56
|
+
diagnostics.push({
|
|
57
|
+
id: `phpstan:global:${message.slice(0, 40)}`,
|
|
58
|
+
message,
|
|
59
|
+
filePath: fallbackPath,
|
|
60
|
+
line: 1,
|
|
61
|
+
column: 1,
|
|
62
|
+
severity: "error",
|
|
63
|
+
semantic: "blocking",
|
|
64
|
+
tool: "phpstan",
|
|
65
|
+
rule: "phpstan/analysis",
|
|
66
|
+
fixable: false,
|
|
67
|
+
});
|
|
68
|
+
}
|
|
37
69
|
return diagnostics;
|
|
38
70
|
}
|
|
39
71
|
catch {
|
|
@@ -41,7 +73,7 @@ export function parsePhpstanJson(raw, fallbackPath, cwd) {
|
|
|
41
73
|
}
|
|
42
74
|
}
|
|
43
75
|
async function resolvePhpstan(cwd) {
|
|
44
|
-
if (await
|
|
76
|
+
if (await phpstan.isAvailableAsync(cwd))
|
|
45
77
|
return phpstan.getCommand(cwd);
|
|
46
78
|
return resolveVendorToolCommand(cwd, "phpstan", ".bat");
|
|
47
79
|
}
|
|
@@ -66,14 +98,15 @@ const phpstanRunner = {
|
|
|
66
98
|
return { status: "skipped", diagnostics: [], semantic: "none" };
|
|
67
99
|
const absPath = path.resolve(cwd, ctx.filePath);
|
|
68
100
|
const result = await safeSpawnAsync(cmd, ["analyse", "--error-format=json", "--no-progress", absPath], { timeout: 30000, cwd });
|
|
69
|
-
// phpstan exits 0 = no errors, 1 = errors found, 2 = fatal
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
101
|
+
// phpstan exits 0 = no errors, 1 = errors found, 2 = fatal. The fatal
|
|
102
|
+
// case used to return `skipped` silently; routing it through the shared
|
|
103
|
+
// seam keeps that verdict and adds the bounded `runner-empty-result` row
|
|
104
|
+
// (#1816), and the exit-1 case now also records when the JSON report
|
|
105
|
+
// parses to nothing (#1948) — the shape the error-count-as-array bug had.
|
|
106
|
+
const run = parseToolRun("phpstan", { result, exitCodes: PHPSTAN_EXIT_CODES }, (out) => parsePhpstanJson(out, ctx.filePath, cwd), { parseOutput: result.stdout ?? "" });
|
|
107
|
+
if (run.skipped)
|
|
108
|
+
return run.skipped;
|
|
109
|
+
const diagnostics = run.diagnostics;
|
|
77
110
|
if (diagnostics.length === 0) {
|
|
78
111
|
return { status: "succeeded", diagnostics: [], semantic: "none" };
|
|
79
112
|
}
|