projscan 0.9.2 → 0.11.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (115) hide show
  1. package/README.md +37 -7
  2. package/dist/analyzers/deadCodeCheck.d.ts +10 -12
  3. package/dist/analyzers/deadCodeCheck.js +41 -69
  4. package/dist/analyzers/deadCodeCheck.js.map +1 -1
  5. package/dist/analyzers/pythonDependencyRiskCheck.d.ts +2 -0
  6. package/dist/analyzers/pythonDependencyRiskCheck.js +114 -0
  7. package/dist/analyzers/pythonDependencyRiskCheck.js.map +1 -0
  8. package/dist/analyzers/pythonLinterCheck.d.ts +2 -0
  9. package/dist/analyzers/pythonLinterCheck.js +119 -0
  10. package/dist/analyzers/pythonLinterCheck.js.map +1 -0
  11. package/dist/analyzers/pythonTestCheck.d.ts +2 -0
  12. package/dist/analyzers/pythonTestCheck.js +97 -0
  13. package/dist/analyzers/pythonTestCheck.js.map +1 -0
  14. package/dist/analyzers/pythonUnusedDependencyCheck.d.ts +2 -0
  15. package/dist/analyzers/pythonUnusedDependencyCheck.js +76 -0
  16. package/dist/analyzers/pythonUnusedDependencyCheck.js.map +1 -0
  17. package/dist/cli/index.js +294 -10
  18. package/dist/cli/index.js.map +1 -1
  19. package/dist/core/ast.d.ts +2 -0
  20. package/dist/core/ast.js +35 -2
  21. package/dist/core/ast.js.map +1 -1
  22. package/dist/core/codeGraph.d.ts +8 -7
  23. package/dist/core/codeGraph.js +50 -72
  24. package/dist/core/codeGraph.js.map +1 -1
  25. package/dist/core/couplingAnalyzer.d.ts +18 -0
  26. package/dist/core/couplingAnalyzer.js +174 -0
  27. package/dist/core/couplingAnalyzer.js.map +1 -0
  28. package/dist/core/fileInspector.d.ts +3 -0
  29. package/dist/core/fileInspector.js +78 -3
  30. package/dist/core/fileInspector.js.map +1 -1
  31. package/dist/core/hotspotAnalyzer.d.ts +13 -0
  32. package/dist/core/hotspotAnalyzer.js +29 -6
  33. package/dist/core/hotspotAnalyzer.js.map +1 -1
  34. package/dist/core/indexCache.js +8 -1
  35. package/dist/core/indexCache.js.map +1 -1
  36. package/dist/core/issueEngine.js +10 -0
  37. package/dist/core/issueEngine.js.map +1 -1
  38. package/dist/core/languages/LanguageAdapter.d.ts +36 -0
  39. package/dist/core/languages/LanguageAdapter.js +2 -0
  40. package/dist/core/languages/LanguageAdapter.js.map +1 -0
  41. package/dist/core/languages/goAdapter.d.ts +2 -0
  42. package/dist/core/languages/goAdapter.js +136 -0
  43. package/dist/core/languages/goAdapter.js.map +1 -0
  44. package/dist/core/languages/goCyclomatic.d.ts +21 -0
  45. package/dist/core/languages/goCyclomatic.js +55 -0
  46. package/dist/core/languages/goCyclomatic.js.map +1 -0
  47. package/dist/core/languages/goExports.d.ts +26 -0
  48. package/dist/core/languages/goExports.js +89 -0
  49. package/dist/core/languages/goExports.js.map +1 -0
  50. package/dist/core/languages/goImports.d.ts +26 -0
  51. package/dist/core/languages/goImports.js +64 -0
  52. package/dist/core/languages/goImports.js.map +1 -0
  53. package/dist/core/languages/goManifests.d.ts +19 -0
  54. package/dist/core/languages/goManifests.js +56 -0
  55. package/dist/core/languages/goManifests.js.map +1 -0
  56. package/dist/core/languages/javascriptAdapter.d.ts +2 -0
  57. package/dist/core/languages/javascriptAdapter.js +68 -0
  58. package/dist/core/languages/javascriptAdapter.js.map +1 -0
  59. package/dist/core/languages/pythonAdapter.d.ts +6 -0
  60. package/dist/core/languages/pythonAdapter.js +147 -0
  61. package/dist/core/languages/pythonAdapter.js.map +1 -0
  62. package/dist/core/languages/pythonCyclomatic.d.ts +18 -0
  63. package/dist/core/languages/pythonCyclomatic.js +45 -0
  64. package/dist/core/languages/pythonCyclomatic.js.map +1 -0
  65. package/dist/core/languages/pythonExports.d.ts +28 -0
  66. package/dist/core/languages/pythonExports.js +169 -0
  67. package/dist/core/languages/pythonExports.js.map +1 -0
  68. package/dist/core/languages/pythonImports.d.ts +22 -0
  69. package/dist/core/languages/pythonImports.js +104 -0
  70. package/dist/core/languages/pythonImports.js.map +1 -0
  71. package/dist/core/languages/pythonManifests.d.ts +34 -0
  72. package/dist/core/languages/pythonManifests.js +344 -0
  73. package/dist/core/languages/pythonManifests.js.map +1 -0
  74. package/dist/core/languages/registry.d.ts +5 -0
  75. package/dist/core/languages/registry.js +31 -0
  76. package/dist/core/languages/registry.js.map +1 -0
  77. package/dist/core/languages/treeSitterLoader.d.ts +14 -0
  78. package/dist/core/languages/treeSitterLoader.js +76 -0
  79. package/dist/core/languages/treeSitterLoader.js.map +1 -0
  80. package/dist/core/monorepo.d.ts +20 -0
  81. package/dist/core/monorepo.js +270 -0
  82. package/dist/core/monorepo.js.map +1 -0
  83. package/dist/core/prDiff.d.ts +43 -0
  84. package/dist/core/prDiff.js +298 -0
  85. package/dist/core/prDiff.js.map +1 -0
  86. package/dist/core/searchIndex.js +8 -0
  87. package/dist/core/searchIndex.js.map +1 -1
  88. package/dist/core/telemetry.d.ts +90 -0
  89. package/dist/core/telemetry.js +199 -0
  90. package/dist/core/telemetry.js.map +1 -0
  91. package/dist/grammars/tree-sitter-go.wasm +0 -0
  92. package/dist/grammars/tree-sitter-python.wasm +0 -0
  93. package/dist/grammars/web-tree-sitter.wasm +0 -0
  94. package/dist/mcp/server.js +22 -0
  95. package/dist/mcp/server.js.map +1 -1
  96. package/dist/mcp/tools.js +317 -20
  97. package/dist/mcp/tools.js.map +1 -1
  98. package/dist/reporters/consoleReporter.d.ts +4 -1
  99. package/dist/reporters/consoleReporter.js +113 -0
  100. package/dist/reporters/consoleReporter.js.map +1 -1
  101. package/dist/reporters/jsonReporter.d.ts +4 -1
  102. package/dist/reporters/jsonReporter.js +9 -0
  103. package/dist/reporters/jsonReporter.js.map +1 -1
  104. package/dist/reporters/markdownReporter.d.ts +4 -1
  105. package/dist/reporters/markdownReporter.js +103 -3
  106. package/dist/reporters/markdownReporter.js.map +1 -1
  107. package/dist/types.d.ts +115 -0
  108. package/dist/utils/cache.d.ts +3 -0
  109. package/dist/utils/cache.js +51 -0
  110. package/dist/utils/cache.js.map +1 -0
  111. package/dist/utils/config.js +10 -0
  112. package/dist/utils/config.js.map +1 -1
  113. package/dist/utils/fileWalker.js +14 -0
  114. package/dist/utils/fileWalker.js.map +1 -1
  115. package/package.json +11 -5
@@ -0,0 +1,344 @@
1
+ import fs from 'node:fs/promises';
2
+ import path from 'node:path';
3
+ const LOCKFILES = [
4
+ 'poetry.lock',
5
+ 'Pipfile.lock',
6
+ 'pdm.lock',
7
+ 'uv.lock',
8
+ 'conda-lock.yml',
9
+ 'conda-lock.yaml',
10
+ ];
11
+ export async function detectPythonProject(rootPath, files) {
12
+ const hasPython = files.some((f) => f.extension === '.py' || f.extension === '.pyw');
13
+ if (!hasPython)
14
+ return null;
15
+ const roots = [];
16
+ const manifestFiles = [];
17
+ const declared = [];
18
+ const pyprojectPath = path.join(rootPath, 'pyproject.toml');
19
+ const pyprojectContent = await tryRead(pyprojectPath);
20
+ if (pyprojectContent !== null) {
21
+ manifestFiles.push('pyproject.toml');
22
+ declared.push(...parsePyproject(pyprojectContent));
23
+ roots.push(...extractPyprojectRoots(pyprojectContent));
24
+ }
25
+ const setupCfgContent = await tryRead(path.join(rootPath, 'setup.cfg'));
26
+ if (setupCfgContent !== null) {
27
+ manifestFiles.push('setup.cfg');
28
+ declared.push(...parseSetupCfg(setupCfgContent));
29
+ }
30
+ const setupPyContent = await tryRead(path.join(rootPath, 'setup.py'));
31
+ if (setupPyContent !== null) {
32
+ manifestFiles.push('setup.py');
33
+ declared.push(...parseSetupPyInstallRequires(setupPyContent));
34
+ }
35
+ // Read requirements*.txt at repo root.
36
+ const reqFiles = files
37
+ .filter((f) => (!f.directory || f.directory === '.') &&
38
+ /^requirements(-.*)?\.txt$/i.test(path.basename(f.relativePath)))
39
+ .map((f) => f.relativePath);
40
+ for (const rel of reqFiles) {
41
+ const content = await tryRead(path.join(rootPath, rel));
42
+ if (content === null)
43
+ continue;
44
+ manifestFiles.push(rel);
45
+ const isDev = /requirements(-test|-dev|-lint)\.txt$/i.test(rel);
46
+ declared.push(...parseRequirements(content, rel, isDev ? 'dev' : 'main'));
47
+ }
48
+ // Infer package roots from __init__.py placement if none declared.
49
+ if (roots.length === 0) {
50
+ roots.push(...inferRootsFromInitFiles(files));
51
+ }
52
+ // Always fall back to repo root.
53
+ if (roots.length === 0)
54
+ roots.push('.');
55
+ // Lockfile detection.
56
+ let hasLockfile = false;
57
+ for (const name of LOCKFILES) {
58
+ const lockPath = path.join(rootPath, name);
59
+ if ((await tryRead(lockPath)) !== null) {
60
+ hasLockfile = true;
61
+ break;
62
+ }
63
+ }
64
+ if (!hasLockfile) {
65
+ // requirements.txt with pinned versions counts as a lockfile for us.
66
+ for (const rel of reqFiles) {
67
+ const content = await tryRead(path.join(rootPath, rel));
68
+ if (content !== null && hasPinnedRequirements(content)) {
69
+ hasLockfile = true;
70
+ break;
71
+ }
72
+ }
73
+ }
74
+ return {
75
+ packageRoots: dedupe(roots),
76
+ manifestFiles,
77
+ declared,
78
+ hasLockfile,
79
+ };
80
+ }
81
+ async function tryRead(absolutePath) {
82
+ try {
83
+ return await fs.readFile(absolutePath, 'utf-8');
84
+ }
85
+ catch {
86
+ return null;
87
+ }
88
+ }
89
+ function dedupe(arr) {
90
+ return [...new Set(arr)];
91
+ }
92
+ // ── pyproject.toml ───────────────────────────────────────────
93
+ export function parsePyproject(content) {
94
+ const out = [];
95
+ // [project.dependencies] as a list of PEP 508 strings OR
96
+ // [project] dependencies = [ ... ]
97
+ const pep621Deps = extractListBlock(content, /(?:^|\n)\s*dependencies\s*=\s*\[/);
98
+ for (const { name, versionSpec, line } of pep621Deps) {
99
+ out.push({ name, versionSpec, source: 'pyproject.toml', line, scope: 'main' });
100
+ }
101
+ // [project.optional-dependencies] groups → all treated as 'dev'.
102
+ // Entries may be inline (`test = ["a", "b"]`) OR multiline; iterate over all
103
+ // string literals in the block rather than splitting by lines.
104
+ const optBlockRe = /\[project\.optional-dependencies\]([\s\S]*?)(?=\n\[|$)/;
105
+ const optMatch = optBlockRe.exec(content);
106
+ if (optMatch) {
107
+ const blockStart = optMatch.index + optMatch[0].indexOf(optMatch[1]);
108
+ const block = optMatch[1];
109
+ const stringRe = /["']([^"'\n]+)["']/g;
110
+ let sm;
111
+ while ((sm = stringRe.exec(block))) {
112
+ const { name, versionSpec } = splitPep508(sm[1]);
113
+ if (!name)
114
+ continue;
115
+ const line = offsetToLine(content, blockStart + sm.index);
116
+ out.push({ name, versionSpec, source: 'pyproject.toml', line, scope: 'dev' });
117
+ }
118
+ }
119
+ // [tool.poetry.dependencies] / [tool.poetry.group.<name>.dependencies]
120
+ const poetryMainRe = /\[tool\.poetry\.dependencies\]([\s\S]*?)(?=\n\[|$)/;
121
+ const poetryMainMatch = poetryMainRe.exec(content);
122
+ if (poetryMainMatch) {
123
+ const offset = offsetToLine(content, poetryMainMatch.index);
124
+ for (const { name, versionSpec, line } of parsePoetryKv(poetryMainMatch[1], offset)) {
125
+ if (name === 'python')
126
+ continue;
127
+ out.push({ name, versionSpec, source: 'pyproject.toml', line, scope: 'main' });
128
+ }
129
+ }
130
+ const poetryGroupRe = /\[tool\.poetry\.group\.[\w.-]+\.dependencies\]([\s\S]*?)(?=\n\[|$)/g;
131
+ let gm;
132
+ while ((gm = poetryGroupRe.exec(content))) {
133
+ const offset = offsetToLine(content, gm.index);
134
+ for (const { name, versionSpec, line } of parsePoetryKv(gm[1], offset)) {
135
+ out.push({ name, versionSpec, source: 'pyproject.toml', line, scope: 'dev' });
136
+ }
137
+ }
138
+ return out;
139
+ }
140
+ function extractPyprojectRoots(content) {
141
+ const roots = [];
142
+ // [tool.setuptools.packages.find] where = ['src']
143
+ const findWhereRe = /\[tool\.setuptools\.packages\.find\]([\s\S]*?)(?=\n\[|$)/;
144
+ const findMatch = findWhereRe.exec(content);
145
+ if (findMatch) {
146
+ const whereRe = /where\s*=\s*\[\s*([^\]]+?)\s*\]/;
147
+ const whereMatch = whereRe.exec(findMatch[1]);
148
+ if (whereMatch) {
149
+ for (const s of extractStringList(whereMatch[1]))
150
+ roots.push(s);
151
+ }
152
+ }
153
+ // [tool.setuptools] package-dir or [tool.setuptools.package-dir] { '' = 'src' }
154
+ const pkgDirRe = /package[-_]dir\s*=\s*\{[^}]*""\s*=\s*["']([^"']+)["']/;
155
+ const pkgDirMatch = pkgDirRe.exec(content);
156
+ if (pkgDirMatch)
157
+ roots.push(pkgDirMatch[1]);
158
+ // Poetry explicit packages: [tool.poetry] packages = [{ include = "foo", from = "src" }]
159
+ const poetryPackagesRe = /\[tool\.poetry\][\s\S]*?packages\s*=\s*\[([\s\S]*?)\]/;
160
+ const poetryPkg = poetryPackagesRe.exec(content);
161
+ if (poetryPkg) {
162
+ const fromRe = /from\s*=\s*["']([^"']+)["']/g;
163
+ let m;
164
+ while ((m = fromRe.exec(poetryPkg[1])))
165
+ roots.push(m[1]);
166
+ }
167
+ return dedupe(roots);
168
+ }
169
+ function parsePoetryKv(block, lineOffset) {
170
+ const out = [];
171
+ const lines = block.split('\n');
172
+ for (let i = 0; i < lines.length; i++) {
173
+ const line = lines[i].replace(/#.*$/, '').trim();
174
+ if (!line)
175
+ continue;
176
+ // name = "^1.0.0" | name = { version = "...", ... }
177
+ const m = /^([A-Za-z_][\w.-]*)\s*=\s*(.+)$/.exec(line);
178
+ if (!m)
179
+ continue;
180
+ const name = m[1];
181
+ let versionSpec = m[2].trim();
182
+ if (versionSpec.startsWith('{')) {
183
+ const vm = /version\s*=\s*["']([^"']+)["']/.exec(versionSpec);
184
+ versionSpec = vm ? vm[1] : '';
185
+ }
186
+ else if (/^["']/.test(versionSpec)) {
187
+ versionSpec = versionSpec.replace(/^["']|["']$/g, '');
188
+ }
189
+ out.push({ name, versionSpec, line: lineOffset + i + 1 });
190
+ }
191
+ return out;
192
+ }
193
+ function extractListBlock(content, opener) {
194
+ const m = opener.exec(content);
195
+ if (!m)
196
+ return [];
197
+ // Find the matching ']' by simple bracket-depth scan from the '['.
198
+ const start = content.indexOf('[', m.index);
199
+ if (start < 0)
200
+ return [];
201
+ let depth = 1;
202
+ let end = start + 1;
203
+ while (end < content.length && depth > 0) {
204
+ const ch = content[end];
205
+ if (ch === '[')
206
+ depth++;
207
+ else if (ch === ']')
208
+ depth--;
209
+ end++;
210
+ }
211
+ const inside = content.slice(start + 1, end - 1);
212
+ const baseLine = offsetToLine(content, start + 1);
213
+ return extractListValues(inside, baseLine);
214
+ }
215
+ function extractListValues(block, lineOffset) {
216
+ const out = [];
217
+ const lines = block.split('\n');
218
+ for (let i = 0; i < lines.length; i++) {
219
+ const stripped = lines[i].replace(/#.*$/, '').trim();
220
+ // Entries look like "requests>=2.25.0",
221
+ const m = /^["']([^"']+)["']/.exec(stripped);
222
+ if (!m)
223
+ continue;
224
+ const { name, versionSpec } = splitPep508(m[1]);
225
+ if (!name)
226
+ continue;
227
+ out.push({ name, versionSpec, line: lineOffset + i });
228
+ }
229
+ return out;
230
+ }
231
+ function extractStringList(fragment) {
232
+ const out = [];
233
+ const re = /["']([^"']+)["']/g;
234
+ let m;
235
+ while ((m = re.exec(fragment)))
236
+ out.push(m[1]);
237
+ return out;
238
+ }
239
+ function offsetToLine(content, offset) {
240
+ let line = 0;
241
+ for (let i = 0; i < offset && i < content.length; i++) {
242
+ if (content[i] === '\n')
243
+ line++;
244
+ }
245
+ return line + 1;
246
+ }
247
+ // ── setup.py / setup.cfg ──────────────────────────────────────
248
+ function parseSetupPyInstallRequires(content) {
249
+ const out = [];
250
+ const m = /install_requires\s*=\s*\[([\s\S]*?)\]/.exec(content);
251
+ if (!m)
252
+ return out;
253
+ const inside = m[1];
254
+ const baseLine = offsetToLine(content, m.index + m[0].indexOf('['));
255
+ for (const { name, versionSpec, line } of extractListValues(inside, baseLine)) {
256
+ out.push({ name, versionSpec, source: 'setup.py', line, scope: 'main' });
257
+ }
258
+ return out;
259
+ }
260
+ function parseSetupCfg(content) {
261
+ const out = [];
262
+ const m = /\[options\][\s\S]*?install_requires\s*=\s*([\s\S]*?)(?=\n\[|\n\n|$)/.exec(content);
263
+ if (!m)
264
+ return out;
265
+ const baseLine = offsetToLine(content, m.index + m[0].indexOf('install_requires'));
266
+ const lines = m[1].split('\n');
267
+ for (let i = 0; i < lines.length; i++) {
268
+ const stripped = lines[i].replace(/#.*$/, '').trim();
269
+ if (!stripped)
270
+ continue;
271
+ const { name, versionSpec } = splitPep508(stripped);
272
+ if (!name)
273
+ continue;
274
+ out.push({ name, versionSpec, source: 'setup.cfg', line: baseLine + i + 1, scope: 'main' });
275
+ }
276
+ return out;
277
+ }
278
+ // ── requirements.txt ──────────────────────────────────────────
279
+ export function parseRequirements(content, sourceFile, scope) {
280
+ const out = [];
281
+ const lines = content.split('\n');
282
+ for (let i = 0; i < lines.length; i++) {
283
+ const raw = lines[i];
284
+ const stripped = raw.replace(/\s+#.*$/, '').trim();
285
+ if (!stripped || stripped.startsWith('#'))
286
+ continue;
287
+ if (stripped.startsWith('-'))
288
+ continue; // -r, -e, -c, etc.
289
+ const { name, versionSpec } = splitPep508(stripped);
290
+ if (!name)
291
+ continue;
292
+ out.push({ name, versionSpec, source: sourceFile, line: i + 1, scope });
293
+ }
294
+ return out;
295
+ }
296
+ function hasPinnedRequirements(content) {
297
+ for (const raw of content.split('\n')) {
298
+ const line = raw.replace(/\s+#.*$/, '').trim();
299
+ if (!line || line.startsWith('#') || line.startsWith('-'))
300
+ continue;
301
+ if (/==/.test(line))
302
+ return true;
303
+ }
304
+ return false;
305
+ }
306
+ // ── PEP 508 splitter ──────────────────────────────────────────
307
+ export function splitPep508(spec) {
308
+ // Strip environment markers: `foo; python_version < "3.10"`.
309
+ const semi = spec.indexOf(';');
310
+ let core = semi >= 0 ? spec.slice(0, semi) : spec;
311
+ // Strip extras: `foo[extra1,extra2]`.
312
+ core = core.replace(/\[[^\]]*\]/, '');
313
+ core = core.trim();
314
+ // Name is up to the first version-spec character or whitespace.
315
+ const m = /^([A-Za-z_][\w.-]*)(.*)$/.exec(core);
316
+ if (!m)
317
+ return { name: '', versionSpec: '' };
318
+ return { name: m[1].toLowerCase(), versionSpec: m[2].trim() };
319
+ }
320
+ // ── __init__.py-walk fallback ─────────────────────────────────
321
+ function inferRootsFromInitFiles(files) {
322
+ // Find every dir that contains __init__.py, then take the SHALLOWEST ones
323
+ // whose parent is not itself an __init__.py holder - those parents are the
324
+ // candidate source roots.
325
+ const initDirs = new Set();
326
+ for (const f of files) {
327
+ if (path.basename(f.relativePath) === '__init__.py') {
328
+ initDirs.add(f.directory === '.' ? '' : f.directory);
329
+ }
330
+ }
331
+ if (initDirs.size === 0)
332
+ return [];
333
+ const candidateParents = new Set();
334
+ for (const dir of initDirs) {
335
+ const parent = dir === '' ? '.' : path.posix.dirname(dir);
336
+ const parentKey = parent === '.' ? '' : parent;
337
+ // Skip if parent also has __init__.py (that's a nested package).
338
+ if (initDirs.has(parentKey))
339
+ continue;
340
+ candidateParents.add(parent === '' ? '.' : parent);
341
+ }
342
+ return [...candidateParents];
343
+ }
344
+ //# sourceMappingURL=pythonManifests.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pythonManifests.js","sourceRoot":"","sources":["../../../src/core/languages/pythonManifests.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ import type { LanguageAdapter } from './LanguageAdapter.js';
2
+ export declare function registerAdapter(adapter: LanguageAdapter): void;
3
+ export declare function getAdapterFor(filePath: string): LanguageAdapter | undefined;
4
+ export declare function isAdapterParseable(filePath: string): boolean;
5
+ export declare function listAdapters(): readonly LanguageAdapter[];
@@ -0,0 +1,31 @@
1
+ import path from 'node:path';
2
+ import { javascriptAdapter } from './javascriptAdapter.js';
3
+ import { pythonAdapter } from './pythonAdapter.js';
4
+ import { goAdapter } from './goAdapter.js';
5
+ const adapters = [javascriptAdapter, pythonAdapter, goAdapter];
6
+ const byExtension = new Map();
7
+ function rebuildIndex() {
8
+ byExtension.clear();
9
+ for (const adapter of adapters) {
10
+ for (const ext of adapter.extensions) {
11
+ byExtension.set(ext, adapter);
12
+ }
13
+ }
14
+ }
15
+ rebuildIndex();
16
+ export function registerAdapter(adapter) {
17
+ if (!adapters.includes(adapter)) {
18
+ adapters.push(adapter);
19
+ rebuildIndex();
20
+ }
21
+ }
22
+ export function getAdapterFor(filePath) {
23
+ return byExtension.get(path.extname(filePath).toLowerCase());
24
+ }
25
+ export function isAdapterParseable(filePath) {
26
+ return byExtension.has(path.extname(filePath).toLowerCase());
27
+ }
28
+ export function listAdapters() {
29
+ return adapters;
30
+ }
31
+ //# sourceMappingURL=registry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registry.js","sourceRoot":"","sources":["../../../src/core/languages/registry.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAC3D,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAG3C,MAAM,QAAQ,GAAsB,CAAC,iBAAiB,EAAE,aAAa,EAAE,SAAS,CAAC,CAAC;AAClF,MAAM,WAAW,GAAG,IAAI,GAAG,EAA2B,CAAC;AAEvD,SAAS,YAAY;IACnB,WAAW,CAAC,KAAK,EAAE,CAAC;IACpB,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;QAC/B,KAAK,MAAM,GAAG,IAAI,OAAO,CAAC,UAAU,EAAE,CAAC;YACrC,WAAW,CAAC,GAAG,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;QAChC,CAAC;IACH,CAAC;AACH,CAAC;AACD,YAAY,EAAE,CAAC;AAEf,MAAM,UAAU,eAAe,CAAC,OAAwB;IACtD,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC;QAChC,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QACvB,YAAY,EAAE,CAAC;IACjB,CAAC;AACH,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,QAAgB;IAC5C,OAAO,WAAW,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC;AAC/D,CAAC;AAED,MAAM,UAAU,kBAAkB,CAAC,QAAgB;IACjD,OAAO,WAAW,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC;AAC/D,CAAC;AAED,MAAM,UAAU,YAAY;IAC1B,OAAO,QAAQ,CAAC;AAClB,CAAC"}
@@ -0,0 +1,14 @@
1
+ import { Parser, Language } from 'web-tree-sitter';
2
+ /**
3
+ * Tree-sitter grammar version pinned for stability. Any grammar upgrade is a
4
+ * semver-minor that must re-run parser tests - see ROADMAP.
5
+ */
6
+ export declare const TREE_SITTER_PYTHON_VERSION = "0.25.0";
7
+ /** Initialize the web-tree-sitter runtime. Idempotent. */
8
+ export declare function ensureParserInit(): Promise<void>;
9
+ /** Load a named grammar (e.g. 'tree-sitter-python.wasm'). Cached. */
10
+ export declare function loadLanguage(wasmFilename: string): Promise<Language>;
11
+ /** Build a parser pre-configured for a given grammar. */
12
+ export declare function createParserFor(wasmFilename: string): Promise<Parser>;
13
+ /** Reset the global caches. Tests only. */
14
+ export declare function __resetLoaderForTests(): void;
@@ -0,0 +1,76 @@
1
+ import { readFile } from 'node:fs/promises';
2
+ import path from 'node:path';
3
+ import { existsSync } from 'node:fs';
4
+ import { fileURLToPath } from 'node:url';
5
+ import { Parser, Language } from 'web-tree-sitter';
6
+ /**
7
+ * Tree-sitter grammar version pinned for stability. Any grammar upgrade is a
8
+ * semver-minor that must re-run parser tests - see ROADMAP.
9
+ */
10
+ export const TREE_SITTER_PYTHON_VERSION = '0.25.0';
11
+ let parserInitPromise = null;
12
+ const languageCache = new Map();
13
+ /**
14
+ * Resolve the directory that ships our vendored .wasm files.
15
+ * - Installed case: `dist/grammars/` alongside the compiled JS.
16
+ * - Dev case (running ts-node / vitest on src/): node_modules of the repo root.
17
+ * The loader probes both and picks the first that exists.
18
+ */
19
+ function grammarDirs() {
20
+ const here = path.dirname(fileURLToPath(import.meta.url));
21
+ const distDir = path.resolve(here, '..', '..', 'grammars');
22
+ const repoRoot = path.resolve(here, '..', '..', '..');
23
+ const nodeModulesWebTs = path.join(repoRoot, 'node_modules', 'web-tree-sitter');
24
+ const nodeModulesPy = path.join(repoRoot, 'node_modules', 'tree-sitter-python');
25
+ const nodeModulesGo = path.join(repoRoot, 'node_modules', 'tree-sitter-go');
26
+ return [distDir, nodeModulesWebTs, nodeModulesPy, nodeModulesGo];
27
+ }
28
+ function findWasm(filename) {
29
+ for (const dir of grammarDirs()) {
30
+ const candidate = path.join(dir, filename);
31
+ if (existsSync(candidate))
32
+ return candidate;
33
+ }
34
+ throw new Error(`Could not locate ${filename}. Searched: ${grammarDirs().join(', ')}. ` +
35
+ `Run \`npm run build\` to populate dist/grammars/.`);
36
+ }
37
+ /** Initialize the web-tree-sitter runtime. Idempotent. */
38
+ export async function ensureParserInit() {
39
+ if (parserInitPromise)
40
+ return parserInitPromise;
41
+ parserInitPromise = Parser.init({
42
+ locateFile(name) {
43
+ if (name.endsWith('.wasm'))
44
+ return findWasm(name);
45
+ return name;
46
+ },
47
+ });
48
+ return parserInitPromise;
49
+ }
50
+ /** Load a named grammar (e.g. 'tree-sitter-python.wasm'). Cached. */
51
+ export async function loadLanguage(wasmFilename) {
52
+ await ensureParserInit();
53
+ let cached = languageCache.get(wasmFilename);
54
+ if (!cached) {
55
+ cached = (async () => {
56
+ const wasmPath = findWasm(wasmFilename);
57
+ const buf = await readFile(wasmPath);
58
+ return Language.load(buf);
59
+ })();
60
+ languageCache.set(wasmFilename, cached);
61
+ }
62
+ return cached;
63
+ }
64
+ /** Build a parser pre-configured for a given grammar. */
65
+ export async function createParserFor(wasmFilename) {
66
+ const language = await loadLanguage(wasmFilename);
67
+ const parser = new Parser();
68
+ parser.setLanguage(language);
69
+ return parser;
70
+ }
71
+ /** Reset the global caches. Tests only. */
72
+ export function __resetLoaderForTests() {
73
+ parserInitPromise = null;
74
+ languageCache.clear();
75
+ }
76
+ //# sourceMappingURL=treeSitterLoader.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"treeSitterLoader.js","sourceRoot":"","sources":["../../../src/core/languages/treeSitterLoader.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,20 @@
1
+ import type { WorkspaceInfo, WorkspacePackage } from '../types.js';
2
+ /**
3
+ * Detect monorepo workspaces. Covers the three setups that account for the
4
+ * vast majority of JS/TS monorepos: npm/yarn workspaces (package.json
5
+ * `workspaces`), pnpm (pnpm-workspace.yaml), and the Nx/Turbo/Lerna fallback
6
+ * (their files exist but they typically piggy-back on package.json
7
+ * workspaces or rely on a `packages/` convention).
8
+ *
9
+ * Returns kind 'none' for non-monorepos. Always includes the workspace root
10
+ * package itself if it has its own package.json with a name.
11
+ */
12
+ export declare function detectWorkspaces(rootPath: string): Promise<WorkspaceInfo>;
13
+ /**
14
+ * Given a file's project-relative path, return the workspace package whose
15
+ * `relativePath` is its longest matching prefix. Used to filter hotspots /
16
+ * coupling rows by --package.
17
+ */
18
+ export declare function findPackageForFile(workspaces: WorkspaceInfo, filePath: string): WorkspacePackage | null;
19
+ /** Filter helper for callers passing --package <name>. */
20
+ export declare function filterFilesByPackage(workspaces: WorkspaceInfo, packageName: string, files: string[]): string[];