pi-lens 4.1.6 → 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 (120) hide show
  1. package/CHANGELOG.md +239 -0
  2. package/config/dependency-cruiser-eager-allowlist.json +3 -0
  3. package/dist/clients/actionable-warnings.js +30 -4
  4. package/dist/clients/agent-behavior-client.js +2 -0
  5. package/dist/clients/bash-file-access.js +26 -0
  6. package/dist/clients/biome-client.js +1 -1
  7. package/dist/clients/blocker-freshness.js +403 -35
  8. package/dist/clients/bootstrap.js +6 -1
  9. package/dist/clients/cascade-format.js +200 -4
  10. package/dist/clients/code-quality-warnings.js +10 -2
  11. package/dist/clients/degradation-ledger.js +16 -1
  12. package/dist/clients/diagnostic-dispositions.js +12 -1
  13. package/dist/clients/dispatch/ast-grep-catalog.js +65 -0
  14. package/dist/clients/dispatch/auxiliary-lsp.js +28 -0
  15. package/dist/clients/dispatch/dispatcher.js +9 -2
  16. package/dist/clients/dispatch/finding-policy.js +222 -0
  17. package/dist/clients/dispatch/indent-detect.js +389 -13
  18. package/dist/clients/dispatch/integration.js +175 -25
  19. package/dist/clients/dispatch/rule-ignores.js +62 -0
  20. package/dist/clients/dispatch/runners/ast-grep-napi.js +21 -41
  21. package/dist/clients/dispatch/runners/biome-check.js +6 -1
  22. package/dist/clients/dispatch/runners/rust-clippy.js +7 -7
  23. package/dist/clients/dispatch/runners/shfmt.js +2 -12
  24. package/dist/clients/dispatch/runners/tree-sitter.js +2 -21
  25. package/dist/clients/dispatch/runners/utils/runner-helpers.js +1 -1
  26. package/dist/clients/dispatch/types.js +4 -1
  27. package/dist/clients/disposition-publish.js +1 -0
  28. package/dist/clients/effective-config.js +1 -1
  29. package/dist/clients/file-kinds.js +26 -1
  30. package/dist/clients/file-role.js +21 -21
  31. package/dist/clients/file-utils.js +156 -10
  32. package/dist/clients/finding-delivery-gate.js +56 -9
  33. package/dist/clients/format-service.js +39 -21
  34. package/dist/clients/formatters.js +60 -13
  35. package/dist/clients/generation-guard.js +2 -2
  36. package/dist/clients/git-guard.js +11 -3
  37. package/dist/clients/indent-retarget.js +78 -8
  38. package/dist/clients/installer/index.js +333 -114
  39. package/dist/clients/instance-reaper-state.js +7 -0
  40. package/dist/clients/instance-reaper.js +20 -10
  41. package/dist/clients/language-profile.js +23 -1
  42. package/dist/clients/language-registry.js +5 -1
  43. package/dist/clients/latency-logger.js +4 -1
  44. package/dist/clients/lens-engine.js +12 -3
  45. package/dist/clients/lens-events.js +2 -1
  46. package/dist/clients/lens-flag-registry.js +79 -0
  47. package/dist/clients/live-bus-emitter.js +2 -1
  48. package/dist/clients/lsp/client.js +25 -21
  49. package/dist/clients/lsp/config.js +2 -2
  50. package/dist/clients/lsp/index.js +7 -0
  51. package/dist/clients/lsp/launch.js +16 -4
  52. package/dist/clients/lsp/server.js +19 -2
  53. package/dist/clients/lsp/workspace-diagnostics-cache.js +2 -1
  54. package/dist/clients/lsp-mutation.js +5 -3
  55. package/dist/clients/map-with-concurrency.js +12 -8
  56. package/dist/clients/mcp/session.js +36 -4
  57. package/dist/clients/ndjson-logger.js +24 -7
  58. package/dist/clients/observed-mutation.js +40 -2
  59. package/dist/clients/opaque-mutation-scan.js +23 -3
  60. package/dist/clients/opengrep-client.js +110 -15
  61. package/dist/clients/path-utils.js +123 -3
  62. package/dist/clients/performance-report.js +5 -1
  63. package/dist/clients/php-cs-fixer-config.js +1 -1
  64. package/dist/clients/pipeline.js +74 -5
  65. package/dist/clients/project-diagnostics/cache.js +37 -5
  66. package/dist/clients/project-diagnostics/fresh-fetch.js +145 -18
  67. package/dist/clients/project-diagnostics/runner-adapters/dead-code.js +4 -1
  68. package/dist/clients/project-diagnostics/scanner.js +59 -3
  69. package/dist/clients/project-lens-config.js +45 -2
  70. package/dist/clients/read-guard.js +70 -11
  71. package/dist/clients/resource-sampler.js +147 -9
  72. package/dist/clients/ruff-client.js +1 -1
  73. package/dist/clients/runtime-agent-end.js +33 -5
  74. package/dist/clients/runtime-context.js +6 -2
  75. package/dist/clients/runtime-coordinator.js +77 -7
  76. package/dist/clients/runtime-session.js +21 -2
  77. package/dist/clients/runtime-tool-call.js +43 -12
  78. package/dist/clients/runtime-tool-result.js +330 -85
  79. package/dist/clients/runtime-turn.js +147 -17
  80. package/dist/clients/safe-spawn.js +258 -5
  81. package/dist/clients/scratch-tree-policy.js +6 -0
  82. package/dist/clients/session-event-guard.js +50 -5
  83. package/dist/clients/sg-runner.js +23 -11
  84. package/dist/clients/sgconfig.js +79 -2
  85. package/dist/clients/test-runner-client.js +6 -41
  86. package/dist/clients/test-runner-delivery.js +43 -0
  87. package/dist/clients/tool-agreement.js +423 -0
  88. package/dist/clients/tool-config.js +50 -0
  89. package/dist/clients/tool-cwd.js +47 -76
  90. package/dist/clients/tool-policy.js +163 -7
  91. package/dist/clients/tree-sitter-client.js +120 -0
  92. package/dist/clients/tree-sitter-query-loader.js +127 -189
  93. package/dist/clients/widget-state.js +98 -0
  94. package/dist/clients/word-index.js +5 -2
  95. package/dist/clients/write-ordering-guard.js +7 -0
  96. package/dist/index.js +27416 -24153
  97. package/dist/mcp/server.js +5 -2
  98. package/dist/tools/lens-diagnostic-mark.js +7 -1
  99. package/dist/tools/lens-diagnostics.js +168 -53
  100. package/dist/tools/lsp-diagnostics.js +244 -72
  101. package/docs/audit1.md +5 -5
  102. package/docs/dependencies.md +11 -0
  103. package/docs/dispositions.md +52 -0
  104. package/docs/environment-variables.md +2 -2
  105. package/docs/features.md +4 -4
  106. package/docs/globalconfig.md +3 -1
  107. package/docs/language-coverage.md +1 -0
  108. package/docs/pi-lens-fixer.md +53 -94
  109. package/docs/pi-lens-investigator.md +43 -38
  110. package/docs/pi-lens-retro.md +97 -0
  111. package/docs/pi-lens-reviewer.md +53 -66
  112. package/docs/release-qa-baseline.md +22 -0
  113. package/docs/settings.md +7 -4
  114. package/docs/tree-sitter_rules_catalog.md +1 -1
  115. package/docs/usage.md +2 -0
  116. package/package.json +1 -1
  117. package/rules/tree-sitter-queries/typescript/sql-injection.yml +24 -12
  118. package/scripts/analyze-pi-lens-logs.mjs +40 -0
  119. package/skills/pi-lens-ast-grep/SKILL.md +15 -0
  120. package/skills/pi-lens-lsp-navigation/SKILL.md +7 -0
@@ -1,15 +1,13 @@
1
1
  # SQL Injection Detection
2
2
  # Detects unsafe interpolation in SQL-like template literals.
3
- # Demoted from error/blocking to warning on 2026-09-10 (maintainer): the
4
- # query keys on the callee NAME only (query|execute|exec|run), so any
5
- # `run(`…${x}…`)` / `exec(`…`)` in non-SQL code fires — too many false
6
- # positives to block on. A real SQL sink needs a receiver/type signal.
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.
7
5
  id: sql-injection
8
6
  name: SQL Injection Risk
9
- severity: warning
7
+ severity: error
10
8
  category: security
11
9
  defect_class: injection
12
- inline_tier: warning
10
+ inline_tier: blocking
13
11
  language: typescript
14
12
 
15
13
  message: "SQL injection risk — use parameterized queries, never interpolate into SQL"
@@ -30,18 +28,32 @@ description: |
30
28
 
31
29
  query: |
32
30
  (call_expression
33
- function: [
34
- (identifier) @SQL_FUNC
35
- (member_expression property: (property_identifier) @SQL_FUNC)
36
- ]
31
+ function: (identifier) @SQL_FUNC
37
32
  arguments: (arguments
38
- (template_string (template_substitution) @INTERPOLATION))
39
- (#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)$"))
40
48
 
41
49
  metavars:
42
50
  - SQL_FUNC
51
+ - OBJ
52
+ - TEMPLATE
43
53
  - INTERPOLATION
44
54
 
55
+ post_filter: ts_sql_injection_sink
56
+
45
57
  has_fix: false
46
58
 
47
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) {
@@ -9,6 +9,21 @@ Use `ast_grep_search` and `ast_grep_replace` for semantic code search/replace. a
9
9
 
10
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
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: ... }`.
26
+
12
27
  ## When to Use
13
28
 
14
29
  - Function calls, imports, class methods (structured code)
@@ -7,6 +7,13 @@ description: Navigate code with IDE features and run proactive LSP diagnostics o
7
7
 
8
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
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.
16
+
10
17
  ## Diagnostics
11
18
 
12
19
  Use `lens_diagnostics` with `source=lsp` before builds/tests or after touching several files: