@vibgrate/cli 2026.722.1 → 2026.727.1

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 (125) hide show
  1. package/DOCS.md +418 -196
  2. package/README.md +34 -7
  3. package/dist/baseline-K7YBFKZI.js +7 -0
  4. package/dist/{baseline-J44M7MWP.js.map → baseline-K7YBFKZI.js.map} +1 -1
  5. package/dist/chunk-3BVSDMHV.js +2496 -0
  6. package/dist/chunk-3BVSDMHV.js.map +1 -0
  7. package/dist/{chunk-PY3DNX5H.js → chunk-3Q7QBWFW.js} +13 -2
  8. package/dist/chunk-3Q7QBWFW.js.map +1 -0
  9. package/dist/chunk-4CQ3MGNN.js +136 -0
  10. package/dist/chunk-4CQ3MGNN.js.map +1 -0
  11. package/dist/chunk-5I4VSBWQ.js +764 -0
  12. package/dist/chunk-5I4VSBWQ.js.map +1 -0
  13. package/dist/chunk-5Q54GEHM.js +29 -0
  14. package/dist/chunk-5Q54GEHM.js.map +1 -0
  15. package/dist/{chunk-XKXKWYJF.js → chunk-65MEOA4E.js} +21 -18
  16. package/dist/chunk-65MEOA4E.js.map +1 -0
  17. package/dist/{chunk-WNIIKCNF.js → chunk-6IOQJGFT.js} +29 -238
  18. package/dist/chunk-6IOQJGFT.js.map +1 -0
  19. package/dist/{chunk-CS37OBE3.js → chunk-7JHPQ6WF.js} +791 -783
  20. package/dist/chunk-7JHPQ6WF.js.map +1 -0
  21. package/dist/chunk-BPF3YX2U.js +64 -0
  22. package/dist/chunk-BPF3YX2U.js.map +1 -0
  23. package/dist/chunk-BWPBB45M.js +88 -0
  24. package/dist/chunk-BWPBB45M.js.map +1 -0
  25. package/dist/chunk-C4CKTAZP.js +1695 -0
  26. package/dist/chunk-C4CKTAZP.js.map +1 -0
  27. package/dist/chunk-EDAAG7BL.js +612 -0
  28. package/dist/chunk-EDAAG7BL.js.map +1 -0
  29. package/dist/chunk-EDBV33B7.js +57 -0
  30. package/dist/chunk-EDBV33B7.js.map +1 -0
  31. package/dist/chunk-HABUT7HW.js +233 -0
  32. package/dist/chunk-HABUT7HW.js.map +1 -0
  33. package/dist/{chunk-EXQV26MF.js → chunk-HYZVHJ3Q.js} +3 -3
  34. package/dist/{chunk-EXQV26MF.js.map → chunk-HYZVHJ3Q.js.map} +1 -1
  35. package/dist/chunk-IS7VTH2Q.js +627 -0
  36. package/dist/chunk-IS7VTH2Q.js.map +1 -0
  37. package/dist/chunk-IZDH67DX.js +289 -0
  38. package/dist/chunk-IZDH67DX.js.map +1 -0
  39. package/dist/chunk-J7LKEB2R.js +51 -0
  40. package/dist/chunk-J7LKEB2R.js.map +1 -0
  41. package/dist/chunk-JIBOJTGS.js +313 -0
  42. package/dist/chunk-JIBOJTGS.js.map +1 -0
  43. package/dist/chunk-JZYGEZTU.js +82 -0
  44. package/dist/chunk-JZYGEZTU.js.map +1 -0
  45. package/dist/chunk-K7REHDQS.js +776 -0
  46. package/dist/chunk-K7REHDQS.js.map +1 -0
  47. package/dist/chunk-KHJO4D5N.js +108 -0
  48. package/dist/chunk-KHJO4D5N.js.map +1 -0
  49. package/dist/chunk-NDMDSPFX.js +69 -0
  50. package/dist/chunk-NDMDSPFX.js.map +1 -0
  51. package/dist/chunk-OOIG3RUM.js +276 -0
  52. package/dist/chunk-OOIG3RUM.js.map +1 -0
  53. package/dist/{chunk-6CXTPC74.js → chunk-OXQNQW5J.js} +27 -6
  54. package/dist/chunk-OXQNQW5J.js.map +1 -0
  55. package/dist/chunk-PMYWZRRS.js +62 -0
  56. package/dist/chunk-PMYWZRRS.js.map +1 -0
  57. package/dist/chunk-PXHNTC6D.js +382 -0
  58. package/dist/chunk-PXHNTC6D.js.map +1 -0
  59. package/dist/{chunk-VXT6LUGP.js → chunk-S6CYDZEW.js} +1395 -1975
  60. package/dist/chunk-S6CYDZEW.js.map +1 -0
  61. package/dist/chunk-SZLF66FJ.js +843 -0
  62. package/dist/chunk-SZLF66FJ.js.map +1 -0
  63. package/dist/chunk-VXGV6NTD.js +476 -0
  64. package/dist/chunk-VXGV6NTD.js.map +1 -0
  65. package/dist/{chunk-JSNHZCIV.js → chunk-WLETRGAC.js} +16 -9
  66. package/dist/chunk-WLETRGAC.js.map +1 -0
  67. package/dist/{chunk-2EVQKZTO.js → chunk-YDAT7LD2.js} +190 -13
  68. package/dist/chunk-YDAT7LD2.js.map +1 -0
  69. package/dist/cli.js +3451 -509
  70. package/dist/cli.js.map +1 -1
  71. package/dist/execution-env-3BN7Z737.js +3 -0
  72. package/dist/execution-env-3BN7Z737.js.map +1 -0
  73. package/dist/federation-EPZDUWCK.js +6 -0
  74. package/dist/federation-EPZDUWCK.js.map +1 -0
  75. package/dist/git-ref-HPRLUFFW.js +3 -0
  76. package/dist/git-ref-HPRLUFFW.js.map +1 -0
  77. package/dist/graph-backend-ZMSYOZMW.js +10 -0
  78. package/dist/graph-backend-ZMSYOZMW.js.map +1 -0
  79. package/dist/index.d.ts +432 -126
  80. package/dist/index.js +14 -7
  81. package/dist/index.js.map +1 -1
  82. package/dist/{interactive-736PBC7J.js → interactive-ICL7D7LO.js} +185 -365
  83. package/dist/interactive-ICL7D7LO.js.map +1 -0
  84. package/dist/llm-host-2RAYQSDQ.js +8 -0
  85. package/dist/llm-host-2RAYQSDQ.js.map +1 -0
  86. package/dist/load-OHVKDX4R.js +7 -0
  87. package/dist/load-OHVKDX4R.js.map +1 -0
  88. package/dist/local-runtime-OJFLX2HI.js +4 -0
  89. package/dist/local-runtime-OJFLX2HI.js.map +1 -0
  90. package/dist/model-execution-profile-MQ2QCP24.js +3 -0
  91. package/dist/model-execution-profile-MQ2QCP24.js.map +1 -0
  92. package/dist/model-orchestrator-FFTZI3U2.js +8 -0
  93. package/dist/model-orchestrator-FFTZI3U2.js.map +1 -0
  94. package/dist/parse-worker.d.ts +1 -1
  95. package/dist/parse-worker.js +1 -1
  96. package/dist/paths-MCH75O3G.js +5 -0
  97. package/dist/paths-MCH75O3G.js.map +1 -0
  98. package/dist/resolve-gguf-4UPIGPEE.js +7 -0
  99. package/dist/resolve-gguf-4UPIGPEE.js.map +1 -0
  100. package/dist/runtime-session-IDU5BDUJ.js +17 -0
  101. package/dist/runtime-session-IDU5BDUJ.js.map +1 -0
  102. package/dist/session-L2OSDRPI.js +10 -0
  103. package/dist/{session-POJUDFPH.js.map → session-L2OSDRPI.js.map} +1 -1
  104. package/dist/{stream-json-Q2JGWPHB.js → stream-json-F74W5FCK.js} +16 -6
  105. package/dist/stream-json-F74W5FCK.js.map +1 -0
  106. package/dist/{types-Jl6RJ175.d.ts → types-ZMg1mSuu.d.ts} +3 -1
  107. package/dist/vgd-EGBQD7BW.js +16 -0
  108. package/dist/vgd-EGBQD7BW.js.map +1 -0
  109. package/package.json +9 -6
  110. package/dist/baseline-J44M7MWP.js +0 -7
  111. package/dist/chunk-2EVQKZTO.js.map +0 -1
  112. package/dist/chunk-6CXTPC74.js.map +0 -1
  113. package/dist/chunk-CS37OBE3.js.map +0 -1
  114. package/dist/chunk-GGJZA3Q6.js +0 -961
  115. package/dist/chunk-GGJZA3Q6.js.map +0 -1
  116. package/dist/chunk-JBXNQCGE.js +0 -484
  117. package/dist/chunk-JBXNQCGE.js.map +0 -1
  118. package/dist/chunk-JSNHZCIV.js.map +0 -1
  119. package/dist/chunk-PY3DNX5H.js.map +0 -1
  120. package/dist/chunk-VXT6LUGP.js.map +0 -1
  121. package/dist/chunk-WNIIKCNF.js.map +0 -1
  122. package/dist/chunk-XKXKWYJF.js.map +0 -1
  123. package/dist/interactive-736PBC7J.js.map +0 -1
  124. package/dist/session-POJUDFPH.js +0 -6
  125. package/dist/stream-json-Q2JGWPHB.js.map +0 -1
@@ -0,0 +1,276 @@
1
+ import { vibgrateCacheDir } from './chunk-BWPBB45M.js';
2
+ import * as fs from 'fs';
3
+ import * as path2 from 'path';
4
+ import * as https from 'https';
5
+ import * as http from 'http';
6
+ import { createHash } from 'crypto';
7
+ import * as os from 'os';
8
+
9
+ var WEIGHT_DOWNLOAD_HOST_ALLOWLIST = /* @__PURE__ */ new Set([
10
+ "huggingface.co",
11
+ "hf.co",
12
+ "cdn-lfs.huggingface.co",
13
+ "cdn-lfs-us-1.huggingface.co",
14
+ "us.aws.cdn.hf.co",
15
+ "cas-server.xethub.hf.co",
16
+ "objects.githubusercontent.com",
17
+ "github.com"
18
+ ]);
19
+ function isAllowedWeightHost(hostname) {
20
+ const h = hostname.toLowerCase();
21
+ if (WEIGHT_DOWNLOAD_HOST_ALLOWLIST.has(h)) return true;
22
+ if (h.endsWith(".huggingface.co")) return true;
23
+ if (h.endsWith(".hf.co")) return true;
24
+ if (h.endsWith(".cdn.hf.co")) return true;
25
+ return false;
26
+ }
27
+ var FIRST_PARTY_WEIGHT_CATALOG = [
28
+ {
29
+ ref: "qwen2.5-coder-3b-q4_k_m.gguf",
30
+ url: "https://huggingface.co/Qwen/Qwen2.5-Coder-3B-Instruct-GGUF/resolve/main/qwen2.5-coder-3b-instruct-q4_k_m.gguf",
31
+ license: "Apache-2.0",
32
+ packChannel: "2026.07.3",
33
+ // Git LFS oid = content sha256 (from HF API tree, 2026-07-27).
34
+ sha256: "724fb256bec1ff062b2f65e4569e871ad2e95ab2a3989723d1769c54294730b7",
35
+ bytes: 2104932800
36
+ },
37
+ {
38
+ ref: "qwen2.5-coder-7b-q4_k_m.gguf",
39
+ url: "https://huggingface.co/Qwen/Qwen2.5-Coder-7B-Instruct-GGUF/resolve/main/qwen2.5-coder-7b-instruct-q4_k_m.gguf",
40
+ license: "Apache-2.0",
41
+ packChannel: "2026.07.3",
42
+ sha256: "509287f78cb4d4cf6b3843734733b914b2c158e43e22a7f4bf5e963800894d3c",
43
+ bytes: 4683073536
44
+ }
45
+ ];
46
+ function catalogIntegrityReport(catalog = FIRST_PARTY_WEIGHT_CATALOG) {
47
+ const unpinned = catalog.filter((e) => !e.sha256?.trim()).map((e) => e.ref);
48
+ return {
49
+ total: catalog.length,
50
+ pinned: catalog.length - unpinned.length,
51
+ unpinned,
52
+ complete: unpinned.length === 0
53
+ };
54
+ }
55
+ function weightStoreDir(env = process.env) {
56
+ return path2.join(vibgrateCacheDir(env), "weights");
57
+ }
58
+ function weightPathForRef(ref, env = process.env) {
59
+ const base = path2.basename(ref).replace(/[^a-zA-Z0-9._+-]/g, "_");
60
+ return path2.join(weightStoreDir(env), base);
61
+ }
62
+ function isWeightCached(ref, env = process.env) {
63
+ try {
64
+ const p = weightPathForRef(ref, env);
65
+ return fs.existsSync(p) && fs.statSync(p).size > 0;
66
+ } catch {
67
+ return false;
68
+ }
69
+ }
70
+ function lookupCatalog(ref, catalog = FIRST_PARTY_WEIGHT_CATALOG) {
71
+ const want = ref.toLowerCase();
72
+ return catalog.find((e) => e.ref.toLowerCase() === want) ?? catalog.find((e) => want.includes(e.ref.toLowerCase()) || e.ref.toLowerCase().includes(want)) ?? null;
73
+ }
74
+ function isAllowedWeightUrl(url) {
75
+ try {
76
+ const u = new URL(url);
77
+ if (u.protocol !== "https:") return false;
78
+ return isAllowedWeightHost(u.hostname);
79
+ } catch {
80
+ return false;
81
+ }
82
+ }
83
+ var inflight = /* @__PURE__ */ new Map();
84
+ async function ensureWeightCached(ref, options = {}) {
85
+ const env = options.env ?? process.env;
86
+ const dest = weightPathForRef(ref, env);
87
+ if (isWeightCached(ref, env)) {
88
+ return { ok: true, path: dest, fromCache: true };
89
+ }
90
+ const existing = inflight.get(dest);
91
+ if (existing) return existing;
92
+ const work = (async () => {
93
+ if (isWeightCached(ref, env)) {
94
+ return { ok: true, path: dest, fromCache: true };
95
+ }
96
+ const entry = lookupCatalog(ref);
97
+ const url = options.url ?? entry?.url;
98
+ if (!url) {
99
+ return { ok: false, error: `no first-party download URL for weights ref "${ref}" \u2014 set a pack downloadUrl or place a gguf at ${dest}` };
100
+ }
101
+ if (!isAllowedWeightUrl(url)) {
102
+ return { ok: false, error: `weight URL host not allowlisted: ${url}` };
103
+ }
104
+ try {
105
+ fs.mkdirSync(path2.dirname(dest), { recursive: true });
106
+ const tmp = `${dest}.partial.${process.pid}.${Date.now()}`;
107
+ const fetchFn = options.fetchToFile ?? defaultFetchToFile;
108
+ options.onProgress?.(`downloading ${ref}`);
109
+ await fetchFn(url, tmp, options.onProgress);
110
+ const sha = (options.expectedSha256 ?? entry?.sha256)?.trim();
111
+ if (sha) {
112
+ const actual = sha256File(tmp);
113
+ if (actual !== sha.toLowerCase()) {
114
+ try {
115
+ fs.unlinkSync(tmp);
116
+ } catch {
117
+ }
118
+ return { ok: false, error: `sha256 mismatch for ${ref} (expected ${sha}, got ${actual})` };
119
+ }
120
+ } else if (entry && !entry.sha256) {
121
+ options.onProgress?.(`warning: ${ref} has no sha256 pin in catalog \u2014 integrity not verified`);
122
+ }
123
+ if (isWeightCached(ref, env)) {
124
+ try {
125
+ fs.unlinkSync(tmp);
126
+ } catch {
127
+ }
128
+ return { ok: true, path: dest, fromCache: true };
129
+ }
130
+ fs.renameSync(tmp, dest);
131
+ return { ok: true, path: dest, fromCache: false };
132
+ } catch (e) {
133
+ return { ok: false, error: e instanceof Error ? e.message : String(e) };
134
+ } finally {
135
+ inflight.delete(dest);
136
+ }
137
+ })();
138
+ inflight.set(dest, work);
139
+ return work;
140
+ }
141
+ function sha256File(file) {
142
+ const h = createHash("sha256");
143
+ h.update(fs.readFileSync(file));
144
+ return h.digest("hex");
145
+ }
146
+ function defaultFetchToFile(url, dest, onProgress) {
147
+ return new Promise((resolve, reject) => {
148
+ const get = (u, redirects) => {
149
+ if (redirects > 8) {
150
+ reject(new Error("too many redirects"));
151
+ return;
152
+ }
153
+ const lib = u.startsWith("https:") ? https : http;
154
+ const req = lib.get(u, (res) => {
155
+ const code = res.statusCode ?? 0;
156
+ if (code >= 300 && code < 400 && res.headers.location) {
157
+ const next = new URL(res.headers.location, u).href;
158
+ try {
159
+ const nextUrl = new URL(next);
160
+ if (nextUrl.protocol !== "https:" || !isAllowedWeightHost(nextUrl.hostname)) {
161
+ reject(new Error(`redirect host not allowlisted: ${nextUrl.hostname || next}`));
162
+ return;
163
+ }
164
+ } catch {
165
+ reject(new Error("invalid redirect URL"));
166
+ return;
167
+ }
168
+ res.resume();
169
+ get(next, redirects + 1);
170
+ return;
171
+ }
172
+ if (code !== 200) {
173
+ reject(new Error(`HTTP ${code} fetching weights`));
174
+ res.resume();
175
+ return;
176
+ }
177
+ const total = Number(res.headers["content-length"] || 0);
178
+ let got = 0;
179
+ const out = fs.createWriteStream(dest);
180
+ res.on("data", (chunk) => {
181
+ got += chunk.length;
182
+ if (total > 0 && got % (8 * 1024 * 1024) < chunk.length) {
183
+ onProgress?.(`${Math.floor(100 * got / total)}%`);
184
+ }
185
+ });
186
+ res.pipe(out);
187
+ out.on("finish", () => resolve());
188
+ out.on("error", reject);
189
+ res.on("error", reject);
190
+ });
191
+ req.on("error", reject);
192
+ };
193
+ get(url, 0);
194
+ });
195
+ }
196
+ function listCachedWeights(env = process.env) {
197
+ const dir = weightStoreDir(env);
198
+ try {
199
+ return fs.readdirSync(dir).filter((n) => n.endsWith(".gguf")).sort().map((n) => ({ name: n, path: path2.join(dir, n) }));
200
+ } catch {
201
+ return [];
202
+ }
203
+ }
204
+ function discoverModels(home = os.homedir()) {
205
+ return [...ollama(home), ...lmStudio(home), ...looseGguf(home), ...vibgrateWeightStore()].sort(
206
+ (a, b) => a.runtime.localeCompare(b.runtime) || a.name.localeCompare(b.name)
207
+ );
208
+ }
209
+ function vibgrateWeightStore() {
210
+ return listCachedWeights().map((w) => ({ runtime: "gguf", name: w.name, path: w.path }));
211
+ }
212
+ function ollama(home) {
213
+ const base = path2.join(home, ".ollama", "models", "manifests");
214
+ const out = [];
215
+ walk(base, 4, (file) => {
216
+ const rel = path2.relative(base, file).split(path2.sep);
217
+ if (rel.length >= 2) {
218
+ const tag = rel[rel.length - 1];
219
+ const model = rel[rel.length - 2];
220
+ out.push({ runtime: "ollama", name: `${model}:${tag}`, path: file });
221
+ }
222
+ });
223
+ return dedupe(out);
224
+ }
225
+ function lmStudio(home) {
226
+ const bases = [path2.join(home, ".lmstudio", "models"), path2.join(home, ".cache", "lm-studio", "models")];
227
+ const out = [];
228
+ for (const base of bases) {
229
+ walk(base, 5, (file) => {
230
+ if (!file.endsWith(".gguf")) return;
231
+ const rel = path2.relative(base, file).replace(/\\/g, "/");
232
+ out.push({ runtime: "lm-studio", name: rel, path: file });
233
+ });
234
+ }
235
+ return dedupe(out);
236
+ }
237
+ function looseGguf(home) {
238
+ const bases = [path2.join(home, "models"), path2.join(home, ".cache", "huggingface")];
239
+ const out = [];
240
+ for (const base of bases) {
241
+ walk(base, 4, (file) => {
242
+ if (!file.endsWith(".gguf")) return;
243
+ out.push({ runtime: "gguf", name: path2.basename(file), path: file });
244
+ });
245
+ }
246
+ return dedupe(out);
247
+ }
248
+ function walk(dir, depth, onFile) {
249
+ if (depth < 0) return;
250
+ let entries;
251
+ try {
252
+ entries = fs.readdirSync(dir, { withFileTypes: true });
253
+ } catch {
254
+ return;
255
+ }
256
+ for (const e of entries.sort((a, b) => a.name.localeCompare(b.name))) {
257
+ const abs = path2.join(dir, e.name);
258
+ if (e.isDirectory()) walk(abs, depth - 1, onFile);
259
+ else if (e.isFile()) onFile(abs);
260
+ }
261
+ }
262
+ function dedupe(models) {
263
+ const seen = /* @__PURE__ */ new Set();
264
+ const out = [];
265
+ for (const m of models) {
266
+ const key = `${m.runtime}:${m.name}`;
267
+ if (seen.has(key)) continue;
268
+ seen.add(key);
269
+ out.push(m);
270
+ }
271
+ return out;
272
+ }
273
+
274
+ export { catalogIntegrityReport, discoverModels, ensureWeightCached, isWeightCached, listCachedWeights, lookupCatalog, weightPathForRef, weightStoreDir };
275
+ //# sourceMappingURL=chunk-OOIG3RUM.js.map
276
+ //# sourceMappingURL=chunk-OOIG3RUM.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/runtime/weight-store.ts","../src/engine/models.ts"],"names":["path","fs2"],"mappings":"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","file":"chunk-OOIG3RUM.js","sourcesContent":["/**\n * First-party weight store — content-addressed GGUF cache under the Vibgrate\n * cache root (never in-repo). Complements Ollama as a download channel so\n * embedded llama.cpp packs need not depend on a third-party app for weights.\n *\n * Only HTTPS URLs from an allowlist (or pack-declared URLs that pass the same\n * host allowlist) are fetched. No auto-download except via explicit\n * `vg models install` / executor consent.\n */\n\nimport * as fs from 'node:fs';\nimport * as path from 'node:path';\nimport * as https from 'node:https';\nimport * as http from 'node:http';\nimport { createHash } from 'node:crypto';\nimport { vibgrateCacheDir } from './paths.js';\n\nexport const WEIGHT_STORE_SCHEMA = 'weight-store/0' as const;\n\n/** Hosts we will download weights from (no arbitrary open proxy). */\nexport const WEIGHT_DOWNLOAD_HOST_ALLOWLIST = new Set([\n 'huggingface.co',\n 'hf.co',\n 'cdn-lfs.huggingface.co',\n 'cdn-lfs-us-1.huggingface.co',\n 'us.aws.cdn.hf.co',\n 'cas-server.xethub.hf.co',\n 'objects.githubusercontent.com',\n 'github.com',\n]);\n\n/** Host suffixes allowed for HF LFS / Xet CDN redirects. */\nexport function isAllowedWeightHost(hostname: string): boolean {\n const h = hostname.toLowerCase();\n if (WEIGHT_DOWNLOAD_HOST_ALLOWLIST.has(h)) return true;\n if (h.endsWith('.huggingface.co')) return true;\n if (h.endsWith('.hf.co')) return true;\n if (h.endsWith('.cdn.hf.co')) return true;\n return false;\n}\n\nexport interface WeightCatalogEntry {\n /** Stable ref (matches pack weightsRef or basename). */\n ref: string;\n /** HTTPS URL to the GGUF (or redirected LFS object). */\n url: string;\n /** Optional expected size for progress UX. */\n bytes?: number;\n license?: string;\n /**\n * When set, download **must** match this sha256 or install fails (B6).\n * Leave unset only while pinning is pending — status reports unpinned.\n */\n sha256?: string;\n /** Pack channel this entry was verified against. */\n packChannel?: string;\n}\n\n/**\n * Curated first-party catalog — small, versioned with packs. Not a general hub.\n * URLs point at public Hugging Face GGUF artifacts for Qwen2.5-Coder.\n *\n * Integrity: sha256 pins are required for production installs once verified.\n * Entries without sha256 are marked unpinned in {@link catalogIntegrityReport}\n * and still download, but CI should fail if any pack primary lacks a pin.\n */\nexport const FIRST_PARTY_WEIGHT_CATALOG: WeightCatalogEntry[] = [\n {\n ref: 'qwen2.5-coder-3b-q4_k_m.gguf',\n url: 'https://huggingface.co/Qwen/Qwen2.5-Coder-3B-Instruct-GGUF/resolve/main/qwen2.5-coder-3b-instruct-q4_k_m.gguf',\n license: 'Apache-2.0',\n packChannel: '2026.07.3',\n // Git LFS oid = content sha256 (from HF API tree, 2026-07-27).\n sha256: '724fb256bec1ff062b2f65e4569e871ad2e95ab2a3989723d1769c54294730b7',\n bytes: 2_104_932_800,\n },\n {\n ref: 'qwen2.5-coder-7b-q4_k_m.gguf',\n url: 'https://huggingface.co/Qwen/Qwen2.5-Coder-7B-Instruct-GGUF/resolve/main/qwen2.5-coder-7b-instruct-q4_k_m.gguf',\n license: 'Apache-2.0',\n packChannel: '2026.07.3',\n sha256: '509287f78cb4d4cf6b3843734733b914b2c158e43e22a7f4bf5e963800894d3c',\n bytes: 4_683_073_536,\n },\n];\n\nexport interface CatalogIntegrityReport {\n total: number;\n pinned: number;\n unpinned: string[];\n /** True when every entry has sha256. */\n complete: boolean;\n}\n\nexport function catalogIntegrityReport(\n catalog: WeightCatalogEntry[] = FIRST_PARTY_WEIGHT_CATALOG,\n): CatalogIntegrityReport {\n const unpinned = catalog.filter((e) => !e.sha256?.trim()).map((e) => e.ref);\n return {\n total: catalog.length,\n pinned: catalog.length - unpinned.length,\n unpinned,\n complete: unpinned.length === 0,\n };\n}\n\n/** Require sha256 on every catalog entry (CI gate for pack releases). */\nexport function assertCatalogPinned(catalog: WeightCatalogEntry[] = FIRST_PARTY_WEIGHT_CATALOG): void {\n const report = catalogIntegrityReport(catalog);\n if (!report.complete) {\n throw new Error(\n `weight catalog incomplete: ${report.unpinned.length}/${report.total} entries missing sha256: ${report.unpinned.join(', ')}`,\n );\n }\n}\n\nexport function weightStoreDir(env: NodeJS.ProcessEnv = process.env): string {\n return path.join(vibgrateCacheDir(env), 'weights');\n}\n\nexport function weightPathForRef(ref: string, env: NodeJS.ProcessEnv = process.env): string {\n const base = path.basename(ref).replace(/[^a-zA-Z0-9._+-]/g, '_');\n return path.join(weightStoreDir(env), base);\n}\n\nexport function isWeightCached(ref: string, env: NodeJS.ProcessEnv = process.env): boolean {\n try {\n const p = weightPathForRef(ref, env);\n return fs.existsSync(p) && fs.statSync(p).size > 0;\n } catch {\n return false;\n }\n}\n\nexport function lookupCatalog(ref: string, catalog: WeightCatalogEntry[] = FIRST_PARTY_WEIGHT_CATALOG): WeightCatalogEntry | null {\n const want = ref.toLowerCase();\n return (\n catalog.find((e) => e.ref.toLowerCase() === want) ??\n catalog.find((e) => want.includes(e.ref.toLowerCase()) || e.ref.toLowerCase().includes(want)) ??\n null\n );\n}\n\nexport function isAllowedWeightUrl(url: string): boolean {\n try {\n const u = new URL(url);\n if (u.protocol !== 'https:') return false;\n return isAllowedWeightHost(u.hostname);\n } catch {\n return false;\n }\n}\n\nexport interface DownloadWeightOptions {\n env?: NodeJS.ProcessEnv;\n /** Override catalog URL. */\n url?: string;\n expectedSha256?: string;\n onProgress?: (line: string) => void;\n /** Injectable fetch for tests. */\n fetchToFile?: (url: string, dest: string, onProgress?: (line: string) => void) => Promise<void>;\n}\n\nexport interface DownloadWeightResult {\n ok: boolean;\n path?: string;\n error?: string;\n fromCache?: boolean;\n}\n\n/** In-flight downloads: one network fetch per dest path (concurrent install-safe). */\nconst inflight = new Map<string, Promise<DownloadWeightResult>>();\n\n/**\n * Ensure weights for `ref` exist in the first-party store. Downloads when missing.\n * Concurrent callers for the same ref share a single download promise.\n */\nexport async function ensureWeightCached(ref: string, options: DownloadWeightOptions = {}): Promise<DownloadWeightResult> {\n const env = options.env ?? process.env;\n const dest = weightPathForRef(ref, env);\n if (isWeightCached(ref, env)) {\n return { ok: true, path: dest, fromCache: true };\n }\n\n const existing = inflight.get(dest);\n if (existing) return existing;\n\n const work = (async (): Promise<DownloadWeightResult> => {\n // Re-check after joining the queue.\n if (isWeightCached(ref, env)) {\n return { ok: true, path: dest, fromCache: true };\n }\n\n const entry = lookupCatalog(ref);\n const url = options.url ?? entry?.url;\n if (!url) {\n return { ok: false, error: `no first-party download URL for weights ref \"${ref}\" — set a pack downloadUrl or place a gguf at ${dest}` };\n }\n if (!isAllowedWeightUrl(url)) {\n return { ok: false, error: `weight URL host not allowlisted: ${url}` };\n }\n\n try {\n fs.mkdirSync(path.dirname(dest), { recursive: true });\n const tmp = `${dest}.partial.${process.pid}.${Date.now()}`;\n const fetchFn = options.fetchToFile ?? defaultFetchToFile;\n options.onProgress?.(`downloading ${ref}`);\n await fetchFn(url, tmp, options.onProgress);\n const sha = (options.expectedSha256 ?? entry?.sha256)?.trim();\n if (sha) {\n const actual = sha256File(tmp);\n if (actual !== sha.toLowerCase()) {\n try {\n fs.unlinkSync(tmp);\n } catch {\n /* ignore */\n }\n return { ok: false, error: `sha256 mismatch for ${ref} (expected ${sha}, got ${actual})` };\n }\n } else if (entry && !entry.sha256) {\n options.onProgress?.(`warning: ${ref} has no sha256 pin in catalog — integrity not verified`);\n }\n // Atomic publish: if another worker won the race, drop our partial.\n if (isWeightCached(ref, env)) {\n try {\n fs.unlinkSync(tmp);\n } catch {\n /* ignore */\n }\n return { ok: true, path: dest, fromCache: true };\n }\n fs.renameSync(tmp, dest);\n return { ok: true, path: dest, fromCache: false };\n } catch (e) {\n return { ok: false, error: e instanceof Error ? e.message : String(e) };\n } finally {\n inflight.delete(dest);\n }\n })();\n\n inflight.set(dest, work);\n return work;\n}\n\nfunction sha256File(file: string): string {\n const h = createHash('sha256');\n h.update(fs.readFileSync(file));\n return h.digest('hex');\n}\n\n/** Minimal HTTPS GET with redirect follow (tests inject fetchToFile). */\nexport function defaultFetchToFile(url: string, dest: string, onProgress?: (line: string) => void): Promise<void> {\n return new Promise((resolve, reject) => {\n const get = (u: string, redirects: number): void => {\n if (redirects > 8) {\n reject(new Error('too many redirects'));\n return;\n }\n const lib = u.startsWith('https:') ? https : http;\n const req = lib.get(u, (res) => {\n const code = res.statusCode ?? 0;\n if (code >= 300 && code < 400 && res.headers.location) {\n const next = new URL(res.headers.location, u).href;\n // Redirects must stay on HTTPS + allowlisted hosts (incl. HF LFS/Xet CDNs).\n try {\n const nextUrl = new URL(next);\n if (nextUrl.protocol !== 'https:' || !isAllowedWeightHost(nextUrl.hostname)) {\n reject(new Error(`redirect host not allowlisted: ${nextUrl.hostname || next}`));\n return;\n }\n } catch {\n reject(new Error('invalid redirect URL'));\n return;\n }\n res.resume();\n get(next, redirects + 1);\n return;\n }\n if (code !== 200) {\n reject(new Error(`HTTP ${code} fetching weights`));\n res.resume();\n return;\n }\n const total = Number(res.headers['content-length'] || 0);\n let got = 0;\n const out = fs.createWriteStream(dest);\n res.on('data', (chunk: Buffer) => {\n got += chunk.length;\n if (total > 0 && got % (8 * 1024 * 1024) < chunk.length) {\n onProgress?.(`${Math.floor((100 * got) / total)}%`);\n }\n });\n res.pipe(out);\n out.on('finish', () => resolve());\n out.on('error', reject);\n res.on('error', reject);\n });\n req.on('error', reject);\n };\n get(url, 0);\n });\n}\n\n/** List GGUF files already in the first-party store (for discovery). */\nexport function listCachedWeights(env: NodeJS.ProcessEnv = process.env): Array<{ name: string; path: string }> {\n const dir = weightStoreDir(env);\n try {\n return fs\n .readdirSync(dir)\n .filter((n) => n.endsWith('.gguf'))\n .sort()\n .map((n) => ({ name: n, path: path.join(dir, n) }));\n } catch {\n return [];\n }\n}\n","import * as fs from 'node:fs';\nimport * as os from 'node:os';\nimport * as path from 'node:path';\nimport { listCachedWeights } from '../runtime/weight-store.js';\n\n/**\n * Local-model discovery (VG-LOCAL-MODELS §9.2) — be a no-key *consumer* of the\n * developer's local model fleet. Fully offline and deterministic: inspect the\n * on-disk layouts of Ollama / LM Studio / llama.cpp / the Vibgrate weight store,\n * never the network. No runtime is built or launched.\n */\n\nexport interface LocalModel {\n runtime: 'ollama' | 'lm-studio' | 'gguf';\n name: string;\n path: string;\n}\n\nexport function discoverModels(home = os.homedir()): LocalModel[] {\n return [...ollama(home), ...lmStudio(home), ...looseGguf(home), ...vibgrateWeightStore()].sort(\n (a, b) => a.runtime.localeCompare(b.runtime) || a.name.localeCompare(b.name),\n );\n}\n\n/** First-party GGUF cache (runtime/weight-store.ts). */\nfunction vibgrateWeightStore(): LocalModel[] {\n return listCachedWeights().map((w) => ({ runtime: 'gguf' as const, name: w.name, path: w.path }));\n}\n\nfunction ollama(home: string): LocalModel[] {\n const base = path.join(home, '.ollama', 'models', 'manifests');\n const out: LocalModel[] = [];\n walk(base, 4, (file) => {\n // .../library/<model>/<tag>\n const rel = path.relative(base, file).split(path.sep);\n if (rel.length >= 2) {\n const tag = rel[rel.length - 1];\n const model = rel[rel.length - 2];\n out.push({ runtime: 'ollama', name: `${model}:${tag}`, path: file });\n }\n });\n return dedupe(out);\n}\n\nfunction lmStudio(home: string): LocalModel[] {\n const bases = [path.join(home, '.lmstudio', 'models'), path.join(home, '.cache', 'lm-studio', 'models')];\n const out: LocalModel[] = [];\n for (const base of bases) {\n walk(base, 5, (file) => {\n if (!file.endsWith('.gguf')) return;\n const rel = path.relative(base, file).replace(/\\\\/g, '/');\n out.push({ runtime: 'lm-studio', name: rel, path: file });\n });\n }\n return dedupe(out);\n}\n\nfunction looseGguf(home: string): LocalModel[] {\n const bases = [path.join(home, 'models'), path.join(home, '.cache', 'huggingface')];\n const out: LocalModel[] = [];\n for (const base of bases) {\n walk(base, 4, (file) => {\n if (!file.endsWith('.gguf')) return;\n out.push({ runtime: 'gguf', name: path.basename(file), path: file });\n });\n }\n return dedupe(out);\n}\n\nfunction walk(dir: string, depth: number, onFile: (file: string) => void): void {\n if (depth < 0) return;\n let entries: fs.Dirent[];\n try {\n entries = fs.readdirSync(dir, { withFileTypes: true });\n } catch {\n return;\n }\n for (const e of entries.sort((a, b) => a.name.localeCompare(b.name))) {\n const abs = path.join(dir, e.name);\n if (e.isDirectory()) walk(abs, depth - 1, onFile);\n else if (e.isFile()) onFile(abs);\n }\n}\n\nfunction dedupe(models: LocalModel[]): LocalModel[] {\n const seen = new Set<string>();\n const out: LocalModel[] = [];\n for (const m of models) {\n const key = `${m.runtime}:${m.name}`;\n if (seen.has(key)) continue;\n seen.add(key);\n out.push(m);\n }\n return out;\n}\n"]}
@@ -1,5 +1,6 @@
1
- import { buildCodeContext, buildMessages, parseEdits, applyEdits, unifiedDiff, redactSecrets } from './chunk-CS37OBE3.js';
2
- import { recordCliCall, CLI_TOOL_ALIASES } from './chunk-WNIIKCNF.js';
1
+ import { buildMessages, parseEdits, applyEdits, unifiedDiff, redactSecrets } from './chunk-7JHPQ6WF.js';
2
+ import { recordCliCall, CLI_TOOL_ALIASES, buildCodeContext, buildTaskCapsule, capsuleToCodeContext } from './chunk-EDAAG7BL.js';
3
+ import { repositoryIdFromRoot } from './chunk-BWPBB45M.js';
3
4
  import * as fs from 'fs';
4
5
  import * as path from 'path';
5
6
 
@@ -25,8 +26,14 @@ async function runCodeSession(options) {
25
26
  phasesRun.push(p);
26
27
  onPhase(p, detail);
27
28
  };
28
- phase("inspect", "building graph-grounded context");
29
- const context = buildCodeContext(graph, instruction, { budget, files });
29
+ phase("inspect", options.capsule ? "building source-bearing task capsule" : "building graph-grounded context");
30
+ const context = buildSessionContext(graph, instruction, {
31
+ budget,
32
+ files,
33
+ capsule: options.capsule,
34
+ root,
35
+ fsImpl
36
+ });
30
37
  if (options.attribution?.client) {
31
38
  const seedFiles = new Set(context.seeds.map((s) => s.node.file).filter(Boolean));
32
39
  recordCliCall(
@@ -128,6 +135,20 @@ function undoChanges(changes, fsImpl) {
128
135
  }
129
136
  return restored;
130
137
  }
138
+ function buildSessionContext(graph, instruction, opts) {
139
+ const budget = opts.budget;
140
+ const files = opts.files;
141
+ if (!opts.capsule) {
142
+ return buildCodeContext(graph, instruction, { budget, files });
143
+ }
144
+ const capsule = buildTaskCapsule(graph, instruction, {
145
+ budget,
146
+ files,
147
+ readFile: (rel) => opts.fsImpl.read(rel),
148
+ repositoryId: repositoryIdFromRoot(opts.root)
149
+ });
150
+ return capsuleToCodeContext(capsule);
151
+ }
131
152
  async function complete(providers, messages, chatOptions, correlationId) {
132
153
  if (providers.length === 0) throw new Error(`no model provider available (ref ${correlationId})`);
133
154
  let lastErr;
@@ -230,5 +251,5 @@ function shortId() {
230
251
  }
231
252
 
232
253
  export { commitChanges, nodeCodeFs, runCodeSession, undoChanges };
233
- //# sourceMappingURL=chunk-6CXTPC74.js.map
234
- //# sourceMappingURL=chunk-6CXTPC74.js.map
254
+ //# sourceMappingURL=chunk-OXQNQW5J.js.map
255
+ //# sourceMappingURL=chunk-OXQNQW5J.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/code/session.ts"],"names":["resolve"],"mappings":"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","file":"chunk-OXQNQW5J.js","sourcesContent":["/**\n * The `vg code` governance session (VG-CLI-CODE §7).\n *\n * This is the load-bearing rule the whole platform is built on, applied to code\n * edits: a state-altering change goes **through** the lifecycle, never around it\n * (GUARDRAILS §5). One run walks inspect → assess → dry-run → approve → execute\n * → verify → log:\n *\n * inspect build the graph-grounded context for the instruction\n * assess ask the routed model for a terse edit; apply it deterministically\n * (in memory); compute the diff and the blast radius\n * dry-run the DEFAULT terminal state — propose the change, write nothing\n * approve writing requires explicit consent; without it we stop at dry-run\n * execute write the approved changes to disk\n * verify confirm the files on disk match what was approved (+ optional cmd)\n * log append an immutable, secret-free audit record with a correlation id\n *\n * Everything is deterministic except the single model call, which is isolated\n * behind the provider list (tried in order, falling back on transport failure).\n * The filesystem and clock are injectable so the whole session is testable\n * offline with no writes escaping a temp dir.\n */\n\nimport * as fs from 'node:fs';\nimport * as path from 'node:path';\nimport { buildCodeContext } from './context.js';\nimport { buildTaskCapsule, capsuleToCodeContext } from './capsule.js';\nimport { recordCliCall, CLI_TOOL_ALIASES } from '../engine/savings.js';\nimport { repositoryIdFromRoot } from '../runtime/paths.js';\nimport { parseEdits, applyEdits, type SymbolSpan } from './apply.js';\nimport { unifiedDiff } from './diff.js';\nimport { buildMessages } from './prompt.js';\nimport { redactSecrets } from './providers.js';\nimport type { ChatOptions, CodeContext, CodeSessionResult, FileChange, LifecyclePhase, Provider, ProviderResult } from './types.js';\nimport type { VgGraph } from '../schema.js';\n\n/** Minimal filesystem seam so the session is testable without touching real disk. */\nexport interface CodeFs {\n read(file: string): string | null;\n write(file: string, content: string): void;\n remove(file: string): void;\n appendAudit(line: string): void;\n}\n\nexport interface RunSessionOptions {\n graph: VgGraph;\n root: string;\n instruction: string;\n /** Providers to try in order (from the router); the first that answers wins. */\n providers: Provider[];\n /** Write to disk? Default false — dry-run is the safe default (GUARDRAILS §3.2). */\n apply?: boolean;\n /** Explicit consent for the write (`--yes`); without it, a requested apply stops at dry-run. */\n consent?: boolean;\n /** Restrict the edit surface to these files. */\n files?: string[];\n /** Context token budget. */\n budget?: number;\n chatOptions?: ChatOptions;\n /** Injectable filesystem (defaults to a real, root-scoped fs). */\n fsImpl?: CodeFs;\n /** Injectable clock (ms) for the audit timestamp. */\n now?: () => number;\n /** Injectable correlation id (defaults to a random short id). */\n correlationId?: string;\n /** Progress callback per phase. */\n onPhase?: (phase: LifecyclePhase, detail: string) => void;\n /** Skip appending to the audit log (used by tests/dry programmatic calls). */\n noAudit?: boolean;\n /**\n * Who is making the graph-backed call, for per-model savings auditing. When\n * `client` is set, the context-assembly step (a `query_graph`-equivalent) is\n * recorded to the local savings ledger tagged with the provider + model, so\n * `vg savings` can break usage down per model. VG Code always sets this.\n */\n attribution?: { client: string; provider?: string; model?: string };\n /**\n * Use a source-bearing Task Capsule for the inspect context (Fusion Runtime\n * Phase 0 A/B). Default false keeps the metadata-only path.\n */\n capsule?: boolean;\n}\n\nexport async function runCodeSession(options: RunSessionOptions): Promise<CodeSessionResult> {\n const {\n graph,\n root,\n instruction,\n providers,\n apply = false,\n consent = false,\n files,\n budget,\n chatOptions,\n now = () => 0,\n onPhase = () => {},\n } = options;\n const fsImpl = options.fsImpl ?? nodeCodeFs(root);\n const correlationId = options.correlationId ?? shortId();\n const phasesRun: LifecyclePhase[] = [];\n const phase = (p: LifecyclePhase, detail: string): void => {\n phasesRun.push(p);\n onPhase(p, detail);\n };\n\n // ── inspect ──────────────────────────────────────────────────────────────\n phase('inspect', options.capsule ? 'building source-bearing task capsule' : 'building graph-grounded context');\n const context = buildSessionContext(graph, instruction, {\n budget,\n files,\n capsule: options.capsule,\n root,\n fsImpl,\n });\n\n // Per-model savings: the context build is VG Code's `query_graph`-equivalent.\n // Record it (counts only — never code or the instruction) tagged with the\n // model, so `vg savings` audits usage per model. Local-only, best-effort.\n if (options.attribution?.client) {\n const seedFiles = new Set(context.seeds.map((s) => s.node.file).filter(Boolean));\n recordCliCall(\n root,\n {\n tool: CLI_TOOL_ALIASES.ask,\n client: options.attribution.client,\n provider: options.attribution.provider,\n model: options.attribution.model,\n outcome: context.seeds.length ? 'complete' : 'miss',\n vgTokens: context.tokensEstimate,\n baselineFiles: seedFiles.size,\n },\n now(),\n );\n }\n\n // ── assess ──────────────────────────────────────────────────────────────\n phase('assess', 'asking the routed model for a minimal edit');\n const messages = buildMessages(context);\n const { result, provider, fellBack } = await complete(providers, messages, chatOptions, correlationId);\n\n const edits = parseEdits(result.text);\n const spans = spanIndex(graph);\n const applied = applyEdits(\n edits,\n (file) => fsImpl.read(file),\n (file) => spans.get(normalize(file)) ?? [],\n );\n\n const changes: FileChange[] = [];\n for (const [file, entry] of [...applied.entries()].sort((a, b) => a[0].localeCompare(b[0]))) {\n changes.push({\n file,\n before: entry.before,\n after: entry.after,\n outcomes: entry.outcomes,\n diff: unifiedDiff(entry.before, entry.after, file),\n });\n }\n\n // ── dry-run (always produced) ─────────────────────────────────────────────\n phase('dry-run', `${changes.length} file(s) would change`);\n\n const anyApplicable = changes.some((c) => c.diff !== '' && c.outcomes.some((o) => o.status === 'applied'));\n const base: CodeSessionResult = {\n instruction,\n provider: { id: provider.id, model: provider.model, local: provider.local, fellBack },\n phasesRun,\n changes,\n applied: false,\n verification: { ran: false, ok: false, detail: 'dry-run — no changes written' },\n correlationId,\n };\n\n // ── approve ───────────────────────────────────────────────────────────────\n // Writing is opt-in AND consent-gated. A requested apply without consent is\n // not an error — it degrades to a dry-run so the caller can review, then\n // re-run with --yes. This is the \"never destructive-by-default\" guardrail.\n if (!apply) {\n if (!options.noAudit) writeAudit(fsImpl, base, now());\n return base;\n }\n if (!consent) {\n const stopped = { ...base, verification: { ran: false, ok: false, detail: 'apply requested without consent — re-run with --yes to write these changes' } };\n if (!options.noAudit) writeAudit(fsImpl, stopped, now());\n return stopped;\n }\n if (!anyApplicable) {\n const nothing = { ...base, verification: { ran: false, ok: false, detail: 'nothing to write — no edit applied cleanly' } };\n if (!options.noAudit) writeAudit(fsImpl, nothing, now());\n return nothing;\n }\n phase('approve', 'consent given (--yes)');\n\n // ── execute ───────────────────────────────────────────────────────────────\n phase('execute', 'writing approved changes');\n for (const change of changes) {\n if (change.diff === '') continue; // no-op file\n if (!change.outcomes.some((o) => o.status === 'applied')) continue; // nothing applied cleanly here\n if (change.after === null) fsImpl.remove(change.file);\n else fsImpl.write(change.file, change.after);\n }\n\n // ── verify ────────────────────────────────────────────────────────────────\n phase('verify', 'confirming on-disk content matches the approved change');\n const verification = verifyWrites(fsImpl, changes);\n\n // ── log ───────────────────────────────────────────────────────────────────\n phase('log', 'recording an audit entry');\n const final: CodeSessionResult = { ...base, applied: true, verification };\n if (!options.noAudit) writeAudit(fsImpl, final, now());\n return final;\n}\n\n/**\n * Commit an already-computed dry-run result: write the cleanly-applied changes,\n * verify them on disk, and append the audit record — the \"approve → execute →\n * verify → log\" tail of the lifecycle, run against a proposal the caller has\n * already shown and had approved (the interactive REPL uses this so it never\n * calls the model twice or writes something different from what was reviewed).\n */\nexport function commitChanges(result: CodeSessionResult, fsImpl: CodeFs, now: () => number = () => 0): CodeSessionResult {\n const anyApplicable = result.changes.some((c) => c.diff !== '' && c.outcomes.some((o) => o.status === 'applied'));\n if (!anyApplicable) {\n return { ...result, applied: false, verification: { ran: false, ok: false, detail: 'nothing to write — no edit applied cleanly' } };\n }\n for (const change of result.changes) {\n if (change.diff === '' || !change.outcomes.some((o) => o.status === 'applied')) continue;\n if (change.after === null) fsImpl.remove(change.file);\n else fsImpl.write(change.file, change.after);\n }\n const verification = verifyWrites(fsImpl, result.changes);\n const final: CodeSessionResult = { ...result, applied: true, verification, phasesRun: [...result.phasesRun, 'approve', 'execute', 'verify', 'log'] };\n writeAudit(fsImpl, final, now());\n return final;\n}\n\n/**\n * Undo a set of applied changes by restoring each file's prior content — the\n * `/undo` command. A created file (before === null) is removed; an edited or\n * deleted file is restored to its `before`. Only cleanly-applied changes are\n * reverted. Returns the files it restored.\n */\nexport function undoChanges(changes: FileChange[], fsImpl: CodeFs): string[] {\n const restored: string[] = [];\n for (const ch of changes) {\n if (!ch.outcomes.some((o) => o.status === 'applied')) continue;\n if (ch.before === null) fsImpl.remove(ch.file);\n else fsImpl.write(ch.file, ch.before);\n restored.push(ch.file);\n }\n return restored;\n}\n\nfunction buildSessionContext(\n graph: VgGraph,\n instruction: string,\n opts: { budget?: number; files?: string[]; capsule?: boolean; root: string; fsImpl: CodeFs },\n): CodeContext {\n const budget = opts.budget;\n const files = opts.files;\n if (!opts.capsule) {\n return buildCodeContext(graph, instruction, { budget, files });\n }\n const capsule = buildTaskCapsule(graph, instruction, {\n budget,\n files,\n readFile: (rel) => opts.fsImpl.read(rel),\n repositoryId: repositoryIdFromRoot(opts.root),\n });\n return capsuleToCodeContext(capsule);\n}\n\n/** Try each provider in order; fall back on transport failure. Throws the last actionable error. */\nasync function complete(\n providers: Provider[],\n messages: ReturnType<typeof buildMessages>,\n chatOptions: ChatOptions | undefined,\n correlationId: string,\n): Promise<{ result: ProviderResult; provider: Provider; fellBack: boolean }> {\n if (providers.length === 0) throw new Error(`no model provider available (ref ${correlationId})`);\n let lastErr: unknown;\n for (let i = 0; i < providers.length; i++) {\n const provider = providers[i];\n try {\n const result = await provider.chat(messages, { temperature: 0, ...chatOptions });\n return { result, provider, fellBack: i > 0 };\n } catch (e) {\n lastErr = e;\n }\n }\n const message = lastErr instanceof Error ? redactSecrets(lastErr.message) : String(lastErr);\n throw new Error(`${message} (ref ${correlationId})`);\n}\n\n/** Confirm each written file's on-disk content equals what we approved. */\nfunction verifyWrites(fsImpl: CodeFs, changes: FileChange[]): { ran: boolean; ok: boolean; detail: string } {\n let checked = 0;\n const mismatches: string[] = [];\n for (const change of changes) {\n if (change.diff === '' || !change.outcomes.some((o) => o.status === 'applied')) continue;\n checked++;\n const onDisk = fsImpl.read(change.file);\n if (onDisk !== change.after) mismatches.push(change.file);\n }\n if (mismatches.length) return { ran: true, ok: false, detail: `on-disk content differs for: ${mismatches.join(', ')}` };\n return { ran: true, ok: true, detail: `wrote and verified ${checked} file(s)` };\n}\n\n/** An append-only, secret-free audit record (GUARDRAILS §2.6 / §5). No file contents, no keys. */\nfunction writeAudit(fsImpl: CodeFs, r: CodeSessionResult, ts: number): void {\n const record = {\n ts,\n correlationId: r.correlationId,\n instruction: r.instruction.slice(0, 500),\n provider: r.provider.id,\n model: r.provider.model,\n local: r.provider.local,\n applied: r.applied,\n files: r.changes.map((c) => ({ file: c.file, statuses: c.outcomes.map((o) => o.status) })),\n verification: r.verification,\n phases: r.phasesRun,\n };\n try {\n fsImpl.appendAudit(JSON.stringify(record));\n } catch {\n /* audit is best-effort; never fail the run on a logging problem */\n }\n}\n\n/** Build a per-file map of symbol spans for graph-scoped edit disambiguation. */\nfunction spanIndex(graph: VgGraph): Map<string, SymbolSpan[]> {\n const map = new Map<string, SymbolSpan[]>();\n for (const n of graph.nodes) {\n if (n.kind === 'file' || n.kind === 'external') continue;\n const file = normalize(n.file);\n const list = map.get(file) ?? [];\n list.push({ qualifiedName: n.qualifiedName, file, start: n.span.start, end: n.span.end });\n map.set(file, list);\n }\n return map;\n}\n\nfunction normalize(file: string): string {\n return file.replace(/\\\\/g, '/').replace(/^\\.\\//, '');\n}\n\n/** Default filesystem impl, scoped to `root`. Refuses paths that escape the root. */\nexport function nodeCodeFs(root: string): CodeFs {\n const resolve = (file: string): string => {\n const abs = path.resolve(root, file);\n const rel = path.relative(root, abs);\n if (rel.startsWith('..') || path.isAbsolute(rel)) {\n throw new Error(`edit path escapes the project root: ${file} — refusing to touch files outside ${root}`);\n }\n return abs;\n };\n return {\n read(file) {\n try {\n return fs.readFileSync(resolve(file), 'utf8');\n } catch {\n return null;\n }\n },\n write(file, content) {\n const abs = resolve(file);\n fs.mkdirSync(path.dirname(abs), { recursive: true });\n fs.writeFileSync(abs, content);\n },\n remove(file) {\n try {\n fs.rmSync(resolve(file));\n } catch {\n /* already gone */\n }\n },\n appendAudit(line) {\n const dir = path.join(root, '.vibgrate');\n fs.mkdirSync(dir, { recursive: true });\n fs.appendFileSync(path.join(dir, 'code-audit.jsonl'), line + '\\n');\n },\n };\n}\n\n/** Short, URL-safe correlation id. Not a graph artifact, so runtime randomness is fine here. */\nfunction shortId(): string {\n let s = '';\n const alphabet = 'abcdefghijklmnopqrstuvwxyz0123456789';\n for (let i = 0; i < 8; i++) s += alphabet[Math.floor(Math.random() * alphabet.length)];\n return s;\n}\n"]}
@@ -0,0 +1,62 @@
1
+ import { daemonDir } from './chunk-BWPBB45M.js';
2
+ import * as path from 'path';
3
+ import * as net from 'net';
4
+
5
+ function vgdSocketPath(env = process.env, platform = process.platform) {
6
+ if (platform === "win32") {
7
+ return path.join("\\\\.\\pipe", "vibgrate-vgd");
8
+ }
9
+ return path.join(daemonDir(env, platform), "vgd.sock");
10
+ }
11
+ function vgdPidPath(env = process.env, platform = process.platform) {
12
+ return path.join(daemonDir(env, platform), "vgd.pid");
13
+ }
14
+ function vgdRequest(request, options = {}) {
15
+ const socketPath = options.socketPath ?? vgdSocketPath();
16
+ const timeoutMs = options.timeoutMs ?? 2e3;
17
+ return new Promise((resolve, reject) => {
18
+ const socket = net.createConnection(socketPath);
19
+ let settled = false;
20
+ let buffer = "";
21
+ const finish = (err, value) => {
22
+ if (settled) return;
23
+ settled = true;
24
+ clearTimeout(timer);
25
+ socket.destroy();
26
+ if (err) reject(err);
27
+ else resolve(value);
28
+ };
29
+ const timer = setTimeout(() => finish(new Error(`vgd did not respond within ${timeoutMs}ms`)), timeoutMs);
30
+ socket.setEncoding("utf8");
31
+ socket.on("connect", () => {
32
+ socket.write(JSON.stringify(request) + "\n");
33
+ });
34
+ socket.on("data", (chunk) => {
35
+ buffer += chunk;
36
+ const nl = buffer.indexOf("\n");
37
+ if (nl < 0) return;
38
+ const line = buffer.slice(0, nl).trim();
39
+ try {
40
+ finish(void 0, JSON.parse(line));
41
+ } catch (e) {
42
+ finish(e instanceof Error ? e : new Error(String(e)));
43
+ }
44
+ });
45
+ socket.on("error", (err) => finish(err));
46
+ socket.on("end", () => {
47
+ if (!settled) finish(new Error("vgd closed the connection before responding"));
48
+ });
49
+ });
50
+ }
51
+ async function vgdIsRunning(options = {}) {
52
+ try {
53
+ const res = await vgdRequest({ op: "ping" }, options);
54
+ return res.ok === true && "pong" in res && res.pong === true;
55
+ } catch {
56
+ return false;
57
+ }
58
+ }
59
+
60
+ export { vgdIsRunning, vgdPidPath, vgdRequest, vgdSocketPath };
61
+ //# sourceMappingURL=chunk-PMYWZRRS.js.map
62
+ //# sourceMappingURL=chunk-PMYWZRRS.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/runtime/vgd/paths.ts","../src/runtime/vgd/client.ts"],"names":[],"mappings":"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","file":"chunk-PMYWZRRS.js","sourcesContent":["import * as path from 'node:path';\nimport { daemonDir } from '../paths.js';\n\n/** Socket (or named-pipe) path for the local vgd instance. */\nexport function vgdSocketPath(env: NodeJS.ProcessEnv = process.env, platform: NodeJS.Platform = process.platform): string {\n if (platform === 'win32') {\n return path.join('\\\\\\\\.\\\\pipe', 'vibgrate-vgd');\n }\n return path.join(daemonDir(env, platform), 'vgd.sock');\n}\n\n/** PID file for quick status without a round-trip (Unix). */\nexport function vgdPidPath(env: NodeJS.ProcessEnv = process.env, platform: NodeJS.Platform = process.platform): string {\n return path.join(daemonDir(env, platform), 'vgd.pid');\n}\n","import * as net from 'node:net';\nimport type { VgdRequest, VgdResponse } from './protocol.js';\nimport { vgdSocketPath } from './paths.js';\n\nexport interface VgdClientOptions {\n socketPath?: string;\n /** Connect timeout in ms (default 2000). */\n timeoutMs?: number;\n}\n\n/**\n * Send one request to a running vgd and return the parsed response.\n * Rejects if the daemon is not reachable.\n */\nexport function vgdRequest(request: VgdRequest, options: VgdClientOptions = {}): Promise<VgdResponse> {\n const socketPath = options.socketPath ?? vgdSocketPath();\n const timeoutMs = options.timeoutMs ?? 2000;\n\n return new Promise((resolve, reject) => {\n const socket = net.createConnection(socketPath);\n let settled = false;\n let buffer = '';\n\n const finish = (err?: Error, value?: VgdResponse): void => {\n if (settled) return;\n settled = true;\n clearTimeout(timer);\n socket.destroy();\n if (err) reject(err);\n else resolve(value!);\n };\n\n const timer = setTimeout(() => finish(new Error(`vgd did not respond within ${timeoutMs}ms`)), timeoutMs);\n\n socket.setEncoding('utf8');\n socket.on('connect', () => {\n socket.write(JSON.stringify(request) + '\\n');\n });\n socket.on('data', (chunk: string) => {\n buffer += chunk;\n const nl = buffer.indexOf('\\n');\n if (nl < 0) return;\n const line = buffer.slice(0, nl).trim();\n try {\n finish(undefined, JSON.parse(line) as VgdResponse);\n } catch (e) {\n finish(e instanceof Error ? e : new Error(String(e)));\n }\n });\n socket.on('error', (err) => finish(err));\n socket.on('end', () => {\n if (!settled) finish(new Error('vgd closed the connection before responding'));\n });\n });\n}\n\n/** True when a local vgd answers ping. */\nexport async function vgdIsRunning(options: VgdClientOptions = {}): Promise<boolean> {\n try {\n const res = await vgdRequest({ op: 'ping' }, options);\n return res.ok === true && 'pong' in res && res.pong === true;\n } catch {\n return false;\n }\n}\n"]}