@herbertgao/pi-extensions 2026.8.6 → 2026.8.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +8 -6
- package/node_modules/@herbertgao/pi-cc-extensions/README.en.md +2 -2
- package/node_modules/@herbertgao/pi-cc-extensions/README.md +2 -2
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/config/config.ts +19 -7
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/config/panel.ts +30 -9
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/feature/compact-thinking.ts +320 -22
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/compact-mode.ts +94 -77
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/message-display.ts +79 -17
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/mouse/hover.ts +27 -0
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/mouse/interaction.ts +66 -17
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/mouse/layout.ts +41 -2
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/tool/diff/diff-renderer.ts +75 -6
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/tool/diff/types.ts +7 -3
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/tool/grouping.ts +64 -1
- package/node_modules/@herbertgao/pi-cc-extensions/package.json +3 -3
- package/node_modules/@herbertgao/pi-subagents/CHANGELOG.md +6 -0
- package/node_modules/@herbertgao/pi-subagents/README.md +30 -22
- package/node_modules/@herbertgao/pi-subagents/examples/agent-tool-description.md +5 -5
- package/node_modules/@herbertgao/pi-subagents/package.json +7 -7
- package/node_modules/@herbertgao/pi-subagents/src/agent-file-toggle.ts +7 -1
- package/node_modules/@herbertgao/pi-subagents/src/agent-manager.ts +48 -19
- package/node_modules/@herbertgao/pi-subagents/src/agent-runner.ts +17 -13
- package/node_modules/@herbertgao/pi-subagents/src/custom-agents.ts +26 -2
- package/node_modules/@herbertgao/pi-subagents/src/index.ts +219 -40
- package/node_modules/@herbertgao/pi-subagents/src/invocation-config.ts +101 -3
- package/node_modules/@herbertgao/pi-subagents/src/nested-tools.ts +18 -4
- package/node_modules/@herbertgao/pi-subagents/src/settings.ts +99 -0
- package/node_modules/@herbertgao/pi-subagents/src/types.ts +22 -3
- package/node_modules/@herbertgao/pi-subagents/src/ui/agent-widget.ts +51 -3
- package/node_modules/@herbertgao/pi-subagents/src/ui/conversation-viewer.ts +20 -2
- package/node_modules/@herbertgao/pi-subagents/src/ui/fleet-list.ts +21 -6
- package/node_modules/@herbertgao/pi-subagents/src/usage.ts +129 -1
- package/node_modules/@herbertgao/pi-subagents/src/worktree.ts +20 -0
- package/node_modules/@juicesharp/rpiv-ask-user-question/README.md +5 -4
- package/node_modules/@juicesharp/rpiv-ask-user-question/ask-user-question.ts +174 -100
- package/node_modules/@juicesharp/rpiv-ask-user-question/config.ts +25 -0
- package/node_modules/@juicesharp/rpiv-ask-user-question/docs/configuration.md +13 -4
- package/node_modules/@juicesharp/rpiv-ask-user-question/docs/hosts.md +5 -1
- package/node_modules/@juicesharp/rpiv-ask-user-question/docs/keyboard.md +10 -2
- package/node_modules/@juicesharp/rpiv-ask-user-question/docs/localization.md +10 -6
- package/node_modules/@juicesharp/rpiv-ask-user-question/docs/tool-schema.md +11 -5
- package/node_modules/@juicesharp/rpiv-ask-user-question/locales/en.json +5 -2
- package/node_modules/@juicesharp/rpiv-ask-user-question/locales/zh.json +2 -2
- package/node_modules/@juicesharp/rpiv-ask-user-question/package.json +3 -2
- package/node_modules/@juicesharp/rpiv-ask-user-question/state/build-questionnaire.ts +10 -0
- package/node_modules/@juicesharp/rpiv-ask-user-question/state/key-router.ts +140 -97
- package/node_modules/@juicesharp/rpiv-ask-user-question/state/questionnaire-session.ts +63 -28
- package/node_modules/@juicesharp/rpiv-ask-user-question/state/selectors/projections.ts +22 -15
- package/node_modules/@juicesharp/rpiv-ask-user-question/state/state-reducer.ts +11 -1
- package/node_modules/@juicesharp/rpiv-ask-user-question/state/state.ts +14 -6
- package/node_modules/@juicesharp/rpiv-ask-user-question/tool/response-envelope.ts +11 -0
- package/node_modules/@juicesharp/rpiv-ask-user-question/tool/types.ts +11 -0
- package/node_modules/@juicesharp/rpiv-ask-user-question/view/components/multi-select-view.ts +31 -17
- package/node_modules/@juicesharp/rpiv-ask-user-question/view/components/preview/preview-block-renderer.ts +15 -6
- package/node_modules/@juicesharp/rpiv-ask-user-question/view/components/wrapping-select.ts +15 -6
- package/node_modules/@juicesharp/rpiv-ask-user-question/view/dialog-builder.ts +86 -38
- package/node_modules/@juicesharp/rpiv-ask-user-question/view/tab-content-strategy.ts +76 -9
- package/node_modules/@narumitw/pi-btw/README.md +120 -111
- package/node_modules/@narumitw/pi-btw/dist/index.ts +2898 -0
- package/node_modules/@narumitw/pi-btw/dist/index.ts.map +7 -0
- package/node_modules/@narumitw/pi-btw/package.json +10 -6
- package/node_modules/@narumitw/pi-btw/src/btw.ts +36 -40
- package/node_modules/@narumitw/pi-btw/src/fullscreen-ui.ts +55 -10
- package/node_modules/@narumitw/pi-btw/src/main-tree-picker.ts +390 -0
- package/node_modules/@narumitw/pi-btw/src/menu.ts +45 -2
- package/node_modules/@narumitw/pi-btw/src/transcript-pager.ts +136 -45
- package/node_modules/@pi-plugins/fast-mode/dist/index.mjs +44 -1856
- package/node_modules/@pi-plugins/fast-mode/dist/index.mjs.map +1 -1
- package/node_modules/@pi-plugins/fast-mode/package.json +4 -6
- package/node_modules/pi-lens/CHANGELOG.md +999 -0
- package/node_modules/pi-lens/README.md +117 -3
- package/node_modules/pi-lens/config/ruff/core.toml +42 -0
- package/node_modules/pi-lens/dist/clients/actionable-warnings.js +130 -27
- package/node_modules/pi-lens/dist/clients/advisory-provenance.js +126 -13
- package/node_modules/pi-lens/dist/clients/agent-nudge.js +67 -11
- package/node_modules/pi-lens/dist/clients/ast-grep-client.js +9 -3
- package/node_modules/pi-lens/dist/clients/atomic-write.js +9 -3
- package/node_modules/pi-lens/dist/clients/bash-file-access.js +381 -13
- package/node_modules/pi-lens/dist/clients/biome-client.js +61 -30
- package/node_modules/pi-lens/dist/clients/blocker-freshness.js +428 -0
- package/node_modules/pi-lens/dist/clients/blocker-past-eof.js +129 -0
- package/node_modules/pi-lens/dist/clients/bootstrap.js +12 -1
- package/node_modules/pi-lens/dist/clients/bounded-pid-file-lock.js +12 -3
- package/node_modules/pi-lens/dist/clients/bounded-telemetry.js +206 -0
- package/node_modules/pi-lens/dist/clients/cache-observability.js +353 -76
- package/node_modules/pi-lens/dist/clients/cascade-budget.js +196 -0
- package/node_modules/pi-lens/dist/clients/cascade-format.js +20 -1
- package/node_modules/pi-lens/dist/clients/cascade-types.js +9 -1
- package/node_modules/pi-lens/dist/clients/child-unref.js +54 -6
- package/node_modules/pi-lens/dist/clients/code-quality-warnings.js +76 -24
- package/node_modules/pi-lens/dist/clients/dead-code-client.js +123 -31
- package/node_modules/pi-lens/dist/clients/deadline-utils.js +8 -1
- package/node_modules/pi-lens/dist/clients/debug-handles.js +5 -0
- package/node_modules/pi-lens/dist/clients/degradation-ledger.js +84 -14
- package/node_modules/pi-lens/dist/clients/demoted-finding-render.js +155 -0
- package/node_modules/pi-lens/dist/clients/dependency-checker.js +25 -3
- package/node_modules/pi-lens/dist/clients/deps/pi-tui.js +8 -2
- package/node_modules/pi-lens/dist/clients/deps/typebox.js +8 -3
- package/node_modules/pi-lens/dist/clients/diagnostic-dispositions.js +147 -33
- package/node_modules/pi-lens/dist/clients/diagnostic-line-freshness.js +298 -0
- package/node_modules/pi-lens/dist/clients/dispatch/dispatcher.js +52 -2
- package/node_modules/pi-lens/dist/clients/dispatch/integration.js +256 -88
- package/node_modules/pi-lens/dist/clients/dispatch/lazy.js +7 -4
- package/node_modules/pi-lens/dist/clients/dispatch/plan.js +5 -0
- package/node_modules/pi-lens/dist/clients/dispatch/runners/ast-grep-napi.js +234 -18
- package/node_modules/pi-lens/dist/clients/dispatch/runners/biome-check.js +187 -19
- package/node_modules/pi-lens/dist/clients/dispatch/runners/cpp-check.js +6 -3
- package/node_modules/pi-lens/dist/clients/dispatch/runners/credo.js +11 -9
- package/node_modules/pi-lens/dist/clients/dispatch/runners/cue-vet.js +398 -0
- package/node_modules/pi-lens/dist/clients/dispatch/runners/detekt.js +9 -6
- package/node_modules/pi-lens/dist/clients/dispatch/runners/elixir-check.js +11 -3
- package/node_modules/pi-lens/dist/clients/dispatch/runners/eslint.js +12 -7
- package/node_modules/pi-lens/dist/clients/dispatch/runners/go-vet.js +18 -0
- package/node_modules/pi-lens/dist/clients/dispatch/runners/hadolint.js +9 -7
- package/node_modules/pi-lens/dist/clients/dispatch/runners/helm-render.js +895 -0
- package/node_modules/pi-lens/dist/clients/dispatch/runners/htmlhint.js +8 -6
- package/node_modules/pi-lens/dist/clients/dispatch/runners/index.js +4 -0
- package/node_modules/pi-lens/dist/clients/dispatch/runners/javac.js +16 -3
- package/node_modules/pi-lens/dist/clients/dispatch/runners/lsp.js +60 -53
- package/node_modules/pi-lens/dist/clients/dispatch/runners/markdownlint.js +16 -2
- package/node_modules/pi-lens/dist/clients/dispatch/runners/mypy.js +25 -2
- package/node_modules/pi-lens/dist/clients/dispatch/runners/oxlint.js +20 -5
- package/node_modules/pi-lens/dist/clients/dispatch/runners/phpstan.js +44 -11
- package/node_modules/pi-lens/dist/clients/dispatch/runners/psscriptanalyzer.js +331 -55
- package/node_modules/pi-lens/dist/clients/dispatch/runners/pyright.js +38 -5
- package/node_modules/pi-lens/dist/clients/dispatch/runners/rust-clippy.js +97 -19
- package/node_modules/pi-lens/dist/clients/dispatch/runners/spellcheck.js +17 -8
- package/node_modules/pi-lens/dist/clients/dispatch/runners/sqlfluff.js +32 -4
- package/node_modules/pi-lens/dist/clients/dispatch/runners/stylelint.js +47 -3
- package/node_modules/pi-lens/dist/clients/dispatch/runners/swiftlint.js +14 -4
- package/node_modules/pi-lens/dist/clients/dispatch/runners/taplo.js +127 -28
- package/node_modules/pi-lens/dist/clients/dispatch/runners/tflint.js +12 -7
- package/node_modules/pi-lens/dist/clients/dispatch/runners/trivy-config.js +73 -12
- package/node_modules/pi-lens/dist/clients/dispatch/runners/utils/availability-policy.js +275 -13
- package/node_modules/pi-lens/dist/clients/dispatch/runners/utils/candidate-probe.js +21 -6
- package/node_modules/pi-lens/dist/clients/dispatch/runners/utils/lazy-installer.js +260 -27
- package/node_modules/pi-lens/dist/clients/dispatch/runners/utils/runner-helpers.js +734 -64
- package/node_modules/pi-lens/dist/clients/dispatch/runners/utils/spawn-outcome.js +86 -11
- package/node_modules/pi-lens/dist/clients/dispatch/runners/utils/tool-failure.js +188 -0
- package/node_modules/pi-lens/dist/clients/dispatch/runners/utils/toolchain-availability.js +9 -0
- package/node_modules/pi-lens/dist/clients/dispatch/runners/vale.js +21 -10
- package/node_modules/pi-lens/dist/clients/dispatch/runners/yamllint.js +18 -2
- package/node_modules/pi-lens/dist/clients/dispatch/runners/zig-check.js +4 -2
- package/node_modules/pi-lens/dist/clients/event-loop-monitor.js +28 -5
- package/node_modules/pi-lens/dist/clients/extension-log.js +22 -1
- package/node_modules/pi-lens/dist/clients/file-kinds.js +8 -2
- package/node_modules/pi-lens/dist/clients/finding-delivery-gate.js +316 -0
- package/node_modules/pi-lens/dist/clients/finding-identity.js +88 -0
- package/node_modules/pi-lens/dist/clients/formatters-lazy.js +3 -2
- package/node_modules/pi-lens/dist/clients/formatters.js +500 -115
- package/node_modules/pi-lens/dist/clients/generation-guard.js +216 -0
- package/node_modules/pi-lens/dist/clients/git-guard.js +31 -0
- package/node_modules/pi-lens/dist/clients/gitleaks-client.js +181 -8
- package/node_modules/pi-lens/dist/clients/govulncheck-client.js +109 -9
- package/node_modules/pi-lens/dist/clients/grammar-source.js +333 -10
- package/node_modules/pi-lens/dist/clients/host-ports.js +8 -0
- package/node_modules/pi-lens/dist/clients/installer/index.js +1114 -100
- package/node_modules/pi-lens/dist/clients/installer/managed-tool-refresh-session.js +58 -0
- package/node_modules/pi-lens/dist/clients/installer/managed-tool-refresh.js +715 -0
- package/node_modules/pi-lens/dist/clients/instance-reaper.js +643 -97
- package/node_modules/pi-lens/dist/clients/instance-registry.js +87 -17
- package/node_modules/pi-lens/dist/clients/jscpd-client.js +87 -8
- package/node_modules/pi-lens/dist/clients/knip-client.js +310 -10
- package/node_modules/pi-lens/dist/clients/language-policy.js +8 -2
- package/node_modules/pi-lens/dist/clients/language-profile.js +9 -2
- package/node_modules/pi-lens/dist/clients/latency-logger.js +440 -11
- package/node_modules/pi-lens/dist/clients/lazy-import.js +21 -0
- package/node_modules/pi-lens/dist/clients/ledger-bounds.js +21 -0
- package/node_modules/pi-lens/dist/clients/lens-flag-registry.js +8 -0
- package/node_modules/pi-lens/dist/clients/lsp/cascade-tier.js +128 -8
- package/node_modules/pi-lens/dist/clients/lsp/client.js +1660 -164
- package/node_modules/pi-lens/dist/clients/lsp/diagnostic-binding.js +83 -1
- package/node_modules/pi-lens/dist/clients/lsp/document-drift.js +389 -0
- package/node_modules/pi-lens/dist/clients/lsp/index.js +2423 -151
- package/node_modules/pi-lens/dist/clients/lsp/inferred-project.js +215 -0
- package/node_modules/pi-lens/dist/clients/lsp/jvm-runtime.js +146 -14
- package/node_modules/pi-lens/dist/clients/lsp/language.js +48 -4
- package/node_modules/pi-lens/dist/clients/lsp/server.js +277 -16
- package/node_modules/pi-lens/dist/clients/lsp/spawn-history.js +22 -0
- package/node_modules/pi-lens/dist/clients/lsp/sync-kind.js +43 -0
- package/node_modules/pi-lens/dist/clients/lsp/tsserver-sync.js +79 -3
- package/node_modules/pi-lens/dist/clients/lsp/wait-policy/strategies.js +43 -0
- package/node_modules/pi-lens/dist/clients/lsp/workspace-diagnostics-cache.js +422 -28
- package/node_modules/pi-lens/dist/clients/lsp/workspace-diagnostics-session.js +30 -0
- package/node_modules/pi-lens/dist/clients/lsp/workspace-sweep-hold.js +175 -0
- package/node_modules/pi-lens/dist/clients/lsp-lazy.js +3 -2
- package/node_modules/pi-lens/dist/clients/mcp/session.js +10 -2
- package/node_modules/pi-lens/dist/clients/module-report.js +22 -1
- package/node_modules/pi-lens/dist/clients/ndjson-logger.js +114 -23
- package/node_modules/pi-lens/dist/clients/opengrep-client.js +15 -1
- package/node_modules/pi-lens/dist/clients/package-manager.js +170 -14
- package/node_modules/pi-lens/dist/clients/path-attribution-telemetry.js +27 -0
- package/node_modules/pi-lens/dist/clients/path-utils.js +160 -0
- package/node_modules/pi-lens/dist/clients/pipeline.js +154 -33
- package/node_modules/pi-lens/dist/clients/post-autofix-notice.js +37 -0
- package/node_modules/pi-lens/dist/clients/project-diagnostics/cache.js +17 -3
- package/node_modules/pi-lens/dist/clients/project-diagnostics/extractors.js +89 -22
- package/node_modules/pi-lens/dist/clients/project-diagnostics/fresh-fetch.js +84 -14
- package/node_modules/pi-lens/dist/clients/project-diagnostics/runner-adapters/gitleaks.js +15 -3
- package/node_modules/pi-lens/dist/clients/project-diagnostics/runner-adapters/trivy.js +50 -2
- package/node_modules/pi-lens/dist/clients/project-diagnostics/scanner.js +23 -9
- package/node_modules/pi-lens/dist/clients/project-lens-config.js +3 -0
- package/node_modules/pi-lens/dist/clients/project-report.js +62 -27
- package/node_modules/pi-lens/dist/clients/project-snapshot.js +299 -0
- package/node_modules/pi-lens/dist/clients/quiet-window-config.js +47 -0
- package/node_modules/pi-lens/dist/clients/quiet-window.js +11 -25
- package/node_modules/pi-lens/dist/clients/read-guard-logger.js +8 -3
- package/node_modules/pi-lens/dist/clients/read-guard.js +253 -10
- package/node_modules/pi-lens/dist/clients/resource-sampler.js +49 -17
- package/node_modules/pi-lens/dist/clients/reverse-deps.js +50 -11
- package/node_modules/pi-lens/dist/clients/review-graph/builder.js +194 -31
- package/node_modules/pi-lens/dist/clients/review-graph/query.js +52 -4
- package/node_modules/pi-lens/dist/clients/review-graph/revision-drift.js +21 -0
- package/node_modules/pi-lens/dist/clients/review-graph/workspace-modules.js +6 -3
- package/node_modules/pi-lens/dist/clients/runtime-agent-end.js +96 -7
- package/node_modules/pi-lens/dist/clients/runtime-context.js +8 -1
- package/node_modules/pi-lens/dist/clients/runtime-coordinator.js +352 -45
- package/node_modules/pi-lens/dist/clients/runtime-session.js +373 -9
- package/node_modules/pi-lens/dist/clients/runtime-tool-call.js +217 -22
- package/node_modules/pi-lens/dist/clients/runtime-tool-result.js +212 -79
- package/node_modules/pi-lens/dist/clients/runtime-turn.js +620 -67
- package/node_modules/pi-lens/dist/clients/safe-spawn.js +220 -7
- package/node_modules/pi-lens/dist/clients/scratch-tree-policy.js +161 -0
- package/node_modules/pi-lens/dist/clients/search-read-registration.js +34 -6
- package/node_modules/pi-lens/dist/clients/security-scan-client.js +157 -24
- package/node_modules/pi-lens/dist/clients/session-event-guard.js +184 -0
- package/node_modules/pi-lens/dist/clients/sg-runner.js +116 -22
- package/node_modules/pi-lens/dist/clients/single-flight.js +158 -0
- package/node_modules/pi-lens/dist/clients/source-filter.js +6 -2
- package/node_modules/pi-lens/dist/clients/stale-marker.js +17 -0
- package/node_modules/pi-lens/dist/clients/startup-scan.js +5 -2
- package/node_modules/pi-lens/dist/clients/startup-timing.js +19 -1
- package/node_modules/pi-lens/dist/clients/test-runner-client.js +151 -16
- package/node_modules/pi-lens/dist/clients/tool-event.js +56 -5
- package/node_modules/pi-lens/dist/clients/tool-policy.js +125 -20
- package/node_modules/pi-lens/dist/clients/tree-sitter-cache.js +75 -1
- package/node_modules/pi-lens/dist/clients/tree-sitter-client.js +769 -64
- package/node_modules/pi-lens/dist/clients/tree-sitter-logger.js +1 -0
- package/node_modules/pi-lens/dist/clients/tree-sitter-shared.js +11 -0
- package/node_modules/pi-lens/dist/clients/tree-sitter-symbol-extractor.js +90 -0
- package/node_modules/pi-lens/dist/clients/trivy-client.js +19 -1
- package/node_modules/pi-lens/dist/clients/widget-state.js +336 -36
- package/node_modules/pi-lens/dist/clients/zizmor-config.js +214 -14
- package/node_modules/pi-lens/dist/index.js +61407 -48577
- package/node_modules/pi-lens/dist/tools/lens-diagnostics.js +476 -57
- package/node_modules/pi-lens/dist/tools/lsp-diagnostics.js +132 -43
- package/node_modules/pi-lens/dist/tools/lsp-navigation.js +46 -7
- package/node_modules/pi-lens/docs/agent-guide.md +6 -1
- package/node_modules/pi-lens/docs/ast-grep_rules_catalog.md +515 -506
- package/node_modules/pi-lens/docs/dispositions.md +21 -0
- package/node_modules/pi-lens/docs/features.md +19 -5
- package/node_modules/pi-lens/docs/globalconfig.md +3 -0
- package/node_modules/pi-lens/docs/language-coverage.md +71 -5
- package/node_modules/pi-lens/docs/mcp.md +2 -2
- package/node_modules/pi-lens/docs/servercapabilities.md +4 -1
- package/node_modules/pi-lens/docs/settings.md +19 -1
- package/node_modules/pi-lens/docs/usage.md +1 -0
- package/node_modules/pi-lens/package.json +27 -10
- package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/__snapshots__/no-reflect-get-js-snapshot.yml +23 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/__snapshots__/no-reflect-get-snapshot.yml +23 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/__snapshots__/ts-void-zero-snapshot.yml +23 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-bare-object-param-test.yml +16 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-chained-type-assertions-test.yml +15 -1
- package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-compile-call-test.yml +29 -1
- package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-dupe-class-members-test.yml +33 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-inner-html-js-test.yml +7 -1
- package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-inner-html-test.yml +7 -1
- package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-known-value-widening-test.yml +9 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-non-null-assertion-test.yml +216 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-reflect-apply-js-test.yml +2 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-reflect-apply-test.yml +2 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-reflect-get-js-test.yml +2 -1
- package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-reflect-get-test.yml +2 -1
- package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-return-value-in-generator-test.yml +12 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-runtime-typeof-test.yml +33 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-server-bind-wildcard-test.yml +9 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-shape-in-symbol-names-test.yml +13 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-sql-in-code-js-test.yml +5 -1
- package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-sql-in-code-test.yml +5 -1
- package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-unknown-parameters-test.yml +12 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-unknown-returns-test.yml +16 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-unsafe-dictionary-any-test.yml +10 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-unsafe-dictionary-unknown-test.yml +8 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/redundant-unsafe-function-test.yml +35 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/require-safety-comment-for-as-unknown-as-test.yml +177 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/ts-void-zero-test.yml +1 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-await-expression-member-js.yml +13 -2
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-await-expression-member.yml +13 -2
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-bare-host-path-in-win32-branch.yml +2 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-bare-object-param.yml +60 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-chained-type-assertions.yml +57 -12
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-compile-call.yml +63 -5
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-dupe-class-members.yml +52 -8
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-inner-html-js.yml +27 -2
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-inner-html.yml +27 -2
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-known-value-widening.yml +71 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-non-null-assertion.yml +316 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-raw-json-store-write.yml +7 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-reflect-apply-js.yml +22 -2
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-reflect-apply.yml +23 -2
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-reflect-get-js.yml +33 -5
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-reflect-get.yml +34 -8
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-return-value-in-generator.yml +22 -5
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-runtime-typeof.yml +121 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-server-bind-wildcard.yml +23 -7
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-shape-in-symbol-names.yml +68 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-sql-in-code-js.yml +41 -2
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-sql-in-code.yml +41 -2
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-unknown-laundering.yml +6 -1
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-unknown-parameters.yml +67 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-unknown-returns.yml +106 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-unsafe-dictionary-any.yml +50 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-unsafe-dictionary-unknown.yml +56 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-win32-isabsolute-for-qualification.yml +2 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/redundant-unsafe-function.yml +32 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/require-safety-comment-for-as-unknown-as.yml +184 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/ts-void-zero.yml +5 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/self-scan-baseline.json +5 -0
- package/node_modules/pi-lens/scripts/analyze-pi-lens-logs.mjs +53 -1
- package/node_modules/pi-lens/scripts/download-grammars.js +25 -0
- package/node_modules/pi-lens/scripts/grammars.lock.json +9 -0
- package/node_modules/pi-lens/scripts/install-selftest.mjs +99 -11
- package/node_modules/pi-lens/scripts/lib/host-provided-deps.mjs +75 -0
- package/node_modules/pi-lens/scripts/lib/warm-loader-cache.mjs +285 -0
- package/node_modules/pi-lens/scripts/warm-loader-cache.mjs +233 -0
- package/node_modules/pi-lens/skills/pi-lens-ast-grep/SKILL.md +2 -0
- package/node_modules/pi-lens/skills/pi-lens-write-ast-grep-rule/SKILL.md +80 -3
- package/node_modules/pi-lens/skills/pi-lens-write-ast-grep-rule/reference.md +41 -0
- package/node_modules/pi-lens/vendor/grammars/tree-sitter-cue.wasm +0 -0
- package/node_modules/pi-mcp-adapter/CHANGELOG.md +36 -0
- package/node_modules/pi-mcp-adapter/README.md +47 -5
- package/node_modules/pi-mcp-adapter/cli.js +163 -1
- package/node_modules/pi-mcp-adapter/commands.ts +128 -22
- package/node_modules/pi-mcp-adapter/config.ts +25 -7
- package/node_modules/pi-mcp-adapter/direct-tools.ts +5 -4
- package/node_modules/pi-mcp-adapter/index.ts +219 -32
- package/node_modules/pi-mcp-adapter/init.ts +36 -4
- package/node_modules/pi-mcp-adapter/lifecycle.ts +315 -24
- package/node_modules/pi-mcp-adapter/mcp-auth-flow.ts +39 -6
- package/node_modules/pi-mcp-adapter/mcp-bearer-store.ts +387 -0
- package/node_modules/pi-mcp-adapter/mcp-callback-server.ts +27 -3
- package/node_modules/pi-mcp-adapter/mcp-code.ts +4 -0
- package/node_modules/pi-mcp-adapter/mcp-panel.ts +42 -13
- package/node_modules/pi-mcp-adapter/metadata-cache.ts +32 -21
- package/node_modules/pi-mcp-adapter/package-mcp-loader.ts +168 -0
- package/node_modules/pi-mcp-adapter/package.json +3 -1
- package/node_modules/pi-mcp-adapter/proxy-modes.ts +5 -4
- package/node_modules/pi-mcp-adapter/request-headers-command.ts +31 -37
- package/node_modules/pi-mcp-adapter/search-ranking.ts +92 -22
- package/node_modules/pi-mcp-adapter/server-manager.ts +140 -2
- package/node_modules/pi-mcp-adapter/session-recovery.ts +7 -0
- package/node_modules/pi-mcp-adapter/tool-approval.ts +15 -2
- package/node_modules/pi-mcp-adapter/tool-result-renderer.ts +44 -4
- package/node_modules/pi-mcp-adapter/types.ts +2 -0
- package/node_modules/pi-mcp-adapter/ui-server.ts +18 -16
- package/node_modules/pi-mcp-adapter/utils.ts +70 -0
- package/node_modules/pi-web-access/CHANGELOG.md +37 -0
- package/node_modules/pi-web-access/README.md +32 -13
- package/node_modules/pi-web-access/anysearch.ts +4 -2
- package/node_modules/pi-web-access/brave.ts +16 -4
- package/node_modules/pi-web-access/chrome-cookies.ts +86 -15
- package/node_modules/pi-web-access/curator-page.ts +6 -3
- package/node_modules/pi-web-access/curator-server.ts +4 -1
- package/node_modules/pi-web-access/data-uri-sanitize.ts +406 -0
- package/node_modules/pi-web-access/exa.ts +18 -7
- package/node_modules/pi-web-access/extract.ts +40 -5
- package/node_modules/pi-web-access/firecrawl.ts +18 -2
- package/node_modules/pi-web-access/gemini-search.ts +16 -4
- package/node_modules/pi-web-access/github-extract.ts +65 -36
- package/node_modules/pi-web-access/index.ts +60 -61
- package/node_modules/pi-web-access/openai-search.ts +17 -6
- package/node_modules/pi-web-access/package.json +1 -1
- package/node_modules/pi-web-access/page-query.ts +4 -2
- package/node_modules/pi-web-access/parallel-mcp.ts +249 -0
- package/node_modules/pi-web-access/parallel.ts +2 -2
- package/node_modules/pi-web-access/pdf-extract.ts +18 -5
- package/node_modules/pi-web-access/query-rewrite.ts +51 -0
- package/node_modules/pi-web-access/serper.ts +211 -0
- package/node_modules/pi-web-access/ssrf-protection.ts +12 -2
- package/node_modules/pi-web-access/summary-model-scope.ts +12 -4
- package/node_modules/pi-web-access/summary-review.ts +44 -22
- package/node_modules/pi-web-access/tavily.ts +16 -4
- package/node_modules/pi-web-access/utils.ts +87 -0
- package/node_modules/pi-web-access/valyu.ts +199 -0
- package/package.json +14 -14
|
@@ -1390,8 +1390,17 @@ export class TestRunnerClient {
|
|
|
1390
1390
|
const output = `${stdout}\n${stderr}`;
|
|
1391
1391
|
const lower = output.toLowerCase();
|
|
1392
1392
|
let passed = 0;
|
|
1393
|
-
|
|
1393
|
+
// #1487: NOT `exitCode === 0 ? 0 : 1`. Pre-seeding `failed` to 1 on a
|
|
1394
|
+
// non-zero exit made the runner-error branch below unreachable — it
|
|
1395
|
+
// requires `failed === 0`, which a spawn/config/load failure (no
|
|
1396
|
+
// counts to parse) could never reach once this had already claimed
|
|
1397
|
+
// the slot. `matched` tracks whether a count parser actually found
|
|
1398
|
+
// real counts; the exit-code-distrust fallback further down uses it
|
|
1399
|
+
// to tell "a runner that never ran" from "a runner whose summary
|
|
1400
|
+
// legitimately parsed to zero failures".
|
|
1401
|
+
let failed = 0;
|
|
1394
1402
|
let skipped = 0;
|
|
1403
|
+
let matched = false;
|
|
1395
1404
|
// #1480: `number | undefined`, and sourced per runner. This used to be
|
|
1396
1405
|
// `let duration = 0` with only go's probe able to move it, so every
|
|
1397
1406
|
// other runner reported a zero it never measured.
|
|
@@ -1401,12 +1410,14 @@ export class TestRunnerClient {
|
|
|
1401
1410
|
passed = Number.parseInt(cargoSummary[1], 10);
|
|
1402
1411
|
failed = Number.parseInt(cargoSummary[2], 10);
|
|
1403
1412
|
skipped = Number.parseInt(cargoSummary[3], 10);
|
|
1413
|
+
matched = true;
|
|
1404
1414
|
}
|
|
1405
1415
|
const dotnetSummary = output.match(/Failed:\s*(\d+),\s*Passed:\s*(\d+),\s*Skipped:\s*(\d+)/i);
|
|
1406
1416
|
if (dotnetSummary) {
|
|
1407
1417
|
failed = Number.parseInt(dotnetSummary[1], 10);
|
|
1408
1418
|
passed = Number.parseInt(dotnetSummary[2], 10);
|
|
1409
1419
|
skipped = Number.parseInt(dotnetSummary[3], 10);
|
|
1420
|
+
matched = true;
|
|
1410
1421
|
}
|
|
1411
1422
|
// #1480 (adjacent, duration-independent): surefire prints one
|
|
1412
1423
|
// `Tests run:` line PER TEST CLASS (those carry `Time elapsed:`) and
|
|
@@ -1444,12 +1455,14 @@ export class TestRunnerClient {
|
|
|
1444
1455
|
failed = mavenFailed;
|
|
1445
1456
|
skipped = mavenSkipped;
|
|
1446
1457
|
passed = Math.max(0, total - failed - skipped);
|
|
1458
|
+
matched = true;
|
|
1447
1459
|
}
|
|
1448
1460
|
const rspecSummary = output.match(/(\d+)\s+examples?,\s+(\d+)\s+failures?/i);
|
|
1449
1461
|
if (rspecSummary) {
|
|
1450
1462
|
const total = Number.parseInt(rspecSummary[1], 10);
|
|
1451
1463
|
failed = Number.parseInt(rspecSummary[2], 10);
|
|
1452
1464
|
passed = Math.max(0, total - failed);
|
|
1465
|
+
matched = true;
|
|
1453
1466
|
}
|
|
1454
1467
|
const minitestSummary = output.match(/(\d+)\s+runs?,\s+\d+\s+assertions?,\s+(\d+)\s+failures?,\s+(\d+)\s+errors?/i);
|
|
1455
1468
|
if (minitestSummary) {
|
|
@@ -1458,41 +1471,160 @@ export class TestRunnerClient {
|
|
|
1458
1471
|
const errors = Number.parseInt(minitestSummary[3], 10);
|
|
1459
1472
|
failed = failures + errors;
|
|
1460
1473
|
passed = Math.max(0, total - failed);
|
|
1474
|
+
matched = true;
|
|
1461
1475
|
}
|
|
1462
1476
|
const gradleSummary = output.match(/(\d+)\s+tests? completed,\s+(\d+)\s+failed/i);
|
|
1463
1477
|
if (gradleSummary) {
|
|
1464
1478
|
const total = Number.parseInt(gradleSummary[1], 10);
|
|
1465
1479
|
failed = Number.parseInt(gradleSummary[2], 10);
|
|
1466
1480
|
passed = Math.max(0, total - failed);
|
|
1481
|
+
matched = true;
|
|
1482
|
+
}
|
|
1483
|
+
// #1487/#1524/#1524-r3: `--- FAIL: TestName` is extracted first and
|
|
1484
|
+
// separately from the other two name patterns, because it is the
|
|
1485
|
+
// ONLY one of the three that is unambiguous evidence a real go test
|
|
1486
|
+
// ran — see the `runnerError` comment below for why the other two
|
|
1487
|
+
// may no longer veto on their own. go otherwise has no count parser
|
|
1488
|
+
// at all (only a duration probe), so without this go's `matched`
|
|
1489
|
+
// stayed false even on a real failure.
|
|
1490
|
+
//
|
|
1491
|
+
// #1524-r3: go ALSO gets a real count parser here, not just a name
|
|
1492
|
+
// extractor. A panic inside `TestMain`/package `init` (exit 2) never
|
|
1493
|
+
// prints a `--- FAIL:` line — there is no test to name, the process
|
|
1494
|
+
// died before any test ran — so `goFailNames` alone left `matched`
|
|
1495
|
+
// false and such a panic hit the same runner-error branch as a
|
|
1496
|
+
// spawn failure, even though `go test` DID run and DID fail. `FAIL
|
|
1497
|
+
// \t<pkg>` is go's own per-package verdict line and is printed for
|
|
1498
|
+
// exactly this case; `ok <pkg> <n>s` is its pass counterpart.
|
|
1499
|
+
// Package-line counts, like the go duration probe above, take the
|
|
1500
|
+
// FIRST package summary only — the same known limit already
|
|
1501
|
+
// documented on `parseGenericRunnerDuration`.
|
|
1502
|
+
const goFailNames = [
|
|
1503
|
+
...output.matchAll(/--- FAIL:[^\S\n]+([^\s(]+)/g),
|
|
1504
|
+
];
|
|
1505
|
+
// #1524-r4: only COUNT unparented failures. go prints a `--- FAIL:`
|
|
1506
|
+
// line for every level of a failing subtest tree — `TestA` AND
|
|
1507
|
+
// `TestA/sub` each get their own line for what is really one
|
|
1508
|
+
// underlying failure — so counting every line inflated `failed`
|
|
1509
|
+
// (two lines here read as two failures for one broken test). A name
|
|
1510
|
+
// containing "/" whose prefix up to that "/" is itself in the list
|
|
1511
|
+
// is a subtest of an already-counted parent; only names that are
|
|
1512
|
+
// NOT such a subtest count. `goFailNames` itself (all lines) is
|
|
1513
|
+
// still what decides `matched`/the runner-error veto below and
|
|
1514
|
+
// what's listed in `failures` — subtest names are still useful
|
|
1515
|
+
// detail there, just not double-counted.
|
|
1516
|
+
const goFailNameSet = new Set(goFailNames.map((m) => m[1].trim()));
|
|
1517
|
+
const goTopLevelFailCount = goFailNames.filter((m) => {
|
|
1518
|
+
const name = m[1].trim();
|
|
1519
|
+
const slash = name.indexOf("/");
|
|
1520
|
+
return slash === -1 || !goFailNameSet.has(name.slice(0, slash));
|
|
1521
|
+
}).length;
|
|
1522
|
+
if (runner === "go") {
|
|
1523
|
+
// #1524-r4: `(?![^\n]*\[(?:build|setup) failed\])` rejects go's
|
|
1524
|
+
// INFRASTRUCTURE verdict lines — `FAIL <pkg> [build failed]` (a
|
|
1525
|
+
// compile error) and `FAIL <pkg> [setup failed]` (no packages to
|
|
1526
|
+
// test) — which matched the same shape as a real `FAIL <pkg>
|
|
1527
|
+
// <duration>` test verdict line. Neither ran a single test; both
|
|
1528
|
+
// were rendering as `✗ 1/1 failed ✗ go failure` instead of the
|
|
1529
|
+
// runner error they are.
|
|
1530
|
+
const goFailPackage = /^FAIL(?![^\n]*\[(?:build|setup) failed\])[^\S\n]+\S+/m.test(output);
|
|
1531
|
+
const goOkPackages = [
|
|
1532
|
+
...output.matchAll(/^ok[^\S\n]+\S+[^\S\n]+[\d.]+s/gm),
|
|
1533
|
+
];
|
|
1534
|
+
if (goFailNames.length > 0 || goFailPackage) {
|
|
1535
|
+
failed = Math.max(failed, goTopLevelFailCount || 1);
|
|
1536
|
+
matched = true;
|
|
1537
|
+
}
|
|
1538
|
+
// #1524-r4: unconditional, not `else if`. A multi-package run
|
|
1539
|
+
// can have BOTH a real failure and packages that passed clean —
|
|
1540
|
+
// `ok a` / `--- FAIL: TestB` / `ok c` is 2 passed AND 1 failed,
|
|
1541
|
+
// not "1 failed, 0 passed" with the green packages silently
|
|
1542
|
+
// dropped because the fail branch above already ran.
|
|
1543
|
+
if (goOkPackages.length > 0) {
|
|
1544
|
+
passed = Math.max(passed, goOkPackages.length);
|
|
1545
|
+
matched = true;
|
|
1546
|
+
}
|
|
1467
1547
|
}
|
|
1468
|
-
//
|
|
1469
|
-
//
|
|
1470
|
-
//
|
|
1471
|
-
|
|
1548
|
+
// #1524-r3: anchored to line START (`^`), and `[^\S\n]` (horizontal
|
|
1549
|
+
// whitespace only) in place of `\s` between the keyword and the
|
|
1550
|
+
// name. The prior `\bFAILED\s+([^\n]+)` and `Failure:\s+([^\n]+)`
|
|
1551
|
+
// let their OWN `\s+` gap cross the newline: a bare `FAILED` at the
|
|
1552
|
+
// end of a line has nothing after it on that line, so `\s+` ate the
|
|
1553
|
+
// newline itself and `([^\n]+)` captured the FIRST TOKEN OF THE
|
|
1554
|
+
// NEXT LINE as the "test name" — proven on a gradle compile failure
|
|
1555
|
+
// (`> Task :compileJava FAILED` followed by
|
|
1556
|
+
// `FAILURE: Build failed with an exception.`, which then rendered
|
|
1557
|
+
// as the invented failure name) and the newline-spanning shape in
|
|
1558
|
+
// general (`FAILED\n\nsome trailing note` → name "some trailing
|
|
1559
|
+
// note"). Requiring `(\S.*)$` on the SAME line makes a keyword with
|
|
1560
|
+
// nothing following it on that line simply not match, rather than
|
|
1561
|
+
// reaching across for content that was never the name.
|
|
1562
|
+
const failures = [];
|
|
1563
|
+
for (const m of goFailNames.slice(0, 5)) {
|
|
1564
|
+
failures.push({ name: m[1].trim(), message: m[1].trim() });
|
|
1565
|
+
}
|
|
1566
|
+
const otherNames = [
|
|
1567
|
+
...output.matchAll(/^[^\S\n]*FAILED[^\S\n]+(\S.*)$/gm),
|
|
1568
|
+
...output.matchAll(/^[^\S\n]*Failure:[^\S\n]+(\S.*)$/gm),
|
|
1569
|
+
];
|
|
1570
|
+
for (const m of otherNames) {
|
|
1571
|
+
if (failures.length >= 5)
|
|
1572
|
+
break;
|
|
1573
|
+
failures.push({ name: m[1].trim(), message: m[1].trim() });
|
|
1574
|
+
}
|
|
1575
|
+
// #1487: gated on `!matched`, not on `failed === 0`. A non-zero exit
|
|
1576
|
+
// with NO count parser match — a spawn/config/load failure, nothing
|
|
1577
|
+
// ran — is infrastructure, not a test verdict: report it as a runner
|
|
1578
|
+
// error. A non-zero exit a count parser DID match (even to a
|
|
1579
|
+
// legitimate `failed === 0`, e.g. a green last module of a red
|
|
1580
|
+
// reactor) is a real run that produced real counts, so it is never a
|
|
1581
|
+
// runner error, and the exit-code-distrust guard below still forces
|
|
1582
|
+
// at least one failure so it can't render as PASS.
|
|
1583
|
+
//
|
|
1584
|
+
// #1524-r3: the veto is `goFailNames.length === 0`, NOT
|
|
1585
|
+
// `failures.length === 0`. Only `--- FAIL:` is a marker a test
|
|
1586
|
+
// runner emits SPECIFICALLY for a failed test; `FAILED`/`Failure:`
|
|
1587
|
+
// are generic words a build tool prints for reasons that have
|
|
1588
|
+
// nothing to do with a test — a gradle task failing to compile, a
|
|
1589
|
+
// maven goal failing before surefire ever runs, an rspec file that
|
|
1590
|
+
// never loaded. Letting those two veto the runner-error branch on
|
|
1591
|
+
// their own reintroduced #1487's exact symptom for the commonest
|
|
1592
|
+
// gradle/maven/rspec failure shapes (proven: `[ERROR] Failed to
|
|
1593
|
+
// execute goal ... FAILED` and rspec's `Failure: cannot load such
|
|
1594
|
+
// file` both rendered as a fabricated test failure instead of the
|
|
1595
|
+
// runner error they actually are). They still label a name onto
|
|
1596
|
+
// `failures` above when `matched` or `goFailNames` already settled
|
|
1597
|
+
// the question some other way, but they no longer settle it alone.
|
|
1598
|
+
const runnerError = exitCode !== 0 && !matched && goFailNames.length === 0 && lower.includes("error")
|
|
1472
1599
|
? `Runner ${runner} exited with ${exitCode}`
|
|
1473
1600
|
: undefined;
|
|
1601
|
+
// #1524-r4 (tidy): a runner-error result reports through
|
|
1602
|
+
// `formatResult`'s runner-error branch, not the failed-tests
|
|
1603
|
+
// branch, so any name `otherNames` picked up before this was
|
|
1604
|
+
// decided (e.g. a same-line `Failure: cannot load such file`)
|
|
1605
|
+
// would sit in `failures` unused but visible to anything reading
|
|
1606
|
+
// the raw `TestResult` — an error result with a non-empty
|
|
1607
|
+
// `failures` list is a self-contradiction. Clear it here so the
|
|
1608
|
+
// result is one or the other, never both.
|
|
1609
|
+
if (runnerError) {
|
|
1610
|
+
failures.length = 0;
|
|
1611
|
+
}
|
|
1474
1612
|
// #1480 (adjacent): a non-zero exit is the runner saying the run
|
|
1475
1613
|
// failed. Every count parser above can legitimately arrive at
|
|
1476
1614
|
// `failed === 0` — a summary that only covers part of the run, a green
|
|
1477
1615
|
// module of a red reactor build, a failure outside any test — and the
|
|
1478
1616
|
// turn-end log would then print PASS over a build the runner rejected.
|
|
1479
1617
|
// Trust the exit code: no parse of the text may talk it out of at least
|
|
1480
|
-
// one failure.
|
|
1481
|
-
|
|
1618
|
+
// one failure. Skipped when `runnerError` is set — that case already
|
|
1619
|
+
// reports through `formatResult`'s runner-error branch, which requires
|
|
1620
|
+
// `passed === 0 && failed === 0` to stay reachable, and forcing
|
|
1621
|
+
// `failed` to 1 here would make it unreachable again (#1487).
|
|
1622
|
+
if (exitCode !== 0 && failed === 0 && !runnerError) {
|
|
1482
1623
|
failed = 1;
|
|
1483
1624
|
}
|
|
1484
1625
|
if (passed === 0 && failed === 0 && skipped === 0 && exitCode === 0) {
|
|
1485
1626
|
passed = 1;
|
|
1486
1627
|
}
|
|
1487
|
-
const failures = [];
|
|
1488
|
-
const names = [
|
|
1489
|
-
...output.matchAll(/--- FAIL:\s+([^\s(]+)/g),
|
|
1490
|
-
...output.matchAll(/\bFAILED\s+([^\n]+)/g),
|
|
1491
|
-
...output.matchAll(/Failure:\s+([^\n]+)/g),
|
|
1492
|
-
];
|
|
1493
|
-
for (const m of names.slice(0, 5)) {
|
|
1494
|
-
failures.push({ name: m[1].trim(), message: m[1].trim() });
|
|
1495
|
-
}
|
|
1496
1628
|
if (failures.length === 0 && failed > 0) {
|
|
1497
1629
|
const firstLine = output
|
|
1498
1630
|
.split("\n")
|
|
@@ -1501,6 +1633,9 @@ export class TestRunnerClient {
|
|
|
1501
1633
|
.slice(0, 300) || `Tests failed for runner ${runner}`;
|
|
1502
1634
|
failures.push({ name: `${runner} failure`, message: firstLine });
|
|
1503
1635
|
}
|
|
1636
|
+
this.log(runnerError
|
|
1637
|
+
? `Generic runner ${runner}: never started (${runnerError})`
|
|
1638
|
+
: `Generic runner ${runner}: ran (matched=${matched}, passed=${passed}, failed=${failed}, failures=${failures.length})`);
|
|
1504
1639
|
return {
|
|
1505
1640
|
file: testFile,
|
|
1506
1641
|
sourceFile: "",
|
|
@@ -33,13 +33,19 @@
|
|
|
33
33
|
* enumerate the built-ins only; pi-lens's `tool_call`/`tool_result` paths
|
|
34
34
|
* also key off `lsp_navigation` and pi-lens's own registered tools, which no
|
|
35
35
|
* host discriminator names.
|
|
36
|
-
* 4. **
|
|
36
|
+
* 4. **The host union is narrower than the events pi-lens handles.** The host
|
|
37
37
|
* `ToolResultEvent` declares `toolCallId`/`input`/`content`/`isError`/
|
|
38
38
|
* `details`/`usage`; pi-lens's local `ToolResultEvent`
|
|
39
|
-
* (`clients/runtime-tool-result.ts`)
|
|
40
|
-
* `id`/`callId`/`requestId`/`provider`/`model
|
|
41
|
-
* the telemetry-identity path
|
|
42
|
-
* `
|
|
39
|
+
* (`clients/runtime-tool-result.ts`) declares the subset it reads. It used
|
|
40
|
+
* to additionally carry `id`/`callId`/`requestId`/`provider`/`model`/
|
|
41
|
+
* `sessionId`/`session` "for the telemetry-identity path" — #1655 item 2
|
|
42
|
+
* deleted all seven, because pi's `afterToolCall` builds the event with
|
|
43
|
+
* exactly `type`/`toolName`/`toolCallId`/`input`/`content`/`details`/
|
|
44
|
+
* `isError`/`usage` (`dist/core/agent-session.js:243-256`, source
|
|
45
|
+
* `src/core/agent-session.ts:502-516`), so the branch reading them was dead
|
|
46
|
+
* code. The standing reason not to narrow is point 3: pi-lens also
|
|
47
|
+
* synthesizes its OWN `tool_result` payloads (bash-derived writes,
|
|
48
|
+
* partial-apply) that no host discriminator would admit.
|
|
43
49
|
*
|
|
44
50
|
* What IS consolidated is the part that costs nothing: the host's `details`
|
|
45
51
|
* SHAPES are type-only exports, so `EditToolDetails` & co. are imported as
|
|
@@ -47,8 +53,53 @@
|
|
|
47
53
|
* payloads (`searchReads`, `piLensPartialApply`) stay hand-declared — no host
|
|
48
54
|
* type describes them.
|
|
49
55
|
*/
|
|
56
|
+
import { sanitizeCorrelationId } from "./read-guard-logger.js";
|
|
50
57
|
export function isToolCallEventType(toolName, event) {
|
|
51
58
|
return (!!event &&
|
|
52
59
|
typeof event === "object" &&
|
|
53
60
|
event.toolName === toolName);
|
|
54
61
|
}
|
|
62
|
+
/**
|
|
63
|
+
* Resolve a STABLE correlation id shared between a `tool_call` and its
|
|
64
|
+
* paired `tool_result`, checking every field name a host is known to use
|
|
65
|
+
* (#1642 F4) — the SDK declares `toolCallId` (see the file header above for
|
|
66
|
+
* why pi-lens can't import the SDK's own type at runtime), but
|
|
67
|
+
* `read-guard-logger.ts`'s `getReadGuardCorrelationId` already had to widen
|
|
68
|
+
* to `callId`/`requestId`/`id` for hosts that populate one of those instead.
|
|
69
|
+
* Single source of truth for that field list — do not hand-roll a narrower
|
|
70
|
+
* `event.toolCallId` read at a new call site.
|
|
71
|
+
*
|
|
72
|
+
* Deliberately does NOT fall back to a generated id the way
|
|
73
|
+
* `getReadGuardCorrelationId` does: that fallback is minted fresh on EVERY
|
|
74
|
+
* call (a bare per-invocation counter), which is exactly right for grouping
|
|
75
|
+
* one call's own log lines but useless — actively misleading — for
|
|
76
|
+
* correlating two SEPARATE events (a `tool_call` and its `tool_result`)
|
|
77
|
+
* against each other. `undefined` means the host supplies no stable
|
|
78
|
+
* identity at all under any known field; callers decide their own safe
|
|
79
|
+
* default for that case rather than treat a generated id as a match.
|
|
80
|
+
*/
|
|
81
|
+
export function resolveToolCallCorrelationId(event) {
|
|
82
|
+
const value = (event ?? {});
|
|
83
|
+
for (const candidate of [
|
|
84
|
+
value.toolCallId,
|
|
85
|
+
value.callId,
|
|
86
|
+
value.requestId,
|
|
87
|
+
// Widest rung, only reached when toolCallId/callId/requestId are all
|
|
88
|
+
// absent (#1678 item 2): this assumes a host's `id` field identifies
|
|
89
|
+
// one TOOL CALL. A host that instead populates `id` per MESSAGE (one
|
|
90
|
+
// id shared by every tool call in that message) would cross two
|
|
91
|
+
// parallel calls in the same turn under the same id. Stated plainly:
|
|
92
|
+
// real pi builds `tool_call`/`tool_result` events with exactly
|
|
93
|
+
// `toolCallId` and no bare `id` field at all (see the file header
|
|
94
|
+
// above, #1655 item 2, `src/core/agent-session.ts:502-516`), so this
|
|
95
|
+
// rung is dead code against today's host — kept only in case a
|
|
96
|
+
// different host shape needs it; drop it once #1655's audit confirms
|
|
97
|
+
// none does.
|
|
98
|
+
value.id,
|
|
99
|
+
]) {
|
|
100
|
+
const sanitized = sanitizeCorrelationId(candidate);
|
|
101
|
+
if (sanitized)
|
|
102
|
+
return sanitized;
|
|
103
|
+
}
|
|
104
|
+
return undefined;
|
|
105
|
+
}
|
|
@@ -3,7 +3,7 @@ import * as path from "node:path";
|
|
|
3
3
|
import { TERRAGRUNT_FILENAMES } from "./file-kinds.js";
|
|
4
4
|
import { logLatency } from "./latency-logger.js";
|
|
5
5
|
import { resolvePackagePath } from "./package-root.js";
|
|
6
|
-
import { findNearestContaining, walkUpDirs } from "./path-utils.js";
|
|
6
|
+
import { findNearestContaining, normalizeMapKey, walkUpDirs, } from "./path-utils.js";
|
|
7
7
|
import { loadProjectSnapshotWithoutWordIndex } from "./project-snapshot.js";
|
|
8
8
|
// Extension → formatter policy. This map, `FORMATTER_POLICY_BY_FILENAME`, and
|
|
9
9
|
// `AUTO_INSTALLABLE_DEFAULT_FORMATTERS` are the inverse of the formatter
|
|
@@ -272,7 +272,7 @@ const FORMATTER_POLICY_BY_EXTENSION = new Map([
|
|
|
272
272
|
formatterNames: ["swiftformat"],
|
|
273
273
|
defaultFormatter: "swiftformat",
|
|
274
274
|
defaultWhenUnconfigured: false,
|
|
275
|
-
gate: "
|
|
275
|
+
gate: "config-first",
|
|
276
276
|
},
|
|
277
277
|
],
|
|
278
278
|
[
|
|
@@ -281,7 +281,7 @@ const FORMATTER_POLICY_BY_EXTENSION = new Map([
|
|
|
281
281
|
formatterNames: ["fantomas"],
|
|
282
282
|
defaultFormatter: "fantomas",
|
|
283
283
|
defaultWhenUnconfigured: false,
|
|
284
|
-
gate: "
|
|
284
|
+
gate: "config-first",
|
|
285
285
|
},
|
|
286
286
|
],
|
|
287
287
|
[
|
|
@@ -290,7 +290,7 @@ const FORMATTER_POLICY_BY_EXTENSION = new Map([
|
|
|
290
290
|
formatterNames: ["fantomas"],
|
|
291
291
|
defaultFormatter: "fantomas",
|
|
292
292
|
defaultWhenUnconfigured: false,
|
|
293
|
-
gate: "
|
|
293
|
+
gate: "config-first",
|
|
294
294
|
},
|
|
295
295
|
],
|
|
296
296
|
[
|
|
@@ -299,7 +299,7 @@ const FORMATTER_POLICY_BY_EXTENSION = new Map([
|
|
|
299
299
|
formatterNames: ["fantomas"],
|
|
300
300
|
defaultFormatter: "fantomas",
|
|
301
301
|
defaultWhenUnconfigured: false,
|
|
302
|
-
gate: "
|
|
302
|
+
gate: "config-first",
|
|
303
303
|
},
|
|
304
304
|
],
|
|
305
305
|
[
|
|
@@ -317,7 +317,7 @@ const FORMATTER_POLICY_BY_EXTENSION = new Map([
|
|
|
317
317
|
formatterNames: ["mix"],
|
|
318
318
|
defaultFormatter: "mix",
|
|
319
319
|
defaultWhenUnconfigured: false,
|
|
320
|
-
gate: "
|
|
320
|
+
gate: "config-first",
|
|
321
321
|
},
|
|
322
322
|
],
|
|
323
323
|
[
|
|
@@ -326,7 +326,7 @@ const FORMATTER_POLICY_BY_EXTENSION = new Map([
|
|
|
326
326
|
formatterNames: ["mix"],
|
|
327
327
|
defaultFormatter: "mix",
|
|
328
328
|
defaultWhenUnconfigured: false,
|
|
329
|
-
gate: "
|
|
329
|
+
gate: "config-first",
|
|
330
330
|
},
|
|
331
331
|
],
|
|
332
332
|
[
|
|
@@ -335,7 +335,7 @@ const FORMATTER_POLICY_BY_EXTENSION = new Map([
|
|
|
335
335
|
formatterNames: ["mix"],
|
|
336
336
|
defaultFormatter: "mix",
|
|
337
337
|
defaultWhenUnconfigured: false,
|
|
338
|
-
gate: "
|
|
338
|
+
gate: "config-first",
|
|
339
339
|
},
|
|
340
340
|
],
|
|
341
341
|
[
|
|
@@ -344,7 +344,7 @@ const FORMATTER_POLICY_BY_EXTENSION = new Map([
|
|
|
344
344
|
formatterNames: ["mix"],
|
|
345
345
|
defaultFormatter: "mix",
|
|
346
346
|
defaultWhenUnconfigured: false,
|
|
347
|
-
gate: "
|
|
347
|
+
gate: "config-first",
|
|
348
348
|
},
|
|
349
349
|
],
|
|
350
350
|
[
|
|
@@ -353,7 +353,7 @@ const FORMATTER_POLICY_BY_EXTENSION = new Map([
|
|
|
353
353
|
formatterNames: ["mix"],
|
|
354
354
|
defaultFormatter: "mix",
|
|
355
355
|
defaultWhenUnconfigured: false,
|
|
356
|
-
gate: "
|
|
356
|
+
gate: "config-first",
|
|
357
357
|
},
|
|
358
358
|
],
|
|
359
359
|
[
|
|
@@ -443,7 +443,7 @@ const FORMATTER_POLICY_BY_EXTENSION = new Map([
|
|
|
443
443
|
formatterNames: ["csharpier"],
|
|
444
444
|
defaultFormatter: "csharpier",
|
|
445
445
|
defaultWhenUnconfigured: false,
|
|
446
|
-
gate: "
|
|
446
|
+
gate: "config-first",
|
|
447
447
|
},
|
|
448
448
|
],
|
|
449
449
|
[
|
|
@@ -461,7 +461,7 @@ const FORMATTER_POLICY_BY_EXTENSION = new Map([
|
|
|
461
461
|
formatterNames: ["ormolu"],
|
|
462
462
|
defaultFormatter: "ormolu",
|
|
463
463
|
defaultWhenUnconfigured: false,
|
|
464
|
-
gate: "
|
|
464
|
+
gate: "config-first",
|
|
465
465
|
},
|
|
466
466
|
],
|
|
467
467
|
[
|
|
@@ -470,7 +470,7 @@ const FORMATTER_POLICY_BY_EXTENSION = new Map([
|
|
|
470
470
|
formatterNames: ["ormolu"],
|
|
471
471
|
defaultFormatter: "ormolu",
|
|
472
472
|
defaultWhenUnconfigured: false,
|
|
473
|
-
gate: "
|
|
473
|
+
gate: "config-first",
|
|
474
474
|
},
|
|
475
475
|
],
|
|
476
476
|
[
|
|
@@ -533,7 +533,7 @@ const FORMATTER_POLICY_BY_EXTENSION = new Map([
|
|
|
533
533
|
formatterNames: ["taplo"],
|
|
534
534
|
defaultFormatter: "taplo",
|
|
535
535
|
defaultWhenUnconfigured: false,
|
|
536
|
-
gate: "
|
|
536
|
+
gate: "config-first",
|
|
537
537
|
},
|
|
538
538
|
],
|
|
539
539
|
[
|
|
@@ -542,7 +542,7 @@ const FORMATTER_POLICY_BY_EXTENSION = new Map([
|
|
|
542
542
|
formatterNames: ["terraform"],
|
|
543
543
|
defaultFormatter: "terraform",
|
|
544
544
|
defaultWhenUnconfigured: false,
|
|
545
|
-
gate: "
|
|
545
|
+
gate: "config-first",
|
|
546
546
|
},
|
|
547
547
|
],
|
|
548
548
|
[
|
|
@@ -551,7 +551,7 @@ const FORMATTER_POLICY_BY_EXTENSION = new Map([
|
|
|
551
551
|
formatterNames: ["terraform"],
|
|
552
552
|
defaultFormatter: "terraform",
|
|
553
553
|
defaultWhenUnconfigured: false,
|
|
554
|
-
gate: "
|
|
554
|
+
gate: "config-first",
|
|
555
555
|
},
|
|
556
556
|
],
|
|
557
557
|
[
|
|
@@ -653,6 +653,15 @@ const FORMATTER_POLICY_BY_EXTENSION = new Map([
|
|
|
653
653
|
gate: "smart-default",
|
|
654
654
|
},
|
|
655
655
|
],
|
|
656
|
+
[
|
|
657
|
+
".cue",
|
|
658
|
+
{
|
|
659
|
+
formatterNames: ["cue"],
|
|
660
|
+
defaultFormatter: "cue",
|
|
661
|
+
defaultWhenUnconfigured: true,
|
|
662
|
+
gate: "smart-default",
|
|
663
|
+
},
|
|
664
|
+
],
|
|
656
665
|
]);
|
|
657
666
|
// oxfmt supports these extensions — registered as a candidate formatter for each.
|
|
658
667
|
// Using a post-processing pass avoids repeating the same modification across
|
|
@@ -2025,10 +2034,17 @@ export function ruffConfigArgs(cwd) {
|
|
|
2025
2034
|
* `config/biome/core.jsonc` fallback — applies on `lint --write` too.
|
|
2026
2035
|
*/
|
|
2027
2036
|
export function biomeConfigArgs(cwd) {
|
|
2037
|
+
// A project config wins outright (#1731, discipline A): passing
|
|
2038
|
+
// `--config-path` even when the project ships `biome.json(c)` pinned
|
|
2039
|
+
// biome's config resolution to that ONE file, so a monorepo package
|
|
2040
|
+
// underneath `cwd` with its own `biome.json` never got to extend/override
|
|
2041
|
+
// the root config the way biome's own nested-config resolution allows. No
|
|
2042
|
+
// flag at all lets biome discover it unaided, exactly like the ruff/
|
|
2043
|
+
// markdownlint fallbacks above skip `--config` under the same condition.
|
|
2044
|
+
if (getBiomeConfigPath(cwd))
|
|
2045
|
+
return [];
|
|
2028
2046
|
return [
|
|
2029
|
-
"--config-path=" +
|
|
2030
|
-
(getBiomeConfigPath(cwd) ??
|
|
2031
|
-
resolvePackagePath(import.meta.url, "config/biome/core.jsonc")),
|
|
2047
|
+
"--config-path=" + resolvePackagePath(import.meta.url, "config/biome/core.jsonc"),
|
|
2032
2048
|
];
|
|
2033
2049
|
}
|
|
2034
2050
|
export function hasGolangciConfig(cwd) {
|
|
@@ -2079,6 +2095,89 @@ export function hasCmakeFormatConfig(cwd) {
|
|
|
2079
2095
|
"cmake-format.yml",
|
|
2080
2096
|
]) !== undefined);
|
|
2081
2097
|
}
|
|
2098
|
+
// PSScriptAnalyzerSettings.psd1 is the conventional settings file PowerShell
|
|
2099
|
+
// projects use to configure `Invoke-Formatter`/`Invoke-ScriptAnalyzer` (passed
|
|
2100
|
+
// via `-Settings`); `ScriptAnalyzerSettings.psd1` is the same convention minus
|
|
2101
|
+
// the "PS" prefix and shows up in some repos too. Either one opting a project
|
|
2102
|
+
// into explicit PSScriptAnalyzer config is enough to select the formatter
|
|
2103
|
+
// (#1572 — `psscriptanalyzer-format` had no case here at all, so it could
|
|
2104
|
+
// never be selected regardless of project config).
|
|
2105
|
+
const PSSCRIPTANALYZER_SETTINGS_FILES = [
|
|
2106
|
+
"PSScriptAnalyzerSettings.psd1",
|
|
2107
|
+
"ScriptAnalyzerSettings.psd1",
|
|
2108
|
+
];
|
|
2109
|
+
/**
|
|
2110
|
+
* The nearest PSScriptAnalyzer settings file's full path, or `undefined`.
|
|
2111
|
+
* `formatters.ts`'s `resolveCommand` passes this straight to
|
|
2112
|
+
* `Invoke-Formatter -Settings` (#1572 review F2) — gating on the file's
|
|
2113
|
+
* PRESENCE without ever reading its RULES would run the project's file
|
|
2114
|
+
* through the stock `CodeFormatting` ruleset regardless of what it declared,
|
|
2115
|
+
* the same stock-style imposition #1144 banned for the other formatters.
|
|
2116
|
+
*/
|
|
2117
|
+
export function findPSScriptAnalyzerConfigPath(cwd) {
|
|
2118
|
+
for (const dir of walkUpDirs(cwd)) {
|
|
2119
|
+
for (const name of PSSCRIPTANALYZER_SETTINGS_FILES) {
|
|
2120
|
+
const candidate = path.join(dir, name);
|
|
2121
|
+
if (fs.existsSync(candidate))
|
|
2122
|
+
return candidate;
|
|
2123
|
+
}
|
|
2124
|
+
}
|
|
2125
|
+
return undefined;
|
|
2126
|
+
}
|
|
2127
|
+
export function hasPSScriptAnalyzerConfig(cwd) {
|
|
2128
|
+
return findPSScriptAnalyzerConfigPath(cwd) !== undefined;
|
|
2129
|
+
}
|
|
2130
|
+
// #1595 sweep — 7 of the 8 formatters #1572 left unreachable (038cd1df flipped
|
|
2131
|
+
// defaultWhenUnconfigured to false for these without adding an explicit-config
|
|
2132
|
+
// check; see EXPLICIT_FORMATTER_CONFIG_CHECKS in formatters.ts). nixfmt is the
|
|
2133
|
+
// 8th and stays unreachable: it is deliberately unconfigurable (no rc file,
|
|
2134
|
+
// no CLI flag surface) and has no project-level manifest marker analogous to
|
|
2135
|
+
// `terraform init`'s lock file, so there is no honest "explicit opt-in" signal
|
|
2136
|
+
// to gate on — see the KNOWN_UNREACHABLE_FORMATTERS comment in
|
|
2137
|
+
// formatter-policy-consistency.test.ts.
|
|
2138
|
+
export function hasCsharpierConfig(cwd) {
|
|
2139
|
+
return (findNearestContaining(cwd, [
|
|
2140
|
+
".csharpierrc",
|
|
2141
|
+
".csharpierrc.json",
|
|
2142
|
+
".csharpierrc.yaml",
|
|
2143
|
+
".csharpierrc.yml",
|
|
2144
|
+
]) !== undefined);
|
|
2145
|
+
}
|
|
2146
|
+
// Ormolu has no general settings file, but it does read a project `.ormolu`
|
|
2147
|
+
// file for custom operator fixity declarations (the only file-based config
|
|
2148
|
+
// surface Ormolu supports) — real, if narrow, per its own docs.
|
|
2149
|
+
export function hasOrmoluConfig(cwd) {
|
|
2150
|
+
return findNearestContaining(cwd, [".ormolu"]) !== undefined;
|
|
2151
|
+
}
|
|
2152
|
+
export function hasTaploConfig(cwd) {
|
|
2153
|
+
return findNearestContaining(cwd, ["taplo.toml", ".taplo.toml"]) !== undefined;
|
|
2154
|
+
}
|
|
2155
|
+
// `terraform fmt` itself is deliberately unconfigurable (no rc file, no
|
|
2156
|
+
// per-project options — HashiCorp's own docs call this out). The nearest
|
|
2157
|
+
// thing to an explicit per-project opt-in is `.terraform.lock.hcl`, written
|
|
2158
|
+
// only by `terraform init`: it marks a directory the user has deliberately
|
|
2159
|
+
// set up as a Terraform root, as opposed to a stray `.tf`/`.tfvars` file
|
|
2160
|
+
// dropped into an unrelated repo. A manifest marker, per #1595's own guidance
|
|
2161
|
+
// for formatters with no dedicated config-file convention.
|
|
2162
|
+
export function hasTerraformConfig(cwd) {
|
|
2163
|
+
return findNearestContaining(cwd, [".terraform.lock.hcl"]) !== undefined;
|
|
2164
|
+
}
|
|
2165
|
+
export function hasSwiftformatConfig(cwd) {
|
|
2166
|
+
return findNearestContaining(cwd, [".swiftformat"]) !== undefined;
|
|
2167
|
+
}
|
|
2168
|
+
// Fantomas has no dedicated rc file; its documented config surface is
|
|
2169
|
+
// `.editorconfig` (fsharp_*-prefixed keys) or a `.fantomasignore` file (the
|
|
2170
|
+
// one Fantomas-specific marker it does ship). Mirrors hasGoogleJavaFormatConfig's
|
|
2171
|
+
// precedent for formatters whose only config surface is .editorconfig.
|
|
2172
|
+
export function hasFantomasConfig(cwd) {
|
|
2173
|
+
return (findNearestContaining(cwd, [".fantomasignore", ".editorconfig"]) !==
|
|
2174
|
+
undefined);
|
|
2175
|
+
}
|
|
2176
|
+
// `.formatter.exs` is THE convention `mix format` reads project config from
|
|
2177
|
+
// (inputs, line_length, plugins) — universal in Elixir projects that use it.
|
|
2178
|
+
export function hasMixFormatConfig(cwd) {
|
|
2179
|
+
return findNearestContaining(cwd, [".formatter.exs"]) !== undefined;
|
|
2180
|
+
}
|
|
2082
2181
|
export function hasPhpstanConfig(cwd) {
|
|
2083
2182
|
return findNearestContaining(cwd, PHPSTAN_CONFIGS) !== undefined;
|
|
2084
2183
|
}
|
|
@@ -2283,10 +2382,16 @@ const COMPILED_CLASSES_DIRS = [
|
|
|
2283
2382
|
path.join("out", "production"),
|
|
2284
2383
|
path.join("bin", "main"),
|
|
2285
2384
|
];
|
|
2286
|
-
export function hasJavaBuildDescriptor(cwd) {
|
|
2385
|
+
export function hasJavaBuildDescriptor(cwd, ceiling) {
|
|
2386
|
+
const normalizedCeiling = ceiling
|
|
2387
|
+
? normalizeMapKey(path.resolve(ceiling))
|
|
2388
|
+
: undefined;
|
|
2287
2389
|
for (const dir of walkUpDirs(cwd)) {
|
|
2288
2390
|
if (JAVA_BUILD_DESCRIPTORS.some((d) => fs.existsSync(path.join(dir, d))))
|
|
2289
2391
|
return true;
|
|
2392
|
+
if (normalizedCeiling &&
|
|
2393
|
+
normalizeMapKey(path.resolve(dir)) === normalizedCeiling)
|
|
2394
|
+
break;
|
|
2290
2395
|
}
|
|
2291
2396
|
return false;
|
|
2292
2397
|
}
|