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,169 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Tests for file-kinds.ts
|
|
3
|
-
* Centralized file type detection
|
|
4
|
-
*/
|
|
5
|
-
import { describe, expect, it } from "vitest";
|
|
6
|
-
import { detectFileKind, getExtensionsForKind, getFileKindLabel, getLanguageId, isCodeKind, isConfigKind, isFileKind, isScannableFile, } from "./file-kinds.js";
|
|
7
|
-
describe("detectFileKind", () => {
|
|
8
|
-
it("should detect JavaScript/TypeScript files", () => {
|
|
9
|
-
expect(detectFileKind("src/app.ts")).toBe("jsts");
|
|
10
|
-
expect(detectFileKind("src/app.tsx")).toBe("jsts");
|
|
11
|
-
expect(detectFileKind("src/app.js")).toBe("jsts");
|
|
12
|
-
expect(detectFileKind("src/app.jsx")).toBe("jsts");
|
|
13
|
-
expect(detectFileKind("src/app.mjs")).toBe("jsts");
|
|
14
|
-
expect(detectFileKind("src/app.cjs")).toBe("jsts");
|
|
15
|
-
});
|
|
16
|
-
it("should detect Python files", () => {
|
|
17
|
-
expect(detectFileKind("app.py")).toBe("python");
|
|
18
|
-
expect(detectFileKind("tests/test_app.py")).toBe("python");
|
|
19
|
-
});
|
|
20
|
-
it("should detect Go files", () => {
|
|
21
|
-
expect(detectFileKind("main.go")).toBe("go");
|
|
22
|
-
expect(detectFileKind("pkg/utils.go")).toBe("go");
|
|
23
|
-
});
|
|
24
|
-
it("should detect Rust files", () => {
|
|
25
|
-
expect(detectFileKind("main.rs")).toBe("rust");
|
|
26
|
-
expect(detectFileKind("lib/app.rs")).toBe("rust");
|
|
27
|
-
});
|
|
28
|
-
it("should detect C++ files", () => {
|
|
29
|
-
expect(detectFileKind("main.cpp")).toBe("cxx");
|
|
30
|
-
expect(detectFileKind("header.hpp")).toBe("cxx");
|
|
31
|
-
expect(detectFileKind("file.cc")).toBe("cxx");
|
|
32
|
-
expect(detectFileKind("file.hxx")).toBe("cxx");
|
|
33
|
-
});
|
|
34
|
-
it("should detect CMake files", () => {
|
|
35
|
-
expect(detectFileKind("CMakeLists.txt")).toBe("cmake");
|
|
36
|
-
expect(detectFileKind("build.cmake")).toBe("cmake");
|
|
37
|
-
});
|
|
38
|
-
it("should detect Shell files", () => {
|
|
39
|
-
expect(detectFileKind("script.sh")).toBe("shell");
|
|
40
|
-
expect(detectFileKind("script.bash")).toBe("shell");
|
|
41
|
-
expect(detectFileKind("Makefile")).toBe("shell");
|
|
42
|
-
});
|
|
43
|
-
it("should detect JSON files", () => {
|
|
44
|
-
expect(detectFileKind("config.json")).toBe("json");
|
|
45
|
-
expect(detectFileKind("package.json")).toBe("json");
|
|
46
|
-
});
|
|
47
|
-
it("should detect Markdown files", () => {
|
|
48
|
-
expect(detectFileKind("README.md")).toBe("markdown");
|
|
49
|
-
expect(detectFileKind("docs/guide.mdx")).toBe("markdown");
|
|
50
|
-
});
|
|
51
|
-
it("should detect CSS files", () => {
|
|
52
|
-
expect(detectFileKind("style.css")).toBe("css");
|
|
53
|
-
expect(detectFileKind("style.scss")).toBe("css");
|
|
54
|
-
expect(detectFileKind("style.less")).toBe("css");
|
|
55
|
-
});
|
|
56
|
-
it("should detect YAML files", () => {
|
|
57
|
-
expect(detectFileKind("config.yaml")).toBe("yaml");
|
|
58
|
-
expect(detectFileKind("config.yml")).toBe("yaml");
|
|
59
|
-
});
|
|
60
|
-
it("should return undefined for unknown extensions", () => {
|
|
61
|
-
expect(detectFileKind("file.xyz")).toBeUndefined();
|
|
62
|
-
expect(detectFileKind("file")).toBeUndefined();
|
|
63
|
-
});
|
|
64
|
-
it("should handle case-insensitive extensions", () => {
|
|
65
|
-
expect(detectFileKind("file.TS")).toBe("jsts");
|
|
66
|
-
expect(detectFileKind("file.PY")).toBe("python");
|
|
67
|
-
});
|
|
68
|
-
it("should handle paths with special characters", () => {
|
|
69
|
-
expect(detectFileKind("/path/to/file.ts")).toBe("jsts");
|
|
70
|
-
expect(detectFileKind("C:\\path\\to\\file.py")).toBe("python");
|
|
71
|
-
});
|
|
72
|
-
});
|
|
73
|
-
describe("isFileKind", () => {
|
|
74
|
-
it("should check single file kind", () => {
|
|
75
|
-
expect(isFileKind("app.ts", "jsts")).toBe(true);
|
|
76
|
-
expect(isFileKind("app.py", "jsts")).toBe(false);
|
|
77
|
-
});
|
|
78
|
-
it("should check multiple file kinds", () => {
|
|
79
|
-
expect(isFileKind("app.ts", ["jsts", "python"])).toBe(true);
|
|
80
|
-
expect(isFileKind("app.py", ["jsts", "python"])).toBe(true);
|
|
81
|
-
expect(isFileKind("app.go", ["jsts", "python"])).toBe(false);
|
|
82
|
-
});
|
|
83
|
-
it("should return false for undefined file kind", () => {
|
|
84
|
-
expect(isFileKind("file.xyz", "jsts")).toBe(false);
|
|
85
|
-
expect(isFileKind("file.xyz", ["jsts", "python"])).toBe(false);
|
|
86
|
-
});
|
|
87
|
-
});
|
|
88
|
-
describe("isCodeKind", () => {
|
|
89
|
-
it("should identify code file kinds", () => {
|
|
90
|
-
expect(isCodeKind("jsts")).toBe(true);
|
|
91
|
-
expect(isCodeKind("python")).toBe(true);
|
|
92
|
-
expect(isCodeKind("go")).toBe(true);
|
|
93
|
-
expect(isCodeKind("rust")).toBe(true);
|
|
94
|
-
expect(isCodeKind("cxx")).toBe(true);
|
|
95
|
-
expect(isCodeKind("shell")).toBe(true);
|
|
96
|
-
});
|
|
97
|
-
it("should reject non-code file kinds", () => {
|
|
98
|
-
expect(isCodeKind("json")).toBe(false);
|
|
99
|
-
expect(isCodeKind("markdown")).toBe(false);
|
|
100
|
-
expect(isCodeKind("css")).toBe(false);
|
|
101
|
-
});
|
|
102
|
-
});
|
|
103
|
-
describe("isConfigKind", () => {
|
|
104
|
-
it("should identify config file kinds", () => {
|
|
105
|
-
expect(isConfigKind("json")).toBe(true);
|
|
106
|
-
expect(isConfigKind("yaml")).toBe(true);
|
|
107
|
-
expect(isConfigKind("markdown")).toBe(true);
|
|
108
|
-
expect(isConfigKind("css")).toBe(true);
|
|
109
|
-
});
|
|
110
|
-
it("should reject non-config file kinds", () => {
|
|
111
|
-
expect(isConfigKind("jsts")).toBe(false);
|
|
112
|
-
expect(isConfigKind("python")).toBe(false);
|
|
113
|
-
expect(isConfigKind("go")).toBe(false);
|
|
114
|
-
});
|
|
115
|
-
});
|
|
116
|
-
describe("isScannableFile", () => {
|
|
117
|
-
it("should return true for code files", () => {
|
|
118
|
-
expect(isScannableFile("app.ts")).toBe(true);
|
|
119
|
-
expect(isScannableFile("app.py")).toBe(true);
|
|
120
|
-
});
|
|
121
|
-
it("should return true for config files", () => {
|
|
122
|
-
expect(isScannableFile("config.json")).toBe(true);
|
|
123
|
-
expect(isScannableFile("README.md")).toBe(true);
|
|
124
|
-
});
|
|
125
|
-
it("should return false for test files", () => {
|
|
126
|
-
expect(isScannableFile("app.test.ts")).toBe(false);
|
|
127
|
-
expect(isScannableFile("app.spec.ts")).toBe(false);
|
|
128
|
-
expect(isScannableFile("test-app.ts")).toBe(false);
|
|
129
|
-
});
|
|
130
|
-
it("should return false for unknown extensions", () => {
|
|
131
|
-
expect(isScannableFile("file.xyz")).toBe(false);
|
|
132
|
-
});
|
|
133
|
-
});
|
|
134
|
-
describe("getLanguageId", () => {
|
|
135
|
-
it("should return correct language IDs", () => {
|
|
136
|
-
expect(getLanguageId("jsts")).toBe("typescript");
|
|
137
|
-
expect(getLanguageId("python")).toBe("python");
|
|
138
|
-
expect(getLanguageId("go")).toBe("go");
|
|
139
|
-
expect(getLanguageId("rust")).toBe("rust");
|
|
140
|
-
expect(getLanguageId("cxx")).toBe("cpp");
|
|
141
|
-
expect(getLanguageId("json")).toBe("json");
|
|
142
|
-
});
|
|
143
|
-
it("should return plaintext for unknown kinds", () => {
|
|
144
|
-
expect(getLanguageId("unknown")).toBe("plaintext");
|
|
145
|
-
});
|
|
146
|
-
});
|
|
147
|
-
describe("getExtensionsForKind", () => {
|
|
148
|
-
it("should return extensions for jsts", () => {
|
|
149
|
-
const exts = getExtensionsForKind("jsts");
|
|
150
|
-
expect(exts).toContain(".ts");
|
|
151
|
-
expect(exts).toContain(".tsx");
|
|
152
|
-
expect(exts).toContain(".js");
|
|
153
|
-
expect(exts).toContain(".jsx");
|
|
154
|
-
});
|
|
155
|
-
it("should return extensions for python", () => {
|
|
156
|
-
const exts = getExtensionsForKind("python");
|
|
157
|
-
expect(exts).toEqual([".py"]);
|
|
158
|
-
});
|
|
159
|
-
});
|
|
160
|
-
describe("getFileKindLabel", () => {
|
|
161
|
-
it("should return human-readable labels", () => {
|
|
162
|
-
expect(getFileKindLabel("jsts")).toBe("JavaScript/TypeScript");
|
|
163
|
-
expect(getFileKindLabel("python")).toBe("Python");
|
|
164
|
-
expect(getFileKindLabel("cxx")).toBe("C/C++");
|
|
165
|
-
});
|
|
166
|
-
it("should return kind as fallback", () => {
|
|
167
|
-
expect(getFileKindLabel("unknown")).toBe("unknown");
|
|
168
|
-
});
|
|
169
|
-
});
|
|
@@ -1,210 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Tests for file-kinds.ts
|
|
3
|
-
* Centralized file type detection
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
import { describe, expect, it } from "vitest";
|
|
7
|
-
import {
|
|
8
|
-
detectFileKind,
|
|
9
|
-
getExtensionsForKind,
|
|
10
|
-
getFileKindLabel,
|
|
11
|
-
getLanguageId,
|
|
12
|
-
isCodeKind,
|
|
13
|
-
isConfigKind,
|
|
14
|
-
isFileKind,
|
|
15
|
-
isScannableFile,
|
|
16
|
-
} from "./file-kinds.js";
|
|
17
|
-
|
|
18
|
-
describe("detectFileKind", () => {
|
|
19
|
-
it("should detect JavaScript/TypeScript files", () => {
|
|
20
|
-
expect(detectFileKind("src/app.ts")).toBe("jsts");
|
|
21
|
-
expect(detectFileKind("src/app.tsx")).toBe("jsts");
|
|
22
|
-
expect(detectFileKind("src/app.js")).toBe("jsts");
|
|
23
|
-
expect(detectFileKind("src/app.jsx")).toBe("jsts");
|
|
24
|
-
expect(detectFileKind("src/app.mjs")).toBe("jsts");
|
|
25
|
-
expect(detectFileKind("src/app.cjs")).toBe("jsts");
|
|
26
|
-
});
|
|
27
|
-
|
|
28
|
-
it("should detect Python files", () => {
|
|
29
|
-
expect(detectFileKind("app.py")).toBe("python");
|
|
30
|
-
expect(detectFileKind("tests/test_app.py")).toBe("python");
|
|
31
|
-
});
|
|
32
|
-
|
|
33
|
-
it("should detect Go files", () => {
|
|
34
|
-
expect(detectFileKind("main.go")).toBe("go");
|
|
35
|
-
expect(detectFileKind("pkg/utils.go")).toBe("go");
|
|
36
|
-
});
|
|
37
|
-
|
|
38
|
-
it("should detect Rust files", () => {
|
|
39
|
-
expect(detectFileKind("main.rs")).toBe("rust");
|
|
40
|
-
expect(detectFileKind("lib/app.rs")).toBe("rust");
|
|
41
|
-
});
|
|
42
|
-
|
|
43
|
-
it("should detect C++ files", () => {
|
|
44
|
-
expect(detectFileKind("main.cpp")).toBe("cxx");
|
|
45
|
-
expect(detectFileKind("header.hpp")).toBe("cxx");
|
|
46
|
-
expect(detectFileKind("file.cc")).toBe("cxx");
|
|
47
|
-
expect(detectFileKind("file.hxx")).toBe("cxx");
|
|
48
|
-
});
|
|
49
|
-
|
|
50
|
-
it("should detect CMake files", () => {
|
|
51
|
-
expect(detectFileKind("CMakeLists.txt")).toBe("cmake");
|
|
52
|
-
expect(detectFileKind("build.cmake")).toBe("cmake");
|
|
53
|
-
});
|
|
54
|
-
|
|
55
|
-
it("should detect Shell files", () => {
|
|
56
|
-
expect(detectFileKind("script.sh")).toBe("shell");
|
|
57
|
-
expect(detectFileKind("script.bash")).toBe("shell");
|
|
58
|
-
expect(detectFileKind("Makefile")).toBe("shell");
|
|
59
|
-
});
|
|
60
|
-
|
|
61
|
-
it("should detect JSON files", () => {
|
|
62
|
-
expect(detectFileKind("config.json")).toBe("json");
|
|
63
|
-
expect(detectFileKind("package.json")).toBe("json");
|
|
64
|
-
});
|
|
65
|
-
|
|
66
|
-
it("should detect Markdown files", () => {
|
|
67
|
-
expect(detectFileKind("README.md")).toBe("markdown");
|
|
68
|
-
expect(detectFileKind("docs/guide.mdx")).toBe("markdown");
|
|
69
|
-
});
|
|
70
|
-
|
|
71
|
-
it("should detect CSS files", () => {
|
|
72
|
-
expect(detectFileKind("style.css")).toBe("css");
|
|
73
|
-
expect(detectFileKind("style.scss")).toBe("css");
|
|
74
|
-
expect(detectFileKind("style.less")).toBe("css");
|
|
75
|
-
});
|
|
76
|
-
|
|
77
|
-
it("should detect YAML files", () => {
|
|
78
|
-
expect(detectFileKind("config.yaml")).toBe("yaml");
|
|
79
|
-
expect(detectFileKind("config.yml")).toBe("yaml");
|
|
80
|
-
});
|
|
81
|
-
|
|
82
|
-
it("should return undefined for unknown extensions", () => {
|
|
83
|
-
expect(detectFileKind("file.xyz")).toBeUndefined();
|
|
84
|
-
expect(detectFileKind("file")).toBeUndefined();
|
|
85
|
-
});
|
|
86
|
-
|
|
87
|
-
it("should handle case-insensitive extensions", () => {
|
|
88
|
-
expect(detectFileKind("file.TS")).toBe("jsts");
|
|
89
|
-
expect(detectFileKind("file.PY")).toBe("python");
|
|
90
|
-
});
|
|
91
|
-
|
|
92
|
-
it("should handle paths with special characters", () => {
|
|
93
|
-
expect(detectFileKind("/path/to/file.ts")).toBe("jsts");
|
|
94
|
-
expect(detectFileKind("C:\\path\\to\\file.py")).toBe("python");
|
|
95
|
-
});
|
|
96
|
-
});
|
|
97
|
-
|
|
98
|
-
describe("isFileKind", () => {
|
|
99
|
-
it("should check single file kind", () => {
|
|
100
|
-
expect(isFileKind("app.ts", "jsts")).toBe(true);
|
|
101
|
-
expect(isFileKind("app.py", "jsts")).toBe(false);
|
|
102
|
-
});
|
|
103
|
-
|
|
104
|
-
it("should check multiple file kinds", () => {
|
|
105
|
-
expect(isFileKind("app.ts", ["jsts", "python"])).toBe(true);
|
|
106
|
-
expect(isFileKind("app.py", ["jsts", "python"])).toBe(true);
|
|
107
|
-
expect(isFileKind("app.go", ["jsts", "python"])).toBe(false);
|
|
108
|
-
});
|
|
109
|
-
|
|
110
|
-
it("should return false for undefined file kind", () => {
|
|
111
|
-
expect(isFileKind("file.xyz", "jsts")).toBe(false);
|
|
112
|
-
expect(isFileKind("file.xyz", ["jsts", "python"])).toBe(false);
|
|
113
|
-
});
|
|
114
|
-
});
|
|
115
|
-
|
|
116
|
-
describe("isCodeKind", () => {
|
|
117
|
-
it("should identify code file kinds", () => {
|
|
118
|
-
expect(isCodeKind("jsts")).toBe(true);
|
|
119
|
-
expect(isCodeKind("python")).toBe(true);
|
|
120
|
-
expect(isCodeKind("go")).toBe(true);
|
|
121
|
-
expect(isCodeKind("rust")).toBe(true);
|
|
122
|
-
expect(isCodeKind("cxx")).toBe(true);
|
|
123
|
-
expect(isCodeKind("shell")).toBe(true);
|
|
124
|
-
});
|
|
125
|
-
|
|
126
|
-
it("should reject non-code file kinds", () => {
|
|
127
|
-
expect(isCodeKind("json")).toBe(false);
|
|
128
|
-
expect(isCodeKind("markdown")).toBe(false);
|
|
129
|
-
expect(isCodeKind("css")).toBe(false);
|
|
130
|
-
});
|
|
131
|
-
});
|
|
132
|
-
|
|
133
|
-
describe("isConfigKind", () => {
|
|
134
|
-
it("should identify config file kinds", () => {
|
|
135
|
-
expect(isConfigKind("json")).toBe(true);
|
|
136
|
-
expect(isConfigKind("yaml")).toBe(true);
|
|
137
|
-
expect(isConfigKind("markdown")).toBe(true);
|
|
138
|
-
expect(isConfigKind("css")).toBe(true);
|
|
139
|
-
});
|
|
140
|
-
|
|
141
|
-
it("should reject non-config file kinds", () => {
|
|
142
|
-
expect(isConfigKind("jsts")).toBe(false);
|
|
143
|
-
expect(isConfigKind("python")).toBe(false);
|
|
144
|
-
expect(isConfigKind("go")).toBe(false);
|
|
145
|
-
});
|
|
146
|
-
});
|
|
147
|
-
|
|
148
|
-
describe("isScannableFile", () => {
|
|
149
|
-
it("should return true for code files", () => {
|
|
150
|
-
expect(isScannableFile("app.ts")).toBe(true);
|
|
151
|
-
expect(isScannableFile("app.py")).toBe(true);
|
|
152
|
-
});
|
|
153
|
-
|
|
154
|
-
it("should return true for config files", () => {
|
|
155
|
-
expect(isScannableFile("config.json")).toBe(true);
|
|
156
|
-
expect(isScannableFile("README.md")).toBe(true);
|
|
157
|
-
});
|
|
158
|
-
|
|
159
|
-
it("should return false for test files", () => {
|
|
160
|
-
expect(isScannableFile("app.test.ts")).toBe(false);
|
|
161
|
-
expect(isScannableFile("app.spec.ts")).toBe(false);
|
|
162
|
-
expect(isScannableFile("test-app.ts")).toBe(false);
|
|
163
|
-
});
|
|
164
|
-
|
|
165
|
-
it("should return false for unknown extensions", () => {
|
|
166
|
-
expect(isScannableFile("file.xyz")).toBe(false);
|
|
167
|
-
});
|
|
168
|
-
});
|
|
169
|
-
|
|
170
|
-
describe("getLanguageId", () => {
|
|
171
|
-
it("should return correct language IDs", () => {
|
|
172
|
-
expect(getLanguageId("jsts")).toBe("typescript");
|
|
173
|
-
expect(getLanguageId("python")).toBe("python");
|
|
174
|
-
expect(getLanguageId("go")).toBe("go");
|
|
175
|
-
expect(getLanguageId("rust")).toBe("rust");
|
|
176
|
-
expect(getLanguageId("cxx")).toBe("cpp");
|
|
177
|
-
expect(getLanguageId("json")).toBe("json");
|
|
178
|
-
});
|
|
179
|
-
|
|
180
|
-
it("should return plaintext for unknown kinds", () => {
|
|
181
|
-
expect(getLanguageId("unknown" as any)).toBe("plaintext");
|
|
182
|
-
});
|
|
183
|
-
});
|
|
184
|
-
|
|
185
|
-
describe("getExtensionsForKind", () => {
|
|
186
|
-
it("should return extensions for jsts", () => {
|
|
187
|
-
const exts = getExtensionsForKind("jsts");
|
|
188
|
-
expect(exts).toContain(".ts");
|
|
189
|
-
expect(exts).toContain(".tsx");
|
|
190
|
-
expect(exts).toContain(".js");
|
|
191
|
-
expect(exts).toContain(".jsx");
|
|
192
|
-
});
|
|
193
|
-
|
|
194
|
-
it("should return extensions for python", () => {
|
|
195
|
-
const exts = getExtensionsForKind("python");
|
|
196
|
-
expect(exts).toEqual([".py"]);
|
|
197
|
-
});
|
|
198
|
-
});
|
|
199
|
-
|
|
200
|
-
describe("getFileKindLabel", () => {
|
|
201
|
-
it("should return human-readable labels", () => {
|
|
202
|
-
expect(getFileKindLabel("jsts")).toBe("JavaScript/TypeScript");
|
|
203
|
-
expect(getFileKindLabel("python")).toBe("Python");
|
|
204
|
-
expect(getFileKindLabel("cxx")).toBe("C/C++");
|
|
205
|
-
});
|
|
206
|
-
|
|
207
|
-
it("should return kind as fallback", () => {
|
|
208
|
-
expect(getFileKindLabel("unknown" as any)).toBe("unknown");
|
|
209
|
-
});
|
|
210
|
-
});
|
package/clients/file-time.js
DELETED
|
@@ -1,152 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* FileTime Tracking for pi-lens
|
|
3
|
-
*
|
|
4
|
-
* Prevents race conditions when auto-formatting or external tools modify files.
|
|
5
|
-
* Tracks file modification times and sizes to detect external changes.
|
|
6
|
-
*
|
|
7
|
-
* Inspired by OpenCode's FileTime system - ensures agents re-read files
|
|
8
|
-
* that have been modified externally (including by formatters).
|
|
9
|
-
*/
|
|
10
|
-
import * as fs from "node:fs";
|
|
11
|
-
import * as path from "node:path";
|
|
12
|
-
// --- Singleton State ---
|
|
13
|
-
const globalState = {
|
|
14
|
-
reads: new Map(),
|
|
15
|
-
locks: new Map(),
|
|
16
|
-
};
|
|
17
|
-
// --- Public API ---
|
|
18
|
-
export class FileTime {
|
|
19
|
-
constructor(sessionID) {
|
|
20
|
-
this.sessionID = sessionID;
|
|
21
|
-
}
|
|
22
|
-
/**
|
|
23
|
-
* Record a file read with current stats
|
|
24
|
-
* Call this after ANY file modification (including formatting)
|
|
25
|
-
*/
|
|
26
|
-
read(filePath) {
|
|
27
|
-
const absolutePath = path.resolve(filePath);
|
|
28
|
-
const stamp = createStamp(absolutePath);
|
|
29
|
-
let sessionReads = globalState.reads.get(this.sessionID);
|
|
30
|
-
if (!sessionReads) {
|
|
31
|
-
sessionReads = new Map();
|
|
32
|
-
globalState.reads.set(this.sessionID, sessionReads);
|
|
33
|
-
}
|
|
34
|
-
sessionReads.set(absolutePath, stamp);
|
|
35
|
-
return stamp;
|
|
36
|
-
}
|
|
37
|
-
/**
|
|
38
|
-
* Get last recorded stamp for a file
|
|
39
|
-
*/
|
|
40
|
-
get(filePath) {
|
|
41
|
-
const absolutePath = path.resolve(filePath);
|
|
42
|
-
const sessionReads = globalState.reads.get(this.sessionID);
|
|
43
|
-
return sessionReads?.get(absolutePath);
|
|
44
|
-
}
|
|
45
|
-
/**
|
|
46
|
-
* Assert file hasn't changed since last read
|
|
47
|
-
* Throws error if file modified externally - forces agent to re-read
|
|
48
|
-
*/
|
|
49
|
-
assert(filePath) {
|
|
50
|
-
const absolutePath = path.resolve(filePath);
|
|
51
|
-
const sessionReads = globalState.reads.get(this.sessionID);
|
|
52
|
-
const recorded = sessionReads?.get(absolutePath);
|
|
53
|
-
if (!recorded) {
|
|
54
|
-
throw new FileTimeError(`You must read file ${absolutePath} before modifying it. Use the read tool first.`, absolutePath, "not-read");
|
|
55
|
-
}
|
|
56
|
-
const current = createStamp(absolutePath);
|
|
57
|
-
const changed = current.mtime !== recorded.mtime ||
|
|
58
|
-
current.ctime !== recorded.ctime ||
|
|
59
|
-
current.size !== recorded.size;
|
|
60
|
-
if (changed) {
|
|
61
|
-
throw new FileTimeError(`File ${absolutePath} has been modified since it was last read.\n` +
|
|
62
|
-
`Last modification: ${new Date(current.mtime ?? Date.now()).toISOString()}\n` +
|
|
63
|
-
`Last read: ${recorded.readAt.toISOString()}\n\n` +
|
|
64
|
-
`Please read the file again before modifying it.`, absolutePath, "modified");
|
|
65
|
-
}
|
|
66
|
-
}
|
|
67
|
-
/**
|
|
68
|
-
* Check if file has changed (non-throwing version of assert)
|
|
69
|
-
*/
|
|
70
|
-
hasChanged(filePath) {
|
|
71
|
-
const absolutePath = path.resolve(filePath);
|
|
72
|
-
const sessionReads = globalState.reads.get(this.sessionID);
|
|
73
|
-
const recorded = sessionReads?.get(absolutePath);
|
|
74
|
-
if (!recorded)
|
|
75
|
-
return true; // Never read = changed
|
|
76
|
-
const current = createStamp(absolutePath);
|
|
77
|
-
return (current.mtime !== recorded.mtime ||
|
|
78
|
-
current.ctime !== recorded.ctime ||
|
|
79
|
-
current.size !== recorded.size);
|
|
80
|
-
}
|
|
81
|
-
/**
|
|
82
|
-
* Acquire exclusive lock on file
|
|
83
|
-
* Prevents concurrent modifications to same file
|
|
84
|
-
*/
|
|
85
|
-
async withLock(filePath, fn) {
|
|
86
|
-
const absolutePath = path.resolve(filePath);
|
|
87
|
-
// Wait for existing lock
|
|
88
|
-
while (globalState.locks.has(absolutePath)) {
|
|
89
|
-
const existing = globalState.locks.get(absolutePath);
|
|
90
|
-
if (existing)
|
|
91
|
-
await existing;
|
|
92
|
-
}
|
|
93
|
-
// Create new lock
|
|
94
|
-
const lockPromise = fn().finally(() => {
|
|
95
|
-
globalState.locks.delete(absolutePath);
|
|
96
|
-
});
|
|
97
|
-
globalState.locks.set(absolutePath, lockPromise.then(() => { }));
|
|
98
|
-
return lockPromise;
|
|
99
|
-
}
|
|
100
|
-
/**
|
|
101
|
-
* Clear all tracked files for this session
|
|
102
|
-
*/
|
|
103
|
-
clear() {
|
|
104
|
-
globalState.reads.delete(this.sessionID);
|
|
105
|
-
}
|
|
106
|
-
/**
|
|
107
|
-
* Clear specific file tracking
|
|
108
|
-
*/
|
|
109
|
-
clearFile(filePath) {
|
|
110
|
-
const absolutePath = path.resolve(filePath);
|
|
111
|
-
const sessionReads = globalState.reads.get(this.sessionID);
|
|
112
|
-
sessionReads?.delete(absolutePath);
|
|
113
|
-
}
|
|
114
|
-
}
|
|
115
|
-
// --- Error Type ---
|
|
116
|
-
export class FileTimeError extends Error {
|
|
117
|
-
constructor(message, filePath, reason) {
|
|
118
|
-
super(message);
|
|
119
|
-
this.name = "FileTimeError";
|
|
120
|
-
this.filePath = filePath;
|
|
121
|
-
this.reason = reason;
|
|
122
|
-
}
|
|
123
|
-
}
|
|
124
|
-
// --- Utilities ---
|
|
125
|
-
function createStamp(filePath) {
|
|
126
|
-
try {
|
|
127
|
-
const stats = fs.statSync(filePath);
|
|
128
|
-
return {
|
|
129
|
-
readAt: new Date(),
|
|
130
|
-
mtime: stats.mtime.getTime(),
|
|
131
|
-
ctime: stats.ctime.getTime(),
|
|
132
|
-
size: stats.size,
|
|
133
|
-
};
|
|
134
|
-
}
|
|
135
|
-
catch {
|
|
136
|
-
// File doesn't exist - return empty stamp
|
|
137
|
-
return {
|
|
138
|
-
readAt: new Date(),
|
|
139
|
-
mtime: undefined,
|
|
140
|
-
ctime: undefined,
|
|
141
|
-
size: undefined,
|
|
142
|
-
};
|
|
143
|
-
}
|
|
144
|
-
}
|
|
145
|
-
// --- Global Helpers ---
|
|
146
|
-
export function createFileTime(sessionID) {
|
|
147
|
-
return new FileTime(sessionID);
|
|
148
|
-
}
|
|
149
|
-
export function clearAllSessions() {
|
|
150
|
-
globalState.reads.clear();
|
|
151
|
-
globalState.locks.clear();
|
|
152
|
-
}
|
package/clients/file-utils.js
DELETED
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Shared file path utilities for pi-lens
|
|
3
|
-
*/
|
|
4
|
-
/**
|
|
5
|
-
* Directories to exclude from all scans (build outputs, dependencies, caches).
|
|
6
|
-
* Used consistently across all scanners to avoid noise from generated files.
|
|
7
|
-
*/
|
|
8
|
-
export const EXCLUDED_DIRS = [
|
|
9
|
-
"node_modules",
|
|
10
|
-
".git",
|
|
11
|
-
"dist",
|
|
12
|
-
"build",
|
|
13
|
-
".next",
|
|
14
|
-
".pi-lens",
|
|
15
|
-
".pi", // pi agent directory
|
|
16
|
-
".ruff_cache", // Python linter cache
|
|
17
|
-
"venv",
|
|
18
|
-
".venv",
|
|
19
|
-
"coverage",
|
|
20
|
-
"__pycache__",
|
|
21
|
-
".tox",
|
|
22
|
-
".pytest_cache",
|
|
23
|
-
];
|
|
24
|
-
/**
|
|
25
|
-
* Check if file path is a test/fixture/mock file.
|
|
26
|
-
* Used by secrets scanner, rate command, and dispatch runners
|
|
27
|
-
* to skip these files (false positives on fake credentials, etc).
|
|
28
|
-
*/
|
|
29
|
-
export function isTestFile(filePath) {
|
|
30
|
-
const normalized = filePath.replace(/\\/g, "/");
|
|
31
|
-
return (normalized.includes(".test.") ||
|
|
32
|
-
normalized.includes(".spec.") ||
|
|
33
|
-
normalized.includes("/test/") ||
|
|
34
|
-
normalized.includes("/tests/") ||
|
|
35
|
-
normalized.includes("__tests__/") ||
|
|
36
|
-
normalized.includes("test-utils") ||
|
|
37
|
-
normalized.startsWith("test-") ||
|
|
38
|
-
normalized.includes(".fixture.") ||
|
|
39
|
-
normalized.includes(".mock."));
|
|
40
|
-
}
|