aimux-cli 0.1.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 (207) hide show
  1. package/README.md +743 -0
  2. package/bin/aimux +2 -0
  3. package/dist/agent-events.d.ts +20 -0
  4. package/dist/agent-events.js +2 -0
  5. package/dist/agent-events.js.map +1 -0
  6. package/dist/agent-message-parts.d.ts +17 -0
  7. package/dist/agent-message-parts.js +31 -0
  8. package/dist/agent-message-parts.js.map +1 -0
  9. package/dist/agent-output-parser.d.ts +16 -0
  10. package/dist/agent-output-parser.js +229 -0
  11. package/dist/agent-output-parser.js.map +1 -0
  12. package/dist/agent-tracker.d.ts +9 -0
  13. package/dist/agent-tracker.js +144 -0
  14. package/dist/agent-tracker.js.map +1 -0
  15. package/dist/agent-watcher.d.ts +15 -0
  16. package/dist/agent-watcher.js +2 -0
  17. package/dist/agent-watcher.js.map +1 -0
  18. package/dist/attachment-store.d.ts +35 -0
  19. package/dist/attachment-store.js +129 -0
  20. package/dist/attachment-store.js.map +1 -0
  21. package/dist/builtin-metadata-watchers.d.ts +2 -0
  22. package/dist/builtin-metadata-watchers.js +275 -0
  23. package/dist/builtin-metadata-watchers.js.map +1 -0
  24. package/dist/claude-hooks.d.ts +29 -0
  25. package/dist/claude-hooks.js +106 -0
  26. package/dist/claude-hooks.js.map +1 -0
  27. package/dist/config.d.ts +78 -0
  28. package/dist/config.js +172 -0
  29. package/dist/config.js.map +1 -0
  30. package/dist/context/compactor.d.ts +20 -0
  31. package/dist/context/compactor.js +212 -0
  32. package/dist/context/compactor.js.map +1 -0
  33. package/dist/context/context-bridge.d.ts +67 -0
  34. package/dist/context/context-bridge.js +471 -0
  35. package/dist/context/context-bridge.js.map +1 -0
  36. package/dist/context/context-file.d.ts +11 -0
  37. package/dist/context/context-file.js +93 -0
  38. package/dist/context/context-file.js.map +1 -0
  39. package/dist/context/history.d.ts +40 -0
  40. package/dist/context/history.js +108 -0
  41. package/dist/context/history.js.map +1 -0
  42. package/dist/daemon.d.ts +39 -0
  43. package/dist/daemon.js +344 -0
  44. package/dist/daemon.js.map +1 -0
  45. package/dist/dashboard-session-registry.d.ts +47 -0
  46. package/dist/dashboard-session-registry.js +161 -0
  47. package/dist/dashboard-session-registry.js.map +1 -0
  48. package/dist/dashboard-state.d.ts +18 -0
  49. package/dist/dashboard-state.js +26 -0
  50. package/dist/dashboard-state.js.map +1 -0
  51. package/dist/dashboard.d.ts +118 -0
  52. package/dist/dashboard.js +91 -0
  53. package/dist/dashboard.js.map +1 -0
  54. package/dist/debug.d.ts +7 -0
  55. package/dist/debug.js +41 -0
  56. package/dist/debug.js.map +1 -0
  57. package/dist/fast-control.d.ts +45 -0
  58. package/dist/fast-control.js +174 -0
  59. package/dist/fast-control.js.map +1 -0
  60. package/dist/hotkeys.d.ts +44 -0
  61. package/dist/hotkeys.js +118 -0
  62. package/dist/hotkeys.js.map +1 -0
  63. package/dist/http-client.d.ts +10 -0
  64. package/dist/http-client.js +54 -0
  65. package/dist/http-client.js.map +1 -0
  66. package/dist/instance-directory.d.ts +32 -0
  67. package/dist/instance-directory.js +82 -0
  68. package/dist/instance-directory.js.map +1 -0
  69. package/dist/instance-registry.d.ts +38 -0
  70. package/dist/instance-registry.js +208 -0
  71. package/dist/instance-registry.js.map +1 -0
  72. package/dist/key-parser.d.ts +30 -0
  73. package/dist/key-parser.js +272 -0
  74. package/dist/key-parser.js.map +1 -0
  75. package/dist/last-used.d.ts +31 -0
  76. package/dist/last-used.js +93 -0
  77. package/dist/last-used.js.map +1 -0
  78. package/dist/main.d.ts +1 -0
  79. package/dist/main.js +2483 -0
  80. package/dist/main.js.map +1 -0
  81. package/dist/metadata-server.d.ts +268 -0
  82. package/dist/metadata-server.js +1379 -0
  83. package/dist/metadata-server.js.map +1 -0
  84. package/dist/metadata-store.d.ts +80 -0
  85. package/dist/metadata-store.js +87 -0
  86. package/dist/metadata-store.js.map +1 -0
  87. package/dist/multiplexer.d.ts +471 -0
  88. package/dist/multiplexer.js +5714 -0
  89. package/dist/multiplexer.js.map +1 -0
  90. package/dist/notification-context.d.ts +18 -0
  91. package/dist/notification-context.js +68 -0
  92. package/dist/notification-context.js.map +1 -0
  93. package/dist/notifications.d.ts +38 -0
  94. package/dist/notifications.js +111 -0
  95. package/dist/notifications.js.map +1 -0
  96. package/dist/notify.d.ts +10 -0
  97. package/dist/notify.js +62 -0
  98. package/dist/notify.js.map +1 -0
  99. package/dist/orchestration-actions.d.ts +76 -0
  100. package/dist/orchestration-actions.js +310 -0
  101. package/dist/orchestration-actions.js.map +1 -0
  102. package/dist/orchestration-dispatcher.d.ts +22 -0
  103. package/dist/orchestration-dispatcher.js +49 -0
  104. package/dist/orchestration-dispatcher.js.map +1 -0
  105. package/dist/orchestration-routing.d.ts +20 -0
  106. package/dist/orchestration-routing.js +78 -0
  107. package/dist/orchestration-routing.js.map +1 -0
  108. package/dist/orchestration.d.ts +26 -0
  109. package/dist/orchestration.js +110 -0
  110. package/dist/orchestration.js.map +1 -0
  111. package/dist/osc-notifications.d.ts +15 -0
  112. package/dist/osc-notifications.js +180 -0
  113. package/dist/osc-notifications.js.map +1 -0
  114. package/dist/paths.d.ts +55 -0
  115. package/dist/paths.js +259 -0
  116. package/dist/paths.js.map +1 -0
  117. package/dist/plugin-runtime.d.ts +46 -0
  118. package/dist/plugin-runtime.js +180 -0
  119. package/dist/plugin-runtime.js.map +1 -0
  120. package/dist/project-events.d.ts +36 -0
  121. package/dist/project-events.js +63 -0
  122. package/dist/project-events.js.map +1 -0
  123. package/dist/project-scanner.d.ts +38 -0
  124. package/dist/project-scanner.js +243 -0
  125. package/dist/project-scanner.js.map +1 -0
  126. package/dist/project-service-manifest.d.ts +18 -0
  127. package/dist/project-service-manifest.js +56 -0
  128. package/dist/project-service-manifest.js.map +1 -0
  129. package/dist/recency.d.ts +2 -0
  130. package/dist/recency.js +34 -0
  131. package/dist/recency.js.map +1 -0
  132. package/dist/recorder.d.ts +14 -0
  133. package/dist/recorder.js +130 -0
  134. package/dist/recorder.js.map +1 -0
  135. package/dist/session-bootstrap.d.ts +45 -0
  136. package/dist/session-bootstrap.js +436 -0
  137. package/dist/session-bootstrap.js.map +1 -0
  138. package/dist/session-message-history.d.ts +27 -0
  139. package/dist/session-message-history.js +105 -0
  140. package/dist/session-message-history.js.map +1 -0
  141. package/dist/session-runtime.d.ts +44 -0
  142. package/dist/session-runtime.js +56 -0
  143. package/dist/session-runtime.js.map +1 -0
  144. package/dist/session-semantics.d.ts +35 -0
  145. package/dist/session-semantics.js +110 -0
  146. package/dist/session-semantics.js.map +1 -0
  147. package/dist/status-detector.d.ts +17 -0
  148. package/dist/status-detector.js +67 -0
  149. package/dist/status-detector.js.map +1 -0
  150. package/dist/statusline-model.d.ts +103 -0
  151. package/dist/statusline-model.js +177 -0
  152. package/dist/statusline-model.js.map +1 -0
  153. package/dist/task-dispatcher.d.ts +63 -0
  154. package/dist/task-dispatcher.js +210 -0
  155. package/dist/task-dispatcher.js.map +1 -0
  156. package/dist/task-workflow.d.ts +13 -0
  157. package/dist/task-workflow.js +153 -0
  158. package/dist/task-workflow.js.map +1 -0
  159. package/dist/tasks.d.ts +60 -0
  160. package/dist/tasks.js +120 -0
  161. package/dist/tasks.js.map +1 -0
  162. package/dist/team.d.ts +28 -0
  163. package/dist/team.js +91 -0
  164. package/dist/team.js.map +1 -0
  165. package/dist/terminal-host.d.ts +10 -0
  166. package/dist/terminal-host.js +52 -0
  167. package/dist/terminal-host.js.map +1 -0
  168. package/dist/threads.d.ts +61 -0
  169. package/dist/threads.js +200 -0
  170. package/dist/threads.js.map +1 -0
  171. package/dist/tmux-doctor.d.ts +47 -0
  172. package/dist/tmux-doctor.js +112 -0
  173. package/dist/tmux-doctor.js.map +1 -0
  174. package/dist/tmux-runtime-manager.d.ts +164 -0
  175. package/dist/tmux-runtime-manager.js +794 -0
  176. package/dist/tmux-runtime-manager.js.map +1 -0
  177. package/dist/tmux-session-transport.d.ts +31 -0
  178. package/dist/tmux-session-transport.js +115 -0
  179. package/dist/tmux-session-transport.js.map +1 -0
  180. package/dist/tmux-statusline.d.ts +17 -0
  181. package/dist/tmux-statusline.js +166 -0
  182. package/dist/tmux-statusline.js.map +1 -0
  183. package/dist/tool-output-watchers.d.ts +10 -0
  184. package/dist/tool-output-watchers.js +190 -0
  185. package/dist/tool-output-watchers.js.map +1 -0
  186. package/dist/tui/render/box.d.ts +1 -0
  187. package/dist/tui/render/box.js +20 -0
  188. package/dist/tui/render/box.js.map +1 -0
  189. package/dist/tui/render/text.d.ts +8 -0
  190. package/dist/tui/render/text.js +92 -0
  191. package/dist/tui/render/text.js.map +1 -0
  192. package/dist/tui/screens/dashboard-renderers.d.ts +23 -0
  193. package/dist/tui/screens/dashboard-renderers.js +411 -0
  194. package/dist/tui/screens/dashboard-renderers.js.map +1 -0
  195. package/dist/tui/screens/overlay-renderers.d.ts +10 -0
  196. package/dist/tui/screens/overlay-renderers.js +274 -0
  197. package/dist/tui/screens/overlay-renderers.js.map +1 -0
  198. package/dist/tui/screens/subscreen-renderers.d.ts +9 -0
  199. package/dist/tui/screens/subscreen-renderers.js +327 -0
  200. package/dist/tui/screens/subscreen-renderers.js.map +1 -0
  201. package/dist/workflow.d.ts +19 -0
  202. package/dist/workflow.js +111 -0
  203. package/dist/workflow.js.map +1 -0
  204. package/dist/worktree.d.ts +23 -0
  205. package/dist/worktree.js +101 -0
  206. package/dist/worktree.js.map +1 -0
  207. package/package.json +70 -0
@@ -0,0 +1,471 @@
1
+ import { readFileSync, existsSync, statSync, writeFileSync, mkdirSync } from "node:fs";
2
+ import { join } from "node:path";
3
+ import { simpleGit } from "simple-git";
4
+ import { appendEntry } from "./context-file.js";
5
+ import { loadConfig } from "../config.js";
6
+ import { getRecordingsDir, getContextDir } from "../paths.js";
7
+ import { appendTurn, readHistory } from "./history.js";
8
+ import { algorithmicCompact } from "./compactor.js";
9
+ import { debugTurn, debugGit, debugContext, debugCompact } from "../debug.js";
10
+ import { TmuxRuntimeManager } from "../tmux-runtime-manager.js";
11
+ import { classifyToolPane } from "../tool-output-watchers.js";
12
+ const git = simpleGit();
13
+ const MAX_LIVE_MD_BYTES = 50 * 1024;
14
+ const MAX_LIVE_MD_LINES = 200;
15
+ /**
16
+ * Capture git diff and write a context entry on session exit.
17
+ */
18
+ export async function captureGitContext(sessionName, tool) {
19
+ try {
20
+ const diff = await git.diff();
21
+ const diffStat = await git.diffSummary();
22
+ if (diffStat.files.length === 0 && !diff)
23
+ return;
24
+ const recentOutput = getRecentOutput(sessionName, 30);
25
+ const entry = {
26
+ sessionName,
27
+ tool,
28
+ timestamp: new Date(),
29
+ prompt: "(session exit)",
30
+ response: recentOutput || `Session ended. ${diffStat.files.length} file(s) changed.`,
31
+ files: diffStat.files.map((f) => f.file),
32
+ diff: diff ? diff.slice(0, 2000) : undefined,
33
+ };
34
+ await appendEntry(entry);
35
+ }
36
+ catch { }
37
+ }
38
+ /**
39
+ * Simple string hash for change detection.
40
+ */
41
+ function simpleHash(str) {
42
+ let hash = 0;
43
+ for (let i = 0; i < str.length; i++) {
44
+ const ch = str.charCodeAt(i);
45
+ hash = ((hash << 5) - hash + ch) | 0;
46
+ }
47
+ return hash.toString(36);
48
+ }
49
+ function boundLiveSnapshot(text) {
50
+ const lines = text.split("\n").slice(-MAX_LIVE_MD_LINES);
51
+ let bounded = lines.join("\n").trim();
52
+ if (Buffer.byteLength(bounded) <= MAX_LIVE_MD_BYTES) {
53
+ return bounded;
54
+ }
55
+ while (lines.length > 1 && Buffer.byteLength(lines.join("\n")) > MAX_LIVE_MD_BYTES) {
56
+ lines.shift();
57
+ }
58
+ bounded = lines.join("\n").trim();
59
+ if (Buffer.byteLength(bounded) <= MAX_LIVE_MD_BYTES) {
60
+ return bounded;
61
+ }
62
+ const buf = Buffer.from(bounded);
63
+ return buf
64
+ .subarray(buf.length - MAX_LIVE_MD_BYTES)
65
+ .toString("utf-8")
66
+ .trim();
67
+ }
68
+ /**
69
+ * Live context watcher. Tmux pane snapshots are the primary continuity source:
70
+ * they keep `live.md` current and backfill append-only history when a tool settles.
71
+ *
72
+ * Raw terminal recordings are kept as secondary audit/backfill artifacts only.
73
+ * They may yield extra turns when available, but continuity should not depend on
74
+ * recordings existing or parsing perfectly.
75
+ */
76
+ export class ContextWatcher {
77
+ capturePane;
78
+ constructor(capturePane = (target) => new TmuxRuntimeManager().captureTarget(target, { startLine: -120 })) {
79
+ this.capturePane = capturePane;
80
+ }
81
+ interval = null;
82
+ sessions = [];
83
+ /** Track how far we've read into each session's secondary raw recording */
84
+ readOffsets = new Map();
85
+ /** Track last turn type per session to detect response→prompt transitions */
86
+ lastTurnTypes = new Map();
87
+ /** Hash of last git diff output for change detection */
88
+ lastDiffHash = "";
89
+ /** Total turn count across all sessions, for compaction trigger */
90
+ totalTurnCount = 0;
91
+ /** Track which sessions have new turns since last write */
92
+ dirtySessions = new Set();
93
+ /** Track last pane snapshot hash per session for tmux-backed live context. */
94
+ paneSnapshotHashes = new Map();
95
+ panePromptVisible = new Map();
96
+ updateSessions(sessions) {
97
+ this.sessions = sessions;
98
+ }
99
+ start(intervalMs = 1_000) {
100
+ if (this.interval)
101
+ return;
102
+ // Initialize read offsets to current file sizes (don't process existing content)
103
+ for (const session of this.sessions) {
104
+ this.initOffset(session.id);
105
+ }
106
+ this.interval = setInterval(() => this.tick().catch(() => { }), intervalMs);
107
+ }
108
+ stop() {
109
+ if (this.interval) {
110
+ clearInterval(this.interval);
111
+ this.interval = null;
112
+ }
113
+ // Mark all sessions dirty for final write
114
+ for (const session of this.sessions) {
115
+ this.dirtySessions.add(session.id);
116
+ }
117
+ this.writeLiveContext();
118
+ }
119
+ async syncNow(sessionId) {
120
+ const sessions = sessionId ? this.sessions.filter((session) => session.id === sessionId) : this.sessions;
121
+ for (const session of sessions) {
122
+ if (!this.readOffsets.has(session.id)) {
123
+ this.initOffset(session.id);
124
+ }
125
+ await this.extractNewContent(session);
126
+ this.capturePaneSnapshot(session);
127
+ }
128
+ if (this.dirtySessions.size > 0) {
129
+ this.writeLiveContext();
130
+ }
131
+ }
132
+ initOffset(sessionId) {
133
+ const txtPath = this.recordingPath(sessionId);
134
+ try {
135
+ const stat = statSync(txtPath);
136
+ this.readOffsets.set(sessionId, stat.size);
137
+ }
138
+ catch {
139
+ this.readOffsets.set(sessionId, 0);
140
+ }
141
+ }
142
+ recordingPath(sessionId) {
143
+ return join(getRecordingsDir(), `${sessionId}.txt`);
144
+ }
145
+ async tick() {
146
+ await this.syncNow();
147
+ }
148
+ /**
149
+ * Read new content from a session's raw recording since our last read offset.
150
+ * This is a secondary audit/backfill path; tmux pane capture is primary.
151
+ */
152
+ async extractNewContent(session) {
153
+ const txtPath = this.recordingPath(session.id);
154
+ if (!existsSync(txtPath))
155
+ return;
156
+ try {
157
+ const content = readFileSync(txtPath, "utf-8");
158
+ const offset = this.readOffsets.get(session.id) ?? 0;
159
+ if (content.length <= offset)
160
+ return;
161
+ const newContent = content.slice(offset);
162
+ this.readOffsets.set(session.id, content.length);
163
+ // Skip if just whitespace/control chars
164
+ const trimmed = newContent.replace(/[\s\r\n]/g, "");
165
+ if (trimmed.length < 10)
166
+ return;
167
+ // Parse new content into turns
168
+ const turns = parseConversationTurns(newContent, session.command, session.turnPatterns);
169
+ for (const turn of turns) {
170
+ const prevType = this.lastTurnTypes.get(session.id);
171
+ // When a prompt appears after a response, the agent finished — check git diff
172
+ if (turn.type === "prompt" && prevType === "response") {
173
+ await this.captureGitDiff(session.id);
174
+ }
175
+ // Persist to JSONL
176
+ const historyTurn = {
177
+ ts: new Date().toISOString(),
178
+ type: turn.type,
179
+ content: turn.content,
180
+ };
181
+ appendTurn(session.id, historyTurn);
182
+ this.totalTurnCount++;
183
+ this.dirtySessions.add(session.id);
184
+ this.lastTurnTypes.set(session.id, turn.type);
185
+ debugTurn(session.id, turn.type, turn.content.length);
186
+ // Trigger algorithmic compaction periodically
187
+ const compactEvery = loadConfig().compactEveryNTurns;
188
+ if (this.totalTurnCount > 0 && this.totalTurnCount % compactEvery === 0) {
189
+ const sessionIds = this.sessions.map((s) => s.id);
190
+ debugCompact(sessionIds.length, this.totalTurnCount);
191
+ algorithmicCompact(sessionIds);
192
+ }
193
+ }
194
+ }
195
+ catch { }
196
+ }
197
+ capturePaneSnapshot(session) {
198
+ if (!session.tmuxTarget)
199
+ return;
200
+ let text = "";
201
+ try {
202
+ text = this.capturePane(session.tmuxTarget);
203
+ }
204
+ catch {
205
+ return;
206
+ }
207
+ const normalized = text
208
+ .split("\n")
209
+ .map(normalizeTerminalLine)
210
+ .filter((line) => !isLikelyUiChrome(line))
211
+ .join("\n")
212
+ .trim();
213
+ if (!normalized)
214
+ return;
215
+ const hash = simpleHash(normalized);
216
+ const { promptVisible } = classifyToolPane(session.command, text);
217
+ this.panePromptVisible.set(session.id, promptVisible);
218
+ if (this.paneSnapshotHashes.get(session.id) === hash)
219
+ return;
220
+ this.paneSnapshotHashes.set(session.id, hash);
221
+ const sessionDir = join(getContextDir(), session.id);
222
+ if (!existsSync(sessionDir))
223
+ mkdirSync(sessionDir, { recursive: true });
224
+ const snapshotBody = boundLiveSnapshot(normalized);
225
+ const snapshot = [
226
+ `# ${session.id} (${session.command}) — Live Snapshot`,
227
+ "",
228
+ `Updated: ${new Date().toISOString()}`,
229
+ "",
230
+ "Recent terminal output:",
231
+ "",
232
+ snapshotBody,
233
+ "",
234
+ ].join("\n");
235
+ writeFileSync(join(sessionDir, "live.md"), snapshot);
236
+ debugContext("wrote", `${session.id}/live.md`, snapshot.length);
237
+ const turns = readHistory(session.id, { lastN: 1 });
238
+ if (promptVisible) {
239
+ const snapshotTurn = normalized.split("\n").slice(-80).join("\n").trim();
240
+ if (snapshotTurn) {
241
+ const lastTurn = turns.at(-1);
242
+ if (!lastTurn || lastTurn.content !== snapshotTurn) {
243
+ appendTurn(session.id, {
244
+ ts: new Date().toISOString(),
245
+ type: "response",
246
+ content: snapshotTurn,
247
+ });
248
+ this.dirtySessions.add(session.id);
249
+ debugTurn(session.id, "response", snapshotTurn.length);
250
+ }
251
+ }
252
+ }
253
+ }
254
+ /**
255
+ * Check for git changes and append a git turn to history if files changed.
256
+ */
257
+ async captureGitDiff(sessionId) {
258
+ try {
259
+ const diff = await git.diff();
260
+ const hash = simpleHash(diff || "");
261
+ if (hash === this.lastDiffHash)
262
+ return;
263
+ this.lastDiffHash = hash;
264
+ if (!diff)
265
+ return;
266
+ const diffStat = await git.diffSummary();
267
+ if (diffStat.files.length === 0)
268
+ return;
269
+ const gitTurn = {
270
+ ts: new Date().toISOString(),
271
+ type: "git",
272
+ content: `${diffStat.files.length} file(s) changed`,
273
+ files: diffStat.files.map((f) => f.file),
274
+ diff: diff.slice(0, 2000),
275
+ };
276
+ debugGit(diffStat.files.length, diff.length);
277
+ appendTurn(sessionId, gitTurn);
278
+ }
279
+ catch { }
280
+ }
281
+ /**
282
+ * Write per-session live context from history JSONL files.
283
+ * Each session gets its own context/{session-id}/live.md.
284
+ */
285
+ writeLiveContext() {
286
+ const baseDir = getContextDir();
287
+ if (!existsSync(baseDir))
288
+ mkdirSync(baseDir, { recursive: true });
289
+ const turnsPerSession = loadConfig().liveWindowSize;
290
+ const sessionsToWrite = this.sessions.filter((s) => this.dirtySessions.has(s.id));
291
+ this.dirtySessions.clear();
292
+ for (const session of sessionsToWrite) {
293
+ const sessionDir = join(baseDir, session.id);
294
+ if (!existsSync(sessionDir))
295
+ mkdirSync(sessionDir, { recursive: true });
296
+ let windowSize = turnsPerSession;
297
+ while (windowSize >= 2) {
298
+ const content = this.buildSessionLiveContent(session, windowSize);
299
+ if (content.length <= MAX_LIVE_MD_BYTES || windowSize <= 2) {
300
+ if (content.length > 2) {
301
+ const livePath = join(sessionDir, "live.md");
302
+ writeFileSync(livePath, content);
303
+ debugContext("wrote", `${session.id}/live.md`, content.length);
304
+ }
305
+ break;
306
+ }
307
+ windowSize = Math.floor(windowSize * 0.7);
308
+ }
309
+ }
310
+ }
311
+ /**
312
+ * Build live.md content for a single session from its history.
313
+ */
314
+ buildSessionLiveContent(session, turnsPerSession) {
315
+ const turns = readHistory(session.id, { lastN: turnsPerSession });
316
+ if (turns.length === 0)
317
+ return "";
318
+ const sections = [`# ${session.id} (${session.command}) — Live Context\n`];
319
+ sections.push(`Updated: ${new Date().toISOString()}\n`);
320
+ for (const turn of turns) {
321
+ const time = turn.ts.slice(11, 16); // HH:MM from ISO string
322
+ if (turn.type === "prompt") {
323
+ sections.push(`**[${time}] User:** ${truncate(turn.content, 200)}\n`);
324
+ }
325
+ else if (turn.type === "response") {
326
+ sections.push(`**[${time}] Agent:** ${truncate(turn.content, 500)}\n`);
327
+ if (turn.files && turn.files.length > 0) {
328
+ sections.push(` *Files: ${turn.files.join(", ")}*\n`);
329
+ }
330
+ }
331
+ else if (turn.type === "git") {
332
+ if (turn.files && turn.files.length > 0) {
333
+ sections.push(` *Files changed: ${turn.files.join(", ")}*\n`);
334
+ }
335
+ }
336
+ }
337
+ return sections.join("\n");
338
+ }
339
+ }
340
+ function normalizeTerminalLine(line) {
341
+ return line
342
+ .replace(/\u00a0/g, " ")
343
+ .replace(/\r/g, "")
344
+ .replace(/[\u200b-\u200d\u2060\ufeff]/g, "")
345
+ .replace(/\s+$/g, "");
346
+ }
347
+ function isLikelyUiChrome(line) {
348
+ const trimmed = line.trim();
349
+ if (!trimmed)
350
+ return true;
351
+ if (/^[─│╭╮╯╰┌┐└┘├┤┬┴┼═║╔╗╚╝╠╣╦╩╬]+$/.test(trimmed))
352
+ return true;
353
+ if (/^[╰╭][─┄━]+/.test(trimmed))
354
+ return true;
355
+ if (/^│\s*$/.test(trimmed))
356
+ return true;
357
+ return false;
358
+ }
359
+ /**
360
+ * Parse raw terminal recording output into conversation turns.
361
+ * Recordings are treated as a best-effort recovery path, not the primary continuity source.
362
+ */
363
+ function parseConversationTurns(text, tool, turnPatterns) {
364
+ const turns = [];
365
+ const lines = text.split("\n").map(normalizeTerminalLine);
366
+ const patterns = turnPatterns ?? [/^[>❯$]\s*(.+)/];
367
+ let currentType = null;
368
+ let currentContent = [];
369
+ for (const line of lines) {
370
+ const trimmed = line.trim();
371
+ if (isLikelyUiChrome(line))
372
+ continue;
373
+ // Check if this line is a prompt
374
+ let isPrompt = false;
375
+ let promptContent = "";
376
+ for (const pattern of patterns) {
377
+ const match = trimmed.match(pattern);
378
+ if (match) {
379
+ isPrompt = true;
380
+ // Use captured group if present; skip if no capture (bare prompt marker)
381
+ promptContent = match[1]?.trim() ?? "";
382
+ break;
383
+ }
384
+ }
385
+ if (isPrompt && promptContent) {
386
+ // Save previous turn
387
+ if (currentType && currentContent.length > 0) {
388
+ turns.push({
389
+ type: currentType,
390
+ content: currentContent.join("\n").trim(),
391
+ });
392
+ }
393
+ currentType = "prompt";
394
+ currentContent = [promptContent];
395
+ }
396
+ else if (currentType === "prompt" && !isPrompt) {
397
+ // Transition from prompt to response
398
+ if (currentContent.length > 0) {
399
+ turns.push({
400
+ type: "prompt",
401
+ content: currentContent.join("\n").trim(),
402
+ });
403
+ }
404
+ currentType = "response";
405
+ currentContent = [trimmed];
406
+ }
407
+ else if (currentType === "response") {
408
+ currentContent.push(trimmed);
409
+ }
410
+ else if (!currentType) {
411
+ // If the recording starts mid-response, recover useful content instead of discarding it.
412
+ currentType = "response";
413
+ currentContent = [trimmed];
414
+ }
415
+ }
416
+ // Save last turn
417
+ if (currentType && currentContent.length > 0) {
418
+ turns.push({
419
+ type: currentType,
420
+ content: currentContent.join("\n").trim(),
421
+ });
422
+ }
423
+ return turns;
424
+ }
425
+ /** Get recent stripped output from a session's raw recording as a fallback/debug aid. */
426
+ export function getRecentOutput(sessionId, maxLines = 20) {
427
+ const txtPath = join(getRecordingsDir(), `${sessionId}.txt`);
428
+ if (!existsSync(txtPath))
429
+ return "";
430
+ try {
431
+ const content = readFileSync(txtPath, "utf-8");
432
+ const lines = content.split("\n");
433
+ return lines.slice(-maxLines).join("\n").trim();
434
+ }
435
+ catch {
436
+ return "";
437
+ }
438
+ }
439
+ /** Build a context preamble for a new session from other sessions' per-session context files. */
440
+ export function buildContextPreamble(otherSessionIds, maxLinesPerSession = 10) {
441
+ const contextDir = getContextDir();
442
+ const sections = [];
443
+ for (const id of otherSessionIds) {
444
+ // Try per-session live.md first
445
+ const sessionLivePath = join(contextDir, id, "live.md");
446
+ if (existsSync(sessionLivePath)) {
447
+ try {
448
+ const content = readFileSync(sessionLivePath, "utf-8");
449
+ if (content.trim()) {
450
+ sections.push(content);
451
+ continue;
452
+ }
453
+ }
454
+ catch { }
455
+ }
456
+ // Fallback to raw recording snippets only when no live context file exists.
457
+ const output = getRecentOutput(id, maxLinesPerSession);
458
+ if (output) {
459
+ sections.push(`--- Recent output from ${id} ---\n${output}`);
460
+ }
461
+ }
462
+ if (sections.length === 0)
463
+ return "";
464
+ return "=== Context from other aimux sessions ===\n\n" + sections.join("\n\n") + "\n\n=== End context ===\n";
465
+ }
466
+ function truncate(text, max) {
467
+ if (text.length <= max)
468
+ return text;
469
+ return text.slice(0, max) + "...";
470
+ }
471
+ //# sourceMappingURL=context-bridge.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"context-bridge.js","sourceRoot":"","sources":["../../src/context/context-bridge.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ export interface ContextEntry {
2
+ sessionName: string;
3
+ tool: string;
4
+ timestamp: Date;
5
+ prompt: string;
6
+ response: string;
7
+ files: string[];
8
+ diff?: string;
9
+ }
10
+ export declare function appendEntry(entry: ContextEntry): Promise<void>;
11
+ export declare function readContext(maxEntries?: number): string;
@@ -0,0 +1,93 @@
1
+ import { existsSync, readFileSync, writeFileSync, mkdirSync, readdirSync } from "node:fs";
2
+ import { dirname, join } from "node:path";
3
+ import * as lockfile from "proper-lockfile";
4
+ import { getContextDir, getContextPathForDate } from "../paths.js";
5
+ function truncate(text, maxLen) {
6
+ if (text.length <= maxLen)
7
+ return text;
8
+ return text.slice(0, maxLen) + "\n... (truncated)";
9
+ }
10
+ function formatEntry(entry) {
11
+ const time = entry.timestamp.toLocaleTimeString("en-US", {
12
+ hour: "2-digit",
13
+ minute: "2-digit",
14
+ hour12: false,
15
+ });
16
+ const lines = [
17
+ `### [${time}] ${entry.sessionName} (${entry.tool})`,
18
+ `<!-- aimux:entry session=${entry.sessionName} tool=${entry.tool} ts=${entry.timestamp.toISOString()} -->`,
19
+ "",
20
+ `**Prompt:** ${entry.prompt}`,
21
+ "",
22
+ `**Response:**`,
23
+ truncate(entry.response.trim(), 1000),
24
+ "",
25
+ ];
26
+ if (entry.files.length > 0) {
27
+ lines.push("**Files changed:**");
28
+ for (const f of entry.files) {
29
+ lines.push(`- \`${f}\``);
30
+ }
31
+ lines.push("");
32
+ }
33
+ if (entry.diff) {
34
+ lines.push("<details><summary>Diff</summary>", "", "```diff");
35
+ lines.push(entry.diff);
36
+ lines.push("```", "", "</details>");
37
+ lines.push("");
38
+ }
39
+ lines.push("---", "");
40
+ return lines.join("\n");
41
+ }
42
+ function ensureDayFile(filePath, date) {
43
+ const dir = dirname(filePath);
44
+ if (!existsSync(dir)) {
45
+ mkdirSync(dir, { recursive: true });
46
+ }
47
+ if (!existsSync(filePath)) {
48
+ const dateStr = date.toISOString().split("T")[0];
49
+ writeFileSync(filePath, `# aimux Context — ${dateStr}\n\n`);
50
+ }
51
+ }
52
+ export async function appendEntry(entry) {
53
+ const now = entry.timestamp;
54
+ const filePath = getContextPathForDate(now);
55
+ ensureDayFile(filePath, now);
56
+ let release;
57
+ try {
58
+ release = await lockfile.lock(filePath, {
59
+ retries: { retries: 5, minTimeout: 50 },
60
+ });
61
+ const existing = readFileSync(filePath, "utf-8");
62
+ const newContent = existing + formatEntry(entry);
63
+ writeFileSync(filePath, newContent);
64
+ }
65
+ finally {
66
+ if (release)
67
+ await release();
68
+ }
69
+ }
70
+ export function readContext(maxEntries = 20) {
71
+ const contextDir = getContextDir();
72
+ if (!existsSync(contextDir))
73
+ return "";
74
+ const files = readdirSync(contextDir)
75
+ .filter((f) => f.match(/^\d{4}-\d{2}-\d{2}\.md$/))
76
+ .sort()
77
+ .reverse();
78
+ if (files.length === 0)
79
+ return "";
80
+ const allEntries = [];
81
+ for (const file of files) {
82
+ const content = readFileSync(join(contextDir, file), "utf-8");
83
+ const entries = content.split(/(?=### \[)/).filter((e) => e.startsWith("### ["));
84
+ allEntries.push(...entries.reverse());
85
+ if (allEntries.length >= maxEntries)
86
+ break;
87
+ }
88
+ const selected = allEntries.slice(0, maxEntries).reverse();
89
+ if (selected.length === 0)
90
+ return "";
91
+ return selected.join("");
92
+ }
93
+ //# sourceMappingURL=context-file.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"context-file.js","sourceRoot":"","sources":["../../src/context/context-file.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,40 @@
1
+ export interface HistoryTurn {
2
+ ts: string;
3
+ type: "prompt" | "response" | "git";
4
+ content: string;
5
+ files?: string[];
6
+ diff?: string;
7
+ }
8
+ /**
9
+ * Append a single turn to the session's JSONL history file.
10
+ * Creates the history directory if it doesn't exist.
11
+ */
12
+ export declare function appendTurn(sessionId: string, turn: HistoryTurn): void;
13
+ /**
14
+ * Read turns from a session's JSONL history file.
15
+ *
16
+ * Options:
17
+ * - lastN: return only the last N turns
18
+ * - since: filter to turns with ts >= since (ISO string comparison)
19
+ * - maxBytes: max bytes to read from the file (default 100KB).
20
+ * When the file exceeds this, reads from the tail of the file.
21
+ */
22
+ export declare function readHistory(sessionId: string, opts?: {
23
+ lastN?: number;
24
+ since?: string;
25
+ maxBytes?: number;
26
+ }): HistoryTurn[];
27
+ /**
28
+ * List all session IDs that have history files.
29
+ * Scans history dir for .jsonl files and returns IDs (filename without extension).
30
+ */
31
+ export declare function listSessionIds(): string[];
32
+ /**
33
+ * Read history from multiple sessions, merge by timestamp.
34
+ * lastN applies per-session (each session contributes at most lastN turns).
35
+ */
36
+ export declare function readAllHistories(sessionIds: string[], opts?: {
37
+ lastN?: number;
38
+ since?: string;
39
+ maxBytes?: number;
40
+ }): HistoryTurn[];