@herbertgao/pi-extensions 2026.8.5 → 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 +2 -2
- package/node_modules/@herbertgao/pi-cc-extensions/README.md +2 -2
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/config/config.ts +19 -7
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/config/panel.ts +30 -9
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/feature/compact-thinking.ts +272 -22
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/feature/context.ts +74 -5
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/compact-mode.ts +94 -77
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/markdown-enhance.ts +48 -6
- 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 +16 -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 +22 -15
- 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 +34 -10
- package/node_modules/@herbertgao/pi-subagents/src/usage.ts +129 -1
- package/node_modules/@herbertgao/pi-subagents/src/worktree.ts +29 -5
- package/node_modules/@juicesharp/rpiv-ask-user-question/README.md +3 -0
- package/node_modules/@juicesharp/rpiv-ask-user-question/ask-user-question.ts +46 -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 +8 -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 +119 -103
- 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 +13 -9
- package/node_modules/@narumitw/pi-btw/src/btw.ts +40 -42
- 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 +78 -15
- package/node_modules/@narumitw/pi-btw/src/settings.ts +22 -2
- package/node_modules/@narumitw/pi-btw/src/transcript-pager.ts +136 -45
- package/node_modules/pi-lens/CHANGELOG.md +1004 -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 +427 -0
- package/node_modules/pi-lens/dist/clients/agent-nudge.js +79 -16
- 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 +176 -37
- 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/bus-events-logger.js +62 -6
- package/node_modules/pi-lens/dist/clients/bus-publish.js +11 -3
- package/node_modules/pi-lens/dist/clients/cascade-budget.js +196 -0
- package/node_modules/pi-lens/dist/clients/cascade-format.js +76 -2
- 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/console-guard-install.js +16 -4
- package/node_modules/pi-lens/dist/clients/dead-code-client.js +249 -52
- 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 +43 -9
- package/node_modules/pi-lens/dist/clients/diagnostic-dispositions.js +153 -37
- package/node_modules/pi-lens/dist/clients/diagnostic-line-freshness.js +298 -0
- package/node_modules/pi-lens/dist/clients/diagnostics-publish.js +10 -3
- package/node_modules/pi-lens/dist/clients/dispatch/dispatcher.js +165 -11
- package/node_modules/pi-lens/dist/clients/dispatch/integration.js +325 -72
- 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 +81 -41
- 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 +488 -0
- package/node_modules/pi-lens/dist/clients/dispatch/runners/utils/candidate-probe.js +84 -0
- 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 +943 -93
- 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 +106 -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/disposition-publish.js +10 -3
- package/node_modules/pi-lens/dist/clients/eval-timestamp.js +17 -0
- package/node_modules/pi-lens/dist/clients/event-loop-monitor.js +28 -5
- package/node_modules/pi-lens/dist/clients/extension-log.js +317 -3
- 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/fix-worklog.js +5 -1
- package/node_modules/pi-lens/dist/clients/format-events-publish.js +39 -8
- 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 +49 -21
- package/node_modules/pi-lens/dist/clients/gitleaks-client.js +181 -8
- package/node_modules/pi-lens/dist/clients/go-client.js +21 -39
- package/node_modules/pi-lens/dist/clients/govulncheck-client.js +219 -10
- package/node_modules/pi-lens/dist/clients/grammar-source.js +333 -10
- package/node_modules/pi-lens/dist/clients/host-ports.js +9 -1
- package/node_modules/pi-lens/dist/clients/installer/index.js +1119 -101
- 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 +86 -15
- package/node_modules/pi-lens/dist/clients/knip-client.js +361 -24
- 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 +487 -9
- 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-events.js +56 -25
- package/node_modules/pi-lens/dist/clients/lens-flag-registry.js +16 -0
- package/node_modules/pi-lens/dist/clients/live-bus-emitter.js +45 -2
- package/node_modules/pi-lens/dist/clients/lsp/aggregation.js +30 -4
- package/node_modules/pi-lens/dist/clients/lsp/cascade-tier.js +160 -20
- package/node_modules/pi-lens/dist/clients/lsp/client.js +1666 -148
- package/node_modules/pi-lens/dist/clients/lsp/diagnostic-binding.js +111 -0
- package/node_modules/pi-lens/dist/clients/lsp/document-drift.js +389 -0
- package/node_modules/pi-lens/dist/clients/lsp/index.js +2496 -171
- 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 +517 -69
- 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 +172 -0
- package/node_modules/pi-lens/dist/clients/lsp/wait-policy/classification.js +21 -5
- package/node_modules/pi-lens/dist/clients/lsp/wait-policy/strategies.js +61 -3
- 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/analyze.js +4 -0
- package/node_modules/pi-lens/dist/clients/mcp/session.js +39 -18
- package/node_modules/pi-lens/dist/clients/model-provider.js +53 -0
- 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 +178 -30
- 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 +85 -15
- 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/runner-findings.js +23 -2
- 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 +76 -4
- package/node_modules/pi-lens/dist/clients/run-duration.js +55 -0
- package/node_modules/pi-lens/dist/clients/runtime-agent-end.js +248 -13
- package/node_modules/pi-lens/dist/clients/runtime-context.js +112 -12
- package/node_modules/pi-lens/dist/clients/runtime-coordinator.js +472 -61
- package/node_modules/pi-lens/dist/clients/runtime-session.js +359 -13
- package/node_modules/pi-lens/dist/clients/runtime-tool-call.js +217 -22
- package/node_modules/pi-lens/dist/clients/runtime-tool-result.js +269 -22
- package/node_modules/pi-lens/dist/clients/runtime-turn.js +948 -87
- package/node_modules/pi-lens/dist/clients/rust-client.js +21 -37
- 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 +224 -8
- package/node_modules/pi-lens/dist/clients/sg-runner.js +249 -37
- package/node_modules/pi-lens/dist/clients/single-flight.js +158 -0
- package/node_modules/pi-lens/dist/clients/smells-rollup.js +18 -11
- package/node_modules/pi-lens/dist/clients/stale-marker.js +17 -0
- package/node_modules/pi-lens/dist/clients/startup-timing.js +26 -2
- package/node_modules/pi-lens/dist/clients/test-runner-client.js +574 -32
- package/node_modules/pi-lens/dist/clients/tool-event.js +56 -5
- package/node_modules/pi-lens/dist/clients/tool-policy.js +127 -20
- package/node_modules/pi-lens/dist/clients/tool-set-policy.js +76 -0
- 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/warm-attach.js +17 -0
- package/node_modules/pi-lens/dist/clients/widget-state.js +336 -36
- package/node_modules/pi-lens/dist/clients/word-index.js +305 -33
- package/node_modules/pi-lens/dist/clients/zizmor-config.js +214 -14
- package/node_modules/pi-lens/dist/index.js +64677 -49484
- package/node_modules/pi-lens/dist/mcp/server.js +8 -2
- package/node_modules/pi-lens/dist/tools/activate-tools.js +17 -5
- package/node_modules/pi-lens/dist/tools/ast-grep-replace.js +9 -4
- package/node_modules/pi-lens/dist/tools/lens-diagnostic-mark.js +5 -2
- package/node_modules/pi-lens/dist/tools/lens-diagnostics.js +469 -56
- package/node_modules/pi-lens/dist/tools/lsp-diagnostics.js +190 -46
- package/node_modules/pi-lens/dist/tools/lsp-navigation.js +46 -7
- package/node_modules/pi-lens/dist/tools/symbol-search.js +1 -1
- package/node_modules/pi-lens/docs/agent-guide.md +44 -14
- package/node_modules/pi-lens/docs/ast-grep_rules_catalog.md +518 -501
- package/node_modules/pi-lens/docs/dispositions.md +21 -0
- package/node_modules/pi-lens/docs/features.md +33 -6
- package/node_modules/pi-lens/docs/globalconfig.md +14 -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 +25 -1
- package/node_modules/pi-lens/docs/usage.md +24 -5
- package/node_modules/pi-lens/docs/word-index.md +35 -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 +22 -0
- 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-conditional-empty-object-spread-js-test.yml +9 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-conditional-empty-object-spread-test.yml +9 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-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 +9 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-reflect-apply-test.yml +9 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-reflect-get-js-test.yml +9 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-reflect-get-test.yml +9 -0
- 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-laundering-test.yml +11 -0
- 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 +66 -0
- 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-conditional-empty-object-spread-js.yml +21 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-conditional-empty-object-spread.yml +29 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-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 +29 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-reflect-apply.yml +30 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-reflect-get-js.yml +41 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-reflect-get.yml +42 -0
- 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 +32 -0
- 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 +132 -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 +12 -11
- package/node_modules/pi-lens/skills/pi-lens-lsp-navigation/SKILL.md +22 -22
- package/node_modules/pi-lens/skills/pi-lens-write-ast-grep-rule/SKILL.md +87 -116
- package/node_modules/pi-lens/skills/pi-lens-write-ast-grep-rule/reference.md +170 -0
- package/node_modules/pi-lens/skills/pi-lens-write-tree-sitter-rule/SKILL.md +3 -1
- package/node_modules/pi-lens/vendor/grammars/tree-sitter-cue.wasm +0 -0
- package/node_modules/pi-mcp-adapter/CHANGELOG.md +49 -0
- package/node_modules/pi-mcp-adapter/README.md +51 -6
- package/node_modules/pi-mcp-adapter/agent-dir.ts +12 -4
- package/node_modules/pi-mcp-adapter/cli.js +188 -5
- package/node_modules/pi-mcp-adapter/commands.ts +128 -22
- package/node_modules/pi-mcp-adapter/config.ts +28 -10
- package/node_modules/pi-mcp-adapter/direct-tools.ts +23 -19
- 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/mcp-setup-panel.ts +2 -1
- package/node_modules/pi-mcp-adapter/metadata-cache.ts +46 -25
- package/node_modules/pi-mcp-adapter/package-mcp-loader.ts +168 -0
- package/node_modules/pi-mcp-adapter/package.json +4 -1
- package/node_modules/pi-mcp-adapter/proxy-modes.ts +5 -4
- package/node_modules/pi-mcp-adapter/request-headers-command.ts +330 -0
- package/node_modules/pi-mcp-adapter/search-ranking.ts +92 -22
- package/node_modules/pi-mcp-adapter/server-manager.ts +145 -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-metadata.ts +38 -18
- package/node_modules/pi-mcp-adapter/tool-result-renderer.ts +44 -4
- package/node_modules/pi-mcp-adapter/types.ts +95 -10
- package/node_modules/pi-mcp-adapter/ui-server.ts +18 -16
- package/node_modules/pi-mcp-adapter/utils.ts +70 -0
- package/node_modules/pi-web-access/CHANGELOG.md +37 -0
- package/node_modules/pi-web-access/README.md +38 -14
- package/node_modules/pi-web-access/anysearch.ts +4 -2
- package/node_modules/pi-web-access/auth-fetch.ts +148 -0
- package/node_modules/pi-web-access/brave.ts +16 -4
- package/node_modules/pi-web-access/chrome-cookies.ts +110 -23
- package/node_modules/pi-web-access/curator-page.ts +8 -3
- package/node_modules/pi-web-access/curator-server.ts +5 -1
- package/node_modules/pi-web-access/exa.ts +18 -7
- package/node_modules/pi-web-access/extract.ts +134 -37
- package/node_modules/pi-web-access/fetch-params.ts +17 -3
- package/node_modules/pi-web-access/firecrawl.ts +172 -12
- package/node_modules/pi-web-access/gemini-search.ts +33 -7
- package/node_modules/pi-web-access/index.ts +160 -104
- package/node_modules/pi-web-access/package.json +2 -2
- 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 +51 -23
- 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/node_modules/pi-web-access/youtube-extract.ts +2 -2
- package/package.json +13 -13
|
@@ -18,10 +18,14 @@
|
|
|
18
18
|
* Install: cargo install typos-cli
|
|
19
19
|
* Or: npm install -g typos-cli (if wrapped)
|
|
20
20
|
*/
|
|
21
|
+
import { skipUnlessToolRan } from "./utils/tool-failure.js";
|
|
21
22
|
import { safeSpawnAsync } from "../../safe-spawn.js";
|
|
22
23
|
import { PRIORITY } from "../priorities.js";
|
|
23
24
|
import { createAvailabilityChecker } from "./utils/runner-helpers.js";
|
|
24
25
|
const typos = createAvailabilityChecker("typos", ".exe");
|
|
26
|
+
// typos-cli exit codes: 0 = no typos, 2 = typos found, 1 = an error that
|
|
27
|
+
// stopped the scan. Anything nonzero outside {2} is a rejected invocation.
|
|
28
|
+
const TYPOS_EXIT_CODES = { ran: [2] };
|
|
25
29
|
/**
|
|
26
30
|
* Parse typos-cli JSON output (JSON Lines format)
|
|
27
31
|
*
|
|
@@ -90,6 +94,16 @@ const spellcheckRunner = {
|
|
|
90
94
|
const result = await safeSpawnAsync(typos.getCommand(ctx.cwd || process.cwd()), args, {
|
|
91
95
|
timeout: 15000,
|
|
92
96
|
});
|
|
97
|
+
// #1816: typos-cli exits 0 clean, 2 with typos found, and 1 on an ERROR
|
|
98
|
+
// (unreadable config, bad argument). The `status === 2 || stdout` test
|
|
99
|
+
// below is false for exit 1 with an empty stdout, so a failed run was
|
|
100
|
+
// reported as a clean file. Only 0 and 2 are runs.
|
|
101
|
+
const skipped = skipUnlessToolRan("spellcheck", {
|
|
102
|
+
result,
|
|
103
|
+
exitCodes: TYPOS_EXIT_CODES,
|
|
104
|
+
});
|
|
105
|
+
if (skipped)
|
|
106
|
+
return skipped;
|
|
93
107
|
// typos-cli exits with code 2 if typos found, 0 if clean
|
|
94
108
|
const hasTypos = result.status === 2 || result.stdout?.trim();
|
|
95
109
|
if (!hasTypos) {
|
|
@@ -2,7 +2,17 @@ import { safeSpawnAsync } from "../../safe-spawn.js";
|
|
|
2
2
|
import { getLinterPolicyForCwd, hasSqlfluffConfig } from "../../tool-policy.js";
|
|
3
3
|
import { PRIORITY } from "../priorities.js";
|
|
4
4
|
import { createAvailabilityChecker, resolveToolCommandWithInstallFallback, } from "./utils/runner-helpers.js";
|
|
5
|
+
import { skipUnlessToolRan } from "./utils/tool-failure.js";
|
|
5
6
|
const sqlfluff = createAvailabilityChecker("sqlfluff", ".exe");
|
|
7
|
+
// sqlfluff exit codes (its CLI docs): 0 = clean, 1 = violations found, 2 = a
|
|
8
|
+
// user error that stopped the lint (unknown dialect, unreadable config).
|
|
9
|
+
// Only 2 is a rejected invocation.
|
|
10
|
+
//
|
|
11
|
+
// The exit TABLE is what protects this runner, not the nothing-to-parse rule:
|
|
12
|
+
// sqlfluff writes its user errors to STDOUT, not stderr (live: an unknown
|
|
13
|
+
// dialect prints the error there), so stdout is non-empty and the fallback
|
|
14
|
+
// rule would read the failed run as a run that found nothing.
|
|
15
|
+
const SQLFLUFF_EXIT_CODES = { ran: [1] };
|
|
6
16
|
export { hasSqlfluffConfig };
|
|
7
17
|
// sqlfluff's JSON lint output does not carry a per-violation fixable flag —
|
|
8
18
|
// `sqlfluff fix` is a separate command and the lint surface doesn't tell us
|
|
@@ -131,7 +141,17 @@ const sqlfluffRunner = {
|
|
|
131
141
|
}
|
|
132
142
|
const result = await safeSpawnAsync(cmd, args, {
|
|
133
143
|
timeout: 20000,
|
|
144
|
+
cwd,
|
|
145
|
+
});
|
|
146
|
+
// #1816: this runner read `result.status` zero times, so a user error
|
|
147
|
+
// fell through `parseSqlfluffOutput`'s JSON catch to zero violations and
|
|
148
|
+
// reported the SQL file as clean.
|
|
149
|
+
const skipped = skipUnlessToolRan("sqlfluff", {
|
|
150
|
+
result,
|
|
151
|
+
exitCodes: SQLFLUFF_EXIT_CODES,
|
|
134
152
|
});
|
|
153
|
+
if (skipped)
|
|
154
|
+
return skipped;
|
|
135
155
|
const diagnostics = parseSqlfluffOutput(result.stdout ?? "", ctx.filePath);
|
|
136
156
|
if (diagnostics.length === 0) {
|
|
137
157
|
return { status: "succeeded", diagnostics: [], semantic: "none" };
|
|
@@ -3,7 +3,20 @@ import { safeSpawnAsync } from "../../safe-spawn.js";
|
|
|
3
3
|
import { getLinterPolicyForCwd, hasStylelintConfig, } from "../../tool-policy.js";
|
|
4
4
|
import { PRIORITY } from "../priorities.js";
|
|
5
5
|
import { createAvailabilityChecker, resolveToolCommandWithInstallFallback, } from "./utils/runner-helpers.js";
|
|
6
|
+
import { skipUnlessToolRan } from "./utils/tool-failure.js";
|
|
6
7
|
const stylelint = createAvailabilityChecker("stylelint", ".cmd");
|
|
8
|
+
// stylelint exit codes (its "Exit codes" docs page): 0 = no problems, 1 = a
|
|
9
|
+
// fatal error, 2 = lint problems found, 78 = a configuration error.
|
|
10
|
+
//
|
|
11
|
+
// 1 is listed as a run here rather than a rejection. The evidence for that is
|
|
12
|
+
// NOT a live stylelint: it is this repo's own hand-written fixture
|
|
13
|
+
// (tests/clients/dispatch/runners/stylelint-fixable.test.ts), which reports
|
|
14
|
+
// findings under exit 1. Rather than rewrite a fixture whose provenance is
|
|
15
|
+
// unknown, the table keeps 1 permissive. That is safe because a genuinely
|
|
16
|
+
// fatal stylelint under `--formatter json` writes nothing to stdout, so the
|
|
17
|
+
// nothing-to-parse rule still catches it. 78 is the rejection this table
|
|
18
|
+
// exists to name.
|
|
19
|
+
const STYLELINT_EXIT_CODES = { ran: [1, 2] };
|
|
7
20
|
// Stylelint's standard JSON output reports only aggregate fixableErrorCount /
|
|
8
21
|
// fixableWarningCount per file — there is no per-warning fix flag in the CLI
|
|
9
22
|
// surface. To route the actionable warnings here without a tool rewrite, we
|
|
@@ -100,6 +113,15 @@ const stylelintRunner = {
|
|
|
100
113
|
if (!cmd)
|
|
101
114
|
return { status: "skipped", diagnostics: [], semantic: "none" };
|
|
102
115
|
const result = await safeSpawnAsync(cmd, ["--formatter", "json", ctx.filePath], { timeout: 20000, cwd });
|
|
116
|
+
// #1816: this runner read `result.status` zero times, so an exit-78
|
|
117
|
+
// config error (or an exit-1 crash) fell through parseStylelintJson's
|
|
118
|
+
// catch to zero diagnostics and reported a clean stylesheet.
|
|
119
|
+
const skipped = skipUnlessToolRan("stylelint", {
|
|
120
|
+
result,
|
|
121
|
+
exitCodes: STYLELINT_EXIT_CODES,
|
|
122
|
+
});
|
|
123
|
+
if (skipped)
|
|
124
|
+
return skipped;
|
|
103
125
|
const raw = result.stdout ?? "";
|
|
104
126
|
const diagnostics = parseStylelintJson(raw, ctx.filePath);
|
|
105
127
|
if (diagnostics.length === 0) {
|
|
@@ -2,6 +2,7 @@ import * as path from "node:path";
|
|
|
2
2
|
import { safeSpawnAsync } from "../../safe-spawn.js";
|
|
3
3
|
import { PRIORITY } from "../priorities.js";
|
|
4
4
|
import { createAvailabilityChecker, resolveToolCommandWithInstallFallback, } from "./utils/runner-helpers.js";
|
|
5
|
+
import { skipUnlessToolRan } from "./utils/tool-failure.js";
|
|
5
6
|
const swiftlint = createAvailabilityChecker("swiftlint", ".exe");
|
|
6
7
|
// SwiftLint rules whose rule class declares a `corrector` — i.e. rules that
|
|
7
8
|
// `swiftlint --fix` rewrites deterministically. The JSON reporter does not
|
|
@@ -126,6 +127,15 @@ const swiftlintRunner = {
|
|
|
126
127
|
if (!cmd)
|
|
127
128
|
return { status: "skipped", diagnostics: [], semantic: "none" };
|
|
128
129
|
const result = await safeSpawnAsync(cmd, ["--reporter", "json", path.resolve(cwd, ctx.filePath)], { cwd, timeout: 15000 });
|
|
130
|
+
// #1816: this runner read `result.status` zero times, so a SwiftLint
|
|
131
|
+
// that refused the invocation reported a clean Swift file. No exit-code
|
|
132
|
+
// table is declared: SwiftLint's nonzero codes are not documented
|
|
133
|
+
// stably enough to call any of them a rejection, so classification
|
|
134
|
+
// rests on the conservative rule — a nonzero exit with nothing to parse
|
|
135
|
+
// never ran.
|
|
136
|
+
const skipped = skipUnlessToolRan("swiftlint", { result });
|
|
137
|
+
if (skipped)
|
|
138
|
+
return skipped;
|
|
129
139
|
// SwiftLint exits non-zero on violations — stdout still has the JSON
|
|
130
140
|
const raw = result.stdout || "";
|
|
131
141
|
const diagnostics = parseSwiftLintOutput(raw, ctx.filePath);
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import * as path from "node:path";
|
|
2
|
+
import { findLocalBinUpwards } from "../../package-manager.js";
|
|
2
3
|
import { safeSpawnAsync } from "../../safe-spawn.js";
|
|
3
4
|
import { getLinterPolicyForCwd } from "../../tool-policy.js";
|
|
4
5
|
import { PRIORITY } from "../priorities.js";
|
|
@@ -45,12 +46,23 @@ const taploRunner = {
|
|
|
45
46
|
if (lspPrimaryCoversFile(ctx, "toml") && (await ctx.hasTool("taplo"))) {
|
|
46
47
|
return { status: "skipped", diagnostics: [], semantic: "none" };
|
|
47
48
|
}
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
49
|
+
// Project binary first (#1731, discipline B): `taplo.isAvailableAsync`
|
|
50
|
+
// resolves through `findManagedNodeToolBinary`, pi-lens's own managed
|
|
51
|
+
// shim — checked BEFORE any project-local candidate, so a project's own
|
|
52
|
+
// `node_modules/.bin/taplo` (npm `@taplo/cli`) never won once the managed
|
|
53
|
+
// copy answered. `findLocalBinUpwards` defaults to `.cmd` on Windows,
|
|
54
|
+
// matching that npm shim; the availability checker's `.exe` extension is
|
|
55
|
+
// correct for pi-lens's OWN managed install (a GitHub-release binary,
|
|
56
|
+
// `clients/installer/index.ts` taplo entry), a different artifact with a
|
|
57
|
+
// different extension, so it stays as the checker's fallback only.
|
|
58
|
+
let cmd = findLocalBinUpwards("taplo", cwd) ?? null;
|
|
59
|
+
if (!cmd) {
|
|
60
|
+
if (await (taplo.isAvailableAsync(cwd))) {
|
|
61
|
+
cmd = taplo.getCommand(cwd);
|
|
62
|
+
}
|
|
63
|
+
else {
|
|
64
|
+
cmd = await resolveToolCommandWithInstallFallback(cwd, "taplo");
|
|
65
|
+
}
|
|
54
66
|
}
|
|
55
67
|
if (!cmd)
|
|
56
68
|
return { status: "skipped", diagnostics: [], semantic: "none" };
|
|
@@ -10,6 +10,11 @@
|
|
|
10
10
|
* v1 scope — the highest-value, lowest-overlap surface:
|
|
11
11
|
* - **Kubernetes manifests** (yaml with an `apiVersion:` + `kind:` signature):
|
|
12
12
|
* zero existing coverage in pi-lens, so no dedup needed.
|
|
13
|
+
* - **CloudFormation templates** (yaml OR json with an
|
|
14
|
+
* `AWSTemplateFormatVersion` key, or a `Resources` map whose entries carry
|
|
15
|
+
* an `AWS::`/`Custom::`-namespaced `Type`; refs #1757): same zero-overlap
|
|
16
|
+
* rationale as Kubernetes — trivy's `cloudformation` misconfig scanner is
|
|
17
|
+
* the only IaC-misconfig coverage pi-lens has for CFN.
|
|
13
18
|
* - **Dockerfiles**: overlaps hadolint on a few rules (`:latest`, root, …);
|
|
14
19
|
* the dispatcher suppresses trivy-config findings that hadolint already
|
|
15
20
|
* reports at the same line (`suppressTrivyConfigDockerOverlap`), so trivy
|
|
@@ -17,12 +22,11 @@
|
|
|
17
22
|
*
|
|
18
23
|
* - **Terraform**: the `.tf` language files themselves — trivy evaluates
|
|
19
24
|
* the Terraform language directly, so no content gate is needed (unlike
|
|
20
|
-
* the yaml/k8s
|
|
21
|
-
* excluded: trivy has no terragrunt support, and terragrunt
|
|
22
|
-
* covered by the terragrunt runner instead.
|
|
25
|
+
* the yaml/k8s/CloudFormation heuristics above). Terragrunt (`.hcl`) is
|
|
26
|
+
* deliberately excluded: trivy has no terragrunt support, and terragrunt
|
|
27
|
+
* config is covered by the terragrunt runner instead.
|
|
23
28
|
*
|
|
24
|
-
* Deferred (tracked on #131): Helm chart rendering, Docker Compose
|
|
25
|
-
* CloudFormation.
|
|
29
|
+
* Deferred (tracked on #131): Helm chart rendering, Docker Compose.
|
|
26
30
|
*
|
|
27
31
|
* Gating: the same explicit `trivy.enabled` opt-in as the session-scan modes —
|
|
28
32
|
* trivy is opt-in, period. (Misconfig needs only the small policy bundle, not
|
|
@@ -31,13 +35,14 @@
|
|
|
31
35
|
*
|
|
32
36
|
* Refs: #131 (Mode 2)
|
|
33
37
|
*/
|
|
38
|
+
import { formatToolFailure } from "./utils/tool-failure.js";
|
|
34
39
|
import * as fs from "node:fs";
|
|
35
40
|
import * as path from "node:path";
|
|
41
|
+
import { incrementDegradationCount } from "../../degradation-ledger.js";
|
|
36
42
|
import { safeSpawnAsync } from "../../safe-spawn.js";
|
|
37
43
|
import { isTrivyEnabled, resolveSeverityFloor, } from "../../trivy-client.js";
|
|
38
44
|
import { PRIORITY } from "../priorities.js";
|
|
39
45
|
import { createAvailabilityChecker, resolveAvailableOrInstall, } from "./utils/runner-helpers.js";
|
|
40
|
-
import { spawnFailedWithNoOutput } from "./utils/spawn-outcome.js";
|
|
41
46
|
const trivy = createAvailabilityChecker("trivy", ".exe");
|
|
42
47
|
/**
|
|
43
48
|
* Heuristic: does this YAML look like a Kubernetes manifest (vs a CI workflow,
|
|
@@ -53,6 +58,23 @@ export function looksLikeKubernetesManifest(content) {
|
|
|
53
58
|
}
|
|
54
59
|
return false;
|
|
55
60
|
}
|
|
61
|
+
/**
|
|
62
|
+
* Heuristic: does this file (yaml OR json) look like a CloudFormation
|
|
63
|
+
* template? The unambiguous signal is the `AWSTemplateFormatVersion` key,
|
|
64
|
+
* present on the vast majority of real templates; SAM templates instead
|
|
65
|
+
* declare `Transform: AWS::Serverless-2016-10-31` (or an array containing
|
|
66
|
+
* it). Templates that skip both still always declare a `Resources` map whose
|
|
67
|
+
* entries carry a `Type` in the `AWS::`/`Custom::`/`Alexa::` namespaces — the
|
|
68
|
+
* one field CFN mandates on every resource. Any one signal qualifies (refs
|
|
69
|
+
* #1757).
|
|
70
|
+
*/
|
|
71
|
+
export function looksLikeCloudFormationTemplate(content) {
|
|
72
|
+
if (/AWSTemplateFormatVersion/.test(content))
|
|
73
|
+
return true;
|
|
74
|
+
if (/Transform:\s*(\[.*)?["']?AWS::Serverless/.test(content))
|
|
75
|
+
return true;
|
|
76
|
+
return /Type["']?\s*:\s*["']?(AWS|Custom|Alexa)::/.test(content);
|
|
77
|
+
}
|
|
56
78
|
function normalizeSeverity(raw) {
|
|
57
79
|
const s = typeof raw === "string" ? raw.toUpperCase() : "";
|
|
58
80
|
if (s === "CRITICAL" || s === "HIGH" || s === "MEDIUM" || s === "LOW") {
|
|
@@ -122,7 +144,7 @@ export function parseTrivyConfigOutput(raw, filePath) {
|
|
|
122
144
|
}
|
|
123
145
|
const trivyConfigRunner = {
|
|
124
146
|
id: "trivy-config",
|
|
125
|
-
appliesTo: ["docker", "yaml", "terraform"],
|
|
147
|
+
appliesTo: ["docker", "yaml", "terraform", "json"],
|
|
126
148
|
priority: PRIORITY.GENERAL_ANALYSIS,
|
|
127
149
|
enabledByDefault: true,
|
|
128
150
|
skipTestFiles: false,
|
|
@@ -133,8 +155,10 @@ const trivyConfigRunner = {
|
|
|
133
155
|
return { status: "skipped", diagnostics: [], semantic: "none" };
|
|
134
156
|
}
|
|
135
157
|
const absPath = path.resolve(cwd, ctx.filePath);
|
|
136
|
-
// YAML is far broader than k8s;
|
|
137
|
-
|
|
158
|
+
// YAML is far broader than k8s/CloudFormation; JSON is far broader than
|
|
159
|
+
// CloudFormation — only scan files that look like one of the IaC
|
|
160
|
+
// manifest shapes trivy's misconfig scanners understand (refs #1757).
|
|
161
|
+
if (ctx.kind === "yaml" || ctx.kind === "json") {
|
|
138
162
|
let content = "";
|
|
139
163
|
try {
|
|
140
164
|
content = fs.readFileSync(absPath, "utf-8");
|
|
@@ -142,7 +166,11 @@ const trivyConfigRunner = {
|
|
|
142
166
|
catch {
|
|
143
167
|
return { status: "skipped", diagnostics: [], semantic: "none" };
|
|
144
168
|
}
|
|
145
|
-
|
|
169
|
+
const isManifest = ctx.kind === "yaml"
|
|
170
|
+
? looksLikeKubernetesManifest(content) ||
|
|
171
|
+
looksLikeCloudFormationTemplate(content)
|
|
172
|
+
: looksLikeCloudFormationTemplate(content);
|
|
173
|
+
if (!isManifest) {
|
|
146
174
|
return { status: "skipped", diagnostics: [], semantic: "none" };
|
|
147
175
|
}
|
|
148
176
|
}
|
|
@@ -160,15 +188,48 @@ const trivyConfigRunner = {
|
|
|
160
188
|
const severities = resolveSeverityFloor(cwd).join(",");
|
|
161
189
|
const result = await safeSpawnAsync(cmd, [
|
|
162
190
|
"config",
|
|
191
|
+
// `--quiet` alone suppresses both the progress bar and log output.
|
|
192
|
+
// `--no-progress` is NOT a `config` subcommand flag (unlike `fs`,
|
|
193
|
+
// which does accept it) — trivy 0.73.0 exits 1 on the rejected
|
|
194
|
+
// flag, but prints its full usage/help text (thousands of bytes)
|
|
195
|
+
// to STDOUT before the FATAL line on stderr. That stdout is
|
|
196
|
+
// non-empty, so an empty-output-only guard did not catch it: the
|
|
197
|
+
// help text failed to JSON-parse, `parseTrivyConfigOutput`
|
|
198
|
+
// returned `[]`, and this reported `{ status: "succeeded",
|
|
199
|
+
// diagnostics: [] }` — a clean scan — on every single real
|
|
200
|
+
// invocation (refs #1757; verified against the real installed
|
|
201
|
+
// binary, not assumed).
|
|
163
202
|
"--quiet",
|
|
164
|
-
"--no-progress",
|
|
165
203
|
"--format",
|
|
166
204
|
"json",
|
|
167
205
|
"--severity",
|
|
168
206
|
severities,
|
|
169
207
|
absPath,
|
|
170
208
|
], { cwd, timeout: 60_000 });
|
|
171
|
-
|
|
209
|
+
// `trivy config` is not given `--exit-code`, so it exits 0 whenever it
|
|
210
|
+
// completed (findings included — see parseTrivyConfigOutput's severity
|
|
211
|
+
// mapping for how CRITICAL becomes blocking). ANY nonzero status is
|
|
212
|
+
// therefore a real error, WITH or WITHOUT something on stdout — mirrors
|
|
213
|
+
// the model already in clients/dispatch/runners/helm-render.ts's
|
|
214
|
+
// runIacPass, which has the same "trivy prints usage text on a bad
|
|
215
|
+
// flag" exposure and already got this right. A bounded ledger record
|
|
216
|
+
// means a broken trivy invocation can no longer go unnoticed for an
|
|
217
|
+
// entire lane's lifetime the way this one did (refs #1757).
|
|
218
|
+
if (result.error || result.status !== 0) {
|
|
219
|
+
// #1816: one shared wording, one truncation, signal named. `subject`
|
|
220
|
+
// stays the file path — the discriminating identity a reader needs
|
|
221
|
+
// is WHICH file trivy stopped covering.
|
|
222
|
+
incrementDegradationCount({
|
|
223
|
+
kind: "runner-empty-result",
|
|
224
|
+
subject: absPath,
|
|
225
|
+
reason: formatToolFailure({
|
|
226
|
+
tool: "trivy config",
|
|
227
|
+
status: result.status,
|
|
228
|
+
signal: result.signal,
|
|
229
|
+
stderr: result.stderr || result.error?.message,
|
|
230
|
+
stdout: result.stdout,
|
|
231
|
+
}),
|
|
232
|
+
});
|
|
172
233
|
return { status: "skipped", diagnostics: [], semantic: "none" };
|
|
173
234
|
}
|
|
174
235
|
const diagnostics = parseTrivyConfigOutput(result.stdout || "", ctx.filePath);
|