@herbertgao/pi-extensions 2026.9.2 → 2026.9.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +4 -2
- package/THIRD_PARTY_NOTICES.md +49 -0
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/compact-mode.ts +3 -2
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/default-mode.ts +16 -11
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/tool/diff/diff-renderer.ts +20 -6
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/tool/grouping.ts +12 -7
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/tool/result.ts +98 -0
- package/node_modules/@herbertgao/pi-cc-extensions/package.json +3 -3
- 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-antigravity/LICENSE +21 -0
- package/node_modules/pi-antigravity/README.md +194 -0
- package/node_modules/pi-antigravity/package.json +67 -0
- package/node_modules/pi-antigravity/src/auth/index.ts +14 -0
- package/node_modules/pi-antigravity/src/auth/oauth.ts +442 -0
- package/node_modules/pi-antigravity/src/client/client.ts +561 -0
- package/node_modules/pi-antigravity/src/client/index.ts +1 -0
- package/node_modules/pi-antigravity/src/diagnostics/diagnostics.ts +96 -0
- package/node_modules/pi-antigravity/src/diagnostics/index.ts +1 -0
- package/node_modules/pi-antigravity/src/image/image.ts +336 -0
- package/node_modules/pi-antigravity/src/image/index.ts +1 -0
- package/node_modules/pi-antigravity/src/index.ts +280 -0
- package/node_modules/pi-antigravity/src/models/discovery.ts +154 -0
- package/node_modules/pi-antigravity/src/models/grouping.ts +424 -0
- package/node_modules/pi-antigravity/src/models/index.ts +3 -0
- package/node_modules/pi-antigravity/src/models/models.ts +500 -0
- package/node_modules/pi-antigravity/src/stream/index.ts +1 -0
- package/node_modules/pi-antigravity/src/stream/stream.ts +1460 -0
- package/node_modules/pi-antigravity/src/types/enums.ts +42 -0
- package/node_modules/pi-antigravity/src/types/index.ts +2 -0
- package/node_modules/pi-antigravity/src/types/types.ts +292 -0
- package/node_modules/pi-antigravity/src/usage/index.ts +1 -0
- package/node_modules/pi-antigravity/src/usage/usage.ts +371 -0
- package/node_modules/pi-antigravity/src/utils/http.ts +91 -0
- package/node_modules/pi-antigravity/src/utils/index.ts +3 -0
- package/node_modules/pi-antigravity/src/utils/security.ts +73 -0
- package/node_modules/pi-antigravity/src/utils/util.ts +132 -0
- package/node_modules/pi-antigravity/tsconfig.json +21 -0
- 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 +11 -5
- package/node_modules/pi-lens/dist/tools/ast-dump.js +0 -103
|
@@ -6,7 +6,6 @@
|
|
|
6
6
|
*/
|
|
7
7
|
import * as fs from "node:fs";
|
|
8
8
|
import * as path from "node:path";
|
|
9
|
-
import { Type } from "../clients/deps/typebox.js";
|
|
10
9
|
import { getProjectIgnoreMatcher, isExcludedDirName, } from "../clients/file-utils.js";
|
|
11
10
|
import { getLSPService, groupFilesByPrimaryServer, runPerServerGroups, } from "../clients/lsp/index.js";
|
|
12
11
|
import { buildScopeKey, createWorkspaceDiagnosticsCacheContext, } from "../clients/lsp/workspace-diagnostics-cache.js";
|
|
@@ -20,23 +19,26 @@ import { attemptTsserverSyncDiagnostics } from "../clients/lsp/tsserver-sync.js"
|
|
|
20
19
|
import { convertLspDiagnostics } from "../clients/dispatch/utils/lsp-diagnostics.js";
|
|
21
20
|
import { demoteInferredProjectDiagnostics } from "../clients/lsp/inferred-project.js";
|
|
22
21
|
import { isBlocking, reconcileScanDiagnostics, } from "../clients/widget-state.js";
|
|
23
|
-
import {
|
|
24
|
-
import { makeProgressReporter, scanningSummaryLine } from "./scan-progress.js";
|
|
22
|
+
import { makeProgressReporter } from "./scan-progress.js";
|
|
25
23
|
import { isWarmAttached, tryWarmAttachedDiagnostics, } from "../clients/warm-attach.js";
|
|
26
24
|
import { extensionsForLanguage, SCAN_LANGUAGE_PRIORITY, } from "../clients/language-registry.js";
|
|
27
25
|
const MAX_FILES = 100;
|
|
28
|
-
const MAX_BATCH_FILES = 100;
|
|
26
|
+
export const MAX_BATCH_FILES = 100;
|
|
29
27
|
const MAX_DIAGNOSTICS = 200;
|
|
30
28
|
const DEFAULT_BATCH_CONCURRENCY = 8;
|
|
31
29
|
const MAX_BATCH_CONCURRENCY = 16;
|
|
32
30
|
const DEFAULT_BATCH_FILE_DEADLINE_MS = 15_000;
|
|
33
31
|
// LSP severities: 1=Error, 2=Warning, 3=Information, 4=Hint
|
|
34
|
-
const SEVERITY_NAMES = {
|
|
32
|
+
export const SEVERITY_NAMES = {
|
|
35
33
|
1: "error",
|
|
36
34
|
2: "warning",
|
|
37
35
|
3: "information",
|
|
38
36
|
4: "hint",
|
|
39
37
|
};
|
|
38
|
+
export const LSP_SEVERITY_FILTERS = [
|
|
39
|
+
...Object.values(SEVERITY_NAMES),
|
|
40
|
+
"all",
|
|
41
|
+
];
|
|
40
42
|
function batchFileDeadlineMs() {
|
|
41
43
|
const raw = Number(process.env.PI_LENS_LSP_BATCH_FILE_MS);
|
|
42
44
|
return Number.isFinite(raw) && raw > 0 ? raw : DEFAULT_BATCH_FILE_DEADLINE_MS;
|
|
@@ -216,102 +218,8 @@ nextWriteIndex,
|
|
|
216
218
|
// injecting "Unresolved from this turn" for three more turns after answering
|
|
217
219
|
// "confirmed clean" for the same file. index.ts injects
|
|
218
220
|
// `runtime.retireInlineBlockerOnConfirmedClean`. Optional/undefined in tests.
|
|
219
|
-
onConfirmedNoBlockers) {
|
|
221
|
+
onConfirmedNoBlockers, getService = getLSPService) {
|
|
220
222
|
return {
|
|
221
|
-
name: "lsp_diagnostics",
|
|
222
|
-
label: "LSP Diagnostics",
|
|
223
|
-
description: "Get errors, warnings, and hints from language servers for a file or directory. " +
|
|
224
|
-
"Use BEFORE running builds to proactively check for issues. " +
|
|
225
|
-
"Works on directories by auto-detecting file extensions and scanning all matching files.",
|
|
226
|
-
promptSnippet: "Get LSP diagnostics for a file or directory (use before builds)",
|
|
227
|
-
renderResult: compactRenderResult(({ details, args, isError, text }) => {
|
|
228
|
-
// Streaming progress partials render the live bar (see scanningSummaryLine).
|
|
229
|
-
const scanning = scanningSummaryLine(details, text);
|
|
230
|
-
if (scanning)
|
|
231
|
-
return scanning;
|
|
232
|
-
if (isError) {
|
|
233
|
-
return `lsp_diagnostics — ${text.split("\n")[0] ?? "error"}`;
|
|
234
|
-
}
|
|
235
|
-
const count = details?.totalDiagnostics ?? details?.diagnostics?.length ?? 0;
|
|
236
|
-
const target = baseName(details?.filePath ?? args.path) || "workspace";
|
|
237
|
-
const files = details?.filesChecked ?? details?.filesScanned;
|
|
238
|
-
const scope = typeof files === "number" && files > 1
|
|
239
|
-
? ` across ${files} files`
|
|
240
|
-
: target
|
|
241
|
-
? ` ${target}`
|
|
242
|
-
: "";
|
|
243
|
-
const noun = count === 1 ? "diagnostic" : "diagnostics";
|
|
244
|
-
// #533: a batch/directory result with any unconfirmed files must NEVER
|
|
245
|
-
// compact-render as a bare "N diagnostics" — that erases the fact some
|
|
246
|
-
// files' clean status was never actually confirmed by the server.
|
|
247
|
-
const unconfirmedFiles = details?.unconfirmedFiles ?? 0;
|
|
248
|
-
const navigationOnlyFiles = details?.navigationOnlyFiles ?? 0;
|
|
249
|
-
if (navigationOnlyFiles > 0) {
|
|
250
|
-
return `lsp_diagnostics${scope} — ${count} ${noun} · ${details?.cleanFiles ?? 0} clean · ${navigationOnlyFiles} navigation-only`;
|
|
251
|
-
}
|
|
252
|
-
if (unconfirmedFiles > 0) {
|
|
253
|
-
const cleanFiles = details?.cleanFiles ?? 0;
|
|
254
|
-
const timedOutFiles = details?.timedOutFiles ?? 0;
|
|
255
|
-
const suffix = timedOutFiles > 0 ? ` (${timedOutFiles} timed out)` : "";
|
|
256
|
-
return `lsp_diagnostics${scope} — ${count} ${noun} · ${cleanFiles} clean · ${unconfirmedFiles} unconfirmed${suffix}`;
|
|
257
|
-
}
|
|
258
|
-
const outcomeCounts = details?.outcomeCounts;
|
|
259
|
-
const notConfirmed = outcomeCounts
|
|
260
|
-
? (outcomeCounts.inconclusive ?? 0) +
|
|
261
|
-
(outcomeCounts.unavailable ?? 0) +
|
|
262
|
-
(outcomeCounts.unsupported ?? 0) +
|
|
263
|
-
(outcomeCounts.failed ?? 0)
|
|
264
|
-
: 0;
|
|
265
|
-
if (notConfirmed > 0) {
|
|
266
|
-
return `lsp_diagnostics${scope} — ${count} ${noun} · ${notConfirmed} checks not confirmed`;
|
|
267
|
-
}
|
|
268
|
-
if ((details?.incompleteFiles ?? 0) > 0) {
|
|
269
|
-
return `lsp_diagnostics${scope} — incomplete (${details?.incompleteFiles} files not confirmed)`;
|
|
270
|
-
}
|
|
271
|
-
// Single-file mode: 0 diagnostics from an unconfirmed result — either a
|
|
272
|
-
// silent-on-clean server or (#570) a timed-out check — is not a clean
|
|
273
|
-
// render either.
|
|
274
|
-
if (count === 0 && details?.unconfirmed) {
|
|
275
|
-
return details?.timedOut
|
|
276
|
-
? `lsp_diagnostics${scope} — timed out (result may be incomplete)`
|
|
277
|
-
: `lsp_diagnostics${scope} — unconfirmed (server cannot confirm clean)`;
|
|
278
|
-
}
|
|
279
|
-
return `lsp_diagnostics${scope} — ${count} ${noun}`;
|
|
280
|
-
}),
|
|
281
|
-
parameters: Type.Object({
|
|
282
|
-
path: Type.Optional(Type.String({
|
|
283
|
-
description: "File or directory path to check. For directories, all matching source files are scanned.",
|
|
284
|
-
})),
|
|
285
|
-
paths: Type.Optional(Type.Array(Type.String(), {
|
|
286
|
-
minItems: 1,
|
|
287
|
-
maxItems: MAX_BATCH_FILES,
|
|
288
|
-
description: "Explicit files to check as a bounded-concurrency batch. When provided, path is ignored.",
|
|
289
|
-
})),
|
|
290
|
-
severity: Type.Optional(Type.String({
|
|
291
|
-
enum: ["error", "warning", "information", "hint", "all"],
|
|
292
|
-
description: "Filter by severity level (default: all)",
|
|
293
|
-
})),
|
|
294
|
-
concurrency: Type.Optional(Type.Number({
|
|
295
|
-
description: "Batch/directory concurrency, in distinct LSP server groups run in parallel " +
|
|
296
|
-
"(default 8, max 16) — not individual files. Files sharing one server " +
|
|
297
|
-
"(e.g. a same-language batch) are always processed one at a time against " +
|
|
298
|
-
"that server regardless of this value; this caps how many DIFFERENT " +
|
|
299
|
-
"servers run concurrently.",
|
|
300
|
-
})),
|
|
301
|
-
waitMs: Type.Optional(Type.Number({
|
|
302
|
-
description: "Optional per-file LSP wait budget for batch diagnostics. Uses server defaults when omitted.",
|
|
303
|
-
})),
|
|
304
|
-
serverScope: Type.Optional(Type.String({
|
|
305
|
-
enum: ["primary", "all"],
|
|
306
|
-
description: "'primary' (fast, low-noise): only the file's actual language " +
|
|
307
|
-
"server (e.g. typescript) — for 'does this have real type " +
|
|
308
|
-
"errors'. 'all' (default): also touches cross-cutting auxiliary " +
|
|
309
|
-
"scanners (ast-grep, opengrep, zizmor, typos, marksman) attached " +
|
|
310
|
-
"to this file, including findings for files not yet dispatched " +
|
|
311
|
-
"this session. Primary confirmation is always reported " +
|
|
312
|
-
"separately from auxiliary findings regardless of this setting.",
|
|
313
|
-
})),
|
|
314
|
-
}),
|
|
315
223
|
async execute(_toolCallId, params, _signal, onUpdate, ctx) {
|
|
316
224
|
// Escape aborts the turn via ctx.signal; honor both it and the tool-call
|
|
317
225
|
// signal so a batch/directory scan cancels rather than grinding on.
|
|
@@ -327,7 +235,7 @@ onConfirmedNoBlockers) {
|
|
|
327
235
|
? Math.floor(typedParams.waitMs)
|
|
328
236
|
: undefined;
|
|
329
237
|
const serverScope = typedParams.serverScope === "primary" ? "primary" : "all";
|
|
330
|
-
const lspService =
|
|
238
|
+
const lspService = getService();
|
|
331
239
|
if (!lspService) {
|
|
332
240
|
return {
|
|
333
241
|
content: [
|
|
@@ -450,7 +358,7 @@ async function collectDiagnosticsForFile(absPath, lspService, waitMs, serverScop
|
|
|
450
358
|
const attached = await tryWarmAttachedDiagnostics(absPath, content, attachedBudgetMs, "sweep");
|
|
451
359
|
if (attached?.available) {
|
|
452
360
|
const scopedDiagnostics = serverScope === "primary"
|
|
453
|
-
? attached.response.diagnostics.filter((item) => item.
|
|
361
|
+
? attached.response.diagnostics.filter((item) => item.serverId === primaryServerId(absPath))
|
|
454
362
|
: attached.response.diagnostics;
|
|
455
363
|
const filtered = applyAuxiliarySuppressions(scopedDiagnostics, content, { fileRole: detectFileRole(absPath, content) });
|
|
456
364
|
return {
|
|
@@ -546,6 +454,7 @@ function diagnosticsToFileDiags(file, diagnostics) {
|
|
|
546
454
|
severity: d.severity,
|
|
547
455
|
message: d.message,
|
|
548
456
|
source: d.source,
|
|
457
|
+
serverId: d.serverId,
|
|
549
458
|
code: d.code,
|
|
550
459
|
}));
|
|
551
460
|
}
|
|
@@ -704,7 +613,9 @@ observedAt) {
|
|
|
704
613
|
scanOrigin: "lsp_diagnostics",
|
|
705
614
|
});
|
|
706
615
|
const retagged = retagAuxiliaryDiagnostics(diagnostics, rawDiags, content ?? "", { cwd, fileRole: detectFileRole(file, content) });
|
|
707
|
-
reconcileScanDiagnostics(file, retagged, true, writeIndex, observedAt);
|
|
616
|
+
const reconciled = reconcileScanDiagnostics(file, retagged, true, writeIndex, observedAt);
|
|
617
|
+
if (!reconciled)
|
|
618
|
+
return { confirmed: false, blocking: true };
|
|
708
619
|
// #1561: the blocking tally comes from the SAME `isBlocking` predicate the
|
|
709
620
|
// footer counts with — no second severity rule for the blocker-retire
|
|
710
621
|
// decision to drift away from.
|
|
@@ -965,8 +876,8 @@ onConfirmedNoBlockers) {
|
|
|
965
876
|
});
|
|
966
877
|
}
|
|
967
878
|
const primaryId = primaryServerId(absPath);
|
|
968
|
-
const primaryDiags = limited.filter((d) => d.
|
|
969
|
-
const auxiliaryDiags = limited.filter((d) => d.
|
|
879
|
+
const primaryDiags = limited.filter((d) => d.serverId === primaryId);
|
|
880
|
+
const auxiliaryDiags = limited.filter((d) => d.serverId !== primaryId);
|
|
970
881
|
// Primary confirmation is always its own line, independent of how many
|
|
971
882
|
// auxiliary findings exist — a wall of ast-grep/opengrep noise must never
|
|
972
883
|
// bury whether the actual language server confirmed the file clean.
|
|
@@ -999,7 +910,7 @@ onConfirmedNoBlockers) {
|
|
|
999
910
|
// this result does NOT speak for, so "no auxiliary findings" can never be read
|
|
1000
911
|
// as "the security scanners found nothing".
|
|
1001
912
|
const coverageLine = unconfirmedServerIds.length > 0
|
|
1002
|
-
? `Auxiliary coverage INCOMPLETE — ${[...unconfirmedServerIds].join(", ")} did not answer within the wait budget, so ${unconfirmedServerIds.length === 1 ? "its findings are" : "their findings are"} NOT included here. This is not a clean bill of health for ${unconfirmedServerIds.length === 1 ? "that scanner" : "those scanners"}; re-check after the next edit
|
|
913
|
+
? `Auxiliary coverage INCOMPLETE — ${[...unconfirmedServerIds].join(", ")} did not answer within the wait budget, so ${unconfirmedServerIds.length === 1 ? "its findings are" : "their findings are"} NOT included here. This is not a clean bill of health for ${unconfirmedServerIds.length === 1 ? "that scanner" : "those scanners"}; re-check after the next edit. waitMs can extend an ordinary wait, but it cannot override a session-demoted scanner.`
|
|
1003
914
|
: undefined;
|
|
1004
915
|
let text;
|
|
1005
916
|
if (total === 0) {
|
|
@@ -1228,8 +1139,8 @@ async function collectBatchDiagnostics(files, severity, lspService, options) {
|
|
|
1228
1139
|
// `clean`/`unconfirmed` above already reflect ONLY the primary server's
|
|
1229
1140
|
// confirmation; this split does the same job for the listed diagnostics.
|
|
1230
1141
|
const primaryIdByFile = new Map(results.map((r) => [r.file, r.primaryServerId]));
|
|
1231
|
-
const primaryDisplay = display.filter((d) => d.
|
|
1232
|
-
const auxiliaryDisplay = display.filter((d) => d.
|
|
1142
|
+
const primaryDisplay = display.filter((d) => d.serverId === primaryIdByFile.get(d.file));
|
|
1143
|
+
const auxiliaryDisplay = display.filter((d) => d.serverId !== primaryIdByFile.get(d.file));
|
|
1233
1144
|
return {
|
|
1234
1145
|
results,
|
|
1235
1146
|
fileErrors,
|
|
@@ -1332,8 +1243,8 @@ async function runBatchFileDiagnostics(absPaths, severity, lspService, options)
|
|
|
1332
1243
|
file: result.file,
|
|
1333
1244
|
outcome: result.outcome,
|
|
1334
1245
|
reason: result.inconclusiveReason ?? result.error ?? result.unavailable,
|
|
1335
|
-
primaryDiagnosticsCount: result.diagnostics.filter((diagnostic) => diagnostic.
|
|
1336
|
-
auxiliaryDiagnosticsCount: result.diagnostics.filter((diagnostic) => diagnostic.
|
|
1246
|
+
primaryDiagnosticsCount: result.diagnostics.filter((diagnostic) => diagnostic.serverId === result.primaryServerId).length,
|
|
1247
|
+
auxiliaryDiagnosticsCount: result.diagnostics.filter((diagnostic) => diagnostic.serverId !== result.primaryServerId).length,
|
|
1337
1248
|
})),
|
|
1338
1249
|
outcomeCounts,
|
|
1339
1250
|
incompleteFiles: incompleteFiles > 0 ? incompleteFiles : undefined,
|
|
@@ -557,29 +557,8 @@ getFlag, mutationDeps) {
|
|
|
557
557
|
return {
|
|
558
558
|
name: "lsp_navigation",
|
|
559
559
|
label: "LSP Navigate",
|
|
560
|
-
description:
|
|
561
|
-
|
|
562
|
-
"- definition: Jump to where a symbol is defined\n" +
|
|
563
|
-
"- typeDefinition: Jump to the definition of a symbol's TYPE (e.g. the class/interface of a variable)\n" +
|
|
564
|
-
"- declaration: Jump to a symbol's declaration (e.g. an extern/forward decl, distinct from its definition)\n" +
|
|
565
|
-
"- references: Find all usages of a symbol\n" +
|
|
566
|
-
"- hover: Get type/doc info at a position\n" +
|
|
567
|
-
"- signatureHelp: Show callable signatures at cursor\n" +
|
|
568
|
-
"- documentSymbol: List all symbols (functions/classes/vars) in a file\n" +
|
|
569
|
-
"- findSymbol: Search document symbols in a file by name/detail with optional kind/top-level/exact filters\n" +
|
|
570
|
-
"- workspaceSymbol: Search symbols across the whole project (best with path context)\n" +
|
|
571
|
-
"- codeAction: Find available quick fixes/refactors at a range\n" +
|
|
572
|
-
"- rename: Compute or apply workspace edits for renaming a symbol\n" +
|
|
573
|
-
"- rename_file: Preview/apply LSP-aware source file rename notifications\n" +
|
|
574
|
-
"- implementation: Jump to interface implementations\n" +
|
|
575
|
-
"- prepareCallHierarchy: Get callable item at position (for incoming/outgoing)\n" +
|
|
576
|
-
"- incomingCalls: Find all functions/methods that CALL this function\n" +
|
|
577
|
-
"- outgoingCalls: Find all functions/methods CALLED by this function\n" +
|
|
578
|
-
"- executeCommand: Run a server-advertised command via workspace/executeCommand. HARDENED: allowlisted to commands the server advertised; dry-run by default (reports whether advertised) — set apply:true to actually run. Pass command (+ optional commandArguments).\n" +
|
|
579
|
-
"- workspaceDiagnostics: List all diagnostics tracked by active LSP clients\n" +
|
|
580
|
-
"- capabilities: Show cached operation support for active LSP servers\n\n" +
|
|
581
|
-
"Line and character are 1-based (as shown in editors). For position-based operations, prefer passing symbol when you know the line but not the exact character; character can be omitted or -1 and pi-lens will resolve the symbol column. Use symbol#N for repeated symbols on the same line (1-based occurrence).",
|
|
582
|
-
promptSnippet: "Find definitions, references, and hover info via LSP",
|
|
560
|
+
description: 'Navigate source with language-server operations such as definition, references, hover, and rename. Example: use `{operation: "references", path: "src/app.ts", line: 12}`.',
|
|
561
|
+
promptSnippet: "Navigate definitions and references with LSP",
|
|
583
562
|
renderResult: compactRenderResult(({ details, args, isError, text }) => {
|
|
584
563
|
const op = details?.operation ??
|
|
585
564
|
(typeof args.operation === "string" ? args.operation : "lsp");
|
|
@@ -594,56 +573,55 @@ getFlag, mutationDeps) {
|
|
|
594
573
|
}),
|
|
595
574
|
parameters: Type.Object({
|
|
596
575
|
operation: Type.String({
|
|
597
|
-
description: "LSP operation to perform. Valid values: "
|
|
598
|
-
VALID_OPERATIONS.join(", "),
|
|
576
|
+
description: "LSP operation to perform. Valid values: definition, typeDefinition, declaration, references, hover, signatureHelp, documentSymbol, findSymbol, workspaceSymbol, codeAction, rename, rename_file, implementation, prepareCallHierarchy, incomingCalls, outgoingCalls, executeCommand, workspaceDiagnostics, capabilities.",
|
|
599
577
|
}),
|
|
600
578
|
path: Type.Optional(Type.String({
|
|
601
|
-
description: "
|
|
579
|
+
description: "Target file path.",
|
|
602
580
|
})),
|
|
603
581
|
line: Type.Optional(Type.Number({
|
|
604
|
-
description: "
|
|
582
|
+
description: "1-based line number.",
|
|
605
583
|
})),
|
|
606
584
|
character: Type.Optional(Type.Number({
|
|
607
|
-
description: "
|
|
585
|
+
description: "1-based character offset.",
|
|
608
586
|
})),
|
|
609
587
|
symbol: Type.Optional(Type.String({
|
|
610
|
-
description: "Symbol
|
|
588
|
+
description: "Symbol for automatic character resolution.",
|
|
611
589
|
})),
|
|
612
590
|
endLine: Type.Optional(Type.Number({
|
|
613
|
-
description: "
|
|
591
|
+
description: "1-based range end line.",
|
|
614
592
|
})),
|
|
615
593
|
endCharacter: Type.Optional(Type.Number({
|
|
616
|
-
description: "
|
|
594
|
+
description: "1-based range end character.",
|
|
617
595
|
})),
|
|
618
596
|
newName: Type.Optional(Type.String({
|
|
619
|
-
description: "
|
|
597
|
+
description: "New symbol name.",
|
|
620
598
|
})),
|
|
621
599
|
newFilePath: Type.Optional(Type.String({
|
|
622
|
-
description: "
|
|
600
|
+
description: "New file path.",
|
|
623
601
|
})),
|
|
624
602
|
apply: Type.Optional(Type.Boolean({
|
|
625
|
-
description: "
|
|
603
|
+
description: "Apply a mutation instead of previewing it.",
|
|
626
604
|
})),
|
|
627
605
|
command: Type.Optional(Type.String({
|
|
628
|
-
description: "
|
|
606
|
+
description: "Server command identifier.",
|
|
629
607
|
})),
|
|
630
608
|
commandArguments: Type.Optional(Type.Array(Type.Unknown(), {
|
|
631
|
-
description: "
|
|
609
|
+
description: "Arguments for the server command.",
|
|
632
610
|
})),
|
|
633
611
|
query: Type.Optional(Type.String({
|
|
634
|
-
description: "Symbol
|
|
612
|
+
description: "Symbol search query.",
|
|
635
613
|
})),
|
|
636
614
|
kinds: Type.Optional(Type.Array(Type.String(), {
|
|
637
|
-
description: "
|
|
615
|
+
description: "Symbol-kind filters.",
|
|
638
616
|
})),
|
|
639
617
|
exactMatch: Type.Optional(Type.Boolean({
|
|
640
|
-
description: "
|
|
618
|
+
description: "Require an exact symbol match.",
|
|
641
619
|
})),
|
|
642
620
|
topLevelOnly: Type.Optional(Type.Boolean({
|
|
643
|
-
description: "
|
|
621
|
+
description: "Exclude nested symbols.",
|
|
644
622
|
})),
|
|
645
623
|
maxResults: Type.Optional(Type.Number({
|
|
646
|
-
description: "
|
|
624
|
+
description: "Maximum symbol matches.",
|
|
647
625
|
})),
|
|
648
626
|
callHierarchyItem: Type.Optional(Type.Object({
|
|
649
627
|
name: Type.String(),
|
|
@@ -669,9 +647,7 @@ getFlag, mutationDeps) {
|
|
|
669
647
|
character: Type.Number(),
|
|
670
648
|
}),
|
|
671
649
|
}),
|
|
672
|
-
}, {
|
|
673
|
-
description: "Call hierarchy item. Required for incomingCalls/outgoingCalls",
|
|
674
|
-
})),
|
|
650
|
+
}, {})),
|
|
675
651
|
}),
|
|
676
652
|
async execute(_toolCallId, params, _signal, _onUpdate, ctx) {
|
|
677
653
|
const startedAt = Date.now();
|
|
@@ -26,12 +26,8 @@ export function createModuleReportTool(getProjectRoot) {
|
|
|
26
26
|
return {
|
|
27
27
|
name: "module_report",
|
|
28
28
|
label: "Module Report",
|
|
29
|
-
description: "
|
|
30
|
-
|
|
31
|
-
'Pass `blastRadius: true` to also get the cross-file blast radius — the transitive dependents of this module aggregated to ranked file `read` args ("if you change this, verify these files"). Read-only over the cached graph; omitted on a cold cache. Supersedes the standalone impact query.\n' +
|
|
32
|
-
"Pass `callGraph: true` to include bounded derived callers/callees from the cached FunctionCallGraph; unavailable cache state is explicit and never reported as zero calls.\n" +
|
|
33
|
-
'`view: "compact"` returns a line-oriented text rendering (one line per symbol/callback, cheapest option) instead of JSON — same data, roughly a quarter of the token cost; use it for a quick skim. Default view returns JSON. An outline shows shape, not bodies — it does NOT count as having read a symbol\'s body for editing; use read_symbol for that.',
|
|
34
|
-
promptSnippet: "Navigable file outline — a cheap substitute for reading a whole file",
|
|
29
|
+
description: "Return a navigable source-module outline with symbols, references, and read handles. An outline shows shape, not bodies, and does not satisfy read-before-edit; `read_symbol` and `read_enclosing` return body text and record read coverage. On a cold cache, project_report and symbol_search return available: false with a retry hint and start a non-blocking background build; module_report degrades to outline-only with cache freshness explicit. Example: use module_report on `src/app.ts` before read_symbol.",
|
|
30
|
+
promptSnippet: "Outline a source module before reading a body",
|
|
35
31
|
renderResult: compactRenderResult(({ details, args, isError }) => {
|
|
36
32
|
const base = baseName(args.path) || "module";
|
|
37
33
|
if (isError || details?.available === false) {
|
|
@@ -48,7 +44,7 @@ export function createModuleReportTool(getProjectRoot) {
|
|
|
48
44
|
}),
|
|
49
45
|
parameters: Type.Object({
|
|
50
46
|
path: Type.String({
|
|
51
|
-
description: "
|
|
47
|
+
description: "Source file, e.g. `src/app.ts`.",
|
|
52
48
|
}),
|
|
53
49
|
maxRefsPerSymbol: Type.Optional(Type.Number({
|
|
54
50
|
description: "Cap on who-uses-this entries per symbol (default 10).",
|
|
@@ -157,7 +153,7 @@ export function createReadSymbolTool(getProjectRoot, recordSymbolRead) {
|
|
|
157
153
|
return {
|
|
158
154
|
name: "read_symbol",
|
|
159
155
|
label: "Read Symbol",
|
|
160
|
-
description: "Return
|
|
156
|
+
description: "Return one symbol's verbatim source. An outline shows shape, not bodies, and does not satisfy read-before-edit; `read_symbol` and `read_enclosing` return body text and record read coverage. Example: use read_symbol after module_report identifies `parseConfig`.",
|
|
161
157
|
promptSnippet: "Read one symbol's body instead of the whole file",
|
|
162
158
|
renderResult: compactRenderResult(({ details, args, isError, lineCount }) => {
|
|
163
159
|
const base = baseName(args.path);
|
|
@@ -259,7 +255,7 @@ export function createReadEnclosingTool(getProjectRoot, recordSymbolRead) {
|
|
|
259
255
|
return {
|
|
260
256
|
name: "read_enclosing",
|
|
261
257
|
label: "Read Enclosing",
|
|
262
|
-
description: "Return the
|
|
258
|
+
description: "Return the smallest symbol or callback enclosing a line. An outline shows shape, not bodies, and does not satisfy read-before-edit; `read_symbol` and `read_enclosing` return body text and record read coverage. Example: use read_enclosing after a diagnostic points to line 42.",
|
|
263
259
|
promptSnippet: "Read the enclosing symbol or callback body for a line",
|
|
264
260
|
renderResult: compactRenderResult(({ details, args, isError }) => {
|
|
265
261
|
const base = baseName(args.path);
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
*/
|
|
10
10
|
import { Type } from "../clients/deps/typebox.js";
|
|
11
11
|
import { projectReport, renderCompactProjectReport, } from "../clients/lens-engine.js";
|
|
12
|
-
import { compactRenderResult } from "./render-compact.js";
|
|
12
|
+
import { compactRenderResult, renderToolText, } from "./render-compact.js";
|
|
13
13
|
function errorMessage(err) {
|
|
14
14
|
return err instanceof Error ? err.message : String(err);
|
|
15
15
|
}
|
|
@@ -17,9 +17,8 @@ export function createProjectReportTool(getProjectRoot) {
|
|
|
17
17
|
return {
|
|
18
18
|
name: "project_report",
|
|
19
19
|
label: "Project Report",
|
|
20
|
-
description: "
|
|
21
|
-
|
|
22
|
-
promptSnippet: "Project-level orientation from the review graph",
|
|
20
|
+
description: "Orient in a project from its review graph, with ranked hubs and entry points. On a cold cache, project_report and symbol_search return available: false with a retry hint and start a non-blocking background build; module_report degrades to outline-only with cache freshness explicit. Example: use project_report before module_report when the target file is unknown.",
|
|
21
|
+
promptSnippet: "Orient in a project before choosing a file",
|
|
23
22
|
renderResult: compactRenderResult(({ details, isError }) => {
|
|
24
23
|
if (isError || details?.available === false) {
|
|
25
24
|
return `project_report — unavailable${details?.hint ? `: ${details.hint}` : ""}`;
|
|
@@ -28,7 +27,9 @@ export function createProjectReportTool(getProjectRoot) {
|
|
|
28
27
|
`${details?.hubs ?? 0} hub(s)`,
|
|
29
28
|
`${details?.entryPoints ?? 0} entry point(s)`,
|
|
30
29
|
];
|
|
31
|
-
const view = details?.view && details.view !== "default"
|
|
30
|
+
const view = details?.view && details.view !== "default"
|
|
31
|
+
? ` [${details.view}]`
|
|
32
|
+
: "";
|
|
32
33
|
return `project_report ${parts.join(" · ")}${view}`;
|
|
33
34
|
}),
|
|
34
35
|
parameters: Type.Object({
|
|
@@ -55,24 +56,14 @@ export function createProjectReportTool(getProjectRoot) {
|
|
|
55
56
|
}
|
|
56
57
|
catch (err) {
|
|
57
58
|
return {
|
|
58
|
-
|
|
59
|
-
{
|
|
60
|
-
type: "text",
|
|
61
|
-
text: `Project report failed: ${errorMessage(err)}`,
|
|
62
|
-
},
|
|
63
|
-
],
|
|
59
|
+
...renderToolText(`Project report failed: ${errorMessage(err)}`),
|
|
64
60
|
isError: true,
|
|
65
61
|
details: { available: false },
|
|
66
62
|
};
|
|
67
63
|
}
|
|
68
64
|
if (!report.available) {
|
|
69
65
|
return {
|
|
70
|
-
|
|
71
|
-
{
|
|
72
|
-
type: "text",
|
|
73
|
-
text: report.hint ?? "No review graph cached for this workspace yet.",
|
|
74
|
-
},
|
|
75
|
-
],
|
|
66
|
+
...renderToolText(report.hint ?? "No review graph cached for this workspace yet.", report),
|
|
76
67
|
isError: true,
|
|
77
68
|
details: { available: false, hint: report.hint },
|
|
78
69
|
};
|
|
@@ -82,6 +73,7 @@ export function createProjectReportTool(getProjectRoot) {
|
|
|
82
73
|
: JSON.stringify(report);
|
|
83
74
|
return {
|
|
84
75
|
content: [{ type: "text", text }],
|
|
76
|
+
isError: false,
|
|
85
77
|
details: {
|
|
86
78
|
available: true,
|
|
87
79
|
hubs: report.hubs?.length ?? 0,
|