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.
- package/CHANGELOG.md +239 -0
- package/config/dependency-cruiser-eager-allowlist.json +3 -0
- package/dist/clients/actionable-warnings.js +30 -4
- package/dist/clients/agent-behavior-client.js +2 -0
- package/dist/clients/bash-file-access.js +26 -0
- package/dist/clients/biome-client.js +1 -1
- package/dist/clients/blocker-freshness.js +403 -35
- package/dist/clients/bootstrap.js +6 -1
- package/dist/clients/cascade-format.js +200 -4
- package/dist/clients/code-quality-warnings.js +10 -2
- package/dist/clients/degradation-ledger.js +16 -1
- package/dist/clients/diagnostic-dispositions.js +12 -1
- package/dist/clients/dispatch/ast-grep-catalog.js +65 -0
- package/dist/clients/dispatch/auxiliary-lsp.js +28 -0
- package/dist/clients/dispatch/dispatcher.js +9 -2
- package/dist/clients/dispatch/finding-policy.js +222 -0
- package/dist/clients/dispatch/indent-detect.js +389 -13
- package/dist/clients/dispatch/integration.js +175 -25
- package/dist/clients/dispatch/rule-ignores.js +62 -0
- package/dist/clients/dispatch/runners/ast-grep-napi.js +21 -41
- package/dist/clients/dispatch/runners/biome-check.js +6 -1
- package/dist/clients/dispatch/runners/rust-clippy.js +7 -7
- package/dist/clients/dispatch/runners/shfmt.js +2 -12
- package/dist/clients/dispatch/runners/tree-sitter.js +2 -21
- package/dist/clients/dispatch/runners/utils/runner-helpers.js +1 -1
- package/dist/clients/dispatch/types.js +4 -1
- package/dist/clients/disposition-publish.js +1 -0
- package/dist/clients/effective-config.js +1 -1
- package/dist/clients/file-kinds.js +26 -1
- package/dist/clients/file-role.js +21 -21
- package/dist/clients/file-utils.js +156 -10
- package/dist/clients/finding-delivery-gate.js +56 -9
- package/dist/clients/format-service.js +39 -21
- package/dist/clients/formatters.js +60 -13
- package/dist/clients/generation-guard.js +2 -2
- package/dist/clients/git-guard.js +11 -3
- package/dist/clients/indent-retarget.js +78 -8
- package/dist/clients/installer/index.js +333 -114
- package/dist/clients/instance-reaper-state.js +7 -0
- package/dist/clients/instance-reaper.js +20 -10
- package/dist/clients/language-profile.js +23 -1
- package/dist/clients/language-registry.js +5 -1
- package/dist/clients/latency-logger.js +4 -1
- package/dist/clients/lens-engine.js +12 -3
- package/dist/clients/lens-events.js +2 -1
- package/dist/clients/lens-flag-registry.js +79 -0
- package/dist/clients/live-bus-emitter.js +2 -1
- package/dist/clients/lsp/client.js +25 -21
- package/dist/clients/lsp/config.js +2 -2
- package/dist/clients/lsp/index.js +7 -0
- package/dist/clients/lsp/launch.js +16 -4
- package/dist/clients/lsp/server.js +19 -2
- package/dist/clients/lsp/workspace-diagnostics-cache.js +2 -1
- package/dist/clients/lsp-mutation.js +5 -3
- package/dist/clients/map-with-concurrency.js +12 -8
- package/dist/clients/mcp/session.js +36 -4
- package/dist/clients/ndjson-logger.js +24 -7
- package/dist/clients/observed-mutation.js +40 -2
- package/dist/clients/opaque-mutation-scan.js +23 -3
- package/dist/clients/opengrep-client.js +110 -15
- package/dist/clients/path-utils.js +123 -3
- package/dist/clients/performance-report.js +5 -1
- package/dist/clients/php-cs-fixer-config.js +1 -1
- package/dist/clients/pipeline.js +74 -5
- package/dist/clients/project-diagnostics/cache.js +37 -5
- package/dist/clients/project-diagnostics/fresh-fetch.js +145 -18
- package/dist/clients/project-diagnostics/runner-adapters/dead-code.js +4 -1
- package/dist/clients/project-diagnostics/scanner.js +59 -3
- package/dist/clients/project-lens-config.js +45 -2
- package/dist/clients/read-guard.js +70 -11
- package/dist/clients/resource-sampler.js +147 -9
- package/dist/clients/ruff-client.js +1 -1
- package/dist/clients/runtime-agent-end.js +33 -5
- package/dist/clients/runtime-context.js +6 -2
- package/dist/clients/runtime-coordinator.js +77 -7
- package/dist/clients/runtime-session.js +21 -2
- package/dist/clients/runtime-tool-call.js +43 -12
- package/dist/clients/runtime-tool-result.js +330 -85
- package/dist/clients/runtime-turn.js +147 -17
- package/dist/clients/safe-spawn.js +258 -5
- package/dist/clients/scratch-tree-policy.js +6 -0
- package/dist/clients/session-event-guard.js +50 -5
- package/dist/clients/sg-runner.js +23 -11
- package/dist/clients/sgconfig.js +79 -2
- package/dist/clients/test-runner-client.js +6 -41
- package/dist/clients/test-runner-delivery.js +43 -0
- package/dist/clients/tool-agreement.js +423 -0
- package/dist/clients/tool-config.js +50 -0
- package/dist/clients/tool-cwd.js +47 -76
- package/dist/clients/tool-policy.js +163 -7
- package/dist/clients/tree-sitter-client.js +120 -0
- package/dist/clients/tree-sitter-query-loader.js +127 -189
- package/dist/clients/widget-state.js +98 -0
- package/dist/clients/word-index.js +5 -2
- package/dist/clients/write-ordering-guard.js +7 -0
- package/dist/index.js +27416 -24153
- package/dist/mcp/server.js +5 -2
- package/dist/tools/lens-diagnostic-mark.js +7 -1
- package/dist/tools/lens-diagnostics.js +168 -53
- package/dist/tools/lsp-diagnostics.js +244 -72
- package/docs/audit1.md +5 -5
- package/docs/dependencies.md +11 -0
- package/docs/dispositions.md +52 -0
- package/docs/environment-variables.md +2 -2
- package/docs/features.md +4 -4
- package/docs/globalconfig.md +3 -1
- package/docs/language-coverage.md +1 -0
- package/docs/pi-lens-fixer.md +53 -94
- package/docs/pi-lens-investigator.md +43 -38
- package/docs/pi-lens-retro.md +97 -0
- package/docs/pi-lens-reviewer.md +53 -66
- package/docs/release-qa-baseline.md +22 -0
- package/docs/settings.md +7 -4
- package/docs/tree-sitter_rules_catalog.md +1 -1
- package/docs/usage.md +2 -0
- package/package.json +1 -1
- package/rules/tree-sitter-queries/typescript/sql-injection.yml +24 -12
- package/scripts/analyze-pi-lens-logs.mjs +40 -0
- package/skills/pi-lens-ast-grep/SKILL.md +15 -0
- 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
|
-
#
|
|
4
|
-
#
|
|
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:
|
|
7
|
+
severity: error
|
|
10
8
|
category: security
|
|
11
9
|
defect_class: injection
|
|
12
|
-
inline_tier:
|
|
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:
|