@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
|
@@ -32,17 +32,8 @@ export function createAstGrepReplaceTool(astGrepClient) {
|
|
|
32
32
|
return {
|
|
33
33
|
name: "ast_grep_replace",
|
|
34
34
|
label: "AST Replace",
|
|
35
|
-
description:
|
|
36
|
-
|
|
37
|
-
" - pattern='console.log($MSG)' rewrite='logger.info($MSG)'\n" +
|
|
38
|
-
" - pattern='var $X' rewrite='let $X'\n" +
|
|
39
|
-
" - pattern='function $NAME() { }' rewrite='' (delete)\n\n" +
|
|
40
|
-
"❌ BAD patterns (will error):\n" +
|
|
41
|
-
" - Raw text without code structure\n" +
|
|
42
|
-
' - Missing parentheses: use it($TEST) not it"text"\n' +
|
|
43
|
-
" - Incomplete code fragments\n\n" +
|
|
44
|
-
"Always use 'paths' to scope to specific files/folders. Dry-run first to preview changes.",
|
|
45
|
-
promptSnippet: "AST-aware structural find-and-replace",
|
|
35
|
+
description: 'Find and rewrite code by AST structure; preview by default. Example: `{pattern: "var $X", rewrite: "let $X", apply: false}`.',
|
|
36
|
+
promptSnippet: "Preview an AST-aware code rewrite",
|
|
46
37
|
renderResult: compactRenderResult(({ details, isError, text }) => {
|
|
47
38
|
if (details?.stalePreview) {
|
|
48
39
|
return `ast_grep_replace — stale preview, re-run with apply:false`;
|
|
@@ -93,6 +84,9 @@ export function createAstGrepReplaceTool(astGrepClient) {
|
|
|
93
84
|
const lang = (params.lang ?? "").replace(/^"|"$/g, "");
|
|
94
85
|
const pathsCount = paths?.length ?? 1;
|
|
95
86
|
const applyFlag = apply ?? false;
|
|
87
|
+
// MCP passes Infinity so the shared result seam receives the complete
|
|
88
|
+
// tool rendering. Pi keeps the historical 50-item content contract.
|
|
89
|
+
const resultMaxItems = ctx.resultMaxItems ?? 50;
|
|
96
90
|
function logOutcome(outcome, details = {}) {
|
|
97
91
|
try {
|
|
98
92
|
logAstGrepToolEvent({
|
|
@@ -193,7 +187,7 @@ export function createAstGrepReplaceTool(astGrepClient) {
|
|
|
193
187
|
details: {},
|
|
194
188
|
};
|
|
195
189
|
}
|
|
196
|
-
const output = astGrepClient.formatMatches(ruleResult.matches, !applyFlag, true);
|
|
190
|
+
const output = astGrepClient.formatMatches(ruleResult.matches, !applyFlag, true, resultMaxItems);
|
|
197
191
|
logOutcome(ruleResult.matches.length === 0 ? "no_matches" : "success", {
|
|
198
192
|
matchCount: ruleResult.matches.length,
|
|
199
193
|
});
|
|
@@ -230,7 +224,8 @@ export function createAstGrepReplaceTool(astGrepClient) {
|
|
|
230
224
|
};
|
|
231
225
|
}
|
|
232
226
|
const isDryRun = !applyFlag;
|
|
233
|
-
const output = astGrepClient.formatMatches(result.matches, isDryRun, true
|
|
227
|
+
const output = astGrepClient.formatMatches(result.matches, isDryRun, true, // showModeIndicator
|
|
228
|
+
resultMaxItems);
|
|
234
229
|
logOutcome(result.matches.length === 0 ? "no_matches" : "success", {
|
|
235
230
|
matchCount: result.matches.length,
|
|
236
231
|
truncated: result.truncated,
|
|
@@ -140,9 +140,10 @@ function toMatchLocations(matches, contextLines) {
|
|
|
140
140
|
}
|
|
141
141
|
function suggestedDump(lang) {
|
|
142
142
|
return {
|
|
143
|
-
tool: "
|
|
143
|
+
tool: "ast_grep_search",
|
|
144
|
+
mode: "dump",
|
|
144
145
|
lang,
|
|
145
|
-
note: "Run
|
|
146
|
+
note: "Run ast_grep_search with dump=true on a small representative source snippet (not a whole file) to inspect AST node kinds before retrying the search.",
|
|
146
147
|
};
|
|
147
148
|
}
|
|
148
149
|
function lineCount(value) {
|
|
@@ -221,28 +222,37 @@ function getPatternHint(pattern, lang, selector) {
|
|
|
221
222
|
return 'Hint: Rust fn patterns need params and body. Try "fn $NAME($$$) { $$$ }"';
|
|
222
223
|
}
|
|
223
224
|
}
|
|
224
|
-
return "Hint: No matches. Retry once with a smaller valid AST pattern scoped to the same paths (for example a call like `foo($$$ARGS)`, an import statement, or `function $NAME($$$ARGS) { $$$BODY }`). If you're actually looking for a name/usage rather than a structural pattern, prefer symbol_search (ranked identifier search) or module_report (file outline) over another AST retry; lsp_navigation findReferences finds exact call sites once you have a definition. If that also fails, use grep for text search, or
|
|
225
|
+
return "Hint: No matches. Retry once with a smaller valid AST pattern scoped to the same paths (for example a call like `foo($$$ARGS)`, an import statement, or `function $NAME($$$ARGS) { $$$BODY }`). If you're actually looking for a name/usage rather than a structural pattern, prefer symbol_search (ranked identifier search) or module_report (file outline) over another AST retry; lsp_navigation findReferences finds exact call sites once you have a definition. If that also fails, use grep for text search, or ast_grep_search with dump=true on a small representative snippet to inspect node kinds.";
|
|
226
|
+
}
|
|
227
|
+
/** One-session response for callers holding a pre-fold tool name. */
|
|
228
|
+
export function astGrepDumpCompatibilityResult(params, surface) {
|
|
229
|
+
return {
|
|
230
|
+
content: [
|
|
231
|
+
{
|
|
232
|
+
type: "text",
|
|
233
|
+
text: `The ast_grep_dump tool was retired. Call ${surface === "mcp" ? "pilens_" : ""}ast_grep_search with dump=true and put the snippet in pattern instead.`,
|
|
234
|
+
},
|
|
235
|
+
],
|
|
236
|
+
isError: true,
|
|
237
|
+
details: {
|
|
238
|
+
compatibility: "ast_grep_dump -> ast_grep_search",
|
|
239
|
+
call: {
|
|
240
|
+
tool: surface === "mcp" ? "pilens_ast_grep_search" : "ast_grep_search",
|
|
241
|
+
arguments: {
|
|
242
|
+
dump: true,
|
|
243
|
+
pattern: params.source,
|
|
244
|
+
lang: params.lang,
|
|
245
|
+
},
|
|
246
|
+
},
|
|
247
|
+
},
|
|
248
|
+
};
|
|
225
249
|
}
|
|
226
250
|
export function createAstGrepSearchTool(astGrepClient) {
|
|
227
251
|
return {
|
|
228
252
|
name: "ast_grep_search",
|
|
229
253
|
label: "AST Search",
|
|
230
|
-
description: "Search
|
|
231
|
-
|
|
232
|
-
" - function $NAME($$$ARGS) { $$$BODY } (function declaration)\n" +
|
|
233
|
-
" - fetchMetrics($$$ARGS) (call with any arguments)\n" +
|
|
234
|
-
' - import { $$$NAMES } from "module-name" (exact string-literal import)\n' +
|
|
235
|
-
" - console.log($MSG) (method call)\n\n" +
|
|
236
|
-
"❌ BAD patterns (multiple nodes / raw text):\n" +
|
|
237
|
-
' - it"test name" (missing parens - use it($TEST))\n' +
|
|
238
|
-
" - console.log without args (incomplete code)\n" +
|
|
239
|
-
" - arbitrary text without code structure\n\n" +
|
|
240
|
-
'Metavariables match AST nodes, not text inside quoted string literals: `from "$PATH"` matches the literal text $PATH. Use an exact quoted string for a known import, or grep for wildcard text. ' +
|
|
241
|
-
"Use 'paths' to scope to specific files/folders. " +
|
|
242
|
-
"Use 'nodeKind' to find every node of a known AST kind, or 'ast_grep_dump' first when the kind is unknown. " +
|
|
243
|
-
"Avoid 'selector' unless you know the exact AST node kind; it narrows matching and does not extract fields. " +
|
|
244
|
-
'If this tool is inactive, call pi_lens_activate_tools with tools=["ast_grep_search"]; activation takes effect next turn. If zero matches, retry once with a simpler AST pattern, then use ast_grep_dump on a small representative snippet before falling back to grep.',
|
|
245
|
-
promptSnippet: "AST-aware structural code search",
|
|
254
|
+
description: "Search source by AST structure rather than text. Example: find calls with `console.log($MSG)`.",
|
|
255
|
+
promptSnippet: "Search source by AST structure",
|
|
246
256
|
renderResult: compactRenderResult(({ details, isError, text }) => {
|
|
247
257
|
if (details?.validateOnly) {
|
|
248
258
|
const mode = details.mode ?? "pattern";
|
|
@@ -260,59 +270,58 @@ export function createAstGrepSearchTool(astGrepClient) {
|
|
|
260
270
|
return `ast_grep_search — ${count}${ofTotal} match${count === 1 && !ofTotal ? "" : "es"}${applied}`;
|
|
261
271
|
}),
|
|
262
272
|
parameters: Type.Object({
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
})),
|
|
273
|
+
dump: Type.Optional(Type.Boolean()),
|
|
274
|
+
pattern: Type.Optional(Type.String({ description: "AST pattern." })),
|
|
266
275
|
lang: Type.String({
|
|
267
276
|
enum: [...LANGUAGES],
|
|
268
277
|
description: "Target language",
|
|
269
278
|
}),
|
|
270
279
|
paths: Type.Optional(Type.Array(Type.String(), {
|
|
271
280
|
maxItems: MAX_PATHS,
|
|
272
|
-
description:
|
|
281
|
+
description: "Files or directories to search.",
|
|
273
282
|
})),
|
|
274
283
|
selector: Type.Optional(Type.String({
|
|
275
|
-
description: "
|
|
284
|
+
description: "AST node kind filter.",
|
|
276
285
|
})),
|
|
277
286
|
context: Type.Optional(Type.Number({
|
|
278
|
-
description: "
|
|
287
|
+
description: "Context lines around matches.",
|
|
279
288
|
})),
|
|
280
289
|
nodeKind: Type.Optional(Type.String({
|
|
281
|
-
description: "
|
|
290
|
+
description: "AST node kind without a pattern.",
|
|
282
291
|
})),
|
|
283
292
|
insideKind: Type.Optional(Type.String({
|
|
284
|
-
description:
|
|
293
|
+
description: "Ancestor AST node kind filter.",
|
|
285
294
|
})),
|
|
286
295
|
hasKind: Type.Optional(Type.String({
|
|
287
|
-
description:
|
|
296
|
+
description: "Immediate-child AST node kind filter.",
|
|
288
297
|
})),
|
|
289
298
|
hasDescendantKind: Type.Optional(Type.String({
|
|
290
|
-
description: "
|
|
299
|
+
description: "Recursive descendant AST node kind filter.",
|
|
291
300
|
})),
|
|
292
301
|
follows: Type.Optional(Type.String({
|
|
293
|
-
description:
|
|
302
|
+
description: "Preceding sibling pattern filter.",
|
|
294
303
|
})),
|
|
295
304
|
precedes: Type.Optional(Type.String({
|
|
296
|
-
description: "
|
|
305
|
+
description: "Following sibling pattern filter.",
|
|
297
306
|
})),
|
|
298
307
|
rule: Type.Optional(Type.String({
|
|
299
|
-
description: "Raw ast-grep YAML rule.
|
|
308
|
+
description: "Raw ast-grep YAML rule.",
|
|
300
309
|
})),
|
|
301
310
|
skip: Type.Optional(Type.Number({
|
|
302
|
-
description: "
|
|
311
|
+
description: "Matches to skip for pagination.",
|
|
303
312
|
})),
|
|
304
313
|
maxMatches: Type.Optional(Type.Number({
|
|
305
|
-
description:
|
|
314
|
+
description: "Maximum matches to return.",
|
|
306
315
|
})),
|
|
307
316
|
groupByFile: Type.Optional(Type.Boolean({
|
|
308
|
-
description: "
|
|
317
|
+
description: "Group matches by file.",
|
|
309
318
|
})),
|
|
310
319
|
strictness: Type.Optional(Type.String({
|
|
311
320
|
enum: ["smart", "relaxed", "ast", "cst", "signature", "template"],
|
|
312
|
-
description: "Pattern matching strictness.
|
|
321
|
+
description: "Pattern matching strictness.",
|
|
313
322
|
})),
|
|
314
323
|
validateOnly: Type.Optional(Type.Boolean({
|
|
315
|
-
description: "Validate
|
|
324
|
+
description: "Validate without scanning.",
|
|
316
325
|
})),
|
|
317
326
|
}),
|
|
318
327
|
async execute(_toolCallId, params, _signal, _onUpdate, ctx) {
|
|
@@ -321,7 +330,7 @@ export function createAstGrepSearchTool(astGrepClient) {
|
|
|
321
330
|
const abortSignal = combineAbortSignals(_signal, ctx.signal);
|
|
322
331
|
const startedAt = Date.now();
|
|
323
332
|
const deadlineAt = startedAt + AST_GREP_SEARCH_TIMEOUT_MS;
|
|
324
|
-
const { paths, nodeKind, selector, context, skip, maxMatches, groupByFile, strictness, rule, insideKind, hasKind, hasDescendantKind, follows, precedes, validateOnly, } = params;
|
|
333
|
+
const { paths, nodeKind, selector, context, skip, maxMatches, groupByFile, strictness, rule, insideKind, hasKind, hasDescendantKind, follows, precedes, validateOnly, dump, } = params;
|
|
325
334
|
const pattern = typeof params.pattern === "string" ? params.pattern : "";
|
|
326
335
|
const rawLang = typeof params.lang === "string" ? params.lang : "";
|
|
327
336
|
const normalizedNodeKind = typeof nodeKind === "string" ? nodeKind.trim() : "";
|
|
@@ -329,6 +338,7 @@ export function createAstGrepSearchTool(astGrepClient) {
|
|
|
329
338
|
const lang = rawLang.replace(/^"|"$/g, "");
|
|
330
339
|
const searchPathsCount = paths?.length ?? 1;
|
|
331
340
|
const executionOptions = { signal: abortSignal, deadlineAt };
|
|
341
|
+
const dumpMode = dump === true;
|
|
332
342
|
function logOutcome(outcome, details = {}) {
|
|
333
343
|
try {
|
|
334
344
|
const errorRaw = _telemetryErrorForTest(details.errorRaw);
|
|
@@ -401,7 +411,7 @@ export function createAstGrepSearchTool(astGrepClient) {
|
|
|
401
411
|
details: {},
|
|
402
412
|
};
|
|
403
413
|
}
|
|
404
|
-
if (!hasPattern && !hasRawRule && !hasNodeKind) {
|
|
414
|
+
if (!dumpMode && !hasPattern && !hasRawRule && !hasNodeKind) {
|
|
405
415
|
logOutcome("error", {
|
|
406
416
|
errorRaw: "pattern is required unless rule or nodeKind is provided",
|
|
407
417
|
});
|
|
@@ -456,6 +466,40 @@ export function createAstGrepSearchTool(astGrepClient) {
|
|
|
456
466
|
}
|
|
457
467
|
if (abortSignal?.aborted)
|
|
458
468
|
return abortError();
|
|
469
|
+
if (dumpMode) {
|
|
470
|
+
if (!pattern.trim()) {
|
|
471
|
+
const errorRaw = "source is required when dump is true";
|
|
472
|
+
logOutcome("error", { errorRaw });
|
|
473
|
+
return {
|
|
474
|
+
content: [{ type: "text", text: `Error: ${errorRaw}` }],
|
|
475
|
+
isError: true,
|
|
476
|
+
details: { mode: "dump", lang },
|
|
477
|
+
};
|
|
478
|
+
}
|
|
479
|
+
const result = await astGrepClient.dumpAst(pattern, lang);
|
|
480
|
+
if (result.error) {
|
|
481
|
+
logOutcome("error", { errorRaw: result.error });
|
|
482
|
+
return {
|
|
483
|
+
content: [
|
|
484
|
+
{ type: "text", text: `Error: ${result.error}` },
|
|
485
|
+
],
|
|
486
|
+
isError: true,
|
|
487
|
+
details: { mode: "dump", lang },
|
|
488
|
+
};
|
|
489
|
+
}
|
|
490
|
+
const output = result.output ?? "";
|
|
491
|
+
logOutcome("success", { matchCount: lineCount(output) });
|
|
492
|
+
return {
|
|
493
|
+
content: [{ type: "text", text: output }],
|
|
494
|
+
details: {
|
|
495
|
+
mode: "dump",
|
|
496
|
+
lang,
|
|
497
|
+
matchCount: lineCount(output),
|
|
498
|
+
totalMatches: lineCount(output),
|
|
499
|
+
truncated: false,
|
|
500
|
+
},
|
|
501
|
+
};
|
|
502
|
+
}
|
|
459
503
|
if (!hasRawRule &&
|
|
460
504
|
hasPattern &&
|
|
461
505
|
looksLikeRuleYamlOrPlainText(pattern)) {
|
|
@@ -33,12 +33,12 @@ function summarize(view) {
|
|
|
33
33
|
`${selected} server(s) selected${deniedClause} · ` +
|
|
34
34
|
`${tools} tool(s)`);
|
|
35
35
|
}
|
|
36
|
-
export function createEffectiveConfigTool(getProjectRoot) {
|
|
36
|
+
export function createEffectiveConfigTool(getProjectRoot, getNoTools) {
|
|
37
37
|
return {
|
|
38
38
|
name: "effective_config",
|
|
39
39
|
label: "Effective Config",
|
|
40
|
-
description: "
|
|
41
|
-
promptSnippet: "
|
|
40
|
+
description: "Explain resolved configuration and provenance. Response is redacted by construction: it contains no environment values, no command arguments beyond the binary, and home-relative paths; a tier-denied LSP decision cannot be lifted by a nearer config. Example: pass `file` to see why its LSP server is selected.",
|
|
41
|
+
promptSnippet: "Explain resolved configuration",
|
|
42
42
|
renderResult: compactRenderResult(({ details, isError }) => isError
|
|
43
43
|
? "effective_config — failed"
|
|
44
44
|
: (details?.summary ?? "effective_config")),
|
|
@@ -57,6 +57,7 @@ export function createEffectiveConfigTool(getProjectRoot) {
|
|
|
57
57
|
cwd,
|
|
58
58
|
...(params.file === undefined ? {} : { file: params.file }),
|
|
59
59
|
redact: true,
|
|
60
|
+
noTools: getNoTools?.(),
|
|
60
61
|
});
|
|
61
62
|
const summary = summarize(view);
|
|
62
63
|
return {
|
|
@@ -178,16 +178,7 @@ getIdentity) {
|
|
|
178
178
|
return {
|
|
179
179
|
name: "lens_diagnostic_mark",
|
|
180
180
|
label: "Mark Diagnostic",
|
|
181
|
-
description: "Record a disposition for a
|
|
182
|
-
"it was reported with. false-positive/suppress persist across sessions; defer lasts only for the " +
|
|
183
|
-
"current session (resurfaces next time); flagged marks it for you to come back and fix, and shows " +
|
|
184
|
-
"up tagged in a later lens_diagnostics mode=full. suppress additionally writes a `pi-lens-ignore: " +
|
|
185
|
-
"<rule>` comment into the source above the flagged line — rule is required for suppress. " +
|
|
186
|
-
"The line is verified/reanchored against current diagnostics before writing (#802): if a live " +
|
|
187
|
-
"diagnostic for this tool/rule/message is now at a different line, that line is used instead of " +
|
|
188
|
-
"the one you passed. When suppressing several findings in the SAME file in one turn, work " +
|
|
189
|
-
"bottom-up (highest line number first) — each inserted comment shifts later lines down by one, " +
|
|
190
|
-
"and reanchoring can't always disambiguate two nearby findings.",
|
|
181
|
+
description: "Record a disposition for a diagnostic. Exact reported identity is required; suppress re-anchors against live diagnostics and writes an inline ignore comment, apply multiple suppressions bottom-up, and defer is session-only. Example: mark a false positive with its reported file, line, rule, and message.",
|
|
191
182
|
promptSnippet: "Use lens_diagnostic_mark to dismiss a false-positive, suppress a won't-fix, defer, or flag a finding to fix later",
|
|
192
183
|
parameters: Type.Object({
|
|
193
184
|
filePath: Type.String({
|