pi-lens 3.2.0 → 3.3.1
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 +20 -0
- package/README.md +4 -10
- package/clients/__tests__/file-time.test.js +216 -0
- package/clients/__tests__/format-service.test.js +245 -0
- package/clients/__tests__/formatters.test.js +271 -0
- package/clients/agent-behavior-client.test.js +94 -0
- package/clients/biome-client.test.js +144 -0
- package/clients/cache-manager.test.js +197 -0
- package/clients/complexity-client.test.js +234 -0
- package/clients/dependency-checker.test.js +60 -0
- package/clients/dispatch/__tests__/autofix-integration.test.js +245 -0
- package/clients/dispatch/__tests__/runner-registration.test.js +234 -0
- package/clients/dispatch/__tests__/runner-registration.test.ts +2 -2
- package/clients/dispatch/dispatcher.edge.test.js +82 -0
- package/clients/dispatch/dispatcher.format.test.js +46 -0
- package/clients/dispatch/dispatcher.inline.test.js +74 -0
- package/clients/dispatch/dispatcher.test.js +116 -0
- package/clients/dispatch/runners/architect.test.js +138 -0
- package/clients/dispatch/runners/ast-grep-napi.test.js +106 -0
- package/clients/dispatch/runners/lsp.js +42 -5
- package/clients/dispatch/runners/oxlint.test.js +230 -0
- package/clients/dispatch/runners/pyright.test.js +98 -0
- package/clients/dispatch/runners/python-slop.test.js +203 -0
- package/clients/dispatch/runners/scan_codebase.test.js +89 -0
- package/clients/dispatch/runners/shellcheck.test.js +98 -0
- package/clients/dispatch/runners/spellcheck.test.js +158 -0
- package/clients/dispatch/utils/format-utils.js +1 -6
- package/clients/dispatch/utils/format-utils.ts +1 -6
- package/clients/dogfood.test.js +201 -0
- package/clients/file-kinds.test.js +169 -0
- package/clients/formatters.js +1 -1
- package/clients/go-client.test.js +127 -0
- package/clients/jscpd-client.test.js +127 -0
- package/clients/knip-client.test.js +112 -0
- package/clients/lsp/__tests__/client.test.js +310 -0
- package/clients/lsp/__tests__/client.test.ts +1 -46
- package/clients/lsp/__tests__/config.test.js +167 -0
- package/clients/lsp/__tests__/error-recovery.test.js +213 -0
- package/clients/lsp/__tests__/integration.test.js +127 -0
- package/clients/lsp/__tests__/launch.test.js +313 -0
- package/clients/lsp/__tests__/server.test.js +259 -0
- package/clients/lsp/__tests__/service.test.js +435 -0
- package/clients/lsp/client.js +32 -44
- package/clients/lsp/client.ts +36 -45
- package/clients/lsp/launch.js +11 -6
- package/clients/lsp/launch.ts +11 -6
- package/clients/lsp/server.js +27 -2
- package/clients/metrics-client.test.js +141 -0
- package/clients/ruff-client.test.js +132 -0
- package/clients/rust-client.test.js +108 -0
- package/clients/sanitize.test.js +177 -0
- package/clients/secrets-scanner.test.js +100 -0
- package/clients/test-runner-client.test.js +192 -0
- package/clients/todo-scanner.test.js +301 -0
- package/clients/type-coverage-client.test.js +105 -0
- package/clients/typescript-client.codefix.test.js +157 -0
- package/clients/typescript-client.test.js +105 -0
- package/commands/rate.test.js +119 -0
- package/index.ts +66 -72
- package/package.json +1 -1
- package/clients/bus/bus.js +0 -191
- package/clients/bus/bus.ts +0 -251
- package/clients/bus/events.js +0 -214
- package/clients/bus/events.ts +0 -279
- package/clients/bus/index.js +0 -8
- package/clients/bus/index.ts +0 -9
- package/clients/bus/integration.js +0 -158
- package/clients/bus/integration.ts +0 -227
- package/clients/dispatch/bus-dispatcher.js +0 -178
- package/clients/dispatch/bus-dispatcher.ts +0 -258
- package/clients/services/__tests__/effect-integration.test.ts +0 -111
- package/clients/services/effect-integration.js +0 -198
- package/clients/services/effect-integration.ts +0 -276
- package/clients/services/index.js +0 -7
- package/clients/services/index.ts +0 -8
- package/clients/services/runner-service.js +0 -134
- package/clients/services/runner-service.ts +0 -225
|
@@ -1,225 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Effect-TS Service Infrastructure for pi-lens
|
|
3
|
-
*
|
|
4
|
-
* Simplified implementation focusing on:
|
|
5
|
-
* - Concurrent runner execution with resource limits
|
|
6
|
-
* - Timeout handling with proper process cleanup
|
|
7
|
-
* - Error recovery
|
|
8
|
-
*/
|
|
9
|
-
|
|
10
|
-
import { Effect } from "effect";
|
|
11
|
-
|
|
12
|
-
// --- Configuration ---
|
|
13
|
-
|
|
14
|
-
/** Maximum concurrent runner processes to prevent resource contention */
|
|
15
|
-
const DEFAULT_CONCURRENCY = 3;
|
|
16
|
-
|
|
17
|
-
/** Maximum concurrent formatters */
|
|
18
|
-
const DEFAULT_FORMATTER_CONCURRENCY = 2;
|
|
19
|
-
|
|
20
|
-
// --- Error Types ---
|
|
21
|
-
|
|
22
|
-
export class RunnerError {
|
|
23
|
-
readonly _tag = "RunnerError";
|
|
24
|
-
constructor(
|
|
25
|
-
readonly runnerId: string,
|
|
26
|
-
readonly cause: unknown,
|
|
27
|
-
) {}
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
export class TimeoutError {
|
|
31
|
-
readonly _tag = "TimeoutError";
|
|
32
|
-
constructor(
|
|
33
|
-
readonly operation: string,
|
|
34
|
-
readonly timeoutMs: number,
|
|
35
|
-
) {}
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
// --- Result Types ---
|
|
39
|
-
|
|
40
|
-
export interface RunnerResult {
|
|
41
|
-
diagnostics: Array<{
|
|
42
|
-
id: string;
|
|
43
|
-
message: string;
|
|
44
|
-
severity: "error" | "warning" | "info" | "hint";
|
|
45
|
-
semantic?: "blocking" | "warning" | "fixed" | "silent" | "none";
|
|
46
|
-
}>;
|
|
47
|
-
durationMs: number;
|
|
48
|
-
error?: string;
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
export interface ConcurrentRunnerResult {
|
|
52
|
-
runnerId: string;
|
|
53
|
-
status: "success" | "failure" | "skipped";
|
|
54
|
-
diagnostics: Array<{
|
|
55
|
-
id: string;
|
|
56
|
-
message: string;
|
|
57
|
-
severity: "error" | "warning" | "info" | "hint";
|
|
58
|
-
semantic?: "blocking" | "warning" | "fixed" | "silent" | "none";
|
|
59
|
-
}>;
|
|
60
|
-
durationMs: number;
|
|
61
|
-
error?: string;
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
// --- Concurrent Execution Helper ---
|
|
65
|
-
|
|
66
|
-
/**
|
|
67
|
-
* Run multiple runners concurrently with Effect
|
|
68
|
-
*
|
|
69
|
-
* Features:
|
|
70
|
-
* - Parallel execution with Effect.all (limited concurrency to prevent resource exhaustion)
|
|
71
|
-
* - Per-runner timeout handling
|
|
72
|
-
* - Graceful error recovery (individual failures don't stop others)
|
|
73
|
-
* - Automatic resource cleanup
|
|
74
|
-
*
|
|
75
|
-
* Concurrency is limited to DEFAULT_CONCURRENCY (3) to prevent:
|
|
76
|
-
* - CPU thrashing from too many parallel processes
|
|
77
|
-
* - Memory exhaustion from large LSP initializations
|
|
78
|
-
* - File descriptor exhaustion
|
|
79
|
-
*/
|
|
80
|
-
export function runRunnersConcurrent(
|
|
81
|
-
filePath: string,
|
|
82
|
-
runnerIds: string[],
|
|
83
|
-
runSingle: (filePath: string, runnerId: string) => Promise<RunnerResult>,
|
|
84
|
-
timeoutMs = 30_000,
|
|
85
|
-
concurrency = DEFAULT_CONCURRENCY,
|
|
86
|
-
): Effect.Effect<ConcurrentRunnerResult[], never, never> {
|
|
87
|
-
return Effect.gen(function* () {
|
|
88
|
-
const _startTime = Date.now();
|
|
89
|
-
|
|
90
|
-
// Run runners with limited concurrency
|
|
91
|
-
// This prevents resource contention when many linters are configured
|
|
92
|
-
const results = yield* Effect.all(
|
|
93
|
-
runnerIds.map((runnerId) =>
|
|
94
|
-
Effect.gen(function* () {
|
|
95
|
-
const runnerStart = Date.now();
|
|
96
|
-
|
|
97
|
-
// Execute with timeout and error handling
|
|
98
|
-
const result = yield* Effect.tryPromise({
|
|
99
|
-
try: () => runSingle(filePath, runnerId),
|
|
100
|
-
catch: (err) => err,
|
|
101
|
-
}).pipe(
|
|
102
|
-
Effect.timeout(timeoutMs),
|
|
103
|
-
Effect.catchAll((err) =>
|
|
104
|
-
Effect.succeed({
|
|
105
|
-
diagnostics: [],
|
|
106
|
-
durationMs: Date.now() - runnerStart,
|
|
107
|
-
error: String(err),
|
|
108
|
-
}),
|
|
109
|
-
),
|
|
110
|
-
);
|
|
111
|
-
|
|
112
|
-
const isError = "error" in result;
|
|
113
|
-
|
|
114
|
-
return {
|
|
115
|
-
runnerId,
|
|
116
|
-
status: isError ? ("failure" as const) : ("success" as const),
|
|
117
|
-
diagnostics: isError ? [] : result.diagnostics,
|
|
118
|
-
durationMs: isError ? result.durationMs : result.durationMs,
|
|
119
|
-
error: isError ? result.error : undefined,
|
|
120
|
-
};
|
|
121
|
-
}),
|
|
122
|
-
),
|
|
123
|
-
{ concurrency }, // Limited concurrency to prevent resource exhaustion
|
|
124
|
-
);
|
|
125
|
-
|
|
126
|
-
return results;
|
|
127
|
-
});
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
/**
|
|
131
|
-
* Run multiple formatters concurrently with limited concurrency
|
|
132
|
-
*
|
|
133
|
-
* Formatters are typically I/O bound, so we can be slightly more aggressive
|
|
134
|
-
* than runners, but still limit to prevent overwhelming the system.
|
|
135
|
-
*/
|
|
136
|
-
export function runFormattersConcurrent<T>(
|
|
137
|
-
formatters: Array<() => Promise<T>>,
|
|
138
|
-
timeoutMs = 30_000,
|
|
139
|
-
concurrency = DEFAULT_FORMATTER_CONCURRENCY,
|
|
140
|
-
): Effect.Effect<T[], never, never> {
|
|
141
|
-
return Effect.gen(function* () {
|
|
142
|
-
const results = yield* Effect.all(
|
|
143
|
-
formatters.map((formatter) =>
|
|
144
|
-
Effect.gen(function* () {
|
|
145
|
-
const result = yield* Effect.tryPromise({
|
|
146
|
-
try: () => formatter(),
|
|
147
|
-
catch: (err) => err,
|
|
148
|
-
}).pipe(
|
|
149
|
-
Effect.timeout(timeoutMs),
|
|
150
|
-
Effect.catchAll((err) => Effect.succeed(err as T)),
|
|
151
|
-
);
|
|
152
|
-
return result;
|
|
153
|
-
}),
|
|
154
|
-
),
|
|
155
|
-
{ concurrency },
|
|
156
|
-
);
|
|
157
|
-
return results;
|
|
158
|
-
});
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
/**
|
|
162
|
-
* Run a single runner with timeout and error handling
|
|
163
|
-
*/
|
|
164
|
-
export function runRunnerWithTimeout(
|
|
165
|
-
filePath: string,
|
|
166
|
-
runnerId: string,
|
|
167
|
-
runSingle: (filePath: string, runnerId: string) => Promise<RunnerResult>,
|
|
168
|
-
timeoutMs = 30_000,
|
|
169
|
-
): Effect.Effect<RunnerResult, RunnerError | TimeoutError, never> {
|
|
170
|
-
return Effect.gen(function* () {
|
|
171
|
-
const startTime = Date.now();
|
|
172
|
-
|
|
173
|
-
const result = yield* Effect.tryPromise({
|
|
174
|
-
try: () => runSingle(filePath, runnerId),
|
|
175
|
-
catch: (err) => new RunnerError(runnerId, err),
|
|
176
|
-
}).pipe(
|
|
177
|
-
Effect.timeout(timeoutMs),
|
|
178
|
-
Effect.mapError((err) => {
|
|
179
|
-
if (err instanceof RunnerError) return err;
|
|
180
|
-
return new TimeoutError(`runner:${runnerId}`, timeoutMs);
|
|
181
|
-
}),
|
|
182
|
-
);
|
|
183
|
-
|
|
184
|
-
return {
|
|
185
|
-
diagnostics: result.diagnostics,
|
|
186
|
-
durationMs: Date.now() - startTime,
|
|
187
|
-
};
|
|
188
|
-
});
|
|
189
|
-
}
|
|
190
|
-
|
|
191
|
-
// --- Execution Helpers ---
|
|
192
|
-
|
|
193
|
-
/**
|
|
194
|
-
* Execute Effect and get result
|
|
195
|
-
*/
|
|
196
|
-
export function executeEffect<T>(
|
|
197
|
-
effect: Effect.Effect<T, never, never>,
|
|
198
|
-
): Promise<T> {
|
|
199
|
-
return Effect.runPromise(effect);
|
|
200
|
-
}
|
|
201
|
-
|
|
202
|
-
/**
|
|
203
|
-
* Execute Effect with error handling
|
|
204
|
-
*/
|
|
205
|
-
export function executeEffectWithError<T, E>(
|
|
206
|
-
effect: Effect.Effect<T, E, never>,
|
|
207
|
-
onError: (err: E) => T,
|
|
208
|
-
): Promise<T> {
|
|
209
|
-
return Effect.runPromise(
|
|
210
|
-
Effect.catchAll(effect, (err) => Effect.succeed(onError(err))),
|
|
211
|
-
);
|
|
212
|
-
}
|
|
213
|
-
|
|
214
|
-
// --- Error Formatting ---
|
|
215
|
-
|
|
216
|
-
export function formatError(err: RunnerError | TimeoutError): string {
|
|
217
|
-
switch (err._tag) {
|
|
218
|
-
case "RunnerError":
|
|
219
|
-
return `Runner ${err.runnerId} failed: ${err.cause}`;
|
|
220
|
-
case "TimeoutError":
|
|
221
|
-
return `Operation ${err.operation} timed out after ${err.timeoutMs}ms`;
|
|
222
|
-
default:
|
|
223
|
-
return "Unknown error";
|
|
224
|
-
}
|
|
225
|
-
}
|