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,44 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Shared formatting utilities for the dispatch system.
|
|
3
|
-
*/
|
|
4
|
-
export const EMOJI = {
|
|
5
|
-
blocking: "🔴",
|
|
6
|
-
warning: "🟡",
|
|
7
|
-
fixed: "✅",
|
|
8
|
-
info: "ℹ️",
|
|
9
|
-
silent: "📊",
|
|
10
|
-
none: "",
|
|
11
|
-
};
|
|
12
|
-
/**
|
|
13
|
-
* Format a single diagnostic for display
|
|
14
|
-
*/
|
|
15
|
-
export function formatDiagnostic(d) {
|
|
16
|
-
const line = d.line ? `L${d.line}: ` : "";
|
|
17
|
-
const indented = d.message.split("\n").join("\n ");
|
|
18
|
-
return ` ${line}${indented}`;
|
|
19
|
-
}
|
|
20
|
-
/**
|
|
21
|
-
* Format a group of diagnostics with semantic header
|
|
22
|
-
*/
|
|
23
|
-
export function formatDiagnostics(diagnostics, semantic, maxDisplay = 10) {
|
|
24
|
-
if (diagnostics.length === 0)
|
|
25
|
-
return "";
|
|
26
|
-
const emoji = EMOJI[semantic] ?? EMOJI.warning;
|
|
27
|
-
let output = "";
|
|
28
|
-
if (semantic === "blocking") {
|
|
29
|
-
output += `\n${emoji} STOP — ${diagnostics.length} issue(s) must be fixed:\n`;
|
|
30
|
-
}
|
|
31
|
-
else if (semantic === "warning") {
|
|
32
|
-
output += `\n${emoji} ${diagnostics.length} warning(s):\n`;
|
|
33
|
-
}
|
|
34
|
-
else if (semantic === "fixed") {
|
|
35
|
-
output += `\n${emoji} Auto-fixed ${diagnostics.length} issue(s):\n`;
|
|
36
|
-
}
|
|
37
|
-
for (const d of diagnostics.slice(0, maxDisplay)) {
|
|
38
|
-
output += `${formatDiagnostic(d)}\n`;
|
|
39
|
-
}
|
|
40
|
-
if (diagnostics.length > maxDisplay) {
|
|
41
|
-
output += ` ... and ${diagnostics.length - maxDisplay} more\n`;
|
|
42
|
-
}
|
|
43
|
-
return output;
|
|
44
|
-
}
|
package/clients/dogfood.test.js
DELETED
|
@@ -1,201 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Meta-test: Run similarity detection on pi-lens codebase
|
|
3
|
-
*
|
|
4
|
-
* This is a "dogfood" test - we run the reuse detection on our own code
|
|
5
|
-
* to see what it finds. Educational and useful for improving the algorithm!
|
|
6
|
-
*/
|
|
7
|
-
import * as fs from "node:fs/promises";
|
|
8
|
-
import * as path from "node:path";
|
|
9
|
-
import { fileURLToPath } from "node:url";
|
|
10
|
-
import { glob } from "glob";
|
|
11
|
-
import { beforeAll, describe, expect, it } from "vitest";
|
|
12
|
-
import { buildProjectIndex, findSimilarFunctions, } from "./project-index.js";
|
|
13
|
-
import { calculateSimilarity as calcMatrixSimilarity } from "./state-matrix.js";
|
|
14
|
-
// Find project root by looking for package.json
|
|
15
|
-
async function findProjectRoot(startDir) {
|
|
16
|
-
let dir = startDir;
|
|
17
|
-
while (dir !== path.dirname(dir)) {
|
|
18
|
-
try {
|
|
19
|
-
await fs.access(path.join(dir, "package.json"));
|
|
20
|
-
return dir;
|
|
21
|
-
}
|
|
22
|
-
catch {
|
|
23
|
-
dir = path.dirname(dir);
|
|
24
|
-
}
|
|
25
|
-
}
|
|
26
|
-
throw new Error("Could not find project root (no package.json)");
|
|
27
|
-
}
|
|
28
|
-
// Test a known similar pair
|
|
29
|
-
const _SIMILAR_FUNCTIONS = {
|
|
30
|
-
description: "Extracting similar logic patterns in pi-lens",
|
|
31
|
-
pairs: [
|
|
32
|
-
{
|
|
33
|
-
name: "runners/index.ts pattern",
|
|
34
|
-
files: [
|
|
35
|
-
"clients/dispatch/runners/index.ts",
|
|
36
|
-
"clients/dispatch/runners/architect.ts",
|
|
37
|
-
],
|
|
38
|
-
expected: "High similarity in runner registration patterns",
|
|
39
|
-
},
|
|
40
|
-
{
|
|
41
|
-
name: "Client pattern",
|
|
42
|
-
files: ["clients/typescript-client.ts", "clients/biome-client.ts"],
|
|
43
|
-
expected: "Similar client structures",
|
|
44
|
-
},
|
|
45
|
-
],
|
|
46
|
-
};
|
|
47
|
-
describe("🐶 Dogfood Test: Similarity on pi-lens codebase", () => {
|
|
48
|
-
let index;
|
|
49
|
-
let projectRoot;
|
|
50
|
-
beforeAll(async () => {
|
|
51
|
-
// Find project root
|
|
52
|
-
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
53
|
-
projectRoot = await findProjectRoot(__dirname);
|
|
54
|
-
// Build index of the entire codebase
|
|
55
|
-
console.log("\n🏗️ Building index of pi-lens codebase...");
|
|
56
|
-
console.log(` Project root: ${projectRoot}`);
|
|
57
|
-
const files = await glob("clients/**/*.ts", {
|
|
58
|
-
cwd: projectRoot,
|
|
59
|
-
ignore: ["**/*.test.ts", "**/*.spec.ts", "**/node_modules/**"],
|
|
60
|
-
});
|
|
61
|
-
console.log(` Found ${files.length} source files`);
|
|
62
|
-
const absoluteFiles = files.map((f) => path.join(projectRoot, f));
|
|
63
|
-
index = await buildProjectIndex(projectRoot, absoluteFiles);
|
|
64
|
-
console.log(` Indexed ${index.entries.size} functions`);
|
|
65
|
-
// Show some indexed functions
|
|
66
|
-
const sample = Array.from(index.entries.values()).slice(0, 5);
|
|
67
|
-
console.log("\n📋 Sample indexed functions:");
|
|
68
|
-
sample.forEach((e, i) => {
|
|
69
|
-
console.log(` ${i + 1}. ${e.id} (${e.transitionCount} transitions)`);
|
|
70
|
-
});
|
|
71
|
-
}, 30000); // 30s timeout for indexing
|
|
72
|
-
describe("Index validation", () => {
|
|
73
|
-
it("should have indexed functions", () => {
|
|
74
|
-
expect(index.entries.size).toBeGreaterThan(0);
|
|
75
|
-
console.log(`\n✅ Indexed ${index.entries.size} functions`);
|
|
76
|
-
});
|
|
77
|
-
it("should have functions with >20 transitions", () => {
|
|
78
|
-
const complex = Array.from(index.entries.values()).filter((e) => e.transitionCount >= 20);
|
|
79
|
-
expect(complex.length).toBeGreaterThan(0);
|
|
80
|
-
console.log(`\n✅ ${complex.length} functions pass complexity guardrail`);
|
|
81
|
-
});
|
|
82
|
-
});
|
|
83
|
-
describe("Find similar functions in our own codebase", () => {
|
|
84
|
-
it("should find similar patterns among runners", async () => {
|
|
85
|
-
// Find runner files
|
|
86
|
-
const runnerEntries = Array.from(index.entries.values()).filter((e) => e.filePath.includes("dispatch/runners/"));
|
|
87
|
-
console.log(`\n🔍 Testing ${runnerEntries.length} runner functions`);
|
|
88
|
-
const similarities = [];
|
|
89
|
-
// Compare each pair
|
|
90
|
-
for (let i = 0; i < runnerEntries.length; i++) {
|
|
91
|
-
for (let j = i + 1; j < runnerEntries.length; j++) {
|
|
92
|
-
const entry1 = runnerEntries[i];
|
|
93
|
-
const entry2 = runnerEntries[j];
|
|
94
|
-
// Skip if same file
|
|
95
|
-
if (entry1.filePath === entry2.filePath)
|
|
96
|
-
continue;
|
|
97
|
-
const sim = calcMatrixSimilarity(entry1.matrix, entry2.matrix);
|
|
98
|
-
if (sim >= 0.75) {
|
|
99
|
-
similarities.push({
|
|
100
|
-
func1: entry1.id,
|
|
101
|
-
func2: entry2.id,
|
|
102
|
-
similarity: sim,
|
|
103
|
-
});
|
|
104
|
-
}
|
|
105
|
-
}
|
|
106
|
-
}
|
|
107
|
-
// Sort by similarity
|
|
108
|
-
similarities.sort((a, b) => b.similarity - a.similarity);
|
|
109
|
-
console.log(`\n📊 Found ${similarities.length} similar pairs (>75%):`);
|
|
110
|
-
similarities.slice(0, 5).forEach((s, i) => {
|
|
111
|
-
console.log(` ${i + 1}. ${s.func1} ↔ ${s.func2}`);
|
|
112
|
-
console.log(` Similarity: ${(s.similarity * 100).toFixed(1)}%`);
|
|
113
|
-
});
|
|
114
|
-
// Log findings but don't fail - this is exploratory
|
|
115
|
-
expect(similarities.length).toBeGreaterThanOrEqual(0);
|
|
116
|
-
});
|
|
117
|
-
it("should find similar client patterns", async () => {
|
|
118
|
-
const clientEntries = Array.from(index.entries.values()).filter((e) => e.filePath.includes("clients/") &&
|
|
119
|
-
e.filePath.includes("-client.ts") &&
|
|
120
|
-
!e.filePath.includes("test"));
|
|
121
|
-
console.log(`\n🔍 Testing ${clientEntries.length} client functions`);
|
|
122
|
-
const similarities = [];
|
|
123
|
-
for (let i = 0; i < clientEntries.length; i++) {
|
|
124
|
-
for (let j = i + 1; j < clientEntries.length; j++) {
|
|
125
|
-
const entry1 = clientEntries[i];
|
|
126
|
-
const entry2 = clientEntries[j];
|
|
127
|
-
if (entry1.filePath === entry2.filePath)
|
|
128
|
-
continue;
|
|
129
|
-
const sim = calcMatrixSimilarity(entry1.matrix, entry2.matrix);
|
|
130
|
-
if (sim >= 0.75) {
|
|
131
|
-
similarities.push({
|
|
132
|
-
func1: entry1.id,
|
|
133
|
-
func2: entry2.id,
|
|
134
|
-
similarity: sim,
|
|
135
|
-
});
|
|
136
|
-
}
|
|
137
|
-
}
|
|
138
|
-
}
|
|
139
|
-
similarities.sort((a, b) => b.similarity - a.similarity);
|
|
140
|
-
console.log(`\n📊 Found ${similarities.length} similar client patterns (>75%):`);
|
|
141
|
-
similarities.slice(0, 3).forEach((s, i) => {
|
|
142
|
-
console.log(` ${i + 1}. ${s.func1} ↔ ${s.func2}`);
|
|
143
|
-
console.log(` Similarity: ${(s.similarity * 100).toFixed(1)}%`);
|
|
144
|
-
});
|
|
145
|
-
expect(similarities.length).toBeGreaterThanOrEqual(0);
|
|
146
|
-
});
|
|
147
|
-
});
|
|
148
|
-
describe("Find potential refactor opportunities", () => {
|
|
149
|
-
it("should identify duplicate utility functions", () => {
|
|
150
|
-
// Look for functions with very high similarity (>90%)
|
|
151
|
-
const entries = Array.from(index.entries.values());
|
|
152
|
-
const seenPairs = new Set(); // Deduplicate A→B and B→A
|
|
153
|
-
const duplicates = [];
|
|
154
|
-
for (const entry of entries) {
|
|
155
|
-
const matches = findSimilarFunctions(entry.matrix, index, 0.9, 3);
|
|
156
|
-
for (const match of matches) {
|
|
157
|
-
if (match.targetId === entry.id)
|
|
158
|
-
continue;
|
|
159
|
-
// Canonical pair key (sorted to avoid A,B and B,A)
|
|
160
|
-
const pairKey = [entry.id, match.targetId].sort().join("::");
|
|
161
|
-
if (seenPairs.has(pairKey))
|
|
162
|
-
continue;
|
|
163
|
-
seenPairs.add(pairKey);
|
|
164
|
-
duplicates.push({
|
|
165
|
-
func: entry.id,
|
|
166
|
-
similarTo: match.targetId,
|
|
167
|
-
similarity: match.similarity,
|
|
168
|
-
});
|
|
169
|
-
}
|
|
170
|
-
}
|
|
171
|
-
console.log(`\n🎯 Found ${duplicates.length} unique potential duplicates (>90%):`);
|
|
172
|
-
duplicates.slice(0, 5).forEach((d, i) => {
|
|
173
|
-
console.log(` ${i + 1}. ${d.func}`);
|
|
174
|
-
console.log(` Similar to: ${d.similarTo}`);
|
|
175
|
-
console.log(` Match: ${(d.similarity * 100).toFixed(1)}%`);
|
|
176
|
-
});
|
|
177
|
-
// This is informational - we don't assert on it
|
|
178
|
-
expect(true).toBe(true);
|
|
179
|
-
});
|
|
180
|
-
});
|
|
181
|
-
describe("Complexity distribution", () => {
|
|
182
|
-
it("should show transition count distribution", () => {
|
|
183
|
-
const entries = Array.from(index.entries.values());
|
|
184
|
-
const transitionCounts = entries.map((e) => e.transitionCount);
|
|
185
|
-
const avg = transitionCounts.reduce((a, b) => a + b, 0) / transitionCounts.length;
|
|
186
|
-
const min = Math.min(...transitionCounts);
|
|
187
|
-
const max = Math.max(...transitionCounts);
|
|
188
|
-
const belowThreshold = transitionCounts.filter((c) => c < 20).length;
|
|
189
|
-
const aboveThreshold = transitionCounts.filter((c) => c >= 20).length;
|
|
190
|
-
console.log("\n📊 Complexity Distribution:");
|
|
191
|
-
console.log(` Total functions: ${entries.length}`);
|
|
192
|
-
console.log(` Below threshold (<20): ${belowThreshold}`);
|
|
193
|
-
console.log(` Above threshold (≥20): ${aboveThreshold}`);
|
|
194
|
-
console.log(` Min transitions: ${min}`);
|
|
195
|
-
console.log(` Max transitions: ${max}`);
|
|
196
|
-
console.log(` Average: ${avg.toFixed(1)}`);
|
|
197
|
-
// Most functions should pass the guardrail
|
|
198
|
-
expect(aboveThreshold).toBeGreaterThan(0);
|
|
199
|
-
});
|
|
200
|
-
});
|
|
201
|
-
});
|
package/clients/dogfood.test.ts
DELETED
|
@@ -1,269 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Meta-test: Run similarity detection on pi-lens codebase
|
|
3
|
-
*
|
|
4
|
-
* This is a "dogfood" test - we run the reuse detection on our own code
|
|
5
|
-
* to see what it finds. Educational and useful for improving the algorithm!
|
|
6
|
-
*/
|
|
7
|
-
|
|
8
|
-
import * as fs from "node:fs/promises";
|
|
9
|
-
import * as path from "node:path";
|
|
10
|
-
import { fileURLToPath } from "node:url";
|
|
11
|
-
import { glob } from "glob";
|
|
12
|
-
import { beforeAll, describe, expect, it } from "vitest";
|
|
13
|
-
import {
|
|
14
|
-
buildProjectIndex,
|
|
15
|
-
findSimilarFunctions,
|
|
16
|
-
type IndexEntry,
|
|
17
|
-
type ProjectIndex,
|
|
18
|
-
} from "./project-index.js";
|
|
19
|
-
import { calculateSimilarity as calcMatrixSimilarity } from "./state-matrix.js";
|
|
20
|
-
|
|
21
|
-
// Find project root by looking for package.json
|
|
22
|
-
async function findProjectRoot(startDir: string): Promise<string> {
|
|
23
|
-
let dir = startDir;
|
|
24
|
-
while (dir !== path.dirname(dir)) {
|
|
25
|
-
try {
|
|
26
|
-
await fs.access(path.join(dir, "package.json"));
|
|
27
|
-
return dir;
|
|
28
|
-
} catch {
|
|
29
|
-
dir = path.dirname(dir);
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
|
-
throw new Error("Could not find project root (no package.json)");
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
// Test a known similar pair
|
|
36
|
-
const _SIMILAR_FUNCTIONS = {
|
|
37
|
-
description: "Extracting similar logic patterns in pi-lens",
|
|
38
|
-
pairs: [
|
|
39
|
-
{
|
|
40
|
-
name: "runners/index.ts pattern",
|
|
41
|
-
files: [
|
|
42
|
-
"clients/dispatch/runners/index.ts",
|
|
43
|
-
"clients/dispatch/runners/architect.ts",
|
|
44
|
-
],
|
|
45
|
-
expected: "High similarity in runner registration patterns",
|
|
46
|
-
},
|
|
47
|
-
{
|
|
48
|
-
name: "Client pattern",
|
|
49
|
-
files: ["clients/typescript-client.ts", "clients/biome-client.ts"],
|
|
50
|
-
expected: "Similar client structures",
|
|
51
|
-
},
|
|
52
|
-
],
|
|
53
|
-
};
|
|
54
|
-
|
|
55
|
-
describe("🐶 Dogfood Test: Similarity on pi-lens codebase", () => {
|
|
56
|
-
let index: ProjectIndex;
|
|
57
|
-
let projectRoot: string;
|
|
58
|
-
|
|
59
|
-
beforeAll(async () => {
|
|
60
|
-
// Find project root
|
|
61
|
-
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
62
|
-
projectRoot = await findProjectRoot(__dirname);
|
|
63
|
-
|
|
64
|
-
// Build index of the entire codebase
|
|
65
|
-
console.log("\n🏗️ Building index of pi-lens codebase...");
|
|
66
|
-
console.log(` Project root: ${projectRoot}`);
|
|
67
|
-
|
|
68
|
-
const files = await glob("clients/**/*.ts", {
|
|
69
|
-
cwd: projectRoot,
|
|
70
|
-
ignore: ["**/*.test.ts", "**/*.spec.ts", "**/node_modules/**"],
|
|
71
|
-
});
|
|
72
|
-
|
|
73
|
-
console.log(` Found ${files.length} source files`);
|
|
74
|
-
|
|
75
|
-
const absoluteFiles = files.map((f) => path.join(projectRoot, f));
|
|
76
|
-
index = await buildProjectIndex(projectRoot, absoluteFiles);
|
|
77
|
-
|
|
78
|
-
console.log(` Indexed ${index.entries.size} functions`);
|
|
79
|
-
|
|
80
|
-
// Show some indexed functions
|
|
81
|
-
const sample = Array.from(index.entries.values()).slice(0, 5);
|
|
82
|
-
console.log("\n📋 Sample indexed functions:");
|
|
83
|
-
sample.forEach((e: IndexEntry, i: number) => {
|
|
84
|
-
console.log(` ${i + 1}. ${e.id} (${e.transitionCount} transitions)`);
|
|
85
|
-
});
|
|
86
|
-
}, 30000); // 30s timeout for indexing
|
|
87
|
-
|
|
88
|
-
describe("Index validation", () => {
|
|
89
|
-
it("should have indexed functions", () => {
|
|
90
|
-
expect(index.entries.size).toBeGreaterThan(0);
|
|
91
|
-
console.log(`\n✅ Indexed ${index.entries.size} functions`);
|
|
92
|
-
});
|
|
93
|
-
|
|
94
|
-
it("should have functions with >20 transitions", () => {
|
|
95
|
-
const complex = Array.from(index.entries.values()).filter(
|
|
96
|
-
(e) => e.transitionCount >= 20,
|
|
97
|
-
);
|
|
98
|
-
expect(complex.length).toBeGreaterThan(0);
|
|
99
|
-
console.log(`\n✅ ${complex.length} functions pass complexity guardrail`);
|
|
100
|
-
});
|
|
101
|
-
});
|
|
102
|
-
|
|
103
|
-
describe("Find similar functions in our own codebase", () => {
|
|
104
|
-
it("should find similar patterns among runners", async () => {
|
|
105
|
-
// Find runner files
|
|
106
|
-
const runnerEntries = Array.from(index.entries.values()).filter(
|
|
107
|
-
(e: IndexEntry) => e.filePath.includes("dispatch/runners/"),
|
|
108
|
-
);
|
|
109
|
-
|
|
110
|
-
console.log(`\n🔍 Testing ${runnerEntries.length} runner functions`);
|
|
111
|
-
|
|
112
|
-
const similarities: {
|
|
113
|
-
func1: string;
|
|
114
|
-
func2: string;
|
|
115
|
-
similarity: number;
|
|
116
|
-
}[] = [];
|
|
117
|
-
|
|
118
|
-
// Compare each pair
|
|
119
|
-
for (let i = 0; i < runnerEntries.length; i++) {
|
|
120
|
-
for (let j = i + 1; j < runnerEntries.length; j++) {
|
|
121
|
-
const entry1 = runnerEntries[i];
|
|
122
|
-
const entry2 = runnerEntries[j];
|
|
123
|
-
|
|
124
|
-
// Skip if same file
|
|
125
|
-
if (entry1.filePath === entry2.filePath) continue;
|
|
126
|
-
|
|
127
|
-
const sim = calcMatrixSimilarity(entry1.matrix, entry2.matrix);
|
|
128
|
-
|
|
129
|
-
if (sim >= 0.75) {
|
|
130
|
-
similarities.push({
|
|
131
|
-
func1: entry1.id,
|
|
132
|
-
func2: entry2.id,
|
|
133
|
-
similarity: sim,
|
|
134
|
-
});
|
|
135
|
-
}
|
|
136
|
-
}
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
// Sort by similarity
|
|
140
|
-
similarities.sort((a, b) => b.similarity - a.similarity);
|
|
141
|
-
|
|
142
|
-
console.log(`\n📊 Found ${similarities.length} similar pairs (>75%):`);
|
|
143
|
-
similarities.slice(0, 5).forEach((s, i) => {
|
|
144
|
-
console.log(` ${i + 1}. ${s.func1} ↔ ${s.func2}`);
|
|
145
|
-
console.log(` Similarity: ${(s.similarity * 100).toFixed(1)}%`);
|
|
146
|
-
});
|
|
147
|
-
|
|
148
|
-
// Log findings but don't fail - this is exploratory
|
|
149
|
-
expect(similarities.length).toBeGreaterThanOrEqual(0);
|
|
150
|
-
});
|
|
151
|
-
|
|
152
|
-
it("should find similar client patterns", async () => {
|
|
153
|
-
const clientEntries = Array.from(index.entries.values()).filter(
|
|
154
|
-
(e: IndexEntry) =>
|
|
155
|
-
e.filePath.includes("clients/") &&
|
|
156
|
-
e.filePath.includes("-client.ts") &&
|
|
157
|
-
!e.filePath.includes("test"),
|
|
158
|
-
);
|
|
159
|
-
|
|
160
|
-
console.log(`\n🔍 Testing ${clientEntries.length} client functions`);
|
|
161
|
-
|
|
162
|
-
const similarities: {
|
|
163
|
-
func1: string;
|
|
164
|
-
func2: string;
|
|
165
|
-
similarity: number;
|
|
166
|
-
}[] = [];
|
|
167
|
-
|
|
168
|
-
for (let i = 0; i < clientEntries.length; i++) {
|
|
169
|
-
for (let j = i + 1; j < clientEntries.length; j++) {
|
|
170
|
-
const entry1 = clientEntries[i];
|
|
171
|
-
const entry2 = clientEntries[j];
|
|
172
|
-
|
|
173
|
-
if (entry1.filePath === entry2.filePath) continue;
|
|
174
|
-
|
|
175
|
-
const sim = calcMatrixSimilarity(entry1.matrix, entry2.matrix);
|
|
176
|
-
|
|
177
|
-
if (sim >= 0.75) {
|
|
178
|
-
similarities.push({
|
|
179
|
-
func1: entry1.id,
|
|
180
|
-
func2: entry2.id,
|
|
181
|
-
similarity: sim,
|
|
182
|
-
});
|
|
183
|
-
}
|
|
184
|
-
}
|
|
185
|
-
}
|
|
186
|
-
|
|
187
|
-
similarities.sort((a, b) => b.similarity - a.similarity);
|
|
188
|
-
|
|
189
|
-
console.log(
|
|
190
|
-
`\n📊 Found ${similarities.length} similar client patterns (>75%):`,
|
|
191
|
-
);
|
|
192
|
-
similarities.slice(0, 3).forEach((s, i) => {
|
|
193
|
-
console.log(` ${i + 1}. ${s.func1} ↔ ${s.func2}`);
|
|
194
|
-
console.log(` Similarity: ${(s.similarity * 100).toFixed(1)}%`);
|
|
195
|
-
});
|
|
196
|
-
|
|
197
|
-
expect(similarities.length).toBeGreaterThanOrEqual(0);
|
|
198
|
-
});
|
|
199
|
-
});
|
|
200
|
-
|
|
201
|
-
describe("Find potential refactor opportunities", () => {
|
|
202
|
-
it("should identify duplicate utility functions", () => {
|
|
203
|
-
// Look for functions with very high similarity (>90%)
|
|
204
|
-
const entries = Array.from(index.entries.values());
|
|
205
|
-
const seenPairs = new Set<string>(); // Deduplicate A→B and B→A
|
|
206
|
-
const duplicates: {
|
|
207
|
-
func: string;
|
|
208
|
-
similarTo: string;
|
|
209
|
-
similarity: number;
|
|
210
|
-
}[] = [];
|
|
211
|
-
|
|
212
|
-
for (const entry of entries) {
|
|
213
|
-
const matches = findSimilarFunctions(entry.matrix, index, 0.9, 3);
|
|
214
|
-
for (const match of matches) {
|
|
215
|
-
if (match.targetId === entry.id) continue;
|
|
216
|
-
|
|
217
|
-
// Canonical pair key (sorted to avoid A,B and B,A)
|
|
218
|
-
const pairKey = [entry.id, match.targetId].sort().join("::");
|
|
219
|
-
if (seenPairs.has(pairKey)) continue;
|
|
220
|
-
|
|
221
|
-
seenPairs.add(pairKey);
|
|
222
|
-
duplicates.push({
|
|
223
|
-
func: entry.id,
|
|
224
|
-
similarTo: match.targetId,
|
|
225
|
-
similarity: match.similarity,
|
|
226
|
-
});
|
|
227
|
-
}
|
|
228
|
-
}
|
|
229
|
-
|
|
230
|
-
console.log(
|
|
231
|
-
`\n🎯 Found ${duplicates.length} unique potential duplicates (>90%):`,
|
|
232
|
-
);
|
|
233
|
-
duplicates.slice(0, 5).forEach((d, i) => {
|
|
234
|
-
console.log(` ${i + 1}. ${d.func}`);
|
|
235
|
-
console.log(` Similar to: ${d.similarTo}`);
|
|
236
|
-
console.log(` Match: ${(d.similarity * 100).toFixed(1)}%`);
|
|
237
|
-
});
|
|
238
|
-
|
|
239
|
-
// This is informational - we don't assert on it
|
|
240
|
-
expect(true).toBe(true);
|
|
241
|
-
});
|
|
242
|
-
});
|
|
243
|
-
|
|
244
|
-
describe("Complexity distribution", () => {
|
|
245
|
-
it("should show transition count distribution", () => {
|
|
246
|
-
const entries = Array.from(index.entries.values());
|
|
247
|
-
const transitionCounts = entries.map((e) => e.transitionCount);
|
|
248
|
-
|
|
249
|
-
const avg =
|
|
250
|
-
transitionCounts.reduce((a, b) => a + b, 0) / transitionCounts.length;
|
|
251
|
-
const min = Math.min(...transitionCounts);
|
|
252
|
-
const max = Math.max(...transitionCounts);
|
|
253
|
-
|
|
254
|
-
const belowThreshold = transitionCounts.filter((c) => c < 20).length;
|
|
255
|
-
const aboveThreshold = transitionCounts.filter((c) => c >= 20).length;
|
|
256
|
-
|
|
257
|
-
console.log("\n📊 Complexity Distribution:");
|
|
258
|
-
console.log(` Total functions: ${entries.length}`);
|
|
259
|
-
console.log(` Below threshold (<20): ${belowThreshold}`);
|
|
260
|
-
console.log(` Above threshold (≥20): ${aboveThreshold}`);
|
|
261
|
-
console.log(` Min transitions: ${min}`);
|
|
262
|
-
console.log(` Max transitions: ${max}`);
|
|
263
|
-
console.log(` Average: ${avg.toFixed(1)}`);
|
|
264
|
-
|
|
265
|
-
// Most functions should pass the guardrail
|
|
266
|
-
expect(aboveThreshold).toBeGreaterThan(0);
|
|
267
|
-
});
|
|
268
|
-
});
|
|
269
|
-
});
|
package/clients/file-kinds.js
DELETED
|
@@ -1,177 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* File Kind Detection for pi-lens
|
|
3
|
-
*
|
|
4
|
-
* Centralized file type detection to avoid duplication across clients.
|
|
5
|
-
* Maps file extensions and paths to semantic file kinds.
|
|
6
|
-
*/
|
|
7
|
-
import { basename, extname } from "node:path";
|
|
8
|
-
// --- Extension Maps ---
|
|
9
|
-
const KIND_EXTENSIONS = {
|
|
10
|
-
jsts: [".js", ".jsx", ".ts", ".tsx", ".mjs", ".cjs", ".svelte"],
|
|
11
|
-
python: [".py"],
|
|
12
|
-
go: [".go"],
|
|
13
|
-
rust: [".rs"],
|
|
14
|
-
cxx: [
|
|
15
|
-
".c",
|
|
16
|
-
".cc",
|
|
17
|
-
".cpp",
|
|
18
|
-
".cxx",
|
|
19
|
-
".h",
|
|
20
|
-
".hh",
|
|
21
|
-
".hpp",
|
|
22
|
-
".hxx",
|
|
23
|
-
".ixx",
|
|
24
|
-
".ipp",
|
|
25
|
-
".inl",
|
|
26
|
-
".tpp",
|
|
27
|
-
".txx",
|
|
28
|
-
],
|
|
29
|
-
cmake: [".cmake"],
|
|
30
|
-
shell: [".sh", ".bash", ".zsh", ".fish"],
|
|
31
|
-
json: [".json", ".jsonc", ".json5"],
|
|
32
|
-
markdown: [".md", ".mdx"],
|
|
33
|
-
css: [".css", ".scss", ".sass", ".less"],
|
|
34
|
-
yaml: [".yaml", ".yml"],
|
|
35
|
-
};
|
|
36
|
-
// Reverse map: extension → file kind (for fast lookup)
|
|
37
|
-
const EXT_TO_KIND = new Map();
|
|
38
|
-
for (const [kind, exts] of Object.entries(KIND_EXTENSIONS)) {
|
|
39
|
-
for (const ext of exts) {
|
|
40
|
-
EXT_TO_KIND.set(ext.toLowerCase(), kind);
|
|
41
|
-
}
|
|
42
|
-
// Also register without leading dot
|
|
43
|
-
for (const ext of exts) {
|
|
44
|
-
if (ext.startsWith(".")) {
|
|
45
|
-
EXT_TO_KIND.set(ext.slice(1).toLowerCase(), kind);
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
// Special filenames that indicate a file kind
|
|
50
|
-
const SPECIAL_FILENAMES = [
|
|
51
|
-
{ pattern: /^CMakeLists\.txt$/i, kind: "cmake" },
|
|
52
|
-
{ pattern: /^Makefile$/i, kind: "shell" },
|
|
53
|
-
{ pattern: /^ Dockerfile(\.\w+)?$/i, kind: "shell" },
|
|
54
|
-
];
|
|
55
|
-
// --- Detection Functions ---
|
|
56
|
-
/**
|
|
57
|
-
* Detect the file kind from a file path.
|
|
58
|
-
* Returns the semantic file kind or undefined if unknown.
|
|
59
|
-
*/
|
|
60
|
-
export function detectFileKind(filePath) {
|
|
61
|
-
if (!filePath || typeof filePath !== "string") {
|
|
62
|
-
return undefined;
|
|
63
|
-
}
|
|
64
|
-
// Check special filenames first
|
|
65
|
-
const base = basename(filePath);
|
|
66
|
-
for (const { pattern, kind } of SPECIAL_FILENAMES) {
|
|
67
|
-
if (pattern.test(base)) {
|
|
68
|
-
return kind;
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
// Check by extension
|
|
72
|
-
const ext = extname(filePath).toLowerCase();
|
|
73
|
-
return EXT_TO_KIND.get(ext);
|
|
74
|
-
}
|
|
75
|
-
/**
|
|
76
|
-
* Check if a file kind is supported by a specific tool or capability.
|
|
77
|
-
*
|
|
78
|
-
* @example
|
|
79
|
-
* // Check if TypeScript file
|
|
80
|
-
* if (isFileKind(filePath, "jsts")) { ... }
|
|
81
|
-
*
|
|
82
|
-
* // Check for multiple kinds
|
|
83
|
-
* if (isFileKind(filePath, ["jsts", "python"])) { ... }
|
|
84
|
-
*/
|
|
85
|
-
export function isFileKind(filePath, kind) {
|
|
86
|
-
const detected = detectFileKind(filePath);
|
|
87
|
-
if (!detected)
|
|
88
|
-
return false;
|
|
89
|
-
if (Array.isArray(kind)) {
|
|
90
|
-
return kind.includes(detected);
|
|
91
|
-
}
|
|
92
|
-
return detected === kind;
|
|
93
|
-
}
|
|
94
|
-
/**
|
|
95
|
-
* Get all file kinds that match a given file extension.
|
|
96
|
-
* Useful for listing which tools might handle a file.
|
|
97
|
-
*/
|
|
98
|
-
export function getFileKindsForExtension(ext) {
|
|
99
|
-
const normalizedExt = ext.startsWith(".") ? ext : `.${ext}`;
|
|
100
|
-
const kind = EXT_TO_KIND.get(normalizedExt.toLowerCase());
|
|
101
|
-
return kind ? [kind] : [];
|
|
102
|
-
}
|
|
103
|
-
/**
|
|
104
|
-
* Check if a file kind represents a code file (not config/markdown).
|
|
105
|
-
*/
|
|
106
|
-
export function isCodeKind(kind) {
|
|
107
|
-
return ["jsts", "python", "go", "rust", "cxx", "shell"].includes(kind);
|
|
108
|
-
}
|
|
109
|
-
/**
|
|
110
|
-
* Check if a file kind represents a text/config file.
|
|
111
|
-
*/
|
|
112
|
-
export function isConfigKind(kind) {
|
|
113
|
-
return ["json", "yaml", "markdown", "css"].includes(kind);
|
|
114
|
-
}
|
|
115
|
-
/**
|
|
116
|
-
* Get human-readable description of a file kind.
|
|
117
|
-
*/
|
|
118
|
-
export function getFileKindLabel(kind) {
|
|
119
|
-
const labels = {
|
|
120
|
-
jsts: "JavaScript/TypeScript",
|
|
121
|
-
python: "Python",
|
|
122
|
-
go: "Go",
|
|
123
|
-
rust: "Rust",
|
|
124
|
-
cxx: "C/C++",
|
|
125
|
-
cmake: "CMake",
|
|
126
|
-
shell: "Shell",
|
|
127
|
-
json: "JSON",
|
|
128
|
-
markdown: "Markdown",
|
|
129
|
-
css: "CSS",
|
|
130
|
-
yaml: "YAML",
|
|
131
|
-
};
|
|
132
|
-
return labels[kind] ?? kind;
|
|
133
|
-
}
|
|
134
|
-
/**
|
|
135
|
-
* Get file extensions for a file kind.
|
|
136
|
-
*/
|
|
137
|
-
export function getExtensionsForKind(kind) {
|
|
138
|
-
return [...(KIND_EXTENSIONS[kind] ?? [])];
|
|
139
|
-
}
|
|
140
|
-
/**
|
|
141
|
-
* Check if a file should be scanned for linting/formatting.
|
|
142
|
-
* Excludes test files, generated files, etc.
|
|
143
|
-
*/
|
|
144
|
-
export function isScannableFile(filePath) {
|
|
145
|
-
const kind = detectFileKind(filePath);
|
|
146
|
-
if (!kind)
|
|
147
|
-
return false;
|
|
148
|
-
// Exclude test files for most kinds
|
|
149
|
-
const base = basename(filePath);
|
|
150
|
-
if (base.includes(".test.") ||
|
|
151
|
-
base.includes(".spec.") ||
|
|
152
|
-
base.startsWith("test-") ||
|
|
153
|
-
base.startsWith("spec-")) {
|
|
154
|
-
return false;
|
|
155
|
-
}
|
|
156
|
-
// Only scan code and config files
|
|
157
|
-
return isCodeKind(kind) || isConfigKind(kind);
|
|
158
|
-
}
|
|
159
|
-
/**
|
|
160
|
-
* Get the language identifier for LSP/tools that use language IDs.
|
|
161
|
-
*/
|
|
162
|
-
export function getLanguageId(kind) {
|
|
163
|
-
const languageIds = {
|
|
164
|
-
jsts: "typescript",
|
|
165
|
-
python: "python",
|
|
166
|
-
go: "go",
|
|
167
|
-
rust: "rust",
|
|
168
|
-
cxx: "cpp",
|
|
169
|
-
cmake: "cmake",
|
|
170
|
-
shell: "shell",
|
|
171
|
-
json: "json",
|
|
172
|
-
markdown: "markdown",
|
|
173
|
-
css: "css",
|
|
174
|
-
yaml: "yaml",
|
|
175
|
-
};
|
|
176
|
-
return languageIds[kind] ?? "plaintext";
|
|
177
|
-
}
|