@vpxa/kb 0.1.1 → 0.1.2

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 (136) hide show
  1. package/package.json +1 -1
  2. package/packages/analyzers/dist/blast-radius-analyzer.js +13 -114
  3. package/packages/analyzers/dist/dependency-analyzer.js +11 -425
  4. package/packages/analyzers/dist/diagram-generator.js +4 -86
  5. package/packages/analyzers/dist/entry-point-analyzer.js +5 -239
  6. package/packages/analyzers/dist/index.js +1 -23
  7. package/packages/analyzers/dist/knowledge-producer.js +24 -113
  8. package/packages/analyzers/dist/pattern-analyzer.js +5 -359
  9. package/packages/analyzers/dist/regex-call-graph.js +1 -428
  10. package/packages/analyzers/dist/structure-analyzer.js +4 -258
  11. package/packages/analyzers/dist/symbol-analyzer.js +13 -442
  12. package/packages/analyzers/dist/ts-call-graph.js +1 -160
  13. package/packages/analyzers/dist/types.js +0 -1
  14. package/packages/chunker/dist/call-graph-extractor.js +1 -90
  15. package/packages/chunker/dist/chunker-factory.js +1 -36
  16. package/packages/chunker/dist/chunker.interface.js +0 -1
  17. package/packages/chunker/dist/code-chunker.js +14 -134
  18. package/packages/chunker/dist/generic-chunker.js +5 -72
  19. package/packages/chunker/dist/index.js +1 -21
  20. package/packages/chunker/dist/markdown-chunker.js +7 -119
  21. package/packages/chunker/dist/treesitter-chunker.js +8 -234
  22. package/packages/cli/dist/commands/analyze.js +3 -112
  23. package/packages/cli/dist/commands/context-cmds.js +1 -155
  24. package/packages/cli/dist/commands/environment.js +2 -204
  25. package/packages/cli/dist/commands/execution.js +1 -137
  26. package/packages/cli/dist/commands/graph.js +7 -81
  27. package/packages/cli/dist/commands/init.js +9 -87
  28. package/packages/cli/dist/commands/knowledge.js +1 -139
  29. package/packages/cli/dist/commands/search.js +8 -267
  30. package/packages/cli/dist/commands/system.js +4 -241
  31. package/packages/cli/dist/commands/workspace.js +2 -388
  32. package/packages/cli/dist/context.js +1 -14
  33. package/packages/cli/dist/helpers.js +3 -458
  34. package/packages/cli/dist/index.js +3 -69
  35. package/packages/cli/dist/kb-init.js +1 -82
  36. package/packages/cli/dist/types.js +0 -1
  37. package/packages/core/dist/constants.js +1 -43
  38. package/packages/core/dist/content-detector.js +1 -79
  39. package/packages/core/dist/errors.js +1 -40
  40. package/packages/core/dist/index.js +1 -9
  41. package/packages/core/dist/logger.js +1 -34
  42. package/packages/core/dist/types.js +0 -1
  43. package/packages/embeddings/dist/embedder.interface.js +0 -1
  44. package/packages/embeddings/dist/index.js +1 -5
  45. package/packages/embeddings/dist/onnx-embedder.js +1 -82
  46. package/packages/indexer/dist/file-hasher.js +1 -13
  47. package/packages/indexer/dist/filesystem-crawler.js +1 -125
  48. package/packages/indexer/dist/graph-extractor.js +1 -111
  49. package/packages/indexer/dist/incremental-indexer.js +1 -278
  50. package/packages/indexer/dist/index.js +1 -14
  51. package/packages/server/dist/api.js +1 -9
  52. package/packages/server/dist/config.js +1 -75
  53. package/packages/server/dist/curated-manager.js +9 -356
  54. package/packages/server/dist/index.js +1 -134
  55. package/packages/server/dist/replay-interceptor.js +1 -38
  56. package/packages/server/dist/resources/resources.js +2 -40
  57. package/packages/server/dist/server.js +1 -247
  58. package/packages/server/dist/tools/analyze.tools.js +1 -288
  59. package/packages/server/dist/tools/forge.tools.js +11 -499
  60. package/packages/server/dist/tools/forget.tool.js +3 -39
  61. package/packages/server/dist/tools/graph.tool.js +5 -110
  62. package/packages/server/dist/tools/list.tool.js +5 -53
  63. package/packages/server/dist/tools/lookup.tool.js +8 -51
  64. package/packages/server/dist/tools/onboard.tool.js +2 -112
  65. package/packages/server/dist/tools/produce.tool.js +4 -74
  66. package/packages/server/dist/tools/read.tool.js +4 -47
  67. package/packages/server/dist/tools/reindex.tool.js +2 -70
  68. package/packages/server/dist/tools/remember.tool.js +3 -42
  69. package/packages/server/dist/tools/replay.tool.js +6 -88
  70. package/packages/server/dist/tools/search.tool.js +17 -327
  71. package/packages/server/dist/tools/status.tool.js +3 -68
  72. package/packages/server/dist/tools/toolkit.tools.js +20 -1673
  73. package/packages/server/dist/tools/update.tool.js +3 -39
  74. package/packages/server/dist/tools/utility.tools.js +19 -456
  75. package/packages/store/dist/graph-store.interface.js +0 -1
  76. package/packages/store/dist/index.js +1 -9
  77. package/packages/store/dist/lance-store.js +1 -258
  78. package/packages/store/dist/sqlite-graph-store.js +8 -309
  79. package/packages/store/dist/store-factory.js +1 -14
  80. package/packages/store/dist/store.interface.js +0 -1
  81. package/packages/tools/dist/batch.js +1 -45
  82. package/packages/tools/dist/changelog.js +2 -112
  83. package/packages/tools/dist/check.js +2 -59
  84. package/packages/tools/dist/checkpoint.js +2 -43
  85. package/packages/tools/dist/codemod.js +2 -69
  86. package/packages/tools/dist/compact.js +3 -60
  87. package/packages/tools/dist/data-transform.js +1 -124
  88. package/packages/tools/dist/dead-symbols.js +2 -71
  89. package/packages/tools/dist/delegate.js +3 -128
  90. package/packages/tools/dist/diff-parse.js +3 -153
  91. package/packages/tools/dist/digest.js +7 -242
  92. package/packages/tools/dist/encode.js +1 -46
  93. package/packages/tools/dist/env-info.js +1 -58
  94. package/packages/tools/dist/eval.js +3 -79
  95. package/packages/tools/dist/evidence-map.js +3 -203
  96. package/packages/tools/dist/file-summary.js +2 -106
  97. package/packages/tools/dist/file-walk.js +1 -75
  98. package/packages/tools/dist/find-examples.js +3 -48
  99. package/packages/tools/dist/find.js +1 -120
  100. package/packages/tools/dist/forge-classify.js +2 -319
  101. package/packages/tools/dist/forge-ground.js +1 -184
  102. package/packages/tools/dist/git-context.js +3 -46
  103. package/packages/tools/dist/graph-query.js +1 -194
  104. package/packages/tools/dist/health.js +1 -118
  105. package/packages/tools/dist/http-request.js +1 -58
  106. package/packages/tools/dist/index.js +1 -273
  107. package/packages/tools/dist/lane.js +7 -227
  108. package/packages/tools/dist/measure.js +2 -119
  109. package/packages/tools/dist/onboard.js +42 -1136
  110. package/packages/tools/dist/parse-output.js +2 -158
  111. package/packages/tools/dist/process-manager.js +1 -69
  112. package/packages/tools/dist/queue.js +2 -126
  113. package/packages/tools/dist/regex-test.js +1 -39
  114. package/packages/tools/dist/rename.js +2 -70
  115. package/packages/tools/dist/replay.js +6 -108
  116. package/packages/tools/dist/schema-validate.js +1 -141
  117. package/packages/tools/dist/scope-map.js +1 -72
  118. package/packages/tools/dist/snippet.js +1 -80
  119. package/packages/tools/dist/stash.js +2 -60
  120. package/packages/tools/dist/stratum-card.js +5 -238
  121. package/packages/tools/dist/symbol.js +3 -87
  122. package/packages/tools/dist/test-run.js +2 -55
  123. package/packages/tools/dist/text-utils.js +2 -31
  124. package/packages/tools/dist/time-utils.js +1 -135
  125. package/packages/tools/dist/trace.js +2 -114
  126. package/packages/tools/dist/truncation.js +10 -41
  127. package/packages/tools/dist/watch.js +1 -61
  128. package/packages/tools/dist/web-fetch.js +9 -244
  129. package/packages/tools/dist/web-search.js +1 -46
  130. package/packages/tools/dist/workset.js +2 -77
  131. package/packages/tui/dist/App.js +260 -52468
  132. package/packages/tui/dist/index.js +286 -54551
  133. package/packages/tui/dist/panels/CuratedPanel.js +211 -34291
  134. package/packages/tui/dist/panels/LogPanel.js +259 -51703
  135. package/packages/tui/dist/panels/SearchPanel.js +212 -34824
  136. package/packages/tui/dist/panels/StatusPanel.js +211 -34304
@@ -1,428 +1 @@
1
- import { readdirSync, readFileSync } from "node:fs";
2
- import { extname, join, relative } from "node:path";
3
- const SKIP_DIRS = /* @__PURE__ */ new Set([
4
- "node_modules",
5
- ".git",
6
- "dist",
7
- "build",
8
- "coverage",
9
- ".turbo",
10
- ".cache",
11
- "cdk.out",
12
- ".venv",
13
- "venv",
14
- "__pycache__",
15
- "target",
16
- "vendor",
17
- "bin",
18
- "obj"
19
- ]);
20
- const CODE_EXTENSIONS = /* @__PURE__ */ new Set([
21
- ".ts",
22
- ".tsx",
23
- ".js",
24
- ".jsx",
25
- ".java",
26
- ".py",
27
- ".go",
28
- ".cs",
29
- ".kt",
30
- ".scala",
31
- ".rs",
32
- ".rb",
33
- ".php",
34
- ".swift"
35
- ]);
36
- async function extractRegexCallGraph(rootPath) {
37
- const startTime = Date.now();
38
- const files = collectFiles(rootPath);
39
- if (files.length === 0) return null;
40
- const cappedFiles = files.slice(0, 800);
41
- const fileImports = /* @__PURE__ */ new Map();
42
- const moduleExports = /* @__PURE__ */ new Map();
43
- for (const fullPath of cappedFiles) {
44
- const relPath = relative(rootPath, fullPath).replace(/\\/g, "/");
45
- const content = readFileSync(fullPath, "utf-8");
46
- const ext = extname(fullPath).toLowerCase();
47
- const imports = parseImports(content, ext);
48
- fileImports.set(relPath, imports);
49
- const exports = parseExports(content, ext);
50
- moduleExports.set(relPath, exports);
51
- }
52
- const stemToFiles = buildStemLookup(cappedFiles, rootPath);
53
- const edgeMap = /* @__PURE__ */ new Map();
54
- for (const [callerRel, imports] of fileImports) {
55
- if (isTestPath(callerRel)) continue;
56
- const callerContent = readFileSync(join(rootPath, callerRel), "utf-8");
57
- const bodyContent = stripImportLines(callerContent, extname(callerRel));
58
- for (const imp of imports) {
59
- if (!imp.isRelative) continue;
60
- const targetPaths = resolveImportPath(callerRel, imp.source, stemToFiles, extname(callerRel));
61
- if (targetPaths.length === 0) continue;
62
- const targetRel = targetPaths[0];
63
- if (isTestPath(targetRel)) continue;
64
- if (callerRel === targetRel) continue;
65
- let usedSymbols;
66
- if (imp.symbols.length > 0) {
67
- usedSymbols = imp.symbols.filter((sym) => {
68
- const regex = new RegExp(`\\b${escapeRegex(sym)}\\b`);
69
- return regex.test(bodyContent);
70
- });
71
- } else {
72
- usedSymbols = ["*"];
73
- }
74
- if (usedSymbols.length === 0) continue;
75
- const edgeKey = `${callerRel}|${targetRel}`;
76
- const existing = edgeMap.get(edgeKey);
77
- if (existing) {
78
- for (const s of usedSymbols) existing.add(s);
79
- } else {
80
- edgeMap.set(edgeKey, new Set(usedSymbols));
81
- }
82
- }
83
- }
84
- const edges = [];
85
- for (const [key, syms] of edgeMap) {
86
- const [from, to] = key.split("|");
87
- edges.push({ from, to, symbols: [...syms].sort().slice(0, 10) });
88
- }
89
- edges.sort((a, b) => b.symbols.length - a.symbols.length);
90
- return {
91
- edges,
92
- fileCount: cappedFiles.length,
93
- edgeCount: edges.length,
94
- durationMs: Date.now() - startTime
95
- };
96
- }
97
- function parseImports(content, ext) {
98
- const imports = [];
99
- switch (ext) {
100
- case ".ts":
101
- case ".tsx":
102
- case ".js":
103
- case ".jsx": {
104
- const esNamed = /import\s+(?:type\s+)?\{([^}]+)\}\s+from\s+['"]([^'"]+)['"]/g;
105
- let m;
106
- while ((m = esNamed.exec(content)) !== null) {
107
- const symbols = m[1].split(",").map((s) => {
108
- const parts = s.trim().split(/\s+as\s+/);
109
- return (parts[parts.length - 1] || "").trim();
110
- }).filter(Boolean);
111
- imports.push({ source: m[2], symbols, isRelative: m[2].startsWith(".") });
112
- }
113
- const esDefault = /import\s+(\w+)\s+from\s+['"]([^'"]+)['"]/g;
114
- while ((m = esDefault.exec(content)) !== null) {
115
- if (m[1] === "type") continue;
116
- imports.push({ source: m[2], symbols: [m[1]], isRelative: m[2].startsWith(".") });
117
- }
118
- const cjsNamed = /(?:const|let|var)\s+\{([^}]+)\}\s*=\s*require\(\s*['"]([^'"]+)['"]\s*\)/g;
119
- while ((m = cjsNamed.exec(content)) !== null) {
120
- const symbols = m[1].split(",").map((s) => s.trim().split(":")[0].trim()).filter(Boolean);
121
- imports.push({ source: m[2], symbols, isRelative: m[2].startsWith(".") });
122
- }
123
- break;
124
- }
125
- case ".java":
126
- case ".kt":
127
- case ".scala": {
128
- const javaImport = /^import\s+(?:static\s+)?([\w.]+)\s*;/gm;
129
- let m;
130
- while ((m = javaImport.exec(content)) !== null) {
131
- const parts = m[1].split(".");
132
- const lastPart = parts[parts.length - 1];
133
- if (lastPart === "*") {
134
- imports.push({
135
- source: m[1],
136
- symbols: [],
137
- isRelative: isInternalJavaImport(m[1], content)
138
- });
139
- } else {
140
- imports.push({
141
- source: m[1],
142
- symbols: [lastPart],
143
- isRelative: isInternalJavaImport(m[1], content)
144
- });
145
- }
146
- }
147
- break;
148
- }
149
- case ".py": {
150
- const fromImport = /^from\s+([\w.]+)\s+import\s+(.+)$/gm;
151
- let m;
152
- while ((m = fromImport.exec(content)) !== null) {
153
- const symbols = m[2].split(",").map((s) => {
154
- const parts = s.trim().split(/\s+as\s+/);
155
- return (parts[parts.length - 1] || "").trim();
156
- }).filter((s) => s && s !== "(");
157
- imports.push({ source: m[1], symbols, isRelative: m[1].startsWith(".") });
158
- }
159
- const plainImport = /^import\s+([\w.]+)(?:\s+as\s+(\w+))?\s*$/gm;
160
- while ((m = plainImport.exec(content)) !== null) {
161
- const pyParts = m[1].split(".");
162
- const alias = m[2] || pyParts[pyParts.length - 1];
163
- imports.push({ source: m[1], symbols: [alias], isRelative: m[1].startsWith(".") });
164
- }
165
- break;
166
- }
167
- case ".go": {
168
- const goSingle = /import\s+(?:(\w+)\s+)?[""]([^""]+)[""]/g;
169
- let m;
170
- while ((m = goSingle.exec(content)) !== null) {
171
- const goParts = m[2].split("/");
172
- const alias = m[1] || goParts[goParts.length - 1];
173
- imports.push({
174
- source: m[2],
175
- symbols: [alias],
176
- isRelative: !m[2].includes(".") && !m[2].startsWith("github.com")
177
- });
178
- }
179
- const goBlock = /import\s*\(([\s\S]*?)\)/g;
180
- while ((m = goBlock.exec(content)) !== null) {
181
- const blockContent = m[1];
182
- const lineRe = /(?:(\w+)\s+)?[""]([^""]+)[""]/g;
183
- let lm;
184
- while ((lm = lineRe.exec(blockContent)) !== null) {
185
- const blockParts = lm[2].split("/");
186
- const alias = lm[1] || blockParts[blockParts.length - 1];
187
- imports.push({
188
- source: lm[2],
189
- symbols: [alias],
190
- isRelative: !lm[2].includes(".") && !lm[2].startsWith("github.com")
191
- });
192
- }
193
- }
194
- break;
195
- }
196
- case ".cs": {
197
- const csUsing = /^using\s+(?:static\s+)?([\w.]+)\s*;/gm;
198
- let m;
199
- while ((m = csUsing.exec(content)) !== null) {
200
- const parts = m[1].split(".");
201
- imports.push({ source: m[1], symbols: [parts[parts.length - 1]], isRelative: true });
202
- }
203
- break;
204
- }
205
- case ".rs": {
206
- const rsUse = /^use\s+([\w:]+(?:::\w+)*)/gm;
207
- let m;
208
- while ((m = rsUse.exec(content)) !== null) {
209
- const parts = m[1].split("::");
210
- const lastPart = parts[parts.length - 1];
211
- imports.push({
212
- source: m[1],
213
- symbols: lastPart === "*" ? [] : [lastPart],
214
- isRelative: m[1].startsWith("crate") || m[1].startsWith("super")
215
- });
216
- }
217
- break;
218
- }
219
- }
220
- return imports;
221
- }
222
- function parseExports(content, ext) {
223
- const exports = /* @__PURE__ */ new Set();
224
- switch (ext) {
225
- case ".ts":
226
- case ".tsx":
227
- case ".js":
228
- case ".jsx": {
229
- const exportPattern = /export\s+(?:default\s+)?(?:abstract\s+)?(?:async\s+)?(?:function|class|const|let|var|type|interface|enum)\s+(\w+)/g;
230
- let m;
231
- while ((m = exportPattern.exec(content)) !== null) exports.add(m[1]);
232
- break;
233
- }
234
- case ".java":
235
- case ".kt":
236
- case ".scala": {
237
- const javaPattern = /(?:public|protected)\s+(?:static\s+)?(?:abstract\s+)?(?:final\s+)?(?:class|interface|enum|record|@interface)\s+(\w+)/g;
238
- let m;
239
- while ((m = javaPattern.exec(content)) !== null) exports.add(m[1]);
240
- const methodPattern = /(?:public|protected)\s+(?:static\s+)?(?:abstract\s+)?(?:final\s+)?\w+(?:<[^>]+>)?\s+(\w+)\s*\(/g;
241
- while ((m = methodPattern.exec(content)) !== null) {
242
- if (![
243
- "if",
244
- "for",
245
- "while",
246
- "switch",
247
- "catch",
248
- "return",
249
- "class",
250
- "interface",
251
- "enum",
252
- "new"
253
- ].includes(m[1])) {
254
- exports.add(m[1]);
255
- }
256
- }
257
- break;
258
- }
259
- case ".py": {
260
- const pyPattern = /^(?:def|class)\s+([A-Z_]\w*)/gm;
261
- let m;
262
- while ((m = pyPattern.exec(content)) !== null) {
263
- if (!m[1].startsWith("_")) exports.add(m[1]);
264
- }
265
- break;
266
- }
267
- case ".go": {
268
- const goPattern = /^(?:func|type|var|const)\s+(\(?[A-Z]\w*)/gm;
269
- let m;
270
- while ((m = goPattern.exec(content)) !== null) exports.add(m[1].replace("(", ""));
271
- break;
272
- }
273
- }
274
- return exports;
275
- }
276
- function isInternalJavaImport(importPath, fileContent) {
277
- const pkgMatch = fileContent.match(/^package\s+([\w.]+)\s*;/m);
278
- if (!pkgMatch) return false;
279
- const filePkg = pkgMatch[1];
280
- const fileParts = filePkg.split(".");
281
- const importParts = importPath.split(".");
282
- return fileParts.length >= 2 && importParts.length >= 2 && fileParts[0] === importParts[0] && fileParts[1] === importParts[1];
283
- }
284
- function escapeRegex(s) {
285
- return s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
286
- }
287
- function stripImportLines(content, ext) {
288
- switch (ext) {
289
- case ".ts":
290
- case ".tsx":
291
- case ".js":
292
- case ".jsx":
293
- return content.replace(/^import\s+.+$/gm, "").replace(/^const\s+.+=\s*require\(.+$/gm, "");
294
- case ".java":
295
- case ".kt":
296
- case ".scala":
297
- return content.replace(/^import\s+.+;$/gm, "");
298
- case ".py":
299
- return content.replace(/^(?:from\s+.+import\s+.+|import\s+.+)$/gm, "");
300
- case ".go":
301
- return content.replace(/^import\s+.+$/gm, "").replace(/import\s*\([\s\S]*?\)/g, "");
302
- case ".cs":
303
- return content.replace(/^using\s+.+;$/gm, "");
304
- case ".rs":
305
- return content.replace(/^use\s+.+;$/gm, "");
306
- default:
307
- return content;
308
- }
309
- }
310
- function buildStemLookup(files, rootPath) {
311
- const lookup = /* @__PURE__ */ new Map();
312
- for (const fullPath of files) {
313
- const relPath = relative(rootPath, fullPath).replace(/\\/g, "/");
314
- const withoutExt = relPath.replace(/\.[^.]+$/, "");
315
- addToLookup(lookup, withoutExt, relPath);
316
- const stemParts = withoutExt.split("/");
317
- const baseName = stemParts[stemParts.length - 1];
318
- addToLookup(lookup, baseName, relPath);
319
- }
320
- return lookup;
321
- }
322
- function addToLookup(lookup, key, value) {
323
- const existing = lookup.get(key);
324
- if (existing) existing.push(value);
325
- else lookup.set(key, [value]);
326
- }
327
- function resolveImportPath(callerRel, source, stemLookup, callerExt) {
328
- switch (callerExt) {
329
- case ".ts":
330
- case ".tsx":
331
- case ".js":
332
- case ".jsx": {
333
- if (!source.startsWith(".")) return [];
334
- const callerDir = callerRel.split("/").slice(0, -1).join("/");
335
- const resolved = normalizePath(callerDir ? `${callerDir}/${source}` : source);
336
- for (const ext of ["", ".ts", ".tsx", ".js", ".jsx", "/index.ts", "/index.js"]) {
337
- const candidates = stemLookup.get(resolved + ext) || stemLookup.get((resolved + ext).replace(/\.[^.]+$/, ""));
338
- if (candidates && candidates.length > 0) return [candidates[0]];
339
- }
340
- const direct = stemLookup.get(resolved.replace(/\.[^.]+$/, ""));
341
- if (direct) return [direct[0]];
342
- return [];
343
- }
344
- case ".java":
345
- case ".kt":
346
- case ".scala": {
347
- const parts = source.split(".");
348
- const className = parts[parts.length - 1];
349
- if (className === "*") return [];
350
- const candidates = stemLookup.get(className);
351
- if (candidates) return [candidates[0]];
352
- return [];
353
- }
354
- case ".py": {
355
- if (source.startsWith(".")) {
356
- const callerDir = callerRel.split("/").slice(0, -1).join("/");
357
- const modulePath2 = source.replace(/^\.+/, "").replace(/\./g, "/");
358
- const resolved = callerDir ? `${callerDir}/${modulePath2}` : modulePath2;
359
- const pyResParts = resolved.split("/");
360
- const candidates2 = stemLookup.get(resolved) || stemLookup.get(pyResParts[pyResParts.length - 1]);
361
- if (candidates2) return [candidates2[0]];
362
- }
363
- const modulePath = source.replace(/\./g, "/");
364
- const candidates = stemLookup.get(modulePath);
365
- if (candidates) return [candidates[0]];
366
- return [];
367
- }
368
- case ".go": {
369
- const goSegments = source.split("/");
370
- const lastSeg = goSegments[goSegments.length - 1];
371
- const candidates = stemLookup.get(lastSeg);
372
- if (candidates) return [candidates[0]];
373
- return [];
374
- }
375
- default:
376
- return [];
377
- }
378
- }
379
- function normalizePath(p) {
380
- const parts = p.split("/");
381
- const result = [];
382
- for (const part of parts) {
383
- if (part === "." || part === "") continue;
384
- if (part === "..") {
385
- result.pop();
386
- continue;
387
- }
388
- result.push(part);
389
- }
390
- return result.join("/");
391
- }
392
- function isTestPath(fp) {
393
- const segments = fp.split("/");
394
- return segments.some(
395
- (s) => s === "test" || s === "tests" || s === "__tests__" || s === "spec" || s === "test_" || s === "__test__"
396
- ) || /\.(test|spec)\.[^.]+$/.test(fp);
397
- }
398
- function collectFiles(rootPath) {
399
- const files = [];
400
- const walk = (dir, depth) => {
401
- if (depth > 10) return;
402
- try {
403
- for (const entry of readdirSync(dir, { withFileTypes: true })) {
404
- if (SKIP_DIRS.has(entry.name) || entry.name.startsWith(".")) continue;
405
- const fullPath = join(dir, entry.name);
406
- if (entry.isDirectory()) {
407
- walk(fullPath, depth + 1);
408
- } else {
409
- const ext = extname(entry.name).toLowerCase();
410
- if (!CODE_EXTENSIONS.has(ext)) continue;
411
- if (entry.name.endsWith(".d.ts")) continue;
412
- if (/\.(test|spec)\.[^.]+$/.test(entry.name)) continue;
413
- const relDir = relative(rootPath, dir).replace(/\\/g, "/");
414
- if (relDir.split("/").some((s) => s === "test" || s === "tests" || s === "__tests__" || s === "spec"))
415
- continue;
416
- files.push(fullPath);
417
- }
418
- }
419
- } catch {
420
- }
421
- };
422
- walk(rootPath, 0);
423
- return files;
424
- }
425
- export {
426
- extractRegexCallGraph
427
- };
428
- //# sourceMappingURL=regex-call-graph.js.map
1
+ import{readdirSync as _,readFileSync as R}from"node:fs";import{extname as x,join as E,relative as y}from"node:path";const S=new Set(["node_modules",".git","dist","build","coverage",".turbo",".cache","cdk.out",".venv","venv","__pycache__","target","vendor","bin","obj"]),k=new Set([".ts",".tsx",".js",".jsx",".java",".py",".go",".cs",".kt",".scala",".rs",".rb",".php",".swift"]);async function q(e){const a=Date.now(),t=T(e);if(t.length===0)return null;const n=t.slice(0,800),s=new Map,r=new Map;for(const l of n){const g=y(e,l).replace(/\\/g,"/"),p=R(l,"utf-8"),u=x(l).toLowerCase(),m=I(p,u);s.set(g,m);const h=W(p,u);r.set(g,h)}const i=M(n,e),c=new Map;for(const[l,g]of s){if($(l))continue;const p=R(E(e,l),"utf-8"),u=C(p,x(l));for(const m of g){if(!m.isRelative)continue;const h=D(l,m.source,i,x(l));if(h.length===0)continue;const d=h[0];if($(d)||l===d)continue;let f;if(m.symbols.length>0?f=m.symbols.filter(w=>new RegExp(`\\b${A(w)}\\b`).test(u)):f=["*"],f.length===0)continue;const b=`${l}|${d}`,v=c.get(b);if(v)for(const w of f)v.add(w);else c.set(b,new Set(f))}}const o=[];for(const[l,g]of c){const[p,u]=l.split("|");o.push({from:p,to:u,symbols:[...g].sort().slice(0,10)})}return o.sort((l,g)=>g.symbols.length-l.symbols.length),{edges:o,fileCount:n.length,edgeCount:o.length,durationMs:Date.now()-a}}function I(e,a){const t=[];switch(a){case".ts":case".tsx":case".js":case".jsx":{const n=/import\s+(?:type\s+)?\{([^}]+)\}\s+from\s+['"]([^'"]+)['"]/g;let s;for(;(s=n.exec(e))!==null;){const c=s[1].split(",").map(o=>{const l=o.trim().split(/\s+as\s+/);return(l[l.length-1]||"").trim()}).filter(Boolean);t.push({source:s[2],symbols:c,isRelative:s[2].startsWith(".")})}const r=/import\s+(\w+)\s+from\s+['"]([^'"]+)['"]/g;for(;(s=r.exec(e))!==null;)s[1]!=="type"&&t.push({source:s[2],symbols:[s[1]],isRelative:s[2].startsWith(".")});const i=/(?:const|let|var)\s+\{([^}]+)\}\s*=\s*require\(\s*['"]([^'"]+)['"]\s*\)/g;for(;(s=i.exec(e))!==null;){const c=s[1].split(",").map(o=>o.trim().split(":")[0].trim()).filter(Boolean);t.push({source:s[2],symbols:c,isRelative:s[2].startsWith(".")})}break}case".java":case".kt":case".scala":{const n=/^import\s+(?:static\s+)?([\w.]+)\s*;/gm;let s;for(;(s=n.exec(e))!==null;){const r=s[1].split("."),i=r[r.length-1];i==="*"?t.push({source:s[1],symbols:[],isRelative:P(s[1],e)}):t.push({source:s[1],symbols:[i],isRelative:P(s[1],e)})}break}case".py":{const n=/^from\s+([\w.]+)\s+import\s+(.+)$/gm;let s;for(;(s=n.exec(e))!==null;){const i=s[2].split(",").map(c=>{const o=c.trim().split(/\s+as\s+/);return(o[o.length-1]||"").trim()}).filter(c=>c&&c!=="(");t.push({source:s[1],symbols:i,isRelative:s[1].startsWith(".")})}const r=/^import\s+([\w.]+)(?:\s+as\s+(\w+))?\s*$/gm;for(;(s=r.exec(e))!==null;){const i=s[1].split("."),c=s[2]||i[i.length-1];t.push({source:s[1],symbols:[c],isRelative:s[1].startsWith(".")})}break}case".go":{const n=/import\s+(?:(\w+)\s+)?[""]([^""]+)[""]/g;let s;for(;(s=n.exec(e))!==null;){const i=s[2].split("/"),c=s[1]||i[i.length-1];t.push({source:s[2],symbols:[c],isRelative:!s[2].includes(".")&&!s[2].startsWith("github.com")})}const r=/import\s*\(([\s\S]*?)\)/g;for(;(s=r.exec(e))!==null;){const i=s[1],c=/(?:(\w+)\s+)?[""]([^""]+)[""]/g;let o;for(;(o=c.exec(i))!==null;){const l=o[2].split("/"),g=o[1]||l[l.length-1];t.push({source:o[2],symbols:[g],isRelative:!o[2].includes(".")&&!o[2].startsWith("github.com")})}}break}case".cs":{const n=/^using\s+(?:static\s+)?([\w.]+)\s*;/gm;let s;for(;(s=n.exec(e))!==null;){const r=s[1].split(".");t.push({source:s[1],symbols:[r[r.length-1]],isRelative:!0})}break}case".rs":{const n=/^use\s+([\w:]+(?:::\w+)*)/gm;let s;for(;(s=n.exec(e))!==null;){const r=s[1].split("::"),i=r[r.length-1];t.push({source:s[1],symbols:i==="*"?[]:[i],isRelative:s[1].startsWith("crate")||s[1].startsWith("super")})}break}}return t}function W(e,a){const t=new Set;switch(a){case".ts":case".tsx":case".js":case".jsx":{const n=/export\s+(?:default\s+)?(?:abstract\s+)?(?:async\s+)?(?:function|class|const|let|var|type|interface|enum)\s+(\w+)/g;let s;for(;(s=n.exec(e))!==null;)t.add(s[1]);break}case".java":case".kt":case".scala":{const n=/(?:public|protected)\s+(?:static\s+)?(?:abstract\s+)?(?:final\s+)?(?:class|interface|enum|record|@interface)\s+(\w+)/g;let s;for(;(s=n.exec(e))!==null;)t.add(s[1]);const r=/(?:public|protected)\s+(?:static\s+)?(?:abstract\s+)?(?:final\s+)?\w+(?:<[^>]+>)?\s+(\w+)\s*\(/g;for(;(s=r.exec(e))!==null;)["if","for","while","switch","catch","return","class","interface","enum","new"].includes(s[1])||t.add(s[1]);break}case".py":{const n=/^(?:def|class)\s+([A-Z_]\w*)/gm;let s;for(;(s=n.exec(e))!==null;)s[1].startsWith("_")||t.add(s[1]);break}case".go":{const n=/^(?:func|type|var|const)\s+(\(?[A-Z]\w*)/gm;let s;for(;(s=n.exec(e))!==null;)t.add(s[1].replace("(",""));break}}return t}function P(e,a){const t=a.match(/^package\s+([\w.]+)\s*;/m);if(!t)return!1;const s=t[1].split("."),r=e.split(".");return s.length>=2&&r.length>=2&&s[0]===r[0]&&s[1]===r[1]}function A(e){return e.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}function C(e,a){switch(a){case".ts":case".tsx":case".js":case".jsx":return e.replace(/^import\s+.+$/gm,"").replace(/^const\s+.+=\s*require\(.+$/gm,"");case".java":case".kt":case".scala":return e.replace(/^import\s+.+;$/gm,"");case".py":return e.replace(/^(?:from\s+.+import\s+.+|import\s+.+)$/gm,"");case".go":return e.replace(/^import\s+.+$/gm,"").replace(/import\s*\([\s\S]*?\)/g,"");case".cs":return e.replace(/^using\s+.+;$/gm,"");case".rs":return e.replace(/^use\s+.+;$/gm,"");default:return e}}function M(e,a){const t=new Map;for(const n of e){const s=y(a,n).replace(/\\/g,"/"),r=s.replace(/\.[^.]+$/,"");j(t,r,s);const i=r.split("/"),c=i[i.length-1];j(t,c,s)}return t}function j(e,a,t){const n=e.get(a);n?n.push(t):e.set(a,[t])}function D(e,a,t,n){switch(n){case".ts":case".tsx":case".js":case".jsx":{if(!a.startsWith("."))return[];const s=e.split("/").slice(0,-1).join("/"),r=N(s?`${s}/${a}`:a);for(const c of["",".ts",".tsx",".js",".jsx","/index.ts","/index.js"]){const o=t.get(r+c)||t.get((r+c).replace(/\.[^.]+$/,""));if(o&&o.length>0)return[o[0]]}const i=t.get(r.replace(/\.[^.]+$/,""));return i?[i[0]]:[]}case".java":case".kt":case".scala":{const s=a.split("."),r=s[s.length-1];if(r==="*")return[];const i=t.get(r);return i?[i[0]]:[]}case".py":{if(a.startsWith(".")){const i=e.split("/").slice(0,-1).join("/"),c=a.replace(/^\.+/,"").replace(/\./g,"/"),o=i?`${i}/${c}`:c,l=o.split("/"),g=t.get(o)||t.get(l[l.length-1]);if(g)return[g[0]]}const s=a.replace(/\./g,"/"),r=t.get(s);return r?[r[0]]:[]}case".go":{const s=a.split("/"),r=s[s.length-1],i=t.get(r);return i?[i[0]]:[]}default:return[]}}function N(e){const a=e.split("/"),t=[];for(const n of a)if(!(n==="."||n==="")){if(n===".."){t.pop();continue}t.push(n)}return t.join("/")}function $(e){return e.split("/").some(t=>t==="test"||t==="tests"||t==="__tests__"||t==="spec"||t==="test_"||t==="__test__")||/\.(test|spec)\.[^.]+$/.test(e)}function T(e){const a=[],t=(n,s)=>{if(!(s>10))try{for(const r of _(n,{withFileTypes:!0})){if(S.has(r.name)||r.name.startsWith("."))continue;const i=E(n,r.name);if(r.isDirectory())t(i,s+1);else{const c=x(r.name).toLowerCase();if(!k.has(c)||r.name.endsWith(".d.ts")||/\.(test|spec)\.[^.]+$/.test(r.name)||y(e,n).replace(/\\/g,"/").split("/").some(l=>l==="test"||l==="tests"||l==="__tests__"||l==="spec"))continue;a.push(i)}}}catch{}};return t(e,0),a}export{q as extractRegexCallGraph};