@blulotus/trellis-core 0.7.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 (218) hide show
  1. package/LICENSE +235 -0
  2. package/dist/channel/api/assert.d.ts +3 -0
  3. package/dist/channel/api/assert.d.ts.map +1 -0
  4. package/dist/channel/api/assert.js +11 -0
  5. package/dist/channel/api/assert.js.map +1 -0
  6. package/dist/channel/api/context.d.ts +21 -0
  7. package/dist/channel/api/context.d.ts.map +1 -0
  8. package/dist/channel/api/context.js +99 -0
  9. package/dist/channel/api/context.js.map +1 -0
  10. package/dist/channel/api/create.d.ts +9 -0
  11. package/dist/channel/api/create.d.ts.map +1 -0
  12. package/dist/channel/api/create.js +104 -0
  13. package/dist/channel/api/create.js.map +1 -0
  14. package/dist/channel/api/inbox.d.ts +51 -0
  15. package/dist/channel/api/inbox.d.ts.map +1 -0
  16. package/dist/channel/api/inbox.js +176 -0
  17. package/dist/channel/api/inbox.js.map +1 -0
  18. package/dist/channel/api/interrupt.d.ts +31 -0
  19. package/dist/channel/api/interrupt.d.ts.map +1 -0
  20. package/dist/channel/api/interrupt.js +102 -0
  21. package/dist/channel/api/interrupt.js.map +1 -0
  22. package/dist/channel/api/post-thread.d.ts +14 -0
  23. package/dist/channel/api/post-thread.d.ts.map +1 -0
  24. package/dist/channel/api/post-thread.js +109 -0
  25. package/dist/channel/api/post-thread.js.map +1 -0
  26. package/dist/channel/api/read.d.ts +17 -0
  27. package/dist/channel/api/read.d.ts.map +1 -0
  28. package/dist/channel/api/read.js +44 -0
  29. package/dist/channel/api/read.js.map +1 -0
  30. package/dist/channel/api/resolve.d.ts +21 -0
  31. package/dist/channel/api/resolve.d.ts.map +1 -0
  32. package/dist/channel/api/resolve.js +28 -0
  33. package/dist/channel/api/resolve.js.map +1 -0
  34. package/dist/channel/api/runtime.d.ts +70 -0
  35. package/dist/channel/api/runtime.d.ts.map +1 -0
  36. package/dist/channel/api/runtime.js +11 -0
  37. package/dist/channel/api/runtime.js.map +1 -0
  38. package/dist/channel/api/send.d.ts +4 -0
  39. package/dist/channel/api/send.d.ts.map +1 -0
  40. package/dist/channel/api/send.js +52 -0
  41. package/dist/channel/api/send.js.map +1 -0
  42. package/dist/channel/api/spawn.d.ts +13 -0
  43. package/dist/channel/api/spawn.d.ts.map +1 -0
  44. package/dist/channel/api/spawn.js +54 -0
  45. package/dist/channel/api/spawn.js.map +1 -0
  46. package/dist/channel/api/title.d.ts +5 -0
  47. package/dist/channel/api/title.d.ts.map +1 -0
  48. package/dist/channel/api/title.js +40 -0
  49. package/dist/channel/api/title.js.map +1 -0
  50. package/dist/channel/api/types.d.ts +65 -0
  51. package/dist/channel/api/types.d.ts.map +1 -0
  52. package/dist/channel/api/types.js +2 -0
  53. package/dist/channel/api/types.js.map +1 -0
  54. package/dist/channel/api/watch-channels.d.ts +40 -0
  55. package/dist/channel/api/watch-channels.d.ts.map +1 -0
  56. package/dist/channel/api/watch-channels.js +143 -0
  57. package/dist/channel/api/watch-channels.js.map +1 -0
  58. package/dist/channel/api/watch.d.ts +11 -0
  59. package/dist/channel/api/watch.d.ts.map +1 -0
  60. package/dist/channel/api/watch.js +17 -0
  61. package/dist/channel/api/watch.js.map +1 -0
  62. package/dist/channel/api/workers.d.ts +69 -0
  63. package/dist/channel/api/workers.d.ts.map +1 -0
  64. package/dist/channel/api/workers.js +145 -0
  65. package/dist/channel/api/workers.js.map +1 -0
  66. package/dist/channel/index.d.ts +38 -0
  67. package/dist/channel/index.d.ts.map +1 -0
  68. package/dist/channel/index.js +23 -0
  69. package/dist/channel/index.js.map +1 -0
  70. package/dist/channel/internal/store/channel-metadata.d.ts +23 -0
  71. package/dist/channel/internal/store/channel-metadata.d.ts.map +1 -0
  72. package/dist/channel/internal/store/channel-metadata.js +94 -0
  73. package/dist/channel/internal/store/channel-metadata.js.map +1 -0
  74. package/dist/channel/internal/store/delivery.d.ts +27 -0
  75. package/dist/channel/internal/store/delivery.d.ts.map +1 -0
  76. package/dist/channel/internal/store/delivery.js +37 -0
  77. package/dist/channel/internal/store/delivery.js.map +1 -0
  78. package/dist/channel/internal/store/events.d.ts +215 -0
  79. package/dist/channel/internal/store/events.d.ts.map +1 -0
  80. package/dist/channel/internal/store/events.js +206 -0
  81. package/dist/channel/internal/store/events.js.map +1 -0
  82. package/dist/channel/internal/store/filter.d.ts +21 -0
  83. package/dist/channel/internal/store/filter.d.ts.map +1 -0
  84. package/dist/channel/internal/store/filter.js +75 -0
  85. package/dist/channel/internal/store/filter.js.map +1 -0
  86. package/dist/channel/internal/store/inbox.d.ts +17 -0
  87. package/dist/channel/internal/store/inbox.d.ts.map +1 -0
  88. package/dist/channel/internal/store/inbox.js +30 -0
  89. package/dist/channel/internal/store/inbox.js.map +1 -0
  90. package/dist/channel/internal/store/lock.d.ts +17 -0
  91. package/dist/channel/internal/store/lock.d.ts.map +1 -0
  92. package/dist/channel/internal/store/lock.js +88 -0
  93. package/dist/channel/internal/store/lock.js.map +1 -0
  94. package/dist/channel/internal/store/paths.d.ts +57 -0
  95. package/dist/channel/internal/store/paths.d.ts.map +1 -0
  96. package/dist/channel/internal/store/paths.js +264 -0
  97. package/dist/channel/internal/store/paths.js.map +1 -0
  98. package/dist/channel/internal/store/schema.d.ts +77 -0
  99. package/dist/channel/internal/store/schema.d.ts.map +1 -0
  100. package/dist/channel/internal/store/schema.js +127 -0
  101. package/dist/channel/internal/store/schema.js.map +1 -0
  102. package/dist/channel/internal/store/seq.d.ts +12 -0
  103. package/dist/channel/internal/store/seq.d.ts.map +1 -0
  104. package/dist/channel/internal/store/seq.js +133 -0
  105. package/dist/channel/internal/store/seq.js.map +1 -0
  106. package/dist/channel/internal/store/thread-state.d.ts +37 -0
  107. package/dist/channel/internal/store/thread-state.d.ts.map +1 -0
  108. package/dist/channel/internal/store/thread-state.js +206 -0
  109. package/dist/channel/internal/store/thread-state.js.map +1 -0
  110. package/dist/channel/internal/store/watch.d.ts +10 -0
  111. package/dist/channel/internal/store/watch.d.ts.map +1 -0
  112. package/dist/channel/internal/store/watch.js +122 -0
  113. package/dist/channel/internal/store/watch.js.map +1 -0
  114. package/dist/channel/internal/store/worker-state.d.ts +56 -0
  115. package/dist/channel/internal/store/worker-state.d.ts.map +1 -0
  116. package/dist/channel/internal/store/worker-state.js +220 -0
  117. package/dist/channel/internal/store/worker-state.js.map +1 -0
  118. package/dist/index.d.ts +3 -0
  119. package/dist/index.d.ts.map +1 -0
  120. package/dist/index.js +7 -0
  121. package/dist/index.js.map +1 -0
  122. package/dist/mem/adapters/claude.d.ts +22 -0
  123. package/dist/mem/adapters/claude.d.ts.map +1 -0
  124. package/dist/mem/adapters/claude.js +209 -0
  125. package/dist/mem/adapters/claude.js.map +1 -0
  126. package/dist/mem/adapters/codex.d.ts +55 -0
  127. package/dist/mem/adapters/codex.d.ts.map +1 -0
  128. package/dist/mem/adapters/codex.js +344 -0
  129. package/dist/mem/adapters/codex.js.map +1 -0
  130. package/dist/mem/adapters/grok.d.ts +41 -0
  131. package/dist/mem/adapters/grok.d.ts.map +1 -0
  132. package/dist/mem/adapters/grok.js +202 -0
  133. package/dist/mem/adapters/grok.js.map +1 -0
  134. package/dist/mem/adapters/opencode.d.ts +19 -0
  135. package/dist/mem/adapters/opencode.d.ts.map +1 -0
  136. package/dist/mem/adapters/opencode.js +25 -0
  137. package/dist/mem/adapters/opencode.js.map +1 -0
  138. package/dist/mem/adapters/pi.d.ts +24 -0
  139. package/dist/mem/adapters/pi.d.ts.map +1 -0
  140. package/dist/mem/adapters/pi.js +290 -0
  141. package/dist/mem/adapters/pi.js.map +1 -0
  142. package/dist/mem/adapters/zcode.d.ts +76 -0
  143. package/dist/mem/adapters/zcode.d.ts.map +1 -0
  144. package/dist/mem/adapters/zcode.js +434 -0
  145. package/dist/mem/adapters/zcode.js.map +1 -0
  146. package/dist/mem/context.d.ts +23 -0
  147. package/dist/mem/context.d.ts.map +1 -0
  148. package/dist/mem/context.js +120 -0
  149. package/dist/mem/context.js.map +1 -0
  150. package/dist/mem/dialogue.d.ts +32 -0
  151. package/dist/mem/dialogue.d.ts.map +1 -0
  152. package/dist/mem/dialogue.js +0 -0
  153. package/dist/mem/dialogue.js.map +1 -0
  154. package/dist/mem/filter.d.ts +31 -0
  155. package/dist/mem/filter.d.ts.map +1 -0
  156. package/dist/mem/filter.js +66 -0
  157. package/dist/mem/filter.js.map +1 -0
  158. package/dist/mem/index.d.ts +18 -0
  159. package/dist/mem/index.d.ts.map +1 -0
  160. package/dist/mem/index.js +17 -0
  161. package/dist/mem/index.js.map +1 -0
  162. package/dist/mem/internal/jsonl.d.ts +35 -0
  163. package/dist/mem/internal/jsonl.d.ts.map +1 -0
  164. package/dist/mem/internal/jsonl.js +125 -0
  165. package/dist/mem/internal/jsonl.js.map +1 -0
  166. package/dist/mem/internal/paths.d.ts +38 -0
  167. package/dist/mem/internal/paths.d.ts.map +1 -0
  168. package/dist/mem/internal/paths.js +126 -0
  169. package/dist/mem/internal/paths.js.map +1 -0
  170. package/dist/mem/internal/sqlite-readonly.d.ts +77 -0
  171. package/dist/mem/internal/sqlite-readonly.d.ts.map +1 -0
  172. package/dist/mem/internal/sqlite-readonly.js +797 -0
  173. package/dist/mem/internal/sqlite-readonly.js.map +1 -0
  174. package/dist/mem/phase.d.ts +45 -0
  175. package/dist/mem/phase.d.ts.map +1 -0
  176. package/dist/mem/phase.js +220 -0
  177. package/dist/mem/phase.js.map +1 -0
  178. package/dist/mem/projects.d.ts +13 -0
  179. package/dist/mem/projects.d.ts.map +1 -0
  180. package/dist/mem/projects.js +47 -0
  181. package/dist/mem/projects.js.map +1 -0
  182. package/dist/mem/search.d.ts +39 -0
  183. package/dist/mem/search.d.ts.map +1 -0
  184. package/dist/mem/search.js +133 -0
  185. package/dist/mem/search.js.map +1 -0
  186. package/dist/mem/sessions.d.ts +38 -0
  187. package/dist/mem/sessions.d.ts.map +1 -0
  188. package/dist/mem/sessions.js +313 -0
  189. package/dist/mem/sessions.js.map +1 -0
  190. package/dist/mem/types.d.ts +188 -0
  191. package/dist/mem/types.d.ts.map +1 -0
  192. package/dist/mem/types.js +10 -0
  193. package/dist/mem/types.js.map +1 -0
  194. package/dist/task/index.d.ts +9 -0
  195. package/dist/task/index.d.ts.map +1 -0
  196. package/dist/task/index.js +9 -0
  197. package/dist/task/index.js.map +1 -0
  198. package/dist/task/paths.d.ts +37 -0
  199. package/dist/task/paths.d.ts.map +1 -0
  200. package/dist/task/paths.js +49 -0
  201. package/dist/task/paths.js.map +1 -0
  202. package/dist/task/phase.d.ts +27 -0
  203. package/dist/task/phase.d.ts.map +1 -0
  204. package/dist/task/phase.js +24 -0
  205. package/dist/task/phase.js.map +1 -0
  206. package/dist/task/records.d.ts +39 -0
  207. package/dist/task/records.d.ts.map +1 -0
  208. package/dist/task/records.js +89 -0
  209. package/dist/task/records.js.map +1 -0
  210. package/dist/task/schema.d.ts +77 -0
  211. package/dist/task/schema.d.ts.map +1 -0
  212. package/dist/task/schema.js +220 -0
  213. package/dist/task/schema.js.map +1 -0
  214. package/dist/testing/index.d.ts +2 -0
  215. package/dist/testing/index.d.ts.map +1 -0
  216. package/dist/testing/index.js +4 -0
  217. package/dist/testing/index.js.map +1 -0
  218. package/package.json +77 -0
@@ -0,0 +1,220 @@
1
+ import { matchesInboxPolicy, DEFAULT_INBOX_POLICY } from "./inbox.js";
2
+ const TERMINAL_LIFECYCLES = new Set([
3
+ "done",
4
+ "error",
5
+ "killed",
6
+ "crashed",
7
+ ]);
8
+ function strField(ev, key) {
9
+ const v = ev[key];
10
+ return typeof v === "string" ? v : undefined;
11
+ }
12
+ function numField(ev, key) {
13
+ const v = ev[key];
14
+ return typeof v === "number" ? v : undefined;
15
+ }
16
+ /**
17
+ * Resolve the worker id an event refers to, and whether the event kind
18
+ * is allowed to *create* a worker entry (only `spawned` and clearly
19
+ * worker-identified terminal events can — this avoids phantom workers
20
+ * from plain `by` aliases).
21
+ */
22
+ function identifyWorker(ev) {
23
+ switch (ev.kind) {
24
+ case "spawned": {
25
+ const id = strField(ev, "as");
26
+ return id ? { id, canCreate: true } : null;
27
+ }
28
+ case "turn_started":
29
+ case "turn_finished":
30
+ case "interrupt_requested":
31
+ case "interrupted": {
32
+ const id = strField(ev, "worker");
33
+ return id ? { id, canCreate: false } : null;
34
+ }
35
+ case "killed": {
36
+ const explicit = strField(ev, "worker") ?? strField(ev, "as");
37
+ if (explicit)
38
+ return { id: explicit, canCreate: true };
39
+ const by = ev.by;
40
+ if (by.startsWith("supervisor:")) {
41
+ return { id: by.slice("supervisor:".length), canCreate: true };
42
+ }
43
+ return { id: by, canCreate: false };
44
+ }
45
+ case "done":
46
+ case "error": {
47
+ const explicit = strField(ev, "worker") ?? strField(ev, "as");
48
+ if (explicit)
49
+ return { id: explicit, canCreate: true };
50
+ const by = ev.by;
51
+ if (by.startsWith("supervisor:")) {
52
+ return { id: by.slice("supervisor:".length), canCreate: true };
53
+ }
54
+ return { id: by, canCreate: false };
55
+ }
56
+ default:
57
+ return null;
58
+ }
59
+ }
60
+ function blankWorker(id, ev) {
61
+ return {
62
+ workerId: id,
63
+ lifecycle: "running",
64
+ terminal: false,
65
+ activity: "idle",
66
+ pendingMessageCount: 0,
67
+ inboxPolicy: DEFAULT_INBOX_POLICY,
68
+ updatedAt: ev.ts,
69
+ lastSeq: ev.seq,
70
+ consumedInputSeq: 0,
71
+ };
72
+ }
73
+ /**
74
+ * Project durable channel events into the worker registry. Pure — only
75
+ * the event log feeds the projection (no pid files, no inbox cursors).
76
+ */
77
+ export function reduceWorkerRegistry(events, channel) {
78
+ const acc = new Map();
79
+ for (const ev of events) {
80
+ const ident = identifyWorker(ev);
81
+ if (!ident)
82
+ continue;
83
+ let w = acc.get(ident.id);
84
+ if (!w) {
85
+ if (!ident.canCreate)
86
+ continue;
87
+ w = blankWorker(ident.id, ev);
88
+ acc.set(ident.id, w);
89
+ }
90
+ w.updatedAt = ev.ts;
91
+ w.lastSeq = ev.seq;
92
+ switch (ev.kind) {
93
+ case "spawned": {
94
+ w.lifecycle = "running";
95
+ w.terminal = false;
96
+ w.activity = "idle";
97
+ delete w.activeTurnId;
98
+ delete w.activeTurnStartedAt;
99
+ delete w.exitCode;
100
+ delete w.signal;
101
+ delete w.reason;
102
+ delete w.error;
103
+ w.spawnedAt = ev.ts;
104
+ w.idleSince = ev.ts;
105
+ w.startedBy = ev.by;
106
+ w.provider = strField(ev, "provider") ?? w.provider;
107
+ w.agent = strField(ev, "agent") ?? w.agent;
108
+ w.inboxPolicy =
109
+ strField(ev, "inboxPolicy") ??
110
+ w.inboxPolicy;
111
+ break;
112
+ }
113
+ case "turn_started": {
114
+ w.activity = "mid-turn";
115
+ w.activeTurnId = strField(ev, "turnId");
116
+ w.activeTurnStartedAt = ev.ts;
117
+ delete w.idleSince;
118
+ const inputSeq = numField(ev, "inputSeq");
119
+ if (inputSeq !== undefined && inputSeq > w.consumedInputSeq) {
120
+ w.consumedInputSeq = inputSeq;
121
+ }
122
+ break;
123
+ }
124
+ case "turn_finished": {
125
+ w.activity = "idle";
126
+ delete w.activeTurnId;
127
+ delete w.activeTurnStartedAt;
128
+ w.idleSince = ev.ts;
129
+ break;
130
+ }
131
+ case "interrupted": {
132
+ // An interrupt aborts the active turn.
133
+ w.activity = "idle";
134
+ delete w.activeTurnId;
135
+ delete w.activeTurnStartedAt;
136
+ w.idleSince = ev.ts;
137
+ break;
138
+ }
139
+ case "interrupt_requested":
140
+ // Durable intent only — no lifecycle/activity change.
141
+ break;
142
+ case "done": {
143
+ w.activity = "idle";
144
+ delete w.activeTurnId;
145
+ delete w.activeTurnStartedAt;
146
+ if (ev.synthesized === true) {
147
+ w.lifecycle = "done";
148
+ w.terminal = true;
149
+ w.exitCode = numField(ev, "exit_code") ?? w.exitCode;
150
+ delete w.idleSince;
151
+ }
152
+ else {
153
+ w.idleSince = ev.ts;
154
+ }
155
+ break;
156
+ }
157
+ case "error": {
158
+ w.activity = "idle";
159
+ delete w.activeTurnId;
160
+ delete w.activeTurnStartedAt;
161
+ w.error = strField(ev, "message") ?? w.error;
162
+ if (ev.synthesized === true ||
163
+ ev.by.startsWith("supervisor:")) {
164
+ w.lifecycle = "error";
165
+ w.terminal = true;
166
+ w.exitCode = numField(ev, "exit_code") ?? w.exitCode;
167
+ w.signal = strField(ev, "exit_signal") ?? w.signal;
168
+ delete w.idleSince;
169
+ }
170
+ else {
171
+ w.idleSince = ev.ts;
172
+ }
173
+ break;
174
+ }
175
+ case "killed": {
176
+ const reason = strField(ev, "reason");
177
+ w.lifecycle = reason === "crash" ? "crashed" : "killed";
178
+ w.terminal = true;
179
+ w.activity = "idle";
180
+ delete w.activeTurnId;
181
+ delete w.activeTurnStartedAt;
182
+ delete w.idleSince;
183
+ w.reason = reason ?? w.reason;
184
+ w.signal = strField(ev, "signal") ?? w.signal;
185
+ break;
186
+ }
187
+ default:
188
+ break;
189
+ }
190
+ }
191
+ // Second pass: pending message count from durable events only.
192
+ for (const w of acc.values()) {
193
+ if (w.terminal) {
194
+ w.pendingMessageCount = 0;
195
+ continue;
196
+ }
197
+ let pending = 0;
198
+ for (const ev of events) {
199
+ if (ev.seq <= w.consumedInputSeq)
200
+ continue;
201
+ if (matchesInboxPolicy(ev, w.workerId, w.inboxPolicy))
202
+ pending++;
203
+ }
204
+ w.pendingMessageCount = pending;
205
+ }
206
+ const workers = [];
207
+ for (const w of acc.values()) {
208
+ const { consumedInputSeq: _drop, ...state } = w;
209
+ void _drop;
210
+ if (channel)
211
+ state.channel = channel;
212
+ workers.push(state);
213
+ }
214
+ workers.sort((a, b) => a.workerId.localeCompare(b.workerId));
215
+ return { workers };
216
+ }
217
+ export function isTerminalLifecycle(lifecycle) {
218
+ return TERMINAL_LIFECYCLES.has(lifecycle);
219
+ }
220
+ //# sourceMappingURL=worker-state.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"worker-state.js","sourceRoot":"","sources":["../../../../src/channel/internal/store/worker-state.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ export * from "./channel/index.js";
2
+ export * from "./task/index.js";
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAKA,cAAc,oBAAoB,CAAC;AACnC,cAAc,iBAAiB,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,7 @@
1
+ // Root barrel — re-exports the channel and task public APIs so callers
2
+ // can `import { ... } from "@blulotus/trellis-core"`. Sub-path
3
+ // imports (`@blulotus/trellis-core/channel`, `/task`) remain the
4
+ // recommended form for tree-shake-friendly consumption.
5
+ export * from "./channel/index.js";
6
+ export * from "./task/index.js";
7
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,uEAAuE;AACvE,+DAA+D;AAC/D,iEAAiE;AACjE,wDAAwD;AAExD,cAAc,oBAAoB,CAAC;AACnC,cAAc,iBAAiB,CAAC"}
@@ -0,0 +1,22 @@
1
+ /**
2
+ * Persisted Claude Code session reader.
3
+ *
4
+ * Layout: `~/.claude/projects/<sanitized-cwd>/<sessionId>.jsonl`, with an
5
+ * optional `<projectDir>/sessions-index.json` providing cwd / created / title.
6
+ */
7
+ import type { DialogueTurn, MemFilter, MemSessionInfo, SearchHit, TaskPyEvent } from "../types.js";
8
+ export declare function claudeListSessions(f: MemFilter): MemSessionInfo[];
9
+ export declare function claudeExtractDialogue(s: MemSessionInfo): DialogueTurn[];
10
+ export declare function claudeSearch(s: MemSessionInfo, kw: string): SearchHit;
11
+ /**
12
+ * Single-pass scan of a Claude JSONL file that produces both the cleaned
13
+ * dialogue turns (semantically identical to {@link claudeExtractDialogue}) and
14
+ * the list of `task.py create|start` Bash tool_use events with their
15
+ * `turnIndex`. Compaction keeps both `turns` and `events` — the turns those
16
+ * indices point at are still in the pool.
17
+ */
18
+ export declare function collectClaudeTurnsAndEvents(s: MemSessionInfo): {
19
+ turns: DialogueTurn[];
20
+ events: TaskPyEvent[];
21
+ };
22
+ //# sourceMappingURL=claude.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"claude.d.ts","sourceRoot":"","sources":["../../../src/mem/adapters/claude.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAoBH,OAAO,KAAK,EACV,YAAY,EACZ,SAAS,EACT,cAAc,EACd,SAAS,EACT,WAAW,EACZ,MAAM,aAAa,CAAC;AAqCrB,wBAAgB,kBAAkB,CAAC,CAAC,EAAE,SAAS,GAAG,cAAc,EAAE,CAyEjE;AAkBD,wBAAgB,qBAAqB,CAAC,CAAC,EAAE,cAAc,GAAG,YAAY,EAAE,CAuCvE;AAED,wBAAgB,YAAY,CAAC,CAAC,EAAE,cAAc,EAAE,EAAE,EAAE,MAAM,GAAG,SAAS,CAErE;AAED;;;;;;GAMG;AACH,wBAAgB,2BAA2B,CAAC,CAAC,EAAE,cAAc,GAAG;IAC9D,KAAK,EAAE,YAAY,EAAE,CAAC;IACtB,MAAM,EAAE,WAAW,EAAE,CAAC;CACvB,CAkEA"}
@@ -0,0 +1,209 @@
1
+ /**
2
+ * Persisted Claude Code session reader.
3
+ *
4
+ * Layout: `~/.claude/projects/<sanitized-cwd>/<sessionId>.jsonl`, with an
5
+ * optional `<projectDir>/sessions-index.json` providing cwd / created / title.
6
+ */
7
+ import * as fs from "node:fs";
8
+ import * as path from "node:path";
9
+ import { compactionBoundaryTurn, stripInjectionTags, isBootstrapTurn, } from "../dialogue.js";
10
+ import { inRangeOverlap, sameProject } from "../filter.js";
11
+ import { findInJsonl, readJsonFile, readJsonl, readJsonlFirst, } from "../internal/jsonl.js";
12
+ import { CLAUDE_PROJECTS, claudeProjectDirFromCwd } from "../internal/paths.js";
13
+ import { parseTaskPyCommandsAll } from "../phase.js";
14
+ import { searchInDialogue } from "../search.js";
15
+ // ---------- list ----------
16
+ export function claudeListSessions(f) {
17
+ if (!fs.existsSync(CLAUDE_PROJECTS))
18
+ return [];
19
+ const out = [];
20
+ const allDirs = () => fs.readdirSync(CLAUDE_PROJECTS).map((d) => path.join(CLAUDE_PROJECTS, d));
21
+ // --cwd fast path: derive the single project dir from the cwd. If the
22
+ // derived name does not exist on disk (e.g. Claude changed its sanitization
23
+ // scheme), fall back to scanning every project dir — the per-session
24
+ // `sameProject(cwd, f.cwd)` check below still scopes the results, so we never
25
+ // silently return 0.
26
+ const projectDirs = f.cwd
27
+ ? (() => {
28
+ const derived = claudeProjectDirFromCwd(f.cwd);
29
+ return fs.existsSync(derived) ? [derived] : allDirs();
30
+ })()
31
+ : allDirs();
32
+ for (const dir of projectDirs) {
33
+ let entries;
34
+ try {
35
+ entries = fs.readdirSync(dir, { withFileTypes: true });
36
+ }
37
+ catch {
38
+ continue;
39
+ }
40
+ const indexFile = path.join(dir, "sessions-index.json");
41
+ const index = readJsonFile(indexFile);
42
+ const indexById = new Map();
43
+ for (const e of Array.isArray(index?.entries) ? index.entries : []) {
44
+ if (typeof e.id === "string")
45
+ indexById.set(e.id, e);
46
+ }
47
+ for (const e of entries) {
48
+ if (!e.isFile() || !e.name.endsWith(".jsonl"))
49
+ continue;
50
+ const filePath = path.join(dir, e.name);
51
+ const id = e.name.replace(/\.jsonl$/, "");
52
+ const idx = indexById.get(id);
53
+ let cwd = idx?.cwd;
54
+ let created = idx?.created;
55
+ const title = idx?.title;
56
+ if (!cwd || !created) {
57
+ const evt = findInJsonl(filePath, (o) => typeof o.cwd === "string", 100);
58
+ cwd = cwd ?? evt?.cwd;
59
+ created =
60
+ created ??
61
+ evt?.timestamp ??
62
+ readJsonlFirst(filePath)?.timestamp;
63
+ }
64
+ const stat = fs.statSync(filePath);
65
+ const updated = stat.mtime.toISOString();
66
+ // Interval overlap: cross-day sessions that started before --since but
67
+ // were still active inside the window must survive.
68
+ if (!inRangeOverlap(created, updated, f))
69
+ continue;
70
+ if (f.cwd && cwd && !sameProject(cwd, f.cwd))
71
+ continue;
72
+ out.push({
73
+ platform: "claude",
74
+ id,
75
+ title,
76
+ cwd,
77
+ created,
78
+ updated,
79
+ filePath,
80
+ });
81
+ }
82
+ }
83
+ return out;
84
+ }
85
+ // ---------- extract ----------
86
+ /** Pull the text out of a Claude message body, whichever shape it takes. */
87
+ function claudeText(content) {
88
+ if (typeof content === "string")
89
+ return stripInjectionTags(content);
90
+ if (!Array.isArray(content))
91
+ return "";
92
+ const parts = [];
93
+ for (const block of content) {
94
+ if (block.type === "text" && typeof block.text === "string") {
95
+ const cleaned = stripInjectionTags(block.text);
96
+ if (cleaned)
97
+ parts.push(cleaned);
98
+ }
99
+ }
100
+ return parts.join("\n\n");
101
+ }
102
+ export function claudeExtractDialogue(s) {
103
+ // - user: type=="user" + role=="user" + content is a string
104
+ // - assistant: type=="assistant" + role=="assistant", keep only `text` blocks
105
+ // - thinking / tool_use blocks dropped entirely; injection tags stripped
106
+ // - compaction: an `isCompactSummary` user event marks the boundary. Claude
107
+ // keeps writing to the same file, so every pre-compaction turn is still
108
+ // here; the summary becomes marker content instead of replacing them.
109
+ const turns = [];
110
+ readJsonl(s.filePath, (obj) => {
111
+ const t = obj.type;
112
+ const msg = obj.message;
113
+ if (!msg)
114
+ return;
115
+ const content = msg.content;
116
+ if (t === "user" && obj.isCompactSummary === true) {
117
+ turns.push(compactionBoundaryTurn("context compacted here; the turns above are the conversation Claude summarized", claudeText(content)));
118
+ return;
119
+ }
120
+ if (t === "user" && msg.role === "user") {
121
+ if (typeof content === "string") {
122
+ const text = stripInjectionTags(content);
123
+ if (text && !isBootstrapTurn(text, content.length)) {
124
+ turns.push({ role: "user", text });
125
+ }
126
+ }
127
+ }
128
+ else if (t === "assistant" &&
129
+ msg.role === "assistant" &&
130
+ Array.isArray(content)) {
131
+ const text = claudeText(content);
132
+ if (text)
133
+ turns.push({ role: "assistant", text });
134
+ }
135
+ });
136
+ return turns;
137
+ }
138
+ export function claudeSearch(s, kw) {
139
+ return searchInDialogue(claudeExtractDialogue(s), kw);
140
+ }
141
+ /**
142
+ * Single-pass scan of a Claude JSONL file that produces both the cleaned
143
+ * dialogue turns (semantically identical to {@link claudeExtractDialogue}) and
144
+ * the list of `task.py create|start` Bash tool_use events with their
145
+ * `turnIndex`. Compaction keeps both `turns` and `events` — the turns those
146
+ * indices point at are still in the pool.
147
+ */
148
+ export function collectClaudeTurnsAndEvents(s) {
149
+ const turns = [];
150
+ const events = [];
151
+ readJsonl(s.filePath, (obj) => {
152
+ const t = obj.type;
153
+ const msg = obj.message;
154
+ if (!msg)
155
+ return;
156
+ const content = msg.content;
157
+ if (t === "user" && obj.isCompactSummary === true) {
158
+ turns.push(compactionBoundaryTurn("context compacted here; the turns above are the conversation Claude summarized", claudeText(content)));
159
+ return;
160
+ }
161
+ if (t === "user" && msg.role === "user") {
162
+ if (typeof content === "string") {
163
+ const text = stripInjectionTags(content);
164
+ if (text && !isBootstrapTurn(text, content.length)) {
165
+ turns.push({ role: "user", text });
166
+ }
167
+ }
168
+ return;
169
+ }
170
+ if (t === "assistant" &&
171
+ msg.role === "assistant" &&
172
+ Array.isArray(content)) {
173
+ const parts = [];
174
+ for (const block of content) {
175
+ if (block.type === "text" && typeof block.text === "string") {
176
+ const cleaned = stripInjectionTags(block.text);
177
+ if (cleaned)
178
+ parts.push(cleaned);
179
+ }
180
+ else if (block.type === "tool_use") {
181
+ if (block.name !== "Bash")
182
+ continue;
183
+ const inp = block.input;
184
+ if (!inp || typeof inp !== "object")
185
+ continue;
186
+ const command = inp.command;
187
+ if (typeof command !== "string")
188
+ continue;
189
+ const parsedAll = parseTaskPyCommandsAll(command);
190
+ for (const parsed of parsedAll) {
191
+ const ev = {
192
+ action: parsed.action,
193
+ timestamp: obj.timestamp ?? "",
194
+ turnIndex: turns.length,
195
+ ...(parsed.action === "create"
196
+ ? { slug: parsed.slug }
197
+ : { taskDir: parsed.taskDir }),
198
+ };
199
+ events.push(ev);
200
+ }
201
+ }
202
+ }
203
+ if (parts.length)
204
+ turns.push({ role: "assistant", text: parts.join("\n\n") });
205
+ }
206
+ });
207
+ return { turns, events };
208
+ }
209
+ //# sourceMappingURL=claude.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"claude.js","sourceRoot":"","sources":["../../../src/mem/adapters/claude.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,MAAM,SAAS,CAAC;AAC9B,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAElC,OAAO,EACL,sBAAsB,EACtB,kBAAkB,EAClB,eAAe,GAChB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAC3D,OAAO,EACL,WAAW,EACX,YAAY,EACZ,SAAS,EACT,cAAc,GACf,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAAE,eAAe,EAAE,uBAAuB,EAAE,MAAM,sBAAsB,CAAC;AAChF,OAAO,EAAE,sBAAsB,EAAE,MAAM,aAAa,CAAC;AACrD,OAAO,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AA0ChD,6BAA6B;AAE7B,MAAM,UAAU,kBAAkB,CAAC,CAAY;IAC7C,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,eAAe,CAAC;QAAE,OAAO,EAAE,CAAC;IAC/C,MAAM,GAAG,GAAqB,EAAE,CAAC;IACjC,MAAM,OAAO,GAAG,GAAa,EAAE,CAC7B,EAAE,CAAC,WAAW,CAAC,eAAe,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,eAAe,EAAE,CAAC,CAAC,CAAC,CAAC;IAC5E,sEAAsE;IACtE,4EAA4E;IAC5E,qEAAqE;IACrE,8EAA8E;IAC9E,qBAAqB;IACrB,MAAM,WAAW,GAAa,CAAC,CAAC,GAAG;QACjC,CAAC,CAAC,CAAC,GAAG,EAAE;YACJ,MAAM,OAAO,GAAG,uBAAuB,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;YAC/C,OAAO,EAAE,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC;QACxD,CAAC,CAAC,EAAE;QACN,CAAC,CAAC,OAAO,EAAE,CAAC;IAEd,KAAK,MAAM,GAAG,IAAI,WAAW,EAAE,CAAC;QAC9B,IAAI,OAAoB,CAAC;QACzB,IAAI,CAAC;YACH,OAAO,GAAG,EAAE,CAAC,WAAW,CAAC,GAAG,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAC;QACzD,CAAC;QAAC,MAAM,CAAC;YACP,SAAS;QACX,CAAC;QAED,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,qBAAqB,CAAC,CAAC;QACxD,MAAM,KAAK,GAAG,YAAY,CAAc,SAAS,CAAC,CAAC;QACnD,MAAM,SAAS,GAAG,IAAI,GAAG,EAA4B,CAAC;QACtD,KAAK,MAAM,CAAC,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;YACnE,IAAI,OAAO,CAAC,CAAC,EAAE,KAAK,QAAQ;gBAAE,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC;QACvD,CAAC;QAED,KAAK,MAAM,CAAC,IAAI,OAAO,EAAE,CAAC;YACxB,IAAI,CAAC,CAAC,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC;gBAAE,SAAS;YACxD,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC;YACxC,MAAM,EAAE,GAAG,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC;YAC1C,MAAM,GAAG,GAAG,SAAS,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;YAC9B,IAAI,GAAG,GAAuB,GAAG,EAAE,GAAG,CAAC;YACvC,IAAI,OAAO,GAAuB,GAAG,EAAE,OAAO,CAAC;YAC/C,MAAM,KAAK,GAAuB,GAAG,EAAE,KAAK,CAAC;YAE7C,IAAI,CAAC,GAAG,IAAI,CAAC,OAAO,EAAE,CAAC;gBACrB,MAAM,GAAG,GAAG,WAAW,CACrB,QAAQ,EACR,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,CAAC,GAAG,KAAK,QAAQ,EAChC,GAAG,CACJ,CAAC;gBACF,GAAG,GAAG,GAAG,IAAI,GAAG,EAAE,GAAG,CAAC;gBACtB,OAAO;oBACL,OAAO;wBACP,GAAG,EAAE,SAAS;wBACd,cAAc,CAAc,QAAQ,CAAC,EAAE,SAAS,CAAC;YACrD,CAAC;YAED,MAAM,IAAI,GAAG,EAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;YACnC,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,WAAW,EAAE,CAAC;YACzC,uEAAuE;YACvE,oDAAoD;YACpD,IAAI,CAAC,cAAc,CAAC,OAAO,EAAE,OAAO,EAAE,CAAC,CAAC;gBAAE,SAAS;YACnD,IAAI,CAAC,CAAC,GAAG,IAAI,GAAG,IAAI,CAAC,WAAW,CAAC,GAAG,EAAE,CAAC,CAAC,GAAG,CAAC;gBAAE,SAAS;YAEvD,GAAG,CAAC,IAAI,CAAC;gBACP,QAAQ,EAAE,QAAQ;gBAClB,EAAE;gBACF,KAAK;gBACL,GAAG;gBACH,OAAO;gBACP,OAAO;gBACP,QAAQ;aACT,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED,gCAAgC;AAEhC,4EAA4E;AAC5E,SAAS,UAAU,CAAC,OAA2C;IAC7D,IAAI,OAAO,OAAO,KAAK,QAAQ;QAAE,OAAO,kBAAkB,CAAC,OAAO,CAAC,CAAC;IACpE,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC;QAAE,OAAO,EAAE,CAAC;IACvC,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;QAC5B,IAAI,KAAK,CAAC,IAAI,KAAK,MAAM,IAAI,OAAO,KAAK,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;YAC5D,MAAM,OAAO,GAAG,kBAAkB,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;YAC/C,IAAI,OAAO;gBAAE,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QACnC,CAAC;IACH,CAAC;IACD,OAAO,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;AAC5B,CAAC;AAED,MAAM,UAAU,qBAAqB,CAAC,CAAiB;IACrD,4DAA4D;IAC5D,8EAA8E;IAC9E,yEAAyE;IACzE,4EAA4E;IAC5E,0EAA0E;IAC1E,wEAAwE;IACxE,MAAM,KAAK,GAAmB,EAAE,CAAC;IACjC,SAAS,CAAc,CAAC,CAAC,QAAQ,EAAE,CAAC,GAAG,EAAE,EAAE;QACzC,MAAM,CAAC,GAAG,GAAG,CAAC,IAAI,CAAC;QACnB,MAAM,GAAG,GAAG,GAAG,CAAC,OAAO,CAAC;QACxB,IAAI,CAAC,GAAG;YAAE,OAAO;QACjB,MAAM,OAAO,GAAG,GAAG,CAAC,OAAO,CAAC;QAC5B,IAAI,CAAC,KAAK,MAAM,IAAI,GAAG,CAAC,gBAAgB,KAAK,IAAI,EAAE,CAAC;YAClD,KAAK,CAAC,IAAI,CACR,sBAAsB,CACpB,gFAAgF,EAChF,UAAU,CAAC,OAAO,CAAC,CACpB,CACF,CAAC;YACF,OAAO;QACT,CAAC;QACD,IAAI,CAAC,KAAK,MAAM,IAAI,GAAG,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;YACxC,IAAI,OAAO,OAAO,KAAK,QAAQ,EAAE,CAAC;gBAChC,MAAM,IAAI,GAAG,kBAAkB,CAAC,OAAO,CAAC,CAAC;gBACzC,IAAI,IAAI,IAAI,CAAC,eAAe,CAAC,IAAI,EAAE,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;oBACnD,KAAK,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;gBACrC,CAAC;YACH,CAAC;QACH,CAAC;aAAM,IACL,CAAC,KAAK,WAAW;YACjB,GAAG,CAAC,IAAI,KAAK,WAAW;YACxB,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,EACtB,CAAC;YACD,MAAM,IAAI,GAAG,UAAU,CAAC,OAAO,CAAC,CAAC;YACjC,IAAI,IAAI;gBAAE,KAAK,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,WAAW,EAAE,IAAI,EAAE,CAAC,CAAC;QACpD,CAAC;IACH,CAAC,CAAC,CAAC;IACH,OAAO,KAAK,CAAC;AACf,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,CAAiB,EAAE,EAAU;IACxD,OAAO,gBAAgB,CAAC,qBAAqB,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;AACxD,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,2BAA2B,CAAC,CAAiB;IAI3D,MAAM,KAAK,GAAmB,EAAE,CAAC;IACjC,MAAM,MAAM,GAAkB,EAAE,CAAC;IAEjC,SAAS,CAAc,CAAC,CAAC,QAAQ,EAAE,CAAC,GAAG,EAAE,EAAE;QACzC,MAAM,CAAC,GAAG,GAAG,CAAC,IAAI,CAAC;QACnB,MAAM,GAAG,GAAG,GAAG,CAAC,OAAO,CAAC;QACxB,IAAI,CAAC,GAAG;YAAE,OAAO;QACjB,MAAM,OAAO,GAAG,GAAG,CAAC,OAAO,CAAC;QAE5B,IAAI,CAAC,KAAK,MAAM,IAAI,GAAG,CAAC,gBAAgB,KAAK,IAAI,EAAE,CAAC;YAClD,KAAK,CAAC,IAAI,CACR,sBAAsB,CACpB,gFAAgF,EAChF,UAAU,CAAC,OAAO,CAAC,CACpB,CACF,CAAC;YACF,OAAO;QACT,CAAC;QAED,IAAI,CAAC,KAAK,MAAM,IAAI,GAAG,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;YACxC,IAAI,OAAO,OAAO,KAAK,QAAQ,EAAE,CAAC;gBAChC,MAAM,IAAI,GAAG,kBAAkB,CAAC,OAAO,CAAC,CAAC;gBACzC,IAAI,IAAI,IAAI,CAAC,eAAe,CAAC,IAAI,EAAE,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;oBACnD,KAAK,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;gBACrC,CAAC;YACH,CAAC;YACD,OAAO;QACT,CAAC;QAED,IACE,CAAC,KAAK,WAAW;YACjB,GAAG,CAAC,IAAI,KAAK,WAAW;YACxB,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,EACtB,CAAC;YACD,MAAM,KAAK,GAAa,EAAE,CAAC;YAC3B,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;gBAC5B,IAAI,KAAK,CAAC,IAAI,KAAK,MAAM,IAAI,OAAO,KAAK,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;oBAC5D,MAAM,OAAO,GAAG,kBAAkB,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;oBAC/C,IAAI,OAAO;wBAAE,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;gBACnC,CAAC;qBAAM,IAAI,KAAK,CAAC,IAAI,KAAK,UAAU,EAAE,CAAC;oBACrC,IAAI,KAAK,CAAC,IAAI,KAAK,MAAM;wBAAE,SAAS;oBACpC,MAAM,GAAG,GAAG,KAAK,CAAC,KAAK,CAAC;oBACxB,IAAI,CAAC,GAAG,IAAI,OAAO,GAAG,KAAK,QAAQ;wBAAE,SAAS;oBAC9C,MAAM,OAAO,GAAI,GAA6B,CAAC,OAAO,CAAC;oBACvD,IAAI,OAAO,OAAO,KAAK,QAAQ;wBAAE,SAAS;oBAC1C,MAAM,SAAS,GAAG,sBAAsB,CAAC,OAAO,CAAC,CAAC;oBAClD,KAAK,MAAM,MAAM,IAAI,SAAS,EAAE,CAAC;wBAC/B,MAAM,EAAE,GAAgB;4BACtB,MAAM,EAAE,MAAM,CAAC,MAAM;4BACrB,SAAS,EAAE,GAAG,CAAC,SAAS,IAAI,EAAE;4BAC9B,SAAS,EAAE,KAAK,CAAC,MAAM;4BACvB,GAAG,CAAC,MAAM,CAAC,MAAM,KAAK,QAAQ;gCAC5B,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,EAAE;gCACvB,CAAC,CAAC,EAAE,OAAO,EAAE,MAAM,CAAC,OAAO,EAAE,CAAC;yBACjC,CAAC;wBACF,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;oBAClB,CAAC;gBACH,CAAC;YACH,CAAC;YACD,IAAI,KAAK,CAAC,MAAM;gBACd,KAAK,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,WAAW,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;QAChE,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC;AAC3B,CAAC"}
@@ -0,0 +1,55 @@
1
+ /**
2
+ * Persisted Codex session reader.
3
+ *
4
+ * Layout: `~/.codex/sessions/**\/rollout-<ts>-<id>.jsonl`. Metadata is read
5
+ * from the first event's `payload`; the filename timestamp is a fallback
6
+ * `created`.
7
+ *
8
+ * Compaction: a top-level `compacted` event marks where Codex cut its own
9
+ * context. Its `payload.replacement_history` is NOT a summary — measured over
10
+ * 1865 local rollouts it is a verbatim retained slice of the conversation
11
+ * (268k `message/user` items, 3 `message/assistant`). In a resumed session it
12
+ * is the only place the earlier conversation exists at all. So the boundary is
13
+ * marked, the already-collected turns are kept, and `replacement_history` is
14
+ * merged in with occurrence-counted dedupe — turns already in the pool are not
15
+ * re-added, turns only Codex retained are recovered.
16
+ *
17
+ * Multi-agent: `response_item` / `agent_message` events carry
18
+ * `Message Type: NEW_TASK | MESSAGE | FINAL_ANSWER` envelopes. Only
19
+ * `FINAL_ANSWER` has a plaintext payload; `NEW_TASK` / `MESSAGE` payloads are
20
+ * `encrypted_content` and cannot be read back, which is reported rather than
21
+ * papered over. `event_msg` / `agent_message` is a byte-identical duplicate of
22
+ * the following `response_item` / `message` / `assistant` and stays excluded.
23
+ */
24
+ import type { DialogueTurn, MemFilter, MemSessionInfo, MemWarning, SearchHit, TaskPyEvent } from "../types.js";
25
+ /**
26
+ * Recover the shell command string from a Codex `function_call` event's
27
+ * `arguments` field. Codex versions vary in how they encode it:
28
+ *
29
+ * - a raw shell string
30
+ * - a stringified JSON object with `cmd` / `command` (string) or
31
+ * `argv` (string[] — joined with spaces)
32
+ * - a raw object with the same `cmd` / `command` / `argv` shape
33
+ *
34
+ * Returns `undefined` when no command can be recovered.
35
+ */
36
+ export declare function commandFromCodexArguments(argsRaw: unknown): string | undefined;
37
+ export declare function codexListSessions(f: MemFilter): MemSessionInfo[];
38
+ export declare function codexExtractDialogue(s: MemSessionInfo, warnings?: MemWarning[]): DialogueTurn[];
39
+ export declare function codexSearch(s: MemSessionInfo, kw: string): SearchHit;
40
+ /**
41
+ * Codex twin of `collectClaudeTurnsAndEvents`. Single pass over the rollout
42
+ * file; emits both the cleaned dialogue turns and the list of
43
+ * `task.py create|start` invocations found inside `function_call` events whose
44
+ * `name === "exec_command"` (or `"shell"`).
45
+ *
46
+ * Compaction keeps everything: collected turns stay, retained history is merged
47
+ * ahead of them, and a boundary marker records the cut. Event `turnIndex`es
48
+ * recorded before a compaction are shifted by the number of recovered turns so
49
+ * brainstorm windows keep pointing at the same conversation.
50
+ */
51
+ export declare function collectCodexTurnsAndEvents(s: MemSessionInfo, warnings?: MemWarning[]): {
52
+ turns: DialogueTurn[];
53
+ events: TaskPyEvent[];
54
+ };
55
+ //# sourceMappingURL=codex.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"codex.d.ts","sourceRoot":"","sources":["../../../src/mem/adapters/codex.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAgBH,OAAO,KAAK,EAEV,YAAY,EACZ,SAAS,EACT,cAAc,EACd,UAAU,EACV,SAAS,EACT,WAAW,EACZ,MAAM,aAAa,CAAC;AAoCrB;;;;;;;;;;GAUG;AACH,wBAAgB,yBAAyB,CAAC,OAAO,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,CAgC9E;AAID,wBAAgB,iBAAiB,CAAC,CAAC,EAAE,SAAS,GAAG,cAAc,EAAE,CAmChE;AAyJD,wBAAgB,oBAAoB,CAClC,CAAC,EAAE,cAAc,EACjB,QAAQ,CAAC,EAAE,UAAU,EAAE,GACtB,YAAY,EAAE,CAEhB;AAED,wBAAgB,WAAW,CAAC,CAAC,EAAE,cAAc,EAAE,EAAE,EAAE,MAAM,GAAG,SAAS,CAIpE;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,0BAA0B,CACxC,CAAC,EAAE,cAAc,EACjB,QAAQ,CAAC,EAAE,UAAU,EAAE,GACtB;IACD,KAAK,EAAE,YAAY,EAAE,CAAC;IACtB,MAAM,EAAE,WAAW,EAAE,CAAC;CACvB,CAiFA"}