sidekick-shared 0.29.0 → 0.30.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 (142) hide show
  1. package/CHANGELOG.md +48 -0
  2. package/README.md +198 -56
  3. package/dist/aggregation/EventAggregator.d.ts +96 -2
  4. package/dist/aggregation/EventAggregator.js +535 -42
  5. package/dist/aggregation/snapshot.d.ts +37 -8
  6. package/dist/aggregation/snapshot.js +31 -9
  7. package/dist/aggregation/types.d.ts +38 -1
  8. package/dist/browser.d.ts +9 -1
  9. package/dist/browser.js +29 -3
  10. package/dist/context/sessionContext.js +8 -0
  11. package/dist/esm/aggregation/EventAggregator.js +535 -42
  12. package/dist/esm/aggregation/snapshot.js +31 -9
  13. package/dist/esm/browser.js +3 -0
  14. package/dist/esm/context/sessionContext.js +8 -0
  15. package/dist/esm/fileContinuity.js +149 -0
  16. package/dist/esm/formatters/toolSummary.js +4 -1
  17. package/dist/esm/index.js +7 -2
  18. package/dist/esm/modelCatalog.js +5 -4
  19. package/dist/esm/modelContext.js +4 -3
  20. package/dist/esm/modelInfo.js +4 -3
  21. package/dist/esm/node.js +3 -1
  22. package/dist/esm/observedContextWindows.js +2 -1
  23. package/dist/esm/ownKey.js +26 -0
  24. package/dist/esm/parsers/codexParser.js +372 -7
  25. package/dist/esm/parsers/openCodeParser.js +2 -1
  26. package/dist/esm/parsers/subagentEndState.js +61 -0
  27. package/dist/esm/parsers/subagentScanner.js +37 -12
  28. package/dist/esm/parsers/subagentTraceParser.js +103 -37
  29. package/dist/esm/pricingCatalog.js +3 -2
  30. package/dist/esm/promptHistory.js +22 -11
  31. package/dist/esm/providers/claudeCode.js +60 -29
  32. package/dist/esm/providers/codex.js +235 -201
  33. package/dist/esm/providers/codexCompressedReader.js +184 -0
  34. package/dist/esm/providers/codexDatabase.js +47 -2
  35. package/dist/esm/providers/codexRollouts.js +20 -2
  36. package/dist/esm/providers/codexSubagents.js +456 -0
  37. package/dist/esm/providers/compressedRollouts.js +330 -0
  38. package/dist/esm/providers/factory.js +4 -1
  39. package/dist/esm/providers/rolloutWalker.js +32 -4
  40. package/dist/esm/schemas/sessionEvent.js +63 -14
  41. package/dist/esm/sessionMonitor.js +7 -1
  42. package/dist/esm/sessionPreviews.js +9 -0
  43. package/dist/esm/sessionPromptHistory.js +5 -3
  44. package/dist/esm/subagentActivity.js +125 -0
  45. package/dist/esm/subagentDisplayState.js +81 -0
  46. package/dist/esm/subagentSpawn.js +363 -0
  47. package/dist/esm/testing/codexSubagentFixtures.js +336 -0
  48. package/dist/esm/toolCallOrigins.js +17 -10
  49. package/dist/esm/toolCategory.js +6 -2
  50. package/dist/esm/transcript.js +8 -0
  51. package/dist/esm/turns/assistantTurn.js +6 -2
  52. package/dist/esm/usage/claudeUsageDedupe.js +68 -0
  53. package/dist/esm/usage/usageEvents.js +4 -1
  54. package/dist/esm/watchers/eventBridge.js +45 -0
  55. package/dist/esm/watchers/factory.js +5 -3
  56. package/dist/esm/watchers/jsonlTail.js +82 -48
  57. package/dist/esm/watchers/jsonlWatcher.js +61 -4
  58. package/dist/esm/watchers/providerReaderWatcher.js +18 -4
  59. package/dist/esm/zaiQuota.js +2 -1
  60. package/dist/fileContinuity.d.ts +95 -0
  61. package/dist/fileContinuity.js +187 -0
  62. package/dist/formatters/toolSummary.js +4 -1
  63. package/dist/index.d.ts +19 -7
  64. package/dist/index.js +48 -10
  65. package/dist/modelCatalog.js +5 -4
  66. package/dist/modelContext.js +4 -3
  67. package/dist/modelInfo.js +4 -3
  68. package/dist/node.d.ts +5 -1
  69. package/dist/node.js +18 -2
  70. package/dist/observedContextWindows.js +2 -1
  71. package/dist/ownKey.d.ts +16 -0
  72. package/dist/ownKey.js +30 -0
  73. package/dist/parsers/codexParser.d.ts +107 -0
  74. package/dist/parsers/codexParser.js +373 -7
  75. package/dist/parsers/openCodeParser.js +2 -1
  76. package/dist/parsers/subagentEndState.d.ts +20 -0
  77. package/dist/parsers/subagentEndState.js +65 -0
  78. package/dist/parsers/subagentScanner.d.ts +19 -6
  79. package/dist/parsers/subagentScanner.js +37 -12
  80. package/dist/parsers/subagentTraceParser.d.ts +33 -5
  81. package/dist/parsers/subagentTraceParser.js +103 -37
  82. package/dist/pricingCatalog.js +3 -2
  83. package/dist/promptHistory.d.ts +13 -3
  84. package/dist/promptHistory.js +22 -11
  85. package/dist/providers/claudeCode.js +59 -28
  86. package/dist/providers/codex.d.ts +35 -5
  87. package/dist/providers/codex.js +232 -198
  88. package/dist/providers/codexCompressedReader.d.ts +58 -0
  89. package/dist/providers/codexCompressedReader.js +221 -0
  90. package/dist/providers/codexDatabase.d.ts +25 -0
  91. package/dist/providers/codexDatabase.js +48 -2
  92. package/dist/providers/codexRollouts.d.ts +16 -2
  93. package/dist/providers/codexRollouts.js +20 -2
  94. package/dist/providers/codexSubagents.d.ts +66 -0
  95. package/dist/providers/codexSubagents.js +495 -0
  96. package/dist/providers/compressedRollouts.d.ts +114 -0
  97. package/dist/providers/compressedRollouts.js +380 -0
  98. package/dist/providers/factory.d.ts +5 -0
  99. package/dist/providers/factory.js +4 -1
  100. package/dist/providers/rolloutWalker.d.ts +15 -2
  101. package/dist/providers/rolloutWalker.js +33 -4
  102. package/dist/providers/types.d.ts +36 -1
  103. package/dist/schemas/index.d.ts +1 -0
  104. package/dist/schemas/sessionEvent.d.ts +51 -10
  105. package/dist/schemas/sessionEvent.js +63 -14
  106. package/dist/sessionMonitor.d.ts +6 -0
  107. package/dist/sessionMonitor.js +7 -1
  108. package/dist/sessionPreviews.js +9 -0
  109. package/dist/sessionPromptHistory.d.ts +5 -0
  110. package/dist/sessionPromptHistory.js +5 -36
  111. package/dist/subagentActivity.d.ts +91 -0
  112. package/dist/subagentActivity.js +132 -0
  113. package/dist/subagentDisplayState.d.ts +81 -0
  114. package/dist/subagentDisplayState.js +86 -0
  115. package/dist/subagentSpawn.d.ts +175 -0
  116. package/dist/subagentSpawn.js +385 -0
  117. package/dist/testing/codexSubagentFixtures.d.ts +48 -0
  118. package/dist/testing/codexSubagentFixtures.js +344 -0
  119. package/dist/toolCallOrigins.d.ts +5 -0
  120. package/dist/toolCallOrigins.js +17 -10
  121. package/dist/toolCategory.js +6 -2
  122. package/dist/transcript.js +8 -0
  123. package/dist/turns/assistantTurn.d.ts +4 -0
  124. package/dist/turns/assistantTurn.js +6 -2
  125. package/dist/types/codex.d.ts +71 -2
  126. package/dist/types/sessionEvent.d.ts +38 -3
  127. package/dist/usage/claudeUsageDedupe.d.ts +31 -0
  128. package/dist/usage/claudeUsageDedupe.js +68 -0
  129. package/dist/usage/usageEvents.d.ts +4 -1
  130. package/dist/usage/usageEvents.js +4 -1
  131. package/dist/watchers/eventBridge.js +45 -0
  132. package/dist/watchers/factory.d.ts +6 -0
  133. package/dist/watchers/factory.js +5 -3
  134. package/dist/watchers/jsonlTail.d.ts +27 -4
  135. package/dist/watchers/jsonlTail.js +84 -48
  136. package/dist/watchers/jsonlWatcher.d.ts +22 -1
  137. package/dist/watchers/jsonlWatcher.js +60 -3
  138. package/dist/watchers/providerReaderWatcher.d.ts +7 -0
  139. package/dist/watchers/providerReaderWatcher.js +18 -4
  140. package/dist/watchers/types.d.ts +12 -0
  141. package/dist/zaiQuota.js +2 -1
  142. package/package.json +1 -1
@@ -0,0 +1,344 @@
1
+ "use strict";
2
+ /**
3
+ * Redacted rollouts in the shape Codex 0.166 writes for multi-agent sessions:
4
+ * a parent that spawns a child (`spawn_agent` → `SubAgentActivity` started →
5
+ * `{"task_name": …}` output → MESSAGE / FINAL_ANSWER agent messages →
6
+ * `completed`), a failed spawn, `followup_task` / `send_message` /
7
+ * `interrupt_agent` interactions, and a forked child whose rollout embeds the
8
+ * parent's history (and session_meta) before its
9
+ * `subagent_history_start_ordinal`, which itself spawns a grandchild.
10
+ * Payload text is placeholder; ids are synthetic.
11
+ *
12
+ * Test-only helpers.
13
+ *
14
+ * @module testing/codexSubagentFixtures
15
+ */
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ exports.GRANDCHILD_PATH = exports.CHILD_PATH = exports.CHILD_TURN_ID = exports.CALL_SPAWN_GRANDCHILD = exports.CALL_INTERRUPT = exports.CALL_SEND = exports.CALL_FOLLOWUP = exports.CALL_SPAWN_FAILED = exports.CALL_SPAWN = exports.GRANDCHILD_ID = exports.CHILD_ID = exports.PARENT_ID = void 0;
18
+ exports.at = at;
19
+ exports.parentRollout = parentRollout;
20
+ exports.childRollout = childRollout;
21
+ exports.grandchildRollout = grandchildRollout;
22
+ exports.toJsonl = toJsonl;
23
+ exports.PARENT_ID = '01a18f87-0000-7000-8000-000000000001';
24
+ exports.CHILD_ID = '01a18f9d-0000-7000-8000-000000000002';
25
+ exports.GRANDCHILD_ID = '01a18fa0-0000-7000-8000-000000000003';
26
+ exports.CALL_SPAWN = 'call_spawn_builder';
27
+ exports.CALL_SPAWN_FAILED = 'call_spawn_failed';
28
+ exports.CALL_FOLLOWUP = 'call_followup_builder';
29
+ exports.CALL_SEND = 'call_send_builder';
30
+ exports.CALL_INTERRUPT = 'call_interrupt_builder';
31
+ exports.CALL_SPAWN_GRANDCHILD = 'call_spawn_deep_dive';
32
+ exports.CHILD_TURN_ID = '01a18f9d-0000-7000-8000-0000000000t1';
33
+ exports.CHILD_PATH = '/root/review_builder';
34
+ exports.GRANDCHILD_PATH = '/root/review_builder/deep_dive';
35
+ /** `2026-10-31T01:<minute>:<second>.000Z`. */
36
+ function at(minute, second = 0) {
37
+ return `2026-10-31T01:${String(minute).padStart(2, '0')}:${String(second).padStart(2, '0')}.000Z`;
38
+ }
39
+ function numbered(rows) {
40
+ return rows.map((row, ordinal) => ({ timestamp: row.timestamp, ordinal, ...row }));
41
+ }
42
+ function tokenCount(timestamp, total, last) {
43
+ return {
44
+ timestamp,
45
+ type: 'event_msg',
46
+ payload: {
47
+ type: 'token_count',
48
+ info: {
49
+ total_token_usage: { input_tokens: total, output_tokens: 0, total_tokens: total },
50
+ last_token_usage: { input_tokens: last, output_tokens: 0, total_tokens: last },
51
+ },
52
+ },
53
+ };
54
+ }
55
+ function functionCall(timestamp, callId, name, args, namespace = 'collaboration') {
56
+ return {
57
+ timestamp,
58
+ type: 'response_item',
59
+ payload: {
60
+ type: 'function_call',
61
+ status: 'completed',
62
+ id: `fc_${callId}`,
63
+ name,
64
+ ...(namespace ? { namespace } : {}),
65
+ arguments: JSON.stringify(args),
66
+ call_id: callId,
67
+ },
68
+ };
69
+ }
70
+ function output(timestamp, callId, text) {
71
+ return {
72
+ timestamp,
73
+ type: 'response_item',
74
+ payload: { type: 'function_call_output', call_id: callId, output: text },
75
+ };
76
+ }
77
+ function activity(timestamp, threadId, item) {
78
+ return {
79
+ timestamp,
80
+ type: 'event_msg',
81
+ payload: {
82
+ type: 'item_completed',
83
+ thread_id: threadId,
84
+ turn_id: `${threadId}-turn`,
85
+ item: { type: 'SubAgentActivity', model: null, reasoning_effort: null, ...item },
86
+ },
87
+ };
88
+ }
89
+ function agentMessage(timestamp, id, author, recipient, messageType, payload) {
90
+ return {
91
+ timestamp,
92
+ type: 'response_item',
93
+ payload: {
94
+ type: 'agent_message',
95
+ id,
96
+ author,
97
+ recipient,
98
+ content: [
99
+ {
100
+ type: 'input_text',
101
+ text: `Message Type: ${messageType}\nTask name: ${recipient}\nSender: ${author}\nPayload:\n${payload}`,
102
+ },
103
+ ...(payload ? [] : [{ type: 'encrypted_content', encrypted_content: 'gAAAA-redacted' }]),
104
+ ],
105
+ },
106
+ };
107
+ }
108
+ function exec(timestamp, callId) {
109
+ return functionCall(timestamp, callId, 'exec_command', { cmd: 'rg TODO' }, undefined);
110
+ }
111
+ /** The parent session's rollout (ordinals 0…). */
112
+ function parentRollout(options) {
113
+ const rows = [
114
+ {
115
+ timestamp: at(15),
116
+ type: 'session_meta',
117
+ payload: {
118
+ id: exports.PARENT_ID,
119
+ session_id: exports.PARENT_ID,
120
+ timestamp: at(15),
121
+ cwd: options.cwd,
122
+ originator: 'codex-tui',
123
+ cli_version: '0.166.0',
124
+ source: 'vscode',
125
+ thread_source: 'user',
126
+ history_mode: 'paginated',
127
+ base_instructions: { text: 'Parent base instructions.' },
128
+ },
129
+ },
130
+ {
131
+ timestamp: at(15, 1),
132
+ type: 'turn_context',
133
+ payload: { model: 'gpt-test', cwd: options.cwd },
134
+ },
135
+ {
136
+ timestamp: at(15, 2),
137
+ type: 'response_item',
138
+ payload: {
139
+ type: 'message',
140
+ role: 'user',
141
+ content: [{ type: 'input_text', text: 'Review the builder.' }],
142
+ },
143
+ },
144
+ tokenCount(at(15, 3), 1000, 1000),
145
+ functionCall(at(40, 33), exports.CALL_SPAWN, 'spawn_agent', {
146
+ task_name: 'review_builder',
147
+ message: 'gAAAA-redacted',
148
+ }),
149
+ options.withoutActivity
150
+ ? null
151
+ : activity(at(40, 33), exports.PARENT_ID, {
152
+ id: exports.CALL_SPAWN,
153
+ kind: 'started',
154
+ model: 'gpt-test',
155
+ reasoning_effort: 'high',
156
+ agent_thread_id: exports.CHILD_ID,
157
+ agent_path: exports.CHILD_PATH,
158
+ }),
159
+ output(at(40, 34), exports.CALL_SPAWN, JSON.stringify({ task_name: exports.CHILD_PATH })),
160
+ functionCall(at(40, 35), exports.CALL_SPAWN_FAILED, 'spawn_agent', {
161
+ task_name: 'review_extra',
162
+ message: 'gAAAA-redacted',
163
+ }),
164
+ output(at(40, 35), exports.CALL_SPAWN_FAILED, 'collab spawn failed: agent thread limit reached'),
165
+ {
166
+ timestamp: at(41, 8),
167
+ type: 'inter_agent_communication_metadata',
168
+ payload: { trigger_turn: false },
169
+ },
170
+ agentMessage(at(41, 8), 'amsg_progress', exports.CHILD_PATH, '/root', 'MESSAGE', ''),
171
+ options.withoutActivity || options.withoutCompleted
172
+ ? null
173
+ : activity(at(42, 21), exports.PARENT_ID, {
174
+ id: `subagent-completed-${exports.CHILD_TURN_ID}`,
175
+ kind: 'completed',
176
+ agent_thread_id: exports.CHILD_ID,
177
+ agent_path: exports.CHILD_PATH,
178
+ }),
179
+ agentMessage(at(42, 25), 'amsg_final', exports.CHILD_PATH, '/root', 'FINAL_ANSWER', 'Found two issues.'),
180
+ functionCall(at(45, 37), exports.CALL_FOLLOWUP, 'followup_task', {
181
+ target: 'review_builder',
182
+ message: 'gAAAA-redacted',
183
+ }),
184
+ options.withoutActivity
185
+ ? null
186
+ : activity(at(45, 37), exports.PARENT_ID, {
187
+ id: exports.CALL_FOLLOWUP,
188
+ kind: 'interacted',
189
+ agent_thread_id: exports.CHILD_ID,
190
+ agent_path: exports.CHILD_PATH,
191
+ }),
192
+ output(at(45, 38), exports.CALL_FOLLOWUP, ''),
193
+ functionCall(at(45, 40), exports.CALL_SEND, 'send_message', {
194
+ target: 'review_builder',
195
+ message: 'gAAAA-redacted',
196
+ }),
197
+ options.withoutActivity
198
+ ? null
199
+ : activity(at(45, 40), exports.PARENT_ID, {
200
+ id: exports.CALL_SEND,
201
+ kind: 'interacted',
202
+ agent_thread_id: exports.CHILD_ID,
203
+ agent_path: exports.CHILD_PATH,
204
+ }),
205
+ functionCall(at(46, 0), exports.CALL_INTERRUPT, 'interrupt_agent', { target: 'review_builder' }),
206
+ options.withoutActivity
207
+ ? null
208
+ : activity(at(46, 0), exports.PARENT_ID, {
209
+ id: exports.CALL_INTERRUPT,
210
+ kind: 'interrupted',
211
+ agent_thread_id: exports.CHILD_ID,
212
+ agent_path: exports.CHILD_PATH,
213
+ }),
214
+ tokenCount(at(46, 5), 2000, 1000),
215
+ ];
216
+ return numbered(rows.filter((row) => row !== null));
217
+ }
218
+ /** Records the child inherits from the parent (re-stamped at fork time, as Codex does). */
219
+ const INHERITED_RECORDS = 5;
220
+ /** The forked child's rollout: its meta, the parent's history, then its own records. */
221
+ function childRollout(options) {
222
+ const start = 1 + INHERITED_RECORDS;
223
+ return numbered([
224
+ {
225
+ timestamp: at(40, 33),
226
+ type: 'session_meta',
227
+ payload: {
228
+ id: exports.CHILD_ID,
229
+ session_id: exports.PARENT_ID,
230
+ forked_from_id: exports.PARENT_ID,
231
+ parent_thread_id: exports.PARENT_ID,
232
+ timestamp: at(40, 33),
233
+ cwd: options.cwd,
234
+ originator: 'codex-tui',
235
+ cli_version: '0.166.0',
236
+ source: {
237
+ subagent: {
238
+ thread_spawn: {
239
+ parent_thread_id: exports.PARENT_ID,
240
+ depth: 1,
241
+ agent_path: exports.CHILD_PATH,
242
+ agent_nickname: 'Banach',
243
+ agent_role: null,
244
+ },
245
+ },
246
+ },
247
+ thread_source: 'subagent',
248
+ agent_nickname: 'Banach',
249
+ agent_path: exports.CHILD_PATH,
250
+ history_mode: 'paginated',
251
+ subagent_history_start_ordinal: start,
252
+ multi_agent_version: 'v2',
253
+ },
254
+ },
255
+ // The parent's history, embedded by the fork.
256
+ {
257
+ timestamp: at(40, 33),
258
+ type: 'session_meta',
259
+ payload: {
260
+ id: exports.PARENT_ID,
261
+ timestamp: at(15),
262
+ cwd: '/somewhere/else',
263
+ source: 'vscode',
264
+ base_instructions: { text: 'Parent base instructions.' },
265
+ },
266
+ },
267
+ { timestamp: at(40, 33), type: 'turn_context', payload: { model: 'gpt-parent' } },
268
+ exec(at(40, 33), 'call_parent_exec'),
269
+ tokenCount(at(40, 33), 5000, 5000),
270
+ {
271
+ timestamp: at(40, 33),
272
+ type: 'response_item',
273
+ payload: {
274
+ type: 'message',
275
+ role: 'developer',
276
+ content: [{ type: 'input_text', text: 'You are now a newly spawned child agent.' }],
277
+ },
278
+ },
279
+ // The child's own records.
280
+ {
281
+ timestamp: at(40, 34),
282
+ type: 'event_msg',
283
+ payload: { type: 'task_started', turn_id: exports.CHILD_TURN_ID },
284
+ },
285
+ { timestamp: at(40, 34), type: 'turn_context', payload: { model: 'gpt-test' } },
286
+ exec(at(40, 35), 'call_child_exec'),
287
+ output(at(40, 36), 'call_child_exec', 'Process exited with code 0'),
288
+ tokenCount(at(40, 37), 300, 300),
289
+ functionCall(at(40, 38), exports.CALL_SPAWN_GRANDCHILD, 'spawn_agent', {
290
+ task_name: 'deep_dive',
291
+ message: 'gAAAA-redacted',
292
+ }),
293
+ activity(at(40, 38), exports.CHILD_ID, {
294
+ id: exports.CALL_SPAWN_GRANDCHILD,
295
+ kind: 'started',
296
+ agent_thread_id: exports.GRANDCHILD_ID,
297
+ agent_path: exports.GRANDCHILD_PATH,
298
+ }),
299
+ output(at(40, 39), exports.CALL_SPAWN_GRANDCHILD, JSON.stringify({ task_name: exports.GRANDCHILD_PATH })),
300
+ tokenCount(at(42, 20), 500, 200),
301
+ ]);
302
+ }
303
+ /** The grandchild's rollout (depth 2): a fork of the child. */
304
+ function grandchildRollout(options) {
305
+ return numbered([
306
+ {
307
+ timestamp: at(40, 38),
308
+ type: 'session_meta',
309
+ payload: {
310
+ id: exports.GRANDCHILD_ID,
311
+ session_id: exports.PARENT_ID,
312
+ forked_from_id: exports.CHILD_ID,
313
+ parent_thread_id: exports.CHILD_ID,
314
+ timestamp: at(40, 38),
315
+ cwd: options.cwd,
316
+ cli_version: '0.166.0',
317
+ source: {
318
+ subagent: {
319
+ thread_spawn: {
320
+ parent_thread_id: exports.CHILD_ID,
321
+ depth: 2,
322
+ agent_path: exports.GRANDCHILD_PATH,
323
+ agent_nickname: 'Noether',
324
+ agent_role: 'explorer',
325
+ },
326
+ },
327
+ },
328
+ thread_source: 'subagent',
329
+ agent_nickname: 'Noether',
330
+ agent_path: exports.GRANDCHILD_PATH,
331
+ agent_role: 'explorer',
332
+ subagent_history_start_ordinal: 3,
333
+ },
334
+ },
335
+ { timestamp: at(40, 38), type: 'session_meta', payload: { id: exports.CHILD_ID, cwd: options.cwd } },
336
+ exec(at(40, 38), 'call_child_exec'),
337
+ exec(at(40, 40), 'call_grandchild_exec'),
338
+ tokenCount(at(40, 41), 50, 50),
339
+ ]);
340
+ }
341
+ /** Rows as JSONL text. */
342
+ function toJsonl(rows) {
343
+ return rows.map((row) => JSON.stringify(row)).join('\n') + '\n';
344
+ }
@@ -32,6 +32,11 @@ export interface FindToolCallOriginsOptions {
32
32
  providers?: PromptHistoryProvider[];
33
33
  /** Stops between files and lines; the promise rejects with the signal's reason. */
34
34
  signal?: AbortSignal;
35
+ /**
36
+ * Codex: also search compressed rollouts (`….jsonl.zst`), as for
37
+ * `collectPromptHistory()`. Default false.
38
+ */
39
+ includeCompressedRollouts?: boolean;
35
40
  }
36
41
  export interface ToolCallOrigin {
37
42
  provider: PromptHistoryProvider;
@@ -57,6 +57,8 @@ exports.findToolCallOrigins = findToolCallOrigins;
57
57
  const fs = __importStar(require("fs"));
58
58
  const path = __importStar(require("path"));
59
59
  const readline = __importStar(require("readline"));
60
+ const stream_1 = require("stream");
61
+ const compressedRollouts_1 = require("./providers/compressedRollouts");
60
62
  const promptHistory_1 = require("./promptHistory");
61
63
  const codexRolloutOrigin_1 = require("./parsers/codexRolloutOrigin");
62
64
  const workspaceRoots_1 = require("./workspaceRoots");
@@ -78,7 +80,9 @@ async function findToolCallOrigins(options) {
78
80
  return found;
79
81
  const providers = options.providers ?? ['claude-code', 'codex'];
80
82
  const sinceMs = options.since ? options.since.getTime() : null;
81
- const candidates = await (0, promptHistory_1.listCandidates)(providers, listingRoots, sinceMs);
83
+ const candidates = await (0, promptHistory_1.listCandidates)(providers, listingRoots, sinceMs, {
84
+ includeCompressedRollouts: options.includeCompressedRollouts,
85
+ });
82
86
  const byProviderSession = new Map();
83
87
  for (const candidate of candidates) {
84
88
  byProviderSession.set(`${candidate.provider}:${candidate.sessionId}`, candidate);
@@ -188,21 +192,15 @@ function claudeSubagentTranscripts(sessionFile, sessionId) {
188
192
  }));
189
193
  }
190
194
  async function readFirstRecord(filePath) {
191
- let handle;
192
195
  try {
193
- handle = await fs.promises.open(filePath, 'r');
194
- const buffer = Buffer.alloc(256 * 1024);
195
- const { bytesRead } = await handle.read(buffer, 0, buffer.length, 0);
196
- const text = buffer.subarray(0, bytesRead).toString('utf8');
196
+ // A compressed rollout's head is decompressed.
197
+ const text = (await (0, compressedRollouts_1.readRolloutHeadAsync)(filePath, 256 * 1024)).toString('utf8');
197
198
  const newline = text.indexOf('\n');
198
199
  return JSON.parse(newline === -1 ? text : text.slice(0, newline));
199
200
  }
200
201
  catch {
201
202
  return undefined;
202
203
  }
203
- finally {
204
- await handle?.close();
205
- }
206
204
  }
207
205
  /** Fail-closed scope check on a recorded working directory. */
208
206
  function inScope(cwd, roots, realpaths) {
@@ -223,7 +221,16 @@ async function scanForIds(filePath, provider, wanted, roots, realpaths, signal)
223
221
  const hits = [];
224
222
  let stream;
225
223
  try {
226
- stream = fs.createReadStream(filePath, { encoding: 'utf8' });
224
+ if ((0, compressedRollouts_1.isCompressedRolloutPath)(filePath)) {
225
+ // Compressed rollouts are complete; search their decompressed content.
226
+ const content = await (0, compressedRollouts_1.readRolloutBufferAsync)(filePath);
227
+ if (!content)
228
+ return hits;
229
+ stream = stream_1.Readable.from([content.toString('utf8')]);
230
+ }
231
+ else {
232
+ stream = fs.createReadStream(filePath, { encoding: 'utf8' });
233
+ }
227
234
  }
228
235
  catch {
229
236
  return hits;
@@ -20,7 +20,11 @@ exports.TOOL_CATEGORIES = [
20
20
  'mcp',
21
21
  'other',
22
22
  ];
23
- /** Lower-cased tool names of every provider, by category. */
23
+ /**
24
+ * Lower-cased tool names of every provider, by category. Codex's bare `wait`
25
+ * is a code-mode cell wait, not a subagent wait (that is `wait_agent`), so it
26
+ * is `other`.
27
+ */
24
28
  const CATEGORY_BY_NAME = new Map([
25
29
  [
26
30
  'shell',
@@ -54,7 +58,7 @@ const CATEGORY_BY_NAME = new Map([
54
58
  'send_message',
55
59
  'followup_task',
56
60
  'list_agents',
57
- 'wait',
61
+ 'interrupt_agent',
58
62
  ],
59
63
  ],
60
64
  [
@@ -2,6 +2,8 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.projectSessionTranscript = projectSessionTranscript;
4
4
  const usageNormalization_1 = require("./usageNormalization");
5
+ const subagentSpawn_1 = require("./subagentSpawn");
6
+ const subagentActivity_1 = require("./subagentActivity");
5
7
  const EMPTY_TOTALS = {
6
8
  uncachedInputTokens: 0,
7
9
  cacheReadTokens: 0,
@@ -28,6 +30,12 @@ function projectSessionTranscript(events, options = {}) {
28
30
  let cwd;
29
31
  let gitBranch;
30
32
  events.forEach((event, eventIndex) => {
33
+ // A reader's synthetic notice that a background task finished, not a message.
34
+ if ((0, subagentSpawn_1.isTaskNotificationSystemEvent)(event) || (0, subagentSpawn_1.isTaskStatusSystemEvent)(event))
35
+ return;
36
+ // Likewise a subagent lifecycle record (opt-in Codex parser event).
37
+ if ((0, subagentActivity_1.isSubagentActivitySystemEvent)(event))
38
+ return;
31
39
  if (nonEmpty(event.cwd))
32
40
  cwd = event.cwd;
33
41
  if (nonEmpty(event.gitBranch))
@@ -70,6 +70,10 @@ export interface ReasoningSummary {
70
70
  body: string;
71
71
  }
72
72
  export declare function reasoningSummary(text: string): ReasoningSummary;
73
+ /**
74
+ * Whether a tool call spawns a subagent (`Agent`, or its earlier name `Task`).
75
+ * Codex `spawn_agent` is not included here (its turns project as before).
76
+ */
73
77
  export declare function isAssistantTurnSubagentTool(toolName: string | undefined): boolean;
74
78
  export declare function segmentAssistantTurn(events: readonly AssistantTurnEvent[], options?: SegmentAssistantTurnOptions): AssistantTurnProjection;
75
79
  export declare function assistantTurnEventsFromSessionEvents(events: readonly SessionEvent[]): AssistantTurnEvent[];
@@ -6,12 +6,12 @@ exports.segmentAssistantTurn = segmentAssistantTurn;
6
6
  exports.assistantTurnEventsFromSessionEvents = assistantTurnEventsFromSessionEvents;
7
7
  exports.extractTurnSubagents = extractTurnSubagents;
8
8
  const toolSummary_1 = require("../formatters/toolSummary");
9
+ const subagentSpawn_1 = require("../subagentSpawn");
9
10
  const DEFAULT_NARRATION_CHARS = 4000;
10
11
  const DEFAULT_REASONING_CHARS = 8000;
11
12
  const DEFAULT_PROCESS_STEPS = 60;
12
13
  const DEFAULT_REASONING_BLOCKS = 24;
13
14
  const DEFAULT_TOOL_INPUT_CHARS = 200;
14
- const SUBAGENT_TOOL_NAMES = new Set(['Task']);
15
15
  const LABEL_MAX = 80;
16
16
  const TITLE_RE = /^\s*\*\*([^*\n]+)\*\*[ \t]*(?:\n+([\s\S]*))?$/;
17
17
  const TITLE_MAX = 100;
@@ -29,8 +29,12 @@ function reasoningSummary(text) {
29
29
  }
30
30
  return { title: null, body: trimmed };
31
31
  }
32
+ /**
33
+ * Whether a tool call spawns a subagent (`Agent`, or its earlier name `Task`).
34
+ * Codex `spawn_agent` is not included here (its turns project as before).
35
+ */
32
36
  function isAssistantTurnSubagentTool(toolName) {
33
- return toolName != null && SUBAGENT_TOOL_NAMES.has(toolName);
37
+ return typeof toolName === 'string' && subagentSpawn_1.SUBAGENT_SPAWN_TOOL_NAMES.includes(toolName);
34
38
  }
35
39
  function segmentAssistantTurn(events, options = {}) {
36
40
  const maxNarrationChars = options.maxNarrationChars ?? DEFAULT_NARRATION_CHARS;
@@ -16,6 +16,12 @@ export interface CodexRolloutLine {
16
16
  timestamp: string;
17
17
  /** Discriminator for the payload type */
18
18
  type: 'session_meta' | 'response_item' | 'compacted' | 'turn_context' | 'event_msg';
19
+ /**
20
+ * Zero-based position of the record in its rollout (recent Codex versions).
21
+ * In a forked subagent rollout, records before the child's
22
+ * `session_meta.subagent_history_start_ordinal` are the parent's history.
23
+ */
24
+ ordinal?: number;
19
25
  /** Type-specific payload */
20
26
  payload: CodexSessionMeta | CodexResponseItem | CodexCompacted | CodexTurnContext | CodexEventMsg;
21
27
  }
@@ -37,13 +43,32 @@ export interface CodexSessionMeta {
37
43
  dirty?: boolean;
38
44
  };
39
45
  forked_from_id?: string;
46
+ /** The root session of a subagent tree (recent Codex versions). */
47
+ session_id?: string;
48
+ /** Subagents: the thread that spawned this one. */
49
+ parent_thread_id?: string;
50
+ /** `user`, `subagent`, … (recent Codex versions). */
51
+ thread_source?: string;
52
+ /** Subagents: display nickname, e.g. `Banach`. */
53
+ agent_nickname?: string | null;
54
+ /** Subagents: agent path, e.g. `/root/review_builder`. */
55
+ agent_path?: string | null;
56
+ /** Subagents: requested role (`agent_type`), when one was given. */
57
+ agent_role?: string | null;
58
+ /**
59
+ * Forked subagents: the ordinal of the first record that is the child's
60
+ * own; earlier records are the parent's history the fork embeds.
61
+ */
62
+ subagent_history_start_ordinal?: number;
63
+ history_mode?: string;
64
+ multi_agent_version?: string;
40
65
  }
41
66
  /**
42
67
  * A response item from the model.
43
68
  * The payload IS the item directly (no .item wrapper).
44
69
  * Tagged union on `type`.
45
70
  */
46
- export type CodexResponseItem = CodexMessageItem | CodexReasoningItem | CodexFunctionCallItem | CodexFunctionCallOutputItem | CodexLocalShellCallItem | CodexWebSearchCallItem | CodexCustomToolCallItem | CodexCustomToolCallOutputItem;
71
+ export type CodexResponseItem = CodexMessageItem | CodexAgentMessageItem | CodexReasoningItem | CodexFunctionCallItem | CodexFunctionCallOutputItem | CodexLocalShellCallItem | CodexWebSearchCallItem | CodexCustomToolCallItem | CodexCustomToolCallOutputItem;
47
72
  /** Chat message (user, assistant, or developer). */
48
73
  export interface CodexMessageItem {
49
74
  type: 'message';
@@ -53,6 +78,22 @@ export interface CodexMessageItem {
53
78
  status?: string;
54
79
  phase?: string;
55
80
  }
81
+ /**
82
+ * A message between agents of a multi-agent session (`author` and
83
+ * `recipient` are agent paths such as `/root/review_builder` and `/root`).
84
+ * Its first text part starts `Message Type: MESSAGE | NEW_TASK |
85
+ * FINAL_ANSWER`, followed by `Task name:`, `Sender:`, and `Payload:` lines.
86
+ */
87
+ export interface CodexAgentMessageItem {
88
+ type: 'agent_message';
89
+ id?: string;
90
+ author?: string;
91
+ recipient?: string;
92
+ content: Array<CodexContentPart | {
93
+ type: 'encrypted_content';
94
+ encrypted_content?: string;
95
+ }>;
96
+ }
56
97
  /** Content part within a message. */
57
98
  export interface CodexContentPart {
58
99
  type: 'output_text' | 'input_text' | 'refusal' | 'text';
@@ -79,6 +120,8 @@ export interface CodexFunctionCallItem {
79
120
  name: string;
80
121
  arguments: string;
81
122
  status?: string;
123
+ /** Tool namespace, e.g. `collaboration` for the multi-agent tools. */
124
+ namespace?: string;
82
125
  }
83
126
  /** Result of a function call. */
84
127
  export interface CodexFunctionCallOutputItem {
@@ -140,7 +183,7 @@ export interface CodexTurnContext {
140
183
  * Tagged union on `type`.
141
184
  */
142
185
  export type CodexEventMsg = CodexEvent;
143
- export type CodexEvent = CodexTurnStartedEvent | CodexTurnCompleteEvent | CodexTaskStartedEvent | CodexTaskCompleteEvent | CodexTurnAbortedEvent | CodexTokenCountEvent | CodexAgentMessageEvent | CodexAgentReasoningEvent | CodexUserMessageEvent | CodexExecCommandBeginEvent | CodexExecCommandEndEvent | CodexMcpToolCallBeginEvent | CodexMcpToolCallEndEvent | CodexErrorEvent | CodexContextCompactedEvent | CodexPatchAppliedEvent | CodexBackgroundEvent | CodexGenericEvent;
186
+ export type CodexEvent = CodexTurnStartedEvent | CodexTurnCompleteEvent | CodexTaskStartedEvent | CodexTaskCompleteEvent | CodexTurnAbortedEvent | CodexTokenCountEvent | CodexAgentMessageEvent | CodexAgentReasoningEvent | CodexUserMessageEvent | CodexExecCommandBeginEvent | CodexExecCommandEndEvent | CodexMcpToolCallBeginEvent | CodexMcpToolCallEndEvent | CodexErrorEvent | CodexContextCompactedEvent | CodexPatchAppliedEvent | CodexItemCompletedEvent | CodexBackgroundEvent | CodexGenericEvent;
144
187
  export interface CodexTurnStartedEvent {
145
188
  type: 'turn_started';
146
189
  turn_id?: string;
@@ -264,6 +307,28 @@ export interface CodexPatchAppliedEvent {
264
307
  additions?: number;
265
308
  deletions?: number;
266
309
  }
310
+ /**
311
+ * A completed turn item. `SubAgentActivity` items record the multi-agent
312
+ * lifecycle: `kind` `started` (id = the spawn call), `completed` (id =
313
+ * `subagent-completed-<child turn id>`), `interacted` (id = a
314
+ * `followup_task` / `send_message` call), `interrupted` (id = an
315
+ * `interrupt_agent` call).
316
+ */
317
+ export interface CodexItemCompletedEvent {
318
+ type: 'item_completed';
319
+ thread_id?: string;
320
+ turn_id?: string;
321
+ item?: {
322
+ type?: string;
323
+ id?: string;
324
+ kind?: string;
325
+ agent_thread_id?: string;
326
+ agent_path?: string;
327
+ model?: string | null;
328
+ reasoning_effort?: string | null;
329
+ [key: string]: unknown;
330
+ };
331
+ }
267
332
  export interface CodexBackgroundEvent {
268
333
  type: 'background';
269
334
  message?: string;
@@ -291,6 +356,10 @@ export interface CodexDbThread {
291
356
  source?: string;
292
357
  agent_nickname?: string | null;
293
358
  agent_role?: string | null;
359
+ /** Subagents: agent path, e.g. `/root/review_builder` (recent schemas). */
360
+ agent_path?: string | null;
361
+ /** `user`, `subagent`, … (recent schemas). */
362
+ thread_source?: string | null;
294
363
  /** 1 once the thread is archived; Codex then moves its rollout to `archived_sessions/`. */
295
364
  archived?: number;
296
365
  /** Unix seconds when the thread was archived. */