farming-code 2.2.30 → 2.2.32

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 (377) hide show
  1. package/THIRD_PARTY_NOTICES.md +7 -0
  2. package/backend/acp/{client-services.js → client-services.cjs} +132 -134
  3. package/backend/acp/packaged-claude-acp.cjs +37 -0
  4. package/backend/acp/packaged-codex-acp.cjs +37 -0
  5. package/backend/acp/patch-decisions.cjs +182 -0
  6. package/backend/acp/permission-security.cjs +131 -0
  7. package/backend/{acp-checkpoint-store.js → acp-checkpoint-store.cjs} +90 -59
  8. package/backend/{acp-runtime.js → acp-runtime.cjs} +1220 -1112
  9. package/backend/acp-session-state.cjs +622 -0
  10. package/backend/acp-transcript.cjs +525 -0
  11. package/backend/agent-env.cjs +257 -0
  12. package/backend/agent-extension-discovery.cjs +452 -0
  13. package/backend/agent-extension-inventory.cjs +116 -0
  14. package/backend/agent-json-stream.cjs +283 -0
  15. package/backend/agent-lifecycle-journal.cjs +185 -0
  16. package/backend/{agent-manager.js → agent-manager.cjs} +3116 -4275
  17. package/backend/agent-order-transaction.cjs +85 -0
  18. package/backend/agent-order.cjs +159 -0
  19. package/backend/agent-provider-session.cjs +98 -0
  20. package/backend/agent-runtime-binding.cjs +179 -0
  21. package/backend/agent-session-history.cjs +1022 -0
  22. package/backend/agent-session-inventory.cjs +291 -0
  23. package/backend/async-cache.cjs +104 -0
  24. package/backend/atomic-json-store.cjs +67 -0
  25. package/backend/auth.cjs +261 -0
  26. package/backend/authoritative-inventory-cache.cjs +383 -0
  27. package/backend/business-health.cjs +68 -0
  28. package/backend/chat-runtime.cjs +50 -0
  29. package/backend/claude-settings.cjs +132 -0
  30. package/backend/cli-agents.cjs +435 -0
  31. package/backend/codex-context-window.cjs +196 -0
  32. package/backend/codex-models.cjs +228 -0
  33. package/backend/codex-session-archive.cjs +82 -0
  34. package/backend/codex-session-history.cjs +590 -0
  35. package/backend/{codex-terminal-profile.js → codex-terminal-profile.cjs} +149 -155
  36. package/backend/codex-transcript-sanitizer.cjs +130 -0
  37. package/backend/codex-transcript.cjs +2107 -0
  38. package/backend/command-runner-child.cjs +105 -0
  39. package/backend/config-manager.cjs +1263 -0
  40. package/backend/control-api.cjs +439 -0
  41. package/backend/data/LICENSE.cua +21 -0
  42. package/backend/executable-discovery.cjs +204 -0
  43. package/backend/farming-agent-bootstrap.cjs +81 -0
  44. package/backend/farming-agent-bootstrap.zh_cn.md +6 -2
  45. package/backend/{farming-app-cli.js → farming-app-cli.cjs} +441 -493
  46. package/backend/farming-cli.cjs +414 -0
  47. package/backend/farming-net-pass.cjs +319 -0
  48. package/backend/farming-net-registry.cjs +123 -0
  49. package/backend/farming-net-server.cjs +309 -0
  50. package/backend/farming-session-store.cjs +651 -0
  51. package/backend/git-worktree-info.cjs +181 -0
  52. package/backend/haiku-token.cjs +828 -0
  53. package/backend/index-html.cjs +96 -0
  54. package/backend/input-parts.cjs +68 -0
  55. package/backend/input-routing.cjs +40 -0
  56. package/backend/{local-session-engine.js → local-session-engine.cjs} +276 -282
  57. package/backend/main-agent-skills.cjs +309 -0
  58. package/backend/main-page-session.cjs +132 -0
  59. package/backend/native-pty-controller-generation.cjs +139 -0
  60. package/backend/{native-pty-host-client.js → native-pty-host-client.cjs} +338 -346
  61. package/backend/native-pty-host-identity.cjs +125 -0
  62. package/backend/native-pty-host-path.cjs +68 -0
  63. package/backend/{native-pty-host.js → native-pty-host.cjs} +480 -569
  64. package/backend/native-session-engine.cjs +296 -0
  65. package/backend/network.cjs +57 -0
  66. package/backend/npm-update-helper.cjs +399 -0
  67. package/backend/packaged-node-pty.cjs +120 -0
  68. package/backend/preview-session-manager.cjs +89 -0
  69. package/backend/provider-adapters.cjs +492 -0
  70. package/backend/provider-home-configuration.cjs +211 -0
  71. package/backend/provider-session-id.cjs +79 -0
  72. package/backend/provider-session-service.cjs +333 -0
  73. package/backend/qr-share-tickets.cjs +119 -0
  74. package/backend/resource-broadcast-protocol.cjs +50 -0
  75. package/backend/review-diff-router.cjs +202 -0
  76. package/backend/review-diff-service.cjs +1267 -0
  77. package/backend/review-session-router.cjs +93 -0
  78. package/backend/review-session-service.cjs +470 -0
  79. package/backend/review-session-store.cjs +161 -0
  80. package/backend/review-state-router.cjs +132 -0
  81. package/backend/review-state-store.cjs +299 -0
  82. package/backend/run-history-store.cjs +97 -0
  83. package/backend/runtime-dependency-manager.cjs +893 -0
  84. package/backend/runtime-executable-invocation.cjs +37 -0
  85. package/backend/runtime-observation.cjs +96 -0
  86. package/backend/server-process-identity.cjs +70 -0
  87. package/backend/server.cjs +3356 -0
  88. package/backend/session-engine-bridge.cjs +144 -0
  89. package/backend/session-engine-router.cjs +105 -0
  90. package/backend/session-engine.cjs +64 -0
  91. package/backend/session-stream-protocol.cjs +181 -0
  92. package/backend/shell-busy-integration.cjs +442 -0
  93. package/backend/slash-command-discovery.cjs +423 -0
  94. package/backend/storage-layout.cjs +263 -0
  95. package/backend/system-monitor.cjs +96 -0
  96. package/backend/terminal-attach-checkpoint.cjs +73 -0
  97. package/backend/terminal-exit-quiescence.cjs +57 -0
  98. package/backend/{terminal-reducer-flow-control.js → terminal-reducer-flow-control.cjs} +45 -22
  99. package/backend/terminal-runtime-cleanup.cjs +99 -0
  100. package/backend/{terminal-screen-state.js → terminal-screen-state.cjs} +100 -108
  101. package/backend/{terminal-screen-worker-pool.js → terminal-screen-worker-pool.cjs} +89 -79
  102. package/backend/{terminal-screen-worker-thread.js → terminal-screen-worker-thread.cjs} +64 -65
  103. package/backend/terminal-screen-worker.cjs +352 -0
  104. package/backend/terminal-state-serialization.cjs +147 -0
  105. package/backend/{terminal-status.js → terminal-status.cjs} +137 -187
  106. package/backend/theme-manager.cjs +185 -0
  107. package/backend/{update-service.js → update-service.cjs} +258 -248
  108. package/backend/usage-forecast.cjs +95 -0
  109. package/backend/{usage-history-client.js → usage-history-client.cjs} +144 -94
  110. package/backend/usage-history-smoke.cjs +85 -0
  111. package/backend/usage-history-worker.cjs +60 -0
  112. package/backend/{usage-monitor.js → usage-monitor.cjs} +363 -390
  113. package/backend/workspace-directory.cjs +239 -0
  114. package/backend/workspace-discovery.cjs +271 -0
  115. package/backend/{workspace-file-router.js → workspace-file-router.cjs} +213 -282
  116. package/backend/{workspace-file-service.js → workspace-file-service.cjs} +1139 -1318
  117. package/backend/workspace-root-registry.cjs +192 -0
  118. package/bin/farming +1 -1
  119. package/dist/acp/codex-acp-1.1.4.mjs +18 -1
  120. package/dist/assets/App-BCkdpWB6.css +1 -0
  121. package/dist/assets/App-CRjKpaGp.js +697 -0
  122. package/dist/assets/CodeSelect-Ci8sKZPU.js +1 -0
  123. package/dist/assets/CodeSelect-T2eNzrOc.css +1 -0
  124. package/dist/assets/{FileEditorMarkdownPreview-Cs9cLv8a.js → FileEditorMarkdownPreview-V06QHlAg.js} +55 -55
  125. package/dist/assets/FileEditorPane-BX-Wjg9U.js +2 -0
  126. package/dist/assets/IconGlyphs-YhV7tqd4.js +1 -0
  127. package/dist/assets/ProjectFilesSection-BDT2_r0o.js +12 -0
  128. package/dist/assets/ReviewPage-BqAs5sG1.js +3 -0
  129. package/dist/assets/code-dark-B7eM_9G9.css +1 -0
  130. package/dist/assets/{cssMode-Bdg5RpcJ.js → cssMode-ADdAlxTO.js} +1 -1
  131. package/dist/assets/{editor.api2-D74ufkbr.js → editor.api2-BFLAr0YF.js} +162 -162
  132. package/dist/assets/file-icons-BpeqWkIB.js +1 -0
  133. package/dist/assets/{freemarker2-DfMDJfnE.js → freemarker2-C90q5jrp.js} +1 -1
  134. package/dist/assets/{handlebars-BEdPtzMT.js → handlebars-BwUQcEDq.js} +1 -1
  135. package/dist/assets/{html-B1fPb1QD.js → html-1s3uPKfh.js} +1 -1
  136. package/dist/assets/{htmlMode-CY2ZjHxH.js → htmlMode-xtKD99de.js} +1 -1
  137. package/dist/assets/{index-D-zetSol.js → index-C8MchCem.js} +3 -3
  138. package/dist/assets/{javascript-BV2OsWA0.js → javascript-Ph7ijyny.js} +1 -1
  139. package/dist/assets/{jsonMode-zd07aeuX.js → jsonMode-D-jGAnFH.js} +1 -1
  140. package/dist/assets/linkComputer-CbGyI_qx.js +1 -0
  141. package/dist/assets/{liquid-BParI24X.js → liquid-0IamE_cI.js} +1 -1
  142. package/dist/assets/{lspLanguageFeatures-BzredkoV.js → lspLanguageFeatures-BxnQunWF.js} +1 -1
  143. package/dist/assets/main-CLKXa6hf.css +1 -0
  144. package/dist/assets/{mdx-vGzUJN98.js → mdx-DdNmfivn.js} +1 -1
  145. package/dist/assets/{monaco.contribution-BmaeBQEc.js → monaco.contribution-B43jsUs1.js} +2 -2
  146. package/dist/assets/{python-CUwdLgsI.js → python-IAt4X5TS.js} +1 -1
  147. package/dist/assets/{razor-BScebUxU.js → razor-DRkFYW0S.js} +1 -1
  148. package/dist/assets/review-C8-oPKXk.css +1 -0
  149. package/dist/assets/{tsMode-DzUAibXK.js → tsMode-_d_4U2gf.js} +1 -1
  150. package/dist/assets/{typescript-D9EOeM7N.js → typescript-C7zcMq9l.js} +1 -1
  151. package/dist/assets/{workers-DAiomYZM.js → workers-D0nOyJzf.js} +1 -1
  152. package/dist/assets/workspace-editor-model-DND_Y-Bj.js +1 -0
  153. package/dist/assets/workspace-editor-monaco-BPWhgcIB.js +4 -0
  154. package/dist/assets/workspace-editor-monaco-N641qPjX.js +1 -0
  155. package/dist/assets/workspace-view-state-k1bTlJ_Z.js +13 -0
  156. package/dist/assets/{xml-wWl1dhkQ.js → xml-BR-HvxT8.js} +1 -1
  157. package/dist/assets/{yaml-Dc2WDaOZ.js → yaml-YtFQwh4q.js} +1 -1
  158. package/dist/index.html +1 -1
  159. package/extensions/browser/backend/agent-browser-runtime.cjs +1040 -0
  160. package/extensions/browser/backend/agent-capability.cjs +85 -0
  161. package/extensions/browser/backend/browser-mcp-server.cjs +655 -0
  162. package/extensions/browser/backend/browser-resource-manager.cjs +1486 -0
  163. package/extensions/browser/backend/browser-resource-store.cjs +228 -0
  164. package/extensions/browser/backend/browser-router.cjs +203 -0
  165. package/extensions/browser/backend/executable-discovery.cjs +248 -0
  166. package/extensions/browser/backend/farming-browser-client.cjs +116 -0
  167. package/extensions/browser/backend/index.cjs +32 -0
  168. package/extensions/browser/backend/managed-chromium-installer.cjs +833 -0
  169. package/extensions/browser/bin/farming-browser +16 -7
  170. package/extensions/computer/backend/agent-capability.cjs +72 -0
  171. package/extensions/computer/backend/computer-constants.cjs +59 -0
  172. package/extensions/computer/backend/computer-mcp-server.cjs +182 -0
  173. package/extensions/computer/backend/computer-resource-manager.cjs +1219 -0
  174. package/extensions/computer/backend/computer-resource-store.cjs +190 -0
  175. package/extensions/computer/backend/computer-router.cjs +257 -0
  176. package/extensions/computer/backend/cua-tools.json +3067 -0
  177. package/extensions/computer/backend/farming-computer-client.cjs +84 -0
  178. package/extensions/computer/backend/index.cjs +35 -0
  179. package/extensions/computer/backend/isolated-browser-provider.cjs +157 -0
  180. package/extensions/computer/bin/farming-computer +131 -0
  181. package/frontend/farming-net/app.js +255 -262
  182. package/frontend/ghostty-loader.js +24 -20
  183. package/frontend/reading-anchor.js +210 -193
  184. package/frontend/runtime-paths.js +24 -26
  185. package/frontend/session-bridge.js +90 -111
  186. package/frontend/session-modal-bridge.js +184 -302
  187. package/frontend/skin-bridge.js +20 -23
  188. package/frontend/skins/crt/app.js +7686 -7901
  189. package/frontend/skins/crt/effects.js +7 -6
  190. package/frontend/skins/crt/index.html +6 -6
  191. package/frontend/skins/crt/styles/markdown.css +4 -4
  192. package/frontend/terminal-bridge.js +174 -181
  193. package/frontend/terminal-replay.js +320 -345
  194. package/frontend/theme-loader.js +55 -71
  195. package/package.json +64 -37
  196. package/shared/backend-connection-status.js +38 -69
  197. package/shared/browser-protocol.js +235 -110
  198. package/shared/websocket-liveness.js +40 -0
  199. package/backend/acp/packaged-claude-acp.js +0 -13
  200. package/backend/acp/packaged-codex-acp.js +0 -13
  201. package/backend/acp/patch-decisions.js +0 -153
  202. package/backend/acp/permission-security.js +0 -108
  203. package/backend/acp-session-state.js +0 -634
  204. package/backend/acp-transcript.js +0 -512
  205. package/backend/agent-env.js +0 -250
  206. package/backend/agent-json-stream.js +0 -268
  207. package/backend/agent-lifecycle-journal.js +0 -133
  208. package/backend/agent-order.js +0 -166
  209. package/backend/agent-provider-session.js +0 -76
  210. package/backend/agent-runtime-binding.js +0 -174
  211. package/backend/agent-session-history.js +0 -986
  212. package/backend/async-cache.js +0 -94
  213. package/backend/atomic-json-store.js +0 -37
  214. package/backend/auth.js +0 -251
  215. package/backend/chat-runtime.js +0 -28
  216. package/backend/claude-settings.js +0 -121
  217. package/backend/cli-agents.js +0 -486
  218. package/backend/codex-context-window.js +0 -189
  219. package/backend/codex-models.js +0 -226
  220. package/backend/codex-session-archive.js +0 -65
  221. package/backend/codex-session-history.js +0 -647
  222. package/backend/codex-transcript-sanitizer.js +0 -115
  223. package/backend/codex-transcript.js +0 -2362
  224. package/backend/command-runner-child.js +0 -67
  225. package/backend/config-manager.js +0 -1117
  226. package/backend/control-api.js +0 -455
  227. package/backend/executable-discovery.js +0 -216
  228. package/backend/farming-agent-bootstrap.js +0 -49
  229. package/backend/farming-cli.js +0 -403
  230. package/backend/farming-net-pass.js +0 -285
  231. package/backend/farming-net-registry.js +0 -112
  232. package/backend/farming-net-server.js +0 -298
  233. package/backend/farming-session-store.js +0 -677
  234. package/backend/git-worktree-info.js +0 -181
  235. package/backend/haiku-token.js +0 -772
  236. package/backend/index-html.js +0 -80
  237. package/backend/input-parts.js +0 -54
  238. package/backend/input-routing.js +0 -24
  239. package/backend/json-cli-runtime.js +0 -275
  240. package/backend/main-agent-skills.js +0 -288
  241. package/backend/main-page-session.js +0 -122
  242. package/backend/native-pty-controller-generation.js +0 -106
  243. package/backend/native-pty-host-identity.js +0 -86
  244. package/backend/native-pty-host-path.js +0 -42
  245. package/backend/native-session-engine.js +0 -268
  246. package/backend/network.js +0 -23
  247. package/backend/npm-update-helper.js +0 -374
  248. package/backend/packaged-node-pty.js +0 -99
  249. package/backend/preview-session-manager.js +0 -68
  250. package/backend/provider-adapters.js +0 -399
  251. package/backend/provider-session-id.js +0 -47
  252. package/backend/provider-session-service.js +0 -345
  253. package/backend/qr-share-tickets.js +0 -100
  254. package/backend/review-diff-router.js +0 -180
  255. package/backend/review-diff-service.js +0 -1270
  256. package/backend/review-session-router.js +0 -74
  257. package/backend/review-session-service.js +0 -446
  258. package/backend/review-session-store.js +0 -151
  259. package/backend/review-state-router.js +0 -116
  260. package/backend/review-state-store.js +0 -286
  261. package/backend/run-history-store.js +0 -67
  262. package/backend/runtime-dependency-manager.js +0 -759
  263. package/backend/runtime-executable-invocation.js +0 -20
  264. package/backend/runtime-observation.js +0 -81
  265. package/backend/server-process-identity.js +0 -47
  266. package/backend/server.js +0 -3225
  267. package/backend/session-engine-bridge.js +0 -129
  268. package/backend/session-engine-router.js +0 -66
  269. package/backend/session-engine.js +0 -39
  270. package/backend/session-stream-protocol.js +0 -185
  271. package/backend/shell-busy-integration.js +0 -472
  272. package/backend/slash-command-discovery.js +0 -433
  273. package/backend/storage-layout.js +0 -205
  274. package/backend/system-monitor.js +0 -77
  275. package/backend/terminal-attach-checkpoint.js +0 -74
  276. package/backend/terminal-exit-quiescence.js +0 -39
  277. package/backend/terminal-runtime-cleanup.js +0 -80
  278. package/backend/terminal-screen-worker.js +0 -337
  279. package/backend/terminal-state-serialization.js +0 -127
  280. package/backend/theme-manager.js +0 -163
  281. package/backend/usage-forecast.js +0 -86
  282. package/backend/usage-history-scanner.ts +0 -2718
  283. package/backend/usage-history-smoke.js +0 -64
  284. package/backend/usage-history-worker.js +0 -34
  285. package/backend/workspace-directory.js +0 -232
  286. package/backend/workspace-discovery.js +0 -311
  287. package/backend/workspace-root-registry.js +0 -166
  288. package/dist/assets/App-BKNUILuL.css +0 -1
  289. package/dist/assets/App-Z1N7T0eM.js +0 -695
  290. package/dist/assets/FileEditorPane-CNtuGjQ3.js +0 -2
  291. package/dist/assets/IconGlyphs-BClgag6E.js +0 -1
  292. package/dist/assets/ProjectFilesSection-K3GHuQ4U.js +0 -12
  293. package/dist/assets/ReviewPage-BRuxFaH5.js +0 -3
  294. package/dist/assets/code-dark-kLsQLvpf.css +0 -1
  295. package/dist/assets/file-icons-BOlcJ0ZF.js +0 -1
  296. package/dist/assets/main-DUTz-Rd2.css +0 -1
  297. package/dist/assets/review-BcnwQtJv.css +0 -1
  298. package/dist/assets/workspace-editor-model-CSGCl21x.js +0 -1
  299. package/dist/assets/workspace-editor-monaco-CJNwbpCy.js +0 -4
  300. package/dist/assets/workspace-editor-monaco-CO9w8YV0.js +0 -1
  301. package/dist/assets/workspace-view-state-BjKPYp0E.js +0 -7
  302. package/extensions/browser/backend/agent-browser-runtime.js +0 -1041
  303. package/extensions/browser/backend/agent-capability.js +0 -55
  304. package/extensions/browser/backend/browser-mcp-server.js +0 -621
  305. package/extensions/browser/backend/browser-resource-manager.js +0 -1331
  306. package/extensions/browser/backend/browser-resource-store.js +0 -190
  307. package/extensions/browser/backend/browser-router.js +0 -141
  308. package/extensions/browser/backend/executable-discovery.js +0 -238
  309. package/extensions/browser/backend/farming-browser-client.js +0 -83
  310. package/extensions/browser/backend/index.js +0 -7
  311. package/extensions/browser/backend/managed-chromium-installer.js +0 -593
  312. package/extensions/browser/frontend/BrowserSidebarPortals.tsx +0 -360
  313. package/extensions/browser/frontend/BrowserViewer.tsx +0 -500
  314. package/extensions/browser/frontend/browser-resource-state.ts +0 -60
  315. package/extensions/browser/frontend/browser.css +0 -567
  316. package/extensions/browser/frontend/types.ts +0 -38
  317. package/extensions/browser/frontend/useBrowserResources.ts +0 -166
  318. package/frontend/vendor/ghostty-web/index.d.ts +0 -1842
  319. package/shared/backend-connection-status.d.ts +0 -37
  320. package/shared/browser-protocol.d.ts +0 -5
  321. /package/dist/assets/{api-w2x5QfxB.js → api-ByCV9MEr.js} +0 -0
  322. /package/dist/assets/{core-vPkV8P_m.js → core-Czwdx12k.js} +0 -0
  323. /package/dist/assets/{fsharp-DNZNZyEE.js → fsharp-BjPpkoJe.js} +0 -0
  324. /package/dist/assets/{go-_kPJjNc_.js → go-BkIDmSUP.js} +0 -0
  325. /package/dist/assets/{graphql-4HCNVt5g.js → graphql-CCJTpqi1.js} +0 -0
  326. /package/dist/assets/{hcl-C87ymY0o.js → hcl-s4z8lUFg.js} +0 -0
  327. /package/dist/assets/{ini-BYrrGNTc.js → ini-CyUW1I7Z.js} +0 -0
  328. /package/dist/assets/{java-B211rJbk.js → java-CFCcGRiM.js} +0 -0
  329. /package/dist/assets/{julia-DVPsRtBm.js → julia-DQyH_EYb.js} +0 -0
  330. /package/dist/assets/{kotlin-BYyNerjp.js → kotlin-B8hA5O51.js} +0 -0
  331. /package/dist/assets/{less-EC9UblGE.js → less-DaVdaas0.js} +0 -0
  332. /package/dist/assets/{lexon-B1yuUdqW.js → lexon-DLBhPd3y.js} +0 -0
  333. /package/dist/assets/{lua-Bo6GFzxT.js → lua-gB1c_cif.js} +0 -0
  334. /package/dist/assets/{m3-C-Y9cBVI.js → m3-C2T3z3gB.js} +0 -0
  335. /package/dist/assets/{markdown-BHu-wLbe.js → markdown-CKq-Euj1.js} +0 -0
  336. /package/dist/assets/{mips-Dkds26rX.js → mips-Bcs5qIDX.js} +0 -0
  337. /package/dist/assets/{msdax-PU4g-8_g.js → msdax-CBP48FHF.js} +0 -0
  338. /package/dist/assets/{mysql-fPpuGpS7.js → mysql-c7tiPcFj.js} +0 -0
  339. /package/dist/assets/{objective-c-Wy1e5JUf.js → objective-c-D4BZkeEV.js} +0 -0
  340. /package/dist/assets/{pascal-BIXwvrqU.js → pascal-CJDZg0MN.js} +0 -0
  341. /package/dist/assets/{pascaligo-DwR0AtL_.js → pascaligo-Bygi8Ynl.js} +0 -0
  342. /package/dist/assets/{perl-CGHAl8my.js → perl-aS8bkf7E.js} +0 -0
  343. /package/dist/assets/{pgsql-B91M73E2.js → pgsql-CzNAYFYl.js} +0 -0
  344. /package/dist/assets/{php-C70ttrCx.js → php-DOtoEFTT.js} +0 -0
  345. /package/dist/assets/{pla-BNrXaRh0.js → pla-DugRnao1.js} +0 -0
  346. /package/dist/assets/{postiats-Dv2IAZR9.js → postiats-DsXwusKh.js} +0 -0
  347. /package/dist/assets/{powerquery-CkY5Wq7J.js → powerquery-DL3o72oD.js} +0 -0
  348. /package/dist/assets/{powershell-uGIYLU3C.js → powershell-C1qHekys.js} +0 -0
  349. /package/dist/assets/{protobuf-CavfmJu-.js → protobuf-DHgsc-cH.js} +0 -0
  350. /package/dist/assets/{pug-Drqnyitx.js → pug-FZXlE_Iu.js} +0 -0
  351. /package/dist/assets/{qrcode-7uGsTEmi.js → qrcode-DJDTdjL7.js} +0 -0
  352. /package/dist/assets/{qsharp-C7yF-Dti.js → qsharp-bLyhI3DT.js} +0 -0
  353. /package/dist/assets/{r-HXLGP0_-.js → r-DjFGXbAa.js} +0 -0
  354. /package/dist/assets/{redis-C4y6mf2p.js → redis-DSoZ_V6u.js} +0 -0
  355. /package/dist/assets/{redshift-DdQrFPrv.js → redshift-CzkdCsrg.js} +0 -0
  356. /package/dist/assets/{restructuredtext-CBrf2PNj.js → restructuredtext-B_XPrGCQ.js} +0 -0
  357. /package/dist/assets/{ruby-CVtMoX2B.js → ruby-Cry2RneJ.js} +0 -0
  358. /package/dist/assets/{rust-Ckq4sbMP.js → rust-CWzdbFq1.js} +0 -0
  359. /package/dist/assets/{sb-er66OpE3.js → sb-DmofU59h.js} +0 -0
  360. /package/dist/assets/{scala-BdWZz-hH.js → scala-BUC2l-vN.js} +0 -0
  361. /package/dist/assets/{scheme-kTV_s2kP.js → scheme-CNIB_72f.js} +0 -0
  362. /package/dist/assets/{scss-Bymy2VJQ.js → scss-DcL4-NbX.js} +0 -0
  363. /package/dist/assets/{shell-bwEP1LQ1.js → shell-CgAGvSSA.js} +0 -0
  364. /package/dist/assets/{solidity-DCddeBgL.js → solidity-DSkt6O_P.js} +0 -0
  365. /package/dist/assets/{sophia-BMN3AQig.js → sophia--5ytcjDN.js} +0 -0
  366. /package/dist/assets/{sparql-CSXOLjzi.js → sparql-C1Srr7cD.js} +0 -0
  367. /package/dist/assets/{sql-COg8ewmK.js → sql-2k_O5fj7.js} +0 -0
  368. /package/dist/assets/{st-CIaZtBS_.js → st-DCCCPqfz.js} +0 -0
  369. /package/dist/assets/{swift-DXiOhUHu.js → swift-Dd8mAfOt.js} +0 -0
  370. /package/dist/assets/{systemverilog-BTDE6Dr2.js → systemverilog-B0-aZYXu.js} +0 -0
  371. /package/dist/assets/{tcl-B0zy9NvV.js → tcl-CZAZwPVX.js} +0 -0
  372. /package/dist/assets/{twig-D594l4Z1.js → twig-D-Ag0tdS.js} +0 -0
  373. /package/dist/assets/{typespec-XKVjaPqo.js → typespec-B7kTFp0Z.js} +0 -0
  374. /package/dist/assets/{useWorkspaceMenuKeyboard-Bpy_s69Z.js → useWorkspaceMenuKeyboard-uYZpDxhU.js} +0 -0
  375. /package/dist/assets/{vb-B2wYoKRV.js → vb-20w1JPum.js} +0 -0
  376. /package/dist/assets/{wgsl-D0Yf2LbK.js → wgsl-CLJfqFt0.js} +0 -0
  377. /package/dist/assets/{workspace-working-copy-C3FSR3N6.js → workspace-working-copy-Cfz07cOd.js} +0 -0
@@ -0,0 +1,2107 @@
1
+ // Generated by scripts/build-backend-runtime.ts. Do not edit.
2
+ "use strict";
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
7
+ var __export = (target, all) => {
8
+ for (var name in all)
9
+ __defProp(target, name, { get: all[name], enumerable: true });
10
+ };
11
+ var __copyProps = (to, from, except, desc) => {
12
+ if (from && typeof from === "object" || typeof from === "function") {
13
+ for (let key of __getOwnPropNames(from))
14
+ if (!__hasOwnProp.call(to, key) && key !== except)
15
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
16
+ }
17
+ return to;
18
+ };
19
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
20
+ var codex_transcript_exports = {};
21
+ __export(codex_transcript_exports, {
22
+ DEFAULT_MAX_TURNS: () => DEFAULT_MAX_TURNS,
23
+ buildTranscriptFromEvents: () => buildTranscriptFromEvents,
24
+ buildTranscriptFromLines: () => buildTranscriptFromLines,
25
+ stripUserMessagePrefix: () => stripUserMessagePrefix,
26
+ textFromContent: () => textFromContent,
27
+ visibleUserMessageText: () => visibleUserMessageText
28
+ });
29
+ module.exports = __toCommonJS(codex_transcript_exports);
30
+ var import_codex_transcript_sanitizer = require("./codex-transcript-sanitizer.cjs");
31
+ const fs = require("fs");
32
+ const path = require("path");
33
+ function isDataRecord(value) {
34
+ return value !== null && typeof value === "object" && !Array.isArray(value);
35
+ }
36
+ function dataRecord(value) {
37
+ return isDataRecord(value) ? value : {};
38
+ }
39
+ function isTranscriptImage(value) {
40
+ return isDataRecord(value) && typeof value.id === "string" && typeof value.url === "string";
41
+ }
42
+ function isTranscriptFile(value) {
43
+ return isDataRecord(value) && typeof value.name === "string" && typeof value.content === "string";
44
+ }
45
+ const DEFAULT_MAX_TURNS = 240;
46
+ const USER_MESSAGE_BEGIN = "## My request for Codex:";
47
+ const MAX_USER_IMAGES_PER_TURN = 6;
48
+ const MAX_USER_IMAGE_URL_LENGTH = 5 * 1024 * 1024;
49
+ const MAX_LOCAL_IMAGE_BYTES = 5 * 1024 * 1024;
50
+ const MAX_USER_AUDIOS_PER_TURN = 6;
51
+ const MAX_USER_AUDIO_URL_LENGTH = 10 * 1024 * 1024;
52
+ const MAX_LOCAL_AUDIO_BYTES = 10 * 1024 * 1024;
53
+ const MAX_USER_FILES_PER_TURN = 6;
54
+ const MAX_USER_FILE_CONTENT_CHARS = 5e4;
55
+ const CODEX_HISTORY_IMAGE_LINK_PATTERN = /\[@(?:image|[^\]]+\.(?:gif|jpe?g|png|svg|webp))\]\(([^)\n]+)\)/gi;
56
+ const LOCAL_IMAGE_MIME_BY_EXT = {
57
+ ".gif": "image/gif",
58
+ ".jpeg": "image/jpeg",
59
+ ".jpg": "image/jpeg",
60
+ ".png": "image/png",
61
+ ".svg": "image/svg+xml",
62
+ ".webp": "image/webp"
63
+ };
64
+ const LOCAL_AUDIO_MIME_BY_EXT = {
65
+ ".aac": "audio/aac",
66
+ ".flac": "audio/flac",
67
+ ".m4a": "audio/mp4",
68
+ ".mp3": "audio/mpeg",
69
+ ".oga": "audio/ogg",
70
+ ".ogg": "audio/ogg",
71
+ ".opus": "audio/ogg",
72
+ ".wav": "audio/wav",
73
+ ".webm": "audio/webm"
74
+ };
75
+ function normalizeText(value) {
76
+ return String(value || "").replace(/\r\n/g, "\n").replace(/\r/g, "\n").trim();
77
+ }
78
+ function normalizeDeltaText(value) {
79
+ return String(value || "").replace(/\r\n/g, "\n").replace(/\r/g, "\n");
80
+ }
81
+ function extractMemoryCitationBlock(value) {
82
+ const text = normalizeText(value);
83
+ if (!text) return { text: "", detail: "" };
84
+ const blocks = [];
85
+ const cleaned = text.replace(/<oai-mem-citation>[\s\S]*?<\/oai-mem-citation>/g, (block) => {
86
+ blocks.push(block);
87
+ return "";
88
+ });
89
+ return {
90
+ text: normalizeText(cleaned),
91
+ detail: blocks.map(formatRawMemoryCitationBlock).filter(Boolean).join("\n\n")
92
+ };
93
+ }
94
+ function formatRawMemoryCitationBlock(block) {
95
+ return normalizeText(block).replace(/<\/?oai-mem-citation>/g, "").replace(/<citation_entries>/g, "citation entries:\n").replace(/<\/citation_entries>/g, "").replace(/<rollout_ids>/g, "\nrollout ids:\n").replace(/<\/rollout_ids>/g, "").replace(/<[^>]+>/g, "").split("\n").map((line) => line.trim()).filter(Boolean).join("\n");
96
+ }
97
+ function detailForMemoryCitation(memoryCitation) {
98
+ const citation = dataRecord(memoryCitation);
99
+ if (!memoryCitation || !isDataRecord(memoryCitation)) return "";
100
+ const rows = [];
101
+ const entries = Array.isArray(citation.entries) ? citation.entries : [];
102
+ for (const entry of entries) {
103
+ if (!isDataRecord(entry)) continue;
104
+ const pathLabel = compactInline(entry.path || "");
105
+ const lineStart = entry.lineStart ?? entry.line_start;
106
+ const lineEnd = entry.lineEnd ?? entry.line_end;
107
+ const lineLabel = Number.isFinite(lineStart) ? `:${lineStart}${Number.isFinite(lineEnd) && lineEnd !== lineStart ? `-${lineEnd}` : ""}` : "";
108
+ const note = compactInline(entry.note || "");
109
+ rows.push(`${pathLabel}${lineLabel}${note ? ` | ${note}` : ""}`);
110
+ }
111
+ const threadIds = Array.isArray(citation.threadIds) ? citation.threadIds : Array.isArray(citation.thread_ids) ? citation.thread_ids : [];
112
+ if (threadIds.length) rows.push(`threads: ${threadIds.map((id) => compactInline(id)).filter(Boolean).join(", ")}`);
113
+ return summarizeOutput(rows.join("\n"));
114
+ }
115
+ function appendMemoryCitation(turn, id, memoryCitation, rawDetail = "") {
116
+ const detail = [detailForMemoryCitation(memoryCitation), rawDetail].filter(Boolean).join("\n\n");
117
+ if (!detail) return;
118
+ appendProcess(turn, {
119
+ id: `${id || turn.id || "message"}-memory-citation`,
120
+ type: "citation",
121
+ title: "Memory citations",
122
+ detail,
123
+ status: "completed"
124
+ });
125
+ }
126
+ function finalMessageText(value, turn, id, memoryCitation = void 0) {
127
+ const extracted = extractMemoryCitationBlock(value);
128
+ appendMemoryCitation(turn, id, memoryCitation, extracted.detail);
129
+ const heartbeatMessage = (0, import_codex_transcript_sanitizer.heartbeatAssistantMessage)(extracted.text);
130
+ if (heartbeatMessage || heartbeatMessage === "") {
131
+ const text = normalizeText(extracted.text);
132
+ if (/^<heartbeat(?:\s+[^>]*)?>[\s\S]*<\/heartbeat>$/i.test(text)) return heartbeatMessage;
133
+ }
134
+ return (0, import_codex_transcript_sanitizer.stripCodexInternalContextBlocks)(extracted.text);
135
+ }
136
+ function stripUserMessagePrefix(value) {
137
+ const text = normalizeText(value);
138
+ const index = text.indexOf(USER_MESSAGE_BEGIN);
139
+ return index >= 0 ? text.slice(index + USER_MESSAGE_BEGIN.length).trim() : text;
140
+ }
141
+ function isInjectedContextMessage(value) {
142
+ return (0, import_codex_transcript_sanitizer.isCodexInjectedContextMessage)(value);
143
+ }
144
+ function renderedAttachmentKindSet(options = {}) {
145
+ return new Set(Array.isArray(options.renderedAttachmentKinds) ? options.renderedAttachmentKinds : []);
146
+ }
147
+ function extractComposerFileAttachments(value) {
148
+ const text = normalizeText(value);
149
+ if (!text) return { text: "", files: [] };
150
+ const files = [];
151
+ const pattern = /(^|\n{2,})\s*Attached file:\s*([^\n]*)(?:\n{2,}|\n)([\s\S]*?)(?=\n{2,}\s*Attached (?:file|image):|\n{2,}\s*<image\b|$)/gi;
152
+ const stripped = text.replace(pattern, (_match, prefix, rawName, rawContent) => {
153
+ if (files.length < MAX_USER_FILES_PER_TURN) {
154
+ const name = compactInline(rawName, `attachment-${files.length + 1}`);
155
+ const originalContent = String(rawContent || "").replace(/\r\n/g, "\n").replace(/\r/g, "\n").trimEnd();
156
+ const errorMatch = originalContent.trim().match(/^\[([^\]]+)\]$/);
157
+ const truncatedMarker = originalContent.match(/\n{2,}\[File truncated after\s+(\d+)\s+characters\]\s*$/i);
158
+ const contentWithoutMarker = truncatedMarker ? originalContent.slice(0, truncatedMarker.index).trimEnd() : originalContent;
159
+ const truncated = Boolean(truncatedMarker) || contentWithoutMarker.length > MAX_USER_FILE_CONTENT_CHARS;
160
+ files.push({
161
+ id: `file-${files.length + 1}`,
162
+ name,
163
+ content: errorMatch ? "" : contentWithoutMarker.slice(0, MAX_USER_FILE_CONTENT_CHARS),
164
+ error: errorMatch ? errorMatch[1] : "",
165
+ truncated
166
+ });
167
+ }
168
+ return prefix || "";
169
+ }).replace(/\n{3,}/g, "\n\n").trim();
170
+ return { text: stripped, files };
171
+ }
172
+ function findLastTranscriptTimestamp(text) {
173
+ const pattern = /(?:^|\n)(?:[A-Za-z]+day\s+)?\d{1,2}:\d{2}\s*(?:AM|PM)\s*\n/gi;
174
+ let match = null;
175
+ let next;
176
+ while (next = pattern.exec(text)) match = next;
177
+ if (!match) return null;
178
+ return {
179
+ index: match.index + (match[0].startsWith("\n") ? 1 : 0),
180
+ end: match.index + match[0].length
181
+ };
182
+ }
183
+ function extractReferencedPastedTranscriptContext(value) {
184
+ const text = normalizeText(value);
185
+ if (!text || text.length < 1200 || !/\nReferenced pasted text files:\n/i.test(text)) {
186
+ return { text, files: [] };
187
+ }
188
+ const referenceMatch = text.match(/\nReferenced pasted text files:\n[\s\S]*?(?=\n(?:Sent as goal|Goal blocked|\d{1,2}:\d{2}\s*(?:AM|PM)|$))/i);
189
+ if (!referenceMatch || referenceMatch.index === void 0) return { text, files: [] };
190
+ const beforeReference = text.slice(0, referenceMatch.index).trimEnd();
191
+ const timestamp = findLastTranscriptTimestamp(beforeReference);
192
+ if (!timestamp || timestamp.index < 400) return { text, files: [] };
193
+ const pastedContext = beforeReference.slice(0, timestamp.index).trim();
194
+ const userRequest = beforeReference.slice(timestamp.end).trim();
195
+ if (!pastedContext || !userRequest) return { text, files: [] };
196
+ const referenceBlock = referenceMatch[0].trim();
197
+ const remaining = text.slice(referenceMatch.index + referenceMatch[0].length).trim();
198
+ const trailingContext = remaining ? remaining.replace(/^Sent as goal\s*/i, "").trim() : "";
199
+ const content = [pastedContext, trailingContext].filter(Boolean).join("\n\n---\n\n");
200
+ const truncated = content.length > MAX_USER_FILE_CONTENT_CHARS;
201
+ return {
202
+ text: [userRequest, referenceBlock].filter(Boolean).join("\n\n"),
203
+ files: [{
204
+ id: "file-pasted-transcript-context",
205
+ name: "pasted-transcript-context.txt",
206
+ content: content.slice(0, MAX_USER_FILE_CONTENT_CHARS),
207
+ truncated
208
+ }]
209
+ };
210
+ }
211
+ function extractCodexApprovalTranscriptContext(value) {
212
+ const text = normalizeText(value);
213
+ if (!text || text.length < 500 || !/^The following is the Codex agent history(?: whose request action you are assessing| added since your last approval assessment)\b/i.test(text)) {
214
+ return { text, files: [] };
215
+ }
216
+ const firstParagraph = text.split(/\n{2,}/)[0].trim();
217
+ const truncated = text.length > MAX_USER_FILE_CONTENT_CHARS;
218
+ return {
219
+ text: firstParagraph,
220
+ files: [{
221
+ id: "file-codex-approval-transcript",
222
+ name: "codex-approval-transcript.txt",
223
+ content: text.slice(0, MAX_USER_FILE_CONTENT_CHARS),
224
+ truncated
225
+ }]
226
+ };
227
+ }
228
+ function parseSubagentNotification(value) {
229
+ const text = normalizeText(value);
230
+ const match = text.match(/^<subagent_notification(?:\s+[^>]*)?>([\s\S]*?)<\/subagent_notification>$/i);
231
+ if (!match) return null;
232
+ const payload = parseJsonValue(match[1]);
233
+ if (!payload || typeof payload !== "object") {
234
+ return {
235
+ title: "Subagent update",
236
+ detail: normalizeText(match[1]),
237
+ status: "completed"
238
+ };
239
+ }
240
+ const record = payload;
241
+ const status = dataRecord(record.status);
242
+ const completed = typeof status.completed === "string" ? status.completed : "";
243
+ const failed = typeof status.failed === "string" ? status.failed : "";
244
+ const detail = completed || failed || compactInline(status.message || record.message || "");
245
+ return {
246
+ title: failed ? "Subagent failed" : completed ? "Subagent completed" : "Subagent update",
247
+ detail,
248
+ status: failed ? "failed" : "completed"
249
+ };
250
+ }
251
+ function stripRenderedAttachmentTagBlocks(value, renderedKinds) {
252
+ const text = normalizeText(value);
253
+ if (!text) return "";
254
+ let next = text;
255
+ for (const kind of renderedKinds) {
256
+ const tagName = String(kind || "").replace(/[^a-z0-9_-]/gi, "");
257
+ if (!tagName) continue;
258
+ const pattern = new RegExp(`(^|\\n{2,})\\s*<${tagName}\\b[\\s\\S]*?<\\/${tagName}>\\s*(?=\\n{2,}|$)`, "gi");
259
+ next = next.replace(pattern, "$1");
260
+ }
261
+ return next.replace(/\n{3,}/g, "\n\n").trim();
262
+ }
263
+ function stripRenderedComposerAttachmentBlocks(value, renderedKinds) {
264
+ const text = normalizeText(value);
265
+ if (!text) return "";
266
+ let next = text;
267
+ for (const kind of renderedKinds) {
268
+ const label = String(kind || "").replace(/[^a-z0-9_-]/gi, "");
269
+ if (!label) continue;
270
+ if (label.toLowerCase() === "file") {
271
+ next = extractComposerFileAttachments(next).text;
272
+ continue;
273
+ }
274
+ const title = label.charAt(0).toUpperCase() + label.slice(1);
275
+ const pattern = new RegExp(`(^|\\n{2,})\\s*Attached ${label}:[^\\n]*(?:\\n{2,}|\\n)(?:${title} path:|\\[[^\\]]+\\])[^\\n]*(?=\\n{2,}|$)`, "gi");
276
+ next = next.replace(pattern, "$1");
277
+ }
278
+ return next.replace(/\n{3,}/g, "\n\n").trim();
279
+ }
280
+ function stripRenderedCodexHistoryAttachmentLinks(value, renderedKinds) {
281
+ const text = normalizeText(value);
282
+ if (!text || !renderedKinds.has("image")) return text;
283
+ CODEX_HISTORY_IMAGE_LINK_PATTERN.lastIndex = 0;
284
+ return text.replace(CODEX_HISTORY_IMAGE_LINK_PATTERN, "").replace(/\n{3,}/g, "\n\n").trim();
285
+ }
286
+ function visibleUserMessageText(value, options = {}) {
287
+ const rawText = stripUserMessagePrefix(value);
288
+ const heartbeatMessage = (0, import_codex_transcript_sanitizer.heartbeatUserMessage)(rawText);
289
+ if (heartbeatMessage) return heartbeatMessage;
290
+ const text = (0, import_codex_transcript_sanitizer.stripCodexInternalContextBlocks)(rawText);
291
+ if (isInjectedContextMessage(text)) return "";
292
+ const renderedKinds = renderedAttachmentKindSet(options);
293
+ return stripRenderedCodexHistoryAttachmentLinks(
294
+ stripRenderedComposerAttachmentBlocks(stripRenderedAttachmentTagBlocks(text, renderedKinds), renderedKinds),
295
+ renderedKinds
296
+ );
297
+ }
298
+ function renderedAttachmentKindsForTurn(turn) {
299
+ const kinds = [];
300
+ if (turn && Array.isArray(turn.userImages) && turn.userImages.length > 0) kinds.push("image");
301
+ if (turn && Array.isArray(turn.userAudios) && turn.userAudios.length > 0) kinds.push("audio");
302
+ if (turn && Array.isArray(turn.userFiles) && turn.userFiles.length > 0) kinds.push("file");
303
+ return kinds;
304
+ }
305
+ function renderedAttachmentKindsForAttachments({
306
+ images = [],
307
+ audios = [],
308
+ files = []
309
+ } = {}) {
310
+ const kinds = [];
311
+ if (Array.isArray(images) && images.length > 0) kinds.push("image");
312
+ if (Array.isArray(audios) && audios.length > 0) kinds.push("audio");
313
+ if (Array.isArray(files) && files.length > 0) kinds.push("file");
314
+ return kinds;
315
+ }
316
+ function parseJsonValue(value) {
317
+ if (!value) return null;
318
+ if (typeof value === "object") return value;
319
+ if (typeof value !== "string") return null;
320
+ try {
321
+ return JSON.parse(value);
322
+ } catch {
323
+ return null;
324
+ }
325
+ }
326
+ function compactInline(value, fallback = "") {
327
+ const text = normalizeText(value).replace(/\s+/g, " ");
328
+ return text || fallback;
329
+ }
330
+ function humanizeType(value, fallback = "Event") {
331
+ const text = String(value || "").replace(/([a-z0-9])([A-Z])/g, "$1 $2").replace(/[_-]+/g, " ").trim();
332
+ if (!text) return fallback;
333
+ return text.split(/\s+/).map((word) => word.charAt(0).toUpperCase() + word.slice(1)).join(" ");
334
+ }
335
+ function textFromContent(content) {
336
+ if (typeof content === "string") return normalizeText(content);
337
+ if (content && typeof content === "object" && !Array.isArray(content)) {
338
+ const record = content;
339
+ if (typeof record.text === "string") return normalizeText(record.text);
340
+ if (typeof record.content === "string") return normalizeText(record.content);
341
+ if (Array.isArray(record.content)) return textFromContent(record.content);
342
+ if (Array.isArray(record.content_items)) return textFromContent(record.content_items);
343
+ if (Array.isArray(record.contentItems)) return textFromContent(record.contentItems);
344
+ return "";
345
+ }
346
+ if (!Array.isArray(content)) return "";
347
+ return content.map((part) => {
348
+ if (!part || typeof part !== "object") return "";
349
+ if (typeof part.text === "string") return part.text;
350
+ if (typeof part.content === "string") return part.content;
351
+ return "";
352
+ }).filter(Boolean).join("\n\n").trim();
353
+ }
354
+ function imageAltFromContentPart(part, index) {
355
+ const fallback = `Image ${index + 1}`;
356
+ if (!part || typeof part !== "object") return fallback;
357
+ return compactInline(part.name || part.filename || part.path || part.alt || "", fallback);
358
+ }
359
+ function imageAltFromPath(filePath, index) {
360
+ const basename = path.basename(String(filePath || ""));
361
+ return basename || `Image ${index + 1}`;
362
+ }
363
+ function isDisplayableImageUrl(url) {
364
+ if (typeof url !== "string" || !url) return false;
365
+ if (url.length > MAX_USER_IMAGE_URL_LENGTH) return false;
366
+ return url.startsWith("data:image/") || url.startsWith("http://") || url.startsWith("https://");
367
+ }
368
+ function imagesFromContent(content) {
369
+ if (!Array.isArray(content)) return [];
370
+ const images = [];
371
+ for (const partValue of content) {
372
+ if (!isDataRecord(partValue)) continue;
373
+ const part = partValue;
374
+ if (part.type === "localImage") {
375
+ const image = imageFromLocalPath(part.path, images.length);
376
+ if (image) images.push(image);
377
+ if (images.length >= MAX_USER_IMAGES_PER_TURN) break;
378
+ continue;
379
+ }
380
+ if (part.type !== "input_image" && part.type !== "inputImage" && part.type !== "image") continue;
381
+ const url = part.image_url || part.imageUrl || part.url || part.data;
382
+ if (isDisplayableImageUrl(url)) {
383
+ images.push({
384
+ id: `image-${images.length + 1}`,
385
+ url,
386
+ alt: imageAltFromContentPart(part, images.length)
387
+ });
388
+ } else {
389
+ const localImage = imageFromLocalPath(part.path || part.file || part.localPath, images.length);
390
+ if (localImage) images.push(localImage);
391
+ }
392
+ if (images.length >= MAX_USER_IMAGES_PER_TURN) break;
393
+ }
394
+ return images;
395
+ }
396
+ function audioMimeFromUrl(url) {
397
+ const dataMime = String(url || "").match(/^data:(audio\/[^;,]+)[;,]/i)?.[1];
398
+ if (dataMime) return dataMime.toLowerCase();
399
+ try {
400
+ return LOCAL_AUDIO_MIME_BY_EXT[path.extname(new URL(String(url || "")).pathname).toLowerCase()] || "";
401
+ } catch {
402
+ return "";
403
+ }
404
+ }
405
+ function audioNameFromPart(part, index) {
406
+ const explicit = compactInline(part?.name || part?.filename || "");
407
+ if (explicit) return explicit;
408
+ const target = String(part?.path || part?.url || "");
409
+ if (target && !/^data:/i.test(target)) {
410
+ try {
411
+ const basename = path.basename(new URL(target, "file:///").pathname);
412
+ if (basename) return basename;
413
+ } catch {
414
+ const basename = path.basename(target);
415
+ if (basename) return basename;
416
+ }
417
+ }
418
+ return `Audio ${index + 1}`;
419
+ }
420
+ function audioFromLocalPath(filePath, index) {
421
+ const normalized = String(filePath || "").trim();
422
+ if (!normalized || normalized.includes("\0")) return null;
423
+ const mimeType = LOCAL_AUDIO_MIME_BY_EXT[path.extname(normalized).toLowerCase()];
424
+ if (!mimeType) return null;
425
+ try {
426
+ const stat = fs.statSync(normalized);
427
+ if (!stat.isFile() || stat.size <= 0 || stat.size > MAX_LOCAL_AUDIO_BYTES) return null;
428
+ return {
429
+ id: `local-audio-${index + 1}`,
430
+ url: `data:${mimeType};base64,${fs.readFileSync(normalized).toString("base64")}`,
431
+ mimeType,
432
+ name: path.basename(normalized) || `Audio ${index + 1}`
433
+ };
434
+ } catch {
435
+ return null;
436
+ }
437
+ }
438
+ function audiosFromContent(content) {
439
+ if (!Array.isArray(content)) return [];
440
+ const audios = [];
441
+ for (const part of content) {
442
+ if (!part || typeof part !== "object") continue;
443
+ let audio = null;
444
+ if (part.type === "localAudio") {
445
+ audio = audioFromLocalPath(part.path, audios.length);
446
+ } else if (part.type === "audio") {
447
+ const url = String(part.url || "");
448
+ if (url.length <= MAX_USER_AUDIO_URL_LENGTH && (/^data:audio\//i.test(url) || /^https?:\/\//i.test(url))) {
449
+ audio = {
450
+ id: `audio-${audios.length + 1}`,
451
+ url,
452
+ mimeType: audioMimeFromUrl(url),
453
+ name: audioNameFromPart(part, audios.length)
454
+ };
455
+ }
456
+ }
457
+ if (audio && !audios.some((existing) => existing.url === audio.url)) audios.push(audio);
458
+ if (audios.length >= MAX_USER_AUDIOS_PER_TURN) break;
459
+ }
460
+ return audios;
461
+ }
462
+ function inlineImageFromEntry(entryValue, index) {
463
+ if (typeof entryValue === "string") {
464
+ return isDisplayableImageUrl(entryValue) ? { id: `image-${index + 1}`, url: entryValue, alt: `Image ${index + 1}` } : null;
465
+ }
466
+ if (!isDataRecord(entryValue)) return null;
467
+ const entry = entryValue;
468
+ const url = entry.image_url || entry.imageUrl || entry.url || entry.data;
469
+ if (!isDisplayableImageUrl(url)) return imageFromLocalPath(entry.path || entry.file || entry.localPath, index);
470
+ return {
471
+ id: `image-${index + 1}`,
472
+ url,
473
+ alt: imageAltFromContentPart(entry, index)
474
+ };
475
+ }
476
+ function imageFromValue(value, index, alt = "") {
477
+ if (isDisplayableImageUrl(value)) {
478
+ return { id: `image-${index + 1}`, url: value, alt: compactInline(alt, `Image ${index + 1}`) };
479
+ }
480
+ return imageFromLocalPath(value, index);
481
+ }
482
+ function imagesFromImageItem(item) {
483
+ if (!item || typeof item !== "object") return [];
484
+ const candidates = [
485
+ item.result,
486
+ item.src,
487
+ item.url,
488
+ item.saved_path,
489
+ item.savedPath,
490
+ item.path
491
+ ];
492
+ const images = [];
493
+ for (const candidate of candidates) {
494
+ const image = imageFromValue(candidate, images.length, item.title || item.alt || "Generated image");
495
+ if (!image || images.some((existing) => existing.url === image.url)) continue;
496
+ images.push(image);
497
+ if (images.length >= MAX_USER_IMAGES_PER_TURN) break;
498
+ }
499
+ return images;
500
+ }
501
+ function imageFromLocalPath(filePath, index) {
502
+ const normalized = String(filePath || "").trim();
503
+ if (!normalized || normalized.includes("\0")) return null;
504
+ const ext = path.extname(normalized).toLowerCase();
505
+ const mime = LOCAL_IMAGE_MIME_BY_EXT[ext];
506
+ if (!mime) return null;
507
+ let stat = null;
508
+ try {
509
+ stat = fs.statSync(normalized);
510
+ } catch {
511
+ return null;
512
+ }
513
+ if (!stat.isFile() || stat.size <= 0 || stat.size > MAX_LOCAL_IMAGE_BYTES) return null;
514
+ try {
515
+ const base64 = fs.readFileSync(normalized).toString("base64");
516
+ return {
517
+ id: `local-image-${index + 1}`,
518
+ url: `data:${mime};base64,${base64}`,
519
+ alt: imageAltFromPath(normalized, index)
520
+ };
521
+ } catch {
522
+ return null;
523
+ }
524
+ }
525
+ function imagesFromUserMessagePayload(payload) {
526
+ const images = [];
527
+ const appendImage = (image) => {
528
+ if (!image || images.length >= MAX_USER_IMAGES_PER_TURN) return;
529
+ if (images.some((existing) => existing.url === image.url)) return;
530
+ images.push({
531
+ ...image,
532
+ id: image.id || `image-${images.length + 1}`
533
+ });
534
+ };
535
+ const inlineImages = Array.isArray(payload.images) ? payload.images : [];
536
+ for (const image of imagesFromContent(inlineImages)) {
537
+ appendImage(image);
538
+ }
539
+ for (const entry of inlineImages) {
540
+ appendImage(inlineImageFromEntry(entry, images.length));
541
+ }
542
+ const localImages = Array.isArray(payload.local_images) ? payload.local_images : Array.isArray(payload.localImages) ? payload.localImages : [];
543
+ for (const entry of localImages) {
544
+ const filePath = typeof entry === "string" ? entry : isDataRecord(entry) ? entry.path || entry.file || entry.url : "";
545
+ appendImage(imageFromLocalPath(filePath, images.length));
546
+ }
547
+ return images;
548
+ }
549
+ function summarizeStructuredOutput(output) {
550
+ if (typeof output === "string") return summarizeOutput(output);
551
+ if (Array.isArray(output)) {
552
+ const text = output.map((part) => {
553
+ if (!part || typeof part !== "object") return "";
554
+ if (typeof part.text === "string") return part.text;
555
+ if (typeof part.content === "string") return part.content;
556
+ if (typeof part.value === "string") return part.value;
557
+ return JSON.stringify(part);
558
+ }).filter(Boolean).join("\n");
559
+ return summarizeOutput(text);
560
+ }
561
+ if (output && typeof output === "object") {
562
+ const record = dataRecord(output);
563
+ if (typeof record.content === "string") return summarizeOutput(record.content);
564
+ if (Array.isArray(record.content)) return summarizeStructuredOutput(record.content);
565
+ if (Array.isArray(record.content_items)) return summarizeStructuredOutput(record.content_items);
566
+ if (Array.isArray(record.contentItems)) return summarizeStructuredOutput(record.contentItems);
567
+ return summarizeOutput(JSON.stringify(output, null, 2));
568
+ }
569
+ return "";
570
+ }
571
+ function imagesFromStructuredOutput(output) {
572
+ if (Array.isArray(output)) return imagesFromContent(output);
573
+ if (output && typeof output === "object") {
574
+ const record = dataRecord(output);
575
+ const images = [];
576
+ const append = (image) => {
577
+ if (!image || images.length >= MAX_USER_IMAGES_PER_TURN) return;
578
+ if (images.some((existing) => existing.url === image.url)) return;
579
+ images.push(image);
580
+ };
581
+ for (const field of ["content", "content_items", "contentItems"]) {
582
+ if (!Array.isArray(record[field])) continue;
583
+ for (const image of imagesFromContent(record[field])) append(image);
584
+ }
585
+ return images;
586
+ }
587
+ return [];
588
+ }
589
+ function commandText(command) {
590
+ if (Array.isArray(command)) return command.map((part) => String(part || "")).filter(Boolean).join(" ");
591
+ return normalizeText(command);
592
+ }
593
+ function titleForParsedCommand(parsed) {
594
+ if (!parsed || typeof parsed !== "object") return "";
595
+ const kind = String(parsed.type || "").trim();
596
+ const lowerKind = kind.replace(/_/g, "").toLowerCase();
597
+ const commandName = compactInline(parsed.command || parsed.cmd || "");
598
+ if (lowerKind === "search") {
599
+ const name2 = compactInline(parsed.query || parsed.name || commandName || parsed.path || "");
600
+ return name2 ? `Searched ${name2}` : "Searched files";
601
+ }
602
+ const name = compactInline(parsed.name || parsed.path || parsed.query || commandName || "");
603
+ if (lowerKind === "read") return name ? `Read ${name}` : "Read file";
604
+ if (lowerKind === "listfiles") return name ? `Listed ${name}` : "Listed files";
605
+ if (lowerKind === "write") return name ? `Edited ${name}` : "Edited file";
606
+ return "";
607
+ }
608
+ function titleForCommandExecution(payload) {
609
+ const actions = Array.isArray(payload.command_actions) ? payload.command_actions : payload.commandActions;
610
+ const parsedActions = Array.isArray(actions) ? actions : payload.parsed_cmd;
611
+ const parsed = Array.isArray(parsedActions) && parsedActions.length === 1 ? titleForParsedCommand(parsedActions[0]) : "";
612
+ if (parsed) return parsed;
613
+ const cmd = compactInline(commandText(payload.command));
614
+ return cmd ? `Ran ${cmd}` : "Ran command";
615
+ }
616
+ function summarizeApplyPatchText(input) {
617
+ const text = normalizeText(input);
618
+ if (!text.startsWith("*** Begin Patch")) return "";
619
+ const rows = [];
620
+ let active = null;
621
+ const flush = () => {
622
+ if (!active) return;
623
+ const statLabel = [
624
+ active.added > 0 ? `+${active.added}` : "",
625
+ active.removed > 0 ? `-${active.removed}` : ""
626
+ ].filter(Boolean).join(" ");
627
+ rows.push(`${active.kind} ${active.path}${statLabel ? ` ${statLabel}` : ""}`);
628
+ };
629
+ for (const line of text.split("\n")) {
630
+ const addMatch = line.match(/^\*\*\* Add File: (.+)$/);
631
+ const updateMatch = line.match(/^\*\*\* Update File: (.+)$/);
632
+ const deleteMatch = line.match(/^\*\*\* Delete File: (.+)$/);
633
+ const moveMatch = line.match(/^\*\*\* Move to: (.+)$/);
634
+ if (addMatch || updateMatch || deleteMatch) {
635
+ flush();
636
+ active = {
637
+ kind: addMatch ? "add" : deleteMatch ? "delete" : "update",
638
+ path: addMatch?.[1] || updateMatch?.[1] || deleteMatch?.[1] || "",
639
+ added: 0,
640
+ removed: 0
641
+ };
642
+ continue;
643
+ }
644
+ if (moveMatch && active) {
645
+ active.kind = "move";
646
+ active.path = moveMatch[1] || active.path;
647
+ continue;
648
+ }
649
+ if (!active || line.startsWith("+++") || line.startsWith("---")) continue;
650
+ if (line.startsWith("+")) active.added += 1;
651
+ else if (line.startsWith("-")) active.removed += 1;
652
+ }
653
+ flush();
654
+ return rows.slice(0, 16).join("\n");
655
+ }
656
+ function applyPatchTitleFromText(input) {
657
+ const summary = summarizeApplyPatchText(input);
658
+ if (!summary) return "";
659
+ const count = summary.split("\n").filter(Boolean).length;
660
+ if (count === 1) return "Edited 1 file";
661
+ if (count > 1) return `Edited ${count} files`;
662
+ return "";
663
+ }
664
+ function processTitleForFunctionCall(payload) {
665
+ const name = String(payload.name || "").trim();
666
+ const args = parseJsonValue(payload.arguments);
667
+ if (name === "exec_command") {
668
+ const cmd = normalizeText(args && typeof args === "object" ? args.cmd : "").replace(/\s+/g, " ");
669
+ return cmd ? `Ran ${cmd}` : "Ran command";
670
+ }
671
+ if (name === "apply_patch") return applyPatchTitleFromText(payload.input || payload.arguments) || "Applied patch";
672
+ if (name === "view_image") return "Viewed image";
673
+ if (name === "update_plan") return "Updated plan";
674
+ if (name === "read_mcp_resource") return "Read resource";
675
+ if (name) return `Used ${name}`;
676
+ return "Used tool";
677
+ }
678
+ function processTypeForFunctionCall(payload) {
679
+ const name = String(payload.name || "").trim();
680
+ if (name === "exec_command") return "command";
681
+ if (name === "apply_patch") return "patch";
682
+ if (name === "view_image") return "image";
683
+ if (name === "update_plan") return "plan";
684
+ if (name === "imagegen" || name === "image_gen" || name === "image_generation") return "image-generation";
685
+ return "tool";
686
+ }
687
+ function detailForFunctionCall(payload) {
688
+ const args = normalizeText(payload.arguments || payload.input);
689
+ if (!args) return "";
690
+ if (String(payload.name || "").trim() === "apply_patch") {
691
+ const patchSummary = summarizeApplyPatchText(args);
692
+ if (patchSummary) return patchSummary;
693
+ }
694
+ const parsed = parseJsonValue(args);
695
+ if (parsed && typeof parsed === "object") {
696
+ const record = parsed;
697
+ if (typeof record.cmd === "string") return record.cmd;
698
+ if (typeof record.prompt === "string") return record.prompt;
699
+ return JSON.stringify(parsed, null, 2);
700
+ }
701
+ return args;
702
+ }
703
+ function titleForLocalShell(payload) {
704
+ const action = dataRecord(payload.action);
705
+ const command = action.command || action.cmd || payload.command;
706
+ const cmd = compactInline(command);
707
+ return cmd ? `Ran ${cmd}` : "Ran local shell";
708
+ }
709
+ function detailForLocalShell(payload) {
710
+ const action = dataRecord(payload.action);
711
+ return summarizeOutput([
712
+ action.cwd ? `cwd: ${action.cwd}` : "",
713
+ action.command || action.cmd || "",
714
+ payload.status ? `status: ${payload.status}` : ""
715
+ ].filter(Boolean).join("\n"));
716
+ }
717
+ function summarizeOutput(output) {
718
+ const text = normalizeText(output);
719
+ if (!text) return "";
720
+ const lines = text.split("\n").map((line) => line.trimEnd()).filter(Boolean);
721
+ const visible = lines.slice(0, 8).join("\n");
722
+ if (lines.length <= 8) return visible;
723
+ return `${visible}
724
+ ... +${lines.length - 8} lines`;
725
+ }
726
+ function summarizeCommandOutput(payload) {
727
+ const chunks = [
728
+ payload.formatted_output,
729
+ payload.aggregated_output,
730
+ payload.aggregatedOutput,
731
+ payload.stdout,
732
+ payload.stderr
733
+ ].filter((value) => normalizeText(value));
734
+ const output = chunks.join("\n");
735
+ const prefix = [];
736
+ if (payload.cwd) prefix.push(`cwd: ${payload.cwd}`);
737
+ if (Number.isFinite(payload.exit_code)) prefix.push(`exit: ${payload.exit_code}`);
738
+ else if (Number.isFinite(payload.exitCode)) prefix.push(`exit: ${payload.exitCode}`);
739
+ const body = summarizeOutput(output);
740
+ return [prefix.join(" \xB7 "), body].filter(Boolean).join("\n");
741
+ }
742
+ function normalizePatchChanges(changes) {
743
+ if (Array.isArray(changes)) {
744
+ return changes.map((change, index) => {
745
+ if (!change || typeof change !== "object") {
746
+ return { path: `change-${index + 1}`, kind: "", diff: "" };
747
+ }
748
+ return {
749
+ path: change.path || change.file || change.name || `change-${index + 1}`,
750
+ kind: change.kind || change.type || "",
751
+ diff: change.diff || change.unified_diff || change.content || ""
752
+ };
753
+ });
754
+ }
755
+ if (!changes || typeof changes !== "object") return [];
756
+ return Object.entries(changes).map(([file, change]) => ({
757
+ path: file,
758
+ kind: change && typeof change === "object" ? change.kind || change.type || "" : "",
759
+ diff: change && typeof change === "object" ? change.diff || change.unified_diff || change.content || "" : ""
760
+ }));
761
+ }
762
+ function summarizePatchChanges(changes) {
763
+ const normalized = normalizePatchChanges(changes);
764
+ const rows = normalized.slice(0, 16).map((change) => {
765
+ const stats = patchChangeStats(change);
766
+ const statLabel = [
767
+ stats.added > 0 ? `+${stats.added}` : "",
768
+ stats.removed > 0 ? `-${stats.removed}` : ""
769
+ ].filter(Boolean).join(" ");
770
+ return `${change.kind ? `${change.kind} ` : ""}${change.path}${statLabel ? ` ${statLabel}` : ""}`;
771
+ });
772
+ if (normalized.length > 16) rows.push(`... +${normalized.length - 16} files`);
773
+ return rows.join("\n");
774
+ }
775
+ function diffStats(diff) {
776
+ const text = normalizeText(diff);
777
+ if (!text) return { added: 0, removed: 0 };
778
+ return text.split("\n").reduce((stats, line) => {
779
+ if (line.startsWith("+++") || line.startsWith("---")) return stats;
780
+ if (line.startsWith("+")) stats.added += 1;
781
+ else if (line.startsWith("-")) stats.removed += 1;
782
+ return stats;
783
+ }, { added: 0, removed: 0 });
784
+ }
785
+ function rawContentLineCount(content) {
786
+ const text = normalizeText(content);
787
+ if (!text) return 0;
788
+ return text.split("\n").length;
789
+ }
790
+ function patchChangeStats(change) {
791
+ const stats = diffStats(change.diff);
792
+ if (stats.added > 0 || stats.removed > 0) return stats;
793
+ const kind = String(change.kind || "").toLowerCase();
794
+ const lines = rawContentLineCount(change.diff);
795
+ if (!lines) return stats;
796
+ if (kind === "add" || kind === "added") return { added: lines, removed: 0 };
797
+ if (kind === "delete" || kind === "deleted") return { added: 0, removed: lines };
798
+ return stats;
799
+ }
800
+ function titleForPatch(payload) {
801
+ if (payload.success === false) return "Patch failed";
802
+ const changes = normalizePatchChanges(payload.changes).length;
803
+ if (changes === 1) return "Edited 1 file";
804
+ if (changes > 1) return `Edited ${changes} files`;
805
+ return "Applied patch";
806
+ }
807
+ function titleForReviewAction(actionValue) {
808
+ const action = dataRecord(actionValue);
809
+ if (!action || typeof action !== "object") return "approval";
810
+ const type = String(action.type || "").replace(/[_-]/g, "").toLowerCase();
811
+ if (type === "command") return compactInline(action.command, "command");
812
+ if (type === "execve") return compactInline([action.program, ...Array.isArray(action.argv) ? action.argv : []].filter(Boolean).join(" "), "exec");
813
+ if (type === "applypatch") {
814
+ const files = Array.isArray(action.files) ? action.files : [];
815
+ return files.length ? `patch ${files.slice(0, 3).join(", ")}` : "patch";
816
+ }
817
+ if (type === "networkaccess") return compactInline(action.target || action.host, "network access");
818
+ if (type === "mcptoolcall") return compactInline([action.server, action.toolName || action.toolTitle].filter(Boolean).join("/"), "MCP tool");
819
+ if (type === "requestpermissions") return compactInline(action.reason, "permission request");
820
+ return compactInline(action.type, "approval");
821
+ }
822
+ function detailForReview(payload) {
823
+ const review = dataRecord(payload.review);
824
+ const action = dataRecord(payload.action);
825
+ return [
826
+ review.status ? `status: ${review.status}` : "",
827
+ review.riskLevel ? `risk: ${review.riskLevel}` : "",
828
+ review.rationale || "",
829
+ action.cwd ? `cwd: ${action.cwd}` : "",
830
+ payload.decisionSource ? `decision: ${payload.decisionSource}` : ""
831
+ ].filter(Boolean).join("\n");
832
+ }
833
+ function detailForHook(run) {
834
+ const entries = Array.isArray(run.entries) ? run.entries.map((entry) => {
835
+ if (!entry || typeof entry !== "object") return "";
836
+ const kind = compactInline(entry.kind || "");
837
+ const text = normalizeText(entry.text);
838
+ return [kind, text].filter(Boolean).join(": ");
839
+ }).filter(Boolean) : [];
840
+ return [
841
+ run.statusMessage || run.status_message || "",
842
+ run.sourcePath || run.source_path ? `source: ${run.sourcePath || run.source_path}` : "",
843
+ Number.isFinite(run.durationMs) ? `duration: ${run.durationMs}ms` : "",
844
+ Number.isFinite(run.duration_ms) ? `duration: ${run.duration_ms}ms` : "",
845
+ ...entries
846
+ ].filter(Boolean).join("\n");
847
+ }
848
+ function statusForHook(run, fallback = "running") {
849
+ const status = String(run && run.status || "").toLowerCase();
850
+ if (status === "failed" || status === "blocked" || status === "stopped") return "failed";
851
+ if (status === "completed") return "completed";
852
+ return fallback;
853
+ }
854
+ function titleForMcp(payload) {
855
+ const invocation = dataRecord(payload.invocation);
856
+ const server = compactInline(invocation.server || payload.server || "");
857
+ const tool = compactInline(invocation.tool || payload.tool || "");
858
+ if (server && tool) return `Used ${server}/${tool}`;
859
+ if (tool) return `Used ${tool}`;
860
+ return "Used MCP tool";
861
+ }
862
+ function detailForMcp(payload) {
863
+ const invocation = dataRecord(payload.invocation);
864
+ const result = dataRecord(payload.result);
865
+ const detail = [];
866
+ if (invocation.arguments) detail.push(JSON.stringify(invocation.arguments, null, 2));
867
+ else if (payload.arguments) detail.push(JSON.stringify(payload.arguments, null, 2));
868
+ if (payload.result && isDataRecord(payload.result)) {
869
+ if (Array.isArray(result.content)) {
870
+ const text = result.content.map((part) => part && typeof part.text === "string" ? part.text : "").filter(Boolean).join("\n");
871
+ if (text) detail.push(text);
872
+ }
873
+ if (result.is_error) detail.push("is_error: true");
874
+ }
875
+ return summarizeOutput(detail.join("\n"));
876
+ }
877
+ function textFromUserInput(content) {
878
+ if (typeof content === "string") return normalizeText(content);
879
+ if (!Array.isArray(content)) return "";
880
+ return content.map((part) => {
881
+ if (!part || typeof part !== "object") return "";
882
+ if (part.type === "Text" && typeof part.text === "string") return part.text;
883
+ if (part.type === "text" && typeof part.text === "string") return part.text;
884
+ if (part.type === "mention") return compactInline(part.name || part.path || "");
885
+ if (part.type === "skill") {
886
+ const name = compactInline(part.name || path.basename(part.path || ""));
887
+ return name ? `$${name}` : "";
888
+ }
889
+ if (typeof part.text === "string") return part.text;
890
+ return "";
891
+ }).filter(Boolean).join(" ").replace(/\s+([,.;:!?,。;:!?])/g, "$1").trim();
892
+ }
893
+ function textFromUserMessagePayload(payload) {
894
+ const direct = normalizeText(payload.message);
895
+ if (direct) return direct;
896
+ const textElements = Array.isArray(payload.text_elements) ? payload.text_elements : Array.isArray(payload.textElements) ? payload.textElements : [];
897
+ return textElements.map((element) => {
898
+ if (typeof element === "string") return element;
899
+ if (!element || typeof element !== "object") return "";
900
+ if (typeof element.text === "string") return element.text;
901
+ if (typeof element.content === "string") return element.content;
902
+ if (Array.isArray(element.content)) return textFromContent(element.content);
903
+ return "";
904
+ }).filter(Boolean).join("\n\n").trim();
905
+ }
906
+ function turnItemType(item) {
907
+ if (!item || typeof item !== "object") return "";
908
+ return String(item.type || "").trim().replace(/[_-]/g, "").toLowerCase();
909
+ }
910
+ function itemStatus(item, fallback = "") {
911
+ return String(item.status || item.statusText || fallback);
912
+ }
913
+ function responseItemTurnId(payload) {
914
+ if (!payload || typeof payload !== "object") return "";
915
+ const metadata = dataRecord(
916
+ payload.internal_chat_message_metadata_passthrough || payload.internalChatMessageMetadataPassthrough
917
+ );
918
+ return payload.turn_id || payload.turnId || metadata && (metadata.turn_id || metadata.turnId) || "";
919
+ }
920
+ function normalizeEventEnvelope(event) {
921
+ if (!isDataRecord(event)) return { type: "", payload: null };
922
+ if (typeof event.method === "string") {
923
+ return {
924
+ type: event.method,
925
+ payload: dataRecord(event.params)
926
+ };
927
+ }
928
+ const payload = isDataRecord(event.payload) ? event.payload : event;
929
+ return {
930
+ type: String(event.type || ""),
931
+ payload
932
+ };
933
+ }
934
+ function isIgnoredEventType(type) {
935
+ return [
936
+ "token_count",
937
+ "thread_goal_updated",
938
+ "thread_name_updated"
939
+ ].includes(type);
940
+ }
941
+ function detailForPlanSteps(steps) {
942
+ if (!Array.isArray(steps)) return "";
943
+ return steps.map((step) => {
944
+ if (!step || typeof step !== "object") return "";
945
+ const status = String(step.status || "").replace(/[_-]/g, "").toLowerCase();
946
+ const marker = status === "completed" || step.completed === true ? "[x]" : status === "inprogress" ? "[>]" : "[ ]";
947
+ return `${marker} ${compactInline(step.step || step.text || step.title || "")}`;
948
+ }).filter((line) => line.trim() !== "[ ]" && line.trim() !== "[x]" && line.trim() !== "[>]").join("\n");
949
+ }
950
+ function applyUserMessageToTurn(turn, { id = "", message = "", images = [], audios = [] } = {}) {
951
+ if (!turn) return;
952
+ const subagentNotification = parseSubagentNotification(message);
953
+ if (subagentNotification) {
954
+ appendProcess(turn, {
955
+ id: id || `${turn.id}-subagent-notification-${turn.processItems.length + 1}`,
956
+ type: "subagent",
957
+ title: subagentNotification.title,
958
+ detail: subagentNotification.detail,
959
+ status: subagentNotification.status
960
+ });
961
+ return;
962
+ }
963
+ const userImages = Array.isArray(images) ? images.filter(Boolean) : [];
964
+ const userAudios = Array.isArray(audios) ? audios.filter(Boolean) : [];
965
+ const pastedTranscript = extractReferencedPastedTranscriptContext(message);
966
+ const approvalTranscript = extractCodexApprovalTranscriptContext(pastedTranscript.text);
967
+ const userFiles = [
968
+ ...pastedTranscript.files,
969
+ ...approvalTranscript.files,
970
+ ...extractComposerFileAttachments(approvalTranscript.text).files
971
+ ].slice(0, MAX_USER_FILES_PER_TURN);
972
+ const text = visibleUserMessageText(approvalTranscript.text, {
973
+ renderedAttachmentKinds: renderedAttachmentKindsForAttachments({
974
+ images: userImages,
975
+ audios: userAudios,
976
+ files: userFiles
977
+ })
978
+ });
979
+ if (!text && userImages.length <= 0 && userAudios.length <= 0 && userFiles.length <= 0) return;
980
+ if (!turn.userMessage) {
981
+ if (text) turn.userMessage = text;
982
+ if (userImages.length) turn.userImages = userImages;
983
+ if (userAudios.length) turn.userAudios = userAudios;
984
+ if (userFiles.length) turn.userFiles = userFiles;
985
+ return;
986
+ }
987
+ if (text && turn.userMessage === text && userImages.length === 0 && userAudios.length === 0 && userFiles.length === 0) {
988
+ return;
989
+ }
990
+ appendProcess(turn, {
991
+ id: id || `${turn.id}-user-steer-${turn.processItems.length + 1}`,
992
+ type: "user-steer",
993
+ title: text || "User added context",
994
+ detail: text,
995
+ images: userImages,
996
+ audios: userAudios,
997
+ files: userFiles,
998
+ status: "completed"
999
+ });
1000
+ }
1001
+ function appendTurnItem(turn, item, status = "") {
1002
+ const type = turnItemType(item);
1003
+ if (!type) return false;
1004
+ if (type === "usermessage") {
1005
+ const images = imagesFromContent(item.content);
1006
+ const audios = audiosFromContent(item.content);
1007
+ applyUserMessageToTurn(turn, {
1008
+ id: item.id,
1009
+ message: textFromUserInput(item.content),
1010
+ images,
1011
+ audios
1012
+ });
1013
+ return true;
1014
+ }
1015
+ if (type === "hookprompt") {
1016
+ const fragments = Array.isArray(item.fragments) ? item.fragments : [];
1017
+ const text = fragments.map((fragment) => fragment && fragment.text).filter(Boolean).join("\n\n");
1018
+ if (text) appendProcess(turn, { id: item.id, type: "hook", title: "Hook prompt", detail: text, status });
1019
+ return true;
1020
+ }
1021
+ if (type === "agentmessage") {
1022
+ const text = Array.isArray(item.content) ? item.content.map((part) => part && part.text).filter(Boolean).join("\n\n") : normalizeText(item.text);
1023
+ if (text && (item.phase === "final_answer" || !item.phase)) {
1024
+ turn.finalMessage = finalMessageText(text, turn, item.id, item.memoryCitation || item.memory_citation);
1025
+ } else if (text) {
1026
+ const extracted = extractMemoryCitationBlock(text);
1027
+ appendMemoryCitation(turn, item.id, item.memoryCitation || item.memory_citation, extracted.detail);
1028
+ if (extracted.text) appendProcess(turn, { id: item.id, type: "message", title: extracted.text.split("\n")[0], detail: extracted.text });
1029
+ }
1030
+ return true;
1031
+ }
1032
+ if (type === "plan") {
1033
+ appendProcess(turn, { id: item.id, type: "plan", title: "Updated plan", detail: item.text, status });
1034
+ return true;
1035
+ }
1036
+ if (type === "todolist") {
1037
+ const detail = detailForPlanSteps(Array.isArray(item.items) ? item.items : []);
1038
+ appendProcess(turn, { id: item.id, type: "plan", title: "Updated todos", detail, status });
1039
+ return true;
1040
+ }
1041
+ if (type === "reasoning") {
1042
+ const text = [
1043
+ item.text,
1044
+ ...Array.isArray(item.summary_text) ? item.summary_text : [],
1045
+ ...Array.isArray(item.summary) ? item.summary : [],
1046
+ ...Array.isArray(item.content) ? item.content : []
1047
+ ].map(textFromContent).filter(Boolean).join("\n");
1048
+ if (text) appendProcess(turn, { id: item.id, type: "reasoning", title: "Reasoned", detail: text, status });
1049
+ return true;
1050
+ }
1051
+ if (type === "commandexecution") {
1052
+ appendProcess(turn, {
1053
+ id: item.id,
1054
+ type: "command",
1055
+ title: titleForCommandExecution(item),
1056
+ detail: summarizeCommandOutput(item),
1057
+ status: status || itemStatus(item)
1058
+ });
1059
+ return true;
1060
+ }
1061
+ if (type === "filechange") {
1062
+ appendProcess(turn, {
1063
+ id: item.id,
1064
+ type: "patch",
1065
+ title: titleForPatch(item),
1066
+ detail: summarizePatchChanges(item.changes),
1067
+ status: status || itemStatus(item)
1068
+ });
1069
+ return true;
1070
+ }
1071
+ if (type === "mcptoolcall") {
1072
+ appendProcess(turn, {
1073
+ id: item.id,
1074
+ type: "mcp",
1075
+ title: titleForMcp(item),
1076
+ detail: detailForMcp(item),
1077
+ images: imagesFromStructuredOutput(item.result),
1078
+ status: status || itemStatus(item)
1079
+ });
1080
+ return true;
1081
+ }
1082
+ if (type === "dynamictoolcall") {
1083
+ const name = [item.namespace, item.tool].filter(Boolean).join("/");
1084
+ appendProcess(turn, {
1085
+ id: item.id,
1086
+ type: "tool",
1087
+ title: name ? `Used ${name}` : "Used tool",
1088
+ detail: summarizeOutput(JSON.stringify(item.arguments || item.content_items || item.contentItems || "", null, 2)),
1089
+ images: imagesFromStructuredOutput(item.content_items || item.contentItems),
1090
+ status: status || itemStatus(item)
1091
+ });
1092
+ return true;
1093
+ }
1094
+ if (type === "collabagenttoolcall") {
1095
+ const tool = compactInline(item.tool, "agent tool");
1096
+ const receivers = Array.isArray(item.receiver_thread_ids) ? item.receiver_thread_ids : item.receiverThreadIds;
1097
+ appendProcess(turn, {
1098
+ id: item.id,
1099
+ type: "agent-tool",
1100
+ title: `Agent ${tool}`,
1101
+ detail: summarizeOutput([item.prompt, Array.isArray(receivers) && receivers.length ? `receivers: ${receivers.join(", ")}` : ""].filter(Boolean).join("\n")),
1102
+ status: status || itemStatus(item)
1103
+ });
1104
+ return true;
1105
+ }
1106
+ if (type === "subagentactivity") {
1107
+ const kind = compactInline(item.kind, "activity");
1108
+ const agentPath = compactInline(item.agent_path || item.agentPath || item.agent_thread_id || item.agentThreadId);
1109
+ appendProcess(turn, {
1110
+ id: item.id,
1111
+ type: "sub-agent",
1112
+ title: agentPath ? `${kind} ${agentPath}` : `Sub-agent ${kind}`,
1113
+ status
1114
+ });
1115
+ return true;
1116
+ }
1117
+ if (type === "websearch") {
1118
+ appendProcess(turn, { id: item.id, type: "web-search", title: compactInline(item.query, "Searched web"), status });
1119
+ return true;
1120
+ }
1121
+ if (type === "imageview") {
1122
+ appendProcess(turn, {
1123
+ id: item.id,
1124
+ type: "image",
1125
+ title: compactInline(item.path, "Viewed image"),
1126
+ images: imagesFromImageItem(item),
1127
+ status
1128
+ });
1129
+ return true;
1130
+ }
1131
+ if (type === "sleep") {
1132
+ const duration = item.duration_ms || item.durationMs;
1133
+ appendProcess(turn, {
1134
+ id: item.id,
1135
+ type: "sleep",
1136
+ title: typeof duration === "number" ? `Slept for ${Math.round(duration / 1e3)}s` : "Slept",
1137
+ status: status || itemStatus(item)
1138
+ });
1139
+ return true;
1140
+ }
1141
+ if (type === "imagegeneration") {
1142
+ const detail = [
1143
+ item.saved_path || item.savedPath,
1144
+ item.revised_prompt || item.revisedPrompt,
1145
+ item.status
1146
+ ].map((value) => compactInline(value)).filter(Boolean).join("\n");
1147
+ appendProcess(turn, {
1148
+ id: item.id,
1149
+ type: "image-generation",
1150
+ title: "Generated image",
1151
+ detail,
1152
+ images: imagesFromImageItem(item),
1153
+ status: status || itemStatus(item)
1154
+ });
1155
+ return true;
1156
+ }
1157
+ if (type === "enteredreviewmode" || type === "exitedreviewmode") {
1158
+ appendProcess(turn, {
1159
+ id: item.id,
1160
+ type: "review",
1161
+ title: type === "enteredreviewmode" ? "Entered review mode" : "Exited review mode",
1162
+ detail: item.review || "",
1163
+ status
1164
+ });
1165
+ return true;
1166
+ }
1167
+ if (type === "contextcompaction") {
1168
+ appendProcess(turn, { id: item.id, type: "compaction", title: "Compacted context", status });
1169
+ return true;
1170
+ }
1171
+ if (type === "error") {
1172
+ appendProcess(turn, {
1173
+ id: item.id,
1174
+ type: "error",
1175
+ title: compactInline(item.message, "Error"),
1176
+ detail: item.detail || item.error || "",
1177
+ status: itemStatus(item, "failed")
1178
+ });
1179
+ return true;
1180
+ }
1181
+ appendProcess(turn, {
1182
+ id: item.id,
1183
+ type: "event",
1184
+ title: humanizeType(item.type, "Codex event"),
1185
+ detail: summarizeOutput(JSON.stringify(item, null, 2)),
1186
+ status: status || itemStatus(item)
1187
+ });
1188
+ return true;
1189
+ }
1190
+ function appendResponseItem(turn, payload, functionCalls) {
1191
+ if (!turn || !payload || typeof payload !== "object") return false;
1192
+ if (payload.type === "message") {
1193
+ const text = textFromContent(payload.content);
1194
+ const images = imagesFromContent(payload.content);
1195
+ if (!text && images.length <= 0) return true;
1196
+ if (payload.role === "user") {
1197
+ applyUserMessageToTurn(turn, {
1198
+ id: payload.id,
1199
+ message: text,
1200
+ images
1201
+ });
1202
+ } else if (payload.role === "assistant" && text && (payload.phase === "final_answer" || !payload.phase && !turn.finalMessage)) {
1203
+ turn.finalMessage = finalMessageText(text, turn, payload.id, payload.memoryCitation || payload.memory_citation);
1204
+ } else if (payload.role === "assistant" && text) {
1205
+ const extracted = extractMemoryCitationBlock(text);
1206
+ appendMemoryCitation(turn, payload.id, payload.memoryCitation || payload.memory_citation, extracted.detail);
1207
+ appendProcess(turn, {
1208
+ id: payload.id,
1209
+ type: "message",
1210
+ title: (extracted.text || text).split("\n")[0],
1211
+ detail: extracted.text || text
1212
+ });
1213
+ }
1214
+ return true;
1215
+ }
1216
+ if (payload.type === "agent_message") {
1217
+ const text = textFromContent(payload.content);
1218
+ appendProcess(turn, {
1219
+ id: payload.id,
1220
+ type: "agent-message",
1221
+ title: [payload.author, payload.recipient].filter(Boolean).join(" -> ") || "Agent message",
1222
+ detail: text
1223
+ });
1224
+ return true;
1225
+ }
1226
+ if (payload.type === "reasoning") {
1227
+ const summary = [
1228
+ ...Array.isArray(payload.summary) ? payload.summary.map(textFromContent) : [],
1229
+ ...Array.isArray(payload.content) ? payload.content.map(textFromContent) : []
1230
+ ].filter(Boolean).join("\n");
1231
+ if (summary) {
1232
+ appendProcess(turn, {
1233
+ id: payload.id,
1234
+ type: "reasoning",
1235
+ title: "Reasoned",
1236
+ detail: summary
1237
+ });
1238
+ }
1239
+ return true;
1240
+ }
1241
+ if (payload.type === "additional_tools") {
1242
+ const count = Array.isArray(payload.tools) ? payload.tools.length : 0;
1243
+ appendProcess(turn, {
1244
+ id: payload.id,
1245
+ type: "tool",
1246
+ title: count ? `Added ${count} tools` : "Added tools",
1247
+ detail: summarizeOutput(JSON.stringify(payload.tools || "", null, 2)),
1248
+ status: "completed"
1249
+ });
1250
+ return true;
1251
+ }
1252
+ if (payload.type === "local_shell_call") {
1253
+ appendProcess(turn, {
1254
+ id: payload.call_id || payload.id,
1255
+ type: "command",
1256
+ title: titleForLocalShell(payload),
1257
+ detail: detailForLocalShell(payload),
1258
+ status: payload.status || "completed"
1259
+ });
1260
+ return true;
1261
+ }
1262
+ if (payload.type === "function_call" || payload.type === "custom_tool_call") {
1263
+ const title = processTitleForFunctionCall(payload);
1264
+ const processType = processTypeForFunctionCall(payload);
1265
+ const callId = String(payload.call_id || payload.id || "");
1266
+ if (callId) functionCalls.set(callId, { title, type: processType });
1267
+ appendProcess(turn, {
1268
+ id: callId || payload.id,
1269
+ type: processType,
1270
+ title,
1271
+ detail: detailForFunctionCall(payload),
1272
+ status: "running"
1273
+ });
1274
+ return true;
1275
+ }
1276
+ if (payload.type === "function_call_output" || payload.type === "custom_tool_call_output") {
1277
+ const callId = String(payload.call_id || "");
1278
+ const callMeta = functionCalls.get(callId);
1279
+ appendProcess(turn, {
1280
+ id: callId || payload.id,
1281
+ type: callMeta?.type || "tool-output",
1282
+ title: callMeta?.title || "Tool output",
1283
+ detail: summarizeStructuredOutput(payload.output),
1284
+ images: imagesFromStructuredOutput(payload.output),
1285
+ mergeDetail: true,
1286
+ status: "completed"
1287
+ });
1288
+ return true;
1289
+ }
1290
+ if (payload.type === "web_search_call") {
1291
+ const action = dataRecord(payload.action);
1292
+ appendProcess(turn, {
1293
+ id: payload.id,
1294
+ type: "web-search",
1295
+ title: compactInline(action.query, "Searched web"),
1296
+ detail: payload.action ? summarizeOutput(JSON.stringify(payload.action, null, 2)) : "",
1297
+ status: payload.status || "completed"
1298
+ });
1299
+ return true;
1300
+ }
1301
+ if (payload.type === "tool_search_call" || payload.type === "tool_search_output") {
1302
+ const callId = payload.call_id || payload.id || "";
1303
+ appendProcess(turn, {
1304
+ id: callId,
1305
+ type: "tool",
1306
+ title: "Searched tools",
1307
+ detail: summarizeOutput(JSON.stringify(payload.arguments || payload.tools || "", null, 2)),
1308
+ status: payload.type === "tool_search_call" ? payload.status || "running" : payload.status || "completed"
1309
+ });
1310
+ return true;
1311
+ }
1312
+ if (payload.type === "image_generation_call") {
1313
+ appendProcess(turn, {
1314
+ id: payload.id,
1315
+ type: "image-generation",
1316
+ title: "Generated image",
1317
+ detail: compactInline(payload.revised_prompt || payload.status || ""),
1318
+ images: imagesFromImageItem(payload),
1319
+ status: payload.status || "running"
1320
+ });
1321
+ return true;
1322
+ }
1323
+ if (payload.type === "compaction" || payload.type === "compaction_summary" || payload.type === "compaction_trigger" || payload.type === "context_compaction") {
1324
+ appendProcess(turn, {
1325
+ id: payload.id,
1326
+ type: "compaction",
1327
+ title: payload.type === "compaction_trigger" ? "Compaction triggered" : "Compacted context",
1328
+ detail: compactInline(payload.encrypted_content || payload.status || ""),
1329
+ status: payload.status || "completed"
1330
+ });
1331
+ return true;
1332
+ }
1333
+ appendProcess(turn, {
1334
+ id: payload.id || payload.call_id,
1335
+ type: "event",
1336
+ title: humanizeType(payload.type, "Codex response item"),
1337
+ detail: summarizeOutput(JSON.stringify(payload, null, 2)),
1338
+ status: payload.status || ""
1339
+ });
1340
+ return true;
1341
+ }
1342
+ function newTurn(id = "") {
1343
+ return {
1344
+ id: String(id || `turn-${Date.now()}-${Math.random().toString(36).slice(2)}`),
1345
+ userMessage: "",
1346
+ userImages: [],
1347
+ userAudios: [],
1348
+ userFiles: [],
1349
+ finalMessage: "",
1350
+ startedAt: null,
1351
+ completedAt: null,
1352
+ durationMs: null,
1353
+ status: "inProgress",
1354
+ model: "",
1355
+ effort: "",
1356
+ cwd: "",
1357
+ processItems: []
1358
+ };
1359
+ }
1360
+ function isEmptyTurn(turn) {
1361
+ return !turn.userMessage && (!Array.isArray(turn.userImages) || turn.userImages.length === 0) && (!Array.isArray(turn.userAudios) || turn.userAudios.length === 0) && (!Array.isArray(turn.userFiles) || turn.userFiles.length === 0) && !turn.finalMessage && turn.processItems.length === 0;
1362
+ }
1363
+ function hasRunningProcessItems(turn) {
1364
+ return turn.processItems.some((item) => {
1365
+ const status = String(item.status || "").replace(/[_-]/g, "").toLowerCase();
1366
+ return status === "running" || status === "inprogress" || status === "pending";
1367
+ });
1368
+ }
1369
+ function isStandaloneThreadSettingsTurn(turn) {
1370
+ if (!turn || turn.status !== "inProgress" || turn.userMessage || turn.finalMessage) return false;
1371
+ const items = Array.isArray(turn.processItems) ? turn.processItems : [];
1372
+ return items.length > 0 && items.every((item) => item && item.type === "event" && item.title === "Thread Settings Applied");
1373
+ }
1374
+ function processItemIdentity(item) {
1375
+ return [
1376
+ String(item?.type || ""),
1377
+ String(item?.title || "").trim(),
1378
+ String(item?.detail || "").trim(),
1379
+ String(item?.status || "").trim()
1380
+ ].join("\0");
1381
+ }
1382
+ function dedupeAdjacentProcessItems(items) {
1383
+ const deduped = [];
1384
+ let previousKey = "";
1385
+ for (const item of items || []) {
1386
+ const key = processItemIdentity(item);
1387
+ if (key && key === previousKey) continue;
1388
+ deduped.push(item);
1389
+ previousKey = key;
1390
+ }
1391
+ return deduped;
1392
+ }
1393
+ function sanitizeProcessItemForOutput(item) {
1394
+ if (!item || typeof item !== "object") return null;
1395
+ const title = (0, import_codex_transcript_sanitizer.stripCodexInternalContextBlocks)(item.title);
1396
+ const detail = (0, import_codex_transcript_sanitizer.stripCodexInternalContextBlocks)(item.detail);
1397
+ if (!title && !detail && (!Array.isArray(item.images) || item.images.length <= 0) && (!Array.isArray(item.audios) || item.audios.length <= 0) && (!Array.isArray(item.files) || item.files.length <= 0)) {
1398
+ return null;
1399
+ }
1400
+ return {
1401
+ ...item,
1402
+ title: title || item.title,
1403
+ detail
1404
+ };
1405
+ }
1406
+ function normalizeTurnForOutput(turn) {
1407
+ if (!turn || typeof turn !== "object") return turn;
1408
+ turn.userMessage = visibleUserMessageText(turn.userMessage, {
1409
+ renderedAttachmentKinds: renderedAttachmentKindsForTurn(turn)
1410
+ });
1411
+ turn.finalMessage = (0, import_codex_transcript_sanitizer.stripCodexInternalContextBlocks)(turn.finalMessage);
1412
+ turn.processItems = dedupeAdjacentProcessItems(turn.processItems).map(sanitizeProcessItemForOutput).filter((item) => item !== null);
1413
+ if (turn.status === "inProgress" && turn.finalMessage && !hasRunningProcessItems(turn)) {
1414
+ turn.status = "completed";
1415
+ }
1416
+ return turn;
1417
+ }
1418
+ function completeTurn(turn, payload = {}) {
1419
+ if (!turn) return;
1420
+ turn.status = payload.type === "turn_aborted" || payload.type === "task_aborted" ? "interrupted" : "completed";
1421
+ if (typeof payload.completed_at === "number") turn.completedAt = payload.completed_at;
1422
+ if (typeof payload.completedAt === "number") turn.completedAt = payload.completedAt;
1423
+ const nestedTurn = dataRecord(payload.turn);
1424
+ if (typeof nestedTurn.completedAt === "number") {
1425
+ turn.completedAt = nestedTurn.completedAt;
1426
+ }
1427
+ if (typeof payload.duration_ms === "number") turn.durationMs = payload.duration_ms;
1428
+ if (typeof payload.durationMs === "number") turn.durationMs = payload.durationMs;
1429
+ if (typeof nestedTurn.durationMs === "number") {
1430
+ turn.durationMs = nestedTurn.durationMs;
1431
+ }
1432
+ if (!turn.finalMessage && typeof payload.last_agent_message === "string") {
1433
+ turn.finalMessage = finalMessageText(payload.last_agent_message, turn, `${turn.id}-last-agent-message`);
1434
+ }
1435
+ }
1436
+ function appendTurnSnapshot(turns, turnValue) {
1437
+ if (!isDataRecord(turnValue)) return false;
1438
+ const turn = turnValue;
1439
+ const normalizedTurn = newTurn(turn.id);
1440
+ normalizedTurn.status = String(turn.status || normalizedTurn.status);
1441
+ normalizedTurn.startedAt = typeof turn.startedAt === "number" ? turn.startedAt : null;
1442
+ normalizedTurn.completedAt = typeof turn.completedAt === "number" ? turn.completedAt : null;
1443
+ normalizedTurn.durationMs = typeof turn.durationMs === "number" ? turn.durationMs : null;
1444
+ if (Array.isArray(turn.items)) {
1445
+ for (const item of turn.items) {
1446
+ if (!isDataRecord(item)) continue;
1447
+ appendTurnItem(normalizedTurn, item, itemStatus(item, normalizedTurn.status));
1448
+ }
1449
+ }
1450
+ if (isDataRecord(turn.error)) {
1451
+ appendTurnItem(normalizedTurn, { type: "error", id: `${normalizedTurn.id}-error`, ...turn.error }, "failed");
1452
+ }
1453
+ if (!isEmptyTurn(normalizedTurn)) turns.push(normalizedTurn);
1454
+ return true;
1455
+ }
1456
+ function appendProcess(turn, item) {
1457
+ if (!turn || !item || !item.title) return;
1458
+ const id = String(item.id || `${turn.id}-process-${turn.processItems.length + 1}`);
1459
+ const detail = normalizeText(item.detail);
1460
+ const files = (Array.isArray(item.files) ? item.files : []).filter(isTranscriptFile).slice(0, MAX_USER_FILES_PER_TURN);
1461
+ const images = (Array.isArray(item.images) ? item.images : []).filter(isTranscriptImage).slice(0, MAX_USER_IMAGES_PER_TURN);
1462
+ const next = {
1463
+ id,
1464
+ type: String(item.type || "event"),
1465
+ title: normalizeText(item.title).slice(0, 240),
1466
+ detail: detail.slice(0, 4e3),
1467
+ images,
1468
+ files,
1469
+ status: String(item.status || "")
1470
+ };
1471
+ const existing = turn.processItems.find((entry) => entry.id === id);
1472
+ if (existing) {
1473
+ existing.type = next.type || existing.type;
1474
+ if (!item.mergeDetail) existing.title = next.title || existing.title;
1475
+ if (item.mergeDetail && existing.detail && next.detail && existing.detail !== next.detail) {
1476
+ existing.detail = `${existing.detail}
1477
+
1478
+ ${next.detail}`.slice(0, 4e3);
1479
+ } else {
1480
+ existing.detail = next.detail || existing.detail;
1481
+ }
1482
+ if (next.images.length) {
1483
+ const urls = new Set(existing.images.map((image) => image.url));
1484
+ existing.images = [
1485
+ ...existing.images,
1486
+ ...next.images.filter((image) => image.url && !urls.has(image.url))
1487
+ ].slice(0, MAX_USER_IMAGES_PER_TURN);
1488
+ }
1489
+ if (next.files.length) {
1490
+ const keys = new Set(existing.files.map((file) => `${file.name}\0${file.content}\0${file.error}`));
1491
+ existing.files = [
1492
+ ...existing.files,
1493
+ ...next.files.filter((file) => !keys.has(`${file.name}\0${file.content}\0${file.error}`))
1494
+ ].slice(0, MAX_USER_FILES_PER_TURN);
1495
+ }
1496
+ existing.status = next.status || existing.status;
1497
+ return;
1498
+ }
1499
+ turn.processItems.push(next);
1500
+ }
1501
+ function appendProcessDelta(turn, item) {
1502
+ if (!turn || !item || !item.title) return;
1503
+ const id = String(item.id || `${turn.id}-process-${turn.processItems.length + 1}`);
1504
+ const delta = normalizeDeltaText(item.delta);
1505
+ const existing = turn.processItems.find((entry) => entry.id === id);
1506
+ if (existing) {
1507
+ existing.type = String(item.type || existing.type);
1508
+ existing.title = String(item.title || existing.title);
1509
+ if (delta) existing.detail = `${existing.detail || ""}${delta}`.slice(0, 4e3);
1510
+ existing.status = String(item.status || existing.status);
1511
+ return;
1512
+ }
1513
+ turn.processItems.push({
1514
+ id,
1515
+ type: String(item.type || "event"),
1516
+ title: normalizeText(item.title).slice(0, 240),
1517
+ detail: delta.slice(0, 4e3),
1518
+ images: [],
1519
+ files: [],
1520
+ status: String(item.status || "")
1521
+ });
1522
+ }
1523
+ function buildTranscriptFromLines(lines, options = {}) {
1524
+ const turns = [];
1525
+ let active = null;
1526
+ const functionCalls = /* @__PURE__ */ new Map();
1527
+ const resumeSnapshotTurn = (id) => {
1528
+ if (!id) return null;
1529
+ for (let index = turns.length - 1; index >= 0; index -= 1) {
1530
+ if (turns[index] && turns[index].id === id && turns[index].status === "inProgress") {
1531
+ return turns.splice(index, 1)[0] || null;
1532
+ }
1533
+ }
1534
+ return null;
1535
+ };
1536
+ const ensureActive = (id = "") => {
1537
+ if (active && (!id || active.id === id)) return active;
1538
+ if (active && !isEmptyTurn(active)) turns.push(active);
1539
+ active = resumeSnapshotTurn(id) || newTurn(id);
1540
+ return active;
1541
+ };
1542
+ const finishActive = (payload = {}) => {
1543
+ if (!active) return;
1544
+ completeTurn(active, payload);
1545
+ if (!isEmptyTurn(active)) turns.push(active);
1546
+ active = null;
1547
+ };
1548
+ for (const line of lines) {
1549
+ if (!line.trim()) continue;
1550
+ let event = null;
1551
+ try {
1552
+ event = JSON.parse(line);
1553
+ } catch {
1554
+ continue;
1555
+ }
1556
+ const { type: eventType, payload } = normalizeEventEnvelope(event);
1557
+ if (!payload) continue;
1558
+ if (eventType === "turn_context") {
1559
+ const turn = ensureActive(payload.turn_id);
1560
+ turn.cwd = typeof payload.cwd === "string" ? payload.cwd : turn.cwd;
1561
+ turn.model = typeof payload.model === "string" ? payload.model : turn.model;
1562
+ turn.effort = typeof payload.effort === "string" ? payload.effort : turn.effort;
1563
+ continue;
1564
+ }
1565
+ if (eventType === "compacted") {
1566
+ appendProcess(ensureActive(), {
1567
+ type: "compaction",
1568
+ title: "Compacted context",
1569
+ detail: payload.message || ""
1570
+ });
1571
+ continue;
1572
+ }
1573
+ const providerThread = dataRecord(payload.thread);
1574
+ if (eventType === "thread/read" && Array.isArray(providerThread.turns)) {
1575
+ if (active && !isEmptyTurn(active)) turns.push(active);
1576
+ active = null;
1577
+ turns.length = 0;
1578
+ for (const turn of providerThread.turns) appendTurnSnapshot(turns, turn);
1579
+ continue;
1580
+ }
1581
+ if (eventType === "thread/items/list" && Array.isArray(payload.data)) {
1582
+ if (active && !isEmptyTurn(active)) turns.push(active);
1583
+ active = newTurn(payload.turnId || payload.turn_id || "thread-items-list");
1584
+ active.status = "completed";
1585
+ for (const item of payload.data) {
1586
+ if (!isDataRecord(item)) continue;
1587
+ appendTurnItem(active, item, itemStatus(item, active.status));
1588
+ }
1589
+ if (!isEmptyTurn(active)) turns.push(active);
1590
+ active = null;
1591
+ continue;
1592
+ }
1593
+ if (eventType === "turn" || eventType === "turn/snapshot") {
1594
+ if (appendTurnSnapshot(turns, payload.turn || payload)) continue;
1595
+ }
1596
+ if (eventType === "turn.started" || eventType === "turn_started" || eventType === "turn/started") {
1597
+ const nestedTurn = dataRecord(payload.turn);
1598
+ const turn = ensureActive(payload.turn_id || payload.turnId || nestedTurn.id);
1599
+ turn.status = "inProgress";
1600
+ if (typeof nestedTurn.startedAt === "number") turn.startedAt = nestedTurn.startedAt;
1601
+ if (typeof nestedTurn.status === "string") turn.status = nestedTurn.status;
1602
+ if (typeof payload.startedAtMs === "number") turn.startedAt = payload.startedAtMs;
1603
+ continue;
1604
+ }
1605
+ if (eventType === "item.started" || eventType === "item.updated" || eventType === "item.completed" || eventType === "item/started" || eventType === "item/updated" || eventType === "item/completed") {
1606
+ const status = eventType === "item.started" || eventType === "item/started" ? "running" : eventType === "item.updated" || eventType === "item/updated" ? itemStatus(dataRecord(payload.item), "running") : itemStatus(dataRecord(payload.item), "completed");
1607
+ if (appendTurnItem(ensureActive(payload.turn_id || payload.turnId), dataRecord(payload.item), status)) continue;
1608
+ }
1609
+ if (eventType === "turn.completed" || eventType === "turn_complete" || eventType === "turn/completed") {
1610
+ const completedTurn = dataRecord(payload.turn);
1611
+ if (Array.isArray(completedTurn.items)) {
1612
+ const turn = ensureActive(completedTurn.id);
1613
+ for (const item of completedTurn.items) {
1614
+ if (!isDataRecord(item)) continue;
1615
+ appendTurnItem(turn, item, itemStatus(item, String(completedTurn.status || "completed")));
1616
+ }
1617
+ }
1618
+ finishActive({
1619
+ ...payload,
1620
+ type: "turn_complete",
1621
+ turn_id: payload.turn_id || payload.turnId || completedTurn.id,
1622
+ duration_ms: payload.duration_ms || payload.durationMs || completedTurn.durationMs
1623
+ });
1624
+ continue;
1625
+ }
1626
+ if (eventType === "turn/plan/updated") {
1627
+ appendProcess(ensureActive(payload.turn_id || payload.turnId), {
1628
+ id: payload.id || `${payload.turnId || payload.turn_id || "turn"}-plan`,
1629
+ type: "plan",
1630
+ title: "Updated plan",
1631
+ detail: detailForPlanSteps(payload.plan),
1632
+ status: "completed"
1633
+ });
1634
+ continue;
1635
+ }
1636
+ if (eventType === "item/agentMessage/delta") {
1637
+ const turn = ensureActive(payload.turn_id || payload.turnId);
1638
+ const delta = normalizeDeltaText(payload.delta);
1639
+ if (delta) {
1640
+ turn.finalMessage = `${turn.finalMessage || ""}${delta}`;
1641
+ }
1642
+ continue;
1643
+ }
1644
+ if (eventType === "item/plan/delta") {
1645
+ appendProcessDelta(ensureActive(payload.turn_id || payload.turnId), {
1646
+ id: payload.item_id || payload.itemId,
1647
+ type: "plan",
1648
+ title: "Updated plan",
1649
+ delta: payload.delta,
1650
+ status: "running"
1651
+ });
1652
+ continue;
1653
+ }
1654
+ if (eventType === "item/reasoning/summaryTextDelta" || eventType === "item/reasoning/textDelta") {
1655
+ appendProcessDelta(ensureActive(payload.turn_id || payload.turnId), {
1656
+ id: payload.item_id || payload.itemId,
1657
+ type: "reasoning",
1658
+ title: "Reasoned",
1659
+ delta: payload.delta,
1660
+ status: "running"
1661
+ });
1662
+ continue;
1663
+ }
1664
+ if (eventType === "item/reasoning/summaryPartAdded") {
1665
+ appendProcessDelta(ensureActive(payload.turn_id || payload.turnId), {
1666
+ id: payload.item_id || payload.itemId,
1667
+ type: "reasoning",
1668
+ title: "Reasoned",
1669
+ delta: "\n",
1670
+ status: "running"
1671
+ });
1672
+ continue;
1673
+ }
1674
+ if (eventType === "item/commandExecution/outputDelta") {
1675
+ appendProcessDelta(ensureActive(payload.turn_id || payload.turnId), {
1676
+ id: payload.item_id || payload.itemId,
1677
+ type: "command",
1678
+ title: "Ran command",
1679
+ delta: payload.delta,
1680
+ status: "running"
1681
+ });
1682
+ continue;
1683
+ }
1684
+ if (eventType === "item/fileChange/outputDelta") {
1685
+ appendProcessDelta(ensureActive(payload.turn_id || payload.turnId), {
1686
+ id: payload.item_id || payload.itemId,
1687
+ type: "patch",
1688
+ title: "Applied patch",
1689
+ delta: payload.delta,
1690
+ status: "running"
1691
+ });
1692
+ continue;
1693
+ }
1694
+ if (eventType === "item/fileChange/patchUpdated") {
1695
+ appendProcess(ensureActive(payload.turn_id || payload.turnId), {
1696
+ id: payload.item_id || payload.itemId,
1697
+ type: "patch",
1698
+ title: titleForPatch(payload),
1699
+ detail: summarizePatchChanges(payload.changes),
1700
+ status: "running"
1701
+ });
1702
+ continue;
1703
+ }
1704
+ if (eventType === "turn/diff/updated") {
1705
+ appendProcess(ensureActive(payload.turn_id || payload.turnId), {
1706
+ id: `${payload.turnId || payload.turn_id || "turn"}-diff`,
1707
+ type: "patch",
1708
+ title: "Updated diff",
1709
+ detail: summarizeOutput(payload.diff),
1710
+ status: "running"
1711
+ });
1712
+ continue;
1713
+ }
1714
+ if (eventType === "item/autoApprovalReview/started" || eventType === "item/autoApprovalReview/completed") {
1715
+ const completed = eventType.endsWith("/completed");
1716
+ const actionTitle = titleForReviewAction(payload.action);
1717
+ appendProcess(ensureActive(payload.turn_id || payload.turnId), {
1718
+ id: payload.reviewId || payload.review_id || payload.targetItemId || payload.target_item_id,
1719
+ type: "review",
1720
+ title: completed ? `Reviewed ${actionTitle}` : `Reviewing ${actionTitle}`,
1721
+ detail: detailForReview(payload),
1722
+ status: completed ? "completed" : "running"
1723
+ });
1724
+ continue;
1725
+ }
1726
+ if (eventType === "item/commandExecution/terminalInteraction") {
1727
+ appendProcess(ensureActive(payload.turn_id || payload.turnId), {
1728
+ id: payload.item_id || payload.itemId,
1729
+ type: "command",
1730
+ title: "Interacted with terminal",
1731
+ detail: normalizeText(payload.stdin),
1732
+ status: "running",
1733
+ mergeDetail: true
1734
+ });
1735
+ continue;
1736
+ }
1737
+ if (eventType === "item/mcpToolCall/progress") {
1738
+ appendProcessDelta(ensureActive(payload.turn_id || payload.turnId), {
1739
+ id: payload.item_id || payload.itemId,
1740
+ type: "mcp",
1741
+ title: "MCP progress",
1742
+ delta: payload.message ? `${payload.message}
1743
+ ` : "",
1744
+ status: "running"
1745
+ });
1746
+ continue;
1747
+ }
1748
+ if (eventType === "hook/started" || eventType === "hook/completed") {
1749
+ const run = dataRecord(payload.run);
1750
+ const completed = eventType.endsWith("/completed");
1751
+ const eventName = run.eventName || run.event_name;
1752
+ appendProcess(ensureActive(payload.turn_id || payload.turnId), {
1753
+ id: run.id || `${payload.turnId || payload.turn_id || "turn"}-hook`,
1754
+ type: "hook",
1755
+ title: completed ? `Completed ${compactInline(eventName, "hook")}` : `Running ${compactInline(eventName, "hook")}`,
1756
+ detail: detailForHook(run),
1757
+ status: statusForHook(run, completed ? "completed" : "running")
1758
+ });
1759
+ continue;
1760
+ }
1761
+ if (eventType === "serverRequest/resolved") {
1762
+ appendProcess(ensureActive(payload.turn_id || payload.turnId), {
1763
+ id: payload.requestId || payload.request_id,
1764
+ type: "event",
1765
+ title: "Resolved server request",
1766
+ detail: payload.requestId || payload.request_id || "",
1767
+ status: "completed"
1768
+ });
1769
+ continue;
1770
+ }
1771
+ if (eventType === "thread/compacted") {
1772
+ appendProcess(ensureActive(payload.turn_id || payload.turnId), {
1773
+ id: `${payload.turnId || payload.turn_id || "turn"}-compacted`,
1774
+ type: "compaction",
1775
+ title: "Compacted context",
1776
+ status: "completed"
1777
+ });
1778
+ continue;
1779
+ }
1780
+ if (eventType === "model/rerouted") {
1781
+ appendProcess(ensureActive(payload.turn_id || payload.turnId), {
1782
+ id: `${payload.turnId || payload.turn_id || "turn"}-model-rerouted`,
1783
+ type: "event",
1784
+ title: `Rerouted ${compactInline(payload.fromModel || payload.from_model, "model")} to ${compactInline(payload.toModel || payload.to_model, "model")}`,
1785
+ detail: compactInline(payload.reason),
1786
+ status: "completed"
1787
+ });
1788
+ continue;
1789
+ }
1790
+ if (eventType === "model/verification") {
1791
+ appendProcess(ensureActive(payload.turn_id || payload.turnId), {
1792
+ id: `${payload.turnId || payload.turn_id || "turn"}-model-verification`,
1793
+ type: "event",
1794
+ title: "Verified model",
1795
+ detail: summarizeOutput(JSON.stringify(payload.verifications || [], null, 2)),
1796
+ status: "completed"
1797
+ });
1798
+ continue;
1799
+ }
1800
+ if (eventType === "model/safetyBuffering/updated") {
1801
+ appendProcess(ensureActive(payload.turn_id || payload.turnId), {
1802
+ id: `${payload.turnId || payload.turn_id || "turn"}-safety-buffering`,
1803
+ type: "warning",
1804
+ title: payload.showBufferingUi === false ? "Safety buffering hidden" : "Safety buffering",
1805
+ detail: [
1806
+ payload.model ? `model: ${payload.model}` : "",
1807
+ Array.isArray(payload.useCases) && payload.useCases.length ? `use cases: ${payload.useCases.join(", ")}` : "",
1808
+ Array.isArray(payload.reasons) && payload.reasons.length ? `reasons: ${payload.reasons.join(", ")}` : "",
1809
+ payload.fasterModel ? `faster model: ${payload.fasterModel}` : ""
1810
+ ].filter(Boolean).join("\n"),
1811
+ status: payload.showBufferingUi === false ? "completed" : "warning"
1812
+ });
1813
+ continue;
1814
+ }
1815
+ if (eventType === "turn/moderationMetadata") {
1816
+ appendProcess(ensureActive(payload.turn_id || payload.turnId), {
1817
+ id: `${payload.turnId || payload.turn_id || "turn"}-moderation`,
1818
+ type: "event",
1819
+ title: "Updated moderation metadata",
1820
+ detail: summarizeOutput(JSON.stringify(payload.metadata || {}, null, 2)),
1821
+ status: "completed"
1822
+ });
1823
+ continue;
1824
+ }
1825
+ if (eventType === "rawResponseItem/completed") {
1826
+ const turn = ensureActive(payload.turn_id || payload.turnId);
1827
+ if (appendResponseItem(turn, dataRecord(payload.item), functionCalls)) continue;
1828
+ }
1829
+ if (eventType === "turn.failed" || eventType === "error") {
1830
+ const turn = ensureActive(payload.turn_id || payload.turnId);
1831
+ const error = isDataRecord(payload.error) ? payload.error : payload;
1832
+ appendProcess(turn, {
1833
+ type: "error",
1834
+ title: compactInline(error.message || error.code, "Error"),
1835
+ detail: error.detail || error.error || "",
1836
+ status: "failed"
1837
+ });
1838
+ finishActive({
1839
+ ...payload,
1840
+ type: "turn_aborted"
1841
+ });
1842
+ continue;
1843
+ }
1844
+ if (eventType === "warning" || eventType === "guardianWarning" || eventType === "configWarning" || eventType === "deprecationNotice") {
1845
+ const message = payload.message || payload.summary || payload.title || "Warning";
1846
+ appendProcess(ensureActive(payload.turn_id || payload.turnId), {
1847
+ type: "warning",
1848
+ title: compactInline(message, "Warning"),
1849
+ detail: payload.details || payload.path || "",
1850
+ status: "warning"
1851
+ });
1852
+ continue;
1853
+ }
1854
+ if (eventType === "windows/worldWritableWarning") {
1855
+ const paths = Array.isArray(payload.samplePaths) ? payload.samplePaths : [];
1856
+ appendProcess(ensureActive(payload.turn_id || payload.turnId), {
1857
+ type: "warning",
1858
+ title: "World-writable paths detected",
1859
+ detail: paths.concat(payload.extraCount ? [`... +${payload.extraCount} more`] : []).join("\n"),
1860
+ status: "warning"
1861
+ });
1862
+ continue;
1863
+ }
1864
+ if (eventType === "thread/realtime/transcript/delta" || eventType === "thread/realtime/transcript/done") {
1865
+ const turn = ensureActive(payload.turn_id || payload.turnId || `${payload.threadId || payload.thread_id || "realtime"}-realtime`);
1866
+ const text = eventType.endsWith("/done") ? normalizeText(payload.text) : normalizeDeltaText(payload.delta);
1867
+ const role = String(payload.role || "").toLowerCase();
1868
+ if (role === "user") {
1869
+ const nextMessage = eventType.endsWith("/done") ? text : `${turn.userMessage || ""}${text}`;
1870
+ turn.userMessage = visibleUserMessageText(nextMessage, {
1871
+ renderedAttachmentKinds: renderedAttachmentKindsForTurn(turn)
1872
+ });
1873
+ } else if (text) {
1874
+ turn.finalMessage = eventType.endsWith("/done") ? text : `${turn.finalMessage || ""}${text}`;
1875
+ }
1876
+ continue;
1877
+ }
1878
+ if (eventType === "thread/realtime/itemAdded") {
1879
+ const turn = ensureActive(payload.turn_id || payload.turnId || `${payload.threadId || payload.thread_id || "realtime"}-realtime`);
1880
+ const realtimeItem = dataRecord(payload.item);
1881
+ if (appendTurnItem(turn, realtimeItem, itemStatus(realtimeItem, "completed"))) continue;
1882
+ if (appendResponseItem(turn, realtimeItem, functionCalls)) continue;
1883
+ }
1884
+ if (eventType === "thread/realtime/error") {
1885
+ appendProcess(ensureActive(payload.turn_id || payload.turnId || `${payload.threadId || payload.thread_id || "realtime"}-realtime`), {
1886
+ type: "error",
1887
+ title: "Realtime error",
1888
+ detail: payload.message || JSON.stringify(payload),
1889
+ status: "failed"
1890
+ });
1891
+ continue;
1892
+ }
1893
+ if (eventType === "event_msg") {
1894
+ if (payload.type === "task_started" || payload.type === "turn_started") {
1895
+ const turn = ensureActive(payload.turn_id);
1896
+ if (typeof payload.started_at === "number") turn.startedAt = payload.started_at;
1897
+ turn.status = "inProgress";
1898
+ continue;
1899
+ }
1900
+ if (payload.type === "user_message") {
1901
+ const previousTurn = active;
1902
+ if (previousTurn?.userMessage && (previousTurn.finalMessage || previousTurn.status !== "inProgress")) {
1903
+ finishActive();
1904
+ }
1905
+ const turn = ensureActive(payload.turn_id);
1906
+ const images = imagesFromUserMessagePayload(payload);
1907
+ applyUserMessageToTurn(turn, {
1908
+ id: payload.id || payload.call_id,
1909
+ message: textFromUserMessagePayload(payload),
1910
+ images
1911
+ });
1912
+ continue;
1913
+ }
1914
+ if (payload.type === "agent_message") {
1915
+ const message = normalizeText(payload.message);
1916
+ if (!message) continue;
1917
+ const turn = ensureActive(payload.turn_id);
1918
+ if (payload.phase === "final_answer" || !payload.phase) {
1919
+ turn.finalMessage = finalMessageText(message, turn, payload.id || payload.call_id || `${turn.id}-agent-message`, payload.memoryCitation || payload.memory_citation);
1920
+ } else {
1921
+ const extracted = extractMemoryCitationBlock(message);
1922
+ appendMemoryCitation(turn, payload.id || payload.call_id || `${turn.id}-agent-message`, payload.memoryCitation || payload.memory_citation, extracted.detail);
1923
+ appendProcess(turn, {
1924
+ type: "message",
1925
+ title: (extracted.text || message).split("\n")[0],
1926
+ detail: extracted.text || message
1927
+ });
1928
+ }
1929
+ continue;
1930
+ }
1931
+ if (payload.type === "agent_reasoning" || payload.type === "agent_reasoning_raw_content") {
1932
+ const text = normalizeText(payload.text || payload.message);
1933
+ if (text) {
1934
+ appendProcess(ensureActive(payload.turn_id), {
1935
+ type: "reasoning",
1936
+ title: "Reasoned",
1937
+ detail: text
1938
+ });
1939
+ }
1940
+ continue;
1941
+ }
1942
+ if (payload.type === "item_completed" || payload.type === "item_started" || payload.type === "item_updated") {
1943
+ const turn = ensureActive(payload.turn_id);
1944
+ const status = payload.type === "item_started" ? "running" : payload.type === "item_updated" ? itemStatus(dataRecord(payload.item), "running") : itemStatus(dataRecord(payload.item), "completed");
1945
+ if (appendTurnItem(turn, dataRecord(payload.item), status)) continue;
1946
+ }
1947
+ if (payload.type === "plan_update") {
1948
+ appendProcess(ensureActive(payload.turn_id), {
1949
+ id: payload.call_id || payload.id || "plan-update",
1950
+ type: "plan",
1951
+ title: "Updated plan",
1952
+ detail: [
1953
+ normalizeText(payload.explanation || ""),
1954
+ detailForPlanSteps(payload.plan)
1955
+ ].filter(Boolean).join("\n"),
1956
+ status: "completed"
1957
+ });
1958
+ continue;
1959
+ }
1960
+ if (payload.type === "raw_response_item") {
1961
+ const turn = ensureActive(payload.turn_id);
1962
+ if (appendResponseItem(turn, dataRecord(payload.item), functionCalls)) continue;
1963
+ }
1964
+ if (payload.type === "patch_apply_end") {
1965
+ appendProcess(ensureActive(payload.turn_id), {
1966
+ id: payload.call_id,
1967
+ type: "patch",
1968
+ title: titleForPatch(payload),
1969
+ detail: [summarizePatchChanges(payload.changes), summarizeOutput([payload.stdout, payload.stderr].filter(Boolean).join("\n"))].filter(Boolean).join("\n"),
1970
+ status: payload.success === false ? "failed" : "completed"
1971
+ });
1972
+ continue;
1973
+ }
1974
+ if (payload.type === "exec_command_end") {
1975
+ appendProcess(ensureActive(payload.turn_id), {
1976
+ id: payload.call_id || payload.process_id,
1977
+ type: "command",
1978
+ title: titleForCommandExecution(payload),
1979
+ detail: summarizeCommandOutput(payload),
1980
+ status: Number.isFinite(payload.exit_code) && payload.exit_code !== 0 ? "failed" : "completed"
1981
+ });
1982
+ continue;
1983
+ }
1984
+ if (payload.type === "mcp_tool_call_end") {
1985
+ appendProcess(ensureActive(payload.turn_id), {
1986
+ id: payload.call_id,
1987
+ type: "mcp",
1988
+ title: titleForMcp(payload),
1989
+ detail: detailForMcp(payload),
1990
+ images: imagesFromStructuredOutput(payload.result),
1991
+ status: dataRecord(payload.result).is_error ? "failed" : "completed"
1992
+ });
1993
+ continue;
1994
+ }
1995
+ if (payload.type === "web_search_end") {
1996
+ const query = payload.query || dataRecord(payload.action).query;
1997
+ appendProcess(ensureActive(payload.turn_id), {
1998
+ id: payload.call_id,
1999
+ type: "web-search",
2000
+ title: compactInline(query, "Searched web"),
2001
+ detail: payload.action ? summarizeOutput(JSON.stringify(payload.action, null, 2)) : "",
2002
+ status: "completed"
2003
+ });
2004
+ continue;
2005
+ }
2006
+ if (payload.type === "image_generation_end") {
2007
+ appendProcess(ensureActive(payload.turn_id), {
2008
+ id: payload.call_id,
2009
+ type: "image-generation",
2010
+ title: "Generated image",
2011
+ detail: compactInline(payload.saved_path || payload.revised_prompt || payload.status || ""),
2012
+ images: imagesFromImageItem(payload),
2013
+ status: payload.status || "completed"
2014
+ });
2015
+ continue;
2016
+ }
2017
+ if (payload.type === "dynamic_tool_call_request" || payload.type === "dynamic_tool_call_response") {
2018
+ appendProcess(ensureActive(payload.turn_id || payload.turnId), {
2019
+ id: payload.call_id || payload.callId,
2020
+ type: "tool",
2021
+ title: payload.tool ? `Used ${payload.tool}` : "Used tool",
2022
+ detail: summarizeOutput(JSON.stringify(payload.arguments || payload.content_items || payload.contentItems || "", null, 2)),
2023
+ images: imagesFromStructuredOutput(payload.content_items || payload.contentItems),
2024
+ mergeDetail: payload.type === "dynamic_tool_call_response",
2025
+ status: payload.type === "dynamic_tool_call_request" ? "running" : payload.success === false ? "failed" : "completed"
2026
+ });
2027
+ continue;
2028
+ }
2029
+ if (payload.type === "sub_agent_activity") {
2030
+ const kind = compactInline(payload.kind, "activity");
2031
+ const agentPath = compactInline(payload.agent_path || payload.agentPath || payload.agent_thread_id || payload.agentThreadId);
2032
+ appendProcess(ensureActive(payload.turn_id), {
2033
+ id: payload.id || payload.call_id,
2034
+ type: "sub-agent",
2035
+ title: agentPath ? `${kind} ${agentPath}` : `Sub-agent ${kind}`,
2036
+ status: "completed"
2037
+ });
2038
+ continue;
2039
+ }
2040
+ if (payload.type === "entered_review_mode" || payload.type === "exited_review_mode") {
2041
+ appendProcess(ensureActive(payload.turn_id), {
2042
+ type: "review",
2043
+ title: payload.type === "entered_review_mode" ? "Entered review mode" : "Exited review mode",
2044
+ detail: summarizeOutput(payload.user_facing_hint || JSON.stringify(payload.review_output || payload.target || "", null, 2))
2045
+ });
2046
+ continue;
2047
+ }
2048
+ if (payload.type === "error" || payload.type === "warning" || payload.type === "guardian_warning" || payload.type === "stream_error") {
2049
+ appendProcess(ensureActive(payload.turn_id), {
2050
+ type: payload.type === "error" ? "error" : "warning",
2051
+ title: payload.type === "error" ? "Error" : "Warning",
2052
+ detail: payload.message || payload.error || JSON.stringify(payload),
2053
+ status: payload.type === "error" ? "failed" : "warning"
2054
+ });
2055
+ continue;
2056
+ }
2057
+ if (payload.type === "task_complete" || payload.type === "turn_complete" || payload.type === "task_aborted" || payload.type === "turn_aborted") {
2058
+ finishActive(payload);
2059
+ continue;
2060
+ }
2061
+ if (payload.type === "context_compacted") {
2062
+ appendProcess(ensureActive(payload.turn_id), {
2063
+ type: "compaction",
2064
+ title: "Compacted context"
2065
+ });
2066
+ continue;
2067
+ }
2068
+ if (payload.type === "thread_rolled_back") {
2069
+ appendProcess(ensureActive(payload.turn_id), {
2070
+ type: "rollback",
2071
+ title: "Rolled back thread",
2072
+ detail: payload.message || payload.rollback_to_item_id || ""
2073
+ });
2074
+ continue;
2075
+ }
2076
+ if (!isIgnoredEventType(String(payload.type || ""))) {
2077
+ appendProcess(ensureActive(payload.turn_id), {
2078
+ id: payload.id || payload.call_id,
2079
+ type: "event",
2080
+ title: humanizeType(payload.type, "Codex event"),
2081
+ detail: summarizeOutput(JSON.stringify(payload, null, 2)),
2082
+ status: payload.status || ""
2083
+ });
2084
+ }
2085
+ }
2086
+ if (eventType === "response_item") {
2087
+ const turn = ensureActive(responseItemTurnId(payload));
2088
+ if (appendResponseItem(turn, payload, functionCalls)) continue;
2089
+ }
2090
+ }
2091
+ if (active && !isEmptyTurn(active)) turns.push(active);
2092
+ const maxTurns = Number.isFinite(options.maxTurns) ? Math.max(1, Math.floor(options.maxTurns)) : DEFAULT_MAX_TURNS;
2093
+ return turns.map(normalizeTurnForOutput).filter((turn) => turn && !isEmptyTurn(turn) && !isStandaloneThreadSettingsTurn(turn)).slice(-maxTurns);
2094
+ }
2095
+ function buildTranscriptFromEvents(events, options = {}) {
2096
+ const lines = Array.isArray(events) ? events.filter((event) => event && typeof event === "object").map((event) => JSON.stringify(event)) : [];
2097
+ return buildTranscriptFromLines(lines, options);
2098
+ }
2099
+ // Annotate the CommonJS export names for ESM import in node:
2100
+ 0 && (module.exports = {
2101
+ DEFAULT_MAX_TURNS,
2102
+ buildTranscriptFromEvents,
2103
+ buildTranscriptFromLines,
2104
+ stripUserMessagePrefix,
2105
+ textFromContent,
2106
+ visibleUserMessageText
2107
+ });