@cloudcli-ai/cloudcli 1.37.2 → 1.37.3

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 (328) hide show
  1. package/README.md +269 -0
  2. package/dist/assets/{abnfDiagram-N423BO3Z-C4UAoHJb.js → abnfDiagram-N423BO3Z-CJntskwA.js} +1 -1
  3. package/dist/assets/{arc-B8jF-ja9.js → arc-CIfH4uMN.js} +1 -1
  4. package/dist/assets/{architectureDiagram-T3A2C74G-C_Wur_CU.js → architectureDiagram-T3A2C74G-_IpEkukg.js} +1 -1
  5. package/dist/assets/{blockDiagram-VBNYF7ZC-Cq4P1i8t.js → blockDiagram-VBNYF7ZC-BttxrpgZ.js} +1 -1
  6. package/dist/assets/{c4Diagram-5PPSVZJV-C1wG4eUj.js → c4Diagram-5PPSVZJV-g51dSRr1.js} +1 -1
  7. package/dist/assets/channel-C5xU9jMw.js +1 -0
  8. package/dist/assets/{chunk-2GRJ4B5K-B8fnBG6E.js → chunk-2GRJ4B5K-D_-LbQUa.js} +1 -1
  9. package/dist/assets/{chunk-2Q5K7J3B-WdfPooPJ.js → chunk-2Q5K7J3B-BtlHzwaO.js} +1 -1
  10. package/dist/assets/{chunk-5RXB4S5H-DhZJuG2E.js → chunk-5RXB4S5H-UzkpvpAT.js} +1 -1
  11. package/dist/assets/{chunk-5VM5RSS4-B0rjslal.js → chunk-5VM5RSS4-BKwx5Gag.js} +1 -1
  12. package/dist/assets/{chunk-6Q2QTUOP-CG2Oj4jL.js → chunk-6Q2QTUOP-D_KEBH5f.js} +1 -1
  13. package/dist/assets/{chunk-GF5L2VYU-rrl2lRxY.js → chunk-GF5L2VYU-rK2DGyto.js} +1 -1
  14. package/dist/assets/{chunk-JWPE2WC7-CjVbrVMA.js → chunk-JWPE2WC7-CeBl_N9i.js} +1 -1
  15. package/dist/assets/{chunk-KBJHAD2P-CRzKgU8S.js → chunk-KBJHAD2P-BiQLWVIr.js} +1 -1
  16. package/dist/assets/{chunk-RYQCIY6F-DBz4GTZF.js → chunk-RYQCIY6F-C1knVGV5.js} +1 -1
  17. package/dist/assets/{chunk-XXDRQBXY-wHxalsXk.js → chunk-XXDRQBXY-CtKbJkvF.js} +1 -1
  18. package/dist/assets/classDiagram-JCYQIIEL-CRrL3vp7.js +1 -0
  19. package/dist/assets/classDiagram-v2-OCEON4UE-CRrL3vp7.js +1 -0
  20. package/dist/assets/{cose-bilkent-JH36ORCC-s1hygY8e.js → cose-bilkent-JH36ORCC-DjX8y40Z.js} +1 -1
  21. package/dist/assets/{cynefin-VYW2F7L2-C4LGV15i.js → cynefin-VYW2F7L2-DM6YeRba.js} +1 -1
  22. package/dist/assets/{cynefinDiagram-MW4NZA55-C5uhu7B3.js → cynefinDiagram-MW4NZA55-wZJ-vy5B.js} +1 -1
  23. package/dist/assets/{dagre-VZM6K2ZE-B-OBTewm.js → dagre-VZM6K2ZE-BzP0ejkH.js} +1 -1
  24. package/dist/assets/{diagram-7IWD3JNH-BjGKQxih.js → diagram-7IWD3JNH-BTL_j23J.js} +1 -1
  25. package/dist/assets/{diagram-B4RE2ZJO-BMKz1X2L.js → diagram-B4RE2ZJO-Cf1Norgu.js} +1 -1
  26. package/dist/assets/{diagram-LBJQPF4R-DNh-GhKC.js → diagram-LBJQPF4R-DPiUEKr-.js} +1 -1
  27. package/dist/assets/{diagram-Q27KOJAE-BaTG9jPT.js → diagram-Q27KOJAE-CTcTpiz5.js} +1 -1
  28. package/dist/assets/{diagram-UB23O5K3-BUwo2OvJ.js → diagram-UB23O5K3-DPMSdYm0.js} +1 -1
  29. package/dist/assets/{ebnfDiagram-BXEA7PRR-DAZgfzX2.js → ebnfDiagram-BXEA7PRR-7yvD6uiF.js} +1 -1
  30. package/dist/assets/{erDiagram-JOGREHBK-1w1CcGEb.js → erDiagram-JOGREHBK-CfgeDoV6.js} +1 -1
  31. package/dist/assets/{flowDiagram-UKHOOZJN-D4EII8Jj.js → flowDiagram-UKHOOZJN-B27ng5zu.js} +1 -1
  32. package/dist/assets/{ganttDiagram-PKOTCBZU-ChvJZAgB.js → ganttDiagram-PKOTCBZU-CcC6b_7t.js} +1 -1
  33. package/dist/assets/{gitGraphDiagram-DS77QQ5N-DtOn41S8.js → gitGraphDiagram-DS77QQ5N-BX5kPGrO.js} +1 -1
  34. package/dist/assets/index-BTDHQ6Id.css +32 -0
  35. package/dist/assets/index-sFfz8iBR.js +4931 -0
  36. package/dist/assets/{infoDiagram-6WML65LV-DN_PVEJZ.js → infoDiagram-6WML65LV-CUP-SlN4.js} +1 -1
  37. package/dist/assets/{ishikawaDiagram-WSZJBQD7-DbkF1kXb.js → ishikawaDiagram-WSZJBQD7-BTTDhOpX.js} +1 -1
  38. package/dist/assets/{journeyDiagram-NVQOT4AX-pJwmhddE.js → journeyDiagram-NVQOT4AX-ARXcc61m.js} +1 -1
  39. package/dist/assets/{kanban-definition-27J2QSJJ-PPAPgNp5.js → kanban-definition-27J2QSJJ-BieMpqMA.js} +1 -1
  40. package/dist/assets/{linear-iPR-J9f7.js → linear-61vxjRnP.js} +1 -1
  41. package/dist/assets/{mermaid.core-BEUL86Z6.js → mermaid.core-nhnwkfQx.js} +5 -5
  42. package/dist/assets/{mindmap-definition-FAOFIHXS-BvZoBib7.js → mindmap-definition-FAOFIHXS-Cm6x5vT1.js} +1 -1
  43. package/dist/assets/{pegDiagram-VL7TDLO6-DhYreaUd.js → pegDiagram-VL7TDLO6-CcYBq_9H.js} +1 -1
  44. package/dist/assets/{pieDiagram-7S7Q4E2Y-CrOHlyD0.js → pieDiagram-7S7Q4E2Y-CfvIjfzo.js} +1 -1
  45. package/dist/assets/{quadrantDiagram-CIZ2JOQS-D4g5yH3t.js → quadrantDiagram-CIZ2JOQS-SgYoWPNb.js} +1 -1
  46. package/dist/assets/{railroadDiagram-AXF67PYL-Dj39lHlf.js → railroadDiagram-AXF67PYL-D2Mu5E_f.js} +1 -1
  47. package/dist/assets/{requirementDiagram-LRYGKXZP-1AS4Zgm_.js → requirementDiagram-LRYGKXZP-Azwe_k4Q.js} +1 -1
  48. package/dist/assets/{sankeyDiagram-W5VNT64P-CKlMn19P.js → sankeyDiagram-W5VNT64P-DN1Ju3PA.js} +1 -1
  49. package/dist/assets/{sequenceDiagram-SI44F4Z6-B_j3qyvo.js → sequenceDiagram-SI44F4Z6-Bj4qC34S.js} +1 -1
  50. package/dist/assets/server.browser-CtX3Hdl5.js +27 -0
  51. package/dist/assets/{sizeCapture-X5ZJPWSS-Bp2Op16v.js → sizeCapture-X5ZJPWSS-Co4PdklG.js} +1 -1
  52. package/dist/assets/{stateDiagram-OKZ733FA-C0cN6DoY.js → stateDiagram-OKZ733FA-nOvL9dRC.js} +1 -1
  53. package/dist/assets/stateDiagram-v2-UEYNNEHI-DNv8ppw7.js +1 -0
  54. package/dist/assets/{swimlanes-SLNWSIFB-BEvXOV9b.js → swimlanes-SLNWSIFB-CCK3wMid.js} +2 -2
  55. package/dist/assets/swimlanesDiagram-ULZ7WXOC-DnfbNQEp.js +8 -0
  56. package/dist/assets/{timeline-definition-Z64GVDOM-zdJQinvZ.js → timeline-definition-Z64GVDOM-BC29RNFm.js} +1 -1
  57. package/dist/assets/{vendor-codemirror-OwyKSvPE.js → vendor-codemirror-CYrSt7-U.js} +18 -18
  58. package/dist/assets/{vennDiagram-T6HMQDX7-DuF1uZMY.js → vennDiagram-T6HMQDX7-pZlZCtEo.js} +1 -1
  59. package/dist/assets/{wardleyDiagram-T6FBY63Y-B9AlLQup.js → wardleyDiagram-T6FBY63Y-De8k2-zM.js} +1 -1
  60. package/dist/assets/{xychartDiagram-ELKLHX3M-DTJX48Qg.js → xychartDiagram-ELKLHX3M-Bk8ykH0w.js} +1 -1
  61. package/dist/index.html +3 -3
  62. package/dist-server/server/index.js +7 -3
  63. package/dist-server/server/index.js.map +1 -1
  64. package/dist-server/server/modules/agent/agent.routes.js +2 -2
  65. package/dist-server/server/modules/agent/agent.routes.js.map +1 -1
  66. package/dist-server/server/modules/agent/tests/agent.routes.test.js +30 -1
  67. package/dist-server/server/modules/agent/tests/agent.routes.test.js.map +1 -1
  68. package/dist-server/server/modules/browser-use/browser-use.routes.js +39 -33
  69. package/dist-server/server/modules/browser-use/browser-use.routes.js.map +1 -1
  70. package/dist-server/server/modules/database/connection.js +1 -1
  71. package/dist-server/server/modules/database/connection.js.map +1 -1
  72. package/dist-server/server/modules/database/index.js +5 -0
  73. package/dist-server/server/modules/database/index.js.map +1 -1
  74. package/dist-server/server/modules/database/migrations.js +32 -1
  75. package/dist-server/server/modules/database/migrations.js.map +1 -1
  76. package/dist-server/server/modules/database/repositories/scheduled-messages.db.js +71 -0
  77. package/dist-server/server/modules/database/repositories/scheduled-messages.db.js.map +1 -0
  78. package/dist-server/server/modules/database/repositories/session-drafts.db.js +105 -0
  79. package/dist-server/server/modules/database/repositories/session-drafts.db.js.map +1 -0
  80. package/dist-server/server/modules/database/repositories/sessions.db.js +137 -5
  81. package/dist-server/server/modules/database/repositories/sessions.db.js.map +1 -1
  82. package/dist-server/server/modules/database/repositories/user-preferences.db.js +65 -0
  83. package/dist-server/server/modules/database/repositories/user-preferences.db.js.map +1 -0
  84. package/dist-server/server/modules/database/schema.js +92 -0
  85. package/dist-server/server/modules/database/schema.js.map +1 -1
  86. package/dist-server/server/modules/database/tests/sessions.db.integration.test.js +39 -0
  87. package/dist-server/server/modules/database/tests/sessions.db.integration.test.js.map +1 -1
  88. package/dist-server/server/modules/database/tests/user-preferences.db.integration.test.js +105 -0
  89. package/dist-server/server/modules/database/tests/user-preferences.db.integration.test.js.map +1 -0
  90. package/dist-server/server/modules/projects/services/project-delete.service.js +12 -1
  91. package/dist-server/server/modules/projects/services/project-delete.service.js.map +1 -1
  92. package/dist-server/server/modules/projects/services/project-star.service.js +2 -2
  93. package/dist-server/server/modules/projects/services/project-star.service.js.map +1 -1
  94. package/dist-server/server/modules/providers/index.js +3 -0
  95. package/dist-server/server/modules/providers/index.js.map +1 -1
  96. package/dist-server/server/modules/providers/list/claude/claude-auth.provider.js +20 -1
  97. package/dist-server/server/modules/providers/list/claude/claude-auth.provider.js.map +1 -1
  98. package/dist-server/server/modules/providers/list/claude/claude-fork.provider.js +46 -0
  99. package/dist-server/server/modules/providers/list/claude/claude-fork.provider.js.map +1 -0
  100. package/dist-server/server/modules/providers/list/claude/claude-models.provider.js +35 -6
  101. package/dist-server/server/modules/providers/list/claude/claude-models.provider.js.map +1 -1
  102. package/dist-server/server/modules/providers/list/claude/claude-runtime.provider.js +168 -38
  103. package/dist-server/server/modules/providers/list/claude/claude-runtime.provider.js.map +1 -1
  104. package/dist-server/server/modules/providers/list/claude/claude-sessions.provider.js +388 -50
  105. package/dist-server/server/modules/providers/list/claude/claude-sessions.provider.js.map +1 -1
  106. package/dist-server/server/modules/providers/list/claude/claude-skills.provider.js +4 -1
  107. package/dist-server/server/modules/providers/list/claude/claude-skills.provider.js.map +1 -1
  108. package/dist-server/server/modules/providers/list/claude/claude.provider.js +2 -0
  109. package/dist-server/server/modules/providers/list/claude/claude.provider.js.map +1 -1
  110. package/dist-server/server/modules/providers/list/codex/codex-app-server.client.js +204 -0
  111. package/dist-server/server/modules/providers/list/codex/codex-app-server.client.js.map +1 -0
  112. package/dist-server/server/modules/providers/list/codex/codex-fork.provider.js +32 -0
  113. package/dist-server/server/modules/providers/list/codex/codex-fork.provider.js.map +1 -0
  114. package/dist-server/server/modules/providers/list/codex/codex-models.provider.js +16 -0
  115. package/dist-server/server/modules/providers/list/codex/codex-models.provider.js.map +1 -1
  116. package/dist-server/server/modules/providers/list/codex/codex-runtime.provider.js +60 -49
  117. package/dist-server/server/modules/providers/list/codex/codex-runtime.provider.js.map +1 -1
  118. package/dist-server/server/modules/providers/list/codex/codex-session-synchronizer.provider.js +8 -0
  119. package/dist-server/server/modules/providers/list/codex/codex-session-synchronizer.provider.js.map +1 -1
  120. package/dist-server/server/modules/providers/list/codex/codex-sessions.provider.js +1565 -432
  121. package/dist-server/server/modules/providers/list/codex/codex-sessions.provider.js.map +1 -1
  122. package/dist-server/server/modules/providers/list/codex/codex.provider.js +2 -0
  123. package/dist-server/server/modules/providers/list/codex/codex.provider.js.map +1 -1
  124. package/dist-server/server/modules/providers/list/cursor/cursor-runtime.provider.js +8 -6
  125. package/dist-server/server/modules/providers/list/cursor/cursor-runtime.provider.js.map +1 -1
  126. package/dist-server/server/modules/providers/list/cursor/cursor-session-synchronizer.provider.js.map +1 -1
  127. package/dist-server/server/modules/providers/list/opencode/opencode-models.provider.js +258 -6
  128. package/dist-server/server/modules/providers/list/opencode/opencode-models.provider.js.map +1 -1
  129. package/dist-server/server/modules/providers/provider.routes.js +24 -0
  130. package/dist-server/server/modules/providers/provider.routes.js.map +1 -1
  131. package/dist-server/server/modules/providers/services/provider-capabilities.service.js +14 -0
  132. package/dist-server/server/modules/providers/services/provider-capabilities.service.js.map +1 -1
  133. package/dist-server/server/modules/providers/services/provider-token-usage.service.js +139 -35
  134. package/dist-server/server/modules/providers/services/provider-token-usage.service.js.map +1 -1
  135. package/dist-server/server/modules/providers/services/session-history-cache.service.js +87 -0
  136. package/dist-server/server/modules/providers/services/session-history-cache.service.js.map +1 -0
  137. package/dist-server/server/modules/providers/services/session-synchronizer.service.js +105 -32
  138. package/dist-server/server/modules/providers/services/session-synchronizer.service.js.map +1 -1
  139. package/dist-server/server/modules/providers/services/sessions-watcher.service.js +3 -60
  140. package/dist-server/server/modules/providers/services/sessions-watcher.service.js.map +1 -1
  141. package/dist-server/server/modules/providers/services/sessions.service.js +179 -9
  142. package/dist-server/server/modules/providers/services/sessions.service.js.map +1 -1
  143. package/dist-server/server/modules/providers/tests/claude-auth.test.js +52 -0
  144. package/dist-server/server/modules/providers/tests/claude-auth.test.js.map +1 -1
  145. package/dist-server/server/modules/providers/tests/claude-models.test.js +39 -0
  146. package/dist-server/server/modules/providers/tests/claude-models.test.js.map +1 -0
  147. package/dist-server/server/modules/providers/tests/claude-sessions.test.js +465 -39
  148. package/dist-server/server/modules/providers/tests/claude-sessions.test.js.map +1 -1
  149. package/dist-server/server/modules/providers/tests/claude-subagent-echo.test.js +16 -0
  150. package/dist-server/server/modules/providers/tests/claude-subagent-echo.test.js.map +1 -0
  151. package/dist-server/server/modules/providers/tests/claude-token-budget.test.js +85 -0
  152. package/dist-server/server/modules/providers/tests/claude-token-budget.test.js.map +1 -0
  153. package/dist-server/server/modules/providers/tests/codex-message-editing.test.js +338 -0
  154. package/dist-server/server/modules/providers/tests/codex-message-editing.test.js.map +1 -0
  155. package/dist-server/server/modules/providers/tests/codex-runtime.test.js +51 -0
  156. package/dist-server/server/modules/providers/tests/codex-runtime.test.js.map +1 -0
  157. package/dist-server/server/modules/providers/tests/codex-session-fork.test.js +54 -0
  158. package/dist-server/server/modules/providers/tests/codex-session-fork.test.js.map +1 -0
  159. package/dist-server/server/modules/providers/tests/codex-sessions.test.js +304 -15
  160. package/dist-server/server/modules/providers/tests/codex-sessions.test.js.map +1 -1
  161. package/dist-server/server/modules/providers/tests/opencode-models.test.js +117 -4
  162. package/dist-server/server/modules/providers/tests/opencode-models.test.js.map +1 -1
  163. package/dist-server/server/modules/providers/tests/provider-token-usage.service.test.js +164 -1
  164. package/dist-server/server/modules/providers/tests/provider-token-usage.service.test.js.map +1 -1
  165. package/dist-server/server/modules/providers/tests/session-fork.test.js +113 -0
  166. package/dist-server/server/modules/providers/tests/session-fork.test.js.map +1 -0
  167. package/dist-server/server/modules/providers/tests/session-history-cache.service.test.js +120 -0
  168. package/dist-server/server/modules/providers/tests/session-history-cache.service.test.js.map +1 -0
  169. package/dist-server/server/modules/providers/tests/session-orphan-prune.test.js +90 -0
  170. package/dist-server/server/modules/providers/tests/session-orphan-prune.test.js.map +1 -0
  171. package/dist-server/server/modules/providers/tests/session-synchronizer-coalescing.test.js +122 -0
  172. package/dist-server/server/modules/providers/tests/session-synchronizer-coalescing.test.js.map +1 -0
  173. package/dist-server/server/modules/providers/tests/sessions.service.test.js +45 -1
  174. package/dist-server/server/modules/providers/tests/sessions.service.test.js.map +1 -1
  175. package/dist-server/server/modules/providers/tests/skills.test.js +15 -3
  176. package/dist-server/server/modules/providers/tests/skills.test.js.map +1 -1
  177. package/dist-server/server/modules/scheduled-messages/index.js +5 -0
  178. package/dist-server/server/modules/scheduled-messages/index.js.map +1 -0
  179. package/dist-server/server/modules/scheduled-messages/scheduled-messages.routes.js +47 -0
  180. package/dist-server/server/modules/scheduled-messages/scheduled-messages.routes.js.map +1 -0
  181. package/dist-server/server/modules/scheduled-messages/services/scheduled-message-dispatcher.service.js +163 -0
  182. package/dist-server/server/modules/scheduled-messages/services/scheduled-message-dispatcher.service.js.map +1 -0
  183. package/dist-server/server/modules/scheduled-messages/services/scheduled-messages.service.js +95 -0
  184. package/dist-server/server/modules/scheduled-messages/services/scheduled-messages.service.js.map +1 -0
  185. package/dist-server/server/modules/scheduled-messages/tests/scheduled-messages.test.js +255 -0
  186. package/dist-server/server/modules/scheduled-messages/tests/scheduled-messages.test.js.map +1 -0
  187. package/dist-server/server/modules/taskmaster/taskmaster.routes.js +23 -23
  188. package/dist-server/server/modules/taskmaster/taskmaster.routes.js.map +1 -1
  189. package/dist-server/server/modules/taskmaster/tests/taskmaster.routes.test.js +48 -0
  190. package/dist-server/server/modules/taskmaster/tests/taskmaster.routes.test.js.map +1 -1
  191. package/dist-server/server/modules/user/tests/user.service.test.js +70 -0
  192. package/dist-server/server/modules/user/tests/user.service.test.js.map +1 -1
  193. package/dist-server/server/modules/user/user.module.js +10 -1
  194. package/dist-server/server/modules/user/user.module.js.map +1 -1
  195. package/dist-server/server/modules/user/user.routes.js +44 -0
  196. package/dist-server/server/modules/user/user.routes.js.map +1 -1
  197. package/dist-server/server/modules/user/user.service.js +75 -0
  198. package/dist-server/server/modules/user/user.service.js.map +1 -1
  199. package/dist-server/server/modules/voice/tests/voice.service.test.js +3 -2
  200. package/dist-server/server/modules/voice/tests/voice.service.test.js.map +1 -1
  201. package/dist-server/server/modules/websocket/index.js +7 -0
  202. package/dist-server/server/modules/websocket/index.js.map +1 -1
  203. package/dist-server/server/modules/websocket/services/chat-run-registry.service.js +10 -44
  204. package/dist-server/server/modules/websocket/services/chat-run-registry.service.js.map +1 -1
  205. package/dist-server/server/modules/websocket/services/chat-session-writer.service.js +35 -5
  206. package/dist-server/server/modules/websocket/services/chat-session-writer.service.js.map +1 -1
  207. package/dist-server/server/modules/websocket/services/chat-websocket.service.js +166 -9
  208. package/dist-server/server/modules/websocket/services/chat-websocket.service.js.map +1 -1
  209. package/dist-server/server/modules/websocket/services/session-upsert-broadcast.service.js +94 -0
  210. package/dist-server/server/modules/websocket/services/session-upsert-broadcast.service.js.map +1 -0
  211. package/dist-server/server/modules/websocket/services/shell-websocket.service.js +9 -3
  212. package/dist-server/server/modules/websocket/services/shell-websocket.service.js.map +1 -1
  213. package/dist-server/server/modules/websocket/tests/chat-edit-send.test.js +263 -0
  214. package/dist-server/server/modules/websocket/tests/chat-edit-send.test.js.map +1 -0
  215. package/dist-server/server/modules/websocket/tests/chat-run-registry.test.js +29 -3
  216. package/dist-server/server/modules/websocket/tests/chat-run-registry.test.js.map +1 -1
  217. package/dist-server/server/modules/websocket/tests/session-upsert-broadcast.test.js +106 -0
  218. package/dist-server/server/modules/websocket/tests/session-upsert-broadcast.test.js.map +1 -0
  219. package/dist-server/server/modules/websocket/tests/shell-websocket.service.test.js +80 -0
  220. package/dist-server/server/modules/websocket/tests/shell-websocket.service.test.js.map +1 -1
  221. package/dist-server/server/shared/claude-cli-path.js +22 -5
  222. package/dist-server/server/shared/claude-cli-path.js.map +1 -1
  223. package/dist-server/server/shared/index.js +3 -0
  224. package/dist-server/server/shared/index.js.map +1 -0
  225. package/dist-server/server/shared/message-unification.js +376 -0
  226. package/dist-server/server/shared/message-unification.js.map +1 -0
  227. package/dist-server/server/shared/tests/claude-cli-path.test.js +45 -1
  228. package/dist-server/server/shared/tests/claude-cli-path.test.js.map +1 -1
  229. package/dist-server/server/shared/tests/message-unification.test.js +174 -0
  230. package/dist-server/server/shared/tests/message-unification.test.js.map +1 -0
  231. package/dist-server/server/shared/utils.js +34 -0
  232. package/dist-server/server/shared/utils.js.map +1 -1
  233. package/package.json +19 -16
  234. package/server/index.ts +11 -4
  235. package/server/modules/agent/agent.routes.ts +2 -2
  236. package/server/modules/agent/tests/agent.routes.test.ts +33 -1
  237. package/server/modules/browser-use/browser-use.routes.ts +96 -33
  238. package/server/modules/database/connection.ts +2 -1
  239. package/server/modules/database/index.ts +10 -0
  240. package/server/modules/database/migrations.ts +37 -0
  241. package/server/modules/database/repositories/scheduled-messages.db.ts +127 -0
  242. package/server/modules/database/repositories/session-drafts.db.ts +171 -0
  243. package/server/modules/database/repositories/sessions.db.ts +196 -3
  244. package/server/modules/database/repositories/user-preferences.db.ts +80 -0
  245. package/server/modules/database/schema.ts +96 -0
  246. package/server/modules/database/tests/sessions.db.integration.test.ts +52 -0
  247. package/server/modules/database/tests/user-preferences.db.integration.test.ts +135 -0
  248. package/server/modules/projects/services/project-delete.service.ts +13 -1
  249. package/server/modules/projects/services/project-star.service.ts +2 -2
  250. package/server/modules/providers/index.ts +4 -0
  251. package/server/modules/providers/list/claude/claude-auth.provider.ts +21 -1
  252. package/server/modules/providers/list/claude/claude-fork.provider.ts +57 -0
  253. package/server/modules/providers/list/claude/claude-models.provider.ts +38 -6
  254. package/server/modules/providers/list/claude/claude-runtime.provider.js +188 -39
  255. package/server/modules/providers/list/claude/claude-sessions.provider.ts +478 -54
  256. package/server/modules/providers/list/claude/claude-skills.provider.ts +4 -1
  257. package/server/modules/providers/list/claude/claude.provider.ts +3 -0
  258. package/server/modules/providers/list/codex/codex-app-server.client.ts +243 -0
  259. package/server/modules/providers/list/codex/codex-fork.provider.ts +40 -0
  260. package/server/modules/providers/list/codex/codex-models.provider.ts +16 -0
  261. package/server/modules/providers/list/codex/{codex-runtime.provider.js → codex-runtime.provider.ts} +93 -66
  262. package/server/modules/providers/list/codex/codex-session-synchronizer.provider.ts +9 -0
  263. package/server/modules/providers/list/codex/codex-sessions.provider.ts +1806 -477
  264. package/server/modules/providers/list/codex/codex.provider.ts +3 -0
  265. package/server/modules/providers/list/cursor/cursor-runtime.provider.js +8 -6
  266. package/server/modules/providers/list/cursor/cursor-session-synchronizer.provider.ts +0 -1
  267. package/server/modules/providers/list/opencode/opencode-models.provider.ts +279 -6
  268. package/server/modules/providers/provider.routes.ts +31 -0
  269. package/server/modules/providers/services/provider-capabilities.service.ts +23 -0
  270. package/server/modules/providers/services/provider-token-usage.service.ts +166 -39
  271. package/server/modules/providers/services/session-history-cache.service.ts +139 -0
  272. package/server/modules/providers/services/session-synchronizer.service.ts +125 -38
  273. package/server/modules/providers/services/sessions-watcher.service.ts +3 -64
  274. package/server/modules/providers/services/sessions.service.ts +201 -9
  275. package/server/modules/providers/tests/claude-auth.test.ts +58 -0
  276. package/server/modules/providers/tests/claude-models.test.ts +87 -0
  277. package/server/modules/providers/tests/claude-sessions.test.ts +552 -40
  278. package/server/modules/providers/tests/claude-subagent-echo.test.ts +25 -0
  279. package/server/modules/providers/tests/claude-token-budget.test.ts +104 -0
  280. package/server/modules/providers/tests/codex-message-editing.test.ts +419 -0
  281. package/server/modules/providers/tests/codex-runtime.test.ts +58 -0
  282. package/server/modules/providers/tests/codex-session-fork.test.ts +59 -0
  283. package/server/modules/providers/tests/codex-sessions.test.ts +337 -15
  284. package/server/modules/providers/tests/opencode-models.test.ts +166 -8
  285. package/server/modules/providers/tests/provider-token-usage.service.test.ts +188 -1
  286. package/server/modules/providers/tests/session-fork.test.ts +173 -0
  287. package/server/modules/providers/tests/session-history-cache.service.test.ts +143 -0
  288. package/server/modules/providers/tests/session-orphan-prune.test.ts +107 -0
  289. package/server/modules/providers/tests/session-synchronizer-coalescing.test.ts +136 -0
  290. package/server/modules/providers/tests/sessions.service.test.ts +67 -1
  291. package/server/modules/providers/tests/skills.test.ts +21 -5
  292. package/server/modules/scheduled-messages/index.ts +8 -0
  293. package/server/modules/scheduled-messages/scheduled-messages.routes.ts +68 -0
  294. package/server/modules/scheduled-messages/services/scheduled-message-dispatcher.service.ts +203 -0
  295. package/server/modules/scheduled-messages/services/scheduled-messages.service.ts +121 -0
  296. package/server/modules/scheduled-messages/tests/scheduled-messages.test.ts +310 -0
  297. package/server/modules/taskmaster/taskmaster.routes.ts +23 -33
  298. package/server/modules/taskmaster/tests/taskmaster.routes.test.ts +57 -0
  299. package/server/modules/user/tests/user.service.test.ts +90 -0
  300. package/server/modules/user/user.module.ts +10 -1
  301. package/server/modules/user/user.routes.ts +44 -0
  302. package/server/modules/user/user.service.ts +105 -0
  303. package/server/modules/voice/tests/voice.service.test.ts +3 -2
  304. package/server/modules/websocket/index.ts +8 -0
  305. package/server/modules/websocket/services/chat-run-registry.service.ts +17 -50
  306. package/server/modules/websocket/services/chat-session-writer.service.ts +36 -6
  307. package/server/modules/websocket/services/chat-websocket.service.ts +244 -15
  308. package/server/modules/websocket/services/session-upsert-broadcast.service.ts +108 -0
  309. package/server/modules/websocket/services/shell-websocket.service.ts +10 -3
  310. package/server/modules/websocket/tests/chat-edit-send.test.ts +309 -0
  311. package/server/modules/websocket/tests/chat-run-registry.test.ts +34 -3
  312. package/server/modules/websocket/tests/session-upsert-broadcast.test.ts +138 -0
  313. package/server/modules/websocket/tests/shell-websocket.service.test.ts +108 -0
  314. package/server/shared/claude-cli-path.ts +24 -6
  315. package/server/shared/index.ts +3 -0
  316. package/server/shared/interfaces.ts +62 -0
  317. package/server/shared/message-unification.ts +449 -0
  318. package/server/shared/tests/claude-cli-path.test.ts +58 -1
  319. package/server/shared/tests/message-unification.test.ts +218 -0
  320. package/server/shared/types.ts +123 -2
  321. package/server/shared/utils.ts +40 -0
  322. package/dist/assets/channel-_falYbU1.js +0 -1
  323. package/dist/assets/classDiagram-JCYQIIEL-Dn-3CfpR.js +0 -1
  324. package/dist/assets/classDiagram-v2-OCEON4UE-Dn-3CfpR.js +0 -1
  325. package/dist/assets/index-CzPLBvXT.css +0 -32
  326. package/dist/assets/index-DFkBBuSA.js +0 -1549
  327. package/dist/assets/stateDiagram-v2-UEYNNEHI-BvBxUUrZ.js +0 -1
  328. package/dist/assets/swimlanesDiagram-ULZ7WXOC-CsE-x4YK.js +0 -8
@@ -0,0 +1,218 @@
1
+ import assert from 'node:assert/strict';
2
+ import test from 'node:test';
3
+
4
+ import { prepareTranscriptMessages } from '@/shared/message-unification.js';
5
+ import type { NormalizedMessage } from '@/shared/types.js';
6
+
7
+ let nextId = 0;
8
+
9
+ const message = (fields: Partial<NormalizedMessage>): NormalizedMessage => ({
10
+ id: `m-${(nextId += 1)}`,
11
+ sessionId: 'session',
12
+ timestamp: '2026-08-22T00:00:00.000Z',
13
+ provider: 'claude',
14
+ kind: 'text',
15
+ ...fields,
16
+ } as NormalizedMessage);
17
+
18
+ const prose = () => message({ kind: 'text', role: 'assistant', content: 'Working on it.' });
19
+
20
+ const taskCall = (
21
+ toolName: string,
22
+ toolId: string,
23
+ toolInput: Record<string, unknown>,
24
+ toolUseResult: unknown,
25
+ ) => message({ kind: 'tool_use', toolName, toolId, toolInput, toolResult: { content: 'ok', toolUseResult } });
26
+
27
+ const todosOf = (entry: NormalizedMessage) =>
28
+ (entry.toolInput as { todos: Array<{ content: string; status: string }> }).todos
29
+ .map((todo) => `${todo.status}:${todo.content}`);
30
+
31
+ test('Claude task-tracker calls become one evolving checklist', () => {
32
+ const unified = prepareTranscriptMessages([
33
+ taskCall('TaskCreate', 't1', { subject: 'Read notes', activeForm: 'Reading notes' }, { task: { id: '1' } }),
34
+ taskCall('TaskCreate', 't2', { subject: 'Run tests', activeForm: 'Running tests' }, { task: { id: '2' } }),
35
+ prose(),
36
+ taskCall('TaskUpdate', 't3', { taskId: '1', status: 'completed' }, { success: true }),
37
+ ]);
38
+
39
+ const snapshots = unified.filter((entry) => entry.toolName === 'TodoWrite');
40
+ assert.equal(snapshots.length, 2, 'the two adjacent creates collapse into one snapshot');
41
+ assert.deepEqual(todosOf(snapshots[0]), ['pending:Read notes', 'pending:Run tests']);
42
+ assert.deepEqual(todosOf(snapshots[1]), ['completed:Read notes', 'pending:Run tests']);
43
+ assert.equal(
44
+ (snapshots[0].toolInput as { todos: Array<{ activeForm?: string }> }).todos[0].activeForm,
45
+ 'Reading notes',
46
+ );
47
+ });
48
+
49
+ test('a task listing keeps the wording each task was created with', () => {
50
+ const unified = prepareTranscriptMessages([
51
+ taskCall('TaskCreate', 't1', { subject: 'Read notes', activeForm: 'Reading notes' }, { task: { id: '1' } }),
52
+ prose(),
53
+ taskCall('TaskList', 't2', {}, { tasks: [{ id: '1', subject: 'Read notes', status: 'in_progress' }] }),
54
+ ]);
55
+
56
+ const listed = unified.filter((entry) => entry.toolName === 'TodoWrite').at(-1);
57
+ assert.deepEqual(todosOf(listed!), ['in_progress:Read notes']);
58
+ assert.equal(
59
+ (listed!.toolInput as { todos: Array<{ activeForm?: string }> }).todos[0].activeForm,
60
+ 'Reading notes',
61
+ );
62
+ });
63
+
64
+ test('a checklist that has not changed since it was last drawn is dropped', () => {
65
+ const unified = prepareTranscriptMessages([
66
+ message({ kind: 'tool_use', toolName: 'TodoWrite', toolId: 'w1', toolInput: { todos: [{ content: 'Ship it', status: 'pending' }] } }),
67
+ prose(),
68
+ message({ kind: 'tool_use', toolName: 'TodoWrite', toolId: 'w2', toolInput: { todos: [{ content: 'Ship it', status: 'pending' }] } }),
69
+ ]);
70
+
71
+ assert.deepEqual(unified.map((entry) => entry.toolId), ['w1', undefined]);
72
+ });
73
+
74
+ test('a superseded checklist and its result row both go', () => {
75
+ const unified = prepareTranscriptMessages([
76
+ message({ kind: 'tool_use', toolName: 'TodoWrite', toolId: 'w1', toolInput: { todos: [{ content: 'One', status: 'pending' }] } }),
77
+ message({ kind: 'tool_result', toolId: 'w1', content: 'stale' }),
78
+ message({ kind: 'tool_use', toolName: 'TodoWrite', toolId: 'w2', toolInput: { todos: [{ content: 'One', status: 'completed' }] } }),
79
+ message({ kind: 'tool_result', toolId: 'w2', content: 'fresh' }),
80
+ ]);
81
+
82
+ assert.deepEqual(unified.map((entry) => entry.toolId), ['w2']);
83
+ });
84
+
85
+ test('a result that names its call is not shipped alongside it', () => {
86
+ const unified = prepareTranscriptMessages([
87
+ message({ kind: 'tool_use', toolName: 'Bash', toolId: 'b1', toolInput: { command: 'ls' }, toolResult: { content: 'a\nb' } }),
88
+ message({ kind: 'tool_result', toolId: 'b1', content: 'a\nb' }),
89
+ ]);
90
+
91
+ assert.equal(unified.length, 1, 'the result already rides on the call it belongs to');
92
+ assert.equal(unified[0].kind, 'tool_use');
93
+ assert.equal(unified[0].toolResult?.content, 'a\nb');
94
+ });
95
+
96
+ test('a result with no call to attach to is kept', () => {
97
+ const unified = prepareTranscriptMessages([
98
+ message({ kind: 'tool_result', content: 'orphaned output' }),
99
+ ]);
100
+
101
+ assert.deepEqual(unified.map((entry) => entry.kind), ['tool_result']);
102
+ });
103
+
104
+ test("Codex's request_user_input becomes an answered AskUserQuestion", () => {
105
+ const [unified] = prepareTranscriptMessages([
106
+ message({
107
+ provider: 'codex',
108
+ kind: 'tool_use',
109
+ toolName: 'request_user_input',
110
+ toolId: 'call-1',
111
+ toolInput: JSON.stringify({
112
+ questions: [{ id: 'season', header: 'Quick test', question: 'Which season?', options: [{ label: 'Summer' }] }],
113
+ }),
114
+ toolResult: { content: '{"answers":{"season":{"answers":["Summer"]}}}' },
115
+ }),
116
+ ]);
117
+
118
+ assert.equal(unified.toolName, 'AskUserQuestion');
119
+ assert.deepEqual((unified.toolInput as { answers: unknown }).answers, { 'Which season?': 'Summer' });
120
+ });
121
+
122
+ test('a multi-select Codex answer keeps every label it picked', () => {
123
+ const [unified] = prepareTranscriptMessages([
124
+ message({
125
+ provider: 'codex',
126
+ kind: 'tool_use',
127
+ toolName: 'request_user_input',
128
+ toolId: 'call-1',
129
+ toolInput: JSON.stringify({ questions: [{ id: 'scope', question: 'Which areas?', options: [] }] }),
130
+ toolResult: { content: '{"answers":{"scope":{"answers":["Providers","Tests"]}}}' },
131
+ }),
132
+ ]);
133
+
134
+ assert.deepEqual((unified.toolInput as { answers: unknown }).answers, { 'Which areas?': 'Providers, Tests' });
135
+ });
136
+
137
+ test("Claude's AskUserQuestion answer is folded into the question it answers", () => {
138
+ const [unified] = prepareTranscriptMessages([
139
+ message({
140
+ kind: 'tool_use',
141
+ toolName: 'AskUserQuestion',
142
+ toolId: 'call-1',
143
+ toolInput: { questions: [{ question: 'What next?', header: 'Focus', options: [{ label: 'Branch changes' }] }] },
144
+ toolResult: {
145
+ content: 'Your questions have been answered.',
146
+ toolUseResult: { answers: { 'What next?': 'Branch changes' } },
147
+ },
148
+ }),
149
+ ]);
150
+
151
+ assert.deepEqual((unified.toolInput as { answers: unknown }).answers, { 'What next?': 'Branch changes' });
152
+ });
153
+
154
+ test('a live Claude answer is recovered from the acknowledgement sentence', () => {
155
+ const [unified] = prepareTranscriptMessages([
156
+ message({
157
+ kind: 'tool_use',
158
+ toolName: 'AskUserQuestion',
159
+ toolId: 'call-1',
160
+ toolInput: { questions: [{ question: 'What next?', options: [] }] },
161
+ toolResult: {
162
+ content: 'Your questions have been answered: "What next?"="Branch changes". You can now continue.',
163
+ },
164
+ }),
165
+ ]);
166
+
167
+ assert.deepEqual((unified.toolInput as { answers: unknown }).answers, { 'What next?': 'Branch changes' });
168
+ });
169
+
170
+ test('a question that was never answered carries no answers', () => {
171
+ const [unified] = prepareTranscriptMessages([
172
+ message({
173
+ kind: 'tool_use',
174
+ toolName: 'AskUserQuestion',
175
+ toolId: 'call-1',
176
+ toolInput: { questions: [{ question: 'What next?', options: [] }] },
177
+ toolResult: { content: '<tool_use_error>InputValidationError</tool_use_error>', isError: true },
178
+ }),
179
+ ]);
180
+
181
+ assert.equal((unified.toolInput as { answers?: unknown }).answers, undefined);
182
+ });
183
+
184
+ test('a huge tool output is capped, and says how much it dropped', () => {
185
+ const body = 'x'.repeat(120_000);
186
+ const [unified] = prepareTranscriptMessages([
187
+ message({
188
+ kind: 'tool_use',
189
+ toolName: 'Read',
190
+ toolId: 'r1',
191
+ toolInput: { file_path: '/tmp/shot.png' },
192
+ toolResult: { content: body, toolUseResult: { file: { base64: body } } },
193
+ }),
194
+ ]);
195
+
196
+ const content = String(unified.toolResult?.content);
197
+ assert.ok(content.length < body.length / 2, 'the output must not survive at full size');
198
+ assert.match(content, /… 80000 more characters$/);
199
+ const nested = (unified.toolResult?.toolUseResult as { file: { base64: string } }).file.base64;
200
+ assert.equal(nested, content, 'the structured copy is capped the same way');
201
+ });
202
+
203
+ test('a search result keeps every file it found', () => {
204
+ const filenames = Array.from({ length: 900 }, (_, index) => `/repo/src/file-${index}.ts`);
205
+ const [unified] = prepareTranscriptMessages([
206
+ message({
207
+ kind: 'tool_use',
208
+ toolName: 'Glob',
209
+ toolId: 'g1',
210
+ toolInput: { pattern: '**/*.ts' },
211
+ toolResult: { content: 'ok', toolUseResult: { numFiles: filenames.length, filenames } },
212
+ }),
213
+ ]);
214
+
215
+ const result = unified.toolResult?.toolUseResult as { filenames: string[]; numFiles: number };
216
+ assert.equal(result.numFiles, 900);
217
+ assert.deepEqual(result.filenames, filenames);
218
+ });
@@ -186,9 +186,10 @@ export type MessageKind =
186
186
  | 'complete'
187
187
  | 'status'
188
188
  | 'permission_request'
189
+ | 'permission_resolved'
189
190
  | 'permission_cancelled'
190
191
  | 'session_created'
191
- | 'interactive_prompt'
192
+ | 'history_truncated'
192
193
  | 'task_notification';
193
194
 
194
195
  /**
@@ -215,6 +216,42 @@ export type GatewayEventKind =
215
216
  */
216
217
  export type ServerEventKind = MessageKind | GatewayEventKind;
217
218
 
219
+ /** The owning project as it appears inside a `session_upserted` delta. */
220
+ export type SessionUpsertedProject = {
221
+ projectId: string;
222
+ path: string;
223
+ fullPath: string;
224
+ displayName: string;
225
+ isStarred: boolean;
226
+ };
227
+
228
+ /**
229
+ * The `session_upserted` sidebar delta, built only by
230
+ * `modules/websocket/services/session-upsert-broadcast.service.ts`.
231
+ *
232
+ * Typed rather than assembled as an untyped object literal because the payload
233
+ * used to be built in two places and silently drifted apart: one copy set
234
+ * `providerSessionId` and the other did not, and nothing could detect it.
235
+ *
236
+ * `providerSessionId` is how a client recognises that a row it is currently
237
+ * showing has been merged into its canonical app-session row, so it is always
238
+ * present — `null` only while the provider has not reported an id yet.
239
+ */
240
+ export type SessionUpsertedEvent = {
241
+ kind: 'session_upserted';
242
+ sessionId: string;
243
+ providerSessionId: string | null;
244
+ provider: LLMProvider;
245
+ session: {
246
+ id: string;
247
+ summary: string;
248
+ messageCount: number;
249
+ lastActivity: string;
250
+ };
251
+ project: SessionUpsertedProject | null;
252
+ timestamp: string;
253
+ };
254
+
218
255
  /**
219
256
  * Provider-neutral message envelope used in REST responses and realtime channels.
220
257
  *
@@ -223,6 +260,13 @@ export type ServerEventKind = MessageKind | GatewayEventKind;
223
260
  */
224
261
  export type NormalizedMessage = {
225
262
  id: string;
263
+ /**
264
+ * The provider's own identifier for the transcript row this message came
265
+ * from, when the provider has stable per-row identity (today: Claude's
266
+ * `uuid`). It is what "edit this message" and "fork from here" address, so it
267
+ * has to survive a reload — never a value this app synthesized.
268
+ */
269
+ transcriptAnchorId?: string;
226
270
  sessionId: string;
227
271
  timestamp: string;
228
272
  provider: LLMProvider;
@@ -274,13 +318,90 @@ export type NormalizedMessage = {
274
318
  status?: string;
275
319
  summary?: string;
276
320
  tokenBudget?: unknown;
277
- subagentTools?: unknown;
321
+ /**
322
+ * Timeline of everything a subagent did, attached to the `tool_use` that
323
+ * spawned it. Present for Claude `Agent`/`Task` calls and Codex
324
+ * `spawn_agent` calls; absent for every other tool.
325
+ */
326
+ subagentTools?: SubagentActivity[];
327
+ /** Identity and lifecycle of the subagent this `tool_use` spawned. */
328
+ subagent?: SubagentInfo;
329
+ /** Stored memory the reply drew on, when the provider reports it. */
330
+ memoryCitations?: MemoryCitation[];
278
331
  toolUseResult?: unknown;
279
332
  sequence?: number;
280
333
  rowid?: number;
281
334
  [key: string]: unknown;
282
335
  };
283
336
 
337
+ /**
338
+ * One stored memory an assistant reply drew on.
339
+ *
340
+ * Codex appends these to a reply that used its memory files, naming the file
341
+ * and line range it read plus a short note on what it took from there. The
342
+ * transcript shows them as a footnote so a memory-derived claim is traceable
343
+ * rather than arriving as an unattributed assertion.
344
+ */
345
+ export type MemoryCitation = {
346
+ /** File and line range that was read, e.g. `MEMORY.md:137-142`. */
347
+ source: string;
348
+ /** What the reply took from that range, when the provider states it. */
349
+ note?: string;
350
+ };
351
+
352
+ /**
353
+ * One entry in a subagent's recorded timeline.
354
+ *
355
+ * Providers store a subagent's work in a separate transcript (Claude:
356
+ * `<session>/subagents/agent-<id>.jsonl`; Codex: a sibling rollout keyed by
357
+ * `agent_thread_id`). Both are flattened into this shape so the transcript can
358
+ * replay a subagent's run with the same renderers the main thread uses.
359
+ *
360
+ * `kind` decides which fields matter: `tool` uses the tool fields, `text` and
361
+ * `thinking` use `content`. Consumers must not assume tool fields exist on the
362
+ * text kinds.
363
+ */
364
+ export type SubagentActivity = {
365
+ kind: 'tool' | 'text' | 'thinking';
366
+ timestamp?: string;
367
+ /** Tool-call identity; only set when `kind` is `tool`. */
368
+ toolId?: string;
369
+ toolName?: string;
370
+ toolInput?: unknown;
371
+ toolResult?: { content?: string; isError?: boolean } | null;
372
+ /** Message body; only set when `kind` is `text` or `thinking`. */
373
+ content?: string;
374
+ };
375
+
376
+ /**
377
+ * Identity and lifecycle of one spawned subagent, normalized across providers.
378
+ *
379
+ * `status` is `running` until the call that spawned the agent resolves. After
380
+ * that it is whatever the provider reported — Claude's task notification
381
+ * carries one — and `completed` when the provider reported nothing. A failed
382
+ * tool call *inside* the agent is not a failed agent, so it is never inferred
383
+ * from the transcript.
384
+ */
385
+ export type SubagentInfo = {
386
+ /** Provider-native agent id — Claude `agentId`, Codex `agent_thread_id`. */
387
+ id: string;
388
+ /** Human-facing label: Claude's agent type, or Codex's assigned nickname. */
389
+ name?: string;
390
+ /** Agent type/preset when the provider records one (Claude `agentType`). */
391
+ type?: string;
392
+ /** One-line task summary shown in the collapsed header. */
393
+ description?: string;
394
+ status: 'running' | 'completed' | 'failed';
395
+ /** Model the subagent ran on, when the provider records it. */
396
+ model?: string;
397
+ /**
398
+ * How many activities the agent actually recorded. It exceeds
399
+ * `subagentTools.length` when a long run was truncated for transport, which
400
+ * lets the UI say so instead of silently showing a partial timeline.
401
+ */
402
+ activityCount?: number;
403
+ };
404
+
284
405
  /**
285
406
  * Output gateway shared by WebSocket and SSE provider runs.
286
407
  *
@@ -27,6 +27,7 @@ import type {
27
27
  ProviderCurrentActiveModel,
28
28
  ProviderModelsDefinition,
29
29
  ProviderSkillSource,
30
+ SubagentActivity,
30
31
  WorkspacePathValidationResult,
31
32
  } from '@/shared/types.js';
32
33
 
@@ -391,6 +392,45 @@ export function createCompleteMessage(opts: {
391
392
  });
392
393
  }
393
394
 
395
+ // ---------------------------
396
+ //----------------- SUBAGENT TIMELINE UTILITIES ------------
397
+ /**
398
+ * Longest tool output kept on one subagent activity.
399
+ *
400
+ * A subagent's timeline is nested inside a collapsed panel, so it is a preview
401
+ * of what the agent did, never the primary place its output is read. Sending
402
+ * every child command's full output made the history payload of an
403
+ * agent-heavy session grow by megabytes for content almost nobody expands.
404
+ */
405
+ const MAX_SUBAGENT_ACTIVITY_CONTENT = 4000;
406
+
407
+ function truncateForPreview(value: string | undefined): string | undefined {
408
+ if (typeof value !== 'string' || value.length <= MAX_SUBAGENT_ACTIVITY_CONTENT) {
409
+ return value;
410
+ }
411
+ const omitted = value.length - MAX_SUBAGENT_ACTIVITY_CONTENT;
412
+ return `${value.slice(0, MAX_SUBAGENT_ACTIVITY_CONTENT)}\n… ${omitted} more characters`;
413
+ }
414
+
415
+ /**
416
+ * Trims one subagent activity down to what its nested preview can show.
417
+ *
418
+ * Used by both provider session adapters so a Claude agent's timeline and a
419
+ * Codex agent's timeline cost the same to transport.
420
+ */
421
+ export function truncateSubagentActivity(activity: SubagentActivity): SubagentActivity {
422
+ const truncatedContent = truncateForPreview(activity.content);
423
+ const truncatedResult = activity.toolResult
424
+ ? { ...activity.toolResult, content: truncateForPreview(activity.toolResult.content) }
425
+ : activity.toolResult;
426
+
427
+ if (truncatedContent === activity.content && truncatedResult === activity.toolResult) {
428
+ return activity;
429
+ }
430
+
431
+ return { ...activity, content: truncatedContent, toolResult: truncatedResult };
432
+ }
433
+
394
434
  // ---------------------------
395
435
  //----------------- CONVERSATION HISTORY PAGINATION UTILITIES ------------
396
436
  /**
@@ -1 +0,0 @@
1
- import{af as o,ag as n}from"./mermaid.core-BEUL86Z6.js";const t=(a,r)=>o.lang.round(n.parse(a)[r]);export{t as c};
@@ -1 +0,0 @@
1
- import{s as a,c as s,a as e,C as t}from"./chunk-GF5L2VYU-rrl2lRxY.js";import{_ as i}from"./mermaid.core-BEUL86Z6.js";import"./chunk-5VM5RSS4-B0rjslal.js";import"./chunk-XXDRQBXY-wHxalsXk.js";import"./chunk-KBJHAD2P-CRzKgU8S.js";import"./chunk-2GRJ4B5K-B8fnBG6E.js";import"./index-DFkBBuSA.js";import"./vendor-codemirror-OwyKSvPE.js";import"./vendor-react-BGZc9oRE.js";import"./vendor-xterm-CS4rQ5Mr.js";var c={parser:e,get db(){return new t},renderer:s,styles:a,init:i(r=>{r.class||(r.class={}),r.class.arrowMarkerAbsolute=r.arrowMarkerAbsolute},"init")};export{c as diagram};
@@ -1 +0,0 @@
1
- import{s as a,c as s,a as e,C as t}from"./chunk-GF5L2VYU-rrl2lRxY.js";import{_ as i}from"./mermaid.core-BEUL86Z6.js";import"./chunk-5VM5RSS4-B0rjslal.js";import"./chunk-XXDRQBXY-wHxalsXk.js";import"./chunk-KBJHAD2P-CRzKgU8S.js";import"./chunk-2GRJ4B5K-B8fnBG6E.js";import"./index-DFkBBuSA.js";import"./vendor-codemirror-OwyKSvPE.js";import"./vendor-react-BGZc9oRE.js";import"./vendor-xterm-CS4rQ5Mr.js";var c={parser:e,get db(){return new t},renderer:s,styles:a,init:i(r=>{r.class||(r.class={}),r.class.arrowMarkerAbsolute=r.arrowMarkerAbsolute},"init")};export{c as diagram};