@xopcai/xopc 0.0.113 → 0.0.115

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 (567) hide show
  1. package/dist/browser-ext/manifest.json +1 -1
  2. package/dist/extensions/feishu/src/outbound/media-load.js +1 -1
  3. package/dist/extensions/feishu/src/workflow-progress.js +1 -1
  4. package/dist/extensions/telegram/src/adapters/streaming-adapter.js +1 -1
  5. package/dist/extensions/telegram/src/inbound-processor.js +1 -1
  6. package/dist/extensions/telegram/src/plugin.js +1 -1
  7. package/dist/extensions/telegram/src/routing-integration.js +2 -2
  8. package/dist/extensions/telegram/src/update-offset-store.js +1 -1
  9. package/dist/extensions/telegram/src/workflow-progress.js +1 -1
  10. package/dist/extensions/telegram/xopc.extension.json +1 -1
  11. package/dist/extensions/weixin/src/api/api.js +2 -2
  12. package/dist/extensions/weixin/src/auth/accounts.js +1 -1
  13. package/dist/extensions/weixin/src/cdn/upload.js +1 -1
  14. package/dist/extensions/weixin/src/media/data-url.js +1 -1
  15. package/dist/extensions/weixin/src/messaging/debug-mode.js +1 -1
  16. package/dist/extensions/weixin/src/messaging/inbound.js +1 -1
  17. package/dist/extensions/weixin/src/messaging/process-message.js +1 -1
  18. package/dist/extensions/weixin/src/plugin.js +1 -1
  19. package/dist/extensions/weixin/src/storage/sync-buf.js +1 -1
  20. package/dist/extensions/weixin/src/workflow-progress.js +1 -1
  21. package/dist/gateway/static/root/assets/{agent-avatar-dicebear-CBlklyNr.js → agent-avatar-dicebear-DVnBfANm.js} +1 -1
  22. package/dist/gateway/static/root/assets/agent-browser-settings-page-DPXc4hz8.js +6 -0
  23. package/dist/gateway/static/root/assets/agent-defaults-tabbed-page-CTJ0YnRQ.js +1 -0
  24. package/dist/gateway/static/root/assets/agents-zJXQfJ_W.js +71 -0
  25. package/dist/gateway/static/root/assets/{app-management-settings-panel-28E_WfMe.js → app-management-settings-panel-DzGbdr04.js} +1 -1
  26. package/dist/gateway/static/root/assets/{appearance-settings-Do1z0XgJ.js → appearance-settings-BQpPSTHD.js} +1 -1
  27. package/dist/gateway/static/root/assets/apps-page-CPjfyzSD.js +1 -0
  28. package/dist/gateway/static/root/assets/{archive-plugin-BAFlsov_.js → archive-plugin-CXu-Csep.js} +1 -1
  29. package/dist/gateway/static/root/assets/{attachment-load-V3qGPC3x.js → attachment-load-BAjgOoGY.js} +1 -1
  30. package/dist/gateway/static/root/assets/{binary-plugins-DT8NvA6W.js → binary-plugins-BSBgB2hO.js} +1 -1
  31. package/dist/gateway/static/root/assets/{block-editor-CdLMEcHd.js → block-editor-BpXw9TTR.js} +3 -3
  32. package/dist/gateway/static/root/assets/channels-settings-BbPUpzWB.js +1 -0
  33. package/dist/gateway/static/root/assets/{config-api-Bf5mjpu7.js → config-api-NOoPiIYz.js} +1 -1
  34. package/dist/gateway/static/root/assets/connectors-settings-CAXYMOdp.js +2 -0
  35. package/dist/gateway/static/root/assets/{cron-api--pAB_rps.js → cron-api-C9BOqAXd.js} +1 -1
  36. package/dist/gateway/static/root/assets/cron-page-DuUbBeKI.js +3 -0
  37. package/dist/gateway/static/root/assets/{dreaming-settings-6UZE1FSK.js → dreaming-settings-DQ4DtiK1.js} +1 -1
  38. package/dist/gateway/static/root/assets/{extension-debug-page-BGhE7msg.js → extension-debug-page-D9kgUHCc.js} +1 -1
  39. package/dist/gateway/static/root/assets/{extension-page-CvpI45WG.js → extension-page-CGyhXqzR.js} +1 -1
  40. package/dist/gateway/static/root/assets/{extension-settings-page-DAmR5FUe.js → extension-settings-page-DL8Xquqd.js} +1 -1
  41. package/dist/gateway/static/root/assets/{fetch-NZmjSXLl.js → fetch-D0VXA932.js} +1 -1
  42. package/dist/gateway/static/root/assets/{format-interval-label-qhth3BMV.js → format-interval-label-Be8SmgUw.js} +1 -1
  43. package/dist/gateway/static/root/assets/{gateway-config-api-CaXBt-9R.js → gateway-config-api-C-xjn__h.js} +1 -1
  44. package/dist/gateway/static/root/assets/{gateway-settings-DphpbLBc.js → gateway-settings-BMPwIjKI.js} +1 -1
  45. package/dist/gateway/static/root/assets/{gateway-startup-retry-Be1omjh3.js → gateway-startup-retry-DERUH61L.js} +1 -1
  46. package/dist/gateway/static/root/assets/goal-detail-page-BJsyjJnF.js +1 -0
  47. package/dist/gateway/static/root/assets/goals-config-api-BPmqWk90.js +1 -0
  48. package/dist/gateway/static/root/assets/goals-page-BerDgIhw.js +2 -0
  49. package/dist/gateway/static/root/assets/goals-settings-ByTjeAto.js +1 -0
  50. package/dist/gateway/static/root/assets/{heartbeat-config-api-BzO6G4fD.js → heartbeat-config-api-Bfdzr8oV.js} +1 -1
  51. package/dist/gateway/static/root/assets/{heartbeat-settings-DCST9-du.js → heartbeat-settings-TbHgcjTn.js} +1 -1
  52. package/dist/gateway/static/root/assets/index-AkTrf6Pb.js +122 -0
  53. package/dist/gateway/static/root/assets/index-fh5sXTj9.css +1 -0
  54. package/dist/gateway/static/root/assets/{interval-presets-DJmshV8n.js → interval-presets-utKbuCRY.js} +1 -1
  55. package/dist/gateway/static/root/assets/{keyboard-shortcuts-settings-9AUUlQ5Q.js → keyboard-shortcuts-settings-CjqS6c6V.js} +1 -1
  56. package/dist/gateway/static/root/assets/logs-page-DGXuPf5B.js +2 -0
  57. package/dist/gateway/static/root/assets/{markdown-split-CYYELqAr.js → markdown-split-DW8C47iB.js} +1 -1
  58. package/dist/gateway/static/root/assets/{media-plugins-BEcMR2M8.js → media-plugins-D6HwDhDT.js} +1 -1
  59. package/dist/gateway/static/root/assets/messages-upgxw6Ub.js +3 -0
  60. package/dist/gateway/static/root/assets/models-hub-panel-Bot16nn7.js +2 -0
  61. package/dist/gateway/static/root/assets/note-detail-page-Brlyou8M.js +2 -0
  62. package/dist/gateway/static/root/assets/{note-image-lightbox-DNAoPcmm.js → note-image-lightbox-pJM35Pz5.js} +1 -1
  63. package/dist/gateway/static/root/assets/notes-page-DvZ4pwc-.js +1 -0
  64. package/dist/gateway/static/root/assets/{preview-open-alternatives-BPLz0AIv.js → preview-open-alternatives-CVwHuyN6.js} +1 -1
  65. package/dist/gateway/static/root/assets/remote-access-hub-BZEDmxbZ.js +1 -0
  66. package/dist/gateway/static/root/assets/{save-bar-controls-CrWwWRVK.js → save-bar-controls-Ba-UEk7x.js} +1 -1
  67. package/dist/gateway/static/root/assets/{schedule-field-CF2sadvN.js → schedule-field-CNN9595U.js} +1 -1
  68. package/dist/gateway/static/root/assets/{schema-form-Di5cKjYE.js → schema-form-DnNMmtD5.js} +1 -1
  69. package/dist/gateway/static/root/assets/sessions-page-DdGGlsfn.js +1 -0
  70. package/dist/gateway/static/root/assets/settings-advanced-gate-DlkEkPf9.js +1 -0
  71. package/dist/gateway/static/root/assets/{settings-collapsible-section-Chh282jW.js → settings-collapsible-section-CmOz80i5.js} +1 -1
  72. package/dist/gateway/static/root/assets/{settings-form-section-Dq-83cQd.js → settings-form-section-BmK7JJOV.js} +1 -1
  73. package/dist/gateway/static/root/assets/settings-page-DFPTrsPF.js +1 -0
  74. package/dist/gateway/static/root/assets/setup-status-panel-CYCCfgh4.js +1 -0
  75. package/dist/gateway/static/root/assets/{share-preview-page-0FXYnSUA.js → share-preview-page-Dp2qGrHC.js} +1 -1
  76. package/dist/gateway/static/root/assets/shares-settings-Bff1pGd0.js +1 -0
  77. package/dist/gateway/static/root/assets/skill-reload-api-CJGKpBur.js +1 -0
  78. package/dist/gateway/static/root/assets/skills-page-C6ocduTD.js +2 -0
  79. package/dist/gateway/static/root/assets/{system-settings-panel-W1pTcojB.js → system-settings-panel-5jrIEr5b.js} +1 -1
  80. package/dist/gateway/static/root/assets/{use-agent-defaults-form-BVRvkK7m.js → use-agent-defaults-form-BuiXLIs5.js} +1 -1
  81. package/dist/gateway/static/root/assets/{use-channel-catalog-CgJibfMM.js → use-channel-catalog-CHlO8J9G.js} +1 -1
  82. package/dist/gateway/static/root/assets/{use-settings-tab-guard-Bw_qkRQE.js → use-settings-tab-guard-CW5JORnl.js} +1 -1
  83. package/dist/gateway/static/root/assets/voice-api-key-field-DDoQyghO.js +1 -0
  84. package/dist/gateway/static/root/assets/{voice-player-store-C7lziaAx.js → voice-player-store-DDDWYHvg.js} +1 -1
  85. package/dist/gateway/static/root/assets/workflow-page.utils-CKjeEGqx.js +1 -0
  86. package/dist/gateway/static/root/assets/workflows-page-B604ehHG.js +18 -0
  87. package/dist/gateway/static/root/index.html +5 -5
  88. package/dist/gateway/static/root/logo.svg +4 -3
  89. package/dist/package.js +1 -1
  90. package/dist/src/agent/agent-manager.d.ts +8 -0
  91. package/dist/src/agent/agent-manager.js +63 -28
  92. package/dist/src/agent/agent-manager.js.map +1 -1
  93. package/dist/src/agent/agent-scope.js +1 -1
  94. package/dist/src/agent/bootstrap/load-bootstrap-files.js +1 -1
  95. package/dist/src/agent/bootstrap/project-agents-context.d.ts +2 -0
  96. package/dist/src/agent/bootstrap/project-agents-context.js +32 -0
  97. package/dist/src/agent/bootstrap/project-agents-context.js.map +1 -0
  98. package/dist/src/agent/context/workspace-seed.js +2 -2
  99. package/dist/src/agent/context/workspace-state.js +1 -1
  100. package/dist/src/agent/context/workspace.js +1 -1
  101. package/dist/src/agent/embedded/session-tool-result-guard.js +8 -1
  102. package/dist/src/agent/embedded/session-tool-result-guard.js.map +1 -1
  103. package/dist/src/agent/goals/checklist-judge.d.ts +1 -0
  104. package/dist/src/agent/goals/checklist-judge.js +3 -2
  105. package/dist/src/agent/goals/checklist-judge.js.map +1 -1
  106. package/dist/src/agent/goals/evaluate-turn.d.ts +1 -1
  107. package/dist/src/agent/goals/evaluate-turn.js +1 -0
  108. package/dist/src/agent/goals/evaluate-turn.js.map +1 -1
  109. package/dist/src/agent/goals/goal-locale.js +2 -2
  110. package/dist/src/agent/goals/persistent-goal-service.js +2 -4
  111. package/dist/src/agent/goals/persistent-goal-service.js.map +1 -1
  112. package/dist/src/agent/goals/post-turn.d.ts +6 -1
  113. package/dist/src/agent/goals/post-turn.js +15 -6
  114. package/dist/src/agent/goals/post-turn.js.map +1 -1
  115. package/dist/src/agent/image/load-image-media.js +2 -2
  116. package/dist/src/agent/inbound/inbound-loop.js +5 -1
  117. package/dist/src/agent/inbound/inbound-loop.js.map +1 -1
  118. package/dist/src/agent/inbound/turn-dispatcher.d.ts +2 -2
  119. package/dist/src/agent/inbound/turn-dispatcher.js +2 -2
  120. package/dist/src/agent/inbound/turn-dispatcher.js.map +1 -1
  121. package/dist/src/agent/ipc/inbox.js +3 -3
  122. package/dist/src/agent/ipc/socket.js +1 -1
  123. package/dist/src/agent/mcp/bundle-mcp-materialize.d.ts +27 -0
  124. package/dist/src/agent/mcp/bundle-mcp-materialize.js +50 -2
  125. package/dist/src/agent/mcp/bundle-mcp-materialize.js.map +1 -1
  126. package/dist/src/agent/mcp/bundle-mcp-runtime.js +79 -4
  127. package/dist/src/agent/mcp/bundle-mcp-runtime.js.map +1 -1
  128. package/dist/src/agent/mcp/bundle-mcp-types.d.ts +19 -0
  129. package/dist/src/agent/mcp/mcp-transport-config.js +1 -1
  130. package/dist/src/agent/mcp/mcp-transport.js +1 -1
  131. package/dist/src/agent/memory/builtin-memory-store.js +1 -1
  132. package/dist/src/agent/memory/dreaming/deep-promotion.js +1 -1
  133. package/dist/src/agent/memory/dreaming/events.js +1 -1
  134. package/dist/src/agent/memory/dreaming/last-run.js +1 -1
  135. package/dist/src/agent/memory/dreaming/light-sweep.js +1 -1
  136. package/dist/src/agent/memory/dreaming/preview.js +1 -1
  137. package/dist/src/agent/memory/dreaming/rem-patterns.js +1 -1
  138. package/dist/src/agent/memory/dreaming/short-term-store.js +1 -1
  139. package/dist/src/agent/memory/dreaming/utils.js +1 -1
  140. package/dist/src/agent/memory/memory-flush.js +1 -1
  141. package/dist/src/agent/memory/plugin-discovery.js +1 -1
  142. package/dist/src/agent/models/manager.js +1 -1
  143. package/dist/src/agent/prompt/memory/index.js +1 -1
  144. package/dist/src/agent/prompt/service-prompt-builder.js +2 -2
  145. package/dist/src/agent/reply/post-compaction-context.js +1 -1
  146. package/dist/src/agent/reply/workspace-boundary-read.js +1 -1
  147. package/dist/src/agent/sandbox/path-policy.js +2 -2
  148. package/dist/src/agent/service/btw-query.js +11 -3
  149. package/dist/src/agent/service/btw-query.js.map +1 -1
  150. package/dist/src/agent/service/parse-outbound-session-key.js +13 -8
  151. package/dist/src/agent/service/parse-outbound-session-key.js.map +1 -1
  152. package/dist/src/agent/service/process-direct-one-shot.d.ts +2 -2
  153. package/dist/src/agent/service/process-direct-one-shot.js +1 -1
  154. package/dist/src/agent/service/process-direct-one-shot.js.map +1 -1
  155. package/dist/src/agent/service/process-direct-streaming.d.ts +2 -2
  156. package/dist/src/agent/service/process-direct-streaming.js +1 -1
  157. package/dist/src/agent/service/process-direct-streaming.js.map +1 -1
  158. package/dist/src/agent/service.d.ts +1 -1
  159. package/dist/src/agent/service.js +13 -9
  160. package/dist/src/agent/service.js.map +1 -1
  161. package/dist/src/agent/service.types.d.ts +5 -0
  162. package/dist/src/agent/session/session-inspector.js +1 -1
  163. package/dist/src/agent/skills/config.js +2 -2
  164. package/dist/src/agent/skills/filesystem-watcher.js +5 -4
  165. package/dist/src/agent/skills/filesystem-watcher.js.map +1 -1
  166. package/dist/src/agent/skills/hub-hash.js +2 -2
  167. package/dist/src/agent/skills/hub-lock.js +1 -1
  168. package/dist/src/agent/skills/hub-pull.js +2 -2
  169. package/dist/src/agent/skills/index.js +4 -3
  170. package/dist/src/agent/skills/index.js.map +1 -1
  171. package/dist/src/agent/skills/installer.js +2 -2
  172. package/dist/src/agent/skills/managed-store.js +1 -1
  173. package/dist/src/agent/skills/skill-manage-ops.js +3 -2
  174. package/dist/src/agent/skills/skill-manage-ops.js.map +1 -1
  175. package/dist/src/agent/skills/skill-manager.js +1 -1
  176. package/dist/src/agent/skills/skill-view-path.js +1 -1
  177. package/dist/src/agent/skills/test-framework.js +1 -1
  178. package/dist/src/agent/skills/types.d.ts +1 -1
  179. package/dist/src/agent/skills/watcher.js +2 -5
  180. package/dist/src/agent/skills/watcher.js.map +1 -1
  181. package/dist/src/agent/skills/workspace-skills-dir.d.ts +1 -0
  182. package/dist/src/agent/skills/workspace-skills-dir.js +11 -0
  183. package/dist/src/agent/skills/workspace-skills-dir.js.map +1 -0
  184. package/dist/src/agent/starter-agents.js +1 -1
  185. package/dist/src/agent/tool-manuals/browser.d.ts +1 -1
  186. package/dist/src/agent/tool-manuals/browser.js +62 -3
  187. package/dist/src/agent/tool-manuals/browser.js.map +1 -1
  188. package/dist/src/agent/tools/browser/tool/browser-use-tool.d.ts +4 -1
  189. package/dist/src/agent/tools/browser/tool/browser-use-tool.js +13 -4
  190. package/dist/src/agent/tools/browser/tool/browser-use-tool.js.map +1 -1
  191. package/dist/src/agent/tools/browser/tool/schemas.d.ts +0 -2
  192. package/dist/src/agent/tools/browser/tool/schemas.js +1 -2
  193. package/dist/src/agent/tools/browser/tool/schemas.js.map +1 -1
  194. package/dist/src/agent/tools/dreaming-tool.js +1 -1
  195. package/dist/src/agent/tools/factory.js +1 -10
  196. package/dist/src/agent/tools/factory.js.map +1 -1
  197. package/dist/src/agent/tools/find.js +1 -1
  198. package/dist/src/agent/tools/grep.js +1 -1
  199. package/dist/src/agent/tools/image-generate-tool.js +1 -1
  200. package/dist/src/agent/tools/skill-manage-tool.js +2 -2
  201. package/dist/src/agent/tools/skill-manage-tool.js.map +1 -1
  202. package/dist/src/agent/tools/workflow-tool.js +1 -1
  203. package/dist/src/agent/workflow/catalog.js +1 -1
  204. package/dist/src/agent/workflow/snapshot.d.ts +10 -0
  205. package/dist/src/agent/workflow/snapshot.js +136 -1
  206. package/dist/src/agent/workflow/snapshot.js.map +1 -1
  207. package/dist/src/agent/workflow/subagent-runner.js +18 -1
  208. package/dist/src/agent/workflow/subagent-runner.js.map +1 -1
  209. package/dist/src/ai-assist/text-assist.js +1 -1
  210. package/dist/src/auth/credentials.js +2 -2
  211. package/dist/src/auth/profiles/store.js +2 -2
  212. package/dist/src/auth/sync-provider-auth.js +1 -1
  213. package/dist/src/browser/actions/extension-registry-bridge.js +91 -7
  214. package/dist/src/browser/actions/extension-registry-bridge.js.map +1 -1
  215. package/dist/src/browser/actions/registry.js +383 -7
  216. package/dist/src/browser/actions/registry.js.map +1 -1
  217. package/dist/src/browser/actions/types.d.ts +11 -3
  218. package/dist/src/browser/cache-dir-policy.js +1 -1
  219. package/dist/src/browser/cdp-local-launcher.js +2 -2
  220. package/dist/src/browser/index.js +2 -2
  221. package/dist/src/browser/pipeline/output.d.ts +18 -16
  222. package/dist/src/browser/pipeline/output.js +28 -20
  223. package/dist/src/browser/pipeline/output.js.map +1 -1
  224. package/dist/src/browser/pipeline/runner.d.ts +7 -14
  225. package/dist/src/browser/pipeline/runner.js +349 -102
  226. package/dist/src/browser/pipeline/runner.js.map +1 -1
  227. package/dist/src/browser/pipeline/schema.d.ts +1 -0
  228. package/dist/src/browser/pipeline/schema.js +35 -58
  229. package/dist/src/browser/pipeline/schema.js.map +1 -1
  230. package/dist/src/browser/pipeline/source.d.ts +2 -0
  231. package/dist/src/browser/pipeline/source.js +10 -1
  232. package/dist/src/browser/pipeline/source.js.map +1 -1
  233. package/dist/src/browser/pipeline/template.d.ts +10 -2
  234. package/dist/src/browser/pipeline/template.js +50 -8
  235. package/dist/src/browser/pipeline/template.js.map +1 -1
  236. package/dist/src/browser/providers/browser-ext-install.js +4 -4
  237. package/dist/src/browser/providers/cloakbrowser.js +5 -5
  238. package/dist/src/browser/providers/playwright-doctor.js +1 -1
  239. package/dist/src/browser/stealth.js +1 -1
  240. package/dist/src/channels/catalog/channel-catalog-service.d.ts +2 -1
  241. package/dist/src/channels/catalog/channel-catalog-service.js +133 -16
  242. package/dist/src/channels/catalog/channel-catalog-service.js.map +1 -1
  243. package/dist/src/channels/catalog/channel-catalog-types.d.ts +13 -0
  244. package/dist/src/channels/outbound/persist-store.js +1 -1
  245. package/dist/src/channels/pairing/allow-from-file.js +1 -1
  246. package/dist/src/channels/pairing/pairing-store.js +2 -2
  247. package/dist/src/chat-commands/agent-edit.js +2 -2
  248. package/dist/src/chat-commands/builtins/config.js +5 -7
  249. package/dist/src/chat-commands/builtins/config.js.map +1 -1
  250. package/dist/src/chat-commands/context.d.ts +5 -0
  251. package/dist/src/chat-commands/context.js +18 -9
  252. package/dist/src/chat-commands/context.js.map +1 -1
  253. package/dist/src/chat-commands/index.d.ts +1 -1
  254. package/dist/src/chat-commands/index.js +2 -2
  255. package/dist/src/chat-commands/index.js.map +1 -1
  256. package/dist/src/chat-commands/processor.js +22 -21
  257. package/dist/src/chat-commands/processor.js.map +1 -1
  258. package/dist/src/chat-commands/session-key.d.ts +3 -15
  259. package/dist/src/chat-commands/session-key.js +3 -49
  260. package/dist/src/chat-commands/session-key.js.map +1 -1
  261. package/dist/src/chat-commands/types.d.ts +4 -0
  262. package/dist/src/cli/commands/browser-cli-helpers.js +11 -5
  263. package/dist/src/cli/commands/browser-cli-helpers.js.map +1 -1
  264. package/dist/src/cli/commands/config.js +1 -1
  265. package/dist/src/cli/commands/doctor/checks/channel-config.js +14 -1
  266. package/dist/src/cli/commands/doctor/checks/channel-config.js.map +1 -1
  267. package/dist/src/cli/commands/doctor/checks/config-health.js +1 -1
  268. package/dist/src/cli/commands/doctor/checks/database-schema.js +1 -1
  269. package/dist/src/cli/commands/doctor/checks/provider-auth.js +1 -1
  270. package/dist/src/cli/commands/doctor/checks/session-integrity.js +8 -8
  271. package/dist/src/cli/commands/doctor/checks/session-integrity.js.map +1 -1
  272. package/dist/src/cli/commands/doctor/checks/state-integrity.js +1 -1
  273. package/dist/src/cli/commands/doctor/checks/workspace-status.js +1 -1
  274. package/dist/src/cli/commands/extension-create.js +1 -1
  275. package/dist/src/cli/commands/extension-dev.js +2 -2
  276. package/dist/src/cli/commands/extension-marketplace.js +2 -2
  277. package/dist/src/cli/commands/extension-pack.js +2 -2
  278. package/dist/src/cli/commands/extension.js +3 -3
  279. package/dist/src/cli/commands/gateway/logs.js +1 -1
  280. package/dist/src/cli/commands/image.js +1 -1
  281. package/dist/src/cli/commands/init.js +2 -2
  282. package/dist/src/cli/commands/models.js +1 -1
  283. package/dist/src/cli/commands/skills-test.js +1 -1
  284. package/dist/src/cli/templates.js +1 -1
  285. package/dist/src/cli/utils/gateway-client.js +1 -1
  286. package/dist/src/cli/utils/init-workspace-core.js +2 -2
  287. package/dist/src/config/agent-profile.js +1 -1
  288. package/dist/src/config/agent-typed-models.js +1 -1
  289. package/dist/src/config/gateway-bind.js +1 -1
  290. package/dist/src/config/index.js +7 -7
  291. package/dist/src/config/loader.js +4 -4
  292. package/dist/src/config/models-json.js +2 -2
  293. package/dist/src/config/paths-state.js +1 -1
  294. package/dist/src/config/paths.js +1 -1
  295. package/dist/src/config/profile.js +1 -1
  296. package/dist/src/config/reload.js +1 -1
  297. package/dist/src/config/rules.js +5 -0
  298. package/dist/src/config/rules.js.map +1 -1
  299. package/dist/src/config/schema.d.ts +8 -0
  300. package/dist/src/config/schema.js +7 -0
  301. package/dist/src/config/schema.js.map +1 -1
  302. package/dist/src/config/web-patch.d.ts +1 -0
  303. package/dist/src/config/web-patch.js +1 -0
  304. package/dist/src/config/web-patch.js.map +1 -1
  305. package/dist/src/config/workspace-path.js +1 -1
  306. package/dist/src/connectors/builtin-catalog.js +180 -1
  307. package/dist/src/connectors/builtin-catalog.js.map +1 -1
  308. package/dist/src/connectors/health.js +18 -9
  309. package/dist/src/connectors/health.js.map +1 -1
  310. package/dist/src/connectors/types.d.ts +19 -0
  311. package/dist/src/connectors/usage.js +12 -4
  312. package/dist/src/connectors/usage.js.map +1 -1
  313. package/dist/src/cron/executor.js +1 -1
  314. package/dist/src/cron/service.js +1 -1
  315. package/dist/src/daemon/constants.js +1 -1
  316. package/dist/src/daemon/install-plan.js +2 -2
  317. package/dist/src/daemon/launchd.js +2 -2
  318. package/dist/src/daemon/schtasks.js +2 -2
  319. package/dist/src/daemon/systemd.js +2 -2
  320. package/dist/src/extensions/bundle-mcp.js +1 -1
  321. package/dist/src/extensions/discover-extensions.js +2 -2
  322. package/dist/src/extensions/health.js +1 -1
  323. package/dist/src/extensions/install.js +2 -2
  324. package/dist/src/extensions/loader.js +2 -2
  325. package/dist/src/extensions/lockfile.js +3 -3
  326. package/dist/src/extensions/security.js +1 -1
  327. package/dist/src/extensions/types/tui.d.ts +2 -0
  328. package/dist/src/extensions/update.js +2 -2
  329. package/dist/src/gateway/agents-admin.js +2 -2
  330. package/dist/src/gateway/file-path-classifier.js +2 -2
  331. package/dist/src/gateway/heartbeat/service.js +13 -1
  332. package/dist/src/gateway/heartbeat/service.js.map +1 -1
  333. package/dist/src/gateway/hono/app.js +18 -5
  334. package/dist/src/gateway/hono/app.js.map +1 -1
  335. package/dist/src/gateway/hono/lib/config-payload.d.ts +3 -1
  336. package/dist/src/gateway/hono/lib/config-payload.js +7 -4
  337. package/dist/src/gateway/hono/lib/config-payload.js.map +1 -1
  338. package/dist/src/gateway/hono/lib/extension-store.js +2 -2
  339. package/dist/src/gateway/hono/lib/static-ui.js +2 -2
  340. package/dist/src/gateway/hono/middleware/strict-rate-limit.d.ts +4 -0
  341. package/dist/src/gateway/hono/middleware/strict-rate-limit.js +19 -5
  342. package/dist/src/gateway/hono/middleware/strict-rate-limit.js.map +1 -1
  343. package/dist/src/gateway/hono/oauth-async.js +1 -1
  344. package/dist/src/gateway/hono/routes/agent-stream.js +6 -6
  345. package/dist/src/gateway/hono/routes/agent-stream.js.map +1 -1
  346. package/dist/src/gateway/hono/routes/agents.js +1 -1
  347. package/dist/src/gateway/hono/routes/auth-registry-extensions.js +1 -1
  348. package/dist/src/gateway/hono/routes/channels.js +18 -14
  349. package/dist/src/gateway/hono/routes/channels.js.map +1 -1
  350. package/dist/src/gateway/hono/routes/config-patch/gateway.d.ts +1 -1
  351. package/dist/src/gateway/hono/routes/config-patch/gateway.js +6 -0
  352. package/dist/src/gateway/hono/routes/config-patch/gateway.js.map +1 -1
  353. package/dist/src/gateway/hono/routes/config-patch/misc.js +1 -1
  354. package/dist/src/gateway/hono/routes/deps.d.ts +1 -0
  355. package/dist/src/gateway/hono/routes/dreaming.js +1 -1
  356. package/dist/src/gateway/hono/routes/goals.js +16 -3
  357. package/dist/src/gateway/hono/routes/goals.js.map +1 -1
  358. package/dist/src/gateway/hono/routes/host-fs.js +2 -2
  359. package/dist/src/gateway/hono/routes/logs.js +1 -0
  360. package/dist/src/gateway/hono/routes/logs.js.map +1 -1
  361. package/dist/src/gateway/hono/routes/mcp.js +27 -8
  362. package/dist/src/gateway/hono/routes/mcp.js.map +1 -1
  363. package/dist/src/gateway/hono/routes/models.js +1 -1
  364. package/dist/src/gateway/hono/routes/notes.js +14 -2
  365. package/dist/src/gateway/hono/routes/notes.js.map +1 -1
  366. package/dist/src/gateway/hono/routes/sessions.js +62 -4
  367. package/dist/src/gateway/hono/routes/sessions.js.map +1 -1
  368. package/dist/src/gateway/hono/routes/shares.js +1 -1
  369. package/dist/src/gateway/hono/routes/workflows.js +1 -1
  370. package/dist/src/gateway/hono/routes/workspace.js +5 -68
  371. package/dist/src/gateway/hono/routes/workspace.js.map +1 -1
  372. package/dist/src/gateway/hono/sse.d.ts +2 -2
  373. package/dist/src/gateway/hono/sse.js +7 -15
  374. package/dist/src/gateway/hono/sse.js.map +1 -1
  375. package/dist/src/gateway/lock.js +3 -3
  376. package/dist/src/gateway/ports.js +1 -1
  377. package/dist/src/gateway/rate-limit/buckets.d.ts +3 -0
  378. package/dist/src/gateway/rate-limit/buckets.js +12 -0
  379. package/dist/src/gateway/rate-limit/buckets.js.map +1 -1
  380. package/dist/src/gateway/resolve-webchat-session-key.d.ts +2 -6
  381. package/dist/src/gateway/resolve-webchat-session-key.js +5 -31
  382. package/dist/src/gateway/resolve-webchat-session-key.js.map +1 -1
  383. package/dist/src/gateway/service/agent-runner.d.ts +2 -3
  384. package/dist/src/gateway/service/agent-runner.js +9 -22
  385. package/dist/src/gateway/service/agent-runner.js.map +1 -1
  386. package/dist/src/gateway/service/config-coordinator.js +1 -1
  387. package/dist/src/gateway/service/marketplace-service.js +2 -2
  388. package/dist/src/gateway/service/run-gateway-agent.js +9 -7
  389. package/dist/src/gateway/service/run-gateway-agent.js.map +1 -1
  390. package/dist/src/gateway/service/sessions-api.d.ts +9 -0
  391. package/dist/src/gateway/service/sessions-api.js +11 -0
  392. package/dist/src/gateway/service/sessions-api.js.map +1 -1
  393. package/dist/src/gateway/service.d.ts +1 -1
  394. package/dist/src/gateway/service.js +23 -9
  395. package/dist/src/gateway/service.js.map +1 -1
  396. package/dist/src/gateway/workspace-file-search.d.ts +9 -0
  397. package/dist/src/gateway/workspace-file-search.js +76 -0
  398. package/dist/src/gateway/workspace-file-search.js.map +1 -0
  399. package/dist/src/gateway/workspace-fs-file-list.js +1 -1
  400. package/dist/src/goals/goal-notifications.d.ts +2 -0
  401. package/dist/src/goals/goal-notifications.js +16 -11
  402. package/dist/src/goals/goal-notifications.js.map +1 -1
  403. package/dist/src/goals/goal-service.js +1 -6
  404. package/dist/src/goals/goal-service.js.map +1 -1
  405. package/dist/src/goals/goal-workflow-judge.js +2 -2
  406. package/dist/src/i18n/goals-bundle.js +1 -1
  407. package/dist/src/i18n/index.js +1 -1
  408. package/dist/src/i18n/share-tool-bundle.js +2 -2
  409. package/dist/src/infra/brew.js +1 -1
  410. package/dist/src/infra/package-json.js +1 -1
  411. package/dist/src/infra/package-update-steps.js +1 -1
  412. package/dist/src/infra/path-env.js +2 -2
  413. package/dist/src/infra/restart.js +1 -1
  414. package/dist/src/infra/stable-node-path.js +1 -1
  415. package/dist/src/infra/update-check.js +1 -1
  416. package/dist/src/infra/update-global.js +1 -1
  417. package/dist/src/infra/update-lock.js +2 -2
  418. package/dist/src/infra/update-restart.js +1 -1
  419. package/dist/src/infra/update-runner.js +1 -1
  420. package/dist/src/infra/update-startup.js +1 -1
  421. package/dist/src/infra/write-file-atomic.js +2 -2
  422. package/dist/src/media/store.js +1 -1
  423. package/dist/src/notes/agent-context.js +1 -1
  424. package/dist/src/notes/service.js +1 -1
  425. package/dist/src/notes/store.js +2 -2
  426. package/dist/src/project-trust/trust-store.js +4 -2
  427. package/dist/src/project-trust/trust-store.js.map +1 -1
  428. package/dist/src/providers/auth-runtime/auth-profile-store.js +1 -1
  429. package/dist/src/providers/index.js +1 -1
  430. package/dist/src/providers/model-registry.js +4 -4
  431. package/dist/src/session/index.d.ts +1 -1
  432. package/dist/src/session/index.js +2 -2
  433. package/dist/src/session/init-session-turn.js +7 -10
  434. package/dist/src/session/init-session-turn.js.map +1 -1
  435. package/dist/src/session/manager.d.ts +5 -1
  436. package/dist/src/session/manager.js +5 -2
  437. package/dist/src/session/manager.js.map +1 -1
  438. package/dist/src/session/reset-type.d.ts +0 -2
  439. package/dist/src/session/reset-type.js +3 -9
  440. package/dist/src/session/reset-type.js.map +1 -1
  441. package/dist/src/session/resolve-session.js +10 -21
  442. package/dist/src/session/resolve-session.js.map +1 -1
  443. package/dist/src/session/session-title.js +2 -2
  444. package/dist/src/session/store.d.ts +11 -3
  445. package/dist/src/session/store.js +30 -14
  446. package/dist/src/session/store.js.map +1 -1
  447. package/dist/src/session/types.d.ts +2 -4
  448. package/dist/src/session/types.js.map +1 -1
  449. package/dist/src/share/share-auto.js +2 -2
  450. package/dist/src/share/share-store.js +3 -3
  451. package/dist/src/share/share-thumbnail.js +2 -2
  452. package/dist/src/share/share-zip.js +1 -1
  453. package/dist/src/share/site-share-store.js +3 -3
  454. package/dist/src/share/site-static-serve.js +1 -1
  455. package/dist/src/storage/sqlite/connection.js +1 -1
  456. package/dist/src/storage/sqlite/index.d.ts +2 -2
  457. package/dist/src/storage/sqlite/index.js +3 -3
  458. package/dist/src/storage/sqlite/memory-index-repository.js +2 -2
  459. package/dist/src/storage/sqlite/migrations/010_session_id_identity.sql +30 -0
  460. package/dist/src/storage/sqlite/migrations/discover.js +1 -1
  461. package/dist/src/storage/sqlite/migrations/runner.d.ts +2 -2
  462. package/dist/src/storage/sqlite/migrations/runner.js +5 -5
  463. package/dist/src/storage/sqlite/migrations/runner.js.map +1 -1
  464. package/dist/src/storage/sqlite/migrations/runner.ts +2 -2
  465. package/dist/src/storage/sqlite/row-mappers.d.ts +4 -4
  466. package/dist/src/storage/sqlite/row-mappers.js +11 -14
  467. package/dist/src/storage/sqlite/row-mappers.js.map +1 -1
  468. package/dist/src/storage/sqlite/schema.js +4 -4
  469. package/dist/src/storage/sqlite/schema.js.map +1 -1
  470. package/dist/src/storage/sqlite/schema.sql +37 -10
  471. package/dist/src/storage/sqlite/session-metadata.d.ts +2 -7
  472. package/dist/src/storage/sqlite/session-metadata.js +18 -72
  473. package/dist/src/storage/sqlite/session-metadata.js.map +1 -1
  474. package/dist/src/storage/sqlite/session-repository.d.ts +6 -5
  475. package/dist/src/storage/sqlite/session-repository.js +34 -40
  476. package/dist/src/storage/sqlite/session-repository.js.map +1 -1
  477. package/dist/src/storage/sqlite/transcript-repository.d.ts +2 -2
  478. package/dist/src/storage/sqlite/transcript-repository.js +52 -52
  479. package/dist/src/storage/sqlite/transcript-repository.js.map +1 -1
  480. package/dist/src/tui/backends/embedded-backend.d.ts +18 -4
  481. package/dist/src/tui/backends/embedded-backend.js +100 -1
  482. package/dist/src/tui/backends/embedded-backend.js.map +1 -1
  483. package/dist/src/tui/backends/gateway-sse-backend.d.ts +5 -1
  484. package/dist/src/tui/backends/gateway-sse-backend.js +45 -2
  485. package/dist/src/tui/backends/gateway-sse-backend.js.map +1 -1
  486. package/dist/src/tui/clipboard-image.js +3 -3
  487. package/dist/src/tui/components/chat-log.d.ts +2 -0
  488. package/dist/src/tui/components/chat-log.js +19 -0
  489. package/dist/src/tui/components/chat-log.js.map +1 -1
  490. package/dist/src/tui/extension-host/autocomplete.d.ts +3 -2
  491. package/dist/src/tui/extension-host/autocomplete.js +29 -12
  492. package/dist/src/tui/extension-host/autocomplete.js.map +1 -1
  493. package/dist/src/tui/extension-host/load-extensions.js +1 -1
  494. package/dist/src/tui/extension-host/runtime.d.ts +12 -0
  495. package/dist/src/tui/extension-host/runtime.js +6 -4
  496. package/dist/src/tui/extension-host/runtime.js.map +1 -1
  497. package/dist/src/tui/theme-manager.js +1 -1
  498. package/dist/src/tui/tui-backend.d.ts +23 -0
  499. package/dist/src/tui/tui-command-formatters.js +4 -4
  500. package/dist/src/tui/tui-commands.d.ts +16 -3
  501. package/dist/src/tui/tui-commands.js +134 -27
  502. package/dist/src/tui/tui-commands.js.map +1 -1
  503. package/dist/src/tui/tui-file-autocomplete.d.ts +5 -0
  504. package/dist/src/tui/tui-file-autocomplete.js +26 -0
  505. package/dist/src/tui/tui-file-autocomplete.js.map +1 -0
  506. package/dist/src/tui/tui-keybindings-file.js +1 -1
  507. package/dist/src/tui/tui-picker-overlay.js +1 -1
  508. package/dist/src/tui/tui-scoped-models.js +2 -2
  509. package/dist/src/tui/tui-settings.js +1 -1
  510. package/dist/src/tui/tui-startup-resources.js +1 -1
  511. package/dist/src/tui/tui-startup-text.js +1 -1
  512. package/dist/src/tui/tui-startup-text.js.map +1 -1
  513. package/dist/src/tui/tui.js +106 -17
  514. package/dist/src/tui/tui.js.map +1 -1
  515. package/dist/src/tunnel/frpc-binary.js +4 -4
  516. package/dist/src/tunnel/frpc-config.js +1 -1
  517. package/dist/src/tunnel/frpc-extract.js +1 -1
  518. package/dist/src/tunnel/tunnel-state.js +1 -1
  519. package/dist/src/utils/logger/audit.js +1 -1
  520. package/dist/src/utils/logger/context.d.ts +2 -2
  521. package/dist/src/utils/logger/context.js +2 -1
  522. package/dist/src/utils/logger/context.js.map +1 -1
  523. package/dist/src/utils/logger/log-store.js +2 -1
  524. package/dist/src/utils/logger/log-store.js.map +1 -1
  525. package/dist/src/utils/logger/pino-record.js +3 -0
  526. package/dist/src/utils/logger/pino-record.js.map +1 -1
  527. package/dist/src/utils/logger/rotation.js +1 -1
  528. package/dist/src/utils/logger/streams.js +1 -1
  529. package/dist/src/utils/logger/types.d.ts +5 -0
  530. package/dist/src/utils/logger/types.js.map +1 -1
  531. package/dist/src/voice/tts/audio.js +1 -1
  532. package/dist/src/voice/tts/providers/edge-speech.js +2 -2
  533. package/dist/src/workflows/draft/workflow-draft-service.js +1 -1
  534. package/dist/src/workflows/service/workflow-run-service.js +1 -1
  535. package/dist/src/workflows/service/workflow-session-bridge.js +13 -1
  536. package/dist/src/workflows/service/workflow-session-bridge.js.map +1 -1
  537. package/dist/src/workflows/store/event-store.js +1 -1
  538. package/dist/src/workflows/store/run-store.js +1 -1
  539. package/package.json +1 -1
  540. package/dist/gateway/static/root/assets/agent-browser-settings-page-rGbKc2Hh.js +0 -6
  541. package/dist/gateway/static/root/assets/agent-defaults-tabbed-page-CtwVbjOA.js +0 -1
  542. package/dist/gateway/static/root/assets/agents-CCBmGcwc.js +0 -71
  543. package/dist/gateway/static/root/assets/apps-page-xwCsJS15.js +0 -1
  544. package/dist/gateway/static/root/assets/channels-settings-C044DcYk.js +0 -1
  545. package/dist/gateway/static/root/assets/connectors-settings-8VEWUOTj.js +0 -2
  546. package/dist/gateway/static/root/assets/cron-page-DqmNGNOy.js +0 -3
  547. package/dist/gateway/static/root/assets/goal-detail-page-bv0VRDaf.js +0 -1
  548. package/dist/gateway/static/root/assets/goals-page-1Ywnt4Cb.js +0 -2
  549. package/dist/gateway/static/root/assets/goals-settings-ceEBjnfc.js +0 -1
  550. package/dist/gateway/static/root/assets/index-Cxm6xsps.js +0 -122
  551. package/dist/gateway/static/root/assets/index-b_R4tKqt.css +0 -1
  552. package/dist/gateway/static/root/assets/logs-page-B_wrxhee.js +0 -2
  553. package/dist/gateway/static/root/assets/messages-CkT-lcgP.js +0 -3
  554. package/dist/gateway/static/root/assets/models-hub-panel-D0JDSbNu.js +0 -2
  555. package/dist/gateway/static/root/assets/note-detail-page-DpFV-EO6.js +0 -2
  556. package/dist/gateway/static/root/assets/notes-page-CdkjTch8.js +0 -1
  557. package/dist/gateway/static/root/assets/remote-access-hub-DSYVAi96.js +0 -1
  558. package/dist/gateway/static/root/assets/sessions-page-CenkcVjF.js +0 -1
  559. package/dist/gateway/static/root/assets/settings-advanced-gate-D9sva86V.js +0 -1
  560. package/dist/gateway/static/root/assets/settings-page-DL35U0x0.js +0 -1
  561. package/dist/gateway/static/root/assets/setup-status-panel-Ctwbp9Er.js +0 -1
  562. package/dist/gateway/static/root/assets/shares-settings-DIM3JNsr.js +0 -1
  563. package/dist/gateway/static/root/assets/skill-reload-api-DAlNaNzL.js +0 -1
  564. package/dist/gateway/static/root/assets/skills-page-CLrHVzAt.js +0 -2
  565. package/dist/gateway/static/root/assets/voice-api-key-field-vYAO71Gn.js +0 -1
  566. package/dist/gateway/static/root/assets/workflow-page.utils-sgHjOXOm.js +0 -1
  567. package/dist/gateway/static/root/assets/workflows-page-DYyOTmFx.js +0 -18
@@ -1 +1 @@
1
- {"version":3,"file":"context.js","names":[],"sources":["../../../src/chat-commands/context.ts"],"sourcesContent":["/**\n * Command Context Implementation\n * \n * Provides the concrete implementation of CommandContext interface,\n * bridging commands to core services (AgentService, SessionStore, etc.)\n */\n\nimport type {\n CommandContext,\n ReplyOptions,\n UIComponent,\n SessionInfo,\n ModelInfo,\n UsageStats,\n PlatformFeature,\n MessageSource,\n CompactSessionResult,\n} from './types.js';\nimport { getSessionDisplayName } from './session-key.js';\nimport type { Config } from '../config/schema.js';\nimport type { AgentMessage } from '@earendil-works/pi-agent-core';\nimport type { MessageBus } from '../infra/bus/index.js';\nimport type { SessionStore, SessionConfigStore } from '../session/index.js';\nimport { createLogger } from '../utils/logger.js';\nimport { getRoutingInfo } from './session-key.js';\nimport { saveConfig } from '../config/loader.js';\nimport type { ThinkLevel, ReasoningLevel, VerboseLevel } from '../agent/transcript/thinking-types.js';\nimport { mkdir, writeFile } from 'fs/promises';\nimport { join } from 'path';\nimport { effectiveWorkspacePathForSession } from '../session/session-workspace.js';\nimport { wrapMarkdownExportAsHtml } from '../session/chat-export.js';\nimport type { CompactionResult } from '../agent/memory/compaction.js';\nimport type { PersistentGoalApis } from '../agent/goals/persistent-goal-apis.js';\nimport type { WorkflowRunServiceLike } from '../workflows/service/workflow-run-service.types.js';\n\nconst log = createLogger('CommandContext');\n\nexport interface CommandContextDeps {\n sessionKey: string;\n source: MessageSource;\n channelId: string;\n chatId: string;\n senderId: string;\n isGroup: boolean;\n config: Config;\n bus: MessageBus;\n sessionStore: SessionStore;\n sessionConfigStore?: SessionConfigStore;\n /** After persisting session thinking, sync pi-agent in-memory state */\n applySessionThinkingLevel?: (sessionKey: string, level: ThinkLevel) => void;\n // Callbacks for platform-specific operations\n replyHandler: (text: string, options?: ReplyOptions) => Promise<void>;\n componentHandler?: (component: UIComponent) => Promise<void>;\n typingHandler?: (typing: boolean) => Promise<void>;\n supportedFeatures: PlatformFeature[];\n /** Called after session files are removed so in-memory agents match disk */\n invalidateAgentSession?: (sessionKey: string) => void;\n /** Reset session in place (archive + new session id); optional — falls back to clearSession */\n resetSession?: (sessionKey: string) => Promise<void>;\n // Model management (optional, will be injected)\n getCurrentModel?: () => string;\n switchModel?: (modelId: string) => Promise<boolean>;\n listModels?: () => Promise<ModelInfo[]>;\n getUsage?: () => Promise<UsageStats>;\n /** Stop current LLM turn and clear channel preview stream (Telegram draft, etc.) */\n abortCurrentTurn?: () => Promise<void>;\n /** Reload skills from disk and refresh active agent prompts. */\n reloadSkills?: () => Promise<void>;\n\n compactSession?: (\n sessionKey: string,\n options?: { instructions?: string; force?: boolean },\n ) => Promise<CompactionResult>;\n\n btwQuery?: (sessionKey: string, question: string) => Promise<{ text: string; error?: string }>;\n\n getSessionContextReport?: (\n sessionKey: string,\n mode: 'list' | 'detail' | 'json',\n ) => Promise<string>;\n\n persistentGoalApis?: PersistentGoalApis;\n workflowRunService?: WorkflowRunServiceLike;\n}\n\nexport class CommandContextImpl implements CommandContext {\n readonly sessionKey: string;\n readonly source: MessageSource;\n readonly channelId: string;\n readonly chatId: string;\n readonly senderId: string;\n readonly isGroup: boolean;\n readonly config: Config;\n readonly abortCurrentTurn?: () => Promise<void>;\n readonly reloadSkills?: () => Promise<void>;\n readonly persistentGoalApis?: PersistentGoalApis;\n readonly workflowRunApis?: CommandContext['workflowRunApis'];\n\n private deps: CommandContextDeps;\n\n constructor(deps: CommandContextDeps) {\n this.sessionKey = deps.sessionKey;\n this.source = deps.source;\n this.channelId = deps.channelId;\n this.chatId = deps.chatId;\n this.senderId = deps.senderId;\n this.isGroup = deps.isGroup;\n this.config = deps.config;\n this.deps = deps;\n\n if (deps.abortCurrentTurn) {\n const run = deps.abortCurrentTurn;\n this.abortCurrentTurn = async () => {\n await run();\n };\n }\n\n if (deps.reloadSkills) {\n const run = deps.reloadSkills;\n this.reloadSkills = async () => {\n await run();\n };\n }\n\n this.persistentGoalApis = deps.persistentGoalApis;\n if (deps.workflowRunService) {\n this.workflowRunApis = {\n service: deps.workflowRunService,\n startWorkflowRun: (params) => deps.workflowRunService!.startWorkflowRun(params),\n };\n }\n }\n\n // === Reply API ===\n\n async reply(text: string, options?: ReplyOptions): Promise<void> {\n await this.deps.replyHandler(text, options);\n }\n\n async replyComponent(component: UIComponent): Promise<void> {\n if (this.deps.componentHandler) {\n await this.deps.componentHandler(component);\n } else {\n // Fallback to text representation\n await this.reply(this.renderComponentAsText(component));\n }\n }\n\n async setTyping(typing: boolean): Promise<void> {\n if (this.deps.typingHandler) {\n await this.deps.typingHandler(typing);\n }\n }\n\n // === Session Management ===\n\n async getSession(): Promise<AgentMessage[]> {\n return this.deps.sessionStore.load(this.sessionKey);\n }\n\n async resetSession(): Promise<void> {\n if (this.deps.resetSession) {\n await this.deps.resetSession(this.sessionKey);\n } else if (typeof this.deps.sessionStore.reset === 'function') {\n const outcome = await this.deps.sessionStore.reset(this.sessionKey);\n if (!outcome) {\n throw new Error('Session not found');\n }\n this.deps.invalidateAgentSession?.(this.sessionKey);\n } else {\n await this.clearSession();\n return;\n }\n\n const routing = getRoutingInfo(this.sessionKey);\n await this.deps.bus.publishOutbound({\n channel: routing.channel,\n chat_id: routing.chatId,\n content: '✅ New session started. Previous transcript archived; model and session overrides kept.',\n type: 'message',\n metadata: {\n threadId: routing.threadId,\n },\n });\n\n log.info({ sessionKey: this.sessionKey }, 'Session reset');\n }\n\n async clearSession(): Promise<void> {\n // Archive first if has messages\n const messages = await this.getSession();\n if (messages.length > 0) {\n await this.deps.sessionStore.archive(this.sessionKey);\n log.info({ sessionKey: this.sessionKey, messageCount: messages.length }, 'Session archived');\n }\n\n // Delete session\n await this.deps.sessionStore.deleteSession(this.sessionKey);\n this.deps.invalidateAgentSession?.(this.sessionKey);\n\n // Publish outbound message to confirm\n const routing = getRoutingInfo(this.sessionKey);\n await this.deps.bus.publishOutbound({\n channel: routing.channel,\n chat_id: routing.chatId,\n content: '✅ Session cleared.',\n type: 'message',\n metadata: {\n threadId: routing.threadId,\n },\n });\n\n log.info({ sessionKey: this.sessionKey }, 'Session cleared');\n }\n\n async archiveSession(): Promise<void> {\n await this.deps.sessionStore.archive(this.sessionKey);\n log.info({ sessionKey: this.sessionKey }, 'Session archived');\n }\n\n async listSessions(): Promise<SessionInfo[]> {\n // TODO: Implement listSessions in SessionStore\n // For now, return current session only\n const messages = await this.getSession();\n return [{\n key: this.sessionKey,\n name: getSessionDisplayName(this.sessionKey),\n messageCount: messages.length,\n createdAt: new Date(),\n updatedAt: new Date(),\n isActive: true,\n }];\n }\n\n async switchSession(sessionKey: string): Promise<void> {\n // This is mainly for CLI/Web UI where you can switch between sessions\n // For Telegram, each chat has its own session\n log.info({ from: this.sessionKey, to: sessionKey }, 'Session switch requested');\n \n // Note: In the current architecture, switching session means\n // the next message will use a different sessionKey\n // The actual switch happens at the adapter level\n }\n\n // === Model Management ===\n\n getCurrentModel(): string {\n if (this.deps.getCurrentModel) {\n return this.deps.getCurrentModel();\n }\n \n // Fallback to config default\n return this.config.agents?.defaults?.models?.chat?.primary || 'minimax/minimax-m2.1';\n }\n\n async listModels(): Promise<ModelInfo[]> {\n if (this.deps.listModels) {\n return this.deps.listModels();\n }\n \n // Fallback to empty list\n return [];\n }\n\n async switchModel(modelId: string): Promise<boolean> {\n if (this.deps.switchModel) {\n return this.deps.switchModel(modelId);\n }\n \n // No model manager available\n await this.reply('❌ Model switching not available in this context.');\n return false;\n }\n\n async getUsage(): Promise<UsageStats> {\n if (this.deps.getUsage) {\n return this.deps.getUsage();\n }\n \n // Fallback: calculate from session\n const messages = await this.getSession();\n let promptTokens = 0;\n let completionTokens = 0;\n \n for (const msg of messages) {\n if ('usage' in msg && msg.usage) {\n promptTokens += msg.usage.input || 0;\n completionTokens += msg.usage.output || 0;\n }\n }\n \n return {\n promptTokens,\n completionTokens,\n totalTokens: promptTokens + completionTokens,\n messageCount: messages.length,\n };\n }\n\n // === Platform Features ===\n\n supports(feature: PlatformFeature): boolean {\n return this.deps.supportedFeatures.includes(feature);\n }\n\n // === Configuration ===\n\n getConfig(): Config {\n return this.config;\n }\n\n async updateConfig(path: string, value: unknown): Promise<boolean> {\n try {\n // Update config object using path\n const keys = path.split('.');\n let target: Record<string, unknown> = this.config as Record<string, unknown>;\n \n for (let i = 0; i < keys.length - 1; i++) {\n const key = keys[i];\n if (!(key in target) || typeof target[key] !== 'object' || target[key] === null) {\n target[key] = {};\n }\n target = target[key] as Record<string, unknown>;\n }\n \n target[keys[keys.length - 1]] = value;\n \n // Save to disk\n await saveConfig(this.config);\n \n log.info({ path, value }, 'Config updated via command');\n return true;\n } catch (error) {\n log.error({ err: error, path, value }, 'Failed to update config');\n return false;\n }\n }\n\n // === Private Helpers ===\n\n // === Thinking Configuration ===\n\n /**\n * Get the session config store (if available)\n */\n getSessionConfigStore(): SessionConfigStore | undefined {\n return this.deps.sessionConfigStore;\n }\n\n /**\n * Get current thinking level (session override or default)\n */\n async getThinkingLevel(): Promise<ThinkLevel | undefined> {\n const configStore = this.deps.sessionConfigStore;\n if (configStore) {\n const sessionConfig = await configStore.get(this.sessionKey);\n if (sessionConfig?.thinkingLevel) {\n return sessionConfig.thinkingLevel;\n }\n }\n // Fallback to agent default\n return this.config.agents?.defaults?.thinkingDefault;\n }\n\n /**\n * Set thinking level for this session\n */\n async setThinkingLevel(level: ThinkLevel): Promise<void> {\n const configStore = this.deps.sessionConfigStore;\n if (configStore) {\n await configStore.update(this.sessionKey, { thinkingLevel: level });\n }\n this.deps.applySessionThinkingLevel?.(this.sessionKey, level);\n }\n\n syncAgentThinkingLevel(level: ThinkLevel): void {\n this.deps.applySessionThinkingLevel?.(this.sessionKey, level);\n }\n\n async compactSession(options?: { instructions?: string; force?: boolean }): Promise<CompactSessionResult | null> {\n if (!this.deps.compactSession) {\n return null;\n }\n const r = await this.deps.compactSession(this.sessionKey, options);\n return {\n compacted: r.compacted,\n tokensBefore: r.tokensBefore,\n tokensAfter: r.tokensAfter,\n summary: r.summary,\n };\n }\n\n async btwQuery(question: string): Promise<{ text: string; error?: string }> {\n if (!this.deps.btwQuery) {\n return { text: '', error: 'Side questions are not available in this environment.' };\n }\n return this.deps.btwQuery(this.sessionKey, question);\n }\n\n async exportSessionToWorkspace(format: 'markdown' | 'html' | 'json'): Promise<{ path: string }> {\n const exportFmt = format === 'json' ? 'json' : 'markdown';\n let body = await this.deps.sessionStore.exportSession(this.sessionKey, exportFmt);\n if (format === 'html') {\n body = wrapMarkdownExportAsHtml(`Session ${this.sessionKey}`, body);\n }\n const sc = this.deps.sessionConfigStore\n ? await this.deps.sessionConfigStore.get(this.sessionKey)\n : null;\n const root = effectiveWorkspacePathForSession(this.config, this.sessionKey, sc);\n const dir = join(root, 'exports');\n await mkdir(dir, { recursive: true });\n const safe = this.sessionKey.replace(/[^a-zA-Z0-9._-]+/g, '_').slice(0, 96);\n const ext = format === 'json' ? 'json' : format === 'html' ? 'html' : 'md';\n const name = `session-${safe}-${Date.now()}.${ext}`;\n const outPath = join(dir, name);\n await writeFile(outPath, body, 'utf-8');\n return { path: outPath };\n }\n\n async agentContextReport(mode: 'list' | 'detail' | 'json' = 'list'): Promise<string> {\n if (!this.deps.getSessionContextReport) {\n return 'Context report is not available in this environment.';\n }\n return this.deps.getSessionContextReport(this.sessionKey, mode);\n }\n\n /**\n * Get current reasoning level (session override or default)\n */\n async getReasoningLevel(): Promise<ReasoningLevel | undefined> {\n const configStore = this.deps.sessionConfigStore;\n if (configStore) {\n const sessionConfig = await configStore.get(this.sessionKey);\n if (sessionConfig?.reasoningLevel) {\n return sessionConfig.reasoningLevel;\n }\n }\n // Fallback to agent default\n return this.config.agents?.defaults?.reasoningDefault;\n }\n\n /**\n * Set reasoning level for this session\n */\n async setReasoningLevel(level: ReasoningLevel): Promise<void> {\n const configStore = this.deps.sessionConfigStore;\n if (configStore) {\n await configStore.update(this.sessionKey, { reasoningLevel: level });\n }\n }\n\n /**\n * Get current verbose level (session override or default)\n */\n async getVerboseLevel(): Promise<VerboseLevel | undefined> {\n const configStore = this.deps.sessionConfigStore;\n if (configStore) {\n const sessionConfig = await configStore.get(this.sessionKey);\n if (sessionConfig?.verboseLevel) {\n return sessionConfig.verboseLevel;\n }\n }\n // Fallback to agent default\n return this.config.agents?.defaults?.verboseDefault;\n }\n\n /**\n * Set verbose level for this session\n */\n async setVerboseLevel(level: VerboseLevel): Promise<void> {\n const configStore = this.deps.sessionConfigStore;\n if (configStore) {\n await configStore.update(this.sessionKey, { verboseLevel: level });\n }\n }\n\n private renderComponentAsText(component: UIComponent): string {\n switch (component.type) {\n case 'buttons':\n return component.buttons.map(b => `[${b.text}]`).join(' ');\n \n case 'select':\n return component.options.map(o => `- ${o.label}`).join('\\n');\n \n case 'model-picker':\n return component.providers.map(p => \n `**${p.name}**\\n${p.models.map(m => ` - ${m.name}`).join('\\n')}`\n ).join('\\n\\n');\n \n case 'usage-display':\n return `📊 Usage Stats:\\n` +\n `📥 Prompt: ${component.stats.promptTokens.toLocaleString()} tokens\\n` +\n `📤 Completion: ${component.stats.completionTokens.toLocaleString()} tokens\\n` +\n `📊 Total: ${component.stats.totalTokens.toLocaleString()} tokens`;\n \n case 'session-list':\n return component.sessions.map(s => \n `${s.isActive ? '▶️' : ' '} ${s.key} (${s.messageCount} messages)`\n ).join('\\n');\n \n case 'text-input':\n return component.placeholder || 'Enter text...';\n \n default:\n return '[UI Component]';\n }\n }\n}\n\n/**\n * Create a command context from dependencies\n */\nexport function createCommandContext(deps: CommandContextDeps): CommandContext {\n return new CommandContextImpl(deps);\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"context.js","names":[],"sources":["../../../src/chat-commands/context.ts"],"sourcesContent":["/**\n * Command Context Implementation\n * \n * Provides the concrete implementation of CommandContext interface,\n * bridging commands to core services (AgentService, SessionStore, etc.)\n */\n\nimport type {\n CommandContext,\n ReplyOptions,\n UIComponent,\n SessionInfo,\n ModelInfo,\n UsageStats,\n PlatformFeature,\n MessageSource,\n CompactSessionResult,\n} from './types.js';\nimport { getSessionDisplayName } from './session-key.js';\nimport type { Config } from '../config/schema.js';\nimport type { AgentMessage } from '@earendil-works/pi-agent-core';\nimport type { MessageBus } from '../infra/bus/index.js';\nimport type { SessionStore, SessionConfigStore } from '../session/index.js';\nimport { createLogger } from '../utils/logger.js';\nimport { saveConfig } from '../config/loader.js';\nimport type { ThinkLevel, ReasoningLevel, VerboseLevel } from '../agent/transcript/thinking-types.js';\nimport { mkdir, writeFile } from 'fs/promises';\nimport { join } from 'path';\nimport { effectiveWorkspacePathForSession } from '../session/session-workspace.js';\nimport { wrapMarkdownExportAsHtml } from '../session/chat-export.js';\nimport type { CompactionResult } from '../agent/memory/compaction.js';\nimport type { PersistentGoalApis } from '../agent/goals/persistent-goal-apis.js';\nimport type { WorkflowRunServiceLike } from '../workflows/service/workflow-run-service.types.js';\n\nconst log = createLogger('CommandContext');\n\nexport interface CommandContextDeps {\n sessionKey: string;\n source: MessageSource;\n channelId: string;\n chatId: string;\n senderId: string;\n isGroup: boolean;\n accountId?: string;\n threadId?: string;\n config: Config;\n bus: MessageBus;\n sessionStore: SessionStore;\n sessionConfigStore?: SessionConfigStore;\n /** After persisting session thinking, sync pi-agent in-memory state */\n applySessionThinkingLevel?: (sessionKey: string, level: ThinkLevel) => void;\n // Callbacks for platform-specific operations\n replyHandler: (text: string, options?: ReplyOptions) => Promise<void>;\n componentHandler?: (component: UIComponent) => Promise<void>;\n typingHandler?: (typing: boolean) => Promise<void>;\n supportedFeatures: PlatformFeature[];\n /** Called after session files are removed so in-memory agents match disk */\n invalidateAgentSession?: (sessionKey: string) => void;\n /** Reset session in place (archive + new session id); optional — falls back to clearSession */\n resetSession?: (sessionKey: string) => Promise<void>;\n // Model management (optional, will be injected)\n getCurrentModel?: () => string;\n switchModel?: (modelId: string) => Promise<boolean>;\n listModels?: () => Promise<ModelInfo[]>;\n getUsage?: () => Promise<UsageStats>;\n /** Stop current LLM turn and clear channel preview stream (Telegram draft, etc.) */\n abortCurrentTurn?: () => Promise<void>;\n /** Reload skills from disk and refresh active agent prompts. */\n reloadSkills?: () => Promise<void>;\n\n compactSession?: (\n sessionKey: string,\n options?: { instructions?: string; force?: boolean },\n ) => Promise<CompactionResult>;\n\n btwQuery?: (sessionKey: string, question: string) => Promise<{ text: string; error?: string }>;\n\n getSessionContextReport?: (\n sessionKey: string,\n mode: 'list' | 'detail' | 'json',\n ) => Promise<string>;\n\n persistentGoalApis?: PersistentGoalApis;\n workflowRunService?: WorkflowRunServiceLike;\n}\n\nexport class CommandContextImpl implements CommandContext {\n readonly sessionKey: string;\n readonly source: MessageSource;\n readonly channelId: string;\n readonly chatId: string;\n readonly senderId: string;\n readonly isGroup: boolean;\n readonly accountId?: string;\n readonly threadId?: string;\n readonly config: Config;\n readonly abortCurrentTurn?: () => Promise<void>;\n readonly reloadSkills?: () => Promise<void>;\n readonly persistentGoalApis?: PersistentGoalApis;\n readonly workflowRunApis?: CommandContext['workflowRunApis'];\n\n private deps: CommandContextDeps;\n\n constructor(deps: CommandContextDeps) {\n this.sessionKey = deps.sessionKey;\n this.source = deps.source;\n this.channelId = deps.channelId;\n this.chatId = deps.chatId;\n this.senderId = deps.senderId;\n this.isGroup = deps.isGroup;\n this.accountId = deps.accountId;\n this.threadId = deps.threadId;\n this.config = deps.config;\n this.deps = deps;\n\n if (deps.abortCurrentTurn) {\n const run = deps.abortCurrentTurn;\n this.abortCurrentTurn = async () => {\n await run();\n };\n }\n\n if (deps.reloadSkills) {\n const run = deps.reloadSkills;\n this.reloadSkills = async () => {\n await run();\n };\n }\n\n this.persistentGoalApis = deps.persistentGoalApis;\n if (deps.workflowRunService) {\n this.workflowRunApis = {\n service: deps.workflowRunService,\n startWorkflowRun: (params) => deps.workflowRunService!.startWorkflowRun(params),\n };\n }\n }\n\n private outboundMetadata(extra?: Record<string, unknown>): Record<string, unknown> {\n return {\n accountId: this.deps.accountId,\n threadId: this.deps.threadId,\n ...extra,\n };\n }\n\n // === Reply API ===\n\n async reply(text: string, options?: ReplyOptions): Promise<void> {\n await this.deps.replyHandler(text, options);\n }\n\n async replyComponent(component: UIComponent): Promise<void> {\n if (this.deps.componentHandler) {\n await this.deps.componentHandler(component);\n } else {\n // Fallback to text representation\n await this.reply(this.renderComponentAsText(component));\n }\n }\n\n async setTyping(typing: boolean): Promise<void> {\n if (this.deps.typingHandler) {\n await this.deps.typingHandler(typing);\n }\n }\n\n // === Session Management ===\n\n async getSession(): Promise<AgentMessage[]> {\n return this.deps.sessionStore.load(this.sessionKey);\n }\n\n async resetSession(): Promise<void> {\n if (this.deps.resetSession) {\n await this.deps.resetSession(this.sessionKey);\n } else if (typeof this.deps.sessionStore.reset === 'function') {\n const outcome = await this.deps.sessionStore.reset(this.sessionKey);\n if (!outcome) {\n throw new Error('Session not found');\n }\n this.deps.invalidateAgentSession?.(this.sessionKey);\n } else {\n await this.clearSession();\n return;\n }\n\n await this.deps.bus.publishOutbound({\n channel: this.source,\n chat_id: this.chatId,\n content: '✅ New session started. Previous transcript archived; model and session overrides kept.',\n type: 'message',\n metadata: this.outboundMetadata(),\n });\n\n log.info({ sessionKey: this.sessionKey }, 'Session reset');\n }\n\n async clearSession(): Promise<void> {\n // Archive first if has messages\n const messages = await this.getSession();\n if (messages.length > 0) {\n await this.deps.sessionStore.archive(this.sessionKey);\n log.info({ sessionKey: this.sessionKey, messageCount: messages.length }, 'Session archived');\n }\n\n // Delete session\n await this.deps.sessionStore.deleteSession(this.sessionKey);\n this.deps.invalidateAgentSession?.(this.sessionKey);\n\n // Publish outbound message to confirm\n await this.deps.bus.publishOutbound({\n channel: this.source,\n chat_id: this.chatId,\n content: '✅ Session cleared.',\n type: 'message',\n metadata: this.outboundMetadata(),\n });\n\n log.info({ sessionKey: this.sessionKey }, 'Session cleared');\n }\n\n async archiveSession(): Promise<void> {\n await this.deps.sessionStore.archive(this.sessionKey);\n log.info({ sessionKey: this.sessionKey }, 'Session archived');\n }\n\n async listSessions(): Promise<SessionInfo[]> {\n // TODO: Implement listSessions in SessionStore\n // For now, return current session only\n const messages = await this.getSession();\n return [{\n key: this.sessionKey,\n name: getSessionDisplayName(this.sessionKey),\n messageCount: messages.length,\n createdAt: new Date(),\n updatedAt: new Date(),\n isActive: true,\n }];\n }\n\n async switchSession(sessionKey: string): Promise<void> {\n // This is mainly for CLI/Web UI where you can switch between sessions\n // For Telegram, each chat has its own session\n log.info({ from: this.sessionKey, to: sessionKey }, 'Session switch requested');\n \n // Note: In the current architecture, switching session means\n // the next message will use a different sessionKey\n // The actual switch happens at the adapter level\n }\n\n // === Model Management ===\n\n getCurrentModel(): string {\n if (this.deps.getCurrentModel) {\n return this.deps.getCurrentModel();\n }\n \n // Fallback to config default\n return this.config.agents?.defaults?.models?.chat?.primary || 'minimax/minimax-m2.1';\n }\n\n async listModels(): Promise<ModelInfo[]> {\n if (this.deps.listModels) {\n return this.deps.listModels();\n }\n \n // Fallback to empty list\n return [];\n }\n\n async switchModel(modelId: string): Promise<boolean> {\n if (this.deps.switchModel) {\n return this.deps.switchModel(modelId);\n }\n \n // No model manager available\n await this.reply('❌ Model switching not available in this context.');\n return false;\n }\n\n async getUsage(): Promise<UsageStats> {\n if (this.deps.getUsage) {\n return this.deps.getUsage();\n }\n \n // Fallback: calculate from session\n const messages = await this.getSession();\n let promptTokens = 0;\n let completionTokens = 0;\n \n for (const msg of messages) {\n if ('usage' in msg && msg.usage) {\n promptTokens += msg.usage.input || 0;\n completionTokens += msg.usage.output || 0;\n }\n }\n \n return {\n promptTokens,\n completionTokens,\n totalTokens: promptTokens + completionTokens,\n messageCount: messages.length,\n };\n }\n\n // === Platform Features ===\n\n supports(feature: PlatformFeature): boolean {\n return this.deps.supportedFeatures.includes(feature);\n }\n\n // === Configuration ===\n\n getConfig(): Config {\n return this.config;\n }\n\n async updateConfig(path: string, value: unknown): Promise<boolean> {\n try {\n // Update config object using path\n const keys = path.split('.');\n let target: Record<string, unknown> = this.config as Record<string, unknown>;\n \n for (let i = 0; i < keys.length - 1; i++) {\n const key = keys[i];\n if (!(key in target) || typeof target[key] !== 'object' || target[key] === null) {\n target[key] = {};\n }\n target = target[key] as Record<string, unknown>;\n }\n \n target[keys[keys.length - 1]] = value;\n \n // Save to disk\n await saveConfig(this.config);\n \n log.info({ path, value }, 'Config updated via command');\n return true;\n } catch (error) {\n log.error({ err: error, path, value }, 'Failed to update config');\n return false;\n }\n }\n\n // === Private Helpers ===\n\n // === Thinking Configuration ===\n\n /**\n * Get the session config store (if available)\n */\n getSessionConfigStore(): SessionConfigStore | undefined {\n return this.deps.sessionConfigStore;\n }\n\n /**\n * Get current thinking level (session override or default)\n */\n async getThinkingLevel(): Promise<ThinkLevel | undefined> {\n const configStore = this.deps.sessionConfigStore;\n if (configStore) {\n const sessionConfig = await configStore.get(this.sessionKey);\n if (sessionConfig?.thinkingLevel) {\n return sessionConfig.thinkingLevel;\n }\n }\n // Fallback to agent default\n return this.config.agents?.defaults?.thinkingDefault;\n }\n\n /**\n * Set thinking level for this session\n */\n async setThinkingLevel(level: ThinkLevel): Promise<void> {\n const configStore = this.deps.sessionConfigStore;\n if (configStore) {\n await configStore.update(this.sessionKey, { thinkingLevel: level });\n }\n this.deps.applySessionThinkingLevel?.(this.sessionKey, level);\n }\n\n syncAgentThinkingLevel(level: ThinkLevel): void {\n this.deps.applySessionThinkingLevel?.(this.sessionKey, level);\n }\n\n async compactSession(options?: { instructions?: string; force?: boolean }): Promise<CompactSessionResult | null> {\n if (!this.deps.compactSession) {\n return null;\n }\n const r = await this.deps.compactSession(this.sessionKey, options);\n return {\n compacted: r.compacted,\n tokensBefore: r.tokensBefore,\n tokensAfter: r.tokensAfter,\n summary: r.summary,\n };\n }\n\n async btwQuery(question: string): Promise<{ text: string; error?: string }> {\n if (!this.deps.btwQuery) {\n return { text: '', error: 'Side questions are not available in this environment.' };\n }\n return this.deps.btwQuery(this.sessionKey, question);\n }\n\n async exportSessionToWorkspace(format: 'markdown' | 'html' | 'json'): Promise<{ path: string }> {\n const exportFmt = format === 'json' ? 'json' : 'markdown';\n let body = await this.deps.sessionStore.exportSession(this.sessionKey, exportFmt);\n if (format === 'html') {\n body = wrapMarkdownExportAsHtml(`Session ${this.sessionKey}`, body);\n }\n const sc = this.deps.sessionConfigStore\n ? await this.deps.sessionConfigStore.get(this.sessionKey)\n : null;\n const root = effectiveWorkspacePathForSession(this.config, this.sessionKey, sc);\n const dir = join(root, 'exports');\n await mkdir(dir, { recursive: true });\n const safe = this.sessionKey.replace(/[^a-zA-Z0-9._-]+/g, '_').slice(0, 96);\n const ext = format === 'json' ? 'json' : format === 'html' ? 'html' : 'md';\n const name = `session-${safe}-${Date.now()}.${ext}`;\n const outPath = join(dir, name);\n await writeFile(outPath, body, 'utf-8');\n return { path: outPath };\n }\n\n async agentContextReport(mode: 'list' | 'detail' | 'json' = 'list'): Promise<string> {\n if (!this.deps.getSessionContextReport) {\n return 'Context report is not available in this environment.';\n }\n return this.deps.getSessionContextReport(this.sessionKey, mode);\n }\n\n /**\n * Get current reasoning level (session override or default)\n */\n async getReasoningLevel(): Promise<ReasoningLevel | undefined> {\n const configStore = this.deps.sessionConfigStore;\n if (configStore) {\n const sessionConfig = await configStore.get(this.sessionKey);\n if (sessionConfig?.reasoningLevel) {\n return sessionConfig.reasoningLevel;\n }\n }\n // Fallback to agent default\n return this.config.agents?.defaults?.reasoningDefault;\n }\n\n /**\n * Set reasoning level for this session\n */\n async setReasoningLevel(level: ReasoningLevel): Promise<void> {\n const configStore = this.deps.sessionConfigStore;\n if (configStore) {\n await configStore.update(this.sessionKey, { reasoningLevel: level });\n }\n }\n\n /**\n * Get current verbose level (session override or default)\n */\n async getVerboseLevel(): Promise<VerboseLevel | undefined> {\n const configStore = this.deps.sessionConfigStore;\n if (configStore) {\n const sessionConfig = await configStore.get(this.sessionKey);\n if (sessionConfig?.verboseLevel) {\n return sessionConfig.verboseLevel;\n }\n }\n // Fallback to agent default\n return this.config.agents?.defaults?.verboseDefault;\n }\n\n /**\n * Set verbose level for this session\n */\n async setVerboseLevel(level: VerboseLevel): Promise<void> {\n const configStore = this.deps.sessionConfigStore;\n if (configStore) {\n await configStore.update(this.sessionKey, { verboseLevel: level });\n }\n }\n\n private renderComponentAsText(component: UIComponent): string {\n switch (component.type) {\n case 'buttons':\n return component.buttons.map(b => `[${b.text}]`).join(' ');\n \n case 'select':\n return component.options.map(o => `- ${o.label}`).join('\\n');\n \n case 'model-picker':\n return component.providers.map(p => \n `**${p.name}**\\n${p.models.map(m => ` - ${m.name}`).join('\\n')}`\n ).join('\\n\\n');\n \n case 'usage-display':\n return `📊 Usage Stats:\\n` +\n `📥 Prompt: ${component.stats.promptTokens.toLocaleString()} tokens\\n` +\n `📤 Completion: ${component.stats.completionTokens.toLocaleString()} tokens\\n` +\n `📊 Total: ${component.stats.totalTokens.toLocaleString()} tokens`;\n \n case 'session-list':\n return component.sessions.map(s => \n `${s.isActive ? '▶️' : ' '} ${s.key} (${s.messageCount} messages)`\n ).join('\\n');\n \n case 'text-input':\n return component.placeholder || 'Enter text...';\n \n default:\n return '[UI Component]';\n }\n }\n}\n\n/**\n * Create a command context from dependencies\n */\nexport function createCommandContext(deps: CommandContextDeps): CommandContext {\n return new CommandContextImpl(deps);\n}\n"],"mappings":"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"}
@@ -5,7 +5,7 @@
5
5
  * Telegram, Feishu, Web UI, CLI, and other channel surfaces.
6
6
  */
7
7
  export type { MessageSource, UnifiedMessage, PlatformMetadata, MessageAttachment, CommandDefinition, CommandCategory, CommandScope, CommandHandler, CommandResult, CommandContext, ReplyOptions, UIComponent, ButtonGroup, SelectMenu, ModelPicker, UsageDisplay, SessionList, TextInput, ProviderInfo, ModelInfo, UsageStats, SessionInfo, PlatformFeature, ChannelAdapter, ReplyPayload, } from './types.js';
8
- export { generateSessionKey, parseSessionKey, isValidSessionKey, getSessionDisplayName, getRoutingInfo, type SessionKeyContext, } from './session-key.js';
8
+ export { generateSessionKey, getSessionDisplayName, type SessionKeyContext } from './session-key.js';
9
9
  export { normalizeTelegramCommandName, parseSlashCommand } from './command-parse.js';
10
10
  export { CommandRegistry, commandRegistry } from './registry.js';
11
11
  export type { CommandRegistry as CommandRegistryType } from './types.js';
@@ -1,6 +1,6 @@
1
1
  import { normalizeTelegramCommandName, parseSlashCommand } from "./command-parse.js";
2
2
  import { CommandRegistry, commandRegistry } from "./registry.js";
3
- import { generateSessionKey, getRoutingInfo, getSessionDisplayName, isValidSessionKey, parseSessionKey } from "./session-key.js";
3
+ import { generateSessionKey, getSessionDisplayName } from "./session-key.js";
4
4
  import { registerSessionCommands } from "./builtins/session.js";
5
5
  import { registerModelCommands } from "./builtins/model.js";
6
6
  import { registerSystemCommands } from "./builtins/system.js";
@@ -37,6 +37,6 @@ function initializeCommands() {
37
37
  registerAgentEditCommand();
38
38
  }
39
39
  //#endregion
40
- export { CommandContextImpl, CommandRegistry, commandRegistry, createCommandContext, generateSessionKey, getRoutingInfo, getSessionDisplayName, initializeCommands, isValidSessionKey, normalizeTelegramCommandName, parseSessionKey, parseSlashCommand, registerAgentEditCommand, registerConfigCommand, registerContextCommands, registerGoalCommand, registerModelCommands, registerSessionCommands, registerSubgoalCommand, registerSystemCommands, registerTTSCommands, registerThinkingCommands, registerWorkflowCommands };
40
+ export { CommandContextImpl, CommandRegistry, commandRegistry, createCommandContext, generateSessionKey, getSessionDisplayName, initializeCommands, normalizeTelegramCommandName, parseSlashCommand, registerAgentEditCommand, registerConfigCommand, registerContextCommands, registerGoalCommand, registerModelCommands, registerSessionCommands, registerSubgoalCommand, registerSystemCommands, registerTTSCommands, registerThinkingCommands, registerWorkflowCommands };
41
41
 
42
42
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":[],"sources":["../../../src/chat-commands/index.ts"],"sourcesContent":["/**\n * Unified Command System\n *\n * Provides a platform-agnostic command system that works across\n * Telegram, Feishu, Web UI, CLI, and other channel surfaces.\n */\n\n// Built-in Commands (import first to avoid circular deps)\nimport { registerSessionCommands } from './builtins/session.js';\nimport { registerModelCommands } from './builtins/model.js';\nimport { registerSystemCommands } from './builtins/system.js';\nimport { registerTTSCommands } from './builtins/tts.js';\nimport { registerThinkingCommands } from './builtins/thinking.js';\nimport { registerConfigCommand } from './builtins/config.js';\nimport { registerContextCommands } from './builtins/context.js';\nimport { registerGoalCommand } from './builtins/goal.js';\nimport { registerSubgoalCommand } from './builtins/subgoal.js';\nimport { registerWorkflowCommands } from './builtins/workflow.js';\nimport { registerAgentEditCommand } from './agent-edit.js';\n\n// Types\nexport type {\n MessageSource,\n UnifiedMessage,\n PlatformMetadata,\n MessageAttachment,\n CommandDefinition,\n CommandCategory,\n CommandScope,\n CommandHandler,\n CommandResult,\n CommandContext,\n ReplyOptions,\n UIComponent,\n ButtonGroup,\n SelectMenu,\n ModelPicker,\n UsageDisplay,\n SessionList,\n TextInput,\n ProviderInfo,\n ModelInfo,\n UsageStats,\n SessionInfo,\n PlatformFeature,\n ChannelAdapter,\n ReplyPayload,\n} from './types.js';\n\n// Session Key\nexport {\n generateSessionKey,\n parseSessionKey,\n isValidSessionKey,\n getSessionDisplayName,\n getRoutingInfo,\n type SessionKeyContext,\n} from './session-key.js';\n\n// Command parsing helpers\nexport { normalizeTelegramCommandName, parseSlashCommand } from './command-parse.js';\n\n// Registry\nexport { CommandRegistry, commandRegistry } from './registry.js';\nexport type { CommandRegistry as CommandRegistryType } from './types.js';\n\n// Context\nexport { CommandContextImpl, createCommandContext } from './context.js';\n\n// Built-in Commands\nexport { registerSessionCommands } from './builtins/session.js';\nexport { registerModelCommands } from './builtins/model.js';\nexport { registerSystemCommands } from './builtins/system.js';\nexport { registerTTSCommands } from './builtins/tts.js';\nexport { registerThinkingCommands } from './builtins/thinking.js';\nexport { registerConfigCommand } from './builtins/config.js';\nexport { registerContextCommands } from './builtins/context.js';\nexport { registerGoalCommand } from './builtins/goal.js';\nexport { registerSubgoalCommand } from './builtins/subgoal.js';\nexport { registerWorkflowCommands } from './builtins/workflow.js';\nexport { registerAgentEditCommand } from './agent-edit.js';\n\n/**\n * Initialize the command system with all built-in commands\n */\nexport function initializeCommands(): void {\n registerSessionCommands();\n registerModelCommands();\n registerSystemCommands();\n registerConfigCommand();\n registerContextCommands();\n registerTTSCommands();\n registerThinkingCommands();\n registerGoalCommand();\n registerSubgoalCommand();\n registerWorkflowCommands();\n registerAgentEditCommand();\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;AAqFA,SAAgB,qBAA2B;AACzC,0BAAyB;AACzB,wBAAuB;AACvB,yBAAwB;AACxB,wBAAuB;AACvB,0BAAyB;AACzB,sBAAqB;AACrB,2BAA0B;AAC1B,sBAAqB;AACrB,yBAAwB;AACxB,2BAA0B;AAC1B,2BAA0B"}
1
+ {"version":3,"file":"index.js","names":[],"sources":["../../../src/chat-commands/index.ts"],"sourcesContent":["/**\n * Unified Command System\n *\n * Provides a platform-agnostic command system that works across\n * Telegram, Feishu, Web UI, CLI, and other channel surfaces.\n */\n\n// Built-in Commands (import first to avoid circular deps)\nimport { registerSessionCommands } from './builtins/session.js';\nimport { registerModelCommands } from './builtins/model.js';\nimport { registerSystemCommands } from './builtins/system.js';\nimport { registerTTSCommands } from './builtins/tts.js';\nimport { registerThinkingCommands } from './builtins/thinking.js';\nimport { registerConfigCommand } from './builtins/config.js';\nimport { registerContextCommands } from './builtins/context.js';\nimport { registerGoalCommand } from './builtins/goal.js';\nimport { registerSubgoalCommand } from './builtins/subgoal.js';\nimport { registerWorkflowCommands } from './builtins/workflow.js';\nimport { registerAgentEditCommand } from './agent-edit.js';\n\n// Types\nexport type {\n MessageSource,\n UnifiedMessage,\n PlatformMetadata,\n MessageAttachment,\n CommandDefinition,\n CommandCategory,\n CommandScope,\n CommandHandler,\n CommandResult,\n CommandContext,\n ReplyOptions,\n UIComponent,\n ButtonGroup,\n SelectMenu,\n ModelPicker,\n UsageDisplay,\n SessionList,\n TextInput,\n ProviderInfo,\n ModelInfo,\n UsageStats,\n SessionInfo,\n PlatformFeature,\n ChannelAdapter,\n ReplyPayload,\n} from './types.js';\n\n// Session display helpers\nexport { generateSessionKey, getSessionDisplayName, type SessionKeyContext } from './session-key.js';\n\n// Command parsing helpers\nexport { normalizeTelegramCommandName, parseSlashCommand } from './command-parse.js';\n\n// Registry\nexport { CommandRegistry, commandRegistry } from './registry.js';\nexport type { CommandRegistry as CommandRegistryType } from './types.js';\n\n// Context\nexport { CommandContextImpl, createCommandContext } from './context.js';\n\n// Built-in Commands\nexport { registerSessionCommands } from './builtins/session.js';\nexport { registerModelCommands } from './builtins/model.js';\nexport { registerSystemCommands } from './builtins/system.js';\nexport { registerTTSCommands } from './builtins/tts.js';\nexport { registerThinkingCommands } from './builtins/thinking.js';\nexport { registerConfigCommand } from './builtins/config.js';\nexport { registerContextCommands } from './builtins/context.js';\nexport { registerGoalCommand } from './builtins/goal.js';\nexport { registerSubgoalCommand } from './builtins/subgoal.js';\nexport { registerWorkflowCommands } from './builtins/workflow.js';\nexport { registerAgentEditCommand } from './agent-edit.js';\n\n/**\n * Initialize the command system with all built-in commands\n */\nexport function initializeCommands(): void {\n registerSessionCommands();\n registerModelCommands();\n registerSystemCommands();\n registerConfigCommand();\n registerContextCommands();\n registerTTSCommands();\n registerThinkingCommands();\n registerGoalCommand();\n registerSubgoalCommand();\n registerWorkflowCommands();\n registerAgentEditCommand();\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;AA8EA,SAAgB,qBAA2B;AACzC,0BAAyB;AACzB,wBAAuB;AACvB,yBAAwB;AACxB,wBAAuB;AACvB,0BAAyB;AACzB,sBAAqB;AACrB,2BAA0B;AAC1B,sBAAqB;AACrB,yBAAwB;AACxB,2BAA0B;AAC1B,2BAA0B"}
@@ -1,11 +1,17 @@
1
1
  import { createLogger } from "../utils/logger/index.js";
2
2
  import { init_logger } from "../utils/logger.js";
3
3
  import { commandRegistry } from "./registry.js";
4
- import { getRoutingInfo } from "./session-key.js";
5
4
  import { createCommandContext } from "./context.js";
6
5
  //#region src/chat-commands/processor.ts
7
6
  init_logger();
8
7
  const log = createLogger("CommandProcessor");
8
+ function commandOutboundMetadata(message, extra) {
9
+ return {
10
+ accountId: message.platformData.accountId,
11
+ threadId: message.platformData.threadId,
12
+ ...extra
13
+ };
14
+ }
9
15
  /**
10
16
  * Process a unified message
11
17
  * Returns true if the message was handled (command or otherwise), false if should continue to AI
@@ -26,23 +32,19 @@ async function executeCommand(message, deps) {
26
32
  }, "Executing command");
27
33
  const ctx = await createCommandContextFromMessage(message, deps);
28
34
  const result = await commandRegistry.execute(commandName, ctx, commandArgs || "");
29
- if (result.content) {
30
- const routing = getRoutingInfo(message.sessionKey);
31
- await deps.bus.publishOutbound({
32
- channel: routing.channel,
33
- chat_id: routing.chatId,
34
- content: result.content,
35
- type: "message",
36
- metadata: { threadId: routing.threadId }
37
- });
38
- }
35
+ if (result.content) await deps.bus.publishOutbound({
36
+ channel: message.source,
37
+ chat_id: message.chatId,
38
+ content: result.content,
39
+ type: "message",
40
+ metadata: commandOutboundMetadata(message)
41
+ });
39
42
  return true;
40
43
  }
41
44
  /**
42
45
  * Create a command context from a unified message
43
46
  */
44
47
  async function createCommandContextFromMessage(message, deps) {
45
- const routing = getRoutingInfo(message.sessionKey);
46
48
  return createCommandContext({
47
49
  sessionKey: message.sessionKey,
48
50
  source: message.source,
@@ -50,27 +52,26 @@ async function createCommandContextFromMessage(message, deps) {
50
52
  chatId: message.chatId,
51
53
  senderId: message.senderId,
52
54
  isGroup: message.platformData.isGroup,
55
+ accountId: message.platformData.accountId,
56
+ threadId: message.platformData.threadId,
53
57
  config: deps.config,
54
58
  bus: deps.bus,
55
59
  sessionStore: deps.sessionStore,
56
60
  replyHandler: async (text, options) => {
57
61
  await deps.bus.publishOutbound({
58
- channel: routing.channel,
59
- chat_id: routing.chatId,
62
+ channel: message.source,
63
+ chat_id: message.chatId,
60
64
  content: text,
61
65
  type: "message",
62
- metadata: {
63
- threadId: routing.threadId,
64
- parseMode: options?.parseMode
65
- }
66
+ metadata: commandOutboundMetadata(message, { parseMode: options?.parseMode })
66
67
  });
67
68
  },
68
69
  typingHandler: async (typing) => {
69
70
  await deps.bus.publishOutbound({
70
- channel: routing.channel,
71
- chat_id: routing.chatId,
71
+ channel: message.source,
72
+ chat_id: message.chatId,
72
73
  type: typing ? "typing_on" : "typing_off",
73
- metadata: { threadId: routing.threadId }
74
+ metadata: commandOutboundMetadata(message)
74
75
  });
75
76
  },
76
77
  supportedFeatures: ["markdown", "typing"],
@@ -1 +1 @@
1
- {"version":3,"file":"processor.js","names":[],"sources":["../../../src/chat-commands/processor.ts"],"sourcesContent":["/**\n * Command Processor\n *\n * Integrates the command system with AgentService.\n * Processes incoming messages and routes commands appropriately.\n */\n\nimport type { UnifiedMessage, CommandContext } from './types.js';\nimport { commandRegistry } from './registry.js';\nimport { createCommandContext } from './context.js';\nimport type { MessageBus } from '../infra/bus/index.js';\nimport type { SessionStore } from '../session/index.js';\nimport type { Config } from '../config/schema.js';\nimport { createLogger } from '../utils/logger.js';\nimport { getRoutingInfo } from './session-key.js';\n\nconst log = createLogger('CommandProcessor');\n\nexport interface CommandProcessorDeps {\n bus: MessageBus;\n sessionStore: SessionStore;\n config: Config;\n // Model management callbacks\n getCurrentModel: () => string;\n switchModel: (modelId: string) => Promise<boolean>;\n listModels: () => Promise<Array<{ id: string; name: string; provider: string }>>;\n getUsage: () => Promise<{ promptTokens: number; completionTokens: number; totalTokens: number; messageCount: number }>;\n}\n\n/**\n * Process a unified message\n * Returns true if the message was handled (command or otherwise), false if should continue to AI\n */\nexport async function processMessage(\n message: UnifiedMessage,\n deps: CommandProcessorDeps\n): Promise<boolean> {\n // If it's a command, execute it\n if (message.isCommand && message.commandName) {\n return executeCommand(message, deps);\n }\n\n // Not a command, let AI handle it\n return false;\n}\n\n/**\n * Execute a command from a unified message\n */\nasync function executeCommand(\n message: UnifiedMessage,\n deps: CommandProcessorDeps\n): Promise<boolean> {\n const { commandName, commandArgs } = message;\n \n if (!commandName) return false;\n\n log.info({ command: commandName, sessionKey: message.sessionKey }, 'Executing command');\n\n // Create command context\n const ctx = await createCommandContextFromMessage(message, deps);\n\n // Execute command\n const result = await commandRegistry.execute(commandName, ctx, commandArgs || '');\n\n // Send response if there's content\n if (result.content) {\n const routing = getRoutingInfo(message.sessionKey);\n await deps.bus.publishOutbound({\n channel: routing.channel,\n chat_id: routing.chatId,\n content: result.content,\n type: 'message',\n metadata: {\n threadId: routing.threadId,\n },\n });\n }\n\n return true;\n}\n\n/**\n * Create a command context from a unified message\n */\nasync function createCommandContextFromMessage(\n message: UnifiedMessage,\n deps: CommandProcessorDeps\n): Promise<CommandContext> {\n const routing = getRoutingInfo(message.sessionKey);\n\n return createCommandContext({\n sessionKey: message.sessionKey,\n source: message.source,\n channelId: message.channelId,\n chatId: message.chatId,\n senderId: message.senderId,\n isGroup: message.platformData.isGroup,\n config: deps.config,\n bus: deps.bus,\n sessionStore: deps.sessionStore,\n \n // Reply handler\n replyHandler: async (text: string, options?) => {\n await deps.bus.publishOutbound({\n channel: routing.channel,\n chat_id: routing.chatId,\n content: text,\n type: 'message',\n metadata: {\n threadId: routing.threadId,\n parseMode: options?.parseMode,\n },\n });\n },\n\n // Typing handler\n typingHandler: async (typing: boolean) => {\n await deps.bus.publishOutbound({\n channel: routing.channel,\n chat_id: routing.chatId,\n type: typing ? 'typing_on' : 'typing_off',\n metadata: {\n threadId: routing.threadId,\n },\n });\n },\n\n // Supported features (would be determined by channel)\n supportedFeatures: ['markdown', 'typing'],\n\n // Model management\n getCurrentModel: deps.getCurrentModel,\n switchModel: deps.switchModel,\n listModels: deps.listModels,\n getUsage: deps.getUsage,\n });\n}\n"],"mappings":";;;;;;aAakD;AAGlD,MAAM,MAAM,aAAa,mBAAmB;;;;;AAiB5C,eAAsB,eACpB,SACA,MACkB;AAElB,KAAI,QAAQ,aAAa,QAAQ,YAC/B,QAAO,eAAe,SAAS,KAAK;AAItC,QAAO;;;;;AAMT,eAAe,eACb,SACA,MACkB;CAClB,MAAM,EAAE,aAAa,gBAAgB;AAErC,KAAI,CAAC,YAAa,QAAO;AAEzB,KAAI,KAAK;EAAE,SAAS;EAAa,YAAY,QAAQ;EAAY,EAAE,oBAAoB;CAGvF,MAAM,MAAM,MAAM,gCAAgC,SAAS,KAAK;CAGhE,MAAM,SAAS,MAAM,gBAAgB,QAAQ,aAAa,KAAK,eAAe,GAAG;AAGjF,KAAI,OAAO,SAAS;EAClB,MAAM,UAAU,eAAe,QAAQ,WAAW;AAClD,QAAM,KAAK,IAAI,gBAAgB;GAC7B,SAAS,QAAQ;GACjB,SAAS,QAAQ;GACjB,SAAS,OAAO;GAChB,MAAM;GACN,UAAU,EACR,UAAU,QAAQ,UACnB;GACF,CAAC;;AAGJ,QAAO;;;;;AAMT,eAAe,gCACb,SACA,MACyB;CACzB,MAAM,UAAU,eAAe,QAAQ,WAAW;AAElD,QAAO,qBAAqB;EAC1B,YAAY,QAAQ;EACpB,QAAQ,QAAQ;EAChB,WAAW,QAAQ;EACnB,QAAQ,QAAQ;EAChB,UAAU,QAAQ;EAClB,SAAS,QAAQ,aAAa;EAC9B,QAAQ,KAAK;EACb,KAAK,KAAK;EACV,cAAc,KAAK;EAGnB,cAAc,OAAO,MAAc,YAAa;AAC9C,SAAM,KAAK,IAAI,gBAAgB;IAC7B,SAAS,QAAQ;IACjB,SAAS,QAAQ;IACjB,SAAS;IACT,MAAM;IACN,UAAU;KACR,UAAU,QAAQ;KAClB,WAAW,SAAS;KACrB;IACF,CAAC;;EAIJ,eAAe,OAAO,WAAoB;AACxC,SAAM,KAAK,IAAI,gBAAgB;IAC7B,SAAS,QAAQ;IACjB,SAAS,QAAQ;IACjB,MAAM,SAAS,cAAc;IAC7B,UAAU,EACR,UAAU,QAAQ,UACnB;IACF,CAAC;;EAIJ,mBAAmB,CAAC,YAAY,SAAS;EAGzC,iBAAiB,KAAK;EACtB,aAAa,KAAK;EAClB,YAAY,KAAK;EACjB,UAAU,KAAK;EAChB,CAAC"}
1
+ {"version":3,"file":"processor.js","names":[],"sources":["../../../src/chat-commands/processor.ts"],"sourcesContent":["/**\n * Command Processor\n *\n * Integrates the command system with AgentService.\n * Processes incoming messages and routes commands appropriately.\n */\n\nimport type { UnifiedMessage, CommandContext } from './types.js';\nimport { commandRegistry } from './registry.js';\nimport { createCommandContext } from './context.js';\nimport type { MessageBus } from '../infra/bus/index.js';\nimport type { SessionStore } from '../session/index.js';\nimport type { Config } from '../config/schema.js';\nimport { createLogger } from '../utils/logger.js';\n\nconst log = createLogger('CommandProcessor');\n\nfunction commandOutboundMetadata(message: UnifiedMessage, extra?: Record<string, unknown>): Record<string, unknown> {\n return {\n accountId: message.platformData.accountId,\n threadId: message.platformData.threadId,\n ...extra,\n };\n}\n\nexport interface CommandProcessorDeps {\n bus: MessageBus;\n sessionStore: SessionStore;\n config: Config;\n // Model management callbacks\n getCurrentModel: () => string;\n switchModel: (modelId: string) => Promise<boolean>;\n listModels: () => Promise<Array<{ id: string; name: string; provider: string }>>;\n getUsage: () => Promise<{ promptTokens: number; completionTokens: number; totalTokens: number; messageCount: number }>;\n}\n\n/**\n * Process a unified message\n * Returns true if the message was handled (command or otherwise), false if should continue to AI\n */\nexport async function processMessage(\n message: UnifiedMessage,\n deps: CommandProcessorDeps\n): Promise<boolean> {\n // If it's a command, execute it\n if (message.isCommand && message.commandName) {\n return executeCommand(message, deps);\n }\n\n // Not a command, let AI handle it\n return false;\n}\n\n/**\n * Execute a command from a unified message\n */\nasync function executeCommand(\n message: UnifiedMessage,\n deps: CommandProcessorDeps\n): Promise<boolean> {\n const { commandName, commandArgs } = message;\n \n if (!commandName) return false;\n\n log.info({ command: commandName, sessionKey: message.sessionKey }, 'Executing command');\n\n // Create command context\n const ctx = await createCommandContextFromMessage(message, deps);\n\n // Execute command\n const result = await commandRegistry.execute(commandName, ctx, commandArgs || '');\n\n // Send response if there's content\n if (result.content) {\n await deps.bus.publishOutbound({\n channel: message.source,\n chat_id: message.chatId,\n content: result.content,\n type: 'message',\n metadata: commandOutboundMetadata(message),\n });\n }\n\n return true;\n}\n\n/**\n * Create a command context from a unified message\n */\nasync function createCommandContextFromMessage(\n message: UnifiedMessage,\n deps: CommandProcessorDeps\n): Promise<CommandContext> {\n return createCommandContext({\n sessionKey: message.sessionKey,\n source: message.source,\n channelId: message.channelId,\n chatId: message.chatId,\n senderId: message.senderId,\n isGroup: message.platformData.isGroup,\n accountId: message.platformData.accountId,\n threadId: message.platformData.threadId,\n config: deps.config,\n bus: deps.bus,\n sessionStore: deps.sessionStore,\n \n // Reply handler\n replyHandler: async (text: string, options?) => {\n await deps.bus.publishOutbound({\n channel: message.source,\n chat_id: message.chatId,\n content: text,\n type: 'message',\n metadata: commandOutboundMetadata(message, {\n parseMode: options?.parseMode,\n }),\n });\n },\n\n // Typing handler\n typingHandler: async (typing: boolean) => {\n await deps.bus.publishOutbound({\n channel: message.source,\n chat_id: message.chatId,\n type: typing ? 'typing_on' : 'typing_off',\n metadata: commandOutboundMetadata(message),\n });\n },\n\n // Supported features (would be determined by channel)\n supportedFeatures: ['markdown', 'typing'],\n\n // Model management\n getCurrentModel: deps.getCurrentModel,\n switchModel: deps.switchModel,\n listModels: deps.listModels,\n getUsage: deps.getUsage,\n });\n}\n"],"mappings":";;;;;aAakD;AAElD,MAAM,MAAM,aAAa,mBAAmB;AAE5C,SAAS,wBAAwB,SAAyB,OAA0D;AAClH,QAAO;EACL,WAAW,QAAQ,aAAa;EAChC,UAAU,QAAQ,aAAa;EAC/B,GAAG;EACJ;;;;;;AAkBH,eAAsB,eACpB,SACA,MACkB;AAElB,KAAI,QAAQ,aAAa,QAAQ,YAC/B,QAAO,eAAe,SAAS,KAAK;AAItC,QAAO;;;;;AAMT,eAAe,eACb,SACA,MACkB;CAClB,MAAM,EAAE,aAAa,gBAAgB;AAErC,KAAI,CAAC,YAAa,QAAO;AAEzB,KAAI,KAAK;EAAE,SAAS;EAAa,YAAY,QAAQ;EAAY,EAAE,oBAAoB;CAGvF,MAAM,MAAM,MAAM,gCAAgC,SAAS,KAAK;CAGhE,MAAM,SAAS,MAAM,gBAAgB,QAAQ,aAAa,KAAK,eAAe,GAAG;AAGjF,KAAI,OAAO,QACT,OAAM,KAAK,IAAI,gBAAgB;EAC7B,SAAS,QAAQ;EACjB,SAAS,QAAQ;EACjB,SAAS,OAAO;EAChB,MAAM;EACN,UAAU,wBAAwB,QAAQ;EAC3C,CAAC;AAGJ,QAAO;;;;;AAMT,eAAe,gCACb,SACA,MACyB;AACzB,QAAO,qBAAqB;EAC1B,YAAY,QAAQ;EACpB,QAAQ,QAAQ;EAChB,WAAW,QAAQ;EACnB,QAAQ,QAAQ;EAChB,UAAU,QAAQ;EAClB,SAAS,QAAQ,aAAa;EAC9B,WAAW,QAAQ,aAAa;EAChC,UAAU,QAAQ,aAAa;EAC/B,QAAQ,KAAK;EACb,KAAK,KAAK;EACV,cAAc,KAAK;EAGnB,cAAc,OAAO,MAAc,YAAa;AAC9C,SAAM,KAAK,IAAI,gBAAgB;IAC7B,SAAS,QAAQ;IACjB,SAAS,QAAQ;IACjB,SAAS;IACT,MAAM;IACN,UAAU,wBAAwB,SAAS,EACzC,WAAW,SAAS,WACrB,CAAC;IACH,CAAC;;EAIJ,eAAe,OAAO,WAAoB;AACxC,SAAM,KAAK,IAAI,gBAAgB;IAC7B,SAAS,QAAQ;IACjB,SAAS,QAAQ;IACjB,MAAM,SAAS,cAAc;IAC7B,UAAU,wBAAwB,QAAQ;IAC3C,CAAC;;EAIJ,mBAAmB,CAAC,YAAY,SAAS;EAGzC,iBAAiB,KAAK;EACtB,aAAa,KAAK;EAClB,YAAY,KAAK;EACjB,UAAU,KAAK;EAChB,CAAC"}
@@ -1,5 +1,7 @@
1
1
  /**
2
- * Session Key Generator — OpenClaw `agent:{agentId}:{rest}` format.
2
+ * Chat-command session display helpers.
3
+ *
4
+ * Session routing is resolved from SessionMetadata, not by parsing session keys.
3
5
  */
4
6
  import type { MessageSource } from './types.js';
5
7
  export interface SessionKeyContext {
@@ -16,18 +18,4 @@ export interface SessionKeyContext {
16
18
  identityLinks?: Record<string, string[]>;
17
19
  }
18
20
  export declare function generateSessionKey(ctx: SessionKeyContext): string;
19
- export declare function parseSessionKey(sessionKey: string): {
20
- source: MessageSource;
21
- type: 'dm' | 'group' | 'thread' | 'direct' | 'other';
22
- chatId: string;
23
- threadId?: string;
24
- agentId?: string;
25
- accountId?: string;
26
- };
27
- export declare function isValidSessionKey(sessionKey: string): boolean;
28
21
  export declare function getSessionDisplayName(sessionKey: string): string;
29
- export declare function getRoutingInfo(sessionKey: string): {
30
- channel: string;
31
- chatId: string;
32
- threadId?: string;
33
- };
@@ -1,5 +1,5 @@
1
1
  import { buildAgentMainSessionKey, buildAgentPeerSessionKey } from "../routing/agent-session-key.js";
2
- import { init_session_key, parseSessionKey as parseSessionKey$1 } from "../routing/session-key.js";
2
+ import { init_session_key } from "../routing/session-key.js";
3
3
  //#region src/chat-commands/session-key.ts
4
4
  init_session_key();
5
5
  function generateSessionKey(ctx) {
@@ -47,56 +47,10 @@ function generateSessionKey(ctx) {
47
47
  if (ctx.threadId) key = `${key}:thread:${ctx.threadId.toLowerCase()}`;
48
48
  return key;
49
49
  }
50
- function parseSessionKey(sessionKey) {
51
- const parsed = parseSessionKey$1(sessionKey);
52
- if (!parsed) return {
53
- source: "system",
54
- type: "other",
55
- chatId: "unknown"
56
- };
57
- let type;
58
- switch (parsed.peerKind) {
59
- case "dm":
60
- case "direct":
61
- type = parsed.peerKind === "direct" && parsed.peerId === "main" ? "direct" : "dm";
62
- break;
63
- case "group":
64
- case "channel":
65
- type = parsed.threadId ? "thread" : "group";
66
- break;
67
- default: type = "other";
68
- }
69
- return {
70
- source: parsed.source,
71
- type,
72
- chatId: parsed.peerId,
73
- threadId: parsed.threadId,
74
- agentId: parsed.agentId,
75
- accountId: parsed.accountId
76
- };
77
- }
78
- function isValidSessionKey(sessionKey) {
79
- return parseSessionKey$1(sessionKey) !== null;
80
- }
81
50
  function getSessionDisplayName(sessionKey) {
82
- const parsed = parseSessionKey(sessionKey);
83
- switch (parsed.type) {
84
- case "dm": return `Private Chat (${parsed.source})`;
85
- case "group": return `Group (${parsed.source})`;
86
- case "thread": return `Thread (${parsed.source})`;
87
- case "direct": return parsed.chatId === "main" ? "Main session" : `Direct (${parsed.source})`;
88
- default: return `${parsed.source}:${parsed.chatId}`;
89
- }
90
- }
91
- function getRoutingInfo(sessionKey) {
92
- const parsed = parseSessionKey(sessionKey);
93
- return {
94
- channel: parsed.source,
95
- chatId: parsed.chatId,
96
- threadId: parsed.threadId
97
- };
51
+ return sessionKey.trim() || "Session";
98
52
  }
99
53
  //#endregion
100
- export { generateSessionKey, getRoutingInfo, getSessionDisplayName, isValidSessionKey, parseSessionKey };
54
+ export { generateSessionKey, getSessionDisplayName };
101
55
 
102
56
  //# sourceMappingURL=session-key.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"session-key.js","names":["parseRoutingSessionKey"],"sources":["../../../src/chat-commands/session-key.ts"],"sourcesContent":["/**\n * Session Key Generator OpenClaw `agent:{agentId}:{rest}` format.\n */\n\nimport type { MessageSource } from './types.js';\nimport {\n buildAgentMainSessionKey,\n buildAgentPeerSessionKey,\n parseSessionKey as parseRoutingSessionKey,\n} from '../routing/session-key.js';\n\nexport interface SessionKeyContext {\n source: MessageSource;\n channelId?: string;\n chatId: string;\n senderId: string;\n isGroup: boolean;\n threadId?: string;\n agentId?: string;\n accountId?: string;\n mainKey?: string;\n dmScope?: 'main' | 'per-peer' | 'per-channel-peer' | 'per-account-channel-peer';\n identityLinks?: Record<string, string[]>;\n}\n\nexport function generateSessionKey(ctx: SessionKeyContext): string {\n const effectiveAgentId = ctx.agentId ?? 'main';\n const effectiveAccountId = ctx.accountId ?? 'default';\n const channel = ctx.source === 'webui' ? 'webchat' : ctx.source;\n\n if (ctx.source === 'cli') {\n if (ctx.chatId === 'direct' || ctx.chatId === 'main') {\n return buildAgentMainSessionKey({ agentId: effectiveAgentId, mainKey: ctx.mainKey });\n }\n return buildAgentPeerSessionKey({\n agentId: effectiveAgentId,\n mainKey: ctx.mainKey,\n channel: 'cli',\n accountId: effectiveAccountId,\n peerKind: 'direct',\n peerId: ctx.chatId,\n dmScope: 'per-peer',\n });\n }\n\n if (!ctx.isGroup) {\n const key = buildAgentPeerSessionKey({\n agentId: effectiveAgentId,\n mainKey: ctx.mainKey,\n channel,\n accountId: effectiveAccountId,\n peerKind: 'direct',\n peerId: ctx.senderId,\n identityLinks: ctx.identityLinks,\n dmScope: ctx.dmScope ?? 'per-account-channel-peer',\n });\n if (ctx.threadId) {\n return `${key}:thread:${ctx.threadId.toLowerCase()}`;\n }\n return key;\n }\n\n let key = buildAgentPeerSessionKey({\n agentId: effectiveAgentId,\n mainKey: ctx.mainKey,\n channel,\n accountId: effectiveAccountId,\n peerKind: 'group',\n peerId: ctx.chatId,\n identityLinks: ctx.identityLinks,\n });\n if (ctx.threadId) {\n key = `${key}:thread:${ctx.threadId.toLowerCase()}`;\n }\n return key;\n}\n\nexport function parseSessionKey(sessionKey: string): {\n source: MessageSource;\n type: 'dm' | 'group' | 'thread' | 'direct' | 'other';\n chatId: string;\n threadId?: string;\n agentId?: string;\n accountId?: string;\n} {\n const parsed = parseRoutingSessionKey(sessionKey);\n\n if (!parsed) {\n return {\n source: 'system',\n type: 'other',\n chatId: 'unknown',\n };\n }\n\n let type: 'dm' | 'group' | 'thread' | 'direct' | 'other';\n switch (parsed.peerKind) {\n case 'dm':\n case 'direct':\n type = parsed.peerKind === 'direct' && parsed.peerId === 'main' ? 'direct' : 'dm';\n break;\n case 'group':\n case 'channel':\n type = parsed.threadId ? 'thread' : 'group';\n break;\n default:\n type = 'other';\n }\n\n return {\n source: parsed.source as MessageSource,\n type,\n chatId: parsed.peerId,\n threadId: parsed.threadId,\n agentId: parsed.agentId,\n accountId: parsed.accountId,\n };\n}\n\nexport function isValidSessionKey(sessionKey: string): boolean {\n return parseRoutingSessionKey(sessionKey) !== null;\n}\n\nexport function getSessionDisplayName(sessionKey: string): string {\n const parsed = parseSessionKey(sessionKey);\n\n switch (parsed.type) {\n case 'dm':\n return `Private Chat (${parsed.source})`;\n case 'group':\n return `Group (${parsed.source})`;\n case 'thread':\n return `Thread (${parsed.source})`;\n case 'direct':\n return parsed.chatId === 'main' ? 'Main session' : `Direct (${parsed.source})`;\n default:\n return `${parsed.source}:${parsed.chatId}`;\n }\n}\n\nexport function getRoutingInfo(sessionKey: string): {\n channel: string;\n chatId: string;\n threadId?: string;\n} {\n const parsed = parseSessionKey(sessionKey);\n\n return {\n channel: parsed.source,\n chatId: parsed.chatId,\n threadId: parsed.threadId,\n };\n}\n"],"mappings":";;;kBASmC;AAgBnC,SAAgB,mBAAmB,KAAgC;CACjE,MAAM,mBAAmB,IAAI,WAAW;CACxC,MAAM,qBAAqB,IAAI,aAAa;CAC5C,MAAM,UAAU,IAAI,WAAW,UAAU,YAAY,IAAI;AAEzD,KAAI,IAAI,WAAW,OAAO;AACxB,MAAI,IAAI,WAAW,YAAY,IAAI,WAAW,OAC5C,QAAO,yBAAyB;GAAE,SAAS;GAAkB,SAAS,IAAI;GAAS,CAAC;AAEtF,SAAO,yBAAyB;GAC9B,SAAS;GACT,SAAS,IAAI;GACb,SAAS;GACT,WAAW;GACX,UAAU;GACV,QAAQ,IAAI;GACZ,SAAS;GACV,CAAC;;AAGJ,KAAI,CAAC,IAAI,SAAS;EAChB,MAAM,MAAM,yBAAyB;GACnC,SAAS;GACT,SAAS,IAAI;GACb;GACA,WAAW;GACX,UAAU;GACV,QAAQ,IAAI;GACZ,eAAe,IAAI;GACnB,SAAS,IAAI,WAAW;GACzB,CAAC;AACF,MAAI,IAAI,SACN,QAAO,GAAG,IAAI,UAAU,IAAI,SAAS,aAAa;AAEpD,SAAO;;CAGT,IAAI,MAAM,yBAAyB;EACjC,SAAS;EACT,SAAS,IAAI;EACb;EACA,WAAW;EACX,UAAU;EACV,QAAQ,IAAI;EACZ,eAAe,IAAI;EACpB,CAAC;AACF,KAAI,IAAI,SACN,OAAM,GAAG,IAAI,UAAU,IAAI,SAAS,aAAa;AAEnD,QAAO;;AAGT,SAAgB,gBAAgB,YAO9B;CACA,MAAM,SAASA,kBAAuB,WAAW;AAEjD,KAAI,CAAC,OACH,QAAO;EACL,QAAQ;EACR,MAAM;EACN,QAAQ;EACT;CAGH,IAAI;AACJ,SAAQ,OAAO,UAAf;EACE,KAAK;EACL,KAAK;AACH,UAAO,OAAO,aAAa,YAAY,OAAO,WAAW,SAAS,WAAW;AAC7E;EACF,KAAK;EACL,KAAK;AACH,UAAO,OAAO,WAAW,WAAW;AACpC;EACF,QACE,QAAO;;AAGX,QAAO;EACL,QAAQ,OAAO;EACf;EACA,QAAQ,OAAO;EACf,UAAU,OAAO;EACjB,SAAS,OAAO;EAChB,WAAW,OAAO;EACnB;;AAGH,SAAgB,kBAAkB,YAA6B;AAC7D,QAAOA,kBAAuB,WAAW,KAAK;;AAGhD,SAAgB,sBAAsB,YAA4B;CAChE,MAAM,SAAS,gBAAgB,WAAW;AAE1C,SAAQ,OAAO,MAAf;EACE,KAAK,KACH,QAAO,iBAAiB,OAAO,OAAO;EACxC,KAAK,QACH,QAAO,UAAU,OAAO,OAAO;EACjC,KAAK,SACH,QAAO,WAAW,OAAO,OAAO;EAClC,KAAK,SACH,QAAO,OAAO,WAAW,SAAS,iBAAiB,WAAW,OAAO,OAAO;EAC9E,QACE,QAAO,GAAG,OAAO,OAAO,GAAG,OAAO;;;AAIxC,SAAgB,eAAe,YAI7B;CACA,MAAM,SAAS,gBAAgB,WAAW;AAE1C,QAAO;EACL,SAAS,OAAO;EAChB,QAAQ,OAAO;EACf,UAAU,OAAO;EAClB"}
1
+ {"version":3,"file":"session-key.js","names":[],"sources":["../../../src/chat-commands/session-key.ts"],"sourcesContent":["/**\n * Chat-command session display helpers.\n *\n * Session routing is resolved from SessionMetadata, not by parsing session keys.\n */\n\nimport type { MessageSource } from './types.js';\nimport {\n buildAgentMainSessionKey,\n buildAgentPeerSessionKey,\n} from '../routing/session-key.js';\n\nexport interface SessionKeyContext {\n source: MessageSource;\n channelId?: string;\n chatId: string;\n senderId: string;\n isGroup: boolean;\n threadId?: string;\n agentId?: string;\n accountId?: string;\n mainKey?: string;\n dmScope?: 'main' | 'per-peer' | 'per-channel-peer' | 'per-account-channel-peer';\n identityLinks?: Record<string, string[]>;\n}\n\nexport function generateSessionKey(ctx: SessionKeyContext): string {\n const effectiveAgentId = ctx.agentId ?? 'main';\n const effectiveAccountId = ctx.accountId ?? 'default';\n const channel = ctx.source === 'webui' ? 'webchat' : ctx.source;\n\n if (ctx.source === 'cli') {\n if (ctx.chatId === 'direct' || ctx.chatId === 'main') {\n return buildAgentMainSessionKey({ agentId: effectiveAgentId, mainKey: ctx.mainKey });\n }\n return buildAgentPeerSessionKey({\n agentId: effectiveAgentId,\n mainKey: ctx.mainKey,\n channel: 'cli',\n accountId: effectiveAccountId,\n peerKind: 'direct',\n peerId: ctx.chatId,\n dmScope: 'per-peer',\n });\n }\n\n if (!ctx.isGroup) {\n const key = buildAgentPeerSessionKey({\n agentId: effectiveAgentId,\n mainKey: ctx.mainKey,\n channel,\n accountId: effectiveAccountId,\n peerKind: 'direct',\n peerId: ctx.senderId,\n identityLinks: ctx.identityLinks,\n dmScope: ctx.dmScope ?? 'per-account-channel-peer',\n });\n if (ctx.threadId) {\n return `${key}:thread:${ctx.threadId.toLowerCase()}`;\n }\n return key;\n }\n\n let key = buildAgentPeerSessionKey({\n agentId: effectiveAgentId,\n mainKey: ctx.mainKey,\n channel,\n accountId: effectiveAccountId,\n peerKind: 'group',\n peerId: ctx.chatId,\n identityLinks: ctx.identityLinks,\n });\n if (ctx.threadId) {\n key = `${key}:thread:${ctx.threadId.toLowerCase()}`;\n }\n return key;\n}\n\nexport function getSessionDisplayName(sessionKey: string): string {\n const trimmed = sessionKey.trim();\n return trimmed || 'Session';\n}\n"],"mappings":";;;kBAUmC;AAgBnC,SAAgB,mBAAmB,KAAgC;CACjE,MAAM,mBAAmB,IAAI,WAAW;CACxC,MAAM,qBAAqB,IAAI,aAAa;CAC5C,MAAM,UAAU,IAAI,WAAW,UAAU,YAAY,IAAI;AAEzD,KAAI,IAAI,WAAW,OAAO;AACxB,MAAI,IAAI,WAAW,YAAY,IAAI,WAAW,OAC5C,QAAO,yBAAyB;GAAE,SAAS;GAAkB,SAAS,IAAI;GAAS,CAAC;AAEtF,SAAO,yBAAyB;GAC9B,SAAS;GACT,SAAS,IAAI;GACb,SAAS;GACT,WAAW;GACX,UAAU;GACV,QAAQ,IAAI;GACZ,SAAS;GACV,CAAC;;AAGJ,KAAI,CAAC,IAAI,SAAS;EAChB,MAAM,MAAM,yBAAyB;GACnC,SAAS;GACT,SAAS,IAAI;GACb;GACA,WAAW;GACX,UAAU;GACV,QAAQ,IAAI;GACZ,eAAe,IAAI;GACnB,SAAS,IAAI,WAAW;GACzB,CAAC;AACF,MAAI,IAAI,SACN,QAAO,GAAG,IAAI,UAAU,IAAI,SAAS,aAAa;AAEpD,SAAO;;CAGT,IAAI,MAAM,yBAAyB;EACjC,SAAS;EACT,SAAS,IAAI;EACb;EACA,WAAW;EACX,UAAU;EACV,QAAQ,IAAI;EACZ,eAAe,IAAI;EACpB,CAAC;AACF,KAAI,IAAI,SACN,OAAM,GAAG,IAAI,UAAU,IAAI,SAAS,aAAa;AAEnD,QAAO;;AAGT,SAAgB,sBAAsB,YAA4B;AAEhE,QADgB,WAAW,MACb,IAAI"}
@@ -117,6 +117,10 @@ export interface CommandContext {
117
117
  senderId: string;
118
118
  /** Whether this is a group context */
119
119
  isGroup: boolean;
120
+ /** Account ID for multi-account channels, when supplied by routing metadata. */
121
+ accountId?: string;
122
+ /** Thread/topic ID for threaded channels, when supplied by routing metadata. */
123
+ threadId?: string;
120
124
  /** Bot configuration */
121
125
  config: Config;
122
126
  /** Send a text reply */
@@ -3,8 +3,8 @@ import { loadPlaywrightCoreModule } from "../../browser/providers/playwright-doc
3
3
  import { BrowserManager } from "../../browser/manager.js";
4
4
  import { resolveBrowserBackendFromConfig } from "../../browser/backend-from-config.js";
5
5
  import { createBrowserActionRegistry } from "../../browser/actions/registry.js";
6
- import { runBrowserPipeline, validateBrowserPipeline } from "../../browser/pipeline/runner.js";
7
6
  import { loadBrowserPipelineSource } from "../../browser/pipeline/source.js";
7
+ import { runBrowserPipeline, validateBrowserPipelineSource } from "../../browser/pipeline/runner.js";
8
8
  import "../../browser/index.js";
9
9
  //#region src/cli/commands/browser-cli-helpers.ts
10
10
  init_loader();
@@ -57,8 +57,11 @@ async function executeBrowserCliAction(action, args) {
57
57
  }
58
58
  async function validatePipelineCli(file) {
59
59
  let yamlSource;
60
+ let sourceLocation;
60
61
  try {
61
- yamlSource = (await loadBrowserPipelineSource(file)).source;
62
+ const loaded = await loadBrowserPipelineSource(file);
63
+ yamlSource = loaded.source;
64
+ sourceLocation = loaded.location;
62
65
  } catch (e) {
63
66
  const msg = e instanceof Error ? e.message : String(e);
64
67
  console.error(`Failed to read pipeline source: ${msg}`);
@@ -66,7 +69,7 @@ async function validatePipelineCli(file) {
66
69
  return;
67
70
  }
68
71
  const registry = createBrowserActionRegistry();
69
- const result = validateBrowserPipeline(yamlSource, registry);
72
+ const result = await validateBrowserPipelineSource(yamlSource, registry, sourceLocation);
70
73
  if (result.ok) console.log(`✓ Pipeline "${result.document.name}" is valid (${result.document.pipeline.length} steps).`);
71
74
  else {
72
75
  console.error("✗ Pipeline validation failed:");
@@ -76,8 +79,11 @@ async function validatePipelineCli(file) {
76
79
  }
77
80
  async function runPipelineCli(file, args) {
78
81
  let yamlSource;
82
+ let sourceLocation;
79
83
  try {
80
- yamlSource = (await loadBrowserPipelineSource(file)).source;
84
+ const loaded = await loadBrowserPipelineSource(file);
85
+ yamlSource = loaded.source;
86
+ sourceLocation = loaded.location;
81
87
  } catch (e) {
82
88
  const msg = e instanceof Error ? e.message : String(e);
83
89
  console.error(`Failed to read pipeline source: ${msg}`);
@@ -86,7 +92,7 @@ async function runPipelineCli(file, args) {
86
92
  }
87
93
  const registry = createBrowserActionRegistry();
88
94
  const ctx = await getActionContext();
89
- const result = await runBrowserPipeline(yamlSource, args, ctx, registry);
95
+ const result = await runBrowserPipeline(yamlSource, args, ctx, registry, { sourceLocation });
90
96
  if (result.ok) {
91
97
  if (result.text) console.log(result.text);
92
98
  if (result.data && !result.text) console.log(JSON.stringify(result.data, null, 2));
@@ -1 +1 @@
1
- {"version":3,"file":"browser-cli-helpers.js","names":[],"sources":["../../../../src/cli/commands/browser-cli-helpers.ts"],"sourcesContent":["/**\n * CLI helpers for `xopc browser` — shared runtime setup for CLI browser commands.\n */\n\nimport type { Page } from 'playwright-core';\n\nimport { BrowserManager, resolveBrowserBackendFromConfig, createBrowserActionRegistry } from '../../browser/index.js';\nimport { loadPlaywrightCoreModule } from '../../browser/providers/playwright-doctor.js';\nimport { validateBrowserPipeline, runBrowserPipeline } from '../../browser/pipeline/runner.js';\nimport { loadBrowserPipelineSource } from '../../browser/pipeline/source.js';\nimport type { BrowserActionContext } from '../../browser/actions/types.js';\nimport { loadConfig } from '../../config/loader.js';\n\nlet _manager: BrowserManager | null = null;\n/** When set, `xopc browser open --headless` overrides config for this CLI invocation. */\nlet browserCliHeadlessOverride: boolean | undefined;\n\nasync function getManager(): Promise<BrowserManager> {\n if (_manager) return _manager;\n const config = await loadConfig();\n _manager = new BrowserManager({\n getHeadless: () => {\n if (typeof browserCliHeadlessOverride === 'boolean') return browserCliHeadlessOverride;\n return config?.agents?.defaults?.browser?.headless === true;\n },\n getBackend: () => resolveBrowserBackendFromConfig(config),\n });\n return _manager;\n}\n\nasync function getActionContext(): Promise<BrowserActionContext> {\n const manager = await getManager();\n await manager.ensureConnected();\n const ext = manager.getExtensionProvider();\n const page: Page = ext ? (null as unknown as Page) : await manager.getPage('cli');\n const config = await loadConfig();\n return { page, manager, config, taskId: 'cli' };\n}\n\nexport async function executeBrowserCliAction(action: string, args: Record<string, unknown>): Promise<void> {\n const prevOverride = browserCliHeadlessOverride;\n if (typeof args.headless === 'boolean') {\n browserCliHeadlessOverride = args.headless;\n }\n try {\n const registry = createBrowserActionRegistry();\n const ctx = await getActionContext();\n\n const result = await registry.execute(action, ctx, args);\n\n if (result.ok) {\n if (result.text) console.log(result.text);\n if (result.data && !result.text) console.log(JSON.stringify(result.data, null, 2));\n } else {\n console.error(`[${result.error?.code}] ${result.error?.message}`);\n process.exitCode = 1;\n }\n\n // Close after non-persistent actions\n if (action === 'close') {\n await _manager?.shutdown();\n _manager = null;\n }\n } finally {\n browserCliHeadlessOverride = prevOverride;\n }\n}\n\nexport async function validatePipelineCli(file: string): Promise<void> {\n let yamlSource: string;\n try {\n yamlSource = (await loadBrowserPipelineSource(file)).source;\n } catch (e) {\n const msg = e instanceof Error ? e.message : String(e);\n console.error(`Failed to read pipeline source: ${msg}`);\n process.exitCode = 1;\n return;\n }\n\n const registry = createBrowserActionRegistry();\n const result = validateBrowserPipeline(yamlSource, registry);\n\n if (result.ok) {\n console.log(`✓ Pipeline \"${result.document!.name}\" is valid (${result.document!.pipeline.length} steps).`);\n } else {\n console.error('✗ Pipeline validation failed:');\n for (const err of result.errors) {\n console.error(` ${err.path}: ${err.message}`);\n }\n process.exitCode = 1;\n }\n}\n\nexport async function runPipelineCli(file: string, args: Record<string, unknown>): Promise<void> {\n let yamlSource: string;\n try {\n yamlSource = (await loadBrowserPipelineSource(file)).source;\n } catch (e) {\n const msg = e instanceof Error ? e.message : String(e);\n console.error(`Failed to read pipeline source: ${msg}`);\n process.exitCode = 1;\n return;\n }\n\n const registry = createBrowserActionRegistry();\n const ctx = await getActionContext();\n const result = await runBrowserPipeline(yamlSource, args, ctx, registry);\n\n if (result.ok) {\n if (result.text) console.log(result.text);\n if (result.data && !result.text) console.log(JSON.stringify(result.data, null, 2));\n } else {\n console.error(`Pipeline failed: [${result.error?.code}] ${result.error?.message}`);\n if (result.diagnostics?.snapshot) {\n console.error(`Snapshot:\\n${result.diagnostics.snapshot.slice(0, 2000)}`);\n }\n process.exitCode = 1;\n }\n\n await _manager?.shutdown();\n _manager = null;\n}\n\nexport async function doctorCli(): Promise<void> {\n console.log('Browser Doctor');\n console.log('──────────────');\n\n // Check playwright-core\n try {\n const pw = await loadPlaywrightCoreModule();\n const chromium = pw.chromium ?? (pw as any).default?.chromium;\n if (chromium) {\n console.log('✓ playwright-core installed');\n // Try to detect browsers\n const execPath = chromium.executablePath?.();\n if (execPath) {\n console.log(` Chromium path: ${execPath}`);\n } else {\n console.log(' ⚠ No default Chromium path detected. Run: npx playwright install chromium');\n }\n } else {\n console.log('✗ playwright-core chromium not available');\n }\n } catch {\n console.log('✗ playwright-core not installed');\n }\n\n // Check config\n try {\n const config = await loadConfig();\n const browser = config?.agents?.defaults?.browser;\n console.log(`\\nConfig:`);\n console.log(` enabled: ${browser?.enabled !== false}`);\n console.log(` headless: ${browser?.headless === true}`);\n console.log(` backend: ${browser?.backend ?? 'extension'}`);\n console.log(` provider: ${browser?.cloudProvider ?? 'local'}`);\n if (browser?.cdpUrl) console.log(` cdp: ${browser.cdpUrl}`);\n if (browser?.backend === 'extension' || browser?.extension) {\n const ext = browser?.extension;\n const port = ext?.port ?? 19820;\n const host = ext?.host ?? '127.0.0.1';\n console.log(`\\nExtension Bridge:`);\n console.log(` endpoint: ws://${host}:${port}/browser-ext`);\n try {\n const { browserExtDoctor } = await import('../../browser/providers/browser-ext-install.js');\n const artifacts = await browserExtDoctor();\n console.log(` artifacts: ${artifacts.installed ? '✓ installed' : '✗ not installed'}`);\n if (artifacts.extensionDir) console.log(` path: ${artifacts.extensionDir}`);\n if (artifacts.needsRefresh) console.log(` refresh: ⚠ bundled update available`);\n } catch {\n console.log(` artifacts: ⚠ could not check`);\n }\n // Try to ping the extension WS server\n try {\n const res = await fetch(`http://${host}:${port}/`);\n const data = await res.json() as { ok?: boolean; connected?: boolean };\n if (data.ok) {\n console.log(` server: ✓ running`);\n console.log(` extension: ${data.connected ? '✓ connected' : '⚠ waiting for connection'}`);\n }\n } catch {\n console.log(` server: ✗ not running (start xopc with backend: 'extension' to enable)`);\n }\n }\n } catch {\n console.log('\\n⚠ Could not load config');\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"browser-cli-helpers.js","names":[],"sources":["../../../../src/cli/commands/browser-cli-helpers.ts"],"sourcesContent":["/**\n * CLI helpers for `xopc browser` — shared runtime setup for CLI browser commands.\n */\n\nimport type { Page } from 'playwright-core';\n\nimport { BrowserManager, resolveBrowserBackendFromConfig, createBrowserActionRegistry } from '../../browser/index.js';\nimport { loadPlaywrightCoreModule } from '../../browser/providers/playwright-doctor.js';\nimport { runBrowserPipeline, validateBrowserPipelineSource } from '../../browser/pipeline/runner.js';\nimport { loadBrowserPipelineSource } from '../../browser/pipeline/source.js';\nimport type { BrowserActionContext } from '../../browser/actions/types.js';\nimport { loadConfig } from '../../config/loader.js';\n\nlet _manager: BrowserManager | null = null;\n/** When set, `xopc browser open --headless` overrides config for this CLI invocation. */\nlet browserCliHeadlessOverride: boolean | undefined;\n\nasync function getManager(): Promise<BrowserManager> {\n if (_manager) return _manager;\n const config = await loadConfig();\n _manager = new BrowserManager({\n getHeadless: () => {\n if (typeof browserCliHeadlessOverride === 'boolean') return browserCliHeadlessOverride;\n return config?.agents?.defaults?.browser?.headless === true;\n },\n getBackend: () => resolveBrowserBackendFromConfig(config),\n });\n return _manager;\n}\n\nasync function getActionContext(): Promise<BrowserActionContext> {\n const manager = await getManager();\n await manager.ensureConnected();\n const ext = manager.getExtensionProvider();\n const page: Page = ext ? (null as unknown as Page) : await manager.getPage('cli');\n const config = await loadConfig();\n return { page, manager, config, taskId: 'cli' };\n}\n\nexport async function executeBrowserCliAction(action: string, args: Record<string, unknown>): Promise<void> {\n const prevOverride = browserCliHeadlessOverride;\n if (typeof args.headless === 'boolean') {\n browserCliHeadlessOverride = args.headless;\n }\n try {\n const registry = createBrowserActionRegistry();\n const ctx = await getActionContext();\n\n const result = await registry.execute(action, ctx, args);\n\n if (result.ok) {\n if (result.text) console.log(result.text);\n if (result.data && !result.text) console.log(JSON.stringify(result.data, null, 2));\n } else {\n console.error(`[${result.error?.code}] ${result.error?.message}`);\n process.exitCode = 1;\n }\n\n // Close after non-persistent actions\n if (action === 'close') {\n await _manager?.shutdown();\n _manager = null;\n }\n } finally {\n browserCliHeadlessOverride = prevOverride;\n }\n}\n\nexport async function validatePipelineCli(file: string): Promise<void> {\n let yamlSource: string;\n let sourceLocation: string | undefined;\n try {\n const loaded = await loadBrowserPipelineSource(file);\n yamlSource = loaded.source;\n sourceLocation = loaded.location;\n } catch (e) {\n const msg = e instanceof Error ? e.message : String(e);\n console.error(`Failed to read pipeline source: ${msg}`);\n process.exitCode = 1;\n return;\n }\n\n const registry = createBrowserActionRegistry();\n const result = await validateBrowserPipelineSource(yamlSource, registry, sourceLocation);\n\n if (result.ok) {\n console.log(`✓ Pipeline \"${result.document!.name}\" is valid (${result.document!.pipeline.length} steps).`);\n } else {\n console.error('✗ Pipeline validation failed:');\n for (const err of result.errors) {\n console.error(` ${err.path}: ${err.message}`);\n }\n process.exitCode = 1;\n }\n}\n\nexport async function runPipelineCli(file: string, args: Record<string, unknown>): Promise<void> {\n let yamlSource: string;\n let sourceLocation: string | undefined;\n try {\n const loaded = await loadBrowserPipelineSource(file);\n yamlSource = loaded.source;\n sourceLocation = loaded.location;\n } catch (e) {\n const msg = e instanceof Error ? e.message : String(e);\n console.error(`Failed to read pipeline source: ${msg}`);\n process.exitCode = 1;\n return;\n }\n\n const registry = createBrowserActionRegistry();\n const ctx = await getActionContext();\n const result = await runBrowserPipeline(yamlSource, args, ctx, registry, { sourceLocation });\n\n if (result.ok) {\n if (result.text) console.log(result.text);\n if (result.data && !result.text) console.log(JSON.stringify(result.data, null, 2));\n } else {\n console.error(`Pipeline failed: [${result.error?.code}] ${result.error?.message}`);\n if (result.diagnostics?.snapshot) {\n console.error(`Snapshot:\\n${result.diagnostics.snapshot.slice(0, 2000)}`);\n }\n process.exitCode = 1;\n }\n\n await _manager?.shutdown();\n _manager = null;\n}\n\nexport async function doctorCli(): Promise<void> {\n console.log('Browser Doctor');\n console.log('──────────────');\n\n // Check playwright-core\n try {\n const pw = await loadPlaywrightCoreModule();\n const chromium = pw.chromium ?? (pw as any).default?.chromium;\n if (chromium) {\n console.log('✓ playwright-core installed');\n // Try to detect browsers\n const execPath = chromium.executablePath?.();\n if (execPath) {\n console.log(` Chromium path: ${execPath}`);\n } else {\n console.log(' ⚠ No default Chromium path detected. Run: npx playwright install chromium');\n }\n } else {\n console.log('✗ playwright-core chromium not available');\n }\n } catch {\n console.log('✗ playwright-core not installed');\n }\n\n // Check config\n try {\n const config = await loadConfig();\n const browser = config?.agents?.defaults?.browser;\n console.log(`\\nConfig:`);\n console.log(` enabled: ${browser?.enabled !== false}`);\n console.log(` headless: ${browser?.headless === true}`);\n console.log(` backend: ${browser?.backend ?? 'extension'}`);\n console.log(` provider: ${browser?.cloudProvider ?? 'local'}`);\n if (browser?.cdpUrl) console.log(` cdp: ${browser.cdpUrl}`);\n if (browser?.backend === 'extension' || browser?.extension) {\n const ext = browser?.extension;\n const port = ext?.port ?? 19820;\n const host = ext?.host ?? '127.0.0.1';\n console.log(`\\nExtension Bridge:`);\n console.log(` endpoint: ws://${host}:${port}/browser-ext`);\n try {\n const { browserExtDoctor } = await import('../../browser/providers/browser-ext-install.js');\n const artifacts = await browserExtDoctor();\n console.log(` artifacts: ${artifacts.installed ? '✓ installed' : '✗ not installed'}`);\n if (artifacts.extensionDir) console.log(` path: ${artifacts.extensionDir}`);\n if (artifacts.needsRefresh) console.log(` refresh: ⚠ bundled update available`);\n } catch {\n console.log(` artifacts: ⚠ could not check`);\n }\n // Try to ping the extension WS server\n try {\n const res = await fetch(`http://${host}:${port}/`);\n const data = await res.json() as { ok?: boolean; connected?: boolean };\n if (data.ok) {\n console.log(` server: ✓ running`);\n console.log(` extension: ${data.connected ? '✓ connected' : '⚠ waiting for connection'}`);\n }\n } catch {\n console.log(` server: ✗ not running (start xopc with backend: 'extension' to enable)`);\n }\n }\n } catch {\n console.log('\\n⚠ Could not load config');\n }\n}\n"],"mappings":"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"}
@@ -1,5 +1,5 @@
1
- import { init_write_file_atomic, writeTextAtomic } from "../../infra/write-file-atomic.js";
2
1
  import { ConfigSchema, init_schema } from "../../config/schema.js";
2
+ import { init_write_file_atomic, writeTextAtomic } from "../../infra/write-file-atomic.js";
3
3
  import { resolveGatewayLocalClientHost } from "../../config/gateway-bind.js";
4
4
  import { formatExamples, register } from "../registry.js";
5
5
  import { existsSync, readFileSync } from "fs";
@@ -1,4 +1,4 @@
1
- import { buildChannelCatalogForConfig, init_channel_catalog_service } from "../../../../channels/catalog/channel-catalog-service.js";
1
+ import { buildChannelCatalogForConfig, getChannelSetupStatus, init_channel_catalog_service } from "../../../../channels/catalog/channel-catalog-service.js";
2
2
  import { init_loader, loadConfig } from "../../../../config/loader.js";
3
3
  import { existsSync } from "node:fs";
4
4
  //#region src/cli/commands/doctor/checks/channel-config.ts
@@ -45,6 +45,19 @@ async function checkChannelConfig(ctx) {
45
45
  message: `Enabled channel(s) are not declared by installed extensions: ${unknownIds.join(", ")}.`,
46
46
  hints: ["Install or enable an extension that declares each channel contribution."]
47
47
  };
48
+ const notReady = enabledIds.map((id) => ({
49
+ id,
50
+ status: getChannelSetupStatus(cfg, id, catalog.byId.get(id))
51
+ })).filter((item) => !item.status.ready);
52
+ if (notReady.length > 0) return {
53
+ id: "channel-config",
54
+ label: "Channels",
55
+ status: "fail",
56
+ message: `Enabled channel(s) need setup before they can run: ${notReady.map((item) => item.id).join(", ")}.`,
57
+ hints: notReady.flatMap((item) => {
58
+ return item.status.issues.length > 0 ? item.status.issues.map((issue) => `${item.id}: ${issue.message}`) : [`${item.id}: complete the required channel setup or disable the channel.`];
59
+ })
60
+ };
48
61
  return {
49
62
  id: "channel-config",
50
63
  label: "Channels",
@@ -1 +1 @@
1
- {"version":3,"file":"channel-config.js","names":[],"sources":["../../../../../../src/cli/commands/doctor/checks/channel-config.ts"],"sourcesContent":["import { existsSync } from 'node:fs';\n\nimport { buildChannelCatalogForConfig } from '../../../../channels/catalog/channel-catalog-service.js';\nimport { loadConfig } from '../../../../config/loader.js';\nimport type { Config } from '../../../../config/schema.js';\nimport type { CheckResult, DoctorContext } from '../types.js';\n\nfunction isEnabledChannelConfig(value: unknown): value is { enabled: true } {\n return typeof value === 'object' && value !== null && !Array.isArray(value) && (value as { enabled?: unknown }).enabled === true;\n}\n\nexport async function checkChannelConfig(ctx: DoctorContext): Promise<CheckResult> {\n if (!existsSync(ctx.configPath)) {\n return {\n id: 'channel-config',\n label: 'Channels',\n status: 'skip',\n message: 'No config file; skipped.',\n hints: [],\n };\n }\n\n let cfg: Config;\n try {\n cfg = loadConfig(ctx.configPath);\n } catch {\n return {\n id: 'channel-config',\n label: 'Channels',\n status: 'skip',\n message: 'Config could not be loaded; skipped.',\n hints: [],\n };\n }\n\n const channels = cfg.channels as Record<string, unknown> | undefined;\n const enabledIds = Object.entries(channels ?? {})\n .filter(([, value]) => isEnabledChannelConfig(value))\n .map(([id]) => id);\n\n if (enabledIds.length === 0) {\n return {\n id: 'channel-config',\n label: 'Channels',\n status: 'skip',\n message: 'No channels enabled; skipped.',\n hints: [],\n };\n }\n\n const catalog = buildChannelCatalogForConfig(cfg);\n const unknownIds = enabledIds.filter((id) => !catalog.byId.has(id));\n if (unknownIds.length > 0) {\n return {\n id: 'channel-config',\n label: 'Channels',\n status: 'fail',\n message: `Enabled channel(s) are not declared by installed extensions: ${unknownIds.join(', ')}.`,\n hints: ['Install or enable an extension that declares each channel contribution.'],\n };\n }\n\n return {\n id: 'channel-config',\n label: 'Channels',\n status: 'pass',\n message: `Enabled channel configuration loaded for: ${enabledIds.join(', ')}.`,\n hints: [],\n };\n}\n"],"mappings":";;;;8BAEuG;aAC7C;AAI1D,SAAS,uBAAuB,OAA4C;AAC1E,QAAO,OAAO,UAAU,YAAY,UAAU,QAAQ,CAAC,MAAM,QAAQ,MAAM,IAAK,MAAgC,YAAY;;AAG9H,eAAsB,mBAAmB,KAA0C;AACjF,KAAI,CAAC,WAAW,IAAI,WAAW,CAC7B,QAAO;EACL,IAAI;EACJ,OAAO;EACP,QAAQ;EACR,SAAS;EACT,OAAO,EAAE;EACV;CAGH,IAAI;AACJ,KAAI;AACF,QAAM,WAAW,IAAI,WAAW;SAC1B;AACN,SAAO;GACL,IAAI;GACJ,OAAO;GACP,QAAQ;GACR,SAAS;GACT,OAAO,EAAE;GACV;;CAGH,MAAM,WAAW,IAAI;CACrB,MAAM,aAAa,OAAO,QAAQ,YAAY,EAAE,CAAC,CAC9C,QAAQ,GAAG,WAAW,uBAAuB,MAAM,CAAC,CACpD,KAAK,CAAC,QAAQ,GAAG;AAEpB,KAAI,WAAW,WAAW,EACxB,QAAO;EACL,IAAI;EACJ,OAAO;EACP,QAAQ;EACR,SAAS;EACT,OAAO,EAAE;EACV;CAGH,MAAM,UAAU,6BAA6B,IAAI;CACjD,MAAM,aAAa,WAAW,QAAQ,OAAO,CAAC,QAAQ,KAAK,IAAI,GAAG,CAAC;AACnE,KAAI,WAAW,SAAS,EACtB,QAAO;EACL,IAAI;EACJ,OAAO;EACP,QAAQ;EACR,SAAS,gEAAgE,WAAW,KAAK,KAAK,CAAC;EAC/F,OAAO,CAAC,0EAA0E;EACnF;AAGH,QAAO;EACL,IAAI;EACJ,OAAO;EACP,QAAQ;EACR,SAAS,6CAA6C,WAAW,KAAK,KAAK,CAAC;EAC5E,OAAO,EAAE;EACV"}
1
+ {"version":3,"file":"channel-config.js","names":[],"sources":["../../../../../../src/cli/commands/doctor/checks/channel-config.ts"],"sourcesContent":["import { existsSync } from 'node:fs';\n\nimport {\n buildChannelCatalogForConfig,\n getChannelSetupStatus,\n} from '../../../../channels/catalog/channel-catalog-service.js';\nimport { loadConfig } from '../../../../config/loader.js';\nimport type { Config } from '../../../../config/schema.js';\nimport type { CheckResult, DoctorContext } from '../types.js';\n\nfunction isEnabledChannelConfig(value: unknown): value is { enabled: true } {\n return typeof value === 'object' && value !== null && !Array.isArray(value) && (value as { enabled?: unknown }).enabled === true;\n}\n\nexport async function checkChannelConfig(ctx: DoctorContext): Promise<CheckResult> {\n if (!existsSync(ctx.configPath)) {\n return {\n id: 'channel-config',\n label: 'Channels',\n status: 'skip',\n message: 'No config file; skipped.',\n hints: [],\n };\n }\n\n let cfg: Config;\n try {\n cfg = loadConfig(ctx.configPath);\n } catch {\n return {\n id: 'channel-config',\n label: 'Channels',\n status: 'skip',\n message: 'Config could not be loaded; skipped.',\n hints: [],\n };\n }\n\n const channels = cfg.channels as Record<string, unknown> | undefined;\n const enabledIds = Object.entries(channels ?? {})\n .filter(([, value]) => isEnabledChannelConfig(value))\n .map(([id]) => id);\n\n if (enabledIds.length === 0) {\n return {\n id: 'channel-config',\n label: 'Channels',\n status: 'skip',\n message: 'No channels enabled; skipped.',\n hints: [],\n };\n }\n\n const catalog = buildChannelCatalogForConfig(cfg);\n const unknownIds = enabledIds.filter((id) => !catalog.byId.has(id));\n if (unknownIds.length > 0) {\n return {\n id: 'channel-config',\n label: 'Channels',\n status: 'fail',\n message: `Enabled channel(s) are not declared by installed extensions: ${unknownIds.join(', ')}.`,\n hints: ['Install or enable an extension that declares each channel contribution.'],\n };\n }\n\n const notReady = enabledIds\n .map((id) => ({ id, status: getChannelSetupStatus(cfg, id, catalog.byId.get(id)) }))\n .filter((item) => !item.status.ready);\n if (notReady.length > 0) {\n return {\n id: 'channel-config',\n label: 'Channels',\n status: 'fail',\n message: `Enabled channel(s) need setup before they can run: ${notReady.map((item) => item.id).join(', ')}.`,\n hints: notReady.flatMap((item) => {\n const issues = item.status.issues.length > 0\n ? item.status.issues.map((issue) => `${item.id}: ${issue.message}`)\n : [`${item.id}: complete the required channel setup or disable the channel.`];\n return issues;\n }),\n };\n }\n\n return {\n id: 'channel-config',\n label: 'Channels',\n status: 'pass',\n message: `Enabled channel configuration loaded for: ${enabledIds.join(', ')}.`,\n hints: [],\n };\n}\n"],"mappings":";;;;8BAKiE;aACP;AAI1D,SAAS,uBAAuB,OAA4C;AAC1E,QAAO,OAAO,UAAU,YAAY,UAAU,QAAQ,CAAC,MAAM,QAAQ,MAAM,IAAK,MAAgC,YAAY;;AAG9H,eAAsB,mBAAmB,KAA0C;AACjF,KAAI,CAAC,WAAW,IAAI,WAAW,CAC7B,QAAO;EACL,IAAI;EACJ,OAAO;EACP,QAAQ;EACR,SAAS;EACT,OAAO,EAAE;EACV;CAGH,IAAI;AACJ,KAAI;AACF,QAAM,WAAW,IAAI,WAAW;SAC1B;AACN,SAAO;GACL,IAAI;GACJ,OAAO;GACP,QAAQ;GACR,SAAS;GACT,OAAO,EAAE;GACV;;CAGH,MAAM,WAAW,IAAI;CACrB,MAAM,aAAa,OAAO,QAAQ,YAAY,EAAE,CAAC,CAC9C,QAAQ,GAAG,WAAW,uBAAuB,MAAM,CAAC,CACpD,KAAK,CAAC,QAAQ,GAAG;AAEpB,KAAI,WAAW,WAAW,EACxB,QAAO;EACL,IAAI;EACJ,OAAO;EACP,QAAQ;EACR,SAAS;EACT,OAAO,EAAE;EACV;CAGH,MAAM,UAAU,6BAA6B,IAAI;CACjD,MAAM,aAAa,WAAW,QAAQ,OAAO,CAAC,QAAQ,KAAK,IAAI,GAAG,CAAC;AACnE,KAAI,WAAW,SAAS,EACtB,QAAO;EACL,IAAI;EACJ,OAAO;EACP,QAAQ;EACR,SAAS,gEAAgE,WAAW,KAAK,KAAK,CAAC;EAC/F,OAAO,CAAC,0EAA0E;EACnF;CAGH,MAAM,WAAW,WACd,KAAK,QAAQ;EAAE;EAAI,QAAQ,sBAAsB,KAAK,IAAI,QAAQ,KAAK,IAAI,GAAG,CAAC;EAAE,EAAE,CACnF,QAAQ,SAAS,CAAC,KAAK,OAAO,MAAM;AACvC,KAAI,SAAS,SAAS,EACpB,QAAO;EACL,IAAI;EACJ,OAAO;EACP,QAAQ;EACR,SAAS,sDAAsD,SAAS,KAAK,SAAS,KAAK,GAAG,CAAC,KAAK,KAAK,CAAC;EAC1G,OAAO,SAAS,SAAS,SAAS;AAIhC,UAHe,KAAK,OAAO,OAAO,SAAS,IACvC,KAAK,OAAO,OAAO,KAAK,UAAU,GAAG,KAAK,GAAG,IAAI,MAAM,UAAU,GACjE,CAAC,GAAG,KAAK,GAAG,+DAA+D;IAE/E;EACH;AAGH,QAAO;EACL,IAAI;EACJ,OAAO;EACP,QAAQ;EACR,SAAS,6CAA6C,WAAW,KAAK,KAAK,CAAC;EAC5E,OAAO,EAAE;EACV"}
@@ -1,7 +1,7 @@
1
1
  import { ConfigSchema, init_schema } from "../../../../config/schema.js";
2
2
  import { init_loader, loadConfig, saveConfig } from "../../../../config/loader.js";
3
- import { existsSync, mkdirSync, readFileSync } from "node:fs";
4
3
  import { dirname } from "node:path";
4
+ import { existsSync, mkdirSync, readFileSync } from "node:fs";
5
5
  //#region src/cli/commands/doctor/checks/config-health.ts
6
6
  init_loader();
7
7
  init_schema();
@@ -52,7 +52,7 @@ async function checkDatabaseSchema(ctx) {
52
52
  id: "database-schema",
53
53
  label: "Database schema",
54
54
  status: "pass",
55
- message: `SQLite schema v${status.dbVersion} (current release v9).`,
55
+ message: `SQLite schema v${status.dbVersion} (current release v10).`,
56
56
  hints: []
57
57
  };
58
58
  }
@@ -1,6 +1,6 @@
1
- import { PROVIDER_ENV_MAP, getApiKeyFromEnv, init_env_keys } from "../../../../providers/env-keys.js";
2
1
  import { getAgentDefaultModelRef, init_schema, parseModelRef } from "../../../../config/schema.js";
3
2
  import { init_loader, loadConfig } from "../../../../config/loader.js";
3
+ import { PROVIDER_ENV_MAP, getApiKeyFromEnv, init_env_keys } from "../../../../providers/env-keys.js";
4
4
  import { existsSync } from "node:fs";
5
5
  //#region src/cli/commands/doctor/checks/provider-auth.ts
6
6
  init_loader();