@herbertgao/pi-extensions 2026.8.4 → 2026.8.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +4 -4
- package/node_modules/@herbertgao/pi-cc-extensions/README.en.md +10 -2
- package/node_modules/@herbertgao/pi-cc-extensions/README.md +10 -2
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/config/config.ts +24 -0
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/config/panel.ts +91 -1
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/feature/compact-thinking.ts +7 -3
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/index.ts +7 -6
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/compact-mode.ts +21 -12
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/default-mode.ts +4 -5
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/markdown-enhance.ts +5 -8
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/tool/grouping.ts +22 -12
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/tool/result.ts +2 -4
- package/node_modules/@herbertgao/pi-cc-extensions/package.json +3 -3
- package/node_modules/@herbertgao/pi-subagents/CHANGELOG.md +8 -0
- package/node_modules/@herbertgao/pi-subagents/package.json +8 -4
- package/node_modules/@herbertgao/pi-subagents/src/agent-color.ts +72 -67
- package/node_modules/@herbertgao/pi-subagents/src/agent-file-toggle.ts +255 -0
- package/node_modules/@herbertgao/pi-subagents/src/agent-manager.ts +191 -3
- package/node_modules/@herbertgao/pi-subagents/src/agent-runner.ts +15 -2
- package/node_modules/@herbertgao/pi-subagents/src/index.ts +289 -113
- package/node_modules/@herbertgao/pi-subagents/src/output-file.ts +24 -1
- package/node_modules/@herbertgao/pi-subagents/src/ui/agent-widget.ts +24 -2
- package/node_modules/@herbertgao/pi-subagents/src/ui/schedule-menu.ts +9 -8
- package/node_modules/@herbertgao/pi-subagents/src/ui/select-item.ts +48 -0
- package/node_modules/@juicesharp/rpiv-ask-user-question/docs/keyboard.md +7 -0
- package/node_modules/@juicesharp/rpiv-ask-user-question/package.json +2 -2
- package/node_modules/@juicesharp/rpiv-ask-user-question/state/build-questionnaire.ts +7 -0
- package/node_modules/@juicesharp/rpiv-ask-user-question/state/key-router.ts +16 -5
- package/node_modules/@juicesharp/rpiv-ask-user-question/state/questionnaire-session.ts +4 -2
- package/node_modules/@narumitw/pi-btw/README.md +8 -7
- package/node_modules/@narumitw/pi-btw/package.json +2 -2
- package/node_modules/@narumitw/pi-btw/src/menu.ts +1 -0
- package/node_modules/pi-lens/CHANGELOG.md +2440 -954
- package/node_modules/pi-lens/README.md +13 -0
- package/node_modules/pi-lens/dist/clients/actionable-warnings.js +73 -18
- package/node_modules/pi-lens/dist/clients/agent-behavior-client.js +21 -4
- package/node_modules/pi-lens/dist/clients/ast-grep-client.js +68 -16
- package/node_modules/pi-lens/dist/clients/ast-grep-types.js +0 -1
- package/node_modules/pi-lens/dist/clients/ast-grep-yaml-synth.js +37 -10
- package/node_modules/pi-lens/dist/clients/atomic-write-staging.js +63 -0
- package/node_modules/pi-lens/dist/clients/atomic-write.js +114 -14
- package/node_modules/pi-lens/dist/clients/bash-file-access.js +193 -23
- package/node_modules/pi-lens/dist/clients/biome-client.js +29 -25
- package/node_modules/pi-lens/dist/clients/bootstrap.js +11 -2
- package/node_modules/pi-lens/dist/clients/bounded-cache.js +34 -0
- package/node_modules/pi-lens/dist/clients/bounded-pid-file-lock.js +192 -0
- package/node_modules/pi-lens/dist/clients/bus-publish.js +10 -3
- package/node_modules/pi-lens/dist/clients/cache/rule-cache.js +47 -5
- package/node_modules/pi-lens/dist/clients/cache-manager.js +97 -9
- package/node_modules/pi-lens/dist/clients/cache-observability.js +301 -14
- package/node_modules/pi-lens/dist/clients/call-graph.js +449 -117
- package/node_modules/pi-lens/dist/clients/child-unref.js +85 -0
- package/node_modules/pi-lens/dist/clients/codebase-model.js +52 -23
- package/node_modules/pi-lens/dist/clients/collateral-test-role.js +40 -0
- package/node_modules/pi-lens/dist/clients/complexity-client.js +2 -1
- package/node_modules/pi-lens/dist/clients/console-guard-install.js +14 -0
- package/node_modules/pi-lens/dist/clients/cooperative-budget.js +42 -0
- package/node_modules/pi-lens/dist/clients/dead-code-client.js +2 -1
- package/node_modules/pi-lens/dist/clients/debug-handles.js +206 -0
- package/node_modules/pi-lens/dist/clients/debug-heap.js +167 -0
- package/node_modules/pi-lens/dist/clients/degradation-ledger.js +153 -0
- package/node_modules/pi-lens/dist/clients/dependency-checker.js +347 -75
- package/node_modules/pi-lens/dist/clients/diagnostic-dispositions.js +61 -11
- package/node_modules/pi-lens/dist/clients/diagnostics-publish.js +10 -3
- package/node_modules/pi-lens/dist/clients/dispatch/dispatcher.js +63 -20
- package/node_modules/pi-lens/dist/clients/dispatch/facts/function-facts.js +23 -7
- package/node_modules/pi-lens/dist/clients/dispatch/facts/import-facts.js +8 -18
- package/node_modules/pi-lens/dist/clients/dispatch/facts/tree-sitter-facts.js +8 -5
- package/node_modules/pi-lens/dist/clients/dispatch/indent-detect.js +35 -0
- package/node_modules/pi-lens/dist/clients/dispatch/inline-suppressions.js +17 -8
- package/node_modules/pi-lens/dist/clients/dispatch/integration.js +1085 -681
- package/node_modules/pi-lens/dist/clients/dispatch/lazy.js +14 -0
- package/node_modules/pi-lens/dist/clients/dispatch/plan.js +11 -1
- package/node_modules/pi-lens/dist/clients/dispatch/rule-id-normalize.js +50 -0
- package/node_modules/pi-lens/dist/clients/dispatch/rule-policy.js +135 -0
- package/node_modules/pi-lens/dist/clients/dispatch/runners/ast-grep-napi.js +23 -5
- package/node_modules/pi-lens/dist/clients/dispatch/runners/biome-check.js +5 -9
- package/node_modules/pi-lens/dist/clients/dispatch/runners/detekt.js +3 -2
- package/node_modules/pi-lens/dist/clients/dispatch/runners/hadolint.js +2 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/helm-lint.js +154 -0
- package/node_modules/pi-lens/dist/clients/dispatch/runners/htmlhint.js +3 -2
- package/node_modules/pi-lens/dist/clients/dispatch/runners/index.js +5 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/lsp.js +14 -6
- package/node_modules/pi-lens/dist/clients/dispatch/runners/markdownlint.js +4 -9
- package/node_modules/pi-lens/dist/clients/dispatch/runners/pyright.js +9 -5
- package/node_modules/pi-lens/dist/clients/dispatch/runners/ruff.js +4 -8
- package/node_modules/pi-lens/dist/clients/dispatch/runners/shellcheck.js +2 -3
- package/node_modules/pi-lens/dist/clients/dispatch/runners/shfmt.js +2 -3
- package/node_modules/pi-lens/dist/clients/dispatch/runners/spotbugs.js +2 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/taplo.js +2 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/terragrunt.js +163 -0
- package/node_modules/pi-lens/dist/clients/dispatch/runners/tflint.js +37 -5
- package/node_modules/pi-lens/dist/clients/dispatch/runners/tree-sitter.js +3 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/trivy-config.js +13 -7
- package/node_modules/pi-lens/dist/clients/dispatch/runners/utils/lazy-installer.js +3 -0
- package/node_modules/pi-lens/dist/clients/dispatch/runners/utils/runner-helpers.js +277 -26
- package/node_modules/pi-lens/dist/clients/dispatch/runners/utils/spawn-outcome.js +22 -0
- package/node_modules/pi-lens/dist/clients/dispatch/runners/yaml-rule-parser.js +5 -4
- package/node_modules/pi-lens/dist/clients/disposition-publish.js +10 -3
- package/node_modules/pi-lens/dist/clients/durable-store.js +97 -0
- package/node_modules/pi-lens/dist/clients/event-loop-monitor.js +94 -3
- package/node_modules/pi-lens/dist/clients/extension-log.js +139 -0
- package/node_modules/pi-lens/dist/clients/extension-mode.js +73 -0
- package/node_modules/pi-lens/dist/clients/file-kinds.js +57 -0
- package/node_modules/pi-lens/dist/clients/file-role.js +18 -3
- package/node_modules/pi-lens/dist/clients/file-utils.js +56 -34
- package/node_modules/pi-lens/dist/clients/format-events-publish.js +16 -3
- package/node_modules/pi-lens/dist/clients/format-service.js +24 -8
- package/node_modules/pi-lens/dist/clients/formatters-lazy.js +8 -0
- package/node_modules/pi-lens/dist/clients/formatters.js +358 -61
- package/node_modules/pi-lens/dist/clients/generated-artifacts.js +148 -15
- package/node_modules/pi-lens/dist/clients/git-guard.js +681 -11
- package/node_modules/pi-lens/dist/clients/git-tracked-ignore.js +4 -0
- package/node_modules/pi-lens/dist/clients/go-client.js +2 -1
- package/node_modules/pi-lens/dist/clients/govulncheck-client.js +8 -0
- package/node_modules/pi-lens/dist/clients/grammar-source.js +12 -4
- package/node_modules/pi-lens/dist/clients/gzip-stage-write.js +21 -3
- package/node_modules/pi-lens/dist/clients/host-ports.js +31 -0
- package/node_modules/pi-lens/dist/clients/installer/index.js +390 -99
- package/node_modules/pi-lens/dist/clients/instance-reaper.js +142 -172
- package/node_modules/pi-lens/dist/clients/jscpd-client.js +31 -54
- package/node_modules/pi-lens/dist/clients/knip-client.js +15 -36
- package/node_modules/pi-lens/dist/clients/language-policy.js +14 -2
- package/node_modules/pi-lens/dist/clients/language-profile.js +13 -7
- package/node_modules/pi-lens/dist/clients/latency-logger.js +23 -1
- package/node_modules/pi-lens/dist/clients/lens-config.js +12 -1
- package/node_modules/pi-lens/dist/clients/lens-engine.js +86 -17
- package/node_modules/pi-lens/dist/clients/lens-events.js +27 -4
- package/node_modules/pi-lens/dist/clients/lens-flag-registry.js +8 -0
- package/node_modules/pi-lens/dist/clients/lens-map.js +94 -19
- package/node_modules/pi-lens/dist/clients/live-bus-emitter.js +30 -0
- package/node_modules/pi-lens/dist/clients/log-cleanup.js +2 -1
- package/node_modules/pi-lens/dist/clients/lsp/cascade-tier.js +1 -1
- package/node_modules/pi-lens/dist/clients/lsp/client.js +493 -48
- package/node_modules/pi-lens/dist/clients/lsp/config.js +13 -2
- package/node_modules/pi-lens/dist/clients/lsp/diagnostic-binding.js +86 -0
- package/node_modules/pi-lens/dist/clients/lsp/edits.js +1012 -121
- package/node_modules/pi-lens/dist/clients/lsp/index.js +1807 -780
- package/node_modules/pi-lens/dist/clients/lsp/launch.js +32 -26
- package/node_modules/pi-lens/dist/clients/lsp/path-utils.js +1 -1
- package/node_modules/pi-lens/dist/clients/lsp/ruby-drive-dirs.js +83 -0
- package/node_modules/pi-lens/dist/clients/lsp/server.js +196 -32
- package/node_modules/pi-lens/dist/clients/lsp/workspace-diagnostics-cache.js +28 -4
- package/node_modules/pi-lens/dist/clients/lsp-lazy.js +8 -0
- package/node_modules/pi-lens/dist/clients/lsp-mutation.js +248 -0
- package/node_modules/pi-lens/dist/clients/mcp/analyze.js +123 -32
- package/node_modules/pi-lens/dist/clients/mcp/ipc.js +157 -24
- package/node_modules/pi-lens/dist/clients/mcp/session.js +216 -8
- package/node_modules/pi-lens/dist/clients/memory-sampler.js +115 -0
- package/node_modules/pi-lens/dist/clients/metrics-client.js +2 -1
- package/node_modules/pi-lens/dist/clients/metrics-history.js +2 -1
- package/node_modules/pi-lens/dist/clients/module-report-lsp.js +5 -0
- package/node_modules/pi-lens/dist/clients/module-report.js +168 -3
- package/node_modules/pi-lens/dist/clients/ndjson-logger.js +319 -118
- package/node_modules/pi-lens/dist/clients/opengrep-client.js +1 -1
- package/node_modules/pi-lens/dist/clients/partial-edit-apply.js +120 -5
- package/node_modules/pi-lens/dist/clients/path-utils.js +110 -9
- package/node_modules/pi-lens/dist/clients/pipeline.js +47 -13
- package/node_modules/pi-lens/dist/clients/print-mode.js +21 -0
- package/node_modules/pi-lens/dist/clients/project-changes.js +40 -0
- package/node_modules/pi-lens/dist/clients/project-diagnostics/cache.js +3 -2
- package/node_modules/pi-lens/dist/clients/project-diagnostics/runner-adapters/call-graph-impact.js +8 -0
- package/node_modules/pi-lens/dist/clients/project-diagnostics/scanner.js +21 -1
- package/node_modules/pi-lens/dist/clients/project-lens-config.js +86 -9
- package/node_modules/pi-lens/dist/clients/project-report.js +27 -13
- package/node_modules/pi-lens/dist/clients/project-snapshot.js +175 -20
- package/node_modules/pi-lens/dist/clients/project-trust.js +181 -0
- package/node_modules/pi-lens/dist/clients/quiet-window.js +18 -4
- package/node_modules/pi-lens/dist/clients/read-bridge.js +147 -0
- package/node_modules/pi-lens/dist/clients/read-guard-logger.js +159 -1
- package/node_modules/pi-lens/dist/clients/read-guard-tool-lines.js +150 -29
- package/node_modules/pi-lens/dist/clients/read-guard.js +185 -4
- package/node_modules/pi-lens/dist/clients/resource-sampler.js +70 -84
- package/node_modules/pi-lens/dist/clients/review-graph/builder.js +1122 -221
- package/node_modules/pi-lens/dist/clients/review-graph/git-identity.js +2 -1
- package/node_modules/pi-lens/dist/clients/review-graph/import-resolvers.js +21 -10
- package/node_modules/pi-lens/dist/clients/review-graph/symbol-id.js +46 -0
- package/node_modules/pi-lens/dist/clients/review-graph/tsconfig-paths.js +57 -6
- package/node_modules/pi-lens/dist/clients/review-graph/workspace-modules.js +51 -3
- package/node_modules/pi-lens/dist/clients/review-graph-logger.js +30 -1
- package/node_modules/pi-lens/dist/clients/ruff-client.js +27 -44
- package/node_modules/pi-lens/dist/clients/runtime-agent-end.js +107 -73
- package/node_modules/pi-lens/dist/clients/runtime-context.js +36 -12
- package/node_modules/pi-lens/dist/clients/runtime-coordinator.js +74 -6
- package/node_modules/pi-lens/dist/clients/runtime-session.js +405 -117
- package/node_modules/pi-lens/dist/clients/runtime-tool-call.js +71 -48
- package/node_modules/pi-lens/dist/clients/runtime-tool-result.js +218 -23
- package/node_modules/pi-lens/dist/clients/runtime-turn.js +237 -64
- package/node_modules/pi-lens/dist/clients/rust-client.js +2 -1
- package/node_modules/pi-lens/dist/clients/safe-spawn.js +777 -62
- package/node_modules/pi-lens/dist/clients/security-scan-client.js +2 -1
- package/node_modules/pi-lens/dist/clients/session-state-store.js +3 -2
- package/node_modules/pi-lens/dist/clients/sg-runner.js +284 -174
- package/node_modules/pi-lens/dist/clients/slow-fs.js +2 -1
- package/node_modules/pi-lens/dist/clients/smells-rollup.js +224 -0
- package/node_modules/pi-lens/dist/clients/source-filter.js +184 -20
- package/node_modules/pi-lens/dist/clients/source-walker.js +66 -10
- package/node_modules/pi-lens/dist/clients/startup-scan.js +15 -16
- package/node_modules/pi-lens/dist/clients/startup-timing.js +1 -1
- package/node_modules/pi-lens/dist/clients/test-runner-client.js +38 -8
- package/node_modules/pi-lens/dist/clients/tool-event.js +35 -0
- package/node_modules/pi-lens/dist/clients/tool-policy.js +388 -39
- package/node_modules/pi-lens/dist/clients/tool-render.js +155 -0
- package/node_modules/pi-lens/dist/clients/tree-sitter-cache.js +6 -1
- package/node_modules/pi-lens/dist/clients/tree-sitter-client.js +419 -50
- package/node_modules/pi-lens/dist/clients/tree-sitter-logger.js +21 -0
- package/node_modules/pi-lens/dist/clients/tree-sitter-query-loader.js +7 -1
- package/node_modules/pi-lens/dist/clients/tree-sitter-shared.js +7 -2
- package/node_modules/pi-lens/dist/clients/tree-sitter-symbol-extractor.js +44 -7
- package/node_modules/pi-lens/dist/clients/user-notify.js +51 -0
- package/node_modules/pi-lens/dist/clients/vanished-instance-marker.js +57 -0
- package/node_modules/pi-lens/dist/clients/warm-attach.js +33 -13
- package/node_modules/pi-lens/dist/clients/widget-state.js +300 -43
- package/node_modules/pi-lens/dist/clients/word-index.js +391 -64
- package/node_modules/pi-lens/dist/clients/workspace-topology.js +89 -6
- package/node_modules/pi-lens/dist/index.js +49361 -36888
- package/node_modules/pi-lens/dist/mcp/analyze-cli.js +182 -29
- package/node_modules/pi-lens/dist/mcp/server.js +211 -44
- package/node_modules/pi-lens/dist/tools/ast-grep-search.js +93 -27
- package/node_modules/pi-lens/dist/tools/lens-diagnostics.js +200 -36
- package/node_modules/pi-lens/dist/tools/lsp-diagnostics.js +153 -40
- package/node_modules/pi-lens/dist/tools/lsp-navigation.js +46 -3
- package/node_modules/pi-lens/dist/tools/module-report.js +9 -0
- package/node_modules/pi-lens/docs/agent-guide.md +2 -2
- package/node_modules/pi-lens/docs/agent-tools.md +21 -10
- package/node_modules/pi-lens/docs/analysisall.md +192 -0
- package/node_modules/pi-lens/docs/api-ports-inventory.md +165 -0
- package/node_modules/pi-lens/docs/ast-grep_rules_catalog.md +5 -2
- package/node_modules/pi-lens/docs/durable-store-audit-1202.md +32 -0
- package/node_modules/pi-lens/docs/environment-variables.md +44 -0
- package/node_modules/pi-lens/docs/fable.md +27 -0
- package/node_modules/pi-lens/docs/features.md +31 -2
- package/node_modules/pi-lens/docs/globalconfig.md +45 -1
- package/node_modules/pi-lens/docs/language-coverage.md +4 -3
- package/node_modules/pi-lens/docs/lsp-capability-matrix.md +2 -2
- package/node_modules/pi-lens/docs/mcp.md +37 -4
- package/node_modules/pi-lens/docs/servercapabilities.md +3 -3
- package/node_modules/pi-lens/docs/settings.md +12 -1
- package/node_modules/pi-lens/docs/tools.md +4 -1
- package/node_modules/pi-lens/docs/usage.md +18 -0
- package/node_modules/pi-lens/package.json +10 -10
- package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-bare-except-test.yml +49 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-bare-host-path-in-win32-branch-test.yml +87 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-nested-links-test.yml +11 -1
- package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-raw-json-store-write-test.yml +17 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-win32-isabsolute-for-qualification-test.yml +16 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-bare-except.yml +3 -15
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-bare-host-path-in-win32-branch.yml +25 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-nested-links.yml +7 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-raw-json-store-write.yml +30 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-win32-isabsolute-for-qualification.yml +23 -0
- package/node_modules/pi-lens/rules/tree-sitter-queries/tsx/no-nested-links.yml +4 -6
- package/node_modules/pi-lens/rules/tree-sitter-queries/typescript/duplicate-function-arg.yml +2 -2
- package/node_modules/pi-lens/scripts/analyze-pi-lens-logs.mjs +55 -2
- package/node_modules/pi-mcp-adapter/CHANGELOG.md +25 -0
- package/node_modules/pi-mcp-adapter/README.md +34 -3
- package/node_modules/pi-mcp-adapter/agent-plugin-loader.ts +1 -1
- package/node_modules/pi-mcp-adapter/commands.ts +15 -7
- package/node_modules/pi-mcp-adapter/direct-tools.ts +54 -7
- package/node_modules/pi-mcp-adapter/host-html-template.ts +0 -8
- package/node_modules/pi-mcp-adapter/index.ts +8 -3
- package/node_modules/pi-mcp-adapter/init.ts +29 -5
- package/node_modules/pi-mcp-adapter/lifecycle.ts +0 -4
- package/node_modules/pi-mcp-adapter/mcp-auth-flow.ts +1 -2
- package/node_modules/pi-mcp-adapter/mcp-auth.ts +60 -2
- package/node_modules/pi-mcp-adapter/mcp-panel.ts +45 -9
- package/node_modules/pi-mcp-adapter/mcp-script-worker.mjs +22 -20
- package/node_modules/pi-mcp-adapter/metadata-cache.ts +27 -4
- package/node_modules/pi-mcp-adapter/npx-resolver.ts +81 -26
- package/node_modules/pi-mcp-adapter/package.json +3 -3
- package/node_modules/pi-mcp-adapter/proxy-modes.ts +108 -26
- package/node_modules/pi-mcp-adapter/search-ranking.ts +86 -7
- package/node_modules/pi-mcp-adapter/server-manager.ts +36 -7
- package/node_modules/pi-mcp-adapter/session-recovery.ts +8 -2
- package/node_modules/pi-mcp-adapter/tool-approval.ts +48 -7
- package/node_modules/pi-mcp-adapter/tool-metadata.ts +42 -4
- package/node_modules/pi-mcp-adapter/tool-result-renderer.ts +138 -12
- package/node_modules/pi-mcp-adapter/types.ts +93 -27
- package/node_modules/pi-mcp-adapter/ui-server.ts +20 -1
- package/package.json +11 -12
- package/node_modules/pi-lens/dist/clients/ast-grep-parser.js +0 -86
- package/node_modules/pi-lens/dist/clients/lsp/interactive-install.js +0 -367
- package/node_modules/pi-lens/dist/clients/lsp/lsp-index.js +0 -10
- package/node_modules/pi-lens/dist/clients/lsp/server-strategies.js +0 -5
- package/node_modules/pi-lens/dist/clients/project-metadata.js +0 -690
- package/node_modules/pi-lens/dist/clients/source-groups.js +0 -96
- package/node_modules/pi-lens/dist/clients/startup-marker.js +0 -6
- package/node_modules/pi-lens/dist/clients/types.js +0 -11
|
@@ -6,11 +6,11 @@
|
|
|
6
6
|
*
|
|
7
7
|
* Requires: pyright (pip install pyright or npm install -g pyright)
|
|
8
8
|
*/
|
|
9
|
-
import {
|
|
9
|
+
import { logExtension } from "../../extension-log.js";
|
|
10
10
|
import { getLSPService } from "../../lsp/index.js";
|
|
11
11
|
import { safeSpawnAsync } from "../../safe-spawn.js";
|
|
12
12
|
import { PRIORITY } from "../priorities.js";
|
|
13
|
-
import { createAvailabilityChecker } from "./utils/runner-helpers.js";
|
|
13
|
+
import { createAvailabilityChecker, resolveAvailableOrInstall, } from "./utils/runner-helpers.js";
|
|
14
14
|
const pyright = createAvailabilityChecker("pyright", ".exe");
|
|
15
15
|
const pyrightRunner = {
|
|
16
16
|
id: "pyright",
|
|
@@ -34,9 +34,9 @@ const pyrightRunner = {
|
|
|
34
34
|
if (await (pyright.isAvailableAsync(cwd))) {
|
|
35
35
|
cmd = pyright.getCommand(cwd);
|
|
36
36
|
}
|
|
37
|
-
// Strategy 2:
|
|
37
|
+
// Strategy 2: use the shared availability taxonomy and install suppression.
|
|
38
38
|
if (!cmd) {
|
|
39
|
-
const installedPath = await
|
|
39
|
+
const installedPath = await resolveAvailableOrInstall(pyright, "pyright", cwd);
|
|
40
40
|
if (installedPath)
|
|
41
41
|
cmd = installedPath;
|
|
42
42
|
}
|
|
@@ -85,7 +85,11 @@ const pyrightRunner = {
|
|
|
85
85
|
// pi-lens-ignore: missing-error-propagation
|
|
86
86
|
}
|
|
87
87
|
catch {
|
|
88
|
-
|
|
88
|
+
logExtension({
|
|
89
|
+
subsystem: "runner:pyright",
|
|
90
|
+
message: `JSON parse failed for ${ctx.filePath} — raw output: ${output.slice(0, 200)}`,
|
|
91
|
+
metadata: { filePath: ctx.filePath },
|
|
92
|
+
});
|
|
89
93
|
return {
|
|
90
94
|
status: "failed",
|
|
91
95
|
diagnostics: [],
|
|
@@ -6,10 +6,9 @@
|
|
|
6
6
|
* mutating files mid-dispatch after LSP sync has already happened.
|
|
7
7
|
* Supports venv-local installations.
|
|
8
8
|
*/
|
|
9
|
-
import { resolvePackagePath } from "../../package-root.js";
|
|
10
9
|
import { safeSpawnAsync } from "../../safe-spawn.js";
|
|
11
10
|
import { stripAnsi } from "../../sanitize.js";
|
|
12
|
-
import { getAutofixCapability, getLinterPolicyForCwd,
|
|
11
|
+
import { getAutofixCapability, getLinterPolicyForCwd, ruffConfigArgs, } from "../../tool-policy.js";
|
|
13
12
|
import { PRIORITY } from "../priorities.js";
|
|
14
13
|
import { parseRuffOutput } from "./utils/diagnostic-parsers.js";
|
|
15
14
|
import { createAvailabilityChecker, resolveAvailableOrInstall, } from "./utils/runner-helpers.js";
|
|
@@ -61,12 +60,9 @@ const ruffRunner = {
|
|
|
61
60
|
if (!cmd) {
|
|
62
61
|
return { status: "skipped", diagnostics: [], semantic: "none" };
|
|
63
62
|
}
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
"--config",
|
|
68
|
-
resolvePackagePath(import.meta.url, "config/ruff/core.toml"),
|
|
69
|
-
];
|
|
63
|
+
// Shared config-args seam (#1247): the autofix path consumes the same
|
|
64
|
+
// builder, so the package-owned fallback config can never drift.
|
|
65
|
+
const configArgs = ruffConfigArgs(cwd);
|
|
70
66
|
// Step 1: Capture diagnostics (before fixing) — teaching signal for the agent
|
|
71
67
|
const checkResult = await safeSpawnAsync(cmd, ["check", "--output-format", "json", ...configArgs, ctx.filePath], { timeout: 30000 });
|
|
72
68
|
const raw = stripAnsi(checkResult.stdout + checkResult.stderr);
|
|
@@ -21,10 +21,9 @@
|
|
|
21
21
|
*/
|
|
22
22
|
import * as fs from "node:fs";
|
|
23
23
|
import * as path from "node:path";
|
|
24
|
-
import { ensureTool } from "../../installer/index.js";
|
|
25
24
|
import { safeSpawnAsync } from "../../safe-spawn.js";
|
|
26
25
|
import { PRIORITY } from "../priorities.js";
|
|
27
|
-
import { createAvailabilityChecker, lspPrimaryCoversFile, } from "./utils/runner-helpers.js";
|
|
26
|
+
import { createAvailabilityChecker, lspPrimaryCoversFile, resolveAvailableOrInstall, } from "./utils/runner-helpers.js";
|
|
28
27
|
const shellcheck = createAvailabilityChecker("shellcheck", ".exe");
|
|
29
28
|
function findShellcheckConfig(cwd) {
|
|
30
29
|
const local = path.join(cwd, ".shellcheckrc");
|
|
@@ -127,7 +126,7 @@ const shellcheckRunner = {
|
|
|
127
126
|
cmd = shellcheck.getCommand(cwd);
|
|
128
127
|
}
|
|
129
128
|
else {
|
|
130
|
-
const managed = await
|
|
129
|
+
const managed = await resolveAvailableOrInstall(shellcheck, "shellcheck", cwd);
|
|
131
130
|
if (managed)
|
|
132
131
|
cmd = managed;
|
|
133
132
|
}
|
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
import * as fs from "node:fs";
|
|
2
2
|
import * as path from "node:path";
|
|
3
|
-
import { ensureTool } from "../../installer/index.js";
|
|
4
3
|
import { safeSpawnAsync } from "../../safe-spawn.js";
|
|
5
4
|
import { PRIORITY } from "../priorities.js";
|
|
6
|
-
import { createAvailabilityChecker } from "./utils/runner-helpers.js";
|
|
5
|
+
import { createAvailabilityChecker, resolveAvailableOrInstall, } from "./utils/runner-helpers.js";
|
|
7
6
|
const shfmt = createAvailabilityChecker("shfmt", ".exe");
|
|
8
7
|
// shfmt's only config source is .editorconfig. We treat its presence as the
|
|
9
8
|
// opt-in for the (non-error) format-diff warning, so out of the box shfmt only
|
|
@@ -39,7 +38,7 @@ const shfmtRunner = {
|
|
|
39
38
|
cmd = shfmt.getCommand(cwd);
|
|
40
39
|
}
|
|
41
40
|
else {
|
|
42
|
-
const installed = await
|
|
41
|
+
const installed = await resolveAvailableOrInstall(shfmt, "shfmt", cwd);
|
|
43
42
|
if (!installed) {
|
|
44
43
|
return { status: "skipped", diagnostics: [], semantic: "none" };
|
|
45
44
|
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import * as fs from "node:fs";
|
|
2
2
|
import * as os from "node:os";
|
|
3
3
|
import * as path from "node:path";
|
|
4
|
+
import { BoundedLruCache } from "../../bounded-cache.js";
|
|
4
5
|
import { safeSpawnAsync } from "../../safe-spawn.js";
|
|
5
6
|
import { findCompiledClassesDir } from "../../tool-policy.js";
|
|
6
7
|
import { PRIORITY } from "../priorities.js";
|
|
@@ -11,7 +12,7 @@ const java = createAvailabilityChecker("java", ".exe", ["-version"]);
|
|
|
11
12
|
const spotbugs = createAvailabilityChecker("spotbugs", ".bat", ["-version"]);
|
|
12
13
|
const MAX_DIAGNOSTICS = 50;
|
|
13
14
|
const MAX_XML_BYTES = 4 * 1024 * 1024;
|
|
14
|
-
const scanCache = new
|
|
15
|
+
const scanCache = new BoundedLruCache(32);
|
|
15
16
|
/** Reset the SpotBugs scan cache (tests). */
|
|
16
17
|
export function _resetSpotbugsCacheForTests() {
|
|
17
18
|
scanCache.clear();
|
|
@@ -3,6 +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, lspPrimaryCoversFile, resolveToolCommandWithInstallFallback, } from "./utils/runner-helpers.js";
|
|
6
|
+
import { spawnFailedWithNoOutput } from "./utils/spawn-outcome.js";
|
|
6
7
|
const taplo = createAvailabilityChecker("taplo", ".exe");
|
|
7
8
|
function parseTaploOutput(raw, filePath) {
|
|
8
9
|
try {
|
|
@@ -55,7 +56,7 @@ const taploRunner = {
|
|
|
55
56
|
return { status: "skipped", diagnostics: [], semantic: "none" };
|
|
56
57
|
const absPath = path.resolve(cwd, ctx.filePath);
|
|
57
58
|
const result = await safeSpawnAsync(cmd, ["check", "--output=json", absPath], { cwd, timeout: 15000 });
|
|
58
|
-
if (result
|
|
59
|
+
if (spawnFailedWithNoOutput(result)) {
|
|
59
60
|
return { status: "skipped", diagnostics: [], semantic: "none" };
|
|
60
61
|
}
|
|
61
62
|
const diagnostics = parseTaploOutput(result.stdout || "", ctx.filePath);
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
import * as path from "node:path";
|
|
2
|
+
import { safeSpawnAsync } from "../../safe-spawn.js";
|
|
3
|
+
import { pathsEqual } from "../../path-utils.js";
|
|
4
|
+
import { getLinterPolicyForCwd } from "../../tool-policy.js";
|
|
5
|
+
import { PRIORITY } from "../priorities.js";
|
|
6
|
+
import { createAvailabilityChecker, resolveAvailableOrInstall, } from "./utils/runner-helpers.js";
|
|
7
|
+
import { spawnFailedWithNoOutput } from "./utils/spawn-outcome.js";
|
|
8
|
+
const terragrunt = createAvailabilityChecker("terragrunt", ".exe");
|
|
9
|
+
function normalizeSeverity(raw) {
|
|
10
|
+
if (typeof raw === "number")
|
|
11
|
+
return raw === 1 ? "error" : "warning";
|
|
12
|
+
if (typeof raw === "string" && raw.toLowerCase() === "error")
|
|
13
|
+
return "error";
|
|
14
|
+
return "warning";
|
|
15
|
+
}
|
|
16
|
+
function toRawDiagnostics(parsed) {
|
|
17
|
+
if (Array.isArray(parsed))
|
|
18
|
+
return parsed;
|
|
19
|
+
if (!parsed || typeof parsed !== "object")
|
|
20
|
+
return [];
|
|
21
|
+
const invalidFiles = parsed.invalid_files;
|
|
22
|
+
if (!Array.isArray(invalidFiles))
|
|
23
|
+
return [];
|
|
24
|
+
return invalidFiles.flatMap((f) => Array.isArray(f?.diagnostics) ? f.diagnostics : []);
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Parse `terragrunt hcl validate --json` output.
|
|
28
|
+
*
|
|
29
|
+
* OBSERVED CONTRACT (captured empirically from terragrunt v1.1.2, win-x64):
|
|
30
|
+
* the payload is a FLAT JSON array of diagnostic objects on stdout, e.g.
|
|
31
|
+
*
|
|
32
|
+
* [{"range":{"filename":"<ABSOLUTE path>","start":{"line":1,"column":8,...},
|
|
33
|
+
* "end":{...}},"snippet":{...},"summary":"Unclosed configuration block",
|
|
34
|
+
* "detail":"...","severity":"error"}]
|
|
35
|
+
*
|
|
36
|
+
* Key facts: `severity` is a STRING ("error"), `range.filename` is an ABSOLUTE
|
|
37
|
+
* path (host separator), and a CLEAN unit prints NOTHING (empty stdout, exit 0)
|
|
38
|
+
* — not `[]`. The nested `{invalid_files:[{diagnostics:[...]}]}` wrapper and the
|
|
39
|
+
* numeric (1=error/2=warning) severity encoding were NOT observed on v1.1.2 and
|
|
40
|
+
* are retained only as a tolerant fallback for other/older shapes.
|
|
41
|
+
* Malformed/unparseable input returns [].
|
|
42
|
+
*/
|
|
43
|
+
export function parseTerragruntOutput(raw, filePath, absPath = path.resolve(filePath)) {
|
|
44
|
+
if (!raw.trim())
|
|
45
|
+
return [];
|
|
46
|
+
let parsed;
|
|
47
|
+
try {
|
|
48
|
+
parsed = JSON.parse(raw);
|
|
49
|
+
}
|
|
50
|
+
catch {
|
|
51
|
+
return [];
|
|
52
|
+
}
|
|
53
|
+
// Resolved against the unit dir, not compared by basename: a unit that
|
|
54
|
+
// includes its parent via find_in_parent_folders() gets diagnostics from a
|
|
55
|
+
// parent terragrunt.hcl, whose basename matches but whose lines do not.
|
|
56
|
+
const unitDir = path.dirname(absPath);
|
|
57
|
+
const diagnostics = [];
|
|
58
|
+
for (const d of toRawDiagnostics(parsed)) {
|
|
59
|
+
if (!d || typeof d !== "object")
|
|
60
|
+
continue;
|
|
61
|
+
const diagFile = d.range?.filename;
|
|
62
|
+
if (diagFile && !pathsEqual(path.resolve(unitDir, diagFile), absPath))
|
|
63
|
+
continue;
|
|
64
|
+
const line = d.range?.start?.line ?? 1;
|
|
65
|
+
const column = d.range?.start?.column ?? 1;
|
|
66
|
+
const severity = normalizeSeverity(d.severity);
|
|
67
|
+
const message = d.summary ?? d.detail ?? "terragrunt hcl validate error";
|
|
68
|
+
// No rule code in hcl validate output, so the message carries the identity.
|
|
69
|
+
const idMessage = message
|
|
70
|
+
.toLowerCase()
|
|
71
|
+
.replace(/[^a-z0-9]+/g, "-")
|
|
72
|
+
.slice(0, 80);
|
|
73
|
+
diagnostics.push({
|
|
74
|
+
id: `terragrunt-hclvalidate-${line}-${column}-${idMessage}`,
|
|
75
|
+
message,
|
|
76
|
+
filePath,
|
|
77
|
+
line,
|
|
78
|
+
column,
|
|
79
|
+
severity,
|
|
80
|
+
semantic: severity === "error" ? "blocking" : "warning",
|
|
81
|
+
tool: "terragrunt",
|
|
82
|
+
fixable: false,
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
return diagnostics;
|
|
86
|
+
}
|
|
87
|
+
const SKIPPED = {
|
|
88
|
+
status: "skipped",
|
|
89
|
+
diagnostics: [],
|
|
90
|
+
semantic: "none",
|
|
91
|
+
};
|
|
92
|
+
/**
|
|
93
|
+
* Runner for `terragrunt hcl validate --json`, the linter for terragrunt units.
|
|
94
|
+
*
|
|
95
|
+
* REQUIRES the redesigned terragrunt CLI: the `terragrunt hcl validate` /
|
|
96
|
+
* `terragrunt hcl fmt` command group replaced the old `hclvalidate`/`hclfmt`
|
|
97
|
+
* top-level commands in the CLI redesign (~terragrunt v0.75; the legacy names
|
|
98
|
+
* were removed in v1.0). Contract verified empirically on terragrunt v1.1.2.
|
|
99
|
+
*
|
|
100
|
+
* Observed exit-code / output table (terragrunt v1.1.2, win-x64):
|
|
101
|
+
* - clean unit ............ exit 0, EMPTY stdout (no `[]`)
|
|
102
|
+
* - validation findings ... exit 1, flat JSON array on stdout (+ a log line
|
|
103
|
+
* "N HCL validation error(s) found" on stderr)
|
|
104
|
+
* - unknown command ....... an older binary that predates `hcl validate`
|
|
105
|
+
* exits non-zero with the error on STDERR and EMPTY
|
|
106
|
+
* stdout; `spawnFailedWithNoOutput` classifies that
|
|
107
|
+
* as SKIPPED (never a false blocker, and never a
|
|
108
|
+
* false CLEAN — a nonzero exit carries no
|
|
109
|
+
* `SpawnResult.error`, so the status has to be part
|
|
110
|
+
* of the test).
|
|
111
|
+
*
|
|
112
|
+
* `hcl validate` recursively validates the unit(s) at its working dir; it has no
|
|
113
|
+
* per-file flag (`--filter` takes component filter-syntax, NOT a filename — a
|
|
114
|
+
* bare basename silently matches zero components and suppresses ALL findings,
|
|
115
|
+
* verified on v1.1.2). So we validate the edited file's unit directory and
|
|
116
|
+
* attribute findings back to the edited file by absolute path in
|
|
117
|
+
* parseTerragruntOutput.
|
|
118
|
+
*
|
|
119
|
+
* Misdetection edge: `root.hcl` is filename-detected as terragrunt, so a
|
|
120
|
+
* `root.hcl` that is NOT a terragrunt file still gets validated here — `hcl
|
|
121
|
+
* validate` just checks generic HCL, so a non-terragrunt file fails soft
|
|
122
|
+
* (either clean or a plain HCL diagnostic, never a spurious hard blocker).
|
|
123
|
+
*/
|
|
124
|
+
const terragruntRunner = {
|
|
125
|
+
id: "terragrunt",
|
|
126
|
+
appliesTo: ["terragrunt"],
|
|
127
|
+
priority: PRIORITY.GENERAL_ANALYSIS,
|
|
128
|
+
enabledByDefault: true,
|
|
129
|
+
skipTestFiles: false,
|
|
130
|
+
async run(ctx) {
|
|
131
|
+
const cwd = ctx.cwd || process.cwd();
|
|
132
|
+
const policy = getLinterPolicyForCwd(ctx.filePath, cwd);
|
|
133
|
+
if (policy && !policy.preferredRunners.includes("terragrunt"))
|
|
134
|
+
return SKIPPED;
|
|
135
|
+
let cmd = null;
|
|
136
|
+
if (await terragrunt.isAvailableAsync(cwd)) {
|
|
137
|
+
cmd = terragrunt.getCommand(cwd);
|
|
138
|
+
}
|
|
139
|
+
else {
|
|
140
|
+
const managed = await resolveAvailableOrInstall(terragrunt, "terragrunt", cwd);
|
|
141
|
+
if (managed)
|
|
142
|
+
cmd = managed;
|
|
143
|
+
}
|
|
144
|
+
if (!cmd)
|
|
145
|
+
return SKIPPED;
|
|
146
|
+
const absPath = path.resolve(cwd, ctx.filePath);
|
|
147
|
+
const fileDir = path.dirname(absPath);
|
|
148
|
+
const result = await safeSpawnAsync(cmd, ["hcl", "validate", "--json", "--non-interactive"], { cwd: fileDir, timeout: 30000 });
|
|
149
|
+
if (spawnFailedWithNoOutput(result))
|
|
150
|
+
return SKIPPED;
|
|
151
|
+
const diagnostics = parseTerragruntOutput(result.stdout || "", ctx.filePath, absPath);
|
|
152
|
+
if (diagnostics.length === 0) {
|
|
153
|
+
return { status: "succeeded", diagnostics: [], semantic: "none" };
|
|
154
|
+
}
|
|
155
|
+
const hasErrors = diagnostics.some((d) => d.severity === "error");
|
|
156
|
+
return {
|
|
157
|
+
status: hasErrors ? "failed" : "succeeded",
|
|
158
|
+
diagnostics,
|
|
159
|
+
semantic: hasErrors ? "blocking" : "warning",
|
|
160
|
+
};
|
|
161
|
+
},
|
|
162
|
+
};
|
|
163
|
+
export default terragruntRunner;
|
|
@@ -1,9 +1,26 @@
|
|
|
1
1
|
import * as path from "node:path";
|
|
2
|
-
import { ensureTool } from "../../installer/index.js";
|
|
3
2
|
import { safeSpawnAsync } from "../../safe-spawn.js";
|
|
4
|
-
import {
|
|
3
|
+
import { getLinterPolicyForCwd } from "../../tool-policy.js";
|
|
4
|
+
import { findNearestDirWithAnyBasename } from "../../workspace-topology.js";
|
|
5
|
+
import { createAvailabilityChecker, resolveAvailableOrInstall, } from "./utils/runner-helpers.js";
|
|
6
|
+
import { spawnFailedWithNoOutput } from "./utils/spawn-outcome.js";
|
|
5
7
|
import { PRIORITY } from "../priorities.js";
|
|
6
8
|
const tflint = createAvailabilityChecker("tflint", ".exe");
|
|
9
|
+
const TFLINT_CONFIG = ".tflint.hcl";
|
|
10
|
+
/**
|
|
11
|
+
* tflint resolves `.tflint.hcl` from its own working directory and never walks
|
|
12
|
+
* parents (its only fallback is `~/.tflint.hcl`). We run it from the edited
|
|
13
|
+
* file's directory, so a repo-root config would govern nothing beneath the
|
|
14
|
+
* root unless we name it explicitly. Returns null when `TFLINT_CONFIG_FILE` is
|
|
15
|
+
* set: `--config` outranks the env var in tflint's own precedence, so passing
|
|
16
|
+
* one would override a deliberate choice.
|
|
17
|
+
*/
|
|
18
|
+
function findTflintConfig(fileDir) {
|
|
19
|
+
if (process.env.TFLINT_CONFIG_FILE)
|
|
20
|
+
return null;
|
|
21
|
+
const dir = findNearestDirWithAnyBasename(fileDir, [TFLINT_CONFIG]);
|
|
22
|
+
return dir ? path.join(dir, TFLINT_CONFIG) : null;
|
|
23
|
+
}
|
|
7
24
|
function parseTflintOutput(raw, filePath) {
|
|
8
25
|
try {
|
|
9
26
|
const parsed = JSON.parse(raw);
|
|
@@ -36,12 +53,16 @@ const tflintRunner = {
|
|
|
36
53
|
skipTestFiles: false,
|
|
37
54
|
async run(ctx) {
|
|
38
55
|
const cwd = ctx.cwd || process.cwd();
|
|
56
|
+
const policy = getLinterPolicyForCwd(ctx.filePath, cwd);
|
|
57
|
+
if (policy && !policy.preferredRunners.includes("tflint")) {
|
|
58
|
+
return { status: "skipped", diagnostics: [], semantic: "none" };
|
|
59
|
+
}
|
|
39
60
|
let cmd = null;
|
|
40
61
|
if (await (tflint.isAvailableAsync(cwd))) {
|
|
41
62
|
cmd = tflint.getCommand(cwd);
|
|
42
63
|
}
|
|
43
64
|
else {
|
|
44
|
-
const managed = await
|
|
65
|
+
const managed = await resolveAvailableOrInstall(tflint, "tflint", cwd);
|
|
45
66
|
if (managed)
|
|
46
67
|
cmd = managed;
|
|
47
68
|
}
|
|
@@ -49,8 +70,19 @@ const tflintRunner = {
|
|
|
49
70
|
return { status: "skipped", diagnostics: [], semantic: "none" };
|
|
50
71
|
const absPath = path.resolve(cwd, ctx.filePath);
|
|
51
72
|
const fileDir = path.dirname(absPath);
|
|
52
|
-
const
|
|
53
|
-
|
|
73
|
+
const args = [
|
|
74
|
+
"--format=json",
|
|
75
|
+
"--no-color",
|
|
76
|
+
`--filter=${path.basename(absPath)}`,
|
|
77
|
+
];
|
|
78
|
+
const configPath = findTflintConfig(fileDir);
|
|
79
|
+
if (configPath)
|
|
80
|
+
args.push(`--config=${configPath}`);
|
|
81
|
+
const result = await safeSpawnAsync(cmd, args, {
|
|
82
|
+
cwd: fileDir,
|
|
83
|
+
timeout: 30000,
|
|
84
|
+
});
|
|
85
|
+
if (spawnFailedWithNoOutput(result)) {
|
|
54
86
|
return { status: "skipped", diagnostics: [], semantic: "none" };
|
|
55
87
|
}
|
|
56
88
|
const diagnostics = parseTflintOutput(result.stdout || "", ctx.filePath);
|
|
@@ -525,7 +525,9 @@ const treeSitterRunner = {
|
|
|
525
525
|
});
|
|
526
526
|
}
|
|
527
527
|
else {
|
|
528
|
-
|
|
528
|
+
// #1333: the logTreeSitter call below already carries this failure to
|
|
529
|
+
// tree-sitter.log — the console.error was a duplicate RAW write into
|
|
530
|
+
// pi's frame, not a second destination. Sink kept, write dropped.
|
|
529
531
|
logTreeSitter({
|
|
530
532
|
phase: "query_error",
|
|
531
533
|
filePath,
|
|
@@ -15,8 +15,14 @@
|
|
|
15
15
|
* reports at the same line (`suppressTrivyConfigDockerOverlap`), so trivy
|
|
16
16
|
* only adds the security checks hadolint lacks.
|
|
17
17
|
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
18
|
+
* - **Terraform**: the `.tf` language files themselves — trivy evaluates
|
|
19
|
+
* the Terraform language directly, so no content gate is needed (unlike
|
|
20
|
+
* the yaml/k8s heuristic above). Terragrunt (`.hcl`) is deliberately
|
|
21
|
+
* excluded: trivy has no terragrunt support, and terragrunt config is
|
|
22
|
+
* covered by the terragrunt runner instead.
|
|
23
|
+
*
|
|
24
|
+
* Deferred (tracked on #131): Helm chart rendering, Docker Compose,
|
|
25
|
+
* CloudFormation.
|
|
20
26
|
*
|
|
21
27
|
* Gating: the same explicit `trivy.enabled` opt-in as the session-scan modes —
|
|
22
28
|
* trivy is opt-in, period. (Misconfig needs only the small policy bundle, not
|
|
@@ -30,7 +36,8 @@ import * as path from "node:path";
|
|
|
30
36
|
import { safeSpawnAsync } from "../../safe-spawn.js";
|
|
31
37
|
import { isTrivyEnabled, resolveSeverityFloor, } from "../../trivy-client.js";
|
|
32
38
|
import { PRIORITY } from "../priorities.js";
|
|
33
|
-
import { createAvailabilityChecker } from "./utils/runner-helpers.js";
|
|
39
|
+
import { createAvailabilityChecker, resolveAvailableOrInstall, } from "./utils/runner-helpers.js";
|
|
40
|
+
import { spawnFailedWithNoOutput } from "./utils/spawn-outcome.js";
|
|
34
41
|
const trivy = createAvailabilityChecker("trivy", ".exe");
|
|
35
42
|
/**
|
|
36
43
|
* Heuristic: does this YAML look like a Kubernetes manifest (vs a CI workflow,
|
|
@@ -115,7 +122,7 @@ export function parseTrivyConfigOutput(raw, filePath) {
|
|
|
115
122
|
}
|
|
116
123
|
const trivyConfigRunner = {
|
|
117
124
|
id: "trivy-config",
|
|
118
|
-
appliesTo: ["docker", "yaml"],
|
|
125
|
+
appliesTo: ["docker", "yaml", "terraform"],
|
|
119
126
|
priority: PRIORITY.GENERAL_ANALYSIS,
|
|
120
127
|
enabledByDefault: true,
|
|
121
128
|
skipTestFiles: false,
|
|
@@ -144,8 +151,7 @@ const trivyConfigRunner = {
|
|
|
144
151
|
cmd = trivy.getCommand(cwd);
|
|
145
152
|
}
|
|
146
153
|
else {
|
|
147
|
-
const
|
|
148
|
-
const managed = await ensureTool("trivy");
|
|
154
|
+
const managed = await resolveAvailableOrInstall(trivy, "trivy", cwd);
|
|
149
155
|
if (managed)
|
|
150
156
|
cmd = managed;
|
|
151
157
|
}
|
|
@@ -162,7 +168,7 @@ const trivyConfigRunner = {
|
|
|
162
168
|
severities,
|
|
163
169
|
absPath,
|
|
164
170
|
], { cwd, timeout: 60_000 });
|
|
165
|
-
if (result
|
|
171
|
+
if (spawnFailedWithNoOutput(result)) {
|
|
166
172
|
return { status: "skipped", diagnostics: [], semantic: "none" };
|
|
167
173
|
}
|
|
168
174
|
const diagnostics = parseTrivyConfigOutput(result.stdout || "", ctx.filePath);
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { safeSpawnAsync } from "../../../safe-spawn.js";
|
|
2
|
+
import { assertInstallAllowed } from "../../../project-trust.js";
|
|
2
3
|
const attempted = new Set();
|
|
3
4
|
function key(cwd, tool) {
|
|
4
5
|
return `${cwd}:${tool}`;
|
|
@@ -9,6 +10,8 @@ function key(cwd, tool) {
|
|
|
9
10
|
* Installs are attempted once per cwd+tool per session to avoid repeated churn.
|
|
10
11
|
*/
|
|
11
12
|
export async function tryLazyInstall(tool, cwd) {
|
|
13
|
+
if (!assertInstallAllowed(`runner lazy install: ${tool}`))
|
|
14
|
+
return false;
|
|
12
15
|
const k = key(cwd, tool);
|
|
13
16
|
if (attempted.has(k))
|
|
14
17
|
return false;
|