pi-lens 3.1.2 → 3.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 +55 -0
- package/README.md +16 -12
- package/clients/ast-grep-client.js +8 -1
- package/clients/ast-grep-client.ts +9 -1
- package/clients/biome-client.js +51 -38
- package/clients/biome-client.ts +60 -58
- package/clients/dependency-checker.js +30 -1
- package/clients/dependency-checker.ts +35 -1
- package/clients/dispatch/__tests__/runner-registration.test.ts +286 -282
- package/clients/dispatch/bus-dispatcher.js +15 -14
- package/clients/dispatch/bus-dispatcher.ts +32 -25
- package/clients/dispatch/dispatcher.js +18 -25
- package/clients/dispatch/dispatcher.test.ts +2 -1
- package/clients/dispatch/dispatcher.ts +17 -28
- package/clients/dispatch/plan.js +77 -32
- package/clients/dispatch/plan.ts +78 -32
- package/clients/dispatch/runners/ast-grep-napi.js +36 -376
- package/clients/dispatch/runners/ast-grep-napi.ts +60 -433
- package/clients/dispatch/runners/index.js +8 -4
- package/clients/dispatch/runners/index.ts +8 -4
- package/clients/dispatch/runners/lsp.js +65 -0
- package/clients/dispatch/runners/lsp.ts +125 -0
- package/clients/dispatch/runners/oxlint.js +2 -2
- package/clients/dispatch/runners/oxlint.ts +2 -2
- package/clients/dispatch/runners/pyright.js +24 -8
- package/clients/dispatch/runners/pyright.ts +28 -14
- package/clients/dispatch/runners/rust-clippy.js +2 -2
- package/clients/dispatch/runners/rust-clippy.ts +2 -4
- package/clients/dispatch/runners/tree-sitter.js +14 -2
- package/clients/dispatch/runners/tree-sitter.ts +15 -2
- package/clients/dispatch/runners/ts-lsp.js +3 -3
- package/clients/dispatch/runners/ts-lsp.ts +8 -5
- package/clients/dispatch/runners/yaml-rule-parser.js +292 -0
- package/clients/dispatch/runners/yaml-rule-parser.ts +338 -0
- package/clients/dispatch/types.js +3 -0
- package/clients/dispatch/types.ts +3 -0
- package/clients/formatters.js +67 -14
- package/clients/formatters.ts +68 -15
- package/clients/installer/index.js +78 -10
- package/clients/installer/index.ts +519 -426
- package/clients/jscpd-client.js +28 -0
- package/clients/jscpd-client.ts +41 -3
- package/clients/knip-client.js +30 -1
- package/clients/knip-client.ts +34 -2
- package/clients/lsp/__tests__/client.test.ts +64 -41
- package/clients/lsp/__tests__/config.test.ts +25 -17
- package/clients/lsp/__tests__/launch.test.ts +108 -43
- package/clients/lsp/__tests__/service.test.ts +76 -48
- package/clients/lsp/client.js +87 -2
- package/clients/lsp/client.ts +150 -6
- package/clients/lsp/config.js +8 -11
- package/clients/lsp/config.ts +24 -21
- package/clients/lsp/index.js +69 -0
- package/clients/lsp/index.ts +82 -0
- package/clients/lsp/interactive-install.js +19 -8
- package/clients/lsp/interactive-install.ts +52 -27
- package/clients/lsp/launch.js +182 -32
- package/clients/lsp/launch.ts +241 -38
- package/clients/lsp/path-utils.js +3 -46
- package/clients/lsp/path-utils.ts +11 -51
- package/clients/lsp/server.js +93 -71
- package/clients/lsp/server.ts +173 -131
- package/clients/path-utils.js +142 -0
- package/clients/path-utils.ts +153 -0
- package/clients/ruff-client.js +33 -4
- package/clients/ruff-client.ts +44 -13
- package/clients/safe-spawn.js +3 -1
- package/clients/safe-spawn.ts +3 -1
- package/clients/services/effect-integration.js +11 -7
- package/clients/services/effect-integration.ts +34 -26
- package/clients/sg-runner.js +51 -9
- package/clients/sg-runner.ts +58 -15
- package/clients/tree-sitter-client.js +12 -0
- package/clients/tree-sitter-client.ts +12 -0
- package/clients/typescript-client.js +6 -2
- package/clients/typescript-client.ts +9 -2
- package/commands/booboo.js +2 -4
- package/commands/booboo.ts +2 -4
- package/index.ts +377 -93
- package/package.json +2 -1
- package/rules/tree-sitter-queries/tsx/no-nested-links.yml +45 -0
- package/rules/tree-sitter-queries/typescript/constructor-super.yml +55 -0
- package/rules/tree-sitter-queries/typescript/debugger.yml +1 -1
- package/rules/tree-sitter-queries/typescript/no-dupe-class-members.yml +47 -0
- package/tsconfig.json +1 -1
- package/clients/__tests__/file-time.test.js +0 -216
- package/clients/__tests__/format-service.test.js +0 -245
- package/clients/__tests__/formatters.test.js +0 -271
- package/clients/agent-behavior-client.test.js +0 -94
- package/clients/ast-grep-client.test.js +0 -129
- package/clients/ast-grep-client.test.ts +0 -155
- package/clients/biome-client.test.js +0 -144
- package/clients/cache-manager.test.js +0 -197
- package/clients/complexity-client.test.js +0 -234
- package/clients/dependency-checker.test.js +0 -60
- package/clients/dispatch/__tests__/autofix-integration.test.js +0 -245
- package/clients/dispatch/__tests__/runner-registration.test.js +0 -236
- package/clients/dispatch/dispatcher.edge.test.js +0 -82
- package/clients/dispatch/dispatcher.format.test.js +0 -46
- package/clients/dispatch/dispatcher.inline.test.js +0 -74
- package/clients/dispatch/dispatcher.test.js +0 -115
- package/clients/dispatch/runners/architect.test.js +0 -138
- package/clients/dispatch/runners/ast-grep-napi.test.js +0 -106
- package/clients/dispatch/runners/oxlint.test.js +0 -230
- package/clients/dispatch/runners/pyright.test.js +0 -98
- package/clients/dispatch/runners/python-slop.test.js +0 -203
- package/clients/dispatch/runners/scan_codebase.test.js +0 -89
- package/clients/dispatch/runners/shellcheck.test.js +0 -98
- package/clients/dispatch/runners/spellcheck.test.js +0 -158
- package/clients/dispatch/runners/ts-slop.test.js +0 -180
- package/clients/dispatch/runners/ts-slop.test.ts +0 -230
- package/clients/dogfood.test.js +0 -201
- package/clients/file-kinds.test.js +0 -169
- package/clients/go-client.test.js +0 -127
- package/clients/jscpd-client.test.js +0 -127
- package/clients/knip-client.test.js +0 -112
- package/clients/lsp/__tests__/client.test.js +0 -325
- package/clients/lsp/__tests__/config.test.js +0 -166
- package/clients/lsp/__tests__/error-recovery.test.js +0 -213
- package/clients/lsp/__tests__/integration.test.js +0 -127
- package/clients/lsp/__tests__/launch.test.js +0 -260
- package/clients/lsp/__tests__/server.test.js +0 -259
- package/clients/lsp/__tests__/service.test.js +0 -417
- package/clients/metrics-client.test.js +0 -141
- package/clients/ruff-client.test.js +0 -132
- package/clients/rust-client.test.js +0 -108
- package/clients/sanitize.test.js +0 -177
- package/clients/secrets-scanner.test.js +0 -100
- package/clients/services/__tests__/effect-integration.test.js +0 -86
- package/clients/test-runner-client.test.js +0 -192
- package/clients/todo-scanner.test.js +0 -301
- package/clients/type-coverage-client.test.js +0 -105
- package/clients/typescript-client.codefix.test.js +0 -157
- package/clients/typescript-client.test.js +0 -105
- package/commands/clients/ast-grep-client.js +0 -250
- package/commands/clients/ast-grep-parser.js +0 -86
- package/commands/clients/ast-grep-rule-manager.js +0 -91
- package/commands/clients/ast-grep-types.js +0 -9
- package/commands/clients/biome-client.js +0 -380
- package/commands/clients/complexity-client.js +0 -667
- package/commands/clients/file-kinds.js +0 -177
- package/commands/clients/file-utils.js +0 -40
- package/commands/clients/jscpd-client.js +0 -169
- package/commands/clients/knip-client.js +0 -211
- package/commands/clients/ruff-client.js +0 -297
- package/commands/clients/safe-spawn.js +0 -88
- package/commands/clients/scan-utils.js +0 -83
- package/commands/clients/sg-runner.js +0 -190
- package/commands/clients/types.js +0 -11
- package/commands/clients/typescript-client.js +0 -505
- package/commands/rate.test.js +0 -119
- package/rules/ast-grep-rules/rules/no-dangerously-set-inner-html.yml +0 -13
- package/rules/ast-grep-rules/rules/no-debugger.yml +0 -12
- package/rules/ast-grep-rules/rules/no-eval.yml +0 -13
|
@@ -1,30 +1,22 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Bus-Integrated Dispatcher for pi-lens
|
|
3
|
-
*
|
|
4
|
-
* Bridges the declarative dispatch system with the event bus.
|
|
5
|
-
*
|
|
6
|
-
* Changes from original dispatcher:
|
|
7
|
-
* - Publishes events for each runner lifecycle phase
|
|
8
|
-
* - Supports concurrent execution with progress tracking
|
|
9
|
-
* - Integrates with DiagnosticAggregator for results
|
|
10
|
-
*/
|
|
11
|
-
|
|
12
1
|
import {
|
|
2
|
+
type Diagnostic,
|
|
13
3
|
DiagnosticFound,
|
|
14
|
-
RunnerStarted,
|
|
15
|
-
RunnerCompleted,
|
|
16
|
-
AutoFixApplied,
|
|
17
4
|
FileModified,
|
|
18
|
-
ReportReady,
|
|
19
|
-
type Diagnostic,
|
|
20
5
|
type OutputSemantic,
|
|
6
|
+
ReportReady,
|
|
7
|
+
RunnerCompleted,
|
|
8
|
+
RunnerStarted,
|
|
21
9
|
} from "../bus/events.js";
|
|
22
|
-
import {
|
|
23
|
-
import { formatDiagnostic, formatDiagnostics, EMOJI } from "./utils/format-utils.js";
|
|
10
|
+
import { formatDiagnostics } from "./utils/format-utils.js";
|
|
24
11
|
// Import runners to register them
|
|
25
12
|
import "./runners/index.js";
|
|
26
13
|
|
|
27
|
-
import type {
|
|
14
|
+
import type {
|
|
15
|
+
DispatchContext,
|
|
16
|
+
RunnerDefinition,
|
|
17
|
+
RunnerGroup,
|
|
18
|
+
RunnerResult,
|
|
19
|
+
} from "./types.js";
|
|
28
20
|
|
|
29
21
|
// --- Enhanced Dispatch Result ---
|
|
30
22
|
|
|
@@ -53,7 +45,7 @@ async function runRunner(
|
|
|
53
45
|
defaultSemantic: OutputSemantic,
|
|
54
46
|
): Promise<RunnerResult & { durationMs: number }> {
|
|
55
47
|
const startTime = Date.now();
|
|
56
|
-
|
|
48
|
+
|
|
57
49
|
// Publish runner started event
|
|
58
50
|
RunnerStarted.publish({
|
|
59
51
|
runnerId: runner.id,
|
|
@@ -62,6 +54,15 @@ async function runRunner(
|
|
|
62
54
|
});
|
|
63
55
|
|
|
64
56
|
try {
|
|
57
|
+
// Check when() condition async-safely (sync filter in caller can't await Promises)
|
|
58
|
+
if (runner.when && !(await runner.when(ctx))) {
|
|
59
|
+
return {
|
|
60
|
+
status: "skipped",
|
|
61
|
+
diagnostics: [],
|
|
62
|
+
semantic: defaultSemantic,
|
|
63
|
+
durationMs: Date.now() - startTime,
|
|
64
|
+
};
|
|
65
|
+
}
|
|
65
66
|
const result = await runner.run(ctx);
|
|
66
67
|
const durationMs = Date.now() - startTime;
|
|
67
68
|
|
|
@@ -77,7 +78,8 @@ async function runRunner(
|
|
|
77
78
|
|
|
78
79
|
// Publish runner completed event
|
|
79
80
|
// Map "succeeded" to "completed" for the event status
|
|
80
|
-
const eventStatus =
|
|
81
|
+
const eventStatus =
|
|
82
|
+
result.status === "succeeded" ? "completed" : result.status;
|
|
81
83
|
RunnerCompleted.publish({
|
|
82
84
|
runnerId: runner.id,
|
|
83
85
|
filePath: ctx.filePath,
|
|
@@ -137,10 +139,11 @@ export async function dispatchConcurrent(
|
|
|
137
139
|
})
|
|
138
140
|
: group.runnerIds;
|
|
139
141
|
|
|
142
|
+
// Note: when() is async — must be awaited. Filter it out here synchronously
|
|
143
|
+
// (runners without when always run; runners with when are checked inside runRunner).
|
|
140
144
|
const runners = runnerIds
|
|
141
145
|
.map((id) => getRunner(id))
|
|
142
|
-
.filter((r): r is RunnerDefinition => r !== undefined)
|
|
143
|
-
.filter((r) => (r.when ? r.when(ctx) : true));
|
|
146
|
+
.filter((r): r is RunnerDefinition => r !== undefined);
|
|
144
147
|
|
|
145
148
|
const semantic = group.semantic ?? "warning";
|
|
146
149
|
|
|
@@ -226,7 +229,10 @@ export async function dispatchConcurrent(
|
|
|
226
229
|
export async function dispatchLintWithBus(
|
|
227
230
|
filePath: string,
|
|
228
231
|
cwd: string,
|
|
229
|
-
pi: {
|
|
232
|
+
pi: {
|
|
233
|
+
getFlag(flag: string): string | boolean | undefined;
|
|
234
|
+
log?: (msg: string) => void;
|
|
235
|
+
},
|
|
230
236
|
): Promise<string> {
|
|
231
237
|
const { createDispatchContext } = await import("./dispatcher.js");
|
|
232
238
|
const { getRunnersForKind } = await import("./dispatcher.js");
|
|
@@ -238,7 +244,8 @@ export async function dispatchLintWithBus(
|
|
|
238
244
|
changeType: "external",
|
|
239
245
|
});
|
|
240
246
|
|
|
241
|
-
|
|
247
|
+
// blockingOnly=true: post-write dispatch only reports blocking errors (same as standard dispatchLint)
|
|
248
|
+
const ctx = createDispatchContext(filePath, cwd, pi, undefined, true);
|
|
242
249
|
|
|
243
250
|
const kind = ctx.kind;
|
|
244
251
|
if (!kind) return "";
|
|
@@ -16,6 +16,7 @@
|
|
|
16
16
|
import { detectFileKind } from "../file-kinds.js";
|
|
17
17
|
import { isTestFile } from "../file-utils.js";
|
|
18
18
|
import { logLatency } from "../latency-logger.js";
|
|
19
|
+
import { normalizeMapKey } from "../path-utils.js";
|
|
19
20
|
import { safeSpawn } from "../safe-spawn.js";
|
|
20
21
|
import { formatDiagnostics } from "./utils/format-utils.js";
|
|
21
22
|
// --- In-Memory Baseline Store ---
|
|
@@ -24,10 +25,10 @@ export function createBaselineStore() {
|
|
|
24
25
|
const baselines = new Map();
|
|
25
26
|
return {
|
|
26
27
|
get(filePath) {
|
|
27
|
-
return baselines.get(filePath);
|
|
28
|
+
return baselines.get(normalizeMapKey(filePath));
|
|
28
29
|
},
|
|
29
30
|
set(filePath, diagnostics) {
|
|
30
|
-
baselines.set(filePath, diagnostics);
|
|
31
|
+
baselines.set(normalizeMapKey(filePath), diagnostics);
|
|
31
32
|
},
|
|
32
33
|
clear() {
|
|
33
34
|
baselines.clear();
|
|
@@ -37,10 +38,8 @@ export function createBaselineStore() {
|
|
|
37
38
|
// --- Runner Registry ---
|
|
38
39
|
const globalRegistry = new Map();
|
|
39
40
|
export function registerRunner(runner) {
|
|
40
|
-
if (globalRegistry.has(runner.id))
|
|
41
|
-
|
|
42
|
-
return;
|
|
43
|
-
}
|
|
41
|
+
if (globalRegistry.has(runner.id))
|
|
42
|
+
return; // Already registered, skip silently
|
|
44
43
|
globalRegistry.set(runner.id, runner);
|
|
45
44
|
}
|
|
46
45
|
export function getRunner(id) {
|
|
@@ -91,9 +90,11 @@ function checkToolAvailability(command) {
|
|
|
91
90
|
}
|
|
92
91
|
// --- Dispatch Context Factory ---
|
|
93
92
|
export function createDispatchContext(filePath, cwd, pi, baselines, blockingOnly) {
|
|
94
|
-
|
|
93
|
+
// Normalize path for consistent Map key usage on Windows
|
|
94
|
+
const normalizedFilePath = normalizeMapKey(filePath);
|
|
95
|
+
const kind = detectFileKind(normalizedFilePath);
|
|
95
96
|
return {
|
|
96
|
-
filePath,
|
|
97
|
+
filePath: normalizedFilePath,
|
|
97
98
|
cwd,
|
|
98
99
|
kind,
|
|
99
100
|
pi,
|
|
@@ -168,12 +169,17 @@ export async function dispatchForFile(ctx, groups) {
|
|
|
168
169
|
let stopped = false;
|
|
169
170
|
const runnerLatencies = [];
|
|
170
171
|
// Debug logging goes to latency log only (not console - avoid noise)
|
|
172
|
+
const allRunnerIds = groups.flatMap((g) => g.runnerIds);
|
|
171
173
|
logLatency({
|
|
172
174
|
type: "phase",
|
|
173
175
|
filePath: ctx.filePath,
|
|
174
176
|
phase: "dispatch_start",
|
|
175
177
|
durationMs: 0,
|
|
176
|
-
metadata: {
|
|
178
|
+
metadata: {
|
|
179
|
+
groupCount: groups.length,
|
|
180
|
+
kind: ctx.kind,
|
|
181
|
+
runners: allRunnerIds.join(","),
|
|
182
|
+
},
|
|
177
183
|
});
|
|
178
184
|
for (const group of groups) {
|
|
179
185
|
if (stopped && ctx.pi.getFlag("stop-on-error")) {
|
|
@@ -256,10 +262,6 @@ export async function dispatchForFile(ctx, groups) {
|
|
|
256
262
|
diagnosticCount: result.diagnostics.length,
|
|
257
263
|
semantic: result.semantic ?? semantic,
|
|
258
264
|
});
|
|
259
|
-
// Log slow runners immediately for real-time debugging
|
|
260
|
-
if (duration > 500) {
|
|
261
|
-
ctx.log(`⚠️ SLOW RUNNER: ${runnerId} took ${duration}ms (${result.status}, ${result.diagnostics.length} issues)`);
|
|
262
|
-
}
|
|
263
265
|
// Apply delta mode filtering
|
|
264
266
|
let diagnostics = result.diagnostics;
|
|
265
267
|
if (ctx.deltaMode && result.semantic !== "silent") {
|
|
@@ -312,18 +314,9 @@ export async function dispatchForFile(ctx, groups) {
|
|
|
312
314
|
if (latencyReports.length > 100) {
|
|
313
315
|
latencyReports.shift();
|
|
314
316
|
}
|
|
315
|
-
//
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
type: "runner",
|
|
319
|
-
filePath: ctx.filePath,
|
|
320
|
-
runnerId: runner.runnerId,
|
|
321
|
-
durationMs: runner.durationMs,
|
|
322
|
-
status: runner.status,
|
|
323
|
-
diagnosticCount: runner.diagnosticCount,
|
|
324
|
-
semantic: runner.semantic,
|
|
325
|
-
});
|
|
326
|
-
}
|
|
317
|
+
// Runner latencies already logged immediately after execution (line ~329)
|
|
318
|
+
// The runnerLatencies array is stored in latencyReport for aggregate analysis
|
|
319
|
+
// No need to log again here - would create duplicates in the log
|
|
327
320
|
// Log summary to latency log only (not console - avoid noise)
|
|
328
321
|
logLatency({
|
|
329
322
|
type: "tool_result",
|
|
@@ -97,7 +97,8 @@ describe("Dispatch Context", () => {
|
|
|
97
97
|
|
|
98
98
|
const ctx = createDispatchContext("test.ts", "/project", mockPi);
|
|
99
99
|
|
|
100
|
-
|
|
100
|
+
// Path is normalized to absolute path (Windows compatibility)
|
|
101
|
+
expect(ctx.filePath).toContain("test.ts");
|
|
101
102
|
expect(ctx.cwd).toBe("/project");
|
|
102
103
|
expect(ctx.autofix).toBe(false);
|
|
103
104
|
expect(ctx.deltaMode).toBe(true);
|
|
@@ -18,6 +18,7 @@ import type { FileKind } from "../file-kinds.js";
|
|
|
18
18
|
import { detectFileKind } from "../file-kinds.js";
|
|
19
19
|
import { isTestFile } from "../file-utils.js";
|
|
20
20
|
import { logLatency } from "../latency-logger.js";
|
|
21
|
+
import { normalizeMapKey } from "../path-utils.js";
|
|
21
22
|
import { safeSpawn } from "../safe-spawn.js";
|
|
22
23
|
import type {
|
|
23
24
|
BaselineStore,
|
|
@@ -40,10 +41,10 @@ export function createBaselineStore(): BaselineStore {
|
|
|
40
41
|
|
|
41
42
|
return {
|
|
42
43
|
get(filePath) {
|
|
43
|
-
return baselines.get(filePath);
|
|
44
|
+
return baselines.get(normalizeMapKey(filePath));
|
|
44
45
|
},
|
|
45
46
|
set(filePath, diagnostics) {
|
|
46
|
-
baselines.set(filePath, diagnostics);
|
|
47
|
+
baselines.set(normalizeMapKey(filePath), diagnostics);
|
|
47
48
|
},
|
|
48
49
|
clear() {
|
|
49
50
|
baselines.clear();
|
|
@@ -56,10 +57,7 @@ export function createBaselineStore(): BaselineStore {
|
|
|
56
57
|
const globalRegistry = new Map<string, RunnerDefinition>();
|
|
57
58
|
|
|
58
59
|
export function registerRunner(runner: RunnerDefinition): void {
|
|
59
|
-
if (globalRegistry.has(runner.id))
|
|
60
|
-
console.error(`[dispatch] Duplicate runner: ${runner.id}`);
|
|
61
|
-
return;
|
|
62
|
-
}
|
|
60
|
+
if (globalRegistry.has(runner.id)) return; // Already registered, skip silently
|
|
63
61
|
globalRegistry.set(runner.id, runner);
|
|
64
62
|
}
|
|
65
63
|
|
|
@@ -127,10 +125,12 @@ export function createDispatchContext(
|
|
|
127
125
|
baselines?: BaselineStore,
|
|
128
126
|
blockingOnly?: boolean,
|
|
129
127
|
): DispatchContext {
|
|
130
|
-
|
|
128
|
+
// Normalize path for consistent Map key usage on Windows
|
|
129
|
+
const normalizedFilePath = normalizeMapKey(filePath);
|
|
130
|
+
const kind = detectFileKind(normalizedFilePath);
|
|
131
131
|
|
|
132
132
|
return {
|
|
133
|
-
filePath,
|
|
133
|
+
filePath: normalizedFilePath,
|
|
134
134
|
cwd,
|
|
135
135
|
kind,
|
|
136
136
|
pi,
|
|
@@ -267,12 +267,17 @@ export async function dispatchForFile(
|
|
|
267
267
|
const runnerLatencies: RunnerLatency[] = [];
|
|
268
268
|
|
|
269
269
|
// Debug logging goes to latency log only (not console - avoid noise)
|
|
270
|
+
const allRunnerIds = groups.flatMap((g) => g.runnerIds);
|
|
270
271
|
logLatency({
|
|
271
272
|
type: "phase",
|
|
272
273
|
filePath: ctx.filePath,
|
|
273
274
|
phase: "dispatch_start",
|
|
274
275
|
durationMs: 0,
|
|
275
|
-
metadata: {
|
|
276
|
+
metadata: {
|
|
277
|
+
groupCount: groups.length,
|
|
278
|
+
kind: ctx.kind,
|
|
279
|
+
runners: allRunnerIds.join(","),
|
|
280
|
+
},
|
|
276
281
|
});
|
|
277
282
|
|
|
278
283
|
for (const group of groups) {
|
|
@@ -364,13 +369,6 @@ export async function dispatchForFile(
|
|
|
364
369
|
semantic: result.semantic ?? semantic,
|
|
365
370
|
});
|
|
366
371
|
|
|
367
|
-
// Log slow runners immediately for real-time debugging
|
|
368
|
-
if (duration > 500) {
|
|
369
|
-
ctx.log(
|
|
370
|
-
`⚠️ SLOW RUNNER: ${runnerId} took ${duration}ms (${result.status}, ${result.diagnostics.length} issues)`,
|
|
371
|
-
);
|
|
372
|
-
}
|
|
373
|
-
|
|
374
372
|
// Apply delta mode filtering
|
|
375
373
|
let diagnostics = result.diagnostics;
|
|
376
374
|
if (ctx.deltaMode && result.semantic !== "silent") {
|
|
@@ -437,18 +435,9 @@ export async function dispatchForFile(
|
|
|
437
435
|
latencyReports.shift();
|
|
438
436
|
}
|
|
439
437
|
|
|
440
|
-
//
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
type: "runner",
|
|
444
|
-
filePath: ctx.filePath,
|
|
445
|
-
runnerId: runner.runnerId,
|
|
446
|
-
durationMs: runner.durationMs,
|
|
447
|
-
status: runner.status,
|
|
448
|
-
diagnosticCount: runner.diagnosticCount,
|
|
449
|
-
semantic: runner.semantic,
|
|
450
|
-
});
|
|
451
|
-
}
|
|
438
|
+
// Runner latencies already logged immediately after execution (line ~329)
|
|
439
|
+
// The runnerLatencies array is stored in latencyReport for aggregate analysis
|
|
440
|
+
// No need to log again here - would create duplicates in the log
|
|
452
441
|
|
|
453
442
|
// Log summary to latency log only (not console - avoid noise)
|
|
454
443
|
logLatency({
|
package/clients/dispatch/plan.js
CHANGED
|
@@ -11,6 +11,13 @@
|
|
|
11
11
|
*/
|
|
12
12
|
/**
|
|
13
13
|
* Tool plans organized by purpose
|
|
14
|
+
*
|
|
15
|
+
* CORE PRINCIPLE: File write only runs BLOCKING tools
|
|
16
|
+
* - Type checking (LSP) - blocking errors
|
|
17
|
+
* - Security/correctness lint - blocking errors
|
|
18
|
+
* - Auto-format/auto-fix handled by direct calls in index.ts (not here)
|
|
19
|
+
*
|
|
20
|
+
* Warning-only tools run on /lens-booboo command only
|
|
14
21
|
*/
|
|
15
22
|
export const TOOL_PLANS = {
|
|
16
23
|
/**
|
|
@@ -19,17 +26,18 @@ export const TOOL_PLANS = {
|
|
|
19
26
|
jsts: {
|
|
20
27
|
name: "JavaScript/TypeScript Linting",
|
|
21
28
|
groups: [
|
|
22
|
-
//
|
|
23
|
-
{ mode: "all", runnerIds: ["
|
|
24
|
-
//
|
|
25
|
-
{ mode: "
|
|
26
|
-
//
|
|
27
|
-
|
|
28
|
-
//
|
|
29
|
-
|
|
29
|
+
// LSP type checking (unified for all languages) - priority 4, blocking errors
|
|
30
|
+
{ mode: "all", runnerIds: ["lsp"], filterKinds: ["jsts"] },
|
|
31
|
+
// Tree-sitter native structural analysis (blocking rules: constructor-super, dangerouslySetInnerHTML, etc.)
|
|
32
|
+
{ mode: "all", runnerIds: ["tree-sitter"], filterKinds: ["jsts"] },
|
|
33
|
+
// AST structural analysis (blocking: no-dupe-keys, no-hardcoded-secrets, jwt-no-verify, etc.)
|
|
34
|
+
// DISABLED in post-write - ast-grep-napi can crash. Runs via /lens-booboo only.
|
|
35
|
+
// { mode: "all", runnerIds: ["ast-grep-napi"], filterKinds: ["jsts"] },
|
|
36
|
+
// Type safety checks (has some blocking errors)
|
|
37
|
+
{ mode: "fallback", runnerIds: ["type-safety"], filterKinds: ["jsts"] },
|
|
30
38
|
// Note: ast-grep CLI kept for ast_grep_search/ast_grep_replace tools only
|
|
31
|
-
//
|
|
32
|
-
|
|
39
|
+
// Note: biome, oxlint handled by direct auto-fix calls in index.ts (not in dispatch)
|
|
40
|
+
// Architectural rules (guidance only, not blocking) - runs via /lens-booboo only
|
|
33
41
|
],
|
|
34
42
|
},
|
|
35
43
|
/**
|
|
@@ -38,10 +46,13 @@ export const TOOL_PLANS = {
|
|
|
38
46
|
python: {
|
|
39
47
|
name: "Python Linting",
|
|
40
48
|
groups: [
|
|
41
|
-
//
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
49
|
+
// Pyright type checking (standard mode - no LSP flag needed)
|
|
50
|
+
// Provides Python type errors in standard pi mode
|
|
51
|
+
{ mode: "all", runnerIds: ["pyright"], filterKinds: ["python"] },
|
|
52
|
+
// LSP type checking (unified) - when --lens-lsp enabled
|
|
53
|
+
{ mode: "all", runnerIds: ["lsp"], filterKinds: ["python"] },
|
|
54
|
+
// Note: ruff handled by direct auto-fix calls in index.ts (not in dispatch)
|
|
55
|
+
// Architectural rules (guidance only, not blocking) - runs via /lens-booboo only
|
|
45
56
|
],
|
|
46
57
|
},
|
|
47
58
|
/**
|
|
@@ -50,10 +61,11 @@ export const TOOL_PLANS = {
|
|
|
50
61
|
go: {
|
|
51
62
|
name: "Go Linting",
|
|
52
63
|
groups: [
|
|
53
|
-
//
|
|
54
|
-
{ mode: "
|
|
55
|
-
//
|
|
56
|
-
{ mode: "fallback", runnerIds: ["
|
|
64
|
+
// LSP type checking (gopls)
|
|
65
|
+
{ mode: "all", runnerIds: ["lsp"], filterKinds: ["go"] },
|
|
66
|
+
// Go vet for additional checks (warning only, but low cost)
|
|
67
|
+
{ mode: "fallback", runnerIds: ["go-vet"], filterKinds: ["go"] },
|
|
68
|
+
// Architectural rules (guidance only, not blocking) - runs via /lens-booboo only
|
|
57
69
|
],
|
|
58
70
|
},
|
|
59
71
|
/**
|
|
@@ -62,10 +74,11 @@ export const TOOL_PLANS = {
|
|
|
62
74
|
rust: {
|
|
63
75
|
name: "Rust Linting",
|
|
64
76
|
groups: [
|
|
65
|
-
//
|
|
66
|
-
{ mode: "
|
|
67
|
-
//
|
|
68
|
-
{ mode: "fallback", runnerIds: ["
|
|
77
|
+
// LSP type checking (rust-analyzer)
|
|
78
|
+
{ mode: "all", runnerIds: ["lsp"], filterKinds: ["rust"] },
|
|
79
|
+
// Cargo clippy for additional checks
|
|
80
|
+
{ mode: "fallback", runnerIds: ["rust-clippy"], filterKinds: ["rust"] },
|
|
81
|
+
// Architectural rules (guidance only, not blocking) - runs via /lens-booboo only
|
|
69
82
|
],
|
|
70
83
|
},
|
|
71
84
|
/**
|
|
@@ -74,8 +87,7 @@ export const TOOL_PLANS = {
|
|
|
74
87
|
cxx: {
|
|
75
88
|
name: "C/C++ Linting",
|
|
76
89
|
groups: [
|
|
77
|
-
|
|
78
|
-
{ mode: "fallback", runnerIds: ["architect"] },
|
|
90
|
+
// Architectural rules (guidance only, not blocking) - runs via /lens-booboo only
|
|
79
91
|
],
|
|
80
92
|
},
|
|
81
93
|
/**
|
|
@@ -84,8 +96,8 @@ export const TOOL_PLANS = {
|
|
|
84
96
|
json: {
|
|
85
97
|
name: "JSON Processing",
|
|
86
98
|
groups: [
|
|
87
|
-
|
|
88
|
-
|
|
99
|
+
// Note: Biome handles JSON formatting via direct call in index.ts
|
|
100
|
+
// No additional linting needed for JSON
|
|
89
101
|
],
|
|
90
102
|
},
|
|
91
103
|
/**
|
|
@@ -94,7 +106,7 @@ export const TOOL_PLANS = {
|
|
|
94
106
|
markdown: {
|
|
95
107
|
name: "Markdown Processing",
|
|
96
108
|
groups: [
|
|
97
|
-
// Spellcheck for typos
|
|
109
|
+
// Spellcheck for typos (warning only, but useful)
|
|
98
110
|
{ mode: "fallback", runnerIds: ["spellcheck"] },
|
|
99
111
|
],
|
|
100
112
|
},
|
|
@@ -104,10 +116,9 @@ export const TOOL_PLANS = {
|
|
|
104
116
|
shell: {
|
|
105
117
|
name: "Shell Script Linting",
|
|
106
118
|
groups: [
|
|
107
|
-
// Shellcheck for bash/sh/zsh linting
|
|
119
|
+
// Shellcheck for bash/sh/zsh linting (has blocking errors for syntax)
|
|
108
120
|
{ mode: "fallback", runnerIds: ["shellcheck"] },
|
|
109
|
-
// Architectural rules
|
|
110
|
-
{ mode: "fallback", runnerIds: ["architect"] },
|
|
121
|
+
// Architectural rules (guidance only, not blocking) - runs via /lens-booboo only
|
|
111
122
|
],
|
|
112
123
|
},
|
|
113
124
|
/**
|
|
@@ -116,8 +127,7 @@ export const TOOL_PLANS = {
|
|
|
116
127
|
cmake: {
|
|
117
128
|
name: "CMake Processing",
|
|
118
129
|
groups: [
|
|
119
|
-
|
|
120
|
-
{ mode: "fallback", runnerIds: ["architect"] },
|
|
130
|
+
// Architectural rules (guidance only, not blocking) - runs via /lens-booboo only
|
|
121
131
|
],
|
|
122
132
|
},
|
|
123
133
|
};
|
|
@@ -133,3 +143,38 @@ export function getToolPlan(kind) {
|
|
|
133
143
|
export function getAllToolPlans() {
|
|
134
144
|
return TOOL_PLANS;
|
|
135
145
|
}
|
|
146
|
+
/**
|
|
147
|
+
* Full lint plan for /lens-booboo command (includes warning-only tools)
|
|
148
|
+
* This includes ALL runners for comprehensive analysis
|
|
149
|
+
*/
|
|
150
|
+
export const FULL_LINT_PLANS = {
|
|
151
|
+
...TOOL_PLANS,
|
|
152
|
+
// Override jsts to include warning-only tools
|
|
153
|
+
jsts: {
|
|
154
|
+
name: "JavaScript/TypeScript Full Lint",
|
|
155
|
+
groups: [
|
|
156
|
+
{ mode: "all", runnerIds: ["lsp"], filterKinds: ["jsts"] },
|
|
157
|
+
{ mode: "all", runnerIds: ["tree-sitter"], filterKinds: ["jsts"] },
|
|
158
|
+
{ mode: "all", runnerIds: ["ast-grep-napi"], filterKinds: ["jsts"] },
|
|
159
|
+
// Warning-only tools (for full lint, not file write)
|
|
160
|
+
{
|
|
161
|
+
mode: "fallback",
|
|
162
|
+
runnerIds: ["biome-lint", "oxlint"],
|
|
163
|
+
filterKinds: ["jsts"],
|
|
164
|
+
},
|
|
165
|
+
{ mode: "fallback", runnerIds: ["type-safety"], filterKinds: ["jsts"] },
|
|
166
|
+
{ mode: "fallback", runnerIds: ["architect"], filterKinds: ["jsts"] },
|
|
167
|
+
],
|
|
168
|
+
},
|
|
169
|
+
// Override python to include warning-only tools
|
|
170
|
+
python: {
|
|
171
|
+
name: "Python Full Lint",
|
|
172
|
+
groups: [
|
|
173
|
+
{ mode: "all", runnerIds: ["lsp"], filterKinds: ["python"] },
|
|
174
|
+
// Warning-only tools
|
|
175
|
+
{ mode: "fallback", runnerIds: ["ruff-lint"], filterKinds: ["python"] },
|
|
176
|
+
{ mode: "fallback", runnerIds: ["python-slop"], filterKinds: ["python"] },
|
|
177
|
+
{ mode: "fallback", runnerIds: ["architect"], filterKinds: ["python"] },
|
|
178
|
+
],
|
|
179
|
+
},
|
|
180
|
+
};
|