@vibgrate/cli 2026.813.1 → 2026.814.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (123) hide show
  1. package/DOCS.md +258 -22
  2. package/NOTICE +7 -0
  3. package/README.md +273 -11
  4. package/dist/agent-5ANHRYEI.js +26 -0
  5. package/dist/{agent-N3CP3SPI.js.map → agent-5ANHRYEI.js.map} +1 -1
  6. package/dist/approvals-T2KXPJLV.js +9 -0
  7. package/dist/approvals-T2KXPJLV.js.map +1 -0
  8. package/dist/baseline-WVD6P5IO.js +9 -0
  9. package/dist/{baseline-ZMRZRGFI.js.map → baseline-WVD6P5IO.js.map} +1 -1
  10. package/dist/{checkpoint-4WFZMKEO.js → checkpoint-UYMYMMQO.js} +6 -3
  11. package/dist/checkpoint-UYMYMMQO.js.map +1 -0
  12. package/dist/chunk-2H2U3DC7.js +6 -0
  13. package/dist/{chunk-RT7P5AYU.js.map → chunk-2H2U3DC7.js.map} +1 -1
  14. package/dist/chunk-2U37PFB2.js +64 -0
  15. package/dist/chunk-2U37PFB2.js.map +1 -0
  16. package/dist/{chunk-GOPANQZT.js → chunk-54RGT2T5.js} +3 -3
  17. package/dist/{chunk-GOPANQZT.js.map → chunk-54RGT2T5.js.map} +1 -1
  18. package/dist/{chunk-OYHAF2J2.js → chunk-5GLQNMTI.js} +5 -5
  19. package/dist/{chunk-OYHAF2J2.js.map → chunk-5GLQNMTI.js.map} +1 -1
  20. package/dist/{chunk-EWZKOU66.js → chunk-75LJM5XD.js} +30 -66
  21. package/dist/chunk-75LJM5XD.js.map +1 -0
  22. package/dist/{chunk-KF2QT6RY.js → chunk-7NMXE6KG.js} +4 -4
  23. package/dist/{chunk-KF2QT6RY.js.map → chunk-7NMXE6KG.js.map} +1 -1
  24. package/dist/{chunk-UZP623Y4.js → chunk-7QDHQLUS.js} +4 -4
  25. package/dist/{chunk-UZP623Y4.js.map → chunk-7QDHQLUS.js.map} +1 -1
  26. package/dist/chunk-AJS4EL2C.js +266 -0
  27. package/dist/chunk-AJS4EL2C.js.map +1 -0
  28. package/dist/{chunk-Z3MUWXP3.js → chunk-BH54SLGZ.js} +4 -4
  29. package/dist/{chunk-Z3MUWXP3.js.map → chunk-BH54SLGZ.js.map} +1 -1
  30. package/dist/{chunk-CJNWHXQD.js → chunk-DSUGC7F5.js} +4 -4
  31. package/dist/{chunk-CJNWHXQD.js.map → chunk-DSUGC7F5.js.map} +1 -1
  32. package/dist/{chunk-FBVKQXBH.js → chunk-FOW5IF73.js} +3 -3
  33. package/dist/{chunk-FBVKQXBH.js.map → chunk-FOW5IF73.js.map} +1 -1
  34. package/dist/{chunk-6GQLEDVK.js → chunk-IHLLWBZU.js} +6 -5
  35. package/dist/chunk-IHLLWBZU.js.map +1 -0
  36. package/dist/{chunk-RHKJPTON.js → chunk-IHXNOY3R.js} +208 -56
  37. package/dist/chunk-IHXNOY3R.js.map +1 -0
  38. package/dist/{chunk-5JJBGBP2.js → chunk-JCN6MSXQ.js} +7 -7
  39. package/dist/{chunk-5JJBGBP2.js.map → chunk-JCN6MSXQ.js.map} +1 -1
  40. package/dist/{chunk-YJU7S7N6.js → chunk-KGPX4EUN.js} +4 -4
  41. package/dist/{chunk-YJU7S7N6.js.map → chunk-KGPX4EUN.js.map} +1 -1
  42. package/dist/{chunk-ADP6ITGF.js → chunk-N3XFY3PX.js} +68 -11
  43. package/dist/chunk-N3XFY3PX.js.map +1 -0
  44. package/dist/{chunk-JYM4QT6F.js → chunk-NKFXXP6W.js} +5 -5
  45. package/dist/{chunk-JYM4QT6F.js.map → chunk-NKFXXP6W.js.map} +1 -1
  46. package/dist/{chunk-5ROZODMW.js → chunk-TFAXW7VM.js} +2 -2
  47. package/dist/chunk-TFAXW7VM.js.map +1 -0
  48. package/dist/{chunk-6423BHLN.js → chunk-TNROG5CO.js} +19 -9
  49. package/dist/chunk-TNROG5CO.js.map +1 -0
  50. package/dist/chunk-TVDYEHIM.js +174 -0
  51. package/dist/chunk-TVDYEHIM.js.map +1 -0
  52. package/dist/{chunk-7ZHSSGUF.js → chunk-WQLZSVNF.js} +4 -3
  53. package/dist/chunk-WQLZSVNF.js.map +1 -0
  54. package/dist/{chunk-3WUTQYRY.js → chunk-WWGLVF7D.js} +9 -8
  55. package/dist/chunk-WWGLVF7D.js.map +1 -0
  56. package/dist/{chunk-KBP7GJV6.js → chunk-X76VPOYH.js} +19 -9
  57. package/dist/chunk-X76VPOYH.js.map +1 -0
  58. package/dist/{chunk-IJQOZ6ZD.js → chunk-YNV5M3JW.js} +8 -8
  59. package/dist/chunk-YNV5M3JW.js.map +1 -0
  60. package/dist/{chunk-Z3AYOZ3C.js → chunk-YQNTIBKS.js} +6 -6
  61. package/dist/{chunk-Z3AYOZ3C.js.map → chunk-YQNTIBKS.js.map} +1 -1
  62. package/dist/cli.js +1130 -489
  63. package/dist/cli.js.map +1 -1
  64. package/dist/embed-worker-main.js +4 -3
  65. package/dist/embed-worker-main.js.map +1 -1
  66. package/dist/{ensure-map-PHAJACFF.js → ensure-map-HQ7A5NDL.js} +15 -14
  67. package/dist/{ensure-map-PHAJACFF.js.map → ensure-map-HQ7A5NDL.js.map} +1 -1
  68. package/dist/fastembed-S6YEJYQV.js +292 -0
  69. package/dist/fastembed-S6YEJYQV.js.map +1 -0
  70. package/dist/graph-backend-W2TNTMY7.js +14 -0
  71. package/dist/{graph-backend-4B3MTVIW.js.map → graph-backend-W2TNTMY7.js.map} +1 -1
  72. package/dist/index.d.ts +4 -3
  73. package/dist/index.js +14 -13
  74. package/dist/index.js.map +1 -1
  75. package/dist/{interactive-WUXMXFNM.js → interactive-EW2VJ3BZ.js} +32 -30
  76. package/dist/interactive-EW2VJ3BZ.js.map +1 -0
  77. package/dist/load-64RK5O6C.js +10 -0
  78. package/dist/{load-EUZSV73H.js.map → load-64RK5O6C.js.map} +1 -1
  79. package/dist/{run-outcome-O5PR7ZCK.js → run-outcome-6QNQIHPV.js} +6 -5
  80. package/dist/run-outcome-6QNQIHPV.js.map +1 -0
  81. package/dist/runtime-session-RJHH3KMF.js +21 -0
  82. package/dist/{runtime-session-PPQDTFIK.js.map → runtime-session-RJHH3KMF.js.map} +1 -1
  83. package/dist/session-4BGYASOH.js +16 -0
  84. package/dist/{session-WS7SOVJE.js.map → session-4BGYASOH.js.map} +1 -1
  85. package/dist/session-store-AQUORKWB.js +4 -0
  86. package/dist/{session-store-KGONLWHN.js.map → session-store-AQUORKWB.js.map} +1 -1
  87. package/dist/{stream-json-7MK3QQYG.js → stream-json-GY5N7WZT.js} +76 -24
  88. package/dist/stream-json-GY5N7WZT.js.map +1 -0
  89. package/dist/version-DPAMQW6M.js +4 -0
  90. package/dist/version-DPAMQW6M.js.map +1 -0
  91. package/dist/{vg-mcp-bridge-DQLCHBI6.js → vg-mcp-bridge-IGHJKKSL.js} +11 -10
  92. package/dist/vg-mcp-bridge-IGHJKKSL.js.map +1 -0
  93. package/dist/{vgd-Y25XSQGZ.js → vgd-ORPA5C2K.js} +12 -11
  94. package/dist/vgd-ORPA5C2K.js.map +1 -0
  95. package/dist/worktree-session-D575IQWM.js +82 -0
  96. package/dist/worktree-session-D575IQWM.js.map +1 -0
  97. package/package.json +4 -2
  98. package/dist/agent-N3CP3SPI.js +0 -24
  99. package/dist/baseline-ZMRZRGFI.js +0 -9
  100. package/dist/checkpoint-4WFZMKEO.js.map +0 -1
  101. package/dist/chunk-3WUTQYRY.js.map +0 -1
  102. package/dist/chunk-5ROZODMW.js.map +0 -1
  103. package/dist/chunk-6423BHLN.js.map +0 -1
  104. package/dist/chunk-6GQLEDVK.js.map +0 -1
  105. package/dist/chunk-7ZHSSGUF.js.map +0 -1
  106. package/dist/chunk-ADP6ITGF.js.map +0 -1
  107. package/dist/chunk-EWZKOU66.js.map +0 -1
  108. package/dist/chunk-IJQOZ6ZD.js.map +0 -1
  109. package/dist/chunk-KBP7GJV6.js.map +0 -1
  110. package/dist/chunk-RHKJPTON.js.map +0 -1
  111. package/dist/chunk-RT7P5AYU.js +0 -6
  112. package/dist/chunk-Z7FM3ETS.js +0 -126
  113. package/dist/chunk-Z7FM3ETS.js.map +0 -1
  114. package/dist/graph-backend-4B3MTVIW.js +0 -13
  115. package/dist/interactive-WUXMXFNM.js.map +0 -1
  116. package/dist/load-EUZSV73H.js +0 -9
  117. package/dist/run-outcome-O5PR7ZCK.js.map +0 -1
  118. package/dist/runtime-session-PPQDTFIK.js +0 -20
  119. package/dist/session-WS7SOVJE.js +0 -15
  120. package/dist/session-store-KGONLWHN.js +0 -4
  121. package/dist/stream-json-7MK3QQYG.js.map +0 -1
  122. package/dist/vg-mcp-bridge-DQLCHBI6.js.map +0 -1
  123. package/dist/vgd-Y25XSQGZ.js.map +0 -1
@@ -0,0 +1,266 @@
1
+ import * as fs from 'fs';
2
+ import * as path from 'path';
3
+
4
+ // src/code/session-store.ts
5
+ function sessionsDir(root) {
6
+ return path.join(root, ".vibgrate", "code-sessions");
7
+ }
8
+ function latestPointer(root) {
9
+ return path.join(sessionsDir(root), "latest.json");
10
+ }
11
+ function indexFile(root) {
12
+ return path.join(sessionsDir(root), "index.json");
13
+ }
14
+ function sessionTitle(session) {
15
+ const explicit = session.title?.trim();
16
+ if (explicit) return explicit.slice(0, 80);
17
+ return (session.tasks?.[0]?.instruction?.trim() || "New chat").slice(0, 80);
18
+ }
19
+ function toIndexEntry(session) {
20
+ return {
21
+ id: session.id,
22
+ provider: session.provider ?? "",
23
+ model: session.model ?? "",
24
+ startedAt: session.startedAt ?? 0,
25
+ updatedAt: session.updatedAt ?? session.startedAt ?? 0,
26
+ taskCount: session.tasks.length,
27
+ title: sessionTitle(session),
28
+ ...session.forkedFrom ? { forkedFrom: session.forkedFrom } : {},
29
+ ...session.worktree ? { worktreeId: session.worktree.id } : {}
30
+ };
31
+ }
32
+ function readSessionIndex(root) {
33
+ try {
34
+ const raw = JSON.parse(fs.readFileSync(indexFile(root), "utf8"));
35
+ if (!Array.isArray(raw?.sessions)) return null;
36
+ return raw.sessions.filter((s) => s && typeof s.id === "string" && typeof s.title === "string");
37
+ } catch {
38
+ return null;
39
+ }
40
+ }
41
+ function writeSessionIndex(root, entries) {
42
+ try {
43
+ fs.mkdirSync(sessionsDir(root), { recursive: true });
44
+ fs.writeFileSync(indexFile(root), JSON.stringify({ sessions: entries }, null, 2));
45
+ } catch {
46
+ }
47
+ }
48
+ function updateSessionIndex(root, session) {
49
+ const entries = readSessionIndex(root) ?? rebuildSessionIndex(root);
50
+ const next = entries.filter((e) => e.id !== session.id);
51
+ next.push(toIndexEntry(session));
52
+ next.sort((a, b) => b.updatedAt - a.updatedAt);
53
+ writeSessionIndex(root, next);
54
+ }
55
+ function rebuildSessionIndex(root) {
56
+ const entries = [];
57
+ try {
58
+ const dir = sessionsDir(root);
59
+ if (!fs.existsSync(dir)) return entries;
60
+ for (const f of fs.readdirSync(dir)) {
61
+ if (!f.endsWith(".json") || f === "latest.json" || f === "index.json") continue;
62
+ try {
63
+ const raw = JSON.parse(fs.readFileSync(path.join(dir, f), "utf8"));
64
+ if (raw?.id && Array.isArray(raw.tasks)) entries.push(toIndexEntry(raw));
65
+ } catch {
66
+ }
67
+ }
68
+ } catch {
69
+ }
70
+ entries.sort((a, b) => b.updatedAt - a.updatedAt);
71
+ return entries;
72
+ }
73
+ function saveSession(root, session) {
74
+ try {
75
+ const dir = sessionsDir(root);
76
+ fs.mkdirSync(dir, { recursive: true });
77
+ fs.writeFileSync(path.join(dir, `${session.id}.json`), JSON.stringify(session, null, 2));
78
+ fs.writeFileSync(latestPointer(root), JSON.stringify({ id: session.id }));
79
+ updateSessionIndex(root, session);
80
+ } catch {
81
+ }
82
+ }
83
+ function renameSession(root, id, title) {
84
+ const s = loadSession(root, id);
85
+ if (!s) return false;
86
+ const t = title.trim().slice(0, 120);
87
+ const next = { ...s };
88
+ if (t) next.title = t;
89
+ else delete next.title;
90
+ try {
91
+ fs.writeFileSync(path.join(sessionsDir(root), `${next.id}.json`), JSON.stringify(next, null, 2));
92
+ updateSessionIndex(root, next);
93
+ return true;
94
+ } catch {
95
+ return false;
96
+ }
97
+ }
98
+ function deleteSession(root, id) {
99
+ const safe = id.replace(/[^a-zA-Z0-9_-]/g, "");
100
+ if (!safe || safe !== id) return false;
101
+ const file = path.join(sessionsDir(root), `${safe}.json`);
102
+ if (!fs.existsSync(file)) return false;
103
+ try {
104
+ fs.unlinkSync(file);
105
+ } catch {
106
+ return false;
107
+ }
108
+ const entries = (readSessionIndex(root) ?? rebuildSessionIndex(root)).filter((e) => e.id !== safe);
109
+ writeSessionIndex(root, entries);
110
+ try {
111
+ const { id: latest } = JSON.parse(fs.readFileSync(latestPointer(root), "utf8"));
112
+ if (latest === safe) fs.unlinkSync(latestPointer(root));
113
+ } catch {
114
+ }
115
+ return true;
116
+ }
117
+ function forkSession(root, id, newId, now) {
118
+ const src = loadSession(root, id);
119
+ if (!src) return void 0;
120
+ const fork = {
121
+ ...src,
122
+ id: newId,
123
+ title: `(Fork) ${sessionTitle(src)}`.slice(0, 120),
124
+ forkedFrom: src.id,
125
+ updatedAt: now
126
+ };
127
+ try {
128
+ const dir = sessionsDir(root);
129
+ fs.mkdirSync(dir, { recursive: true });
130
+ fs.writeFileSync(path.join(dir, `${newId}.json`), JSON.stringify(fork, null, 2));
131
+ updateSessionIndex(root, fork);
132
+ return fork;
133
+ } catch {
134
+ return void 0;
135
+ }
136
+ }
137
+ function rewindSession(root, id, keepTurns, now) {
138
+ const s = loadSession(root, id);
139
+ if (!s) return void 0;
140
+ const keep = Math.floor(keepTurns);
141
+ if (keep < 0 || keep >= s.tasks.length) return void 0;
142
+ const next = { ...s, tasks: s.tasks.slice(0, keep), updatedAt: now, lastChanges: [] };
143
+ try {
144
+ fs.writeFileSync(path.join(sessionsDir(root), `${next.id}.json`), JSON.stringify(next, null, 2));
145
+ updateSessionIndex(root, next);
146
+ return next;
147
+ } catch {
148
+ return void 0;
149
+ }
150
+ }
151
+ function loadLatestSession(root) {
152
+ try {
153
+ const { id } = JSON.parse(fs.readFileSync(latestPointer(root), "utf8"));
154
+ return loadSession(root, id);
155
+ } catch {
156
+ }
157
+ return void 0;
158
+ }
159
+ function looksLikeSessionId(v) {
160
+ return /^[a-z0-9]{10}$/.test(v);
161
+ }
162
+ function loadSession(root, id) {
163
+ try {
164
+ const safe = id.replace(/[^a-zA-Z0-9_-]/g, "");
165
+ if (!safe || safe !== id) return void 0;
166
+ const raw = JSON.parse(fs.readFileSync(path.join(sessionsDir(root), `${safe}.json`), "utf8"));
167
+ if (Array.isArray(raw.tasks) && raw.id) return raw;
168
+ } catch {
169
+ }
170
+ return void 0;
171
+ }
172
+ function listSessions(root, limit = 50) {
173
+ const indexed = readSessionIndex(root);
174
+ if (indexed) {
175
+ return [...indexed].sort((a, b) => b.updatedAt - a.updatedAt).slice(0, Math.max(1, limit));
176
+ }
177
+ const scanned = rebuildSessionIndex(root);
178
+ if (scanned.length) writeSessionIndex(root, scanned);
179
+ return scanned.slice(0, Math.max(1, limit));
180
+ }
181
+ function setLatestSession(root, id) {
182
+ const s = loadSession(root, id);
183
+ if (!s) return false;
184
+ try {
185
+ fs.mkdirSync(sessionsDir(root), { recursive: true });
186
+ fs.writeFileSync(latestPointer(root), JSON.stringify({ id: s.id }));
187
+ return true;
188
+ } catch {
189
+ return false;
190
+ }
191
+ }
192
+ var MAX_INSTRUCTION_CHARS = 32e3;
193
+ var MAX_SUMMARY_CHARS = 2e5;
194
+ function recapSnippet(text, max) {
195
+ const s = String(text || "").replace(/\s+/g, " ").trim();
196
+ if (s.length <= max) return s;
197
+ return s.slice(0, Math.max(0, max - 1)) + "\u2026";
198
+ }
199
+ function summarizeSession(session) {
200
+ if (session.tasks.length === 0) return "";
201
+ const lines = session.tasks.slice(-8).map((t, i) => {
202
+ const instr = recapSnippet(t.instruction, 120);
203
+ const sum = recapSnippet(t.summary, 200);
204
+ const files = t.files.length ? ` (${t.files.join(", ")})` : "";
205
+ return `${i + 1}. ${instr} \u2014 ${sum}${files}`;
206
+ });
207
+ return `Earlier in this session (${session.provider}/${session.model}) you did:
208
+ ${lines.join("\n")}`;
209
+ }
210
+ function newSession(id, provider, model, now) {
211
+ return { id, provider, model, startedAt: now, updatedAt: now, tasks: [], lastChanges: [] };
212
+ }
213
+ function condenseSession(session, now) {
214
+ if (session.tasks.length <= 1) return session;
215
+ const files = [...new Set(session.tasks.flatMap((t) => t.files))];
216
+ const lines = session.tasks.slice(-12).map((t) => `${t.instruction.slice(0, 80)} \u2014 ${t.summary.slice(0, 80)}`);
217
+ const checkpoint = {
218
+ instruction: `(compacted: ${session.tasks.length} earlier task(s))`,
219
+ summary: lines.join(" \xB7 ").slice(0, 1500),
220
+ files,
221
+ stopped: "compacted",
222
+ ts: now
223
+ };
224
+ return { ...session, updatedAt: now, tasks: [checkpoint] };
225
+ }
226
+ function recordTask(session, task, now) {
227
+ const files = [...new Set(task.changes.map((c) => c.file))];
228
+ const instruction = String(task.instruction ?? "").slice(0, MAX_INSTRUCTION_CHARS);
229
+ const summary = String(task.summary ?? "").slice(0, MAX_SUMMARY_CHARS);
230
+ const attachments = sanitizeAttachments(task.attachments);
231
+ return {
232
+ ...session,
233
+ updatedAt: now,
234
+ tasks: [
235
+ ...session.tasks,
236
+ {
237
+ instruction,
238
+ summary,
239
+ files,
240
+ stopped: task.stopped,
241
+ ts: now,
242
+ ...attachments.length ? { attachments } : {}
243
+ }
244
+ ],
245
+ lastChanges: task.changes.length ? task.changes : session.lastChanges
246
+ };
247
+ }
248
+ function sanitizeAttachments(raw) {
249
+ if (!Array.isArray(raw)) return [];
250
+ const out = [];
251
+ for (const a of raw.slice(0, 8)) {
252
+ if (!a || typeof a !== "object") continue;
253
+ const r = a;
254
+ const name = typeof r.name === "string" ? r.name.trim().slice(0, 120) : "";
255
+ if (!name) continue;
256
+ const kind = r.kind === "image" ? "image" : "text";
257
+ const mediaType = typeof r.mediaType === "string" ? r.mediaType.slice(0, 80) : void 0;
258
+ const bytes = typeof r.bytes === "number" && Number.isFinite(r.bytes) && r.bytes >= 0 ? r.bytes : void 0;
259
+ out.push({ name, kind, ...mediaType ? { mediaType } : {}, ...bytes !== void 0 ? { bytes } : {} });
260
+ }
261
+ return out;
262
+ }
263
+
264
+ export { condenseSession, deleteSession, forkSession, listSessions, loadLatestSession, loadSession, looksLikeSessionId, newSession, readSessionIndex, rebuildSessionIndex, recordTask, renameSession, rewindSession, sanitizeAttachments, saveSession, sessionTitle, sessionsDir, setLatestSession, summarizeSession };
265
+ //# sourceMappingURL=chunk-AJS4EL2C.js.map
266
+ //# sourceMappingURL=chunk-AJS4EL2C.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/code/session-store.ts"],"names":[],"mappings":"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","file":"chunk-AJS4EL2C.js","sourcesContent":["/**\n * Session persistence for VG Code (VG-CLI-CODE §16) — `vg code --continue`.\n *\n * A coding session is a series of tasks; this stores each turn's instruction and\n * final answer (plus which files changed) and the last change-set so `/undo`\n * survives a restart. History → pick reloads those turns into the panel so the\n * user can re-read the full thread. `--continue` reloads the most recent session\n * and seeds the model with a *short recap* of prior turns (see\n * {@link summarizeSession}) — never raw file bodies or tool transcripts.\n *\n * Pure over an injected clock; the store is JSON under `.vibgrate/code-sessions/`.\n */\n\nimport * as fs from 'node:fs';\nimport * as path from 'node:path';\nimport type { FileChange } from './types.js';\n\n/**\n * What was attached to a turn, as METADATA only — name, kind, size. The bytes\n * are deliberately absent: a session file that carried a 20 MiB screenshot\n * would be unreadable, unsyncable, and would blow the History index it feeds.\n * A restored chat shows what was attached, not the attachment itself.\n */\nexport interface SessionAttachment {\n name: string;\n kind: 'image' | 'text';\n mediaType?: string;\n bytes?: number;\n}\n\nexport interface SessionTask {\n instruction: string;\n summary: string;\n files: string[];\n stopped: string;\n ts: number;\n /** v5: what the user attached to this turn (metadata only). */\n attachments?: SessionAttachment[];\n}\n\nexport interface StoredSession {\n id: string;\n provider: string;\n model: string;\n startedAt: number;\n updatedAt: number;\n /** User-chosen chat name (rename). Absent → derived from the first task. */\n title?: string;\n /** Set when this chat was forked from another (History shows the lineage). */\n forkedFrom?: string;\n /** Set when this chat runs in an isolated git worktree (P3 worktree sessions). */\n worktree?: { id: string; path: string; base: string };\n tasks: SessionTask[];\n /** The most recent change-set, so `/undo` works after `--continue`. */\n lastChanges: FileChange[];\n}\n\nexport function sessionsDir(root: string): string {\n return path.join(root, '.vibgrate', 'code-sessions');\n}\nfunction latestPointer(root: string): string {\n return path.join(sessionsDir(root), 'latest.json');\n}\nfunction indexFile(root: string): string {\n return path.join(sessionsDir(root), 'index.json');\n}\n\n/** One row of the History index — everything a list UI needs, no session parse. */\nexport interface SessionIndexEntry {\n id: string;\n provider: string;\n model: string;\n startedAt: number;\n updatedAt: number;\n taskCount: number;\n title: string;\n forkedFrom?: string;\n /** Set when the chat runs in an isolated worktree (History shows a WT badge). */\n worktreeId?: string;\n}\n\n/** The derived list title: explicit rename wins, else the first instruction. */\nexport function sessionTitle(session: Pick<StoredSession, 'title' | 'tasks'>): string {\n const explicit = session.title?.trim();\n if (explicit) return explicit.slice(0, 80);\n return (session.tasks?.[0]?.instruction?.trim() || 'New chat').slice(0, 80);\n}\n\nfunction toIndexEntry(session: StoredSession): SessionIndexEntry {\n return {\n id: session.id,\n provider: session.provider ?? '',\n model: session.model ?? '',\n startedAt: session.startedAt ?? 0,\n updatedAt: session.updatedAt ?? session.startedAt ?? 0,\n taskCount: session.tasks.length,\n title: sessionTitle(session),\n ...(session.forkedFrom ? { forkedFrom: session.forkedFrom } : {}),\n ...(session.worktree ? { worktreeId: session.worktree.id } : {}),\n };\n}\n\n/**\n * Read the History index, or null when absent/unreadable. The index is a\n * best-effort cache maintained on every save/rename/delete: History UIs read\n * one small file instead of parsing every stored session (whose summaries can\n * run to 200k chars each). A missing or stale index is never an error — list\n * paths fall back to the full directory scan and rewrite it.\n */\nexport function readSessionIndex(root: string): SessionIndexEntry[] | null {\n try {\n const raw = JSON.parse(fs.readFileSync(indexFile(root), 'utf8')) as {\n sessions?: SessionIndexEntry[];\n };\n if (!Array.isArray(raw?.sessions)) return null;\n return raw.sessions.filter((s) => s && typeof s.id === 'string' && typeof s.title === 'string');\n } catch {\n return null;\n }\n}\n\nfunction writeSessionIndex(root: string, entries: SessionIndexEntry[]): void {\n try {\n fs.mkdirSync(sessionsDir(root), { recursive: true });\n fs.writeFileSync(indexFile(root), JSON.stringify({ sessions: entries }, null, 2));\n } catch {\n /* best-effort cache */\n }\n}\n\n/** Upsert one session's index row (called from every save). */\nfunction updateSessionIndex(root: string, session: StoredSession): void {\n const entries = readSessionIndex(root) ?? rebuildSessionIndex(root);\n const next = entries.filter((e) => e.id !== session.id);\n next.push(toIndexEntry(session));\n next.sort((a, b) => b.updatedAt - a.updatedAt);\n writeSessionIndex(root, next);\n}\n\n/** Rebuild the index from the stored files (missing/corrupt index, migrations). */\nexport function rebuildSessionIndex(root: string): SessionIndexEntry[] {\n const entries: SessionIndexEntry[] = [];\n try {\n const dir = sessionsDir(root);\n if (!fs.existsSync(dir)) return entries;\n for (const f of fs.readdirSync(dir)) {\n if (!f.endsWith('.json') || f === 'latest.json' || f === 'index.json') continue;\n try {\n const raw = JSON.parse(fs.readFileSync(path.join(dir, f), 'utf8')) as StoredSession;\n if (raw?.id && Array.isArray(raw.tasks)) entries.push(toIndexEntry(raw));\n } catch {\n /* skip bad file */\n }\n }\n } catch {\n /* no dir */\n }\n entries.sort((a, b) => b.updatedAt - a.updatedAt);\n return entries;\n}\n\n/** Write a session and update the `latest` pointer + index. Best-effort; never throws. */\nexport function saveSession(root: string, session: StoredSession): void {\n try {\n const dir = sessionsDir(root);\n fs.mkdirSync(dir, { recursive: true });\n fs.writeFileSync(path.join(dir, `${session.id}.json`), JSON.stringify(session, null, 2));\n fs.writeFileSync(latestPointer(root), JSON.stringify({ id: session.id }));\n updateSessionIndex(root, session);\n } catch {\n /* persistence is best-effort */\n }\n}\n\n/*\n * NOTE: rename/delete/fork/rewind below are the store's REFERENCE mutations.\n * The VS Code extension mirrors them over the same files\n * (packages/vibgrate-vscode/src/codeSessionHistory.ts) because it cannot link\n * this library — a semantic change must land on both sides, and the\n * extension's protocol-conformance test pins the shared index.json shape.\n */\n\n/**\n * Rename a stored chat. Empty title clears the rename (back to the derived\n * name). Returns false when the session does not exist or the write failed.\n */\nexport function renameSession(root: string, id: string, title: string): boolean {\n const s = loadSession(root, id);\n if (!s) return false;\n const t = title.trim().slice(0, 120);\n const next: StoredSession = { ...s };\n if (t) next.title = t;\n else delete next.title;\n try {\n fs.writeFileSync(path.join(sessionsDir(root), `${next.id}.json`), JSON.stringify(next, null, 2));\n updateSessionIndex(root, next);\n return true;\n } catch {\n return false;\n }\n}\n\n/**\n * Delete a stored chat (and its index row). The `latest` pointer is cleared\n * when it referenced the deleted chat, so `--continue` cannot resume a ghost.\n */\nexport function deleteSession(root: string, id: string): boolean {\n const safe = id.replace(/[^a-zA-Z0-9_-]/g, '');\n if (!safe || safe !== id) return false;\n const file = path.join(sessionsDir(root), `${safe}.json`);\n if (!fs.existsSync(file)) return false;\n try {\n fs.unlinkSync(file);\n } catch {\n return false;\n }\n const entries = (readSessionIndex(root) ?? rebuildSessionIndex(root)).filter((e) => e.id !== safe);\n writeSessionIndex(root, entries);\n try {\n const { id: latest } = JSON.parse(fs.readFileSync(latestPointer(root), 'utf8')) as { id: string };\n if (latest === safe) fs.unlinkSync(latestPointer(root));\n } catch {\n /* no pointer */\n }\n return true;\n}\n\n/**\n * Fork a stored chat: copy it under a fresh id, renamed \"(Fork) <title>\", so\n * the user can explore an alternative continuation without losing the original.\n * Returns the new session, or undefined when the source is missing/unwritable.\n */\nexport function forkSession(\n root: string,\n id: string,\n newId: string,\n now: number,\n): StoredSession | undefined {\n const src = loadSession(root, id);\n if (!src) return undefined;\n const fork: StoredSession = {\n ...src,\n id: newId,\n title: `(Fork) ${sessionTitle(src)}`.slice(0, 120),\n forkedFrom: src.id,\n updatedAt: now,\n };\n try {\n const dir = sessionsDir(root);\n fs.mkdirSync(dir, { recursive: true });\n fs.writeFileSync(path.join(dir, `${newId}.json`), JSON.stringify(fork, null, 2));\n updateSessionIndex(root, fork);\n return fork;\n } catch {\n return undefined;\n }\n}\n\n/**\n * Rewind a stored chat to its first `keepTurns` tasks (0 empties it). The\n * discarded turns are gone from the recap the next launch seeds — pair with\n * checkpoint restores to also rewind the files. Returns the rewound session,\n * or undefined when the session is missing or `keepTurns` is not a rewind.\n */\nexport function rewindSession(\n root: string,\n id: string,\n keepTurns: number,\n now: number,\n): StoredSession | undefined {\n const s = loadSession(root, id);\n if (!s) return undefined;\n const keep = Math.floor(keepTurns);\n if (keep < 0 || keep >= s.tasks.length) return undefined;\n const next: StoredSession = { ...s, tasks: s.tasks.slice(0, keep), updatedAt: now, lastChanges: [] };\n try {\n fs.writeFileSync(path.join(sessionsDir(root), `${next.id}.json`), JSON.stringify(next, null, 2));\n updateSessionIndex(root, next);\n return next;\n } catch {\n return undefined;\n }\n}\n\n/** Load the most recent session, or undefined if none/there was a read error. */\nexport function loadLatestSession(root: string): StoredSession | undefined {\n try {\n const { id } = JSON.parse(fs.readFileSync(latestPointer(root), 'utf8')) as { id: string };\n return loadSession(root, id);\n } catch {\n /* no session */\n }\n return undefined;\n}\n\n/**\n * True for a string shaped like a minted session id (see `sessionId()` in\n * interactive.ts: exactly ten lowercase `[a-z0-9]` characters). `--continue`\n * takes an optional id, and commander cannot tell an id from the first word of\n * an instruction (`vg code --continue fix the tests` hands the parser\n * `continue=\"fix\"`) — callers use this shape test to fold anything else back\n * into the instruction instead of losing it to a doomed session lookup.\n */\nexport function looksLikeSessionId(v: string): boolean {\n return /^[a-z0-9]{10}$/.test(v);\n}\n\n/** Load one session by id, or undefined if missing/invalid. */\nexport function loadSession(root: string, id: string): StoredSession | undefined {\n try {\n const safe = id.replace(/[^a-zA-Z0-9_-]/g, '');\n if (!safe || safe !== id) return undefined;\n const raw = JSON.parse(fs.readFileSync(path.join(sessionsDir(root), `${safe}.json`), 'utf8')) as StoredSession;\n if (Array.isArray(raw.tasks) && raw.id) return raw;\n } catch {\n /* missing */\n }\n return undefined;\n}\n\nexport type SessionListEntry = SessionIndexEntry;\n\n/**\n * List stored sessions newest-first (multi-chat history). Served from the\n * index when one exists; otherwise a full scan that also rewrites the index\n * so the next list is cheap. Best-effort.\n */\nexport function listSessions(root: string, limit = 50): SessionListEntry[] {\n const indexed = readSessionIndex(root);\n if (indexed) {\n return [...indexed].sort((a, b) => b.updatedAt - a.updatedAt).slice(0, Math.max(1, limit));\n }\n const scanned = rebuildSessionIndex(root);\n if (scanned.length) writeSessionIndex(root, scanned);\n return scanned.slice(0, Math.max(1, limit));\n}\n\n/** Point `latest` at an existing session (resume a prior chat). */\nexport function setLatestSession(root: string, id: string): boolean {\n const s = loadSession(root, id);\n if (!s) return false;\n try {\n fs.mkdirSync(sessionsDir(root), { recursive: true });\n fs.writeFileSync(latestPointer(root), JSON.stringify({ id: s.id }));\n return true;\n } catch {\n return false;\n }\n}\n\n/**\n * Cap stored fields so a runaway answer cannot fill the disk, while still\n * keeping enough of each prompt/answer for History → reload to repaint the\n * full panel transcript (the old 300-char cap cut answers mid-sentence).\n */\nconst MAX_INSTRUCTION_CHARS = 32_000;\nconst MAX_SUMMARY_CHARS = 200_000;\n\n/** Truncate for model recaps only — disk storage keeps the longer form. */\nfunction recapSnippet(text: string, max: number): string {\n const s = String(text || '').replace(/\\s+/g, ' ').trim();\n if (s.length <= max) return s;\n return s.slice(0, Math.max(0, max - 1)) + '…';\n}\n\n/** A short natural-language recap of a session to seed a continued run's context. */\nexport function summarizeSession(session: StoredSession): string {\n if (session.tasks.length === 0) return '';\n const lines = session.tasks.slice(-8).map((t, i) => {\n const instr = recapSnippet(t.instruction, 120);\n const sum = recapSnippet(t.summary, 200);\n const files = t.files.length ? ` (${t.files.join(', ')})` : '';\n return `${i + 1}. ${instr} — ${sum}${files}`;\n });\n return `Earlier in this session (${session.provider}/${session.model}) you did:\\n${lines.join('\\n')}`;\n}\n\n/** A fresh session record. `id` and `now` are injected so this stays deterministic. */\nexport function newSession(id: string, provider: string, model: string, now: number): StoredSession {\n return { id, provider, model, startedAt: now, updatedAt: now, tasks: [], lastChanges: [] };\n}\n\n/**\n * Manually compact a session: collapse all recorded tasks into a single\n * checkpoint entry so the recap seeded into future turns shrinks to one line\n * per prior task, capped. Deterministic (no model call) — the in-turn LLM\n * compaction handles rich summaries; this is the user-invoked `/compact`.\n */\nexport function condenseSession(session: StoredSession, now: number): StoredSession {\n if (session.tasks.length <= 1) return session;\n const files = [...new Set(session.tasks.flatMap((t) => t.files))];\n const lines = session.tasks\n .slice(-12)\n .map((t) => `${t.instruction.slice(0, 80)} — ${t.summary.slice(0, 80)}`);\n const checkpoint: SessionTask = {\n instruction: `(compacted: ${session.tasks.length} earlier task(s))`,\n summary: lines.join(' · ').slice(0, 1500),\n files,\n stopped: 'compacted',\n ts: now,\n };\n return { ...session, updatedAt: now, tasks: [checkpoint] };\n}\n\n/** Append a completed task (immutably updating the record's timestamps). */\nexport function recordTask(\n session: StoredSession,\n task: {\n instruction: string;\n summary: string;\n changes: FileChange[];\n stopped: string;\n attachments?: SessionAttachment[];\n },\n now: number,\n): StoredSession {\n const files = [...new Set(task.changes.map((c) => c.file))];\n const instruction = String(task.instruction ?? '').slice(0, MAX_INSTRUCTION_CHARS);\n const summary = String(task.summary ?? '').slice(0, MAX_SUMMARY_CHARS);\n const attachments = sanitizeAttachments(task.attachments);\n return {\n ...session,\n updatedAt: now,\n tasks: [\n ...session.tasks,\n {\n instruction,\n summary,\n files,\n stopped: task.stopped,\n ts: now,\n ...(attachments.length ? { attachments } : {}),\n },\n ],\n lastChanges: task.changes.length ? task.changes : session.lastChanges,\n };\n}\n\n/** Metadata only, capped and name-trimmed — never any file content. */\nexport function sanitizeAttachments(raw: unknown): SessionAttachment[] {\n if (!Array.isArray(raw)) return [];\n const out: SessionAttachment[] = [];\n for (const a of raw.slice(0, 8)) {\n if (!a || typeof a !== 'object') continue;\n const r = a as Record<string, unknown>;\n const name = typeof r.name === 'string' ? r.name.trim().slice(0, 120) : '';\n if (!name) continue;\n const kind = r.kind === 'image' ? 'image' : 'text';\n const mediaType = typeof r.mediaType === 'string' ? r.mediaType.slice(0, 80) : undefined;\n const bytes = typeof r.bytes === 'number' && Number.isFinite(r.bytes) && r.bytes >= 0 ? r.bytes : undefined;\n out.push({ name, kind, ...(mediaType ? { mediaType } : {}), ...(bytes !== undefined ? { bytes } : {}) });\n }\n return out;\n}\n"]}
@@ -1,5 +1,5 @@
1
- import { runBuild } from './chunk-5JJBGBP2.js';
2
- import { loadGraph } from './chunk-7ZHSSGUF.js';
1
+ import { runBuild } from './chunk-JCN6MSXQ.js';
2
+ import { loadGraph } from './chunk-WQLZSVNF.js';
3
3
 
4
4
  // src/code/ensure-map.ts
5
5
  async function ensureCodeMap(root, global, hooks) {
@@ -38,5 +38,5 @@ async function ensureCodeMap(root, global, hooks) {
38
38
  }
39
39
 
40
40
  export { ensureCodeMap };
41
- //# sourceMappingURL=chunk-Z3MUWXP3.js.map
42
- //# sourceMappingURL=chunk-Z3MUWXP3.js.map
41
+ //# sourceMappingURL=chunk-BH54SLGZ.js.map
42
+ //# sourceMappingURL=chunk-BH54SLGZ.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/code/ensure-map.ts"],"names":[],"mappings":";;;;AA4BA,eAAsB,aAAA,CACpB,IAAA,EACA,MAAA,EACA,KAAA,EAC4B;AAC5B,EAAA,IAAI,SAAA,CAAU,IAAA,EAAM,MAAA,CAAO,KAAK,GAAG,OAAO,OAAA;AAE1C,EAAA,KAAA,EAAO,UAAA,GAAa;AAAA,IAClB,KAAA,EAAO,OAAA;AAAA,IACP,OAAA,EAAS,+DAAA;AAAA,IACT,GAAA,EAAK;AAAA,GACN,CAAA;AAED,EAAA,IAAI;AACF,IAAA,MAAM,QAAA;AAAA,MACJ,CAAC,IAAI,CAAA;AAAA,MACL,EAAE,IAAA,EAAM,KAAA,EAAO,MAAA,EAAQ,KAAA,EAAM;AAAA,MAC7B,EAAE,GAAG,MAAA,EAAQ,KAAA,EAAO,IAAA,EAAK;AAAA,MACzB;AAAA,QACE,eAAA,EAAiB,CAAC,IAAA,EAAM,KAAA,KAAU;AAChC,UAAA,MAAM,GAAA,GAAM,KAAA,GAAQ,CAAA,GAAI,IAAA,CAAK,GAAA,CAAI,EAAA,EAAI,IAAA,CAAK,KAAA,CAAO,IAAA,GAAO,KAAA,GAAS,GAAG,CAAC,CAAA,GAAI,KAAA,CAAA;AACzE,UAAA,KAAA,EAAO,UAAA,GAAa;AAAA,YAClB,KAAA,EAAO,UAAA;AAAA,YACP,OAAA,EACE,KAAA,GAAQ,CAAA,GACJ,CAAA,oBAAA,EAAkB,IAAA,CAAK,cAAA,EAAgB,CAAA,CAAA,EAAI,KAAA,CAAM,cAAA,EAAgB,CAAA,CAAA,GACjE,qBAAA;AAAA,YACN;AAAA,WACD,CAAA;AAAA,QACH;AAAA;AACF,KACF;AACA,IAAA,KAAA,EAAO,UAAA,GAAa,EAAE,KAAA,EAAO,MAAA,EAAQ,SAAS,gDAAA,EAAwC,GAAA,EAAK,KAAK,CAAA;AAChG,IAAA,OAAO,OAAA;AAAA,EACT,SAAS,CAAA,EAAG;AACV,IAAA,MAAM,UAAU,CAAA,YAAa,KAAA,GAAQ,CAAA,CAAE,OAAA,GAAU,OAAO,CAAC,CAAA;AACzD,IAAA,KAAA,EAAO,UAAA,GAAa;AAAA,MAClB,KAAA,EAAO,OAAA;AAAA,MACP,OAAA,EAAS,iCAAiC,OAAO,CAAA;AAAA,KAClD,CAAA;AACD,IAAA,MAAM,CAAA;AAAA,EACR;AACF","file":"chunk-Z3MUWXP3.js","sourcesContent":["/**\n * Ensure a code map exists before VG Code (or any host) starts work.\n *\n * Interactive CLI, `vg code --stream-json`, and VS Code all share this path so\n * the first turn never fails with \"no map found\" — we build once (with progress\n * callbacks for host UIs) and then proceed.\n */\n\nimport { loadGraph } from '../engine/load.js';\nimport { runBuild } from '../commands/build.js';\nimport type { GlobalOpts } from '../cli-options.js';\n\nexport type EnsureMapPhase = 'start' | 'progress' | 'done' | 'error';\n\nexport interface EnsureMapProgress {\n phase: EnsureMapPhase;\n message: string;\n /** 0–100 when known (parse phase); omitted when indeterminate. */\n pct?: number;\n}\n\nexport interface EnsureMapHooks {\n onProgress?: (p: EnsureMapProgress) => void;\n}\n\n/**\n * @returns `ready` when a map already existed; `built` when this call built one.\n */\nexport async function ensureCodeMap(\n root: string,\n global: GlobalOpts,\n hooks?: EnsureMapHooks,\n): Promise<'ready' | 'built'> {\n if (loadGraph(root, global.graph)) return 'ready';\n\n hooks?.onProgress?.({\n phase: 'start',\n message: 'Building the code map for this project… (first run only)',\n pct: 0,\n });\n\n try {\n await runBuild(\n [root],\n { html: false, report: false },\n { ...global, quiet: true },\n {\n onParseProgress: (done, total) => {\n const pct = total > 0 ? Math.min(99, Math.round((done / total) * 100)) : undefined;\n hooks?.onProgress?.({\n phase: 'progress',\n message:\n total > 0\n ? `Parsing files… ${done.toLocaleString()}/${total.toLocaleString()}`\n : 'Parsing files…',\n pct,\n });\n },\n },\n );\n hooks?.onProgress?.({ phase: 'done', message: 'Code map ready — starting your task…', pct: 100 });\n return 'built';\n } catch (e) {\n const message = e instanceof Error ? e.message : String(e);\n hooks?.onProgress?.({\n phase: 'error',\n message: `Could not build the code map: ${message}`,\n });\n throw e;\n }\n}\n"]}
1
+ {"version":3,"sources":["../src/code/ensure-map.ts"],"names":[],"mappings":";;;;AA4BA,eAAsB,aAAA,CACpB,IAAA,EACA,MAAA,EACA,KAAA,EAC4B;AAC5B,EAAA,IAAI,SAAA,CAAU,IAAA,EAAM,MAAA,CAAO,KAAK,GAAG,OAAO,OAAA;AAE1C,EAAA,KAAA,EAAO,UAAA,GAAa;AAAA,IAClB,KAAA,EAAO,OAAA;AAAA,IACP,OAAA,EAAS,+DAAA;AAAA,IACT,GAAA,EAAK;AAAA,GACN,CAAA;AAED,EAAA,IAAI;AACF,IAAA,MAAM,QAAA;AAAA,MACJ,CAAC,IAAI,CAAA;AAAA,MACL,EAAE,IAAA,EAAM,KAAA,EAAO,MAAA,EAAQ,KAAA,EAAM;AAAA,MAC7B,EAAE,GAAG,MAAA,EAAQ,KAAA,EAAO,IAAA,EAAK;AAAA,MACzB;AAAA,QACE,eAAA,EAAiB,CAAC,IAAA,EAAM,KAAA,KAAU;AAChC,UAAA,MAAM,GAAA,GAAM,KAAA,GAAQ,CAAA,GAAI,IAAA,CAAK,GAAA,CAAI,EAAA,EAAI,IAAA,CAAK,KAAA,CAAO,IAAA,GAAO,KAAA,GAAS,GAAG,CAAC,CAAA,GAAI,KAAA,CAAA;AACzE,UAAA,KAAA,EAAO,UAAA,GAAa;AAAA,YAClB,KAAA,EAAO,UAAA;AAAA,YACP,OAAA,EACE,KAAA,GAAQ,CAAA,GACJ,CAAA,oBAAA,EAAkB,IAAA,CAAK,cAAA,EAAgB,CAAA,CAAA,EAAI,KAAA,CAAM,cAAA,EAAgB,CAAA,CAAA,GACjE,qBAAA;AAAA,YACN;AAAA,WACD,CAAA;AAAA,QACH;AAAA;AACF,KACF;AACA,IAAA,KAAA,EAAO,UAAA,GAAa,EAAE,KAAA,EAAO,MAAA,EAAQ,SAAS,gDAAA,EAAwC,GAAA,EAAK,KAAK,CAAA;AAChG,IAAA,OAAO,OAAA;AAAA,EACT,SAAS,CAAA,EAAG;AACV,IAAA,MAAM,UAAU,CAAA,YAAa,KAAA,GAAQ,CAAA,CAAE,OAAA,GAAU,OAAO,CAAC,CAAA;AACzD,IAAA,KAAA,EAAO,UAAA,GAAa;AAAA,MAClB,KAAA,EAAO,OAAA;AAAA,MACP,OAAA,EAAS,iCAAiC,OAAO,CAAA;AAAA,KAClD,CAAA;AACD,IAAA,MAAM,CAAA;AAAA,EACR;AACF","file":"chunk-BH54SLGZ.js","sourcesContent":["/**\n * Ensure a code map exists before VG Code (or any host) starts work.\n *\n * Interactive CLI, `vg code --stream-json`, and VS Code all share this path so\n * the first turn never fails with \"no map found\" — we build once (with progress\n * callbacks for host UIs) and then proceed.\n */\n\nimport { loadGraph } from '../engine/load.js';\nimport { runBuild } from '../commands/build.js';\nimport type { GlobalOpts } from '../cli-options.js';\n\nexport type EnsureMapPhase = 'start' | 'progress' | 'done' | 'error';\n\nexport interface EnsureMapProgress {\n phase: EnsureMapPhase;\n message: string;\n /** 0–100 when known (parse phase); omitted when indeterminate. */\n pct?: number;\n}\n\nexport interface EnsureMapHooks {\n onProgress?: (p: EnsureMapProgress) => void;\n}\n\n/**\n * @returns `ready` when a map already existed; `built` when this call built one.\n */\nexport async function ensureCodeMap(\n root: string,\n global: GlobalOpts,\n hooks?: EnsureMapHooks,\n): Promise<'ready' | 'built'> {\n if (loadGraph(root, global.graph)) return 'ready';\n\n hooks?.onProgress?.({\n phase: 'start',\n message: 'Building the code map for this project… (first run only)',\n pct: 0,\n });\n\n try {\n await runBuild(\n [root],\n { html: false, report: false },\n { ...global, quiet: true },\n {\n onParseProgress: (done, total) => {\n const pct = total > 0 ? Math.min(99, Math.round((done / total) * 100)) : undefined;\n hooks?.onProgress?.({\n phase: 'progress',\n message:\n total > 0\n ? `Parsing files… ${done.toLocaleString()}/${total.toLocaleString()}`\n : 'Parsing files…',\n pct,\n });\n },\n },\n );\n hooks?.onProgress?.({ phase: 'done', message: 'Code map ready — starting your task…', pct: 100 });\n return 'built';\n } catch (e) {\n const message = e instanceof Error ? e.message : String(e);\n hooks?.onProgress?.({\n phase: 'error',\n message: `Could not build the code map: ${message}`,\n });\n throw e;\n }\n}\n"]}
@@ -1,5 +1,5 @@
1
- import { indexFor, userAskFromInstruction, queryGraph, impactOf, conceptMapLines, extractLiteralNeedles } from './chunk-YJU7S7N6.js';
2
- import { cacheDir } from './chunk-EWZKOU66.js';
1
+ import { indexFor, userAskFromInstruction, queryGraph, impactOf, conceptMapLines, extractLiteralNeedles } from './chunk-KGPX4EUN.js';
2
+ import { cacheDir } from './chunk-2U37PFB2.js';
3
3
  import { hashString } from './chunk-JFGYT6BI.js';
4
4
  import * as fs from 'fs';
5
5
  import * as path from 'path';
@@ -642,5 +642,5 @@ function estimateTokens2(text) {
642
642
  }
643
643
 
644
644
  export { CAPSULE_COMPILER_ID, CAPSULE_RANKING_VERSION, CLI_TOOL_ALIASES, PER_FILE_TOKENS, SAVINGS_TOOLS, TASK_CAPSULE_SCHEMA_VERSION, buildCodeContext, buildTaskCapsule, capsuleToCodeContext, clearSavings, readModelSavings, readSavings, readUsage, recordCliCall, recordSaving, sanitizeClient, savingsLedgerPath, savingsRecorded, summarizeCapsule };
645
- //# sourceMappingURL=chunk-CJNWHXQD.js.map
646
- //# sourceMappingURL=chunk-CJNWHXQD.js.map
645
+ //# sourceMappingURL=chunk-DSUGC7F5.js.map
646
+ //# sourceMappingURL=chunk-DSUGC7F5.js.map