@agents-tower/core 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 (178) hide show
  1. package/dist/adapters/claude.d.ts +2 -0
  2. package/dist/adapters/claude.js +43 -0
  3. package/dist/adapters/claude.js.map +1 -0
  4. package/dist/adapters/codex-cloud.d.ts +4 -0
  5. package/dist/adapters/codex-cloud.js +80 -0
  6. package/dist/adapters/codex-cloud.js.map +1 -0
  7. package/dist/adapters/codex-local.d.ts +17 -0
  8. package/dist/adapters/codex-local.js +180 -0
  9. package/dist/adapters/codex-local.js.map +1 -0
  10. package/dist/adapters/cursor-cloud.d.ts +2 -0
  11. package/dist/adapters/cursor-cloud.js +54 -0
  12. package/dist/adapters/cursor-cloud.js.map +1 -0
  13. package/dist/adapters/cursor-local.d.ts +2 -0
  14. package/dist/adapters/cursor-local.js +37 -0
  15. package/dist/adapters/cursor-local.js.map +1 -0
  16. package/dist/adapters/helpers.d.ts +15 -0
  17. package/dist/adapters/helpers.js +33 -0
  18. package/dist/adapters/helpers.js.map +1 -0
  19. package/dist/adapters/hermes.d.ts +2 -0
  20. package/dist/adapters/hermes.js +41 -0
  21. package/dist/adapters/hermes.js.map +1 -0
  22. package/dist/adapters/index.d.ts +2 -0
  23. package/dist/adapters/index.js +37 -0
  24. package/dist/adapters/index.js.map +1 -0
  25. package/dist/adapters/openclaw.d.ts +2 -0
  26. package/dist/adapters/openclaw.js +41 -0
  27. package/dist/adapters/openclaw.js.map +1 -0
  28. package/dist/adapters/presence.d.ts +2 -0
  29. package/dist/adapters/presence.js +36 -0
  30. package/dist/adapters/presence.js.map +1 -0
  31. package/dist/adapters/static-source.d.ts +15 -0
  32. package/dist/adapters/static-source.js +41 -0
  33. package/dist/adapters/static-source.js.map +1 -0
  34. package/dist/adapters/types.d.ts +44 -0
  35. package/dist/adapters/types.js +3 -0
  36. package/dist/adapters/types.js.map +1 -0
  37. package/dist/app-server.d.ts +94 -0
  38. package/dist/app-server.js +382 -0
  39. package/dist/app-server.js.map +1 -0
  40. package/dist/app-settings.d.ts +52 -0
  41. package/dist/app-settings.js +268 -0
  42. package/dist/app-settings.js.map +1 -0
  43. package/dist/appearance.d.ts +6 -0
  44. package/dist/appearance.js +84 -0
  45. package/dist/appearance.js.map +1 -0
  46. package/dist/aseprite.d.ts +4 -0
  47. package/dist/aseprite.js +42 -0
  48. package/dist/aseprite.js.map +1 -0
  49. package/dist/claude-agent-sdk.d.ts +44 -0
  50. package/dist/claude-agent-sdk.js +347 -0
  51. package/dist/claude-agent-sdk.js.map +1 -0
  52. package/dist/claude-home-cache.d.ts +61 -0
  53. package/dist/claude-home-cache.js +438 -0
  54. package/dist/claude-home-cache.js.map +1 -0
  55. package/dist/claude.d.ts +154 -0
  56. package/dist/claude.js +3495 -0
  57. package/dist/claude.js.map +1 -0
  58. package/dist/cloud.d.ts +2 -0
  59. package/dist/cloud.js +25 -0
  60. package/dist/cloud.js.map +1 -0
  61. package/dist/codex-command.d.ts +25 -0
  62. package/dist/codex-command.js +235 -0
  63. package/dist/codex-command.js.map +1 -0
  64. package/dist/codex-session-files.d.ts +8 -0
  65. package/dist/codex-session-files.js +509 -0
  66. package/dist/codex-session-files.js.map +1 -0
  67. package/dist/codex-thread-query.d.ts +14 -0
  68. package/dist/codex-thread-query.js +82 -0
  69. package/dist/codex-thread-query.js.map +1 -0
  70. package/dist/cursor-cloud-data.d.ts +34 -0
  71. package/dist/cursor-cloud-data.js +344 -0
  72. package/dist/cursor-cloud-data.js.map +1 -0
  73. package/dist/cursor-lib/local-discovery.d.ts +17 -0
  74. package/dist/cursor-lib/local-discovery.js +251 -0
  75. package/dist/cursor-lib/local-discovery.js.map +1 -0
  76. package/dist/cursor-lib/shared.d.ts +5 -0
  77. package/dist/cursor-lib/shared.js +88 -0
  78. package/dist/cursor-lib/shared.js.map +1 -0
  79. package/dist/cursor.d.ts +8 -0
  80. package/dist/cursor.js +1584 -0
  81. package/dist/cursor.js.map +1 -0
  82. package/dist/domain/codex-turn-semantics.d.ts +4 -0
  83. package/dist/domain/codex-turn-semantics.js +49 -0
  84. package/dist/domain/codex-turn-semantics.js.map +1 -0
  85. package/dist/domain/workload-policy.d.ts +8 -0
  86. package/dist/domain/workload-policy.js +268 -0
  87. package/dist/domain/workload-policy.js.map +1 -0
  88. package/dist/domain/workspace-activity.d.ts +10 -0
  89. package/dist/domain/workspace-activity.js +372 -0
  90. package/dist/domain/workspace-activity.js.map +1 -0
  91. package/dist/goal.d.ts +11 -0
  92. package/dist/goal.js +76 -0
  93. package/dist/goal.js.map +1 -0
  94. package/dist/hermes-hook-install.d.ts +12 -0
  95. package/dist/hermes-hook-install.js +335 -0
  96. package/dist/hermes-hook-install.js.map +1 -0
  97. package/dist/hermes.d.ts +97 -0
  98. package/dist/hermes.js +2446 -0
  99. package/dist/hermes.js.map +1 -0
  100. package/dist/index.d.ts +28 -0
  101. package/dist/index.js +47 -0
  102. package/dist/index.js.map +1 -0
  103. package/dist/live-monitor-lib/events.d.ts +43 -0
  104. package/dist/live-monitor-lib/events.js +1463 -0
  105. package/dist/live-monitor-lib/events.js.map +1 -0
  106. package/dist/live-monitor-lib/rollout-hooks.d.ts +13 -0
  107. package/dist/live-monitor-lib/rollout-hooks.js +253 -0
  108. package/dist/live-monitor-lib/rollout-hooks.js.map +1 -0
  109. package/dist/live-monitor.d.ts +102 -0
  110. package/dist/live-monitor.js +1461 -0
  111. package/dist/live-monitor.js.map +1 -0
  112. package/dist/local-thread-selection.d.ts +2 -0
  113. package/dist/local-thread-selection.js +58 -0
  114. package/dist/local-thread-selection.js.map +1 -0
  115. package/dist/openclaw.d.ts +41 -0
  116. package/dist/openclaw.js +715 -0
  117. package/dist/openclaw.js.map +1 -0
  118. package/dist/presence.d.ts +9 -0
  119. package/dist/presence.js +108 -0
  120. package/dist/presence.js.map +1 -0
  121. package/dist/project-identity.d.ts +7 -0
  122. package/dist/project-identity.js +162 -0
  123. package/dist/project-identity.js.map +1 -0
  124. package/dist/project-paths.d.ts +23 -0
  125. package/dist/project-paths.js +394 -0
  126. package/dist/project-paths.js.map +1 -0
  127. package/dist/project-storage.d.ts +7 -0
  128. package/dist/project-storage.js +79 -0
  129. package/dist/project-storage.js.map +1 -0
  130. package/dist/room-config.d.ts +21 -0
  131. package/dist/room-config.js +230 -0
  132. package/dist/room-config.js.map +1 -0
  133. package/dist/services/project-discovery.d.ts +1 -0
  134. package/dist/services/project-discovery.js +16 -0
  135. package/dist/services/project-discovery.js.map +1 -0
  136. package/dist/services/project-live-monitor.d.ts +1 -0
  137. package/dist/services/project-live-monitor.js +6 -0
  138. package/dist/services/project-live-monitor.js.map +1 -0
  139. package/dist/services/project-snapshot-coordinator.d.ts +49 -0
  140. package/dist/services/project-snapshot-coordinator.js +152 -0
  141. package/dist/services/project-snapshot-coordinator.js.map +1 -0
  142. package/dist/services/refresh-scheduler.d.ts +8 -0
  143. package/dist/services/refresh-scheduler.js +44 -0
  144. package/dist/services/refresh-scheduler.js.map +1 -0
  145. package/dist/services/snapshot-assembler.d.ts +8 -0
  146. package/dist/services/snapshot-assembler.js +167 -0
  147. package/dist/services/snapshot-assembler.js.map +1 -0
  148. package/dist/services/thread-store.d.ts +4 -0
  149. package/dist/services/thread-store.js +8 -0
  150. package/dist/services/thread-store.js.map +1 -0
  151. package/dist/snapshot-lib/activity-summary.d.ts +3 -0
  152. package/dist/snapshot-lib/activity-summary.js +220 -0
  153. package/dist/snapshot-lib/activity-summary.js.map +1 -0
  154. package/dist/snapshot-lib/dashboard-builder.d.ts +21 -0
  155. package/dist/snapshot-lib/dashboard-builder.js +146 -0
  156. package/dist/snapshot-lib/dashboard-builder.js.map +1 -0
  157. package/dist/snapshot-lib/thread-summary.d.ts +27 -0
  158. package/dist/snapshot-lib/thread-summary.js +953 -0
  159. package/dist/snapshot-lib/thread-summary.js.map +1 -0
  160. package/dist/snapshot.d.ts +2 -0
  161. package/dist/snapshot.js +21 -0
  162. package/dist/snapshot.js.map +1 -0
  163. package/dist/types.d.ts +368 -0
  164. package/dist/types.js +3 -0
  165. package/dist/types.js.map +1 -0
  166. package/dist/utils/json.d.ts +4 -0
  167. package/dist/utils/json.js +29 -0
  168. package/dist/utils/json.js.map +1 -0
  169. package/dist/utils/text.d.ts +3 -0
  170. package/dist/utils/text.js +26 -0
  171. package/dist/utils/text.js.map +1 -0
  172. package/dist/web-search.d.ts +1 -0
  173. package/dist/web-search.js +52 -0
  174. package/dist/web-search.js.map +1 -0
  175. package/dist/workload.d.ts +1 -0
  176. package/dist/workload.js +12 -0
  177. package/dist/workload.js.map +1 -0
  178. package/package.json +19 -0
@@ -0,0 +1,1463 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.asRecord = asRecord;
4
+ exports.asString = asString;
5
+ exports.extractThreadId = extractThreadId;
6
+ exports.collectPaths = collectPaths;
7
+ exports.latestThreadAgentMessage = latestThreadAgentMessage;
8
+ exports.latestThreadAgentMessageIsInLastTurn = latestThreadAgentMessageIsInLastTurn;
9
+ exports.isFinalAgentMessageNotification = isFinalAgentMessageNotification;
10
+ exports.shouldMarkThreadLiveFromAppServerNotification = shouldMarkThreadLiveFromAppServerNotification;
11
+ exports.shouldMarkThreadStoppedFromAppServerNotification = shouldMarkThreadStoppedFromAppServerNotification;
12
+ exports.hasEquivalentRecentMessageEvent = hasEquivalentRecentMessageEvent;
13
+ exports.extractCollabReceiverThreadIds = extractCollabReceiverThreadIds;
14
+ exports.buildThreadReadAgentMessageEvent = buildThreadReadAgentMessageEvent;
15
+ exports.buildDashboardEventFromAppServerMessage = buildDashboardEventFromAppServerMessage;
16
+ exports.appServerDiagnosticNotePrefix = appServerDiagnosticNotePrefix;
17
+ exports.buildAppServerDiagnosticNote = buildAppServerDiagnosticNote;
18
+ exports.buildNeedsUserStateFromServerRequest = buildNeedsUserStateFromServerRequest;
19
+ exports.shouldStopDormantThreadAfterAppServerNotification = shouldStopDormantThreadAfterAppServerNotification;
20
+ const project_paths_1 = require("../project-paths");
21
+ const web_search_1 = require("../web-search");
22
+ function asRecord(value) {
23
+ return typeof value === "object" && value ? value : null;
24
+ }
25
+ function asString(value) {
26
+ return typeof value === "string" && value.length > 0 ? value : undefined;
27
+ }
28
+ function asStringArray(value) {
29
+ return Array.isArray(value) ? value.filter((entry) => typeof entry === "string") : [];
30
+ }
31
+ function asNeedsUserQuestionOption(value) {
32
+ const record = asRecord(value);
33
+ const label = asString(record?.label);
34
+ const description = asString(record?.description);
35
+ if (!label || !description) {
36
+ return null;
37
+ }
38
+ return { label, description };
39
+ }
40
+ function asNeedsUserQuestion(value) {
41
+ const record = asRecord(value);
42
+ const header = asString(record?.header);
43
+ const id = asString(record?.id);
44
+ const question = asString(record?.question);
45
+ if (!header || !id || !question) {
46
+ return null;
47
+ }
48
+ const rawOptions = Array.isArray(record?.options) ? record.options : null;
49
+ const options = rawOptions
50
+ ? rawOptions
51
+ .map((entry) => asNeedsUserQuestionOption(entry))
52
+ .filter((entry) => Boolean(entry))
53
+ : null;
54
+ return {
55
+ header,
56
+ id,
57
+ question,
58
+ required: record?.required === false ? false : undefined,
59
+ isOther: record?.isOther === true,
60
+ isSecret: record?.isSecret === true,
61
+ options
62
+ };
63
+ }
64
+ function asNeedsUserQuestions(value) {
65
+ return Array.isArray(value)
66
+ ? value
67
+ .map((entry) => asNeedsUserQuestion(entry))
68
+ .filter((entry) => Boolean(entry))
69
+ : [];
70
+ }
71
+ function titleCaseIdentifier(value) {
72
+ return value
73
+ .replace(/[_-]+/g, " ")
74
+ .replace(/([a-z0-9])([A-Z])/g, "$1 $2")
75
+ .split(/\s+/)
76
+ .filter(Boolean)
77
+ .map((part) => part.charAt(0).toUpperCase() + part.slice(1))
78
+ .join(" ");
79
+ }
80
+ function parseSchemaOptions(schema) {
81
+ const enumValues = asStringArray(schema.enum);
82
+ if (enumValues.length > 0) {
83
+ return enumValues.map((value) => ({
84
+ label: value,
85
+ description: value
86
+ }));
87
+ }
88
+ const oneOf = Array.isArray(schema.oneOf) ? schema.oneOf : [];
89
+ const oneOfOptions = oneOf
90
+ .map((entry) => {
91
+ const option = asRecord(entry);
92
+ const constValue = asString(option?.const);
93
+ if (!constValue) {
94
+ return null;
95
+ }
96
+ return {
97
+ label: constValue,
98
+ description: asString(option?.title) ?? asString(option?.description) ?? constValue
99
+ };
100
+ })
101
+ .filter((option) => Boolean(option));
102
+ if (oneOfOptions.length > 0) {
103
+ return oneOfOptions;
104
+ }
105
+ const items = asRecord(schema.items);
106
+ const itemEnumValues = asStringArray(items?.enum);
107
+ if (itemEnumValues.length > 0) {
108
+ return itemEnumValues.map((value) => ({
109
+ label: value,
110
+ description: value
111
+ }));
112
+ }
113
+ const nestedItems = asRecord(items?.items);
114
+ const anyOf = Array.isArray(nestedItems?.anyOf)
115
+ ? nestedItems.anyOf
116
+ : Array.isArray(items?.anyOf)
117
+ ? items.anyOf
118
+ : [];
119
+ const anyOfOptions = anyOf
120
+ .map((entry) => {
121
+ const option = asRecord(entry);
122
+ const constValue = asString(option?.const);
123
+ if (!constValue) {
124
+ return null;
125
+ }
126
+ return {
127
+ label: constValue,
128
+ description: asString(option?.title) ?? asString(option?.description) ?? constValue
129
+ };
130
+ })
131
+ .filter((option) => Boolean(option));
132
+ return anyOfOptions.length > 0 ? anyOfOptions : null;
133
+ }
134
+ function parseMcpElicitationQuestions(schema) {
135
+ const properties = asRecord(schema?.properties);
136
+ if (!properties) {
137
+ return [];
138
+ }
139
+ const required = new Set(asStringArray(schema?.required));
140
+ return Object.entries(properties)
141
+ .map((entry) => {
142
+ const [id, rawSchema] = entry;
143
+ const propertySchema = asRecord(rawSchema);
144
+ if (!propertySchema) {
145
+ return null;
146
+ }
147
+ const header = asString(propertySchema.title) ?? titleCaseIdentifier(id);
148
+ const type = asString(propertySchema.type);
149
+ const question = asString(propertySchema.description) ?? header;
150
+ const options = type === "boolean"
151
+ ? [
152
+ { label: "true", description: "True" },
153
+ { label: "false", description: "False" }
154
+ ]
155
+ : parseSchemaOptions(propertySchema);
156
+ return {
157
+ header,
158
+ id,
159
+ question,
160
+ required: required.has(id),
161
+ isSecret: propertySchema.format === "password",
162
+ options
163
+ };
164
+ })
165
+ .filter((question) => Boolean(question));
166
+ }
167
+ function shorten(text, maxLength = 88) {
168
+ const normalized = text.replace(/\s+/g, " ").trim();
169
+ if (normalized.length <= maxLength) {
170
+ return normalized;
171
+ }
172
+ return `${normalized.slice(0, maxLength - 1)}…`;
173
+ }
174
+ function summarizePlanUpdate(params) {
175
+ const explanation = asString(params.explanation);
176
+ if (explanation) {
177
+ return shorten(explanation);
178
+ }
179
+ const plan = Array.isArray(params.plan) ? params.plan : [];
180
+ const entries = plan
181
+ .map((entry) => asRecord(entry))
182
+ .filter((entry) => Boolean(entry))
183
+ .map((entry) => ({
184
+ step: asString(entry.step),
185
+ status: asString(entry.status)
186
+ }))
187
+ .filter((entry) => entry.step);
188
+ if (entries.length === 0) {
189
+ return "Plan";
190
+ }
191
+ const current = entries.find((entry) => entry.status === "inProgress")
192
+ ?? entries.find((entry) => entry.status === "pending")
193
+ ?? entries.at(-1)
194
+ ?? null;
195
+ if (!current?.step) {
196
+ return "Plan";
197
+ }
198
+ const statusLabel = current.status === "inProgress" ? "In progress"
199
+ : current.status === "pending" ? "Pending"
200
+ : current.status === "completed" ? "Completed"
201
+ : null;
202
+ return shorten(statusLabel ? `${statusLabel}: ${current.step}` : current.step);
203
+ }
204
+ function summarizeDiffUpdate(params) {
205
+ const diff = asString(params.diff);
206
+ if (!diff) {
207
+ return "Diff";
208
+ }
209
+ const files = new Set();
210
+ for (const line of diff.split(/\r?\n/)) {
211
+ const gitMatch = line.match(/^diff --git a\/(.+?) b\/(.+)$/);
212
+ if (gitMatch) {
213
+ files.add(gitMatch[2] || gitMatch[1]);
214
+ continue;
215
+ }
216
+ const plusMatch = line.match(/^\+\+\+ b\/(.+)$/);
217
+ if (plusMatch && plusMatch[1] !== "/dev/null") {
218
+ files.add(plusMatch[1]);
219
+ }
220
+ }
221
+ if (files.size === 1) {
222
+ return shorten(Array.from(files)[0] || "Diff");
223
+ }
224
+ if (files.size > 1) {
225
+ return `${files.size} files changed`;
226
+ }
227
+ return shorten(diff);
228
+ }
229
+ function isMeaningfulAgentText(text) {
230
+ if (typeof text !== "string") {
231
+ return false;
232
+ }
233
+ const normalized = text.replace(/\s+/g, " ").trim();
234
+ if (!normalized) {
235
+ return false;
236
+ }
237
+ return !/^[.\-_~`"'!,;:|/\\()[\]{}]+$/.test(normalized);
238
+ }
239
+ function extractNumberValue(value, ...keys) {
240
+ const record = asRecord(value);
241
+ if (!record) {
242
+ return undefined;
243
+ }
244
+ for (const key of keys) {
245
+ const candidate = record[key];
246
+ if (typeof candidate === "number" && Number.isFinite(candidate)) {
247
+ return candidate;
248
+ }
249
+ }
250
+ return undefined;
251
+ }
252
+ function extractThreadId(value) {
253
+ const record = asRecord(value);
254
+ const direct = record ? asString(record.threadId ?? record.thread_id ?? record.conversationId ?? record.conversation_id) : undefined;
255
+ return direct ?? null;
256
+ }
257
+ function extractTurnId(value) {
258
+ const record = asRecord(value);
259
+ return record ? asString(record.turnId ?? record.turn_id) : undefined;
260
+ }
261
+ function extractItemId(value) {
262
+ const record = asRecord(value);
263
+ return record ? asString(record.itemId ?? record.item_id ?? record.callId ?? record.call_id ?? record.id) : undefined;
264
+ }
265
+ function collectPaths(value, output = new Set()) {
266
+ if (typeof value === "string") {
267
+ const normalized = (0, project_paths_1.canonicalizeProjectPath)(value);
268
+ if (normalized) {
269
+ output.add(normalized);
270
+ }
271
+ return output;
272
+ }
273
+ if (Array.isArray(value)) {
274
+ value.forEach((entry) => collectPaths(entry, output));
275
+ return output;
276
+ }
277
+ const record = asRecord(value);
278
+ if (!record) {
279
+ return output;
280
+ }
281
+ for (const [key, entry] of Object.entries(record)) {
282
+ if (/^(\/|[A-Za-z]:[\\/])/.test(key)) {
283
+ collectPaths(key, output);
284
+ }
285
+ if (/(path|cwd|file|grantRoot)/i.test(key)) {
286
+ collectPaths(entry, output);
287
+ continue;
288
+ }
289
+ if (typeof entry === "object" && entry) {
290
+ collectPaths(entry, output);
291
+ }
292
+ }
293
+ return output;
294
+ }
295
+ function primaryPath(value) {
296
+ return [...collectPaths(value)][0] ?? null;
297
+ }
298
+ function latestThreadAgentMessage(thread) {
299
+ for (const turn of [...thread.turns].reverse()) {
300
+ for (const item of [...turn.items].reverse()) {
301
+ const record = asRecord(item);
302
+ if (!record || asString(record.type) !== "agentMessage") {
303
+ continue;
304
+ }
305
+ const text = asString(record.text);
306
+ if (!isMeaningfulAgentText(text)) {
307
+ continue;
308
+ }
309
+ return {
310
+ turnId: asString(record.turnId ?? record.turn_id) ?? turn.id,
311
+ itemId: extractItemId(record),
312
+ phase: asString(record.phase) ?? undefined,
313
+ text
314
+ };
315
+ }
316
+ }
317
+ return null;
318
+ }
319
+ function latestThreadAgentMessageIsInLastTurn(thread) {
320
+ const lastTurn = thread.turns.at(-1);
321
+ const latestMessage = latestThreadAgentMessage(thread);
322
+ return Boolean(lastTurn && latestMessage?.turnId === lastTurn.id);
323
+ }
324
+ function isLiveAppServerMethod(method) {
325
+ return (method === "thread/started"
326
+ || method === "thread/unarchived"
327
+ || method === "turn/started"
328
+ || method === "item/started"
329
+ || method === "item/agentMessage/delta"
330
+ || method === "item/plan/delta"
331
+ || method === "item/reasoning/summaryTextDelta"
332
+ || method === "item/reasoning/summaryPartAdded"
333
+ || method === "item/reasoning/textDelta"
334
+ || method === "item/commandExecution/outputDelta"
335
+ || method === "item/commandExecution/terminalInteraction"
336
+ || method === "item/fileChange/outputDelta"
337
+ || method === "item/fileChange/patchUpdated"
338
+ || method === "item/mcpToolCall/progress"
339
+ || method === "item/commandExecution/requestApproval"
340
+ || method === "item/fileChange/requestApproval"
341
+ || method === "item/tool/requestUserInput"
342
+ || method === "item/tool/call"
343
+ || method === "item/autoApprovalReview/started"
344
+ || method === "item/autoApprovalReview/completed"
345
+ || method === "hook/started"
346
+ || method === "hook/completed"
347
+ || method === "model/rerouted"
348
+ || method === "model/verification"
349
+ || method === "turn/plan/updated"
350
+ || method === "turn/diff/updated");
351
+ }
352
+ function isTurnTerminalAppServerMethod(method) {
353
+ return method === "turn/failed";
354
+ }
355
+ function isFinalAgentMessageNotification(message) {
356
+ if (message.method !== "item/completed") {
357
+ return false;
358
+ }
359
+ const item = asRecord(message.params?.item);
360
+ return asString(item?.type) === "agentMessage" && asString(item?.phase) === "final_answer";
361
+ }
362
+ function shouldMarkThreadLiveFromAppServerNotification(method, statusType) {
363
+ return isLiveAppServerMethod(method) || (method === "thread/status/changed" && statusType === "active");
364
+ }
365
+ function shouldMarkThreadStoppedFromAppServerNotification(method, statusType) {
366
+ return (method === "thread/archived"
367
+ || isTurnTerminalAppServerMethod(method)
368
+ || (method === "thread/status/changed" && statusType === "systemError"));
369
+ }
370
+ function shouldStopDormantThreadAfterNotification(input) {
371
+ if (!input.wasOngoing) {
372
+ return false;
373
+ }
374
+ return input.method === "thread/status/changed" && input.statusType === "notLoaded";
375
+ }
376
+ function hasEquivalentRecentMessageEvent(recentEvents, candidate) {
377
+ if (candidate.kind !== "message") {
378
+ return false;
379
+ }
380
+ return recentEvents.some((event) => {
381
+ if (event.kind !== "message") {
382
+ return false;
383
+ }
384
+ if (event.threadId !== candidate.threadId) {
385
+ return false;
386
+ }
387
+ if (event.itemId && candidate.itemId && event.itemId === candidate.itemId) {
388
+ return true;
389
+ }
390
+ const left = event.detail.trim();
391
+ const right = candidate.detail.trim();
392
+ return left === right || left.startsWith(right) || right.startsWith(left);
393
+ });
394
+ }
395
+ function buildEventId(input) {
396
+ return [
397
+ input.projectRoot,
398
+ input.method,
399
+ input.threadId ?? "",
400
+ input.turnId ?? "",
401
+ input.itemId ?? "",
402
+ input.requestId ?? "",
403
+ input.path ?? ""
404
+ ].join("::");
405
+ }
406
+ function summarizeFileChange(item, fallbackPath) {
407
+ const changes = Array.isArray(item.changes) ? item.changes : [];
408
+ const primaryChange = changes.find((entry) => {
409
+ const record = asRecord(entry);
410
+ return Boolean(record && typeof record.path === "string");
411
+ });
412
+ const changeRecord = asRecord(primaryChange);
413
+ const rawPath = asString(changeRecord?.path) ?? fallbackPath ?? null;
414
+ const path = rawPath ? (0, project_paths_1.canonicalizeProjectPath)(rawPath) ?? rawPath : null;
415
+ const changeKind = asString(changeRecord?.kind) ?? "edit";
416
+ const action = changeKind === "create" ? "created"
417
+ : changeKind === "delete" ? "deleted"
418
+ : changeKind === "move" || changeKind === "rename" ? "moved"
419
+ : "edited";
420
+ return {
421
+ path,
422
+ action,
423
+ title: action === "created" ? "File created"
424
+ : action === "deleted" ? "File deleted"
425
+ : action === "moved" ? "File moved"
426
+ : "File edited",
427
+ detail: path ?? "Files",
428
+ isImage: Boolean(path && /\.(png|jpe?g|gif|webp|svg|bmp)$/i.test(path)),
429
+ linesAdded: extractNumberValue(changeRecord, "linesAdded", "lines_added", "added")
430
+ ?? extractNumberValue(item, "linesAdded", "lines_added"),
431
+ linesRemoved: extractNumberValue(changeRecord, "linesRemoved", "lines_removed", "removed")
432
+ ?? extractNumberValue(item, "linesRemoved", "lines_removed")
433
+ };
434
+ }
435
+ function summarizeCommand(item, method) {
436
+ const command = asString(item.command) ?? method;
437
+ const cwd = asString(item.cwd) ?? null;
438
+ const status = asString(item.status) ?? "inProgress";
439
+ const phase = status === "failed" || status === "declined" ? "failed"
440
+ : status === "completed" || status === "success" ? "completed"
441
+ : "started";
442
+ return { command, cwd, phase };
443
+ }
444
+ function summarizeTool(item, fallbackLabel = "MCP tool") {
445
+ const tool = asString(item.tool)
446
+ ?? asString(item.name)
447
+ ?? asString(item.server)
448
+ ?? fallbackLabel;
449
+ const status = asString(item.status) ?? "inProgress";
450
+ const phase = status === "failed" || status === "declined" ? "failed"
451
+ : status === "completed" || status === "success" ? "completed"
452
+ : "started";
453
+ return {
454
+ tool,
455
+ phase,
456
+ detail: shorten(tool)
457
+ };
458
+ }
459
+ function asReceiverThreadIds(item) {
460
+ const receiverThreadIds = item.receiverThreadIds ?? item.receiver_thread_ids;
461
+ if (Array.isArray(receiverThreadIds)) {
462
+ return receiverThreadIds.filter((entry) => typeof entry === "string" && entry.length > 0);
463
+ }
464
+ const receiverThreadId = asString(item.receiverThreadId ?? item.receiver_thread_id);
465
+ return receiverThreadId ? [receiverThreadId] : [];
466
+ }
467
+ function normalizeCollabToolName(tool) {
468
+ const normalized = tool.replace(/[_\s-]+/g, "").toLowerCase();
469
+ if (normalized === "spawnagent" || normalized === "spawnagents") {
470
+ return "spawn";
471
+ }
472
+ if (normalized === "waitagent" || normalized === "wait") {
473
+ return "wait";
474
+ }
475
+ if (normalized === "sendinput" || normalized === "sendmessage" || normalized === "followuptask") {
476
+ return "send";
477
+ }
478
+ if (normalized === "closeagent") {
479
+ return "close";
480
+ }
481
+ if (normalized === "resumeagent") {
482
+ return "resume";
483
+ }
484
+ return normalized;
485
+ }
486
+ function summarizeCollabAgentTool(item) {
487
+ const rawTool = asString(item.tool) ?? "subagent";
488
+ const receiverCount = asReceiverThreadIds(item).length;
489
+ switch (normalizeCollabToolName(rawTool)) {
490
+ case "spawn":
491
+ return receiverCount > 0
492
+ ? `Spawning ${receiverCount} subagent${receiverCount === 1 ? "" : "s"}`
493
+ : "Spawning subagent";
494
+ case "wait":
495
+ return receiverCount > 1 ? `Waiting on ${receiverCount} subagents` : "Waiting on subagents";
496
+ case "send":
497
+ return receiverCount > 1 ? `Messaging ${receiverCount} subagents` : "Messaging subagent";
498
+ case "close":
499
+ return receiverCount > 1 ? `Closing ${receiverCount} subagents` : "Closing subagent";
500
+ case "resume":
501
+ return receiverCount > 1 ? `Resuming ${receiverCount} subagents` : "Resuming subagent";
502
+ default:
503
+ return rawTool;
504
+ }
505
+ }
506
+ function collabReceiverIsNotFound(item, receiverThreadId) {
507
+ const agentsStates = asRecord(item.agentsStates) ?? asRecord(item.agents_states);
508
+ const state = asRecord(agentsStates?.[receiverThreadId]);
509
+ return asString(state?.status) === "notFound";
510
+ }
511
+ function extractCollabReceiverThreadIds(message) {
512
+ const params = asRecord(message.params) ?? {};
513
+ const item = asRecord(params.item);
514
+ if (!item || asString(item.type) !== "collabAgentToolCall") {
515
+ return [];
516
+ }
517
+ return asReceiverThreadIds(item).filter((threadId) => !collabReceiverIsNotFound(item, threadId));
518
+ }
519
+ function summarizeDynamicTool(params) {
520
+ const namespace = asString(params.namespace);
521
+ const tool = asString(params.tool) ?? asString(params.name) ?? "Tool";
522
+ return namespace ? `${namespace}.${tool}` : tool;
523
+ }
524
+ function summarizeHookRun(params) {
525
+ const run = asRecord(params.run);
526
+ return shorten(asString(run?.statusMessage)
527
+ ?? asString(run?.eventName)
528
+ ?? asString(run?.sourcePath)
529
+ ?? "Hook");
530
+ }
531
+ function summarizeGuardianAction(action) {
532
+ const record = asRecord(action);
533
+ const type = asString(record?.type);
534
+ if (!record || !type) {
535
+ return "Approval review";
536
+ }
537
+ if (type === "command") {
538
+ return shorten(asString(record.command) ?? "Command approval review");
539
+ }
540
+ if (type === "execve") {
541
+ const argv = Array.isArray(record.argv)
542
+ ? record.argv.filter((entry) => typeof entry === "string")
543
+ : [];
544
+ return shorten([asString(record.program), ...argv].filter(Boolean).join(" ") || "Exec approval review");
545
+ }
546
+ if (type === "applyPatch") {
547
+ const files = Array.isArray(record.files)
548
+ ? record.files.filter((entry) => typeof entry === "string")
549
+ : [];
550
+ return files.length === 1 ? shorten(files[0]) : `${files.length || "Patch"} file approval review`;
551
+ }
552
+ if (type === "networkAccess") {
553
+ return shorten(asString(record.target) ?? asString(record.host) ?? "Network approval review");
554
+ }
555
+ if (type === "mcpToolCall") {
556
+ const server = asString(record.server);
557
+ const tool = asString(record.toolTitle) ?? asString(record.toolName);
558
+ return shorten([server, tool].filter(Boolean).join(".") || "MCP tool approval review");
559
+ }
560
+ if (type === "requestPermissions") {
561
+ return shorten(asString(record.reason) ?? "Permission approval review");
562
+ }
563
+ return titleCaseIdentifier(type);
564
+ }
565
+ function summarizeRawResponseItem(item) {
566
+ if (!item) {
567
+ return "Raw response item";
568
+ }
569
+ const type = asString(item.type) ?? "response item";
570
+ const text = asString(item.text)
571
+ ?? asString(item.output_text)
572
+ ?? asString(item.name)
573
+ ?? asString(item.call_id)
574
+ ?? asString(item.id);
575
+ return shorten(text ?? titleCaseIdentifier(type));
576
+ }
577
+ function rateLimitDetail(params) {
578
+ const rateLimits = asRecord(params.rateLimits);
579
+ const reached = asString(rateLimits?.rateLimitReachedType);
580
+ const limitName = asString(rateLimits?.limitName);
581
+ if (reached && limitName) {
582
+ return `${limitName}: ${reached}`;
583
+ }
584
+ return reached ?? limitName ?? "Rate limits updated";
585
+ }
586
+ function diagnosticMessage(params, ...keys) {
587
+ for (const key of keys) {
588
+ const value = asString(params[key]);
589
+ if (value) {
590
+ return value;
591
+ }
592
+ }
593
+ return "";
594
+ }
595
+ function eventBase(context, method, params, overrides) {
596
+ const threadId = overrides.threadId ?? extractThreadId(params) ?? null;
597
+ const turnId = overrides.turnId ?? extractTurnId(params);
598
+ const itemId = overrides.itemId ?? extractItemId(params.item ?? params);
599
+ const requestId = overrides.requestId;
600
+ const path = overrides.path ?? primaryPath(params);
601
+ return {
602
+ id: buildEventId({
603
+ projectRoot: context.projectRoot,
604
+ method,
605
+ threadId,
606
+ turnId,
607
+ itemId,
608
+ requestId,
609
+ path
610
+ }),
611
+ source: "codex",
612
+ confidence: "typed",
613
+ threadId,
614
+ createdAt: context.createdAt ?? new Date().toISOString(),
615
+ method,
616
+ turnId,
617
+ itemId,
618
+ itemType: overrides.itemType,
619
+ requestId,
620
+ kind: "other",
621
+ phase: "updated",
622
+ title: method,
623
+ detail: method,
624
+ path,
625
+ ...overrides
626
+ };
627
+ }
628
+ function buildThreadReadAgentMessageEvent(context, thread) {
629
+ const latestMessage = latestThreadAgentMessage(thread);
630
+ if (!latestMessage) {
631
+ return null;
632
+ }
633
+ const path = (0, project_paths_1.canonicalizeProjectPath)(thread.cwd) ?? thread.cwd;
634
+ const isFinalAnswer = latestMessage.phase === "final_answer";
635
+ return {
636
+ id: buildEventId({
637
+ projectRoot: context.projectRoot,
638
+ method: "thread/read/agentMessage",
639
+ threadId: thread.id,
640
+ turnId: latestMessage.turnId,
641
+ itemId: latestMessage.itemId,
642
+ path
643
+ }),
644
+ source: "codex",
645
+ confidence: "typed",
646
+ threadId: thread.id,
647
+ createdAt: context.createdAt ?? new Date().toISOString(),
648
+ method: "thread/read/agentMessage",
649
+ turnId: latestMessage.turnId,
650
+ itemId: latestMessage.itemId,
651
+ kind: "message",
652
+ phase: isFinalAnswer ? "completed" : "updated",
653
+ title: isFinalAnswer ? "Reply completed" : "Reply updated",
654
+ detail: shorten(latestMessage.text),
655
+ path
656
+ };
657
+ }
658
+ function buildEventFromItem(context, method, params) {
659
+ const item = asRecord(params.item);
660
+ if (!item) {
661
+ return eventBase(context, method, params, {
662
+ kind: "item",
663
+ title: "Item updated",
664
+ detail: method
665
+ });
666
+ }
667
+ const itemType = asString(item.type) ?? "item";
668
+ const itemId = extractItemId(item);
669
+ const phase = method === "item/started" ? "started"
670
+ : method === "item/completed"
671
+ ? (asString(item.status) === "failed" || asString(item.status) === "declined" ? "failed" : "completed")
672
+ : "updated";
673
+ if (itemType === "fileChange") {
674
+ const change = summarizeFileChange(item, primaryPath(params));
675
+ return eventBase(context, method, params, {
676
+ itemId,
677
+ kind: "fileChange",
678
+ phase,
679
+ title: change.title,
680
+ detail: change.detail,
681
+ path: change.path,
682
+ action: change.action,
683
+ isImage: change.isImage,
684
+ linesAdded: change.linesAdded,
685
+ linesRemoved: change.linesRemoved
686
+ });
687
+ }
688
+ if (itemType === "commandExecution") {
689
+ const summary = summarizeCommand(item, method);
690
+ return eventBase(context, method, params, {
691
+ itemId,
692
+ itemType,
693
+ kind: "command",
694
+ phase,
695
+ title: phase === "failed" ? "Command failed"
696
+ : phase === "completed" ? "Command completed"
697
+ : "Command started",
698
+ detail: summary.command,
699
+ command: summary.command,
700
+ cwd: summary.cwd ?? undefined,
701
+ path: summary.cwd
702
+ });
703
+ }
704
+ if (itemType === "enteredReviewMode" || itemType === "exitedReviewMode") {
705
+ return eventBase(context, method, params, {
706
+ itemId,
707
+ itemType,
708
+ kind: "item",
709
+ phase,
710
+ title: itemType === "enteredReviewMode" ? "Review started" : "Review finished",
711
+ detail: shorten(asString(item.review) ?? itemType)
712
+ });
713
+ }
714
+ if (itemType === "collabToolCall" || itemType === "collabAgentToolCall") {
715
+ const detail = summarizeCollabAgentTool(item);
716
+ return eventBase(context, method, params, {
717
+ itemId,
718
+ itemType,
719
+ kind: "subagent",
720
+ phase,
721
+ title: phase === "failed" ? "Subagent failed"
722
+ : phase === "completed" ? "Subagent updated"
723
+ : "Subagent started",
724
+ detail: shorten(detail)
725
+ });
726
+ }
727
+ if (itemType === "agentMessage") {
728
+ const messageText = asString(item.text);
729
+ if (!isMeaningfulAgentText(messageText)) {
730
+ return null;
731
+ }
732
+ return eventBase(context, method, params, {
733
+ itemId,
734
+ itemType,
735
+ kind: "message",
736
+ phase,
737
+ title: phase === "completed" ? "Reply completed" : "Reply updated",
738
+ detail: shorten(messageText)
739
+ });
740
+ }
741
+ if (itemType === "plan") {
742
+ return eventBase(context, method, params, {
743
+ itemId,
744
+ itemType,
745
+ kind: "turn",
746
+ phase: "updated",
747
+ title: "Plan updated",
748
+ detail: shorten(asString(item.text) ?? "Plan")
749
+ });
750
+ }
751
+ if (itemType === "dynamicToolCall" || itemType === "mcpToolCall") {
752
+ return eventBase(context, method, params, {
753
+ itemId,
754
+ itemType,
755
+ kind: "tool",
756
+ phase,
757
+ title: itemType === "dynamicToolCall"
758
+ ? (phase === "failed" ? "Tool failed" : phase === "completed" ? "Tool completed" : "Tool started")
759
+ : (phase === "failed" ? "MCP tool failed" : phase === "completed" ? "MCP tool completed" : "MCP tool started"),
760
+ detail: summarizeTool(item).detail
761
+ });
762
+ }
763
+ if (itemType === "webSearch") {
764
+ return eventBase(context, method, params, {
765
+ itemId,
766
+ itemType,
767
+ kind: "tool",
768
+ phase,
769
+ title: phase === "failed" ? "Web search failed"
770
+ : phase === "completed" ? "Web search completed"
771
+ : "Web search started",
772
+ detail: shorten((0, web_search_1.summarizeWebSearch)(item))
773
+ });
774
+ }
775
+ if (itemType === "imageView") {
776
+ return eventBase(context, method, params, {
777
+ itemId,
778
+ itemType,
779
+ kind: "item",
780
+ phase,
781
+ title: phase === "completed" ? "Image viewed" : "Viewing image",
782
+ detail: shorten(asString(item.path) ?? "Image")
783
+ });
784
+ }
785
+ if (itemType === "reasoning") {
786
+ return eventBase(context, method, params, {
787
+ itemId,
788
+ itemType,
789
+ kind: "item",
790
+ phase,
791
+ title: "Reasoning updated",
792
+ detail: shorten(asString(item.text) ?? asString(item.summary) ?? "Reasoning")
793
+ });
794
+ }
795
+ if (itemType === "contextCompaction") {
796
+ return eventBase(context, method, params, {
797
+ itemId,
798
+ itemType,
799
+ kind: "item",
800
+ phase,
801
+ title: "Context compacted",
802
+ detail: "Conversation history compacted"
803
+ });
804
+ }
805
+ return eventBase(context, method, params, {
806
+ itemId,
807
+ itemType,
808
+ kind: "item",
809
+ phase,
810
+ title: `Item ${phase}`,
811
+ detail: itemType
812
+ });
813
+ }
814
+ function buildDashboardEventFromAppServerMessage(context, message) {
815
+ const method = message.method;
816
+ const params = asRecord(message.params) ?? {};
817
+ const requestId = "id" in message ? String(message.id) : undefined;
818
+ switch (method) {
819
+ case "error": {
820
+ const detail = diagnosticMessage(params, "message", "error") || "Codex app-server error";
821
+ return eventBase(context, method, params, {
822
+ kind: "item",
823
+ phase: "failed",
824
+ title: "Codex error",
825
+ detail: shorten(detail)
826
+ });
827
+ }
828
+ case "warning":
829
+ case "guardianWarning": {
830
+ const detail = diagnosticMessage(params, "message") || "Codex warning";
831
+ return eventBase(context, method, params, {
832
+ kind: "item",
833
+ phase: "failed",
834
+ title: method === "guardianWarning" ? "Guardian warning" : "Codex warning",
835
+ detail: shorten(detail)
836
+ });
837
+ }
838
+ case "configWarning": {
839
+ const detail = diagnosticMessage(params, "details", "summary") || "Configuration warning";
840
+ return eventBase(context, method, params, {
841
+ kind: "item",
842
+ phase: "failed",
843
+ title: "Config warning",
844
+ detail: shorten(detail),
845
+ path: asString(params.path) ?? null
846
+ });
847
+ }
848
+ case "deprecationNotice": {
849
+ const detail = diagnosticMessage(params, "details", "summary") || "Deprecation notice";
850
+ return eventBase(context, method, params, {
851
+ kind: "item",
852
+ phase: "updated",
853
+ title: "Deprecation notice",
854
+ detail: shorten(detail)
855
+ });
856
+ }
857
+ case "thread/started":
858
+ case "thread/archived":
859
+ case "thread/unarchived":
860
+ case "thread/closed":
861
+ return eventBase(context, method, params, {
862
+ kind: "status",
863
+ phase: method === "thread/started" ? "started"
864
+ : method === "thread/archived" || method === "thread/closed" ? "completed"
865
+ : "updated",
866
+ title: method === "thread/started" ? "Thread started"
867
+ : method === "thread/archived" ? "Thread archived"
868
+ : method === "thread/unarchived" ? "Thread unarchived"
869
+ : "Thread closed",
870
+ detail: extractThreadId(params) ?? method
871
+ });
872
+ case "thread/tokenUsage/updated":
873
+ return eventBase(context, method, params, {
874
+ kind: "status",
875
+ phase: "updated",
876
+ title: "Token usage updated",
877
+ detail: "Token usage updated"
878
+ });
879
+ case "thread/status/changed": {
880
+ const status = asRecord(params.status);
881
+ const type = asString(status?.type) ?? "unknown";
882
+ const activeFlags = asStringArray(status?.activeFlags);
883
+ return eventBase(context, method, params, {
884
+ kind: "status",
885
+ phase: activeFlags.includes("waitingOnApproval") || activeFlags.includes("waitingOnUserInput")
886
+ ? "waiting"
887
+ : "updated",
888
+ title: activeFlags.includes("waitingOnApproval") ? "Waiting on approval"
889
+ : activeFlags.includes("waitingOnUserInput") ? "Waiting on input"
890
+ : `Thread ${type}`,
891
+ detail: activeFlags.length > 0 ? activeFlags.join(", ") : type
892
+ });
893
+ }
894
+ case "turn/started": {
895
+ const turn = asRecord(params.turn);
896
+ const turnId = extractTurnId(turn ?? params);
897
+ return eventBase(context, method, params, {
898
+ turnId,
899
+ kind: "turn",
900
+ phase: "started",
901
+ title: "Turn started",
902
+ detail: turnId ?? method
903
+ });
904
+ }
905
+ case "turn/completed": {
906
+ const turn = asRecord(params.turn);
907
+ const turnId = extractTurnId(turn ?? params);
908
+ const turnStatus = asString(turn?.status) ?? "completed";
909
+ const phase = turnStatus === "failed" ? "failed"
910
+ : turnStatus === "interrupted" ? "interrupted"
911
+ : "completed";
912
+ const error = asRecord(turn?.error);
913
+ return eventBase(context, method, params, {
914
+ turnId,
915
+ kind: "turn",
916
+ phase,
917
+ title: phase === "failed" ? "Turn failed"
918
+ : phase === "interrupted" ? "Turn interrupted"
919
+ : "Turn completed",
920
+ detail: phase === "failed"
921
+ ? shorten(asString(error?.message) ?? turnId ?? method)
922
+ : turnId ?? method
923
+ });
924
+ }
925
+ case "turn/interrupted":
926
+ return eventBase(context, method, params, {
927
+ kind: "turn",
928
+ phase: "interrupted",
929
+ title: "Turn interrupted",
930
+ detail: extractTurnId(params) ?? method
931
+ });
932
+ case "turn/failed":
933
+ return eventBase(context, method, params, {
934
+ kind: "turn",
935
+ phase: "failed",
936
+ title: "Turn failed",
937
+ detail: shorten(asString(params.message) ?? extractTurnId(params) ?? method)
938
+ });
939
+ case "turn/plan/updated":
940
+ return eventBase(context, method, params, {
941
+ kind: "turn",
942
+ phase: "updated",
943
+ title: "Plan updated",
944
+ detail: summarizePlanUpdate(params)
945
+ });
946
+ case "turn/diff/updated":
947
+ return eventBase(context, method, params, {
948
+ kind: "turn",
949
+ phase: "updated",
950
+ title: "Diff updated",
951
+ detail: summarizeDiffUpdate(params)
952
+ });
953
+ case "item/started":
954
+ case "item/completed":
955
+ return buildEventFromItem(context, method, params);
956
+ case "item/agentMessage/delta":
957
+ return eventBase(context, method, params, {
958
+ itemId: extractItemId(params),
959
+ kind: "message",
960
+ phase: "updated",
961
+ title: "Reply updated",
962
+ detail: shorten(asString(params.delta) ?? asString(params.textDelta) ?? "Reply")
963
+ });
964
+ case "item/plan/delta":
965
+ return eventBase(context, method, params, {
966
+ itemId: extractItemId(params),
967
+ kind: "turn",
968
+ phase: "updated",
969
+ title: "Plan streaming",
970
+ detail: shorten(asString(params.delta) ?? asString(params.textDelta) ?? "Plan")
971
+ });
972
+ case "item/reasoning/summaryTextDelta":
973
+ case "item/reasoning/summaryPartAdded":
974
+ case "item/reasoning/textDelta":
975
+ return eventBase(context, method, params, {
976
+ itemId: extractItemId(params),
977
+ kind: "message",
978
+ phase: "updated",
979
+ title: "Reasoning updated",
980
+ detail: shorten(asString(params.delta) ?? asString(params.textDelta) ?? "Reasoning")
981
+ });
982
+ case "item/commandExecution/outputDelta":
983
+ return eventBase(context, method, params, {
984
+ itemId: extractItemId(params),
985
+ kind: "command",
986
+ phase: "updated",
987
+ title: "Command output",
988
+ detail: shorten(asString(params.delta) ?? asString(params.textDelta) ?? "Command output")
989
+ });
990
+ case "item/commandExecution/terminalInteraction":
991
+ return eventBase(context, method, params, {
992
+ itemId: extractItemId(params),
993
+ kind: "command",
994
+ phase: "updated",
995
+ title: "Terminal input",
996
+ detail: shorten(asString(params.stdin) ?? "Terminal input"),
997
+ command: asString(params.stdin)
998
+ });
999
+ case "item/fileChange/outputDelta":
1000
+ return eventBase(context, method, params, {
1001
+ itemId: extractItemId(params),
1002
+ kind: "fileChange",
1003
+ phase: "updated",
1004
+ title: "Patch updated",
1005
+ detail: shorten(asString(params.delta) ?? asString(params.textDelta) ?? "Patch output")
1006
+ });
1007
+ case "item/fileChange/patchUpdated": {
1008
+ const change = summarizeFileChange({ changes: params.changes }, primaryPath(params));
1009
+ return eventBase(context, method, params, {
1010
+ itemId: extractItemId(params),
1011
+ kind: "fileChange",
1012
+ phase: "updated",
1013
+ title: "Patch updated",
1014
+ detail: change.detail,
1015
+ path: change.path,
1016
+ action: change.action,
1017
+ isImage: change.isImage,
1018
+ linesAdded: change.linesAdded,
1019
+ linesRemoved: change.linesRemoved
1020
+ });
1021
+ }
1022
+ case "item/mcpToolCall/progress":
1023
+ return eventBase(context, method, params, {
1024
+ itemId: extractItemId(params),
1025
+ itemType: "mcpToolCall",
1026
+ kind: "tool",
1027
+ phase: "updated",
1028
+ title: "MCP tool progress",
1029
+ detail: shorten(asString(params.message) ?? "MCP tool progress")
1030
+ });
1031
+ case "hook/started":
1032
+ case "hook/completed":
1033
+ return eventBase(context, method, params, {
1034
+ itemType: "hook",
1035
+ kind: "tool",
1036
+ phase: method === "hook/completed" ? "completed" : "started",
1037
+ title: method === "hook/completed" ? "Hook completed" : "Hook started",
1038
+ detail: summarizeHookRun(params),
1039
+ path: primaryPath(params.run)
1040
+ });
1041
+ case "item/autoApprovalReview/started":
1042
+ case "item/autoApprovalReview/completed": {
1043
+ const review = asRecord(params.review);
1044
+ const actionDetail = summarizeGuardianAction(params.action);
1045
+ const riskLevel = asString(review?.riskLevel);
1046
+ return eventBase(context, method, params, {
1047
+ itemId: extractItemId(params),
1048
+ kind: "item",
1049
+ phase: method.endsWith("/completed") ? "completed" : "started",
1050
+ title: method.endsWith("/completed") ? "Approval review completed" : "Approval review started",
1051
+ detail: shorten(riskLevel ? `${actionDetail} (${riskLevel})` : actionDetail)
1052
+ });
1053
+ }
1054
+ case "item/commandExecution/requestApproval": {
1055
+ const networkApprovalContext = asRecord(params.networkApprovalContext) ?? null;
1056
+ return eventBase(context, method, params, {
1057
+ requestId,
1058
+ itemId: extractItemId(params),
1059
+ kind: "approval",
1060
+ phase: "waiting",
1061
+ title: networkApprovalContext ? "Network approval requested" : "Command approval requested",
1062
+ detail: shorten(asString(params.command) ?? asString(params.reason) ?? "Approval requested"),
1063
+ command: asString(params.command),
1064
+ cwd: asString(params.cwd),
1065
+ reason: asString(params.reason),
1066
+ availableDecisions: asStringArray(params.availableDecisions),
1067
+ networkApprovalContext
1068
+ });
1069
+ }
1070
+ case "item/fileChange/requestApproval":
1071
+ return eventBase(context, method, params, {
1072
+ requestId,
1073
+ itemId: extractItemId(params),
1074
+ kind: "approval",
1075
+ phase: "waiting",
1076
+ title: "File approval requested",
1077
+ detail: shorten(asString(params.reason) ?? primaryPath(params) ?? "Approval requested"),
1078
+ reason: asString(params.reason),
1079
+ grantRoot: asString(params.grantRoot),
1080
+ availableDecisions: asStringArray(params.availableDecisions)
1081
+ });
1082
+ case "item/permissions/requestApproval":
1083
+ return eventBase(context, method, params, {
1084
+ requestId,
1085
+ itemId: extractItemId(params),
1086
+ kind: "approval",
1087
+ phase: "waiting",
1088
+ title: "Permission approval requested",
1089
+ detail: shorten(asString(params.reason) ?? "Permission approval requested"),
1090
+ cwd: asString(params.cwd),
1091
+ reason: asString(params.reason),
1092
+ availableDecisions: ["accept", "acceptForSession"]
1093
+ });
1094
+ case "item/tool/requestUserInput":
1095
+ return eventBase(context, method, params, {
1096
+ requestId,
1097
+ itemId: extractItemId(params),
1098
+ kind: "input",
1099
+ phase: "waiting",
1100
+ title: "User input requested",
1101
+ detail: shorten(asString(params.reason) ?? asString(params.prompt) ?? "Needs input"),
1102
+ reason: asString(params.reason),
1103
+ availableDecisions: asStringArray(params.availableDecisions)
1104
+ });
1105
+ case "mcpServer/elicitation/request":
1106
+ return eventBase(context, method, params, {
1107
+ requestId,
1108
+ kind: "input",
1109
+ phase: "waiting",
1110
+ title: "MCP input requested",
1111
+ detail: shorten(asString(params.message) ?? "MCP server needs input"),
1112
+ reason: asString(params.message)
1113
+ });
1114
+ case "applyPatchApproval":
1115
+ return eventBase(context, method, params, {
1116
+ requestId,
1117
+ kind: "approval",
1118
+ phase: "waiting",
1119
+ title: "Patch approval requested",
1120
+ detail: shorten(asString(params.reason) ?? primaryPath(params) ?? "Patch approval requested"),
1121
+ reason: asString(params.reason),
1122
+ grantRoot: asString(params.grantRoot),
1123
+ availableDecisions: ["accept", "acceptForSession", "decline", "cancel"]
1124
+ });
1125
+ case "execCommandApproval": {
1126
+ const command = Array.isArray(params.command)
1127
+ ? params.command.filter((entry) => typeof entry === "string").join(" ")
1128
+ : undefined;
1129
+ return eventBase(context, method, params, {
1130
+ requestId,
1131
+ kind: "approval",
1132
+ phase: "waiting",
1133
+ title: "Command approval requested",
1134
+ detail: shorten(command ?? asString(params.reason) ?? "Command approval requested"),
1135
+ command,
1136
+ cwd: asString(params.cwd),
1137
+ reason: asString(params.reason),
1138
+ availableDecisions: ["accept", "acceptForSession", "decline", "cancel"]
1139
+ });
1140
+ }
1141
+ case "item/tool/call":
1142
+ return eventBase(context, method, params, {
1143
+ requestId,
1144
+ itemId: extractItemId(params),
1145
+ itemType: "dynamicToolCall",
1146
+ kind: "tool",
1147
+ phase: "started",
1148
+ title: "Tool call requested",
1149
+ detail: shorten(summarizeDynamicTool(params))
1150
+ });
1151
+ case "rawResponseItem/completed": {
1152
+ const item = asRecord(params.item);
1153
+ return eventBase(context, method, params, {
1154
+ itemId: extractItemId(item ?? params),
1155
+ itemType: asString(item?.type) ?? "responseItem",
1156
+ kind: "item",
1157
+ phase: "completed",
1158
+ title: "Response item completed",
1159
+ detail: summarizeRawResponseItem(item)
1160
+ });
1161
+ }
1162
+ case "model/rerouted":
1163
+ return eventBase(context, method, params, {
1164
+ kind: "item",
1165
+ phase: "updated",
1166
+ title: "Model rerouted",
1167
+ detail: shorten(`${asString(params.fromModel) ?? "model"} -> ${asString(params.toModel) ?? "model"}`)
1168
+ });
1169
+ case "model/verification":
1170
+ return eventBase(context, method, params, {
1171
+ kind: "item",
1172
+ phase: "updated",
1173
+ title: "Model verification",
1174
+ detail: asStringArray(params.verifications).join(", ") || "Model verification"
1175
+ });
1176
+ case "mcpServer/startupStatus/updated": {
1177
+ const status = asString(params.status) ?? "updated";
1178
+ return eventBase(context, method, params, {
1179
+ kind: "tool",
1180
+ phase: status === "failed" || status === "cancelled" ? "failed"
1181
+ : status === "ready" ? "completed"
1182
+ : "started",
1183
+ title: status === "failed" ? "MCP server failed"
1184
+ : status === "ready" ? "MCP server ready"
1185
+ : "MCP server starting",
1186
+ detail: shorten(asString(params.error) ?? asString(params.name) ?? status)
1187
+ });
1188
+ }
1189
+ case "mcpServer/oauthLogin/completed": {
1190
+ const success = params.success === true;
1191
+ return eventBase(context, method, params, {
1192
+ kind: "tool",
1193
+ phase: success ? "completed" : "failed",
1194
+ title: success ? "MCP login completed" : "MCP login failed",
1195
+ detail: shorten(asString(params.error) ?? asString(params.name) ?? "MCP OAuth")
1196
+ });
1197
+ }
1198
+ case "account/rateLimits/updated":
1199
+ return eventBase(context, method, params, {
1200
+ kind: "status",
1201
+ phase: "updated",
1202
+ title: "Rate limits updated",
1203
+ detail: rateLimitDetail(params)
1204
+ });
1205
+ case "windows/worldWritableWarning": {
1206
+ const sampleCount = Array.isArray(params.samplePaths) ? params.samplePaths.length : 0;
1207
+ const extraCount = typeof params.extraCount === "number" && Number.isFinite(params.extraCount) ? params.extraCount : 0;
1208
+ return eventBase(context, method, params, {
1209
+ kind: "item",
1210
+ phase: "failed",
1211
+ title: "Windows permission warning",
1212
+ detail: `${sampleCount + extraCount} world-writable path${sampleCount + extraCount === 1 ? "" : "s"} found`
1213
+ });
1214
+ }
1215
+ case "windowsSandbox/setupCompleted": {
1216
+ const success = params.success === true;
1217
+ return eventBase(context, method, params, {
1218
+ kind: "item",
1219
+ phase: success ? "completed" : "failed",
1220
+ title: success ? "Windows sandbox ready" : "Windows sandbox failed",
1221
+ detail: shorten(asString(params.error) ?? asString(params.mode) ?? "Windows sandbox setup")
1222
+ });
1223
+ }
1224
+ case "serverRequest/resolved": {
1225
+ const pending = context.pendingRequest ?? null;
1226
+ const resolvedRequestId = asString(params.requestId) ?? requestId;
1227
+ if (pending) {
1228
+ return eventBase(context, method, params, {
1229
+ requestId: resolvedRequestId ?? pending.requestId,
1230
+ threadId: pending.threadId,
1231
+ turnId: pending.turnId,
1232
+ itemId: pending.itemId,
1233
+ kind: pending.kind === "approval" ? "approval" : "input",
1234
+ phase: "completed",
1235
+ title: pending.kind === "approval" ? "Approval resolved" : "Input resolved",
1236
+ detail: pending.reason ?? pending.command ?? pending.kind
1237
+ });
1238
+ }
1239
+ return eventBase(context, method, params, {
1240
+ requestId: resolvedRequestId,
1241
+ kind: "other",
1242
+ phase: "completed",
1243
+ title: "Request resolved",
1244
+ detail: resolvedRequestId ?? method
1245
+ });
1246
+ }
1247
+ default:
1248
+ return null;
1249
+ }
1250
+ }
1251
+ function appServerDiagnosticNotePrefix(method) {
1252
+ switch (method) {
1253
+ case "error":
1254
+ return "Codex app-server error:";
1255
+ case "warning":
1256
+ return "Codex warning:";
1257
+ case "guardianWarning":
1258
+ return "Codex guardian warning:";
1259
+ case "configWarning":
1260
+ return "Codex config warning:";
1261
+ case "deprecationNotice":
1262
+ return "Codex deprecation notice:";
1263
+ case "mcpServer/startupStatus/updated":
1264
+ return "Codex MCP server status:";
1265
+ case "mcpServer/oauthLogin/completed":
1266
+ return "Codex MCP login:";
1267
+ case "account/rateLimits/updated":
1268
+ return "Codex rate limit:";
1269
+ case "windows/worldWritableWarning":
1270
+ return "Codex Windows permission warning:";
1271
+ case "windowsSandbox/setupCompleted":
1272
+ return "Codex Windows sandbox:";
1273
+ default:
1274
+ return `Codex ${method}:`;
1275
+ }
1276
+ }
1277
+ function buildAppServerDiagnosticNote(message) {
1278
+ const params = asRecord(message.params) ?? {};
1279
+ const prefix = appServerDiagnosticNotePrefix(message.method);
1280
+ switch (message.method) {
1281
+ case "error": {
1282
+ const detail = diagnosticMessage(params, "message", "error") || "Unknown app-server error";
1283
+ return `${prefix} ${shorten(detail, 160)}`;
1284
+ }
1285
+ case "warning": {
1286
+ const detail = diagnosticMessage(params, "message") || "Warning";
1287
+ return `${prefix} ${shorten(detail, 160)}`;
1288
+ }
1289
+ case "guardianWarning": {
1290
+ const detail = diagnosticMessage(params, "message") || "Guardian warning";
1291
+ return `${prefix} ${shorten(detail, 160)}`;
1292
+ }
1293
+ case "configWarning": {
1294
+ const summary = diagnosticMessage(params, "summary") || "Configuration warning";
1295
+ const details = diagnosticMessage(params, "details");
1296
+ return `${prefix} ${shorten(details ? `${summary}: ${details}` : summary, 160)}`;
1297
+ }
1298
+ case "deprecationNotice": {
1299
+ const summary = diagnosticMessage(params, "summary") || "Deprecation notice";
1300
+ const details = diagnosticMessage(params, "details");
1301
+ return `${prefix} ${shorten(details ? `${summary}: ${details}` : summary, 160)}`;
1302
+ }
1303
+ case "mcpServer/startupStatus/updated": {
1304
+ const status = asString(params.status);
1305
+ if (status !== "failed" && status !== "cancelled") {
1306
+ return null;
1307
+ }
1308
+ const name = asString(params.name) ?? "MCP server";
1309
+ const error = asString(params.error);
1310
+ return `${prefix} ${shorten(error ? `${name} ${status}: ${error}` : `${name} ${status}`, 160)}`;
1311
+ }
1312
+ case "mcpServer/oauthLogin/completed": {
1313
+ if (params.success === true) {
1314
+ return null;
1315
+ }
1316
+ const name = asString(params.name) ?? "MCP server";
1317
+ const error = asString(params.error);
1318
+ return `${prefix} ${shorten(error ? `${name}: ${error}` : `${name} failed`, 160)}`;
1319
+ }
1320
+ case "account/rateLimits/updated": {
1321
+ const detail = rateLimitDetail(params);
1322
+ return detail === "Rate limits updated" ? null : `${prefix} ${shorten(detail, 160)}`;
1323
+ }
1324
+ case "windows/worldWritableWarning": {
1325
+ const sampleCount = Array.isArray(params.samplePaths) ? params.samplePaths.length : 0;
1326
+ const extraCount = typeof params.extraCount === "number" && Number.isFinite(params.extraCount) ? params.extraCount : 0;
1327
+ if (sampleCount + extraCount <= 0 && params.failedScan !== true) {
1328
+ return null;
1329
+ }
1330
+ const scanDetail = params.failedScan === true ? " scan incomplete" : "";
1331
+ return `${prefix} ${sampleCount + extraCount} world-writable path${sampleCount + extraCount === 1 ? "" : "s"} found${scanDetail}`;
1332
+ }
1333
+ case "windowsSandbox/setupCompleted": {
1334
+ if (params.success === true) {
1335
+ return null;
1336
+ }
1337
+ return `${prefix} ${shorten(asString(params.error) ?? "setup failed", 160)}`;
1338
+ }
1339
+ default:
1340
+ return null;
1341
+ }
1342
+ }
1343
+ function buildNeedsUserStateFromServerRequest(message) {
1344
+ const params = asRecord(message.params) ?? {};
1345
+ const threadId = extractThreadId(params);
1346
+ if (!threadId) {
1347
+ return null;
1348
+ }
1349
+ const requestId = String(message.id);
1350
+ if (message.method === "item/commandExecution/requestApproval") {
1351
+ return {
1352
+ kind: "approval",
1353
+ requestId,
1354
+ threadId,
1355
+ createdAt: new Date().toISOString(),
1356
+ requestMethod: message.method,
1357
+ responseKind: "approvalDecision",
1358
+ turnId: extractTurnId(params),
1359
+ itemId: extractItemId(params),
1360
+ reason: asString(params.reason),
1361
+ command: asString(params.command),
1362
+ cwd: asString(params.cwd),
1363
+ availableDecisions: asStringArray(params.availableDecisions),
1364
+ networkApprovalContext: asRecord(params.networkApprovalContext) ?? null
1365
+ };
1366
+ }
1367
+ if (message.method === "item/fileChange/requestApproval") {
1368
+ return {
1369
+ kind: "approval",
1370
+ requestId,
1371
+ threadId,
1372
+ createdAt: new Date().toISOString(),
1373
+ requestMethod: message.method,
1374
+ responseKind: "approvalDecision",
1375
+ turnId: extractTurnId(params),
1376
+ itemId: extractItemId(params),
1377
+ reason: asString(params.reason),
1378
+ grantRoot: asString(params.grantRoot),
1379
+ availableDecisions: asStringArray(params.availableDecisions)
1380
+ };
1381
+ }
1382
+ if (message.method === "item/tool/requestUserInput") {
1383
+ return {
1384
+ kind: "input",
1385
+ requestId,
1386
+ threadId,
1387
+ createdAt: new Date().toISOString(),
1388
+ requestMethod: message.method,
1389
+ responseKind: "toolInput",
1390
+ turnId: extractTurnId(params),
1391
+ itemId: extractItemId(params),
1392
+ reason: asString(params.reason) ?? asString(params.prompt),
1393
+ questions: asNeedsUserQuestions(params.questions),
1394
+ availableDecisions: asStringArray(params.availableDecisions)
1395
+ };
1396
+ }
1397
+ if (message.method === "mcpServer/elicitation/request") {
1398
+ const schema = asRecord(params.requestedSchema);
1399
+ return {
1400
+ kind: "input",
1401
+ requestId,
1402
+ threadId,
1403
+ createdAt: new Date().toISOString(),
1404
+ requestMethod: message.method,
1405
+ responseKind: "mcpElicitation",
1406
+ turnId: extractTurnId(params),
1407
+ reason: asString(params.message),
1408
+ questions: parseMcpElicitationQuestions(schema),
1409
+ requestedSchema: schema
1410
+ };
1411
+ }
1412
+ if (message.method === "item/permissions/requestApproval") {
1413
+ return {
1414
+ kind: "approval",
1415
+ requestId,
1416
+ threadId,
1417
+ createdAt: new Date().toISOString(),
1418
+ requestMethod: message.method,
1419
+ responseKind: "permissionsApproval",
1420
+ turnId: extractTurnId(params),
1421
+ itemId: extractItemId(params),
1422
+ reason: asString(params.reason),
1423
+ cwd: asString(params.cwd),
1424
+ availableDecisions: ["accept", "acceptForSession"],
1425
+ requestedPermissions: asRecord(params.permissions)
1426
+ };
1427
+ }
1428
+ if (message.method === "applyPatchApproval") {
1429
+ return {
1430
+ kind: "approval",
1431
+ requestId,
1432
+ threadId,
1433
+ createdAt: new Date().toISOString(),
1434
+ requestMethod: message.method,
1435
+ responseKind: "legacyReview",
1436
+ reason: asString(params.reason),
1437
+ grantRoot: asString(params.grantRoot),
1438
+ availableDecisions: ["accept", "acceptForSession", "decline", "cancel"]
1439
+ };
1440
+ }
1441
+ if (message.method === "execCommandApproval") {
1442
+ const command = Array.isArray(params.command)
1443
+ ? params.command.filter((entry) => typeof entry === "string").join(" ")
1444
+ : undefined;
1445
+ return {
1446
+ kind: "approval",
1447
+ requestId,
1448
+ threadId,
1449
+ createdAt: new Date().toISOString(),
1450
+ requestMethod: message.method,
1451
+ responseKind: "legacyReview",
1452
+ reason: asString(params.reason),
1453
+ command,
1454
+ cwd: asString(params.cwd),
1455
+ availableDecisions: ["accept", "acceptForSession", "decline", "cancel"]
1456
+ };
1457
+ }
1458
+ return null;
1459
+ }
1460
+ function shouldStopDormantThreadAfterAppServerNotification(input) {
1461
+ return shouldStopDormantThreadAfterNotification(input);
1462
+ }
1463
+ //# sourceMappingURL=events.js.map