pi-lens 4.1.5 → 4.2.0

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.
Files changed (219) hide show
  1. package/CHANGELOG.md +415 -0
  2. package/README.md +13 -8
  3. package/config/dependency-cruiser-eager-allowlist.json +6 -1
  4. package/dist/clients/actionable-warnings.js +30 -4
  5. package/dist/clients/agent-behavior-client.js +2 -0
  6. package/dist/clients/analysed-root.js +1 -0
  7. package/dist/clients/ast-grep-tool-logger.js +1 -1
  8. package/dist/clients/bash-file-access.js +26 -0
  9. package/dist/clients/biome-client.js +13 -2
  10. package/dist/clients/blocker-freshness.js +403 -35
  11. package/dist/clients/bootstrap.js +6 -1
  12. package/dist/clients/bounded-telemetry.js +2 -0
  13. package/dist/clients/cache-observability.js +122 -1
  14. package/dist/clients/cascade-format.js +200 -4
  15. package/dist/clients/code-quality-warnings.js +10 -2
  16. package/dist/clients/complexity-client.js +5 -0
  17. package/dist/clients/config-diagnostic-codes.js +2 -0
  18. package/dist/clients/config-resolve.js +6 -3
  19. package/dist/clients/config-schema.js +17 -0
  20. package/dist/clients/config-warn.js +2 -2
  21. package/dist/clients/dead-code-client.js +8 -1
  22. package/dist/clients/degradation-ledger.js +16 -1
  23. package/dist/clients/dependency-checker.js +5 -1
  24. package/dist/clients/diagnostic-dispositions.js +12 -1
  25. package/dist/clients/dispatch/ast-grep-catalog.js +65 -0
  26. package/dist/clients/dispatch/auxiliary-lsp.js +28 -0
  27. package/dist/clients/dispatch/dispatcher.js +47 -17
  28. package/dist/clients/dispatch/facts/function-facts.js +1 -1
  29. package/dist/clients/dispatch/facts/import-facts.js +5 -1
  30. package/dist/clients/dispatch/finding-policy.js +222 -0
  31. package/dist/clients/dispatch/indent-detect.js +389 -13
  32. package/dist/clients/dispatch/integration.js +175 -25
  33. package/dist/clients/dispatch/rule-ignores.js +62 -0
  34. package/dist/clients/dispatch/runners/actionlint.js +2 -1
  35. package/dist/clients/dispatch/runners/ast-grep-napi.js +21 -41
  36. package/dist/clients/dispatch/runners/biome-check.js +8 -4
  37. package/dist/clients/dispatch/runners/cpp-check.js +4 -3
  38. package/dist/clients/dispatch/runners/credo.js +2 -1
  39. package/dist/clients/dispatch/runners/cue-vet.js +2 -1
  40. package/dist/clients/dispatch/runners/dart-analyze.js +2 -1
  41. package/dist/clients/dispatch/runners/detekt.js +2 -1
  42. package/dist/clients/dispatch/runners/dotnet-build.js +2 -1
  43. package/dist/clients/dispatch/runners/elixir-check.js +2 -1
  44. package/dist/clients/dispatch/runners/eslint.js +2 -1
  45. package/dist/clients/dispatch/runners/fish-indent.js +2 -1
  46. package/dist/clients/dispatch/runners/gleam-check.js +2 -1
  47. package/dist/clients/dispatch/runners/go-vet.js +2 -1
  48. package/dist/clients/dispatch/runners/golangci-lint.js +2 -1
  49. package/dist/clients/dispatch/runners/hadolint.js +2 -1
  50. package/dist/clients/dispatch/runners/helm-lint.js +3 -1
  51. package/dist/clients/dispatch/runners/helm-render.js +2 -1
  52. package/dist/clients/dispatch/runners/htmlhint.js +2 -1
  53. package/dist/clients/dispatch/runners/javac.js +2 -1
  54. package/dist/clients/dispatch/runners/ktlint.js +2 -1
  55. package/dist/clients/dispatch/runners/lsp.js +19 -1
  56. package/dist/clients/dispatch/runners/markdownlint.js +3 -2
  57. package/dist/clients/dispatch/runners/mypy.js +2 -1
  58. package/dist/clients/dispatch/runners/oxlint.js +2 -1
  59. package/dist/clients/dispatch/runners/php-lint.js +2 -1
  60. package/dist/clients/dispatch/runners/phpstan.js +2 -1
  61. package/dist/clients/dispatch/runners/prisma-validate.js +2 -1
  62. package/dist/clients/dispatch/runners/psscriptanalyzer.js +12 -12
  63. package/dist/clients/dispatch/runners/pyright.js +2 -1
  64. package/dist/clients/dispatch/runners/rubocop.js +2 -1
  65. package/dist/clients/dispatch/runners/ruff.js +2 -2
  66. package/dist/clients/dispatch/runners/rust-clippy.js +12 -11
  67. package/dist/clients/dispatch/runners/shellcheck.js +2 -1
  68. package/dist/clients/dispatch/runners/shfmt.js +4 -13
  69. package/dist/clients/dispatch/runners/spellcheck.js +2 -2
  70. package/dist/clients/dispatch/runners/spotbugs.js +2 -1
  71. package/dist/clients/dispatch/runners/sqlfluff.js +3 -2
  72. package/dist/clients/dispatch/runners/stylelint.js +3 -2
  73. package/dist/clients/dispatch/runners/swiftlint.js +2 -1
  74. package/dist/clients/dispatch/runners/taplo.js +2 -1
  75. package/dist/clients/dispatch/runners/terragrunt.js +2 -1
  76. package/dist/clients/dispatch/runners/tflint.js +2 -1
  77. package/dist/clients/dispatch/runners/tree-sitter.js +2 -21
  78. package/dist/clients/dispatch/runners/trivy-config.js +2 -1
  79. package/dist/clients/dispatch/runners/utils/availability-policy.js +5 -0
  80. package/dist/clients/dispatch/runners/utils/candidate-probe.js +2 -2
  81. package/dist/clients/dispatch/runners/utils/runner-helpers.js +8 -2
  82. package/dist/clients/dispatch/runners/vale.js +2 -1
  83. package/dist/clients/dispatch/runners/yamllint.js +4 -3
  84. package/dist/clients/dispatch/runners/zig-check.js +2 -1
  85. package/dist/clients/dispatch/types.js +4 -1
  86. package/dist/clients/disposition-publish.js +1 -0
  87. package/dist/clients/effective-config.js +12 -2
  88. package/dist/clients/extension-log.js +2 -0
  89. package/dist/clients/file-kinds.js +26 -1
  90. package/dist/clients/file-role.js +23 -6
  91. package/dist/clients/file-utils.js +156 -10
  92. package/dist/clients/finding-delivery-gate.js +60 -9
  93. package/dist/clients/format-service.js +39 -21
  94. package/dist/clients/formatters.js +113 -200
  95. package/dist/clients/generation-guard.js +6 -2
  96. package/dist/clients/git-guard.js +11 -3
  97. package/dist/clients/gitleaks-client.js +42 -6
  98. package/dist/clients/govulncheck-client.js +48 -7
  99. package/dist/clients/indent-retarget.js +78 -8
  100. package/dist/clients/installer/index.js +524 -161
  101. package/dist/clients/instance-reaper-state.js +7 -0
  102. package/dist/clients/instance-reaper.js +20 -10
  103. package/dist/clients/jscpd-client.js +9 -1
  104. package/dist/clients/knip-client.js +9 -2
  105. package/dist/clients/language-profile.js +35 -3
  106. package/dist/clients/language-registry.js +5 -1
  107. package/dist/clients/latency-logger.js +6 -1
  108. package/dist/clients/lens-config.js +4 -0
  109. package/dist/clients/lens-engine.js +12 -3
  110. package/dist/clients/lens-events.js +2 -1
  111. package/dist/clients/lens-flag-registry.js +79 -0
  112. package/dist/clients/live-bus-emitter.js +2 -1
  113. package/dist/clients/lsp/client.js +25 -21
  114. package/dist/clients/lsp/config.js +36 -7
  115. package/dist/clients/lsp/diagnostic-binding.js +24 -1
  116. package/dist/clients/lsp/document-drift.js +78 -0
  117. package/dist/clients/lsp/index.js +288 -45
  118. package/dist/clients/lsp/launch.js +16 -4
  119. package/dist/clients/lsp/server.js +79 -15
  120. package/dist/clients/lsp/workspace-diagnostics-cache.js +39 -5
  121. package/dist/clients/lsp-mutation.js +5 -3
  122. package/dist/clients/map-with-concurrency.js +12 -8
  123. package/dist/clients/mcp/analyze.js +3 -0
  124. package/dist/clients/mcp/session.js +38 -4
  125. package/dist/clients/ndjson-logger.js +24 -7
  126. package/dist/clients/observed-mutation.js +40 -2
  127. package/dist/clients/opaque-mutation-scan.js +23 -3
  128. package/dist/clients/opengrep-client.js +111 -14
  129. package/dist/clients/package-manager.js +2 -1
  130. package/dist/clients/path-utils.js +123 -3
  131. package/dist/clients/performance-report.js +5 -1
  132. package/dist/clients/php-cs-fixer-config.js +8 -3
  133. package/dist/clients/pipeline.js +77 -7
  134. package/dist/clients/project-diagnostics/cache.js +37 -5
  135. package/dist/clients/project-diagnostics/fresh-fetch.js +173 -18
  136. package/dist/clients/project-diagnostics/runner-adapters/dead-code.js +4 -1
  137. package/dist/clients/project-diagnostics/runner-adapters/gitleaks.js +10 -9
  138. package/dist/clients/project-diagnostics/scanner.js +59 -3
  139. package/dist/clients/project-lens-config.js +48 -2
  140. package/dist/clients/read-guard-logger.js +2 -0
  141. package/dist/clients/read-guard.js +70 -11
  142. package/dist/clients/resource-sampler.js +147 -9
  143. package/dist/clients/review-graph-logger.js +2 -0
  144. package/dist/clients/ruff-client.js +18 -9
  145. package/dist/clients/runtime-agent-end.js +42 -5
  146. package/dist/clients/runtime-context.js +6 -2
  147. package/dist/clients/runtime-coordinator.js +82 -7
  148. package/dist/clients/runtime-session.js +33 -5
  149. package/dist/clients/runtime-tool-call.js +43 -12
  150. package/dist/clients/runtime-tool-result.js +334 -86
  151. package/dist/clients/runtime-turn.js +195 -18
  152. package/dist/clients/safe-spawn.js +258 -5
  153. package/dist/clients/scratch-tree-policy.js +6 -0
  154. package/dist/clients/security-scan-client.js +2 -2
  155. package/dist/clients/session-event-guard.js +119 -6
  156. package/dist/clients/sg-runner.js +25 -12
  157. package/dist/clients/sgconfig.js +79 -2
  158. package/dist/clients/situational-tool-telemetry.js +108 -0
  159. package/dist/clients/test-runner-client.js +258 -78
  160. package/dist/clients/test-runner-delivery.js +43 -0
  161. package/dist/clients/tool-agreement.js +423 -0
  162. package/dist/clients/tool-config.js +249 -0
  163. package/dist/clients/tool-cwd.js +270 -0
  164. package/dist/clients/tool-policy.js +163 -7
  165. package/dist/clients/tool-probe.js +53 -0
  166. package/dist/clients/tool-set-policy.js +42 -0
  167. package/dist/clients/tree-sitter-client.js +120 -0
  168. package/dist/clients/tree-sitter-query-loader.js +127 -189
  169. package/dist/clients/trivy-client.js +9 -1
  170. package/dist/clients/turn-context.js +52 -0
  171. package/dist/clients/widget-state.js +102 -3
  172. package/dist/clients/word-index.js +5 -2
  173. package/dist/clients/write-ordering-guard.js +7 -0
  174. package/dist/index.js +26968 -21741
  175. package/dist/mcp/analyze-cli.js +3 -2
  176. package/dist/mcp/server.js +140 -161
  177. package/dist/tools/activate-tools.js +10 -7
  178. package/dist/tools/ast-grep-outline.js +2 -13
  179. package/dist/tools/ast-grep-replace.js +8 -13
  180. package/dist/tools/ast-grep-search.js +83 -39
  181. package/dist/tools/effective-config.js +4 -3
  182. package/dist/tools/lens-diagnostic-mark.js +8 -11
  183. package/dist/tools/lens-diagnostics.js +516 -133
  184. package/dist/tools/lsp-diagnostics.js +265 -182
  185. package/dist/tools/lsp-navigation.js +20 -44
  186. package/dist/tools/module-report.js +5 -9
  187. package/dist/tools/project-report.js +9 -17
  188. package/dist/tools/render-compact.js +280 -1
  189. package/dist/tools/symbol-search.js +2 -2
  190. package/docs/agent-guide.md +3 -4
  191. package/docs/agent-tools.md +46 -22
  192. package/docs/audit1.md +5 -5
  193. package/docs/configuration.md +9 -0
  194. package/docs/dependencies.md +11 -0
  195. package/docs/dispositions.md +52 -0
  196. package/docs/environment-variables.md +2 -7
  197. package/docs/features.md +7 -7
  198. package/docs/globalconfig.md +14 -2
  199. package/docs/language-coverage.md +1 -0
  200. package/docs/mcp.md +13 -1
  201. package/docs/pi-lens-fixer.md +48 -18
  202. package/docs/pi-lens-investigator.md +38 -18
  203. package/docs/pi-lens-monitor.md +88 -0
  204. package/docs/pi-lens-retro.md +97 -0
  205. package/docs/pi-lens-reviewer.md +53 -31
  206. package/docs/pi-lens-subagent.md +12 -4
  207. package/docs/public-api-stability.md +1 -0
  208. package/docs/real-harness.md +46 -0
  209. package/docs/release-qa-baseline.md +27 -1
  210. package/docs/servercapabilities.md +1 -6
  211. package/docs/settings.md +44 -6
  212. package/docs/tools_improvement2.md +4 -4
  213. package/docs/usage.md +15 -3
  214. package/package.json +10 -1
  215. package/rules/tree-sitter-queries/typescript/sql-injection.yml +23 -7
  216. package/scripts/analyze-pi-lens-logs.mjs +40 -0
  217. package/skills/pi-lens-ast-grep/SKILL.md +23 -6
  218. package/skills/pi-lens-lsp-navigation/SKILL.md +26 -9
  219. package/dist/tools/ast-dump.js +0 -103
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pi-lens",
3
- "version": "4.1.5",
3
+ "version": "4.2.0",
4
4
  "type": "module",
5
5
  "description": "Real-time code feedback for pi — LSP, linters, formatters, type-checking, structural analysis & booboo",
6
6
  "repository": {
@@ -33,10 +33,13 @@
33
33
  "test:integration": "node scripts/with-test-lock.mjs -- vitest run tests/index-integration.test.ts tests/clients/lsp/integration.test.ts",
34
34
  "test:targeted": "node scripts/with-test-lock.mjs --shared -- vitest run",
35
35
  "test:watch": "vitest",
36
+ "test:real-harness": "node scripts/with-test-lock.mjs --shared -- vitest run",
37
+ "mutation:diff": "node scripts/stryker-diff.mjs --base origin/master --max-files 6",
36
38
  "hygiene": "node scripts/prune-agent-worktrees.mjs",
37
39
  "check": "node scripts/check-extensions.mjs",
38
40
  "selftest:install": "node scripts/install-selftest.mjs",
39
41
  "check:lockfile": "node scripts/check-lockfile-sync.mjs",
42
+ "preflight": "node scripts/pr-preflight.mjs",
40
43
  "knip": "node scripts/run-knip.mjs",
41
44
  "check:grammars": "node scripts/check-grammar-provenance.mjs",
42
45
  "check:grammar-load": "node scripts/check-grammar-load.mjs",
@@ -49,7 +52,9 @@
49
52
  "bench:cascade-budget": "node scripts/bench-cascade-budget.mjs",
50
53
  "bench:word-index-replacement": "node scripts/bench-word-index-replacement.mjs",
51
54
  "logs:smells": "node scripts/analyze-pi-lens-logs.mjs",
55
+ "complexity": "node scripts/complexity-report.mjs",
52
56
  "changelog:check": "node scripts/rollup-changelog.mjs --check",
57
+ "test:regen": "node scripts/regen-test-baseline.mjs",
53
58
  "changelog:release": "node scripts/changelog-release.mjs",
54
59
  "changelog:extract": "node scripts/changelog-extract.mjs",
55
60
  "release:backfill-notes": "node scripts/backfill-github-releases.mjs",
@@ -83,6 +88,7 @@
83
88
  "engines": {
84
89
  "node": ">=22.19.0"
85
90
  },
91
+ "packageManager": "npm@11.18.0",
86
92
  "files": [
87
93
  "dist/",
88
94
  "docs/",
@@ -145,5 +151,8 @@
145
151
  "@ast-grep/cli@0.45.3": true,
146
152
  "@google/genai@1.52.0": true,
147
153
  "protobufjs@7.6.5": true
154
+ },
155
+ "overrides": {
156
+ "qs": "^6.15.4"
148
157
  }
149
158
  }
@@ -1,5 +1,7 @@
1
1
  # SQL Injection Detection
2
- # Detects unsafe interpolation in SQL-like template literals
2
+ # Detects unsafe interpolation in SQL-like template literals.
3
+ # The structural query keeps the common callee set, while the TypeScript-aware
4
+ # post-filter requires a receiver bound to a known DB client or a SQL-leading template.
3
5
  id: sql-injection
4
6
  name: SQL Injection Risk
5
7
  severity: error
@@ -26,18 +28,32 @@ description: |
26
28
 
27
29
  query: |
28
30
  (call_expression
29
- function: [
30
- (identifier) @SQL_FUNC
31
- (member_expression property: (property_identifier) @SQL_FUNC)
32
- ]
31
+ function: (identifier) @SQL_FUNC
33
32
  arguments: (arguments
34
- (template_string (template_substitution) @INTERPOLATION))
35
- (#match? @SQL_FUNC "^(query|execute|exec|run)$"))
33
+ (template_string (template_substitution) @INTERPOLATION) @TEMPLATE)
34
+ (#match? @SQL_FUNC "^(query|execute|exec|run|\\$queryRaw|\\$executeRaw|\\$queryRawUnsafe|\\$executeRawUnsafe|raw|prepare)$"))
35
+ (call_expression
36
+ function: (member_expression
37
+ object: (_) @OBJ
38
+ property: (property_identifier) @SQL_FUNC)
39
+ arguments: (arguments
40
+ (template_string (template_substitution) @INTERPOLATION) @TEMPLATE)
41
+ (#match? @SQL_FUNC "^(query|execute|exec|run|\\$queryRaw|\\$executeRaw|\\$queryRawUnsafe|\\$executeRawUnsafe|raw|prepare)$"))
42
+ (call_expression
43
+ function: (member_expression
44
+ object: (_) @OBJ
45
+ property: (property_identifier) @SQL_FUNC)
46
+ arguments: (template_string (template_substitution) @INTERPOLATION) @TEMPLATE
47
+ (#match? @SQL_FUNC "^(query|execute|exec|run|\\$queryRaw|\\$executeRaw|\\$queryRawUnsafe|\\$executeRawUnsafe|raw|prepare)$"))
36
48
 
37
49
  metavars:
38
50
  - SQL_FUNC
51
+ - OBJ
52
+ - TEMPLATE
39
53
  - INTERPOLATION
40
54
 
55
+ post_filter: ts_sql_injection_sink
56
+
41
57
  has_fix: false
42
58
 
43
59
  tags:
@@ -195,6 +195,7 @@ function createState(files) {
195
195
  projects: counter(),
196
196
  smellTotals: counter(),
197
197
  latency: {
198
+ testRunnerVerdicts: new Map(),
198
199
  runnerStatus: counter(),
199
200
  runnerFailureKinds: counter(),
200
201
  runnerBlockingFindings: counter(),
@@ -381,6 +382,22 @@ async function analyzeLatency(files, state) {
381
382
  const phase = entry.phase ?? "unknown";
382
383
  state.latency.phaseCounts.inc(phase);
383
384
  if (phase.endsWith("_timeout")) state.latency.phaseTimeouts.inc(phase);
385
+ if (phase === "test_runner_verdict_delivery") {
386
+ const sessionId = entry.metadata?.sessionId ?? "unknown";
387
+ const summary = state.latency.testRunnerVerdicts.get(sessionId) ?? {
388
+ total: 0,
389
+ stale: 0,
390
+ unknown: 0,
391
+ };
392
+ const verdictCount = entry.metadata?.verdictCount;
393
+ const staleCount = entry.metadata?.staleCount;
394
+ const unknownCount = entry.metadata?.unknownCount;
395
+ summary.total += typeof verdictCount === "number" ? verdictCount : 1;
396
+ if (typeof staleCount === "number") summary.stale += staleCount;
397
+ else if (entry.metadata?.stale === true) summary.stale += 1;
398
+ if (typeof unknownCount === "number") summary.unknown += unknownCount;
399
+ state.latency.testRunnerVerdicts.set(sessionId, summary);
400
+ }
384
401
  if (phase === "config_resolved") {
385
402
  // #2526. Counted here rather than derived from phaseCounts so the
386
403
  // legacy/record cross-check reads the same row it counts.
@@ -1481,6 +1498,18 @@ function buildReport(state) {
1481
1498
  shownInlineShownAgentUnresolved: state.diagnostics.shownInline.toJSON(),
1482
1499
  },
1483
1500
  latency: {
1501
+ testRunnerVerdicts: Object.fromEntries(
1502
+ [...state.latency.testRunnerVerdicts.entries()].map(
1503
+ ([sessionId, summary]) => [
1504
+ sessionId,
1505
+ {
1506
+ ...summary,
1507
+ denominator: summary.total,
1508
+ rate: summary.total ? summary.stale / summary.total : 0,
1509
+ },
1510
+ ],
1511
+ ),
1512
+ ),
1484
1513
  runnerStatus: state.latency.runnerStatus.top(limit * 2),
1485
1514
  runnerFailureKinds: state.latency.runnerFailureKinds.top(limit * 2),
1486
1515
  runnerBlockingFindings: state.latency.runnerBlockingFindings.toJSON(),
@@ -1672,6 +1701,17 @@ function printReport(report) {
1672
1701
  report.latency.runnerFailureKinds,
1673
1702
  (x) => `${x.count.toString().padStart(5)} ${x.key}`,
1674
1703
  );
1704
+ const verdictSessions = Object.entries(
1705
+ report.latency.testRunnerVerdicts ?? {},
1706
+ );
1707
+ if (verdictSessions.length) {
1708
+ console.log("\nTest-runner stale verdicts per session");
1709
+ for (const [sessionId, summary] of verdictSessions) {
1710
+ console.log(
1711
+ ` ${sessionId}: ${summary.stale}/${summary.total} stale (${(summary.rate * 100).toFixed(1)}%)`,
1712
+ );
1713
+ }
1714
+ }
1675
1715
 
1676
1716
  const a = report.actionable;
1677
1717
  if (a.reports || a.advisoriesInjected) {
@@ -7,7 +7,22 @@ description: Use when searching or replacing code patterns - use ast-grep instea
7
7
 
8
8
  Use `ast_grep_search` and `ast_grep_replace` for semantic code search/replace. ast-grep understands code structure, not just text.
9
9
 
10
- These tools (plus `ast_grep_outline`, `ast_grep_dump`, `lsp_navigation`) are registered but inactive by default on hosts that support pi's dynamic tooling. If a call to one of them isn't recognized, activate it first: `pi_lens_activate_tools tools=["ast_grep_search", "ast_grep_replace"]`.
10
+ These tools (plus `ast_grep_outline`, `lsp_navigation`) are registered but inactive by default on hosts that support pi's dynamic tooling. If a call to one of them isn't recognized, activate it first: `pi_lens_activate_tools tools=["ast_grep_search", "ast_grep_replace"]`.
11
+
12
+ On hosts that aggregate pi-lens behind a single `lens` tool, the `ast_grep_*` tools and `pi_lens_activate_tools` may not be registered at all. There, fall back to the `ast-grep` CLI (alias `sg`) — patterns, metavariables, and YAML rules are identical:
13
+
14
+ ```bash
15
+ # search (≈ ast_grep_search)
16
+ ast-grep run -p 'fetchMetrics($$$ARGS)' -l ts src/
17
+
18
+ # rewrite (≈ ast_grep_replace; -U applies all)
19
+ ast-grep run -p 'var $X' -r 'let $X' -l js src/ -U
20
+
21
+ # full YAML rule (≈ the rule: parameter)
22
+ ast-grep scan --rule my-rule.yml src/
23
+ ```
24
+
25
+ Structural-intent parameters map to YAML constraints: `insideKind` → `inside: { kind: ..., stopBy: end }`, `hasKind`/`hasDescendantKind` → `has: { kind: ... }`, `follows` → `follows: { pattern: ... }`, `precedes` → `precedes: { pattern: ... }`.
11
26
 
12
27
  ## When to Use
13
28
 
@@ -88,15 +103,15 @@ rule:
88
103
  stopBy: end" lang="typescript"
89
104
  ```
90
105
 
91
- ### Debugging unknown node kinds — `ast_grep_dump`
106
+ ### Debugging unknown node kinds — `ast_grep_search` dump mode
92
107
 
93
- When a pattern returns zero matches and you don't know the correct node kind or field name, use `ast_grep_dump` to inspect a SMALL representative snippet:
108
+ When a pattern returns zero matches and you don't know the correct node kind or field name, use `ast_grep_search` with `dump=true` to inspect a SMALL representative snippet:
94
109
 
95
110
  ```
96
- ast_grep_dump source="function foo() { return 1; }" lang="typescript"
111
+ ast_grep_search dump=true pattern="function foo() { return 1; }" lang="typescript"
97
112
  ```
98
113
 
99
- Returns the full indented AST with node kinds and positions. Then use the correct kind in your pattern or `insideKind`. `ast_grep_dump` is registered but inactive by default — call `pi_lens_activate_tools` with `tools: ["ast_grep_dump"]` first if it isn't already active.
114
+ Returns the full indented AST with node kinds and positions. Then use the correct kind in your pattern or `insideKind`.
100
115
 
101
116
  ### Composite (has/inside) in raw YAML
102
117
 
@@ -146,8 +161,10 @@ kind: arrow_function
146
161
 
147
162
  **No matches?**
148
163
 
164
+ For `nodeKind`, do not also pass `pattern` or `rule`; those forms are mutually exclusive. For `rule`, provide YAML containing both `id` and `language` fields. Use `strictness: relaxed` when unnamed punctuation is the only mismatch.
165
+
149
166
  1. Try `strictness: relaxed` — ignores unnamed punctuation (trailing commas, semicolons) that `smart` mode requires
150
- 2. Use `ast_grep_dump` on a sample snippet to verify the correct node kind
167
+ 2. Use `ast_grep_search dump=true` on a sample snippet to verify the correct node kind
151
168
  3. Simplify the pattern and retry once
152
169
  4. Fall back to `grep` or `lsp_navigation`
153
170
 
@@ -5,22 +5,35 @@ description: Navigate code with IDE features and run proactive LSP diagnostics o
5
5
 
6
6
  # LSP Navigation and Diagnostics
7
7
 
8
- Use `lsp_navigation` as **PRIMARY** for code intelligence. Use `lsp_diagnostics` as **PRIMARY** for proactive type/error checks. Do NOT use grep/glob/ast-grep first for code intelligence.
8
+ Use `lsp_navigation` as **PRIMARY** for code intelligence. Use `lens_diagnostics` with `source=lsp` as **PRIMARY** for proactive type/error checks. Do NOT use grep/glob/ast-grep first for code intelligence.
9
+
10
+ ## Aggregate-tool hosts
11
+
12
+ Some hosts expose pi-lens through a single aggregate tool — `lens(action=...)` — instead of registering the standalone names below. On those hosts:
13
+
14
+ - Proactive checks: `lens({ action: "lsp_diagnostics", ... })` — same parameters as the table below; the cached-report entry point maps to `lens({ action: "diagnostics", ... })`.
15
+ - If `lsp_navigation` is not among the aggregate's actions, do not call the standalone name: use the host's structural search funnel (`symbol_search` → `module_report` → `read_symbol`) or the `ast-grep` CLI for navigation instead.
9
16
 
10
17
  ## Diagnostics
11
18
 
12
- Use `lsp_diagnostics` before builds/tests or after touching several files:
19
+ Use `lens_diagnostics` with `source=lsp` before builds/tests or after touching several files:
13
20
 
14
21
  | Need | Tool call |
15
22
  |---|---|
16
- | Check one file | `lsp_diagnostics({ path: "src/file.ts" })` |
17
- | Check a folder | `lsp_diagnostics({ path: "src/", severity: "error" })` |
18
- | Check exact touched files | `lsp_diagnostics({ paths: ["src/a.ts", "src/b.ts"], concurrency: 8 })` |
19
- | Slow server (Rust, Java) | `lsp_diagnostics({ paths: files, waitMs: 2000 })` |
20
- | Include warnings | `lsp_diagnostics({ paths: files, severity: "all" })` |
23
+ | Check one file | `lens_diagnostics({ source: "lsp", scope: "paths", paths: ["src/file.ts"] })` |
24
+ | Check a folder | `lens_diagnostics({ source: "lsp", scope: "workspace", path: "src/", severity: "error" })` |
25
+ | Check exact touched files | `lens_diagnostics({ source: "lsp", scope: "paths", paths: ["src/a.ts", "src/b.ts"] })` |
26
+ | Slow server (Rust, Java) | `lens_diagnostics({ source: "lsp", scope: "paths", paths: files, waitMs: 2000 })` |
27
+ | Include warnings | `lens_diagnostics({ source: "lsp", scope: "paths", paths: files, severity: "all" })` |
21
28
 
22
29
  Prefer explicit `paths` batches after multi-file edits — bounded concurrency, no unrelated directory noise.
23
30
 
31
+ ### Parameter reference
32
+
33
+ `lens_diagnostics` accepts `source: "session" | "lsp"` and `scope: "paths" | "workspace"`. Use `mode: "delta"` for the current turn, `"all"` for the cache-only session view, or `"full"` for an active scan. `path` selects one file or directory; `paths` filters a batch. `severity` is `"error"`, `"warning"`, or `"all"`; `serverScope` is `"primary"` or `"all"`.
34
+
35
+ For `mode: "full"`, `refreshRunners: "cached" | "cheap" | "all" | "none"` (or `false`/`true`) controls project analyzers. The first three string modes can launch a fresh heavyweight analyzer pass, bounded by the slowest runner's roughly 180-second ceiling; `none` disables it. `maxProjectFiles` limits cheap project runners, `maxLspFiles` limits the LSP sweep, and `includeGenerated: true` includes generated-name paths. These three limits apply to full scans. `concurrency` and `waitMs` tune LSP batches.
36
+
24
37
  ## Navigation (Code Intelligence)
25
38
 
26
39
  | Question | Operation | Parameters |
@@ -41,6 +54,10 @@ Prefer explicit `paths` batches after multi-file edits — bounded concurrency,
41
54
  | What commands does the server offer? | `capabilities` | (optional path) — lists advertised commands |
42
55
  | Run a server command (e.g. organize imports) | `executeCommand` | command (+ commandArguments); dry-run unless `apply:true` |
43
56
 
57
+ The `operation` values are `definition`, `typeDefinition`, `declaration`, `references`, `hover`, `signatureHelp`, `documentSymbol`, `findSymbol`, `workspaceSymbol`, `codeAction`, `rename`, `rename_file`, `implementation`, `prepareCallHierarchy`, `incomingCalls`, `outgoingCalls`, `executeCommand`, `workspaceDiagnostics`, and `capabilities`.
58
+
59
+ For `findSymbol`, pass `query`; optionally narrow with `kinds`, `exactMatch`, `topLevelOnly`, and `maxResults`. `rename_file` uses `newFilePath`. `symbol` resolves a character automatically; `character: -1` requests automatic resolution, and `symbol#N` selects a numbered symbol when the result lists one. `callHierarchyItem` is the object returned by `prepareCallHierarchy` and is required by the incoming/outgoing follow-up calls.
60
+
44
61
  ## Call Hierarchy Pattern
45
62
 
46
63
  ```
@@ -59,7 +76,7 @@ lsp_navigation(operation="outgoingCalls", callHierarchyItem=<item from step 1>)
59
76
  - **`workspaceSymbol` empty?** Always pass `path`. Unscoped queries are best-effort and frequently return nothing. If TypeScript returns "No Project", open the scoped file first.
60
77
  - **`references`** — query from the *definition site* for full cross-file coverage; usage-site queries can be partial.
61
78
  - **`signatureHelp`** — only valid at call-site argument positions; declaration positions return empty.
62
- - **`workspaceDiagnostics`** — tracked push snapshot only, not an active check. Use `lsp_diagnostics` when you need fresh results.
79
+ - **`workspaceDiagnostics`** — tracked push snapshot only, not an active check. Use `lens_diagnostics` with `source=lsp` when you need fresh results.
63
80
  - **`codeAction`** — distinguish `quickfix` from generic refactors ("Move to new file"). Generic refactors are not error fixes.
64
81
  - **`prepareCallHierarchy`** — server-capability dependent; if unsupported, skip incoming/outgoing calls.
65
82
 
@@ -74,4 +91,4 @@ lsp_navigation(operation="outgoingCalls", callHierarchyItem=<item from step 1>)
74
91
 
75
92
  ## Golden Rule
76
93
 
77
- **Code intelligence → `lsp_navigation` first. Type/error validation → `lsp_diagnostics` first. Text/pattern search → grep/ast-grep.**
94
+ **Code intelligence → `lsp_navigation` first. Type/error validation → `lens_diagnostics source=lsp` first. Text/pattern search → grep/ast-grep.**
@@ -1,103 +0,0 @@
1
- import { Type } from "../clients/deps/typebox.js";
2
- import { compactRenderResult } from "./render-compact.js";
3
- import { LANGUAGES } from "./shared.js";
4
- function createAstDumpToolWithName(astGrepClient, name) {
5
- return {
6
- name,
7
- label: "AST-Grep Dump",
8
- description: "Dump the tree-sitter AST for a source snippet using ast-grep CLI. Use when ast_grep_search returns zero matches and you need exact node kinds, field names, or nesting. Named nodes only by default; includeAnonymous=true shows punctuation/CST nodes too.",
9
- promptSnippet: "Inspect AST node kinds before writing ast-grep patterns",
10
- renderResult: compactRenderResult(({ details, args, isError, lineCount, text }) => {
11
- const lang = details?.lang ?? (typeof args.lang === "string" ? args.lang : "");
12
- if (isError) {
13
- return `${name} ${lang} — ${text.split("\n")[0] ?? "error"}`.trim();
14
- }
15
- return `${name} ${lang} — ${lineCount} AST nodes`.replace(/\s+/g, " ");
16
- }),
17
- parameters: Type.Object({
18
- source: Type.String({
19
- description: "Source code snippet to parse and dump",
20
- }),
21
- lang: Type.String({
22
- enum: [...LANGUAGES],
23
- description: "Target language",
24
- }),
25
- includeAnonymous: Type.Optional(Type.Boolean({
26
- description: "Show anonymous punctuation/CST nodes too (default false)",
27
- })),
28
- }),
29
- async execute(_toolCallId, params, _signal, _onUpdate) {
30
- const source = typeof params.source === "string" ? params.source : "";
31
- const lang = typeof params.lang === "string"
32
- ? params.lang.replace(/^"|"$/g, "")
33
- : "";
34
- const includeAnonymous = params.includeAnonymous === true;
35
- try {
36
- if (!source.trim()) {
37
- return {
38
- content: [{ type: "text", text: "source is required" }],
39
- isError: true,
40
- details: { lang, includeAnonymous },
41
- };
42
- }
43
- if (_signal.aborted) {
44
- return {
45
- content: [
46
- { type: "text", text: "Error: operation aborted" },
47
- ],
48
- isError: true,
49
- details: { lang, includeAnonymous },
50
- };
51
- }
52
- if (!(await astGrepClient.ensureAvailable())) {
53
- return {
54
- content: [
55
- {
56
- type: "text",
57
- text: "ast-grep CLI not found. Install: npm i -D @ast-grep/cli",
58
- },
59
- ],
60
- isError: true,
61
- details: { lang, includeAnonymous },
62
- };
63
- }
64
- if (_signal.aborted) {
65
- return {
66
- content: [
67
- { type: "text", text: "Error: operation aborted" },
68
- ],
69
- isError: true,
70
- details: { lang, includeAnonymous },
71
- };
72
- }
73
- const result = await astGrepClient.dumpAst(source, lang, {
74
- includeAnonymous,
75
- });
76
- if (result.error) {
77
- return {
78
- content: [
79
- { type: "text", text: `Error: ${result.error}` },
80
- ],
81
- isError: true,
82
- details: { lang, includeAnonymous },
83
- };
84
- }
85
- return {
86
- content: [{ type: "text", text: result.output ?? "" }],
87
- details: { lang, includeAnonymous },
88
- };
89
- }
90
- catch (err) {
91
- const message = err instanceof Error ? err.message : String(err);
92
- return {
93
- content: [{ type: "text", text: `Error: ${message}` }],
94
- isError: true,
95
- details: { lang, includeAnonymous },
96
- };
97
- }
98
- },
99
- };
100
- }
101
- export function createAstGrepDumpTool(astGrepClient) {
102
- return createAstDumpToolWithName(astGrepClient, "ast_grep_dump");
103
- }