pi-lens 3.0.0 → 3.1.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 +93 -0
- package/README.md +13 -10
- package/clients/bus/integration.js +6 -6
- package/clients/bus/integration.ts +36 -23
- package/clients/complexity-client.js +9 -6
- package/clients/complexity-client.ts +9 -6
- package/clients/dispatch/plan.js +2 -3
- package/clients/dispatch/plan.ts +2 -3
- package/clients/dispatch/runners/ast-grep-napi.js +158 -59
- package/clients/dispatch/runners/ast-grep-napi.ts +244 -97
- package/clients/dispatch/runners/ast-grep.js +5 -7
- package/clients/dispatch/runners/ast-grep.ts +13 -12
- package/clients/dispatch/runners/biome.js +3 -3
- package/clients/dispatch/runners/biome.ts +3 -3
- package/clients/dispatch/runners/index.js +5 -3
- package/clients/dispatch/runners/index.ts +5 -3
- package/clients/dispatch/runners/oxlint.js +41 -115
- package/clients/dispatch/runners/oxlint.ts +53 -134
- package/clients/dispatch/runners/pyright.js +2 -2
- package/clients/dispatch/runners/pyright.ts +2 -2
- package/clients/dispatch/runners/ruff.js +2 -2
- package/clients/dispatch/runners/ruff.ts +2 -2
- package/clients/format-service.js +39 -27
- package/clients/format-service.ts +52 -34
- package/clients/safe-spawn-async.js +163 -0
- package/clients/safe-spawn-async.ts +220 -0
- package/clients/safe-spawn.js +170 -27
- package/clients/safe-spawn.ts +208 -29
- package/clients/services/runner-service.js +36 -7
- package/clients/services/runner-service.ts +64 -18
- package/clients/symbol-types.js +5 -0
- package/clients/symbol-types.ts +77 -0
- package/clients/tree-sitter-client.js +4 -0
- package/clients/tree-sitter-client.ts +5 -0
- package/clients/tree-sitter-symbol-extractor.js +289 -0
- package/clients/tree-sitter-symbol-extractor.ts +331 -0
- package/package.json +2 -2
- package/rules/ts-slop-rules/.sgconfig.yml +0 -4
- package/rules/ts-slop-rules/rules/in-correct-optional-input-type.yml +0 -10
- package/rules/ts-slop-rules/rules/jwt-no-verify.yml +0 -13
- package/rules/ts-slop-rules/rules/no-architecture-violation.yml +0 -10
- package/rules/ts-slop-rules/rules/no-case-declarations.yml +0 -10
- package/rules/ts-slop-rules/rules/no-dangerously-set-inner-html.yml +0 -10
- package/rules/ts-slop-rules/rules/no-debugger.yml +0 -10
- package/rules/ts-slop-rules/rules/no-dupe-args.yml +0 -10
- package/rules/ts-slop-rules/rules/no-dupe-class-members.yml +0 -10
- package/rules/ts-slop-rules/rules/no-dupe-keys.yml +0 -10
- package/rules/ts-slop-rules/rules/no-eval.yml +0 -13
- package/rules/ts-slop-rules/rules/no-hardcoded-secrets.yml +0 -12
- package/rules/ts-slop-rules/rules/no-implied-eval.yml +0 -12
- package/rules/ts-slop-rules/rules/no-inner-html.yml +0 -13
- package/rules/ts-slop-rules/rules/no-javascript-url.yml +0 -10
- package/rules/ts-slop-rules/rules/no-mutable-default.yml +0 -10
- package/rules/ts-slop-rules/rules/no-nested-links.yml +0 -12
- package/rules/ts-slop-rules/rules/no-new-symbol.yml +0 -10
- package/rules/ts-slop-rules/rules/no-new-wrappers.yml +0 -13
- package/rules/ts-slop-rules/rules/no-open-redirect.yml +0 -16
- package/rules/ts-slop-rules/rules/weak-rsa-key.yml +0 -12
- /package/rules/{ts-slop-rules/rules/slop-rules.yml → ast-grep-rules/slop-patterns.yml} +0 -0
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,99 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to pi-lens will be documented in this file.
|
|
4
4
|
|
|
5
|
+
## [3.1.0] - 2026-04-01
|
|
6
|
+
|
|
7
|
+
### Changed
|
|
8
|
+
- **Consolidated ast-grep runners** — Unified CLI and NAPI runners with shared rule set
|
|
9
|
+
- NAPI runner now primary for dispatch (100x faster than CLI spawn)
|
|
10
|
+
- Merged ts-slop-rules (21 files) into ast-grep-rules/slop-patterns.yml (33 patterns)
|
|
11
|
+
- Removed 20 duplicate rule files with conflicting IDs (e.g., `ts-jwt-no-verify` vs `jwt-no-verify`)
|
|
12
|
+
- Total: 104 unified rules (71 security/architecture + 33 slop patterns)
|
|
13
|
+
- CLI ast-grep kept only for `ast_grep_search` / `ast_grep_replace` tools
|
|
14
|
+
|
|
15
|
+
### Fixed
|
|
16
|
+
- **ast-grep-napi stability** — Fixed stack overflow crashes in AST traversal
|
|
17
|
+
- Added `_MAX_AST_DEPTH = 50` depth limit to `findByKind()` and `getAllNodes()`
|
|
18
|
+
- Added `_MAX_RULE_DEPTH = 5` recursion limit for structured rules
|
|
19
|
+
- Added `MAX_MATCHES_PER_RULE = 10` to prevent false positive explosions
|
|
20
|
+
- Added `MAX_TOTAL_DIAGNOSTICS = 50` to prevent output spam
|
|
21
|
+
- NAPI runner now safely handles deeply nested TypeScript files
|
|
22
|
+
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
## [3.0.1] - 2026-03-31
|
|
26
|
+
|
|
27
|
+
### Changed
|
|
28
|
+
- **Documentation refresh**: Updated npm and README descriptions for v3.0.0 features
|
|
29
|
+
- New tagline: "pi extension for real-time code quality"
|
|
30
|
+
- Highlights 31 LSP servers, tree-sitter analysis, auto-install capability
|
|
31
|
+
- Clarified blockers vs warnings split (inline vs `/lens-booboo`)
|
|
32
|
+
|
|
33
|
+
### Fixed
|
|
34
|
+
- **Entropy threshold**: Increased from 3.5 → 5.5 bits to reduce false positives
|
|
35
|
+
- Previous threshold was too sensitive for tooling codebases
|
|
36
|
+
- Eliminates ~70-80% of "High entropy" warnings on legitimate complex code
|
|
37
|
+
|
|
38
|
+
---
|
|
39
|
+
|
|
40
|
+
## [3.0.0] - 2026-03-31
|
|
41
|
+
|
|
42
|
+
### Breaking Changes
|
|
43
|
+
|
|
44
|
+
#### Removed - Deprecated Commands
|
|
45
|
+
The following deprecated commands have been removed:
|
|
46
|
+
- `/lens-booboo-fix` → Use `/lens-booboo` with autofix capability
|
|
47
|
+
- `/lens-booboo-delta` → Delta mode now automatic
|
|
48
|
+
- `/lens-booboo-refactor` → Use `/lens-booboo` findings
|
|
49
|
+
- `/lens-metrics` → Metrics now in `/lens-booboo` report
|
|
50
|
+
- `/lens-rate` → Use `/lens-booboo` quality scoring
|
|
51
|
+
|
|
52
|
+
#### Changed - Blockers vs Warnings Architecture
|
|
53
|
+
- **🔴 Blockers** (type errors, secrets, empty catch blocks) → Appear **inline** and stop the agent
|
|
54
|
+
- **🟡 Warnings** (complexity, code smells) → Go to **`/lens-booboo`** only (not inline)
|
|
55
|
+
- Tree-sitter rules with `severity: error` now properly block inline
|
|
56
|
+
- Dispatcher checks individual diagnostic semantic, not just group default
|
|
57
|
+
|
|
58
|
+
### Added - Tree-Sitter Runner
|
|
59
|
+
New structural analysis runner at priority 14:
|
|
60
|
+
- **18 YAML query files** for TypeScript and Python patterns
|
|
61
|
+
- TypeScript: empty-catch, eval, debugger, console-statement, hardcoded-secrets, deep-nesting, deep-promise-chain, mixed-async-styles, nested-ternary, long-parameter-list, await-in-loop, dangerously-set-inner-html
|
|
62
|
+
- Python: bare-except, eval-exec, wildcard-import, is-vs-equals, mutable-default-arg, unreachable-except
|
|
63
|
+
- Blockers appear inline (severity: error), warnings go to `/lens-booboo` (severity: warning)
|
|
64
|
+
|
|
65
|
+
### Added - Auto-Install for Core Tools
|
|
66
|
+
Four tools now auto-install on first use (no manual setup required):
|
|
67
|
+
1. **TypeScript Language Server** (`typescript-language-server`) — TS/JS type checking
|
|
68
|
+
2. **Pyright** — Python type checking (`pip install pyright`)
|
|
69
|
+
3. **Ruff** — Python linting (`pip install ruff`)
|
|
70
|
+
4. **Biome** — JS/TS/JSON linting and formatting
|
|
71
|
+
|
|
72
|
+
Installs to `.pi-lens/tools/` with verification step (`--version` check).
|
|
73
|
+
|
|
74
|
+
### Added - NAPI Security Rules
|
|
75
|
+
Migrated 20 critical security rules to NAPI (fast native execution):
|
|
76
|
+
- Rules with `weight >= 4` are **blocking** (stop the agent)
|
|
77
|
+
- Includes: no-eval, no-hardcoded-secrets, no-implied-eval, no-inner-html, no-dangerously-set-inner-html, no-debugger, no-javascript-url, no-open-redirect, no-mutable-default, weak-rsa-key, jwt-no-verify, and more
|
|
78
|
+
- NAPI runs at priority 15 (after tree-sitter, before slop rules)
|
|
79
|
+
|
|
80
|
+
### Fixed
|
|
81
|
+
- **Tree-sitter query loading**: Added missing `loadQueries()` call before `getAllQueries()`
|
|
82
|
+
- **Windows path handling**: Changed from `lastIndexOf("/")` to `path.dirname()` for cross-platform compatibility
|
|
83
|
+
- **Dispatcher blocker detection**: Now checks if any individual diagnostic has `semantic === "blocking"`
|
|
84
|
+
- **Biome runner npx fallback**: Uses `npx biome` when `biome` not in PATH directly
|
|
85
|
+
- **LSP ENOENT crashes**: Added `_attachErrorHandler()` to all 23 manual-install LSP servers
|
|
86
|
+
- **LSP initialization timeout**: Increased to 120s (was 45s)
|
|
87
|
+
- **ESLint scope reduction**: Removed `.ts/.tsx` from ESLint LSP (now JS/framework files only)
|
|
88
|
+
- **Biome/Prettier race**: Biome is now default (priority 10), Prettier is fallback only
|
|
89
|
+
|
|
90
|
+
### Changed
|
|
91
|
+
- **README reorganization**: Removed redundant sections (Architecture, Language Support, Rules, Delta-mode, Slop Detection)
|
|
92
|
+
- **Consolidated Additional Safeguards** into Features section with Runners table
|
|
93
|
+
- **Updated .gitignore**: Local tracking files stay out of repo
|
|
94
|
+
- **Tuned thresholds**: 70-80% false positive reduction in booboo reports
|
|
95
|
+
|
|
96
|
+
---
|
|
97
|
+
|
|
5
98
|
## [2.7.0] - 2026-03-31
|
|
6
99
|
|
|
7
100
|
### Added - New Lint Runners
|
package/README.md
CHANGED
|
@@ -1,18 +1,20 @@
|
|
|
1
1
|
# pi-lens
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
**pi extension for real-time code quality.** 31 LSP servers, tree-sitter structural analysis, AST pattern matching, auto-install for TypeScript/Python tooling, duplicate detection, complexity metrics, and inline blockers with comprehensive `/lens-booboo` reports.
|
|
4
4
|
|
|
5
5
|
## What pi-lens Does
|
|
6
6
|
|
|
7
7
|
**For every file you edit:**
|
|
8
8
|
1. **Auto-formats** — Detects and runs formatters (Biome, Prettier, Ruff, gofmt, rustfmt, etc.)
|
|
9
|
-
2. **Type-checks** TypeScript, Python, Go, Rust (
|
|
10
|
-
3. **Scans for secrets** —
|
|
9
|
+
2. **Type-checks** — TypeScript, Python, Go, Rust (31 languages with `--lens-lsp`)
|
|
10
|
+
3. **Scans for secrets** — Blocks on hardcoded API keys, tokens, passwords
|
|
11
11
|
4. **Runs linters** — Biome (TS/JS), Ruff (Python), plus structural analysis
|
|
12
|
-
5. **
|
|
13
|
-
6. **
|
|
12
|
+
5. **Tree-sitter analysis** — Deep structural patterns (empty catch, eval, deep nesting, mixed async styles)
|
|
13
|
+
6. **Auto-installs** — TypeScript, Python, Biome, Ruff tools install automatically on first use
|
|
14
|
+
7. **Only shows NEW issues** — Delta-mode tracks baselines and filters pre-existing problems
|
|
14
15
|
|
|
15
|
-
|
|
16
|
+
**🔴 Blockers** (type errors, secrets, empty catches) appear inline and stop the agent until fixed.
|
|
17
|
+
**🟡 Warnings** (complexity, code smells) go to `/lens-booboo` — run it to see them all.
|
|
16
18
|
|
|
17
19
|
## Quick Start
|
|
18
20
|
|
|
@@ -204,12 +206,11 @@ pi-lens uses a **dispatcher-runner architecture** for extensible multi-language
|
|
|
204
206
|
| **ruff** | Python | 10 | Warning | Python linting (delta-tracked) |
|
|
205
207
|
| **oxlint** | TS/JS | 12 | Warning | Fast Rust-based JS/TS linter |
|
|
206
208
|
| **tree-sitter** | TS/JS, Python | 14 | Mixed | AST-based structural analysis (17 patterns) |
|
|
207
|
-
| **ast-grep-napi** | TS/JS | 15 | Warning | **
|
|
209
|
+
| **ast-grep-napi** | TS/JS | 15 | Warning | **Unified structural analysis** (104 rules) |
|
|
208
210
|
| **type-safety** | TS | 20 | Mixed | Switch exhaustiveness (blocking), other (warning) |
|
|
209
211
|
| **shellcheck** | Shell | 20 | Warning | Bash/sh/zsh/fish linting |
|
|
210
212
|
| **python-slop** | Python | 25 | Warning | AI slop detection (~40 patterns) |
|
|
211
213
|
| **spellcheck** | Markdown | 30 | Warning | Typo detection in docs |
|
|
212
|
-
| **ast-grep** | Go, Rust, Python, etc. | 30 | Warning | Structural analysis via CLI (fallback for non-TS/JS) |
|
|
213
214
|
| **similarity** | TS | 35 | Silent | Semantic duplicate detection (metrics only) |
|
|
214
215
|
| **architect** | All | 40 | Warning | Architectural rule violations |
|
|
215
216
|
| **go-vet** | Go | 50 | Warning | Go static analysis |
|
|
@@ -227,7 +228,7 @@ pi-lens uses a **dispatcher-runner architecture** for extensible multi-language
|
|
|
227
228
|
- **Warning** — Shown in `/lens-booboo`, not inline (noise reduction)
|
|
228
229
|
- **Silent** — Tracked in metrics only, never shown
|
|
229
230
|
|
|
230
|
-
**
|
|
231
|
+
**Consolidated runners:** `ast-grep` (CLI) and `ts-slop` merged into `ast-grep-napi` — unified 104-rule set
|
|
231
232
|
|
|
232
233
|
**Tree-sitter runner patterns** (priority 14, AST-based structural analysis):
|
|
233
234
|
|
|
@@ -241,7 +242,9 @@ Python (6 patterns):
|
|
|
241
242
|
|
|
242
243
|
**Custom tree-sitter queries:** Add `.yml` files to `.pi-lens/rules/tree-sitter-queries/{typescript,python}/`
|
|
243
244
|
|
|
244
|
-
**AI Slop Detection:**
|
|
245
|
+
**AI Slop Detection:**
|
|
246
|
+
- `python-slop` runner (priority 25): ~40 patterns for Python code quality
|
|
247
|
+
- `ast-grep-napi` runner (priority 15): 33 slop patterns + 71 security/architecture rules for TypeScript/JavaScript
|
|
245
248
|
|
|
246
249
|
---
|
|
247
250
|
|
|
@@ -7,8 +7,8 @@
|
|
|
7
7
|
* - Real-time progress tracking
|
|
8
8
|
* - Hook integration for tool_result handler
|
|
9
9
|
*/
|
|
10
|
-
import { RunnerStarted, RunnerCompleted, ReportReady, FileModified, DiagnosticAggregator, } from "./events.js";
|
|
11
10
|
import { enableDebug } from "./bus.js";
|
|
11
|
+
import { DiagnosticAggregator, FileModified, ReportReady, RunnerCompleted, RunnerStarted, } from "./events.js";
|
|
12
12
|
const state = {
|
|
13
13
|
aggregator: new DiagnosticAggregator(),
|
|
14
14
|
runnerInProgress: new Set(),
|
|
@@ -21,7 +21,7 @@ let unsubscribers = [];
|
|
|
21
21
|
* Initialize the bus integration
|
|
22
22
|
* Call this from session_start handler
|
|
23
23
|
*/
|
|
24
|
-
export function initBusIntegration(
|
|
24
|
+
export function initBusIntegration(_pi, options) {
|
|
25
25
|
if (state.isEnabled)
|
|
26
26
|
return; // Already initialized
|
|
27
27
|
if (options?.debug) {
|
|
@@ -37,13 +37,13 @@ export function initBusIntegration(pi, options) {
|
|
|
37
37
|
const unsubRunnerCompleted = RunnerCompleted.subscribe((event) => {
|
|
38
38
|
const { runnerId, filePath, durationMs, diagnosticCount } = event.properties;
|
|
39
39
|
state.runnerInProgress.delete(`${runnerId}:${filePath}`);
|
|
40
|
-
// Log slow runners in debug mode
|
|
40
|
+
// Log slow runners in debug mode only
|
|
41
41
|
if (options?.debug && durationMs > 5000) {
|
|
42
42
|
console.error(`[bus] Slow runner: ${runnerId} took ${durationMs}ms for ${filePath}`);
|
|
43
43
|
}
|
|
44
|
-
// Log runners that found issues
|
|
45
|
-
if (diagnosticCount >
|
|
46
|
-
console.error(`[bus] ${runnerId} found ${diagnosticCount} issues in ${filePath}`);
|
|
44
|
+
// Log runners that found excessive issues (indicates rule misconfiguration)
|
|
45
|
+
if (diagnosticCount > 100) {
|
|
46
|
+
console.error(`[bus] ${runnerId} found ${diagnosticCount} issues in ${filePath} (rules may be too broad)`);
|
|
47
47
|
}
|
|
48
48
|
});
|
|
49
49
|
// Cache reports for quick retrieval
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Bus Integration for pi-lens
|
|
3
|
-
*
|
|
3
|
+
*
|
|
4
4
|
* Connects the event bus system to the existing pi-lens architecture.
|
|
5
5
|
* This provides:
|
|
6
6
|
* - Event aggregation for diagnostic collection
|
|
@@ -8,19 +8,16 @@
|
|
|
8
8
|
* - Hook integration for tool_result handler
|
|
9
9
|
*/
|
|
10
10
|
|
|
11
|
+
import type { ExtensionAPI } from "@mariozechner/pi-coding-agent";
|
|
12
|
+
import { enableDebug } from "./bus.js";
|
|
11
13
|
import {
|
|
12
|
-
DiagnosticFound,
|
|
13
|
-
RunnerStarted,
|
|
14
|
-
RunnerCompleted,
|
|
15
|
-
ReportReady,
|
|
16
|
-
FileModified,
|
|
17
|
-
SessionStarted,
|
|
18
|
-
TurnEnded,
|
|
19
|
-
DiagnosticAggregator,
|
|
20
14
|
type Diagnostic,
|
|
15
|
+
DiagnosticAggregator,
|
|
16
|
+
FileModified,
|
|
17
|
+
ReportReady,
|
|
18
|
+
RunnerCompleted,
|
|
19
|
+
RunnerStarted,
|
|
21
20
|
} from "./events.js";
|
|
22
|
-
import { subscribe, enableDebug } from "./bus.js";
|
|
23
|
-
import type { ExtensionAPI } from "@mariozechner/pi-coding-agent";
|
|
24
21
|
|
|
25
22
|
// --- Integration State ---
|
|
26
23
|
|
|
@@ -46,7 +43,10 @@ let unsubscribers: Array<() => void> = [];
|
|
|
46
43
|
* Initialize the bus integration
|
|
47
44
|
* Call this from session_start handler
|
|
48
45
|
*/
|
|
49
|
-
export function initBusIntegration(
|
|
46
|
+
export function initBusIntegration(
|
|
47
|
+
_pi: ExtensionAPI,
|
|
48
|
+
options?: { debug?: boolean },
|
|
49
|
+
): void {
|
|
50
50
|
if (state.isEnabled) return; // Already initialized
|
|
51
51
|
|
|
52
52
|
if (options?.debug) {
|
|
@@ -63,24 +63,29 @@ export function initBusIntegration(pi: ExtensionAPI, options?: { debug?: boolean
|
|
|
63
63
|
});
|
|
64
64
|
|
|
65
65
|
const unsubRunnerCompleted = RunnerCompleted.subscribe((event) => {
|
|
66
|
-
const { runnerId, filePath, durationMs, diagnosticCount } =
|
|
66
|
+
const { runnerId, filePath, durationMs, diagnosticCount } =
|
|
67
|
+
event.properties;
|
|
67
68
|
state.runnerInProgress.delete(`${runnerId}:${filePath}`);
|
|
68
69
|
|
|
69
|
-
// Log slow runners in debug mode
|
|
70
|
+
// Log slow runners in debug mode only
|
|
70
71
|
if (options?.debug && durationMs > 5000) {
|
|
71
|
-
console.error(
|
|
72
|
+
console.error(
|
|
73
|
+
`[bus] Slow runner: ${runnerId} took ${durationMs}ms for ${filePath}`,
|
|
74
|
+
);
|
|
72
75
|
}
|
|
73
76
|
|
|
74
|
-
// Log runners that found issues
|
|
75
|
-
if (diagnosticCount >
|
|
76
|
-
console.error(
|
|
77
|
+
// Log runners that found excessive issues (indicates rule misconfiguration)
|
|
78
|
+
if (diagnosticCount > 100) {
|
|
79
|
+
console.error(
|
|
80
|
+
`[bus] ${runnerId} found ${diagnosticCount} issues in ${filePath} (rules may be too broad)`,
|
|
81
|
+
);
|
|
77
82
|
}
|
|
78
83
|
});
|
|
79
84
|
|
|
80
85
|
// Cache reports for quick retrieval
|
|
81
86
|
const unsubReportReady = ReportReady.subscribe((event) => {
|
|
82
87
|
const { filePath, report, durationMs } = event.properties;
|
|
83
|
-
|
|
88
|
+
|
|
84
89
|
// Store the report
|
|
85
90
|
state.lastReport.set(filePath, {
|
|
86
91
|
output: formatReport(report, durationMs),
|
|
@@ -91,10 +96,10 @@ export function initBusIntegration(pi: ExtensionAPI, options?: { debug?: boolean
|
|
|
91
96
|
// Track file modifications to clear stale data
|
|
92
97
|
const unsubFileModified = FileModified.subscribe((event) => {
|
|
93
98
|
const { filePath } = event.properties;
|
|
94
|
-
|
|
99
|
+
|
|
95
100
|
// Clear cached report for modified file
|
|
96
101
|
state.lastReport.delete(filePath);
|
|
97
|
-
|
|
102
|
+
|
|
98
103
|
// Clear diagnostics aggregator for this file (will be repopulated)
|
|
99
104
|
state.aggregator.clear(filePath);
|
|
100
105
|
});
|
|
@@ -139,7 +144,12 @@ export function shutdownBusIntegration(): void {
|
|
|
139
144
|
// --- Helper Functions ---
|
|
140
145
|
|
|
141
146
|
function formatReport(
|
|
142
|
-
report: {
|
|
147
|
+
report: {
|
|
148
|
+
blockers: Diagnostic[];
|
|
149
|
+
warnings: Diagnostic[];
|
|
150
|
+
fixed: Diagnostic[];
|
|
151
|
+
silent: Diagnostic[];
|
|
152
|
+
},
|
|
143
153
|
durationMs: number,
|
|
144
154
|
): string {
|
|
145
155
|
const lines: string[] = [];
|
|
@@ -198,7 +208,10 @@ export function hasRunnersInProgress(filePath?: string): boolean {
|
|
|
198
208
|
/**
|
|
199
209
|
* Get list of runners in progress
|
|
200
210
|
*/
|
|
201
|
-
export function getRunnersInProgress(): Array<{
|
|
211
|
+
export function getRunnersInProgress(): Array<{
|
|
212
|
+
runnerId: string;
|
|
213
|
+
filePath: string;
|
|
214
|
+
}> {
|
|
202
215
|
return Array.from(state.runnerInProgress).map((key) => {
|
|
203
216
|
const [runnerId, filePath] = key.split(":");
|
|
204
217
|
return { runnerId, filePath };
|
|
@@ -234,9 +234,11 @@ export class ComplexityClient {
|
|
|
234
234
|
if (metrics.maxNestingDepth > 4) {
|
|
235
235
|
parts.push(` Max nesting: ${metrics.maxNestingDepth} levels (consider extracting)`);
|
|
236
236
|
}
|
|
237
|
-
// Code entropy (in bits, >
|
|
238
|
-
|
|
239
|
-
|
|
237
|
+
// Code entropy (in bits, >5.5 = risky AI-induced complexity)
|
|
238
|
+
// Threshold increased from 3.5 to 5.5 to reduce false positives in tooling codebases
|
|
239
|
+
// where diverse method/variable names are naturally expected
|
|
240
|
+
if (metrics.codeEntropy > 5.5) {
|
|
241
|
+
parts.push(` Entropy: ${metrics.codeEntropy.toFixed(1)} bits (>5.5 — risky AI-induced complexity)`);
|
|
240
242
|
}
|
|
241
243
|
// Function length
|
|
242
244
|
if (metrics.maxFunctionLength > 50) {
|
|
@@ -336,8 +338,8 @@ export class ComplexityClient {
|
|
|
336
338
|
if (metrics.maxNestingDepth > 6) {
|
|
337
339
|
warnings.push(`Deep nesting (${metrics.maxNestingDepth} levels) — extract nested logic into separate functions`);
|
|
338
340
|
}
|
|
339
|
-
// Entropy > 5.
|
|
340
|
-
if (metrics.codeEntropy > 5.
|
|
341
|
+
// Entropy > 5.5 is high (was > 3.5 → 5.0, still too sensitive for tooling codebases)
|
|
342
|
+
if (metrics.codeEntropy > 5.5) {
|
|
341
343
|
warnings.push(`High entropy (${metrics.codeEntropy.toFixed(1)} bits) — follow project conventions`);
|
|
342
344
|
}
|
|
343
345
|
// Comments ratio (>60% = excessive, was > 40%)
|
|
@@ -576,7 +578,8 @@ export class ComplexityClient {
|
|
|
576
578
|
/**
|
|
577
579
|
* Calculate Shannon entropy of code tokens (in bits)
|
|
578
580
|
* Uses log2 for entropy measured in bits
|
|
579
|
-
* Threshold: >
|
|
581
|
+
* Threshold: >5.5 bits indicates risky AI-induced complexity
|
|
582
|
+
* (Increased from 3.5 to reduce false positives in tooling codebases)
|
|
580
583
|
*/
|
|
581
584
|
calculateCodeEntropy(sourceText) {
|
|
582
585
|
// Tokenize by splitting on whitespace and common delimiters
|
|
@@ -331,10 +331,12 @@ export class ComplexityClient {
|
|
|
331
331
|
);
|
|
332
332
|
}
|
|
333
333
|
|
|
334
|
-
// Code entropy (in bits, >
|
|
335
|
-
|
|
334
|
+
// Code entropy (in bits, >5.5 = risky AI-induced complexity)
|
|
335
|
+
// Threshold increased from 3.5 to 5.5 to reduce false positives in tooling codebases
|
|
336
|
+
// where diverse method/variable names are naturally expected
|
|
337
|
+
if (metrics.codeEntropy > 5.5) {
|
|
336
338
|
parts.push(
|
|
337
|
-
` Entropy: ${metrics.codeEntropy.toFixed(1)} bits (>
|
|
339
|
+
` Entropy: ${metrics.codeEntropy.toFixed(1)} bits (>5.5 — risky AI-induced complexity)`,
|
|
338
340
|
);
|
|
339
341
|
}
|
|
340
342
|
|
|
@@ -480,8 +482,8 @@ export class ComplexityClient {
|
|
|
480
482
|
);
|
|
481
483
|
}
|
|
482
484
|
|
|
483
|
-
// Entropy > 5.
|
|
484
|
-
if (metrics.codeEntropy > 5.
|
|
485
|
+
// Entropy > 5.5 is high (was > 3.5 → 5.0, still too sensitive for tooling codebases)
|
|
486
|
+
if (metrics.codeEntropy > 5.5) {
|
|
485
487
|
warnings.push(
|
|
486
488
|
`High entropy (${metrics.codeEntropy.toFixed(1)} bits) — follow project conventions`,
|
|
487
489
|
);
|
|
@@ -807,7 +809,8 @@ export class ComplexityClient {
|
|
|
807
809
|
/**
|
|
808
810
|
* Calculate Shannon entropy of code tokens (in bits)
|
|
809
811
|
* Uses log2 for entropy measured in bits
|
|
810
|
-
* Threshold: >
|
|
812
|
+
* Threshold: >5.5 bits indicates risky AI-induced complexity
|
|
813
|
+
* (Increased from 3.5 to reduce false positives in tooling codebases)
|
|
811
814
|
*/
|
|
812
815
|
private calculateCodeEntropy(sourceText: string): number {
|
|
813
816
|
// Tokenize by splitting on whitespace and common delimiters
|
package/clients/dispatch/plan.js
CHANGED
|
@@ -23,12 +23,11 @@ export const TOOL_PLANS = {
|
|
|
23
23
|
{ mode: "all", runnerIds: ["ts-lsp"], filterKinds: ["jsts"] },
|
|
24
24
|
// Then biome or oxlint for fast linting (user preference)
|
|
25
25
|
{ mode: "fallback", runnerIds: ["biome-lint", "oxlint"] },
|
|
26
|
-
// Fast structural analysis via NAPI (
|
|
26
|
+
// Fast structural analysis via NAPI (replaces CLI - 100x faster)
|
|
27
27
|
{ mode: "all", runnerIds: ["ast-grep-napi"] },
|
|
28
28
|
// Type safety checks
|
|
29
29
|
{ mode: "fallback", runnerIds: ["type-safety"] },
|
|
30
|
-
//
|
|
31
|
-
{ mode: "fallback", runnerIds: ["ast-grep"] },
|
|
30
|
+
// Note: ast-grep CLI kept for ast_grep_search/ast_grep_replace tools only
|
|
32
31
|
// Architectural rules
|
|
33
32
|
{ mode: "fallback", runnerIds: ["architect"] },
|
|
34
33
|
],
|
package/clients/dispatch/plan.ts
CHANGED
|
@@ -27,12 +27,11 @@ export const TOOL_PLANS: Record<string, ToolPlan> = {
|
|
|
27
27
|
{ mode: "all", runnerIds: ["ts-lsp"], filterKinds: ["jsts"] },
|
|
28
28
|
// Then biome or oxlint for fast linting (user preference)
|
|
29
29
|
{ mode: "fallback", runnerIds: ["biome-lint", "oxlint"] },
|
|
30
|
-
// Fast structural analysis via NAPI (
|
|
30
|
+
// Fast structural analysis via NAPI (replaces CLI - 100x faster)
|
|
31
31
|
{ mode: "all", runnerIds: ["ast-grep-napi"] },
|
|
32
32
|
// Type safety checks
|
|
33
33
|
{ mode: "fallback", runnerIds: ["type-safety"] },
|
|
34
|
-
//
|
|
35
|
-
{ mode: "fallback", runnerIds: ["ast-grep"] },
|
|
34
|
+
// Note: ast-grep CLI kept for ast_grep_search/ast_grep_replace tools only
|
|
36
35
|
// Architectural rules
|
|
37
36
|
{ mode: "fallback", runnerIds: ["architect"] },
|
|
38
37
|
],
|