@xopcai/xopc 0.0.124 → 0.0.126

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 (496) hide show
  1. package/README.md +56 -102
  2. package/README.zh-CN.md +51 -98
  3. package/dist/browser-ext/manifest.json +1 -1
  4. package/dist/extensions/feishu/src/schema/config-schema.d.ts +6 -6
  5. package/dist/extensions/feishu/src/workflow-progress.js +1 -1
  6. package/dist/extensions/telegram/src/adapters/streaming-adapter.js +1 -1
  7. package/dist/extensions/telegram/src/config-schema.d.ts +8 -8
  8. package/dist/extensions/telegram/src/inbound-processor.js +1 -1
  9. package/dist/extensions/telegram/src/plugin.js +1 -1
  10. package/dist/extensions/telegram/src/routing-integration.js +2 -2
  11. package/dist/extensions/telegram/src/workflow-progress.js +1 -1
  12. package/dist/extensions/telegram/xopc.extension.json +1 -1
  13. package/dist/extensions/weixin/src/api/api.js +1 -1
  14. package/dist/extensions/weixin/src/config-schema.d.ts +3 -3
  15. package/dist/extensions/weixin/src/plugin.js +1 -1
  16. package/dist/extensions/weixin/src/workflow-progress.js +1 -1
  17. package/dist/gateway/static/root/assets/Combination-BzaXOLd9.js +41 -0
  18. package/dist/gateway/static/root/assets/{agent-avatar-dicebear-B5uSVAyJ.js → agent-avatar-dicebear-C70vgt60.js} +1 -1
  19. package/dist/gateway/static/root/assets/agents-DRYVahI-.js +2 -0
  20. package/dist/gateway/static/root/assets/app-management-settings-panel-D9-HW6cy.js +1 -0
  21. package/dist/gateway/static/root/assets/appearance-settings-BHlahIDL.js +1 -0
  22. package/dist/gateway/static/root/assets/apps-page-BdJ1eQg3.js +1 -0
  23. package/dist/gateway/static/root/assets/{archive-plugin-CXUGRp2i.js → archive-plugin-B-aoIt0w.js} +1 -1
  24. package/dist/gateway/static/root/assets/{attachment-load-Cmiub3Wg.js → attachment-load-BD0G0FD5.js} +1 -1
  25. package/dist/gateway/static/root/assets/automation-suggestion-card-iJRVI7aZ.js +1 -0
  26. package/dist/gateway/static/root/assets/automations-page-D8hYQbkl.js +4 -0
  27. package/dist/gateway/static/root/assets/{binary-plugins-0Izz-N3p.js → binary-plugins-B0mNlVSz.js} +1 -1
  28. package/dist/gateway/static/root/assets/{block-editor-C1Kv0IkJ.js → block-editor-CJY9Lu5G.js} +3 -3
  29. package/dist/gateway/static/root/assets/browser-settings-page-CiWEO-Iy.js +8 -0
  30. package/dist/gateway/static/root/assets/capability-presets-api-Bgc8ag55.js +1 -0
  31. package/dist/gateway/static/root/assets/capability-presets-settings-panel-B1nIi0TC.js +1 -0
  32. package/dist/gateway/static/root/assets/{channel-recipient-api-BeA2aVor.js → channel-recipient-api-0sauApoC.js} +1 -1
  33. package/dist/gateway/static/root/assets/channels-settings-BddPdqVo.js +1 -0
  34. package/dist/gateway/static/root/assets/code-editor-gbRgS14t.js +1 -0
  35. package/dist/gateway/static/root/assets/connectors-page-Ba2GDhSE.js +2 -0
  36. package/dist/gateway/static/root/assets/{directory-picker-path-field-2rjzUu57.js → directory-picker-path-field-CiEc4KmY.js} +1 -1
  37. package/dist/gateway/static/root/assets/dist-By6Rh2ee.js +1 -0
  38. package/dist/gateway/static/root/assets/dist-CkobR7mk.js +1 -0
  39. package/dist/gateway/static/root/assets/dist-DokQNVMQ.js +1 -0
  40. package/dist/gateway/static/root/assets/dreaming-settings-4bvpk5wr.js +3 -0
  41. package/dist/gateway/static/root/assets/extension-debug-page-BbyczVZ3.js +1 -0
  42. package/dist/gateway/static/root/assets/extension-page-DLN1I3DR.js +1 -0
  43. package/dist/gateway/static/root/assets/extension-settings-page-D9VGHmYJ.js +1 -0
  44. package/dist/gateway/static/root/assets/{fetch-BU5S0Sn7.js → fetch-5V96dUz3.js} +1 -1
  45. package/dist/gateway/static/root/assets/{gateway-config-api-BIPGwrl1.js → gateway-config-api-BtIzObwp.js} +1 -1
  46. package/dist/gateway/static/root/assets/gateway-settings-KFsGGDhg.js +1 -0
  47. package/dist/gateway/static/root/assets/{gateway-startup-retry-Cd0Zz30N.js → gateway-startup-retry-DEMad2wt.js} +1 -1
  48. package/dist/gateway/static/root/assets/goal-create-dialog-4PcF6Sh6.js +1 -0
  49. package/dist/gateway/static/root/assets/goal-detail-page-B482PSaG.js +1 -0
  50. package/dist/gateway/static/root/assets/{goals-config-api-B95KdGMj.js → goals-config-api-CVN7-pdM.js} +1 -1
  51. package/dist/gateway/static/root/assets/goals-page-CUdgJuDn.js +2 -0
  52. package/dist/gateway/static/root/assets/goals-settings-IYCH3-Pi.js +1 -0
  53. package/dist/gateway/static/root/assets/heartbeat-settings-Cf_a2Bmz.js +1 -0
  54. package/dist/gateway/static/root/assets/{html-workspace-editor-CQLWDiwE.js → html-workspace-editor-DV90ddkE.js} +1 -1
  55. package/dist/gateway/static/root/assets/index-CA2tR2vm.js +256 -0
  56. package/dist/gateway/static/root/assets/index-Ds3u0LOk.css +1 -0
  57. package/dist/gateway/static/root/assets/keyboard-shortcuts-settings-lKTg6St7.js +1 -0
  58. package/dist/gateway/static/root/assets/logs-page-BCporcNH.js +2 -0
  59. package/dist/gateway/static/root/assets/{markdown-editor-AssmZFx4.js → markdown-editor-BFOjBBla.js} +2 -2
  60. package/dist/gateway/static/root/assets/markdown-split-Bv4k6iGJ.js +1 -0
  61. package/dist/gateway/static/root/assets/{media-plugins-BhIQU5yS.js → media-plugins-Bbi8g3N8.js} +1 -1
  62. package/dist/gateway/static/root/assets/messages-C22hxE1N.js +3 -0
  63. package/dist/gateway/static/root/assets/models-hub-panel-D68Pyow7.js +2 -0
  64. package/dist/gateway/static/root/assets/notes-page-CuUMOiyv.js +1 -0
  65. package/dist/gateway/static/root/assets/notes-workbench-Dx2N5zTk.js +2 -0
  66. package/dist/gateway/static/root/assets/page-tabs-Cp395RYD.js +1 -0
  67. package/dist/gateway/static/root/assets/{preview-open-alternatives-DGzet1d7.js → preview-open-alternatives-DqV5OM4m.js} +1 -1
  68. package/dist/gateway/static/root/assets/project-detail-page-sB8AzZi3.js +1 -0
  69. package/dist/gateway/static/root/assets/projects-page-LBnJqWK2.js +1 -0
  70. package/dist/gateway/static/root/assets/remote-access-hub-Dbj0o6SC.js +1 -0
  71. package/dist/gateway/static/root/assets/{save-bar-controls-Cqgb-jqa.js → save-bar-controls-BItmzAzI.js} +1 -1
  72. package/dist/gateway/static/root/assets/{schedule-field-DVZcI8Yt.js → schedule-field-BQ8IjjCn.js} +1 -1
  73. package/dist/gateway/static/root/assets/{schema-form-Bj7sOxC8.js → schema-form-BRpD6x3d.js} +1 -1
  74. package/dist/gateway/static/root/assets/sessions-page-DhDZKspB.js +1 -0
  75. package/dist/gateway/static/root/assets/settings-advanced-gate-BvXLMNL6.js +1 -0
  76. package/dist/gateway/static/root/assets/{settings-collapsible-section-BmXn-8N6.js → settings-collapsible-section-BKSPQM4R.js} +1 -1
  77. package/dist/gateway/static/root/assets/settings-form-section-BmyfthNQ.js +1 -0
  78. package/dist/gateway/static/root/assets/settings-page-Cfm9UxAr.js +1 -0
  79. package/dist/gateway/static/root/assets/settings-page-layout-Bls5tfbH.js +1 -0
  80. package/dist/gateway/static/root/assets/setup-status-panel-kQEsTGAs.js +1 -0
  81. package/dist/gateway/static/root/assets/{share-preview-page-IB1v8i86.js → share-preview-page-DbYZNAPb.js} +1 -1
  82. package/dist/gateway/static/root/assets/shares-settings-BtR4B0kn.js +1 -0
  83. package/dist/gateway/static/root/assets/skill-reload-api-CJNVOWoK.js +1 -0
  84. package/dist/gateway/static/root/assets/skills-page-DcWDHrt3.js +2 -0
  85. package/dist/gateway/static/root/assets/{system-settings-panel-BxQ384RC.js → system-settings-panel-DKDAojWM.js} +1 -1
  86. package/dist/gateway/static/root/assets/{typed-models-lib-BkcpvFYO.js → typed-models-lib-BCCV4Kkp.js} +1 -1
  87. package/dist/gateway/static/root/assets/{use-channel-catalog-Cd0FaEQ4.js → use-channel-catalog-NBqg3iFY.js} +1 -1
  88. package/dist/gateway/static/root/assets/{user-profile-settings-panel-DQ7NnRSY.js → user-profile-settings-panel-suQ2x-LB.js} +1 -1
  89. package/dist/gateway/static/root/assets/{utils-YKhVf7Ka.js → utils-DPGVr3tS.js} +1 -1
  90. package/dist/gateway/static/root/assets/{vendor-codemirror-CNP1wPe7.js → vendor-codemirror-BvNgyE1Q.js} +1 -1
  91. package/dist/gateway/static/root/assets/voice-api-key-field-DaJASKFP.js +1 -0
  92. package/dist/gateway/static/root/assets/work-item-detail-page-BrCZpAWh.js +1 -0
  93. package/dist/gateway/static/root/assets/workflow-run-setup-panel-BTkRVNAh.js +3 -0
  94. package/dist/gateway/static/root/assets/{workflow-start-dialog-BNJVCWoS.js → workflow-start-dialog-DAImVtdO.js} +1 -1
  95. package/dist/gateway/static/root/assets/workflows-page-vyJ8wSXm.js +18 -0
  96. package/dist/gateway/static/root/index.html +8 -7
  97. package/dist/package.js +1 -1
  98. package/dist/src/activity/context.d.ts +11 -0
  99. package/dist/src/activity/context.js +36 -0
  100. package/dist/src/activity/context.js.map +1 -0
  101. package/dist/src/activity/emitter.d.ts +6 -0
  102. package/dist/src/activity/emitter.js +43 -0
  103. package/dist/src/activity/emitter.js.map +1 -0
  104. package/dist/src/activity/index.d.ts +3 -0
  105. package/dist/src/activity/index.js +3 -0
  106. package/dist/src/activity/service.d.ts +12 -0
  107. package/dist/src/activity/service.js +59 -0
  108. package/dist/src/activity/service.js.map +1 -0
  109. package/dist/src/activity/types.d.ts +109 -0
  110. package/dist/src/activity/types.js +1 -0
  111. package/dist/src/agent/agent-manager.d.ts +7 -0
  112. package/dist/src/agent/agent-manager.js +12 -5
  113. package/dist/src/agent/agent-manager.js.map +1 -1
  114. package/dist/src/agent/child-agent-factory.d.ts +2 -0
  115. package/dist/src/agent/child-agent-factory.js +2 -0
  116. package/dist/src/agent/child-agent-factory.js.map +1 -1
  117. package/dist/src/agent/coding/index.d.ts +1 -0
  118. package/dist/src/agent/coding/index.js +2 -0
  119. package/dist/src/agent/coding/turn-diff-tracker.d.ts +67 -0
  120. package/dist/src/agent/coding/turn-diff-tracker.js +233 -0
  121. package/dist/src/agent/coding/turn-diff-tracker.js.map +1 -0
  122. package/dist/src/agent/context/project-context.js +2 -2
  123. package/dist/src/agent/context/workspace-seed.js +2 -2
  124. package/dist/src/agent/embedded/run-for-session.js +1 -1
  125. package/dist/src/agent/goals/post-turn.js +2 -2
  126. package/dist/src/agent/ipc/bus.js +1 -1
  127. package/dist/src/agent/mcp/bundle-mcp-materialize.js +1 -1
  128. package/dist/src/agent/mcp/bundle-mcp-runtime.js +1 -1
  129. package/dist/src/agent/mcp/mcp-transport-config.js +1 -1
  130. package/dist/src/agent/mcp/mcp-transport.js +1 -1
  131. package/dist/src/agent/memory/dreaming/config.d.ts +2 -2
  132. package/dist/src/agent/memory/dreaming/config.js +3 -3
  133. package/dist/src/agent/memory/dreaming/config.js.map +1 -1
  134. package/dist/src/agent/memory/dreaming/constants.d.ts +1 -1
  135. package/dist/src/agent/memory/dreaming/constants.js +1 -1
  136. package/dist/src/agent/memory/dreaming/constants.js.map +1 -1
  137. package/dist/src/agent/memory/dreaming/deep-promotion.d.ts +1 -0
  138. package/dist/src/agent/memory/dreaming/deep-promotion.js +11 -20
  139. package/dist/src/agent/memory/dreaming/deep-promotion.js.map +1 -1
  140. package/dist/src/agent/memory/dreaming/events.d.ts +3 -3
  141. package/dist/src/agent/memory/dreaming/events.js +6 -6
  142. package/dist/src/agent/memory/dreaming/events.js.map +1 -1
  143. package/dist/src/agent/memory/dreaming/last-run.d.ts +2 -2
  144. package/dist/src/agent/memory/dreaming/last-run.js +1 -1
  145. package/dist/src/agent/memory/dreaming/last-run.js.map +1 -1
  146. package/dist/src/agent/memory/dreaming/light-sweep.d.ts +1 -1
  147. package/dist/src/agent/memory/dreaming/light-sweep.js +3 -3
  148. package/dist/src/agent/memory/dreaming/light-sweep.js.map +1 -1
  149. package/dist/src/agent/memory/dreaming/preview.d.ts +1 -0
  150. package/dist/src/agent/memory/dreaming/preview.js +2 -2
  151. package/dist/src/agent/memory/dreaming/preview.js.map +1 -1
  152. package/dist/src/agent/memory/dreaming/rem-patterns.d.ts +1 -1
  153. package/dist/src/agent/memory/dreaming/rem-patterns.js +13 -13
  154. package/dist/src/agent/memory/dreaming/rem-patterns.js.map +1 -1
  155. package/dist/src/agent/memory/dreaming/scope.d.ts +14 -0
  156. package/dist/src/agent/memory/dreaming/scope.js +27 -0
  157. package/dist/src/agent/memory/dreaming/scope.js.map +1 -0
  158. package/dist/src/agent/memory/dreaming/short-term-store.d.ts +4 -4
  159. package/dist/src/agent/memory/dreaming/short-term-store.js +17 -17
  160. package/dist/src/agent/memory/dreaming/short-term-store.js.map +1 -1
  161. package/dist/src/agent/memory/plugin-discovery.js +1 -1
  162. package/dist/src/agent/models/manager.js +1 -1
  163. package/dist/src/agent/orchestration/agent-event-handler.d.ts +2 -0
  164. package/dist/src/agent/orchestration/agent-event-handler.js +13 -0
  165. package/dist/src/agent/orchestration/agent-event-handler.js.map +1 -1
  166. package/dist/src/agent/orchestration/agent-orchestrator.js +22 -12
  167. package/dist/src/agent/orchestration/agent-orchestrator.js.map +1 -1
  168. package/dist/src/agent/sandbox/command-validator.js +12 -0
  169. package/dist/src/agent/sandbox/command-validator.js.map +1 -1
  170. package/dist/src/agent/service.d.ts +2 -1
  171. package/dist/src/agent/service.js +24 -9
  172. package/dist/src/agent/service.js.map +1 -1
  173. package/dist/src/agent/service.types.d.ts +7 -0
  174. package/dist/src/agent/session/session-inspector.d.ts +5 -3
  175. package/dist/src/agent/session/session-inspector.js +17 -8
  176. package/dist/src/agent/session/session-inspector.js.map +1 -1
  177. package/dist/src/agent/skills/hub-pull.js +1 -1
  178. package/dist/src/agent/source-context/types.d.ts +1 -1
  179. package/dist/src/agent/source-context/types.js +1 -1
  180. package/dist/src/agent/source-context/types.js.map +1 -1
  181. package/dist/src/agent/tool-manuals/index.js +15 -6
  182. package/dist/src/agent/tool-manuals/index.js.map +1 -1
  183. package/dist/src/agent/tool-manuals/xopc-use.d.ts +1 -0
  184. package/dist/src/agent/tool-manuals/xopc-use.js +204 -0
  185. package/dist/src/agent/tool-manuals/xopc-use.js.map +1 -0
  186. package/dist/src/agent/tools/apply-patch.js +116 -62
  187. package/dist/src/agent/tools/apply-patch.js.map +1 -1
  188. package/dist/src/agent/tools/concurrency.d.ts +8 -0
  189. package/dist/src/agent/tools/concurrency.js +31 -0
  190. package/dist/src/agent/tools/concurrency.js.map +1 -0
  191. package/dist/src/agent/tools/dreaming-tool.d.ts +2 -0
  192. package/dist/src/agent/tools/dreaming-tool.js +13 -10
  193. package/dist/src/agent/tools/dreaming-tool.js.map +1 -1
  194. package/dist/src/agent/tools/exec-command.js +4 -0
  195. package/dist/src/agent/tools/exec-command.js.map +1 -1
  196. package/dist/src/agent/tools/executor.d.ts +6 -4
  197. package/dist/src/agent/tools/executor.js +7 -4
  198. package/dist/src/agent/tools/executor.js.map +1 -1
  199. package/dist/src/agent/tools/factory.d.ts +10 -0
  200. package/dist/src/agent/tools/factory.js +16 -1
  201. package/dist/src/agent/tools/factory.js.map +1 -1
  202. package/dist/src/agent/tools/find.js +2 -0
  203. package/dist/src/agent/tools/find.js.map +1 -1
  204. package/dist/src/agent/tools/goal-tool.js +2 -2
  205. package/dist/src/agent/tools/grep.js +2 -0
  206. package/dist/src/agent/tools/grep.js.map +1 -1
  207. package/dist/src/agent/tools/index.d.ts +3 -0
  208. package/dist/src/agent/tools/index.js +4 -1
  209. package/dist/src/agent/tools/list-dir.js +2 -0
  210. package/dist/src/agent/tools/list-dir.js.map +1 -1
  211. package/dist/src/agent/tools/memory-tool.d.ts +1 -0
  212. package/dist/src/agent/tools/memory-tool.js +2 -2
  213. package/dist/src/agent/tools/memory-tool.js.map +1 -1
  214. package/dist/src/agent/tools/metadata.d.ts +15 -0
  215. package/dist/src/agent/tools/metadata.js +26 -0
  216. package/dist/src/agent/tools/metadata.js.map +1 -0
  217. package/dist/src/agent/tools/read.js +2 -0
  218. package/dist/src/agent/tools/read.js.map +1 -1
  219. package/dist/src/agent/tools/workflow-tool.js +1 -1
  220. package/dist/src/agent/tools/write.js +6 -0
  221. package/dist/src/agent/tools/write.js.map +1 -1
  222. package/dist/src/agent/tools/xopc-use-tool.d.ts +34 -0
  223. package/dist/src/agent/tools/xopc-use-tool.js +636 -0
  224. package/dist/src/agent/tools/xopc-use-tool.js.map +1 -0
  225. package/dist/src/agent/workflow/subagent-runner.d.ts +1 -0
  226. package/dist/src/agent/workflow/subagent-runner.js +5 -1
  227. package/dist/src/agent/workflow/subagent-runner.js.map +1 -1
  228. package/dist/src/agent/workflow/workflow-child-tools.js +5 -0
  229. package/dist/src/agent/workflow/workflow-child-tools.js.map +1 -1
  230. package/dist/src/agent-manifest/schema.d.ts +27 -27
  231. package/dist/src/automations/api/routes.js +1 -1
  232. package/dist/src/automations/domain/validation.d.ts +55 -55
  233. package/dist/src/automations/draft/automation-draft-validator.d.ts +25 -25
  234. package/dist/src/automations/service/action-executor.js +2 -2
  235. package/dist/src/browser/cdp-local-launcher.js +1 -1
  236. package/dist/src/browser/providers/browser-ext-install.js +3 -3
  237. package/dist/src/browser/providers/cloakbrowser.js +2 -2
  238. package/dist/src/browser/providers/playwright-doctor.js +1 -1
  239. package/dist/src/browser/stealth.js +1 -1
  240. package/dist/src/chat-commands/agent-edit.js +1 -1
  241. package/dist/src/chat-commands/builtins/config.js +1 -1
  242. package/dist/src/chat-commands/builtins/goal.js +2 -2
  243. package/dist/src/chat-commands/context.js +1 -1
  244. package/dist/src/cli/commands/agent.js +1 -1
  245. package/dist/src/cli/commands/doctor/checks/database-schema.js +2 -2
  246. package/dist/src/cli/commands/doctor/checks/session-integrity.js +1 -1
  247. package/dist/src/cli/commands/extension-marketplace.js +1 -1
  248. package/dist/src/cli/commands/extension-pack.js +1 -1
  249. package/dist/src/cli/commands/gateway/lifecycle.js +1 -1
  250. package/dist/src/cli/commands/goal.js +3 -3
  251. package/dist/src/cli/commands/init.js +1 -1
  252. package/dist/src/cli/commands/project.js +4 -4
  253. package/dist/src/config/agent-profile.js +1 -1
  254. package/dist/src/config/gateway-bind.js +1 -1
  255. package/dist/src/config/index.js +1 -1
  256. package/dist/src/config/loader.js +1 -1
  257. package/dist/src/config/models-json.d.ts +14 -14
  258. package/dist/src/config/models-json.js +1 -1
  259. package/dist/src/config/schema.d.ts +60 -60
  260. package/dist/src/connectors/health.d.ts +2 -1
  261. package/dist/src/connectors/health.js +59 -1
  262. package/dist/src/connectors/health.js.map +1 -1
  263. package/dist/src/connectors/install.d.ts +1 -0
  264. package/dist/src/connectors/install.js +28 -1
  265. package/dist/src/connectors/install.js.map +1 -1
  266. package/dist/src/connectors/instances.js +7 -0
  267. package/dist/src/connectors/instances.js.map +1 -1
  268. package/dist/src/connectors/materialize.js +2 -1
  269. package/dist/src/connectors/materialize.js.map +1 -1
  270. package/dist/src/connectors/registries/modelscope.js +38 -13
  271. package/dist/src/connectors/registries/modelscope.js.map +1 -1
  272. package/dist/src/connectors/types.d.ts +2 -0
  273. package/dist/src/daemon/launchd.js +1 -1
  274. package/dist/src/daemon/systemd.js +1 -1
  275. package/dist/src/extensions/discover-extensions.js +1 -1
  276. package/dist/src/extensions/loader.js +2 -2
  277. package/dist/src/gateway/agents-admin.js +1 -1
  278. package/dist/src/gateway/dreaming-automation-reconciler.d.ts +1 -0
  279. package/dist/src/gateway/dreaming-automation-reconciler.js +62 -42
  280. package/dist/src/gateway/dreaming-automation-reconciler.js.map +1 -1
  281. package/dist/src/gateway/hono/app.js +7 -1
  282. package/dist/src/gateway/hono/app.js.map +1 -1
  283. package/dist/src/gateway/hono/lib/config-payload.d.ts +14 -14
  284. package/dist/src/gateway/hono/lib/static-ui.js +1 -1
  285. package/dist/src/gateway/hono/middleware/log-context.js +8 -1
  286. package/dist/src/gateway/hono/middleware/log-context.js.map +1 -1
  287. package/dist/src/gateway/hono/routes/activity.d.ts +14 -0
  288. package/dist/src/gateway/hono/routes/activity.js +72 -0
  289. package/dist/src/gateway/hono/routes/activity.js.map +1 -0
  290. package/dist/src/gateway/hono/routes/connectors.js +46 -2
  291. package/dist/src/gateway/hono/routes/connectors.js.map +1 -1
  292. package/dist/src/gateway/hono/routes/dreaming.js +111 -66
  293. package/dist/src/gateway/hono/routes/dreaming.js.map +1 -1
  294. package/dist/src/gateway/hono/routes/goals.js +1 -1
  295. package/dist/src/gateway/hono/routes/index.js +2 -0
  296. package/dist/src/gateway/hono/routes/index.js.map +1 -1
  297. package/dist/src/gateway/hono/routes/memory.js +2 -2
  298. package/dist/src/gateway/hono/routes/projects.js +903 -50
  299. package/dist/src/gateway/hono/routes/projects.js.map +1 -1
  300. package/dist/src/gateway/hono/routes/sessions.js +102 -2
  301. package/dist/src/gateway/hono/routes/sessions.js.map +1 -1
  302. package/dist/src/gateway/hono/routes/workflows.js +2 -2
  303. package/dist/src/gateway/lock.js +1 -1
  304. package/dist/src/gateway/ports.js +1 -1
  305. package/dist/src/gateway/service/sessions-api.d.ts +10 -0
  306. package/dist/src/gateway/service/sessions-api.js +31 -0
  307. package/dist/src/gateway/service/sessions-api.js.map +1 -1
  308. package/dist/src/gateway/service.js +28 -16
  309. package/dist/src/gateway/service.js.map +1 -1
  310. package/dist/src/goals/goal-store.js +1 -1
  311. package/dist/src/goals/goal-store.js.map +1 -1
  312. package/dist/src/goals/goal-workflow-judge.js +1 -1
  313. package/dist/src/infra/ports.js +1 -1
  314. package/dist/src/infra/ssh-tunnel.js +1 -1
  315. package/dist/src/infra/update-check.js +1 -1
  316. package/dist/src/infra/update-restart.js +1 -1
  317. package/dist/src/mcp/channel-bridge.js +1 -1
  318. package/dist/src/media/store.js +1 -1
  319. package/dist/src/media/store.js.map +1 -1
  320. package/dist/src/media/types.d.ts +1 -1
  321. package/dist/src/media/uri.js +2 -1
  322. package/dist/src/media/uri.js.map +1 -1
  323. package/dist/src/migrations/runner.js +1 -1
  324. package/dist/src/notes/service.js +65 -6
  325. package/dist/src/notes/service.js.map +1 -1
  326. package/dist/src/notes/store.js +1 -1
  327. package/dist/src/projects/project-service.d.ts +2 -1
  328. package/dist/src/projects/project-service.js +59 -2
  329. package/dist/src/projects/project-service.js.map +1 -1
  330. package/dist/src/projects/project-store.d.ts +2 -1
  331. package/dist/src/projects/project-store.js +43 -0
  332. package/dist/src/projects/project-store.js.map +1 -1
  333. package/dist/src/projects/types.d.ts +10 -0
  334. package/dist/src/projects/workspace.js +1 -1
  335. package/dist/src/routing/agent-session-key.js +1 -1
  336. package/dist/src/routing/resolve-route.js +1 -1
  337. package/dist/src/routing/resolve-tui-session-key.js +1 -1
  338. package/dist/src/session/client-history.d.ts +3 -0
  339. package/dist/src/session/client-history.js +24 -9
  340. package/dist/src/session/client-history.js.map +1 -1
  341. package/dist/src/session/init-session-turn.js +1 -1
  342. package/dist/src/session/resolve-session.js +1 -1
  343. package/dist/src/session/session-context-for-llm.d.ts +2 -0
  344. package/dist/src/session/session-context-for-llm.js +14 -1
  345. package/dist/src/session/session-context-for-llm.js.map +1 -1
  346. package/dist/src/session/session-title.js +2 -2
  347. package/dist/src/session/store.js +3 -3
  348. package/dist/src/session/store.js.map +1 -1
  349. package/dist/src/session/types.d.ts +4 -0
  350. package/dist/src/session/types.js.map +1 -1
  351. package/dist/src/storage/sqlite/activity-repository.d.ts +8 -0
  352. package/dist/src/storage/sqlite/activity-repository.js +208 -0
  353. package/dist/src/storage/sqlite/activity-repository.js.map +1 -0
  354. package/dist/src/storage/sqlite/connection.js +1 -1
  355. package/dist/src/storage/sqlite/index.d.ts +1 -0
  356. package/dist/src/storage/sqlite/index.js +2 -1
  357. package/dist/src/storage/sqlite/migrations/022_work_items.sql +61 -0
  358. package/dist/src/storage/sqlite/migrations/023_work_item_attachments.sql +15 -0
  359. package/dist/src/storage/sqlite/migrations/024_activity_events.sql +62 -0
  360. package/dist/src/storage/sqlite/migrations/runner.d.ts +1 -1
  361. package/dist/src/storage/sqlite/migrations/runner.js +3 -3
  362. package/dist/src/storage/sqlite/migrations/runner.js.map +1 -1
  363. package/dist/src/storage/sqlite/migrations/runner.ts +1 -1
  364. package/dist/src/storage/sqlite/row-mappers.js +1 -1
  365. package/dist/src/storage/sqlite/schema.js +1 -1
  366. package/dist/src/storage/sqlite/schema.sql +141 -0
  367. package/dist/src/storage/sqlite/session-repository.js +11 -0
  368. package/dist/src/storage/sqlite/session-repository.js.map +1 -1
  369. package/dist/src/tui/backends/embedded-backend.d.ts +13 -0
  370. package/dist/src/tui/backends/embedded-backend.js +76 -7
  371. package/dist/src/tui/backends/embedded-backend.js.map +1 -1
  372. package/dist/src/tui/backends/gateway-sse-backend.d.ts +13 -0
  373. package/dist/src/tui/backends/gateway-sse-backend.js +53 -0
  374. package/dist/src/tui/backends/gateway-sse-backend.js.map +1 -1
  375. package/dist/src/tui/chat-history.js +16 -3
  376. package/dist/src/tui/chat-history.js.map +1 -1
  377. package/dist/src/tui/clipboard-image.js +1 -1
  378. package/dist/src/tui/components/assistant-message.js +12 -2
  379. package/dist/src/tui/components/assistant-message.js.map +1 -1
  380. package/dist/src/tui/components/chat-log.d.ts +23 -3
  381. package/dist/src/tui/components/chat-log.js +68 -9
  382. package/dist/src/tui/components/chat-log.js.map +1 -1
  383. package/dist/src/tui/components/tool-execution.d.ts +8 -0
  384. package/dist/src/tui/components/tool-execution.js +87 -77
  385. package/dist/src/tui/components/tool-execution.js.map +1 -1
  386. package/dist/src/tui/components/tui-bottom-bar.js +9 -5
  387. package/dist/src/tui/components/tui-bottom-bar.js.map +1 -1
  388. package/dist/src/tui/components/visual-truncate.d.ts +1 -0
  389. package/dist/src/tui/components/visual-truncate.js +28 -1
  390. package/dist/src/tui/components/visual-truncate.js.map +1 -1
  391. package/dist/src/tui/tool-summary.d.ts +22 -0
  392. package/dist/src/tui/tool-summary.js +212 -0
  393. package/dist/src/tui/tool-summary.js.map +1 -0
  394. package/dist/src/tui/tui-backend.d.ts +16 -0
  395. package/dist/src/tui/tui-command-formatters.js +2 -2
  396. package/dist/src/tui/tui-commands.d.ts +9 -0
  397. package/dist/src/tui/tui-commands.js +95 -6
  398. package/dist/src/tui/tui-commands.js.map +1 -1
  399. package/dist/src/tui/tui-picker-overlay.d.ts +1 -0
  400. package/dist/src/tui/tui-picker-overlay.js +36 -1
  401. package/dist/src/tui/tui-picker-overlay.js.map +1 -1
  402. package/dist/src/tui/tui-picker-services.d.ts +13 -0
  403. package/dist/src/tui/tui-run-state.js +11 -0
  404. package/dist/src/tui/tui-run-state.js.map +1 -1
  405. package/dist/src/tui/tui-run-status-format.d.ts +3 -0
  406. package/dist/src/tui/tui-run-status-format.js +33 -0
  407. package/dist/src/tui/tui-run-status-format.js.map +1 -0
  408. package/dist/src/tui/tui-session-actions.d.ts +5 -0
  409. package/dist/src/tui/tui-session-actions.js +24 -0
  410. package/dist/src/tui/tui-session-actions.js.map +1 -1
  411. package/dist/src/tui/tui-timeline-picker.d.ts +19 -0
  412. package/dist/src/tui/tui-timeline-picker.js +81 -0
  413. package/dist/src/tui/tui-timeline-picker.js.map +1 -0
  414. package/dist/src/tui/tui-timeline.d.ts +15 -0
  415. package/dist/src/tui/tui-timeline.js +65 -0
  416. package/dist/src/tui/tui-timeline.js.map +1 -0
  417. package/dist/src/tui/tui-tool-diff.d.ts +15 -0
  418. package/dist/src/tui/tui-tool-diff.js +178 -7
  419. package/dist/src/tui/tui-tool-diff.js.map +1 -1
  420. package/dist/src/tui/tui-types.d.ts +1 -0
  421. package/dist/src/tui/tui-types.js +1 -0
  422. package/dist/src/tui/tui-types.js.map +1 -1
  423. package/dist/src/tui/tui.js +31 -25
  424. package/dist/src/tui/tui.js.map +1 -1
  425. package/dist/src/utils/index.js +1 -1
  426. package/dist/src/utils/logger/index.js +1 -1
  427. package/dist/src/utils/logger/stats.d.ts +3 -3
  428. package/dist/src/utils/logger.js +1 -1
  429. package/dist/src/work-items/agent-context.d.ts +7 -0
  430. package/dist/src/work-items/agent-context.js +75 -0
  431. package/dist/src/work-items/agent-context.js.map +1 -0
  432. package/dist/src/work-items/index.d.ts +4 -0
  433. package/dist/src/work-items/index.js +4 -0
  434. package/dist/src/work-items/types.d.ts +112 -0
  435. package/dist/src/work-items/types.js +1 -0
  436. package/dist/src/work-items/work-item-service.d.ts +35 -0
  437. package/dist/src/work-items/work-item-service.js +277 -0
  438. package/dist/src/work-items/work-item-service.js.map +1 -0
  439. package/dist/src/work-items/work-item-store.d.ts +21 -0
  440. package/dist/src/work-items/work-item-store.js +302 -0
  441. package/dist/src/work-items/work-item-store.js.map +1 -0
  442. package/dist/src/workflows/draft/workflow-draft-service.js +1 -1
  443. package/dist/src/workflows/service/workflow-run-service.js +4 -3
  444. package/dist/src/workflows/service/workflow-run-service.js.map +1 -1
  445. package/dist/src/workflows/service/workflow-session-bridge.js +4 -1
  446. package/dist/src/workflows/service/workflow-session-bridge.js.map +1 -1
  447. package/package.json +5 -5
  448. package/dist/gateway/static/root/assets/Combination-HAlzriaz.js +0 -41
  449. package/dist/gateway/static/root/assets/agents-BjIxt67Z.js +0 -2
  450. package/dist/gateway/static/root/assets/app-management-settings-panel-CYCONLIL.js +0 -1
  451. package/dist/gateway/static/root/assets/appearance-settings-Clw3ryKg.js +0 -1
  452. package/dist/gateway/static/root/assets/apps-page-QICTeGjX.js +0 -1
  453. package/dist/gateway/static/root/assets/automation-suggestion-card-CU0-4nQ-.js +0 -1
  454. package/dist/gateway/static/root/assets/automations-page-Car-jtiz.js +0 -1
  455. package/dist/gateway/static/root/assets/browser-settings-page-CMeBJzlS.js +0 -8
  456. package/dist/gateway/static/root/assets/capability-presets-api-BmQTM9Il.js +0 -1
  457. package/dist/gateway/static/root/assets/capability-presets-settings-panel-DZEJEoCF.js +0 -1
  458. package/dist/gateway/static/root/assets/channels-settings-kkW-xFau.js +0 -1
  459. package/dist/gateway/static/root/assets/code-editor-dZTY2dRW.js +0 -1
  460. package/dist/gateway/static/root/assets/connectors-page-BvaQvO5F.js +0 -2
  461. package/dist/gateway/static/root/assets/dist-Mys7eFJ5.js +0 -1
  462. package/dist/gateway/static/root/assets/dist-wO9a2_ID.js +0 -1
  463. package/dist/gateway/static/root/assets/dreaming-settings-DnHO686d.js +0 -1
  464. package/dist/gateway/static/root/assets/extension-debug-page-BGLRuWVN.js +0 -1
  465. package/dist/gateway/static/root/assets/extension-page-D978ePp9.js +0 -1
  466. package/dist/gateway/static/root/assets/extension-settings-page-B6Ih4Swx.js +0 -1
  467. package/dist/gateway/static/root/assets/gateway-settings-CMEA3r5u.js +0 -1
  468. package/dist/gateway/static/root/assets/goal-create-dialog-B-KHKeXN.js +0 -1
  469. package/dist/gateway/static/root/assets/goal-detail-page-BxrSoWdj.js +0 -1
  470. package/dist/gateway/static/root/assets/goals-page-BTJzIl28.js +0 -2
  471. package/dist/gateway/static/root/assets/goals-settings-BJyEuLLm.js +0 -1
  472. package/dist/gateway/static/root/assets/heartbeat-settings-wkOjYNQT.js +0 -1
  473. package/dist/gateway/static/root/assets/index-BLaXr6Ev.css +0 -1
  474. package/dist/gateway/static/root/assets/index-c_9TVr_C.js +0 -191
  475. package/dist/gateway/static/root/assets/keyboard-shortcuts-settings-BT8T4DyC.js +0 -1
  476. package/dist/gateway/static/root/assets/logs-page-CrxBJUgI.js +0 -2
  477. package/dist/gateway/static/root/assets/markdown-split-Dv66bO2b.js +0 -1
  478. package/dist/gateway/static/root/assets/messages-O6TAtdFC.js +0 -3
  479. package/dist/gateway/static/root/assets/models-hub-panel-DOOpz6y1.js +0 -2
  480. package/dist/gateway/static/root/assets/notes-page-Br16pK9v.js +0 -1
  481. package/dist/gateway/static/root/assets/notes-workbench-PSJAi0ZC.js +0 -2
  482. package/dist/gateway/static/root/assets/project-detail-page-CIGGgKuw.js +0 -1
  483. package/dist/gateway/static/root/assets/projects-page-B2grhsBt.js +0 -1
  484. package/dist/gateway/static/root/assets/remote-access-hub-CXMORxBD.js +0 -1
  485. package/dist/gateway/static/root/assets/sessions-page-Bi2wkBzU.js +0 -1
  486. package/dist/gateway/static/root/assets/settings-advanced-gate-B1L3G4IA.js +0 -1
  487. package/dist/gateway/static/root/assets/settings-form-section-BnqYMWHR.js +0 -1
  488. package/dist/gateway/static/root/assets/settings-page-BfRSHJmO.js +0 -1
  489. package/dist/gateway/static/root/assets/settings-page-layout-CdWZU1hd.js +0 -1
  490. package/dist/gateway/static/root/assets/setup-status-panel-CWtPM7RK.js +0 -1
  491. package/dist/gateway/static/root/assets/shares-settings-ngbsBgij.js +0 -1
  492. package/dist/gateway/static/root/assets/skill-reload-api-BIe442Gv.js +0 -1
  493. package/dist/gateway/static/root/assets/skills-page-BfchZRVa.js +0 -2
  494. package/dist/gateway/static/root/assets/voice-api-key-field-C5Ov8Uk_.js +0 -1
  495. package/dist/gateway/static/root/assets/workflow-run-setup-panel-BYD9BtOq.js +0 -3
  496. package/dist/gateway/static/root/assets/workflows-page-BYF29ANm.js +0 -18
@@ -1 +1 @@
1
- {"version":3,"file":"embedded-backend.js","names":[],"sources":["../../../../src/tui/backends/embedded-backend.ts"],"sourcesContent":["import type { ExtensionRegistryImpl } from '../../extensions/loader.js';\nimport { isAbsolute, relative, resolve } from 'node:path';\nimport type { AgentService } from '../../agent/service.js';\nimport { listAgentEntries, normalizeAgentId } from '../../agent/agent-scope.js';\nimport { resolveAgentIdFromSessionKey } from '../../routing/agent-session-key.js';\nimport { parseModelRef } from '../../agent/models/selection.js';\nimport { createCreateShareTool, isShareToolAvailable } from '../../agent/tools/create-share-tool.js';\nimport { transcriptRowsToClientHistory } from '../../session/client-history.js';\nimport { prependEnvelopeTimestamp } from '../../channels/envelope-timestamp.js';\nimport { loadConfig, getWorkspacePath, saveConfig } from '../../config/index.js';\nimport { getAgentDefaultModelRef, type Config } from '../../config/schema.js';\nimport { setTuiDefaultAgentConfig } from '../../commands/agents.config.js';\nimport { MessageBus, MessageBusShutdownError } from '../../infra/bus/index.js';\nimport { evictEmbeddedSessionRunner } from '../../agent/embedded/session-runner.js';\nimport { buildReviewContext, resolveGitRoot } from '../../review/review-git.js';\nimport { effectiveWorkspacePathForSession } from '../../session/session-workspace.js';\nimport type { ExportFormat } from '../../session/types.js';\nimport { SessionIndex } from '../../session/index.js';\nimport { getSessionMetadata, openXopcDatabase } from '../../storage/sqlite/index.js';\nimport { buildWorkflowChildTools } from '../../agent/workflow/workflow-child-tools.js';\nimport type { GatewayWorkflowHost } from '../../gateway/gateway-workflow-host.types.js';\nimport { WorkflowRunService } from '../../workflows/service/workflow-run-service.js';\nimport { WorkflowSessionBridge } from '../../workflows/service/workflow-session-bridge.js';\nimport { createLogger } from '../../utils/logger.js';\nimport type {\n ChatSendOptions,\n HistoryMessage,\n TuiBackend,\n TuiCompactionResult,\n TuiEvent,\n TuiModelChoice,\n TuiShareRequest,\n TuiShareResult,\n TuiSessionStats,\n TuiSessionItem,\n TuiTranscriptTreeEntry,\n TuiAgentInfo,\n TuiWorkspaceFileSearchEntry,\n TuiWorkflowRunStartRequest,\n TuiWorkflowRunStartResult,\n TuiStartupProjectResult,\n} from '../tui-backend.js';\nimport type { SessionInfo } from '../tui-types.js';\nimport { sessionMetadataToTuiItem } from '../tui-session-format.js';\nimport { computeTuiSessionStats } from '../tui-session-stats.js';\nimport { buildTuiTranscriptTree, transcriptTreeEntryIdToRowNumber } from '../tui-transcript-tree.js';\nimport { ChatStreamMapper } from '../../gateway/chat-stream/mapper.js';\nimport { collectTuiStartupResources } from '../tui-startup-resources.js';\nimport { fuzzySearchWorkspaceFiles } from '../../gateway/workspace-file-search.js';\nimport { inferSuggestedProjectDefaultAgentId, ProjectService } from '../../projects/index.js';\n\nconst log = createLogger('TUI:Embedded');\n\ninterface EmbeddedBackendOptions {\n config?: Config;\n extensionRegistry?: ExtensionRegistryImpl;\n implicitTrustedWorkspace?: string;\n isWorkspaceTrusted?: (workspaceDir: string) => boolean | null | undefined;\n}\n\nfunction isPathSameOrInside(parentDir: string, childDir: string): boolean {\n const rel = relative(resolve(parentDir), resolve(childDir));\n return rel === '' || (!!rel && !rel.startsWith('..') && !isAbsolute(rel));\n}\n\n/**\n * TUI backend that runs the agent in-process (no gateway required).\n *\n * Wraps `AgentService` directly and emits TuiEvents by observing the\n * `MessageBus` output stream.\n */\nexport class EmbeddedBackend implements TuiBackend {\n private bus: MessageBus;\n private agent: AgentService | null = null;\n private agentLoading: Promise<AgentService> | null = null;\n private config: Config | null = null;\n private workspace = '';\n private sessionIndex: SessionIndex | null = null;\n private sessionIndexReady: Promise<void> | null = null;\n private workflowRunService: WorkflowRunService | null = null;\n private running = false;\n private chatAbort: AbortController | null = null;\n\n onEvent?: (evt: TuiEvent) => void;\n onConnected?: () => void;\n onDisconnected?: (reason: string) => void;\n\n constructor(private readonly opts?: EmbeddedBackendOptions) {\n this.bus = new MessageBus();\n }\n\n get connectionLabel(): string {\n return 'local embedded';\n }\n\n start(): void {\n if (this.running) return;\n this.running = true;\n\n const config = this.opts?.config ?? loadConfig();\n this.config = config;\n const workspace = getWorkspacePath(config);\n this.workspace = workspace;\n openXopcDatabase();\n this.sessionIndex = new SessionIndex({ config });\n this.sessionIndexReady = this.sessionIndex.initialize().catch((err: unknown) => {\n const errorMessage = err instanceof Error ? err.message : String(err);\n log.warn({ err, errorMessage }, `Embedded session index initialization failed: ${errorMessage}`);\n throw err;\n });\n\n this.onConnected?.();\n setTimeout(() => {\n void this.ensureAgent().catch((err) => {\n const errorMessage = err instanceof Error ? err.message : String(err);\n log.error({ err, errorMessage }, `Embedded agent failed: ${errorMessage}`);\n this.onDisconnected?.(errorMessage);\n });\n }, 750);\n\n // Process outbound messages in background\n this.processOutbound();\n }\n\n private async ensureAgent(): Promise<AgentService> {\n if (this.agent) {\n return this.agent;\n }\n if (this.agentLoading) {\n return this.agentLoading;\n }\n if (!this.config || !this.sessionIndex) {\n throw new Error('Embedded backend not started');\n }\n\n this.agentLoading = this.createAgent(this.config, this.sessionIndex);\n try {\n return await this.agentLoading;\n } finally {\n this.agentLoading = null;\n }\n }\n\n private async createAgent(config: Config, sessionIndex: SessionIndex): Promise<AgentService> {\n const { AgentService } = await import('../../agent/service.js');\n const workspace = this.workspace || getWorkspacePath(config);\n const modelId = getAgentDefaultModelRef(config);\n const agent = new AgentService(this.bus, {\n workspace,\n model: modelId,\n config,\n sessionStore: sessionIndex.getStore(),\n getWorkflowRunService: () => this.getWorkflowRunService(),\n extensionRegistry: this.opts?.extensionRegistry,\n isWorkspaceTrusted: (workspaceDir) => {\n const explicit = this.opts?.isWorkspaceTrusted?.(workspaceDir);\n if (explicit !== undefined && explicit !== null) {\n return explicit;\n }\n const implicit = this.opts?.implicitTrustedWorkspace;\n if (implicit && isPathSameOrInside(implicit, workspaceDir)) {\n return true;\n }\n return undefined;\n },\n });\n this.agent = agent;\n await agent.start();\n return agent;\n }\n\n stop(): void {\n this.running = false;\n this.chatAbort?.abort();\n this.chatAbort = null;\n this.bus.shutdown();\n void this.agent?.stop();\n this.agent = null;\n }\n\n getActiveSignal(): AbortSignal | undefined {\n const signal = this.chatAbort?.signal;\n return signal && !signal.aborted ? signal : undefined;\n }\n\n private getWorkflowRunService(): WorkflowRunService {\n if (this.workflowRunService) return this.workflowRunService;\n if (!this.config || !this.sessionIndex || !this.agent) {\n throw new Error('Embedded workflow runtime is not ready.');\n }\n\n const host: GatewayWorkflowHost = {\n currentConfig: this.config,\n currentWorkspacePath: this.workspace,\n messageBusInstance: this.bus,\n agentService: {\n getModelForSession: (sessionKey) => this.agent!.getModelForSession(sessionKey),\n },\n sessionIndexInstance: this.sessionIndex,\n emit: (event, payload) => {\n this.onEvent?.({\n event,\n data: payload,\n source: 'broadcast',\n });\n },\n };\n\n this.workflowRunService = new WorkflowRunService({\n service: host,\n sessionBridge: new WorkflowSessionBridge(host),\n buildChildTools: buildWorkflowChildTools,\n });\n return this.workflowRunService;\n }\n\n private activeConfig(): Config {\n return this.config ?? this.opts?.config ?? loadConfig();\n }\n\n async getStartupResources(sessionKey: string) {\n return collectTuiStartupResources(this.activeConfig(), sessionKey);\n }\n\n async startWorkflowRun(opts: TuiWorkflowRunStartRequest): Promise<TuiWorkflowRunStartResult> {\n await this.sessionIndexReady;\n const agentId = opts.agentId?.trim() || resolveAgentIdFromSessionKey(opts.sessionKey);\n const result = await this.getWorkflowRunService().startWorkflowRun({\n agentId,\n definitionId: opts.definitionId,\n parentSessionKey: opts.sessionKey,\n source: { kind: 'chat', sessionKey: opts.sessionKey },\n goal: opts.goal,\n input: opts.input,\n });\n if (result.ok === false) {\n throw new Error(result.message);\n }\n return {\n runId: result.runId,\n sessionKey: result.sessionKey,\n definitionId: opts.definitionId,\n };\n }\n\n async resolveStartupProject(opts: {\n workspacePath: string;\n sessionKey: string;\n agentId: string;\n autoCreate?: boolean;\n }): Promise<TuiStartupProjectResult> {\n await this.sessionIndexReady;\n if (!this.sessionIndex) return { project: null };\n const projects = new ProjectService();\n const defaultAgentId = inferSuggestedProjectDefaultAgentId({\n config: this.activeConfig(),\n workspaceRoot: opts.workspacePath,\n });\n const match = projects.resolveOrCreateForWorkspacePath({\n workspacePath: opts.workspacePath,\n agentId: opts.agentId,\n defaultAgentId,\n autoCreate: opts.autoCreate !== false,\n });\n if (!match) return { project: null };\n const projectAgentId = match.project.defaultAgentId?.trim()\n ? normalizeAgentId(match.project.defaultAgentId)\n : undefined;\n if (projectAgentId && projectAgentId !== normalizeAgentId(opts.agentId)) {\n return { project: match.project, created: match.created, reason: match.reason };\n }\n if (!getSessionMetadata(opts.sessionKey)) {\n await this.sessionIndex.getStore().resolveTranscriptPath(opts.sessionKey, {\n metadata: {\n sourceChannel: 'tui',\n sourceChatId: `default:direct:${opts.sessionKey}`,\n sessionType: 'chat',\n projectId: match.project.id,\n routing: {\n agentId: opts.agentId,\n source: 'tui',\n accountId: 'default',\n peerKind: 'direct',\n peerId: opts.sessionKey,\n },\n },\n });\n }\n projects.attachSession(opts.sessionKey, match.project.id);\n return { project: match.project, created: match.created, reason: match.reason };\n }\n\n async searchWorkspaceFiles(\n sessionKey: string,\n query: string,\n options?: { limit?: number },\n ): Promise<TuiWorkspaceFileSearchEntry[]> {\n if (!this.agent) return [];\n try {\n const workspaceRoot = await this.agent.getEffectiveWorkspacePathForSession(sessionKey);\n return await fuzzySearchWorkspaceFiles(workspaceRoot, query, options?.limit ?? 15);\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n log.warn({ err: error, sessionKey, errorMessage }, `Embedded workspace file search failed: ${errorMessage}`);\n return [];\n }\n }\n\n async getReviewContext(sessionKey: string) {\n const config = this.activeConfig();\n const metadata = getSessionMetadata(sessionKey);\n const project = metadata?.projectId ? new ProjectService().get(metadata.projectId) : null;\n const workspace = effectiveWorkspacePathForSession(config, sessionKey, null, project);\n const cwd = await resolveGitRoot(workspace);\n return buildReviewContext(cwd);\n }\n\n async sendChat(opts: ChatSendOptions): Promise<{ runId: string }> {\n const agent = await this.ensureAgent();\n\n const runId = crypto.randomUUID();\n this.chatAbort?.abort();\n this.chatAbort = new AbortController();\n const signal = this.chatAbort.signal;\n\n const mapper = new ChatStreamMapper({ runId, sessionKey: opts.sessionKey, channel: 'tui' });\n for (const event of mapper.start()) {\n this.onEvent?.({ event: event.type, data: event, source: 'embedded' });\n }\n\n // Run the stream in background so the TUI event loop stays responsive.\n void (async () => {\n try {\n // Prepend envelope timestamp so the model knows the current date/time,\n // matching the behavior of channel pipelines (Telegram, Weixin, etc.).\n // Skip for slash commands — parseSlashCommand requires lines starting with '/'.\n const messageForAgent = opts.message.trimStart().startsWith('/')\n ? opts.message\n : prependEnvelopeTimestamp(opts.message);\n\n const stream = agent.turnDispatcher.processDirectStreaming(\n messageForAgent,\n opts.sessionKey,\n opts.attachments,\n opts.thinking,\n { signal, runId },\n );\n\n for await (const event of stream) {\n if (signal.aborted) break;\n for (const mapped of mapper.map(event)) {\n this.onEvent?.({ event: mapped.type, data: mapped, source: 'embedded' });\n }\n }\n\n if (!signal.aborted) {\n for (const mapped of mapper.end('success')) {\n this.onEvent?.({ event: mapped.type, data: mapped, source: 'embedded' });\n }\n }\n } catch (error) {\n if (signal.aborted) return;\n const errorMessage = error instanceof Error ? error.message : String(error);\n for (const mapped of mapper.error(errorMessage)) {\n this.onEvent?.({ event: mapped.type, data: mapped, source: 'embedded' });\n }\n for (const mapped of mapper.end('error', errorMessage)) {\n this.onEvent?.({ event: mapped.type, data: mapped, source: 'embedded' });\n }\n }\n })();\n\n return { runId };\n }\n\n async abortChat(_opts: { sessionKey: string; runId: string }): Promise<{ ok: boolean }> {\n if (this.chatAbort) {\n this.chatAbort.abort();\n this.chatAbort = null;\n return { ok: true };\n }\n return { ok: false };\n }\n\n async steerChat(opts: { sessionKey: string; message: string }): Promise<{ ok: boolean }> {\n if (!this.agent) return { ok: false };\n const ok = await this.agent.turnDispatcher.steerWebchatSession(opts.sessionKey, opts.message);\n return { ok };\n }\n\n async loadHistory(opts: {\n sessionKey: string;\n limit?: number;\n }): Promise<{ messages: HistoryMessage[] }> {\n if (!this.agent) {\n return { messages: [] };\n }\n try {\n const rows = await this.agent.sessionStore.loadTranscriptRows(opts.sessionKey);\n return {\n messages: transcriptRowsToClientHistory(rows, { limit: opts.limit }),\n };\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n log.warn({ err: error, errorMessage }, `Embedded loadHistory failed: ${errorMessage}`);\n return { messages: [] };\n }\n }\n\n async loadTranscriptTree(sessionKey: string): Promise<TuiTranscriptTreeEntry[]> {\n if (!this.agent) return [];\n try {\n const rows = await this.agent.sessionStore.loadTranscriptRows(sessionKey);\n return buildTuiTranscriptTree(rows);\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n log.warn({ err: error, sessionKey, errorMessage }, `Embedded loadTranscriptTree failed: ${errorMessage}`);\n return [];\n }\n }\n\n async getSessionStats(sessionKey: string): Promise<TuiSessionStats> {\n if (!this.agent) return computeTuiSessionStats([]);\n try {\n const rows = await this.agent.sessionStore.loadTranscriptRows(sessionKey);\n return computeTuiSessionStats(rows);\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n log.warn({ err: error, sessionKey, errorMessage }, `Embedded getSessionStats failed: ${errorMessage}`);\n return computeTuiSessionStats([]);\n }\n }\n\n async listSessions(): Promise<TuiSessionItem[]> {\n if (!this.agent) return [];\n try {\n const result = await this.agent.sessionStore.list({\n limit: 200,\n sortBy: 'updatedAt',\n sortOrder: 'desc',\n });\n return result.items.map(sessionMetadataToTuiItem);\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n log.warn({ err: error, errorMessage }, `Embedded listSessions failed: ${errorMessage}`);\n return [];\n }\n }\n\n async listAgents(): Promise<TuiAgentInfo[]> {\n const config = this.activeConfig();\n const agents = new Map<string, TuiAgentInfo>();\n for (const entry of listAgentEntries(config)) {\n if (entry.enabled === false) continue;\n const id = normalizeAgentId(entry.id);\n agents.set(id, {\n id,\n enabled: true,\n });\n }\n return [...agents.values()].sort((a, b) => a.id.localeCompare(b.id));\n }\n\n async setTuiDefaultAgent(agentId: string): Promise<{ agentId: string }> {\n const result = setTuiDefaultAgentConfig(this.activeConfig(), agentId);\n if (result.ok === false) {\n throw new Error(result.message);\n }\n await saveConfig(result.config);\n this.config = result.config;\n return { agentId: result.agentId };\n }\n\n async renameSession(sessionKey: string, name: string): Promise<{ ok: boolean }> {\n if (!this.agent) return { ok: false };\n try {\n await this.agent.sessionStore.updateMetadata(sessionKey, { name: name.trim() });\n return { ok: true };\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n log.warn({ err: error, sessionKey, errorMessage }, `Embedded renameSession failed: ${errorMessage}`);\n return { ok: false };\n }\n }\n\n async deleteSession(sessionKey: string): Promise<{ ok: boolean }> {\n if (!this.agent) return { ok: false };\n try {\n const ok = await this.agent.sessionStore.deleteSession(sessionKey);\n return { ok };\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n log.warn({ err: error, sessionKey, errorMessage }, `Embedded deleteSession failed: ${errorMessage}`);\n return { ok: false };\n }\n }\n\n async getSessionInfo(sessionKey: string): Promise<SessionInfo> {\n if (!this.agent) {\n const config = this.activeConfig();\n const model = getAgentDefaultModelRef(config);\n return { model: model ?? undefined };\n }\n try {\n const cfg = await this.agent.sessionInspector.agentConfig(sessionKey);\n const parsed = parseModelRef(cfg.model);\n const usage = await this.agent.sessionInspector.contextUsage(sessionKey);\n return {\n model: parsed?.model ?? cfg.model,\n modelProvider: parsed?.provider,\n thinkingLevel: cfg.thinkingLevel,\n reasoningLevel: cfg.reasoningLevel,\n verboseLevel: cfg.verboseLevel,\n totalTokens: usage.estimatedTokens,\n contextWindow: usage.contextWindow,\n contextUsagePercent: usage.usagePercent,\n effectiveWorkspacePath: cfg.effectiveWorkspacePath,\n workingDirectoryLocked: cfg.workingDirectoryLocked,\n };\n } catch (err) {\n const errorMessage = err instanceof Error ? err.message : String(err);\n log.warn({ err, sessionKey, errorMessage }, `getSessionInfo failed: ${errorMessage}`);\n const config = this.activeConfig();\n const model = getAgentDefaultModelRef(config);\n return { model: model ?? undefined };\n }\n }\n\n async listModels(): Promise<TuiModelChoice[]> {\n const { getAvailableModels } = await import('../../providers/index.js');\n const models = await getAvailableModels();\n return models.map((model) => ({\n id: model.id,\n name: model.name ?? model.id,\n provider: model.provider,\n contextWindow: model.contextWindow,\n }));\n }\n\n async resetSession(sessionKey: string): Promise<void> {\n if (!this.agent) return;\n await this.agent.resetSession(sessionKey);\n }\n\n async patchSession(\n sessionKey: string,\n patch: Record<string, unknown>,\n ): Promise<void> {\n const agent = await this.ensureAgent();\n const projectId = typeof patch.projectId === 'string' ? patch.projectId.trim() : '';\n if (projectId) {\n await this.sessionIndexReady;\n await this.sessionIndex?.getStore().resolveTranscriptPath(sessionKey);\n new ProjectService().attachSession(sessionKey, projectId);\n }\n const result = await agent.sessionConfig.patch(sessionKey, {\n model: typeof patch.model === 'string' ? patch.model : undefined,\n thinkingLevel: typeof patch.thinkingLevel === 'string' ? patch.thinkingLevel : undefined,\n reasoningLevel: typeof patch.reasoningLevel === 'string' ? patch.reasoningLevel : undefined,\n verboseLevel: typeof patch.verboseLevel === 'string' ? patch.verboseLevel : undefined,\n workingDirectory: typeof patch.workingDirectory === 'string' ? patch.workingDirectory : undefined,\n });\n if (!result.ok) {\n throw new Error(result.error);\n }\n }\n\n async compactSession(\n sessionKey: string,\n options?: { force?: boolean; instructions?: string },\n ): Promise<TuiCompactionResult> {\n if (!this.agent) return { compacted: false, summary: 'Agent not started' };\n try {\n const result = await this.agent.sessionInspector.compact(sessionKey, {\n force: options?.force ?? true,\n instructions: options?.instructions,\n });\n if (!result.compacted) return { compacted: false, summary: 'Nothing to compact' };\n return {\n compacted: true,\n summary: `Compacted (${result.tokensBefore ?? '?'} → ${result.tokensAfter ?? '?'} tokens)`,\n tokensBefore: result.tokensBefore,\n tokensAfter: result.tokensAfter,\n transcriptSummary: result.summary,\n };\n } catch (err) {\n const errorMessage = err instanceof Error ? err.message : String(err);\n return { compacted: false, summary: errorMessage };\n }\n }\n\n async exportSession(sessionKey: string, format: ExportFormat): Promise<string> {\n if (!this.agent) {\n throw new Error('Agent not started');\n }\n return this.agent.sessionStore.exportSession(sessionKey, format);\n }\n\n async importSession(\n targetSessionKey: string,\n jsonContent: string,\n ): Promise<{ sessionKey: string; rowCount: number }> {\n if (!this.agent) {\n throw new Error('Agent not started');\n }\n return this.agent.sessionStore.importSessionExport(targetSessionKey, jsonContent);\n }\n\n async createShare(\n _sessionKey: string,\n request: TuiShareRequest,\n _options?: { agentId?: string },\n ): Promise<TuiShareResult> {\n if (!this.agent) {\n throw new Error('Agent not started');\n }\n const config = this.activeConfig();\n if (!isShareToolAvailable(config)) {\n throw new Error('Sharing is disabled in gateway config');\n }\n const workspace = getWorkspacePath(config);\n const tool = createCreateShareTool({\n workspace,\n getConfig: () => config,\n getAgentId: () => 'tui',\n });\n const result = await tool.execute(\n 'tui-share',\n {\n filePath: request.path,\n audience: request.audience,\n mode: request.mode,\n title: request.title,\n description: request.description,\n },\n );\n const details = (result.details ?? {}) as Record<string, unknown>;\n const error = typeof details.error === 'string' ? details.error : undefined;\n if (error) {\n throw new Error(error);\n }\n const shareUrl = typeof details.shareUrl === 'string' ? details.shareUrl : undefined;\n if (!shareUrl) {\n const text = result.content\n .map((part) => (part.type === 'text' ? part.text : ''))\n .join('\\n')\n .trim();\n throw new Error(text || 'Share failed');\n }\n return {\n kind: typeof details.kind === 'string' ? details.kind : 'share',\n shareUrl,\n title: typeof details.title === 'string' ? details.title : undefined,\n description: typeof details.description === 'string' ? details.description : undefined,\n thumbnailUrl: typeof details.thumbnailUrl === 'string' ? details.thumbnailUrl : undefined,\n reachability: typeof details.reachability === 'string' ? details.reachability : undefined,\n reachabilityHint:\n typeof details.reachabilityHint === 'string' ? details.reachabilityHint : undefined,\n expiresAt: typeof details.expiresAt === 'string' ? details.expiresAt : undefined,\n maxViews: typeof details.maxViews === 'number' ? details.maxViews : null,\n routingReason:\n typeof (details.routing as { reason?: unknown } | undefined)?.reason === 'string'\n ? ((details.routing as { reason: string }).reason)\n : undefined,\n routingHint:\n typeof (details.routing as { hint?: unknown } | undefined)?.hint === 'string'\n ? ((details.routing as { hint: string }).hint)\n : undefined,\n };\n }\n\n async btwQuery(sessionKey: string, question: string): Promise<{ text: string; error?: string }> {\n if (!this.agent) {\n return { text: '', error: 'Agent not started' };\n }\n return this.agent.sessionInspector.btwQuery(sessionKey, question);\n }\n\n async forkSession(\n sourceSessionKey: string,\n targetSessionKey: string,\n ): Promise<{ sessionKey: string; rowCount: number }> {\n if (!this.agent) {\n throw new Error('Agent not started');\n }\n return this.agent.sessionStore.forkSession(sourceSessionKey, targetSessionKey);\n }\n\n async forkSessionAt(\n sourceSessionKey: string,\n targetSessionKey: string,\n entryId: string,\n ): Promise<{ sessionKey: string; rowCount: number }> {\n if (!this.agent) {\n throw new Error('Agent not started');\n }\n const throughRow = transcriptTreeEntryIdToRowNumber(entryId);\n if (throughRow == null) {\n throw new Error(`Invalid transcript entry: ${entryId}`);\n }\n return this.agent.sessionStore.forkSessionRows(sourceSessionKey, targetSessionKey, { throughRow });\n }\n\n async setTranscriptLabel(\n sessionKey: string,\n entryId: string,\n label: string | undefined,\n ): Promise<{ ok: boolean }> {\n if (!this.agent) {\n throw new Error('Agent not started');\n }\n await this.agent.sessionStore.appendTranscriptLabelEntry(sessionKey, { targetId: entryId, label });\n return { ok: true };\n }\n\n async appendCustomEntry(\n sessionKey: string,\n customType: string,\n data?: unknown,\n ): Promise<{ ok: boolean }> {\n if (!this.agent) {\n throw new Error('Agent not started');\n }\n await this.agent.sessionStore.appendTranscriptCustomEntry(sessionKey, { customType, data });\n return { ok: true };\n }\n\n async appendCustomMessage(\n sessionKey: string,\n message: {\n customType: string;\n content?: string | unknown[];\n display?: boolean;\n details?: unknown;\n },\n ): Promise<{ ok: boolean }> {\n if (!this.agent) {\n throw new Error('Agent not started');\n }\n await this.agent.sessionStore.appendTranscriptCustomMessageEntry(sessionKey, message);\n evictEmbeddedSessionRunner(sessionKey, 'tui_custom_message_appended');\n return { ok: true };\n }\n\n async appendBashExecution(\n sessionKey: string,\n entry: {\n command: string;\n output?: string;\n exitCode?: number | null;\n signal?: string | null;\n excludeFromContext?: boolean;\n truncated?: boolean;\n fullOutputPath?: string;\n },\n ): Promise<{ ok: boolean }> {\n if (!this.agent) {\n throw new Error('Agent not started');\n }\n await this.agent.sessionStore.appendTranscriptBashExecutionEntry(sessionKey, entry);\n evictEmbeddedSessionRunner(sessionKey, 'tui_bash_execution_appended');\n return { ok: true };\n }\n\n private processOutbound(): void {\n void (async () => {\n while (this.running) {\n try {\n const msg = await this.bus.consumeOutbound();\n log.debug({ channel: msg.channel, chatId: msg.chat_id }, 'Outbound message');\n } catch (error) {\n if (error instanceof MessageBusShutdownError) break;\n const errorMessage = error instanceof Error ? error.message : String(error);\n log.warn({ err: error, errorMessage }, `Outbound processor failed: ${errorMessage}`);\n await new Promise((resolve) => setTimeout(resolve, 1000));\n }\n }\n })();\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"embedded-backend.js","names":[],"sources":["../../../../src/tui/backends/embedded-backend.ts"],"sourcesContent":["import type { ExtensionRegistryImpl } from '../../extensions/loader.js';\nimport { isAbsolute, relative, resolve } from 'node:path';\nimport type { AgentService } from '../../agent/service.js';\nimport { listAgentEntries, normalizeAgentId } from '../../agent/agent-scope.js';\nimport { resolveAgentIdFromSessionKey } from '../../routing/agent-session-key.js';\nimport { parseModelRef } from '../../agent/models/selection.js';\nimport { createCreateShareTool, isShareToolAvailable } from '../../agent/tools/create-share-tool.js';\nimport { transcriptRowsToClientHistory } from '../../session/client-history.js';\nimport { buildSessionTimeline, type SessionTimelineItem } from '../../session/transcript-outline.js';\nimport { prependEnvelopeTimestamp } from '../../channels/envelope-timestamp.js';\nimport { loadConfig, getWorkspacePath, saveConfig } from '../../config/index.js';\nimport { getAgentDefaultModelRef, type Config } from '../../config/schema.js';\nimport { setTuiDefaultAgentConfig } from '../../commands/agents.config.js';\nimport { MessageBus, MessageBusShutdownError } from '../../infra/bus/index.js';\nimport { evictEmbeddedSessionRunner } from '../../agent/embedded/session-runner.js';\nimport { buildReviewContext, resolveGitRoot } from '../../review/review-git.js';\nimport { effectiveWorkspacePathForSession } from '../../session/session-workspace.js';\nimport type { ExportFormat } from '../../session/types.js';\nimport { SessionIndex } from '../../session/index.js';\nimport { getSessionMetadata, openXopcDatabase } from '../../storage/sqlite/index.js';\nimport { buildWorkflowChildTools } from '../../agent/workflow/workflow-child-tools.js';\nimport type { GatewayWorkflowHost } from '../../gateway/gateway-workflow-host.types.js';\nimport { WorkflowRunService } from '../../workflows/service/workflow-run-service.js';\nimport { WorkflowSessionBridge } from '../../workflows/service/workflow-session-bridge.js';\nimport { createLogger } from '../../utils/logger.js';\nimport type {\n ChatSendOptions,\n HistoryMessage,\n TuiBackend,\n TuiCompactionResult,\n TuiEvent,\n TuiModelChoice,\n TuiShareRequest,\n TuiShareResult,\n TuiSessionStats,\n TuiSessionItem,\n TuiTranscriptTreeEntry,\n TuiAgentInfo,\n TuiWorkspaceFileSearchEntry,\n TuiWorkflowRunStartRequest,\n TuiWorkflowRunStartResult,\n TuiStartupProjectResult,\n} from '../tui-backend.js';\nimport type { SessionInfo } from '../tui-types.js';\nimport { sessionMetadataToTuiItem } from '../tui-session-format.js';\nimport { computeTuiSessionStats } from '../tui-session-stats.js';\nimport { buildTuiTranscriptTree, transcriptTreeEntryIdToRowNumber } from '../tui-transcript-tree.js';\nimport { ChatStreamMapper } from '../../gateway/chat-stream/mapper.js';\nimport { collectTuiStartupResources } from '../tui-startup-resources.js';\nimport { fuzzySearchWorkspaceFiles } from '../../gateway/workspace-file-search.js';\nimport { inferSuggestedProjectDefaultAgentId, ProjectService } from '../../projects/index.js';\n\nconst log = createLogger('TUI:Embedded');\n\nfunction clampHistoryWindowSpan(value: number | undefined, fallback: number): number {\n const parsed = Math.trunc(value ?? fallback);\n if (!Number.isFinite(parsed)) return fallback;\n return Math.min(200, Math.max(0, parsed));\n}\n\ninterface EmbeddedBackendOptions {\n config?: Config;\n extensionRegistry?: ExtensionRegistryImpl;\n implicitTrustedWorkspace?: string;\n isWorkspaceTrusted?: (workspaceDir: string) => boolean | null | undefined;\n}\n\nfunction isPathSameOrInside(parentDir: string, childDir: string): boolean {\n const rel = relative(resolve(parentDir), resolve(childDir));\n return rel === '' || (!!rel && !rel.startsWith('..') && !isAbsolute(rel));\n}\n\n/**\n * TUI backend that runs the agent in-process (no gateway required).\n *\n * Wraps `AgentService` directly and emits TuiEvents by observing the\n * `MessageBus` output stream.\n */\nexport class EmbeddedBackend implements TuiBackend {\n private bus: MessageBus;\n private agent: AgentService | null = null;\n private agentLoading: Promise<AgentService> | null = null;\n private config: Config | null = null;\n private workspace = '';\n private sessionIndex: SessionIndex | null = null;\n private sessionIndexReady: Promise<void> | null = null;\n private workflowRunService: WorkflowRunService | null = null;\n private running = false;\n private chatAbort: AbortController | null = null;\n\n onEvent?: (evt: TuiEvent) => void;\n onConnected?: () => void;\n onDisconnected?: (reason: string) => void;\n\n constructor(private readonly opts?: EmbeddedBackendOptions) {\n this.bus = new MessageBus();\n }\n\n get connectionLabel(): string {\n return 'local embedded';\n }\n\n start(): void {\n if (this.running) return;\n this.running = true;\n\n const config = this.opts?.config ?? loadConfig();\n this.config = config;\n const workspace = getWorkspacePath(config);\n this.workspace = workspace;\n openXopcDatabase();\n this.sessionIndex = new SessionIndex({ config });\n this.sessionIndexReady = this.sessionIndex.initialize().catch((err: unknown) => {\n const errorMessage = err instanceof Error ? err.message : String(err);\n log.warn({ err, errorMessage }, `Embedded session index initialization failed: ${errorMessage}`);\n throw err;\n });\n\n this.onConnected?.();\n setTimeout(() => {\n void this.ensureAgent().catch((err) => {\n const errorMessage = err instanceof Error ? err.message : String(err);\n log.error({ err, errorMessage }, `Embedded agent failed: ${errorMessage}`);\n this.onDisconnected?.(errorMessage);\n });\n }, 750);\n\n // Process outbound messages in background\n this.processOutbound();\n }\n\n private async ensureAgent(): Promise<AgentService> {\n if (this.agent) {\n return this.agent;\n }\n if (this.agentLoading) {\n return this.agentLoading;\n }\n if (!this.config || !this.sessionIndex) {\n if (!this.running) {\n this.start();\n }\n }\n if (!this.config || !this.sessionIndex) {\n throw new Error('Embedded backend not started');\n }\n\n this.agentLoading = this.createAgent(this.config, this.sessionIndex);\n try {\n return await this.agentLoading;\n } finally {\n this.agentLoading = null;\n }\n }\n\n private async createAgent(config: Config, sessionIndex: SessionIndex): Promise<AgentService> {\n const { AgentService } = await import('../../agent/service.js');\n const workspace = this.workspace || getWorkspacePath(config);\n const modelId = getAgentDefaultModelRef(config);\n const agent = new AgentService(this.bus, {\n workspace,\n model: modelId,\n config,\n sessionStore: sessionIndex.getStore(),\n getWorkflowRunService: () => this.getWorkflowRunService(),\n extensionRegistry: this.opts?.extensionRegistry,\n isWorkspaceTrusted: (workspaceDir) => {\n const explicit = this.opts?.isWorkspaceTrusted?.(workspaceDir);\n if (explicit !== undefined && explicit !== null) {\n return explicit;\n }\n const implicit = this.opts?.implicitTrustedWorkspace;\n if (implicit && isPathSameOrInside(implicit, workspaceDir)) {\n return true;\n }\n return undefined;\n },\n });\n this.agent = agent;\n await agent.start();\n return agent;\n }\n\n stop(): void {\n this.running = false;\n this.chatAbort?.abort();\n this.chatAbort = null;\n this.bus.shutdown();\n void this.agent?.stop();\n this.agent = null;\n }\n\n getActiveSignal(): AbortSignal | undefined {\n const signal = this.chatAbort?.signal;\n return signal && !signal.aborted ? signal : undefined;\n }\n\n private getWorkflowRunService(): WorkflowRunService {\n if (this.workflowRunService) return this.workflowRunService;\n if (!this.config || !this.sessionIndex || !this.agent) {\n throw new Error('Embedded workflow runtime is not ready.');\n }\n\n const host: GatewayWorkflowHost = {\n currentConfig: this.config,\n currentWorkspacePath: this.workspace,\n messageBusInstance: this.bus,\n agentService: {\n getModelForSession: (sessionKey) => this.agent!.getModelForSession(sessionKey),\n },\n sessionIndexInstance: this.sessionIndex,\n emit: (event, payload) => {\n this.onEvent?.({\n event,\n data: payload,\n source: 'broadcast',\n });\n },\n };\n\n this.workflowRunService = new WorkflowRunService({\n service: host,\n sessionBridge: new WorkflowSessionBridge(host),\n buildChildTools: buildWorkflowChildTools,\n });\n return this.workflowRunService;\n }\n\n private activeConfig(): Config {\n return this.config ?? this.opts?.config ?? loadConfig();\n }\n\n async getStartupResources(sessionKey: string) {\n return collectTuiStartupResources(this.activeConfig(), sessionKey);\n }\n\n async startWorkflowRun(opts: TuiWorkflowRunStartRequest): Promise<TuiWorkflowRunStartResult> {\n await this.sessionIndexReady;\n const agentId = opts.agentId?.trim() || resolveAgentIdFromSessionKey(opts.sessionKey);\n const result = await this.getWorkflowRunService().startWorkflowRun({\n agentId,\n definitionId: opts.definitionId,\n parentSessionKey: opts.sessionKey,\n source: { kind: 'chat', sessionKey: opts.sessionKey },\n goal: opts.goal,\n input: opts.input,\n });\n if (result.ok === false) {\n throw new Error(result.message);\n }\n return {\n runId: result.runId,\n sessionKey: result.sessionKey,\n definitionId: opts.definitionId,\n };\n }\n\n async resolveStartupProject(opts: {\n workspacePath: string;\n sessionKey: string;\n agentId: string;\n autoCreate?: boolean;\n }): Promise<TuiStartupProjectResult> {\n await this.sessionIndexReady;\n if (!this.sessionIndex) return { project: null };\n const projects = new ProjectService();\n const defaultAgentId = inferSuggestedProjectDefaultAgentId({\n config: this.activeConfig(),\n workspaceRoot: opts.workspacePath,\n });\n const match = projects.resolveOrCreateForWorkspacePath({\n workspacePath: opts.workspacePath,\n agentId: opts.agentId,\n defaultAgentId,\n autoCreate: opts.autoCreate !== false,\n });\n if (!match) return { project: null };\n const projectAgentId = match.project.defaultAgentId?.trim()\n ? normalizeAgentId(match.project.defaultAgentId)\n : undefined;\n if (projectAgentId && projectAgentId !== normalizeAgentId(opts.agentId)) {\n return { project: match.project, created: match.created, reason: match.reason };\n }\n if (!getSessionMetadata(opts.sessionKey)) {\n await this.sessionIndex.getStore().resolveTranscriptPath(opts.sessionKey, {\n metadata: {\n sourceChannel: 'tui',\n sourceChatId: `default:direct:${opts.sessionKey}`,\n sessionType: 'chat',\n projectId: match.project.id,\n routing: {\n agentId: opts.agentId,\n source: 'tui',\n accountId: 'default',\n peerKind: 'direct',\n peerId: opts.sessionKey,\n },\n },\n });\n }\n projects.attachSession(opts.sessionKey, match.project.id);\n return { project: match.project, created: match.created, reason: match.reason };\n }\n\n async searchWorkspaceFiles(\n sessionKey: string,\n query: string,\n options?: { limit?: number },\n ): Promise<TuiWorkspaceFileSearchEntry[]> {\n if (!this.agent) return [];\n try {\n const workspaceRoot = await this.agent.getEffectiveWorkspacePathForSession(sessionKey);\n return await fuzzySearchWorkspaceFiles(workspaceRoot, query, options?.limit ?? 15);\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n log.warn({ err: error, sessionKey, errorMessage }, `Embedded workspace file search failed: ${errorMessage}`);\n return [];\n }\n }\n\n async getReviewContext(sessionKey: string) {\n const config = this.activeConfig();\n const metadata = getSessionMetadata(sessionKey);\n const project = metadata?.projectId ? new ProjectService().get(metadata.projectId) : null;\n const workspace = effectiveWorkspacePathForSession(config, sessionKey, null, project);\n const cwd = await resolveGitRoot(workspace);\n return buildReviewContext(cwd);\n }\n\n async sendChat(opts: ChatSendOptions): Promise<{ runId: string }> {\n const agent = await this.ensureAgent();\n\n const runId = crypto.randomUUID();\n this.chatAbort?.abort();\n this.chatAbort = new AbortController();\n const signal = this.chatAbort.signal;\n\n const mapper = new ChatStreamMapper({ runId, sessionKey: opts.sessionKey, channel: 'tui' });\n for (const event of mapper.start()) {\n this.onEvent?.({ event: event.type, data: event, source: 'embedded' });\n }\n\n // Run the stream in background so the TUI event loop stays responsive.\n void (async () => {\n try {\n // Prepend envelope timestamp so the model knows the current date/time,\n // matching the behavior of channel pipelines (Telegram, Weixin, etc.).\n // Skip for slash commands — parseSlashCommand requires lines starting with '/'.\n const messageForAgent = opts.message.trimStart().startsWith('/')\n ? opts.message\n : prependEnvelopeTimestamp(opts.message);\n\n const stream = agent.turnDispatcher.processDirectStreaming(\n messageForAgent,\n opts.sessionKey,\n opts.attachments,\n opts.thinking,\n { signal, runId },\n );\n\n for await (const event of stream) {\n if (signal.aborted) break;\n for (const mapped of mapper.map(event)) {\n this.onEvent?.({ event: mapped.type, data: mapped, source: 'embedded' });\n }\n }\n\n if (!signal.aborted) {\n for (const mapped of mapper.end('success')) {\n this.onEvent?.({ event: mapped.type, data: mapped, source: 'embedded' });\n }\n }\n } catch (error) {\n if (signal.aborted) return;\n const errorMessage = error instanceof Error ? error.message : String(error);\n for (const mapped of mapper.error(errorMessage)) {\n this.onEvent?.({ event: mapped.type, data: mapped, source: 'embedded' });\n }\n for (const mapped of mapper.end('error', errorMessage)) {\n this.onEvent?.({ event: mapped.type, data: mapped, source: 'embedded' });\n }\n }\n })();\n\n return { runId };\n }\n\n async abortChat(_opts: { sessionKey: string; runId: string }): Promise<{ ok: boolean }> {\n if (this.chatAbort) {\n this.chatAbort.abort();\n this.chatAbort = null;\n return { ok: true };\n }\n return { ok: false };\n }\n\n async steerChat(opts: { sessionKey: string; message: string }): Promise<{ ok: boolean }> {\n if (!this.agent) return { ok: false };\n const ok = await this.agent.turnDispatcher.steerWebchatSession(opts.sessionKey, opts.message);\n return { ok };\n }\n\n async loadHistory(opts: {\n sessionKey: string;\n limit?: number;\n }): Promise<{ messages: HistoryMessage[] }> {\n if (!this.agent) {\n return { messages: [] };\n }\n try {\n const rows = await this.agent.sessionStore.loadTranscriptRows(opts.sessionKey);\n return {\n messages: transcriptRowsToClientHistory(rows, { limit: opts.limit }),\n };\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n log.warn({ err: error, errorMessage }, `Embedded loadHistory failed: ${errorMessage}`);\n return { messages: [] };\n }\n }\n\n async loadHistoryWindow(opts: {\n sessionKey: string;\n rowNumber: number;\n before?: number;\n after?: number;\n }) {\n if (!this.agent) {\n return { messages: [], startRowNumber: 0, endRowNumber: 0, totalRows: 0 };\n }\n try {\n const rows = await this.agent.sessionStore.loadTranscriptRows(opts.sessionKey);\n const totalRows = rows.length;\n if (totalRows === 0) {\n return { messages: [], startRowNumber: 0, endRowNumber: 0, totalRows };\n }\n const targetRowNumber = Math.min(totalRows, Math.max(1, Math.trunc(opts.rowNumber)));\n const before = clampHistoryWindowSpan(opts.before, 80);\n const after = clampHistoryWindowSpan(opts.after, 120);\n const startRowNumber = Math.max(1, targetRowNumber - before);\n const endRowNumber = Math.min(totalRows, targetRowNumber + after);\n return {\n messages: transcriptRowsToClientHistory(rows, { startRowNumber, endRowNumber }),\n startRowNumber,\n endRowNumber,\n totalRows,\n };\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n log.warn(\n { err: error, sessionKey: opts.sessionKey, rowNumber: opts.rowNumber, errorMessage },\n `Embedded loadHistoryWindow failed: ${errorMessage}`,\n );\n return { messages: [], startRowNumber: 0, endRowNumber: 0, totalRows: 0 };\n }\n }\n\n async loadTranscriptTree(sessionKey: string): Promise<TuiTranscriptTreeEntry[]> {\n if (!this.agent) return [];\n try {\n const rows = await this.agent.sessionStore.loadTranscriptRows(sessionKey);\n return buildTuiTranscriptTree(rows);\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n log.warn({ err: error, sessionKey, errorMessage }, `Embedded loadTranscriptTree failed: ${errorMessage}`);\n return [];\n }\n }\n\n async loadTimeline(sessionKey: string): Promise<SessionTimelineItem[]> {\n if (!this.agent) return [];\n try {\n const rows = await this.agent.sessionStore.loadTranscriptRows(sessionKey);\n return buildSessionTimeline(rows);\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n log.warn({ err: error, sessionKey, errorMessage }, `Embedded loadTimeline failed: ${errorMessage}`);\n return [];\n }\n }\n\n async getSessionStats(sessionKey: string): Promise<TuiSessionStats> {\n if (!this.agent) return computeTuiSessionStats([]);\n try {\n const rows = await this.agent.sessionStore.loadTranscriptRows(sessionKey);\n return computeTuiSessionStats(rows);\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n log.warn({ err: error, sessionKey, errorMessage }, `Embedded getSessionStats failed: ${errorMessage}`);\n return computeTuiSessionStats([]);\n }\n }\n\n async listSessions(): Promise<TuiSessionItem[]> {\n if (!this.agent) return [];\n try {\n const result = await this.agent.sessionStore.list({\n limit: 200,\n sortBy: 'updatedAt',\n sortOrder: 'desc',\n });\n return result.items.map(sessionMetadataToTuiItem);\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n log.warn({ err: error, errorMessage }, `Embedded listSessions failed: ${errorMessage}`);\n return [];\n }\n }\n\n async listAgents(): Promise<TuiAgentInfo[]> {\n const config = this.activeConfig();\n const agents = new Map<string, TuiAgentInfo>();\n for (const entry of listAgentEntries(config)) {\n if (entry.enabled === false) continue;\n const id = normalizeAgentId(entry.id);\n agents.set(id, {\n id,\n enabled: true,\n });\n }\n return [...agents.values()].sort((a, b) => a.id.localeCompare(b.id));\n }\n\n async setTuiDefaultAgent(agentId: string): Promise<{ agentId: string }> {\n const result = setTuiDefaultAgentConfig(this.activeConfig(), agentId);\n if (result.ok === false) {\n throw new Error(result.message);\n }\n await saveConfig(result.config);\n this.config = result.config;\n return { agentId: result.agentId };\n }\n\n async renameSession(sessionKey: string, name: string): Promise<{ ok: boolean }> {\n if (!this.agent) return { ok: false };\n try {\n await this.agent.sessionStore.updateMetadata(sessionKey, { name: name.trim() });\n return { ok: true };\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n log.warn({ err: error, sessionKey, errorMessage }, `Embedded renameSession failed: ${errorMessage}`);\n return { ok: false };\n }\n }\n\n async deleteSession(sessionKey: string): Promise<{ ok: boolean }> {\n if (!this.agent) return { ok: false };\n try {\n const ok = await this.agent.sessionStore.deleteSession(sessionKey);\n return { ok };\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n log.warn({ err: error, sessionKey, errorMessage }, `Embedded deleteSession failed: ${errorMessage}`);\n return { ok: false };\n }\n }\n\n async getSessionInfo(sessionKey: string): Promise<SessionInfo> {\n if (!this.agent) {\n const config = this.activeConfig();\n const model = getAgentDefaultModelRef(config);\n return { model: model ?? undefined };\n }\n try {\n const cfg = await this.agent.sessionInspector.agentConfig(sessionKey);\n const parsed = parseModelRef(cfg.model);\n const usage = await this.agent.sessionInspector.contextUsage(sessionKey);\n return {\n model: parsed?.model ?? cfg.model,\n modelProvider: parsed?.provider,\n thinkingLevel: cfg.thinkingLevel,\n reasoningLevel: cfg.reasoningLevel,\n verboseLevel: cfg.verboseLevel,\n totalTokens: usage.estimatedTokens,\n contextWindow: usage.contextWindow,\n contextUsagePercent: usage.usagePercent,\n effectiveWorkspacePath: cfg.effectiveWorkspacePath,\n workingDirectoryLocked: cfg.workingDirectoryLocked,\n };\n } catch (err) {\n const errorMessage = err instanceof Error ? err.message : String(err);\n log.warn({ err, sessionKey, errorMessage }, `getSessionInfo failed: ${errorMessage}`);\n const config = this.activeConfig();\n const model = getAgentDefaultModelRef(config);\n return { model: model ?? undefined };\n }\n }\n\n async listModels(): Promise<TuiModelChoice[]> {\n const { getAvailableModels } = await import('../../providers/index.js');\n const models = await getAvailableModels();\n return models.map((model) => ({\n id: model.id,\n name: model.name ?? model.id,\n provider: model.provider,\n contextWindow: model.contextWindow,\n }));\n }\n\n async resetSession(sessionKey: string): Promise<void> {\n if (!this.agent) return;\n await this.agent.resetSession(sessionKey);\n }\n\n async patchSession(\n sessionKey: string,\n patch: Record<string, unknown>,\n ): Promise<void> {\n const agent = await this.ensureAgent();\n const projectId = typeof patch.projectId === 'string' ? patch.projectId.trim() : '';\n if (projectId) {\n await this.sessionIndexReady;\n await this.sessionIndex?.getStore().resolveTranscriptPath(sessionKey);\n new ProjectService().attachSession(sessionKey, projectId);\n }\n const result = await agent.sessionConfig.patch(sessionKey, {\n model: typeof patch.model === 'string' ? patch.model : undefined,\n thinkingLevel: typeof patch.thinkingLevel === 'string' ? patch.thinkingLevel : undefined,\n reasoningLevel: typeof patch.reasoningLevel === 'string' ? patch.reasoningLevel : undefined,\n verboseLevel: typeof patch.verboseLevel === 'string' ? patch.verboseLevel : undefined,\n workingDirectory: typeof patch.workingDirectory === 'string' ? patch.workingDirectory : undefined,\n });\n if (!result.ok) {\n throw new Error(result.error);\n }\n }\n\n async compactSession(\n sessionKey: string,\n options?: { force?: boolean; instructions?: string },\n ): Promise<TuiCompactionResult> {\n if (!this.agent) return { compacted: false, summary: 'Agent not started' };\n try {\n const result = await this.agent.sessionInspector.compact(sessionKey, {\n force: options?.force ?? true,\n instructions: options?.instructions,\n });\n if (!result.compacted) return { compacted: false, summary: 'Nothing to compact' };\n return {\n compacted: true,\n summary: `Compacted (${result.tokensBefore ?? '?'} → ${result.tokensAfter ?? '?'} tokens)`,\n tokensBefore: result.tokensBefore,\n tokensAfter: result.tokensAfter,\n transcriptSummary: result.summary,\n };\n } catch (err) {\n const errorMessage = err instanceof Error ? err.message : String(err);\n return { compacted: false, summary: errorMessage };\n }\n }\n\n async exportSession(sessionKey: string, format: ExportFormat): Promise<string> {\n if (!this.agent) {\n throw new Error('Agent not started');\n }\n return this.agent.sessionStore.exportSession(sessionKey, format);\n }\n\n async importSession(\n targetSessionKey: string,\n jsonContent: string,\n ): Promise<{ sessionKey: string; rowCount: number }> {\n if (!this.agent) {\n throw new Error('Agent not started');\n }\n return this.agent.sessionStore.importSessionExport(targetSessionKey, jsonContent);\n }\n\n async createShare(\n _sessionKey: string,\n request: TuiShareRequest,\n _options?: { agentId?: string },\n ): Promise<TuiShareResult> {\n if (!this.agent) {\n throw new Error('Agent not started');\n }\n const config = this.activeConfig();\n if (!isShareToolAvailable(config)) {\n throw new Error('Sharing is disabled in gateway config');\n }\n const workspace = getWorkspacePath(config);\n const tool = createCreateShareTool({\n workspace,\n getConfig: () => config,\n getAgentId: () => 'tui',\n });\n const result = await tool.execute(\n 'tui-share',\n {\n filePath: request.path,\n audience: request.audience,\n mode: request.mode,\n title: request.title,\n description: request.description,\n },\n );\n const details = (result.details ?? {}) as Record<string, unknown>;\n const error = typeof details.error === 'string' ? details.error : undefined;\n if (error) {\n throw new Error(error);\n }\n const shareUrl = typeof details.shareUrl === 'string' ? details.shareUrl : undefined;\n if (!shareUrl) {\n const text = result.content\n .map((part) => (part.type === 'text' ? part.text : ''))\n .join('\\n')\n .trim();\n throw new Error(text || 'Share failed');\n }\n return {\n kind: typeof details.kind === 'string' ? details.kind : 'share',\n shareUrl,\n title: typeof details.title === 'string' ? details.title : undefined,\n description: typeof details.description === 'string' ? details.description : undefined,\n thumbnailUrl: typeof details.thumbnailUrl === 'string' ? details.thumbnailUrl : undefined,\n reachability: typeof details.reachability === 'string' ? details.reachability : undefined,\n reachabilityHint:\n typeof details.reachabilityHint === 'string' ? details.reachabilityHint : undefined,\n expiresAt: typeof details.expiresAt === 'string' ? details.expiresAt : undefined,\n maxViews: typeof details.maxViews === 'number' ? details.maxViews : null,\n routingReason:\n typeof (details.routing as { reason?: unknown } | undefined)?.reason === 'string'\n ? ((details.routing as { reason: string }).reason)\n : undefined,\n routingHint:\n typeof (details.routing as { hint?: unknown } | undefined)?.hint === 'string'\n ? ((details.routing as { hint: string }).hint)\n : undefined,\n };\n }\n\n async btwQuery(sessionKey: string, question: string): Promise<{ text: string; error?: string }> {\n if (!this.agent) {\n return { text: '', error: 'Agent not started' };\n }\n return this.agent.sessionInspector.btwQuery(sessionKey, question);\n }\n\n async forkSession(\n sourceSessionKey: string,\n targetSessionKey: string,\n ): Promise<{ sessionKey: string; rowCount: number }> {\n if (!this.agent) {\n throw new Error('Agent not started');\n }\n return this.agent.sessionStore.forkSession(sourceSessionKey, targetSessionKey);\n }\n\n async forkSessionAt(\n sourceSessionKey: string,\n targetSessionKey: string,\n entryId: string,\n ): Promise<{ sessionKey: string; rowCount: number }> {\n if (!this.agent) {\n throw new Error('Agent not started');\n }\n const throughRow = transcriptTreeEntryIdToRowNumber(entryId);\n if (throughRow == null) {\n throw new Error(`Invalid transcript entry: ${entryId}`);\n }\n return this.agent.sessionStore.forkSessionRows(sourceSessionKey, targetSessionKey, { throughRow });\n }\n\n async setTranscriptLabel(\n sessionKey: string,\n entryId: string,\n label: string | undefined,\n ): Promise<{ ok: boolean }> {\n if (!this.agent) {\n throw new Error('Agent not started');\n }\n await this.agent.sessionStore.appendTranscriptLabelEntry(sessionKey, { targetId: entryId, label });\n return { ok: true };\n }\n\n async appendCustomEntry(\n sessionKey: string,\n customType: string,\n data?: unknown,\n ): Promise<{ ok: boolean }> {\n if (!this.agent) {\n throw new Error('Agent not started');\n }\n await this.agent.sessionStore.appendTranscriptCustomEntry(sessionKey, { customType, data });\n return { ok: true };\n }\n\n async appendCustomMessage(\n sessionKey: string,\n message: {\n customType: string;\n content?: string | unknown[];\n display?: boolean;\n details?: unknown;\n },\n ): Promise<{ ok: boolean }> {\n if (!this.agent) {\n throw new Error('Agent not started');\n }\n await this.agent.sessionStore.appendTranscriptCustomMessageEntry(sessionKey, message);\n evictEmbeddedSessionRunner(sessionKey, 'tui_custom_message_appended');\n return { ok: true };\n }\n\n async appendBashExecution(\n sessionKey: string,\n entry: {\n command: string;\n output?: string;\n exitCode?: number | null;\n signal?: string | null;\n excludeFromContext?: boolean;\n truncated?: boolean;\n fullOutputPath?: string;\n },\n ): Promise<{ ok: boolean }> {\n if (!this.agent) {\n throw new Error('Agent not started');\n }\n await this.agent.sessionStore.appendTranscriptBashExecutionEntry(sessionKey, entry);\n evictEmbeddedSessionRunner(sessionKey, 'tui_bash_execution_appended');\n return { ok: true };\n }\n\n private processOutbound(): void {\n void (async () => {\n while (this.running) {\n try {\n const msg = await this.bus.consumeOutbound();\n log.debug({ channel: msg.channel, chatId: msg.chat_id }, 'Outbound message');\n } catch (error) {\n if (error instanceof MessageBusShutdownError) break;\n const errorMessage = error instanceof Error ? error.message : String(error);\n log.warn({ err: error, errorMessage }, `Outbound processor failed: ${errorMessage}`);\n await new Promise((resolve) => setTimeout(resolve, 1000));\n }\n }\n })();\n }\n}\n"],"mappings":"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"}
@@ -1,4 +1,5 @@
1
1
  import type { ExportFormat } from '../../session/types.js';
2
+ import type { SessionTimelineItem } from '../../session/transcript-outline.js';
2
3
  import type { ChatSendOptions, HistoryMessage, TuiBackend, TuiCompactionResult, TuiEvent, TuiModelChoice, TuiShareRequest, TuiShareResult, TuiSessionStats, TuiSessionItem, TuiStartupResources, TuiTranscriptTreeEntry, TuiAgentInfo, TuiWorkspaceFileSearchEntry, TuiWorkflowRunStartRequest, TuiWorkflowRunStartResult, TuiStartupProjectResult } from '../tui-backend.js';
3
4
  import type { SessionInfo } from '../tui-types.js';
4
5
  import type { ReviewContext } from '../../review/review-git.js';
@@ -71,7 +72,19 @@ export declare class GatewaySseBackend implements TuiBackend {
71
72
  }): Promise<{
72
73
  messages: HistoryMessage[];
73
74
  }>;
75
+ loadHistoryWindow(opts: {
76
+ sessionKey: string;
77
+ rowNumber: number;
78
+ before?: number;
79
+ after?: number;
80
+ }): Promise<{
81
+ messages: import("../../session/client-history.js").ClientHistoryMessage[];
82
+ startRowNumber: number;
83
+ endRowNumber: number;
84
+ totalRows: number;
85
+ }>;
74
86
  loadTranscriptTree(sessionKey: string): Promise<TuiTranscriptTreeEntry[]>;
87
+ loadTimeline(sessionKey: string): Promise<SessionTimelineItem[]>;
75
88
  getSessionStats(sessionKey: string): Promise<TuiSessionStats>;
76
89
  listSessions(): Promise<TuiSessionItem[]>;
77
90
  listAgents(): Promise<TuiAgentInfo[]>;
@@ -414,6 +414,43 @@ var GatewaySseBackend = class {
414
414
  return { messages: [] };
415
415
  }
416
416
  }
417
+ async loadHistoryWindow(opts) {
418
+ const params = new URLSearchParams({
419
+ rowNumber: String(opts.rowNumber),
420
+ before: String(opts.before ?? 80),
421
+ after: String(opts.after ?? 120)
422
+ });
423
+ try {
424
+ const res = await gatewayFetch(this.baseUrl, `/api/sessions/${encodeURIComponent(opts.sessionKey)}/transcript/window?${params.toString()}`, this.token);
425
+ if (!res.ok) return {
426
+ messages: [],
427
+ startRowNumber: 0,
428
+ endRowNumber: 0,
429
+ totalRows: 0
430
+ };
431
+ const payload = (await res.json()).payload ?? {};
432
+ return {
433
+ messages: Array.isArray(payload.messages) ? payload.messages : [],
434
+ startRowNumber: typeof payload.startRowNumber === "number" ? payload.startRowNumber : 0,
435
+ endRowNumber: typeof payload.endRowNumber === "number" ? payload.endRowNumber : 0,
436
+ totalRows: typeof payload.totalRows === "number" ? payload.totalRows : 0
437
+ };
438
+ } catch (error) {
439
+ const errorMessage = error instanceof Error ? error.message : String(error);
440
+ log.warn({
441
+ err: error,
442
+ sessionKey: opts.sessionKey,
443
+ rowNumber: opts.rowNumber,
444
+ errorMessage
445
+ }, `Failed to load history window: ${errorMessage}`);
446
+ return {
447
+ messages: [],
448
+ startRowNumber: 0,
449
+ endRowNumber: 0,
450
+ totalRows: 0
451
+ };
452
+ }
453
+ }
417
454
  async loadTranscriptTree(sessionKey) {
418
455
  try {
419
456
  const res = await gatewayFetch(this.baseUrl, `/api/sessions/${encodeURIComponent(sessionKey)}?include=transcriptRows`, this.token);
@@ -430,6 +467,22 @@ var GatewaySseBackend = class {
430
467
  return [];
431
468
  }
432
469
  }
470
+ async loadTimeline(sessionKey) {
471
+ try {
472
+ const res = await gatewayFetch(this.baseUrl, `/api/sessions/${encodeURIComponent(sessionKey)}/timeline`, this.token);
473
+ if (!res.ok) return [];
474
+ const json = await res.json();
475
+ return Array.isArray(json.items) ? json.items : [];
476
+ } catch (error) {
477
+ const errorMessage = error instanceof Error ? error.message : String(error);
478
+ log.warn({
479
+ err: error,
480
+ sessionKey,
481
+ errorMessage
482
+ }, `Failed to load timeline: ${errorMessage}`);
483
+ return [];
484
+ }
485
+ }
433
486
  async getSessionStats(sessionKey) {
434
487
  try {
435
488
  const res = await gatewayFetch(this.baseUrl, `/api/sessions/${encodeURIComponent(sessionKey)}?include=transcriptRows`, this.token);
@@ -1 +1 @@
1
- {"version":3,"file":"gateway-sse-backend.js","names":[],"sources":["../../../../src/tui/backends/gateway-sse-backend.ts"],"sourcesContent":["import { prependEnvelopeTimestamp } from '../../channels/envelope-timestamp.js';\nimport { parseModelRef } from '../../agent/models/selection.js';\nimport type { ExportFormat } from '../../session/types.js';\nimport type { TranscriptStoredRow } from '../../session/session-context-for-llm.js';\nimport { transcriptRowsToClientHistory } from '../../session/client-history.js';\nimport { createLogger } from '../../utils/logger.js';\nimport { consumeSSEStream, parseSSEData } from '../sse-consumer.js';\nimport type {\n ChatSendOptions,\n HistoryMessage,\n TuiBackend,\n TuiCompactionResult,\n TuiEvent,\n TuiModelChoice,\n TuiShareRequest,\n TuiShareResult,\n TuiSessionStats,\n TuiSessionItem,\n TuiStartupResources,\n TuiTranscriptTreeEntry,\n TuiAgentInfo,\n TuiWorkspaceFileSearchEntry,\n TuiWorkflowRunStartRequest,\n TuiWorkflowRunStartResult,\n TuiStartupProjectResult,\n} from '../tui-backend.js';\nimport type { SessionInfo } from '../tui-types.js';\nimport { computeTuiSessionStats } from '../tui-session-stats.js';\nimport { buildTuiTranscriptTree, transcriptTreeEntryIdToRowNumber } from '../tui-transcript-tree.js';\nimport type { ReviewContext } from '../../review/review-git.js';\n\nconst log = createLogger('TUI:GatewaySSE');\n\ninterface GatewaySSEOptions {\n url: string;\n token?: string;\n}\n\nfunction normalizeGatewayModelChoice(model: TuiModelChoice): TuiModelChoice {\n const providerPrefix = `${model.provider}/`;\n const id = model.id.startsWith(providerPrefix)\n ? model.id.slice(providerPrefix.length)\n : model.id;\n return { ...model, id };\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return !!value && typeof value === 'object' && !Array.isArray(value);\n}\n\nexport function normalizeGatewaySseEvent(evt: TuiEvent): TuiEvent {\n if (evt.event !== 'agent.stream' || !isRecord(evt.data)) return evt;\n const inner = evt.data.event;\n if (!isRecord(inner) || typeof inner.type !== 'string' || !inner.type) return evt;\n return { event: inner.type, data: inner, source: evt.source };\n}\n\n/** Fetch wrapper that adds auth headers. */\nasync function gatewayFetch(\n baseUrl: string,\n path: string,\n token: string | undefined,\n init?: RequestInit,\n): Promise<Response> {\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n ...(token ? { Authorization: `Bearer ${token}` } : {}),\n ...(init?.headers as Record<string, string> | undefined),\n };\n return fetch(`${baseUrl}${path}`, { ...init, headers });\n}\n\n/**\n * TUI backend that communicates with a running xopc gateway via HTTP + SSE.\n *\n * - Agent streaming: `POST /api/agent` with `Accept: text/event-stream`\n * - Broadcast events: `GET /api/events` via long-lived SSE\n * - REST calls for sessions, models, etc.\n */\nexport class GatewaySseBackend implements TuiBackend {\n private readonly baseUrl: string;\n private readonly token: string | undefined;\n private eventAbort: AbortController | null = null;\n private chatAbort: AbortController | null = null;\n\n onEvent?: (evt: TuiEvent) => void;\n onConnected?: () => void;\n onDisconnected?: (reason: string) => void;\n onGap?: (info: { expected: number; received: number }) => void;\n\n constructor(opts: GatewaySSEOptions) {\n this.baseUrl = opts.url.replace(/\\/+$/, '');\n this.token = opts.token;\n }\n\n get connectionLabel(): string {\n return this.baseUrl;\n }\n\n start(): void {\n this.startEventStream();\n }\n\n stop(): void {\n this.eventAbort?.abort();\n this.eventAbort = null;\n this.chatAbort?.abort();\n this.chatAbort = null;\n }\n\n getActiveSignal(): AbortSignal | undefined {\n const signal = this.chatAbort?.signal;\n return signal && !signal.aborted ? signal : undefined;\n }\n\n // ── Agent chat (POST /api/agent → SSE response body) ──\n\n async sendChat(opts: ChatSendOptions): Promise<{ runId: string }> {\n this.chatAbort?.abort();\n this.chatAbort = new AbortController();\n const signal = this.chatAbort.signal;\n const runId = crypto.randomUUID();\n\n\n // Fire-and-forget: run the HTTP request + SSE consumption in background\n // so the TUI event loop stays responsive for keyboard input.\n void (async () => {\n try {\n const res = await gatewayFetch(this.baseUrl, '/api/agent', this.token, {\n method: 'POST',\n headers: { Accept: 'text/event-stream' },\n body: JSON.stringify({\n // Prepend envelope timestamp for regular messages so the model knows\n // the current date/time. Skip for slash commands — parseSlashCommand\n // requires lines starting with '/'.\n message: opts.message.trimStart().startsWith('/')\n ? opts.message\n : prependEnvelopeTimestamp(opts.message),\n channel: 'webchat',\n sessionKey: opts.sessionKey,\n attachments: opts.attachments,\n thinking: opts.thinking,\n }),\n signal,\n });\n\n if (!res.ok) {\n const body = (await res.json().catch(() => ({}))) as { error?: { message?: string } };\n this.onEvent?.({\n event: 'error',\n data: {\n type: 'error',\n runId,\n sessionKey: opts.sessionKey,\n timestamp: Date.now(),\n payload: { code: 'GATEWAY_ERROR', message: body.error?.message ?? `Gateway error: ${res.status}` },\n },\n source: 'agent-response',\n });\n return;\n }\n\n const contentType = res.headers.get('Content-Type') ?? '';\n\n if (contentType.includes('text/event-stream') && res.body) {\n await consumeSSEStream(\n res.body,\n (sseEvent) => {\n if (signal.aborted) return;\n const data = parseSSEData<Record<string, unknown>>(sseEvent.data);\n if (!data) return;\n this.onEvent?.({ event: sseEvent.event, data, source: 'agent-response' });\n },\n signal,\n );\n } else {\n const json = (await res.json()) as { ok?: boolean; payload?: { content?: string } };\n if (json.ok && json.payload?.content) {\n const messageId = `msg_${runId}_1`;\n const base = { runId, sessionKey: opts.sessionKey, timestamp: Date.now() };\n this.onEvent?.({ event: 'run_start', data: { ...base, type: 'run_start', payload: { channel: 'webchat' } }, source: 'agent-response' });\n this.onEvent?.({ event: 'assistant_message_start', data: { ...base, type: 'assistant_message_start', payload: { messageId } }, source: 'agent-response' });\n this.onEvent?.({ event: 'assistant_delta', data: { ...base, type: 'assistant_delta', payload: { messageId, delta: json.payload.content } }, source: 'agent-response' });\n this.onEvent?.({ event: 'assistant_message_end', data: { ...base, type: 'assistant_message_end', payload: { messageId } }, source: 'agent-response' });\n this.onEvent?.({ event: 'run_end', data: { ...base, type: 'run_end', payload: { status: 'success' } }, source: 'agent-response' });\n }\n }\n } catch (error) {\n if (signal.aborted) return;\n const errorMessage = error instanceof Error ? error.message : String(error);\n this.onEvent?.({\n event: 'error',\n data: { type: 'error', runId, sessionKey: opts.sessionKey, timestamp: Date.now(), payload: { code: 'NETWORK_ERROR', message: errorMessage } },\n source: 'agent-response',\n });\n }\n })();\n\n return { runId };\n }\n\n async searchWorkspaceFiles(\n sessionKey: string,\n query: string,\n options?: { limit?: number },\n ): Promise<TuiWorkspaceFileSearchEntry[]> {\n try {\n const params = new URLSearchParams();\n params.set('q', query);\n params.set('limit', String(options?.limit ?? 15));\n params.set('sessionKey', sessionKey);\n const res = await gatewayFetch(\n this.baseUrl,\n `/api/workspace/editor/files/search?${params.toString()}`,\n this.token,\n );\n if (!res.ok) return [];\n const json = (await res.json()) as {\n ok?: boolean;\n payload?: { entries?: TuiWorkspaceFileSearchEntry[] };\n };\n return json.payload?.entries ?? [];\n } catch (err) {\n const errorMessage = err instanceof Error ? err.message : String(err);\n log.warn({ err, sessionKey, errorMessage }, `Gateway workspace file search failed: ${errorMessage}`);\n return [];\n }\n }\n\n async getReviewContext(sessionKey: string): Promise<ReviewContext> {\n const params = new URLSearchParams({ sessionKey });\n const res = await gatewayFetch(this.baseUrl, `/api/review/context?${params.toString()}`, this.token);\n const json = (await res.json().catch(() => ({}))) as {\n ok?: boolean;\n payload?: ReviewContext;\n error?: { message?: string };\n };\n if (!res.ok || !json.ok || !json.payload) {\n throw new Error(json.error?.message ?? `Review context failed (${res.status})`);\n }\n return json.payload;\n }\n\n async startWorkflowRun(opts: TuiWorkflowRunStartRequest): Promise<TuiWorkflowRunStartResult> {\n const goal = opts.goal?.trim();\n const res = await gatewayFetch(this.baseUrl, '/api/workflows/runs', this.token, {\n method: 'POST',\n body: JSON.stringify({\n definitionId: opts.definitionId,\n agentId: opts.agentId,\n parentSessionKey: opts.sessionKey,\n source: { kind: 'chat', sessionKey: opts.sessionKey },\n ...(goal ? { goal } : {}),\n ...(opts.input !== undefined ? { input: opts.input } : {}),\n }),\n });\n const json = (await res.json().catch(() => ({}))) as {\n runId?: string;\n sessionKey?: string;\n error?: string;\n code?: string;\n };\n if (!res.ok || !json.runId || !json.sessionKey) {\n throw new Error(json.error ?? `Workflow start failed (${res.status})`);\n }\n return {\n runId: json.runId,\n sessionKey: json.sessionKey,\n definitionId: opts.definitionId,\n };\n }\n\n async resolveStartupProject(opts: {\n workspacePath: string;\n sessionKey: string;\n agentId: string;\n autoCreate?: boolean;\n }): Promise<TuiStartupProjectResult> {\n const res = await gatewayFetch(this.baseUrl, '/api/projects/resolve-workspace', this.token, {\n method: 'POST',\n body: JSON.stringify(opts),\n });\n const json = (await res.json().catch(() => ({}))) as TuiStartupProjectResult & { ok?: boolean; error?: string };\n if (!res.ok || json.ok === false) {\n throw new Error(json.error ?? `Project workspace resolve failed (${res.status})`);\n }\n return { project: json.project ?? null, created: json.created, reason: json.reason };\n }\n\n async resumeChat(opts: { sessionKey: string; runId: string }): Promise<{ ok: boolean; reason?: string }> {\n this.chatAbort?.abort();\n this.chatAbort = new AbortController();\n const signal = this.chatAbort.signal;\n this.onEvent?.({\n event: 'run_start',\n data: { type: 'run_start', runId: opts.runId, sessionKey: opts.sessionKey, timestamp: Date.now(), payload: { channel: 'webchat' } },\n source: 'agent-resume',\n });\n\n let res: Response;\n try {\n res = await gatewayFetch(this.baseUrl, '/api/agent/resume', this.token, {\n method: 'POST',\n headers: { Accept: 'text/event-stream' },\n body: JSON.stringify({ runId: opts.runId, sessionKey: opts.sessionKey }),\n signal,\n });\n } catch (error) {\n if (signal.aborted) return { ok: false, reason: 'resume aborted' };\n const errorMessage = error instanceof Error ? error.message : String(error);\n return { ok: false, reason: errorMessage };\n }\n\n if (!res.ok) {\n const body = (await res.json().catch(() => ({}))) as { error?: { message?: string } };\n return { ok: false, reason: body.error?.message ?? `Resume failed: ${res.status}` };\n }\n\n const contentType = res.headers.get('Content-Type') ?? '';\n if (!contentType.includes('text/event-stream') || !res.body) {\n return { ok: false, reason: 'Resume endpoint did not return an SSE stream' };\n }\n\n void (async () => {\n try {\n await consumeSSEStream(\n res.body,\n (sseEvent) => {\n if (signal.aborted) return;\n const data = parseSSEData<Record<string, unknown>>(sseEvent.data);\n if (!data) return;\n this.onEvent?.({ event: sseEvent.event, data, source: 'agent-resume' });\n },\n signal,\n );\n } catch (error) {\n if (signal.aborted) return;\n const errorMessage = error instanceof Error ? error.message : String(error);\n this.onEvent?.({\n event: 'error',\n data: { type: 'error', runId: opts.runId, sessionKey: opts.sessionKey, timestamp: Date.now(), payload: { code: 'NETWORK_ERROR', message: errorMessage } },\n source: 'agent-resume',\n });\n }\n })();\n\n return { ok: true };\n }\n\n async abortChat(opts: { sessionKey: string; runId: string }): Promise<{ ok: boolean }> {\n this.chatAbort?.abort();\n this.chatAbort = null;\n try {\n const res = await gatewayFetch(this.baseUrl, '/api/agent/abort', this.token, {\n method: 'POST',\n body: JSON.stringify({ runId: opts.runId }),\n });\n const json = (await res.json()) as { ok?: boolean };\n return { ok: json.ok ?? false };\n } catch {\n return { ok: false };\n }\n }\n\n async steerChat(opts: { sessionKey: string; message: string }): Promise<{ ok: boolean }> {\n try {\n const res = await gatewayFetch(this.baseUrl, '/api/agent/steer', this.token, {\n method: 'POST',\n body: JSON.stringify({ sessionKey: opts.sessionKey, message: opts.message }),\n });\n if (!res.ok) return { ok: false };\n const json = (await res.json()) as { ok?: boolean };\n return { ok: json.ok === true };\n } catch {\n return { ok: false };\n }\n }\n\n // ── REST helpers ──\n\n async getStartupResources(sessionKey: string): Promise<TuiStartupResources> {\n const empty: TuiStartupResources = { context: [], skills: [], workflows: [], connectors: [] };\n try {\n const res = await gatewayFetch(\n this.baseUrl,\n `/api/tui/startup-resources?sessionKey=${encodeURIComponent(sessionKey)}`,\n this.token,\n );\n if (!res.ok) return empty;\n const json = (await res.json()) as { payload?: Partial<TuiStartupResources> };\n return {\n context: Array.isArray(json.payload?.context) ? json.payload.context : [],\n skills: Array.isArray(json.payload?.skills) ? json.payload.skills : [],\n workflows: Array.isArray(json.payload?.workflows) ? json.payload.workflows : [],\n connectors: Array.isArray(json.payload?.connectors) ? json.payload.connectors : [],\n };\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n log.warn({ err: error, sessionKey, errorMessage }, `Failed to load startup resources: ${errorMessage}`);\n return empty;\n }\n }\n\n async loadHistory(opts: {\n sessionKey: string;\n limit?: number;\n }): Promise<{ messages: HistoryMessage[] }> {\n try {\n const res = await gatewayFetch(\n this.baseUrl,\n `/api/sessions/${encodeURIComponent(opts.sessionKey)}?include=transcriptRows`,\n this.token,\n );\n if (!res.ok) return { messages: [] };\n const json = (await res.json()) as {\n session?: { transcriptRows?: unknown[] };\n };\n const rows = Array.isArray(json.session?.transcriptRows)\n ? (json.session.transcriptRows as TranscriptStoredRow[])\n : [];\n return { messages: transcriptRowsToClientHistory(rows, { limit: opts.limit }) };\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n log.warn({ err: error, errorMessage }, `Failed to load history: ${errorMessage}`);\n return { messages: [] };\n }\n }\n\n async loadTranscriptTree(sessionKey: string): Promise<TuiTranscriptTreeEntry[]> {\n try {\n const res = await gatewayFetch(\n this.baseUrl,\n `/api/sessions/${encodeURIComponent(sessionKey)}?include=transcriptRows`,\n this.token,\n );\n if (!res.ok) return [];\n const json = (await res.json()) as {\n session?: { transcriptRows?: unknown[] };\n };\n const rows = Array.isArray(json.session?.transcriptRows)\n ? (json.session.transcriptRows as TranscriptStoredRow[])\n : [];\n return buildTuiTranscriptTree(rows);\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n log.warn({ err: error, sessionKey, errorMessage }, `Failed to load transcript tree: ${errorMessage}`);\n return [];\n }\n }\n\n async getSessionStats(sessionKey: string): Promise<TuiSessionStats> {\n try {\n const res = await gatewayFetch(\n this.baseUrl,\n `/api/sessions/${encodeURIComponent(sessionKey)}?include=transcriptRows`,\n this.token,\n );\n if (!res.ok) return computeTuiSessionStats([]);\n const json = (await res.json()) as {\n session?: { transcriptRows?: unknown[] };\n };\n const rows = Array.isArray(json.session?.transcriptRows)\n ? (json.session.transcriptRows as TranscriptStoredRow[])\n : [];\n return computeTuiSessionStats(rows);\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n log.warn({ err: error, sessionKey, errorMessage }, `Failed to load session stats: ${errorMessage}`);\n return computeTuiSessionStats([]);\n }\n }\n\n async listSessions(): Promise<TuiSessionItem[]> {\n try {\n const res = await gatewayFetch(this.baseUrl, '/api/sessions', this.token);\n if (!res.ok) return [];\n const json = (await res.json()) as {\n items?: Array<{\n key: string;\n name?: string;\n updatedAt?: string;\n estimatedTokens?: number;\n messageCount?: number;\n customData?: Record<string, unknown>;\n cwd?: string;\n }>;\n };\n return (json.items ?? []).map((s) => ({\n key: s.key,\n displayName: s.name,\n updatedAt: s.updatedAt ? Date.parse(s.updatedAt) : undefined,\n totalTokens: s.estimatedTokens ?? null,\n messageCount: typeof s.messageCount === 'number' ? s.messageCount : undefined,\n model:\n typeof s.customData?.model === 'string'\n ? s.customData.model\n : typeof s.customData?.modelRef === 'string'\n ? s.customData.modelRef\n : null,\n forkedFromSessionKey:\n typeof s.customData?.forkedFromSessionKey === 'string'\n ? s.customData.forkedFromSessionKey\n : undefined,\n cwd: typeof s.cwd === 'string' ? s.cwd : undefined,\n }));\n } catch {\n return [];\n }\n }\n\n async listAgents(): Promise<TuiAgentInfo[]> {\n const agents = new Map<string, TuiAgentInfo>();\n try {\n const res = await gatewayFetch(this.baseUrl, '/api/agents', this.token);\n if (res.ok) {\n const json = (await res.json()) as {\n payload?: { agents?: Array<{ id?: unknown; name?: unknown }> };\n };\n for (const row of json.payload?.agents ?? []) {\n if (typeof row.id !== 'string' || !row.id.trim()) continue;\n const id = row.id.trim().toLowerCase();\n agents.set(id, {\n id,\n enabled: true,\n ...(typeof row.name === 'string' && row.name.trim()\n ? { displayName: row.name.trim() }\n : {}),\n });\n }\n }\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n log.warn({ err: error, errorMessage }, `Failed to load agents: ${errorMessage}`);\n }\n return [...agents.values()].sort((a, b) => a.id.localeCompare(b.id));\n }\n\n async setTuiDefaultAgent(agentId: string): Promise<{ agentId: string }> {\n const target = agentId.trim().toLowerCase();\n const res = await gatewayFetch(this.baseUrl, '/api/config', this.token, {\n method: 'PATCH',\n body: JSON.stringify({ tui: { defaultAgent: target } }),\n });\n const json = (await res.json().catch(() => ({}))) as {\n ok?: boolean;\n error?: { message?: string } | string;\n payload?: { config?: { tui?: { defaultAgent?: unknown } } };\n };\n if (!res.ok || json.ok === false) {\n const error =\n typeof json.error === 'string'\n ? json.error\n : json.error?.message;\n throw new Error(error ?? `TUI default agent update failed (${res.status})`);\n }\n const saved = json.payload?.config?.tui?.defaultAgent;\n return { agentId: typeof saved === 'string' && saved.trim() ? saved.trim().toLowerCase() : target };\n }\n\n async getSessionInfo(sessionKey: string): Promise<SessionInfo> {\n const out: SessionInfo = {};\n try {\n const sessionPath = `/api/sessions/${encodeURIComponent(sessionKey)}`;\n const [sessionRes, agentCfgRes] = await Promise.all([\n gatewayFetch(this.baseUrl, sessionPath, this.token),\n gatewayFetch(this.baseUrl, `${sessionPath}/agent-config`, this.token),\n ]);\n\n type SessionRow = {\n name?: string;\n estimatedTokens?: number;\n customData?: Record<string, unknown>;\n };\n let session: SessionRow | undefined;\n\n if (sessionRes.ok) {\n const json = (await sessionRes.json()) as { session?: SessionRow };\n session = json.session;\n if (session) {\n if (session.name) out.displayName = session.name;\n if (session.estimatedTokens != null) out.totalTokens = session.estimatedTokens;\n }\n }\n\n if (agentCfgRes.ok) {\n const json = (await agentCfgRes.json()) as {\n ok?: boolean;\n payload?: {\n model?: string;\n thinkingLevel?: string;\n reasoningLevel?: string;\n verboseLevel?: string;\n effectiveWorkspacePath?: string;\n workingDirectoryLocked?: boolean;\n };\n };\n const p = json.payload;\n if (p?.model && typeof p.model === 'string') {\n const parsed = parseModelRef(p.model);\n if (parsed) {\n out.model = parsed.model;\n out.modelProvider = parsed.provider;\n } else {\n out.model = p.model;\n }\n }\n if (p?.thinkingLevel && typeof p.thinkingLevel === 'string') {\n out.thinkingLevel = p.thinkingLevel;\n }\n if (p?.reasoningLevel && typeof p.reasoningLevel === 'string') {\n out.reasoningLevel = p.reasoningLevel;\n }\n if (p?.verboseLevel && typeof p.verboseLevel === 'string') {\n out.verboseLevel = p.verboseLevel;\n }\n if (p?.effectiveWorkspacePath && typeof p.effectiveWorkspacePath === 'string') {\n out.effectiveWorkspacePath = p.effectiveWorkspacePath;\n }\n if (typeof p?.workingDirectoryLocked === 'boolean') {\n out.workingDirectoryLocked = p.workingDirectoryLocked;\n }\n }\n\n if (!out.model && session?.customData) {\n const cd = session.customData;\n const ref =\n typeof cd.model === 'string'\n ? cd.model\n : typeof cd.modelRef === 'string'\n ? cd.modelRef\n : undefined;\n if (ref) {\n const parsed = parseModelRef(ref);\n if (parsed) {\n out.model = parsed.model;\n out.modelProvider = parsed.provider;\n } else {\n out.model = ref;\n }\n }\n if (!out.modelProvider && typeof cd.modelProvider === 'string') {\n out.modelProvider = cd.modelProvider;\n }\n }\n\n if (out.totalTokens != null) {\n const models = await this.listModels();\n const match = models.find(\n (m) =>\n m.id === out.model &&\n (!out.modelProvider || m.provider === out.modelProvider),\n );\n const contextWindow = match?.contextWindow ?? 128_000;\n out.contextWindow = contextWindow;\n out.contextUsagePercent =\n contextWindow > 0\n ? Math.min(100, Math.round((out.totalTokens / contextWindow) * 100))\n : null;\n }\n\n return out;\n } catch {\n return {};\n }\n }\n\n async listModels(): Promise<TuiModelChoice[]> {\n try {\n const res = await gatewayFetch(this.baseUrl, '/api/models', this.token);\n if (!res.ok) return [];\n const json = (await res.json()) as {\n ok?: boolean;\n payload?: { models?: TuiModelChoice[] };\n };\n return (json.payload?.models ?? []).map(normalizeGatewayModelChoice);\n } catch {\n return [];\n }\n }\n\n async resetSession(sessionKey: string): Promise<void> {\n await gatewayFetch(\n this.baseUrl,\n `/api/sessions/${encodeURIComponent(sessionKey)}/reset`,\n this.token,\n { method: 'POST' },\n ).catch(() => {});\n }\n\n async compactSession(\n sessionKey: string,\n options?: { force?: boolean; instructions?: string },\n ): Promise<TuiCompactionResult> {\n try {\n const res = await gatewayFetch(\n this.baseUrl,\n `/api/sessions/${encodeURIComponent(sessionKey)}/compaction/run`,\n this.token,\n {\n method: 'POST',\n body: JSON.stringify({\n force: options?.force ?? true,\n instructions: options?.instructions,\n }),\n },\n );\n if (!res.ok) {\n return { compacted: false, summary: `Compaction failed (${res.status})` };\n }\n const json = (await res.json()) as {\n ok?: boolean;\n payload?: {\n result?: {\n compacted?: boolean;\n summary?: string;\n tokensBefore?: number;\n tokensAfter?: number;\n };\n };\n };\n const result = json.payload?.result;\n if (!result?.compacted) {\n return { compacted: false, summary: 'Nothing to compact' };\n }\n return {\n compacted: true,\n summary: `Compacted (${result.tokensBefore ?? '?'} → ${result.tokensAfter ?? '?'} tokens)`,\n tokensBefore: result.tokensBefore,\n tokensAfter: result.tokensAfter,\n transcriptSummary: result.summary,\n };\n } catch (err) {\n const errorMessage = err instanceof Error ? err.message : String(err);\n return { compacted: false, summary: errorMessage };\n }\n }\n\n async exportSession(sessionKey: string, format: ExportFormat): Promise<string> {\n const params = new URLSearchParams({ format });\n const res = await gatewayFetch(\n this.baseUrl,\n `/api/sessions/${encodeURIComponent(sessionKey)}/export?${params.toString()}`,\n this.token,\n );\n if (!res.ok) {\n throw new Error(`Export failed (${res.status})`);\n }\n const json = (await res.json()) as { content?: string };\n return json.content ?? '';\n }\n\n async importSession(\n targetSessionKey: string,\n jsonContent: string,\n ): Promise<{ sessionKey: string; rowCount: number }> {\n const res = await gatewayFetch(\n this.baseUrl,\n '/api/sessions/import',\n this.token,\n { method: 'POST', body: JSON.stringify({ targetKey: targetSessionKey, content: jsonContent }) },\n );\n const json = (await res.json().catch(() => ({}))) as {\n ok?: boolean;\n error?: string;\n sessionKey?: string;\n rowCount?: number;\n };\n if (!res.ok || json.ok === false || !json.sessionKey) {\n throw new Error(json.error ?? `Import failed (${res.status})`);\n }\n return { sessionKey: json.sessionKey, rowCount: json.rowCount ?? 0 };\n }\n\n async createShare(\n sessionKey: string,\n request: TuiShareRequest,\n options?: { agentId?: string },\n ): Promise<TuiShareResult> {\n const res = await gatewayFetch(this.baseUrl, '/api/shares/auto', this.token, {\n method: 'POST',\n body: JSON.stringify({\n path: request.path,\n audience: request.audience,\n mode: request.mode,\n title: request.title,\n description: request.description,\n sessionKey,\n agentId: options?.agentId,\n }),\n });\n const json = (await res.json().catch(() => ({}))) as {\n ok?: boolean;\n error?: { message?: string };\n payload?: {\n share?: {\n kind?: string;\n title?: string;\n description?: string;\n shareUrl?: string;\n reachability?: string;\n reachabilityHint?: string | null;\n expiresAt?: string;\n maxViews?: number | null;\n };\n thumbnail?: { url?: string };\n routing?: { reason?: string; hint?: string };\n };\n };\n if (!res.ok || json.ok === false || !json.payload?.share?.shareUrl) {\n throw new Error(json.error?.message ?? `Share failed (${res.status})`);\n }\n const share = json.payload.share;\n return {\n kind: share.kind ?? 'share',\n shareUrl: share.shareUrl,\n title: share.title,\n description: share.description,\n thumbnailUrl: json.payload.thumbnail?.url,\n reachability: share.reachability,\n reachabilityHint: share.reachabilityHint,\n expiresAt: share.expiresAt,\n maxViews: share.maxViews,\n routingReason: json.payload.routing?.reason,\n routingHint: json.payload.routing?.hint,\n };\n }\n\n async btwQuery(sessionKey: string, question: string): Promise<{ text: string; error?: string }> {\n const res = await gatewayFetch(\n this.baseUrl,\n `/api/sessions/${encodeURIComponent(sessionKey)}/btw`,\n this.token,\n { method: 'POST', body: JSON.stringify({ question }) },\n );\n if (!res.ok) {\n return { text: '', error: `BTW failed (${res.status})` };\n }\n return (await res.json()) as { text: string; error?: string };\n }\n\n async forkSession(\n sourceSessionKey: string,\n targetSessionKey: string,\n ): Promise<{ sessionKey: string; rowCount: number }> {\n const res = await gatewayFetch(\n this.baseUrl,\n `/api/sessions/${encodeURIComponent(sourceSessionKey)}/fork`,\n this.token,\n { method: 'POST', body: JSON.stringify({ targetKey: targetSessionKey }) },\n );\n const json = (await res.json().catch(() => ({}))) as {\n ok?: boolean;\n error?: string;\n sessionKey?: string;\n rowCount?: number;\n };\n if (!res.ok || json.ok === false || !json.sessionKey) {\n throw new Error(json.error ?? `Fork failed (${res.status})`);\n }\n return { sessionKey: json.sessionKey, rowCount: json.rowCount ?? 0 };\n }\n\n async forkSessionAt(\n sourceSessionKey: string,\n targetSessionKey: string,\n entryId: string,\n ): Promise<{ sessionKey: string; rowCount: number }> {\n const throughRow = transcriptTreeEntryIdToRowNumber(entryId);\n if (throughRow == null) {\n throw new Error(`Invalid transcript entry: ${entryId}`);\n }\n const res = await gatewayFetch(\n this.baseUrl,\n `/api/sessions/${encodeURIComponent(sourceSessionKey)}/fork-row`,\n this.token,\n { method: 'POST', body: JSON.stringify({ targetKey: targetSessionKey, throughRow }) },\n );\n const json = (await res.json().catch(() => ({}))) as {\n ok?: boolean;\n error?: string;\n sessionKey?: string;\n rowCount?: number;\n };\n if (!res.ok || json.ok === false || !json.sessionKey) {\n throw new Error(json.error ?? `Fork failed (${res.status})`);\n }\n return { sessionKey: json.sessionKey, rowCount: json.rowCount ?? 0 };\n }\n\n async setTranscriptLabel(\n sessionKey: string,\n entryId: string,\n label: string | undefined,\n ): Promise<{ ok: boolean }> {\n const res = await gatewayFetch(\n this.baseUrl,\n `/api/sessions/${encodeURIComponent(sessionKey)}/transcript/label`,\n this.token,\n { method: 'POST', body: JSON.stringify({ targetId: entryId, label }) },\n );\n const json = (await res.json().catch(() => ({}))) as { ok?: boolean; error?: string };\n if (!res.ok || json.ok === false) {\n throw new Error(json.error ?? `Label update failed (${res.status})`);\n }\n return { ok: true };\n }\n\n async appendCustomEntry(\n sessionKey: string,\n customType: string,\n data?: unknown,\n ): Promise<{ ok: boolean }> {\n const res = await gatewayFetch(\n this.baseUrl,\n `/api/sessions/${encodeURIComponent(sessionKey)}/transcript/custom`,\n this.token,\n { method: 'POST', body: JSON.stringify({ customType, data }) },\n );\n const json = (await res.json().catch(() => ({}))) as { ok?: boolean; error?: string };\n if (!res.ok || json.ok === false) {\n throw new Error(json.error ?? `Custom entry append failed (${res.status})`);\n }\n return { ok: true };\n }\n\n async appendCustomMessage(\n sessionKey: string,\n message: {\n customType: string;\n content?: string | unknown[];\n display?: boolean;\n details?: unknown;\n },\n ): Promise<{ ok: boolean }> {\n const res = await gatewayFetch(\n this.baseUrl,\n `/api/sessions/${encodeURIComponent(sessionKey)}/transcript/custom-message`,\n this.token,\n { method: 'POST', body: JSON.stringify(message) },\n );\n const json = (await res.json().catch(() => ({}))) as { ok?: boolean; error?: string };\n if (!res.ok || json.ok === false) {\n throw new Error(json.error ?? `Custom message append failed (${res.status})`);\n }\n return { ok: true };\n }\n\n async appendBashExecution(\n sessionKey: string,\n entry: {\n command: string;\n output?: string;\n exitCode?: number | null;\n signal?: string | null;\n excludeFromContext?: boolean;\n truncated?: boolean;\n fullOutputPath?: string;\n },\n ): Promise<{ ok: boolean }> {\n const res = await gatewayFetch(\n this.baseUrl,\n `/api/sessions/${encodeURIComponent(sessionKey)}/transcript/bash`,\n this.token,\n { method: 'POST', body: JSON.stringify(entry) },\n );\n const json = (await res.json().catch(() => ({}))) as { ok?: boolean; error?: string };\n if (!res.ok || json.ok === false) {\n throw new Error(json.error ?? `Bash execution append failed (${res.status})`);\n }\n return { ok: true };\n }\n\n async patchSession(sessionKey: string, patch: Record<string, unknown>): Promise<void> {\n const res = await gatewayFetch(\n this.baseUrl,\n `/api/sessions/${encodeURIComponent(sessionKey)}/agent-config`,\n this.token,\n { method: 'PATCH', body: JSON.stringify(patch) },\n );\n const json = (await res.json().catch(() => ({}))) as { ok?: boolean; error?: string };\n if (!res.ok || json.ok === false) {\n throw new Error(json.error ?? `Session config patch failed (${res.status})`);\n }\n const projectId = typeof patch.projectId === 'string' ? patch.projectId.trim() : '';\n if (projectId) {\n const metaRes = await gatewayFetch(\n this.baseUrl,\n `/api/sessions/${encodeURIComponent(sessionKey)}`,\n this.token,\n { method: 'PATCH', body: JSON.stringify({ projectId }) },\n );\n const metaJson = (await metaRes.json().catch(() => ({}))) as { ok?: boolean; error?: string };\n if (!metaRes.ok || metaJson.ok === false) {\n throw new Error(metaJson.error ?? `Session project patch failed (${metaRes.status})`);\n }\n }\n }\n\n async renameSession(sessionKey: string, name: string): Promise<{ ok: boolean }> {\n try {\n const res = await gatewayFetch(\n this.baseUrl,\n `/api/sessions/${encodeURIComponent(sessionKey)}/rename`,\n this.token,\n { method: 'POST', body: JSON.stringify({ name }) },\n );\n return { ok: res.ok };\n } catch {\n return { ok: false };\n }\n }\n\n async deleteSession(sessionKey: string): Promise<{ ok: boolean }> {\n try {\n const res = await gatewayFetch(\n this.baseUrl,\n `/api/sessions/${encodeURIComponent(sessionKey)}`,\n this.token,\n { method: 'DELETE' },\n );\n if (!res.ok) return { ok: false };\n const json = (await res.json()) as { deleted?: boolean };\n return { ok: json.deleted !== false };\n } catch {\n return { ok: false };\n }\n }\n\n // ── Broadcast SSE (GET /api/events) ──\n\n private startEventStream(): void {\n this.eventAbort?.abort();\n this.eventAbort = new AbortController();\n\n const url = new URL(`${this.baseUrl}/api/events`);\n if (this.token) url.searchParams.set('token', this.token);\n\n const connect = async () => {\n try {\n const res = await fetch(url.toString(), {\n signal: this.eventAbort!.signal,\n headers: { Accept: 'text/event-stream' },\n });\n\n if (!res.ok || !res.body) {\n this.onDisconnected?.(`event stream error: ${res.status}`);\n this.scheduleReconnect();\n return;\n }\n\n this.onConnected?.();\n\n await consumeSSEStream(\n res.body,\n (sseEvent) => {\n if (sseEvent.event === 'connected') return;\n if (sseEvent.event === 'gap') {\n const gapData = parseSSEData(sseEvent.data) as {\n expected?: unknown;\n received?: unknown;\n } | null;\n if (\n gapData &&\n typeof gapData.expected === 'number' &&\n typeof gapData.received === 'number'\n ) {\n this.onGap?.({ expected: gapData.expected, received: gapData.received });\n }\n return;\n }\n const data = parseSSEData(sseEvent.data);\n if (data !== null) {\n this.onEvent?.(normalizeGatewaySseEvent({ event: sseEvent.event, data, source: 'broadcast' }));\n }\n },\n this.eventAbort!.signal,\n );\n\n // Stream ended normally\n if (!this.eventAbort?.signal.aborted) {\n this.onDisconnected?.('stream closed');\n this.scheduleReconnect();\n }\n } catch (error) {\n if (this.eventAbort?.signal.aborted) return;\n const errorMessage = error instanceof Error ? error.message : String(error);\n log.warn({ err: error, errorMessage }, `Event stream failed: ${errorMessage}`);\n this.onDisconnected?.(errorMessage);\n this.scheduleReconnect();\n }\n };\n\n void connect();\n }\n\n private scheduleReconnect(): void {\n if (this.eventAbort?.signal.aborted) return;\n setTimeout(() => {\n if (!this.eventAbort?.signal.aborted) {\n this.startEventStream();\n }\n }, 3000);\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"gateway-sse-backend.js","names":[],"sources":["../../../../src/tui/backends/gateway-sse-backend.ts"],"sourcesContent":["import { prependEnvelopeTimestamp } from '../../channels/envelope-timestamp.js';\nimport { parseModelRef } from '../../agent/models/selection.js';\nimport type { ExportFormat } from '../../session/types.js';\nimport type { TranscriptStoredRow } from '../../session/session-context-for-llm.js';\nimport { transcriptRowsToClientHistory } from '../../session/client-history.js';\nimport type { SessionTimelineItem } from '../../session/transcript-outline.js';\nimport { createLogger } from '../../utils/logger.js';\nimport { consumeSSEStream, parseSSEData } from '../sse-consumer.js';\nimport type {\n ChatSendOptions,\n HistoryMessage,\n TuiBackend,\n TuiCompactionResult,\n TuiEvent,\n TuiModelChoice,\n TuiShareRequest,\n TuiShareResult,\n TuiSessionStats,\n TuiSessionItem,\n TuiStartupResources,\n TuiTranscriptTreeEntry,\n TuiAgentInfo,\n TuiWorkspaceFileSearchEntry,\n TuiWorkflowRunStartRequest,\n TuiWorkflowRunStartResult,\n TuiStartupProjectResult,\n} from '../tui-backend.js';\nimport type { SessionInfo } from '../tui-types.js';\nimport { computeTuiSessionStats } from '../tui-session-stats.js';\nimport { buildTuiTranscriptTree, transcriptTreeEntryIdToRowNumber } from '../tui-transcript-tree.js';\nimport type { ReviewContext } from '../../review/review-git.js';\n\nconst log = createLogger('TUI:GatewaySSE');\n\ninterface GatewaySSEOptions {\n url: string;\n token?: string;\n}\n\nfunction normalizeGatewayModelChoice(model: TuiModelChoice): TuiModelChoice {\n const providerPrefix = `${model.provider}/`;\n const id = model.id.startsWith(providerPrefix)\n ? model.id.slice(providerPrefix.length)\n : model.id;\n return { ...model, id };\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return !!value && typeof value === 'object' && !Array.isArray(value);\n}\n\nexport function normalizeGatewaySseEvent(evt: TuiEvent): TuiEvent {\n if (evt.event !== 'agent.stream' || !isRecord(evt.data)) return evt;\n const inner = evt.data.event;\n if (!isRecord(inner) || typeof inner.type !== 'string' || !inner.type) return evt;\n return { event: inner.type, data: inner, source: evt.source };\n}\n\n/** Fetch wrapper that adds auth headers. */\nasync function gatewayFetch(\n baseUrl: string,\n path: string,\n token: string | undefined,\n init?: RequestInit,\n): Promise<Response> {\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n ...(token ? { Authorization: `Bearer ${token}` } : {}),\n ...(init?.headers as Record<string, string> | undefined),\n };\n return fetch(`${baseUrl}${path}`, { ...init, headers });\n}\n\n/**\n * TUI backend that communicates with a running xopc gateway via HTTP + SSE.\n *\n * - Agent streaming: `POST /api/agent` with `Accept: text/event-stream`\n * - Broadcast events: `GET /api/events` via long-lived SSE\n * - REST calls for sessions, models, etc.\n */\nexport class GatewaySseBackend implements TuiBackend {\n private readonly baseUrl: string;\n private readonly token: string | undefined;\n private eventAbort: AbortController | null = null;\n private chatAbort: AbortController | null = null;\n\n onEvent?: (evt: TuiEvent) => void;\n onConnected?: () => void;\n onDisconnected?: (reason: string) => void;\n onGap?: (info: { expected: number; received: number }) => void;\n\n constructor(opts: GatewaySSEOptions) {\n this.baseUrl = opts.url.replace(/\\/+$/, '');\n this.token = opts.token;\n }\n\n get connectionLabel(): string {\n return this.baseUrl;\n }\n\n start(): void {\n this.startEventStream();\n }\n\n stop(): void {\n this.eventAbort?.abort();\n this.eventAbort = null;\n this.chatAbort?.abort();\n this.chatAbort = null;\n }\n\n getActiveSignal(): AbortSignal | undefined {\n const signal = this.chatAbort?.signal;\n return signal && !signal.aborted ? signal : undefined;\n }\n\n // ── Agent chat (POST /api/agent → SSE response body) ──\n\n async sendChat(opts: ChatSendOptions): Promise<{ runId: string }> {\n this.chatAbort?.abort();\n this.chatAbort = new AbortController();\n const signal = this.chatAbort.signal;\n const runId = crypto.randomUUID();\n\n\n // Fire-and-forget: run the HTTP request + SSE consumption in background\n // so the TUI event loop stays responsive for keyboard input.\n void (async () => {\n try {\n const res = await gatewayFetch(this.baseUrl, '/api/agent', this.token, {\n method: 'POST',\n headers: { Accept: 'text/event-stream' },\n body: JSON.stringify({\n // Prepend envelope timestamp for regular messages so the model knows\n // the current date/time. Skip for slash commands — parseSlashCommand\n // requires lines starting with '/'.\n message: opts.message.trimStart().startsWith('/')\n ? opts.message\n : prependEnvelopeTimestamp(opts.message),\n channel: 'webchat',\n sessionKey: opts.sessionKey,\n attachments: opts.attachments,\n thinking: opts.thinking,\n }),\n signal,\n });\n\n if (!res.ok) {\n const body = (await res.json().catch(() => ({}))) as { error?: { message?: string } };\n this.onEvent?.({\n event: 'error',\n data: {\n type: 'error',\n runId,\n sessionKey: opts.sessionKey,\n timestamp: Date.now(),\n payload: { code: 'GATEWAY_ERROR', message: body.error?.message ?? `Gateway error: ${res.status}` },\n },\n source: 'agent-response',\n });\n return;\n }\n\n const contentType = res.headers.get('Content-Type') ?? '';\n\n if (contentType.includes('text/event-stream') && res.body) {\n await consumeSSEStream(\n res.body,\n (sseEvent) => {\n if (signal.aborted) return;\n const data = parseSSEData<Record<string, unknown>>(sseEvent.data);\n if (!data) return;\n this.onEvent?.({ event: sseEvent.event, data, source: 'agent-response' });\n },\n signal,\n );\n } else {\n const json = (await res.json()) as { ok?: boolean; payload?: { content?: string } };\n if (json.ok && json.payload?.content) {\n const messageId = `msg_${runId}_1`;\n const base = { runId, sessionKey: opts.sessionKey, timestamp: Date.now() };\n this.onEvent?.({ event: 'run_start', data: { ...base, type: 'run_start', payload: { channel: 'webchat' } }, source: 'agent-response' });\n this.onEvent?.({ event: 'assistant_message_start', data: { ...base, type: 'assistant_message_start', payload: { messageId } }, source: 'agent-response' });\n this.onEvent?.({ event: 'assistant_delta', data: { ...base, type: 'assistant_delta', payload: { messageId, delta: json.payload.content } }, source: 'agent-response' });\n this.onEvent?.({ event: 'assistant_message_end', data: { ...base, type: 'assistant_message_end', payload: { messageId } }, source: 'agent-response' });\n this.onEvent?.({ event: 'run_end', data: { ...base, type: 'run_end', payload: { status: 'success' } }, source: 'agent-response' });\n }\n }\n } catch (error) {\n if (signal.aborted) return;\n const errorMessage = error instanceof Error ? error.message : String(error);\n this.onEvent?.({\n event: 'error',\n data: { type: 'error', runId, sessionKey: opts.sessionKey, timestamp: Date.now(), payload: { code: 'NETWORK_ERROR', message: errorMessage } },\n source: 'agent-response',\n });\n }\n })();\n\n return { runId };\n }\n\n async searchWorkspaceFiles(\n sessionKey: string,\n query: string,\n options?: { limit?: number },\n ): Promise<TuiWorkspaceFileSearchEntry[]> {\n try {\n const params = new URLSearchParams();\n params.set('q', query);\n params.set('limit', String(options?.limit ?? 15));\n params.set('sessionKey', sessionKey);\n const res = await gatewayFetch(\n this.baseUrl,\n `/api/workspace/editor/files/search?${params.toString()}`,\n this.token,\n );\n if (!res.ok) return [];\n const json = (await res.json()) as {\n ok?: boolean;\n payload?: { entries?: TuiWorkspaceFileSearchEntry[] };\n };\n return json.payload?.entries ?? [];\n } catch (err) {\n const errorMessage = err instanceof Error ? err.message : String(err);\n log.warn({ err, sessionKey, errorMessage }, `Gateway workspace file search failed: ${errorMessage}`);\n return [];\n }\n }\n\n async getReviewContext(sessionKey: string): Promise<ReviewContext> {\n const params = new URLSearchParams({ sessionKey });\n const res = await gatewayFetch(this.baseUrl, `/api/review/context?${params.toString()}`, this.token);\n const json = (await res.json().catch(() => ({}))) as {\n ok?: boolean;\n payload?: ReviewContext;\n error?: { message?: string };\n };\n if (!res.ok || !json.ok || !json.payload) {\n throw new Error(json.error?.message ?? `Review context failed (${res.status})`);\n }\n return json.payload;\n }\n\n async startWorkflowRun(opts: TuiWorkflowRunStartRequest): Promise<TuiWorkflowRunStartResult> {\n const goal = opts.goal?.trim();\n const res = await gatewayFetch(this.baseUrl, '/api/workflows/runs', this.token, {\n method: 'POST',\n body: JSON.stringify({\n definitionId: opts.definitionId,\n agentId: opts.agentId,\n parentSessionKey: opts.sessionKey,\n source: { kind: 'chat', sessionKey: opts.sessionKey },\n ...(goal ? { goal } : {}),\n ...(opts.input !== undefined ? { input: opts.input } : {}),\n }),\n });\n const json = (await res.json().catch(() => ({}))) as {\n runId?: string;\n sessionKey?: string;\n error?: string;\n code?: string;\n };\n if (!res.ok || !json.runId || !json.sessionKey) {\n throw new Error(json.error ?? `Workflow start failed (${res.status})`);\n }\n return {\n runId: json.runId,\n sessionKey: json.sessionKey,\n definitionId: opts.definitionId,\n };\n }\n\n async resolveStartupProject(opts: {\n workspacePath: string;\n sessionKey: string;\n agentId: string;\n autoCreate?: boolean;\n }): Promise<TuiStartupProjectResult> {\n const res = await gatewayFetch(this.baseUrl, '/api/projects/resolve-workspace', this.token, {\n method: 'POST',\n body: JSON.stringify(opts),\n });\n const json = (await res.json().catch(() => ({}))) as TuiStartupProjectResult & { ok?: boolean; error?: string };\n if (!res.ok || json.ok === false) {\n throw new Error(json.error ?? `Project workspace resolve failed (${res.status})`);\n }\n return { project: json.project ?? null, created: json.created, reason: json.reason };\n }\n\n async resumeChat(opts: { sessionKey: string; runId: string }): Promise<{ ok: boolean; reason?: string }> {\n this.chatAbort?.abort();\n this.chatAbort = new AbortController();\n const signal = this.chatAbort.signal;\n this.onEvent?.({\n event: 'run_start',\n data: { type: 'run_start', runId: opts.runId, sessionKey: opts.sessionKey, timestamp: Date.now(), payload: { channel: 'webchat' } },\n source: 'agent-resume',\n });\n\n let res: Response;\n try {\n res = await gatewayFetch(this.baseUrl, '/api/agent/resume', this.token, {\n method: 'POST',\n headers: { Accept: 'text/event-stream' },\n body: JSON.stringify({ runId: opts.runId, sessionKey: opts.sessionKey }),\n signal,\n });\n } catch (error) {\n if (signal.aborted) return { ok: false, reason: 'resume aborted' };\n const errorMessage = error instanceof Error ? error.message : String(error);\n return { ok: false, reason: errorMessage };\n }\n\n if (!res.ok) {\n const body = (await res.json().catch(() => ({}))) as { error?: { message?: string } };\n return { ok: false, reason: body.error?.message ?? `Resume failed: ${res.status}` };\n }\n\n const contentType = res.headers.get('Content-Type') ?? '';\n if (!contentType.includes('text/event-stream') || !res.body) {\n return { ok: false, reason: 'Resume endpoint did not return an SSE stream' };\n }\n\n void (async () => {\n try {\n await consumeSSEStream(\n res.body,\n (sseEvent) => {\n if (signal.aborted) return;\n const data = parseSSEData<Record<string, unknown>>(sseEvent.data);\n if (!data) return;\n this.onEvent?.({ event: sseEvent.event, data, source: 'agent-resume' });\n },\n signal,\n );\n } catch (error) {\n if (signal.aborted) return;\n const errorMessage = error instanceof Error ? error.message : String(error);\n this.onEvent?.({\n event: 'error',\n data: { type: 'error', runId: opts.runId, sessionKey: opts.sessionKey, timestamp: Date.now(), payload: { code: 'NETWORK_ERROR', message: errorMessage } },\n source: 'agent-resume',\n });\n }\n })();\n\n return { ok: true };\n }\n\n async abortChat(opts: { sessionKey: string; runId: string }): Promise<{ ok: boolean }> {\n this.chatAbort?.abort();\n this.chatAbort = null;\n try {\n const res = await gatewayFetch(this.baseUrl, '/api/agent/abort', this.token, {\n method: 'POST',\n body: JSON.stringify({ runId: opts.runId }),\n });\n const json = (await res.json()) as { ok?: boolean };\n return { ok: json.ok ?? false };\n } catch {\n return { ok: false };\n }\n }\n\n async steerChat(opts: { sessionKey: string; message: string }): Promise<{ ok: boolean }> {\n try {\n const res = await gatewayFetch(this.baseUrl, '/api/agent/steer', this.token, {\n method: 'POST',\n body: JSON.stringify({ sessionKey: opts.sessionKey, message: opts.message }),\n });\n if (!res.ok) return { ok: false };\n const json = (await res.json()) as { ok?: boolean };\n return { ok: json.ok === true };\n } catch {\n return { ok: false };\n }\n }\n\n // ── REST helpers ──\n\n async getStartupResources(sessionKey: string): Promise<TuiStartupResources> {\n const empty: TuiStartupResources = { context: [], skills: [], workflows: [], connectors: [] };\n try {\n const res = await gatewayFetch(\n this.baseUrl,\n `/api/tui/startup-resources?sessionKey=${encodeURIComponent(sessionKey)}`,\n this.token,\n );\n if (!res.ok) return empty;\n const json = (await res.json()) as { payload?: Partial<TuiStartupResources> };\n return {\n context: Array.isArray(json.payload?.context) ? json.payload.context : [],\n skills: Array.isArray(json.payload?.skills) ? json.payload.skills : [],\n workflows: Array.isArray(json.payload?.workflows) ? json.payload.workflows : [],\n connectors: Array.isArray(json.payload?.connectors) ? json.payload.connectors : [],\n };\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n log.warn({ err: error, sessionKey, errorMessage }, `Failed to load startup resources: ${errorMessage}`);\n return empty;\n }\n }\n\n async loadHistory(opts: {\n sessionKey: string;\n limit?: number;\n }): Promise<{ messages: HistoryMessage[] }> {\n try {\n const res = await gatewayFetch(\n this.baseUrl,\n `/api/sessions/${encodeURIComponent(opts.sessionKey)}?include=transcriptRows`,\n this.token,\n );\n if (!res.ok) return { messages: [] };\n const json = (await res.json()) as {\n session?: { transcriptRows?: unknown[] };\n };\n const rows = Array.isArray(json.session?.transcriptRows)\n ? (json.session.transcriptRows as TranscriptStoredRow[])\n : [];\n return { messages: transcriptRowsToClientHistory(rows, { limit: opts.limit }) };\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n log.warn({ err: error, errorMessage }, `Failed to load history: ${errorMessage}`);\n return { messages: [] };\n }\n }\n\n async loadHistoryWindow(opts: {\n sessionKey: string;\n rowNumber: number;\n before?: number;\n after?: number;\n }) {\n const params = new URLSearchParams({\n rowNumber: String(opts.rowNumber),\n before: String(opts.before ?? 80),\n after: String(opts.after ?? 120),\n });\n try {\n const res = await gatewayFetch(\n this.baseUrl,\n `/api/sessions/${encodeURIComponent(opts.sessionKey)}/transcript/window?${params.toString()}`,\n this.token,\n );\n if (!res.ok) {\n return { messages: [], startRowNumber: 0, endRowNumber: 0, totalRows: 0 };\n }\n const json = (await res.json()) as {\n payload?: {\n messages?: unknown[];\n startRowNumber?: unknown;\n endRowNumber?: unknown;\n totalRows?: unknown;\n };\n };\n const payload = json.payload ?? {};\n return {\n messages: Array.isArray(payload.messages) ? (payload.messages as HistoryMessage[]) : [],\n startRowNumber: typeof payload.startRowNumber === 'number' ? payload.startRowNumber : 0,\n endRowNumber: typeof payload.endRowNumber === 'number' ? payload.endRowNumber : 0,\n totalRows: typeof payload.totalRows === 'number' ? payload.totalRows : 0,\n };\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n log.warn(\n { err: error, sessionKey: opts.sessionKey, rowNumber: opts.rowNumber, errorMessage },\n `Failed to load history window: ${errorMessage}`,\n );\n return { messages: [], startRowNumber: 0, endRowNumber: 0, totalRows: 0 };\n }\n }\n\n async loadTranscriptTree(sessionKey: string): Promise<TuiTranscriptTreeEntry[]> {\n try {\n const res = await gatewayFetch(\n this.baseUrl,\n `/api/sessions/${encodeURIComponent(sessionKey)}?include=transcriptRows`,\n this.token,\n );\n if (!res.ok) return [];\n const json = (await res.json()) as {\n session?: { transcriptRows?: unknown[] };\n };\n const rows = Array.isArray(json.session?.transcriptRows)\n ? (json.session.transcriptRows as TranscriptStoredRow[])\n : [];\n return buildTuiTranscriptTree(rows);\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n log.warn({ err: error, sessionKey, errorMessage }, `Failed to load transcript tree: ${errorMessage}`);\n return [];\n }\n }\n\n async loadTimeline(sessionKey: string): Promise<SessionTimelineItem[]> {\n try {\n const res = await gatewayFetch(\n this.baseUrl,\n `/api/sessions/${encodeURIComponent(sessionKey)}/timeline`,\n this.token,\n );\n if (!res.ok) return [];\n const json = (await res.json()) as { items?: unknown[] };\n return Array.isArray(json.items) ? (json.items as SessionTimelineItem[]) : [];\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n log.warn({ err: error, sessionKey, errorMessage }, `Failed to load timeline: ${errorMessage}`);\n return [];\n }\n }\n\n async getSessionStats(sessionKey: string): Promise<TuiSessionStats> {\n try {\n const res = await gatewayFetch(\n this.baseUrl,\n `/api/sessions/${encodeURIComponent(sessionKey)}?include=transcriptRows`,\n this.token,\n );\n if (!res.ok) return computeTuiSessionStats([]);\n const json = (await res.json()) as {\n session?: { transcriptRows?: unknown[] };\n };\n const rows = Array.isArray(json.session?.transcriptRows)\n ? (json.session.transcriptRows as TranscriptStoredRow[])\n : [];\n return computeTuiSessionStats(rows);\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n log.warn({ err: error, sessionKey, errorMessage }, `Failed to load session stats: ${errorMessage}`);\n return computeTuiSessionStats([]);\n }\n }\n\n async listSessions(): Promise<TuiSessionItem[]> {\n try {\n const res = await gatewayFetch(this.baseUrl, '/api/sessions', this.token);\n if (!res.ok) return [];\n const json = (await res.json()) as {\n items?: Array<{\n key: string;\n name?: string;\n updatedAt?: string;\n estimatedTokens?: number;\n messageCount?: number;\n customData?: Record<string, unknown>;\n cwd?: string;\n }>;\n };\n return (json.items ?? []).map((s) => ({\n key: s.key,\n displayName: s.name,\n updatedAt: s.updatedAt ? Date.parse(s.updatedAt) : undefined,\n totalTokens: s.estimatedTokens ?? null,\n messageCount: typeof s.messageCount === 'number' ? s.messageCount : undefined,\n model:\n typeof s.customData?.model === 'string'\n ? s.customData.model\n : typeof s.customData?.modelRef === 'string'\n ? s.customData.modelRef\n : null,\n forkedFromSessionKey:\n typeof s.customData?.forkedFromSessionKey === 'string'\n ? s.customData.forkedFromSessionKey\n : undefined,\n cwd: typeof s.cwd === 'string' ? s.cwd : undefined,\n }));\n } catch {\n return [];\n }\n }\n\n async listAgents(): Promise<TuiAgentInfo[]> {\n const agents = new Map<string, TuiAgentInfo>();\n try {\n const res = await gatewayFetch(this.baseUrl, '/api/agents', this.token);\n if (res.ok) {\n const json = (await res.json()) as {\n payload?: { agents?: Array<{ id?: unknown; name?: unknown }> };\n };\n for (const row of json.payload?.agents ?? []) {\n if (typeof row.id !== 'string' || !row.id.trim()) continue;\n const id = row.id.trim().toLowerCase();\n agents.set(id, {\n id,\n enabled: true,\n ...(typeof row.name === 'string' && row.name.trim()\n ? { displayName: row.name.trim() }\n : {}),\n });\n }\n }\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n log.warn({ err: error, errorMessage }, `Failed to load agents: ${errorMessage}`);\n }\n return [...agents.values()].sort((a, b) => a.id.localeCompare(b.id));\n }\n\n async setTuiDefaultAgent(agentId: string): Promise<{ agentId: string }> {\n const target = agentId.trim().toLowerCase();\n const res = await gatewayFetch(this.baseUrl, '/api/config', this.token, {\n method: 'PATCH',\n body: JSON.stringify({ tui: { defaultAgent: target } }),\n });\n const json = (await res.json().catch(() => ({}))) as {\n ok?: boolean;\n error?: { message?: string } | string;\n payload?: { config?: { tui?: { defaultAgent?: unknown } } };\n };\n if (!res.ok || json.ok === false) {\n const error =\n typeof json.error === 'string'\n ? json.error\n : json.error?.message;\n throw new Error(error ?? `TUI default agent update failed (${res.status})`);\n }\n const saved = json.payload?.config?.tui?.defaultAgent;\n return { agentId: typeof saved === 'string' && saved.trim() ? saved.trim().toLowerCase() : target };\n }\n\n async getSessionInfo(sessionKey: string): Promise<SessionInfo> {\n const out: SessionInfo = {};\n try {\n const sessionPath = `/api/sessions/${encodeURIComponent(sessionKey)}`;\n const [sessionRes, agentCfgRes] = await Promise.all([\n gatewayFetch(this.baseUrl, sessionPath, this.token),\n gatewayFetch(this.baseUrl, `${sessionPath}/agent-config`, this.token),\n ]);\n\n type SessionRow = {\n name?: string;\n estimatedTokens?: number;\n customData?: Record<string, unknown>;\n };\n let session: SessionRow | undefined;\n\n if (sessionRes.ok) {\n const json = (await sessionRes.json()) as { session?: SessionRow };\n session = json.session;\n if (session) {\n if (session.name) out.displayName = session.name;\n if (session.estimatedTokens != null) out.totalTokens = session.estimatedTokens;\n }\n }\n\n if (agentCfgRes.ok) {\n const json = (await agentCfgRes.json()) as {\n ok?: boolean;\n payload?: {\n model?: string;\n thinkingLevel?: string;\n reasoningLevel?: string;\n verboseLevel?: string;\n effectiveWorkspacePath?: string;\n workingDirectoryLocked?: boolean;\n };\n };\n const p = json.payload;\n if (p?.model && typeof p.model === 'string') {\n const parsed = parseModelRef(p.model);\n if (parsed) {\n out.model = parsed.model;\n out.modelProvider = parsed.provider;\n } else {\n out.model = p.model;\n }\n }\n if (p?.thinkingLevel && typeof p.thinkingLevel === 'string') {\n out.thinkingLevel = p.thinkingLevel;\n }\n if (p?.reasoningLevel && typeof p.reasoningLevel === 'string') {\n out.reasoningLevel = p.reasoningLevel;\n }\n if (p?.verboseLevel && typeof p.verboseLevel === 'string') {\n out.verboseLevel = p.verboseLevel;\n }\n if (p?.effectiveWorkspacePath && typeof p.effectiveWorkspacePath === 'string') {\n out.effectiveWorkspacePath = p.effectiveWorkspacePath;\n }\n if (typeof p?.workingDirectoryLocked === 'boolean') {\n out.workingDirectoryLocked = p.workingDirectoryLocked;\n }\n }\n\n if (!out.model && session?.customData) {\n const cd = session.customData;\n const ref =\n typeof cd.model === 'string'\n ? cd.model\n : typeof cd.modelRef === 'string'\n ? cd.modelRef\n : undefined;\n if (ref) {\n const parsed = parseModelRef(ref);\n if (parsed) {\n out.model = parsed.model;\n out.modelProvider = parsed.provider;\n } else {\n out.model = ref;\n }\n }\n if (!out.modelProvider && typeof cd.modelProvider === 'string') {\n out.modelProvider = cd.modelProvider;\n }\n }\n\n if (out.totalTokens != null) {\n const models = await this.listModels();\n const match = models.find(\n (m) =>\n m.id === out.model &&\n (!out.modelProvider || m.provider === out.modelProvider),\n );\n const contextWindow = match?.contextWindow ?? 128_000;\n out.contextWindow = contextWindow;\n out.contextUsagePercent =\n contextWindow > 0\n ? Math.min(100, Math.round((out.totalTokens / contextWindow) * 100))\n : null;\n }\n\n return out;\n } catch {\n return {};\n }\n }\n\n async listModels(): Promise<TuiModelChoice[]> {\n try {\n const res = await gatewayFetch(this.baseUrl, '/api/models', this.token);\n if (!res.ok) return [];\n const json = (await res.json()) as {\n ok?: boolean;\n payload?: { models?: TuiModelChoice[] };\n };\n return (json.payload?.models ?? []).map(normalizeGatewayModelChoice);\n } catch {\n return [];\n }\n }\n\n async resetSession(sessionKey: string): Promise<void> {\n await gatewayFetch(\n this.baseUrl,\n `/api/sessions/${encodeURIComponent(sessionKey)}/reset`,\n this.token,\n { method: 'POST' },\n ).catch(() => {});\n }\n\n async compactSession(\n sessionKey: string,\n options?: { force?: boolean; instructions?: string },\n ): Promise<TuiCompactionResult> {\n try {\n const res = await gatewayFetch(\n this.baseUrl,\n `/api/sessions/${encodeURIComponent(sessionKey)}/compaction/run`,\n this.token,\n {\n method: 'POST',\n body: JSON.stringify({\n force: options?.force ?? true,\n instructions: options?.instructions,\n }),\n },\n );\n if (!res.ok) {\n return { compacted: false, summary: `Compaction failed (${res.status})` };\n }\n const json = (await res.json()) as {\n ok?: boolean;\n payload?: {\n result?: {\n compacted?: boolean;\n summary?: string;\n tokensBefore?: number;\n tokensAfter?: number;\n };\n };\n };\n const result = json.payload?.result;\n if (!result?.compacted) {\n return { compacted: false, summary: 'Nothing to compact' };\n }\n return {\n compacted: true,\n summary: `Compacted (${result.tokensBefore ?? '?'} → ${result.tokensAfter ?? '?'} tokens)`,\n tokensBefore: result.tokensBefore,\n tokensAfter: result.tokensAfter,\n transcriptSummary: result.summary,\n };\n } catch (err) {\n const errorMessage = err instanceof Error ? err.message : String(err);\n return { compacted: false, summary: errorMessage };\n }\n }\n\n async exportSession(sessionKey: string, format: ExportFormat): Promise<string> {\n const params = new URLSearchParams({ format });\n const res = await gatewayFetch(\n this.baseUrl,\n `/api/sessions/${encodeURIComponent(sessionKey)}/export?${params.toString()}`,\n this.token,\n );\n if (!res.ok) {\n throw new Error(`Export failed (${res.status})`);\n }\n const json = (await res.json()) as { content?: string };\n return json.content ?? '';\n }\n\n async importSession(\n targetSessionKey: string,\n jsonContent: string,\n ): Promise<{ sessionKey: string; rowCount: number }> {\n const res = await gatewayFetch(\n this.baseUrl,\n '/api/sessions/import',\n this.token,\n { method: 'POST', body: JSON.stringify({ targetKey: targetSessionKey, content: jsonContent }) },\n );\n const json = (await res.json().catch(() => ({}))) as {\n ok?: boolean;\n error?: string;\n sessionKey?: string;\n rowCount?: number;\n };\n if (!res.ok || json.ok === false || !json.sessionKey) {\n throw new Error(json.error ?? `Import failed (${res.status})`);\n }\n return { sessionKey: json.sessionKey, rowCount: json.rowCount ?? 0 };\n }\n\n async createShare(\n sessionKey: string,\n request: TuiShareRequest,\n options?: { agentId?: string },\n ): Promise<TuiShareResult> {\n const res = await gatewayFetch(this.baseUrl, '/api/shares/auto', this.token, {\n method: 'POST',\n body: JSON.stringify({\n path: request.path,\n audience: request.audience,\n mode: request.mode,\n title: request.title,\n description: request.description,\n sessionKey,\n agentId: options?.agentId,\n }),\n });\n const json = (await res.json().catch(() => ({}))) as {\n ok?: boolean;\n error?: { message?: string };\n payload?: {\n share?: {\n kind?: string;\n title?: string;\n description?: string;\n shareUrl?: string;\n reachability?: string;\n reachabilityHint?: string | null;\n expiresAt?: string;\n maxViews?: number | null;\n };\n thumbnail?: { url?: string };\n routing?: { reason?: string; hint?: string };\n };\n };\n if (!res.ok || json.ok === false || !json.payload?.share?.shareUrl) {\n throw new Error(json.error?.message ?? `Share failed (${res.status})`);\n }\n const share = json.payload.share;\n return {\n kind: share.kind ?? 'share',\n shareUrl: share.shareUrl,\n title: share.title,\n description: share.description,\n thumbnailUrl: json.payload.thumbnail?.url,\n reachability: share.reachability,\n reachabilityHint: share.reachabilityHint,\n expiresAt: share.expiresAt,\n maxViews: share.maxViews,\n routingReason: json.payload.routing?.reason,\n routingHint: json.payload.routing?.hint,\n };\n }\n\n async btwQuery(sessionKey: string, question: string): Promise<{ text: string; error?: string }> {\n const res = await gatewayFetch(\n this.baseUrl,\n `/api/sessions/${encodeURIComponent(sessionKey)}/btw`,\n this.token,\n { method: 'POST', body: JSON.stringify({ question }) },\n );\n if (!res.ok) {\n return { text: '', error: `BTW failed (${res.status})` };\n }\n return (await res.json()) as { text: string; error?: string };\n }\n\n async forkSession(\n sourceSessionKey: string,\n targetSessionKey: string,\n ): Promise<{ sessionKey: string; rowCount: number }> {\n const res = await gatewayFetch(\n this.baseUrl,\n `/api/sessions/${encodeURIComponent(sourceSessionKey)}/fork`,\n this.token,\n { method: 'POST', body: JSON.stringify({ targetKey: targetSessionKey }) },\n );\n const json = (await res.json().catch(() => ({}))) as {\n ok?: boolean;\n error?: string;\n sessionKey?: string;\n rowCount?: number;\n };\n if (!res.ok || json.ok === false || !json.sessionKey) {\n throw new Error(json.error ?? `Fork failed (${res.status})`);\n }\n return { sessionKey: json.sessionKey, rowCount: json.rowCount ?? 0 };\n }\n\n async forkSessionAt(\n sourceSessionKey: string,\n targetSessionKey: string,\n entryId: string,\n ): Promise<{ sessionKey: string; rowCount: number }> {\n const throughRow = transcriptTreeEntryIdToRowNumber(entryId);\n if (throughRow == null) {\n throw new Error(`Invalid transcript entry: ${entryId}`);\n }\n const res = await gatewayFetch(\n this.baseUrl,\n `/api/sessions/${encodeURIComponent(sourceSessionKey)}/fork-row`,\n this.token,\n { method: 'POST', body: JSON.stringify({ targetKey: targetSessionKey, throughRow }) },\n );\n const json = (await res.json().catch(() => ({}))) as {\n ok?: boolean;\n error?: string;\n sessionKey?: string;\n rowCount?: number;\n };\n if (!res.ok || json.ok === false || !json.sessionKey) {\n throw new Error(json.error ?? `Fork failed (${res.status})`);\n }\n return { sessionKey: json.sessionKey, rowCount: json.rowCount ?? 0 };\n }\n\n async setTranscriptLabel(\n sessionKey: string,\n entryId: string,\n label: string | undefined,\n ): Promise<{ ok: boolean }> {\n const res = await gatewayFetch(\n this.baseUrl,\n `/api/sessions/${encodeURIComponent(sessionKey)}/transcript/label`,\n this.token,\n { method: 'POST', body: JSON.stringify({ targetId: entryId, label }) },\n );\n const json = (await res.json().catch(() => ({}))) as { ok?: boolean; error?: string };\n if (!res.ok || json.ok === false) {\n throw new Error(json.error ?? `Label update failed (${res.status})`);\n }\n return { ok: true };\n }\n\n async appendCustomEntry(\n sessionKey: string,\n customType: string,\n data?: unknown,\n ): Promise<{ ok: boolean }> {\n const res = await gatewayFetch(\n this.baseUrl,\n `/api/sessions/${encodeURIComponent(sessionKey)}/transcript/custom`,\n this.token,\n { method: 'POST', body: JSON.stringify({ customType, data }) },\n );\n const json = (await res.json().catch(() => ({}))) as { ok?: boolean; error?: string };\n if (!res.ok || json.ok === false) {\n throw new Error(json.error ?? `Custom entry append failed (${res.status})`);\n }\n return { ok: true };\n }\n\n async appendCustomMessage(\n sessionKey: string,\n message: {\n customType: string;\n content?: string | unknown[];\n display?: boolean;\n details?: unknown;\n },\n ): Promise<{ ok: boolean }> {\n const res = await gatewayFetch(\n this.baseUrl,\n `/api/sessions/${encodeURIComponent(sessionKey)}/transcript/custom-message`,\n this.token,\n { method: 'POST', body: JSON.stringify(message) },\n );\n const json = (await res.json().catch(() => ({}))) as { ok?: boolean; error?: string };\n if (!res.ok || json.ok === false) {\n throw new Error(json.error ?? `Custom message append failed (${res.status})`);\n }\n return { ok: true };\n }\n\n async appendBashExecution(\n sessionKey: string,\n entry: {\n command: string;\n output?: string;\n exitCode?: number | null;\n signal?: string | null;\n excludeFromContext?: boolean;\n truncated?: boolean;\n fullOutputPath?: string;\n },\n ): Promise<{ ok: boolean }> {\n const res = await gatewayFetch(\n this.baseUrl,\n `/api/sessions/${encodeURIComponent(sessionKey)}/transcript/bash`,\n this.token,\n { method: 'POST', body: JSON.stringify(entry) },\n );\n const json = (await res.json().catch(() => ({}))) as { ok?: boolean; error?: string };\n if (!res.ok || json.ok === false) {\n throw new Error(json.error ?? `Bash execution append failed (${res.status})`);\n }\n return { ok: true };\n }\n\n async patchSession(sessionKey: string, patch: Record<string, unknown>): Promise<void> {\n const res = await gatewayFetch(\n this.baseUrl,\n `/api/sessions/${encodeURIComponent(sessionKey)}/agent-config`,\n this.token,\n { method: 'PATCH', body: JSON.stringify(patch) },\n );\n const json = (await res.json().catch(() => ({}))) as { ok?: boolean; error?: string };\n if (!res.ok || json.ok === false) {\n throw new Error(json.error ?? `Session config patch failed (${res.status})`);\n }\n const projectId = typeof patch.projectId === 'string' ? patch.projectId.trim() : '';\n if (projectId) {\n const metaRes = await gatewayFetch(\n this.baseUrl,\n `/api/sessions/${encodeURIComponent(sessionKey)}`,\n this.token,\n { method: 'PATCH', body: JSON.stringify({ projectId }) },\n );\n const metaJson = (await metaRes.json().catch(() => ({}))) as { ok?: boolean; error?: string };\n if (!metaRes.ok || metaJson.ok === false) {\n throw new Error(metaJson.error ?? `Session project patch failed (${metaRes.status})`);\n }\n }\n }\n\n async renameSession(sessionKey: string, name: string): Promise<{ ok: boolean }> {\n try {\n const res = await gatewayFetch(\n this.baseUrl,\n `/api/sessions/${encodeURIComponent(sessionKey)}/rename`,\n this.token,\n { method: 'POST', body: JSON.stringify({ name }) },\n );\n return { ok: res.ok };\n } catch {\n return { ok: false };\n }\n }\n\n async deleteSession(sessionKey: string): Promise<{ ok: boolean }> {\n try {\n const res = await gatewayFetch(\n this.baseUrl,\n `/api/sessions/${encodeURIComponent(sessionKey)}`,\n this.token,\n { method: 'DELETE' },\n );\n if (!res.ok) return { ok: false };\n const json = (await res.json()) as { deleted?: boolean };\n return { ok: json.deleted !== false };\n } catch {\n return { ok: false };\n }\n }\n\n // ── Broadcast SSE (GET /api/events) ──\n\n private startEventStream(): void {\n this.eventAbort?.abort();\n this.eventAbort = new AbortController();\n\n const url = new URL(`${this.baseUrl}/api/events`);\n if (this.token) url.searchParams.set('token', this.token);\n\n const connect = async () => {\n try {\n const res = await fetch(url.toString(), {\n signal: this.eventAbort!.signal,\n headers: { Accept: 'text/event-stream' },\n });\n\n if (!res.ok || !res.body) {\n this.onDisconnected?.(`event stream error: ${res.status}`);\n this.scheduleReconnect();\n return;\n }\n\n this.onConnected?.();\n\n await consumeSSEStream(\n res.body,\n (sseEvent) => {\n if (sseEvent.event === 'connected') return;\n if (sseEvent.event === 'gap') {\n const gapData = parseSSEData(sseEvent.data) as {\n expected?: unknown;\n received?: unknown;\n } | null;\n if (\n gapData &&\n typeof gapData.expected === 'number' &&\n typeof gapData.received === 'number'\n ) {\n this.onGap?.({ expected: gapData.expected, received: gapData.received });\n }\n return;\n }\n const data = parseSSEData(sseEvent.data);\n if (data !== null) {\n this.onEvent?.(normalizeGatewaySseEvent({ event: sseEvent.event, data, source: 'broadcast' }));\n }\n },\n this.eventAbort!.signal,\n );\n\n // Stream ended normally\n if (!this.eventAbort?.signal.aborted) {\n this.onDisconnected?.('stream closed');\n this.scheduleReconnect();\n }\n } catch (error) {\n if (this.eventAbort?.signal.aborted) return;\n const errorMessage = error instanceof Error ? error.message : String(error);\n log.warn({ err: error, errorMessage }, `Event stream failed: ${errorMessage}`);\n this.onDisconnected?.(errorMessage);\n this.scheduleReconnect();\n }\n };\n\n void connect();\n }\n\n private scheduleReconnect(): void {\n if (this.eventAbort?.signal.aborted) return;\n setTimeout(() => {\n if (!this.eventAbort?.signal.aborted) {\n this.startEventStream();\n }\n }, 3000);\n }\n}\n"],"mappings":"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"}