@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
|
@@ -0,0 +1,398 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `cue vet` — CUE evaluation-error validation (#1522).
|
|
3
|
+
*
|
|
4
|
+
* `cue lsp serve` reports load and parse (syntax) errors as you type
|
|
5
|
+
* (`clients/lsp/wait-policy/strategies.ts`'s `cue` entry) but deliberately
|
|
6
|
+
* leaves conflicting concrete values and failed constraints to `cue vet` —
|
|
7
|
+
* per the CUE wiki, that class needs a full evaluation pass the language
|
|
8
|
+
* server does not run on every keystroke. This runner is the auxiliary that
|
|
9
|
+
* covers the gap, in the same "LSP covers syntax, a CLI covers the rest"
|
|
10
|
+
* shape as terraform's `lsp, tflint, trivy-config` group.
|
|
11
|
+
*
|
|
12
|
+
* `-c=false` (allow incomplete values) is deliberate, not a shortcut: CUE's
|
|
13
|
+
* default `cue vet` requires every regular field to be concrete, so an
|
|
14
|
+
* ordinary schema-only file — a `#Definition` library with no concrete data,
|
|
15
|
+
* a very common authoring pattern — fails vet's default gate with a generic
|
|
16
|
+
* "some instances are incomplete" message and nothing to point at. That is
|
|
17
|
+
* noise, not a defect. `-c=false` accepts incomplete values and still
|
|
18
|
+
* reports a genuine type conflict (verified: `a: int & "hello"` still fails
|
|
19
|
+
* with `-c=false`, an incomplete `a: int` no longer does) — see the fixture
|
|
20
|
+
* at tests/fixtures/tool-smoke/cue-vet/bad.cue.
|
|
21
|
+
*
|
|
22
|
+
* ## Package-scoped, not file-scoped (review round 1, F1)
|
|
23
|
+
*
|
|
24
|
+
* CUE packages are DIRECTORY-scoped: every `.cue` file in a directory
|
|
25
|
+
* sharing a `package` clause is unified into one value. Vetting only the
|
|
26
|
+
* touched file (`cue vet <file>`) was a false-positive machine on the
|
|
27
|
+
* normative split-schema/values authoring style — a `#Service` defined in
|
|
28
|
+
* `schema.cue` and referenced from `values.cue` vets clean as a package but
|
|
29
|
+
* fails `values.cue` alone with `reference "#Service" not found`, because
|
|
30
|
+
* the single-file invocation never loads the sibling that defines it.
|
|
31
|
+
* Verified: a valid two-file package vets clean as `cue vet -c=false .`
|
|
32
|
+
* (exit 0, empty output) but reports a blocking error for `values.cue` in
|
|
33
|
+
* isolation.
|
|
34
|
+
*
|
|
35
|
+
* The fix runs `cue vet -c=false .` from the touched file's directory (the
|
|
36
|
+
* whole package) and then filters the reported errors down to the ones
|
|
37
|
+
* whose location names the touched file — `cue vet`'s locations are
|
|
38
|
+
* `.\<file>:line:col` relative to the vet cwd, so the match is a plain
|
|
39
|
+
* basename compare, no path resolution needed.
|
|
40
|
+
*
|
|
41
|
+
* This is now an honest MISSED-finding tradeoff, not an invented-finding
|
|
42
|
+
* bug: an error whose ONLY location is a sibling file is filtered out here
|
|
43
|
+
* (it will surface when that sibling is itself touched), rather than a
|
|
44
|
+
* clean file being wrongly flagged. An error that names the touched file
|
|
45
|
+
* ANYWHERE in its location list — including as a secondary location on a
|
|
46
|
+
* conflict whose primary site is a sibling — is kept, using that location's
|
|
47
|
+
* line/col, because the touched file is a genuine contributor to it.
|
|
48
|
+
*
|
|
49
|
+
* ## Directory scope can itself be unavailable (review round 2, F5/F6)
|
|
50
|
+
*
|
|
51
|
+
* `cue vet .` is not always a valid unit. Two real, LEGAL directory shapes
|
|
52
|
+
* make it fail before it evaluates anything, with no per-file location at
|
|
53
|
+
* all:
|
|
54
|
+
*
|
|
55
|
+
* - a package-less standalone file (no `package` clause — the common
|
|
56
|
+
* single-file config style): `build constraints exclude all CUE files
|
|
57
|
+
* in .:\n .\standalone.cue: no package name`;
|
|
58
|
+
* - two or more DIFFERENT package names sharing one directory (legal CUE —
|
|
59
|
+
* each is its own independent unit): `found packages "alpha"
|
|
60
|
+
* (alpha.cue) and "beta" (beta.cue) in "."`.
|
|
61
|
+
*
|
|
62
|
+
* Both verified against cue v0.17.1 (exit 1, no `:line:col` anywhere in the
|
|
63
|
+
* output). Before F5/F6, this read as an unattributable whole-vet failure
|
|
64
|
+
* and blocked every edit to an otherwise-clean file of either shape — a
|
|
65
|
+
* regression the F1 fix introduced. The fix: on either signature, fall back
|
|
66
|
+
* to vetting the touched file ALONE (`cue vet -c=false <file>`), which is
|
|
67
|
+
* the CORRECT scope for a file that cannot be unified with anything in its
|
|
68
|
+
* directory — a package-less file is its own unit by definition, and a
|
|
69
|
+
* differently-packaged sibling is never part of the same value regardless of
|
|
70
|
+
* scope. The single-file result needs no further filtering: every location
|
|
71
|
+
* it reports already belongs to that one file.
|
|
72
|
+
*
|
|
73
|
+
* ## A package-less file can vet CLEAN by never being evaluated (review
|
|
74
|
+
* ## round 3, F8)
|
|
75
|
+
*
|
|
76
|
+
* The F5/F6 fallback above only fires when the DIRECTORY vet FAILS. But a
|
|
77
|
+
* directory holding both a packaged file and a package-less file is not a
|
|
78
|
+
* failure at all: `cue vet .` silently BUILDS ONLY THE PACKAGE, excludes the
|
|
79
|
+
* package-less file from evaluation, and exits 0. Verified against the real
|
|
80
|
+
* binary: a package-less `loose.cue` with a genuine conflicting value
|
|
81
|
+
* (`b: int & "x"`) sitting beside a valid packaged `packaged.cue` makes
|
|
82
|
+
* `cue vet -c=false .` exit 0 with empty output — the loose file's defect is
|
|
83
|
+
* never evaluated, and the F5/F6 fallback's `result.status !== 0` gate never
|
|
84
|
+
* triggers because there IS no failure to react to. This is shape 10 from
|
|
85
|
+
* the miss side: an empty result that does not distinguish "clean" from
|
|
86
|
+
* "never evaluated".
|
|
87
|
+
*
|
|
88
|
+
* The fix does not wait for a failure signal at all for this shape: before
|
|
89
|
+
* spawning anything, the touched file's own content is checked for a
|
|
90
|
+
* `package` clause (`hasPackageClause`). A package-less touched file goes
|
|
91
|
+
* straight to single-file scope — it is its own vet unit regardless of what
|
|
92
|
+
* shares its directory, so directory-scoped vet has nothing to add for ITS
|
|
93
|
+
* evaluation errors. Its SYNTAX errors are equally covered single-file
|
|
94
|
+
* (verified: `cue vet <file>` alone reports the identical syntax error a
|
|
95
|
+
* directory-wide parse would have caught for that file — parsing happens
|
|
96
|
+
* before the build-constraint exclusion, but a single-file invocation
|
|
97
|
+
* parses that file too), so nothing is lost by skipping the directory pass
|
|
98
|
+
* for this shape. The F5/F6 `directoryScopeUnavailable` fallback stays as a
|
|
99
|
+
* safety net for what the proactive check cannot see up front — the
|
|
100
|
+
* touched file's content is unreadable, or the touched file DOES declare a
|
|
101
|
+
* package but the directory as a whole still isn't a valid unit (F6's
|
|
102
|
+
* two-different-packages shape).
|
|
103
|
+
*/
|
|
104
|
+
import * as fs from "node:fs";
|
|
105
|
+
import * as path from "node:path";
|
|
106
|
+
import { safeSpawnAsync } from "../../safe-spawn.js";
|
|
107
|
+
import { createAvailabilityChecker, resolveAvailableOrInstall, } from "./utils/runner-helpers.js";
|
|
108
|
+
import { spawnFailedWithNoOutput } from "./utils/spawn-outcome.js";
|
|
109
|
+
import { PRIORITY } from "../priorities.js";
|
|
110
|
+
const cue = createAvailabilityChecker("cue", ".exe", ["version"]);
|
|
111
|
+
/**
|
|
112
|
+
* `cue vet` reports each error as a header line (a field path or a bare
|
|
113
|
+
* message, ending in `:`) followed by zero or more indented location lines
|
|
114
|
+
* (` .\path:line:col`). A syntax error has no field-path prefix; a
|
|
115
|
+
* conflicting-value error carries one location per conflicting side, which
|
|
116
|
+
* can span DIFFERENT files in a multi-file package.
|
|
117
|
+
*
|
|
118
|
+
* Verified against cue v0.17.1:
|
|
119
|
+
* a: conflicting values int and "hello" (mismatched types int and string):
|
|
120
|
+
* .\bad.cue:3:4
|
|
121
|
+
* .\bad.cue:3:10
|
|
122
|
+
* expected '}', found 'EOF':
|
|
123
|
+
* .\syntax.cue:2:6
|
|
124
|
+
* badField.name: conflicting values 5 and string (mismatched types int and string):
|
|
125
|
+
* .\bad-values.cue:3:11
|
|
126
|
+
* .\bad-values.cue:4:8
|
|
127
|
+
* .\schema.cue:4:8
|
|
128
|
+
*
|
|
129
|
+
* A summary-only failure (no location lines at all — e.g. the "some
|
|
130
|
+
* instances are incomplete" message `-c=false` is meant to prevent, a
|
|
131
|
+
* directory-scope failure like `build constraints exclude all CUE files`
|
|
132
|
+
* (handled upstream of this parser — see `directoryScopeUnavailable`), or an
|
|
133
|
+
* unrecognized shape from a future cue version) is intentionally NOT
|
|
134
|
+
* silently dropped: `filterToTouchedFile` and the caller make sure a real
|
|
135
|
+
* vet failure can never present as zero findings (recurring defect shape
|
|
136
|
+
* 10) when nothing in the output could be file-attributed at all.
|
|
137
|
+
*/
|
|
138
|
+
export function parseCueVetOutput(raw) {
|
|
139
|
+
const errors = [];
|
|
140
|
+
let current = null;
|
|
141
|
+
for (const rawLine of raw.split(/\r?\n/)) {
|
|
142
|
+
if (!rawLine.trim())
|
|
143
|
+
continue;
|
|
144
|
+
if (/^\s/.test(rawLine)) {
|
|
145
|
+
if (current) {
|
|
146
|
+
const loc = rawLine.trim().match(/^(.+):(\d+):(\d+)$/);
|
|
147
|
+
if (loc) {
|
|
148
|
+
current.locations.push({
|
|
149
|
+
file: loc[1],
|
|
150
|
+
line: Number.parseInt(loc[2], 10),
|
|
151
|
+
column: Number.parseInt(loc[3], 10),
|
|
152
|
+
});
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
continue;
|
|
156
|
+
}
|
|
157
|
+
if (current)
|
|
158
|
+
errors.push(current);
|
|
159
|
+
current = { message: rawLine.replace(/:\s*$/, "").trim(), locations: [] };
|
|
160
|
+
}
|
|
161
|
+
if (current)
|
|
162
|
+
errors.push(current);
|
|
163
|
+
return errors;
|
|
164
|
+
}
|
|
165
|
+
/**
|
|
166
|
+
* True when `cue vet .`'s failure means the DIRECTORY is not a valid vet
|
|
167
|
+
* unit at all — not a finding about any file's content (review round 2,
|
|
168
|
+
* F5/F6). Both signatures are verified against cue v0.17.1 and carry no
|
|
169
|
+
* `:line:col` anywhere in their output, which is exactly why they used to
|
|
170
|
+
* read as an unattributable whole-vet failure and block every edit.
|
|
171
|
+
*/
|
|
172
|
+
export function directoryScopeUnavailable(raw) {
|
|
173
|
+
return (/build constraints exclude all CUE files/.test(raw) ||
|
|
174
|
+
// The trailing location cue reports (`in "."` vs `in "two-packages"`)
|
|
175
|
+
// depends on how it resolves the vet cwd, not on the shape of the
|
|
176
|
+
// failure — verified both forms against the real binary — so only the
|
|
177
|
+
// structural "found packages X and Y" part is matched.
|
|
178
|
+
/found packages ".+"\s*\(.+\)\s+and\s+".+"\s*\(.+\)\s+in\s+".*"/.test(raw));
|
|
179
|
+
}
|
|
180
|
+
/**
|
|
181
|
+
* True when `content` opens with a `package` clause (review round 3, F8).
|
|
182
|
+
* CUE requires the package clause, when present, to be the first
|
|
183
|
+
* declaration in the file — blank lines and `//` comments above it are
|
|
184
|
+
* fine, verified against the real binary — so the first non-blank,
|
|
185
|
+
* non-comment line is decisive: if it isn't `package <name>`, the file has
|
|
186
|
+
* none, and `cue vet .` will silently exclude it from directory-scoped
|
|
187
|
+
* evaluation (F8) rather than fail outright.
|
|
188
|
+
*
|
|
189
|
+
* File-level attributes (`@extern(embed)` is the documented real case) are
|
|
190
|
+
* ALSO legal before the package clause, and are skipped for the same reason
|
|
191
|
+
* comments are (review round 4, F10) — without this, a file opening with
|
|
192
|
+
* one reads as package-less, gets routed to single-file scope, and a
|
|
193
|
+
* cross-file reference into a sibling then false-positives as "reference
|
|
194
|
+
* not found" on an otherwise clean package (verified against the real
|
|
195
|
+
* binary). Field-level attributes never collide with this: they attach to
|
|
196
|
+
* a field and so always start with the field's name, never `@`.
|
|
197
|
+
*/
|
|
198
|
+
export function hasPackageClause(content) {
|
|
199
|
+
for (const line of content.split(/\r?\n/)) {
|
|
200
|
+
const trimmed = line.trim();
|
|
201
|
+
if (!trimmed || trimmed.startsWith("//") || trimmed.startsWith("@"))
|
|
202
|
+
continue;
|
|
203
|
+
return /^package\s+[A-Za-z_]\w*\b/.test(trimmed);
|
|
204
|
+
}
|
|
205
|
+
return false;
|
|
206
|
+
}
|
|
207
|
+
/** `.\bad.cue`, `./bad.cue`, and `bad.cue` all name the same file. */
|
|
208
|
+
function locationMatchesFile(location, fileName) {
|
|
209
|
+
const normalized = location.file.replace(/\\/g, "/").replace(/^\.\//, "");
|
|
210
|
+
return path.posix.basename(normalized) === fileName;
|
|
211
|
+
}
|
|
212
|
+
function toDiagnostic(id, message, fileName, line, column) {
|
|
213
|
+
return {
|
|
214
|
+
id,
|
|
215
|
+
message: message || "cue vet reported an error",
|
|
216
|
+
filePath: fileName,
|
|
217
|
+
line,
|
|
218
|
+
column,
|
|
219
|
+
severity: "error",
|
|
220
|
+
semantic: "blocking",
|
|
221
|
+
tool: "cue-vet",
|
|
222
|
+
rule: "vet",
|
|
223
|
+
fixable: false,
|
|
224
|
+
};
|
|
225
|
+
}
|
|
226
|
+
/**
|
|
227
|
+
* Filter package-wide vet errors down to the ones that implicate the touched
|
|
228
|
+
* file, and resolve each to that file's own location (the first location
|
|
229
|
+
* line naming it — the field path can carry more than one, see the
|
|
230
|
+
* `badField.name` example above).
|
|
231
|
+
*
|
|
232
|
+
* Returns `undefined` (distinct from an empty array) only when NOTHING in
|
|
233
|
+
* the output could be file-attributed at all — every error lacked location
|
|
234
|
+
* lines entirely — so the caller can fall back to a whole-output diagnostic
|
|
235
|
+
* instead of reporting a false-clean result (shape 10).
|
|
236
|
+
*
|
|
237
|
+
* ## The mixed case (review round 2, F7)
|
|
238
|
+
*
|
|
239
|
+
* A package-wide vet run can return SEVERAL errors, some with locations and
|
|
240
|
+
* some without. The original rule only fell back to `undefined` when EVERY
|
|
241
|
+
* error lacked a location — so one sibling-located error alongside one
|
|
242
|
+
* genuinely unattributable error made `recognized.length` nonzero, and the
|
|
243
|
+
* unattributable error's diagnostic silently vanished (shape 10, from the
|
|
244
|
+
* filter side this time). There is no file this parser can safely charge an
|
|
245
|
+
* unattributable error to, and no file it can safely clear it from either
|
|
246
|
+
* — so the honest rule is: an unattributable error ALWAYS surfaces on the
|
|
247
|
+
* touched file's result, distinct from (never merged with) a real
|
|
248
|
+
* touched-file location match, and independent of whatever sibling-only
|
|
249
|
+
* errors get filtered out alongside it. Only the fully-uniform case (every
|
|
250
|
+
* error unattributable) still returns `undefined`, so the caller's richer
|
|
251
|
+
* whole-output fallback message is used instead of one row per parsed
|
|
252
|
+
* header.
|
|
253
|
+
*/
|
|
254
|
+
export function filterToTouchedFile(errors, fileName) {
|
|
255
|
+
if (errors.length === 0)
|
|
256
|
+
return undefined;
|
|
257
|
+
const withLocation = errors.filter((error) => error.locations.length > 0);
|
|
258
|
+
const unattributable = errors.filter((error) => error.locations.length === 0);
|
|
259
|
+
if (withLocation.length === 0)
|
|
260
|
+
return undefined;
|
|
261
|
+
const diagnostics = [];
|
|
262
|
+
for (const error of withLocation) {
|
|
263
|
+
const match = error.locations.find((location) => locationMatchesFile(location, fileName));
|
|
264
|
+
if (!match)
|
|
265
|
+
continue; // sibling-only finding — surfaces when that file is touched
|
|
266
|
+
diagnostics.push(toDiagnostic(`cue-vet-${diagnostics.length + 1}-${match.line}`, error.message, fileName, match.line, match.column));
|
|
267
|
+
}
|
|
268
|
+
// F7: an error this parser could not pin to any file must never be
|
|
269
|
+
// silently dropped just because a SIBLING error happened to carry a
|
|
270
|
+
// location — surface it too, at line 1 since there is nowhere else to
|
|
271
|
+
// point.
|
|
272
|
+
for (const error of unattributable) {
|
|
273
|
+
diagnostics.push(toDiagnostic(`cue-vet-unattributed-${diagnostics.length + 1}`, error.message, fileName, 1, 1));
|
|
274
|
+
}
|
|
275
|
+
return diagnostics;
|
|
276
|
+
}
|
|
277
|
+
const cueVetRunner = {
|
|
278
|
+
id: "cue-vet",
|
|
279
|
+
appliesTo: ["cue"],
|
|
280
|
+
priority: PRIORITY.GENERAL_ANALYSIS,
|
|
281
|
+
enabledByDefault: true,
|
|
282
|
+
skipTestFiles: false,
|
|
283
|
+
timeoutMs: 30_000,
|
|
284
|
+
async run(ctx) {
|
|
285
|
+
const cwd = ctx.cwd || process.cwd();
|
|
286
|
+
let cmd = null;
|
|
287
|
+
if (await cue.isAvailableAsync(cwd)) {
|
|
288
|
+
cmd = cue.getCommand(cwd);
|
|
289
|
+
}
|
|
290
|
+
else {
|
|
291
|
+
cmd = await resolveAvailableOrInstall(cue, "cue", cwd);
|
|
292
|
+
}
|
|
293
|
+
// An unspawnable `cue` is never a durable "clean" verdict — skip, so the
|
|
294
|
+
// dispatcher's own absence handling reports the gap rather than this
|
|
295
|
+
// runner manufacturing a false "0 findings" (recurring defect shape 10).
|
|
296
|
+
// `createAvailabilityChecker`/`resolveAvailableOrInstall` already route
|
|
297
|
+
// through the shared classify/latch policy, so a probe timeout or host
|
|
298
|
+
// stall re-arms on its own cooldown instead of latching here.
|
|
299
|
+
if (!cmd)
|
|
300
|
+
return { status: "skipped", diagnostics: [], semantic: "none" };
|
|
301
|
+
const absPath = path.resolve(cwd, ctx.filePath);
|
|
302
|
+
const fileDir = path.dirname(absPath);
|
|
303
|
+
const fileName = path.basename(absPath);
|
|
304
|
+
const singleFileArgs = ["vet", "-c=false", `./${fileName}`];
|
|
305
|
+
// F8: read the touched file's OWN content before deciding scope. A
|
|
306
|
+
// package-less file is excluded from directory-scoped evaluation
|
|
307
|
+
// entirely (silently, exit 0) rather than causing a failure, so
|
|
308
|
+
// waiting for the directory vet to fail (the F5/F6 gate below) can
|
|
309
|
+
// never catch this shape — go straight to single-file scope instead.
|
|
310
|
+
// An unreadable file falls through to the directory-scoped path below;
|
|
311
|
+
// package-less-ness that can't be verified is never assumed.
|
|
312
|
+
let touchedContent = null;
|
|
313
|
+
try {
|
|
314
|
+
touchedContent = fs.readFileSync(absPath, "utf8");
|
|
315
|
+
}
|
|
316
|
+
catch {
|
|
317
|
+
touchedContent = null;
|
|
318
|
+
}
|
|
319
|
+
const touchedIsPackageLess = touchedContent !== null && !hasPackageClause(touchedContent);
|
|
320
|
+
let result;
|
|
321
|
+
if (touchedIsPackageLess) {
|
|
322
|
+
result = await safeSpawnAsync(cmd, [...singleFileArgs], {
|
|
323
|
+
cwd: fileDir,
|
|
324
|
+
timeout: 30_000,
|
|
325
|
+
});
|
|
326
|
+
}
|
|
327
|
+
else {
|
|
328
|
+
// Package-scoped (F1): vet the whole directory the touched file lives
|
|
329
|
+
// in, not the file alone — CUE packages unify every file that shares
|
|
330
|
+
// a package clause, so a single-file invocation cannot see a
|
|
331
|
+
// definition or value declared in a sibling.
|
|
332
|
+
result = await safeSpawnAsync(cmd, ["vet", "-c=false", "."], {
|
|
333
|
+
cwd: fileDir,
|
|
334
|
+
timeout: 30_000,
|
|
335
|
+
});
|
|
336
|
+
if (!spawnFailedWithNoOutput(result, `${result.stdout}${result.stderr}`) &&
|
|
337
|
+
result.status !== 0 &&
|
|
338
|
+
directoryScopeUnavailable(`${result.stdout || ""}${result.stderr || ""}`)) {
|
|
339
|
+
// F6: the directory holds two+ DIFFERENTLY-packaged files (the
|
|
340
|
+
// touched file has its own valid package, but the directory as a
|
|
341
|
+
// whole still isn't one unit) — fall back to the touched file
|
|
342
|
+
// alone, which IS a valid unit on its own.
|
|
343
|
+
result = await safeSpawnAsync(cmd, [...singleFileArgs], {
|
|
344
|
+
cwd: fileDir,
|
|
345
|
+
timeout: 30_000,
|
|
346
|
+
});
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
if (spawnFailedWithNoOutput(result, `${result.stdout}${result.stderr}`)) {
|
|
350
|
+
return { status: "skipped", diagnostics: [], semantic: "none" };
|
|
351
|
+
}
|
|
352
|
+
// `cue vet` is silent on success (empty stdout, exit 0) — that IS the
|
|
353
|
+
// clean signal, not an unavailable/errored one, so status 0 with no
|
|
354
|
+
// output reports succeeded/no-findings rather than falling through to
|
|
355
|
+
// the skip above.
|
|
356
|
+
if (result.status === 0) {
|
|
357
|
+
return { status: "succeeded", diagnostics: [], semantic: "none" };
|
|
358
|
+
}
|
|
359
|
+
const raw = `${result.stdout || ""}\n${result.stderr || ""}`.trim();
|
|
360
|
+
const errors = parseCueVetOutput(raw);
|
|
361
|
+
// The single-file path (F5/F6/F8) needs no special-casing: every
|
|
362
|
+
// location it reports already belongs to the one file it vetted, so it
|
|
363
|
+
// trivially matches `fileName` and flows through the same filter as
|
|
364
|
+
// the directory-scoped path — one code path, and a single-file run
|
|
365
|
+
// that somehow fails with no location at all still gets the same
|
|
366
|
+
// never-silently-clean `undefined` fallback as the directory path.
|
|
367
|
+
const filtered = filterToTouchedFile(errors, fileName);
|
|
368
|
+
if (filtered === undefined) {
|
|
369
|
+
// Nonzero exit, some output, but nothing in it could be attributed to
|
|
370
|
+
// ANY file — a real failure must not present as zero findings.
|
|
371
|
+
return {
|
|
372
|
+
status: "failed",
|
|
373
|
+
diagnostics: [
|
|
374
|
+
{
|
|
375
|
+
id: "cue-vet-unparsed",
|
|
376
|
+
message: raw.slice(0, 300) || "cue vet exited non-zero",
|
|
377
|
+
filePath: ctx.filePath,
|
|
378
|
+
line: 1,
|
|
379
|
+
column: 1,
|
|
380
|
+
severity: "error",
|
|
381
|
+
semantic: "blocking",
|
|
382
|
+
tool: "cue-vet",
|
|
383
|
+
rule: "vet",
|
|
384
|
+
fixable: false,
|
|
385
|
+
},
|
|
386
|
+
],
|
|
387
|
+
semantic: "blocking",
|
|
388
|
+
};
|
|
389
|
+
}
|
|
390
|
+
if (filtered.length === 0) {
|
|
391
|
+
// The package has real errors, but none of them implicate the touched
|
|
392
|
+
// file — a sibling's problem, not this file's (the F1 tradeoff).
|
|
393
|
+
return { status: "succeeded", diagnostics: [], semantic: "none" };
|
|
394
|
+
}
|
|
395
|
+
return { status: "failed", diagnostics: filtered, semantic: "blocking" };
|
|
396
|
+
},
|
|
397
|
+
};
|
|
398
|
+
export default cueVetRunner;
|
|
@@ -165,7 +165,15 @@ const elixirCheckRunner = {
|
|
|
165
165
|
return { status: "skipped", diagnostics: [], semantic: "none" };
|
|
166
166
|
}
|
|
167
167
|
const raw = `${result.stderr || ""}\n${result.stdout || ""}`;
|
|
168
|
-
const
|
|
168
|
+
const hasProjectContext = command === "mix";
|
|
169
|
+
const diagnostics = parseElixirOutput(raw, ctx.filePath, cwd).map((d) => hasProjectContext
|
|
170
|
+
? d
|
|
171
|
+
: {
|
|
172
|
+
...d,
|
|
173
|
+
// A direct elixirc invocation cannot resolve Mix dependencies.
|
|
174
|
+
// Standalone findings inform the agent, but cannot block it.
|
|
175
|
+
semantic: "warning",
|
|
176
|
+
});
|
|
169
177
|
if (diagnostics.length === 0) {
|
|
170
178
|
if (result.status && result.status !== 0) {
|
|
171
179
|
return {
|
|
@@ -177,13 +185,13 @@ const elixirCheckRunner = {
|
|
|
177
185
|
`${command} exited non-zero without structured diagnostics`,
|
|
178
186
|
filePath: ctx.filePath,
|
|
179
187
|
severity: "error",
|
|
180
|
-
semantic: "blocking",
|
|
188
|
+
semantic: hasProjectContext ? "blocking" : "warning",
|
|
181
189
|
tool: "elixir-check",
|
|
182
190
|
rule: command,
|
|
183
191
|
fixable: false,
|
|
184
192
|
},
|
|
185
193
|
],
|
|
186
|
-
semantic: "blocking",
|
|
194
|
+
semantic: hasProjectContext ? "blocking" : "warning",
|
|
187
195
|
};
|
|
188
196
|
}
|
|
189
197
|
return { status: "succeeded", diagnostics: [], semantic: "none" };
|
|
@@ -10,24 +10,29 @@ import { safeSpawnAsync } from "../../safe-spawn.js";
|
|
|
10
10
|
import { getAutofixCapability, hasEslintConfig } from "../../tool-policy.js";
|
|
11
11
|
import { PRIORITY } from "../priorities.js";
|
|
12
12
|
import { createCwdCachedProbe, resolveToolCommand, } from "./utils/runner-helpers.js";
|
|
13
|
+
const ESLINT_PROBE_BUDGET_MS = 5000;
|
|
13
14
|
// Per-cwd cached eslint `--version` verification (#120). Before this, every
|
|
14
15
|
// dispatch invocation ran a fresh `safeSpawnAsync(cmd, ["--version"])` after
|
|
15
16
|
// the local cmd resolution. The probe is cached per cwd because
|
|
16
17
|
// `resolveToolCommand("eslint")` is deterministic from cwd; the underlying
|
|
17
18
|
// cmd identity is captured inside the probe closure.
|
|
19
|
+
//
|
|
20
|
+
// The verdict is governed by the shared availability policy (#1494): the probe
|
|
21
|
+
// hands back the spawn result, so one stalled probe on the first JS/TS save
|
|
22
|
+
// expires on a cooldown instead of disabling eslint for the whole session.
|
|
18
23
|
function makeEslintProbe(cmd) {
|
|
19
|
-
return createCwdCachedProbe(
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
});
|
|
24
|
+
return createCwdCachedProbe((cwd) => safeSpawnAsync(cmd, ["--version"], {
|
|
25
|
+
timeout: ESLINT_PROBE_BUDGET_MS,
|
|
26
|
+
cwd,
|
|
27
|
+
}), { tool: "eslint", budgetMs: ESLINT_PROBE_BUDGET_MS });
|
|
23
28
|
}
|
|
24
|
-
const
|
|
29
|
+
const eslintAvailabilityByCmd = new Map();
|
|
25
30
|
function getEslintProbe(cmd) {
|
|
26
|
-
const existing =
|
|
31
|
+
const existing = eslintAvailabilityByCmd.get(cmd);
|
|
27
32
|
if (existing)
|
|
28
33
|
return existing;
|
|
29
34
|
const created = makeEslintProbe(cmd);
|
|
30
|
-
|
|
35
|
+
eslintAvailabilityByCmd.set(cmd, created);
|
|
31
36
|
return created;
|
|
32
37
|
}
|
|
33
38
|
function parseEslintJson(raw, filePath) {
|
|
@@ -7,6 +7,7 @@ import { relative, resolve, sep, posix } from "node:path";
|
|
|
7
7
|
import { GoClient } from "../../go-client.js";
|
|
8
8
|
import { safeSpawnAsync } from "../../safe-spawn.js";
|
|
9
9
|
import { stripAnsi } from "../../sanitize.js";
|
|
10
|
+
import { skipUnlessToolRan } from "./utils/tool-failure.js";
|
|
10
11
|
import { parseGoVetOutput } from "./utils/diagnostic-parsers.js";
|
|
11
12
|
import { PRIORITY } from "../priorities.js";
|
|
12
13
|
const goClient = new GoClient();
|
|
@@ -45,6 +46,23 @@ const goVetRunner = {
|
|
|
45
46
|
cwd,
|
|
46
47
|
});
|
|
47
48
|
const raw = stripAnsi(result.stdout + result.stderr);
|
|
49
|
+
// #1816: `go vet` exits nonzero both for "found problems" and for a
|
|
50
|
+
// toolchain failure it never got past — `go.mod file not found in
|
|
51
|
+
// current directory or any parent directory` is the one that bit us
|
|
52
|
+
// (#263). That prose carries no `file:line:col:` prefix, so it parsed to
|
|
53
|
+
// zero diagnostics and the file was reported CLEAN by a vet that never
|
|
54
|
+
// ran. The exit code cannot separate the two cases; the presence of a
|
|
55
|
+
// parsable diagnostic line can, so that is what the gate is handed.
|
|
56
|
+
const parsableLines = raw
|
|
57
|
+
.split("\n")
|
|
58
|
+
.filter((line) => /^.+?:\d+:\d+:/.test(line))
|
|
59
|
+
.join("\n");
|
|
60
|
+
const skipped = skipUnlessToolRan("go-vet", {
|
|
61
|
+
result,
|
|
62
|
+
output: parsableLines,
|
|
63
|
+
});
|
|
64
|
+
if (skipped)
|
|
65
|
+
return skipped;
|
|
48
66
|
if (result.status === 0 && !raw.trim()) {
|
|
49
67
|
return { status: "succeeded", diagnostics: [], semantic: "none" };
|
|
50
68
|
}
|