poly-weaver 0.7.0 → 0.8.0

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 (186) hide show
  1. package/dist/ansi.d.ts +7 -0
  2. package/dist/ansi.d.ts.map +1 -1
  3. package/dist/ansi.js +30 -0
  4. package/dist/ansi.js.map +1 -1
  5. package/dist/app-header.d.ts +16 -0
  6. package/dist/app-header.d.ts.map +1 -0
  7. package/dist/app-header.js +74 -0
  8. package/dist/app-header.js.map +1 -0
  9. package/dist/cli.js +81 -59
  10. package/dist/cli.js.map +1 -1
  11. package/dist/config.d.ts +1 -0
  12. package/dist/config.d.ts.map +1 -1
  13. package/dist/config.js +6 -0
  14. package/dist/config.js.map +1 -1
  15. package/dist/dump/collector.d.ts +2 -1
  16. package/dist/dump/collector.d.ts.map +1 -1
  17. package/dist/dump/collector.js +1 -0
  18. package/dist/dump/collector.js.map +1 -1
  19. package/dist/dump/hotkey.d.ts +9 -30
  20. package/dist/dump/hotkey.d.ts.map +1 -1
  21. package/dist/dump/hotkey.js +15 -158
  22. package/dist/dump/hotkey.js.map +1 -1
  23. package/dist/dump/service.d.ts +3 -2
  24. package/dist/dump/service.d.ts.map +1 -1
  25. package/dist/dump/service.js +4 -1
  26. package/dist/dump/service.js.map +1 -1
  27. package/dist/dump/types.d.ts +5 -0
  28. package/dist/dump/types.d.ts.map +1 -1
  29. package/dist/flow/built-in/default-factory.d.ts +21 -0
  30. package/dist/flow/built-in/default-factory.d.ts.map +1 -0
  31. package/dist/flow/built-in/default-factory.js +155 -0
  32. package/dist/flow/built-in/default-factory.js.map +1 -0
  33. package/dist/flow/built-in/default.d.ts +4 -4
  34. package/dist/flow/built-in/default.d.ts.map +1 -1
  35. package/dist/flow/built-in/default.js +3 -141
  36. package/dist/flow/built-in/default.js.map +1 -1
  37. package/dist/flow/built-in/default.ts +5 -169
  38. package/dist/flow/built-in/why-so-serious-factory.d.ts +16 -0
  39. package/dist/flow/built-in/why-so-serious-factory.d.ts.map +1 -0
  40. package/dist/flow/built-in/why-so-serious-factory.js +187 -0
  41. package/dist/flow/built-in/why-so-serious-factory.js.map +1 -0
  42. package/dist/flow/built-in/why-so-serious.d.ts +3 -2
  43. package/dist/flow/built-in/why-so-serious.d.ts.map +1 -1
  44. package/dist/flow/built-in/why-so-serious.js +3 -164
  45. package/dist/flow/built-in/why-so-serious.js.map +1 -1
  46. package/dist/flow/custom/AUTHORING.md +13 -0
  47. package/dist/flow/custom/load.d.ts +16 -1
  48. package/dist/flow/custom/load.d.ts.map +1 -1
  49. package/dist/flow/custom/load.js +69 -18
  50. package/dist/flow/custom/load.js.map +1 -1
  51. package/dist/flow/dsl.js +1 -1
  52. package/dist/flow/dsl.js.map +1 -1
  53. package/dist/flow/executor.d.ts.map +1 -1
  54. package/dist/flow/executor.js +44 -8
  55. package/dist/flow/executor.js.map +1 -1
  56. package/dist/flow/types.d.ts +20 -2
  57. package/dist/flow/types.d.ts.map +1 -1
  58. package/dist/flow/types.js.map +1 -1
  59. package/dist/flow-editor/tui.d.ts.map +1 -1
  60. package/dist/flow-editor/tui.js +9 -18
  61. package/dist/flow-editor/tui.js.map +1 -1
  62. package/dist/markdown.d.ts.map +1 -1
  63. package/dist/markdown.js +60 -0
  64. package/dist/markdown.js.map +1 -1
  65. package/dist/orchestrator.d.ts +43 -0
  66. package/dist/orchestrator.d.ts.map +1 -1
  67. package/dist/orchestrator.js +230 -92
  68. package/dist/orchestrator.js.map +1 -1
  69. package/dist/providers/claude/completion-plan-mode.d.ts.map +1 -1
  70. package/dist/providers/claude/completion-plan-mode.js +7 -1
  71. package/dist/providers/claude/completion-plan-mode.js.map +1 -1
  72. package/dist/providers/claude/tool-tracking.d.ts +1 -0
  73. package/dist/providers/claude/tool-tracking.d.ts.map +1 -1
  74. package/dist/providers/claude/tool-tracking.js +3 -0
  75. package/dist/providers/claude/tool-tracking.js.map +1 -1
  76. package/dist/providers/copilot/session.d.ts +35 -1
  77. package/dist/providers/copilot/session.d.ts.map +1 -1
  78. package/dist/providers/copilot/session.js +121 -1
  79. package/dist/providers/copilot/session.js.map +1 -1
  80. package/dist/providers/types.d.ts +3 -1
  81. package/dist/providers/types.d.ts.map +1 -1
  82. package/dist/pty/spawn.d.ts.map +1 -1
  83. package/dist/pty/spawn.js +6 -1
  84. package/dist/pty/spawn.js.map +1 -1
  85. package/dist/pty/types.d.ts +7 -2
  86. package/dist/pty/types.d.ts.map +1 -1
  87. package/dist/resume-tui.d.ts +52 -0
  88. package/dist/resume-tui.d.ts.map +1 -0
  89. package/dist/resume-tui.js +344 -0
  90. package/dist/resume-tui.js.map +1 -0
  91. package/dist/session/flow-snapshot.d.ts +14 -0
  92. package/dist/session/flow-snapshot.d.ts.map +1 -0
  93. package/dist/session/flow-snapshot.js +28 -0
  94. package/dist/session/flow-snapshot.js.map +1 -0
  95. package/dist/session/list.d.ts +16 -0
  96. package/dist/session/list.d.ts.map +1 -0
  97. package/dist/session/list.js +89 -0
  98. package/dist/session/list.js.map +1 -0
  99. package/dist/session/lock.d.ts +26 -0
  100. package/dist/session/lock.d.ts.map +1 -0
  101. package/dist/session/lock.js +95 -0
  102. package/dist/session/lock.js.map +1 -0
  103. package/dist/session/manifest.d.ts +80 -0
  104. package/dist/session/manifest.d.ts.map +1 -0
  105. package/dist/session/manifest.js +2 -0
  106. package/dist/session/manifest.js.map +1 -0
  107. package/dist/session/persistence.d.ts +19 -0
  108. package/dist/session/persistence.d.ts.map +1 -0
  109. package/dist/session/persistence.js +68 -0
  110. package/dist/session/persistence.js.map +1 -0
  111. package/dist/session/process-start-time.d.ts +17 -0
  112. package/dist/session/process-start-time.d.ts.map +1 -0
  113. package/dist/session/process-start-time.js +99 -0
  114. package/dist/session/process-start-time.js.map +1 -0
  115. package/dist/session/restore.d.ts +31 -0
  116. package/dist/session/restore.d.ts.map +1 -0
  117. package/dist/session/restore.js +111 -0
  118. package/dist/session/restore.js.map +1 -0
  119. package/dist/session/resume.d.ts +5 -0
  120. package/dist/session/resume.d.ts.map +1 -0
  121. package/dist/session/resume.js +109 -0
  122. package/dist/session/resume.js.map +1 -0
  123. package/dist/session/session-store.d.ts +43 -0
  124. package/dist/session/session-store.d.ts.map +1 -0
  125. package/dist/session/session-store.js +134 -0
  126. package/dist/session/session-store.js.map +1 -0
  127. package/dist/startup-tui.d.ts +10 -11
  128. package/dist/startup-tui.d.ts.map +1 -1
  129. package/dist/startup-tui.js +25 -108
  130. package/dist/startup-tui.js.map +1 -1
  131. package/dist/status-bar.js +1 -26
  132. package/dist/status-bar.js.map +1 -1
  133. package/dist/terminal/host.d.ts +22 -9
  134. package/dist/terminal/host.d.ts.map +1 -1
  135. package/dist/terminal/host.js +67 -78
  136. package/dist/terminal/host.js.map +1 -1
  137. package/dist/terminal/input-router.d.ts +24 -103
  138. package/dist/terminal/input-router.d.ts.map +1 -1
  139. package/dist/terminal/input-router.js +63 -364
  140. package/dist/terminal/input-router.js.map +1 -1
  141. package/dist/terminal/key-event-source.d.ts +52 -0
  142. package/dist/terminal/key-event-source.d.ts.map +1 -0
  143. package/dist/terminal/key-event-source.js +31 -0
  144. package/dist/terminal/key-event-source.js.map +1 -0
  145. package/dist/terminal/key-to-bytes.d.ts +11 -0
  146. package/dist/terminal/key-to-bytes.d.ts.map +1 -0
  147. package/dist/terminal/key-to-bytes.js +81 -0
  148. package/dist/terminal/key-to-bytes.js.map +1 -0
  149. package/dist/terminal/koffi-loader.d.ts +14 -0
  150. package/dist/terminal/koffi-loader.d.ts.map +1 -1
  151. package/dist/terminal/koffi-loader.js.map +1 -1
  152. package/dist/terminal/render.d.ts +1 -2
  153. package/dist/terminal/render.d.ts.map +1 -1
  154. package/dist/terminal/render.js +1 -30
  155. package/dist/terminal/render.js.map +1 -1
  156. package/dist/terminal/stdin-byte-source.d.ts +27 -0
  157. package/dist/terminal/stdin-byte-source.d.ts.map +1 -0
  158. package/dist/terminal/stdin-byte-source.js +92 -0
  159. package/dist/terminal/stdin-byte-source.js.map +1 -0
  160. package/dist/terminal/win32-console-mode.d.ts.map +1 -1
  161. package/dist/terminal/win32-console-mode.js.map +1 -1
  162. package/dist/terminal/win32-console-source.d.ts +26 -0
  163. package/dist/terminal/win32-console-source.d.ts.map +1 -0
  164. package/dist/terminal/win32-console-source.js +275 -0
  165. package/dist/terminal/win32-console-source.js.map +1 -0
  166. package/dist/terminal/win32-key-translator.d.ts +26 -0
  167. package/dist/terminal/win32-key-translator.d.ts.map +1 -0
  168. package/dist/terminal/win32-key-translator.js +87 -0
  169. package/dist/terminal/win32-key-translator.js.map +1 -0
  170. package/dist/terminal-input.d.ts +10 -0
  171. package/dist/terminal-input.d.ts.map +1 -1
  172. package/dist/terminal-input.js +132 -113
  173. package/dist/terminal-input.js.map +1 -1
  174. package/dist/user/host-curate-prompt.d.ts +2 -1
  175. package/dist/user/host-curate-prompt.d.ts.map +1 -1
  176. package/dist/user/host-curate-prompt.js +13 -11
  177. package/dist/user/host-curate-prompt.js.map +1 -1
  178. package/dist/user/host-prompt.d.ts +4 -1
  179. package/dist/user/host-prompt.d.ts.map +1 -1
  180. package/dist/user/host-prompt.js +24 -6
  181. package/dist/user/host-prompt.js.map +1 -1
  182. package/dist/user/prompt.d.ts +7 -9
  183. package/dist/user/prompt.d.ts.map +1 -1
  184. package/dist/user/prompt.js +14 -23
  185. package/dist/user/prompt.js.map +1 -1
  186. package/package.json +1 -1
@@ -0,0 +1,344 @@
1
+ import { visibleLength, padToWidth, bold, dim, reset, cyan, green, red, HIDE_CURSOR, ALT_SCREEN_ON, ALT_SCREEN_OFF, CSI, } from "./ansi.js";
2
+ import { TuiInputParser } from "./startup-tui.js";
3
+ import { createKeyEventSource } from "./terminal/key-event-source.js";
4
+ import { discardSession, listResumableSessions } from "./session/list.js";
5
+ import { getGitInfo } from "./git-info.js";
6
+ import { checkForUpdate } from "./update-check.js";
7
+ import { renderAppHeader, tildeify } from "./app-header.js";
8
+ // ─── State construction ──────────────────────────────────────────────
9
+ export function buildInitialState(sessions, opts, rows, cols, gitInfo) {
10
+ const newRowIndex = sessions.length;
11
+ return {
12
+ sessions,
13
+ selectedIndex: opts.preferNew ? newRowIndex : 0,
14
+ confirmDiscardFor: null,
15
+ errorMessage: null,
16
+ termRows: rows,
17
+ termCols: cols,
18
+ gitInfo: gitInfo ?? null,
19
+ updateBanner: null,
20
+ };
21
+ }
22
+ // ─── Helpers ─────────────────────────────────────────────────────────
23
+ function ageString(iso) {
24
+ const then = Date.parse(iso);
25
+ if (!Number.isFinite(then))
26
+ return "unknown";
27
+ const diffMs = Date.now() - then;
28
+ const s = Math.max(0, Math.floor(diffMs / 1000));
29
+ if (s < 60)
30
+ return `${s}s ago`;
31
+ const m = Math.floor(s / 60);
32
+ if (m < 60)
33
+ return `${m}m ago`;
34
+ const h = Math.floor(m / 60);
35
+ if (h < 24)
36
+ return `${h}h ago`;
37
+ const d = Math.floor(h / 24);
38
+ return `${d}d ago`;
39
+ }
40
+ function previewTask(text, max = 60) {
41
+ const oneLine = text
42
+ .replace(/\s*\n[\s]*/g, " ↵ ")
43
+ .replace(/\s+/g, " ")
44
+ .trim();
45
+ if (oneLine.length <= max)
46
+ return oneLine;
47
+ return oneLine.slice(0, max - 1) + "…";
48
+ }
49
+ function truncToCols(text, cols) {
50
+ if (visibleLength(text) <= cols)
51
+ return text;
52
+ // Best-effort truncate by visible characters (ignores ANSI codes width)
53
+ let out = "";
54
+ let vis = 0;
55
+ for (const ch of text) {
56
+ if (vis >= cols - 1)
57
+ break;
58
+ out += ch;
59
+ vis++;
60
+ }
61
+ return out + "…";
62
+ }
63
+ // ─── Rendering ───────────────────────────────────────────────────────
64
+ export function render(state, out) {
65
+ const cols = state.termCols;
66
+ const lines = [];
67
+ const pad = (s) => padToWidth(s, cols);
68
+ // Header
69
+ lines.push(...renderAppHeader(cols, state.gitInfo, state.updateBanner));
70
+ const sharedWorkdir = state.sessions[0]?.manifest.workdir;
71
+ if (sharedWorkdir) {
72
+ lines.push(pad(` ${tildeify(sharedWorkdir)}`));
73
+ }
74
+ lines.push(pad(` ${dim}Found ${state.sessions.length} resumable session${state.sessions.length === 1 ? "" : "s"}.${reset}`));
75
+ lines.push(pad(""));
76
+ // Session rows
77
+ state.sessions.forEach((session, idx) => {
78
+ const selected = idx === state.selectedIndex;
79
+ const marker = selected ? `${cyan}▸${reset}` : " ";
80
+ const m = session.manifest;
81
+ const taskPreview = previewTask(m.taskText);
82
+ const age = ageString(m.lastActivityAt);
83
+ const stepLabel = session.lastStepLabel ?? "waiting on first step";
84
+ // Locked rows render with a dim title even when selected, so it's
85
+ // visually obvious they cannot be acted on.
86
+ const titleStyle = (selected && !session.lock) ? `${bold}${green}` : dim;
87
+ const titleText = ` ${marker} ${titleStyle}${taskPreview || "(no task)"}${reset}`;
88
+ lines.push(pad(truncToCols(titleText, cols)));
89
+ const subParts = [];
90
+ subParts.push(`${dim}flow:${reset} ${m.flow.name}`);
91
+ subParts.push(`${dim}last:${reset} ${stepLabel}`);
92
+ subParts.push(`${dim}${age}${reset}`);
93
+ const subtitle = ` ${subParts.join(" ")}`;
94
+ lines.push(pad(truncToCols(subtitle, cols)));
95
+ if (!session.workdirExists) {
96
+ lines.push(pad(` ${red}[workdir missing — discard or recreate]${reset}`));
97
+ }
98
+ if (session.lock) {
99
+ const lockColor = selected ? red : dim;
100
+ lines.push(pad(` ${lockColor}[locked — running since ${ageString(session.lock.startedAt)}]${reset}`));
101
+ }
102
+ if (selected && state.confirmDiscardFor === session.sessionId) {
103
+ lines.push(pad(` ${red}${bold}Press d again to discard, any other key cancels${reset}`));
104
+ }
105
+ lines.push(pad(""));
106
+ });
107
+ // "Start new session" pseudo-row
108
+ const newIdx = state.sessions.length;
109
+ const newSelected = state.selectedIndex === newIdx;
110
+ const newMarker = newSelected ? `${cyan}▸${reset}` : " ";
111
+ const newStyle = newSelected ? `${bold}${green}` : bold;
112
+ lines.push(pad(` ${newMarker} ${newStyle}Start a new session${reset}`));
113
+ lines.push(pad(""));
114
+ if (state.errorMessage) {
115
+ lines.push(pad(` ${red}${state.errorMessage}${reset}`));
116
+ lines.push(pad(""));
117
+ }
118
+ // Footer
119
+ const footer = ` ${dim}↑↓${reset} Navigate ${dim}Enter${reset} Select ${dim}n${reset} New ${dim}d${reset} Discard ${dim}Esc${reset} Quit`;
120
+ lines.push(pad(footer));
121
+ const output = HIDE_CURSOR + `${CSI}H` + lines.join("\n") + `${CSI}J`;
122
+ if (output !== state.lastDrawnOutput) {
123
+ state.lastDrawnOutput = output;
124
+ out.write(output);
125
+ }
126
+ }
127
+ export async function handleEvent(state, event) {
128
+ if (event.type === "ctrl+c" || event.type === "escape") {
129
+ return { kind: "cancel" };
130
+ }
131
+ const lastIdx = state.sessions.length; // "new" row
132
+ const selectedSession = state.sessions[state.selectedIndex];
133
+ // Discard confirmation flow
134
+ if (state.confirmDiscardFor) {
135
+ if (event.type === "insert" && event.text === "d" && selectedSession?.sessionId === state.confirmDiscardFor) {
136
+ // Race-safety: a periodic refresh may have promoted this row to
137
+ // locked between the first and second `d`. Refuse the discard.
138
+ if (selectedSession.lock) {
139
+ state.confirmDiscardFor = null;
140
+ state.errorMessage = "Session is locked by another running poly-weaver process — cannot discard.";
141
+ return { kind: "handled" };
142
+ }
143
+ const target = selectedSession;
144
+ try {
145
+ await discardSession(target.persistentDir);
146
+ state.sessions = state.sessions.filter(s => s.sessionId !== target.sessionId);
147
+ if (state.selectedIndex >= state.sessions.length) {
148
+ state.selectedIndex = state.sessions.length; // land on "new" row
149
+ }
150
+ state.confirmDiscardFor = null;
151
+ state.errorMessage = null;
152
+ }
153
+ catch (err) {
154
+ state.errorMessage = `Failed to discard: ${err instanceof Error ? err.message : err}`;
155
+ state.confirmDiscardFor = null;
156
+ }
157
+ return { kind: "handled" };
158
+ }
159
+ // Any other key cancels the armed state.
160
+ state.confirmDiscardFor = null;
161
+ return { kind: "handled" };
162
+ }
163
+ if (event.type === "up") {
164
+ if (state.selectedIndex > 0)
165
+ state.selectedIndex--;
166
+ state.errorMessage = null;
167
+ return { kind: "handled" };
168
+ }
169
+ if (event.type === "down") {
170
+ if (state.selectedIndex < lastIdx)
171
+ state.selectedIndex++;
172
+ state.errorMessage = null;
173
+ return { kind: "handled" };
174
+ }
175
+ if (event.type === "submit") {
176
+ if (state.selectedIndex === lastIdx)
177
+ return { kind: "new" };
178
+ if (selectedSession) {
179
+ if (selectedSession.lock) {
180
+ state.errorMessage = "Session is locked by another running poly-weaver process — wait for it to exit or pick another.";
181
+ return { kind: "handled" };
182
+ }
183
+ if (!selectedSession.workdirExists) {
184
+ state.errorMessage = "Workdir missing — discard the session or recreate the directory.";
185
+ return { kind: "handled" };
186
+ }
187
+ return { kind: "resume", session: selectedSession };
188
+ }
189
+ return { kind: "handled" };
190
+ }
191
+ if (event.type === "insert" && event.text === "n") {
192
+ return { kind: "new" };
193
+ }
194
+ if (event.type === "insert" && event.text === "d") {
195
+ if (selectedSession) {
196
+ if (selectedSession.lock) {
197
+ state.errorMessage = "Session is locked by another running poly-weaver process — cannot discard.";
198
+ return { kind: "handled" };
199
+ }
200
+ state.confirmDiscardFor = selectedSession.sessionId;
201
+ }
202
+ return { kind: "handled" };
203
+ }
204
+ return { kind: "handled" };
205
+ }
206
+ // ─── Main entry point ────────────────────────────────────────────────
207
+ export async function showResumePicker(sessions, opts = {}, cwd) {
208
+ const rows = process.stdout.rows ?? 24;
209
+ const cols = process.stdout.columns ?? 80;
210
+ const gitInfo = await getGitInfo(cwd ?? process.cwd());
211
+ const state = buildInitialState(sessions, opts, rows, cols, gitInfo);
212
+ process.stdout.write(ALT_SCREEN_ON);
213
+ let disposed = false;
214
+ void checkForUpdate().then((result) => {
215
+ if (disposed || !result)
216
+ return;
217
+ state.updateBanner = result;
218
+ state.lastDrawnOutput = undefined;
219
+ render(state, process.stdout);
220
+ });
221
+ try {
222
+ render(state, process.stdout);
223
+ return await inputLoop(state, cwd);
224
+ }
225
+ finally {
226
+ disposed = true;
227
+ process.stdout.write(ALT_SCREEN_OFF);
228
+ }
229
+ }
230
+ const REFRESH_INTERVAL_MS = 2000;
231
+ /**
232
+ * Reconcile fresh `listResumableSessions` output into `state.sessions`.
233
+ *
234
+ * Preserves in-memory row positions so a row's lock indicator can
235
+ * appear/disappear without the list visually jumping. Selection sticks to
236
+ * the same `sessionId` when possible.
237
+ */
238
+ export function reconcileSessions(state, fresh) {
239
+ const freshById = new Map(fresh.map(s => [s.sessionId, s]));
240
+ const previousSelectedId = state.sessions[state.selectedIndex]?.sessionId;
241
+ // Drop sessions no longer in the fresh list; replace mutable fields on the rest.
242
+ const kept = [];
243
+ for (const existing of state.sessions) {
244
+ const updated = freshById.get(existing.sessionId);
245
+ if (!updated)
246
+ continue;
247
+ kept.push({
248
+ ...existing,
249
+ lastStepLabel: updated.lastStepLabel,
250
+ workdirExists: updated.workdirExists,
251
+ manifest: updated.manifest,
252
+ lock: updated.lock,
253
+ });
254
+ freshById.delete(existing.sessionId);
255
+ }
256
+ // Append any genuinely new sessions at the bottom.
257
+ for (const fresh of freshById.values())
258
+ kept.push(fresh);
259
+ state.sessions = kept;
260
+ // Reposition the selection to the same sessionId if it still exists.
261
+ const newSelectedIdx = previousSelectedId
262
+ ? kept.findIndex(s => s.sessionId === previousSelectedId)
263
+ : -1;
264
+ if (newSelectedIdx >= 0) {
265
+ state.selectedIndex = newSelectedIdx;
266
+ }
267
+ else if (state.selectedIndex > kept.length) {
268
+ state.selectedIndex = kept.length;
269
+ }
270
+ // Discard arming if the armed session is gone or now locked.
271
+ if (state.confirmDiscardFor) {
272
+ const armed = kept.find(s => s.sessionId === state.confirmDiscardFor);
273
+ if (!armed || armed.lock)
274
+ state.confirmDiscardFor = null;
275
+ }
276
+ }
277
+ async function inputLoop(state, workdir) {
278
+ const parser = new TuiInputParser();
279
+ const source = createKeyEventSource();
280
+ source.start();
281
+ return new Promise((resolve) => {
282
+ const handleResult = async (events) => {
283
+ for (const event of events) {
284
+ const result = await handleEvent(state, event);
285
+ switch (result.kind) {
286
+ case "resume":
287
+ cleanup();
288
+ resolve({ mode: "resume", session: result.session });
289
+ return true;
290
+ case "new":
291
+ cleanup();
292
+ resolve({ mode: "new" });
293
+ return true;
294
+ case "cancel":
295
+ cleanup();
296
+ resolve(null);
297
+ return true;
298
+ case "handled":
299
+ break;
300
+ }
301
+ }
302
+ render(state, process.stdout);
303
+ return false;
304
+ };
305
+ const unsubscribe = source.onEvents((keys) => {
306
+ void handleResult(parser.mapKeys(keys));
307
+ });
308
+ const onResize = () => {
309
+ state.termRows = process.stdout.rows ?? 24;
310
+ state.termCols = process.stdout.columns ?? 80;
311
+ state.lastDrawnOutput = undefined;
312
+ render(state, process.stdout);
313
+ };
314
+ process.stdout.on("resize", onResize);
315
+ // Periodic refresh — surfaces lock transitions while the picker is open.
316
+ let refreshing = false;
317
+ const refreshTimer = setInterval(() => {
318
+ if (refreshing)
319
+ return;
320
+ refreshing = true;
321
+ (async () => {
322
+ try {
323
+ const fresh = await listResumableSessions(workdir);
324
+ reconcileSessions(state, fresh);
325
+ render(state, process.stdout);
326
+ }
327
+ catch {
328
+ /* refresh failures are non-fatal */
329
+ }
330
+ finally {
331
+ refreshing = false;
332
+ }
333
+ })();
334
+ }, REFRESH_INTERVAL_MS);
335
+ refreshTimer.unref?.();
336
+ function cleanup() {
337
+ clearInterval(refreshTimer);
338
+ unsubscribe();
339
+ source.stop();
340
+ process.stdout.removeListener("resize", onResize);
341
+ }
342
+ });
343
+ }
344
+ //# sourceMappingURL=resume-tui.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resume-tui.js","sourceRoot":"","sources":["../src/resume-tui.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,aAAa,EAAE,UAAU,EACzB,IAAI,EAAE,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,EAClC,WAAW,EAAE,aAAa,EAAE,cAAc,EAAE,GAAG,GAChD,MAAM,WAAW,CAAC;AACnB,OAAO,EAAE,cAAc,EAAsB,MAAM,kBAAkB,CAAC;AACtE,OAAO,EAAE,oBAAoB,EAAE,MAAM,gCAAgC,CAAC;AACtE,OAAO,EAAE,cAAc,EAAE,qBAAqB,EAAE,MAAM,mBAAmB,CAAC;AAE1E,OAAO,EAAE,UAAU,EAAgB,MAAM,eAAe,CAAC;AACzD,OAAO,EAAE,cAAc,EAAmB,MAAM,mBAAmB,CAAC;AACpE,OAAO,EAAE,eAAe,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AA2B5D,wEAAwE;AAExE,MAAM,UAAU,iBAAiB,CAC/B,QAA6B,EAC7B,IAAsB,EACtB,IAAY,EACZ,IAAY,EACZ,OAAwB;IAExB,MAAM,WAAW,GAAG,QAAQ,CAAC,MAAM,CAAC;IACpC,OAAO;QACL,QAAQ;QACR,aAAa,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC;QAC/C,iBAAiB,EAAE,IAAI;QACvB,YAAY,EAAE,IAAI;QAClB,QAAQ,EAAE,IAAI;QACd,QAAQ,EAAE,IAAI;QACd,OAAO,EAAE,OAAO,IAAI,IAAI;QACxB,YAAY,EAAE,IAAI;KACnB,CAAC;AACJ,CAAC;AAED,wEAAwE;AAExE,SAAS,SAAS,CAAC,GAAW;IAC5B,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAC7B,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC;QAAE,OAAO,SAAS,CAAC;IAC7C,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC;IACjC,MAAM,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC,CAAC;IACjD,IAAI,CAAC,GAAG,EAAE;QAAE,OAAO,GAAG,CAAC,OAAO,CAAC;IAC/B,MAAM,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC;IAC7B,IAAI,CAAC,GAAG,EAAE;QAAE,OAAO,GAAG,CAAC,OAAO,CAAC;IAC/B,MAAM,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC;IAC7B,IAAI,CAAC,GAAG,EAAE;QAAE,OAAO,GAAG,CAAC,OAAO,CAAC;IAC/B,MAAM,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC;IAC7B,OAAO,GAAG,CAAC,OAAO,CAAC;AACrB,CAAC;AAED,SAAS,WAAW,CAAC,IAAY,EAAE,GAAG,GAAG,EAAE;IACzC,MAAM,OAAO,GAAG,IAAI;SACjB,OAAO,CAAC,aAAa,EAAE,KAAK,CAAC;SAC7B,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC;SACpB,IAAI,EAAE,CAAC;IACV,IAAI,OAAO,CAAC,MAAM,IAAI,GAAG;QAAE,OAAO,OAAO,CAAC;IAC1C,OAAO,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,GAAG,CAAC,CAAC,GAAG,GAAG,CAAC;AACzC,CAAC;AAED,SAAS,WAAW,CAAC,IAAY,EAAE,IAAY;IAC7C,IAAI,aAAa,CAAC,IAAI,CAAC,IAAI,IAAI;QAAE,OAAO,IAAI,CAAC;IAC7C,wEAAwE;IACxE,IAAI,GAAG,GAAG,EAAE,CAAC;IACb,IAAI,GAAG,GAAG,CAAC,CAAC;IACZ,KAAK,MAAM,EAAE,IAAI,IAAI,EAAE,CAAC;QACtB,IAAI,GAAG,IAAI,IAAI,GAAG,CAAC;YAAE,MAAM;QAC3B,GAAG,IAAI,EAAE,CAAC;QACV,GAAG,EAAE,CAAC;IACR,CAAC;IACD,OAAO,GAAG,GAAG,GAAG,CAAC;AACnB,CAAC;AAED,wEAAwE;AAExE,MAAM,UAAU,MAAM,CAAC,KAAqB,EAAE,GAAuB;IACnE,MAAM,IAAI,GAAG,KAAK,CAAC,QAAQ,CAAC;IAC5B,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,MAAM,GAAG,GAAG,CAAC,CAAS,EAAU,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC;IAEvD,SAAS;IACT,KAAK,CAAC,IAAI,CAAC,GAAG,eAAe,CAAC,IAAI,EAAE,KAAK,CAAC,OAAO,EAAE,KAAK,CAAC,YAAY,CAAC,CAAC,CAAC;IACxE,MAAM,aAAa,GAAG,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,QAAQ,CAAC,OAAO,CAAC;IAC1D,IAAI,aAAa,EAAE,CAAC;QAClB,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,QAAQ,CAAC,aAAa,CAAC,EAAE,CAAC,CAAC,CAAC;IAClD,CAAC;IACD,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,GAAG,SAAS,KAAK,CAAC,QAAQ,CAAC,MAAM,qBAAqB,KAAK,CAAC,QAAQ,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,IAAI,KAAK,EAAE,CAAC,CAAC,CAAC;IAC9H,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC;IAEpB,eAAe;IACf,KAAK,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,OAAO,EAAE,GAAG,EAAE,EAAE;QACtC,MAAM,QAAQ,GAAG,GAAG,KAAK,KAAK,CAAC,aAAa,CAAC;QAC7C,MAAM,MAAM,GAAG,QAAQ,CAAC,CAAC,CAAC,GAAG,IAAI,IAAI,KAAK,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC;QACnD,MAAM,CAAC,GAAG,OAAO,CAAC,QAAQ,CAAC;QAC3B,MAAM,WAAW,GAAG,WAAW,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC;QAC5C,MAAM,GAAG,GAAG,SAAS,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC;QACxC,MAAM,SAAS,GAAG,OAAO,CAAC,aAAa,IAAI,uBAAuB,CAAC;QAEnE,kEAAkE;QAClE,4CAA4C;QAC5C,MAAM,UAAU,GAAG,CAAC,QAAQ,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,GAAG,KAAK,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC;QACzE,MAAM,SAAS,GAAG,KAAK,MAAM,IAAI,UAAU,GAAG,WAAW,IAAI,WAAW,GAAG,KAAK,EAAE,CAAC;QACnF,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,WAAW,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC;QAE9C,MAAM,QAAQ,GAAa,EAAE,CAAC;QAC9B,QAAQ,CAAC,IAAI,CAAC,GAAG,GAAG,QAAQ,KAAK,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;QACpD,QAAQ,CAAC,IAAI,CAAC,GAAG,GAAG,QAAQ,KAAK,IAAI,SAAS,EAAE,CAAC,CAAC;QAClD,QAAQ,CAAC,IAAI,CAAC,GAAG,GAAG,GAAG,GAAG,GAAG,KAAK,EAAE,CAAC,CAAC;QACtC,MAAM,QAAQ,GAAG,SAAS,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;QAChD,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,WAAW,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC;QAE7C,IAAI,CAAC,OAAO,CAAC,aAAa,EAAE,CAAC;YAC3B,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,SAAS,GAAG,0CAA0C,KAAK,EAAE,CAAC,CAAC,CAAC;QACjF,CAAC;QAED,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC;YACjB,MAAM,SAAS,GAAG,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC;YACvC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,SAAS,SAAS,2BAA2B,SAAS,CAAC,OAAO,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,KAAK,EAAE,CAAC,CAAC,CAAC;QAC7G,CAAC;QAED,IAAI,QAAQ,IAAI,KAAK,CAAC,iBAAiB,KAAK,OAAO,CAAC,SAAS,EAAE,CAAC;YAC9D,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,SAAS,GAAG,GAAG,IAAI,kDAAkD,KAAK,EAAE,CAAC,CAAC,CAAC;QAChG,CAAC;QAED,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC;IACtB,CAAC,CAAC,CAAC;IAEH,iCAAiC;IACjC,MAAM,MAAM,GAAG,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC;IACrC,MAAM,WAAW,GAAG,KAAK,CAAC,aAAa,KAAK,MAAM,CAAC;IACnD,MAAM,SAAS,GAAG,WAAW,CAAC,CAAC,CAAC,GAAG,IAAI,IAAI,KAAK,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC;IACzD,MAAM,QAAQ,GAAG,WAAW,CAAC,CAAC,CAAC,GAAG,IAAI,GAAG,KAAK,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;IACxD,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,SAAS,IAAI,QAAQ,sBAAsB,KAAK,EAAE,CAAC,CAAC,CAAC;IACzE,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC;IAEpB,IAAI,KAAK,CAAC,YAAY,EAAE,CAAC;QACvB,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,GAAG,GAAG,KAAK,CAAC,YAAY,GAAG,KAAK,EAAE,CAAC,CAAC,CAAC;QACzD,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC;IACtB,CAAC;IAED,SAAS;IACT,MAAM,MAAM,GAAG,KAAK,GAAG,KAAK,KAAK,cAAc,GAAG,QAAQ,KAAK,YAAY,GAAG,IAAI,KAAK,SAAS,GAAG,IAAI,KAAK,aAAa,GAAG,MAAM,KAAK,OAAO,CAAC;IAC/I,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC;IAExB,MAAM,MAAM,GAAG,WAAW,GAAG,GAAG,GAAG,GAAG,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,GAAG,GAAG,GAAG,CAAC;IACtE,IAAI,MAAM,KAAK,KAAK,CAAC,eAAe,EAAE,CAAC;QACrC,KAAK,CAAC,eAAe,GAAG,MAAM,CAAC;QAC/B,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;IACpB,CAAC;AACH,CAAC;AAUD,MAAM,CAAC,KAAK,UAAU,WAAW,CAC/B,KAAqB,EACrB,KAAoB;IAEpB,IAAI,KAAK,CAAC,IAAI,KAAK,QAAQ,IAAI,KAAK,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;QACvD,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC;IAC5B,CAAC;IAED,MAAM,OAAO,GAAG,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,YAAY;IACnD,MAAM,eAAe,GAAG,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC;IAE5D,4BAA4B;IAC5B,IAAI,KAAK,CAAC,iBAAiB,EAAE,CAAC;QAC5B,IAAI,KAAK,CAAC,IAAI,KAAK,QAAQ,IAAI,KAAK,CAAC,IAAI,KAAK,GAAG,IAAI,eAAe,EAAE,SAAS,KAAK,KAAK,CAAC,iBAAiB,EAAE,CAAC;YAC5G,gEAAgE;YAChE,+DAA+D;YAC/D,IAAI,eAAe,CAAC,IAAI,EAAE,CAAC;gBACzB,KAAK,CAAC,iBAAiB,GAAG,IAAI,CAAC;gBAC/B,KAAK,CAAC,YAAY,GAAG,4EAA4E,CAAC;gBAClG,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC;YAC7B,CAAC;YACD,MAAM,MAAM,GAAG,eAAe,CAAC;YAC/B,IAAI,CAAC;gBACH,MAAM,cAAc,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC;gBAC3C,KAAK,CAAC,QAAQ,GAAG,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,SAAS,KAAK,MAAM,CAAC,SAAS,CAAC,CAAC;gBAC9E,IAAI,KAAK,CAAC,aAAa,IAAI,KAAK,CAAC,QAAQ,CAAC,MAAM,EAAE,CAAC;oBACjD,KAAK,CAAC,aAAa,GAAG,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,oBAAoB;gBACnE,CAAC;gBACD,KAAK,CAAC,iBAAiB,GAAG,IAAI,CAAC;gBAC/B,KAAK,CAAC,YAAY,GAAG,IAAI,CAAC;YAC5B,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACb,KAAK,CAAC,YAAY,GAAG,sBAAsB,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC;gBACtF,KAAK,CAAC,iBAAiB,GAAG,IAAI,CAAC;YACjC,CAAC;YACD,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC;QAC7B,CAAC;QACD,yCAAyC;QACzC,KAAK,CAAC,iBAAiB,GAAG,IAAI,CAAC;QAC/B,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC;IAC7B,CAAC;IAED,IAAI,KAAK,CAAC,IAAI,KAAK,IAAI,EAAE,CAAC;QACxB,IAAI,KAAK,CAAC,aAAa,GAAG,CAAC;YAAE,KAAK,CAAC,aAAa,EAAE,CAAC;QACnD,KAAK,CAAC,YAAY,GAAG,IAAI,CAAC;QAC1B,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC;IAC7B,CAAC;IACD,IAAI,KAAK,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;QAC1B,IAAI,KAAK,CAAC,aAAa,GAAG,OAAO;YAAE,KAAK,CAAC,aAAa,EAAE,CAAC;QACzD,KAAK,CAAC,YAAY,GAAG,IAAI,CAAC;QAC1B,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC;IAC7B,CAAC;IACD,IAAI,KAAK,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;QAC5B,IAAI,KAAK,CAAC,aAAa,KAAK,OAAO;YAAE,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC;QAC5D,IAAI,eAAe,EAAE,CAAC;YACpB,IAAI,eAAe,CAAC,IAAI,EAAE,CAAC;gBACzB,KAAK,CAAC,YAAY,GAAG,iGAAiG,CAAC;gBACvH,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC;YAC7B,CAAC;YACD,IAAI,CAAC,eAAe,CAAC,aAAa,EAAE,CAAC;gBACnC,KAAK,CAAC,YAAY,GAAG,kEAAkE,CAAC;gBACxF,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC;YAC7B,CAAC;YACD,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,eAAe,EAAE,CAAC;QACtD,CAAC;QACD,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC;IAC7B,CAAC;IACD,IAAI,KAAK,CAAC,IAAI,KAAK,QAAQ,IAAI,KAAK,CAAC,IAAI,KAAK,GAAG,EAAE,CAAC;QAClD,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC;IACzB,CAAC;IACD,IAAI,KAAK,CAAC,IAAI,KAAK,QAAQ,IAAI,KAAK,CAAC,IAAI,KAAK,GAAG,EAAE,CAAC;QAClD,IAAI,eAAe,EAAE,CAAC;YACpB,IAAI,eAAe,CAAC,IAAI,EAAE,CAAC;gBACzB,KAAK,CAAC,YAAY,GAAG,4EAA4E,CAAC;gBAClG,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC;YAC7B,CAAC;YACD,KAAK,CAAC,iBAAiB,GAAG,eAAe,CAAC,SAAS,CAAC;QACtD,CAAC;QACD,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC;IAC7B,CAAC;IACD,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC;AAC7B,CAAC;AAED,wEAAwE;AAExE,MAAM,CAAC,KAAK,UAAU,gBAAgB,CACpC,QAA6B,EAC7B,OAAyB,EAAE,EAC3B,GAAY;IAEZ,MAAM,IAAI,GAAG,OAAO,CAAC,MAAM,CAAC,IAAI,IAAI,EAAE,CAAC;IACvC,MAAM,IAAI,GAAG,OAAO,CAAC,MAAM,CAAC,OAAO,IAAI,EAAE,CAAC;IAC1C,MAAM,OAAO,GAAG,MAAM,UAAU,CAAC,GAAG,IAAI,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC;IACvD,MAAM,KAAK,GAAG,iBAAiB,CAAC,QAAQ,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC;IAErE,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC;IAEpC,IAAI,QAAQ,GAAG,KAAK,CAAC;IACrB,KAAK,cAAc,EAAE,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE;QACpC,IAAI,QAAQ,IAAI,CAAC,MAAM;YAAE,OAAO;QAChC,KAAK,CAAC,YAAY,GAAG,MAAM,CAAC;QAC5B,KAAK,CAAC,eAAe,GAAG,SAAS,CAAC;QAClC,MAAM,CAAC,KAAK,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC;IAChC,CAAC,CAAC,CAAC;IAEH,IAAI,CAAC;QACH,MAAM,CAAC,KAAK,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC;QAC9B,OAAO,MAAM,SAAS,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;IACrC,CAAC;YAAS,CAAC;QACT,QAAQ,GAAG,IAAI,CAAC;QAChB,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC;IACvC,CAAC;AACH,CAAC;AAED,MAAM,mBAAmB,GAAG,IAAI,CAAC;AAEjC;;;;;;GAMG;AACH,MAAM,UAAU,iBAAiB,CAC/B,KAAqB,EACrB,KAA0B;IAE1B,MAAM,SAAS,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;IAC5D,MAAM,kBAAkB,GAAG,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,aAAa,CAAC,EAAE,SAAS,CAAC;IAE1E,iFAAiF;IACjF,MAAM,IAAI,GAAwB,EAAE,CAAC;IACrC,KAAK,MAAM,QAAQ,IAAI,KAAK,CAAC,QAAQ,EAAE,CAAC;QACtC,MAAM,OAAO,GAAG,SAAS,CAAC,GAAG,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC;QAClD,IAAI,CAAC,OAAO;YAAE,SAAS;QACvB,IAAI,CAAC,IAAI,CAAC;YACR,GAAG,QAAQ;YACX,aAAa,EAAE,OAAO,CAAC,aAAa;YACpC,aAAa,EAAE,OAAO,CAAC,aAAa;YACpC,QAAQ,EAAE,OAAO,CAAC,QAAQ;YAC1B,IAAI,EAAE,OAAO,CAAC,IAAI;SACnB,CAAC,CAAC;QACH,SAAS,CAAC,MAAM,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC;IACvC,CAAC;IACD,mDAAmD;IACnD,KAAK,MAAM,KAAK,IAAI,SAAS,CAAC,MAAM,EAAE;QAAE,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAEzD,KAAK,CAAC,QAAQ,GAAG,IAAI,CAAC;IAEtB,qEAAqE;IACrE,MAAM,cAAc,GAAG,kBAAkB;QACvC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,SAAS,KAAK,kBAAkB,CAAC;QACzD,CAAC,CAAC,CAAC,CAAC,CAAC;IACP,IAAI,cAAc,IAAI,CAAC,EAAE,CAAC;QACxB,KAAK,CAAC,aAAa,GAAG,cAAc,CAAC;IACvC,CAAC;SAAM,IAAI,KAAK,CAAC,aAAa,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC;QAC7C,KAAK,CAAC,aAAa,GAAG,IAAI,CAAC,MAAM,CAAC;IACpC,CAAC;IAED,6DAA6D;IAC7D,IAAI,KAAK,CAAC,iBAAiB,EAAE,CAAC;QAC5B,MAAM,KAAK,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,SAAS,KAAK,KAAK,CAAC,iBAAiB,CAAC,CAAC;QACtE,IAAI,CAAC,KAAK,IAAI,KAAK,CAAC,IAAI;YAAE,KAAK,CAAC,iBAAiB,GAAG,IAAI,CAAC;IAC3D,CAAC;AACH,CAAC;AAED,KAAK,UAAU,SAAS,CAAC,KAAqB,EAAE,OAAgB;IAC9D,MAAM,MAAM,GAAG,IAAI,cAAc,EAAE,CAAC;IACpC,MAAM,MAAM,GAAG,oBAAoB,EAAE,CAAC;IACtC,MAAM,CAAC,KAAK,EAAE,CAAC;IAEf,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;QAC7B,MAAM,YAAY,GAAG,KAAK,EAAE,MAAuB,EAAoB,EAAE;YACvE,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;gBAC3B,MAAM,MAAM,GAAG,MAAM,WAAW,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;gBAC/C,QAAQ,MAAM,CAAC,IAAI,EAAE,CAAC;oBACpB,KAAK,QAAQ;wBACX,OAAO,EAAE,CAAC;wBACV,OAAO,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,CAAC,OAAO,EAAE,CAAC,CAAC;wBACrD,OAAO,IAAI,CAAC;oBACd,KAAK,KAAK;wBACR,OAAO,EAAE,CAAC;wBACV,OAAO,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;wBACzB,OAAO,IAAI,CAAC;oBACd,KAAK,QAAQ;wBACX,OAAO,EAAE,CAAC;wBACV,OAAO,CAAC,IAAI,CAAC,CAAC;wBACd,OAAO,IAAI,CAAC;oBACd,KAAK,SAAS;wBACZ,MAAM;gBACV,CAAC;YACH,CAAC;YACD,MAAM,CAAC,KAAK,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC;YAC9B,OAAO,KAAK,CAAC;QACf,CAAC,CAAC;QAEF,MAAM,WAAW,GAAG,MAAM,CAAC,QAAQ,CAAC,CAAC,IAAI,EAAE,EAAE;YAC3C,KAAK,YAAY,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC;QAC1C,CAAC,CAAC,CAAC;QAEH,MAAM,QAAQ,GAAG,GAAS,EAAE;YAC1B,KAAK,CAAC,QAAQ,GAAG,OAAO,CAAC,MAAM,CAAC,IAAI,IAAI,EAAE,CAAC;YAC3C,KAAK,CAAC,QAAQ,GAAG,OAAO,CAAC,MAAM,CAAC,OAAO,IAAI,EAAE,CAAC;YAC9C,KAAK,CAAC,eAAe,GAAG,SAAS,CAAC;YAClC,MAAM,CAAC,KAAK,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC;QAChC,CAAC,CAAC;QACF,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;QAEtC,yEAAyE;QACzE,IAAI,UAAU,GAAG,KAAK,CAAC;QACvB,MAAM,YAAY,GAAG,WAAW,CAAC,GAAG,EAAE;YACpC,IAAI,UAAU;gBAAE,OAAO;YACvB,UAAU,GAAG,IAAI,CAAC;YAClB,CAAC,KAAK,IAAI,EAAE;gBACV,IAAI,CAAC;oBACH,MAAM,KAAK,GAAG,MAAM,qBAAqB,CAAC,OAAO,CAAC,CAAC;oBACnD,iBAAiB,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;oBAChC,MAAM,CAAC,KAAK,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC;gBAChC,CAAC;gBAAC,MAAM,CAAC;oBACP,oCAAoC;gBACtC,CAAC;wBAAS,CAAC;oBACT,UAAU,GAAG,KAAK,CAAC;gBACrB,CAAC;YACH,CAAC,CAAC,EAAE,CAAC;QACP,CAAC,EAAE,mBAAmB,CAAC,CAAC;QACxB,YAAY,CAAC,KAAK,EAAE,EAAE,CAAC;QAEvB,SAAS,OAAO;YACd,aAAa,CAAC,YAAY,CAAC,CAAC;YAC5B,WAAW,EAAE,CAAC;YACd,MAAM,CAAC,IAAI,EAAE,CAAC;YACd,OAAO,CAAC,MAAM,CAAC,cAAc,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;QACpD,CAAC;IACH,CAAC,CAAC,CAAC;AACL,CAAC"}
@@ -0,0 +1,14 @@
1
+ import type { FlowTemplate } from "../flow/types.js";
2
+ /**
3
+ * Copy the flow's source factory file into the persistent session dir.
4
+ * The filename ends with `.mjs` so dynamic-import treats it as an ESM
5
+ * module regardless of any nearby `package.json` "type" field.
6
+ */
7
+ export declare function captureFlowSnapshot(sourceFile: string, persistentDir: string): Promise<void>;
8
+ /**
9
+ * Dynamic-import the saved flow source and invoke its default factory
10
+ * with the current DSL. The flow's *logic* is frozen at save time;
11
+ * DSL primitives come from the running poly-weaver.
12
+ */
13
+ export declare function rehydrateFlow(persistentDir: string): Promise<FlowTemplate>;
14
+ //# sourceMappingURL=flow-snapshot.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"flow-snapshot.d.ts","sourceRoot":"","sources":["../../src/session/flow-snapshot.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAIrD;;;;GAIG;AACH,wBAAsB,mBAAmB,CACvC,UAAU,EAAE,MAAM,EAClB,aAAa,EAAE,MAAM,GACpB,OAAO,CAAC,IAAI,CAAC,CAEf;AAED;;;;GAIG;AACH,wBAAsB,aAAa,CAAC,aAAa,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC,CAUhF"}
@@ -0,0 +1,28 @@
1
+ import { copyFile } from "node:fs/promises";
2
+ import { join } from "node:path";
3
+ import { pathToFileURL } from "node:url";
4
+ import { flowDSL } from "../dsl.js";
5
+ const SNAPSHOT_FILENAME = "flow-source.mjs";
6
+ /**
7
+ * Copy the flow's source factory file into the persistent session dir.
8
+ * The filename ends with `.mjs` so dynamic-import treats it as an ESM
9
+ * module regardless of any nearby `package.json` "type" field.
10
+ */
11
+ export async function captureFlowSnapshot(sourceFile, persistentDir) {
12
+ await copyFile(sourceFile, join(persistentDir, SNAPSHOT_FILENAME));
13
+ }
14
+ /**
15
+ * Dynamic-import the saved flow source and invoke its default factory
16
+ * with the current DSL. The flow's *logic* is frozen at save time;
17
+ * DSL primitives come from the running poly-weaver.
18
+ */
19
+ export async function rehydrateFlow(persistentDir) {
20
+ const url = pathToFileURL(join(persistentDir, SNAPSHOT_FILENAME)).href;
21
+ const mod = await import(url);
22
+ const factory = mod.default;
23
+ if (typeof factory !== "function") {
24
+ throw new Error(`Restored flow snapshot at ${persistentDir}/${SNAPSHOT_FILENAME} has no default-export factory function`);
25
+ }
26
+ return factory(flowDSL);
27
+ }
28
+ //# sourceMappingURL=flow-snapshot.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"flow-snapshot.js","sourceRoot":"","sources":["../../src/session/flow-snapshot.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAGpC,MAAM,iBAAiB,GAAG,iBAAiB,CAAC;AAE5C;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,mBAAmB,CACvC,UAAkB,EAClB,aAAqB;IAErB,MAAM,QAAQ,CAAC,UAAU,EAAE,IAAI,CAAC,aAAa,EAAE,iBAAiB,CAAC,CAAC,CAAC;AACrE,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,aAAqB;IACvD,MAAM,GAAG,GAAG,aAAa,CAAC,IAAI,CAAC,aAAa,EAAE,iBAAiB,CAAC,CAAC,CAAC,IAAI,CAAC;IACvE,MAAM,GAAG,GAAG,MAAM,MAAM,CAAC,GAAG,CAAC,CAAC;IAC9B,MAAM,OAAO,GAAG,GAAG,CAAC,OAAO,CAAC;IAC5B,IAAI,OAAO,OAAO,KAAK,UAAU,EAAE,CAAC;QAClC,MAAM,IAAI,KAAK,CACb,6BAA6B,aAAa,IAAI,iBAAiB,yCAAyC,CACzG,CAAC;IACJ,CAAC;IACD,OAAO,OAAO,CAAC,OAAO,CAAiB,CAAC;AAC1C,CAAC"}
@@ -0,0 +1,16 @@
1
+ import type { SessionDescriptor } from "./manifest.js";
2
+ /**
3
+ * Walk the sessions dir, return descriptors sorted by `lastActivityAt` desc.
4
+ *
5
+ * Side effects:
6
+ * - Drops `status: "complete"` sessions from the result.
7
+ * - Annotates live-locked sessions with a `lock` field (the picker
8
+ * disables Enter / discard on those rows).
9
+ * - Deletes (>7d stale) sessions in place.
10
+ *
11
+ * When `cwd` is provided, returns only sessions whose manifest `workdir`
12
+ * matches exactly (case-insensitive on win32).
13
+ */
14
+ export declare function listResumableSessions(cwd?: string): Promise<SessionDescriptor[]>;
15
+ export declare function discardSession(persistentDir: string): Promise<void>;
16
+ //# sourceMappingURL=list.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"list.d.ts","sourceRoot":"","sources":["../../src/session/list.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,iBAAiB,EAAqC,MAAM,eAAe,CAAC;AAO1F;;;;;;;;;;;GAWG;AACH,wBAAsB,qBAAqB,CAAC,GAAG,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,EAAE,CAAC,CA0BtF;AAgDD,wBAAsB,cAAc,CAAC,aAAa,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAEzE"}
@@ -0,0 +1,89 @@
1
+ import { readdir, rm } from "node:fs/promises";
2
+ import { join, resolve } from "node:path";
3
+ import { getSessionsDir } from "../config.js";
4
+ import { dirExists, readJsonIfExists, stepFilename } from "./persistence.js";
5
+ import { readLiveLockSummary } from "./lock.js";
6
+ const SEVEN_DAYS_MS = 7 * 24 * 60 * 60 * 1000;
7
+ const normalizeForCompare = (p) => process.platform === "win32" ? resolve(p).toLowerCase() : resolve(p);
8
+ /**
9
+ * Walk the sessions dir, return descriptors sorted by `lastActivityAt` desc.
10
+ *
11
+ * Side effects:
12
+ * - Drops `status: "complete"` sessions from the result.
13
+ * - Annotates live-locked sessions with a `lock` field (the picker
14
+ * disables Enter / discard on those rows).
15
+ * - Deletes (>7d stale) sessions in place.
16
+ *
17
+ * When `cwd` is provided, returns only sessions whose manifest `workdir`
18
+ * matches exactly (case-insensitive on win32).
19
+ */
20
+ export async function listResumableSessions(cwd) {
21
+ const sessionsDir = getSessionsDir();
22
+ let entries;
23
+ try {
24
+ entries = await readdir(sessionsDir);
25
+ }
26
+ catch (err) {
27
+ if (err.code === "ENOENT")
28
+ return [];
29
+ throw err;
30
+ }
31
+ const now = Date.now();
32
+ const normalizedFilterCwd = cwd === undefined ? undefined : normalizeForCompare(cwd);
33
+ const descriptors = (await Promise.all(entries.map((entry) => loadDescriptor(join(sessionsDir, entry), now, normalizedFilterCwd)))).filter((d) => d !== undefined);
34
+ descriptors.sort((a, b) => Date.parse(b.manifest.lastActivityAt) - Date.parse(a.manifest.lastActivityAt));
35
+ return descriptors;
36
+ }
37
+ async function loadDescriptor(persistentDir, now, normalizedFilterCwd) {
38
+ try {
39
+ const manifest = await readJsonIfExists(join(persistentDir, "manifest.json"));
40
+ if (!manifest)
41
+ return undefined;
42
+ const lastActivity = Date.parse(manifest.lastActivityAt);
43
+ if (Number.isFinite(lastActivity) && now - lastActivity > SEVEN_DAYS_MS) {
44
+ await rm(persistentDir, { recursive: true, force: true }).catch(() => { });
45
+ return undefined;
46
+ }
47
+ if (manifest.status === "complete")
48
+ return undefined;
49
+ if (normalizedFilterCwd !== undefined &&
50
+ normalizeForCompare(manifest.workdir) !== normalizedFilterCwd) {
51
+ return undefined;
52
+ }
53
+ const [lockSummary, workdirExists, lastStepLabel] = await Promise.all([
54
+ readLiveLockSummary(persistentDir, manifest.createdAt),
55
+ dirExists(manifest.workdir),
56
+ readLastStepLabel(persistentDir, manifest.lastCompletedSeq),
57
+ ]);
58
+ const descriptor = {
59
+ sessionId: manifest.sessionId,
60
+ persistentDir,
61
+ manifest,
62
+ workdirExists,
63
+ lastStepLabel,
64
+ };
65
+ if (lockSummary)
66
+ descriptor.lock = lockSummary;
67
+ return descriptor;
68
+ }
69
+ catch {
70
+ return undefined;
71
+ }
72
+ }
73
+ export async function discardSession(persistentDir) {
74
+ await rm(persistentDir, { recursive: true, force: true });
75
+ }
76
+ async function readLastStepLabel(persistentDir, lastCompletedSeq) {
77
+ if (lastCompletedSeq < 0)
78
+ return undefined;
79
+ try {
80
+ const entry = await readJsonIfExists(join(persistentDir, "steps", stepFilename(lastCompletedSeq)));
81
+ if (!entry)
82
+ return undefined;
83
+ return entry.role + (entry.variant ? `:${entry.variant}` : "");
84
+ }
85
+ catch {
86
+ return undefined;
87
+ }
88
+ }
89
+ //# sourceMappingURL=list.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"list.js","sourceRoot":"","sources":["../../src/session/list.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,26 @@
1
+ export declare function acquireLock(persistentDir: string, sessionCreatedAt: string): Promise<void>;
2
+ export declare function releaseLock(persistentDir: string): Promise<void>;
3
+ export interface LockSummary {
4
+ pid: number;
5
+ hostname: string;
6
+ startedAt: string;
7
+ }
8
+ /**
9
+ * Returns true when another live process likely holds the lock.
10
+ * - Missing lock → false.
11
+ * - Different host → true (defensive cross-host default).
12
+ * - Same host: `process.kill(pid, 0)` — ESRCH ⇒ false, EPERM ⇒ true, success ⇒ true.
13
+ * - Extra guard: if `lock.sessionCreatedAt !== manifestCreatedAt`, the lock is
14
+ * stale (inherited by an unrelated PID via PID reuse) → false.
15
+ * - PID-reuse guard: when the lock has a `processStartTime` and the current
16
+ * start time for `pid` is known and disagrees, the PID has been reused by
17
+ * an unrelated process → false.
18
+ */
19
+ export declare function isLockAlive(persistentDir: string, manifestCreatedAt: string): Promise<boolean>;
20
+ /**
21
+ * Single-read combined liveness check + summary for the picker. Returns
22
+ * `undefined` when the lock is absent or stale; returns the holder summary
23
+ * when alive.
24
+ */
25
+ export declare function readLiveLockSummary(persistentDir: string, manifestCreatedAt: string): Promise<LockSummary | undefined>;
26
+ //# sourceMappingURL=lock.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lock.d.ts","sourceRoot":"","sources":["../../src/session/lock.ts"],"names":[],"mappings":"AAwBA,wBAAsB,WAAW,CAC/B,aAAa,EAAE,MAAM,EACrB,gBAAgB,EAAE,MAAM,GACvB,OAAO,CAAC,IAAI,CAAC,CAUf;AAED,wBAAsB,WAAW,CAAC,aAAa,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAWtE;AAED,MAAM,WAAW,WAAW;IAC1B,GAAG,EAAE,MAAM,CAAC;IACZ,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;CACnB;AA8BD;;;;;;;;;;GAUG;AACH,wBAAsB,WAAW,CAC/B,aAAa,EAAE,MAAM,EACrB,iBAAiB,EAAE,MAAM,GACxB,OAAO,CAAC,OAAO,CAAC,CAIlB;AAED;;;;GAIG;AACH,wBAAsB,mBAAmB,CACvC,aAAa,EAAE,MAAM,EACrB,iBAAiB,EAAE,MAAM,GACxB,OAAO,CAAC,WAAW,GAAG,SAAS,CAAC,CAKlC"}