@vibgrate/cli 2026.728.3 → 2026.728.5

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 (131) hide show
  1. package/dist/baseline-Y5FBYWNJ.js +8 -0
  2. package/dist/{baseline-PPZJBYAJ.js.map → baseline-Y5FBYWNJ.js.map} +1 -1
  3. package/dist/{chunk-A2IYFNCQ.js → chunk-2ZHWF7C6.js} +227 -19
  4. package/dist/chunk-2ZHWF7C6.js.map +1 -0
  5. package/dist/{chunk-UZJS7GMK.js → chunk-3LSG7Z4I.js} +10 -6
  6. package/dist/chunk-3LSG7Z4I.js.map +1 -0
  7. package/dist/{chunk-3BIRGSRS.js → chunk-4JD63RUR.js} +11 -11
  8. package/dist/{chunk-3BIRGSRS.js.map → chunk-4JD63RUR.js.map} +1 -1
  9. package/dist/{chunk-6GRLZ4Z2.js → chunk-643KXZ54.js} +8 -8
  10. package/dist/{chunk-6GRLZ4Z2.js.map → chunk-643KXZ54.js.map} +1 -1
  11. package/dist/{chunk-R2QNFXE5.js → chunk-DBOT2ELH.js} +3 -3
  12. package/dist/{chunk-R2QNFXE5.js.map → chunk-DBOT2ELH.js.map} +1 -1
  13. package/dist/{chunk-6UK6QPTR.js → chunk-EETK7S43.js} +137 -34
  14. package/dist/chunk-EETK7S43.js.map +1 -0
  15. package/dist/{chunk-JRAGO6OB.js → chunk-EVWW3BPM.js} +4 -4
  16. package/dist/{chunk-JRAGO6OB.js.map → chunk-EVWW3BPM.js.map} +1 -1
  17. package/dist/chunk-G4HTI4ZM.js +1537 -0
  18. package/dist/chunk-G4HTI4ZM.js.map +1 -0
  19. package/dist/chunk-IPICO2RV.js +789 -0
  20. package/dist/chunk-IPICO2RV.js.map +1 -0
  21. package/dist/{chunk-VI4ITXHQ.js → chunk-NH5NJ3UO.js} +7 -6
  22. package/dist/chunk-NH5NJ3UO.js.map +1 -0
  23. package/dist/{chunk-6UQMXIAG.js → chunk-OWSFZQOP.js} +62 -12
  24. package/dist/chunk-OWSFZQOP.js.map +1 -0
  25. package/dist/{chunk-WH2N22S3.js → chunk-PRGCCW7D.js} +4 -4
  26. package/dist/{chunk-WH2N22S3.js.map → chunk-PRGCCW7D.js.map} +1 -1
  27. package/dist/chunk-RCP2KQGG.js +3059 -0
  28. package/dist/chunk-RCP2KQGG.js.map +1 -0
  29. package/dist/{chunk-OSD546W7.js → chunk-REIGWTTH.js} +5 -3
  30. package/dist/chunk-REIGWTTH.js.map +1 -0
  31. package/dist/{chunk-B3YUO3NW.js → chunk-RYNAK4LK.js} +3 -3
  32. package/dist/{chunk-B3YUO3NW.js.map → chunk-RYNAK4LK.js.map} +1 -1
  33. package/dist/{chunk-YF43FOPP.js → chunk-RZEXHDCF.js} +33 -14
  34. package/dist/chunk-RZEXHDCF.js.map +1 -0
  35. package/dist/{chunk-VYGEOOLY.js → chunk-SGI5ZP2Y.js} +3 -3
  36. package/dist/{chunk-VYGEOOLY.js.map → chunk-SGI5ZP2Y.js.map} +1 -1
  37. package/dist/{chunk-HK3AWUXH.js → chunk-TCJTQGAO.js} +3 -3
  38. package/dist/{chunk-HK3AWUXH.js.map → chunk-TCJTQGAO.js.map} +1 -1
  39. package/dist/{chunk-ZBTY6VV4.js → chunk-US2DAKCM.js} +15 -5
  40. package/dist/chunk-US2DAKCM.js.map +1 -0
  41. package/dist/{chunk-ON25BX6T.js → chunk-UTNNGKKX.js} +3 -3
  42. package/dist/{chunk-ON25BX6T.js.map → chunk-UTNNGKKX.js.map} +1 -1
  43. package/dist/chunk-VBVY733D.js +2184 -0
  44. package/dist/chunk-VBVY733D.js.map +1 -0
  45. package/dist/{chunk-SZSNPXSW.js → chunk-WHJMS7XC.js} +3 -3
  46. package/dist/{chunk-SZSNPXSW.js.map → chunk-WHJMS7XC.js.map} +1 -1
  47. package/dist/chunk-Z6ZWNWWR.js +30 -0
  48. package/dist/{chunk-DGUM43GV.js.map → chunk-Z6ZWNWWR.js.map} +1 -1
  49. package/dist/cli.js +192 -90
  50. package/dist/cli.js.map +1 -1
  51. package/dist/{execution-env-ZU45JZ4G.js → execution-env-4MS5AYAN.js} +3 -3
  52. package/dist/{execution-env-ZU45JZ4G.js.map → execution-env-4MS5AYAN.js.map} +1 -1
  53. package/dist/{federation-SZWZIFZ7.js → federation-MDQPO3PW.js} +3 -3
  54. package/dist/{federation-SZWZIFZ7.js.map → federation-MDQPO3PW.js.map} +1 -1
  55. package/dist/{fs-O5IQYXHO.js → fs-4G5A65KS.js} +3 -3
  56. package/dist/fs-4G5A65KS.js.map +1 -0
  57. package/dist/{fs-B5HZ2MIU.js → fs-6JKZNQ3U.js} +3 -3
  58. package/dist/fs-6JKZNQ3U.js.map +1 -0
  59. package/dist/{git-ref-XDXB6JP5.js → git-ref-RSRAN4OH.js} +3 -3
  60. package/dist/{git-ref-XDXB6JP5.js.map → git-ref-RSRAN4OH.js.map} +1 -1
  61. package/dist/{graph-backend-UTOL3SHE.js → graph-backend-GBL33GMW.js} +5 -5
  62. package/dist/{graph-backend-UTOL3SHE.js.map → graph-backend-GBL33GMW.js.map} +1 -1
  63. package/dist/index.d.ts +3 -2
  64. package/dist/index.js +12 -10
  65. package/dist/index.js.map +1 -1
  66. package/dist/{interactive-OCWQ326U.js → interactive-KVDKRKNK.js} +45 -24
  67. package/dist/interactive-KVDKRKNK.js.map +1 -0
  68. package/dist/{llm-host-XYBT4267.js → llm-host-5RE34322.js} +3 -3
  69. package/dist/{llm-host-XYBT4267.js.map → llm-host-5RE34322.js.map} +1 -1
  70. package/dist/load-SEFJA3M5.js +8 -0
  71. package/dist/{load-QPOWQD7C.js.map → load-SEFJA3M5.js.map} +1 -1
  72. package/dist/local-runtime-2ED33KK6.js +6 -0
  73. package/dist/{local-runtime-5O2NN3GA.js.map → local-runtime-2ED33KK6.js.map} +1 -1
  74. package/dist/mcp-tools-KAJS34TN.js +4 -0
  75. package/dist/{mcp-tools-I7JK3S2M.js.map → mcp-tools-KAJS34TN.js.map} +1 -1
  76. package/dist/{model-execution-profile-TFBKCNJG.js → model-execution-profile-ELWF3Z6H.js} +3 -3
  77. package/dist/{model-execution-profile-TFBKCNJG.js.map → model-execution-profile-ELWF3Z6H.js.map} +1 -1
  78. package/dist/model-manager-GJ2YSTSK.js +10 -0
  79. package/dist/{model-manager-LB54VSV7.js.map → model-manager-GJ2YSTSK.js.map} +1 -1
  80. package/dist/{model-orchestrator-4M5FG6MN.js → model-orchestrator-LHYPJBFH.js} +3 -3
  81. package/dist/{model-orchestrator-4M5FG6MN.js.map → model-orchestrator-LHYPJBFH.js.map} +1 -1
  82. package/dist/parse-worker.js +2 -2
  83. package/dist/{paths-2RAH3GME.js → paths-62AKTFSR.js} +3 -3
  84. package/dist/{paths-2RAH3GME.js.map → paths-62AKTFSR.js.map} +1 -1
  85. package/dist/{resolve-gguf-4AFRN4CP.js → resolve-gguf-SDIYGGI6.js} +3 -3
  86. package/dist/{resolve-gguf-4AFRN4CP.js.map → resolve-gguf-SDIYGGI6.js.map} +1 -1
  87. package/dist/{runtime-session-EJQZXANB.js → runtime-session-4IACVDSY.js} +7 -7
  88. package/dist/{runtime-session-EJQZXANB.js.map → runtime-session-4IACVDSY.js.map} +1 -1
  89. package/dist/session-2JT4AUZT.js +13 -0
  90. package/dist/{session-ZJGENHKX.js.map → session-2JT4AUZT.js.map} +1 -1
  91. package/dist/session-store-O4XPXKOV.js +4 -0
  92. package/dist/{session-store-WFBX7HXL.js.map → session-store-O4XPXKOV.js.map} +1 -1
  93. package/dist/{sql-extract-JELDZA6W.js → sql-extract-6UJOLJDL.js} +3 -3
  94. package/dist/{sql-extract-JELDZA6W.js.map → sql-extract-6UJOLJDL.js.map} +1 -1
  95. package/dist/stream-json-Y45JBNYP.js +112 -0
  96. package/dist/stream-json-Y45JBNYP.js.map +1 -0
  97. package/dist/ui-K7D3BCHD.js +5 -0
  98. package/dist/ui-K7D3BCHD.js.map +1 -0
  99. package/dist/vg-mcp-bridge-B35WCSAS.js +75 -0
  100. package/dist/vg-mcp-bridge-B35WCSAS.js.map +1 -0
  101. package/dist/{vgd-3MHSB4KA.js → vgd-KDQFS33M.js} +6 -6
  102. package/dist/vgd-KDQFS33M.js.map +1 -0
  103. package/package.json +1 -1
  104. package/dist/baseline-PPZJBYAJ.js +0 -8
  105. package/dist/chunk-57QU36P6.js +0 -5645
  106. package/dist/chunk-57QU36P6.js.map +0 -1
  107. package/dist/chunk-6AXHLQBV.js +0 -1892
  108. package/dist/chunk-6AXHLQBV.js.map +0 -1
  109. package/dist/chunk-6UK6QPTR.js.map +0 -1
  110. package/dist/chunk-6UQMXIAG.js.map +0 -1
  111. package/dist/chunk-A2IYFNCQ.js.map +0 -1
  112. package/dist/chunk-DGUM43GV.js +0 -10
  113. package/dist/chunk-OSD546W7.js.map +0 -1
  114. package/dist/chunk-UZJS7GMK.js.map +0 -1
  115. package/dist/chunk-VI4ITXHQ.js.map +0 -1
  116. package/dist/chunk-YF43FOPP.js.map +0 -1
  117. package/dist/chunk-ZBTY6VV4.js.map +0 -1
  118. package/dist/fs-B5HZ2MIU.js.map +0 -1
  119. package/dist/fs-O5IQYXHO.js.map +0 -1
  120. package/dist/interactive-OCWQ326U.js.map +0 -1
  121. package/dist/load-QPOWQD7C.js +0 -8
  122. package/dist/local-runtime-5O2NN3GA.js +0 -5
  123. package/dist/mcp-tools-I7JK3S2M.js +0 -4
  124. package/dist/model-manager-LB54VSV7.js +0 -10
  125. package/dist/session-ZJGENHKX.js +0 -13
  126. package/dist/session-store-WFBX7HXL.js +0 -4
  127. package/dist/stream-json-Z5KC2DM3.js +0 -78
  128. package/dist/stream-json-Z5KC2DM3.js.map +0 -1
  129. package/dist/ui-Q6DJ3GCU.js +0 -5
  130. package/dist/ui-Q6DJ3GCU.js.map +0 -1
  131. package/dist/vgd-3MHSB4KA.js.map +0 -1
@@ -1,1892 +0,0 @@
1
- import { stableStringify } from './chunk-ZKNB4YH4.js';
2
- import { shortId, canonicalize, hashString } from './chunk-JFGYT6BI.js';
3
- import * as fs4 from 'fs';
4
- import * as path4 from 'path';
5
- import * as os from 'os';
6
- import { execFileSync } from 'child_process';
7
-
8
- var JS_TS_EXT = [".ts", ".tsx", ".mts", ".cts", ".js", ".jsx", ".mjs", ".cjs", ".vue", ".svelte", ".astro"];
9
- var OTHER_EXT = [
10
- ".py",
11
- ".pyi",
12
- ".go",
13
- ".rs",
14
- ".rb",
15
- ".java",
16
- ".cs",
17
- ".php",
18
- ".kt",
19
- ".kts",
20
- ".swift",
21
- ".scala",
22
- ".sc",
23
- ".dart",
24
- ".lua",
25
- ".ex",
26
- ".exs",
27
- ".sh",
28
- ".bash",
29
- ".zig",
30
- ".c",
31
- ".cpp",
32
- ".cc",
33
- ".cxx",
34
- ".hpp",
35
- ".hh",
36
- ".hxx",
37
- ".h",
38
- ".m",
39
- ".mm",
40
- ".ml",
41
- ".mli",
42
- ".res",
43
- ".sol"
44
- ];
45
- var EXT_GROUPS = {
46
- ".py": [".py", ".pyi"],
47
- ".pyi": [".py", ".pyi"],
48
- ".java": [".java"],
49
- ".cs": [".cs"],
50
- ".go": [".go"],
51
- ".rs": [".rs"],
52
- ".rb": [".rb"]
53
- };
54
- for (const e of JS_TS_EXT) EXT_GROUPS[e] = JS_TS_EXT;
55
- var CPP_EXT = [".cpp", ".cc", ".cxx", ".hpp", ".hh", ".hxx", ".h"];
56
- Object.assign(EXT_GROUPS, {
57
- ".php": [".php"],
58
- ".kt": [".kt", ".kts"],
59
- ".kts": [".kt", ".kts"],
60
- ".swift": [".swift"],
61
- ".scala": [".scala", ".sc"],
62
- ".sc": [".scala", ".sc"],
63
- ".dart": [".dart"],
64
- ".lua": [".lua"],
65
- ".ex": [".ex", ".exs"],
66
- ".exs": [".ex", ".exs"],
67
- ".sh": [".sh", ".bash"],
68
- ".bash": [".sh", ".bash"],
69
- ".zig": [".zig"],
70
- ".c": [".c", ".h"],
71
- ".cpp": CPP_EXT,
72
- ".cc": CPP_EXT,
73
- ".cxx": CPP_EXT,
74
- ".hpp": CPP_EXT,
75
- ".hh": CPP_EXT,
76
- ".hxx": CPP_EXT,
77
- ".h": [...CPP_EXT, ".c"],
78
- // ObjC #imports headers; ObjC++ additionally reaches C++ headers.
79
- ".m": [".h", ".m", ".mm"],
80
- ".mm": [".h", ".m", ".mm", ...CPP_EXT],
81
- ".ml": [".ml", ".mli"],
82
- ".mli": [".ml", ".mli"],
83
- ".res": [".res"],
84
- ".sol": [".sol"],
85
- // Template containers: ERB fragments are Ruby; HTML/EJS script is JS.
86
- ".erb": [".rb", ".erb"],
87
- ".html": JS_TS_EXT,
88
- ".htm": JS_TS_EXT,
89
- ".ejs": JS_TS_EXT
90
- });
91
- function buildModuleResolver(root, relSet) {
92
- const probe = makeProbe(relSet);
93
- const suffixIndex = buildSuffixIndex(relSet);
94
- const tsPaths = loadTsconfigPaths(root);
95
- const workspaces = loadWorkspacePackages(root);
96
- function resolveAlias(source) {
97
- if (!tsPaths) return null;
98
- for (const [pattern, targets] of tsPaths.paths) {
99
- const m = matchPattern(pattern, source);
100
- if (m === null) continue;
101
- for (const target of targets) {
102
- const sub = target.replace("*", m);
103
- const rel = posixJoin(tsPaths.baseUrlRel, sub);
104
- const hit = probe(rel);
105
- if (hit) return hit;
106
- }
107
- }
108
- return null;
109
- }
110
- function resolveWorkspace(source) {
111
- if (!workspaces.size) return null;
112
- let best = null;
113
- for (const [name, dirRel] of workspaces) {
114
- if (source === name || source.startsWith(`${name}/`)) {
115
- const rest = source === name ? "" : source.slice(name.length + 1);
116
- if (!best || name.length > best.dirRel.length) best = { dirRel, rest };
117
- }
118
- }
119
- if (!best) return null;
120
- const base = best.rest ? posixJoin(best.dirRel, best.rest) : best.dirRel;
121
- return probe(base) ?? probe(posixJoin(base, "src/index")) ?? probe(posixJoin(base, "index"));
122
- }
123
- return {
124
- resolve(fromRel, source) {
125
- if (source.includes("\\")) source = source.split("\\").join(".");
126
- if (source.startsWith("./") || source.startsWith("../")) {
127
- return probe(posixJoin(path4.posix.dirname(fromRel), source));
128
- }
129
- if (/\.[A-Za-z0-9]+$/.test(source) && !source.startsWith("<")) {
130
- const hit = probe(posixJoin(path4.posix.dirname(fromRel), source));
131
- if (hit) return hit;
132
- }
133
- if (source.startsWith(".")) {
134
- return resolvePyRelative(probe, fromRel, source);
135
- }
136
- return resolveAlias(source) ?? resolveWorkspace(source) ?? resolveSuffix(suffixIndex, fromRel, source) ?? resolveDotted(probe, source);
137
- }
138
- };
139
- }
140
- function buildSuffixIndex(relSet) {
141
- const byLast = /* @__PURE__ */ new Map();
142
- for (const rel of relSet) {
143
- const dot = rel.lastIndexOf(".");
144
- if (dot < 0) continue;
145
- const ext = rel.slice(dot);
146
- if (!EXT_GROUPS[ext]) continue;
147
- let key = rel.slice(0, dot);
148
- const base = key.slice(key.lastIndexOf("/") + 1);
149
- if (base === "__init__" || base === "index") {
150
- key = key.slice(0, Math.max(0, key.length - base.length - 1));
151
- }
152
- if (!key) continue;
153
- const last = key.slice(key.lastIndexOf("/") + 1);
154
- const list = byLast.get(last);
155
- if (list) list.push({ rel, key, ext });
156
- else byLast.set(last, [{ rel, key, ext }]);
157
- }
158
- return byLast;
159
- }
160
- function resolveSuffix(index, fromRel, source) {
161
- if (!/^[A-Za-z_][\w.]*$/.test(source) || !source.includes(".")) return null;
162
- const fromDot = fromRel.lastIndexOf(".");
163
- const fromExt = fromDot >= 0 ? fromRel.slice(fromDot) : "";
164
- const allowed = EXT_GROUPS[fromExt];
165
- if (!allowed) return null;
166
- const q = source.replace(/\./g, "/");
167
- const last = q.slice(q.lastIndexOf("/") + 1);
168
- const cands = index.get(last);
169
- if (!cands) return null;
170
- const matches = cands.filter(
171
- (c) => allowed.includes(c.ext) && (c.key === q || c.key.endsWith("/" + q))
172
- );
173
- if (matches.length === 0) return null;
174
- if (matches.length === 1) return matches[0].rel;
175
- return pickClosest(matches, fromRel).rel;
176
- }
177
- function pickClosest(matches, fromRel) {
178
- const fromSegs = fromRel.split("/");
179
- const score = (rel) => {
180
- const segs = rel.split("/");
181
- let i = 0;
182
- while (i < segs.length && i < fromSegs.length && segs[i] === fromSegs[i]) i++;
183
- return i;
184
- };
185
- return [...matches].sort((a, b) => {
186
- const d = score(b.rel) - score(a.rel);
187
- if (d) return d;
188
- if (a.rel.length !== b.rel.length) return a.rel.length - b.rel.length;
189
- return a.rel < b.rel ? -1 : 1;
190
- })[0];
191
- }
192
- function resolveDotted(probe, source) {
193
- if (!/^[A-Za-z_][\w.]*$/.test(source) || !source.includes(".")) return null;
194
- const slashed = source.replace(/\./g, "/");
195
- return probe(slashed) ?? probe(posixJoin("src", slashed));
196
- }
197
- function resolvePyRelative(probe, fromRel, source) {
198
- let dots = 0;
199
- while (source[dots] === ".") dots++;
200
- const rest = source.slice(dots);
201
- let dir = path4.posix.dirname(fromRel);
202
- for (let i = 1; i < dots; i++) dir = path4.posix.dirname(dir);
203
- const sub = rest.replace(/\./g, "/");
204
- return probe(sub ? posixJoin(dir, sub) : dir);
205
- }
206
- function relativeResolver(relSet) {
207
- const probe = makeProbe(relSet);
208
- return {
209
- resolve(fromRel, source) {
210
- if (source.startsWith(".")) return probe(posixJoin(path4.posix.dirname(fromRel), source));
211
- return resolveDotted(probe, source);
212
- }
213
- };
214
- }
215
- function makeProbe(relSet) {
216
- return (base) => {
217
- const norm = normalizeRel(base);
218
- if (!norm) return null;
219
- if (relSet.has(norm)) return norm;
220
- for (const ext of JS_TS_EXT) if (relSet.has(norm + ext)) return norm + ext;
221
- for (const ext of JS_TS_EXT) if (relSet.has(`${norm}/index${ext}`)) return `${norm}/index${ext}`;
222
- for (const ext of OTHER_EXT) if (relSet.has(norm + ext)) return norm + ext;
223
- if (relSet.has(`${norm}/__init__.py`)) return `${norm}/__init__.py`;
224
- return null;
225
- };
226
- }
227
- function normalizeRel(p) {
228
- const norm = path4.posix.normalize(p);
229
- const stripped = norm.startsWith("./") ? norm.slice(2) : norm;
230
- return stripped.startsWith("..") ? "" : stripped;
231
- }
232
- function posixJoin(a, b) {
233
- return path4.posix.normalize(path4.posix.join(a, b));
234
- }
235
- function matchPattern(pattern, source) {
236
- const star = pattern.indexOf("*");
237
- if (star === -1) return source === pattern ? "" : null;
238
- const prefix = pattern.slice(0, star);
239
- const suffix = pattern.slice(star + 1);
240
- if (!source.startsWith(prefix) || !source.endsWith(suffix)) return null;
241
- if (source.length < prefix.length + suffix.length) return null;
242
- return source.slice(prefix.length, source.length - suffix.length);
243
- }
244
- function loadTsconfigPaths(root) {
245
- for (const name of ["tsconfig.base.json", "tsconfig.json"]) {
246
- const file = path4.join(root, name);
247
- if (fs4.existsSync(file)) {
248
- const merged = readTsconfigChain(root, file, /* @__PURE__ */ new Set());
249
- if (merged && merged.paths.length) return merged;
250
- }
251
- }
252
- return null;
253
- }
254
- function readTsconfigChain(root, file, seen) {
255
- if (seen.has(file) || seen.size > 6) return null;
256
- seen.add(file);
257
- let cfg;
258
- try {
259
- cfg = parseJsonc(fs4.readFileSync(file, "utf8"));
260
- } catch {
261
- return null;
262
- }
263
- const dir = path4.dirname(file);
264
- let base = { baseUrlRel: "", paths: [] };
265
- if (cfg.extends && cfg.extends.startsWith(".")) {
266
- const extPath = path4.resolve(dir, cfg.extends.endsWith(".json") ? cfg.extends : `${cfg.extends}.json`);
267
- if (fs4.existsSync(extPath)) {
268
- const inherited = readTsconfigChain(root, extPath, seen);
269
- if (inherited) base = inherited;
270
- }
271
- }
272
- const co = cfg.compilerOptions ?? {};
273
- const baseUrlRel = co.baseUrl !== void 0 ? path4.relative(root, path4.resolve(dir, co.baseUrl)).split(path4.sep).join("/") : base.baseUrlRel;
274
- const paths = [...base.paths];
275
- if (co.paths) for (const [k, v] of Object.entries(co.paths)) paths.push([k, v]);
276
- return { baseUrlRel, paths };
277
- }
278
- function loadWorkspacePackages(root) {
279
- const map = /* @__PURE__ */ new Map();
280
- const globs = [];
281
- const rootPkg = path4.join(root, "package.json");
282
- if (fs4.existsSync(rootPkg)) {
283
- try {
284
- const pkg = JSON.parse(fs4.readFileSync(rootPkg, "utf8"));
285
- const ws = Array.isArray(pkg.workspaces) ? pkg.workspaces : pkg.workspaces?.packages;
286
- if (ws) globs.push(...ws);
287
- } catch {
288
- }
289
- }
290
- const pnpmWs = path4.join(root, "pnpm-workspace.yaml");
291
- if (fs4.existsSync(pnpmWs)) {
292
- for (const line of fs4.readFileSync(pnpmWs, "utf8").split("\n")) {
293
- const m = /^\s*-\s*['"]?([^'"\n]+)['"]?\s*$/.exec(line);
294
- if (m) globs.push(m[1].trim());
295
- }
296
- }
297
- for (const dir of expandWorkspaceGlobs(root, globs)) {
298
- const pj = path4.join(dir, "package.json");
299
- try {
300
- const name = JSON.parse(fs4.readFileSync(pj, "utf8")).name;
301
- if (name) map.set(name, path4.relative(root, dir).split(path4.sep).join("/"));
302
- } catch {
303
- }
304
- }
305
- return map;
306
- }
307
- function expandWorkspaceGlobs(root, globs) {
308
- const out = /* @__PURE__ */ new Set();
309
- for (const glob of globs) {
310
- const clean = glob.replace(/\/\*\*$/, "").replace(/\/\*$/, "");
311
- const baseDir = path4.join(root, clean);
312
- const recurse = glob.endsWith("**");
313
- if (glob === clean) {
314
- if (fs4.existsSync(path4.join(baseDir, "package.json"))) out.add(baseDir);
315
- continue;
316
- }
317
- collectPackageDirs(baseDir, recurse ? 4 : 1, out);
318
- }
319
- return [...out];
320
- }
321
- function collectPackageDirs(dir, depth, out) {
322
- if (depth < 0) return;
323
- let entries;
324
- try {
325
- entries = fs4.readdirSync(dir, { withFileTypes: true });
326
- } catch {
327
- return;
328
- }
329
- for (const e of entries) {
330
- if (!e.isDirectory() || e.name === "node_modules" || e.name.startsWith(".")) continue;
331
- const child = path4.join(dir, e.name);
332
- if (fs4.existsSync(path4.join(child, "package.json"))) out.add(child);
333
- else collectPackageDirs(child, depth - 1, out);
334
- }
335
- }
336
- function parseJsonc(text) {
337
- return JSON.parse(stripJsonc(text));
338
- }
339
- function stripJsonc(text) {
340
- let out = "";
341
- let inStr = false;
342
- let strCh = "";
343
- for (let i = 0; i < text.length; i++) {
344
- const ch = text[i];
345
- const next = text[i + 1];
346
- if (inStr) {
347
- out += ch;
348
- if (ch === "\\") {
349
- out += next ?? "";
350
- i++;
351
- } else if (ch === strCh) {
352
- inStr = false;
353
- }
354
- continue;
355
- }
356
- if (ch === '"' || ch === "'") {
357
- inStr = true;
358
- strCh = ch;
359
- out += ch;
360
- continue;
361
- }
362
- if (ch === "/" && next === "/") {
363
- while (i < text.length && text[i] !== "\n") i++;
364
- out += "\n";
365
- continue;
366
- }
367
- if (ch === "/" && next === "*") {
368
- i += 2;
369
- while (i < text.length && !(text[i] === "*" && text[i + 1] === "/")) i++;
370
- i++;
371
- continue;
372
- }
373
- out += ch;
374
- }
375
- return out.replace(/,(\s*[}\]])/g, "$1");
376
- }
377
-
378
- // src/engine/ids.ts
379
- function nodeId(parts) {
380
- return shortId(
381
- canonicalize({
382
- t: "node",
383
- kind: parts.kind,
384
- qn: parts.qualifiedName,
385
- file: parts.file,
386
- sig: parts.signature ?? ""
387
- })
388
- );
389
- }
390
- function edgeId(kind, src, dst) {
391
- return shortId(canonicalize({ t: "edge", kind, src, dst }));
392
- }
393
-
394
- // src/engine/tests.ts
395
- function isTestFile(rel) {
396
- const lower = rel.toLowerCase();
397
- const base = rel.split("/").pop() ?? rel;
398
- const lbase = base.toLowerCase();
399
- if (/(^|\/)(__tests__|__test__)\//.test(lower)) return true;
400
- if (/(^|\/)(tests?|spec|specs)\//.test(lower)) return true;
401
- if (/(^|\/)src\/test\//.test(lower)) return true;
402
- if (/\.(test|spec)\.[cm]?[jt]sx?$/.test(lbase)) return true;
403
- if (/^test_.*\.py$/.test(lbase) || /_test\.py$/.test(lbase)) return true;
404
- if (/_test\.go$/.test(lbase)) return true;
405
- if (/[A-Za-z0-9](Test|Tests|IT)\.java$/.test(base)) return true;
406
- if (/_spec\.rb$/.test(lbase) || /_test\.rb$/.test(lbase)) return true;
407
- if (/[A-Za-z0-9](Test|Tests)\.cs$/.test(base)) return true;
408
- if (/[A-Za-z0-9](Test|Tests)\.swift$/.test(base)) return true;
409
- return false;
410
- }
411
- function applyStaticTestLinkage(nodes, edges) {
412
- const byId = new Map(nodes.map((n) => [n.id, n]));
413
- const testFiles = /* @__PURE__ */ new Set();
414
- for (const n of nodes) if (n.kind === "file" && isTestFile(n.file)) testFiles.add(n.file);
415
- const fileNodeIdByRel = /* @__PURE__ */ new Map();
416
- for (const n of nodes) if (n.kind === "file") fileNodeIdByRel.set(n.file, n.id);
417
- const covered = /* @__PURE__ */ new Set();
418
- const newEdges = /* @__PURE__ */ new Map();
419
- for (const e of edges) {
420
- if (e.kind !== "call") continue;
421
- const src = byId.get(e.src);
422
- const dst = byId.get(e.dst);
423
- if (!src || !dst) continue;
424
- if (testFiles.has(src.file) && !testFiles.has(dst.file) && dst.kind !== "external") {
425
- const testFileId = fileNodeIdByRel.get(src.file);
426
- if (!testFileId) continue;
427
- const id = edgeId("test", testFileId, dst.id);
428
- if (!newEdges.has(id)) {
429
- newEdges.set(id, {
430
- id,
431
- kind: "test",
432
- src: testFileId,
433
- dst: dst.id,
434
- resolution: e.resolution,
435
- confidence: e.confidence
436
- });
437
- }
438
- covered.add(dst.id);
439
- }
440
- }
441
- const outNodes = nodes.map((n) => ({ ...n, tested: testedFlag(n, covered.has(n.id), testFiles) }));
442
- const outEdges = [...edges, ...newEdges.values()].sort(
443
- (a, b) => a.kind.localeCompare(b.kind) || a.src.localeCompare(b.src) || a.dst.localeCompare(b.dst)
444
- );
445
- return {
446
- nodes: outNodes,
447
- edges: outEdges,
448
- testFiles: [...testFiles].sort(),
449
- testEdgeCount: newEdges.size
450
- };
451
- }
452
- function testedFlag(node, covered, testFiles) {
453
- if (node.kind === "external" || node.kind === "file" || node.kind === "package" || node.kind === "module") {
454
- return null;
455
- }
456
- if (testFiles.has(node.file)) return null;
457
- if (node.kind === "function" || node.kind === "method") return covered;
458
- return covered ? true : node.tested ?? null;
459
- }
460
- var ECOSYSTEMS = ["npm", "pypi", "go", "rust", "ruby", "php", "dotnet", "swift", "dart", "java"];
461
- function inventory(root) {
462
- const manifests = findManifests(root);
463
- const records = [];
464
- records.push(...npmDeps(manifests.npm));
465
- records.push(...pypiDeps(manifests.pypi));
466
- records.push(...goDeps(manifests.go));
467
- records.push(...cargoDeps(manifests.rust));
468
- records.push(...rubyDeps(manifests.ruby));
469
- records.push(...phpDeps(manifests.php));
470
- records.push(...dotnetDeps(manifests.dotnet));
471
- records.push(...swiftDeps(manifests.swift));
472
- records.push(...dartDeps(manifests.dart));
473
- records.push(...javaDeps(manifests.java));
474
- const seen = /* @__PURE__ */ new Set();
475
- const deduped = records.filter((r) => {
476
- const key = `${r.ecosystem}\0${r.name}`;
477
- if (seen.has(key)) return false;
478
- seen.add(key);
479
- return true;
480
- });
481
- deduped.sort((a, b) => a.ecosystem.localeCompare(b.ecosystem) || a.name.localeCompare(b.name));
482
- const counts = { total: deduped.length };
483
- for (const e of ECOSYSTEMS) counts[e] = 0;
484
- for (const r of deduped) counts[r.ecosystem]++;
485
- return { records: deduped, counts };
486
- }
487
- var SKIP_DIRS = /* @__PURE__ */ new Set([
488
- "node_modules",
489
- ".git",
490
- "dist",
491
- "build",
492
- "out",
493
- ".vibgrate",
494
- "vendor",
495
- ".venv",
496
- "venv",
497
- "env",
498
- "__pycache__",
499
- "target",
500
- ".next",
501
- ".nuxt",
502
- "coverage",
503
- ".cache"
504
- ]);
505
- var MANIFEST_BY_FILE = {
506
- "package.json": "npm",
507
- "requirements.txt": "pypi",
508
- "pyproject.toml": "pypi",
509
- "go.mod": "go",
510
- "Cargo.toml": "rust",
511
- Gemfile: "ruby",
512
- "composer.json": "php",
513
- "Package.swift": "swift",
514
- "pubspec.yaml": "dart",
515
- "pom.xml": "java",
516
- "build.gradle": "java",
517
- "build.gradle.kts": "java"
518
- };
519
- function findManifests(root) {
520
- const set = Object.fromEntries(ECOSYSTEMS.map((e) => [e, []]));
521
- const MAX_ENTRIES = 2e4;
522
- let scanned = 0;
523
- const walk = (dir, depth) => {
524
- if (depth > 8 || scanned > MAX_ENTRIES) return;
525
- let entries;
526
- try {
527
- entries = fs4.readdirSync(dir, { withFileTypes: true });
528
- } catch {
529
- return;
530
- }
531
- for (const e of entries) {
532
- scanned++;
533
- if (scanned > MAX_ENTRIES) break;
534
- if (e.isDirectory()) {
535
- if (!SKIP_DIRS.has(e.name) && !e.name.startsWith(".")) walk(path4.join(dir, e.name), depth + 1);
536
- continue;
537
- }
538
- const eco = MANIFEST_BY_FILE[e.name] ?? (/\.(cs|fs)proj$/i.test(e.name) ? "dotnet" : void 0);
539
- if (eco) set[eco].push(path4.join(dir, e.name));
540
- }
541
- };
542
- walk(root, 0);
543
- for (const e of ECOSYSTEMS) set[e].sort();
544
- return set;
545
- }
546
- function npmDeps(files) {
547
- const out = [];
548
- for (const file of files) {
549
- let pkg;
550
- try {
551
- pkg = JSON.parse(fs4.readFileSync(file, "utf8"));
552
- } catch {
553
- continue;
554
- }
555
- const dir = path4.dirname(file);
556
- const all = { ...pkg.dependencies, ...pkg.devDependencies };
557
- for (const [name, declared] of Object.entries(all)) {
558
- out.push({ name, ecosystem: "npm", declared, installed: installedNpmVersion(dir, name) });
559
- }
560
- }
561
- return out;
562
- }
563
- function installedNpmVersion(dir, name) {
564
- let cur = dir;
565
- for (let i = 0; i < 12; i++) {
566
- const p = path4.join(cur, "node_modules", name, "package.json");
567
- try {
568
- return JSON.parse(fs4.readFileSync(p, "utf8")).version;
569
- } catch {
570
- }
571
- const parent = path4.dirname(cur);
572
- if (parent === cur) break;
573
- cur = parent;
574
- }
575
- return void 0;
576
- }
577
- function installedTreeVersion(root, ecosystem, name) {
578
- if (ecosystem === "pypi") return installedPypiVersion(root, name);
579
- if (ecosystem === "php") return installedPhpVersion(root, name);
580
- return void 0;
581
- }
582
- function normalizePep503(name) {
583
- return name.trim().toLowerCase().replace(/[-_.]+/g, "-");
584
- }
585
- function sitePackagesDirs(base) {
586
- const out = [];
587
- try {
588
- for (const d of fs4.readdirSync(path4.join(base, "lib"))) {
589
- if (d.startsWith("python")) out.push(path4.join(base, "lib", d, "site-packages"));
590
- }
591
- } catch {
592
- }
593
- out.push(path4.join(base, "Lib", "site-packages"));
594
- return out;
595
- }
596
- function installedPypiVersion(root, name) {
597
- const target = normalizePep503(name);
598
- for (const venv of [".venv", "venv", "env", ".tox"]) {
599
- for (const sp of sitePackagesDirs(path4.join(root, venv))) {
600
- let entries;
601
- try {
602
- entries = fs4.readdirSync(sp);
603
- } catch {
604
- continue;
605
- }
606
- for (const entry of entries) {
607
- const m = /^(.+?)-(\d[^-]*)\.dist-info$/.exec(entry);
608
- if (m && normalizePep503(m[1]) === target) return m[2];
609
- }
610
- }
611
- }
612
- return void 0;
613
- }
614
- function installedPhpVersion(root, name) {
615
- let data;
616
- try {
617
- data = JSON.parse(fs4.readFileSync(path4.join(root, "vendor", "composer", "installed.json"), "utf8"));
618
- } catch {
619
- return void 0;
620
- }
621
- const pkgs = Array.isArray(data) ? data : data.packages;
622
- if (!Array.isArray(pkgs)) return void 0;
623
- const p = pkgs.find((x) => x && typeof x === "object" && x.name === name);
624
- return typeof p?.version === "string" ? p.version.replace(/^v/, "") : void 0;
625
- }
626
- function pypiDeps(files) {
627
- const byName = /* @__PURE__ */ new Map();
628
- const add = (name, declared) => {
629
- const clean = name.trim().replace(/\[.*\]$/, "");
630
- if (!clean || clean.toLowerCase() === "python") return;
631
- if (!byName.has(clean)) byName.set(clean, { name: clean, ecosystem: "pypi", declared: declared.trim() || "*" });
632
- };
633
- for (const file of files) {
634
- let text;
635
- try {
636
- text = fs4.readFileSync(file, "utf8");
637
- } catch {
638
- continue;
639
- }
640
- if (path4.basename(file) === "requirements.txt") {
641
- for (const line of text.split("\n")) {
642
- const t = line.trim();
643
- if (!t || t.startsWith("#") || t.startsWith("-")) continue;
644
- const m = /^([A-Za-z0-9._-]+(?:\[[^\]]*\])?)\s*([<>=!~).*]+.*)?$/.exec(t);
645
- if (m) add(m[1], m[2] ?? "*");
646
- }
647
- } else {
648
- for (const dep of pep621Dependencies(text)) {
649
- const m = /^([A-Za-z0-9._-]+(?:\[[^\]]*\])?)\s*(.*)$/.exec(dep.trim());
650
- if (m) add(m[1], m[2] ?? "*");
651
- }
652
- for (const [name, spec] of poetryDependencies(text)) add(name, spec);
653
- }
654
- }
655
- return [...byName.values()];
656
- }
657
- function pep621Dependencies(text) {
658
- const section = sectionBody(text, "project");
659
- if (!section) return [];
660
- const start = /dependencies\s*=\s*\[/.exec(section);
661
- if (!start) return [];
662
- let depth = 0;
663
- let inStr = false;
664
- let strCh = "";
665
- const out = [];
666
- let cur = "";
667
- for (let i = start.index + start[0].length - 1; i < section.length; i++) {
668
- const ch = section[i];
669
- if (inStr) {
670
- if (ch === strCh) {
671
- out.push(cur);
672
- inStr = false;
673
- } else cur += ch;
674
- continue;
675
- }
676
- if (ch === '"' || ch === "'") {
677
- inStr = true;
678
- strCh = ch;
679
- cur = "";
680
- } else if (ch === "[") depth++;
681
- else if (ch === "]") {
682
- depth--;
683
- if (depth === 0) break;
684
- }
685
- }
686
- return out;
687
- }
688
- function poetryDependencies(text) {
689
- const out = [];
690
- const lines = text.split("\n");
691
- let inDeps = false;
692
- for (const raw of lines) {
693
- const line = raw.trim();
694
- if (line.startsWith("[")) {
695
- inDeps = /^\[tool\.poetry(\.group\.[^.\]]+)?\.dependencies\]$/.test(line);
696
- continue;
697
- }
698
- if (!inDeps || !line || line.startsWith("#")) continue;
699
- const m = /^([A-Za-z0-9._-]+)\s*=\s*["']([^"']*)["']/.exec(line);
700
- if (m) out.push([m[1], m[2] || "*"]);
701
- }
702
- return out;
703
- }
704
- function sectionBody(text, name) {
705
- const lines = text.split("\n");
706
- let capturing = false;
707
- const body = [];
708
- for (const raw of lines) {
709
- const line = raw.trim();
710
- if (/^\[/.test(line)) {
711
- if (capturing) break;
712
- capturing = line === `[${name}]`;
713
- continue;
714
- }
715
- if (capturing) body.push(raw);
716
- }
717
- return capturing || body.length ? body.join("\n") : null;
718
- }
719
- function goDeps(files) {
720
- const out = [];
721
- for (const mod of files) {
722
- let text;
723
- try {
724
- text = fs4.readFileSync(mod, "utf8");
725
- } catch {
726
- continue;
727
- }
728
- const re = /^\s*(?:require\s+)?([\w./-]+)\s+v(\S+)/gm;
729
- let m;
730
- while (m = re.exec(text)) {
731
- if (m[1] === "go" || m[1] === "require" || m[1].startsWith("module")) continue;
732
- out.push({ name: m[1], ecosystem: "go", declared: `v${m[2]}` });
733
- }
734
- }
735
- return out;
736
- }
737
- function cargoDeps(files) {
738
- const out = [];
739
- for (const file of files) {
740
- let text;
741
- try {
742
- text = fs4.readFileSync(file, "utf8");
743
- } catch {
744
- continue;
745
- }
746
- for (const table of ["dependencies", "dev-dependencies", "build-dependencies"]) {
747
- const body = sectionBody(text, table);
748
- if (!body) continue;
749
- for (const raw of body.split("\n")) {
750
- const line = raw.trim();
751
- if (!line || line.startsWith("#")) continue;
752
- const m = /^([A-Za-z0-9._-]+)\s*=\s*(.+)$/.exec(line);
753
- if (!m) continue;
754
- const rhs = m[2].trim();
755
- let declared = "*";
756
- if (rhs.startsWith('"')) {
757
- const sm = /^"([^"]+)"/.exec(rhs);
758
- if (sm) declared = sm[1];
759
- } else if (rhs.startsWith("{")) {
760
- const vm = /version\s*=\s*"([^"]+)"/.exec(rhs);
761
- if (vm) declared = vm[1];
762
- }
763
- out.push({ name: m[1], ecosystem: "rust", declared });
764
- }
765
- }
766
- }
767
- return out;
768
- }
769
- function rubyDeps(files) {
770
- const out = [];
771
- for (const file of files) {
772
- let text;
773
- try {
774
- text = fs4.readFileSync(file, "utf8");
775
- } catch {
776
- continue;
777
- }
778
- const re = /^\s*gem\s+["']([^"']+)["']\s*(?:,\s*["']([^"']+)["'])?/gm;
779
- let m;
780
- while (m = re.exec(text)) out.push({ name: m[1], ecosystem: "ruby", declared: m[2] ?? "*" });
781
- }
782
- return out;
783
- }
784
- function phpDeps(files) {
785
- const out = [];
786
- for (const file of files) {
787
- let pkg;
788
- try {
789
- pkg = JSON.parse(fs4.readFileSync(file, "utf8"));
790
- } catch {
791
- continue;
792
- }
793
- const all = { ...pkg.require, ...pkg["require-dev"] };
794
- for (const [name, declared] of Object.entries(all)) {
795
- if (!name.includes("/")) continue;
796
- out.push({ name, ecosystem: "php", declared });
797
- }
798
- }
799
- return out;
800
- }
801
- function dotnetDeps(files) {
802
- const out = [];
803
- for (const file of files) {
804
- let text;
805
- try {
806
- text = fs4.readFileSync(file, "utf8");
807
- } catch {
808
- continue;
809
- }
810
- const tagRe = /<PackageReference\b[^>]*>/gi;
811
- let m;
812
- while (m = tagRe.exec(text)) {
813
- const inc = /Include\s*=\s*"([^"]+)"/i.exec(m[0]);
814
- if (!inc) continue;
815
- const ver = /Version\s*=\s*"([^"]+)"/i.exec(m[0]);
816
- out.push({ name: inc[1], ecosystem: "dotnet", declared: ver?.[1] ?? "*" });
817
- }
818
- }
819
- return out;
820
- }
821
- function swiftDeps(files) {
822
- const out = [];
823
- for (const file of files) {
824
- let text;
825
- try {
826
- text = fs4.readFileSync(file, "utf8");
827
- } catch {
828
- continue;
829
- }
830
- const re = /\.package\(/g;
831
- let m;
832
- while (m = re.exec(text)) {
833
- const win = text.slice(m.index, m.index + 200);
834
- const urlM = /url:\s*"([^"]+)"/.exec(win);
835
- if (!urlM) continue;
836
- const name = (urlM[1].replace(/\.git$/, "").split("/").filter(Boolean).pop() ?? urlM[1]).toLowerCase();
837
- const verM = /"(\d+\.\d+(?:\.\d+)?)"/.exec(win.slice(urlM.index + urlM[0].length));
838
- out.push({ name, ecosystem: "swift", declared: verM?.[1] ?? "*" });
839
- }
840
- }
841
- return out;
842
- }
843
- function dartDeps(files) {
844
- const out = [];
845
- for (const file of files) {
846
- let text;
847
- try {
848
- text = fs4.readFileSync(file, "utf8");
849
- } catch {
850
- continue;
851
- }
852
- let section = "";
853
- for (const raw of text.split("\n")) {
854
- const top = /^([a-z_]+):\s*$/.exec(raw);
855
- if (top) {
856
- section = top[1];
857
- continue;
858
- }
859
- if (section !== "dependencies" && section !== "dev_dependencies") continue;
860
- const m = /^ ([A-Za-z0-9_.]+):\s*(\S.*)?$/.exec(raw);
861
- if (!m || m[1] === "flutter" || m[1] === "sdk") continue;
862
- const declared = (m[2] ?? "").replace(/^["']|["']$/g, "").trim() || "*";
863
- out.push({ name: m[1], ecosystem: "dart", declared });
864
- }
865
- }
866
- return out;
867
- }
868
- function javaDeps(files) {
869
- const out = [];
870
- for (const file of files) {
871
- let text;
872
- try {
873
- text = fs4.readFileSync(file, "utf8");
874
- } catch {
875
- continue;
876
- }
877
- if (path4.basename(file) === "pom.xml") {
878
- for (const block of text.match(/<dependency>[\s\S]*?<\/dependency>/g) ?? []) {
879
- const g = /<groupId>([^<]+)<\/groupId>/.exec(block);
880
- const a = /<artifactId>([^<]+)<\/artifactId>/.exec(block);
881
- if (!g || !a) continue;
882
- const v = /<version>([^<]+)<\/version>/.exec(block);
883
- const declared = v ? v[1].trim().startsWith("${") ? "*" : v[1].trim() : "*";
884
- out.push({ name: `${g[1].trim()}:${a[1].trim()}`, ecosystem: "java", declared });
885
- }
886
- } else {
887
- const re = /(?:implementation|api|compileOnly|runtimeOnly|testImplementation|testRuntimeOnly|annotationProcessor)\s*[(]?\s*["']([\w.-]+):([\w.-]+):([^"']+)["']/g;
888
- let m;
889
- while (m = re.exec(text)) out.push({ name: `${m[1]}:${m[2]}`, ecosystem: "java", declared: m[3] });
890
- }
891
- }
892
- return out;
893
- }
894
- async function enrichOnline(records, fetchImpl = globalThis.fetch) {
895
- for (const r of records) {
896
- if (r.ecosystem !== "npm" || !r.installed) continue;
897
- try {
898
- const res = await fetchImpl(`https://registry.npmjs.org/${encodeURIComponent(r.name)}/latest`);
899
- if (!res.ok) continue;
900
- const data = await res.json();
901
- r.latest = data.version;
902
- r.drift = classify(r.installed, r.latest);
903
- } catch {
904
- r.drift = "unknown";
905
- }
906
- }
907
- }
908
- function classify(installed, latest) {
909
- if (!latest) return "unknown";
910
- const a = installed.split(".").map(Number);
911
- const b = latest.split(".").map(Number);
912
- if (a[0] !== b[0]) return "major";
913
- if (a[1] !== b[1]) return "minor";
914
- if (a[2] !== b[2]) return "patch";
915
- return "current";
916
- }
917
- function lockfileVersion(root, ecosystem, name) {
918
- if (ecosystem === "npm") return packageLockVersion(root, name) ?? yarnLockVersion(root, name);
919
- if (ecosystem === "pypi") return pypiLockVersion(root, name);
920
- if (ecosystem === "rust") return tomlPackageLock(root, "Cargo.lock", name, rustName);
921
- if (ecosystem === "ruby") return gemfileLock(root, name);
922
- if (ecosystem === "php") return composerLock(root, name);
923
- if (ecosystem === "dotnet") return packagesLock(root, name);
924
- if (ecosystem === "swift") return packageResolved(root, name);
925
- if (ecosystem === "dart") return pubspecLock(root, name);
926
- if (ecosystem === "java") return gradleLock(root, name);
927
- return void 0;
928
- }
929
- function gradleLock(root, name) {
930
- let text;
931
- try {
932
- text = fs4.readFileSync(path4.join(root, "gradle.lockfile"), "utf8");
933
- } catch {
934
- return void 0;
935
- }
936
- const m = new RegExp(`^${escapeRegExp(name)}:([^=\\s]+)=`, "m").exec(text);
937
- return m ? m[1] : void 0;
938
- }
939
- function packageResolved(root, name) {
940
- let data;
941
- try {
942
- data = JSON.parse(fs4.readFileSync(path4.join(root, "Package.resolved"), "utf8"));
943
- } catch {
944
- return void 0;
945
- }
946
- const pins = data.pins ?? data.object?.pins;
947
- if (!Array.isArray(pins)) return void 0;
948
- const target = name.toLowerCase();
949
- for (const p of pins) {
950
- const id = (p.identity ?? p.package ?? "").toLowerCase();
951
- if (id === target && p.state?.version) return p.state.version;
952
- }
953
- return void 0;
954
- }
955
- function pubspecLock(root, name) {
956
- let text;
957
- try {
958
- text = fs4.readFileSync(path4.join(root, "pubspec.lock"), "utf8");
959
- } catch {
960
- return void 0;
961
- }
962
- let inPkg = false;
963
- for (const line of text.split("\n")) {
964
- const key = /^ ([A-Za-z0-9_.]+):\s*$/.exec(line);
965
- if (key) {
966
- inPkg = key[1] === name;
967
- continue;
968
- }
969
- if (inPkg) {
970
- const vm = /^\s+version:\s*"?([^"\s]+)"?/.exec(line);
971
- if (vm) return vm[1];
972
- }
973
- }
974
- return void 0;
975
- }
976
- function escapeRegExp(s) {
977
- return s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
978
- }
979
- function gemfileLock(root, name) {
980
- let text;
981
- try {
982
- text = fs4.readFileSync(path4.join(root, "Gemfile.lock"), "utf8");
983
- } catch {
984
- return void 0;
985
- }
986
- const m = new RegExp(`^ ${escapeRegExp(name)} \\((\\d[^)]*)\\)`, "m").exec(text);
987
- return m ? m[1] : void 0;
988
- }
989
- function composerLock(root, name) {
990
- let data;
991
- try {
992
- data = JSON.parse(fs4.readFileSync(path4.join(root, "composer.lock"), "utf8"));
993
- } catch {
994
- return void 0;
995
- }
996
- for (const section of ["packages", "packages-dev"]) {
997
- const arr = data[section];
998
- if (!Array.isArray(arr)) continue;
999
- const p = arr.find((x) => x && x.name === name);
1000
- if (p && typeof p.version === "string") return p.version.replace(/^v/, "");
1001
- }
1002
- return void 0;
1003
- }
1004
- function packagesLock(root, name) {
1005
- let data;
1006
- try {
1007
- data = JSON.parse(fs4.readFileSync(path4.join(root, "packages.lock.json"), "utf8"));
1008
- } catch {
1009
- return void 0;
1010
- }
1011
- const target = name.toLowerCase();
1012
- for (const fw of Object.values(data.dependencies ?? {})) {
1013
- if (!fw || typeof fw !== "object") continue;
1014
- for (const [id, v] of Object.entries(fw)) {
1015
- if (id.toLowerCase() === target && v && typeof v.resolved === "string") return v.resolved;
1016
- }
1017
- }
1018
- return void 0;
1019
- }
1020
- function pep503(name) {
1021
- return name.trim().toLowerCase().replace(/[-_.]+/g, "-");
1022
- }
1023
- function rustName(name) {
1024
- return name.trim().toLowerCase();
1025
- }
1026
- function pypiLockVersion(root, name) {
1027
- return tomlPackageLock(root, "poetry.lock", name, pep503) ?? tomlPackageLock(root, "uv.lock", name, pep503) ?? pipfileLock(root, name);
1028
- }
1029
- function tomlPackageLock(root, file, name, normalize) {
1030
- let text;
1031
- try {
1032
- text = fs4.readFileSync(path4.join(root, file), "utf8");
1033
- } catch {
1034
- return void 0;
1035
- }
1036
- const target = normalize(name);
1037
- for (const block of text.split(/\[\[package\]\]/)) {
1038
- const nm = /(?:^|\n)\s*name\s*=\s*"([^"]+)"/.exec(block);
1039
- if (nm && normalize(nm[1]) === target) {
1040
- const ver = /(?:^|\n)\s*version\s*=\s*"([^"]+)"/.exec(block);
1041
- if (ver) return ver[1];
1042
- }
1043
- }
1044
- return void 0;
1045
- }
1046
- function pipfileLock(root, name) {
1047
- let data;
1048
- try {
1049
- data = JSON.parse(fs4.readFileSync(path4.join(root, "Pipfile.lock"), "utf8"));
1050
- } catch {
1051
- return void 0;
1052
- }
1053
- const target = pep503(name);
1054
- for (const section of ["default", "develop"]) {
1055
- const deps = data[section];
1056
- if (!deps || typeof deps !== "object") continue;
1057
- for (const [k, v] of Object.entries(deps)) {
1058
- if (pep503(k) === target && v && typeof v.version === "string") {
1059
- return v.version.replace(/^==/, "");
1060
- }
1061
- }
1062
- }
1063
- return void 0;
1064
- }
1065
- function packageLockVersion(root, name) {
1066
- let data;
1067
- try {
1068
- data = JSON.parse(fs4.readFileSync(path4.join(root, "package-lock.json"), "utf8"));
1069
- } catch {
1070
- return void 0;
1071
- }
1072
- const top = data.packages?.[`node_modules/${name}`]?.version;
1073
- if (typeof top === "string") return top;
1074
- const v1 = data.dependencies?.[name]?.version;
1075
- return typeof v1 === "string" ? v1 : void 0;
1076
- }
1077
- function yarnLockVersion(root, name) {
1078
- let text;
1079
- try {
1080
- text = fs4.readFileSync(path4.join(root, "yarn.lock"), "utf8");
1081
- } catch {
1082
- return void 0;
1083
- }
1084
- let inBlock = false;
1085
- for (const line of text.split("\n")) {
1086
- if (line && !/^\s/.test(line) && !line.startsWith("#")) {
1087
- inBlock = headerNamesPackage(line, name);
1088
- } else if (inBlock) {
1089
- const m = /^\s+version:?\s+"?([^"\s]+)"?/.exec(line);
1090
- if (m) return m[1];
1091
- }
1092
- }
1093
- return void 0;
1094
- }
1095
- function headerNamesPackage(header, name) {
1096
- return header.replace(/:\s*$/, "").split(",").some((spec) => {
1097
- const s = spec.trim().replace(/^"|"$/g, "");
1098
- const at = s.lastIndexOf("@");
1099
- if (at <= 0) return false;
1100
- const specName = s.slice(0, at);
1101
- return specName === name;
1102
- });
1103
- }
1104
-
1105
- // src/engine/lib.ts
1106
- var LIB_SCHEMA = "vg-lib/1.0";
1107
- function catalogPath(root) {
1108
- return path4.join(root, "vibgrate.lib.json");
1109
- }
1110
- function libDir(root) {
1111
- return path4.join(root, ".vibgrate", "lib");
1112
- }
1113
- function libId(name) {
1114
- return name.trim().toLowerCase().replace(/^@/, "").replace(/[^a-z0-9]+/g, "-").replace(/(^-|-$)/g, "");
1115
- }
1116
- function loadCatalog(root) {
1117
- const file = catalogPath(root);
1118
- if (fs4.existsSync(file)) {
1119
- try {
1120
- const data = JSON.parse(fs4.readFileSync(file, "utf8"));
1121
- if (data.schemaVersion === LIB_SCHEMA && data.libraries) return data;
1122
- } catch {
1123
- }
1124
- }
1125
- return { schemaVersion: LIB_SCHEMA, libraries: {} };
1126
- }
1127
- function saveCatalog(root, catalog) {
1128
- fs4.writeFileSync(catalogPath(root), `${stableStringify(catalog, 2)}
1129
- `);
1130
- }
1131
- function resolveLib(catalog, name) {
1132
- const id = libId(name);
1133
- if (catalog.libraries[id]) return catalog.libraries[id];
1134
- const lower = name.toLowerCase();
1135
- const all = Object.values(catalog.libraries);
1136
- return all.find((e) => e.name.toLowerCase() === lower) ?? all.find((e) => e.id.includes(id) || e.name.toLowerCase().includes(lower));
1137
- }
1138
- function installedVersion(root, name) {
1139
- const rec = inventory(root).records.find((r) => r.name === name);
1140
- return rec?.installed ?? rec?.declared;
1141
- }
1142
- var stripRange = (v) => v?.replace(/^[v^~>=<\s]+/, "");
1143
- function resolveVersion(root, name) {
1144
- const rec = inventory(root).records.find((r) => r.name === name);
1145
- const declared = rec?.declared;
1146
- const installed = rec?.installed ?? (rec ? installedTreeVersion(root, rec.ecosystem, name) : void 0);
1147
- const lockfile = rec ? lockfileVersion(root, rec.ecosystem, name) : void 0;
1148
- let mismatch;
1149
- if (lockfile && installed && stripRange(lockfile) !== stripRange(installed)) {
1150
- mismatch = {
1151
- lockfile,
1152
- installed,
1153
- note: `lockfile pins ${lockfile} but the installed tree has ${installed} \u2014 your install is out of sync with the lockfile (re-install or commit the lock)`
1154
- };
1155
- }
1156
- const served = lockfile ?? installed ?? declared;
1157
- const source = lockfile ? "lockfile" : installed ? "installed" : declared ? "declared" : "unknown";
1158
- return { served, source, lockfile, installed, declared, mismatch };
1159
- }
1160
- function driftFor(root, entry) {
1161
- const installed = installedVersion(root, entry.name);
1162
- if (!installed || entry.version === "*") return { cataloged: entry.version, installed, drift: "unknown" };
1163
- const norm = (v) => v.replace(/^[v^~>=<\s]+/, "");
1164
- const a = norm(entry.version);
1165
- const b = norm(installed);
1166
- if (a === b) return { cataloged: entry.version, installed, drift: "current" };
1167
- return { cataloged: entry.version, installed, drift: cmp(a, b) < 0 ? "behind" : "ahead" };
1168
- }
1169
- function cmp(a, b) {
1170
- const pa = a.split(".").map(Number);
1171
- const pb = b.split(".").map(Number);
1172
- for (let i = 0; i < 3; i++) {
1173
- const d = (pa[i] || 0) - (pb[i] || 0);
1174
- if (d) return d;
1175
- }
1176
- return 0;
1177
- }
1178
- function parseGitSource(source) {
1179
- if (source.startsWith("git+")) return source.slice(4);
1180
- if (/^git@[^:]+:/.test(source)) return source;
1181
- if (/\.git\/?$/.test(source)) return source;
1182
- return null;
1183
- }
1184
- async function addLibrary(source, opts) {
1185
- const { root } = opts;
1186
- let content;
1187
- let type = "local";
1188
- const gitUrl = parseGitSource(source);
1189
- if (gitUrl) {
1190
- if (!opts.allowNetwork) {
1191
- throw new Error(`refusing to clone ${source} without --online (offline by default)`);
1192
- }
1193
- content = cloneAndReadGit(gitUrl);
1194
- type = "git";
1195
- } else if (/^https?:\/\//.test(source)) {
1196
- if (!opts.allowNetwork) {
1197
- throw new Error(`refusing to fetch ${source} without --online (offline by default)`);
1198
- }
1199
- const res = await (opts.fetchImpl ?? globalThis.fetch)(source);
1200
- if (!res.ok) throw new Error(`fetch failed (${res.status}) for ${source}`);
1201
- content = await res.text();
1202
- type = source.endsWith("llms.txt") ? "llms.txt" : source.endsWith(".json") ? "openapi" : "website";
1203
- } else {
1204
- const abs = path4.resolve(root, source);
1205
- if (!fs4.existsSync(abs)) throw new Error(`source not found: ${source}`);
1206
- content = readLocal(abs);
1207
- type = "local";
1208
- }
1209
- const name = opts.name ?? inferName(source);
1210
- const id = libId(name);
1211
- const version = opts.version ?? installedVersion(root, name) ?? "*";
1212
- fs4.mkdirSync(libDir(root), { recursive: true });
1213
- const docFileAbs = path4.join(libDir(root), `${id}.md`);
1214
- fs4.writeFileSync(docFileAbs, content);
1215
- const entry = {
1216
- id,
1217
- name,
1218
- version,
1219
- source: { type, location: source },
1220
- docFile: path4.relative(root, docFileAbs).split(path4.sep).join("/"),
1221
- docHash: hashString(content),
1222
- bytes: Buffer.byteLength(content, "utf8")
1223
- };
1224
- const catalog = loadCatalog(root);
1225
- catalog.libraries[id] = entry;
1226
- saveCatalog(root, catalog);
1227
- return entry;
1228
- }
1229
- function readDoc(root, entry) {
1230
- const abs = path4.resolve(root, entry.docFile);
1231
- return fs4.existsSync(abs) ? fs4.readFileSync(abs, "utf8") : "";
1232
- }
1233
- function npmPackageDir(root, name) {
1234
- let cur = root;
1235
- for (let i = 0; i < 12; i++) {
1236
- const dir = path4.join(cur, "node_modules", name);
1237
- if (fs4.existsSync(path4.join(dir, "package.json"))) return dir;
1238
- const parent = path4.dirname(cur);
1239
- if (parent === cur) break;
1240
- cur = parent;
1241
- }
1242
- return void 0;
1243
- }
1244
- var README_CANDIDATES = ["llms.txt", "README.md", "README.mdx", "README", "readme.md"];
1245
- function packageDocsMarkdown(dir, query) {
1246
- const docsDir = path4.join(dir, "docs");
1247
- if (!fs4.existsSync(docsDir) || !fs4.statSync(docsDir).isDirectory()) return void 0;
1248
- const files = [];
1249
- const walk = (d, depth) => {
1250
- if (depth > 3 || files.length >= 40) return;
1251
- let entries;
1252
- try {
1253
- entries = fs4.readdirSync(d, { withFileTypes: true });
1254
- } catch {
1255
- return;
1256
- }
1257
- entries.sort((a, b) => a.name.localeCompare(b.name));
1258
- for (const e of entries) {
1259
- if (files.length >= 40) return;
1260
- const full = path4.join(d, e.name);
1261
- if (e.isDirectory()) {
1262
- if (e.name.startsWith(".") || e.name === "node_modules") continue;
1263
- walk(full, depth + 1);
1264
- } else if (e.isFile() && /\.(md|mdx)$/i.test(e.name)) {
1265
- files.push(full);
1266
- }
1267
- }
1268
- };
1269
- walk(docsDir, 0);
1270
- if (!files.length) return void 0;
1271
- const terms = (query ?? "").toLowerCase().split(/[^a-z0-9]+/).filter((w) => w.length > 2);
1272
- const scored = files.map((f) => {
1273
- let body = "";
1274
- try {
1275
- body = fs4.readFileSync(f, "utf8");
1276
- } catch {
1277
- return { f, body: "", score: -1 };
1278
- }
1279
- const lc = `${path4.basename(f)}
1280
- ${body}`.toLowerCase();
1281
- const score = terms.length ? terms.filter((t) => lc.includes(t)).length : 1;
1282
- return { f, body, score };
1283
- });
1284
- const picked = (terms.length ? scored.filter((s) => s.score > 0).sort((a, b) => b.score - a.score || a.f.localeCompare(b.f)) : scored).filter((s) => s.body.trim()).slice(0, terms.length ? 8 : 5);
1285
- if (!picked.length) return void 0;
1286
- const text = picked.map((s) => `<!-- ${path4.relative(dir, s.f).split(path4.sep).join("/")} -->
1287
- ${s.body.trim()}`).join("\n\n");
1288
- return {
1289
- text,
1290
- files: picked.map((s) => path4.relative(dir, s.f).split(path4.sep).join("/"))
1291
- };
1292
- }
1293
- function localPackageDocs(root, name, opts) {
1294
- const dir = npmPackageDir(root, name);
1295
- if (!dir) return void 0;
1296
- const version = resolveVersion(root, name).served;
1297
- let primary;
1298
- for (const f of README_CANDIDATES) {
1299
- const p = path4.join(dir, f);
1300
- try {
1301
- const docs = fs4.readFileSync(p, "utf8");
1302
- if (docs.trim()) {
1303
- primary = { docs, source: path4.relative(root, p).split(path4.sep).join("/") };
1304
- break;
1305
- }
1306
- } catch {
1307
- }
1308
- }
1309
- const extra = packageDocsMarkdown(dir, opts?.query);
1310
- if (primary && extra) {
1311
- return {
1312
- docs: `${primary.docs.trim()}
1313
-
1314
- ## Package docs
1315
-
1316
- ${extra.text}`,
1317
- version,
1318
- source: `${primary.source}+docs/`,
1319
- readmeOnly: false
1320
- };
1321
- }
1322
- if (primary) {
1323
- return { ...primary, version, readmeOnly: true };
1324
- }
1325
- if (extra) {
1326
- return {
1327
- docs: extra.text,
1328
- version,
1329
- source: path4.relative(root, path4.join(dir, "docs")).split(path4.sep).join("/") + "/",
1330
- readmeOnly: false
1331
- };
1332
- }
1333
- try {
1334
- const pkg = JSON.parse(fs4.readFileSync(path4.join(dir, "package.json"), "utf8"));
1335
- if (pkg.description?.trim()) {
1336
- return {
1337
- docs: `# ${name}
1338
-
1339
- ${pkg.description}`,
1340
- version: version ?? pkg.version,
1341
- source: path4.relative(root, path4.join(dir, "package.json")).split(path4.sep).join("/"),
1342
- readmeOnly: true
1343
- };
1344
- }
1345
- } catch {
1346
- }
1347
- return void 0;
1348
- }
1349
- function typesFromPkg(dir, pkg) {
1350
- const tryRel = (rel) => {
1351
- if (typeof rel !== "string") return void 0;
1352
- const p = path4.join(dir, rel);
1353
- return fs4.existsSync(p) ? p : void 0;
1354
- };
1355
- const top = tryRel(pkg.types) ?? tryRel(pkg.typings);
1356
- if (top) return top;
1357
- const exp = pkg.exports;
1358
- if (!exp || typeof exp !== "object") return void 0;
1359
- const roots = [];
1360
- if ("." in exp) roots.push(exp["."]);
1361
- else roots.push(...Object.values(exp));
1362
- for (const entry of roots) {
1363
- if (typeof entry === "string") {
1364
- const hit = tryRel(entry.endsWith(".d.ts") ? entry : void 0);
1365
- if (hit) return hit;
1366
- continue;
1367
- }
1368
- if (entry && typeof entry === "object") {
1369
- const o = entry;
1370
- for (const key of ["types", "typings", "import", "require", "default"]) {
1371
- const v = o[key];
1372
- if (typeof v === "string") {
1373
- const hit = tryRel(v.endsWith(".ts") || v.endsWith(".d.ts") || v.endsWith(".mts") || v.endsWith(".cts") ? v : void 0);
1374
- if (hit) return hit;
1375
- } else if (v && typeof v === "object" && typeof v.types === "string") {
1376
- const hit = tryRel(v.types);
1377
- if (hit) return hit;
1378
- }
1379
- }
1380
- }
1381
- }
1382
- return void 0;
1383
- }
1384
- function dtsEntry(dir) {
1385
- try {
1386
- const pkg = JSON.parse(fs4.readFileSync(path4.join(dir, "package.json"), "utf8"));
1387
- const fromPkg = typesFromPkg(dir, pkg);
1388
- if (fromPkg) return fromPkg;
1389
- } catch {
1390
- }
1391
- for (const c of [
1392
- "index.d.ts",
1393
- "dist/index.d.ts",
1394
- "dist/types/index.d.ts",
1395
- "lib/index.d.ts",
1396
- "types/index.d.ts",
1397
- "build/index.d.ts"
1398
- ]) {
1399
- const p = path4.join(dir, c);
1400
- if (fs4.existsSync(p)) return p;
1401
- }
1402
- return void 0;
1403
- }
1404
- var MAX_DTS_FILES = 30;
1405
- var MAX_DTS_BYTES = 512e3;
1406
- function collectDtsFiles(dir) {
1407
- const out = [];
1408
- const walk = (d, depth) => {
1409
- if (depth > 4 || out.length >= MAX_DTS_FILES) return;
1410
- let entries;
1411
- try {
1412
- entries = fs4.readdirSync(d, { withFileTypes: true });
1413
- } catch {
1414
- return;
1415
- }
1416
- entries.sort((a, b) => a.name.localeCompare(b.name));
1417
- for (const e of entries) {
1418
- if (out.length >= MAX_DTS_FILES) return;
1419
- if (e.name === "node_modules" || e.name.startsWith(".")) continue;
1420
- const full = path4.join(d, e.name);
1421
- if (e.isDirectory()) walk(full, depth + 1);
1422
- else if (e.isFile() && /\.d\.(ts|mts|cts)$/.test(e.name)) out.push(full);
1423
- }
1424
- };
1425
- walk(dir, 0);
1426
- return out;
1427
- }
1428
- function extractDtsApi(src, maxDecls = 200) {
1429
- const out = [];
1430
- let depth = 0;
1431
- let capture = null;
1432
- for (const raw of src.split("\n")) {
1433
- const line = raw.trim();
1434
- if (capture === null && depth === 0 && /^export\s+\{[^}]+\}/.test(line)) {
1435
- out.push(raw.trim());
1436
- if (out.length >= maxDecls) break;
1437
- continue;
1438
- }
1439
- if (capture === null && depth === 0 && /^export\b/.test(line) && !/^export\s+(\{|\*|default\b|type\s+\{)/.test(line)) {
1440
- capture = [];
1441
- }
1442
- if (capture) capture.push(raw);
1443
- for (const ch of raw) {
1444
- if (ch === "{") depth++;
1445
- else if (ch === "}") depth = Math.max(0, depth - 1);
1446
- }
1447
- if (capture && depth === 0 && /[;}]\s*$/.test(line)) {
1448
- out.push(capture.join("\n").trim());
1449
- capture = null;
1450
- if (out.length >= maxDecls) break;
1451
- }
1452
- }
1453
- return out;
1454
- }
1455
- function reExportNames(decl) {
1456
- const m = /^export\s*\{([^}]+)\}/.exec(decl.trim());
1457
- if (!m) return [];
1458
- const names = [];
1459
- for (const part of m[1].split(",")) {
1460
- const n = part.trim().split(/\s+as\s+/i).pop()?.trim();
1461
- if (n && /^[A-Za-z_$][\w$]*$/.test(n)) names.push(n);
1462
- }
1463
- return names;
1464
- }
1465
- function localApiSurface(root, name, query) {
1466
- const dir = npmPackageDir(root, name);
1467
- if (!dir) return void 0;
1468
- const entry = dtsEntry(dir);
1469
- const files = entry ? [entry, ...collectDtsFiles(dir).filter((f) => f !== entry)] : collectDtsFiles(dir);
1470
- if (!files.length) return void 0;
1471
- const allDecls = [];
1472
- const seen = /* @__PURE__ */ new Set();
1473
- for (const f of files) {
1474
- let src;
1475
- try {
1476
- const st = fs4.statSync(f);
1477
- if (st.size > MAX_DTS_BYTES) continue;
1478
- src = fs4.readFileSync(f, "utf8");
1479
- } catch {
1480
- continue;
1481
- }
1482
- for (const d of extractDtsApi(src)) {
1483
- if (seen.has(d)) continue;
1484
- seen.add(d);
1485
- allDecls.push(d);
1486
- if (allDecls.length >= 400) break;
1487
- }
1488
- if (allDecls.length >= 400) break;
1489
- }
1490
- if (!allDecls.length) return void 0;
1491
- const terms = (query ?? "").split(/[^A-Za-z0-9_$]+/).filter((w) => w.length > 2);
1492
- if (terms.length) {
1493
- const lcTerms = terms.map((t) => t.toLowerCase());
1494
- const matched = allDecls.filter((d) => {
1495
- const lc = d.toLowerCase();
1496
- return lcTerms.some((t) => lc.includes(t));
1497
- });
1498
- const expanded = [];
1499
- const expandedSeen = /* @__PURE__ */ new Set();
1500
- for (const d of matched) {
1501
- const names = reExportNames(d);
1502
- if (names.length) {
1503
- for (const n of names) {
1504
- const fuller = allDecls.find(
1505
- (x) => !/^export\s*\{/.test(x) && new RegExp(`\\b${n}\\b`).test(x)
1506
- );
1507
- const pick = fuller ?? d;
1508
- if (!expandedSeen.has(pick)) {
1509
- expandedSeen.add(pick);
1510
- expanded.push(pick);
1511
- }
1512
- }
1513
- } else if (!expandedSeen.has(d)) {
1514
- expandedSeen.add(d);
1515
- expanded.push(d);
1516
- }
1517
- }
1518
- if (expanded.length) return expanded.slice(0, 40).join("\n\n");
1519
- }
1520
- return allDecls.slice(0, 80).join("\n\n");
1521
- }
1522
- function cloneAndReadGit(url) {
1523
- const dir = fs4.mkdtempSync(path4.join(os.tmpdir(), "vg-lib-git-"));
1524
- try {
1525
- execFileSync("git", ["clone", "--depth", "1", "--quiet", url, dir], {
1526
- stdio: ["ignore", "ignore", "pipe"]
1527
- });
1528
- } catch (err) {
1529
- fs4.rmSync(dir, { recursive: true, force: true });
1530
- const detail = err instanceof Error && err.message ? `: ${err.message.split("\n")[0]}` : "";
1531
- throw new Error(`git clone failed for ${url}${detail}`);
1532
- }
1533
- try {
1534
- return readGitDocs(dir);
1535
- } finally {
1536
- fs4.rmSync(dir, { recursive: true, force: true });
1537
- }
1538
- }
1539
- function readGitDocs(dir) {
1540
- const docsDir = path4.join(dir, "docs");
1541
- if (fs4.existsSync(docsDir) && fs4.statSync(docsDir).isDirectory()) return readLocal(docsDir);
1542
- const readme = ["README.md", "README.mdx", "README.txt", "README.rst", "readme.md"].map((f) => path4.join(dir, f)).find((p) => fs4.existsSync(p));
1543
- if (readme) return fs4.readFileSync(readme, "utf8");
1544
- return readLocal(dir);
1545
- }
1546
- function readLocal(abs) {
1547
- const stat = fs4.statSync(abs);
1548
- if (stat.isFile()) return fs4.readFileSync(abs, "utf8");
1549
- const parts = [];
1550
- const files = fs4.readdirSync(abs, { withFileTypes: true }).filter((e) => e.isFile() && /\.(md|mdx|txt|rst)$/i.test(e.name)).map((e) => e.name).sort();
1551
- for (const f of files) parts.push(`<!-- ${f} -->
1552
- ${fs4.readFileSync(path4.join(abs, f), "utf8")}`);
1553
- return parts.join("\n\n");
1554
- }
1555
- function inferName(source) {
1556
- const cleaned = source.replace(/^git\+/, "").replace(/\.git\/?$/i, "");
1557
- const base = cleaned.replace(/\/+$/, "").split(/[/:]/).pop() ?? cleaned;
1558
- return base.replace(/\.(md|mdx|txt|rst|json)$/i, "").replace(/^llms$/, "docs");
1559
- }
1560
- function resolve3(parses, resolver) {
1561
- const baseNodes = /* @__PURE__ */ new Map();
1562
- const relSet = new Set(parses.map((p) => p.rel));
1563
- const mod = resolver ?? relativeResolver(relSet);
1564
- const defsByName = /* @__PURE__ */ new Map();
1565
- const defsByFile = /* @__PURE__ */ new Map();
1566
- const fileNodeIdByRel = /* @__PURE__ */ new Map();
1567
- for (const p of parses) {
1568
- const fileId = nodeId({ kind: "file", qualifiedName: p.rel, file: p.rel });
1569
- fileNodeIdByRel.set(p.rel, fileId);
1570
- addNode(baseNodes, {
1571
- id: fileId,
1572
- kind: "file",
1573
- name: path4.posix.basename(p.rel),
1574
- qualifiedName: p.rel,
1575
- file: p.rel,
1576
- span: { start: 1, end: 1 },
1577
- lang: p.lang
1578
- });
1579
- for (const d of p.defs) {
1580
- const id = nodeId({
1581
- kind: d.kind,
1582
- qualifiedName: d.qualifiedName,
1583
- file: p.rel,
1584
- signature: d.signature
1585
- });
1586
- addNode(baseNodes, {
1587
- id,
1588
- kind: d.kind,
1589
- name: d.name,
1590
- qualifiedName: d.qualifiedName,
1591
- file: p.rel,
1592
- span: { start: d.startLine, end: d.endLine },
1593
- lang: p.lang,
1594
- signature: d.signature,
1595
- doc: d.doc
1596
- });
1597
- const ref = {
1598
- id,
1599
- name: d.name,
1600
- qualifiedName: d.qualifiedName,
1601
- rel: p.rel,
1602
- lang: p.lang,
1603
- kind: d.kind,
1604
- startByte: d.startByte,
1605
- endByte: d.endByte
1606
- };
1607
- push(defsByName, d.name, ref);
1608
- push(defsByFile, p.rel, ref);
1609
- }
1610
- }
1611
- const filesByNamespace = /* @__PURE__ */ new Map();
1612
- for (const p of parses) for (const ns of p.namespaces ?? []) addToSet(filesByNamespace, ns, p.rel);
1613
- const relsByLang = /* @__PURE__ */ new Map();
1614
- for (const p of parses) push(relsByLang, p.lang, p.rel);
1615
- const nsReachableByRel = /* @__PURE__ */ new Map();
1616
- const moduleReachableByRel = /* @__PURE__ */ new Map();
1617
- for (const p of parses) {
1618
- if (MODULE_SCOPED_LANGS.has(p.lang)) {
1619
- const mod2 = /* @__PURE__ */ new Set();
1620
- for (const rel of relsByLang.get(p.lang) ?? []) if (rel !== p.rel) mod2.add(rel);
1621
- moduleReachableByRel.set(p.rel, mod2);
1622
- }
1623
- const reach = /* @__PURE__ */ new Set();
1624
- const namespaces = new Set(p.namespaces ?? []);
1625
- for (const imp of p.imports) {
1626
- namespaces.add(imp.source);
1627
- if (IMPORT_NAMES_A_TYPE.has(p.lang)) {
1628
- const sep3 = Math.max(imp.source.lastIndexOf("."), imp.source.lastIndexOf("\\"));
1629
- if (sep3 > 0) namespaces.add(imp.source.slice(0, sep3));
1630
- }
1631
- }
1632
- for (const ns of namespaces) for (const rel of filesByNamespace.get(ns) ?? []) if (rel !== p.rel) reach.add(rel);
1633
- nsReachableByRel.set(p.rel, reach);
1634
- }
1635
- const superTypesByType = /* @__PURE__ */ new Map();
1636
- for (const p of parses) {
1637
- const localDefs = defsByFile.get(p.rel) ?? [];
1638
- for (const h of p.heritage) {
1639
- const encl = enclosingDefRef(localDefs, h.byte);
1640
- if (encl && (encl.kind === "class" || encl.kind === "interface")) addToSet(superTypesByType, encl.name, h.superName);
1641
- }
1642
- }
1643
- const edges = new EdgeSet();
1644
- const unresolved = /* @__PURE__ */ new Map();
1645
- const stats = {
1646
- callsResolved: 0,
1647
- callsUnresolved: 0,
1648
- importsResolvedToFile: 0,
1649
- importsExternal: 0,
1650
- resolvers: ["heuristic"]
1651
- };
1652
- for (const p of parses) {
1653
- const fileId = fileNodeIdByRel.get(p.rel);
1654
- const localByQn = /* @__PURE__ */ new Map();
1655
- for (const ref of defsByFile.get(p.rel) ?? []) localByQn.set(ref.qualifiedName, ref.id);
1656
- for (const d of p.defs) {
1657
- const id = localByQn.get(d.qualifiedName);
1658
- const parentQn = parentQualifiedName(d.qualifiedName);
1659
- const parentId = parentQn ? localByQn.get(parentQn) : void 0;
1660
- edges.add("contains", parentId ?? fileId, id, "heuristic", 1);
1661
- }
1662
- }
1663
- const importedFilesByRel = /* @__PURE__ */ new Map();
1664
- for (const p of parses) {
1665
- const fileId = fileNodeIdByRel.get(p.rel);
1666
- const importedRels = /* @__PURE__ */ new Set();
1667
- for (const imp of p.imports) {
1668
- const targetRel = mod.resolve(p.rel, imp.source);
1669
- if (targetRel && targetRel !== p.rel) {
1670
- importedRels.add(targetRel);
1671
- edges.add("import", fileId, fileNodeIdByRel.get(targetRel), "heuristic", 0.9);
1672
- stats.importsResolvedToFile++;
1673
- } else {
1674
- const extId = ensureExternalNode(baseNodes, imp.source);
1675
- edges.add("import", fileId, extId, "heuristic", 1);
1676
- stats.importsExternal++;
1677
- }
1678
- }
1679
- importedFilesByRel.set(p.rel, importedRels);
1680
- }
1681
- for (const p of parses) {
1682
- const fileId = fileNodeIdByRel.get(p.rel);
1683
- const localDefs = defsByFile.get(p.rel) ?? [];
1684
- const imported = importedFilesByRel.get(p.rel) ?? /* @__PURE__ */ new Set();
1685
- const testCaller = isTestFile(p.rel);
1686
- const nsReach = nsReachableByRel.get(p.rel) ?? /* @__PURE__ */ new Set();
1687
- const modReach = moduleReachableByRel.get(p.rel) ?? /* @__PURE__ */ new Set();
1688
- for (const call of p.calls) {
1689
- const srcId = enclosingDefId(localDefs, call.byte) ?? fileId;
1690
- const resolved = resolveCall(call, p.rel, p.lang, imported, defsByName, srcId, testCaller, nsReach, superTypesByType, modReach);
1691
- if (resolved) {
1692
- edges.add("call", srcId, resolved.id, "heuristic", resolved.confidence);
1693
- stats.callsResolved++;
1694
- } else {
1695
- stats.callsUnresolved++;
1696
- bumpUnresolved(unresolved, srcId, call.callee, "call", p.rel);
1697
- }
1698
- }
1699
- }
1700
- for (const p of parses) {
1701
- const fileId = fileNodeIdByRel.get(p.rel);
1702
- const localDefs = defsByFile.get(p.rel) ?? [];
1703
- const imported = importedFilesByRel.get(p.rel) ?? /* @__PURE__ */ new Set();
1704
- const testCaller = isTestFile(p.rel);
1705
- const nsReach = nsReachableByRel.get(p.rel) ?? /* @__PURE__ */ new Set();
1706
- const modReach = moduleReachableByRel.get(p.rel) ?? /* @__PURE__ */ new Set();
1707
- for (const ref of p.typeRefs) {
1708
- const srcId = enclosingDefId(localDefs, ref.byte) ?? fileId;
1709
- const target = resolveType(ref.name, p.rel, p.lang, imported, defsByName, testCaller, nsReach, modReach);
1710
- if (target) edges.add("references", srcId, target.id, "heuristic", 0.7);
1711
- }
1712
- }
1713
- for (const p of parses) {
1714
- const localDefs = defsByFile.get(p.rel) ?? [];
1715
- const imported = importedFilesByRel.get(p.rel) ?? /* @__PURE__ */ new Set();
1716
- const testCaller = isTestFile(p.rel);
1717
- for (const h of p.heritage) {
1718
- const srcId = enclosingDefId(localDefs, h.byte);
1719
- if (!srcId) continue;
1720
- const nsReach = nsReachableByRel.get(p.rel) ?? /* @__PURE__ */ new Set();
1721
- const modReach = moduleReachableByRel.get(p.rel) ?? /* @__PURE__ */ new Set();
1722
- const target = resolveType(h.superName, p.rel, p.lang, imported, defsByName, testCaller, nsReach, modReach);
1723
- if (target) edges.add(h.kind, srcId, target.id, "heuristic", 0.85);
1724
- else bumpUnresolved(unresolved, srcId, h.superName, h.kind, p.rel);
1725
- }
1726
- }
1727
- const nodes = [...baseNodes.values()].map((n) => ({
1728
- ...n,
1729
- importance: 0,
1730
- centrality: { degree: 0, pagerank: 0, betweenness: 0, eigenvector: 0 },
1731
- area: 0,
1732
- isHub: false,
1733
- tested: null
1734
- }));
1735
- const unresolvedList = [...unresolved.values()].sort(
1736
- (a, b) => a.from.localeCompare(b.from) || a.kind.localeCompare(b.kind) || a.name.localeCompare(b.name)
1737
- );
1738
- return { nodes, edges: edges.toArray(), unresolved: unresolvedList, stats };
1739
- }
1740
- function bumpUnresolved(map, from, name, kind, fromRel) {
1741
- const key = `${from}${kind}${name}`;
1742
- const existing = map.get(key);
1743
- if (existing) existing.count++;
1744
- else map.set(key, { from, name, kind, count: 1, fromRel });
1745
- }
1746
- function addNode(map, n) {
1747
- if (!map.has(n.id)) map.set(n.id, n);
1748
- }
1749
- function ensureExternalNode(map, source) {
1750
- const id = nodeId({ kind: "external", qualifiedName: source, file: "" });
1751
- if (!map.has(id)) {
1752
- map.set(id, {
1753
- id,
1754
- kind: "external",
1755
- name: source,
1756
- qualifiedName: source,
1757
- file: "",
1758
- span: { start: 1, end: 1 },
1759
- lang: "external"
1760
- });
1761
- }
1762
- return id;
1763
- }
1764
- function push(map, key, value) {
1765
- const list = map.get(key);
1766
- if (list) list.push(value);
1767
- else map.set(key, [value]);
1768
- }
1769
- function parentQualifiedName(qn) {
1770
- const idx = qn.lastIndexOf(".");
1771
- return idx > 0 ? qn.slice(0, idx) : null;
1772
- }
1773
- function enclosingDefRef(defs, byte) {
1774
- let best;
1775
- for (const d of defs) {
1776
- if (d.startByte <= byte && d.endByte >= byte) {
1777
- if (!best || d.endByte - d.startByte < best.endByte - best.startByte) best = d;
1778
- }
1779
- }
1780
- return best;
1781
- }
1782
- function enclosingDefId(defs, byte) {
1783
- return enclosingDefRef(defs, byte)?.id;
1784
- }
1785
- function addToSet(map, key, value) {
1786
- const s = map.get(key);
1787
- if (s) s.add(value);
1788
- else map.set(key, /* @__PURE__ */ new Set([value]));
1789
- }
1790
- function parentTypeName(qualifiedName) {
1791
- const i = qualifiedName.lastIndexOf(".");
1792
- return i > 0 ? qualifiedName.slice(0, i) : null;
1793
- }
1794
- function disambiguateInterfaceImpl(pool, superTypesByType) {
1795
- const withParent = pool.map((c) => ({ c, parent: parentTypeName(c.qualifiedName) })).filter((x) => x.parent !== null);
1796
- if (withParent.length < 2) return null;
1797
- const parents = new Set(withParent.map((x) => x.parent));
1798
- const impls = withParent.filter(
1799
- (x) => [...parents].some((other) => other !== x.parent && superTypesByType.get(x.parent)?.has(other))
1800
- );
1801
- if (impls.length === 0) return null;
1802
- const interfaceParents = /* @__PURE__ */ new Set();
1803
- for (const impl of impls) for (const s of superTypesByType.get(impl.parent) ?? []) interfaceParents.add(s);
1804
- const interfaces = withParent.filter((x) => interfaceParents.has(x.parent));
1805
- const uniqueImplIds = new Set(impls.map((x) => x.c.id));
1806
- if (uniqueImplIds.size === 1) return impls[0].c;
1807
- const uniqueIfaceIds = new Set(interfaces.map((x) => x.c.id));
1808
- if (uniqueIfaceIds.size === 1) return interfaces[0].c;
1809
- return null;
1810
- }
1811
- var PACKAGE_SCOPED_LANGS = /* @__PURE__ */ new Set(["go", "java", "cs", "kotlin", "scala", "swift"]);
1812
- var IMPORT_NAMES_A_TYPE = /* @__PURE__ */ new Set(["java", "kotlin", "scala", "php"]);
1813
- var MODULE_SCOPED_LANGS = /* @__PURE__ */ new Set(["swift"]);
1814
- function dirOf(rel) {
1815
- const i = rel.lastIndexOf("/");
1816
- return i >= 0 ? rel.slice(0, i) : "";
1817
- }
1818
- function resolveCall(call, fromRel, fromLang, importedRels, defsByName, enclosingId, fromIsTestFile = false, nsReachableRels = /* @__PURE__ */ new Set(), superTypesByType = /* @__PURE__ */ new Map(), moduleReachableRels = /* @__PURE__ */ new Set()) {
1819
- const candidates = defsByName.get(call.callee);
1820
- if (!candidates || candidates.length === 0) return null;
1821
- const callable = candidates.filter((c) => c.kind === "function" || c.kind === "method");
1822
- const pool = callable.length ? callable : candidates;
1823
- let sameFile = pool.filter((c) => c.rel === fromRel);
1824
- if (call.qualified && enclosingId) sameFile = sameFile.filter((c) => c.id !== enclosingId);
1825
- if (sameFile.length === 1) return { id: sameFile[0].id, confidence: 0.85 };
1826
- if (sameFile.length > 1) {
1827
- const pick = [...sameFile].sort((a, b) => a.id.localeCompare(b.id))[0];
1828
- return { id: pick.id, confidence: 0.4 };
1829
- }
1830
- const dir = dirOf(fromRel);
1831
- const notSelf = (c) => !(call.qualified && enclosingId && c.id === enclosingId);
1832
- const strict = pool.filter(
1833
- (c) => notSelf(c) && (importedRels.has(c.rel) || PACKAGE_SCOPED_LANGS.has(fromLang) && c.lang === fromLang && dirOf(c.rel) === dir || nsReachableRels.has(c.rel))
1834
- );
1835
- if (strict.length === 1) return { id: strict[0].id, confidence: 0.75 };
1836
- const broad = pool.filter((c) => notSelf(c) && (moduleReachableRels.has(c.rel) || strict.includes(c)));
1837
- if (broad.length > 1) {
1838
- const dedup = disambiguateInterfaceImpl(broad, superTypesByType);
1839
- if (dedup) return { id: dedup.id, confidence: 0.6 };
1840
- }
1841
- if (strict.length > 1) return null;
1842
- if (fromLang === "swift" && fromIsTestFile && pool.length === 1) {
1843
- return { id: pool[0].id, confidence: 0.5 };
1844
- }
1845
- return null;
1846
- }
1847
- function resolveType(name, fromRel, fromLang, importedRels, defsByName, fromIsTestFile = false, nsReachableRels = /* @__PURE__ */ new Set(), moduleReachableRels = /* @__PURE__ */ new Set()) {
1848
- const candidates = (defsByName.get(name) ?? []).filter(
1849
- (c) => c.kind === "class" || c.kind === "interface"
1850
- );
1851
- if (candidates.length === 0) return null;
1852
- const sameFile = candidates.filter((c) => c.rel === fromRel);
1853
- if (sameFile.length === 1) return { id: sameFile[0].id };
1854
- const imported = candidates.filter((c) => importedRels.has(c.rel));
1855
- if (imported.length === 1) return { id: imported[0].id };
1856
- if (imported.length > 1) return null;
1857
- if (PACKAGE_SCOPED_LANGS.has(fromLang)) {
1858
- const dir = dirOf(fromRel);
1859
- const samePkg = candidates.filter((c) => c.lang === fromLang && dirOf(c.rel) === dir);
1860
- if (samePkg.length === 1) return { id: samePkg[0].id };
1861
- }
1862
- if (nsReachableRels.size || moduleReachableRels.size) {
1863
- const reach = candidates.filter((c) => nsReachableRels.has(c.rel) || moduleReachableRels.has(c.rel));
1864
- if (reach.length === 1) return { id: reach[0].id };
1865
- }
1866
- if (fromLang === "swift" && fromIsTestFile && candidates.length === 1) {
1867
- return { id: candidates[0].id };
1868
- }
1869
- return null;
1870
- }
1871
- var EdgeSet = class {
1872
- map = /* @__PURE__ */ new Map();
1873
- add(kind, src, dst, resolution, confidence) {
1874
- const id = edgeId(kind, src, dst);
1875
- const existing = this.map.get(id);
1876
- if (existing) {
1877
- existing.count = (existing.count ?? 1) + 1;
1878
- if (confidence > existing.confidence) existing.confidence = confidence;
1879
- return;
1880
- }
1881
- this.map.set(id, { id, kind, src, dst, resolution, confidence, count: 1 });
1882
- }
1883
- toArray() {
1884
- return [...this.map.values()].sort(
1885
- (a, b) => a.kind.localeCompare(b.kind) || a.src.localeCompare(b.src) || a.dst.localeCompare(b.dst)
1886
- );
1887
- }
1888
- };
1889
-
1890
- export { ECOSYSTEMS, addLibrary, applyStaticTestLinkage, buildModuleResolver, catalogPath, driftFor, edgeId, enrichOnline, inventory, isTestFile, libDir, libId, loadCatalog, localApiSurface, localPackageDocs, nodeId, parseJsonc, readDoc, relativeResolver, resolve3 as resolve, resolveLib, resolveVersion, saveCatalog };
1891
- //# sourceMappingURL=chunk-6AXHLQBV.js.map
1892
- //# sourceMappingURL=chunk-6AXHLQBV.js.map