@herbertgao/pi-extensions 2026.9.2 → 2026.9.3
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 +3 -2
- package/THIRD_PARTY_NOTICES.md +24 -0
- package/node_modules/@herbertgao/sol-pi/LICENSE +19 -0
- package/node_modules/@herbertgao/sol-pi/README.md +159 -0
- package/node_modules/@herbertgao/sol-pi/SECURITY.md +26 -0
- package/node_modules/@herbertgao/sol-pi/THIRD_PARTY_NOTICES.md +19 -0
- package/node_modules/@herbertgao/sol-pi/agents-install.md +150 -0
- package/node_modules/@herbertgao/sol-pi/assets/sol-pi-hero.png +0 -0
- package/node_modules/@herbertgao/sol-pi/docs/compatibility.md +69 -0
- package/node_modules/@herbertgao/sol-pi/docs/configuration.md +75 -0
- package/node_modules/@herbertgao/sol-pi/package.json +76 -0
- package/node_modules/@herbertgao/sol-pi/scripts/check-pi-compat.mjs +32 -0
- package/node_modules/@herbertgao/sol-pi/scripts/check-sol-pi-config.mjs +120 -0
- package/node_modules/@herbertgao/sol-pi/sol-pi.example.json +10 -0
- package/node_modules/@herbertgao/sol-pi/src/sol-pi/config.ts +135 -0
- package/node_modules/@herbertgao/sol-pi/src/sol-pi/extensions/action-fusion/file-queue.ts +74 -0
- package/node_modules/@herbertgao/sol-pi/src/sol-pi/extensions/action-fusion/index.ts +185 -0
- package/node_modules/@herbertgao/sol-pi/src/sol-pi/extensions/action-fusion/then-run.ts +128 -0
- package/node_modules/@herbertgao/sol-pi/src/sol-pi/extensions/evidence-preserving-reducer/archive.ts +53 -0
- package/node_modules/@herbertgao/sol-pi/src/sol-pi/extensions/evidence-preserving-reducer/candidate.ts +101 -0
- package/node_modules/@herbertgao/sol-pi/src/sol-pi/extensions/evidence-preserving-reducer/config.ts +71 -0
- package/node_modules/@herbertgao/sol-pi/src/sol-pi/extensions/evidence-preserving-reducer/index.ts +220 -0
- package/node_modules/@herbertgao/sol-pi/src/sol-pi/extensions/evidence-preserving-reducer/journal.ts +25 -0
- package/node_modules/@herbertgao/sol-pi/src/sol-pi/extensions/evidence-preserving-reducer/provider.ts +164 -0
- package/node_modules/@herbertgao/sol-pi/src/sol-pi/extensions/evidence-preserving-reducer/receipt.ts +177 -0
- package/node_modules/@herbertgao/sol-pi/src/sol-pi/extensions/observation-pack/index.ts +227 -0
- package/node_modules/@herbertgao/sol-pi/src/sol-pi/extensions/observation-pack/ledger.ts +20 -0
- package/node_modules/@herbertgao/sol-pi/src/sol-pi/extensions/observation-pack/observation.ts +252 -0
- package/node_modules/@herbertgao/sol-pi/src/sol-pi/extensions/online-context-compact/economics.ts +237 -0
- package/node_modules/@herbertgao/sol-pi/src/sol-pi/extensions/online-context-compact/extension.ts +455 -0
- package/node_modules/@herbertgao/sol-pi/src/sol-pi/extensions/online-context-compact/index.ts +49 -0
- package/node_modules/@herbertgao/sol-pi/src/sol-pi/extensions/online-context-compact/plan.ts +79 -0
- package/node_modules/@herbertgao/sol-pi/src/sol-pi/extensions/online-context-compact/state.ts +208 -0
- package/node_modules/@herbertgao/sol-pi/src/sol-pi/extensions/online-context-compact/tools.ts +100 -0
- package/node_modules/@herbertgao/sol-pi/src/sol-pi/index.ts +42 -0
- package/node_modules/@herbertgao/sol-pi/src/sol-pi/runtime-paths.ts +17 -0
- package/node_modules/@herbertgao/sol-pi/src/sol-pi/tui.ts +71 -0
- package/node_modules/@narumitw/pi-btw/dist/index.ts +12 -2
- package/node_modules/@narumitw/pi-btw/dist/index.ts.map +2 -2
- package/node_modules/@narumitw/pi-btw/package.json +1 -1
- package/node_modules/@narumitw/pi-btw/src/btw.ts +13 -2
- package/node_modules/pi-lens/CHANGELOG.md +176 -0
- package/node_modules/pi-lens/README.md +13 -8
- package/node_modules/pi-lens/config/dependency-cruiser-eager-allowlist.json +3 -1
- package/node_modules/pi-lens/dist/clients/analysed-root.js +1 -0
- package/node_modules/pi-lens/dist/clients/ast-grep-tool-logger.js +1 -1
- package/node_modules/pi-lens/dist/clients/biome-client.js +13 -2
- package/node_modules/pi-lens/dist/clients/bounded-telemetry.js +2 -0
- package/node_modules/pi-lens/dist/clients/cache-observability.js +122 -1
- package/node_modules/pi-lens/dist/clients/complexity-client.js +5 -0
- package/node_modules/pi-lens/dist/clients/config-diagnostic-codes.js +2 -0
- package/node_modules/pi-lens/dist/clients/config-resolve.js +6 -3
- package/node_modules/pi-lens/dist/clients/config-schema.js +17 -0
- package/node_modules/pi-lens/dist/clients/config-warn.js +2 -2
- package/node_modules/pi-lens/dist/clients/dead-code-client.js +8 -1
- package/node_modules/pi-lens/dist/clients/dependency-checker.js +5 -1
- package/node_modules/pi-lens/dist/clients/dispatch/dispatcher.js +38 -15
- package/node_modules/pi-lens/dist/clients/dispatch/facts/function-facts.js +1 -1
- package/node_modules/pi-lens/dist/clients/dispatch/facts/import-facts.js +5 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/actionlint.js +2 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/biome-check.js +2 -3
- package/node_modules/pi-lens/dist/clients/dispatch/runners/cpp-check.js +4 -3
- package/node_modules/pi-lens/dist/clients/dispatch/runners/credo.js +2 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/cue-vet.js +2 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/dart-analyze.js +2 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/detekt.js +2 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/dotnet-build.js +2 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/elixir-check.js +2 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/eslint.js +2 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/fish-indent.js +2 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/gleam-check.js +2 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/go-vet.js +2 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/golangci-lint.js +2 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/hadolint.js +2 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/helm-lint.js +3 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/helm-render.js +2 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/htmlhint.js +2 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/javac.js +2 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/ktlint.js +2 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/lsp.js +19 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/markdownlint.js +3 -2
- package/node_modules/pi-lens/dist/clients/dispatch/runners/mypy.js +2 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/oxlint.js +2 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/php-lint.js +2 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/phpstan.js +2 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/prisma-validate.js +2 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/psscriptanalyzer.js +12 -12
- package/node_modules/pi-lens/dist/clients/dispatch/runners/pyright.js +2 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/rubocop.js +2 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/ruff.js +2 -2
- package/node_modules/pi-lens/dist/clients/dispatch/runners/rust-clippy.js +12 -11
- package/node_modules/pi-lens/dist/clients/dispatch/runners/shellcheck.js +2 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/shfmt.js +2 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/spellcheck.js +2 -2
- package/node_modules/pi-lens/dist/clients/dispatch/runners/spotbugs.js +2 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/sqlfluff.js +3 -2
- package/node_modules/pi-lens/dist/clients/dispatch/runners/stylelint.js +3 -2
- package/node_modules/pi-lens/dist/clients/dispatch/runners/swiftlint.js +2 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/taplo.js +2 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/terragrunt.js +2 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/tflint.js +2 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/trivy-config.js +2 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/utils/availability-policy.js +5 -0
- package/node_modules/pi-lens/dist/clients/dispatch/runners/utils/candidate-probe.js +2 -2
- package/node_modules/pi-lens/dist/clients/dispatch/runners/utils/runner-helpers.js +8 -2
- package/node_modules/pi-lens/dist/clients/dispatch/runners/vale.js +2 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/yamllint.js +4 -3
- package/node_modules/pi-lens/dist/clients/dispatch/runners/zig-check.js +2 -1
- package/node_modules/pi-lens/dist/clients/effective-config.js +12 -2
- package/node_modules/pi-lens/dist/clients/extension-log.js +2 -0
- package/node_modules/pi-lens/dist/clients/file-role.js +18 -1
- package/node_modules/pi-lens/dist/clients/finding-delivery-gate.js +4 -0
- package/node_modules/pi-lens/dist/clients/formatters.js +54 -188
- package/node_modules/pi-lens/dist/clients/generation-guard.js +4 -0
- package/node_modules/pi-lens/dist/clients/gitleaks-client.js +42 -6
- package/node_modules/pi-lens/dist/clients/govulncheck-client.js +48 -7
- package/node_modules/pi-lens/dist/clients/installer/index.js +196 -52
- package/node_modules/pi-lens/dist/clients/jscpd-client.js +9 -1
- package/node_modules/pi-lens/dist/clients/knip-client.js +9 -2
- package/node_modules/pi-lens/dist/clients/language-profile.js +12 -2
- package/node_modules/pi-lens/dist/clients/latency-logger.js +2 -0
- package/node_modules/pi-lens/dist/clients/lens-config.js +4 -0
- package/node_modules/pi-lens/dist/clients/lsp/config.js +36 -7
- package/node_modules/pi-lens/dist/clients/lsp/diagnostic-binding.js +24 -1
- package/node_modules/pi-lens/dist/clients/lsp/document-drift.js +78 -0
- package/node_modules/pi-lens/dist/clients/lsp/index.js +281 -45
- package/node_modules/pi-lens/dist/clients/lsp/server.js +62 -15
- package/node_modules/pi-lens/dist/clients/lsp/workspace-diagnostics-cache.js +37 -4
- package/node_modules/pi-lens/dist/clients/mcp/analyze.js +3 -0
- package/node_modules/pi-lens/dist/clients/mcp/session.js +2 -0
- package/node_modules/pi-lens/dist/clients/opengrep-client.js +2 -0
- package/node_modules/pi-lens/dist/clients/package-manager.js +2 -1
- package/node_modules/pi-lens/dist/clients/php-cs-fixer-config.js +8 -3
- package/node_modules/pi-lens/dist/clients/pipeline.js +3 -2
- package/node_modules/pi-lens/dist/clients/project-diagnostics/fresh-fetch.js +38 -10
- package/node_modules/pi-lens/dist/clients/project-diagnostics/runner-adapters/gitleaks.js +10 -9
- package/node_modules/pi-lens/dist/clients/project-lens-config.js +3 -0
- package/node_modules/pi-lens/dist/clients/read-guard-logger.js +2 -0
- package/node_modules/pi-lens/dist/clients/review-graph-logger.js +2 -0
- package/node_modules/pi-lens/dist/clients/ruff-client.js +18 -9
- package/node_modules/pi-lens/dist/clients/runtime-agent-end.js +9 -0
- package/node_modules/pi-lens/dist/clients/runtime-coordinator.js +5 -0
- package/node_modules/pi-lens/dist/clients/runtime-session.js +13 -4
- package/node_modules/pi-lens/dist/clients/runtime-tool-result.js +4 -1
- package/node_modules/pi-lens/dist/clients/runtime-turn.js +48 -1
- package/node_modules/pi-lens/dist/clients/security-scan-client.js +2 -2
- package/node_modules/pi-lens/dist/clients/session-event-guard.js +69 -1
- package/node_modules/pi-lens/dist/clients/sg-runner.js +2 -1
- package/node_modules/pi-lens/dist/clients/situational-tool-telemetry.js +108 -0
- package/node_modules/pi-lens/dist/clients/test-runner-client.js +291 -76
- package/node_modules/pi-lens/dist/clients/tool-config.js +199 -0
- package/node_modules/pi-lens/dist/clients/tool-cwd.js +299 -0
- package/node_modules/pi-lens/dist/clients/tool-probe.js +53 -0
- package/node_modules/pi-lens/dist/clients/tool-set-policy.js +42 -0
- package/node_modules/pi-lens/dist/clients/trivy-client.js +9 -1
- package/node_modules/pi-lens/dist/clients/turn-context.js +52 -0
- package/node_modules/pi-lens/dist/clients/widget-state.js +4 -3
- package/node_modules/pi-lens/dist/index.js +21969 -20005
- package/node_modules/pi-lens/dist/mcp/analyze-cli.js +3 -2
- package/node_modules/pi-lens/dist/mcp/server.js +135 -159
- package/node_modules/pi-lens/dist/tools/activate-tools.js +10 -7
- package/node_modules/pi-lens/dist/tools/ast-grep-outline.js +2 -13
- package/node_modules/pi-lens/dist/tools/ast-grep-replace.js +8 -13
- package/node_modules/pi-lens/dist/tools/ast-grep-search.js +83 -39
- package/node_modules/pi-lens/dist/tools/effective-config.js +4 -3
- package/node_modules/pi-lens/dist/tools/lens-diagnostic-mark.js +1 -10
- package/node_modules/pi-lens/dist/tools/lens-diagnostics.js +353 -85
- package/node_modules/pi-lens/dist/tools/lsp-diagnostics.js +21 -110
- package/node_modules/pi-lens/dist/tools/lsp-navigation.js +20 -44
- package/node_modules/pi-lens/dist/tools/module-report.js +5 -9
- package/node_modules/pi-lens/dist/tools/project-report.js +9 -17
- package/node_modules/pi-lens/dist/tools/render-compact.js +280 -1
- package/node_modules/pi-lens/dist/tools/symbol-search.js +2 -2
- package/node_modules/pi-lens/docs/agent-guide.md +3 -4
- package/node_modules/pi-lens/docs/agent-tools.md +46 -22
- package/node_modules/pi-lens/docs/configuration.md +9 -0
- package/node_modules/pi-lens/docs/environment-variables.md +0 -5
- package/node_modules/pi-lens/docs/features.md +5 -5
- package/node_modules/pi-lens/docs/globalconfig.md +11 -1
- package/node_modules/pi-lens/docs/mcp.md +13 -1
- package/node_modules/pi-lens/docs/pi-lens-fixer.md +71 -0
- package/node_modules/pi-lens/docs/pi-lens-investigator.md +15 -0
- package/node_modules/pi-lens/docs/pi-lens-monitor.md +88 -0
- package/node_modules/pi-lens/docs/pi-lens-reviewer.md +35 -0
- package/node_modules/pi-lens/docs/pi-lens-subagent.md +12 -4
- package/node_modules/pi-lens/docs/public-api-stability.md +1 -0
- package/node_modules/pi-lens/docs/real-harness.md +46 -0
- package/node_modules/pi-lens/docs/release-qa-baseline.md +5 -1
- package/node_modules/pi-lens/docs/servercapabilities.md +1 -6
- package/node_modules/pi-lens/docs/settings.md +37 -2
- package/node_modules/pi-lens/docs/tools_improvement2.md +4 -4
- package/node_modules/pi-lens/docs/tree-sitter_rules_catalog.md +1 -1
- package/node_modules/pi-lens/docs/usage.md +13 -3
- package/node_modules/pi-lens/package.json +10 -1
- package/node_modules/pi-lens/rules/tree-sitter-queries/typescript/sql-injection.yml +7 -3
- package/node_modules/pi-lens/skills/pi-lens-ast-grep/SKILL.md +8 -6
- package/node_modules/pi-lens/skills/pi-lens-lsp-navigation/SKILL.md +19 -9
- package/node_modules/pi-web-access/CHANGELOG.md +29 -0
- package/node_modules/pi-web-access/README.md +33 -22
- package/node_modules/pi-web-access/abortable.ts +17 -0
- package/node_modules/pi-web-access/crawl4ai.ts +204 -0
- package/node_modules/pi-web-access/credential-source.ts +1 -0
- package/node_modules/pi-web-access/curator-page.ts +20 -2
- package/node_modules/pi-web-access/curator-run.ts +44 -0
- package/node_modules/pi-web-access/curator-server.ts +3 -1
- package/node_modules/pi-web-access/duckduckgo.ts +1 -1
- package/node_modules/pi-web-access/extract.ts +57 -12
- package/node_modules/pi-web-access/fetch-params.ts +1 -1
- package/node_modules/pi-web-access/gemini-search.ts +9 -5
- package/node_modules/pi-web-access/index.ts +25 -18
- package/node_modules/pi-web-access/openai-search.ts +35 -13
- package/node_modules/pi-web-access/package.json +2 -2
- package/node_modules/pi-web-access/page-query.ts +5 -2
- package/node_modules/pi-web-access/query-rewrite.ts +5 -2
- package/node_modules/pi-web-access/serpapi.ts +220 -0
- package/node_modules/pi-web-access/ssrf-protection.ts +5 -1
- package/node_modules/pi-web-access/storage.ts +10 -0
- package/node_modules/pi-web-access/summary-review.ts +34 -21
- package/node_modules/pi-web-access/utils.ts +6 -4
- package/package.json +7 -4
- package/node_modules/pi-lens/dist/tools/ast-dump.js +0 -103
|
@@ -42,6 +42,7 @@ import { LEGACY_ROOT_LSP_KEYS, LSP_NAMESPACE_KEY } from "./config-locations.js";
|
|
|
42
42
|
// every config loader's import graph for one type alias.
|
|
43
43
|
import { DENY_KEY, } from "./config-core/schema.js";
|
|
44
44
|
import { flagConfigSectionKeys, GLOBAL_NON_FLAG_CONFIG_SECTIONS, LENS_FLAGS, PROJECT_FOREIGN_CONFIG_NAMESPACES, PROJECT_NON_FLAG_CONFIG_SECTIONS, } from "./lens-flag-registry.js";
|
|
45
|
+
import { LENS_TOOL_NAMES } from "./tool-config.js";
|
|
45
46
|
/** The JSON Schema dialect the published artifact declares. */
|
|
46
47
|
const CONFIG_SCHEMA_DIALECT = "https://json-schema.org/draft/2020-12/schema";
|
|
47
48
|
/**
|
|
@@ -154,6 +155,22 @@ function buildConfigSchema() {
|
|
|
154
155
|
]) {
|
|
155
156
|
properties[key] = opaque("stable");
|
|
156
157
|
}
|
|
158
|
+
properties.tools = {
|
|
159
|
+
type: "object",
|
|
160
|
+
additionalProperties: true,
|
|
161
|
+
properties: Object.fromEntries(LENS_TOOL_NAMES.map((name) => [
|
|
162
|
+
name,
|
|
163
|
+
{
|
|
164
|
+
type: "object",
|
|
165
|
+
additionalProperties: true,
|
|
166
|
+
properties: {
|
|
167
|
+
enabled: { type: "boolean", [STABILITY_TIER_KEY]: "experimental" },
|
|
168
|
+
},
|
|
169
|
+
[STABILITY_TIER_KEY]: "experimental",
|
|
170
|
+
},
|
|
171
|
+
])),
|
|
172
|
+
[STABILITY_TIER_KEY]: "stable",
|
|
173
|
+
};
|
|
157
174
|
// Namespaces owned by another tool that ride in the same file (`trivy`,
|
|
158
175
|
// `helm`). Reserved so they survive validation, `experimental` because their
|
|
159
176
|
// shape belongs to those runners, not to this schema.
|
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
* extraction — the prose is not API (the code is), but silently rewording a
|
|
23
23
|
* warning inside a refactor is still not a thing this PR does.
|
|
24
24
|
*/
|
|
25
|
-
import { DEPRECATED_CONFIG_SURFACES, } from "./config-diagnostic-codes.js";
|
|
25
|
+
import { DEPRECATED_CONFIG_SURFACES, withConfigDiagnosticCode, } from "./config-diagnostic-codes.js";
|
|
26
26
|
import { recordDegradationOnce } from "./degradation-ledger.js";
|
|
27
27
|
import { errorClassName } from "./error-class.js";
|
|
28
28
|
import { logExtension } from "./extension-log.js";
|
|
@@ -378,7 +378,7 @@ export function warnIgnoredConfigOnce(options) {
|
|
|
378
378
|
logExtension({
|
|
379
379
|
subsystem,
|
|
380
380
|
level: "warn",
|
|
381
|
-
message,
|
|
381
|
+
message: withConfigDiagnosticCode(message, code),
|
|
382
382
|
metadata: { configPath: file, reason, code, ...(key ? { key } : {}) },
|
|
383
383
|
});
|
|
384
384
|
// HUMAN-audience too: a config the user wrote is being ignored. Routed
|
|
@@ -19,6 +19,7 @@ import { findLocalBinsAt, VENV_BIN_DIRS } from "./package-manager.js";
|
|
|
19
19
|
import { findNearestMarkerRoot } from "./path-utils.js";
|
|
20
20
|
import { getScratchTreeFnmatchPatterns } from "./scratch-tree-policy.js";
|
|
21
21
|
import { safeSpawnAsync } from "./safe-spawn.js";
|
|
22
|
+
import { probeToolAsync } from "./tool-probe.js";
|
|
22
23
|
import { classifyProbeFailure, createAvailabilityLatch, logAvailabilityDecision, startHostStallSampler, } from "./dispatch/runners/utils/availability-policy.js";
|
|
23
24
|
import { firstOutputLine, spawnFailedWithNoOutput, } from "./dispatch/runners/utils/spawn-outcome.js";
|
|
24
25
|
import { formatToolFailure } from "./dispatch/runners/utils/tool-failure.js";
|
|
@@ -229,7 +230,7 @@ export class PythonDeadCodeClient {
|
|
|
229
230
|
let probe;
|
|
230
231
|
let hostStallMs;
|
|
231
232
|
try {
|
|
232
|
-
probe = await
|
|
233
|
+
probe = await probeToolAsync(c.cmd, [...c.prefix, "--version"], {
|
|
233
234
|
timeout: 5000,
|
|
234
235
|
});
|
|
235
236
|
}
|
|
@@ -415,9 +416,13 @@ export class PythonDeadCodeClient {
|
|
|
415
416
|
durationMs,
|
|
416
417
|
};
|
|
417
418
|
}
|
|
419
|
+
// vulture's verified exit-code table (above): exit 0 with empty
|
|
420
|
+
// stdout IS the clean-run signal, so this ran over the root
|
|
421
|
+
// (#2154) — unlike knip, whose clean run always prints JSON.
|
|
418
422
|
return {
|
|
419
423
|
...emptyResult(this.language),
|
|
420
424
|
success: true,
|
|
425
|
+
analyzed: true,
|
|
421
426
|
summary: "No dead code found",
|
|
422
427
|
durationMs,
|
|
423
428
|
};
|
|
@@ -430,6 +435,8 @@ export class PythonDeadCodeClient {
|
|
|
430
435
|
return {
|
|
431
436
|
...emptyResult(this.language),
|
|
432
437
|
success: true,
|
|
438
|
+
// #2154: parsed vulture output for this root.
|
|
439
|
+
analyzed: true,
|
|
433
440
|
unusedExports,
|
|
434
441
|
summary: total === 0
|
|
435
442
|
? "No dead code found"
|
|
@@ -815,7 +815,11 @@ export class DependencyChecker {
|
|
|
815
815
|
}
|
|
816
816
|
}
|
|
817
817
|
this.publishState(gen, circular, circularFiles);
|
|
818
|
-
|
|
818
|
+
// #2154: the one madge site that parsed a graph for this root. Every
|
|
819
|
+
// other return here (missing root, no top-level source file, madge
|
|
820
|
+
// unavailable, spawn error, parse throw) is the SAME empty shape and
|
|
821
|
+
// must not be read as "no cycles in this project".
|
|
822
|
+
return { circular, count: circular.length, analyzed: true };
|
|
819
823
|
}
|
|
820
824
|
catch (err) {
|
|
821
825
|
this.log(`Scan error: ${err.message}`);
|
|
@@ -29,7 +29,7 @@ import { isSpawnableCommand } from "../installer/index.js";
|
|
|
29
29
|
import { isAbsoluteFilePath, normalizeEphemeralMapKey, normalizeMapKey, } from "../path-utils.js";
|
|
30
30
|
import { loadPiLensProjectConfig } from "../project-lens-config.js";
|
|
31
31
|
import { RUNTIME_CONFIG, getRunnerTimeoutFloorMs } from "../runtime-config.js";
|
|
32
|
-
import {
|
|
32
|
+
import { probeToolAsync } from "../tool-probe.js";
|
|
33
33
|
import { classifyDiagnostic } from "./diagnostic-taxonomy.js";
|
|
34
34
|
import { classifyProbeFailure, logAvailabilityDecision, startHostStallSampler, transientRetryDelayMs, } from "./runners/utils/availability-policy.js";
|
|
35
35
|
import { recordAvailabilityProbeOverrun, getDispatchAvailabilityGeneration, } from "./runners/utils/runner-helpers.js";
|
|
@@ -147,7 +147,7 @@ export async function checkToolAvailability(command, facts) {
|
|
|
147
147
|
let hostStallMs;
|
|
148
148
|
let probeJoined = false;
|
|
149
149
|
try {
|
|
150
|
-
const shared = dispatcherProbeFlights.run(`dispatcher:${key}`, () =>
|
|
150
|
+
const shared = dispatcherProbeFlights.run(`dispatcher:${key}`, () => probeToolAsync(command, ["--version"], {
|
|
151
151
|
timeout: TOOL_PROBE_TIMEOUT_MS,
|
|
152
152
|
}));
|
|
153
153
|
probeJoined = shared.joined;
|
|
@@ -285,11 +285,13 @@ telemetryModel, telemetryProvider) {
|
|
|
285
285
|
async hasTool(command) {
|
|
286
286
|
return checkToolAvailability(command, facts);
|
|
287
287
|
},
|
|
288
|
-
log(message) {
|
|
288
|
+
log(message, level) {
|
|
289
289
|
// #1333: pi owns the terminal — a runner advisory must never be a raw
|
|
290
290
|
// write. Every DispatchContext.log line lands in extension.log instead.
|
|
291
291
|
logExtension({
|
|
292
292
|
subsystem: "dispatch",
|
|
293
|
+
// exactOptionalPropertyTypes: an omitted level must stay omitted.
|
|
294
|
+
...(level !== undefined && { level }),
|
|
293
295
|
message,
|
|
294
296
|
metadata: { filePath: normalizedFilePath, kind },
|
|
295
297
|
});
|
|
@@ -446,31 +448,49 @@ function buildCoverageNotice(ctx, runnerLatencies) {
|
|
|
446
448
|
...new Set(relevant.flatMap((r) => r.unconfirmedServerIds ?? [])),
|
|
447
449
|
];
|
|
448
450
|
if (unconfirmedServerIds.length > 0) {
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
451
|
+
const deferredIds = new Set(relevant.flatMap((r) => r.deferredServerIds ?? []));
|
|
452
|
+
const markerFor = (ids) => {
|
|
453
|
+
const shown = ids.slice(0, 4);
|
|
454
|
+
const remainder = ids.length - shown.length;
|
|
455
|
+
return `${shown.join(", ")}${remainder > 0 ? ` +${remainder}` : ""}`;
|
|
456
|
+
};
|
|
457
|
+
const deferredServerIds = unconfirmedServerIds.filter((id) => deferredIds.has(id));
|
|
458
|
+
const silentServerIds = unconfirmedServerIds.filter((id) => !deferredIds.has(id));
|
|
459
|
+
// The marker describes this exact scanner set. A scanner can recover
|
|
460
|
+
// while another goes dark on the same file, so the set belongs in the
|
|
461
|
+
// session dedupe identity rather than only kind and path.
|
|
452
462
|
// #2016: these are SCANNER IDS, not filesystem paths. `normalizeMapKey`
|
|
453
463
|
// would realpath each one; on Windows that fails, falls through to
|
|
454
464
|
// `resolveNonExisting`, and resolves the id against the CURRENT process
|
|
455
465
|
// cwd, so the dedupe key differed by platform and by cwd (the #2219
|
|
456
466
|
// non-path-sentinel class). The cheap syntactic fold is what this
|
|
457
|
-
// session-scoped dedupe key actually needs.
|
|
458
|
-
|
|
467
|
+
// session-scoped dedupe key actually needs. Code-unit comparator: the
|
|
468
|
+
// sorted set is a KEY, so ordering must be deterministic across locales
|
|
469
|
+
// — localeCompare is not.
|
|
470
|
+
const dedupeSet = (ids) => [...new Set(ids)]
|
|
459
471
|
.map(normalizeEphemeralMapKey)
|
|
460
|
-
// Code-unit comparator: the sorted set is a dedupe KEY, so ordering
|
|
461
|
-
// must be deterministic across locales — localeCompare is not.
|
|
462
472
|
.sort((a, b) => Number(a > b) - Number(a < b))
|
|
463
473
|
.join(",");
|
|
464
|
-
|
|
474
|
+
// #2810 round 4: the PARTITION is part of the identity, not just the
|
|
475
|
+
// scanner set. The same scanner can be silent on one edit and marked for
|
|
476
|
+
// late delivery on the next; keying on the unconfirmed set alone showed
|
|
477
|
+
// the session whichever message came first and suppressed the other, so a
|
|
478
|
+
// scanner that recovered a delivery path (or lost one) kept the stale
|
|
479
|
+
// wording for the rest of the session.
|
|
480
|
+
const onceKey = `${ctx.kind}:${ctx.filePath}:${dedupeSet(silentServerIds)}|${dedupeSet(deferredServerIds)}`;
|
|
465
481
|
if (coverageNoticeSeen.has(onceKey))
|
|
466
482
|
return undefined;
|
|
467
483
|
coverageNoticeSeen.add(onceKey);
|
|
468
|
-
const
|
|
469
|
-
|
|
470
|
-
|
|
484
|
+
const coverageParts = [];
|
|
485
|
+
if (deferredServerIds.length > 0) {
|
|
486
|
+
coverageParts.push(`coverage: ${markerFor(deferredServerIds)} deferred — diagnostics are incomplete; findings arrive at turn end if the scan lands.`);
|
|
487
|
+
}
|
|
488
|
+
if (silentServerIds.length > 0) {
|
|
489
|
+
coverageParts.push(`coverage: ${markerFor(silentServerIds)} silent — diagnostics are incomplete (not a clean result).`);
|
|
490
|
+
}
|
|
471
491
|
return {
|
|
472
492
|
id: `coverage-partial:${ctx.kind}:${path.basename(ctx.filePath)}`,
|
|
473
|
-
message:
|
|
493
|
+
message: coverageParts.join("\n"),
|
|
474
494
|
filePath: ctx.filePath,
|
|
475
495
|
severity: "warning",
|
|
476
496
|
semantic: "warning",
|
|
@@ -837,6 +857,9 @@ async function runGroup(ctx, group, registry, onRunnerResult) {
|
|
|
837
857
|
...(result.unconfirmedServerIds !== undefined && {
|
|
838
858
|
unconfirmedServerIds: result.unconfirmedServerIds,
|
|
839
859
|
}),
|
|
860
|
+
...(result.deferredServerIds !== undefined && {
|
|
861
|
+
deferredServerIds: result.deferredServerIds,
|
|
862
|
+
}),
|
|
840
863
|
});
|
|
841
864
|
logLatency({
|
|
842
865
|
type: "runner",
|
|
@@ -135,7 +135,7 @@ function isCallPassThrough(stmt, paramNames) {
|
|
|
135
135
|
}
|
|
136
136
|
return { pass: true, target: (expr.children ?? [])[0]?.text };
|
|
137
137
|
}
|
|
138
|
-
function calcCyclomaticComplexity(body) {
|
|
138
|
+
export function calcCyclomaticComplexity(body) {
|
|
139
139
|
let cc = 1;
|
|
140
140
|
walk(body, (node) => {
|
|
141
141
|
if (COMPLEXITY_TYPES.has(node.type)) {
|
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
import { logLatency } from "../../latency-logger.js";
|
|
2
2
|
import { isJstsFactFile } from "../../file-kinds.js";
|
|
3
3
|
import { childrenOfType, firstChildOfType, withFactTree, walk, } from "./tree-sitter-facts.js";
|
|
4
|
+
/** Whether the import-facts provider applies to a source path. */
|
|
5
|
+
export function importFactsApplyTo(filePath) {
|
|
6
|
+
return isJstsFactFile(filePath);
|
|
7
|
+
}
|
|
4
8
|
function stripQuotes(raw) {
|
|
5
9
|
return raw.replace(/^["'`]+|["'`]+$/g, "");
|
|
6
10
|
}
|
|
@@ -69,7 +73,7 @@ export const importFactProvider = {
|
|
|
69
73
|
provides: ["file.imports", "file.reexports", "file.importFactsCoverage"],
|
|
70
74
|
requires: ["file.content"],
|
|
71
75
|
appliesTo(ctx) {
|
|
72
|
-
return
|
|
76
|
+
return importFactsApplyTo(ctx.filePath);
|
|
73
77
|
},
|
|
74
78
|
async run(ctx, store) {
|
|
75
79
|
const content = store.getFileFact(ctx.filePath, "file.content");
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import path from "node:path";
|
|
2
2
|
import { safeSpawnAsync } from "../../safe-spawn.js";
|
|
3
|
+
import { resolveRunnerCwd } from "../../tool-cwd.js";
|
|
3
4
|
import { PRIORITY } from "../priorities.js";
|
|
4
5
|
import { createAvailabilityChecker, resolveToolCommandWithInstallFallback, } from "./utils/runner-helpers.js";
|
|
5
6
|
const actionlint = createAvailabilityChecker("actionlint", ".exe");
|
|
@@ -66,7 +67,7 @@ const actionlintRunner = {
|
|
|
66
67
|
return isGitHubWorkflowFile(ctx.filePath);
|
|
67
68
|
},
|
|
68
69
|
async run(ctx) {
|
|
69
|
-
const cwd = ctx
|
|
70
|
+
const cwd = resolveRunnerCwd(ctx, "actionlint");
|
|
70
71
|
let cmd = null;
|
|
71
72
|
if (await actionlint.isAvailableAsync(cwd)) {
|
|
72
73
|
cmd = actionlint.getCommand(cwd);
|
|
@@ -5,13 +5,12 @@
|
|
|
5
5
|
* Autofix is handled earlier by the post-write pipeline to avoid
|
|
6
6
|
* mutating files mid-dispatch after LSP sync has already happened.
|
|
7
7
|
*/
|
|
8
|
-
import * as path from "node:path";
|
|
9
8
|
import { incrementDegradationCount } from "../../degradation-ledger.js";
|
|
10
9
|
import { mapWithConcurrency } from "../../dependency-checker.js";
|
|
11
10
|
import { safeSpawnAsync } from "../../safe-spawn.js";
|
|
12
11
|
import { biomeConfigArgs, getAutofixCapability, getJstsLintPolicyForCwd, } from "../../tool-policy.js";
|
|
13
12
|
import { PRIORITY } from "../priorities.js";
|
|
14
|
-
import { resolveToolCommandWithInstallFallback } from "./utils/runner-helpers.js";
|
|
13
|
+
import { resolveRunnerCwd, resolveToolCommandWithInstallFallback, } from "./utils/runner-helpers.js";
|
|
15
14
|
import { finishParsedRun } from "./utils/tool-failure.js";
|
|
16
15
|
/**
|
|
17
16
|
* Map biome's own severity vocabulary onto the four-tier `Diagnostic.severity`
|
|
@@ -198,7 +197,7 @@ const biomeCheckJsonRunner = {
|
|
|
198
197
|
appliesTo: ["jsts"],
|
|
199
198
|
priority: PRIORITY.FORMAT_AND_LINT_PRIMARY,
|
|
200
199
|
async run(ctx) {
|
|
201
|
-
const cwd = ctx
|
|
200
|
+
const cwd = resolveRunnerCwd(ctx, "biome");
|
|
202
201
|
const policy = getJstsLintPolicyForCwd(cwd);
|
|
203
202
|
// Defer to ESLint/oxlint if the project has explicitly configured one —
|
|
204
203
|
// biome runs as the default linter only when no alternative is present.
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import * as fs from "node:fs";
|
|
2
2
|
import * as path from "node:path";
|
|
3
3
|
import { safeSpawnAsync } from "../../safe-spawn.js";
|
|
4
|
+
import { probeToolAsync } from "../../tool-probe.js";
|
|
5
|
+
import { resolveRunnerCwd } from "../../tool-cwd.js";
|
|
4
6
|
import { PRIORITY } from "../priorities.js";
|
|
5
7
|
import { createAvailabilityChecker } from "./utils/runner-helpers.js";
|
|
6
8
|
// Per-compiler availability checkers — each one caches per-cwd and
|
|
@@ -100,8 +102,7 @@ async function resolveCompiler(absPath, cwd) {
|
|
|
100
102
|
// Mirrors the deliberate global-PATH probes in utils/runner-helpers.ts:
|
|
101
103
|
// this never resolves a config file or a target path, so there is no cwd
|
|
102
104
|
// for it to get wrong.
|
|
103
|
-
|
|
104
|
-
const clProbe = await safeSpawnAsync("cl", [], { timeout: 5000 });
|
|
105
|
+
const clProbe = await probeToolAsync("cl", [], { timeout: 5000 });
|
|
105
106
|
if (!clProbe.error && clProbe.status !== null) {
|
|
106
107
|
return {
|
|
107
108
|
command: "cl",
|
|
@@ -181,7 +182,7 @@ const cppCheckRunner = {
|
|
|
181
182
|
priority: PRIORITY.GENERAL_ANALYSIS,
|
|
182
183
|
skipTestFiles: false,
|
|
183
184
|
async run(ctx) {
|
|
184
|
-
const cwd = ctx
|
|
185
|
+
const cwd = resolveRunnerCwd(ctx, "cpp-check");
|
|
185
186
|
const absPath = path.resolve(cwd, ctx.filePath);
|
|
186
187
|
const compiler = await resolveCompiler(absPath, cwd);
|
|
187
188
|
if (!compiler) {
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import * as path from "node:path";
|
|
2
2
|
import * as fs from "node:fs";
|
|
3
3
|
import { safeSpawnAsync } from "../../safe-spawn.js";
|
|
4
|
+
import { resolveRunnerCwd } from "../../tool-cwd.js";
|
|
4
5
|
import { PRIORITY } from "../priorities.js";
|
|
5
6
|
import { createCwdCachedProbe } from "./utils/runner-helpers.js";
|
|
6
7
|
const CREDO_PROBE_BUDGET_MS = 10_000;
|
|
@@ -50,7 +51,7 @@ const credoRunner = {
|
|
|
50
51
|
priority: PRIORITY.GENERAL_ANALYSIS,
|
|
51
52
|
skipTestFiles: false,
|
|
52
53
|
async run(ctx) {
|
|
53
|
-
const cwd = ctx
|
|
54
|
+
const cwd = resolveRunnerCwd(ctx, "credo");
|
|
54
55
|
if (!hasMixExs(cwd)) {
|
|
55
56
|
return { status: "skipped", diagnostics: [], semantic: "none" };
|
|
56
57
|
}
|
|
@@ -104,6 +104,7 @@
|
|
|
104
104
|
import * as fs from "node:fs";
|
|
105
105
|
import * as path from "node:path";
|
|
106
106
|
import { safeSpawnAsync } from "../../safe-spawn.js";
|
|
107
|
+
import { resolveRunnerCwd } from "../../tool-cwd.js";
|
|
107
108
|
import { createAvailabilityChecker, resolveAvailableOrInstall, } from "./utils/runner-helpers.js";
|
|
108
109
|
import { spawnFailedWithNoOutput } from "./utils/spawn-outcome.js";
|
|
109
110
|
import { PRIORITY } from "../priorities.js";
|
|
@@ -281,7 +282,7 @@ const cueVetRunner = {
|
|
|
281
282
|
skipTestFiles: false,
|
|
282
283
|
timeoutMs: 30_000,
|
|
283
284
|
async run(ctx) {
|
|
284
|
-
const cwd = ctx
|
|
285
|
+
const cwd = resolveRunnerCwd(ctx, "cue-vet");
|
|
285
286
|
let cmd = null;
|
|
286
287
|
if (await cue.isAvailableAsync(cwd)) {
|
|
287
288
|
cmd = cue.getCommand(cwd);
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import * as path from "node:path";
|
|
2
2
|
import { safeSpawnAsync } from "../../safe-spawn.js";
|
|
3
|
+
import { resolveRunnerCwd } from "../../tool-cwd.js";
|
|
3
4
|
import { createAvailabilityChecker } from "./utils/runner-helpers.js";
|
|
4
5
|
import { PRIORITY } from "../priorities.js";
|
|
5
6
|
const dart = createAvailabilityChecker("dart", ".exe");
|
|
@@ -147,7 +148,7 @@ const dartAnalyzeRunner = {
|
|
|
147
148
|
priority: PRIORITY.GENERAL_ANALYSIS,
|
|
148
149
|
skipTestFiles: false,
|
|
149
150
|
async run(ctx) {
|
|
150
|
-
const cwd = ctx
|
|
151
|
+
const cwd = resolveRunnerCwd(ctx, "dart-analyze");
|
|
151
152
|
const absPath = path.resolve(cwd, ctx.filePath);
|
|
152
153
|
const dartAvailable = await dart.isAvailableAsync(cwd);
|
|
153
154
|
const flutterAvailable = !dartAvailable && (await flutter.isAvailableAsync(cwd));
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import * as fs from "node:fs";
|
|
2
2
|
import * as path from "node:path";
|
|
3
3
|
import { safeSpawnAsync } from "../../safe-spawn.js";
|
|
4
|
+
import { resolveRunnerCwd } from "../../tool-cwd.js";
|
|
4
5
|
import { getLinterPolicyForCwd } from "../../tool-policy.js";
|
|
5
6
|
import { PRIORITY } from "../priorities.js";
|
|
6
7
|
import { createAvailabilityChecker } from "./utils/runner-helpers.js";
|
|
@@ -129,7 +130,7 @@ const detektRunner = {
|
|
|
129
130
|
timeoutMs: 90_000,
|
|
130
131
|
skipTestFiles: false,
|
|
131
132
|
async run(ctx) {
|
|
132
|
-
const cwd = ctx
|
|
133
|
+
const cwd = resolveRunnerCwd(ctx, "detekt");
|
|
133
134
|
const policy = getLinterPolicyForCwd(ctx.filePath, cwd);
|
|
134
135
|
if (policy && !policy.preferredRunners.includes("detekt")) {
|
|
135
136
|
return { status: "skipped", diagnostics: [], semantic: "none" };
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import * as fs from "node:fs";
|
|
2
2
|
import * as path from "node:path";
|
|
3
3
|
import { safeSpawnAsync } from "../../safe-spawn.js";
|
|
4
|
+
import { resolveRunnerCwd } from "../../tool-cwd.js";
|
|
4
5
|
import { PRIORITY } from "../priorities.js";
|
|
5
6
|
import { createAvailabilityChecker } from "./utils/runner-helpers.js";
|
|
6
7
|
const dotnet = createAvailabilityChecker("dotnet", ".exe");
|
|
@@ -118,7 +119,7 @@ const dotnetBuildRunner = {
|
|
|
118
119
|
timeoutMs: 90_000,
|
|
119
120
|
skipTestFiles: false,
|
|
120
121
|
async run(ctx) {
|
|
121
|
-
const cwd = ctx
|
|
122
|
+
const cwd = resolveRunnerCwd(ctx, "dotnet-build");
|
|
122
123
|
if (!(await dotnet.isAvailableAsync(cwd))) {
|
|
123
124
|
return { status: "skipped", diagnostics: [], semantic: "none" };
|
|
124
125
|
}
|
|
@@ -2,6 +2,7 @@ import * as fs from "node:fs";
|
|
|
2
2
|
import * as path from "node:path";
|
|
3
3
|
import { getProjectDataDir } from "../../file-utils.js";
|
|
4
4
|
import { safeSpawnAsync } from "../../safe-spawn.js";
|
|
5
|
+
import { resolveRunnerCwd } from "../../tool-cwd.js";
|
|
5
6
|
import { PRIORITY } from "../priorities.js";
|
|
6
7
|
import { createAvailabilityChecker } from "./utils/runner-helpers.js";
|
|
7
8
|
// Per-cwd cached `--version` probes (#120). Before this, each dispatch
|
|
@@ -141,7 +142,7 @@ const elixirCheckRunner = {
|
|
|
141
142
|
priority: PRIORITY.GENERAL_ANALYSIS,
|
|
142
143
|
skipTestFiles: false,
|
|
143
144
|
async run(ctx) {
|
|
144
|
-
const cwd = ctx
|
|
145
|
+
const cwd = resolveRunnerCwd(ctx, "elixir-check");
|
|
145
146
|
const absPath = path.resolve(cwd, ctx.filePath);
|
|
146
147
|
let command;
|
|
147
148
|
let args = [];
|
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
* Gate: skips when no ESLint config is detected (project uses Biome/OxLint instead).
|
|
8
8
|
*/
|
|
9
9
|
import { safeSpawnAsync } from "../../safe-spawn.js";
|
|
10
|
+
import { resolveRunnerCwd } from "../../tool-cwd.js";
|
|
10
11
|
import { getAutofixCapability, hasEslintConfig } from "../../tool-policy.js";
|
|
11
12
|
import { PRIORITY } from "../priorities.js";
|
|
12
13
|
import { createCwdCachedProbe, resolveToolCommand, } from "./utils/runner-helpers.js";
|
|
@@ -79,7 +80,7 @@ const eslintRunner = {
|
|
|
79
80
|
appliesTo: ["jsts"],
|
|
80
81
|
priority: PRIORITY.LINT_SECONDARY,
|
|
81
82
|
async run(ctx) {
|
|
82
|
-
const cwd = ctx
|
|
83
|
+
const cwd = resolveRunnerCwd(ctx, "eslint");
|
|
83
84
|
const userHasConfig = hasEslintConfig(cwd);
|
|
84
85
|
// Only run if project has an ESLint config.
|
|
85
86
|
if (!userHasConfig) {
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { safeSpawnAsync } from "../../safe-spawn.js";
|
|
2
|
+
import { resolveRunnerCwd } from "../../tool-cwd.js";
|
|
2
3
|
import { PRIORITY } from "../priorities.js";
|
|
3
4
|
import { createAvailabilityChecker } from "./utils/runner-helpers.js";
|
|
4
5
|
// fish_indent ships with fish — not separately installable, no managed fallback
|
|
@@ -9,7 +10,7 @@ const fishIndentRunner = {
|
|
|
9
10
|
priority: PRIORITY.FORMAT_AND_LINT_PRIMARY,
|
|
10
11
|
skipTestFiles: false,
|
|
11
12
|
async run(ctx) {
|
|
12
|
-
const cwd = ctx
|
|
13
|
+
const cwd = resolveRunnerCwd(ctx, "fish-indent");
|
|
13
14
|
const available = await fishIndent.isAvailableAsync(cwd);
|
|
14
15
|
if (!available)
|
|
15
16
|
return { status: "skipped", diagnostics: [], semantic: "none" };
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { safeSpawnAsync } from "../../safe-spawn.js";
|
|
2
|
+
import { resolveRunnerCwd } from "../../tool-cwd.js";
|
|
2
3
|
import { createAvailabilityChecker } from "./utils/runner-helpers.js";
|
|
3
4
|
import { PRIORITY } from "../priorities.js";
|
|
4
5
|
const gleam = createAvailabilityChecker("gleam", ".exe");
|
|
@@ -41,7 +42,7 @@ const gleamCheckRunner = {
|
|
|
41
42
|
priority: PRIORITY.GENERAL_ANALYSIS,
|
|
42
43
|
skipTestFiles: false,
|
|
43
44
|
async run(ctx) {
|
|
44
|
-
const cwd = ctx
|
|
45
|
+
const cwd = resolveRunnerCwd(ctx, "gleam-check");
|
|
45
46
|
if (!(await gleam.isAvailableAsync(cwd))) {
|
|
46
47
|
return { status: "skipped", diagnostics: [], semantic: "none" };
|
|
47
48
|
}
|
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
import { relative, resolve, sep, posix } from "node:path";
|
|
7
7
|
import { goClient } from "../../go-client.js";
|
|
8
8
|
import { safeSpawnAsync } from "../../safe-spawn.js";
|
|
9
|
+
import { resolveRunnerCwd } from "../../tool-cwd.js";
|
|
9
10
|
import { stripAnsi } from "../../sanitize.js";
|
|
10
11
|
import { skipUnlessToolRan } from "./utils/tool-failure.js";
|
|
11
12
|
import { parseGoVetOutput } from "./utils/diagnostic-parsers.js";
|
|
@@ -29,7 +30,7 @@ const goVetRunner = {
|
|
|
29
30
|
// `go.mod file not found` (#263). ctx.cwd is the go.mod module root
|
|
30
31
|
// (resolveLanguageRootForFile, markers ["go.mod"]), so vet the file's
|
|
31
32
|
// package from there.
|
|
32
|
-
const cwd = ctx
|
|
33
|
+
const cwd = resolveRunnerCwd(ctx, "go-vet");
|
|
33
34
|
const fileRel = relative(cwd, ctx.filePath).split(sep).join(posix.sep);
|
|
34
35
|
const pkgPath = fileRel.startsWith("../")
|
|
35
36
|
? // File isn't under ctx.cwd (unexpected — ctx.cwd is the go.mod root).
|
|
@@ -11,6 +11,7 @@
|
|
|
11
11
|
*/
|
|
12
12
|
import * as path from "node:path";
|
|
13
13
|
import { safeSpawnAsync } from "../../safe-spawn.js";
|
|
14
|
+
import { resolveRunnerCwd } from "../../tool-cwd.js";
|
|
14
15
|
import { getLinterPolicyForCwd, hasGolangciConfig } from "../../tool-policy.js";
|
|
15
16
|
import { PRIORITY } from "../priorities.js";
|
|
16
17
|
import { createAvailabilityChecker, resolveAvailableOrInstall, } from "./utils/runner-helpers.js";
|
|
@@ -80,7 +81,7 @@ const golangciRunner = {
|
|
|
80
81
|
priority: PRIORITY.GENERAL_ANALYSIS,
|
|
81
82
|
timeoutMs: 90_000,
|
|
82
83
|
async run(ctx) {
|
|
83
|
-
const cwd = ctx
|
|
84
|
+
const cwd = resolveRunnerCwd(ctx, "golangci-lint");
|
|
84
85
|
const policy = getLinterPolicyForCwd(ctx.filePath, cwd);
|
|
85
86
|
if (policy && !policy.preferredRunners.includes("golangci-lint")) {
|
|
86
87
|
return { status: "skipped", diagnostics: [], semantic: "none" };
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import * as path from "node:path";
|
|
2
2
|
import { safeSpawnAsync } from "../../safe-spawn.js";
|
|
3
|
+
import { resolveRunnerCwd } from "../../tool-cwd.js";
|
|
3
4
|
import { getLinterPolicyForCwd } from "../../tool-policy.js";
|
|
4
5
|
import { PRIORITY } from "../priorities.js";
|
|
5
6
|
import { createAvailabilityChecker, resolveToolCommandWithInstallFallback, } from "./utils/runner-helpers.js";
|
|
@@ -37,7 +38,7 @@ const hadolintRunner = {
|
|
|
37
38
|
priority: PRIORITY.GENERAL_ANALYSIS,
|
|
38
39
|
skipTestFiles: false,
|
|
39
40
|
async run(ctx) {
|
|
40
|
-
const cwd = ctx
|
|
41
|
+
const cwd = resolveRunnerCwd(ctx, "hadolint");
|
|
41
42
|
const policy = getLinterPolicyForCwd(ctx.filePath, cwd);
|
|
42
43
|
if (policy && !policy.preferredRunners.includes("hadolint")) {
|
|
43
44
|
return { status: "skipped", diagnostics: [], semantic: "none" };
|
|
@@ -3,6 +3,7 @@ import { PathKeyedMap } from "../../path-keyed-map.js";
|
|
|
3
3
|
import { normalizeMapKey } from "../../path-utils.js";
|
|
4
4
|
import { safeSpawnAsync } from "../../safe-spawn.js";
|
|
5
5
|
import { truncatedByOutputCap } from "../../spawn-output-cap.js";
|
|
6
|
+
import { resolveRunnerCwd } from "../../tool-cwd.js";
|
|
6
7
|
import { findNearestDirWithMarker } from "../../workspace-topology.js";
|
|
7
8
|
import { PRIORITY } from "../priorities.js";
|
|
8
9
|
import { createAvailabilityChecker, resolveAvailableOrInstall, } from "./utils/runner-helpers.js";
|
|
@@ -147,6 +148,7 @@ const helmLintRunner = {
|
|
|
147
148
|
skipTestFiles: false,
|
|
148
149
|
timeoutMs: 35_000,
|
|
149
150
|
async run(ctx) {
|
|
151
|
+
const cwd = resolveRunnerCwd(ctx, "helm");
|
|
150
152
|
const workspaceRoot = path.resolve(ctx.projectRoot ?? ctx.cwd);
|
|
151
153
|
const startDir = path.dirname(path.resolve(ctx.filePath));
|
|
152
154
|
const discovered = findNearestDirWithMarker(startDir, "chartYamlPath");
|
|
@@ -158,7 +160,7 @@ const helmLintRunner = {
|
|
|
158
160
|
const existing = inFlightByChartRoot.get(chartRoot);
|
|
159
161
|
if (existing)
|
|
160
162
|
return existing;
|
|
161
|
-
const promise = lintChart(chartRoot,
|
|
163
|
+
const promise = lintChart(chartRoot, cwd).finally(() => {
|
|
162
164
|
if (inFlightByChartRoot.get(chartRoot) === promise)
|
|
163
165
|
inFlightByChartRoot.delete(chartRoot);
|
|
164
166
|
});
|
|
@@ -78,6 +78,7 @@ import { normalizeMapKey } from "../../path-utils.js";
|
|
|
78
78
|
import { loadPiLensProjectConfig } from "../../project-lens-config.js";
|
|
79
79
|
import { getProjectTrustState, projectTrustDenialReason, } from "../../project-trust.js";
|
|
80
80
|
import { safeSpawnAsync } from "../../safe-spawn.js";
|
|
81
|
+
import { resolveRunnerCwd } from "../../tool-cwd.js";
|
|
81
82
|
import { killedForOutputCap, truncatedByOutputCap, } from "../../spawn-output-cap.js";
|
|
82
83
|
import { isTrivyEnabled, resolveSeverityFloor } from "../../trivy-client.js";
|
|
83
84
|
import { findNearestDirWithMarker } from "../../workspace-topology.js";
|
|
@@ -896,7 +897,7 @@ const helmRenderRunner = {
|
|
|
896
897
|
skipTestFiles: false,
|
|
897
898
|
timeoutMs: RENDER_TIMEOUT_MS + TRIVY_TIMEOUT_MS + 10_000,
|
|
898
899
|
async run(ctx) {
|
|
899
|
-
const cwd = ctx
|
|
900
|
+
const cwd = resolveRunnerCwd(ctx, "helm-render");
|
|
900
901
|
const workspaceRoot = path.resolve(ctx.projectRoot ?? cwd);
|
|
901
902
|
// Gate 1 — consent, read from the project whose chart would run. Keying
|
|
902
903
|
// this on `cwd` let an opt-in in one directory authorize a DIFFERENT
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import * as path from "node:path";
|
|
2
2
|
import { safeSpawnAsync } from "../../safe-spawn.js";
|
|
3
|
+
import { resolveRunnerCwd } from "../../tool-cwd.js";
|
|
3
4
|
import { getLinterPolicyForCwd } from "../../tool-policy.js";
|
|
4
5
|
import { PRIORITY } from "../priorities.js";
|
|
5
6
|
import { createAvailabilityChecker, resolveToolCommandWithInstallFallback, } from "./utils/runner-helpers.js";
|
|
@@ -49,7 +50,7 @@ const htmlhintRunner = {
|
|
|
49
50
|
priority: PRIORITY.GENERAL_ANALYSIS,
|
|
50
51
|
skipTestFiles: false,
|
|
51
52
|
async run(ctx) {
|
|
52
|
-
const cwd = ctx
|
|
53
|
+
const cwd = resolveRunnerCwd(ctx, "htmlhint");
|
|
53
54
|
const policy = getLinterPolicyForCwd(ctx.filePath, cwd);
|
|
54
55
|
if (policy && !policy.preferredRunners.includes("htmlhint")) {
|
|
55
56
|
return { status: "skipped", diagnostics: [], semantic: "none" };
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import * as path from "node:path";
|
|
2
2
|
import { safeSpawnAsync } from "../../safe-spawn.js";
|
|
3
|
+
import { resolveRunnerCwd } from "../../tool-cwd.js";
|
|
3
4
|
import { hasJavaBuildDescriptor } from "../../tool-policy.js";
|
|
4
5
|
import { PRIORITY } from "../priorities.js";
|
|
5
6
|
import { createAvailabilityChecker } from "./utils/runner-helpers.js";
|
|
@@ -41,7 +42,7 @@ const javacRunner = {
|
|
|
41
42
|
priority: PRIORITY.GENERAL_ANALYSIS,
|
|
42
43
|
skipTestFiles: false,
|
|
43
44
|
async run(ctx) {
|
|
44
|
-
const cwd = ctx
|
|
45
|
+
const cwd = resolveRunnerCwd(ctx, "javac");
|
|
45
46
|
const absPath = path.resolve(cwd, ctx.filePath);
|
|
46
47
|
// Inside a Maven/Gradle project a classpath-less single-file compile
|
|
47
48
|
// cannot produce a valid verdict: every non-JDK import becomes a
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import * as path from "node:path";
|
|
2
2
|
import { safeSpawnAsync } from "../../safe-spawn.js";
|
|
3
|
+
import { resolveRunnerCwd } from "../../tool-cwd.js";
|
|
3
4
|
import { getAutofixCapability, getLinterPolicyForCwd, } from "../../tool-policy.js";
|
|
4
5
|
import { PRIORITY } from "../priorities.js";
|
|
5
6
|
import { createAvailabilityChecker, resolveToolCommandWithInstallFallback, } from "./utils/runner-helpers.js";
|
|
@@ -58,7 +59,7 @@ const ktlintRunner = {
|
|
|
58
59
|
priority: PRIORITY.FORMAT_AND_LINT_PRIMARY,
|
|
59
60
|
skipTestFiles: false,
|
|
60
61
|
async run(ctx) {
|
|
61
|
-
const cwd = ctx
|
|
62
|
+
const cwd = resolveRunnerCwd(ctx, "ktlint");
|
|
62
63
|
const policy = getLinterPolicyForCwd(ctx.filePath, cwd);
|
|
63
64
|
if (policy && !policy.preferredRunners.includes("ktlint")) {
|
|
64
65
|
return { status: "skipped", diagnostics: [], semantic: "none" };
|