pi-lens 3.6.2 → 3.6.4
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 +10 -2
- package/package.json +4 -4
- package/tsconfig.json +1 -1
- package/clients/__tests__/file-time.test.js +0 -216
- package/clients/__tests__/file-time.test.ts +0 -276
- package/clients/__tests__/format-service.test.js +0 -245
- package/clients/__tests__/format-service.test.ts +0 -339
- package/clients/__tests__/formatters.test.js +0 -271
- package/clients/__tests__/formatters.test.ts +0 -401
- package/clients/agent-behavior-client.js +0 -110
- package/clients/agent-behavior-client.test.js +0 -94
- package/clients/agent-behavior-client.test.ts +0 -116
- package/clients/amain-types.js +0 -164
- package/clients/architect-client.js +0 -291
- package/clients/ast-grep-client.js +0 -253
- package/clients/ast-grep-parser.js +0 -84
- package/clients/ast-grep-rule-manager.js +0 -89
- package/clients/ast-grep-types.js +0 -9
- package/clients/auto-loop.js +0 -131
- package/clients/biome-client.js +0 -420
- package/clients/biome-client.test.js +0 -144
- package/clients/biome-client.test.ts +0 -163
- package/clients/cache/rule-cache.js +0 -72
- package/clients/cache-manager.js +0 -245
- package/clients/cache-manager.test.js +0 -197
- package/clients/cache-manager.test.ts +0 -299
- package/clients/complexity-client.js +0 -675
- package/clients/complexity-client.test.js +0 -234
- package/clients/complexity-client.test.ts +0 -255
- package/clients/config-validator.js +0 -465
- package/clients/dependency-checker.js +0 -325
- package/clients/dependency-checker.test.js +0 -60
- package/clients/dependency-checker.test.ts +0 -71
- package/clients/dispatch/__tests__/autofix-integration.test.js +0 -245
- package/clients/dispatch/__tests__/autofix-integration.test.ts +0 -300
- package/clients/dispatch/__tests__/runner-registration.test.js +0 -234
- package/clients/dispatch/__tests__/runner-registration.test.ts +0 -286
- package/clients/dispatch/debug.log +0 -1
- package/clients/dispatch/dispatcher.edge.test.js +0 -82
- package/clients/dispatch/dispatcher.edge.test.ts +0 -100
- package/clients/dispatch/dispatcher.format.test.js +0 -46
- package/clients/dispatch/dispatcher.format.test.ts +0 -58
- package/clients/dispatch/dispatcher.inline.test.js +0 -74
- package/clients/dispatch/dispatcher.inline.test.ts +0 -93
- package/clients/dispatch/dispatcher.js +0 -381
- package/clients/dispatch/dispatcher.test.js +0 -116
- package/clients/dispatch/dispatcher.test.ts +0 -149
- package/clients/dispatch/integration.js +0 -108
- package/clients/dispatch/plan.js +0 -183
- package/clients/dispatch/runners/architect.js +0 -83
- package/clients/dispatch/runners/architect.test.js +0 -138
- package/clients/dispatch/runners/architect.test.ts +0 -162
- package/clients/dispatch/runners/ast-grep-napi.js +0 -405
- package/clients/dispatch/runners/ast-grep-napi.test.js +0 -107
- package/clients/dispatch/runners/ast-grep-napi.test.ts +0 -129
- package/clients/dispatch/runners/ast-grep.js +0 -157
- package/clients/dispatch/runners/biome.js +0 -55
- package/clients/dispatch/runners/config-validation.js +0 -67
- package/clients/dispatch/runners/go-vet.js +0 -48
- package/clients/dispatch/runners/index.js +0 -47
- package/clients/dispatch/runners/lsp.js +0 -102
- package/clients/dispatch/runners/oxlint.js +0 -67
- package/clients/dispatch/runners/oxlint.test.js +0 -230
- package/clients/dispatch/runners/oxlint.test.ts +0 -303
- package/clients/dispatch/runners/pyright.js +0 -100
- package/clients/dispatch/runners/pyright.test.js +0 -98
- package/clients/dispatch/runners/pyright.test.ts +0 -121
- package/clients/dispatch/runners/python-slop.js +0 -97
- package/clients/dispatch/runners/python-slop.test.js +0 -203
- package/clients/dispatch/runners/python-slop.test.ts +0 -298
- package/clients/dispatch/runners/ruff.js +0 -48
- package/clients/dispatch/runners/rust-clippy.js +0 -102
- package/clients/dispatch/runners/scan_codebase.test.js +0 -89
- package/clients/dispatch/runners/scan_codebase.test.ts +0 -105
- package/clients/dispatch/runners/shellcheck.js +0 -147
- package/clients/dispatch/runners/shellcheck.test.js +0 -98
- package/clients/dispatch/runners/shellcheck.test.ts +0 -129
- package/clients/dispatch/runners/similarity.js +0 -230
- package/clients/dispatch/runners/spellcheck.js +0 -106
- package/clients/dispatch/runners/spellcheck.test.js +0 -158
- package/clients/dispatch/runners/spellcheck.test.ts +0 -214
- package/clients/dispatch/runners/tree-sitter.js +0 -246
- package/clients/dispatch/runners/ts-lsp.js +0 -125
- package/clients/dispatch/runners/ts-slop.js +0 -113
- package/clients/dispatch/runners/type-safety.js +0 -142
- package/clients/dispatch/runners/utils/diagnostic-parsers.js +0 -134
- package/clients/dispatch/runners/utils/runner-helpers.js +0 -115
- package/clients/dispatch/runners/utils.js +0 -51
- package/clients/dispatch/runners/yaml-rule-parser.js +0 -360
- package/clients/dispatch/types.js +0 -16
- package/clients/dispatch/utils/format-utils.js +0 -44
- package/clients/dogfood.test.js +0 -201
- package/clients/dogfood.test.ts +0 -269
- package/clients/file-kinds.js +0 -177
- package/clients/file-kinds.test.js +0 -169
- package/clients/file-kinds.test.ts +0 -210
- package/clients/file-time.js +0 -152
- package/clients/file-utils.js +0 -40
- package/clients/fix-scanners.js +0 -204
- package/clients/format-service.js +0 -184
- package/clients/formatters.js +0 -488
- package/clients/go-client.js +0 -203
- package/clients/go-client.test.js +0 -127
- package/clients/go-client.test.ts +0 -143
- package/clients/installer/index.js +0 -403
- package/clients/interviewer-templates.js +0 -75
- package/clients/interviewer.js +0 -173
- package/clients/jscpd-client.js +0 -196
- package/clients/jscpd-client.test.js +0 -127
- package/clients/jscpd-client.test.ts +0 -145
- package/clients/knip-client.js +0 -239
- package/clients/knip-client.test.js +0 -112
- package/clients/knip-client.test.ts +0 -128
- package/clients/latency-logger.js +0 -40
- package/clients/lsp/__tests__/client.test.js +0 -310
- package/clients/lsp/__tests__/client.test.ts +0 -412
- package/clients/lsp/__tests__/config.test.js +0 -167
- package/clients/lsp/__tests__/config.test.ts +0 -217
- package/clients/lsp/__tests__/error-recovery.test.js +0 -213
- package/clients/lsp/__tests__/error-recovery.test.ts +0 -279
- package/clients/lsp/__tests__/integration.test.js +0 -127
- package/clients/lsp/__tests__/integration.test.ts +0 -160
- package/clients/lsp/__tests__/launch.test.js +0 -313
- package/clients/lsp/__tests__/launch.test.ts +0 -394
- package/clients/lsp/__tests__/server.test.js +0 -259
- package/clients/lsp/__tests__/server.test.ts +0 -332
- package/clients/lsp/__tests__/service.test.js +0 -438
- package/clients/lsp/__tests__/service.test.ts +0 -530
- package/clients/lsp/client.js +0 -350
- package/clients/lsp/config.js +0 -112
- package/clients/lsp/index.js +0 -318
- package/clients/lsp/installer/index.js +0 -391
- package/clients/lsp/interactive-install.js +0 -221
- package/clients/lsp/language.js +0 -170
- package/clients/lsp/launch.js +0 -329
- package/clients/lsp/lsp/launch.js +0 -116
- package/clients/lsp/lsp/server.js +0 -532
- package/clients/lsp/lsp-index.js +0 -10
- package/clients/lsp/path-utils.js +0 -5
- package/clients/lsp/server.js +0 -725
- package/clients/lsp/test-py-spawn/requirements.txt +0 -1
- package/clients/lsp/test-py-spawn/test.py +0 -3
- package/clients/lsp/test-py-svc/requirements.txt +0 -1
- package/clients/lsp/test-py-svc/test.py +0 -3
- package/clients/lsp/test-python-project/requirements.txt +0 -1
- package/clients/lsp/test-python-project/test.py +0 -5
- package/clients/metrics-client.js +0 -107
- package/clients/metrics-client.test.js +0 -128
- package/clients/metrics-client.test.ts +0 -163
- package/clients/metrics-history.js +0 -367
- package/clients/path-utils.js +0 -142
- package/clients/pipeline.js +0 -272
- package/clients/production-readiness.js +0 -522
- package/clients/project-index.js +0 -255
- package/clients/project-metadata.js +0 -531
- package/clients/ruff-client.js +0 -325
- package/clients/ruff-client.test.js +0 -132
- package/clients/ruff-client.test.ts +0 -153
- package/clients/rules-scanner.js +0 -97
- package/clients/runner-tracker.js +0 -152
- package/clients/rust-client.js +0 -205
- package/clients/rust-client.test.js +0 -108
- package/clients/rust-client.test.ts +0 -130
- package/clients/safe-spawn-async.js +0 -163
- package/clients/safe-spawn.js +0 -241
- package/clients/sanitize.js +0 -291
- package/clients/sanitize.test.js +0 -177
- package/clients/sanitize.test.ts +0 -223
- package/clients/scan-architectural-debt.js +0 -167
- package/clients/scan-utils.js +0 -83
- package/clients/secrets-scanner.js +0 -119
- package/clients/secrets-scanner.test.js +0 -100
- package/clients/secrets-scanner.test.ts +0 -113
- package/clients/sg-runner.js +0 -292
- package/clients/state-matrix.js +0 -160
- package/clients/subprocess-client.js +0 -65
- package/clients/symbol-types.js +0 -5
- package/clients/test-runner-client.js +0 -523
- package/clients/test-runner-client.test.js +0 -192
- package/clients/test-runner-client.test.ts +0 -253
- package/clients/test-utils.js +0 -27
- package/clients/test-utils.ts +0 -36
- package/clients/todo-scanner.js +0 -200
- package/clients/todo-scanner.test.js +0 -301
- package/clients/todo-scanner.test.ts +0 -352
- package/clients/tool-availability.js +0 -207
- package/clients/tree-sitter-client.js +0 -601
- package/clients/tree-sitter-query-loader.js +0 -355
- package/clients/tree-sitter-symbol-extractor.js +0 -289
- package/clients/ts-service.js +0 -129
- package/clients/type-coverage-client.js +0 -127
- package/clients/type-coverage-client.test.js +0 -105
- package/clients/type-coverage-client.test.ts +0 -125
- package/clients/type-safety-client.js +0 -138
- package/clients/types.js +0 -11
- package/clients/typescript-client.codefix.test.js +0 -157
- package/clients/typescript-client.codefix.test.ts +0 -186
- package/clients/typescript-client.js +0 -509
- package/clients/typescript-client.test.js +0 -105
- package/clients/typescript-client.test.ts +0 -126
- package/commands/booboo.js +0 -1007
- package/commands/fix-from-booboo.js +0 -398
- package/commands/fix-simplified.js +0 -618
- package/commands/rate.js +0 -281
- package/commands/rate.test.js +0 -119
- package/commands/rate.test.ts +0 -131
- package/commands/refactor.js +0 -130
|
@@ -1,352 +0,0 @@
|
|
|
1
|
-
import { afterEach, beforeEach, describe, expect, it } from "vitest";
|
|
2
|
-
import { createTempFile, setupTestEnvironment } from "./test-utils.js";
|
|
3
|
-
import { TodoScanner } from "./todo-scanner.js";
|
|
4
|
-
|
|
5
|
-
describe("TodoScanner", () => {
|
|
6
|
-
let client: TodoScanner;
|
|
7
|
-
let tmpDir: string;
|
|
8
|
-
let cleanup: () => void;
|
|
9
|
-
|
|
10
|
-
beforeEach(() => {
|
|
11
|
-
client = new TodoScanner();
|
|
12
|
-
({ tmpDir, cleanup } = setupTestEnvironment("pi-lens-todo-test-"));
|
|
13
|
-
});
|
|
14
|
-
|
|
15
|
-
afterEach(() => {
|
|
16
|
-
cleanup();
|
|
17
|
-
});
|
|
18
|
-
|
|
19
|
-
describe("scanFile", () => {
|
|
20
|
-
it("should return empty array for non-existent files", () => {
|
|
21
|
-
const result = client.scanFile("/nonexistent/file.ts");
|
|
22
|
-
expect(result).toEqual([]);
|
|
23
|
-
});
|
|
24
|
-
|
|
25
|
-
it("should find TODO comments", () => {
|
|
26
|
-
const content = `
|
|
27
|
-
// TODO: implement this function
|
|
28
|
-
function foo() {}
|
|
29
|
-
`;
|
|
30
|
-
const filePath = createTempFile(tmpDir, "test.ts", content);
|
|
31
|
-
const result = client.scanFile(filePath);
|
|
32
|
-
|
|
33
|
-
expect(result.length).toBe(1);
|
|
34
|
-
expect(result[0].type).toBe("TODO");
|
|
35
|
-
expect(result[0].message).toContain("implement this function");
|
|
36
|
-
});
|
|
37
|
-
|
|
38
|
-
it("should find FIXME comments", () => {
|
|
39
|
-
const content = `
|
|
40
|
-
// FIXME: this is broken
|
|
41
|
-
function foo() {}
|
|
42
|
-
`;
|
|
43
|
-
const filePath = createTempFile(tmpDir, "test.ts", content);
|
|
44
|
-
const result = client.scanFile(filePath);
|
|
45
|
-
|
|
46
|
-
expect(result.length).toBe(1);
|
|
47
|
-
expect(result[0].type).toBe("FIXME");
|
|
48
|
-
});
|
|
49
|
-
|
|
50
|
-
it("should find HACK comments", () => {
|
|
51
|
-
const content = `
|
|
52
|
-
// HACK: temporary workaround
|
|
53
|
-
const x = 1;
|
|
54
|
-
`;
|
|
55
|
-
const filePath = createTempFile(tmpDir, "test.ts", content);
|
|
56
|
-
const result = client.scanFile(filePath);
|
|
57
|
-
|
|
58
|
-
expect(result.length).toBe(1);
|
|
59
|
-
expect(result[0].type).toBe("HACK");
|
|
60
|
-
});
|
|
61
|
-
|
|
62
|
-
it("should find BUG comments", () => {
|
|
63
|
-
const content = `
|
|
64
|
-
// BUG: this causes a crash
|
|
65
|
-
const x = 1;
|
|
66
|
-
`;
|
|
67
|
-
const filePath = createTempFile(tmpDir, "test.ts", content);
|
|
68
|
-
const result = client.scanFile(filePath);
|
|
69
|
-
|
|
70
|
-
expect(result.length).toBe(1);
|
|
71
|
-
expect(result[0].type).toBe("BUG");
|
|
72
|
-
});
|
|
73
|
-
|
|
74
|
-
it("should find NOTE comments", () => {
|
|
75
|
-
const content = `
|
|
76
|
-
// NOTE: important design decision
|
|
77
|
-
const x = 1;
|
|
78
|
-
`;
|
|
79
|
-
const filePath = createTempFile(tmpDir, "test.ts", content);
|
|
80
|
-
const result = client.scanFile(filePath);
|
|
81
|
-
|
|
82
|
-
expect(result.length).toBe(1);
|
|
83
|
-
expect(result[0].type).toBe("NOTE");
|
|
84
|
-
});
|
|
85
|
-
|
|
86
|
-
it("should find TODO in block comments", () => {
|
|
87
|
-
const content = `
|
|
88
|
-
/*
|
|
89
|
-
* TODO: refactor this later
|
|
90
|
-
*/
|
|
91
|
-
const x = 1;
|
|
92
|
-
`;
|
|
93
|
-
const filePath = createTempFile(tmpDir, "test.ts", content);
|
|
94
|
-
const result = client.scanFile(filePath);
|
|
95
|
-
|
|
96
|
-
expect(result.length).toBe(1);
|
|
97
|
-
expect(result[0].type).toBe("TODO");
|
|
98
|
-
});
|
|
99
|
-
|
|
100
|
-
it("should find TODO in JSDoc comments", () => {
|
|
101
|
-
const content = `
|
|
102
|
-
/**
|
|
103
|
-
* TODO: add proper documentation
|
|
104
|
-
*/
|
|
105
|
-
function foo() {}
|
|
106
|
-
`;
|
|
107
|
-
const filePath = createTempFile(tmpDir, "test.ts", content);
|
|
108
|
-
const result = client.scanFile(filePath);
|
|
109
|
-
|
|
110
|
-
expect(result.length).toBe(1);
|
|
111
|
-
expect(result[0].type).toBe("TODO");
|
|
112
|
-
});
|
|
113
|
-
|
|
114
|
-
it("should find TODO in Python comments", () => {
|
|
115
|
-
const content = `
|
|
116
|
-
# TODO: implement this
|
|
117
|
-
def foo():
|
|
118
|
-
pass
|
|
119
|
-
`;
|
|
120
|
-
const filePath = createTempFile(tmpDir, "test.py", content);
|
|
121
|
-
const result = client.scanFile(filePath);
|
|
122
|
-
|
|
123
|
-
expect(result.length).toBe(1);
|
|
124
|
-
expect(result[0].type).toBe("TODO");
|
|
125
|
-
});
|
|
126
|
-
|
|
127
|
-
it("should skip TODO in strings", () => {
|
|
128
|
-
const content = `
|
|
129
|
-
const message = "TODO: buy milk";
|
|
130
|
-
`;
|
|
131
|
-
const filePath = createTempFile(tmpDir, "test.ts", content);
|
|
132
|
-
const result = client.scanFile(filePath);
|
|
133
|
-
|
|
134
|
-
expect(result.length).toBe(0);
|
|
135
|
-
});
|
|
136
|
-
|
|
137
|
-
it("should report correct line numbers", () => {
|
|
138
|
-
const content = `
|
|
139
|
-
const x = 1;
|
|
140
|
-
const y = 2;
|
|
141
|
-
// TODO: fix this
|
|
142
|
-
const z = 3;
|
|
143
|
-
`;
|
|
144
|
-
const filePath = createTempFile(tmpDir, "test.ts", content);
|
|
145
|
-
const result = client.scanFile(filePath);
|
|
146
|
-
|
|
147
|
-
expect(result[0].line).toBe(4);
|
|
148
|
-
});
|
|
149
|
-
|
|
150
|
-
it("should find multiple annotations in one file", () => {
|
|
151
|
-
const content = `
|
|
152
|
-
// TODO: first
|
|
153
|
-
// FIXME: second
|
|
154
|
-
// HACK: third
|
|
155
|
-
`;
|
|
156
|
-
const filePath = createTempFile(tmpDir, "test.ts", content);
|
|
157
|
-
const result = client.scanFile(filePath);
|
|
158
|
-
|
|
159
|
-
expect(result.length).toBe(3);
|
|
160
|
-
});
|
|
161
|
-
});
|
|
162
|
-
|
|
163
|
-
describe("scanDirectory", () => {
|
|
164
|
-
it("should scan all files in directory", () => {
|
|
165
|
-
createTempFile(tmpDir, "file1.ts", "// TODO: task 1");
|
|
166
|
-
createTempFile(tmpDir, "file2.ts", "// FIXME: bug 1");
|
|
167
|
-
createTempFile(tmpDir, "file3.py", "# HACK: workaround");
|
|
168
|
-
|
|
169
|
-
const result = client.scanDirectory(tmpDir);
|
|
170
|
-
|
|
171
|
-
expect(result.items.length).toBe(3);
|
|
172
|
-
});
|
|
173
|
-
|
|
174
|
-
it("should skip node_modules", () => {
|
|
175
|
-
createTempFile(tmpDir, "src/file.ts", "// TODO: task 1");
|
|
176
|
-
createTempFile(
|
|
177
|
-
tmpDir,
|
|
178
|
-
"node_modules/lib/file.ts",
|
|
179
|
-
"// TODO: should be skipped",
|
|
180
|
-
);
|
|
181
|
-
|
|
182
|
-
const result = client.scanDirectory(tmpDir);
|
|
183
|
-
|
|
184
|
-
expect(result.items.length).toBe(1);
|
|
185
|
-
expect(result.items[0].file).not.toContain("node_modules");
|
|
186
|
-
});
|
|
187
|
-
|
|
188
|
-
it("should group items by type", () => {
|
|
189
|
-
createTempFile(tmpDir, "file1.ts", "// TODO: task 1");
|
|
190
|
-
createTempFile(tmpDir, "file2.ts", "// TODO: task 2");
|
|
191
|
-
createTempFile(tmpDir, "file3.ts", "// FIXME: bug 1");
|
|
192
|
-
|
|
193
|
-
const result = client.scanDirectory(tmpDir);
|
|
194
|
-
|
|
195
|
-
expect(result.byType.get("TODO")?.length).toBe(2);
|
|
196
|
-
expect(result.byType.get("FIXME")?.length).toBe(1);
|
|
197
|
-
});
|
|
198
|
-
|
|
199
|
-
it("should group items by file", () => {
|
|
200
|
-
createTempFile(tmpDir, "file1.ts", "// TODO: task 1\n// FIXME: bug 1");
|
|
201
|
-
createTempFile(tmpDir, "file2.ts", "// TODO: task 2");
|
|
202
|
-
|
|
203
|
-
const result = client.scanDirectory(tmpDir);
|
|
204
|
-
|
|
205
|
-
const file1Items = [...result.byFile.entries()].find(([k]) =>
|
|
206
|
-
k.includes("file1.ts"),
|
|
207
|
-
);
|
|
208
|
-
expect(file1Items?.[1].length).toBe(2);
|
|
209
|
-
});
|
|
210
|
-
});
|
|
211
|
-
|
|
212
|
-
describe("formatResult", () => {
|
|
213
|
-
it("should return empty string for no results", () => {
|
|
214
|
-
const result = { items: [], byType: new Map(), byFile: new Map() };
|
|
215
|
-
expect(client.formatResult(result)).toBe("");
|
|
216
|
-
});
|
|
217
|
-
|
|
218
|
-
it("should format results with counts", () => {
|
|
219
|
-
const result = {
|
|
220
|
-
items: [
|
|
221
|
-
{
|
|
222
|
-
type: "TODO" as const,
|
|
223
|
-
message: "task 1",
|
|
224
|
-
file: "test.ts",
|
|
225
|
-
line: 1,
|
|
226
|
-
column: 0,
|
|
227
|
-
},
|
|
228
|
-
{
|
|
229
|
-
type: "FIXME" as const,
|
|
230
|
-
message: "bug 1",
|
|
231
|
-
file: "test.ts",
|
|
232
|
-
line: 2,
|
|
233
|
-
column: 0,
|
|
234
|
-
},
|
|
235
|
-
],
|
|
236
|
-
byType: new Map([
|
|
237
|
-
[
|
|
238
|
-
"TODO",
|
|
239
|
-
[
|
|
240
|
-
{
|
|
241
|
-
type: "TODO" as const,
|
|
242
|
-
message: "task 1",
|
|
243
|
-
file: "test.ts",
|
|
244
|
-
line: 1,
|
|
245
|
-
column: 0,
|
|
246
|
-
},
|
|
247
|
-
],
|
|
248
|
-
],
|
|
249
|
-
]),
|
|
250
|
-
byFile: new Map([
|
|
251
|
-
[
|
|
252
|
-
"test.ts",
|
|
253
|
-
[
|
|
254
|
-
{
|
|
255
|
-
type: "TODO" as const,
|
|
256
|
-
message: "task 1",
|
|
257
|
-
file: "test.ts",
|
|
258
|
-
line: 1,
|
|
259
|
-
column: 0,
|
|
260
|
-
},
|
|
261
|
-
],
|
|
262
|
-
],
|
|
263
|
-
]),
|
|
264
|
-
};
|
|
265
|
-
|
|
266
|
-
const formatted = client.formatResult(result);
|
|
267
|
-
expect(formatted).toContain("2 annotation(s)");
|
|
268
|
-
expect(formatted).toContain("TODO");
|
|
269
|
-
expect(formatted).toContain("FIXME");
|
|
270
|
-
});
|
|
271
|
-
|
|
272
|
-
it("should prioritize FIXME/HACK before TODO", () => {
|
|
273
|
-
const result = {
|
|
274
|
-
items: [
|
|
275
|
-
{
|
|
276
|
-
type: "FIXME" as const,
|
|
277
|
-
message: "bug",
|
|
278
|
-
file: "test.ts",
|
|
279
|
-
line: 2,
|
|
280
|
-
column: 0,
|
|
281
|
-
},
|
|
282
|
-
{
|
|
283
|
-
type: "TODO" as const,
|
|
284
|
-
message: "task",
|
|
285
|
-
file: "test.ts",
|
|
286
|
-
line: 1,
|
|
287
|
-
column: 0,
|
|
288
|
-
},
|
|
289
|
-
],
|
|
290
|
-
byType: new Map(),
|
|
291
|
-
byFile: new Map(),
|
|
292
|
-
};
|
|
293
|
-
|
|
294
|
-
const formatted = client.formatResult(result);
|
|
295
|
-
// Check that FIXME line comes before TODO line in the sorted output
|
|
296
|
-
const fixmeLineIndex = formatted.indexOf("🔴");
|
|
297
|
-
const todoLineIndex = formatted.indexOf("📝");
|
|
298
|
-
expect(fixmeLineIndex).toBeLessThan(todoLineIndex);
|
|
299
|
-
});
|
|
300
|
-
|
|
301
|
-
it("should show correct icons", () => {
|
|
302
|
-
const result = {
|
|
303
|
-
items: [
|
|
304
|
-
{
|
|
305
|
-
type: "FIXME" as const,
|
|
306
|
-
message: "bug",
|
|
307
|
-
file: "test.ts",
|
|
308
|
-
line: 1,
|
|
309
|
-
column: 0,
|
|
310
|
-
},
|
|
311
|
-
{
|
|
312
|
-
type: "HACK" as const,
|
|
313
|
-
message: "hack",
|
|
314
|
-
file: "test.ts",
|
|
315
|
-
line: 2,
|
|
316
|
-
column: 0,
|
|
317
|
-
},
|
|
318
|
-
{
|
|
319
|
-
type: "BUG" as const,
|
|
320
|
-
message: "bug",
|
|
321
|
-
file: "test.ts",
|
|
322
|
-
line: 3,
|
|
323
|
-
column: 0,
|
|
324
|
-
},
|
|
325
|
-
{
|
|
326
|
-
type: "TODO" as const,
|
|
327
|
-
message: "todo",
|
|
328
|
-
file: "test.ts",
|
|
329
|
-
line: 4,
|
|
330
|
-
column: 0,
|
|
331
|
-
},
|
|
332
|
-
{
|
|
333
|
-
type: "NOTE" as const,
|
|
334
|
-
message: "note",
|
|
335
|
-
file: "test.ts",
|
|
336
|
-
line: 5,
|
|
337
|
-
column: 0,
|
|
338
|
-
},
|
|
339
|
-
],
|
|
340
|
-
byType: new Map(),
|
|
341
|
-
byFile: new Map(),
|
|
342
|
-
};
|
|
343
|
-
|
|
344
|
-
const formatted = client.formatResult(result);
|
|
345
|
-
expect(formatted).toContain("🔴"); // FIXME
|
|
346
|
-
expect(formatted).toContain("🟠"); // HACK
|
|
347
|
-
expect(formatted).toContain("🐛"); // BUG
|
|
348
|
-
expect(formatted).toContain("📝"); // TODO
|
|
349
|
-
expect(formatted).toContain("ℹ️"); // NOTE
|
|
350
|
-
});
|
|
351
|
-
});
|
|
352
|
-
});
|
|
@@ -1,207 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Tool Availability Caching for pi-lens
|
|
3
|
-
*
|
|
4
|
-
* Provides cached tool availability checks to avoid repeated spawnSync calls.
|
|
5
|
-
* Tools like biome, ruff, ast-grep are checked once per session.
|
|
6
|
-
*/
|
|
7
|
-
import { safeSpawn } from "./safe-spawn.js";
|
|
8
|
-
// --- Tool Registry ---
|
|
9
|
-
export const TOOL_REGISTRY = [
|
|
10
|
-
{
|
|
11
|
-
name: "biome",
|
|
12
|
-
command: "npx",
|
|
13
|
-
versionCommand: ["@biomejs/biome", "--version"],
|
|
14
|
-
versionPattern: /(\d+\.\d+\.\d+)/,
|
|
15
|
-
},
|
|
16
|
-
{
|
|
17
|
-
name: "ruff",
|
|
18
|
-
command: "ruff",
|
|
19
|
-
versionCommand: ["--version"],
|
|
20
|
-
versionPattern: /(\d+\.\d+\.\d+)/,
|
|
21
|
-
},
|
|
22
|
-
{
|
|
23
|
-
name: "ast-grep",
|
|
24
|
-
command: "npx",
|
|
25
|
-
versionCommand: ["sg", "--version"],
|
|
26
|
-
versionPattern: /(\d+\.\d+\.\d+)/,
|
|
27
|
-
},
|
|
28
|
-
{
|
|
29
|
-
name: "knip",
|
|
30
|
-
command: "npx",
|
|
31
|
-
versionCommand: ["knip", "--version"],
|
|
32
|
-
versionPattern: /(\d+\.\d+\.\d+)/,
|
|
33
|
-
},
|
|
34
|
-
{
|
|
35
|
-
name: "jscpd",
|
|
36
|
-
command: "npx",
|
|
37
|
-
versionCommand: ["jscpd", "--version"],
|
|
38
|
-
versionPattern: /(\d+\.\d+\.\d+)/,
|
|
39
|
-
},
|
|
40
|
-
{
|
|
41
|
-
name: "type-coverage",
|
|
42
|
-
command: "npx",
|
|
43
|
-
versionCommand: ["type-coverage", "--version"],
|
|
44
|
-
versionPattern: /(\d+\.\d+\.\d+)/,
|
|
45
|
-
},
|
|
46
|
-
{
|
|
47
|
-
name: "madge",
|
|
48
|
-
command: "npx",
|
|
49
|
-
versionCommand: ["madge", "--version"],
|
|
50
|
-
versionPattern: /(\d+\.\d+\.\d+)/,
|
|
51
|
-
},
|
|
52
|
-
{
|
|
53
|
-
name: "tsc",
|
|
54
|
-
command: "npx",
|
|
55
|
-
versionCommand: ["tsc", "--version"],
|
|
56
|
-
versionPattern: /Version\s+(\d+\.\d+\.\d+)/,
|
|
57
|
-
},
|
|
58
|
-
{
|
|
59
|
-
name: "go",
|
|
60
|
-
command: "go",
|
|
61
|
-
versionCommand: ["version"],
|
|
62
|
-
versionPattern: /go(\d+\.\d+\.\d+)/,
|
|
63
|
-
},
|
|
64
|
-
{
|
|
65
|
-
name: "cargo",
|
|
66
|
-
command: "cargo",
|
|
67
|
-
versionCommand: ["--version"],
|
|
68
|
-
versionPattern: /(\d+\.\d+\.\d+)/,
|
|
69
|
-
},
|
|
70
|
-
];
|
|
71
|
-
const TOOL_CACHE = new Map();
|
|
72
|
-
const CACHE_TTL_MS = 5 * 60 * 1000; // 5 minutes
|
|
73
|
-
// --- Functions ---
|
|
74
|
-
/**
|
|
75
|
-
* Clear the tool availability cache.
|
|
76
|
-
* Useful for testing or when tool installations change.
|
|
77
|
-
*/
|
|
78
|
-
export function clearToolCache() {
|
|
79
|
-
TOOL_CACHE.clear();
|
|
80
|
-
}
|
|
81
|
-
/**
|
|
82
|
-
* Get cached tool availability or check if available.
|
|
83
|
-
* Uses cached result if within TTL.
|
|
84
|
-
*/
|
|
85
|
-
export function isToolAvailable(toolName) {
|
|
86
|
-
const cached = TOOL_CACHE.get(toolName);
|
|
87
|
-
if (cached && Date.now() - cached.timestamp < CACHE_TTL_MS) {
|
|
88
|
-
return cached.available;
|
|
89
|
-
}
|
|
90
|
-
// Check availability
|
|
91
|
-
const tool = TOOL_REGISTRY.find((t) => t.name === toolName);
|
|
92
|
-
if (!tool) {
|
|
93
|
-
// Unknown tool - try direct command check
|
|
94
|
-
const result = safeSpawn(toolName, ["--version"], {
|
|
95
|
-
timeout: 5000,
|
|
96
|
-
});
|
|
97
|
-
const available = !result.error && result.status === 0;
|
|
98
|
-
TOOL_CACHE.set(toolName, {
|
|
99
|
-
available,
|
|
100
|
-
version: available
|
|
101
|
-
? extractVersion(result.stdout + result.stderr, /(\S+)/)
|
|
102
|
-
: undefined,
|
|
103
|
-
timestamp: Date.now(),
|
|
104
|
-
});
|
|
105
|
-
return available;
|
|
106
|
-
}
|
|
107
|
-
// Check using tool's version command
|
|
108
|
-
if (tool.versionCommand) {
|
|
109
|
-
const result = safeSpawn(tool.command, tool.versionCommand, {
|
|
110
|
-
timeout: 10000,
|
|
111
|
-
});
|
|
112
|
-
const available = !result.error && result.status === 0;
|
|
113
|
-
const output = result.stdout + result.stderr;
|
|
114
|
-
const version = tool.versionPattern
|
|
115
|
-
? extractVersion(output, tool.versionPattern)
|
|
116
|
-
: undefined;
|
|
117
|
-
TOOL_CACHE.set(toolName, {
|
|
118
|
-
available,
|
|
119
|
-
version,
|
|
120
|
-
timestamp: Date.now(),
|
|
121
|
-
});
|
|
122
|
-
return available;
|
|
123
|
-
}
|
|
124
|
-
return false;
|
|
125
|
-
}
|
|
126
|
-
/**
|
|
127
|
-
* Get cached tool version if available.
|
|
128
|
-
*/
|
|
129
|
-
export function getToolVersion(toolName) {
|
|
130
|
-
const cached = TOOL_CACHE.get(toolName);
|
|
131
|
-
if (cached?.version) {
|
|
132
|
-
return cached.version;
|
|
133
|
-
}
|
|
134
|
-
// Try to get version even if not cached
|
|
135
|
-
const tool = TOOL_REGISTRY.find((t) => t.name === toolName);
|
|
136
|
-
if (tool?.versionCommand) {
|
|
137
|
-
const result = safeSpawn(tool.command, tool.versionCommand, {
|
|
138
|
-
timeout: 10000,
|
|
139
|
-
});
|
|
140
|
-
if (!result.error && result.status === 0) {
|
|
141
|
-
const output = result.stdout + result.stderr;
|
|
142
|
-
return tool.versionPattern
|
|
143
|
-
? extractVersion(output, tool.versionPattern)
|
|
144
|
-
: output.trim();
|
|
145
|
-
}
|
|
146
|
-
}
|
|
147
|
-
return undefined;
|
|
148
|
-
}
|
|
149
|
-
/**
|
|
150
|
-
* Check multiple tools at once and return their availability.
|
|
151
|
-
*/
|
|
152
|
-
export function checkToolsAvailable(toolNames) {
|
|
153
|
-
const results = new Map();
|
|
154
|
-
for (const name of toolNames) {
|
|
155
|
-
results.set(name, isToolAvailable(name));
|
|
156
|
-
}
|
|
157
|
-
return results;
|
|
158
|
-
}
|
|
159
|
-
/**
|
|
160
|
-
* Get all available tools.
|
|
161
|
-
*/
|
|
162
|
-
export function getAvailableTools() {
|
|
163
|
-
const available = [];
|
|
164
|
-
for (const tool of TOOL_REGISTRY) {
|
|
165
|
-
if (isToolAvailable(tool.name)) {
|
|
166
|
-
available.push(tool.name);
|
|
167
|
-
}
|
|
168
|
-
}
|
|
169
|
-
return available;
|
|
170
|
-
}
|
|
171
|
-
// --- Helpers ---
|
|
172
|
-
function extractVersion(output, pattern) {
|
|
173
|
-
const match = output.match(pattern);
|
|
174
|
-
return match ? match[1] : undefined;
|
|
175
|
-
}
|
|
176
|
-
/**
|
|
177
|
-
* Convenience wrapper for checking common tools.
|
|
178
|
-
*/
|
|
179
|
-
export class ToolAvailabilityChecker {
|
|
180
|
-
constructor(toolNames) {
|
|
181
|
-
this.toolNames = toolNames;
|
|
182
|
-
}
|
|
183
|
-
/**
|
|
184
|
-
* Check if all tools in the list are available.
|
|
185
|
-
*/
|
|
186
|
-
allAvailable() {
|
|
187
|
-
return this.toolNames.every((name) => isToolAvailable(name));
|
|
188
|
-
}
|
|
189
|
-
/**
|
|
190
|
-
* Check if any tool in the list is available.
|
|
191
|
-
*/
|
|
192
|
-
anyAvailable() {
|
|
193
|
-
return this.toolNames.some((name) => isToolAvailable(name));
|
|
194
|
-
}
|
|
195
|
-
/**
|
|
196
|
-
* Get list of available tools in this list.
|
|
197
|
-
*/
|
|
198
|
-
getAvailable() {
|
|
199
|
-
return this.toolNames.filter((name) => isToolAvailable(name));
|
|
200
|
-
}
|
|
201
|
-
/**
|
|
202
|
-
* Get list of unavailable tools in this list.
|
|
203
|
-
*/
|
|
204
|
-
getUnavailable() {
|
|
205
|
-
return this.toolNames.filter((name) => !isToolAvailable(name));
|
|
206
|
-
}
|
|
207
|
-
}
|