@vpxa/kb 0.1.1 → 0.1.3

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 (138) hide show
  1. package/README.md +3 -3
  2. package/package.json +1 -1
  3. package/packages/analyzers/dist/blast-radius-analyzer.js +13 -114
  4. package/packages/analyzers/dist/dependency-analyzer.js +11 -425
  5. package/packages/analyzers/dist/diagram-generator.js +4 -86
  6. package/packages/analyzers/dist/entry-point-analyzer.js +5 -239
  7. package/packages/analyzers/dist/index.js +1 -23
  8. package/packages/analyzers/dist/knowledge-producer.js +24 -113
  9. package/packages/analyzers/dist/pattern-analyzer.js +5 -359
  10. package/packages/analyzers/dist/regex-call-graph.js +1 -428
  11. package/packages/analyzers/dist/structure-analyzer.js +4 -258
  12. package/packages/analyzers/dist/symbol-analyzer.js +13 -442
  13. package/packages/analyzers/dist/ts-call-graph.js +1 -160
  14. package/packages/analyzers/dist/types.js +0 -1
  15. package/packages/chunker/dist/call-graph-extractor.js +1 -90
  16. package/packages/chunker/dist/chunker-factory.js +1 -36
  17. package/packages/chunker/dist/chunker.interface.js +0 -1
  18. package/packages/chunker/dist/code-chunker.js +14 -134
  19. package/packages/chunker/dist/generic-chunker.js +5 -72
  20. package/packages/chunker/dist/index.js +1 -21
  21. package/packages/chunker/dist/markdown-chunker.js +7 -119
  22. package/packages/chunker/dist/treesitter-chunker.js +8 -234
  23. package/packages/cli/dist/commands/analyze.js +3 -112
  24. package/packages/cli/dist/commands/context-cmds.js +1 -155
  25. package/packages/cli/dist/commands/environment.js +2 -204
  26. package/packages/cli/dist/commands/execution.js +1 -137
  27. package/packages/cli/dist/commands/graph.js +7 -81
  28. package/packages/cli/dist/commands/init.js +9 -87
  29. package/packages/cli/dist/commands/knowledge.js +1 -139
  30. package/packages/cli/dist/commands/search.js +8 -267
  31. package/packages/cli/dist/commands/system.js +4 -241
  32. package/packages/cli/dist/commands/workspace.js +2 -388
  33. package/packages/cli/dist/context.js +1 -14
  34. package/packages/cli/dist/helpers.js +3 -458
  35. package/packages/cli/dist/index.d.ts +1 -1
  36. package/packages/cli/dist/index.js +3 -69
  37. package/packages/cli/dist/kb-init.js +1 -82
  38. package/packages/cli/dist/types.js +0 -1
  39. package/packages/core/dist/constants.js +1 -43
  40. package/packages/core/dist/content-detector.js +1 -79
  41. package/packages/core/dist/errors.js +1 -40
  42. package/packages/core/dist/index.js +1 -9
  43. package/packages/core/dist/logger.js +1 -34
  44. package/packages/core/dist/types.js +0 -1
  45. package/packages/embeddings/dist/embedder.interface.js +0 -1
  46. package/packages/embeddings/dist/index.js +1 -5
  47. package/packages/embeddings/dist/onnx-embedder.js +1 -82
  48. package/packages/indexer/dist/file-hasher.js +1 -13
  49. package/packages/indexer/dist/filesystem-crawler.js +1 -125
  50. package/packages/indexer/dist/graph-extractor.js +1 -111
  51. package/packages/indexer/dist/incremental-indexer.js +1 -278
  52. package/packages/indexer/dist/index.js +1 -14
  53. package/packages/server/dist/api.js +1 -9
  54. package/packages/server/dist/config.js +1 -75
  55. package/packages/server/dist/curated-manager.js +9 -356
  56. package/packages/server/dist/index.js +1 -134
  57. package/packages/server/dist/replay-interceptor.js +1 -38
  58. package/packages/server/dist/resources/resources.js +2 -40
  59. package/packages/server/dist/server.js +1 -247
  60. package/packages/server/dist/tools/analyze.tools.js +1 -288
  61. package/packages/server/dist/tools/forge.tools.js +11 -499
  62. package/packages/server/dist/tools/forget.tool.js +3 -39
  63. package/packages/server/dist/tools/graph.tool.js +5 -110
  64. package/packages/server/dist/tools/list.tool.js +5 -53
  65. package/packages/server/dist/tools/lookup.tool.js +8 -51
  66. package/packages/server/dist/tools/onboard.tool.js +2 -112
  67. package/packages/server/dist/tools/produce.tool.js +4 -74
  68. package/packages/server/dist/tools/read.tool.js +4 -47
  69. package/packages/server/dist/tools/reindex.tool.js +2 -70
  70. package/packages/server/dist/tools/remember.tool.js +3 -42
  71. package/packages/server/dist/tools/replay.tool.js +6 -88
  72. package/packages/server/dist/tools/search.tool.js +17 -327
  73. package/packages/server/dist/tools/status.tool.js +3 -68
  74. package/packages/server/dist/tools/toolkit.tools.js +20 -1673
  75. package/packages/server/dist/tools/update.tool.js +3 -39
  76. package/packages/server/dist/tools/utility.tools.js +19 -456
  77. package/packages/store/dist/graph-store.interface.js +0 -1
  78. package/packages/store/dist/index.js +1 -9
  79. package/packages/store/dist/lance-store.js +1 -258
  80. package/packages/store/dist/sqlite-graph-store.js +8 -309
  81. package/packages/store/dist/store-factory.js +1 -14
  82. package/packages/store/dist/store.interface.js +0 -1
  83. package/packages/tools/dist/batch.js +1 -45
  84. package/packages/tools/dist/changelog.js +2 -112
  85. package/packages/tools/dist/check.js +2 -59
  86. package/packages/tools/dist/checkpoint.js +2 -43
  87. package/packages/tools/dist/codemod.js +2 -69
  88. package/packages/tools/dist/compact.js +3 -60
  89. package/packages/tools/dist/data-transform.js +1 -124
  90. package/packages/tools/dist/dead-symbols.js +2 -71
  91. package/packages/tools/dist/delegate.js +3 -128
  92. package/packages/tools/dist/diff-parse.js +3 -153
  93. package/packages/tools/dist/digest.js +7 -242
  94. package/packages/tools/dist/encode.js +1 -46
  95. package/packages/tools/dist/env-info.js +1 -58
  96. package/packages/tools/dist/eval.js +3 -79
  97. package/packages/tools/dist/evidence-map.js +3 -203
  98. package/packages/tools/dist/file-summary.js +2 -106
  99. package/packages/tools/dist/file-walk.js +1 -75
  100. package/packages/tools/dist/find-examples.js +3 -48
  101. package/packages/tools/dist/find.js +1 -120
  102. package/packages/tools/dist/forge-classify.js +2 -319
  103. package/packages/tools/dist/forge-ground.js +1 -184
  104. package/packages/tools/dist/git-context.js +3 -46
  105. package/packages/tools/dist/graph-query.js +1 -194
  106. package/packages/tools/dist/health.js +1 -118
  107. package/packages/tools/dist/http-request.js +1 -58
  108. package/packages/tools/dist/index.js +1 -273
  109. package/packages/tools/dist/lane.js +7 -227
  110. package/packages/tools/dist/measure.js +2 -119
  111. package/packages/tools/dist/onboard.js +42 -1136
  112. package/packages/tools/dist/parse-output.js +2 -158
  113. package/packages/tools/dist/process-manager.js +1 -69
  114. package/packages/tools/dist/queue.js +2 -126
  115. package/packages/tools/dist/regex-test.js +1 -39
  116. package/packages/tools/dist/rename.js +2 -70
  117. package/packages/tools/dist/replay.js +6 -108
  118. package/packages/tools/dist/schema-validate.js +1 -141
  119. package/packages/tools/dist/scope-map.js +1 -72
  120. package/packages/tools/dist/snippet.js +1 -80
  121. package/packages/tools/dist/stash.js +2 -60
  122. package/packages/tools/dist/stratum-card.js +5 -238
  123. package/packages/tools/dist/symbol.js +3 -87
  124. package/packages/tools/dist/test-run.js +2 -55
  125. package/packages/tools/dist/text-utils.js +2 -31
  126. package/packages/tools/dist/time-utils.js +1 -135
  127. package/packages/tools/dist/trace.js +2 -114
  128. package/packages/tools/dist/truncation.js +10 -41
  129. package/packages/tools/dist/watch.js +1 -61
  130. package/packages/tools/dist/web-fetch.js +9 -244
  131. package/packages/tools/dist/web-search.js +1 -46
  132. package/packages/tools/dist/workset.js +2 -77
  133. package/packages/tui/dist/App.js +260 -52468
  134. package/packages/tui/dist/index.js +286 -54551
  135. package/packages/tui/dist/panels/CuratedPanel.js +211 -34291
  136. package/packages/tui/dist/panels/LogPanel.js +259 -51703
  137. package/packages/tui/dist/panels/SearchPanel.js +212 -34824
  138. package/packages/tui/dist/panels/StatusPanel.js +211 -34304
@@ -1,442 +1,13 @@
1
- import { readdir, readFile } from "node:fs/promises";
2
- import { extname, join, relative } from "node:path";
3
- const CODE_EXTENSIONS = /* @__PURE__ */ new Set([
4
- ".ts",
5
- ".tsx",
6
- ".js",
7
- ".jsx",
8
- ".java",
9
- ".py",
10
- ".go",
11
- ".cs",
12
- ".rb",
13
- ".kt",
14
- ".scala",
15
- ".rs",
16
- ".php",
17
- ".swift"
18
- ]);
19
- const DEFAULT_EXCLUDES = /* @__PURE__ */ new Set([
20
- "node_modules",
21
- ".git",
22
- "dist",
23
- "build",
24
- "coverage",
25
- ".turbo",
26
- ".cache",
27
- "cdk.out",
28
- "__pycache__",
29
- ".venv",
30
- "target",
31
- "bin",
32
- "obj",
33
- ".gradle",
34
- "venv",
35
- "env"
36
- ]);
37
- const TS_PATTERNS = {
38
- exported: [
39
- { pattern: /^export\s+(?:async\s+)?function\s+(\w+)/gm, kind: "function" },
40
- { pattern: /^export\s+(?:default\s+)?class\s+(\w+)/gm, kind: "class" },
41
- { pattern: /^export\s+interface\s+(\w+)/gm, kind: "interface" },
42
- { pattern: /^export\s+type\s+(\w+)/gm, kind: "type" },
43
- { pattern: /^export\s+(?:const|let)\s+(\w+)/gm, kind: "const" },
44
- { pattern: /^export\s+enum\s+(\w+)/gm, kind: "enum" }
45
- ],
46
- local: [
47
- { pattern: /^(?:async\s+)?function\s+(\w+)/gm, kind: "function" },
48
- { pattern: /^class\s+(\w+)/gm, kind: "class" },
49
- { pattern: /^interface\s+(\w+)/gm, kind: "interface" },
50
- { pattern: /^type\s+(\w+)/gm, kind: "type" },
51
- { pattern: /^(?:const|let)\s+(\w+)\s*=/gm, kind: "const" },
52
- { pattern: /^enum\s+(\w+)/gm, kind: "enum" }
53
- ]
54
- };
55
- const JAVA_PATTERNS = {
56
- exported: [
57
- {
58
- pattern: /^[ \t]*public\s+(?:static\s+)?(?:abstract\s+)?class\s+(\w+)/gm,
59
- kind: "class"
60
- },
61
- {
62
- pattern: /^[ \t]*public\s+(?:static\s+)?interface\s+(\w+)/gm,
63
- kind: "interface"
64
- },
65
- {
66
- pattern: /^[ \t]*public\s+(?:static\s+)?enum\s+(\w+)/gm,
67
- kind: "enum"
68
- },
69
- {
70
- pattern: /^[ \t]*public\s+(?:static\s+)?(?:synchronized\s+)?(?:final\s+)?(?:abstract\s+)?(?:\w+(?:<[^>]*>)?(?:\[\])*)\s+(\w+)\s*\(/gm,
71
- kind: "function"
72
- }
73
- ],
74
- local: [
75
- {
76
- pattern: /^[ \t]*(?:private|protected)\s+(?:static\s+)?(?:abstract\s+)?class\s+(\w+)/gm,
77
- kind: "class"
78
- },
79
- {
80
- pattern: /^[ \t]*(?:private|protected)\s+(?:static\s+)?(?:synchronized\s+)?(?:final\s+)?(?:\w+(?:<[^>]*>)?(?:\[\])*)\s+(\w+)\s*\(/gm,
81
- kind: "function"
82
- },
83
- {
84
- pattern: /^[ \t]*(?:private|protected)\s+(?:static\s+)?(?:final\s+)?(?:\w+(?:<[^>]*>)?)\s+(\w+)\s*[;=]/gm,
85
- kind: "variable"
86
- }
87
- ],
88
- skipIndentFilter: true
89
- };
90
- const PYTHON_PATTERNS = {
91
- exported: [
92
- // Top-level functions (no leading whitespace = module-level = "exported")
93
- { pattern: /^def\s+(\w+)\s*\(/gm, kind: "function" },
94
- { pattern: /^async\s+def\s+(\w+)\s*\(/gm, kind: "function" },
95
- { pattern: /^class\s+(\w+)/gm, kind: "class" }
96
- ],
97
- local: [
98
- // Indented methods inside classes
99
- { pattern: /^[ \t]+def\s+(\w+)\s*\(/gm, kind: "function" },
100
- { pattern: /^[ \t]+async\s+def\s+(\w+)\s*\(/gm, kind: "function" }
101
- ],
102
- skipIndentFilter: true
103
- };
104
- const GO_PATTERNS = {
105
- exported: [
106
- // Exported = starts with uppercase
107
- { pattern: /^func\s+([A-Z]\w*)\s*\(/gm, kind: "function" },
108
- // Method with receiver
109
- { pattern: /^func\s+\([^)]+\)\s+([A-Z]\w*)\s*\(/gm, kind: "function" },
110
- { pattern: /^type\s+([A-Z]\w*)\s+struct\b/gm, kind: "class" },
111
- { pattern: /^type\s+([A-Z]\w*)\s+interface\b/gm, kind: "interface" },
112
- { pattern: /^type\s+([A-Z]\w*)\s+/gm, kind: "type" }
113
- ],
114
- local: [
115
- { pattern: /^func\s+([a-z]\w*)\s*\(/gm, kind: "function" },
116
- { pattern: /^func\s+\([^)]+\)\s+([a-z]\w*)\s*\(/gm, kind: "function" },
117
- { pattern: /^type\s+([a-z]\w*)\s+struct\b/gm, kind: "class" },
118
- { pattern: /^type\s+([a-z]\w*)\s+/gm, kind: "type" }
119
- ],
120
- skipIndentFilter: true
121
- };
122
- const CSHARP_PATTERNS = {
123
- exported: [
124
- {
125
- pattern: /^[ \t]*public\s+(?:static\s+)?(?:partial\s+)?(?:abstract\s+)?class\s+(\w+)/gm,
126
- kind: "class"
127
- },
128
- {
129
- pattern: /^[ \t]*public\s+(?:static\s+)?interface\s+(\w+)/gm,
130
- kind: "interface"
131
- },
132
- {
133
- pattern: /^[ \t]*public\s+(?:static\s+)?enum\s+(\w+)/gm,
134
- kind: "enum"
135
- },
136
- {
137
- pattern: /^[ \t]*public\s+(?:static\s+)?(?:virtual\s+)?(?:override\s+)?(?:async\s+)?(?:\w+(?:<[^>]*>)?(?:\[\])?)\s+(\w+)\s*\(/gm,
138
- kind: "function"
139
- }
140
- ],
141
- local: [
142
- {
143
- pattern: /^[ \t]*(?:private|protected|internal)\s+(?:static\s+)?(?:abstract\s+)?class\s+(\w+)/gm,
144
- kind: "class"
145
- },
146
- {
147
- pattern: /^[ \t]*(?:private|protected|internal)\s+(?:static\s+)?(?:async\s+)?(?:\w+(?:<[^>]*>)?)\s+(\w+)\s*\(/gm,
148
- kind: "function"
149
- }
150
- ],
151
- skipIndentFilter: true
152
- };
153
- const KOTLIN_PATTERNS = {
154
- exported: [
155
- { pattern: /^(?:open\s+|data\s+|sealed\s+)?class\s+(\w+)/gm, kind: "class" },
156
- { pattern: /^(?:fun|suspend\s+fun)\s+(\w+)\s*[(<]/gm, kind: "function" },
157
- { pattern: /^interface\s+(\w+)/gm, kind: "interface" },
158
- { pattern: /^object\s+(\w+)/gm, kind: "class" },
159
- { pattern: /^enum\s+class\s+(\w+)/gm, kind: "enum" }
160
- ],
161
- local: [
162
- { pattern: /^[ \t]+(?:private|internal)\s+(?:fun|suspend\s+fun)\s+(\w+)/gm, kind: "function" },
163
- { pattern: /^[ \t]+(?:private|internal)\s+(?:val|var)\s+(\w+)/gm, kind: "variable" }
164
- ],
165
- skipIndentFilter: true
166
- };
167
- const RUBY_PATTERNS = {
168
- exported: [
169
- { pattern: /^class\s+(\w+)/gm, kind: "class" },
170
- { pattern: /^module\s+(\w+)/gm, kind: "class" },
171
- { pattern: /^[ \t]+def\s+self\.(\w+)/gm, kind: "function" }
172
- ],
173
- local: [{ pattern: /^[ \t]+def\s+(\w+)/gm, kind: "function" }],
174
- skipIndentFilter: true
175
- };
176
- const RUST_PATTERNS = {
177
- exported: [
178
- { pattern: /^pub\s+(?:async\s+)?fn\s+(\w+)/gm, kind: "function" },
179
- { pattern: /^pub\s+struct\s+(\w+)/gm, kind: "class" },
180
- { pattern: /^pub\s+trait\s+(\w+)/gm, kind: "interface" },
181
- { pattern: /^pub\s+enum\s+(\w+)/gm, kind: "enum" },
182
- { pattern: /^pub\s+type\s+(\w+)/gm, kind: "type" }
183
- ],
184
- local: [
185
- { pattern: /^(?:async\s+)?fn\s+(\w+)/gm, kind: "function" },
186
- { pattern: /^struct\s+(\w+)/gm, kind: "class" },
187
- { pattern: /^trait\s+(\w+)/gm, kind: "interface" },
188
- { pattern: /^enum\s+(\w+)/gm, kind: "enum" }
189
- ],
190
- skipIndentFilter: true
191
- };
192
- const PHP_PATTERNS = {
193
- exported: [
194
- { pattern: /^[ \t]*(?:abstract\s+)?class\s+(\w+)/gm, kind: "class" },
195
- { pattern: /^[ \t]*interface\s+(\w+)/gm, kind: "interface" },
196
- { pattern: /^[ \t]*public\s+(?:static\s+)?function\s+(\w+)/gm, kind: "function" },
197
- { pattern: /^function\s+(\w+)\s*\(/gm, kind: "function" }
198
- ],
199
- local: [
200
- {
201
- pattern: /^[ \t]*(?:private|protected)\s+(?:static\s+)?function\s+(\w+)/gm,
202
- kind: "function"
203
- }
204
- ],
205
- skipIndentFilter: true
206
- };
207
- const SWIFT_PATTERNS = {
208
- exported: [
209
- { pattern: /^[ \t]*(?:open|public)\s+class\s+(\w+)/gm, kind: "class" },
210
- { pattern: /^[ \t]*(?:open|public)\s+struct\s+(\w+)/gm, kind: "class" },
211
- { pattern: /^[ \t]*(?:open|public)\s+protocol\s+(\w+)/gm, kind: "interface" },
212
- { pattern: /^[ \t]*(?:open|public)\s+enum\s+(\w+)/gm, kind: "enum" },
213
- { pattern: /^[ \t]*(?:open|public)\s+func\s+(\w+)/gm, kind: "function" }
214
- ],
215
- local: [
216
- { pattern: /^[ \t]*(?:private|fileprivate|internal)\s+func\s+(\w+)/gm, kind: "function" },
217
- { pattern: /^[ \t]*(?:private|fileprivate|internal)\s+class\s+(\w+)/gm, kind: "class" }
218
- ],
219
- skipIndentFilter: true
220
- };
221
- const SCALA_PATTERNS = {
222
- exported: [
223
- { pattern: /^[ \t]*(?:case\s+)?class\s+(\w+)/gm, kind: "class" },
224
- { pattern: /^[ \t]*object\s+(\w+)/gm, kind: "class" },
225
- { pattern: /^[ \t]*trait\s+(\w+)/gm, kind: "interface" },
226
- { pattern: /^[ \t]*def\s+(\w+)/gm, kind: "function" }
227
- ],
228
- local: [],
229
- skipIndentFilter: true
230
- };
231
- function getLangPatterns(ext) {
232
- switch (ext) {
233
- case ".ts":
234
- case ".tsx":
235
- case ".js":
236
- case ".jsx":
237
- return TS_PATTERNS;
238
- case ".java":
239
- return JAVA_PATTERNS;
240
- case ".py":
241
- return PYTHON_PATTERNS;
242
- case ".go":
243
- return GO_PATTERNS;
244
- case ".cs":
245
- return CSHARP_PATTERNS;
246
- case ".kt":
247
- return KOTLIN_PATTERNS;
248
- case ".rb":
249
- return RUBY_PATTERNS;
250
- case ".rs":
251
- return RUST_PATTERNS;
252
- case ".php":
253
- return PHP_PATTERNS;
254
- case ".swift":
255
- return SWIFT_PATTERNS;
256
- case ".scala":
257
- return SCALA_PATTERNS;
258
- default:
259
- return TS_PATTERNS;
260
- }
261
- }
262
- function extractSignature(lines, startLine) {
263
- let sig = "";
264
- let parenDepth = 0;
265
- let foundOpen = false;
266
- for (let i = startLine; i < Math.min(startLine + 5, lines.length); i++) {
267
- const line = lines[i].trim();
268
- sig += (sig ? " " : "") + line;
269
- for (const ch of line) {
270
- if (ch === "(") {
271
- parenDepth++;
272
- foundOpen = true;
273
- }
274
- if (ch === ")") parenDepth--;
275
- }
276
- if (foundOpen && parenDepth <= 0) {
277
- return sig.replace(/\s*\{.*$/, "").replace(/\s*:\s*$/, "").trim();
278
- }
279
- }
280
- return sig.trim() || void 0;
281
- }
282
- class SymbolAnalyzer {
283
- name = "symbols";
284
- async analyze(rootPath, options = {}) {
285
- const { format = "markdown", filter } = options;
286
- const startTime = Date.now();
287
- const files = await this.collectFiles(rootPath);
288
- let symbols = [];
289
- for (const filePath of files) {
290
- const content = await readFile(filePath, "utf-8");
291
- const fileSymbols = this.extractSymbols(
292
- content,
293
- relative(rootPath, filePath).replace(/\\/g, "/")
294
- );
295
- symbols.push(...fileSymbols);
296
- }
297
- if (filter) {
298
- const filterLower = filter.toLowerCase();
299
- symbols = symbols.filter((s) => s.name.toLowerCase().includes(filterLower));
300
- }
301
- const output = format === "json" ? JSON.stringify(symbols, null, 2) : this.formatMarkdown(symbols, rootPath);
302
- return {
303
- output,
304
- data: {
305
- symbols,
306
- byKind: this.groupByKind(symbols),
307
- exportedCount: symbols.filter((s) => s.exported).length,
308
- totalCount: symbols.length
309
- },
310
- meta: {
311
- analyzedAt: (/* @__PURE__ */ new Date()).toISOString(),
312
- scope: rootPath,
313
- fileCount: files.length,
314
- durationMs: Date.now() - startTime
315
- }
316
- };
317
- }
318
- async collectFiles(dirPath) {
319
- const files = [];
320
- const walk = async (dir) => {
321
- const entries = await readdir(dir, { withFileTypes: true });
322
- for (const entry of entries) {
323
- if (DEFAULT_EXCLUDES.has(entry.name)) continue;
324
- if (entry.name.startsWith(".")) continue;
325
- const fullPath = join(dir, entry.name);
326
- if (entry.isDirectory()) {
327
- await walk(fullPath);
328
- } else if (CODE_EXTENSIONS.has(extname(entry.name))) {
329
- files.push(fullPath);
330
- }
331
- }
332
- };
333
- await walk(dirPath);
334
- return files;
335
- }
336
- extractSymbols(content, filePath) {
337
- const symbols = [];
338
- const lines = content.split("\n");
339
- const exportedNames = /* @__PURE__ */ new Set();
340
- const ext = extname(filePath);
341
- const lang = getLangPatterns(ext);
342
- for (const { pattern, kind } of lang.exported) {
343
- const regex = new RegExp(pattern.source, pattern.flags);
344
- let match;
345
- while ((match = regex.exec(content)) !== null) {
346
- const name = match[1];
347
- exportedNames.add(name);
348
- const line = content.slice(0, match.index).split("\n").length;
349
- const signature = kind === "function" || kind === "method" ? extractSignature(lines, line - 1) : void 0;
350
- symbols.push({ name, kind, exported: true, filePath, line, signature });
351
- }
352
- }
353
- for (const { pattern, kind } of lang.local) {
354
- const regex = new RegExp(pattern.source, pattern.flags);
355
- let match;
356
- while ((match = regex.exec(content)) !== null) {
357
- const name = match[1];
358
- if (exportedNames.has(name)) continue;
359
- if (!lang.skipIndentFilter) {
360
- const lineIdx = content.slice(0, match.index).split("\n").length - 1;
361
- const lineContent = lines[lineIdx] ?? "";
362
- if (lineContent.startsWith(" ") || lineContent.startsWith(" ")) continue;
363
- }
364
- const line = content.slice(0, match.index).split("\n").length;
365
- const signature = kind === "function" || kind === "method" ? extractSignature(lines, line - 1) : void 0;
366
- symbols.push({ name, kind, exported: false, filePath, line, signature });
367
- }
368
- }
369
- return symbols;
370
- }
371
- groupByKind(symbols) {
372
- const groups = {};
373
- for (const s of symbols) {
374
- groups[s.kind] = (groups[s.kind] ?? 0) + 1;
375
- }
376
- return groups;
377
- }
378
- formatMarkdown(symbols, rootPath) {
379
- const lines = [];
380
- const exported = symbols.filter((s) => s.exported).length;
381
- lines.push(`## Symbols: ${rootPath}
382
- `);
383
- lines.push(`**${symbols.length} symbols** (${exported} exported)
384
- `);
385
- const kindCounts = {};
386
- for (const s of symbols) {
387
- kindCounts[s.kind] = (kindCounts[s.kind] ?? 0) + 1;
388
- }
389
- const kindSummary = Object.entries(kindCounts).sort((a, b) => b[1] - a[1]).map(([kind, count]) => {
390
- const plural = kind === "class" ? "classes" : `${kind}s`;
391
- return `${count} ${plural}`;
392
- }).join(", ");
393
- lines.push(`**Breakdown**: ${kindSummary}
394
- `);
395
- const byFile = {};
396
- for (const s of symbols) {
397
- if (!byFile[s.filePath]) byFile[s.filePath] = [];
398
- byFile[s.filePath].push(s);
399
- }
400
- lines.push(`**${Object.keys(byFile).length} files** with symbols
401
- `);
402
- let totalOutputBytes = 0;
403
- const MAX_OUTPUT_BYTES = 80 * 1024;
404
- const sortedFiles = Object.entries(byFile).sort((a, b) => {
405
- const aExports = a[1].filter((s) => s.exported).length;
406
- const bExports = b[1].filter((s) => s.exported).length;
407
- return bExports - aExports;
408
- });
409
- for (const [file, fileSymbols] of sortedFiles) {
410
- const exportedSyms = fileSymbols.filter((s) => s.exported);
411
- if (exportedSyms.length === 0) continue;
412
- const fileSection = [`### ${file}
413
- `];
414
- for (const s of exportedSyms) {
415
- const sig = s.signature ? ` \u2014 \`${s.signature}\`` : "";
416
- fileSection.push(`- \u{1F4E4} \`${s.kind}\` **${s.name}** (line ${s.line})${sig}`);
417
- }
418
- const internalCount = fileSymbols.length - exportedSyms.length;
419
- if (internalCount > 0) {
420
- fileSection.push(
421
- `- _${internalCount} internal ${internalCount === 1 ? "symbol" : "symbols"}_`
422
- );
423
- }
424
- fileSection.push("");
425
- const sectionText = fileSection.join("\n");
426
- totalOutputBytes += sectionText.length;
427
- if (totalOutputBytes > MAX_OUTPUT_BYTES) {
428
- lines.push(
429
- `
430
- _Output truncated at 80KB. ${Object.keys(byFile).length - lines.filter((l) => l.startsWith("### ")).length} files omitted._`
431
- );
432
- break;
433
- }
434
- lines.push(sectionText);
435
- }
436
- return lines.join("\n");
437
- }
438
- }
439
- export {
440
- SymbolAnalyzer
441
- };
442
- //# sourceMappingURL=symbol-analyzer.js.map
1
+ import{readdir as S,readFile as A}from"node:fs/promises";import{extname as y,join as T,relative as P}from"node:path";const v=new Set([".ts",".tsx",".js",".jsx",".java",".py",".go",".cs",".rb",".kt",".scala",".rs",".php",".swift"]),E=new Set(["node_modules",".git","dist","build","coverage",".turbo",".cache","cdk.out","__pycache__",".venv","target","bin","obj",".gradle","venv","env"]),b={exported:[{pattern:/^export\s+(?:async\s+)?function\s+(\w+)/gm,kind:"function"},{pattern:/^export\s+(?:default\s+)?class\s+(\w+)/gm,kind:"class"},{pattern:/^export\s+interface\s+(\w+)/gm,kind:"interface"},{pattern:/^export\s+type\s+(\w+)/gm,kind:"type"},{pattern:/^export\s+(?:const|let)\s+(\w+)/gm,kind:"const"},{pattern:/^export\s+enum\s+(\w+)/gm,kind:"enum"}],local:[{pattern:/^(?:async\s+)?function\s+(\w+)/gm,kind:"function"},{pattern:/^class\s+(\w+)/gm,kind:"class"},{pattern:/^interface\s+(\w+)/gm,kind:"interface"},{pattern:/^type\s+(\w+)/gm,kind:"type"},{pattern:/^(?:const|let)\s+(\w+)\s*=/gm,kind:"const"},{pattern:/^enum\s+(\w+)/gm,kind:"enum"}]},I={exported:[{pattern:/^[ \t]*public\s+(?:static\s+)?(?:abstract\s+)?class\s+(\w+)/gm,kind:"class"},{pattern:/^[ \t]*public\s+(?:static\s+)?interface\s+(\w+)/gm,kind:"interface"},{pattern:/^[ \t]*public\s+(?:static\s+)?enum\s+(\w+)/gm,kind:"enum"},{pattern:/^[ \t]*public\s+(?:static\s+)?(?:synchronized\s+)?(?:final\s+)?(?:abstract\s+)?(?:\w+(?:<[^>]*>)?(?:\[\])*)\s+(\w+)\s*\(/gm,kind:"function"}],local:[{pattern:/^[ \t]*(?:private|protected)\s+(?:static\s+)?(?:abstract\s+)?class\s+(\w+)/gm,kind:"class"},{pattern:/^[ \t]*(?:private|protected)\s+(?:static\s+)?(?:synchronized\s+)?(?:final\s+)?(?:\w+(?:<[^>]*>)?(?:\[\])*)\s+(\w+)\s*\(/gm,kind:"function"},{pattern:/^[ \t]*(?:private|protected)\s+(?:static\s+)?(?:final\s+)?(?:\w+(?:<[^>]*>)?)\s+(\w+)\s*[;=]/gm,kind:"variable"}],skipIndentFilter:!0},R={exported:[{pattern:/^def\s+(\w+)\s*\(/gm,kind:"function"},{pattern:/^async\s+def\s+(\w+)\s*\(/gm,kind:"function"},{pattern:/^class\s+(\w+)/gm,kind:"class"}],local:[{pattern:/^[ \t]+def\s+(\w+)\s*\(/gm,kind:"function"},{pattern:/^[ \t]+async\s+def\s+(\w+)\s*\(/gm,kind:"function"}],skipIndentFilter:!0},_={exported:[{pattern:/^func\s+([A-Z]\w*)\s*\(/gm,kind:"function"},{pattern:/^func\s+\([^)]+\)\s+([A-Z]\w*)\s*\(/gm,kind:"function"},{pattern:/^type\s+([A-Z]\w*)\s+struct\b/gm,kind:"class"},{pattern:/^type\s+([A-Z]\w*)\s+interface\b/gm,kind:"interface"},{pattern:/^type\s+([A-Z]\w*)\s+/gm,kind:"type"}],local:[{pattern:/^func\s+([a-z]\w*)\s*\(/gm,kind:"function"},{pattern:/^func\s+\([^)]+\)\s+([a-z]\w*)\s*\(/gm,kind:"function"},{pattern:/^type\s+([a-z]\w*)\s+struct\b/gm,kind:"class"},{pattern:/^type\s+([a-z]\w*)\s+/gm,kind:"type"}],skipIndentFilter:!0},F={exported:[{pattern:/^[ \t]*public\s+(?:static\s+)?(?:partial\s+)?(?:abstract\s+)?class\s+(\w+)/gm,kind:"class"},{pattern:/^[ \t]*public\s+(?:static\s+)?interface\s+(\w+)/gm,kind:"interface"},{pattern:/^[ \t]*public\s+(?:static\s+)?enum\s+(\w+)/gm,kind:"enum"},{pattern:/^[ \t]*public\s+(?:static\s+)?(?:virtual\s+)?(?:override\s+)?(?:async\s+)?(?:\w+(?:<[^>]*>)?(?:\[\])?)\s+(\w+)\s*\(/gm,kind:"function"}],local:[{pattern:/^[ \t]*(?:private|protected|internal)\s+(?:static\s+)?(?:abstract\s+)?class\s+(\w+)/gm,kind:"class"},{pattern:/^[ \t]*(?:private|protected|internal)\s+(?:static\s+)?(?:async\s+)?(?:\w+(?:<[^>]*>)?)\s+(\w+)\s*\(/gm,kind:"function"}],skipIndentFilter:!0},L={exported:[{pattern:/^(?:open\s+|data\s+|sealed\s+)?class\s+(\w+)/gm,kind:"class"},{pattern:/^(?:fun|suspend\s+fun)\s+(\w+)\s*[(<]/gm,kind:"function"},{pattern:/^interface\s+(\w+)/gm,kind:"interface"},{pattern:/^object\s+(\w+)/gm,kind:"class"},{pattern:/^enum\s+class\s+(\w+)/gm,kind:"enum"}],local:[{pattern:/^[ \t]+(?:private|internal)\s+(?:fun|suspend\s+fun)\s+(\w+)/gm,kind:"function"},{pattern:/^[ \t]+(?:private|internal)\s+(?:val|var)\s+(\w+)/gm,kind:"variable"}],skipIndentFilter:!0},j={exported:[{pattern:/^class\s+(\w+)/gm,kind:"class"},{pattern:/^module\s+(\w+)/gm,kind:"class"},{pattern:/^[ \t]+def\s+self\.(\w+)/gm,kind:"function"}],local:[{pattern:/^[ \t]+def\s+(\w+)/gm,kind:"function"}],skipIndentFilter:!0},$={exported:[{pattern:/^pub\s+(?:async\s+)?fn\s+(\w+)/gm,kind:"function"},{pattern:/^pub\s+struct\s+(\w+)/gm,kind:"class"},{pattern:/^pub\s+trait\s+(\w+)/gm,kind:"interface"},{pattern:/^pub\s+enum\s+(\w+)/gm,kind:"enum"},{pattern:/^pub\s+type\s+(\w+)/gm,kind:"type"}],local:[{pattern:/^(?:async\s+)?fn\s+(\w+)/gm,kind:"function"},{pattern:/^struct\s+(\w+)/gm,kind:"class"},{pattern:/^trait\s+(\w+)/gm,kind:"interface"},{pattern:/^enum\s+(\w+)/gm,kind:"enum"}],skipIndentFilter:!0},O={exported:[{pattern:/^[ \t]*(?:abstract\s+)?class\s+(\w+)/gm,kind:"class"},{pattern:/^[ \t]*interface\s+(\w+)/gm,kind:"interface"},{pattern:/^[ \t]*public\s+(?:static\s+)?function\s+(\w+)/gm,kind:"function"},{pattern:/^function\s+(\w+)\s*\(/gm,kind:"function"}],local:[{pattern:/^[ \t]*(?:private|protected)\s+(?:static\s+)?function\s+(\w+)/gm,kind:"function"}],skipIndentFilter:!0},N={exported:[{pattern:/^[ \t]*(?:open|public)\s+class\s+(\w+)/gm,kind:"class"},{pattern:/^[ \t]*(?:open|public)\s+struct\s+(\w+)/gm,kind:"class"},{pattern:/^[ \t]*(?:open|public)\s+protocol\s+(\w+)/gm,kind:"interface"},{pattern:/^[ \t]*(?:open|public)\s+enum\s+(\w+)/gm,kind:"enum"},{pattern:/^[ \t]*(?:open|public)\s+func\s+(\w+)/gm,kind:"function"}],local:[{pattern:/^[ \t]*(?:private|fileprivate|internal)\s+func\s+(\w+)/gm,kind:"function"},{pattern:/^[ \t]*(?:private|fileprivate|internal)\s+class\s+(\w+)/gm,kind:"class"}],skipIndentFilter:!0},z={exported:[{pattern:/^[ \t]*(?:case\s+)?class\s+(\w+)/gm,kind:"class"},{pattern:/^[ \t]*object\s+(\w+)/gm,kind:"class"},{pattern:/^[ \t]*trait\s+(\w+)/gm,kind:"interface"},{pattern:/^[ \t]*def\s+(\w+)/gm,kind:"function"}],local:[],skipIndentFilter:!0};function C(k){switch(k){case".ts":case".tsx":case".js":case".jsx":return b;case".java":return I;case".py":return R;case".go":return _;case".cs":return F;case".kt":return L;case".rb":return j;case".rs":return $;case".php":return O;case".swift":return N;case".scala":return z;default:return b}}function h(k,s){let r="",e=0,c=!1;for(let o=s;o<Math.min(s+5,k.length);o++){const i=k[o].trim();r+=(r?" ":"")+i;for(const n of i)n==="("&&(e++,c=!0),n===")"&&e--;if(c&&e<=0)return r.replace(/\s*\{.*$/,"").replace(/\s*:\s*$/,"").trim()}return r.trim()||void 0}class U{name="symbols";async analyze(s,r={}){const{format:e="markdown",filter:c}=r,o=Date.now(),i=await this.collectFiles(s);let n=[];for(const a of i){const d=await A(a,"utf-8"),t=this.extractSymbols(d,P(s,a).replace(/\\/g,"/"));n.push(...t)}if(c){const a=c.toLowerCase();n=n.filter(d=>d.name.toLowerCase().includes(a))}return{output:e==="json"?JSON.stringify(n,null,2):this.formatMarkdown(n,s),data:{symbols:n,byKind:this.groupByKind(n),exportedCount:n.filter(a=>a.exported).length,totalCount:n.length},meta:{analyzedAt:new Date().toISOString(),scope:s,fileCount:i.length,durationMs:Date.now()-o}}}async collectFiles(s){const r=[],e=async c=>{const o=await S(c,{withFileTypes:!0});for(const i of o){if(E.has(i.name)||i.name.startsWith("."))continue;const n=T(c,i.name);i.isDirectory()?await e(n):v.has(y(i.name))&&r.push(n)}};return await e(s),r}extractSymbols(s,r){const e=[],c=s.split(`
2
+ `),o=new Set,i=y(r),n=C(i);for(const{pattern:u,kind:a}of n.exported){const d=new RegExp(u.source,u.flags);let t;for(;(t=d.exec(s))!==null;){const l=t[1];o.add(l);const p=s.slice(0,t.index).split(`
3
+ `).length,f=a==="function"||a==="method"?h(c,p-1):void 0;e.push({name:l,kind:a,exported:!0,filePath:r,line:p,signature:f})}}for(const{pattern:u,kind:a}of n.local){const d=new RegExp(u.source,u.flags);let t;for(;(t=d.exec(s))!==null;){const l=t[1];if(o.has(l))continue;if(!n.skipIndentFilter){const m=s.slice(0,t.index).split(`
4
+ `).length-1,w=c[m]??"";if(w.startsWith(" ")||w.startsWith(" "))continue}const p=s.slice(0,t.index).split(`
5
+ `).length,f=a==="function"||a==="method"?h(c,p-1):void 0;e.push({name:l,kind:a,exported:!1,filePath:r,line:p,signature:f})}}return e}groupByKind(s){const r={};for(const e of s)r[e.kind]=(r[e.kind]??0)+1;return r}formatMarkdown(s,r){const e=[],c=s.filter(t=>t.exported).length;e.push(`## Symbols: ${r}
6
+ `),e.push(`**${s.length} symbols** (${c} exported)
7
+ `);const o={};for(const t of s)o[t.kind]=(o[t.kind]??0)+1;const i=Object.entries(o).sort((t,l)=>l[1]-t[1]).map(([t,l])=>{const p=t==="class"?"classes":`${t}s`;return`${l} ${p}`}).join(", ");e.push(`**Breakdown**: ${i}
8
+ `);const n={};for(const t of s)n[t.filePath]||(n[t.filePath]=[]),n[t.filePath].push(t);e.push(`**${Object.keys(n).length} files** with symbols
9
+ `);let u=0;const a=80*1024,d=Object.entries(n).sort((t,l)=>{const p=t[1].filter(m=>m.exported).length;return l[1].filter(m=>m.exported).length-p});for(const[t,l]of d){const p=l.filter(g=>g.exported);if(p.length===0)continue;const f=[`### ${t}
10
+ `];for(const g of p){const x=g.signature?` \u2014 \`${g.signature}\``:"";f.push(`- \u{1F4E4} \`${g.kind}\` **${g.name}** (line ${g.line})${x}`)}const m=l.length-p.length;m>0&&f.push(`- _${m} internal ${m===1?"symbol":"symbols"}_`),f.push("");const w=f.join(`
11
+ `);if(u+=w.length,u>a){e.push(`
12
+ _Output truncated at 80KB. ${Object.keys(n).length-e.filter(g=>g.startsWith("### ")).length} files omitted._`);break}e.push(w)}return e.join(`
13
+ `)}}export{U as SymbolAnalyzer};
@@ -1,160 +1 @@
1
- import { existsSync, 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
- ]);
13
- async function extractTsCallGraph(rootPath) {
14
- const startTime = Date.now();
15
- if (!hasTsConfig(rootPath)) return null;
16
- let ts;
17
- try {
18
- ts = await import("typescript");
19
- } catch {
20
- return null;
21
- }
22
- const sourceFiles = collectTsFiles(rootPath);
23
- if (sourceFiles.length === 0) return null;
24
- const cappedFiles = sourceFiles.slice(0, 800);
25
- const compilerOptions = loadCompilerOptions(ts, rootPath);
26
- const program = ts.createProgram(cappedFiles, {
27
- ...compilerOptions,
28
- noEmit: true,
29
- skipLibCheck: true,
30
- allowJs: true,
31
- target: ts.ScriptTarget.ESNext,
32
- module: ts.ModuleKind.ESNext,
33
- moduleResolution: ts.ModuleResolutionKind.Bundler
34
- });
35
- const checker = program.getTypeChecker();
36
- const edgeMap = /* @__PURE__ */ new Map();
37
- for (const sourceFile of program.getSourceFiles()) {
38
- const fileName = sourceFile.fileName;
39
- if (sourceFile.isDeclarationFile) continue;
40
- if (fileName.includes("node_modules")) continue;
41
- const callerRel = relative(rootPath, fileName).replace(/\\/g, "/");
42
- if (callerRel.startsWith("..")) continue;
43
- visitNode(ts, sourceFile, sourceFile, checker, rootPath, callerRel, edgeMap);
44
- }
45
- const edges = [];
46
- for (const [key, syms] of edgeMap) {
47
- const [from, to] = key.split("|");
48
- edges.push({ from, to, symbols: [...syms].sort().slice(0, 10) });
49
- }
50
- edges.sort((a, b) => b.symbols.length - a.symbols.length);
51
- return {
52
- edges,
53
- fileCount: cappedFiles.length,
54
- edgeCount: edges.length,
55
- durationMs: Date.now() - startTime
56
- };
57
- }
58
- function hasTsConfig(rootPath) {
59
- if (existsSync(join(rootPath, "tsconfig.json"))) return true;
60
- if (existsSync(join(rootPath, "tsconfig.build.json"))) return true;
61
- try {
62
- for (const entry of readdirSync(rootPath, { withFileTypes: true })) {
63
- if (entry.isDirectory() && !SKIP_DIRS.has(entry.name) && !entry.name.startsWith(".")) {
64
- if (existsSync(join(rootPath, entry.name, "tsconfig.json"))) return true;
65
- }
66
- }
67
- } catch {
68
- }
69
- return false;
70
- }
71
- function loadCompilerOptions(ts, rootPath) {
72
- const tsconfigPath = join(rootPath, "tsconfig.json");
73
- if (!existsSync(tsconfigPath)) return {};
74
- try {
75
- const configFile = ts.readConfigFile(tsconfigPath, (p) => readFileSync(p, "utf-8"));
76
- if (configFile.error) return {};
77
- const parsed = ts.parseJsonConfigFileContent(configFile.config, ts.sys, rootPath);
78
- return parsed.options;
79
- } catch {
80
- return {};
81
- }
82
- }
83
- function collectTsFiles(rootPath) {
84
- const files = [];
85
- const tsExts = /* @__PURE__ */ new Set([".ts", ".tsx"]);
86
- const walk = (dir, depth) => {
87
- if (depth > 10) return;
88
- try {
89
- for (const entry of readdirSync(dir, { withFileTypes: true })) {
90
- if (SKIP_DIRS.has(entry.name) || entry.name.startsWith(".")) continue;
91
- const fullPath = join(dir, entry.name);
92
- if (entry.isDirectory()) {
93
- walk(fullPath, depth + 1);
94
- } else if (tsExts.has(extname(entry.name))) {
95
- if (entry.name.endsWith(".d.ts")) continue;
96
- if (/\.(test|spec)\.[jt]sx?$/.test(entry.name)) continue;
97
- const relDir = relative(rootPath, dir).replace(/\\/g, "/");
98
- if (relDir.split("/").some((s) => s === "test" || s === "tests" || s === "__tests__" || s === "spec"))
99
- continue;
100
- files.push(fullPath);
101
- }
102
- }
103
- } catch {
104
- }
105
- };
106
- walk(rootPath, 0);
107
- return files;
108
- }
109
- function visitNode(ts, node, sourceFile, checker, rootPath, callerRel, edgeMap) {
110
- if (ts.isCallExpression(node) || ts.isNewExpression(node)) {
111
- const expr = node.expression;
112
- resolveCallTarget(ts, expr, checker, rootPath, callerRel, edgeMap);
113
- }
114
- ts.forEachChild(node, (child) => {
115
- visitNode(ts, child, sourceFile, checker, rootPath, callerRel, edgeMap);
116
- });
117
- }
118
- function remapDistToSource(rel) {
119
- const distMatch = rel.match(/^(.+?)\/dist\/(.+)$/);
120
- if (!distMatch) return rel;
121
- const [, prefix, rest] = distMatch;
122
- const srcFile = rest.replace(/\.d\.(m?ts|cts)$/, ".ts");
123
- return `${prefix}/src/${srcFile}`;
124
- }
125
- function resolveCallTarget(ts, expr, checker, rootPath, callerRel, edgeMap) {
126
- try {
127
- let symbol;
128
- let symbolName;
129
- if (ts.isIdentifier(expr)) {
130
- symbol = checker.getSymbolAtLocation(expr);
131
- symbolName = expr.text;
132
- } else if (ts.isPropertyAccessExpression(expr)) {
133
- symbol = checker.getSymbolAtLocation(expr.name);
134
- symbolName = expr.name.text;
135
- }
136
- if (!symbol || !symbolName) return;
137
- if (symbol.flags & ts.SymbolFlags.Alias) {
138
- symbol = checker.getAliasedSymbol(symbol);
139
- }
140
- const declarations = symbol.getDeclarations();
141
- if (!declarations || declarations.length === 0) return;
142
- const declFile = declarations[0].getSourceFile().fileName;
143
- if (declFile.includes("node_modules")) return;
144
- let calleeRel = relative(rootPath, declFile).replace(/\\/g, "/");
145
- calleeRel = remapDistToSource(calleeRel);
146
- if (calleeRel === callerRel || calleeRel.startsWith("..")) return;
147
- const key = `${callerRel}|${calleeRel}`;
148
- const existing = edgeMap.get(key);
149
- if (existing) {
150
- existing.add(symbolName);
151
- } else {
152
- edgeMap.set(key, /* @__PURE__ */ new Set([symbolName]));
153
- }
154
- } catch {
155
- }
156
- }
157
- export {
158
- extractTsCallGraph
159
- };
160
- //# sourceMappingURL=ts-call-graph.js.map
1
+ import{existsSync as m,readdirSync as y,readFileSync as b}from"node:fs";import{extname as F,join as g,relative as d}from"node:path";const S=new Set(["node_modules",".git","dist","build","coverage",".turbo",".cache","cdk.out"]);async function _(e){const t=Date.now();if(!T(e))return null;let s;try{s=await import("typescript")}catch{return null}const i=w(e);if(i.length===0)return null;const r=i.slice(0,800),c=x(s,e),n=s.createProgram(r,{...c,noEmit:!0,skipLibCheck:!0,allowJs:!0,target:s.ScriptTarget.ESNext,module:s.ModuleKind.ESNext,moduleResolution:s.ModuleResolutionKind.Bundler}),o=n.getTypeChecker(),f=new Map;for(const l of n.getSourceFiles()){const a=l.fileName;if(l.isDeclarationFile||a.includes("node_modules"))continue;const p=d(e,a).replace(/\\/g,"/");p.startsWith("..")||h(s,l,l,o,e,p,f)}const u=[];for(const[l,a]of f){const[p,C]=l.split("|");u.push({from:p,to:C,symbols:[...a].sort().slice(0,10)})}return u.sort((l,a)=>a.symbols.length-l.symbols.length),{edges:u,fileCount:r.length,edgeCount:u.length,durationMs:Date.now()-t}}function T(e){if(m(g(e,"tsconfig.json"))||m(g(e,"tsconfig.build.json")))return!0;try{for(const t of y(e,{withFileTypes:!0}))if(t.isDirectory()&&!S.has(t.name)&&!t.name.startsWith(".")&&m(g(e,t.name,"tsconfig.json")))return!0}catch{}return!1}function x(e,t){const s=g(t,"tsconfig.json");if(!m(s))return{};try{const i=e.readConfigFile(s,c=>b(c,"utf-8"));return i.error?{}:e.parseJsonConfigFileContent(i.config,e.sys,t).options}catch{return{}}}function w(e){const t=[],s=new Set([".ts",".tsx"]),i=(r,c)=>{if(!(c>10))try{for(const n of y(r,{withFileTypes:!0})){if(S.has(n.name)||n.name.startsWith("."))continue;const o=g(r,n.name);if(n.isDirectory())i(o,c+1);else if(s.has(F(n.name))){if(n.name.endsWith(".d.ts")||/\.(test|spec)\.[jt]sx?$/.test(n.name)||d(e,r).replace(/\\/g,"/").split("/").some(u=>u==="test"||u==="tests"||u==="__tests__"||u==="spec"))continue;t.push(o)}}}catch{}};return i(e,0),t}function h(e,t,s,i,r,c,n){if(e.isCallExpression(t)||e.isNewExpression(t)){const o=t.expression;D(e,o,i,r,c,n)}e.forEachChild(t,o=>{h(e,o,s,i,r,c,n)})}function E(e){const t=e.match(/^(.+?)\/dist\/(.+)$/);if(!t)return e;const[,s,i]=t,r=i.replace(/\.d\.(m?ts|cts)$/,".ts");return`${s}/src/${r}`}function D(e,t,s,i,r,c){try{let n,o;if(e.isIdentifier(t)?(n=s.getSymbolAtLocation(t),o=t.text):e.isPropertyAccessExpression(t)&&(n=s.getSymbolAtLocation(t.name),o=t.name.text),!n||!o)return;n.flags&e.SymbolFlags.Alias&&(n=s.getAliasedSymbol(n));const f=n.getDeclarations();if(!f||f.length===0)return;const u=f[0].getSourceFile().fileName;if(u.includes("node_modules"))return;let l=d(i,u).replace(/\\/g,"/");if(l=E(l),l===r||l.startsWith(".."))return;const a=`${r}|${l}`,p=c.get(a);p?p.add(o):c.set(a,new Set([o]))}catch{}}export{_ as extractTsCallGraph};
@@ -1 +0,0 @@
1
- //# sourceMappingURL=types.js.map