@xopcai/xopc 0.0.118 → 0.0.120

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 (503) hide show
  1. package/README.md +2 -1
  2. package/README.zh-CN.md +2 -1
  3. package/dist/browser-ext/manifest.json +1 -1
  4. package/dist/extensions/telegram/xopc.extension.json +1 -1
  5. package/dist/gateway/static/root/assets/{agent-avatar-dicebear-dzUrQoeZ.js → agent-avatar-dicebear-APTlX9Sq.js} +1 -1
  6. package/dist/gateway/static/root/assets/agents-CFW_FS_V.js +2 -0
  7. package/dist/gateway/static/root/assets/app-management-settings-panel-DTKc5HHT.js +1 -0
  8. package/dist/gateway/static/root/assets/appearance-settings-BTciFrE9.js +1 -0
  9. package/dist/gateway/static/root/assets/{apps-page--wMEL00f.js → apps-page-DT52OrbM.js} +1 -1
  10. package/dist/gateway/static/root/assets/{archive-plugin-Cki4SfU2.js → archive-plugin-CiHaUMII.js} +1 -1
  11. package/dist/gateway/static/root/assets/{attachment-load-D-KnS2Do.js → attachment-load-t4gSrNjL.js} +1 -1
  12. package/dist/gateway/static/root/assets/automation-suggestion-card-CtysjSoQ.js +1 -0
  13. package/dist/gateway/static/root/assets/automations-page-B2YvT3ES.js +1 -0
  14. package/dist/gateway/static/root/assets/{binary-plugins-D2sgvJja.js → binary-plugins-BAbSldW5.js} +1 -1
  15. package/dist/gateway/static/root/assets/{block-editor-DIq-4Gvb.js → block-editor-BNr_82xl.js} +28 -28
  16. package/dist/gateway/static/root/assets/browser-settings-page-BQEXPhDU.js +8 -0
  17. package/dist/gateway/static/root/assets/capability-presets-api-tzD702Gg.js +1 -0
  18. package/dist/gateway/static/root/assets/capability-presets-settings-panel-AGhTueAc.js +1 -0
  19. package/dist/gateway/static/root/assets/channel-recipient-api-DL_KzwGE.js +1 -0
  20. package/dist/gateway/static/root/assets/channels-settings-DRTutLlN.js +1 -0
  21. package/dist/gateway/static/root/assets/cn-BQ_8x0bT.js +1 -0
  22. package/dist/gateway/static/root/assets/connectors-page-DneJVuge.js +2 -0
  23. package/dist/gateway/static/root/assets/cron-expression-B3B1eqnr.js +2 -0
  24. package/dist/gateway/static/root/assets/dreaming-settings-BEwWA1yf.js +1 -0
  25. package/dist/gateway/static/root/assets/{extension-debug-page-DYu1KaFQ.js → extension-debug-page-Dl2kO0Sf.js} +1 -1
  26. package/dist/gateway/static/root/assets/{extension-page-B3W6QwlZ.js → extension-page-DmbLPsx_.js} +1 -1
  27. package/dist/gateway/static/root/assets/{extension-settings-page-D7VQ-cxE.js → extension-settings-page-BS2rx40e.js} +1 -1
  28. package/dist/gateway/static/root/assets/{fetch-B7xDPu-R.js → fetch-B3ME5Eri.js} +1 -1
  29. package/dist/gateway/static/root/assets/format-cron-label-arqgGlVV.js +1 -0
  30. package/dist/gateway/static/root/assets/{gateway-config-api-BTBLSeUu.js → gateway-config-api-DI9_BBTo.js} +1 -1
  31. package/dist/gateway/static/root/assets/gateway-settings-DAFI_T0W.js +1 -0
  32. package/dist/gateway/static/root/assets/{gateway-startup-retry-CYj9FWCp.js → gateway-startup-retry-CSZQTz6K.js} +1 -1
  33. package/dist/gateway/static/root/assets/goal-detail-page-DLuz4jC9.js +1 -0
  34. package/dist/gateway/static/root/assets/{goals-config-api-CQQgzPr3.js → goals-config-api-Bhzqrp2w.js} +1 -1
  35. package/dist/gateway/static/root/assets/{goals-page-BHitvJAv.js → goals-page-DTAfv9Ft.js} +2 -2
  36. package/dist/gateway/static/root/assets/goals-settings-CWN2iirQ.js +1 -0
  37. package/dist/gateway/static/root/assets/heartbeat-settings-CkkkHvOi.js +1 -0
  38. package/dist/gateway/static/root/assets/index-CnjzMw5i.js +191 -0
  39. package/dist/gateway/static/root/assets/index-E1QinYKp.css +1 -0
  40. package/dist/gateway/static/root/assets/keyboard-shortcuts-settings-kMp08SlX.js +1 -0
  41. package/dist/gateway/static/root/assets/{locale-store-DjbfSsfA.js → locale-store-Ba72bFmP.js} +1 -1
  42. package/dist/gateway/static/root/assets/{logs-page-C2Uqvae9.js → logs-page-CDXDlS_W.js} +2 -2
  43. package/dist/gateway/static/root/assets/{markdown-split-BwOFrJ2E.js → markdown-split-Bc0w40vz.js} +1 -1
  44. package/dist/gateway/static/root/assets/{media-plugins-Cnz6Q5G6.js → media-plugins-DJ_HvgIy.js} +1 -1
  45. package/dist/gateway/static/root/assets/messages-CISb1HLv.js +3 -0
  46. package/dist/gateway/static/root/assets/models-hub-panel-BTwxMIgZ.js +2 -0
  47. package/dist/gateway/static/root/assets/note-detail-page-BBfOeB0m.js +2 -0
  48. package/dist/gateway/static/root/assets/{note-image-lightbox-B-Svpmza.js → note-image-lightbox-4zntqpZq.js} +1 -1
  49. package/dist/gateway/static/root/assets/notes-page-VocWOjoK.js +1 -0
  50. package/dist/gateway/static/root/assets/{preview-open-alternatives-Bss4TiwP.js → preview-open-alternatives-BbA7sRd_.js} +1 -1
  51. package/dist/gateway/static/root/assets/remote-access-hub-CXwjuD_Q.js +1 -0
  52. package/dist/gateway/static/root/assets/{save-bar-controls-BRNjdgKq.js → save-bar-controls-Dividh61.js} +1 -1
  53. package/dist/gateway/static/root/assets/schedule-field-pRheF2CO.js +1 -0
  54. package/dist/gateway/static/root/assets/{schema-form-Dub9sy8r.js → schema-form-D6PiPxfr.js} +1 -1
  55. package/dist/gateway/static/root/assets/sessions-page-CpcVySQK.js +1 -0
  56. package/dist/gateway/static/root/assets/settings-advanced-gate-BVy_TawT.js +1 -0
  57. package/dist/gateway/static/root/assets/{settings-collapsible-section-BeFLavGi.js → settings-collapsible-section-BMCOfuE_.js} +1 -1
  58. package/dist/gateway/static/root/assets/settings-form-section-DBkGwpIN.js +1 -0
  59. package/dist/gateway/static/root/assets/settings-page-CZpNyCWn.js +1 -0
  60. package/dist/gateway/static/root/assets/settings-page-layout-NxoW5Y57.js +1 -0
  61. package/dist/gateway/static/root/assets/setup-status-panel-MVHLLu_a.js +1 -0
  62. package/dist/gateway/static/root/assets/{share-preview-page-C8glrdqe.js → share-preview-page-B0suFCfj.js} +1 -1
  63. package/dist/gateway/static/root/assets/shares-settings-C6DBbQGo.js +1 -0
  64. package/dist/gateway/static/root/assets/skill-reload-api-6hJmhwSn.js +1 -0
  65. package/dist/gateway/static/root/assets/skills-page-Im1MA0Iw.js +2 -0
  66. package/dist/gateway/static/root/assets/system-settings-panel-CrmEnyX4.js +1 -0
  67. package/dist/gateway/static/root/assets/{theme-store-CD2wtgZV.js → theme-store-Bt6vAkSB.js} +1 -1
  68. package/dist/gateway/static/root/assets/typed-models-lib-BAsGn25g.js +1 -0
  69. package/dist/gateway/static/root/assets/{use-channel-catalog-DqlWTsDb.js → use-channel-catalog-C7vcAoGb.js} +1 -1
  70. package/dist/gateway/static/root/assets/user-profile-settings-panel-QAQWGelF.js +1 -0
  71. package/dist/gateway/static/root/assets/utils-Dl9efgnV.js +1 -0
  72. package/dist/gateway/static/root/assets/{voice-api-key-field-C73IVZeC.js → voice-api-key-field-D-6XueTv.js} +1 -1
  73. package/dist/gateway/static/root/assets/{voice-player-store-C_ArLJPM.js → voice-player-store-CMC5NOJp.js} +1 -1
  74. package/dist/gateway/static/root/assets/workflow-run-setup-panel-DVPllR4k.js +3 -0
  75. package/dist/gateway/static/root/assets/workflows-page-B94WISTW.js +18 -0
  76. package/dist/gateway/static/root/index.html +8 -9
  77. package/dist/package.js +1 -1
  78. package/dist/src/agent/agent-manager.d.ts +4 -5
  79. package/dist/src/agent/agent-manager.js +4 -8
  80. package/dist/src/agent/agent-manager.js.map +1 -1
  81. package/dist/src/agent/context/workspace-templates/AGENTS.md +3 -2
  82. package/dist/src/agent/embedded/run-for-session.js +102 -14
  83. package/dist/src/agent/embedded/run-for-session.js.map +1 -1
  84. package/dist/src/agent/fallback/candidates.d.ts +0 -8
  85. package/dist/src/agent/fallback/candidates.js.map +1 -1
  86. package/dist/src/agent/index.js +1 -1
  87. package/dist/src/agent/lifecycle/handlers/compaction.d.ts +1 -3
  88. package/dist/src/agent/lifecycle/handlers/compaction.js +1 -16
  89. package/dist/src/agent/lifecycle/handlers/compaction.js.map +1 -1
  90. package/dist/src/agent/lifecycle/progress.d.ts +0 -1
  91. package/dist/src/agent/lifecycle/progress.js +1 -6
  92. package/dist/src/agent/lifecycle/progress.js.map +1 -1
  93. package/dist/src/agent/lifecycle/timeout-wrapper.d.ts +1 -2
  94. package/dist/src/agent/lifecycle/timeout-wrapper.js +1 -7
  95. package/dist/src/agent/lifecycle/timeout-wrapper.js.map +1 -1
  96. package/dist/src/agent/memory/builtin-memory-store.d.ts +1 -1
  97. package/dist/src/agent/memory/builtin-memory-store.js +1 -1
  98. package/dist/src/agent/memory/builtin-memory-store.js.map +1 -1
  99. package/dist/src/agent/memory/builtin-provider.d.ts +2 -2
  100. package/dist/src/agent/memory/builtin-provider.js +2 -2
  101. package/dist/src/agent/memory/builtin-provider.js.map +1 -1
  102. package/dist/src/agent/memory/dreaming/light-sweep.d.ts +0 -7
  103. package/dist/src/agent/memory/dreaming/light-sweep.js +16 -277
  104. package/dist/src/agent/memory/dreaming/light-sweep.js.map +1 -1
  105. package/dist/src/agent/memory/dreaming/rem-patterns.d.ts +1 -1
  106. package/dist/src/agent/memory/dreaming/rem-patterns.js +1 -1
  107. package/dist/src/agent/memory/dreaming/rem-patterns.js.map +1 -1
  108. package/dist/src/agent/memory/dreaming/short-term-store.d.ts +3 -3
  109. package/dist/src/agent/memory/dreaming/short-term-store.js +5 -5
  110. package/dist/src/agent/memory/dreaming/short-term-store.js.map +1 -1
  111. package/dist/src/agent/memory/dreaming/utils.d.ts +2 -2
  112. package/dist/src/agent/memory/dreaming/utils.js +2 -2
  113. package/dist/src/agent/memory/dreaming/utils.js.map +1 -1
  114. package/dist/src/agent/memory/index.d.ts +0 -2
  115. package/dist/src/agent/memory/index.js +1 -2
  116. package/dist/src/agent/middleware/self-verify.d.ts +0 -1
  117. package/dist/src/agent/middleware/self-verify.js +0 -2
  118. package/dist/src/agent/middleware/self-verify.js.map +1 -1
  119. package/dist/src/agent/models/index.d.ts +1 -1
  120. package/dist/src/agent/models/manager.d.ts +4 -20
  121. package/dist/src/agent/models/manager.js +9 -126
  122. package/dist/src/agent/models/manager.js.map +1 -1
  123. package/dist/src/agent/orchestration/agent-orchestrator.d.ts +0 -4
  124. package/dist/src/agent/orchestration/agent-orchestrator.js +1 -9
  125. package/dist/src/agent/orchestration/agent-orchestrator.js.map +1 -1
  126. package/dist/src/agent/prompt/sections/memory-skills.js +11 -10
  127. package/dist/src/agent/prompt/sections/memory-skills.js.map +1 -1
  128. package/dist/src/agent/prompt/sections/tooling.js +4 -4
  129. package/dist/src/agent/prompt/sections/tooling.js.map +1 -1
  130. package/dist/src/agent/prompt/service-prompt-builder.d.ts +0 -1
  131. package/dist/src/agent/prompt/service-prompt-builder.js +0 -12
  132. package/dist/src/agent/prompt/service-prompt-builder.js.map +1 -1
  133. package/dist/src/agent/prompt/subagent-context.js +1 -1
  134. package/dist/src/agent/prompt/subagent-context.js.map +1 -1
  135. package/dist/src/agent/prompt/types.d.ts +1 -1
  136. package/dist/src/agent/reply/startup-context.js +6 -105
  137. package/dist/src/agent/reply/startup-context.js.map +1 -1
  138. package/dist/src/agent/service.d.ts +1 -12
  139. package/dist/src/agent/service.js +3 -81
  140. package/dist/src/agent/service.js.map +1 -1
  141. package/dist/src/agent/service.types.d.ts +2 -2
  142. package/dist/src/agent/session/session-config-service.d.ts +11 -11
  143. package/dist/src/agent/session/session-config-service.js +14 -14
  144. package/dist/src/agent/session/session-config-service.js.map +1 -1
  145. package/dist/src/agent/session/session-inspector.js +3 -2
  146. package/dist/src/agent/session/session-inspector.js.map +1 -1
  147. package/dist/src/agent/starter-agents.js +12 -12
  148. package/dist/src/agent/starter-agents.js.map +1 -1
  149. package/dist/src/agent/tools/automation-tool.d.ts +14 -0
  150. package/dist/src/agent/tools/automation-tool.js +102 -0
  151. package/dist/src/agent/tools/automation-tool.js.map +1 -0
  152. package/dist/src/agent/tools/delegate-tool.js +1 -1
  153. package/dist/src/agent/tools/delegate-tool.js.map +1 -1
  154. package/dist/src/agent/tools/factory.d.ts +3 -3
  155. package/dist/src/agent/tools/factory.js +2 -2
  156. package/dist/src/agent/tools/factory.js.map +1 -1
  157. package/dist/src/agent/tools/index.d.ts +1 -1
  158. package/dist/src/agent/tools/index.js +2 -2
  159. package/dist/src/agent/tools/memory-tool.js +2 -2
  160. package/dist/src/agent/tools/memory-tool.js.map +1 -1
  161. package/dist/src/agent-manifest/resolver.d.ts +1 -0
  162. package/dist/src/agent-manifest/resolver.js +1 -0
  163. package/dist/src/agent-manifest/resolver.js.map +1 -1
  164. package/dist/src/agent-manifest/schema.d.ts +6 -0
  165. package/dist/src/agent-manifest/schema.js +12 -3
  166. package/dist/src/agent-manifest/schema.js.map +1 -1
  167. package/dist/src/ai-assist/text-assist.d.ts +1 -1
  168. package/dist/src/ai-assist/text-assist.js +56 -0
  169. package/dist/src/ai-assist/text-assist.js.map +1 -1
  170. package/dist/src/auth/profiles/store.js.map +1 -1
  171. package/dist/src/automations/api/routes.d.ts +3 -0
  172. package/dist/src/automations/api/routes.js +193 -0
  173. package/dist/src/automations/api/routes.js.map +1 -0
  174. package/dist/src/automations/domain/index.d.ts +3 -0
  175. package/dist/src/automations/domain/index.js +3 -0
  176. package/dist/src/automations/domain/schedule.d.ts +4 -0
  177. package/dist/src/automations/domain/schedule.js +37 -0
  178. package/dist/src/automations/domain/schedule.js.map +1 -0
  179. package/dist/src/automations/domain/types.d.ts +160 -0
  180. package/dist/src/automations/domain/validation.d.ts +370 -0
  181. package/dist/src/automations/domain/validation.js +149 -0
  182. package/dist/src/automations/domain/validation.js.map +1 -0
  183. package/dist/src/automations/draft/automation-draft-prompt.d.ts +26 -0
  184. package/dist/src/automations/draft/automation-draft-prompt.js +127 -0
  185. package/dist/src/automations/draft/automation-draft-prompt.js.map +1 -0
  186. package/dist/src/automations/draft/automation-draft-service.d.ts +12 -0
  187. package/dist/src/automations/draft/automation-draft-service.js +135 -0
  188. package/dist/src/automations/draft/automation-draft-service.js.map +1 -0
  189. package/dist/src/automations/draft/automation-draft-validator.d.ts +99 -0
  190. package/dist/src/automations/draft/automation-draft-validator.js +105 -0
  191. package/dist/src/automations/draft/automation-draft-validator.js.map +1 -0
  192. package/dist/src/automations/draft/automation-draft.types.d.ts +40 -0
  193. package/dist/src/automations/draft/index.d.ts +3 -0
  194. package/dist/src/automations/draft/index.js +3 -0
  195. package/dist/src/automations/index.d.ts +3 -0
  196. package/dist/src/automations/index.js +8 -0
  197. package/dist/src/automations/product-events.d.ts +5 -0
  198. package/dist/src/automations/product-events.js +21 -0
  199. package/dist/src/automations/product-events.js.map +1 -0
  200. package/dist/src/automations/service/action-executor.d.ts +9 -0
  201. package/dist/src/automations/service/action-executor.js +157 -0
  202. package/dist/src/automations/service/action-executor.js.map +1 -0
  203. package/dist/src/automations/service/automation-service.d.ts +54 -0
  204. package/dist/src/automations/service/automation-service.js +404 -0
  205. package/dist/src/automations/service/automation-service.js.map +1 -0
  206. package/dist/src/automations/service/index.d.ts +2 -0
  207. package/dist/src/automations/service/index.js +3 -0
  208. package/dist/src/automations/storage/automation-repository.d.ts +6 -0
  209. package/dist/src/automations/storage/automation-repository.js +61 -0
  210. package/dist/src/automations/storage/automation-repository.js.map +1 -0
  211. package/dist/src/automations/storage/automation-run-repository.d.ts +17 -0
  212. package/dist/src/automations/storage/automation-run-repository.js +130 -0
  213. package/dist/src/automations/storage/automation-run-repository.js.map +1 -0
  214. package/dist/src/automations/storage/index.d.ts +2 -0
  215. package/dist/src/automations/storage/index.js +3 -0
  216. package/dist/src/channels/plugin-types.d.ts +3 -0
  217. package/dist/src/chat-commands/builtins/thinking.js.map +1 -1
  218. package/dist/src/cli/command-catalog.js +0 -39
  219. package/dist/src/cli/command-catalog.js.map +1 -1
  220. package/dist/src/cli/command-loaders.js +0 -1
  221. package/dist/src/cli/command-loaders.js.map +1 -1
  222. package/dist/src/cli/command-manifest.js +0 -4
  223. package/dist/src/cli/command-manifest.js.map +1 -1
  224. package/dist/src/cli/commands/agents.js +7 -6
  225. package/dist/src/cli/commands/agents.js.map +1 -1
  226. package/dist/src/cli/commands/doctor/checks/database-schema.js +1 -1
  227. package/dist/src/cli/commands/doctor/checks/{cron-health.d.ts → migrations.d.ts} +1 -1
  228. package/dist/src/cli/commands/doctor/checks/migrations.js +40 -0
  229. package/dist/src/cli/commands/doctor/checks/migrations.js.map +1 -0
  230. package/dist/src/cli/commands/doctor/flow.js +2 -2
  231. package/dist/src/cli/commands/doctor/flow.js.map +1 -1
  232. package/dist/src/cli/commands/gateway/call.js +2 -2
  233. package/dist/src/cli/commands/gateway/call.js.map +1 -1
  234. package/dist/src/cli/commands/gateway/run-foreground.js +4 -2
  235. package/dist/src/cli/commands/gateway/run-foreground.js.map +1 -1
  236. package/dist/src/cli/commands/init.js +27 -9
  237. package/dist/src/cli/commands/init.js.map +1 -1
  238. package/dist/src/cli/commands/tui.js +24 -2
  239. package/dist/src/cli/commands/tui.js.map +1 -1
  240. package/dist/src/cli/templates.js +3 -2
  241. package/dist/src/cli/templates.js.map +1 -1
  242. package/dist/src/cli/utils/init-workspace-core.js +2 -0
  243. package/dist/src/cli/utils/init-workspace-core.js.map +1 -1
  244. package/dist/src/commands/agents.config.d.ts +9 -0
  245. package/dist/src/commands/agents.config.js +40 -2
  246. package/dist/src/commands/agents.config.js.map +1 -1
  247. package/dist/src/config/agent-profile.js +4 -3
  248. package/dist/src/config/agent-profile.js.map +1 -1
  249. package/dist/src/config/agent-typed-models.js.map +1 -1
  250. package/dist/src/config/config-surface.d.ts +3 -0
  251. package/dist/src/config/index.d.ts +0 -1
  252. package/dist/src/config/index.js +3 -3
  253. package/dist/src/config/index.js.map +1 -1
  254. package/dist/src/config/paths.d.ts +0 -9
  255. package/dist/src/config/paths.js +1 -14
  256. package/dist/src/config/paths.js.map +1 -1
  257. package/dist/src/config/profile.js +0 -1
  258. package/dist/src/config/profile.js.map +1 -1
  259. package/dist/src/config/rules.js +0 -5
  260. package/dist/src/config/rules.js.map +1 -1
  261. package/dist/src/config/schema.d.ts +13 -12
  262. package/dist/src/config/schema.js +22 -26
  263. package/dist/src/config/schema.js.map +1 -1
  264. package/dist/src/config/web-patch.d.ts +0 -12
  265. package/dist/src/config/web-patch.js +2 -29
  266. package/dist/src/config/web-patch.js.map +1 -1
  267. package/dist/src/extensions/api.d.ts +2 -0
  268. package/dist/src/extensions/api.js +10 -0
  269. package/dist/src/extensions/api.js.map +1 -1
  270. package/dist/src/extensions/extension-registry-impl.d.ts +4 -1
  271. package/dist/src/extensions/extension-registry-impl.js +8 -0
  272. package/dist/src/extensions/extension-registry-impl.js.map +1 -1
  273. package/dist/src/extensions/loader.d.ts +3 -3
  274. package/dist/src/extensions/loader.js +3 -3
  275. package/dist/src/extensions/loader.js.map +1 -1
  276. package/dist/src/extensions/sdk/testing.d.ts +2 -0
  277. package/dist/src/extensions/sdk/testing.js +7 -0
  278. package/dist/src/extensions/sdk/testing.js.map +1 -1
  279. package/dist/src/extensions/types/core.d.ts +10 -1
  280. package/dist/src/extensions/types/index.d.ts +1 -1
  281. package/dist/src/extensions/types/{phase4.d.ts → registration.d.ts} +2 -2
  282. package/dist/src/gateway/agent-builtin-tools.d.ts +1 -1
  283. package/dist/src/gateway/agent-builtin-tools.js +1 -1
  284. package/dist/src/gateway/agent-builtin-tools.js.map +1 -1
  285. package/dist/src/gateway/agents-admin.d.ts +1 -0
  286. package/dist/src/gateway/agents-admin.js +13 -15
  287. package/dist/src/gateway/agents-admin.js.map +1 -1
  288. package/dist/src/gateway/capability-presets-admin.d.ts +1 -0
  289. package/dist/src/gateway/capability-presets-admin.js +19 -10
  290. package/dist/src/gateway/capability-presets-admin.js.map +1 -1
  291. package/dist/src/gateway/dreaming-automation-reconciler.d.ts +11 -0
  292. package/dist/src/gateway/dreaming-automation-reconciler.js +105 -0
  293. package/dist/src/gateway/dreaming-automation-reconciler.js.map +1 -0
  294. package/dist/src/gateway/heartbeat/service.d.ts +0 -2
  295. package/dist/src/gateway/heartbeat/service.js +0 -7
  296. package/dist/src/gateway/heartbeat/service.js.map +1 -1
  297. package/dist/src/gateway/hono/lib/config-payload.d.ts +5 -6
  298. package/dist/src/gateway/hono/lib/config-payload.js +2 -2
  299. package/dist/src/gateway/hono/lib/config-payload.js.map +1 -1
  300. package/dist/src/gateway/hono/routes/agents.js.map +1 -1
  301. package/dist/src/gateway/hono/routes/config-patch/misc.d.ts +1 -1
  302. package/dist/src/gateway/hono/routes/config-patch/misc.js +15 -6
  303. package/dist/src/gateway/hono/routes/config-patch/misc.js.map +1 -1
  304. package/dist/src/gateway/hono/routes/dreaming.js +27 -37
  305. package/dist/src/gateway/hono/routes/dreaming.js.map +1 -1
  306. package/dist/src/gateway/hono/routes/home.d.ts +2 -2
  307. package/dist/src/gateway/hono/routes/home.js +34 -25
  308. package/dist/src/gateway/hono/routes/home.js.map +1 -1
  309. package/dist/src/gateway/hono/routes/lazy-bundles.js +10 -6
  310. package/dist/src/gateway/hono/routes/lazy-bundles.js.map +1 -1
  311. package/dist/src/gateway/hono/routes/migrations.d.ts +3 -0
  312. package/dist/src/gateway/hono/routes/migrations.js +35 -0
  313. package/dist/src/gateway/hono/routes/migrations.js.map +1 -0
  314. package/dist/src/gateway/hono/routes/public-gateway.js +2 -1
  315. package/dist/src/gateway/hono/routes/public-gateway.js.map +1 -1
  316. package/dist/src/gateway/hono/routes/sessions.js +14 -0
  317. package/dist/src/gateway/hono/routes/sessions.js.map +1 -1
  318. package/dist/src/gateway/run-loop.js +2 -0
  319. package/dist/src/gateway/run-loop.js.map +1 -1
  320. package/dist/src/gateway/security/operator-scopes.js +5 -1
  321. package/dist/src/gateway/security/operator-scopes.js.map +1 -1
  322. package/dist/src/gateway/service/config-coordinator.d.ts +4 -4
  323. package/dist/src/gateway/service/config-coordinator.js +14 -8
  324. package/dist/src/gateway/service/config-coordinator.js.map +1 -1
  325. package/dist/src/gateway/service/sessions-api.d.ts +2 -1
  326. package/dist/src/gateway/service/sessions-api.js +6 -1
  327. package/dist/src/gateway/service/sessions-api.js.map +1 -1
  328. package/dist/src/gateway/service.d.ts +7 -3
  329. package/dist/src/gateway/service.js +61 -27
  330. package/dist/src/gateway/service.js.map +1 -1
  331. package/dist/src/goals/goal-service.js +45 -4
  332. package/dist/src/goals/goal-service.js.map +1 -1
  333. package/dist/src/migrations/config/default-capability-preset.d.ts +10 -0
  334. package/dist/src/migrations/config/default-capability-preset.js +135 -0
  335. package/dist/src/migrations/config/default-capability-preset.js.map +1 -0
  336. package/dist/src/migrations/index.d.ts +4 -0
  337. package/dist/src/migrations/index.js +4 -0
  338. package/dist/src/migrations/registry.d.ts +8 -0
  339. package/dist/src/migrations/registry.js +18 -0
  340. package/dist/src/migrations/registry.js.map +1 -0
  341. package/dist/src/migrations/runner.d.ts +17 -0
  342. package/dist/src/migrations/runner.js +191 -0
  343. package/dist/src/migrations/runner.js.map +1 -0
  344. package/dist/src/migrations/types.d.ts +34 -0
  345. package/dist/src/notes/service.js +24 -1
  346. package/dist/src/notes/service.js.map +1 -1
  347. package/dist/src/providers/model-registry.d.ts +0 -1
  348. package/dist/src/providers/model-registry.js +0 -3
  349. package/dist/src/providers/model-registry.js.map +1 -1
  350. package/dist/src/routing/resolve-tui-session-key.d.ts +3 -0
  351. package/dist/src/routing/resolve-tui-session-key.js +14 -3
  352. package/dist/src/routing/resolve-tui-session-key.js.map +1 -1
  353. package/dist/src/session/transcript-outline.d.ts +47 -0
  354. package/dist/src/session/transcript-outline.js +481 -0
  355. package/dist/src/session/transcript-outline.js.map +1 -0
  356. package/dist/src/storage/sqlite/index.d.ts +0 -2
  357. package/dist/src/storage/sqlite/index.js +1 -3
  358. package/dist/src/storage/sqlite/migrations/016_automations.sql +47 -0
  359. package/dist/src/storage/sqlite/migrations/017_automation_run_events.sql +14 -0
  360. package/dist/src/storage/sqlite/migrations/018_automation_safety.sql +1 -0
  361. package/dist/src/storage/sqlite/migrations/runner.d.ts +1 -1
  362. package/dist/src/storage/sqlite/migrations/runner.js +3 -3
  363. package/dist/src/storage/sqlite/migrations/runner.js.map +1 -1
  364. package/dist/src/storage/sqlite/migrations/runner.ts +1 -1
  365. package/dist/src/storage/sqlite/row-mappers.js +3 -1
  366. package/dist/src/storage/sqlite/row-mappers.js.map +1 -1
  367. package/dist/src/storage/sqlite/schema.js +1 -1
  368. package/dist/src/storage/sqlite/schema.sql +56 -46
  369. package/dist/src/tui/backends/embedded-backend.d.ts +6 -0
  370. package/dist/src/tui/backends/embedded-backend.js +19 -9
  371. package/dist/src/tui/backends/embedded-backend.js.map +1 -1
  372. package/dist/src/tui/backends/gateway-sse-backend.d.ts +3 -0
  373. package/dist/src/tui/backends/gateway-sse-backend.js +14 -0
  374. package/dist/src/tui/backends/gateway-sse-backend.js.map +1 -1
  375. package/dist/src/tui/tui-backend.d.ts +4 -0
  376. package/dist/src/tui/tui-commands.d.ts +5 -0
  377. package/dist/src/tui/tui-commands.js +43 -0
  378. package/dist/src/tui/tui-commands.js.map +1 -1
  379. package/dist/src/tui/tui-transcript-tree.d.ts +1 -1
  380. package/dist/src/tui/tui-transcript-tree.js +17 -257
  381. package/dist/src/tui/tui-transcript-tree.js.map +1 -1
  382. package/dist/src/tui/tui-types.d.ts +2 -0
  383. package/dist/src/tui/tui-types.js.map +1 -1
  384. package/dist/src/tui/tui.js +7 -2
  385. package/dist/src/tui/tui.js.map +1 -1
  386. package/dist/src/workflows/domain/index.js +1 -1
  387. package/dist/src/workflows/domain/run.d.ts +7 -7
  388. package/dist/src/workflows/domain/run.js.map +1 -1
  389. package/dist/src/workflows/index.js +2 -2
  390. package/dist/src/workflows/service/workflow-run-service.d.ts +2 -0
  391. package/dist/src/workflows/service/workflow-run-service.js +31 -9
  392. package/dist/src/workflows/service/workflow-run-service.js.map +1 -1
  393. package/dist/src/workflows/service/workflow-run-service.types.d.ts +1 -1
  394. package/package.json +4 -2
  395. package/dist/gateway/static/root/assets/agents-BCxZbkOw.js +0 -2
  396. package/dist/gateway/static/root/assets/app-management-settings-panel-bxYJVJpx.js +0 -1
  397. package/dist/gateway/static/root/assets/appearance-settings-BCIykXlI.js +0 -1
  398. package/dist/gateway/static/root/assets/browser-settings-page-DRhKdn81.js +0 -8
  399. package/dist/gateway/static/root/assets/capability-presets-api-CorhiHlg.js +0 -1
  400. package/dist/gateway/static/root/assets/capability-presets-settings-panel-qFx9Jtce.js +0 -1
  401. package/dist/gateway/static/root/assets/channels-settings-BAwAkqIA.js +0 -1
  402. package/dist/gateway/static/root/assets/cn-JdwAhgNB.js +0 -1
  403. package/dist/gateway/static/root/assets/connectors-page-BQLcfitM.js +0 -2
  404. package/dist/gateway/static/root/assets/createLucideIcon-DPHK1VkS.js +0 -1
  405. package/dist/gateway/static/root/assets/cron-api-qGwmL-24.js +0 -1
  406. package/dist/gateway/static/root/assets/cron-dreaming-jobs-nCMWCf0p.js +0 -1
  407. package/dist/gateway/static/root/assets/cron-page-BBWMAj8-.js +0 -3
  408. package/dist/gateway/static/root/assets/dreaming-settings-Dw89Obml.js +0 -1
  409. package/dist/gateway/static/root/assets/format-cron-label-BsotZDO5.js +0 -2
  410. package/dist/gateway/static/root/assets/format-interval-label-BzxafKxR.js +0 -1
  411. package/dist/gateway/static/root/assets/gateway-settings-Cmwy58rS.js +0 -1
  412. package/dist/gateway/static/root/assets/goal-detail-page-l7mu5GWX.js +0 -1
  413. package/dist/gateway/static/root/assets/goals-settings-CYVY4NGp.js +0 -1
  414. package/dist/gateway/static/root/assets/heartbeat-config-api-DriO_CN9.js +0 -1
  415. package/dist/gateway/static/root/assets/heartbeat-settings-CUQTKxg7.js +0 -1
  416. package/dist/gateway/static/root/assets/index-C17Tsd_b.css +0 -1
  417. package/dist/gateway/static/root/assets/index-Cc41r16l.js +0 -191
  418. package/dist/gateway/static/root/assets/interval-presets-DFPCKW_W.js +0 -1
  419. package/dist/gateway/static/root/assets/keyboard-shortcuts-settings-CcVcqstx.js +0 -1
  420. package/dist/gateway/static/root/assets/messages-B1iSKjiw.js +0 -3
  421. package/dist/gateway/static/root/assets/models-hub-panel-BfLfcta8.js +0 -2
  422. package/dist/gateway/static/root/assets/note-detail-page-BjwOQBfT.js +0 -2
  423. package/dist/gateway/static/root/assets/notes-page-DktdBiwB.js +0 -1
  424. package/dist/gateway/static/root/assets/remote-access-hub-rfVx96fq.js +0 -1
  425. package/dist/gateway/static/root/assets/schedule-field-CUCKODde.js +0 -1
  426. package/dist/gateway/static/root/assets/sessions-page-DbtMFuuH.js +0 -1
  427. package/dist/gateway/static/root/assets/settings-advanced-gate-5re5gAnP.js +0 -1
  428. package/dist/gateway/static/root/assets/settings-form-section-dmyaPOTG.js +0 -1
  429. package/dist/gateway/static/root/assets/settings-page-D-WMyLlj.js +0 -1
  430. package/dist/gateway/static/root/assets/setup-status-panel-Cl-DEJAU.js +0 -1
  431. package/dist/gateway/static/root/assets/shares-settings-CyPVvbLt.js +0 -1
  432. package/dist/gateway/static/root/assets/skill-reload-api-CleTH1oz.js +0 -1
  433. package/dist/gateway/static/root/assets/skills-page-Ck8hdXqR.js +0 -2
  434. package/dist/gateway/static/root/assets/system-settings-panel-DI-LN_8G.js +0 -1
  435. package/dist/gateway/static/root/assets/typed-models-lib-kX9duch4.js +0 -1
  436. package/dist/gateway/static/root/assets/user-profile-settings-panel-B-UFPMXy.js +0 -1
  437. package/dist/gateway/static/root/assets/utils-Dm0hKalR.js +0 -1
  438. package/dist/gateway/static/root/assets/workflows-page-BtFGp2y_.js +0 -18
  439. package/dist/src/agent/fallback/error.d.ts +0 -22
  440. package/dist/src/agent/fallback/error.js +0 -32
  441. package/dist/src/agent/fallback/error.js.map +0 -1
  442. package/dist/src/agent/fallback/index.d.ts +0 -5
  443. package/dist/src/agent/fallback/index.js +0 -9
  444. package/dist/src/agent/fallback/index.js.map +0 -1
  445. package/dist/src/agent/memory/memory-flush.d.ts +0 -27
  446. package/dist/src/agent/memory/memory-flush.js +0 -124
  447. package/dist/src/agent/memory/memory-flush.js.map +0 -1
  448. package/dist/src/agent/orchestration/run-agent-turn-with-fallbacks.d.ts +0 -29
  449. package/dist/src/agent/orchestration/run-agent-turn-with-fallbacks.js +0 -76
  450. package/dist/src/agent/orchestration/run-agent-turn-with-fallbacks.js.map +0 -1
  451. package/dist/src/agent/service/reconcile-dreaming-cron.d.ts +0 -6
  452. package/dist/src/agent/service/reconcile-dreaming-cron.js +0 -84
  453. package/dist/src/agent/service/reconcile-dreaming-cron.js.map +0 -1
  454. package/dist/src/agent/tools/cronjob-tool.d.ts +0 -29
  455. package/dist/src/agent/tools/cronjob-tool.js +0 -274
  456. package/dist/src/agent/tools/cronjob-tool.js.map +0 -1
  457. package/dist/src/cli/commands/cron-cli.d.ts +0 -2
  458. package/dist/src/cli/commands/cron-cli.js +0 -15
  459. package/dist/src/cli/commands/cron-cli.js.map +0 -1
  460. package/dist/src/cli/commands/cron.d.ts +0 -4
  461. package/dist/src/cli/commands/cron.js +0 -188
  462. package/dist/src/cli/commands/cron.js.map +0 -1
  463. package/dist/src/cli/commands/doctor/checks/cron-health.js +0 -35
  464. package/dist/src/cli/commands/doctor/checks/cron-health.js.map +0 -1
  465. package/dist/src/cron/execution-types.d.ts +0 -42
  466. package/dist/src/cron/executor.d.ts +0 -67
  467. package/dist/src/cron/executor.js +0 -669
  468. package/dist/src/cron/executor.js.map +0 -1
  469. package/dist/src/cron/index.d.ts +0 -7
  470. package/dist/src/cron/index.js +0 -7
  471. package/dist/src/cron/job-content.d.ts +0 -5
  472. package/dist/src/cron/job-content.js +0 -15
  473. package/dist/src/cron/job-content.js.map +0 -1
  474. package/dist/src/cron/run-log-store.d.ts +0 -12
  475. package/dist/src/cron/run-log-store.js +0 -58
  476. package/dist/src/cron/run-log-store.js.map +0 -1
  477. package/dist/src/cron/schedule.d.ts +0 -10
  478. package/dist/src/cron/schedule.js +0 -85
  479. package/dist/src/cron/schedule.js.map +0 -1
  480. package/dist/src/cron/service.d.ts +0 -58
  481. package/dist/src/cron/service.js +0 -419
  482. package/dist/src/cron/service.js.map +0 -1
  483. package/dist/src/cron/types.d.ts +0 -183
  484. package/dist/src/cron/validation.d.ts +0 -500
  485. package/dist/src/cron/validation.js +0 -192
  486. package/dist/src/cron/validation.js.map +0 -1
  487. package/dist/src/cron/workflow-run-completion.d.ts +0 -23
  488. package/dist/src/cron/workflow-run-completion.js +0 -72
  489. package/dist/src/cron/workflow-run-completion.js.map +0 -1
  490. package/dist/src/extensions/types/phase4.js +0 -1
  491. package/dist/src/gateway/hono/routes/cron.d.ts +0 -3
  492. package/dist/src/gateway/hono/routes/cron.js +0 -109
  493. package/dist/src/gateway/hono/routes/cron.js.map +0 -1
  494. package/dist/src/storage/sqlite/cron-job-repository.d.ts +0 -6
  495. package/dist/src/storage/sqlite/cron-job-repository.js +0 -70
  496. package/dist/src/storage/sqlite/cron-job-repository.js.map +0 -1
  497. package/dist/src/storage/sqlite/cron-run-repository.d.ts +0 -5
  498. package/dist/src/storage/sqlite/cron-run-repository.js +0 -96
  499. package/dist/src/storage/sqlite/cron-run-repository.js.map +0 -1
  500. /package/dist/src/{cron → automations/domain}/types.js +0 -0
  501. /package/dist/src/{config/defaults.d.ts → automations/draft/automation-draft.types.js} +0 -0
  502. /package/dist/src/{config/defaults.js → extensions/types/registration.js} +0 -0
  503. /package/dist/src/{cron/execution-types.js → migrations/types.js} +0 -0
@@ -3,7 +3,7 @@ import type { ApplyMigrationsOptions } from './types.js';
3
3
  /** Baseline schema version applied from schema.sql on first open. */
4
4
  export declare const XOPC_DB_BASELINE_SCHEMA_VERSION = 11;
5
5
  /** Latest schema version this release supports (increment when adding migrations). */
6
- export declare const XOPC_DB_SCHEMA_VERSION = 15;
6
+ export declare const XOPC_DB_SCHEMA_VERSION = 18;
7
7
  export declare function resolveMigrationsDir(override?: string): string;
8
8
  /**
9
9
  * Apply sequential SQL migrations from (currentVersion + 1) through targetVersion.
@@ -12,7 +12,7 @@ const log = createLogger("Sqlite:Migrations");
12
12
  /** Baseline schema version applied from schema.sql on first open. */
13
13
  const XOPC_DB_BASELINE_SCHEMA_VERSION = 11;
14
14
  /** Latest schema version this release supports (increment when adding migrations). */
15
- const XOPC_DB_SCHEMA_VERSION = 15;
15
+ const XOPC_DB_SCHEMA_VERSION = 18;
16
16
  const MODULE_DIR = dirname(fileURLToPath(import.meta.url));
17
17
  function resolveMigrationsDir(override) {
18
18
  if (override) return override;
@@ -46,7 +46,7 @@ function applySingleMigration(db, migration) {
46
46
  * Each step runs in its own transaction and updates schema_meta on success.
47
47
  */
48
48
  function applyPendingMigrations(db, options = {}) {
49
- const targetVersion = options.targetVersion ?? 15;
49
+ const targetVersion = options.targetVersion ?? 18;
50
50
  let currentVersion = readSchemaVersion(db);
51
51
  if (currentVersion > targetVersion) throw new DatabaseSchemaTooNewError(currentVersion, targetVersion);
52
52
  if (currentVersion >= targetVersion) return currentVersion;
@@ -62,7 +62,7 @@ function applyPendingMigrations(db, options = {}) {
62
62
  }
63
63
  /** Inspect schema version without mutating the database. */
64
64
  function inspectSchemaMigrationStatus(db, options = {}) {
65
- const appVersion = options.targetVersion ?? 15;
65
+ const appVersion = options.targetVersion ?? 18;
66
66
  const dbVersion = readSchemaVersion(db);
67
67
  if (dbVersion > appVersion) return {
68
68
  dbVersion,
@@ -1 +1 @@
1
- {"version":3,"file":"runner.js","names":[],"sources":["../../../../../src/storage/sqlite/migrations/runner.ts"],"sourcesContent":["import { existsSync } from 'node:fs';\nimport { dirname, join } from 'node:path';\nimport { fileURLToPath } from 'node:url';\n\nimport type { DatabaseSync } from 'node:sqlite';\n\nimport { createLogger } from '../../../utils/logger.js';\nimport { readSchemaVersion, setSchemaVersion } from '../schema-version.js';\nimport { discoverSqlMigrations } from './discover.js';\nimport {\n DatabaseSchemaMigrationGapError,\n DatabaseSchemaTooNewError,\n} from './errors.js';\nimport type { ApplyMigrationsOptions, SqlMigration } from './types.js';\n\nconst log = createLogger('Sqlite:Migrations');\n\n/** Baseline schema version applied from schema.sql on first open. */\nexport const XOPC_DB_BASELINE_SCHEMA_VERSION = 11;\n\n/** Latest schema version this release supports (increment when adding migrations). */\nexport const XOPC_DB_SCHEMA_VERSION = 15;\n\nconst MODULE_DIR = dirname(fileURLToPath(import.meta.url));\n\nexport function resolveMigrationsDir(override?: string): string {\n if (override) {\n return override;\n }\n // Packaged Electron gateway bundle: `out/server/index.js` + `out/server/migrations/`.\n const siblingDir = join(MODULE_DIR, 'migrations');\n if (existsSync(siblingDir)) {\n return siblingDir;\n }\n // Dev / dist: SQL files live next to `migrations/runner.js`.\n return MODULE_DIR;\n}\n\nfunction migrationByTarget(\n migrations: SqlMigration[],\n targetVersion: number,\n): SqlMigration | undefined {\n return migrations.find((migration) => migration.targetVersion === targetVersion);\n}\n\nfunction applySingleMigration(db: DatabaseSync, migration: SqlMigration): void {\n log.info({ targetVersion: migration.targetVersion, file: migration.filename }, 'Applying SQLite migration');\n db.exec('BEGIN IMMEDIATE');\n try {\n db.exec(migration.sql);\n setSchemaVersion(db, migration.targetVersion);\n db.exec('COMMIT');\n } catch (error) {\n try {\n db.exec('ROLLBACK');\n } catch {\n /* preserve original error */\n }\n const em = error instanceof Error ? error.message : String(error);\n throw new Error(\n `SQLite migration to v${migration.targetVersion} (${migration.filename}) failed: ${em}`,\n { cause: error },\n );\n }\n}\n\n/**\n * Apply sequential SQL migrations from (currentVersion + 1) through targetVersion.\n * Each step runs in its own transaction and updates schema_meta on success.\n */\nexport function applyPendingMigrations(\n db: DatabaseSync,\n options: ApplyMigrationsOptions = {},\n): number {\n const targetVersion = options.targetVersion ?? XOPC_DB_SCHEMA_VERSION;\n let currentVersion = readSchemaVersion(db);\n\n if (currentVersion > targetVersion) {\n throw new DatabaseSchemaTooNewError(currentVersion, targetVersion);\n }\n\n if (currentVersion >= targetVersion) {\n return currentVersion;\n }\n\n const migrations = discoverSqlMigrations(resolveMigrationsDir(options.migrationsDir));\n\n while (currentVersion < targetVersion) {\n const nextVersion = currentVersion + 1;\n const migration = migrationByTarget(migrations, nextVersion);\n if (!migration) {\n throw new DatabaseSchemaMigrationGapError(currentVersion, targetVersion, nextVersion);\n }\n applySingleMigration(db, migration);\n currentVersion = nextVersion;\n }\n\n return currentVersion;\n}\n\nexport type SchemaMigrationStatus = {\n dbVersion: number;\n appVersion: number;\n pendingVersions: number[];\n isTooNew: boolean;\n hasMigrationGap: boolean;\n missingVersion: number | null;\n};\n\n/** Inspect schema version without mutating the database. */\nexport function inspectSchemaMigrationStatus(\n db: DatabaseSync,\n options: Pick<ApplyMigrationsOptions, 'migrationsDir' | 'targetVersion'> = {},\n): SchemaMigrationStatus {\n const appVersion = options.targetVersion ?? XOPC_DB_SCHEMA_VERSION;\n const dbVersion = readSchemaVersion(db);\n const isTooNew = dbVersion > appVersion;\n\n if (isTooNew) {\n return {\n dbVersion,\n appVersion,\n pendingVersions: [],\n isTooNew: true,\n hasMigrationGap: false,\n missingVersion: null,\n };\n }\n\n const migrations = discoverSqlMigrations(resolveMigrationsDir(options.migrationsDir));\n const pendingVersions: number[] = [];\n let hasMigrationGap = false;\n let missingVersion: number | null = null;\n\n for (let version = dbVersion + 1; version <= appVersion; version++) {\n if (migrationByTarget(migrations, version)) {\n pendingVersions.push(version);\n } else {\n hasMigrationGap = true;\n missingVersion = version;\n break;\n }\n }\n\n return {\n dbVersion,\n appVersion,\n pendingVersions,\n isTooNew: false,\n hasMigrationGap,\n missingVersion,\n };\n}\n"],"mappings":";;;;;;;;;aAMwD;AASxD,MAAM,MAAM,aAAa,oBAAoB;;AAG7C,MAAa,kCAAkC;;AAG/C,MAAa,yBAAyB;AAEtC,MAAM,aAAa,QAAQ,cAAc,OAAO,KAAK,IAAI,CAAC;AAE1D,SAAgB,qBAAqB,UAA2B;AAC9D,KAAI,SACF,QAAO;CAGT,MAAM,aAAa,KAAK,YAAY,aAAa;AACjD,KAAI,WAAW,WAAW,CACxB,QAAO;AAGT,QAAO;;AAGT,SAAS,kBACP,YACA,eAC0B;AAC1B,QAAO,WAAW,MAAM,cAAc,UAAU,kBAAkB,cAAc;;AAGlF,SAAS,qBAAqB,IAAkB,WAA+B;AAC7E,KAAI,KAAK;EAAE,eAAe,UAAU;EAAe,MAAM,UAAU;EAAU,EAAE,4BAA4B;AAC3G,IAAG,KAAK,kBAAkB;AAC1B,KAAI;AACF,KAAG,KAAK,UAAU,IAAI;AACtB,mBAAiB,IAAI,UAAU,cAAc;AAC7C,KAAG,KAAK,SAAS;UACV,OAAO;AACd,MAAI;AACF,MAAG,KAAK,WAAW;UACb;EAGR,MAAM,KAAK,iBAAiB,QAAQ,MAAM,UAAU,OAAO,MAAM;AACjE,QAAM,IAAI,MACR,wBAAwB,UAAU,cAAc,IAAI,UAAU,SAAS,YAAY,MACnF,EAAE,OAAO,OAAO,CACjB;;;;;;;AAQL,SAAgB,uBACd,IACA,UAAkC,EAAE,EAC5B;CACR,MAAM,gBAAgB,QAAQ,iBAAA;CAC9B,IAAI,iBAAiB,kBAAkB,GAAG;AAE1C,KAAI,iBAAiB,cACnB,OAAM,IAAI,0BAA0B,gBAAgB,cAAc;AAGpE,KAAI,kBAAkB,cACpB,QAAO;CAGT,MAAM,aAAa,sBAAsB,qBAAqB,QAAQ,cAAc,CAAC;AAErF,QAAO,iBAAiB,eAAe;EACrC,MAAM,cAAc,iBAAiB;EACrC,MAAM,YAAY,kBAAkB,YAAY,YAAY;AAC5D,MAAI,CAAC,UACH,OAAM,IAAI,gCAAgC,gBAAgB,eAAe,YAAY;AAEvF,uBAAqB,IAAI,UAAU;AACnC,mBAAiB;;AAGnB,QAAO;;;AAaT,SAAgB,6BACd,IACA,UAA2E,EAAE,EACtD;CACvB,MAAM,aAAa,QAAQ,iBAAA;CAC3B,MAAM,YAAY,kBAAkB,GAAG;AAGvC,KAFiB,YAAY,WAG3B,QAAO;EACL;EACA;EACA,iBAAiB,EAAE;EACnB,UAAU;EACV,iBAAiB;EACjB,gBAAgB;EACjB;CAGH,MAAM,aAAa,sBAAsB,qBAAqB,QAAQ,cAAc,CAAC;CACrF,MAAM,kBAA4B,EAAE;CACpC,IAAI,kBAAkB;CACtB,IAAI,iBAAgC;AAEpC,MAAK,IAAI,UAAU,YAAY,GAAG,WAAW,YAAY,UACvD,KAAI,kBAAkB,YAAY,QAAQ,CACxC,iBAAgB,KAAK,QAAQ;MACxB;AACL,oBAAkB;AAClB,mBAAiB;AACjB;;AAIJ,QAAO;EACL;EACA;EACA;EACA,UAAU;EACV;EACA;EACD"}
1
+ {"version":3,"file":"runner.js","names":[],"sources":["../../../../../src/storage/sqlite/migrations/runner.ts"],"sourcesContent":["import { existsSync } from 'node:fs';\nimport { dirname, join } from 'node:path';\nimport { fileURLToPath } from 'node:url';\n\nimport type { DatabaseSync } from 'node:sqlite';\n\nimport { createLogger } from '../../../utils/logger.js';\nimport { readSchemaVersion, setSchemaVersion } from '../schema-version.js';\nimport { discoverSqlMigrations } from './discover.js';\nimport {\n DatabaseSchemaMigrationGapError,\n DatabaseSchemaTooNewError,\n} from './errors.js';\nimport type { ApplyMigrationsOptions, SqlMigration } from './types.js';\n\nconst log = createLogger('Sqlite:Migrations');\n\n/** Baseline schema version applied from schema.sql on first open. */\nexport const XOPC_DB_BASELINE_SCHEMA_VERSION = 11;\n\n/** Latest schema version this release supports (increment when adding migrations). */\nexport const XOPC_DB_SCHEMA_VERSION = 18;\n\nconst MODULE_DIR = dirname(fileURLToPath(import.meta.url));\n\nexport function resolveMigrationsDir(override?: string): string {\n if (override) {\n return override;\n }\n // Packaged Electron gateway bundle: `out/server/index.js` + `out/server/migrations/`.\n const siblingDir = join(MODULE_DIR, 'migrations');\n if (existsSync(siblingDir)) {\n return siblingDir;\n }\n // Dev / dist: SQL files live next to `migrations/runner.js`.\n return MODULE_DIR;\n}\n\nfunction migrationByTarget(\n migrations: SqlMigration[],\n targetVersion: number,\n): SqlMigration | undefined {\n return migrations.find((migration) => migration.targetVersion === targetVersion);\n}\n\nfunction applySingleMigration(db: DatabaseSync, migration: SqlMigration): void {\n log.info({ targetVersion: migration.targetVersion, file: migration.filename }, 'Applying SQLite migration');\n db.exec('BEGIN IMMEDIATE');\n try {\n db.exec(migration.sql);\n setSchemaVersion(db, migration.targetVersion);\n db.exec('COMMIT');\n } catch (error) {\n try {\n db.exec('ROLLBACK');\n } catch {\n /* preserve original error */\n }\n const em = error instanceof Error ? error.message : String(error);\n throw new Error(\n `SQLite migration to v${migration.targetVersion} (${migration.filename}) failed: ${em}`,\n { cause: error },\n );\n }\n}\n\n/**\n * Apply sequential SQL migrations from (currentVersion + 1) through targetVersion.\n * Each step runs in its own transaction and updates schema_meta on success.\n */\nexport function applyPendingMigrations(\n db: DatabaseSync,\n options: ApplyMigrationsOptions = {},\n): number {\n const targetVersion = options.targetVersion ?? XOPC_DB_SCHEMA_VERSION;\n let currentVersion = readSchemaVersion(db);\n\n if (currentVersion > targetVersion) {\n throw new DatabaseSchemaTooNewError(currentVersion, targetVersion);\n }\n\n if (currentVersion >= targetVersion) {\n return currentVersion;\n }\n\n const migrations = discoverSqlMigrations(resolveMigrationsDir(options.migrationsDir));\n\n while (currentVersion < targetVersion) {\n const nextVersion = currentVersion + 1;\n const migration = migrationByTarget(migrations, nextVersion);\n if (!migration) {\n throw new DatabaseSchemaMigrationGapError(currentVersion, targetVersion, nextVersion);\n }\n applySingleMigration(db, migration);\n currentVersion = nextVersion;\n }\n\n return currentVersion;\n}\n\nexport type SchemaMigrationStatus = {\n dbVersion: number;\n appVersion: number;\n pendingVersions: number[];\n isTooNew: boolean;\n hasMigrationGap: boolean;\n missingVersion: number | null;\n};\n\n/** Inspect schema version without mutating the database. */\nexport function inspectSchemaMigrationStatus(\n db: DatabaseSync,\n options: Pick<ApplyMigrationsOptions, 'migrationsDir' | 'targetVersion'> = {},\n): SchemaMigrationStatus {\n const appVersion = options.targetVersion ?? XOPC_DB_SCHEMA_VERSION;\n const dbVersion = readSchemaVersion(db);\n const isTooNew = dbVersion > appVersion;\n\n if (isTooNew) {\n return {\n dbVersion,\n appVersion,\n pendingVersions: [],\n isTooNew: true,\n hasMigrationGap: false,\n missingVersion: null,\n };\n }\n\n const migrations = discoverSqlMigrations(resolveMigrationsDir(options.migrationsDir));\n const pendingVersions: number[] = [];\n let hasMigrationGap = false;\n let missingVersion: number | null = null;\n\n for (let version = dbVersion + 1; version <= appVersion; version++) {\n if (migrationByTarget(migrations, version)) {\n pendingVersions.push(version);\n } else {\n hasMigrationGap = true;\n missingVersion = version;\n break;\n }\n }\n\n return {\n dbVersion,\n appVersion,\n pendingVersions,\n isTooNew: false,\n hasMigrationGap,\n missingVersion,\n };\n}\n"],"mappings":";;;;;;;;;aAMwD;AASxD,MAAM,MAAM,aAAa,oBAAoB;;AAG7C,MAAa,kCAAkC;;AAG/C,MAAa,yBAAyB;AAEtC,MAAM,aAAa,QAAQ,cAAc,OAAO,KAAK,IAAI,CAAC;AAE1D,SAAgB,qBAAqB,UAA2B;AAC9D,KAAI,SACF,QAAO;CAGT,MAAM,aAAa,KAAK,YAAY,aAAa;AACjD,KAAI,WAAW,WAAW,CACxB,QAAO;AAGT,QAAO;;AAGT,SAAS,kBACP,YACA,eAC0B;AAC1B,QAAO,WAAW,MAAM,cAAc,UAAU,kBAAkB,cAAc;;AAGlF,SAAS,qBAAqB,IAAkB,WAA+B;AAC7E,KAAI,KAAK;EAAE,eAAe,UAAU;EAAe,MAAM,UAAU;EAAU,EAAE,4BAA4B;AAC3G,IAAG,KAAK,kBAAkB;AAC1B,KAAI;AACF,KAAG,KAAK,UAAU,IAAI;AACtB,mBAAiB,IAAI,UAAU,cAAc;AAC7C,KAAG,KAAK,SAAS;UACV,OAAO;AACd,MAAI;AACF,MAAG,KAAK,WAAW;UACb;EAGR,MAAM,KAAK,iBAAiB,QAAQ,MAAM,UAAU,OAAO,MAAM;AACjE,QAAM,IAAI,MACR,wBAAwB,UAAU,cAAc,IAAI,UAAU,SAAS,YAAY,MACnF,EAAE,OAAO,OAAO,CACjB;;;;;;;AAQL,SAAgB,uBACd,IACA,UAAkC,EAAE,EAC5B;CACR,MAAM,gBAAgB,QAAQ,iBAAA;CAC9B,IAAI,iBAAiB,kBAAkB,GAAG;AAE1C,KAAI,iBAAiB,cACnB,OAAM,IAAI,0BAA0B,gBAAgB,cAAc;AAGpE,KAAI,kBAAkB,cACpB,QAAO;CAGT,MAAM,aAAa,sBAAsB,qBAAqB,QAAQ,cAAc,CAAC;AAErF,QAAO,iBAAiB,eAAe;EACrC,MAAM,cAAc,iBAAiB;EACrC,MAAM,YAAY,kBAAkB,YAAY,YAAY;AAC5D,MAAI,CAAC,UACH,OAAM,IAAI,gCAAgC,gBAAgB,eAAe,YAAY;AAEvF,uBAAqB,IAAI,UAAU;AACnC,mBAAiB;;AAGnB,QAAO;;;AAaT,SAAgB,6BACd,IACA,UAA2E,EAAE,EACtD;CACvB,MAAM,aAAa,QAAQ,iBAAA;CAC3B,MAAM,YAAY,kBAAkB,GAAG;AAGvC,KAFiB,YAAY,WAG3B,QAAO;EACL;EACA;EACA,iBAAiB,EAAE;EACnB,UAAU;EACV,iBAAiB;EACjB,gBAAgB;EACjB;CAGH,MAAM,aAAa,sBAAsB,qBAAqB,QAAQ,cAAc,CAAC;CACrF,MAAM,kBAA4B,EAAE;CACpC,IAAI,kBAAkB;CACtB,IAAI,iBAAgC;AAEpC,MAAK,IAAI,UAAU,YAAY,GAAG,WAAW,YAAY,UACvD,KAAI,kBAAkB,YAAY,QAAQ,CACxC,iBAAgB,KAAK,QAAQ;MACxB;AACL,oBAAkB;AAClB,mBAAiB;AACjB;;AAIJ,QAAO;EACL;EACA;EACA;EACA,UAAU;EACV;EACA;EACD"}
@@ -19,7 +19,7 @@ const log = createLogger('Sqlite:Migrations');
19
19
  export const XOPC_DB_BASELINE_SCHEMA_VERSION = 11;
20
20
 
21
21
  /** Latest schema version this release supports (increment when adding migrations). */
22
- export const XOPC_DB_SCHEMA_VERSION = 15;
22
+ export const XOPC_DB_SCHEMA_VERSION = 18;
23
23
 
24
24
  const MODULE_DIR = dirname(fileURLToPath(import.meta.url));
25
25
 
@@ -1,7 +1,9 @@
1
+ import { init_agent_session_key, resolveAgentIdFromSessionKey } from "../../routing/agent-session-key.js";
1
2
  import "../../session/types.js";
2
3
  import { buildDefaultSessionMetadata } from "./session-metadata.js";
3
4
  import { isTranscriptContextEntry } from "../../session/session-context-for-llm.js";
4
5
  //#region src/storage/sqlite/row-mappers.ts
6
+ init_agent_session_key();
5
7
  function parseJson(raw) {
6
8
  if (!raw?.trim()) return;
7
9
  try {
@@ -63,7 +65,7 @@ function metadataToSessionInsert(sessionKey, sessionId, metadata, thinkingLevel,
63
65
  const now = Date.now();
64
66
  return {
65
67
  sessionKey,
66
- agentId: metadata.routing?.agentId?.trim().toLowerCase() || "main",
68
+ agentId: metadata.routing?.agentId?.trim().toLowerCase() || resolveAgentIdFromSessionKey(sessionKey),
67
69
  sessionId,
68
70
  status: metadata.status,
69
71
  name: metadata.name ?? null,
@@ -1 +1 @@
1
- {"version":3,"file":"row-mappers.js","names":["msg"],"sources":["../../../../src/storage/sqlite/row-mappers.ts"],"sourcesContent":["import type { AgentMessage } from '@earendil-works/pi-agent-core';\n\nimport type { SessionAgentConfig } from '../../session/config-types.js';\nimport {\n isTranscriptContextEntry,\n type TranscriptStoredRow,\n type XopcTranscriptContextEntry,\n} from '../../session/session-context-for-llm.js';\nimport { SessionStatus, type GlobalSessionStats, type SessionMetadata } from '../../session/types.js';\nimport { buildDefaultSessionMetadata } from './session-metadata.js';\n\nexport type SessionRow = {\n session_key: string;\n agent_id: string;\n session_id: string;\n status: string;\n name: string | null;\n tags_json: string;\n created_at: number;\n updated_at: number;\n last_accessed_at: number;\n session_started_at: number | null;\n last_interaction_at: number | null;\n source_channel: string;\n source_chat_id: string;\n session_type: string | null;\n hidden_from_session_list: number | null;\n parent_session_key: string | null;\n workflow_run_id: string | null;\n workflow_definition_id: string | null;\n workflow_agent_id: string | null;\n workflow_agent_label: string | null;\n routing_json: string | null;\n custom_data_json: string | null;\n abort_cutoff_timestamp: number | null;\n message_count: number;\n estimated_tokens: number;\n compacted_count: number;\n last_flushed_at: string | null;\n flush_count: number;\n thinking_level: string | null;\n verbose_level: string | null;\n cwd?: string | null;\n};\n\nexport type TranscriptEntryRow = {\n entry_id: string;\n session_id: string;\n seq: number;\n entry_kind: string;\n role: string | null;\n payload_json: string;\n created_at: number;\n};\n\nexport type SessionConfigRow = {\n session_key: string;\n thinking_level: string | null;\n reasoning_level: string | null;\n verbose_level: string | null;\n elevated_mode: string | null;\n model_override: string | null;\n provider_override: string | null;\n working_directory_override: string | null;\n updated_at: number;\n};\n\nfunction parseJson<T>(raw: string | null | undefined): T | undefined {\n if (!raw?.trim()) {\n return undefined;\n }\n try {\n return JSON.parse(raw) as T;\n } catch {\n return undefined;\n }\n}\n\nfunction isoFromMs(ms: number | null | undefined): string | undefined {\n if (ms == null || !Number.isFinite(ms)) {\n return undefined;\n }\n return new Date(ms).toISOString();\n}\n\nexport function sessionRowToMetadata(sessionKey: string, row: SessionRow): SessionMetadata {\n const defaults = buildDefaultSessionMetadata(sessionKey);\n const routing = parseJson<SessionMetadata['routing']>(row.routing_json);\n const customData = parseJson<Record<string, unknown>>(row.custom_data_json);\n const tags = parseJson<string[]>(row.tags_json) ?? [];\n const createdAt = isoFromMs(row.created_at) ?? defaults.createdAt;\n const updatedAt = isoFromMs(row.updated_at) ?? defaults.updatedAt;\n const lastAccessedAt = isoFromMs(row.last_accessed_at) ?? defaults.lastAccessedAt;\n\n return {\n ...defaults,\n key: sessionKey,\n status: row.status as SessionStatus,\n name: row.name ?? undefined,\n tags,\n createdAt,\n updatedAt,\n lastAccessedAt,\n sessionStartedAt: isoFromMs(row.session_started_at),\n lastInteractionAt: isoFromMs(row.last_interaction_at),\n sourceChannel: row.source_channel,\n sourceChatId: row.source_chat_id,\n sessionType: (row.session_type ?? defaults.sessionType) as SessionMetadata['sessionType'],\n hiddenFromSessionList: Boolean(row.hidden_from_session_list),\n parentSessionKey: row.parent_session_key ?? undefined,\n workflowRunId: row.workflow_run_id ?? undefined,\n workflowDefinitionId: row.workflow_definition_id ?? undefined,\n workflowAgentId: row.workflow_agent_id ?? undefined,\n workflowAgentLabel: row.workflow_agent_label ?? undefined,\n ...(routing ? { routing } : {}),\n ...(customData ? { customData } : {}),\n abortCutoffTimestamp: row.abort_cutoff_timestamp ?? undefined,\n messageCount: row.message_count,\n estimatedTokens: row.estimated_tokens,\n compactedCount: row.compacted_count,\n lastFlushedAt: row.last_flushed_at ?? undefined,\n flushCount: row.flush_count,\n sessionId: row.session_id,\n cwd: row.cwd ?? undefined,\n stats: {\n messageCount: row.message_count,\n tokenCount: row.estimated_tokens,\n lastTurnAt: row.last_interaction_at ?? undefined,\n },\n };\n}\n\nexport function metadataToSessionInsert(\n sessionKey: string,\n sessionId: string,\n metadata: SessionMetadata,\n thinkingLevel?: string | null,\n verboseLevel?: string | null,\n): {\n sessionKey: string;\n agentId: string;\n sessionId: string;\n status: string;\n name: string | null;\n tagsJson: string;\n createdAt: number;\n updatedAt: number;\n lastAccessedAt: number;\n sessionStartedAt: number | null;\n lastInteractionAt: number | null;\n sourceChannel: string;\n sourceChatId: string;\n sessionType: string;\n hiddenFromSessionList: number;\n parentSessionKey: string | null;\n workflowRunId: string | null;\n workflowDefinitionId: string | null;\n workflowAgentId: string | null;\n workflowAgentLabel: string | null;\n routingJson: string | null;\n customDataJson: string | null;\n abortCutoffTimestamp: number | null;\n messageCount: number;\n estimatedTokens: number;\n compactedCount: number;\n lastFlushedAt: string | null;\n flushCount: number;\n thinkingLevel: string | null;\n verboseLevel: string | null;\n} {\n const now = Date.now();\n const agentId = metadata.routing?.agentId?.trim().toLowerCase() || 'main';\n return {\n sessionKey,\n agentId,\n sessionId,\n status: metadata.status,\n name: metadata.name ?? null,\n tagsJson: JSON.stringify(metadata.tags ?? []),\n createdAt: Date.parse(metadata.createdAt) || now,\n updatedAt: Date.parse(metadata.updatedAt) || now,\n lastAccessedAt: Date.parse(metadata.lastAccessedAt) || now,\n sessionStartedAt: metadata.sessionStartedAt ? Date.parse(metadata.sessionStartedAt) : now,\n lastInteractionAt: metadata.lastInteractionAt ? Date.parse(metadata.lastInteractionAt) : null,\n sourceChannel: metadata.sourceChannel,\n sourceChatId: metadata.sourceChatId,\n sessionType: metadata.sessionType,\n hiddenFromSessionList: metadata.hiddenFromSessionList ? 1 : 0,\n parentSessionKey: metadata.parentSessionKey ?? null,\n workflowRunId: metadata.workflowRunId ?? null,\n workflowDefinitionId: metadata.workflowDefinitionId ?? null,\n workflowAgentId: metadata.workflowAgentId ?? null,\n workflowAgentLabel: metadata.workflowAgentLabel ?? null,\n routingJson: metadata.routing ? JSON.stringify(metadata.routing) : null,\n customDataJson: metadata.customData ? JSON.stringify(metadata.customData) : null,\n abortCutoffTimestamp: metadata.abortCutoffTimestamp ?? null,\n messageCount: metadata.messageCount,\n estimatedTokens: metadata.estimatedTokens,\n compactedCount: metadata.compactedCount,\n lastFlushedAt: metadata.lastFlushedAt ?? null,\n flushCount: metadata.flushCount ?? 0,\n thinkingLevel: thinkingLevel ?? null,\n verboseLevel: verboseLevel ?? null,\n };\n}\n\nexport function sessionConfigRowToConfig(row: SessionConfigRow): SessionAgentConfig {\n return {\n ...(row.thinking_level ? { thinkingLevel: row.thinking_level as SessionAgentConfig['thinkingLevel'] } : {}),\n ...(row.reasoning_level ? { reasoningLevel: row.reasoning_level as SessionAgentConfig['reasoningLevel'] } : {}),\n ...(row.verbose_level ? { verboseLevel: row.verbose_level as SessionAgentConfig['verboseLevel'] } : {}),\n ...(row.elevated_mode ? { elevatedMode: row.elevated_mode as SessionAgentConfig['elevatedMode'] } : {}),\n ...(row.model_override ? { modelOverride: row.model_override } : {}),\n ...(row.provider_override ? { providerOverride: row.provider_override } : {}),\n ...(row.working_directory_override ? { workingDirectoryOverride: row.working_directory_override } : {}),\n updatedAt: row.updated_at,\n };\n}\n\nexport function transcriptEntryRowToStoredRow(row: TranscriptEntryRow): TranscriptStoredRow {\n const payload = JSON.parse(row.payload_json) as TranscriptStoredRow;\n return payload;\n}\n\nexport function classifyStoredRow(row: TranscriptStoredRow): {\n entryKind: 'message' | 'context' | 'compaction';\n role: string | null;\n} {\n if (isTranscriptContextEntry(row)) {\n return { entryKind: 'context', role: null };\n }\n const record = row as AgentMessage & { type?: string };\n if (record.type === 'compaction' || (row as { kind?: string }).kind === 'compaction') {\n return { entryKind: 'compaction', role: null };\n }\n return { entryKind: 'message', role: record.role ?? null };\n}\n\nexport function extractFtsContent(row: TranscriptStoredRow): string {\n if (isTranscriptContextEntry(row)) {\n const ctx = row as XopcTranscriptContextEntry;\n return [ctx.text, ctx.id].filter(Boolean).join(' ');\n }\n const msg = row as AgentMessage;\n return extractTextFromMessageContent((msg as { content?: unknown }).content);\n}\n\nfunction extractTextFromMessageContent(content: unknown): string {\n if (typeof content === 'string') {\n return content;\n }\n if (!Array.isArray(content)) {\n return '';\n }\n const parts: string[] = [];\n for (const block of content) {\n if (!block || typeof block !== 'object') {\n continue;\n }\n const type = (block as { type?: string }).type;\n if (type === 'text' && typeof (block as { text?: string }).text === 'string') {\n parts.push((block as { text: string }).text);\n }\n }\n return parts.join('\\n');\n}\n\nexport function estimateTokensFromMessages(messages: AgentMessage[]): number {\n let total = 0;\n for (const msg of messages) {\n const content = (msg as { content?: unknown }).content;\n const text = extractTextFromMessageContent(content);\n total += Math.ceil(text.length / 4);\n }\n return total;\n}\n\nexport function buildGlobalSessionStats(sessions: SessionMetadata[]): GlobalSessionStats {\n const byChannel: Record<string, number> = {};\n for (const session of sessions) {\n byChannel[session.sourceChannel] = (byChannel[session.sourceChannel] || 0) + 1;\n }\n let oldestSession: string | undefined;\n let newestSession: string | undefined;\n if (sessions.length > 0) {\n const sorted = [...sessions].sort((a, b) => a.createdAt.localeCompare(b.createdAt));\n oldestSession = sorted[0]!.createdAt;\n newestSession = sorted[sorted.length - 1]!.createdAt;\n }\n return {\n totalSessions: sessions.length,\n activeSessions: sessions.filter(\n (s) => s.status === SessionStatus.ACTIVE || s.status === SessionStatus.IDLE,\n ).length,\n archivedSessions: sessions.filter((s) => s.status === SessionStatus.ARCHIVED).length,\n pinnedSessions: sessions.filter((s) => s.status === SessionStatus.PINNED).length,\n totalMessages: sessions.reduce((sum, s) => sum + s.messageCount, 0),\n totalTokens: sessions.reduce((sum, s) => sum + s.estimatedTokens, 0),\n oldestSession,\n newestSession,\n byChannel,\n };\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"row-mappers.js","names":["msg"],"sources":["../../../../src/storage/sqlite/row-mappers.ts"],"sourcesContent":["import type { AgentMessage } from '@earendil-works/pi-agent-core';\n\nimport type { SessionAgentConfig } from '../../session/config-types.js';\nimport {\n isTranscriptContextEntry,\n type TranscriptStoredRow,\n type XopcTranscriptContextEntry,\n} from '../../session/session-context-for-llm.js';\nimport { SessionStatus, type GlobalSessionStats, type SessionMetadata } from '../../session/types.js';\nimport { resolveAgentIdFromSessionKey } from '../../routing/agent-session-key.js';\nimport { buildDefaultSessionMetadata } from './session-metadata.js';\n\nexport type SessionRow = {\n session_key: string;\n agent_id: string;\n session_id: string;\n status: string;\n name: string | null;\n tags_json: string;\n created_at: number;\n updated_at: number;\n last_accessed_at: number;\n session_started_at: number | null;\n last_interaction_at: number | null;\n source_channel: string;\n source_chat_id: string;\n session_type: string | null;\n hidden_from_session_list: number | null;\n parent_session_key: string | null;\n workflow_run_id: string | null;\n workflow_definition_id: string | null;\n workflow_agent_id: string | null;\n workflow_agent_label: string | null;\n routing_json: string | null;\n custom_data_json: string | null;\n abort_cutoff_timestamp: number | null;\n message_count: number;\n estimated_tokens: number;\n compacted_count: number;\n last_flushed_at: string | null;\n flush_count: number;\n thinking_level: string | null;\n verbose_level: string | null;\n cwd?: string | null;\n};\n\nexport type TranscriptEntryRow = {\n entry_id: string;\n session_id: string;\n seq: number;\n entry_kind: string;\n role: string | null;\n payload_json: string;\n created_at: number;\n};\n\nexport type SessionConfigRow = {\n session_key: string;\n thinking_level: string | null;\n reasoning_level: string | null;\n verbose_level: string | null;\n elevated_mode: string | null;\n model_override: string | null;\n provider_override: string | null;\n working_directory_override: string | null;\n updated_at: number;\n};\n\nfunction parseJson<T>(raw: string | null | undefined): T | undefined {\n if (!raw?.trim()) {\n return undefined;\n }\n try {\n return JSON.parse(raw) as T;\n } catch {\n return undefined;\n }\n}\n\nfunction isoFromMs(ms: number | null | undefined): string | undefined {\n if (ms == null || !Number.isFinite(ms)) {\n return undefined;\n }\n return new Date(ms).toISOString();\n}\n\nexport function sessionRowToMetadata(sessionKey: string, row: SessionRow): SessionMetadata {\n const defaults = buildDefaultSessionMetadata(sessionKey);\n const routing = parseJson<SessionMetadata['routing']>(row.routing_json);\n const customData = parseJson<Record<string, unknown>>(row.custom_data_json);\n const tags = parseJson<string[]>(row.tags_json) ?? [];\n const createdAt = isoFromMs(row.created_at) ?? defaults.createdAt;\n const updatedAt = isoFromMs(row.updated_at) ?? defaults.updatedAt;\n const lastAccessedAt = isoFromMs(row.last_accessed_at) ?? defaults.lastAccessedAt;\n\n return {\n ...defaults,\n key: sessionKey,\n status: row.status as SessionStatus,\n name: row.name ?? undefined,\n tags,\n createdAt,\n updatedAt,\n lastAccessedAt,\n sessionStartedAt: isoFromMs(row.session_started_at),\n lastInteractionAt: isoFromMs(row.last_interaction_at),\n sourceChannel: row.source_channel,\n sourceChatId: row.source_chat_id,\n sessionType: (row.session_type ?? defaults.sessionType) as SessionMetadata['sessionType'],\n hiddenFromSessionList: Boolean(row.hidden_from_session_list),\n parentSessionKey: row.parent_session_key ?? undefined,\n workflowRunId: row.workflow_run_id ?? undefined,\n workflowDefinitionId: row.workflow_definition_id ?? undefined,\n workflowAgentId: row.workflow_agent_id ?? undefined,\n workflowAgentLabel: row.workflow_agent_label ?? undefined,\n ...(routing ? { routing } : {}),\n ...(customData ? { customData } : {}),\n abortCutoffTimestamp: row.abort_cutoff_timestamp ?? undefined,\n messageCount: row.message_count,\n estimatedTokens: row.estimated_tokens,\n compactedCount: row.compacted_count,\n lastFlushedAt: row.last_flushed_at ?? undefined,\n flushCount: row.flush_count,\n sessionId: row.session_id,\n cwd: row.cwd ?? undefined,\n stats: {\n messageCount: row.message_count,\n tokenCount: row.estimated_tokens,\n lastTurnAt: row.last_interaction_at ?? undefined,\n },\n };\n}\n\nexport function metadataToSessionInsert(\n sessionKey: string,\n sessionId: string,\n metadata: SessionMetadata,\n thinkingLevel?: string | null,\n verboseLevel?: string | null,\n): {\n sessionKey: string;\n agentId: string;\n sessionId: string;\n status: string;\n name: string | null;\n tagsJson: string;\n createdAt: number;\n updatedAt: number;\n lastAccessedAt: number;\n sessionStartedAt: number | null;\n lastInteractionAt: number | null;\n sourceChannel: string;\n sourceChatId: string;\n sessionType: string;\n hiddenFromSessionList: number;\n parentSessionKey: string | null;\n workflowRunId: string | null;\n workflowDefinitionId: string | null;\n workflowAgentId: string | null;\n workflowAgentLabel: string | null;\n routingJson: string | null;\n customDataJson: string | null;\n abortCutoffTimestamp: number | null;\n messageCount: number;\n estimatedTokens: number;\n compactedCount: number;\n lastFlushedAt: string | null;\n flushCount: number;\n thinkingLevel: string | null;\n verboseLevel: string | null;\n} {\n const now = Date.now();\n const agentId = metadata.routing?.agentId?.trim().toLowerCase()\n || resolveAgentIdFromSessionKey(sessionKey);\n return {\n sessionKey,\n agentId,\n sessionId,\n status: metadata.status,\n name: metadata.name ?? null,\n tagsJson: JSON.stringify(metadata.tags ?? []),\n createdAt: Date.parse(metadata.createdAt) || now,\n updatedAt: Date.parse(metadata.updatedAt) || now,\n lastAccessedAt: Date.parse(metadata.lastAccessedAt) || now,\n sessionStartedAt: metadata.sessionStartedAt ? Date.parse(metadata.sessionStartedAt) : now,\n lastInteractionAt: metadata.lastInteractionAt ? Date.parse(metadata.lastInteractionAt) : null,\n sourceChannel: metadata.sourceChannel,\n sourceChatId: metadata.sourceChatId,\n sessionType: metadata.sessionType,\n hiddenFromSessionList: metadata.hiddenFromSessionList ? 1 : 0,\n parentSessionKey: metadata.parentSessionKey ?? null,\n workflowRunId: metadata.workflowRunId ?? null,\n workflowDefinitionId: metadata.workflowDefinitionId ?? null,\n workflowAgentId: metadata.workflowAgentId ?? null,\n workflowAgentLabel: metadata.workflowAgentLabel ?? null,\n routingJson: metadata.routing ? JSON.stringify(metadata.routing) : null,\n customDataJson: metadata.customData ? JSON.stringify(metadata.customData) : null,\n abortCutoffTimestamp: metadata.abortCutoffTimestamp ?? null,\n messageCount: metadata.messageCount,\n estimatedTokens: metadata.estimatedTokens,\n compactedCount: metadata.compactedCount,\n lastFlushedAt: metadata.lastFlushedAt ?? null,\n flushCount: metadata.flushCount ?? 0,\n thinkingLevel: thinkingLevel ?? null,\n verboseLevel: verboseLevel ?? null,\n };\n}\n\nexport function sessionConfigRowToConfig(row: SessionConfigRow): SessionAgentConfig {\n return {\n ...(row.thinking_level ? { thinkingLevel: row.thinking_level as SessionAgentConfig['thinkingLevel'] } : {}),\n ...(row.reasoning_level ? { reasoningLevel: row.reasoning_level as SessionAgentConfig['reasoningLevel'] } : {}),\n ...(row.verbose_level ? { verboseLevel: row.verbose_level as SessionAgentConfig['verboseLevel'] } : {}),\n ...(row.elevated_mode ? { elevatedMode: row.elevated_mode as SessionAgentConfig['elevatedMode'] } : {}),\n ...(row.model_override ? { modelOverride: row.model_override } : {}),\n ...(row.provider_override ? { providerOverride: row.provider_override } : {}),\n ...(row.working_directory_override ? { workingDirectoryOverride: row.working_directory_override } : {}),\n updatedAt: row.updated_at,\n };\n}\n\nexport function transcriptEntryRowToStoredRow(row: TranscriptEntryRow): TranscriptStoredRow {\n const payload = JSON.parse(row.payload_json) as TranscriptStoredRow;\n return payload;\n}\n\nexport function classifyStoredRow(row: TranscriptStoredRow): {\n entryKind: 'message' | 'context' | 'compaction';\n role: string | null;\n} {\n if (isTranscriptContextEntry(row)) {\n return { entryKind: 'context', role: null };\n }\n const record = row as AgentMessage & { type?: string };\n if (record.type === 'compaction' || (row as { kind?: string }).kind === 'compaction') {\n return { entryKind: 'compaction', role: null };\n }\n return { entryKind: 'message', role: record.role ?? null };\n}\n\nexport function extractFtsContent(row: TranscriptStoredRow): string {\n if (isTranscriptContextEntry(row)) {\n const ctx = row as XopcTranscriptContextEntry;\n return [ctx.text, ctx.id].filter(Boolean).join(' ');\n }\n const msg = row as AgentMessage;\n return extractTextFromMessageContent((msg as { content?: unknown }).content);\n}\n\nfunction extractTextFromMessageContent(content: unknown): string {\n if (typeof content === 'string') {\n return content;\n }\n if (!Array.isArray(content)) {\n return '';\n }\n const parts: string[] = [];\n for (const block of content) {\n if (!block || typeof block !== 'object') {\n continue;\n }\n const type = (block as { type?: string }).type;\n if (type === 'text' && typeof (block as { text?: string }).text === 'string') {\n parts.push((block as { text: string }).text);\n }\n }\n return parts.join('\\n');\n}\n\nexport function estimateTokensFromMessages(messages: AgentMessage[]): number {\n let total = 0;\n for (const msg of messages) {\n const content = (msg as { content?: unknown }).content;\n const text = extractTextFromMessageContent(content);\n total += Math.ceil(text.length / 4);\n }\n return total;\n}\n\nexport function buildGlobalSessionStats(sessions: SessionMetadata[]): GlobalSessionStats {\n const byChannel: Record<string, number> = {};\n for (const session of sessions) {\n byChannel[session.sourceChannel] = (byChannel[session.sourceChannel] || 0) + 1;\n }\n let oldestSession: string | undefined;\n let newestSession: string | undefined;\n if (sessions.length > 0) {\n const sorted = [...sessions].sort((a, b) => a.createdAt.localeCompare(b.createdAt));\n oldestSession = sorted[0]!.createdAt;\n newestSession = sorted[sorted.length - 1]!.createdAt;\n }\n return {\n totalSessions: sessions.length,\n activeSessions: sessions.filter(\n (s) => s.status === SessionStatus.ACTIVE || s.status === SessionStatus.IDLE,\n ).length,\n archivedSessions: sessions.filter((s) => s.status === SessionStatus.ARCHIVED).length,\n pinnedSessions: sessions.filter((s) => s.status === SessionStatus.PINNED).length,\n totalMessages: sessions.reduce((sum, s) => sum + s.messageCount, 0),\n totalTokens: sessions.reduce((sum, s) => sum + s.estimatedTokens, 0),\n oldestSession,\n newestSession,\n byChannel,\n };\n}\n"],"mappings":"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"}
@@ -31,7 +31,7 @@ function ensureXopcDatabaseSchema(db) {
31
31
  bootstrapFreshDatabase(db);
32
32
  currentVersion = 11;
33
33
  }
34
- applyPendingMigrations(db, { targetVersion: 15 });
34
+ applyPendingMigrations(db, { targetVersion: 18 });
35
35
  }
36
36
  //#endregion
37
37
  export { SCHEMA_META_SCHEMA_VERSION_KEY, XOPC_DB_BASELINE_SCHEMA_VERSION, XOPC_DB_SCHEMA_VERSION, ensureSchemaMetaTable, ensureXopcDatabaseSchema, readSchemaVersion, readSchemaVersionForTest, setSchemaVersion };
@@ -1,4 +1,4 @@
1
- -- xopc SQLite schema: sessions, transcripts, cron, notes, memory, FTS
1
+ -- xopc SQLite schema: sessions, transcripts, automations, notes, memory, FTS
2
2
 
3
3
  CREATE TABLE IF NOT EXISTS sessions (
4
4
  session_key TEXT PRIMARY KEY,
@@ -118,55 +118,65 @@ CREATE VIRTUAL TABLE IF NOT EXISTS transcript_fts USING fts5(
118
118
  tokenize='unicode61'
119
119
  );
120
120
 
121
- CREATE TABLE IF NOT EXISTS cron_runs (
122
- run_id TEXT PRIMARY KEY,
123
- job_id TEXT NOT NULL,
124
- status TEXT NOT NULL,
125
- started_at INTEGER NOT NULL,
126
- ended_at INTEGER,
127
- duration_ms INTEGER,
128
- error TEXT,
129
- output TEXT,
130
- retry_count INTEGER NOT NULL DEFAULT 0,
131
- summary TEXT,
132
- session_id TEXT,
133
- session_key TEXT,
134
- session_type TEXT,
135
- model TEXT,
136
- provider TEXT,
137
- usage_json TEXT,
138
- workflow_run_id TEXT
121
+ CREATE TABLE IF NOT EXISTS automations (
122
+ automation_id TEXT PRIMARY KEY,
123
+ name TEXT NOT NULL,
124
+ description TEXT,
125
+ enabled INTEGER NOT NULL,
126
+ trigger_json TEXT NOT NULL,
127
+ action_json TEXT NOT NULL,
128
+ after_run_json TEXT,
129
+ reliability_json TEXT,
130
+ state_json TEXT NOT NULL DEFAULT '{}',
131
+ created_at_ms INTEGER NOT NULL,
132
+ updated_at_ms INTEGER NOT NULL
139
133
  );
140
134
 
141
- CREATE INDEX IF NOT EXISTS idx_cron_runs_job_started
142
- ON cron_runs(job_id, started_at DESC);
143
- CREATE INDEX IF NOT EXISTS idx_cron_runs_started
144
- ON cron_runs(started_at DESC);
145
-
146
- CREATE TABLE IF NOT EXISTS cron_jobs (
147
- job_id TEXT PRIMARY KEY,
148
- name TEXT NOT NULL,
149
- description TEXT,
150
- enabled INTEGER NOT NULL,
151
- delete_after_run INTEGER,
152
- created_at_ms INTEGER NOT NULL,
153
- updated_at_ms INTEGER NOT NULL,
154
- schedule_json TEXT NOT NULL,
155
- session_target TEXT NOT NULL,
156
- wake_mode TEXT NOT NULL,
157
- agent_id TEXT,
158
- session_key TEXT,
159
- working_directory TEXT,
160
- payload_json TEXT NOT NULL,
161
- delivery_json TEXT,
162
- failure_alert_json TEXT,
163
- state_json TEXT NOT NULL DEFAULT '{}'
135
+ CREATE INDEX IF NOT EXISTS idx_automations_enabled
136
+ ON automations(enabled, updated_at_ms DESC);
137
+ CREATE INDEX IF NOT EXISTS idx_automations_updated
138
+ ON automations(updated_at_ms DESC);
139
+
140
+ CREATE TABLE IF NOT EXISTS automation_runs (
141
+ run_id TEXT PRIMARY KEY,
142
+ automation_id TEXT NOT NULL,
143
+ automation_name TEXT NOT NULL,
144
+ status TEXT NOT NULL,
145
+ trigger_snapshot_json TEXT NOT NULL,
146
+ action_snapshot_json TEXT NOT NULL,
147
+ manual INTEGER NOT NULL,
148
+ created_at_ms INTEGER NOT NULL,
149
+ started_at_ms INTEGER,
150
+ ended_at_ms INTEGER,
151
+ duration_ms INTEGER,
152
+ summary TEXT,
153
+ error TEXT,
154
+ session_key TEXT,
155
+ workflow_run_id TEXT,
156
+ model TEXT
164
157
  );
165
158
 
166
- CREATE INDEX IF NOT EXISTS idx_cron_jobs_enabled_next
167
- ON cron_jobs(enabled, job_id);
168
- CREATE INDEX IF NOT EXISTS idx_cron_jobs_updated
169
- ON cron_jobs(updated_at_ms DESC);
159
+ CREATE INDEX IF NOT EXISTS idx_automation_runs_automation_created
160
+ ON automation_runs(automation_id, created_at_ms DESC);
161
+ CREATE INDEX IF NOT EXISTS idx_automation_runs_created
162
+ ON automation_runs(created_at_ms DESC);
163
+ CREATE INDEX IF NOT EXISTS idx_automation_runs_status_created
164
+ ON automation_runs(status, created_at_ms DESC);
165
+
166
+ CREATE TABLE IF NOT EXISTS automation_run_events (
167
+ event_id TEXT PRIMARY KEY,
168
+ run_id TEXT NOT NULL,
169
+ automation_id TEXT NOT NULL,
170
+ type TEXT NOT NULL,
171
+ message TEXT NOT NULL,
172
+ data_json TEXT,
173
+ created_at_ms INTEGER NOT NULL
174
+ );
175
+
176
+ CREATE INDEX IF NOT EXISTS idx_automation_run_events_run_created
177
+ ON automation_run_events(run_id, created_at_ms ASC);
178
+ CREATE INDEX IF NOT EXISTS idx_automation_run_events_automation_created
179
+ ON automation_run_events(automation_id, created_at_ms DESC);
170
180
 
171
181
  CREATE TABLE IF NOT EXISTS workflow_runs (
172
182
  run_id TEXT PRIMARY KEY,
@@ -1,8 +1,10 @@
1
1
  import type { ExtensionRegistryImpl } from '../../extensions/loader.js';
2
+ import { type Config } from '../../config/schema.js';
2
3
  import type { ExportFormat } from '../../session/types.js';
3
4
  import type { ChatSendOptions, HistoryMessage, TuiBackend, TuiCompactionResult, TuiEvent, TuiModelChoice, TuiShareRequest, TuiShareResult, TuiSessionStats, TuiSessionItem, TuiTranscriptTreeEntry, TuiAgentInfo, TuiWorkspaceFileSearchEntry, TuiWorkflowRunStartRequest, TuiWorkflowRunStartResult } from '../tui-backend.js';
4
5
  import type { SessionInfo } from '../tui-types.js';
5
6
  interface EmbeddedBackendOptions {
7
+ config?: Config;
6
8
  extensionRegistry?: ExtensionRegistryImpl;
7
9
  implicitTrustedWorkspace?: string;
8
10
  isWorkspaceTrusted?: (workspaceDir: string) => boolean | null | undefined;
@@ -36,6 +38,7 @@ export declare class EmbeddedBackend implements TuiBackend {
36
38
  stop(): void;
37
39
  getActiveSignal(): AbortSignal | undefined;
38
40
  private getWorkflowRunService;
41
+ private activeConfig;
39
42
  getStartupResources(sessionKey: string): Promise<import("../tui-backend.js").TuiStartupResources>;
40
43
  startWorkflowRun(opts: TuiWorkflowRunStartRequest): Promise<TuiWorkflowRunStartResult>;
41
44
  searchWorkspaceFiles(sessionKey: string, query: string, options?: {
@@ -66,6 +69,9 @@ export declare class EmbeddedBackend implements TuiBackend {
66
69
  getSessionStats(sessionKey: string): Promise<TuiSessionStats>;
67
70
  listSessions(): Promise<TuiSessionItem[]>;
68
71
  listAgents(): Promise<TuiAgentInfo[]>;
72
+ setTuiDefaultAgent(agentId: string): Promise<{
73
+ agentId: string;
74
+ }>;
69
75
  renameSession(sessionKey: string, name: string): Promise<{
70
76
  ok: boolean;
71
77
  }>;
@@ -3,7 +3,7 @@ import { init_agent_scope, listAgentEntries, normalizeAgentId } from "../../agen
3
3
  import { init_agent_session_key, resolveAgentIdFromSessionKey } from "../../routing/agent-session-key.js";
4
4
  import { createLogger } from "../../utils/logger/index.js";
5
5
  import { init_logger } from "../../utils/logger.js";
6
- import { loadConfig } from "../../config/loader.js";
6
+ import { loadConfig, saveConfig } from "../../config/loader.js";
7
7
  import { createCreateShareTool, isShareToolAvailable } from "../../agent/tools/create-share-tool.js";
8
8
  import { openXopcDatabase } from "../../storage/sqlite/connection.js";
9
9
  import "../../storage/sqlite/index.js";
@@ -15,6 +15,7 @@ import "../../session/index.js";
15
15
  import { parseModelRef } from "../../agent/models/selection.js";
16
16
  import { MessageBus, MessageBusShutdownError } from "../../infra/bus/queue.js";
17
17
  import "../../infra/bus/index.js";
18
+ import { setTuiDefaultAgentConfig } from "../../commands/agents.config.js";
18
19
  import { getWorkspacePath } from "../../config/workspace-path-helpers.js";
19
20
  import "../../config/index.js";
20
21
  import { buildWorkflowChildTools } from "../../agent/workflow/workflow-child-tools.js";
@@ -67,7 +68,7 @@ var EmbeddedBackend = class {
67
68
  start() {
68
69
  if (this.running) return;
69
70
  this.running = true;
70
- const config = loadConfig();
71
+ const config = this.opts?.config ?? loadConfig();
71
72
  this.config = config;
72
73
  const workspace = getWorkspacePath(config);
73
74
  this.workspace = workspace;
@@ -163,8 +164,11 @@ var EmbeddedBackend = class {
163
164
  });
164
165
  return this.workflowRunService;
165
166
  }
167
+ activeConfig() {
168
+ return this.config ?? this.opts?.config ?? loadConfig();
169
+ }
166
170
  async getStartupResources(sessionKey) {
167
- return collectTuiStartupResources(loadConfig(), sessionKey);
171
+ return collectTuiStartupResources(this.activeConfig(), sessionKey);
168
172
  }
169
173
  async startWorkflowRun(opts) {
170
174
  await this.sessionIndexReady;
@@ -325,7 +329,7 @@ var EmbeddedBackend = class {
325
329
  }
326
330
  }
327
331
  async listAgents() {
328
- const config = loadConfig();
332
+ const config = this.activeConfig();
329
333
  const agents = /* @__PURE__ */ new Map();
330
334
  for (const entry of listAgentEntries(config)) {
331
335
  if (entry.enabled === false) continue;
@@ -337,6 +341,13 @@ var EmbeddedBackend = class {
337
341
  }
338
342
  return [...agents.values()].sort((a, b) => a.id.localeCompare(b.id));
339
343
  }
344
+ async setTuiDefaultAgent(agentId) {
345
+ const result = setTuiDefaultAgentConfig(this.activeConfig(), agentId);
346
+ if (result.ok === false) throw new Error(result.message);
347
+ await saveConfig(result.config);
348
+ this.config = result.config;
349
+ return { agentId: result.agentId };
350
+ }
340
351
  async renameSession(sessionKey, name) {
341
352
  if (!this.agent) return { ok: false };
342
353
  try {
@@ -367,7 +378,7 @@ var EmbeddedBackend = class {
367
378
  }
368
379
  }
369
380
  async getSessionInfo(sessionKey) {
370
- if (!this.agent) return { model: getAgentDefaultModelRef(loadConfig()) ?? void 0 };
381
+ if (!this.agent) return { model: getAgentDefaultModelRef(this.activeConfig()) ?? void 0 };
371
382
  try {
372
383
  const cfg = await this.agent.sessionInspector.agentConfig(sessionKey);
373
384
  const parsed = parseModelRef(cfg.model);
@@ -391,7 +402,7 @@ var EmbeddedBackend = class {
391
402
  sessionKey,
392
403
  errorMessage
393
404
  }, `getSessionInfo failed: ${errorMessage}`);
394
- return { model: getAgentDefaultModelRef(loadConfig()) ?? void 0 };
405
+ return { model: getAgentDefaultModelRef(this.activeConfig()) ?? void 0 };
395
406
  }
396
407
  }
397
408
  async listModels() {
@@ -408,8 +419,7 @@ var EmbeddedBackend = class {
408
419
  await this.agent.resetSession(sessionKey);
409
420
  }
410
421
  async patchSession(sessionKey, patch) {
411
- if (!this.agent) return;
412
- const result = await this.agent.sessionConfig.patch(sessionKey, {
422
+ const result = await (await this.ensureAgent()).sessionConfig.patch(sessionKey, {
413
423
  model: typeof patch.model === "string" ? patch.model : void 0,
414
424
  thinkingLevel: typeof patch.thinkingLevel === "string" ? patch.thinkingLevel : void 0,
415
425
  reasoningLevel: typeof patch.reasoningLevel === "string" ? patch.reasoningLevel : void 0,
@@ -456,7 +466,7 @@ var EmbeddedBackend = class {
456
466
  }
457
467
  async createShare(_sessionKey, request, _options) {
458
468
  if (!this.agent) throw new Error("Agent not started");
459
- const config = loadConfig();
469
+ const config = this.activeConfig();
460
470
  if (!isShareToolAvailable(config)) throw new Error("Sharing is disabled in gateway config");
461
471
  const result = await createCreateShareTool({
462
472
  workspace: getWorkspacePath(config),
@@ -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 } from '../../config/index.js';\nimport { getAgentDefaultModelRef } from '../../config/schema.js';\nimport { MessageBus, MessageBusShutdownError } from '../../infra/bus/index.js';\nimport { evictEmbeddedSessionRunner } from '../../agent/embedded/session-runner.js';\nimport type { ExportFormat } from '../../session/types.js';\nimport { SessionIndex } from '../../session/index.js';\nimport { 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} 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';\n\nconst log = createLogger('TUI:Embedded');\n\ninterface EmbeddedBackendOptions {\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: ReturnType<typeof loadConfig> | 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 = 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: ReturnType<typeof loadConfig>, 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 async getStartupResources(sessionKey: string) {\n return collectTuiStartupResources(loadConfig(), 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 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 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 = loadConfig();\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 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 = loadConfig();\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 = loadConfig();\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 if (!this.agent) return;\n const result = await this.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 = loadConfig();\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 { 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 type { ExportFormat } from '../../session/types.js';\nimport { SessionIndex } from '../../session/index.js';\nimport { 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} 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';\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 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 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 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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"}