@xopcai/xopc 0.0.103 → 0.0.104

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 (930) hide show
  1. package/README.md +7 -4
  2. package/README.zh-CN.md +7 -4
  3. package/dist/_virtual/_rolldown/runtime.js +2 -3
  4. package/dist/browser-ext/manifest.json +1 -1
  5. package/dist/extensions/feishu/src/adapters/cli-login.d.ts +1 -1
  6. package/dist/extensions/feishu/src/adapters/cli-login.js +1 -1
  7. package/dist/extensions/feishu/src/adapters/cli-login.js.map +1 -1
  8. package/dist/extensions/feishu/src/adapters/gateway-setup.d.ts +2 -0
  9. package/dist/extensions/feishu/src/adapters/gateway-setup.js +225 -0
  10. package/dist/extensions/feishu/src/adapters/gateway-setup.js.map +1 -0
  11. package/dist/extensions/feishu/src/index.d.ts +8 -1
  12. package/dist/extensions/feishu/src/index.js +14 -1
  13. package/dist/extensions/feishu/src/index.js.map +1 -0
  14. package/dist/extensions/feishu/src/outbound/outbound-adapter.js +1 -1
  15. package/dist/extensions/feishu/src/plugin.d.ts +2 -1
  16. package/dist/extensions/feishu/src/plugin.js +2 -0
  17. package/dist/extensions/feishu/src/plugin.js.map +1 -1
  18. package/dist/extensions/feishu/src/streaming/streaming-adapter.js +1 -1
  19. package/dist/extensions/feishu/src/transport/webhook/monitor.js +1 -1
  20. package/dist/extensions/feishu/xopc.extension.json +66 -1
  21. package/dist/extensions/telegram/src/adapters/gateway-setup.d.ts +2 -0
  22. package/dist/extensions/telegram/src/adapters/gateway-setup.js +146 -0
  23. package/dist/extensions/telegram/src/adapters/gateway-setup.js.map +1 -0
  24. package/dist/extensions/telegram/src/adapters/security-adapter.js +1 -1
  25. package/dist/extensions/telegram/src/command-handler.js +1 -2
  26. package/dist/extensions/telegram/src/command-handler.js.map +1 -1
  27. package/dist/extensions/telegram/src/config-schema.js +2 -2
  28. package/dist/extensions/telegram/src/config-schema.js.map +1 -1
  29. package/dist/extensions/telegram/src/doctor.d.ts +1 -0
  30. package/dist/extensions/telegram/src/doctor.js +68 -0
  31. package/dist/extensions/telegram/src/doctor.js.map +1 -1
  32. package/dist/extensions/telegram/src/index.d.ts +8 -1
  33. package/dist/extensions/telegram/src/index.js +15 -2
  34. package/dist/extensions/telegram/src/index.js.map +1 -0
  35. package/dist/extensions/telegram/src/plugin.d.ts +13 -5
  36. package/dist/extensions/telegram/src/plugin.js +32 -12
  37. package/dist/extensions/telegram/src/plugin.js.map +1 -1
  38. package/dist/extensions/telegram/src/proxy-fetch.js +22 -5
  39. package/dist/extensions/telegram/src/proxy-fetch.js.map +1 -1
  40. package/dist/extensions/telegram/xopc.extension.json +412 -5
  41. package/dist/extensions/weixin/src/adapters/onboard-cli.js +2 -2
  42. package/dist/extensions/weixin/src/adapters/onboard-cli.js.map +1 -1
  43. package/dist/extensions/weixin/src/api/api.js +1 -1
  44. package/dist/extensions/weixin/src/index.d.ts +8 -0
  45. package/dist/extensions/weixin/src/index.js +12 -1
  46. package/dist/extensions/weixin/src/index.js.map +1 -0
  47. package/dist/extensions/weixin/src/messaging/process-message.js +1 -1
  48. package/dist/extensions/weixin/src/plugin.d.ts +2 -1
  49. package/dist/extensions/weixin/src/plugin.js +77 -2
  50. package/dist/extensions/weixin/src/plugin.js.map +1 -1
  51. package/dist/extensions/weixin/xopc.extension.json +52 -0
  52. package/dist/gateway/static/root/assets/agents-CvsBrBfi.js +396 -0
  53. package/dist/gateway/static/root/assets/{apps-page-C5RmwmTT.js → apps-page-L-IwQTe0.js} +1 -1
  54. package/dist/gateway/static/root/assets/browser-BLJWD7WI.js +8 -0
  55. package/dist/gateway/static/root/assets/channels-settings-D95KuPeP.js +1 -0
  56. package/dist/gateway/static/root/assets/cron-page-CfkWXDAI.js +1 -0
  57. package/dist/gateway/static/root/assets/{dist-CWm8hTXZ.js → dist-C6vclgEL.js} +1 -1
  58. package/dist/gateway/static/root/assets/{extension-debug-page-BzYgTkS9.js → extension-debug-page-D4JYAbsX.js} +1 -1
  59. package/dist/gateway/static/root/assets/{extension-page-BmTZH6gL.js → extension-page-_T62gi6e.js} +1 -1
  60. package/dist/gateway/static/root/assets/extension-settings-page-CkJbjyM-.js +1 -0
  61. package/dist/gateway/static/root/assets/{fetch-CMoWY2Si.js → fetch-B5aiIguv.js} +1 -1
  62. package/dist/gateway/static/root/assets/gateway-startup-retry-DqmLXhs6.js +1 -0
  63. package/dist/gateway/static/root/assets/heartbeat-config-api-HwJV1K_Y.js +1 -0
  64. package/dist/gateway/static/root/assets/index-BPYKW7FB.css +1 -0
  65. package/dist/gateway/static/root/assets/index-DvTb6wNR.js +4845 -0
  66. package/dist/gateway/static/root/assets/{logs-page-BjdQjHwk.js → logs-page-DsjtTjBy.js} +2 -2
  67. package/dist/gateway/static/root/assets/{note-detail-page-8Er4197b.js → note-detail-page-B2V7RhgD.js} +43 -43
  68. package/dist/gateway/static/root/assets/{note-time-CF3vf1jm.js → note-time-BG8GCTr4.js} +1 -1
  69. package/dist/gateway/static/root/assets/notes-page-xrcVBQ6Z.js +1 -0
  70. package/dist/gateway/static/root/assets/schema-form-S-QUvhul.js +1 -0
  71. package/dist/gateway/static/root/assets/sessions-page-CrQer6Au.js +1 -0
  72. package/dist/gateway/static/root/assets/settings-advanced-gate-DujQl9c7.js +2 -0
  73. package/dist/gateway/static/root/assets/{settings-form-section-C7qA7y0J.js → settings-form-section-r1V7dRV6.js} +1 -1
  74. package/dist/gateway/static/root/assets/settings-page-C9nrONQ2.js +3 -0
  75. package/dist/gateway/static/root/assets/{share-preview-page-Tvr5Mtq5.js → share-preview-page-DOFy0FNt.js} +1 -1
  76. package/dist/gateway/static/root/assets/skills-page-DmTsrs_a.js +2 -0
  77. package/dist/gateway/static/root/assets/{theme-store-HTvJlFLL.js → theme-store-Bo3j5Ovv.js} +1 -1
  78. package/dist/gateway/static/root/assets/url-WgQIjFZu.js +3 -0
  79. package/dist/gateway/static/root/assets/voice-api-key-field-AjmUAlEQ.js +1 -0
  80. package/dist/gateway/static/root/assets/{workflow-page.utils-CeBkAjP7.js → workflow-page.utils-DLEJ92gK.js} +1 -1
  81. package/dist/gateway/static/root/assets/workflows-page-BnjjKrM1.js +27 -0
  82. package/dist/gateway/static/root/index.html +6 -5
  83. package/dist/package.js +1 -1
  84. package/dist/src/agent/agent-manager.d.ts +18 -6
  85. package/dist/src/agent/agent-manager.js +60 -35
  86. package/dist/src/agent/agent-manager.js.map +1 -1
  87. package/dist/src/agent/builtin-agent-ids.d.ts +2 -0
  88. package/dist/src/agent/builtin-agent-ids.js +17 -0
  89. package/dist/src/agent/builtin-agent-ids.js.map +1 -0
  90. package/dist/src/agent/child-agent-factory.d.ts +4 -0
  91. package/dist/src/agent/child-agent-factory.js +28 -8
  92. package/dist/src/agent/child-agent-factory.js.map +1 -1
  93. package/dist/src/agent/context/workspace-seed.js +1 -1
  94. package/dist/src/agent/context/workspace-templates/AGENTS.md +23 -184
  95. package/dist/src/agent/embedded/run-turn.js +8 -2
  96. package/dist/src/agent/embedded/run-turn.js.map +1 -1
  97. package/dist/src/agent/embedded/session-tool-result-guard.js +1 -1
  98. package/dist/src/agent/embedded/subscribe-session.js +33 -51
  99. package/dist/src/agent/embedded/subscribe-session.js.map +1 -1
  100. package/dist/src/agent/embedded/types.d.ts +36 -35
  101. package/dist/src/agent/fallback/candidates.js +1 -1
  102. package/dist/src/agent/fallback/candidates.js.map +1 -1
  103. package/dist/src/agent/inbound/inbound-loop.js +1 -1
  104. package/dist/src/agent/inbound/turn-dispatcher.d.ts +1 -0
  105. package/dist/src/agent/inbound/turn-dispatcher.js +24 -5
  106. package/dist/src/agent/inbound/turn-dispatcher.js.map +1 -1
  107. package/dist/src/agent/models/manager.d.ts +1 -1
  108. package/dist/src/agent/models/manager.js +1 -1
  109. package/dist/src/agent/models/manager.js.map +1 -1
  110. package/dist/src/agent/orchestration/run-agent-turn-with-fallbacks.d.ts +1 -1
  111. package/dist/src/agent/orchestration/run-agent-turn-with-fallbacks.js +1 -1
  112. package/dist/src/agent/orchestration/run-agent-turn-with-fallbacks.js.map +1 -1
  113. package/dist/src/agent/prompt/sections/tooling.js +4 -0
  114. package/dist/src/agent/prompt/sections/tooling.js.map +1 -1
  115. package/dist/src/agent/service/direct-turn-helpers.d.ts +1 -0
  116. package/dist/src/agent/service/direct-turn-helpers.js +1 -1
  117. package/dist/src/agent/service/direct-turn-helpers.js.map +1 -1
  118. package/dist/src/agent/service/process-direct-streaming.d.ts +1 -0
  119. package/dist/src/agent/service/process-direct-streaming.js +35 -18
  120. package/dist/src/agent/service/process-direct-streaming.js.map +1 -1
  121. package/dist/src/agent/service-inbound-utils.d.ts +0 -1
  122. package/dist/src/agent/service-inbound-utils.js +1 -17
  123. package/dist/src/agent/service-inbound-utils.js.map +1 -1
  124. package/dist/src/agent/service.d.ts +4 -4
  125. package/dist/src/agent/service.js +27 -15
  126. package/dist/src/agent/service.js.map +1 -1
  127. package/dist/src/agent/session/session-config-service.d.ts +1 -0
  128. package/dist/src/agent/session/session-config-service.js +9 -1
  129. package/dist/src/agent/session/session-config-service.js.map +1 -1
  130. package/dist/src/agent/session/session-inspector.d.ts +2 -1
  131. package/dist/src/agent/session/session-inspector.js +4 -0
  132. package/dist/src/agent/session/session-inspector.js.map +1 -1
  133. package/dist/src/agent/skills/config.js +1 -3
  134. package/dist/src/agent/skills/config.js.map +1 -1
  135. package/dist/src/agent/skills/format-skills-prompt.d.ts +1 -0
  136. package/dist/src/agent/skills/format-skills-prompt.js +3 -2
  137. package/dist/src/agent/skills/format-skills-prompt.js.map +1 -1
  138. package/dist/src/agent/skills/hub-pull.js +1 -1
  139. package/dist/src/agent/skills/index.js +20 -5
  140. package/dist/src/agent/skills/index.js.map +1 -1
  141. package/dist/src/agent/skills/installer.js +14 -27
  142. package/dist/src/agent/skills/installer.js.map +1 -1
  143. package/dist/src/agent/skills/marketplace/adapters/clawhub/adapter.js +11 -1
  144. package/dist/src/agent/skills/marketplace/adapters/clawhub/adapter.js.map +1 -1
  145. package/dist/src/agent/skills/marketplace/adapters/skillhub/adapter.js +18 -4
  146. package/dist/src/agent/skills/marketplace/adapters/skillhub/adapter.js.map +1 -1
  147. package/dist/src/agent/skills/marketplace/adapters/store/adapter.js +11 -2
  148. package/dist/src/agent/skills/marketplace/adapters/store/adapter.js.map +1 -1
  149. package/dist/src/agent/skills/marketplace/adapters/store/store-api-client.d.ts +2 -2
  150. package/dist/src/agent/skills/marketplace/adapters/store/store-api-client.js.map +1 -1
  151. package/dist/src/agent/skills/skill-manager.d.ts +4 -1
  152. package/dist/src/agent/skills/skill-manager.js +3 -3
  153. package/dist/src/agent/skills/skill-manager.js.map +1 -1
  154. package/dist/src/agent/skills/skill-view-path.d.ts +1 -17
  155. package/dist/src/agent/skills/skill-view-path.js +3 -66
  156. package/dist/src/agent/skills/skill-view-path.js.map +1 -1
  157. package/dist/src/agent/skills/test-framework.js +2 -3
  158. package/dist/src/agent/skills/test-framework.js.map +1 -1
  159. package/dist/src/agent/streaming/reasoning-visibility-sse.js +1 -0
  160. package/dist/src/agent/streaming/reasoning-visibility-sse.js.map +1 -1
  161. package/dist/src/agent/tool-manuals/browser.d.ts +1 -0
  162. package/{skills/browser/SKILL.md → dist/src/agent/tool-manuals/browser.js} +51 -54
  163. package/dist/src/agent/tool-manuals/browser.js.map +1 -0
  164. package/dist/src/agent/tool-manuals/index.d.ts +10 -0
  165. package/dist/src/agent/tool-manuals/index.js +28 -0
  166. package/dist/src/agent/tool-manuals/index.js.map +1 -0
  167. package/dist/src/agent/tools/browser/tool/browser-use-tool.js +1 -1
  168. package/dist/src/agent/tools/browser/tool/browser-use-tool.js.map +1 -1
  169. package/dist/src/agent/tools/factory.js +7 -5
  170. package/dist/src/agent/tools/factory.js.map +1 -1
  171. package/dist/src/agent/tools/index.d.ts +1 -0
  172. package/dist/src/agent/tools/index.js +5 -4
  173. package/dist/src/agent/tools/session-search-tool.js +1 -1
  174. package/dist/src/agent/tools/shell.js +1 -1
  175. package/dist/src/agent/tools/skills-tools.js +37 -8
  176. package/dist/src/agent/tools/skills-tools.js.map +1 -1
  177. package/dist/src/agent/tools/tool-manual-tool.d.ts +6 -0
  178. package/dist/src/agent/tools/tool-manual-tool.js +34 -0
  179. package/dist/src/agent/tools/tool-manual-tool.js.map +1 -0
  180. package/dist/src/agent/tools/web-extract.js +2 -2
  181. package/dist/src/agent/tools/web.js +1 -1
  182. package/dist/src/agent/workflow/catalog.d.ts +7 -2
  183. package/dist/src/agent/workflow/catalog.js +66 -25
  184. package/dist/src/agent/workflow/catalog.js.map +1 -1
  185. package/dist/src/agent/workflow/subagent-runner.d.ts +3 -0
  186. package/dist/src/agent/workflow/subagent-runner.js +50 -4
  187. package/dist/src/agent/workflow/subagent-runner.js.map +1 -1
  188. package/dist/src/agent/workflow/types.d.ts +10 -0
  189. package/dist/src/auth/credentials.js +10 -5
  190. package/dist/src/auth/credentials.js.map +1 -1
  191. package/dist/src/browser/actions/extension-registry-bridge.js +1 -1
  192. package/dist/src/browser/actions/registry.js +2 -2
  193. package/dist/src/browser/cdp-local-launcher.js +1 -1
  194. package/dist/src/browser/index.js +3 -3
  195. package/dist/src/browser/providers/browser-ext-install.js +1 -1
  196. package/dist/src/browser/providers/cloakbrowser.js +1 -1
  197. package/dist/src/channels/catalog/channel-catalog-service.d.ts +11 -0
  198. package/dist/src/channels/catalog/channel-catalog-service.js +168 -0
  199. package/dist/src/channels/catalog/channel-catalog-service.js.map +1 -0
  200. package/dist/src/channels/catalog/channel-catalog-types.d.ts +22 -0
  201. package/dist/src/channels/catalog/channel-catalog-types.js +1 -0
  202. package/dist/src/channels/dock.d.ts +0 -7
  203. package/dist/src/channels/dock.js +1 -21
  204. package/dist/src/channels/index.d.ts +1 -3
  205. package/dist/src/channels/index.js +1 -5
  206. package/dist/src/channels/lifecycle-supervisor.d.ts +1 -0
  207. package/dist/src/channels/lifecycle-supervisor.js +11 -0
  208. package/dist/src/channels/lifecycle-supervisor.js.map +1 -1
  209. package/dist/src/channels/manager.d.ts +1 -0
  210. package/dist/src/channels/manager.js +3 -0
  211. package/dist/src/channels/manager.js.map +1 -1
  212. package/dist/src/channels/pairing/pairing-channel.d.ts +2 -3
  213. package/dist/src/channels/pairing/pairing-messages.js +1 -1
  214. package/dist/src/channels/pairing/pairing-messages.js.map +1 -1
  215. package/dist/src/channels/pairing/pairing-service.d.ts +1 -1
  216. package/dist/src/channels/pairing/pairing-service.js +8 -27
  217. package/dist/src/channels/pairing/pairing-service.js.map +1 -1
  218. package/dist/src/channels/plugin-types.d.ts +3 -1
  219. package/dist/src/channels/plugins/types.adapters.d.ts +55 -2
  220. package/dist/src/channels/telegram/index.js +1 -1
  221. package/dist/src/chat-commands/builtins/config.js +4 -4
  222. package/dist/src/chat-commands/builtins/config.js.map +1 -1
  223. package/dist/src/chat-commands/config-paths.js +1 -1
  224. package/dist/src/chat-commands/config-paths.js.map +1 -1
  225. package/dist/src/chat-commands/context.js +1 -1
  226. package/dist/src/chat-commands/context.js.map +1 -1
  227. package/dist/src/cli/bin.js +1 -1
  228. package/dist/src/cli/command-manifest.js +1 -1
  229. package/dist/src/cli/command-manifest.js.map +1 -1
  230. package/dist/src/cli/commands/agent.js +2 -2
  231. package/dist/src/cli/commands/agent.js.map +1 -1
  232. package/dist/src/cli/commands/agents.js +2 -4
  233. package/dist/src/cli/commands/agents.js.map +1 -1
  234. package/dist/src/cli/commands/auth.js +1 -1
  235. package/dist/src/cli/commands/browser-cli-helpers.js +1 -1
  236. package/dist/src/cli/commands/channels.d.ts +1 -5
  237. package/dist/src/cli/commands/channels.js +115 -281
  238. package/dist/src/cli/commands/channels.js.map +1 -1
  239. package/dist/src/cli/commands/config.js +2 -2
  240. package/dist/src/cli/commands/config.js.map +1 -1
  241. package/dist/src/cli/commands/doctor/checks/channel-config.js +16 -69
  242. package/dist/src/cli/commands/doctor/checks/channel-config.js.map +1 -1
  243. package/dist/src/cli/commands/doctor/checks/channel-pairing-pending.js +6 -4
  244. package/dist/src/cli/commands/doctor/checks/channel-pairing-pending.js.map +1 -1
  245. package/dist/src/cli/commands/doctor/checks/channel-plugins.js +2 -2
  246. package/dist/src/cli/commands/doctor/checks/channel-plugins.js.map +1 -1
  247. package/dist/src/cli/commands/doctor/checks/database-schema.js +1 -1
  248. package/dist/src/cli/commands/doctor/checks/provider-auth.js +13 -9
  249. package/dist/src/cli/commands/doctor/checks/provider-auth.js.map +1 -1
  250. package/dist/src/cli/commands/extension-dev.js +2 -1
  251. package/dist/src/cli/commands/extension-dev.js.map +1 -1
  252. package/dist/src/cli/commands/extension-marketplace.js +2 -1
  253. package/dist/src/cli/commands/extension-marketplace.js.map +1 -1
  254. package/dist/src/cli/commands/extension-pack.js +2 -1
  255. package/dist/src/cli/commands/extension-pack.js.map +1 -1
  256. package/dist/src/cli/commands/models.js +7 -4
  257. package/dist/src/cli/commands/models.js.map +1 -1
  258. package/dist/src/cli/commands/onboard/channels/index.js +1 -1
  259. package/dist/src/cli/commands/onboard/channels/index.js.map +1 -1
  260. package/dist/src/cli/commands/onboard/channels/registry.d.ts +2 -1
  261. package/dist/src/cli/commands/onboard/channels/registry.js +32 -8
  262. package/dist/src/cli/commands/onboard/channels/registry.js.map +1 -1
  263. package/dist/src/cli/commands/onboard/model.js +8 -5
  264. package/dist/src/cli/commands/onboard/model.js.map +1 -1
  265. package/dist/src/cli/commands/onboard.js +4 -6
  266. package/dist/src/cli/commands/onboard.js.map +1 -1
  267. package/dist/src/cli/commands/setup-shared/runner.d.ts +1 -1
  268. package/dist/src/cli/commands/setup-shared/runner.js.map +1 -1
  269. package/dist/src/cli/commands/setup-shared/types.d.ts +1 -1
  270. package/dist/src/cli/commands/setup-shared/types.js.map +1 -1
  271. package/dist/src/cli/commands/tui.js +13 -5
  272. package/dist/src/cli/commands/tui.js.map +1 -1
  273. package/dist/src/cli/extension-cli-register.js +1 -1
  274. package/dist/src/commands/agents.config.d.ts +3 -3
  275. package/dist/src/commands/agents.config.js +7 -7
  276. package/dist/src/commands/agents.config.js.map +1 -1
  277. package/dist/src/config/agent-profile.d.ts +1 -1
  278. package/dist/src/config/agent-profile.js +6 -2
  279. package/dist/src/config/agent-profile.js.map +1 -1
  280. package/dist/src/config/agent-typed-models.d.ts +2 -2
  281. package/dist/src/config/agent-typed-models.js +13 -2
  282. package/dist/src/config/agent-typed-models.js.map +1 -1
  283. package/dist/src/config/index.js +3 -3
  284. package/dist/src/config/integration.d.ts +1 -1
  285. package/dist/src/config/loader.d.ts +0 -1
  286. package/dist/src/config/loader.js +4 -9
  287. package/dist/src/config/loader.js.map +1 -1
  288. package/dist/src/config/models-json.d.ts +6 -6
  289. package/dist/src/config/rules.js +2 -12
  290. package/dist/src/config/rules.js.map +1 -1
  291. package/dist/src/config/schema.d.ts +74 -47
  292. package/dist/src/config/schema.js +28 -66
  293. package/dist/src/config/schema.js.map +1 -1
  294. package/dist/src/config/validate-channel-configs.d.ts +0 -3
  295. package/dist/src/config/validate-channel-configs.js +29 -10
  296. package/dist/src/config/validate-channel-configs.js.map +1 -1
  297. package/dist/src/cron/executor.js +1 -4
  298. package/dist/src/cron/executor.js.map +1 -1
  299. package/dist/src/extensions/activation-context.js +3 -1
  300. package/dist/src/extensions/activation-context.js.map +1 -1
  301. package/dist/src/extensions/activation-planner.js +12 -0
  302. package/dist/src/extensions/activation-planner.js.map +1 -1
  303. package/dist/src/extensions/api.d.ts +5 -1
  304. package/dist/src/extensions/api.js +12 -0
  305. package/dist/src/extensions/api.js.map +1 -1
  306. package/dist/src/extensions/discover-extensions.js +17 -13
  307. package/dist/src/extensions/discover-extensions.js.map +1 -1
  308. package/dist/src/extensions/extension-metadata-snapshot.js +11 -5
  309. package/dist/src/extensions/extension-metadata-snapshot.js.map +1 -1
  310. package/dist/src/extensions/index.js +12 -4
  311. package/dist/src/extensions/index.js.map +1 -0
  312. package/dist/src/extensions/loader.d.ts +5 -1
  313. package/dist/src/extensions/loader.js +12 -11
  314. package/dist/src/extensions/loader.js.map +1 -1
  315. package/dist/src/extensions/manifest-registry.js +98 -93
  316. package/dist/src/extensions/manifest-registry.js.map +1 -1
  317. package/dist/src/extensions/normalize-manifest.js +91 -15
  318. package/dist/src/extensions/normalize-manifest.js.map +1 -1
  319. package/dist/src/extensions/sdk/index.js +1 -1
  320. package/dist/src/extensions/sdk/testing.js +4 -0
  321. package/dist/src/extensions/sdk/testing.js.map +1 -1
  322. package/dist/src/extensions/types/core.d.ts +32 -1
  323. package/dist/src/extensions/types/manifest.d.ts +60 -0
  324. package/dist/src/extensions/types/tui.d.ts +414 -5
  325. package/dist/src/gateway/agent-builtin-tools.d.ts +1 -1
  326. package/dist/src/gateway/agent-builtin-tools.js +16 -0
  327. package/dist/src/gateway/agent-builtin-tools.js.map +1 -1
  328. package/dist/src/gateway/agent-run-relay.d.ts +2 -3
  329. package/dist/src/gateway/agent-run-relay.js +10 -3
  330. package/dist/src/gateway/agent-run-relay.js.map +1 -1
  331. package/dist/src/gateway/agents-admin.d.ts +32 -19
  332. package/dist/src/gateway/agents-admin.js +113 -93
  333. package/dist/src/gateway/agents-admin.js.map +1 -1
  334. package/dist/src/gateway/chat-stream/mapper.d.ts +34 -0
  335. package/dist/src/gateway/chat-stream/mapper.js +244 -0
  336. package/dist/src/gateway/chat-stream/mapper.js.map +1 -0
  337. package/dist/src/gateway/chat-stream/protocol.d.ts +100 -0
  338. package/dist/src/gateway/chat-stream/protocol.js +1 -0
  339. package/dist/src/gateway/heartbeat/service.js +1 -1
  340. package/dist/src/gateway/hono/lib/agent-model.d.ts +4 -4
  341. package/dist/src/gateway/hono/lib/agent-model.js +13 -11
  342. package/dist/src/gateway/hono/lib/agent-model.js.map +1 -1
  343. package/dist/src/gateway/hono/lib/config-payload.d.ts +19 -7
  344. package/dist/src/gateway/hono/lib/config-payload.js +16 -15
  345. package/dist/src/gateway/hono/lib/config-payload.js.map +1 -1
  346. package/dist/src/gateway/hono/routes/agents.js +83 -48
  347. package/dist/src/gateway/hono/routes/agents.js.map +1 -1
  348. package/dist/src/gateway/hono/routes/channels.js +134 -214
  349. package/dist/src/gateway/hono/routes/channels.js.map +1 -1
  350. package/dist/src/gateway/hono/routes/commands-skills.js +10 -4
  351. package/dist/src/gateway/hono/routes/commands-skills.js.map +1 -1
  352. package/dist/src/gateway/hono/routes/config-patch/agents.js +26 -13
  353. package/dist/src/gateway/hono/routes/config-patch/agents.js.map +1 -1
  354. package/dist/src/gateway/hono/routes/config-patch/channels.d.ts +1 -11
  355. package/dist/src/gateway/hono/routes/config-patch/channels.js +18 -165
  356. package/dist/src/gateway/hono/routes/config-patch/channels.js.map +1 -1
  357. package/dist/src/gateway/hono/routes/config.js +5 -2
  358. package/dist/src/gateway/hono/routes/config.js.map +1 -1
  359. package/dist/src/gateway/hono/routes/dreaming.js +1 -1
  360. package/dist/src/gateway/hono/routes/lazy-bundles.js +13 -1
  361. package/dist/src/gateway/hono/routes/lazy-bundles.js.map +1 -1
  362. package/dist/src/gateway/hono/routes/public-gateway.js +2 -4
  363. package/dist/src/gateway/hono/routes/public-gateway.js.map +1 -1
  364. package/dist/src/gateway/hono/routes/sessions.js +179 -0
  365. package/dist/src/gateway/hono/routes/sessions.js.map +1 -1
  366. package/dist/src/gateway/hono/routes/tui.d.ts +3 -0
  367. package/dist/src/gateway/hono/routes/tui.js +16 -0
  368. package/dist/src/gateway/hono/routes/tui.js.map +1 -0
  369. package/dist/src/gateway/hono/routes/workflows.js +25 -1
  370. package/dist/src/gateway/hono/routes/workflows.js.map +1 -1
  371. package/dist/src/gateway/hono/sse.d.ts +5 -7
  372. package/dist/src/gateway/hono/sse.js +21 -38
  373. package/dist/src/gateway/hono/sse.js.map +1 -1
  374. package/dist/src/gateway/protocol.js.map +1 -1
  375. package/dist/src/gateway/service/agent-runner.d.ts +2 -4
  376. package/dist/src/gateway/service/agent-runner.js +1 -1
  377. package/dist/src/gateway/service/agent-runner.js.map +1 -1
  378. package/dist/src/gateway/service/marketplace-service.d.ts +4 -3
  379. package/dist/src/gateway/service/marketplace-service.js +7 -4
  380. package/dist/src/gateway/service/marketplace-service.js.map +1 -1
  381. package/dist/src/gateway/service/run-gateway-agent.d.ts +2 -6
  382. package/dist/src/gateway/service/run-gateway-agent.js +63 -36
  383. package/dist/src/gateway/service/run-gateway-agent.js.map +1 -1
  384. package/dist/src/gateway/service/sessions-api.d.ts +19 -0
  385. package/dist/src/gateway/service/sessions-api.js +12 -0
  386. package/dist/src/gateway/service/sessions-api.js.map +1 -1
  387. package/dist/src/gateway/service.d.ts +6 -0
  388. package/dist/src/gateway/service.js +73 -57
  389. package/dist/src/gateway/service.js.map +1 -1
  390. package/dist/src/heartbeat/index.js +1 -1
  391. package/dist/src/mcp/channel-bridge.js +1 -1
  392. package/dist/src/project-trust/trust-store.d.ts +30 -0
  393. package/dist/src/project-trust/trust-store.js +194 -0
  394. package/dist/src/project-trust/trust-store.js.map +1 -0
  395. package/dist/src/providers/index.d.ts +1 -1
  396. package/dist/src/providers/index.js +18 -7
  397. package/dist/src/providers/index.js.map +1 -1
  398. package/dist/src/routing/resolve-route.d.ts +0 -3
  399. package/dist/src/routing/resolve-route.js.map +1 -1
  400. package/dist/src/routing/resolve-tui-session-key.d.ts +2 -0
  401. package/dist/src/routing/resolve-tui-session-key.js +8 -3
  402. package/dist/src/routing/resolve-tui-session-key.js.map +1 -1
  403. package/dist/src/session/client-history.d.ts +32 -0
  404. package/dist/src/session/client-history.js +232 -1
  405. package/dist/src/session/client-history.js.map +1 -1
  406. package/dist/src/session/manager.d.ts +37 -4
  407. package/dist/src/session/manager.js +39 -15
  408. package/dist/src/session/manager.js.map +1 -1
  409. package/dist/src/session/session-context-for-llm.d.ts +93 -1
  410. package/dist/src/session/session-context-for-llm.js +105 -2
  411. package/dist/src/session/session-context-for-llm.js.map +1 -1
  412. package/dist/src/session/store.d.ts +37 -0
  413. package/dist/src/session/store.js +127 -2
  414. package/dist/src/session/store.js.map +1 -1
  415. package/dist/src/session/stored-rows-to-file-entries.js +37 -1
  416. package/dist/src/session/stored-rows-to-file-entries.js.map +1 -1
  417. package/dist/src/session/types.d.ts +14 -1
  418. package/dist/src/session/types.js.map +1 -1
  419. package/dist/src/share/share-thumbnail.js +1 -1
  420. package/dist/src/storage/sqlite/migrations/004_add_session_type_metadata.sql +15 -0
  421. package/dist/src/storage/sqlite/migrations/runner.d.ts +1 -1
  422. package/dist/src/storage/sqlite/migrations/runner.js +3 -3
  423. package/dist/src/storage/sqlite/migrations/runner.js.map +1 -1
  424. package/dist/src/storage/sqlite/migrations/runner.ts +1 -1
  425. package/dist/src/storage/sqlite/row-mappers.d.ts +14 -1
  426. package/dist/src/storage/sqlite/row-mappers.js +14 -1
  427. package/dist/src/storage/sqlite/row-mappers.js.map +1 -1
  428. package/dist/src/storage/sqlite/schema.js +1 -1
  429. package/dist/src/storage/sqlite/session-metadata.js +1 -0
  430. package/dist/src/storage/sqlite/session-metadata.js.map +1 -1
  431. package/dist/src/storage/sqlite/session-repository.js +52 -25
  432. package/dist/src/storage/sqlite/session-repository.js.map +1 -1
  433. package/dist/src/tui/backends/embedded-backend.d.ts +53 -4
  434. package/dist/src/tui/backends/embedded-backend.js +227 -39
  435. package/dist/src/tui/backends/embedded-backend.js.map +1 -1
  436. package/dist/src/tui/backends/gateway-sse-backend.d.ts +59 -3
  437. package/dist/src/tui/backends/gateway-sse-backend.js +416 -26
  438. package/dist/src/tui/backends/gateway-sse-backend.js.map +1 -1
  439. package/dist/src/tui/chat-history.d.ts +5 -1
  440. package/dist/src/tui/chat-history.js +78 -8
  441. package/dist/src/tui/chat-history.js.map +1 -1
  442. package/dist/src/tui/clipboard-text.d.ts +5 -0
  443. package/dist/src/tui/clipboard-text.js +46 -0
  444. package/dist/src/tui/clipboard-text.js.map +1 -0
  445. package/dist/src/tui/components/assistant-message.d.ts +19 -3
  446. package/dist/src/tui/components/assistant-message.js +115 -9
  447. package/dist/src/tui/components/assistant-message.js.map +1 -1
  448. package/dist/src/tui/components/bash-execution.d.ts +3 -2
  449. package/dist/src/tui/components/bash-execution.js +31 -3
  450. package/dist/src/tui/components/bash-execution.js.map +1 -1
  451. package/dist/src/tui/components/bash-summary.d.ts +23 -0
  452. package/dist/src/tui/components/bash-summary.js +87 -0
  453. package/dist/src/tui/components/bash-summary.js.map +1 -0
  454. package/dist/src/tui/components/branch-message-summary.d.ts +17 -0
  455. package/dist/src/tui/components/branch-message-summary.js +43 -0
  456. package/dist/src/tui/components/branch-message-summary.js.map +1 -0
  457. package/dist/src/tui/components/branch-summary.d.ts +13 -0
  458. package/dist/src/tui/components/branch-summary.js +51 -0
  459. package/dist/src/tui/components/branch-summary.js.map +1 -0
  460. package/dist/src/tui/components/chat-log.d.ts +46 -6
  461. package/dist/src/tui/components/chat-log.js +183 -21
  462. package/dist/src/tui/components/chat-log.js.map +1 -1
  463. package/dist/src/tui/components/compaction-summary.d.ts +13 -0
  464. package/dist/src/tui/components/compaction-summary.js +46 -0
  465. package/dist/src/tui/components/compaction-summary.js.map +1 -0
  466. package/dist/src/tui/components/custom-editor.d.ts +1 -0
  467. package/dist/src/tui/components/custom-editor.js +2 -0
  468. package/dist/src/tui/components/custom-editor.js.map +1 -1
  469. package/dist/src/tui/components/custom-message.d.ts +23 -0
  470. package/dist/src/tui/components/custom-message.js +65 -0
  471. package/dist/src/tui/components/custom-message.js.map +1 -0
  472. package/dist/src/tui/components/extension-dialog.d.ts +42 -0
  473. package/dist/src/tui/components/extension-dialog.js +127 -0
  474. package/dist/src/tui/components/extension-dialog.js.map +1 -0
  475. package/dist/src/tui/components/scoped-models-selector.d.ts +7 -2
  476. package/dist/src/tui/components/scoped-models-selector.js +89 -16
  477. package/dist/src/tui/components/scoped-models-selector.js.map +1 -1
  478. package/dist/src/tui/components/searchable-select-list.d.ts +30 -3
  479. package/dist/src/tui/components/searchable-select-list.js +82 -10
  480. package/dist/src/tui/components/searchable-select-list.js.map +1 -1
  481. package/dist/src/tui/components/session-selector.d.ts +18 -4
  482. package/dist/src/tui/components/session-selector.js +207 -40
  483. package/dist/src/tui/components/session-selector.js.map +1 -1
  484. package/dist/src/tui/components/settings-selector.d.ts +6 -2
  485. package/dist/src/tui/components/settings-selector.js +126 -7
  486. package/dist/src/tui/components/settings-selector.js.map +1 -1
  487. package/dist/src/tui/components/thinking-selector.d.ts +12 -0
  488. package/dist/src/tui/components/thinking-selector.js +48 -0
  489. package/dist/src/tui/components/thinking-selector.js.map +1 -0
  490. package/dist/src/tui/components/tool-execution.d.ts +57 -3
  491. package/dist/src/tui/components/tool-execution.js +378 -28
  492. package/dist/src/tui/components/tool-execution.js.map +1 -1
  493. package/dist/src/tui/components/tui-bottom-bar.d.ts +9 -1
  494. package/dist/src/tui/components/tui-bottom-bar.js +56 -11
  495. package/dist/src/tui/components/tui-bottom-bar.js.map +1 -1
  496. package/dist/src/tui/components/tui-header.d.ts +9 -2
  497. package/dist/src/tui/components/tui-header.js +25 -5
  498. package/dist/src/tui/components/tui-header.js.map +1 -1
  499. package/dist/src/tui/components/user-message.d.ts +4 -2
  500. package/dist/src/tui/components/user-message.js +42 -9
  501. package/dist/src/tui/components/user-message.js.map +1 -1
  502. package/dist/src/tui/components/visual-truncate.d.ts +11 -0
  503. package/dist/src/tui/components/visual-truncate.js +27 -0
  504. package/dist/src/tui/components/visual-truncate.js.map +1 -0
  505. package/dist/src/tui/extension-host/autocomplete.d.ts +43 -0
  506. package/dist/src/tui/extension-host/autocomplete.js +116 -0
  507. package/dist/src/tui/extension-host/autocomplete.js.map +1 -0
  508. package/dist/src/tui/extension-host/host.d.ts +31 -1
  509. package/dist/src/tui/extension-host/host.js +123 -6
  510. package/dist/src/tui/extension-host/host.js.map +1 -1
  511. package/dist/src/tui/extension-host/load-extensions.d.ts +6 -1
  512. package/dist/src/tui/extension-host/load-extensions.js +4 -3
  513. package/dist/src/tui/extension-host/load-extensions.js.map +1 -1
  514. package/dist/src/tui/extension-host/runtime-context.d.ts +21 -0
  515. package/dist/src/tui/extension-host/runtime-context.js +152 -0
  516. package/dist/src/tui/extension-host/runtime-context.js.map +1 -0
  517. package/dist/src/tui/extension-host/runtime.d.ts +52 -4
  518. package/dist/src/tui/extension-host/runtime.js +547 -85
  519. package/dist/src/tui/extension-host/runtime.js.map +1 -1
  520. package/dist/src/tui/extension-host/surface.d.ts +20 -0
  521. package/dist/src/tui/extension-host/surface.js +30 -6
  522. package/dist/src/tui/extension-host/surface.js.map +1 -1
  523. package/dist/src/tui/extension-host/tool-renderers.d.ts +6 -3
  524. package/dist/src/tui/extension-host/tool-renderers.js +43 -5
  525. package/dist/src/tui/extension-host/tool-renderers.js.map +1 -1
  526. package/dist/src/tui/format-tui-hotkeys.d.ts +12 -2
  527. package/dist/src/tui/format-tui-hotkeys.js +22 -5
  528. package/dist/src/tui/format-tui-hotkeys.js.map +1 -1
  529. package/dist/src/tui/tui-agent-events.d.ts +8 -6
  530. package/dist/src/tui/tui-agent-events.js +200 -59
  531. package/dist/src/tui/tui-agent-events.js.map +1 -1
  532. package/dist/src/tui/tui-backend.d.ts +169 -3
  533. package/dist/src/tui/tui-command-formatters.d.ts +76 -0
  534. package/dist/src/tui/tui-command-formatters.js +594 -0
  535. package/dist/src/tui/tui-command-formatters.js.map +1 -0
  536. package/dist/src/tui/tui-commands.d.ts +57 -7
  537. package/dist/src/tui/tui-commands.js +639 -43
  538. package/dist/src/tui/tui-commands.js.map +1 -1
  539. package/dist/src/tui/tui-context-usage.d.ts +1 -1
  540. package/dist/src/tui/tui-context-usage.js +9 -1
  541. package/dist/src/tui/tui-context-usage.js.map +1 -1
  542. package/dist/src/tui/tui-extension-user-message.d.ts +8 -0
  543. package/dist/src/tui/tui-extension-user-message.js +32 -0
  544. package/dist/src/tui/tui-extension-user-message.js.map +1 -0
  545. package/dist/src/tui/tui-follow-up-queue.d.ts +9 -0
  546. package/dist/src/tui/tui-follow-up-queue.js +18 -0
  547. package/dist/src/tui/tui-follow-up-queue.js.map +1 -0
  548. package/dist/src/tui/tui-local-shell.d.ts +11 -1
  549. package/dist/src/tui/tui-local-shell.js +50 -8
  550. package/dist/src/tui/tui-local-shell.js.map +1 -1
  551. package/dist/src/tui/tui-model-picker.d.ts +26 -0
  552. package/dist/src/tui/tui-model-picker.js +152 -0
  553. package/dist/src/tui/tui-model-picker.js.map +1 -0
  554. package/dist/src/tui/tui-oauth-login.d.ts +16 -0
  555. package/dist/src/tui/tui-oauth-login.js +189 -0
  556. package/dist/src/tui/tui-oauth-login.js.map +1 -0
  557. package/dist/src/tui/tui-overlays.d.ts +3 -3
  558. package/dist/src/tui/tui-overlays.js +6 -7
  559. package/dist/src/tui/tui-overlays.js.map +1 -1
  560. package/dist/src/tui/tui-picker-overlay.d.ts +27 -32
  561. package/dist/src/tui/tui-picker-overlay.js +340 -30
  562. package/dist/src/tui/tui-picker-overlay.js.map +1 -1
  563. package/dist/src/tui/tui-picker-services.d.ts +41 -0
  564. package/dist/src/tui/tui-picker-services.js +1 -0
  565. package/dist/src/tui/tui-run-state.d.ts +11 -0
  566. package/dist/src/tui/tui-run-state.js +114 -0
  567. package/dist/src/tui/tui-run-state.js.map +1 -0
  568. package/dist/src/tui/tui-runtime-hints.d.ts +4 -0
  569. package/dist/src/tui/tui-runtime-hints.js +18 -0
  570. package/dist/src/tui/tui-runtime-hints.js.map +1 -0
  571. package/dist/src/tui/tui-scoped-models.d.ts +1 -1
  572. package/dist/src/tui/tui-scoped-models.js +2 -2
  573. package/dist/src/tui/tui-scoped-models.js.map +1 -1
  574. package/dist/src/tui/tui-session-actions.d.ts +5 -3
  575. package/dist/src/tui/tui-session-actions.js +21 -9
  576. package/dist/src/tui/tui-session-actions.js.map +1 -1
  577. package/dist/src/tui/tui-session-format.d.ts +4 -1
  578. package/dist/src/tui/tui-session-format.js +17 -3
  579. package/dist/src/tui/tui-session-format.js.map +1 -1
  580. package/dist/src/tui/tui-session-snapshot.d.ts +82 -0
  581. package/dist/src/tui/tui-session-snapshot.js +184 -0
  582. package/dist/src/tui/tui-session-snapshot.js.map +1 -0
  583. package/dist/src/tui/tui-session-stats.d.ts +3 -0
  584. package/dist/src/tui/tui-session-stats.js +59 -0
  585. package/dist/src/tui/tui-session-stats.js.map +1 -0
  586. package/dist/src/tui/tui-settings.d.ts +21 -0
  587. package/dist/src/tui/tui-settings.js +28 -1
  588. package/dist/src/tui/tui-settings.js.map +1 -1
  589. package/dist/src/tui/tui-skills-autocomplete.js +1 -1
  590. package/dist/src/tui/tui-skills-autocomplete.js.map +1 -1
  591. package/dist/src/tui/tui-startup-resources.d.ts +3 -0
  592. package/dist/src/tui/tui-startup-resources.js +39 -0
  593. package/dist/src/tui/tui-startup-resources.js.map +1 -0
  594. package/dist/src/tui/tui-startup-text.d.ts +10 -0
  595. package/dist/src/tui/tui-startup-text.js +58 -0
  596. package/dist/src/tui/tui-startup-text.js.map +1 -0
  597. package/dist/src/tui/tui-stdio-filter.d.ts +1 -0
  598. package/dist/src/tui/tui-stdio-filter.js +11 -7
  599. package/dist/src/tui/tui-stdio-filter.js.map +1 -1
  600. package/dist/src/tui/tui-submit.d.ts +2 -0
  601. package/dist/src/tui/tui-submit.js +2 -1
  602. package/dist/src/tui/tui-submit.js.map +1 -1
  603. package/dist/src/tui/tui-tool-diff.js +61 -7
  604. package/dist/src/tui/tui-tool-diff.js.map +1 -1
  605. package/dist/src/tui/tui-tool-result.d.ts +17 -0
  606. package/dist/src/tui/tui-tool-result.js +74 -0
  607. package/dist/src/tui/tui-tool-result.js.map +1 -0
  608. package/dist/src/tui/tui-transcript-tree-picker.d.ts +57 -0
  609. package/dist/src/tui/tui-transcript-tree-picker.js +604 -0
  610. package/dist/src/tui/tui-transcript-tree-picker.js.map +1 -0
  611. package/dist/src/tui/tui-transcript-tree.d.ts +7 -0
  612. package/dist/src/tui/tui-transcript-tree.js +316 -0
  613. package/dist/src/tui/tui-transcript-tree.js.map +1 -0
  614. package/dist/src/tui/tui-types.d.ts +25 -34
  615. package/dist/src/tui/tui-types.js +12 -0
  616. package/dist/src/tui/tui-types.js.map +1 -1
  617. package/dist/src/tui/tui.js +1288 -112
  618. package/dist/src/tui/tui.js.map +1 -1
  619. package/dist/src/tui/xopc-tui-keybindings.d.ts +127 -2
  620. package/dist/src/tui/xopc-tui-keybindings.js +127 -2
  621. package/dist/src/tui/xopc-tui-keybindings.js.map +1 -1
  622. package/dist/src/workflows/domain/definition-utils.d.ts +2 -1
  623. package/dist/src/workflows/domain/definition-utils.js +18 -8
  624. package/dist/src/workflows/domain/definition-utils.js.map +1 -1
  625. package/dist/src/workflows/domain/definition.d.ts +25 -0
  626. package/dist/src/workflows/domain/event.d.ts +1 -0
  627. package/dist/src/workflows/domain/result.d.ts +15 -0
  628. package/dist/src/workflows/domain/run.d.ts +2 -0
  629. package/dist/src/workflows/domain/run.js.map +1 -1
  630. package/dist/src/workflows/engine/projector.js +4 -0
  631. package/dist/src/workflows/engine/projector.js.map +1 -1
  632. package/dist/src/workflows/engine/workflow-engine.d.ts +37 -1
  633. package/dist/src/workflows/engine/workflow-engine.js +75 -11
  634. package/dist/src/workflows/engine/workflow-engine.js.map +1 -1
  635. package/dist/src/workflows/index.d.ts +1 -0
  636. package/dist/src/workflows/index.js +4 -1
  637. package/dist/src/workflows/registry/catalog-workflow-definition-registry.d.ts +9 -0
  638. package/dist/src/workflows/registry/catalog-workflow-definition-registry.js +40 -0
  639. package/dist/src/workflows/registry/catalog-workflow-definition-registry.js.map +1 -0
  640. package/dist/src/workflows/registry/index.d.ts +2 -0
  641. package/dist/src/workflows/registry/index.js +2 -0
  642. package/dist/src/workflows/registry/workflow-definition-registry.d.ts +15 -0
  643. package/dist/src/workflows/registry/workflow-definition-registry.js +1 -0
  644. package/dist/src/workflows/runtime/index.d.ts +2 -0
  645. package/dist/src/workflows/runtime/index.js +2 -1
  646. package/dist/src/workflows/runtime/script-workflow-runtime.d.ts +5 -0
  647. package/dist/src/workflows/runtime/script-workflow-runtime.js +15 -0
  648. package/dist/src/workflows/runtime/script-workflow-runtime.js.map +1 -0
  649. package/dist/src/workflows/runtime/workflow-runtime-port.d.ts +16 -0
  650. package/dist/src/workflows/runtime/workflow-runtime-port.js +1 -0
  651. package/dist/src/workflows/service/run-view-to-snapshot.js +3 -0
  652. package/dist/src/workflows/service/run-view-to-snapshot.js.map +1 -1
  653. package/dist/src/workflows/service/workflow-run-service.d.ts +3 -0
  654. package/dist/src/workflows/service/workflow-run-service.js +10 -15
  655. package/dist/src/workflows/service/workflow-run-service.js.map +1 -1
  656. package/dist/src/workflows/service/workflow-session-bridge.d.ts +1 -1
  657. package/dist/src/workflows/service/workflow-session-bridge.js +4 -1
  658. package/dist/src/workflows/service/workflow-session-bridge.js.map +1 -1
  659. package/package.json +21 -15
  660. package/skills/creative/frontend-design/SKILL.md +1 -1
  661. package/skills/creative/theme-factory/SKILL.md +1 -1
  662. package/skills/documents/xlsx/SKILL.md +1 -1
  663. package/skills/engineering/diagnose/SKILL.md +2 -2
  664. package/skills/engineering/tdd/SKILL.md +1 -1
  665. package/skills/tools/github/SKILL.md +6 -1
  666. package/skills/tools/webapp-testing/SKILL.md +4 -1
  667. package/dist/extensions/telegram/src/adapters/config-surface.d.ts +0 -2
  668. package/dist/extensions/telegram/src/adapters/config-surface.js +0 -26
  669. package/dist/extensions/telegram/src/adapters/config-surface.js.map +0 -1
  670. package/dist/extensions/weixin/src/__tests__/workflow-progress.test.js +0 -158
  671. package/dist/extensions/weixin/src/__tests__/workflow-progress.test.js.map +0 -1
  672. package/dist/gateway/static/root/assets/agents-BwXkia_W.js +0 -222
  673. package/dist/gateway/static/root/assets/channels-settings-tlOTdaXw.js +0 -1
  674. package/dist/gateway/static/root/assets/channels-status-swr-D4XjqwqC.js +0 -8
  675. package/dist/gateway/static/root/assets/cron-api-DcmfGuj0.js +0 -1
  676. package/dist/gateway/static/root/assets/cron-page-CijJ4G6F.js +0 -1
  677. package/dist/gateway/static/root/assets/extension-settings-page-CyJk_G64.js +0 -1
  678. package/dist/gateway/static/root/assets/field-primitives-C4GpxsDo.js +0 -1
  679. package/dist/gateway/static/root/assets/heartbeat-config-api-CLD0Gpi3.js +0 -1
  680. package/dist/gateway/static/root/assets/index-0HmunJW9.js +0 -4845
  681. package/dist/gateway/static/root/assets/index-Bk75Phrd.css +0 -1
  682. package/dist/gateway/static/root/assets/notes-page-BBnTh0uI.js +0 -1
  683. package/dist/gateway/static/root/assets/sessions-page-B0riYK7j.js +0 -1
  684. package/dist/gateway/static/root/assets/settings-advanced-gate-DiP_WHu_.js +0 -2
  685. package/dist/gateway/static/root/assets/settings-page-1ZPhcCZ9.js +0 -3
  686. package/dist/gateway/static/root/assets/skills-page-BQ1hllKD.js +0 -2
  687. package/dist/gateway/static/root/assets/url-F3_D_6zZ.js +0 -3
  688. package/dist/gateway/static/root/assets/utils-CPr3FBh2.js +0 -1
  689. package/dist/gateway/static/root/assets/voice-api-key-field-BkbDl6dH.js +0 -1
  690. package/dist/gateway/static/root/assets/workflows-page-D059ysoF.js +0 -27
  691. package/dist/src/agent/embedded/map-stream-events.d.ts +0 -9
  692. package/dist/src/agent/embedded/map-stream-events.js +0 -63
  693. package/dist/src/agent/embedded/map-stream-events.js.map +0 -1
  694. package/dist/src/channels/dock.js.map +0 -1
  695. package/dist/src/channels/plugins/bundled.d.ts +0 -11
  696. package/dist/src/channels/plugins/bundled.js +0 -10
  697. package/dist/src/channels/plugins/bundled.js.map +0 -1
  698. package/dist/src/channels/registry.d.ts +0 -25
  699. package/dist/src/channels/registry.js +0 -82
  700. package/dist/src/channels/registry.js.map +0 -1
  701. package/dist/src/config/localized-text.d.ts +0 -6
  702. package/dist/src/config/localized-text.js +0 -42
  703. package/dist/src/config/localized-text.js.map +0 -1
  704. package/dist/src/generated/bundled-channel-plugins.d.ts +0 -10
  705. package/dist/src/generated/bundled-channel-plugins.js +0 -16
  706. package/dist/src/generated/bundled-channel-plugins.js.map +0 -1
  707. package/dist/src/tui/stream-assembler.d.ts +0 -22
  708. package/dist/src/tui/stream-assembler.js +0 -63
  709. package/dist/src/tui/stream-assembler.js.map +0 -1
  710. package/skills/browser/SKILL-zh.md +0 -188
  711. package/skills/business/company-values/SKILL-zh.md +0 -80
  712. package/skills/business/company-values/SKILL.md +0 -80
  713. package/skills/business/find-community/SKILL-zh.md +0 -50
  714. package/skills/business/find-community/SKILL.md +0 -50
  715. package/skills/business/first-customers/SKILL-zh.md +0 -76
  716. package/skills/business/first-customers/SKILL.md +0 -76
  717. package/skills/business/grow-sustainably/SKILL-zh.md +0 -92
  718. package/skills/business/grow-sustainably/SKILL.md +0 -92
  719. package/skills/business/marketing-plan/SKILL-zh.md +0 -100
  720. package/skills/business/marketing-plan/SKILL.md +0 -100
  721. package/skills/business/minimalist-review/SKILL-zh.md +0 -82
  722. package/skills/business/minimalist-review/SKILL.md +0 -82
  723. package/skills/business/mvp/SKILL-zh.md +0 -81
  724. package/skills/business/mvp/SKILL.md +0 -81
  725. package/skills/business/pricing/SKILL-zh.md +0 -64
  726. package/skills/business/pricing/SKILL.md +0 -64
  727. package/skills/business/processize/SKILL-zh.md +0 -91
  728. package/skills/business/processize/SKILL.md +0 -91
  729. package/skills/business/validate-idea/SKILL-zh.md +0 -68
  730. package/skills/business/validate-idea/SKILL.md +0 -68
  731. package/skills/creative/algorithmic-art/LICENSE.txt +0 -202
  732. package/skills/creative/algorithmic-art/SKILL-zh.md +0 -405
  733. package/skills/creative/algorithmic-art/SKILL.md +0 -405
  734. package/skills/creative/algorithmic-art/templates/generator_template.js +0 -223
  735. package/skills/creative/algorithmic-art/templates/viewer.html +0 -599
  736. package/skills/creative/frontend-design/SKILL-zh.md +0 -42
  737. package/skills/creative/theme-factory/SKILL-zh.md +0 -59
  738. package/skills/creative/web-artifacts-builder/LICENSE.txt +0 -202
  739. package/skills/creative/web-artifacts-builder/SKILL-zh.md +0 -74
  740. package/skills/creative/web-artifacts-builder/SKILL.md +0 -74
  741. package/skills/creative/web-artifacts-builder/scripts/bundle-artifact.sh +0 -54
  742. package/skills/creative/web-artifacts-builder/scripts/init-artifact.sh +0 -322
  743. package/skills/creative/web-artifacts-builder/scripts/shadcn-components.tar.gz +0 -0
  744. package/skills/documents/doc-coauthoring/SKILL-zh.md +0 -375
  745. package/skills/documents/doc-coauthoring/SKILL.md +0 -375
  746. package/skills/documents/docx/LICENSE.txt +0 -30
  747. package/skills/documents/docx/SKILL-zh.md +0 -590
  748. package/skills/documents/docx/SKILL.md +0 -590
  749. package/skills/documents/docx/scripts/__init__.py +0 -1
  750. package/skills/documents/docx/scripts/accept_changes.py +0 -135
  751. package/skills/documents/docx/scripts/comment.py +0 -318
  752. package/skills/documents/docx/scripts/office/helpers/__init__.py +0 -0
  753. package/skills/documents/docx/scripts/office/helpers/merge_runs.py +0 -199
  754. package/skills/documents/docx/scripts/office/helpers/simplify_redlines.py +0 -197
  755. package/skills/documents/docx/scripts/office/pack.py +0 -159
  756. package/skills/documents/docx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-chart.xsd +0 -1499
  757. package/skills/documents/docx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-chartDrawing.xsd +0 -146
  758. package/skills/documents/docx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-diagram.xsd +0 -1085
  759. package/skills/documents/docx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-lockedCanvas.xsd +0 -11
  760. package/skills/documents/docx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-main.xsd +0 -3081
  761. package/skills/documents/docx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-picture.xsd +0 -23
  762. package/skills/documents/docx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-spreadsheetDrawing.xsd +0 -185
  763. package/skills/documents/docx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-wordprocessingDrawing.xsd +0 -287
  764. package/skills/documents/docx/scripts/office/schemas/ISO-IEC29500-4_2016/pml.xsd +0 -1676
  765. package/skills/documents/docx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-additionalCharacteristics.xsd +0 -28
  766. package/skills/documents/docx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-bibliography.xsd +0 -144
  767. package/skills/documents/docx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-commonSimpleTypes.xsd +0 -174
  768. package/skills/documents/docx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-customXmlDataProperties.xsd +0 -25
  769. package/skills/documents/docx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-customXmlSchemaProperties.xsd +0 -18
  770. package/skills/documents/docx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesCustom.xsd +0 -59
  771. package/skills/documents/docx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesExtended.xsd +0 -56
  772. package/skills/documents/docx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesVariantTypes.xsd +0 -195
  773. package/skills/documents/docx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-math.xsd +0 -582
  774. package/skills/documents/docx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-relationshipReference.xsd +0 -25
  775. package/skills/documents/docx/scripts/office/schemas/ISO-IEC29500-4_2016/sml.xsd +0 -4439
  776. package/skills/documents/docx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-main.xsd +0 -570
  777. package/skills/documents/docx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-officeDrawing.xsd +0 -509
  778. package/skills/documents/docx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-presentationDrawing.xsd +0 -12
  779. package/skills/documents/docx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-spreadsheetDrawing.xsd +0 -108
  780. package/skills/documents/docx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-wordprocessingDrawing.xsd +0 -96
  781. package/skills/documents/docx/scripts/office/schemas/ISO-IEC29500-4_2016/wml.xsd +0 -3646
  782. package/skills/documents/docx/scripts/office/schemas/ISO-IEC29500-4_2016/xml.xsd +0 -116
  783. package/skills/documents/docx/scripts/office/schemas/ecma/fouth-edition/opc-contentTypes.xsd +0 -42
  784. package/skills/documents/docx/scripts/office/schemas/ecma/fouth-edition/opc-coreProperties.xsd +0 -50
  785. package/skills/documents/docx/scripts/office/schemas/ecma/fouth-edition/opc-digSig.xsd +0 -49
  786. package/skills/documents/docx/scripts/office/schemas/ecma/fouth-edition/opc-relationships.xsd +0 -33
  787. package/skills/documents/docx/scripts/office/schemas/mce/mc.xsd +0 -75
  788. package/skills/documents/docx/scripts/office/schemas/microsoft/wml-2010.xsd +0 -560
  789. package/skills/documents/docx/scripts/office/schemas/microsoft/wml-2012.xsd +0 -67
  790. package/skills/documents/docx/scripts/office/schemas/microsoft/wml-2018.xsd +0 -14
  791. package/skills/documents/docx/scripts/office/schemas/microsoft/wml-cex-2018.xsd +0 -20
  792. package/skills/documents/docx/scripts/office/schemas/microsoft/wml-cid-2016.xsd +0 -13
  793. package/skills/documents/docx/scripts/office/schemas/microsoft/wml-sdtdatahash-2020.xsd +0 -4
  794. package/skills/documents/docx/scripts/office/schemas/microsoft/wml-symex-2015.xsd +0 -8
  795. package/skills/documents/docx/scripts/office/soffice.py +0 -183
  796. package/skills/documents/docx/scripts/office/unpack.py +0 -132
  797. package/skills/documents/docx/scripts/office/validate.py +0 -111
  798. package/skills/documents/docx/scripts/office/validators/__init__.py +0 -15
  799. package/skills/documents/docx/scripts/office/validators/base.py +0 -847
  800. package/skills/documents/docx/scripts/office/validators/docx.py +0 -446
  801. package/skills/documents/docx/scripts/office/validators/pptx.py +0 -275
  802. package/skills/documents/docx/scripts/office/validators/redlining.py +0 -247
  803. package/skills/documents/docx/scripts/templates/comments.xml +0 -3
  804. package/skills/documents/docx/scripts/templates/commentsExtended.xml +0 -3
  805. package/skills/documents/docx/scripts/templates/commentsExtensible.xml +0 -3
  806. package/skills/documents/docx/scripts/templates/commentsIds.xml +0 -3
  807. package/skills/documents/docx/scripts/templates/people.xml +0 -3
  808. package/skills/documents/pdf/LICENSE.txt +0 -30
  809. package/skills/documents/pdf/SKILL-zh.md +0 -314
  810. package/skills/documents/pdf/SKILL.md +0 -314
  811. package/skills/documents/pdf/forms.md +0 -294
  812. package/skills/documents/pdf/reference.md +0 -612
  813. package/skills/documents/pdf/scripts/check_bounding_boxes.py +0 -65
  814. package/skills/documents/pdf/scripts/check_fillable_fields.py +0 -11
  815. package/skills/documents/pdf/scripts/convert_pdf_to_images.py +0 -33
  816. package/skills/documents/pdf/scripts/create_validation_image.py +0 -37
  817. package/skills/documents/pdf/scripts/extract_form_field_info.py +0 -122
  818. package/skills/documents/pdf/scripts/extract_form_structure.py +0 -115
  819. package/skills/documents/pdf/scripts/fill_fillable_fields.py +0 -98
  820. package/skills/documents/pdf/scripts/fill_pdf_form_with_annotations.py +0 -107
  821. package/skills/documents/pptx/LICENSE.txt +0 -30
  822. package/skills/documents/pptx/SKILL-zh.md +0 -232
  823. package/skills/documents/pptx/SKILL.md +0 -232
  824. package/skills/documents/pptx/editing.md +0 -205
  825. package/skills/documents/pptx/pptxgenjs.md +0 -420
  826. package/skills/documents/pptx/scripts/__init__.py +0 -0
  827. package/skills/documents/pptx/scripts/add_slide.py +0 -195
  828. package/skills/documents/pptx/scripts/clean.py +0 -286
  829. package/skills/documents/pptx/scripts/office/helpers/__init__.py +0 -0
  830. package/skills/documents/pptx/scripts/office/helpers/merge_runs.py +0 -199
  831. package/skills/documents/pptx/scripts/office/helpers/simplify_redlines.py +0 -197
  832. package/skills/documents/pptx/scripts/office/pack.py +0 -159
  833. package/skills/documents/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-chart.xsd +0 -1499
  834. package/skills/documents/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-chartDrawing.xsd +0 -146
  835. package/skills/documents/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-diagram.xsd +0 -1085
  836. package/skills/documents/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-lockedCanvas.xsd +0 -11
  837. package/skills/documents/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-main.xsd +0 -3081
  838. package/skills/documents/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-picture.xsd +0 -23
  839. package/skills/documents/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-spreadsheetDrawing.xsd +0 -185
  840. package/skills/documents/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-wordprocessingDrawing.xsd +0 -287
  841. package/skills/documents/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/pml.xsd +0 -1676
  842. package/skills/documents/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-additionalCharacteristics.xsd +0 -28
  843. package/skills/documents/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-bibliography.xsd +0 -144
  844. package/skills/documents/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-commonSimpleTypes.xsd +0 -174
  845. package/skills/documents/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-customXmlDataProperties.xsd +0 -25
  846. package/skills/documents/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-customXmlSchemaProperties.xsd +0 -18
  847. package/skills/documents/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesCustom.xsd +0 -59
  848. package/skills/documents/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesExtended.xsd +0 -56
  849. package/skills/documents/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesVariantTypes.xsd +0 -195
  850. package/skills/documents/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-math.xsd +0 -582
  851. package/skills/documents/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-relationshipReference.xsd +0 -25
  852. package/skills/documents/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/sml.xsd +0 -4439
  853. package/skills/documents/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-main.xsd +0 -570
  854. package/skills/documents/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-officeDrawing.xsd +0 -509
  855. package/skills/documents/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-presentationDrawing.xsd +0 -12
  856. package/skills/documents/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-spreadsheetDrawing.xsd +0 -108
  857. package/skills/documents/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-wordprocessingDrawing.xsd +0 -96
  858. package/skills/documents/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/wml.xsd +0 -3646
  859. package/skills/documents/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/xml.xsd +0 -116
  860. package/skills/documents/pptx/scripts/office/schemas/ecma/fouth-edition/opc-contentTypes.xsd +0 -42
  861. package/skills/documents/pptx/scripts/office/schemas/ecma/fouth-edition/opc-coreProperties.xsd +0 -50
  862. package/skills/documents/pptx/scripts/office/schemas/ecma/fouth-edition/opc-digSig.xsd +0 -49
  863. package/skills/documents/pptx/scripts/office/schemas/ecma/fouth-edition/opc-relationships.xsd +0 -33
  864. package/skills/documents/pptx/scripts/office/schemas/mce/mc.xsd +0 -75
  865. package/skills/documents/pptx/scripts/office/schemas/microsoft/wml-2010.xsd +0 -560
  866. package/skills/documents/pptx/scripts/office/schemas/microsoft/wml-2012.xsd +0 -67
  867. package/skills/documents/pptx/scripts/office/schemas/microsoft/wml-2018.xsd +0 -14
  868. package/skills/documents/pptx/scripts/office/schemas/microsoft/wml-cex-2018.xsd +0 -20
  869. package/skills/documents/pptx/scripts/office/schemas/microsoft/wml-cid-2016.xsd +0 -13
  870. package/skills/documents/pptx/scripts/office/schemas/microsoft/wml-sdtdatahash-2020.xsd +0 -4
  871. package/skills/documents/pptx/scripts/office/schemas/microsoft/wml-symex-2015.xsd +0 -8
  872. package/skills/documents/pptx/scripts/office/soffice.py +0 -183
  873. package/skills/documents/pptx/scripts/office/unpack.py +0 -132
  874. package/skills/documents/pptx/scripts/office/validate.py +0 -111
  875. package/skills/documents/pptx/scripts/office/validators/__init__.py +0 -15
  876. package/skills/documents/pptx/scripts/office/validators/base.py +0 -847
  877. package/skills/documents/pptx/scripts/office/validators/docx.py +0 -446
  878. package/skills/documents/pptx/scripts/office/validators/pptx.py +0 -275
  879. package/skills/documents/pptx/scripts/office/validators/redlining.py +0 -247
  880. package/skills/documents/pptx/scripts/thumbnail.py +0 -289
  881. package/skills/documents/xlsx/SKILL-zh.md +0 -292
  882. package/skills/engineering/diagnose/SKILL-zh.md +0 -117
  883. package/skills/engineering/grill-with-docs/ADR-FORMAT.md +0 -47
  884. package/skills/engineering/grill-with-docs/CONTEXT-FORMAT.md +0 -77
  885. package/skills/engineering/grill-with-docs/SKILL-zh.md +0 -88
  886. package/skills/engineering/grill-with-docs/SKILL.md +0 -88
  887. package/skills/engineering/improve-codebase-architecture/DEEPENING.md +0 -37
  888. package/skills/engineering/improve-codebase-architecture/INTERFACE-DESIGN.md +0 -44
  889. package/skills/engineering/improve-codebase-architecture/LANGUAGE.md +0 -53
  890. package/skills/engineering/improve-codebase-architecture/SKILL-zh.md +0 -71
  891. package/skills/engineering/improve-codebase-architecture/SKILL.md +0 -71
  892. package/skills/engineering/tdd/SKILL-zh.md +0 -109
  893. package/skills/engineering/to-issues/SKILL-zh.md +0 -81
  894. package/skills/engineering/to-issues/SKILL.md +0 -81
  895. package/skills/engineering/to-prd/SKILL-zh.md +0 -76
  896. package/skills/engineering/to-prd/SKILL.md +0 -74
  897. package/skills/engineering/zoom-out/SKILL-zh.md +0 -7
  898. package/skills/engineering/zoom-out/SKILL.md +0 -7
  899. package/skills/tools/find-skills/SKILL-zh.md +0 -440
  900. package/skills/tools/github/SKILL-zh.md +0 -48
  901. package/skills/tools/internal-comms/LICENSE.txt +0 -202
  902. package/skills/tools/internal-comms/SKILL-zh.md +0 -32
  903. package/skills/tools/internal-comms/SKILL.md +0 -32
  904. package/skills/tools/internal-comms/examples/3p-updates.md +0 -47
  905. package/skills/tools/internal-comms/examples/company-newsletter.md +0 -65
  906. package/skills/tools/internal-comms/examples/faq-answers.md +0 -30
  907. package/skills/tools/internal-comms/examples/general-comms.md +0 -16
  908. package/skills/tools/skill-creator/LICENSE.txt +0 -202
  909. package/skills/tools/skill-creator/SKILL-zh.md +0 -483
  910. package/skills/tools/skill-creator/SKILL.md +0 -485
  911. package/skills/tools/skill-creator/agents/analyzer.md +0 -274
  912. package/skills/tools/skill-creator/agents/comparator.md +0 -202
  913. package/skills/tools/skill-creator/agents/grader.md +0 -223
  914. package/skills/tools/skill-creator/assets/eval_review.html +0 -146
  915. package/skills/tools/skill-creator/eval-viewer/generate_review.py +0 -471
  916. package/skills/tools/skill-creator/eval-viewer/viewer.html +0 -1325
  917. package/skills/tools/skill-creator/references/schemas.md +0 -430
  918. package/skills/tools/skill-creator/scripts/__init__.py +0 -0
  919. package/skills/tools/skill-creator/scripts/aggregate_benchmark.py +0 -401
  920. package/skills/tools/skill-creator/scripts/generate_report.py +0 -326
  921. package/skills/tools/skill-creator/scripts/improve_description.py +0 -247
  922. package/skills/tools/skill-creator/scripts/package_skill.py +0 -136
  923. package/skills/tools/skill-creator/scripts/quick_validate.py +0 -103
  924. package/skills/tools/skill-creator/scripts/run_eval.py +0 -310
  925. package/skills/tools/skill-creator/scripts/run_loop.py +0 -328
  926. package/skills/tools/skill-creator/scripts/utils.py +0 -47
  927. package/skills/tools/summarize/SKILL-zh.md +0 -47
  928. package/skills/tools/weather/SKILL-zh.md +0 -46
  929. package/skills/tools/weather/SKILL.md +0 -46
  930. package/skills/tools/webapp-testing/SKILL-zh.md +0 -96
@@ -1 +1 @@
1
- {"version":3,"file":"pairing-service.js","names":["block"],"sources":["../../../../src/channels/pairing/pairing-service.ts"],"sourcesContent":["import type { Config } from '../../config/schema.js';\nimport { resolveDmPolicy } from '../security.js';\nimport type { DmPolicy } from '../channel-domain.js';\n\nimport { readAllowFromIdsSync, removeAllowFromIdSync } from './allow-from-file.js';\nimport type { PairingCliChannel } from './pairing-channel.js';\nimport { broadcastPairingEvent } from './pairing-events.js';\nimport { PAIRING_PENDING_MAX, PAIRING_STALE_PENDING_MS } from './pairing-constants.js';\nimport {\n approvePairingBySenderIdSync,\n approvePairingCodeSync,\n dismissPairingBySenderIdSync,\n listPendingPairingRequestsSync,\n PAIRING_PENDING_TTL_MS,\n type PairingRequest,\n} from './pairing-store.js';\nimport {\n resolveStandardAllowFromPath,\n resolveStandardPairingPath,\n resolveWeixinAllowFromPath,\n resolveWeixinPairingPath,\n} from './paths.js';\n\n// `PairingPendingView` moved to `./pairing-types.js` (leaf) so\n// `plugins/types.adapters.ts` and other lower-level callers can reference it\n// without forming a `types.adapters → pairing-service → security → plugin-types\n// → types.adapters` cycle. Re-exported here for backward-compat.\nexport { type PairingPendingView } from './pairing-types.js';\nimport type { PairingPendingView } from './pairing-types.js';\n\nexport type ChannelPairingState = {\n channel: PairingCliChannel;\n accountId: string;\n dmPolicy: DmPolicy;\n pending: PairingPendingView[];\n paired: {\n fromConfig: string[];\n fromCredentials: string[];\n };\n};\n\nfunction normalizeAccountId(accountId: string | undefined): string {\n return (accountId ?? 'default').trim().toLowerCase() || 'default';\n}\n\nfunction resolvePairingPaths(channel: PairingCliChannel, accountId: string): {\n pairingPath: string;\n allowPath: string;\n} {\n const normalized = normalizeAccountId(accountId);\n if (channel === 'weixin') {\n return {\n pairingPath: resolveWeixinPairingPath(normalized),\n allowPath: resolveWeixinAllowFromPath(normalized),\n };\n }\n return {\n pairingPath: resolveStandardPairingPath(channel, normalized),\n allowPath: resolveStandardAllowFromPath(channel, normalized),\n };\n}\n\nfunction requestAccountId(entry: PairingRequest): string {\n const fromMeta = entry.meta?.accountId?.trim().toLowerCase();\n return fromMeta || 'default';\n}\n\nfunction toPendingView(entry: PairingRequest): PairingPendingView {\n const createdMs = Date.parse(entry.createdAt);\n const expiresAt = Number.isFinite(createdMs)\n ? new Date(createdMs + PAIRING_PENDING_TTL_MS).toISOString()\n : new Date(Date.now() + PAIRING_PENDING_TTL_MS).toISOString();\n const code = entry.code ?? '';\n const codeLast4 = code.length >= 4 ? code.slice(-4) : code;\n const meta =\n entry.meta && typeof entry.meta === 'object'\n ? Object.fromEntries(\n Object.entries(entry.meta).filter(\n ([k, v]) => k !== 'accountId' && typeof v === 'string' && v.trim() !== '',\n ),\n )\n : undefined;\n return {\n senderId: entry.id,\n codeLast4,\n createdAt: entry.createdAt,\n lastSeenAt: entry.lastSeenAt,\n expiresAt,\n isStale:\n Number.isFinite(createdMs) && Date.now() - (createdMs as number) >= PAIRING_STALE_PENDING_MS,\n meta: meta && Object.keys(meta).length > 0 ? meta : undefined,\n };\n}\n\nfunction pendingEntryStats(pending: PairingRequest[]): {\n pending: number;\n stale: number;\n atCapacity: boolean;\n} {\n const now = Date.now();\n let stale = 0;\n for (const p of pending) {\n const created = Date.parse(p.createdAt);\n if (Number.isFinite(created) && now - created >= PAIRING_STALE_PENDING_MS) {\n stale += 1;\n }\n }\n return {\n pending: pending.length,\n stale,\n atCapacity: pending.length >= PAIRING_PENDING_MAX,\n };\n}\n\nfunction resolveChannelAllowFromConfig(\n config: Config | undefined,\n channel: PairingCliChannel,\n accountId: string,\n): string[] {\n const ch = config?.channels?.[channel as keyof NonNullable<Config['channels']>];\n if (!ch || typeof ch !== 'object' || Array.isArray(ch)) return [];\n const block = ch as Record<string, unknown>;\n const top = Array.isArray(block.allowFrom)\n ? block.allowFrom.map(String).filter(Boolean)\n : [];\n const accounts = block.accounts;\n if (accounts && typeof accounts === 'object' && !Array.isArray(accounts)) {\n const acc = (accounts as Record<string, unknown>)[accountId];\n if (acc && typeof acc === 'object' && !Array.isArray(acc)) {\n const fromAcc = (acc as { allowFrom?: unknown }).allowFrom;\n if (Array.isArray(fromAcc)) {\n return [...new Set([...top, ...fromAcc.map(String).filter(Boolean)])];\n }\n }\n }\n return [...new Set(top)];\n}\n\nfunction resolveChannelEnabled(config: Config | undefined, channel: PairingCliChannel): boolean {\n const ch = config?.channels?.[channel as keyof NonNullable<Config['channels']>];\n if (!ch || typeof ch !== 'object' || Array.isArray(ch)) return false;\n return (ch as { enabled?: boolean }).enabled === true;\n}\n\nfunction resolveAccountEnabled(\n config: Config | undefined,\n channel: PairingCliChannel,\n accountId: string,\n): boolean {\n if (!resolveChannelEnabled(config, channel)) return false;\n const ch = config?.channels?.[channel as keyof NonNullable<Config['channels']>];\n if (!ch || typeof ch !== 'object' || Array.isArray(ch)) return true;\n const block = ch as Record<string, unknown>;\n const accounts = block.accounts;\n if (accounts && typeof accounts === 'object' && !Array.isArray(accounts)) {\n const acc = (accounts as Record<string, unknown>)[accountId];\n if (acc && typeof acc === 'object' && !Array.isArray(acc)) {\n return (acc as { enabled?: boolean }).enabled !== false;\n }\n }\n return true;\n}\n\nfunction resolveChannelDmPolicy(\n config: Config | undefined,\n channel: PairingCliChannel,\n accountId: string,\n): DmPolicy {\n const ch = config?.channels?.[channel as keyof NonNullable<Config['channels']>];\n if (!ch || typeof ch !== 'object' || Array.isArray(ch)) {\n return resolveDmPolicy(undefined, channel === 'weixin' ? 'open' : 'pairing');\n }\n const block = ch as Record<string, unknown>;\n const accounts = block.accounts;\n if (accounts && typeof accounts === 'object' && !Array.isArray(accounts)) {\n const acc = (accounts as Record<string, unknown>)[accountId];\n if (acc && typeof acc === 'object' && !Array.isArray(acc)) {\n const accPolicy = (acc as { dmPolicy?: DmPolicy }).dmPolicy;\n if (accPolicy) return resolveDmPolicy(accPolicy, 'pairing');\n }\n }\n const topPolicy = block.dmPolicy as DmPolicy | undefined;\n return resolveDmPolicy(topPolicy, channel === 'weixin' ? 'open' : 'pairing');\n}\n\nexport type ChannelPairingSummaryEntry = {\n pending: number;\n stale: number;\n atCapacity: boolean;\n};\n\nexport type ChannelPairingSummary = Record<PairingCliChannel, ChannelPairingSummaryEntry>;\n\nexport type PairingPendingIssue = {\n channel: PairingCliChannel;\n accountId: string;\n pending: number;\n stale: number;\n atCapacity: boolean;\n};\n\nfunction resolvePairingAccountIds(config: Config | undefined, channel: PairingCliChannel): string[] {\n const ch = config?.channels?.[channel as keyof NonNullable<Config['channels']>];\n if (!ch || typeof ch !== 'object' || Array.isArray(ch)) {\n return channel === 'telegram' ? ['default'] : [];\n }\n const block = ch as Record<string, unknown>;\n const accounts = block.accounts;\n if (accounts && typeof accounts === 'object' && !Array.isArray(accounts)) {\n const keys = Object.keys(accounts as Record<string, unknown>).sort();\n if (keys.length > 0) return keys;\n }\n if (channel === 'feishu') {\n const appId = typeof block.appId === 'string' ? block.appId.trim() : '';\n const appSecret = typeof block.appSecret === 'string' ? block.appSecret.trim() : '';\n return appId && appSecret ? ['default'] : [];\n }\n if (channel === 'telegram') return ['default'];\n return ['default'];\n}\n\nexport function listChannelPairingSummary(config?: Config): ChannelPairingSummary {\n const channels: PairingCliChannel[] = ['telegram', 'feishu', 'weixin'];\n const summary: ChannelPairingSummary = {\n telegram: { pending: 0, stale: 0, atCapacity: false },\n feishu: { pending: 0, stale: 0, atCapacity: false },\n weixin: { pending: 0, stale: 0, atCapacity: false },\n };\n for (const channel of channels) {\n if (!resolveChannelEnabled(config, channel)) continue;\n const accountIds = resolvePairingAccountIds(config, channel);\n for (const accountId of accountIds) {\n if (!resolveAccountEnabled(config, channel, accountId)) continue;\n if (resolveChannelDmPolicy(config, channel, accountId) !== 'pairing') continue;\n const { pairingPath } = resolvePairingPaths(channel, accountId);\n const pendingRaw = listPendingPairingRequestsSync(pairingPath).filter(\n (r) => requestAccountId(r) === accountId,\n );\n const stats = pendingEntryStats(pendingRaw);\n summary[channel].pending += stats.pending;\n summary[channel].stale += stats.stale;\n summary[channel].atCapacity ||= stats.atCapacity;\n }\n }\n return summary;\n}\n\nexport function collectPairingPendingIssues(config?: Config): PairingPendingIssue[] {\n const issues: PairingPendingIssue[] = [];\n for (const channel of ['telegram', 'feishu', 'weixin'] as const) {\n if (!resolveChannelEnabled(config, channel)) continue;\n const accountIds = resolvePairingAccountIds(config, channel);\n for (const accountId of accountIds) {\n if (!resolveAccountEnabled(config, channel, accountId)) continue;\n if (resolveChannelDmPolicy(config, channel, accountId) !== 'pairing') continue;\n const { pairingPath } = resolvePairingPaths(channel, accountId);\n const pendingRaw = listPendingPairingRequestsSync(pairingPath).filter(\n (r) => requestAccountId(r) === accountId,\n );\n const stats = pendingEntryStats(pendingRaw);\n if (stats.pending > 0) {\n issues.push({ channel, accountId, ...stats });\n }\n }\n }\n return issues;\n}\n\nexport function listChannelPairingState(params: {\n channel: PairingCliChannel;\n accountId?: string;\n config?: Config;\n}): ChannelPairingState {\n const accountId = normalizeAccountId(params.accountId);\n const { pairingPath, allowPath } = resolvePairingPaths(params.channel, accountId);\n const pendingRaw = listPendingPairingRequestsSync(pairingPath).filter(\n (r) => requestAccountId(r) === accountId,\n );\n return {\n channel: params.channel,\n accountId,\n dmPolicy: resolveChannelDmPolicy(params.config, params.channel, accountId),\n pending: pendingRaw.map(toPendingView),\n paired: {\n fromConfig: resolveChannelAllowFromConfig(params.config, params.channel, accountId),\n fromCredentials: readAllowFromIdsSync(allowPath),\n },\n };\n}\n\nexport function approveChannelPairing(params: {\n channel: PairingCliChannel;\n accountId?: string;\n code: string;\n}): { ok: true; senderId: string; alreadyPaired: boolean } | { ok: false; error: string } {\n const accountId = normalizeAccountId(params.accountId);\n const code = params.code.trim();\n if (!code) return { ok: false, error: 'Missing pairing code.' };\n\n const { pairingPath, allowPath } = resolvePairingPaths(params.channel, accountId);\n const alreadyPaired = readAllowFromIdsSync(allowPath);\n\n const result = approvePairingCodeSync({\n pairingFilePath: pairingPath,\n allowFromFilePath: allowPath,\n code,\n accountId,\n });\n if (!result) {\n return { ok: false, error: 'Invalid or expired pairing code (or wrong account).' };\n }\n broadcastPairingEvent('channels.pairing.approved', {\n channel: params.channel,\n accountId,\n senderId: result.senderId,\n });\n return {\n ok: true,\n senderId: result.senderId,\n alreadyPaired: alreadyPaired.includes(result.senderId),\n };\n}\n\nexport function approveChannelPairingBySender(params: {\n channel: PairingCliChannel;\n accountId?: string;\n senderId: string;\n}): { ok: true; senderId: string; alreadyPaired: boolean } | { ok: false; error: string } {\n const accountId = normalizeAccountId(params.accountId);\n const senderId = params.senderId.trim();\n if (!senderId) return { ok: false, error: 'Missing sender id.' };\n\n const { pairingPath, allowPath } = resolvePairingPaths(params.channel, accountId);\n const alreadyPaired = readAllowFromIdsSync(allowPath);\n\n const result = approvePairingBySenderIdSync({\n pairingFilePath: pairingPath,\n allowFromFilePath: allowPath,\n senderId,\n accountId,\n });\n if (!result) {\n return { ok: false, error: 'No pending pairing request for this sender (or wrong account).' };\n }\n broadcastPairingEvent('channels.pairing.approved', {\n channel: params.channel,\n accountId,\n senderId: result.senderId,\n });\n return {\n ok: true,\n senderId: result.senderId,\n alreadyPaired: alreadyPaired.includes(result.senderId),\n };\n}\n\nexport function revokeChannelPairingPaired(params: {\n channel: PairingCliChannel;\n accountId?: string;\n senderId: string;\n}): { ok: true; changed: boolean } | { ok: false; error: string } {\n const accountId = normalizeAccountId(params.accountId);\n const senderId = params.senderId.trim();\n if (!senderId) return { ok: false, error: 'Missing sender id.' };\n\n const { allowPath } = resolvePairingPaths(params.channel, accountId);\n const { changed } = removeAllowFromIdSync(allowPath, senderId);\n if (changed) {\n broadcastPairingEvent('channels.pairing.revoked', {\n channel: params.channel,\n accountId,\n senderId,\n });\n }\n return { ok: true, changed };\n}\n\nexport function dismissChannelPairingPending(params: {\n channel: PairingCliChannel;\n accountId?: string;\n senderId: string;\n}): { ok: true; senderId: string } | { ok: false; error: string } {\n const accountId = normalizeAccountId(params.accountId);\n const senderId = params.senderId.trim();\n if (!senderId) return { ok: false, error: 'Missing sender id.' };\n\n const { pairingPath } = resolvePairingPaths(params.channel, accountId);\n const result = dismissPairingBySenderIdSync({\n pairingFilePath: pairingPath,\n senderId,\n accountId,\n });\n if (!result) {\n return { ok: false, error: 'No pending pairing request for this sender (or wrong account).' };\n }\n broadcastPairingEvent('channels.pairing.dismissed', {\n channel: params.channel,\n accountId,\n senderId: result.senderId,\n });\n return { ok: true, senderId: result.senderId };\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"pairing-service.js","names":["block"],"sources":["../../../../src/channels/pairing/pairing-service.ts"],"sourcesContent":["import type { Config } from '../../config/schema.js';\nimport { resolveDmPolicy } from '../security.js';\nimport type { DmPolicy } from '../channel-domain.js';\n\nimport { readAllowFromIdsSync, removeAllowFromIdSync } from './allow-from-file.js';\nimport type { PairingCliChannel } from './pairing-channel.js';\nimport { broadcastPairingEvent } from './pairing-events.js';\nimport { PAIRING_PENDING_MAX, PAIRING_STALE_PENDING_MS } from './pairing-constants.js';\nimport {\n approvePairingBySenderIdSync,\n approvePairingCodeSync,\n dismissPairingBySenderIdSync,\n listPendingPairingRequestsSync,\n PAIRING_PENDING_TTL_MS,\n type PairingRequest,\n} from './pairing-store.js';\nimport {\n resolveStandardAllowFromPath,\n resolveStandardPairingPath,\n resolveWeixinAllowFromPath,\n resolveWeixinPairingPath,\n} from './paths.js';\n\n// `PairingPendingView` moved to `./pairing-types.js` (leaf) so\n// `plugins/types.adapters.ts` and other lower-level callers can reference it\n// without forming a `types.adapters → pairing-service → security → plugin-types\n// → types.adapters` cycle. Re-exported here for backward-compat.\nexport { type PairingPendingView } from './pairing-types.js';\nimport type { PairingPendingView } from './pairing-types.js';\n\nexport type ChannelPairingState = {\n channel: PairingCliChannel;\n accountId: string;\n dmPolicy: DmPolicy;\n pending: PairingPendingView[];\n paired: {\n fromConfig: string[];\n fromCredentials: string[];\n };\n};\n\nfunction normalizeAccountId(accountId: string | undefined): string {\n return (accountId ?? 'default').trim().toLowerCase() || 'default';\n}\n\nfunction resolvePairingPaths(channel: PairingCliChannel, accountId: string): {\n pairingPath: string;\n allowPath: string;\n} {\n const normalized = normalizeAccountId(accountId);\n if (channel === 'weixin') {\n return {\n pairingPath: resolveWeixinPairingPath(normalized),\n allowPath: resolveWeixinAllowFromPath(normalized),\n };\n }\n return {\n pairingPath: resolveStandardPairingPath(channel, normalized),\n allowPath: resolveStandardAllowFromPath(channel, normalized),\n };\n}\n\nfunction requestAccountId(entry: PairingRequest): string {\n const fromMeta = entry.meta?.accountId?.trim().toLowerCase();\n return fromMeta || 'default';\n}\n\nfunction toPendingView(entry: PairingRequest): PairingPendingView {\n const createdMs = Date.parse(entry.createdAt);\n const expiresAt = Number.isFinite(createdMs)\n ? new Date(createdMs + PAIRING_PENDING_TTL_MS).toISOString()\n : new Date(Date.now() + PAIRING_PENDING_TTL_MS).toISOString();\n const code = entry.code ?? '';\n const codeLast4 = code.length >= 4 ? code.slice(-4) : code;\n const meta =\n entry.meta && typeof entry.meta === 'object'\n ? Object.fromEntries(\n Object.entries(entry.meta).filter(\n ([k, v]) => k !== 'accountId' && typeof v === 'string' && v.trim() !== '',\n ),\n )\n : undefined;\n return {\n senderId: entry.id,\n codeLast4,\n createdAt: entry.createdAt,\n lastSeenAt: entry.lastSeenAt,\n expiresAt,\n isStale:\n Number.isFinite(createdMs) && Date.now() - (createdMs as number) >= PAIRING_STALE_PENDING_MS,\n meta: meta && Object.keys(meta).length > 0 ? meta : undefined,\n };\n}\n\nfunction pendingEntryStats(pending: PairingRequest[]): {\n pending: number;\n stale: number;\n atCapacity: boolean;\n} {\n const now = Date.now();\n let stale = 0;\n for (const p of pending) {\n const created = Date.parse(p.createdAt);\n if (Number.isFinite(created) && now - created >= PAIRING_STALE_PENDING_MS) {\n stale += 1;\n }\n }\n return {\n pending: pending.length,\n stale,\n atCapacity: pending.length >= PAIRING_PENDING_MAX,\n };\n}\n\nfunction resolveChannelAllowFromConfig(\n config: Config | undefined,\n channel: PairingCliChannel,\n accountId: string,\n): string[] {\n const ch = config?.channels?.[channel as keyof NonNullable<Config['channels']>];\n if (!ch || typeof ch !== 'object' || Array.isArray(ch)) return [];\n const block = ch as Record<string, unknown>;\n const top = Array.isArray(block.allowFrom)\n ? block.allowFrom.map(String).filter(Boolean)\n : [];\n const accounts = block.accounts;\n if (accounts && typeof accounts === 'object' && !Array.isArray(accounts)) {\n const acc = (accounts as Record<string, unknown>)[accountId];\n if (acc && typeof acc === 'object' && !Array.isArray(acc)) {\n const fromAcc = (acc as { allowFrom?: unknown }).allowFrom;\n if (Array.isArray(fromAcc)) {\n return [...new Set([...top, ...fromAcc.map(String).filter(Boolean)])];\n }\n }\n }\n return [...new Set(top)];\n}\n\nfunction resolveChannelEnabled(config: Config | undefined, channel: PairingCliChannel): boolean {\n const ch = config?.channels?.[channel as keyof NonNullable<Config['channels']>];\n if (!ch || typeof ch !== 'object' || Array.isArray(ch)) return false;\n return (ch as { enabled?: boolean }).enabled === true;\n}\n\nfunction resolveAccountEnabled(\n config: Config | undefined,\n channel: PairingCliChannel,\n accountId: string,\n): boolean {\n if (!resolveChannelEnabled(config, channel)) return false;\n const ch = config?.channels?.[channel as keyof NonNullable<Config['channels']>];\n if (!ch || typeof ch !== 'object' || Array.isArray(ch)) return true;\n const block = ch as Record<string, unknown>;\n const accounts = block.accounts;\n if (accounts && typeof accounts === 'object' && !Array.isArray(accounts)) {\n const acc = (accounts as Record<string, unknown>)[accountId];\n if (acc && typeof acc === 'object' && !Array.isArray(acc)) {\n return (acc as { enabled?: boolean }).enabled !== false;\n }\n }\n return true;\n}\n\nfunction resolveChannelDmPolicy(\n config: Config | undefined,\n channel: PairingCliChannel,\n accountId: string,\n): DmPolicy {\n const ch = config?.channels?.[channel as keyof NonNullable<Config['channels']>];\n if (!ch || typeof ch !== 'object' || Array.isArray(ch)) {\n return resolveDmPolicy(undefined, channel === 'weixin' ? 'open' : 'pairing');\n }\n const block = ch as Record<string, unknown>;\n const accounts = block.accounts;\n if (accounts && typeof accounts === 'object' && !Array.isArray(accounts)) {\n const acc = (accounts as Record<string, unknown>)[accountId];\n if (acc && typeof acc === 'object' && !Array.isArray(acc)) {\n const accPolicy = (acc as { dmPolicy?: DmPolicy }).dmPolicy;\n if (accPolicy) return resolveDmPolicy(accPolicy, 'pairing');\n }\n }\n const topPolicy = block.dmPolicy as DmPolicy | undefined;\n return resolveDmPolicy(topPolicy, channel === 'weixin' ? 'open' : 'pairing');\n}\n\nexport type ChannelPairingSummaryEntry = {\n pending: number;\n stale: number;\n atCapacity: boolean;\n};\n\nexport type ChannelPairingSummary = Record<string, ChannelPairingSummaryEntry>;\n\nexport type PairingPendingIssue = {\n channel: PairingCliChannel;\n accountId: string;\n pending: number;\n stale: number;\n atCapacity: boolean;\n};\n\nfunction resolvePairingAccountIds(config: Config | undefined, channel: PairingCliChannel): string[] {\n const ch = config?.channels?.[channel as keyof NonNullable<Config['channels']>];\n if (!ch || typeof ch !== 'object' || Array.isArray(ch)) {\n return channel === 'telegram' ? ['default'] : [];\n }\n const block = ch as Record<string, unknown>;\n const accounts = block.accounts;\n if (accounts && typeof accounts === 'object' && !Array.isArray(accounts)) {\n const keys = Object.keys(accounts as Record<string, unknown>).sort();\n if (keys.length > 0) return keys;\n }\n if (channel === 'feishu') {\n const appId = typeof block.appId === 'string' ? block.appId.trim() : '';\n const appSecret = typeof block.appSecret === 'string' ? block.appSecret.trim() : '';\n return appId && appSecret ? ['default'] : [];\n }\n if (channel === 'telegram') return ['default'];\n return ['default'];\n}\n\nexport function listChannelPairingSummary(config?: Config): ChannelPairingSummary {\n const channels = Object.keys(config?.channels ?? {});\n const summary: ChannelPairingSummary = {};\n for (const channel of channels) {\n if (!resolveChannelEnabled(config, channel)) continue;\n summary[channel] = { pending: 0, stale: 0, atCapacity: false };\n const accountIds = resolvePairingAccountIds(config, channel);\n for (const accountId of accountIds) {\n if (!resolveAccountEnabled(config, channel, accountId)) continue;\n if (resolveChannelDmPolicy(config, channel, accountId) !== 'pairing') continue;\n const { pairingPath } = resolvePairingPaths(channel, accountId);\n const pendingRaw = listPendingPairingRequestsSync(pairingPath).filter(\n (r) => requestAccountId(r) === accountId,\n );\n const stats = pendingEntryStats(pendingRaw);\n summary[channel]!.pending += stats.pending;\n summary[channel]!.stale += stats.stale;\n summary[channel]!.atCapacity ||= stats.atCapacity;\n }\n }\n return summary;\n}\n\nexport function collectPairingPendingIssues(config?: Config): PairingPendingIssue[] {\n const issues: PairingPendingIssue[] = [];\n for (const channel of Object.keys(config?.channels ?? {})) {\n if (!resolveChannelEnabled(config, channel)) continue;\n const accountIds = resolvePairingAccountIds(config, channel);\n for (const accountId of accountIds) {\n if (!resolveAccountEnabled(config, channel, accountId)) continue;\n if (resolveChannelDmPolicy(config, channel, accountId) !== 'pairing') continue;\n const { pairingPath } = resolvePairingPaths(channel, accountId);\n const pendingRaw = listPendingPairingRequestsSync(pairingPath).filter(\n (r) => requestAccountId(r) === accountId,\n );\n const stats = pendingEntryStats(pendingRaw);\n if (stats.pending > 0) {\n issues.push({ channel, accountId, ...stats });\n }\n }\n }\n return issues;\n}\n\nexport function listChannelPairingState(params: {\n channel: PairingCliChannel;\n accountId?: string;\n config?: Config;\n}): ChannelPairingState {\n const accountId = normalizeAccountId(params.accountId);\n const { pairingPath, allowPath } = resolvePairingPaths(params.channel, accountId);\n const pendingRaw = listPendingPairingRequestsSync(pairingPath).filter(\n (r) => requestAccountId(r) === accountId,\n );\n return {\n channel: params.channel,\n accountId,\n dmPolicy: resolveChannelDmPolicy(params.config, params.channel, accountId),\n pending: pendingRaw.map(toPendingView),\n paired: {\n fromConfig: resolveChannelAllowFromConfig(params.config, params.channel, accountId),\n fromCredentials: readAllowFromIdsSync(allowPath),\n },\n };\n}\n\nexport function approveChannelPairing(params: {\n channel: PairingCliChannel;\n accountId?: string;\n code: string;\n}): { ok: true; senderId: string; alreadyPaired: boolean } | { ok: false; error: string } {\n const accountId = normalizeAccountId(params.accountId);\n const code = params.code.trim();\n if (!code) return { ok: false, error: 'Missing pairing code.' };\n\n const { pairingPath, allowPath } = resolvePairingPaths(params.channel, accountId);\n const alreadyPaired = readAllowFromIdsSync(allowPath);\n\n const result = approvePairingCodeSync({\n pairingFilePath: pairingPath,\n allowFromFilePath: allowPath,\n code,\n accountId,\n });\n if (!result) {\n return { ok: false, error: 'Invalid or expired pairing code (or wrong account).' };\n }\n broadcastPairingEvent('channels.pairing.approved', {\n channel: params.channel,\n accountId,\n senderId: result.senderId,\n });\n return {\n ok: true,\n senderId: result.senderId,\n alreadyPaired: alreadyPaired.includes(result.senderId),\n };\n}\n\nexport function approveChannelPairingBySender(params: {\n channel: PairingCliChannel;\n accountId?: string;\n senderId: string;\n}): { ok: true; senderId: string; alreadyPaired: boolean } | { ok: false; error: string } {\n const accountId = normalizeAccountId(params.accountId);\n const senderId = params.senderId.trim();\n if (!senderId) return { ok: false, error: 'Missing sender id.' };\n\n const { pairingPath, allowPath } = resolvePairingPaths(params.channel, accountId);\n const alreadyPaired = readAllowFromIdsSync(allowPath);\n\n const result = approvePairingBySenderIdSync({\n pairingFilePath: pairingPath,\n allowFromFilePath: allowPath,\n senderId,\n accountId,\n });\n if (!result) {\n return { ok: false, error: 'No pending pairing request for this sender (or wrong account).' };\n }\n broadcastPairingEvent('channels.pairing.approved', {\n channel: params.channel,\n accountId,\n senderId: result.senderId,\n });\n return {\n ok: true,\n senderId: result.senderId,\n alreadyPaired: alreadyPaired.includes(result.senderId),\n };\n}\n\nexport function revokeChannelPairingPaired(params: {\n channel: PairingCliChannel;\n accountId?: string;\n senderId: string;\n}): { ok: true; changed: boolean } | { ok: false; error: string } {\n const accountId = normalizeAccountId(params.accountId);\n const senderId = params.senderId.trim();\n if (!senderId) return { ok: false, error: 'Missing sender id.' };\n\n const { allowPath } = resolvePairingPaths(params.channel, accountId);\n const { changed } = removeAllowFromIdSync(allowPath, senderId);\n if (changed) {\n broadcastPairingEvent('channels.pairing.revoked', {\n channel: params.channel,\n accountId,\n senderId,\n });\n }\n return { ok: true, changed };\n}\n\nexport function dismissChannelPairingPending(params: {\n channel: PairingCliChannel;\n accountId?: string;\n senderId: string;\n}): { ok: true; senderId: string } | { ok: false; error: string } {\n const accountId = normalizeAccountId(params.accountId);\n const senderId = params.senderId.trim();\n if (!senderId) return { ok: false, error: 'Missing sender id.' };\n\n const { pairingPath } = resolvePairingPaths(params.channel, accountId);\n const result = dismissPairingBySenderIdSync({\n pairingFilePath: pairingPath,\n senderId,\n accountId,\n });\n if (!result) {\n return { ok: false, error: 'No pending pairing request for this sender (or wrong account).' };\n }\n broadcastPairingEvent('channels.pairing.dismissed', {\n channel: params.channel,\n accountId,\n senderId: result.senderId,\n });\n return { ok: true, senderId: result.senderId };\n}\n"],"mappings":"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"}
@@ -4,7 +4,7 @@
4
4
  import type { Config } from '../config/schema.js';
5
5
  import type { MessageBus } from '../infra/bus/index.js';
6
6
  import type { ChannelId, ChannelMeta, ChannelCapabilities } from './plugins/types.core.js';
7
- import type { ChannelPairingAdapter, ChannelAllowlistAdapter, ChannelThreadingAdapter, ChannelLifecycleAdapter, ChannelHeartbeatAdapter, ChannelConfiguredBindingProvider, ChannelMessagingAdapter, ChannelDirectoryAdapter, ChannelResolverAdapter, ChannelAuthAdapter, ChannelElevatedAdapter, ChannelExecApprovalAdapter, ChannelAgentPromptAdapter, ChannelSetupWizard, ChannelCronDeliveryAdapter, ChannelCliLoginAdapter, ChannelConfigSurfaceAdapter, ChannelOnboardAdapter } from './plugins/types.adapters.js';
7
+ import type { ChannelPairingAdapter, ChannelAllowlistAdapter, ChannelThreadingAdapter, ChannelLifecycleAdapter, ChannelHeartbeatAdapter, ChannelConfiguredBindingProvider, ChannelMessagingAdapter, ChannelDirectoryAdapter, ChannelResolverAdapter, ChannelAuthAdapter, ChannelElevatedAdapter, ChannelExecApprovalAdapter, ChannelAgentPromptAdapter, ChannelSetupWizard, ChannelCronDeliveryAdapter, ChannelCliLoginAdapter, ChannelConfigSurfaceAdapter, ChannelOnboardAdapter, ChannelRuntimeActionAdapter } from './plugins/types.adapters.js';
8
8
  export type { ChannelId, ChatType, ChannelMeta, ChannelCapabilities } from './plugins/types.core.js';
9
9
  import type { DmPolicy, GroupPolicy } from './channel-domain.js';
10
10
  export type { DmPolicy, GroupPolicy };
@@ -79,6 +79,7 @@ export interface ChannelDoctorCheckResult {
79
79
  export interface ChannelDoctorAdapter {
80
80
  check(params: {
81
81
  cfg: Config;
82
+ locale?: string;
82
83
  }): Promise<ChannelDoctorCheckResult[]>;
83
84
  }
84
85
  export interface ChannelPlugin<ResolvedAccount = any> {
@@ -123,6 +124,7 @@ export interface ChannelPlugin<ResolvedAccount = any> {
123
124
  resolver?: ChannelResolverAdapter;
124
125
  commands?: ChannelCommandAdapter;
125
126
  actions?: ChannelMessageActionAdapter;
127
+ runtimeActions?: ChannelRuntimeActionAdapter;
126
128
  auth?: ChannelAuthAdapter;
127
129
  elevated?: ChannelElevatedAdapter;
128
130
  execApprovals?: ChannelExecApprovalAdapter;
@@ -7,7 +7,7 @@ import type { SessionStore } from '../../session/store.js';
7
7
  import type { PairingPendingView } from '../pairing/pairing-types.js';
8
8
  export interface ChannelPairingAdapter {
9
9
  /** Credential-store channel key (`telegram` | `feishu` | `weixin`). */
10
- pairingChannel: 'telegram' | 'feishu' | 'weixin';
10
+ pairingChannel: string;
11
11
  listPending(params: {
12
12
  cfg: Config;
13
13
  accountId?: string;
@@ -134,6 +134,59 @@ export interface ChannelAgentPromptAdapter {
134
134
  accountId?: string;
135
135
  }): string | undefined;
136
136
  }
137
+ export type ChannelRuntimeActionPayload = {
138
+ type: 'ok';
139
+ message?: string;
140
+ configChanged?: boolean;
141
+ [key: string]: unknown;
142
+ } | {
143
+ type: 'qr';
144
+ sessionKey: string;
145
+ qrcodeUrl?: string;
146
+ qrPayload?: string;
147
+ statusAction?: string;
148
+ pollIntervalMs?: number;
149
+ expiresInSec?: number;
150
+ message?: string;
151
+ [key: string]: unknown;
152
+ } | {
153
+ type: 'poll';
154
+ phase: 'pending' | 'done' | 'unknown';
155
+ ok?: boolean;
156
+ message?: string;
157
+ accountId?: string;
158
+ qrcodeUrl?: string;
159
+ qrPayload?: string;
160
+ qrStatus?: string;
161
+ configChanged?: boolean;
162
+ [key: string]: unknown;
163
+ } | {
164
+ type: 'diagnostics';
165
+ checks: unknown[];
166
+ [key: string]: unknown;
167
+ } | {
168
+ type: 'form';
169
+ schema: Record<string, unknown>;
170
+ values?: Record<string, unknown>;
171
+ submitAction: string;
172
+ message?: string;
173
+ [key: string]: unknown;
174
+ };
175
+ export interface ChannelRuntimeActionResult {
176
+ ok: boolean;
177
+ payload?: ChannelRuntimeActionPayload;
178
+ message?: string;
179
+ }
180
+ /** Gateway/CLI control-plane actions declared by extension manifests. */
181
+ export interface ChannelRuntimeActionAdapter {
182
+ runAction(params: {
183
+ cfg: Config;
184
+ locale?: string;
185
+ actionId: string;
186
+ accountId?: string;
187
+ input?: unknown;
188
+ }): Promise<ChannelRuntimeActionResult>;
189
+ }
137
190
  /**
138
191
  * Resolves a cron job `delivery.to` string into a normalized chat target for outbound.
139
192
  */
@@ -144,7 +197,7 @@ export interface ChannelCronDeliveryAdapter {
144
197
  metadata?: Record<string, unknown>;
145
198
  }>;
146
199
  }
147
- /** CLI `xopc channels login --channel` for channels that support interactive login. */
200
+ /** Interactive credential login for channels that support terminal setup. */
148
201
  export interface ChannelCliLoginAdapter {
149
202
  runLogin(params: {
150
203
  configPath: string;
@@ -1,6 +1,6 @@
1
+ import { defineChannelPluginEntry } from "../../extensions/sdk/channel-entry.js";
1
2
  import { normalizeTelegramDeliveryChatId } from "../../../extensions/telegram/src/delivery-chat-id.js";
2
3
  import { telegramPlugin } from "../../../extensions/telegram/src/plugin.js";
3
- import { defineChannelPluginEntry } from "../../extensions/sdk/channel-entry.js";
4
4
  import "../../../extensions/telegram/src/index.js";
5
5
  import { generateSessionKeyWithRouting } from "../../../extensions/telegram/src/routing-integration.js";
6
6
  export { defineChannelPluginEntry, generateSessionKeyWithRouting, normalizeTelegramDeliveryChatId, telegramPlugin };
@@ -5,9 +5,9 @@ import { ConfigSchema, init_schema } from "../../config/schema.js";
5
5
  import { init_loader, loadConfig, saveConfig } from "../../config/loader.js";
6
6
  import { init_session_key, parseSessionKey } from "../../routing/session-key.js";
7
7
  import { commandRegistry } from "../registry.js";
8
- import { resolveAllowlistMatchSimple } from "../../channels/security.js";
9
8
  import { parseConfigValue } from "../config-value.js";
10
9
  import { getConfigValueAtPath, parseConfigPath, setConfigValueAtPath, unsetConfigValueAtPath } from "../config-paths.js";
10
+ import { resolveAllowlistMatchSimple } from "../../channels/security.js";
11
11
  //#region src/chat-commands/builtins/config.ts
12
12
  init_schema();
13
13
  init_loader();
@@ -83,8 +83,8 @@ const configCommand = {
83
83
  acceptsArgs: true,
84
84
  examples: [
85
85
  "/config show",
86
- "/config show agents.defaults.model",
87
- "/config set agents.defaults.model=anthropic/claude-opus-4-5",
86
+ "/config show agents.defaults.models.chat",
87
+ "/config set agents.defaults.models.chat.primary=anthropic/claude-opus-4-5",
88
88
  "/config set agents.defaults.temperature=0.5",
89
89
  "/config unset tts"
90
90
  ],
@@ -185,7 +185,7 @@ const configCommand = {
185
185
  log.info({ path: rest }, "Config key removed via /config unset");
186
186
  return { content: `⚙️ Config updated: \`${rest}\` removed.` };
187
187
  }
188
- return { content: "⚙️ *Config Command*\n\n`/config show [path]` — view config (or a specific path)\n`/config set path=value` — update a config value\n`/config unset path` — remove a config key\n\nExamples:\n`/config show agents.defaults.model`\n`/config set agents.defaults.temperature=0.5`\n`/config set agents.defaults.thinkingDefault=medium`\n`/config unset tts`" };
188
+ return { content: "⚙️ *Config Command*\n\n`/config show [path]` — view config (or a specific path)\n`/config set path=value` — update a config value\n`/config unset path` — remove a config key\n\nExamples:\n`/config show agents.defaults.models.chat`\n`/config set agents.defaults.temperature=0.5`\n`/config set agents.defaults.thinkingDefault=medium`\n`/config unset tts`" };
189
189
  }
190
190
  };
191
191
  function registerConfigCommand() {
@@ -1 +1 @@
1
- {"version":3,"file":"config.js","names":[],"sources":["../../../../src/chat-commands/builtins/config.ts"],"sourcesContent":["/**\n * /config — read and write persistent config (~/.xopc/xopc.json) from chat.\n */\n\nimport type { CommandDefinition, CommandContext } from '../types.js';\nimport { commandRegistry } from '../registry.js';\nimport { parseConfigValue } from '../config-value.js';\nimport {\n parseConfigPath,\n getConfigValueAtPath,\n setConfigValueAtPath,\n unsetConfigValueAtPath,\n} from '../config-paths.js';\nimport { ConfigSchema, type TelegramConfig, type WeixinConfig } from '../../config/schema.js';\nimport { loadConfig, saveConfig } from '../../config/loader.js';\nimport { resolveConfigPath } from '../../config/paths.js';\nimport { createLogger } from '../../utils/logger.js';\nimport { parseSessionKey } from '../../routing/session-key.js';\nimport { resolveAllowlistMatchSimple } from '../../channels/security.js';\n\nconst log = createLogger('ConfigCommand');\n\nconst BLOCKED_WRITE_PATHS = new Set(['gateway.auth.token', 'providers']);\n\nfunction isBlockedPath(path: string[]): boolean {\n const joined = path.join('.');\n for (const blocked of BLOCKED_WRITE_PATHS) {\n if (joined === blocked || joined.startsWith(`${blocked}.`)) return true;\n }\n return false;\n}\n\nfunction redactConfigForDisplay(plain: Record<string, unknown>): void {\n if (plain.gateway && typeof plain.gateway === 'object') {\n const gw = plain.gateway as Record<string, unknown>;\n if (gw.auth && typeof gw.auth === 'object') {\n (gw.auth as Record<string, unknown>).token = '[redacted]';\n }\n }\n if (plain.providers !== undefined) plain.providers = '[redacted]';\n}\n\nfunction senderMayWritePersistentConfig(ctx: CommandContext): boolean {\n const { source, senderId, isGroup, sessionKey } = ctx;\n if (source !== 'telegram' && source !== 'weixin') {\n return true;\n }\n\n const cfg = ctx.getConfig?.() ?? ctx.config;\n\n if (source === 'weixin') {\n const wx = cfg.channels?.weixin as WeixinConfig | undefined;\n if (!wx?.enabled) return false;\n const parsed = parseSessionKey(sessionKey);\n const accountId = parsed?.accountId ?? 'default';\n let allowFrom: Array<string | number> = [];\n if (wx.accounts && Object.keys(wx.accounts).length > 0) {\n const acc = wx.accounts[accountId] ?? wx.accounts['default'];\n if (!acc || acc.enabled === false) return false;\n allowFrom = [...(acc.allowFrom ?? [])];\n } else {\n allowFrom = [...(wx.allowFrom ?? [])];\n }\n if (allowFrom.length === 0) return false;\n return resolveAllowlistMatchSimple({ allowFrom, senderId }).allowed;\n }\n\n const tg = cfg.channels?.telegram as TelegramConfig | undefined;\n if (!tg?.enabled) return false;\n const parsed = parseSessionKey(sessionKey);\n const accountId = parsed?.accountId ?? 'default';\n let allowFrom: Array<string | number> = [];\n let groupAllowFrom: Array<string | number> = [];\n if (tg.accounts && Object.keys(tg.accounts).length > 0) {\n const acc = tg.accounts[accountId] ?? tg.accounts['default'];\n if (!acc || acc.enabled === false) return false;\n allowFrom = [...(acc.allowFrom ?? [])];\n groupAllowFrom = [...(acc.groupAllowFrom ?? [])];\n } else {\n allowFrom = [...(tg.allowFrom ?? [])];\n groupAllowFrom = [...(tg.groupAllowFrom ?? [])];\n }\n const list = isGroup && groupAllowFrom.length > 0 ? groupAllowFrom : allowFrom;\n if (list.length === 0) return false;\n return resolveAllowlistMatchSimple({ allowFrom: list, senderId }).allowed;\n}\n\nconst configCommand: CommandDefinition = {\n id: 'system.config',\n name: 'config',\n aliases: ['cfg'],\n description:\n 'Show or update configuration. Usage: /config show [path] | /config set path=value | /config unset path',\n category: 'system',\n scope: ['global', 'private', 'group'],\n acceptsArgs: true,\n examples: [\n '/config show',\n '/config show agents.defaults.model',\n '/config set agents.defaults.model=anthropic/claude-opus-4-5',\n '/config set agents.defaults.temperature=0.5',\n '/config unset tts',\n ],\n handler: async (ctx: CommandContext, args: string) => {\n const parts = args.trim().split(/\\s+/);\n const action = parts[0]?.toLowerCase();\n const rest = parts.slice(1).join(' ').trim();\n\n if (!action || action === 'show' || action === 'get') {\n const config = ctx.getConfig?.() ?? loadConfig(resolveConfigPath());\n const plain = JSON.parse(JSON.stringify(config)) as Record<string, unknown>;\n redactConfigForDisplay(plain);\n\n if (rest) {\n const parsed = parseConfigPath(rest);\n if (!parsed.ok || !parsed.path) {\n return { content: `⚠️ ${parsed.error ?? 'Invalid path.'}`, success: false };\n }\n const value = getConfigValueAtPath(plain, parsed.path);\n const rendered = JSON.stringify(value ?? null, null, 2);\n return { content: `⚙️ \\`${rest}\\`:\\n\\`\\`\\`json\\n${rendered}\\n\\`\\`\\`` };\n }\n\n const json = JSON.stringify(plain, null, 2);\n return { content: `⚙️ Current config:\\n\\`\\`\\`json\\n${json}\\n\\`\\`\\`` };\n }\n\n if (action === 'set') {\n if (!senderMayWritePersistentConfig(ctx)) {\n return {\n content: '⚠️ You are not allowed to change config from this chat surface.',\n success: false,\n };\n }\n const eqIndex = rest.indexOf('=');\n if (eqIndex <= 0) {\n return { content: '⚠️ Usage: /config set path=value', success: false };\n }\n const pathRaw = rest.slice(0, eqIndex).trim();\n const valueRaw = rest.slice(eqIndex + 1);\n\n const parsedPath = parseConfigPath(pathRaw);\n if (!parsedPath.ok || !parsedPath.path) {\n return { content: `⚠️ ${parsedPath.error}`, success: false };\n }\n if (isBlockedPath(parsedPath.path)) {\n return {\n content: `⚠️ Path \\`${pathRaw}\\` cannot be modified via chat for security reasons.`,\n success: false,\n };\n }\n\n const parsedValue = parseConfigValue(valueRaw);\n if (parsedValue.ok === false) {\n return { content: `⚠️ ${parsedValue.error}`, success: false };\n }\n\n const configPath = resolveConfigPath();\n const currentConfig = loadConfig(configPath) as Record<string, unknown>;\n setConfigValueAtPath(currentConfig, parsedPath.path, parsedValue.value);\n\n const validated = ConfigSchema.safeParse(currentConfig);\n if (!validated.success) {\n const firstIssue = validated.error.issues[0];\n const fieldPath = firstIssue.path.join('.');\n return {\n content: `⚠️ Config invalid after set (${fieldPath}: ${firstIssue.message}). Change not saved.`,\n success: false,\n };\n }\n\n await saveConfig(validated.data);\n log.info({ path: pathRaw, value: parsedValue.value }, 'Config updated via /config set');\n\n const valueLabel =\n typeof parsedValue.value === 'string'\n ? `\"${parsedValue.value}\"`\n : JSON.stringify(parsedValue.value);\n return { content: `⚙️ Config updated: \\`${pathRaw}\\` = ${valueLabel}` };\n }\n\n if (action === 'unset') {\n if (!senderMayWritePersistentConfig(ctx)) {\n return {\n content: '⚠️ You are not allowed to change config from this chat surface.',\n success: false,\n };\n }\n if (!rest) {\n return { content: '⚠️ Usage: /config unset path', success: false };\n }\n const parsedPath = parseConfigPath(rest);\n if (!parsedPath.ok || !parsedPath.path) {\n return { content: `⚠️ ${parsedPath.error}`, success: false };\n }\n if (isBlockedPath(parsedPath.path)) {\n return {\n content: `⚠️ Path \\`${rest}\\` cannot be modified via chat for security reasons.`,\n success: false,\n };\n }\n\n const configPath = resolveConfigPath();\n const currentConfig = loadConfig(configPath) as Record<string, unknown>;\n const removed = unsetConfigValueAtPath(currentConfig, parsedPath.path);\n if (!removed) {\n return { content: `⚙️ No config value found at \\`${rest}\\`.`, success: false };\n }\n\n const validated = ConfigSchema.safeParse(currentConfig);\n if (!validated.success) {\n const firstIssue = validated.error.issues[0];\n const fieldPath = firstIssue.path.join('.');\n return {\n content: `⚠️ Config invalid after unset (${fieldPath}: ${firstIssue.message}). Change not saved.`,\n success: false,\n };\n }\n\n await saveConfig(validated.data);\n log.info({ path: rest }, 'Config key removed via /config unset');\n return { content: `⚙️ Config updated: \\`${rest}\\` removed.` };\n }\n\n return {\n content:\n '⚙️ *Config Command*\\n\\n' +\n '`/config show [path]` — view config (or a specific path)\\n' +\n '`/config set path=value` — update a config value\\n' +\n '`/config unset path` — remove a config key\\n\\n' +\n 'Examples:\\n' +\n '`/config show agents.defaults.model`\\n' +\n '`/config set agents.defaults.temperature=0.5`\\n' +\n '`/config set agents.defaults.thinkingDefault=medium`\\n' +\n '`/config unset tts`',\n };\n },\n};\n\nexport function registerConfigCommand(): void {\n commandRegistry.register(configCommand);\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"config.js","names":[],"sources":["../../../../src/chat-commands/builtins/config.ts"],"sourcesContent":["/**\n * /config — read and write persistent config (~/.xopc/xopc.json) from chat.\n */\n\nimport type { CommandDefinition, CommandContext } from '../types.js';\nimport { commandRegistry } from '../registry.js';\nimport { parseConfigValue } from '../config-value.js';\nimport {\n parseConfigPath,\n getConfigValueAtPath,\n setConfigValueAtPath,\n unsetConfigValueAtPath,\n} from '../config-paths.js';\nimport { ConfigSchema, type TelegramConfig, type WeixinConfig } from '../../config/schema.js';\nimport { loadConfig, saveConfig } from '../../config/loader.js';\nimport { resolveConfigPath } from '../../config/paths.js';\nimport { createLogger } from '../../utils/logger.js';\nimport { parseSessionKey } from '../../routing/session-key.js';\nimport { resolveAllowlistMatchSimple } from '../../channels/security.js';\n\nconst log = createLogger('ConfigCommand');\n\nconst BLOCKED_WRITE_PATHS = new Set(['gateway.auth.token', 'providers']);\n\nfunction isBlockedPath(path: string[]): boolean {\n const joined = path.join('.');\n for (const blocked of BLOCKED_WRITE_PATHS) {\n if (joined === blocked || joined.startsWith(`${blocked}.`)) return true;\n }\n return false;\n}\n\nfunction redactConfigForDisplay(plain: Record<string, unknown>): void {\n if (plain.gateway && typeof plain.gateway === 'object') {\n const gw = plain.gateway as Record<string, unknown>;\n if (gw.auth && typeof gw.auth === 'object') {\n (gw.auth as Record<string, unknown>).token = '[redacted]';\n }\n }\n if (plain.providers !== undefined) plain.providers = '[redacted]';\n}\n\nfunction senderMayWritePersistentConfig(ctx: CommandContext): boolean {\n const { source, senderId, isGroup, sessionKey } = ctx;\n if (source !== 'telegram' && source !== 'weixin') {\n return true;\n }\n\n const cfg = ctx.getConfig?.() ?? ctx.config;\n\n if (source === 'weixin') {\n const wx = cfg.channels?.weixin as WeixinConfig | undefined;\n if (!wx?.enabled) return false;\n const parsed = parseSessionKey(sessionKey);\n const accountId = parsed?.accountId ?? 'default';\n let allowFrom: Array<string | number> = [];\n if (wx.accounts && Object.keys(wx.accounts).length > 0) {\n const acc = wx.accounts[accountId] ?? wx.accounts['default'];\n if (!acc || acc.enabled === false) return false;\n allowFrom = [...(acc.allowFrom ?? [])];\n } else {\n allowFrom = [...(wx.allowFrom ?? [])];\n }\n if (allowFrom.length === 0) return false;\n return resolveAllowlistMatchSimple({ allowFrom, senderId }).allowed;\n }\n\n const tg = cfg.channels?.telegram as TelegramConfig | undefined;\n if (!tg?.enabled) return false;\n const parsed = parseSessionKey(sessionKey);\n const accountId = parsed?.accountId ?? 'default';\n let allowFrom: Array<string | number> = [];\n let groupAllowFrom: Array<string | number> = [];\n if (tg.accounts && Object.keys(tg.accounts).length > 0) {\n const acc = tg.accounts[accountId] ?? tg.accounts['default'];\n if (!acc || acc.enabled === false) return false;\n allowFrom = [...(acc.allowFrom ?? [])];\n groupAllowFrom = [...(acc.groupAllowFrom ?? [])];\n } else {\n allowFrom = [...(tg.allowFrom ?? [])];\n groupAllowFrom = [...(tg.groupAllowFrom ?? [])];\n }\n const list = isGroup && groupAllowFrom.length > 0 ? groupAllowFrom : allowFrom;\n if (list.length === 0) return false;\n return resolveAllowlistMatchSimple({ allowFrom: list, senderId }).allowed;\n}\n\nconst configCommand: CommandDefinition = {\n id: 'system.config',\n name: 'config',\n aliases: ['cfg'],\n description:\n 'Show or update configuration. Usage: /config show [path] | /config set path=value | /config unset path',\n category: 'system',\n scope: ['global', 'private', 'group'],\n acceptsArgs: true,\n examples: [\n '/config show',\n '/config show agents.defaults.models.chat',\n '/config set agents.defaults.models.chat.primary=anthropic/claude-opus-4-5',\n '/config set agents.defaults.temperature=0.5',\n '/config unset tts',\n ],\n handler: async (ctx: CommandContext, args: string) => {\n const parts = args.trim().split(/\\s+/);\n const action = parts[0]?.toLowerCase();\n const rest = parts.slice(1).join(' ').trim();\n\n if (!action || action === 'show' || action === 'get') {\n const config = ctx.getConfig?.() ?? loadConfig(resolveConfigPath());\n const plain = JSON.parse(JSON.stringify(config)) as Record<string, unknown>;\n redactConfigForDisplay(plain);\n\n if (rest) {\n const parsed = parseConfigPath(rest);\n if (!parsed.ok || !parsed.path) {\n return { content: `⚠️ ${parsed.error ?? 'Invalid path.'}`, success: false };\n }\n const value = getConfigValueAtPath(plain, parsed.path);\n const rendered = JSON.stringify(value ?? null, null, 2);\n return { content: `⚙️ \\`${rest}\\`:\\n\\`\\`\\`json\\n${rendered}\\n\\`\\`\\`` };\n }\n\n const json = JSON.stringify(plain, null, 2);\n return { content: `⚙️ Current config:\\n\\`\\`\\`json\\n${json}\\n\\`\\`\\`` };\n }\n\n if (action === 'set') {\n if (!senderMayWritePersistentConfig(ctx)) {\n return {\n content: '⚠️ You are not allowed to change config from this chat surface.',\n success: false,\n };\n }\n const eqIndex = rest.indexOf('=');\n if (eqIndex <= 0) {\n return { content: '⚠️ Usage: /config set path=value', success: false };\n }\n const pathRaw = rest.slice(0, eqIndex).trim();\n const valueRaw = rest.slice(eqIndex + 1);\n\n const parsedPath = parseConfigPath(pathRaw);\n if (!parsedPath.ok || !parsedPath.path) {\n return { content: `⚠️ ${parsedPath.error}`, success: false };\n }\n if (isBlockedPath(parsedPath.path)) {\n return {\n content: `⚠️ Path \\`${pathRaw}\\` cannot be modified via chat for security reasons.`,\n success: false,\n };\n }\n\n const parsedValue = parseConfigValue(valueRaw);\n if (parsedValue.ok === false) {\n return { content: `⚠️ ${parsedValue.error}`, success: false };\n }\n\n const configPath = resolveConfigPath();\n const currentConfig = loadConfig(configPath) as Record<string, unknown>;\n setConfigValueAtPath(currentConfig, parsedPath.path, parsedValue.value);\n\n const validated = ConfigSchema.safeParse(currentConfig);\n if (!validated.success) {\n const firstIssue = validated.error.issues[0];\n const fieldPath = firstIssue.path.join('.');\n return {\n content: `⚠️ Config invalid after set (${fieldPath}: ${firstIssue.message}). Change not saved.`,\n success: false,\n };\n }\n\n await saveConfig(validated.data);\n log.info({ path: pathRaw, value: parsedValue.value }, 'Config updated via /config set');\n\n const valueLabel =\n typeof parsedValue.value === 'string'\n ? `\"${parsedValue.value}\"`\n : JSON.stringify(parsedValue.value);\n return { content: `⚙️ Config updated: \\`${pathRaw}\\` = ${valueLabel}` };\n }\n\n if (action === 'unset') {\n if (!senderMayWritePersistentConfig(ctx)) {\n return {\n content: '⚠️ You are not allowed to change config from this chat surface.',\n success: false,\n };\n }\n if (!rest) {\n return { content: '⚠️ Usage: /config unset path', success: false };\n }\n const parsedPath = parseConfigPath(rest);\n if (!parsedPath.ok || !parsedPath.path) {\n return { content: `⚠️ ${parsedPath.error}`, success: false };\n }\n if (isBlockedPath(parsedPath.path)) {\n return {\n content: `⚠️ Path \\`${rest}\\` cannot be modified via chat for security reasons.`,\n success: false,\n };\n }\n\n const configPath = resolveConfigPath();\n const currentConfig = loadConfig(configPath) as Record<string, unknown>;\n const removed = unsetConfigValueAtPath(currentConfig, parsedPath.path);\n if (!removed) {\n return { content: `⚙️ No config value found at \\`${rest}\\`.`, success: false };\n }\n\n const validated = ConfigSchema.safeParse(currentConfig);\n if (!validated.success) {\n const firstIssue = validated.error.issues[0];\n const fieldPath = firstIssue.path.join('.');\n return {\n content: `⚠️ Config invalid after unset (${fieldPath}: ${firstIssue.message}). Change not saved.`,\n success: false,\n };\n }\n\n await saveConfig(validated.data);\n log.info({ path: rest }, 'Config key removed via /config unset');\n return { content: `⚙️ Config updated: \\`${rest}\\` removed.` };\n }\n\n return {\n content:\n '⚙️ *Config Command*\\n\\n' +\n '`/config show [path]` — view config (or a specific path)\\n' +\n '`/config set path=value` — update a config value\\n' +\n '`/config unset path` — remove a config key\\n\\n' +\n 'Examples:\\n' +\n '`/config show agents.defaults.models.chat`\\n' +\n '`/config set agents.defaults.temperature=0.5`\\n' +\n '`/config set agents.defaults.thinkingDefault=medium`\\n' +\n '`/config unset tts`',\n };\n },\n};\n\nexport function registerConfigCommand(): void {\n commandRegistry.register(configCommand);\n}\n"],"mappings":"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"}
@@ -3,7 +3,7 @@ function parseConfigPath(raw) {
3
3
  const parts = raw.trim().split(".").map((p) => p.trim());
4
4
  if (parts.some((p) => !p)) return {
5
5
  ok: false,
6
- error: "Invalid path. Use dot notation (e.g. agents.defaults.model)."
6
+ error: "Invalid path. Use dot notation (e.g. agents.defaults.models.chat.primary)."
7
7
  };
8
8
  return {
9
9
  ok: true,
@@ -1 +1 @@
1
- {"version":3,"file":"config-paths.js","names":[],"sources":["../../../src/chat-commands/config-paths.ts"],"sourcesContent":["type PathNode = Record<string, unknown>;\n\nexport function parseConfigPath(raw: string): { ok: boolean; path?: string[]; error?: string } {\n const parts = raw.trim().split('.').map((p) => p.trim());\n if (parts.some((p) => !p)) {\n return { ok: false, error: 'Invalid path. Use dot notation (e.g. agents.defaults.model).' };\n }\n return { ok: true, path: parts };\n}\n\nexport function getConfigValueAtPath(root: PathNode, path: string[]): unknown {\n let cursor: unknown = root;\n for (const key of path) {\n if (typeof cursor !== 'object' || cursor === null) return undefined;\n cursor = (cursor as PathNode)[key];\n }\n return cursor;\n}\n\nexport function setConfigValueAtPath(root: PathNode, path: string[], value: unknown): void {\n let cursor: PathNode = root;\n for (let i = 0; i < path.length - 1; i++) {\n const key = path[i];\n if (typeof cursor[key] !== 'object' || cursor[key] === null) cursor[key] = {};\n cursor = cursor[key] as PathNode;\n }\n cursor[path[path.length - 1]] = value;\n}\n\nexport function unsetConfigValueAtPath(root: PathNode, path: string[]): boolean {\n let cursor: PathNode = root;\n for (let i = 0; i < path.length - 1; i++) {\n const next = cursor[path[i]];\n if (typeof next !== 'object' || next === null) return false;\n cursor = next as PathNode;\n }\n const leaf = path[path.length - 1];\n if (!(leaf in cursor)) return false;\n delete cursor[leaf];\n return true;\n}\n"],"mappings":";AAEA,SAAgB,gBAAgB,KAA+D;CAC7F,MAAM,QAAQ,IAAI,MAAM,CAAC,MAAM,IAAI,CAAC,KAAK,MAAM,EAAE,MAAM,CAAC;AACxD,KAAI,MAAM,MAAM,MAAM,CAAC,EAAE,CACvB,QAAO;EAAE,IAAI;EAAO,OAAO;EAAgE;AAE7F,QAAO;EAAE,IAAI;EAAM,MAAM;EAAO;;AAGlC,SAAgB,qBAAqB,MAAgB,MAAyB;CAC5E,IAAI,SAAkB;AACtB,MAAK,MAAM,OAAO,MAAM;AACtB,MAAI,OAAO,WAAW,YAAY,WAAW,KAAM,QAAO,KAAA;AAC1D,WAAU,OAAoB;;AAEhC,QAAO;;AAGT,SAAgB,qBAAqB,MAAgB,MAAgB,OAAsB;CACzF,IAAI,SAAmB;AACvB,MAAK,IAAI,IAAI,GAAG,IAAI,KAAK,SAAS,GAAG,KAAK;EACxC,MAAM,MAAM,KAAK;AACjB,MAAI,OAAO,OAAO,SAAS,YAAY,OAAO,SAAS,KAAM,QAAO,OAAO,EAAE;AAC7E,WAAS,OAAO;;AAElB,QAAO,KAAK,KAAK,SAAS,MAAM;;AAGlC,SAAgB,uBAAuB,MAAgB,MAAyB;CAC9E,IAAI,SAAmB;AACvB,MAAK,IAAI,IAAI,GAAG,IAAI,KAAK,SAAS,GAAG,KAAK;EACxC,MAAM,OAAO,OAAO,KAAK;AACzB,MAAI,OAAO,SAAS,YAAY,SAAS,KAAM,QAAO;AACtD,WAAS;;CAEX,MAAM,OAAO,KAAK,KAAK,SAAS;AAChC,KAAI,EAAE,QAAQ,QAAS,QAAO;AAC9B,QAAO,OAAO;AACd,QAAO"}
1
+ {"version":3,"file":"config-paths.js","names":[],"sources":["../../../src/chat-commands/config-paths.ts"],"sourcesContent":["type PathNode = Record<string, unknown>;\n\nexport function parseConfigPath(raw: string): { ok: boolean; path?: string[]; error?: string } {\n const parts = raw.trim().split('.').map((p) => p.trim());\n if (parts.some((p) => !p)) {\n return { ok: false, error: 'Invalid path. Use dot notation (e.g. agents.defaults.models.chat.primary).' };\n }\n return { ok: true, path: parts };\n}\n\nexport function getConfigValueAtPath(root: PathNode, path: string[]): unknown {\n let cursor: unknown = root;\n for (const key of path) {\n if (typeof cursor !== 'object' || cursor === null) return undefined;\n cursor = (cursor as PathNode)[key];\n }\n return cursor;\n}\n\nexport function setConfigValueAtPath(root: PathNode, path: string[], value: unknown): void {\n let cursor: PathNode = root;\n for (let i = 0; i < path.length - 1; i++) {\n const key = path[i];\n if (typeof cursor[key] !== 'object' || cursor[key] === null) cursor[key] = {};\n cursor = cursor[key] as PathNode;\n }\n cursor[path[path.length - 1]] = value;\n}\n\nexport function unsetConfigValueAtPath(root: PathNode, path: string[]): boolean {\n let cursor: PathNode = root;\n for (let i = 0; i < path.length - 1; i++) {\n const next = cursor[path[i]];\n if (typeof next !== 'object' || next === null) return false;\n cursor = next as PathNode;\n }\n const leaf = path[path.length - 1];\n if (!(leaf in cursor)) return false;\n delete cursor[leaf];\n return true;\n}\n"],"mappings":";AAEA,SAAgB,gBAAgB,KAA+D;CAC7F,MAAM,QAAQ,IAAI,MAAM,CAAC,MAAM,IAAI,CAAC,KAAK,MAAM,EAAE,MAAM,CAAC;AACxD,KAAI,MAAM,MAAM,MAAM,CAAC,EAAE,CACvB,QAAO;EAAE,IAAI;EAAO,OAAO;EAA8E;AAE3G,QAAO;EAAE,IAAI;EAAM,MAAM;EAAO;;AAGlC,SAAgB,qBAAqB,MAAgB,MAAyB;CAC5E,IAAI,SAAkB;AACtB,MAAK,MAAM,OAAO,MAAM;AACtB,MAAI,OAAO,WAAW,YAAY,WAAW,KAAM,QAAO,KAAA;AAC1D,WAAU,OAAoB;;AAEhC,QAAO;;AAGT,SAAgB,qBAAqB,MAAgB,MAAgB,OAAsB;CACzF,IAAI,SAAmB;AACvB,MAAK,IAAI,IAAI,GAAG,IAAI,KAAK,SAAS,GAAG,KAAK;EACxC,MAAM,MAAM,KAAK;AACjB,MAAI,OAAO,OAAO,SAAS,YAAY,OAAO,SAAS,KAAM,QAAO,OAAO,EAAE;AAC7E,WAAS,OAAO;;AAElB,QAAO,KAAK,KAAK,SAAS,MAAM;;AAGlC,SAAgB,uBAAuB,MAAgB,MAAyB;CAC9E,IAAI,SAAmB;AACvB,MAAK,IAAI,IAAI,GAAG,IAAI,KAAK,SAAS,GAAG,KAAK;EACxC,MAAM,OAAO,OAAO,KAAK;AACzB,MAAI,OAAO,SAAS,YAAY,SAAS,KAAM,QAAO;AACtD,WAAS;;CAEX,MAAM,OAAO,KAAK,KAAK,SAAS;AAChC,KAAI,EAAE,QAAQ,QAAS,QAAO;AAC9B,QAAO,OAAO;AACd,QAAO"}
@@ -114,7 +114,7 @@ var CommandContextImpl = class {
114
114
  }
115
115
  getCurrentModel() {
116
116
  if (this.deps.getCurrentModel) return this.deps.getCurrentModel();
117
- return this.config.agents?.defaults?.model?.primary || "minimax/minimax-m2.1";
117
+ return this.config.agents?.defaults?.models?.chat?.primary || "minimax/minimax-m2.1";
118
118
  }
119
119
  async listModels() {
120
120
  if (this.deps.listModels) return this.deps.listModels();
@@ -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';\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\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}\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 persistentGoalApis?: PersistentGoalApis;\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 this.persistentGoalApis = deps.persistentGoalApis;\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?.model?.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 { 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';\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\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}\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 persistentGoalApis?: PersistentGoalApis;\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 this.persistentGoalApis = deps.persistentGoalApis;\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,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import { version } from "../../package.js";
3
- import "../infra/http-proxy-env.js";
4
3
  import "./cli-log-level-preset.js";
4
+ import "../infra/http-proxy-env.js";
5
5
  import { ensureXopcCliOnPath } from "../infra/path-env.js";
6
6
  import { formatRootHelp } from "./command-manifest.js";
7
7
  //#region src/cli/bin.ts
@@ -41,7 +41,7 @@ const ROOT_HELP_COMMANDS = [
41
41
  },
42
42
  {
43
43
  name: "channels",
44
- description: "Messaging channel login and credentials"
44
+ description: "Messaging channel configuration"
45
45
  },
46
46
  {
47
47
  name: "auth",
@@ -1 +1 @@
1
- {"version":3,"file":"command-manifest.js","names":[],"sources":["../../../src/cli/command-manifest.ts"],"sourcesContent":["export type RootHelpOption = {\n flags: string;\n description: string;\n};\n\nexport type RootHelpCommand = {\n name: string;\n description: string;\n};\n\nexport const ROOT_COMMAND_DESCRIPTION = 'Ultra-Lightweight Personal AI Assistant';\n\nexport const ROOT_HELP_OPTIONS: RootHelpOption[] = [\n { flags: '-V, --version', description: 'output the version number' },\n { flags: '--verbose', description: 'Enable verbose logging (default: false)' },\n { flags: '--config <path>', description: 'Config file path' },\n { flags: '--workspace <path>', description: 'Workspace directory' },\n { flags: '-h, --help', description: 'display help for command' },\n];\n\nexport const ROOT_HELP_COMMANDS: RootHelpCommand[] = [\n { name: 'init [options]', description: 'Initialize xopc state directories, config, and agent workspace' },\n { name: 'setup [options]', description: 'Initialize config file and workspace directory' },\n { name: 'profile', description: 'Manage xopc state profiles (~/.xopc vs ~/.xopc-<name>)' },\n { name: 'onboard [options]', description: 'Interactive setup wizard for xopc (gateway uses schema defaults)' },\n { name: 'channels', description: 'Messaging channel login and credentials' },\n { name: 'auth', description: 'Manage authentication credentials' },\n { name: 'agent [options]', description: 'Chat with the AI agent' },\n { name: 'tui [options]', description: 'Interactive terminal UI (pi-tui)' },\n { name: 'tunnel', description: 'Manage FRP remote access tunnel' },\n { name: 'gateway [options]', description: 'Start the xopc gateway server' },\n { name: 'session', description: 'Session management commands' },\n { name: 'doctor [options]', description: 'Check xopc installation health and diagnose common issues' },\n { name: 'update [options]', description: 'Check for and install xopc updates' },\n { name: 'logs', description: 'Manage and query logs' },\n { name: 'cron', description: 'Manage scheduled tasks' },\n { name: 'config [options]', description: 'View and edit configuration' },\n { name: 'image', description: 'Configure image generation and understanding models' },\n { name: 'models [options]', description: 'List and manage models and model auth' },\n { name: 'providers', description: 'Manage LLM provider credentials (user-friendly hub over `xopc auth`)' },\n { name: 'voice', description: 'Configure text-to-speech (TTS) output' },\n { name: 'search', description: 'Manage web-search providers (brave / tavily / bing / searxng)' },\n { name: 'skills', description: 'Manage skills' },\n { name: 'tailscale', description: 'Tailscale status for gateway remote access' },\n { name: 'browser', description: 'Browser automation commands (uses Playwright)' },\n { name: 'agents', description: 'Manage agents (config + workspace)' },\n { name: 'extensions', description: 'Manage extensions' },\n { name: 'help [command]', description: 'display help for command' },\n];\n\nfunction formatRows(rows: Array<{ label: string; description: string }>): string {\n const labelWidth = Math.max(...rows.map((row) => row.label.length)) + 2;\n return rows.map((row) => ` ${row.label.padEnd(labelWidth)}${row.description}`).join('\\n');\n}\n\nexport function formatRootHelp(): string {\n const options = formatRows(ROOT_HELP_OPTIONS.map((option) => ({ label: option.flags, description: option.description })));\n const commands = formatRows(\n ROOT_HELP_COMMANDS.map((command) => ({ label: command.name, description: command.description })),\n );\n return `Usage: xopc [options] [command]\n\n${ROOT_COMMAND_DESCRIPTION}\n\nOptions:\n${options}\n\nCommands:\n${commands}`;\n}\n"],"mappings":";AAUA,MAAa,2BAA2B;AAExC,MAAa,oBAAsC;CACjD;EAAE,OAAO;EAAiB,aAAa;EAA6B;CACpE;EAAE,OAAO;EAAa,aAAa;EAA2C;CAC9E;EAAE,OAAO;EAAmB,aAAa;EAAoB;CAC7D;EAAE,OAAO;EAAsB,aAAa;EAAuB;CACnE;EAAE,OAAO;EAAc,aAAa;EAA4B;CACjE;AAED,MAAa,qBAAwC;CACnD;EAAE,MAAM;EAAkB,aAAa;EAAkE;CACzG;EAAE,MAAM;EAAmB,aAAa;EAAkD;CAC1F;EAAE,MAAM;EAAW,aAAa;EAA0D;CAC1F;EAAE,MAAM;EAAqB,aAAa;EAAoE;CAC9G;EAAE,MAAM;EAAY,aAAa;EAA2C;CAC5E;EAAE,MAAM;EAAQ,aAAa;EAAqC;CAClE;EAAE,MAAM;EAAmB,aAAa;EAA0B;CAClE;EAAE,MAAM;EAAiB,aAAa;EAAoC;CAC1E;EAAE,MAAM;EAAU,aAAa;EAAmC;CAClE;EAAE,MAAM;EAAqB,aAAa;EAAiC;CAC3E;EAAE,MAAM;EAAW,aAAa;EAA+B;CAC/D;EAAE,MAAM;EAAoB,aAAa;EAA6D;CACtG;EAAE,MAAM;EAAoB,aAAa;EAAsC;CAC/E;EAAE,MAAM;EAAQ,aAAa;EAAyB;CACtD;EAAE,MAAM;EAAQ,aAAa;EAA0B;CACvD;EAAE,MAAM;EAAoB,aAAa;EAA+B;CACxE;EAAE,MAAM;EAAS,aAAa;EAAuD;CACrF;EAAE,MAAM;EAAoB,aAAa;EAAyC;CAClF;EAAE,MAAM;EAAa,aAAa;EAAwE;CAC1G;EAAE,MAAM;EAAS,aAAa;EAAyC;CACvE;EAAE,MAAM;EAAU,aAAa;EAAiE;CAChG;EAAE,MAAM;EAAU,aAAa;EAAiB;CAChD;EAAE,MAAM;EAAa,aAAa;EAA8C;CAChF;EAAE,MAAM;EAAW,aAAa;EAAiD;CACjF;EAAE,MAAM;EAAU,aAAa;EAAsC;CACrE;EAAE,MAAM;EAAc,aAAa;EAAqB;CACxD;EAAE,MAAM;EAAkB,aAAa;EAA4B;CACpE;AAED,SAAS,WAAW,MAA6D;CAC/E,MAAM,aAAa,KAAK,IAAI,GAAG,KAAK,KAAK,QAAQ,IAAI,MAAM,OAAO,CAAC,GAAG;AACtE,QAAO,KAAK,KAAK,QAAQ,KAAK,IAAI,MAAM,OAAO,WAAW,GAAG,IAAI,cAAc,CAAC,KAAK,KAAK;;AAG5F,SAAgB,iBAAyB;AAKvC,QAAO;;EAEP,yBAAyB;;;EANT,WAAW,kBAAkB,KAAK,YAAY;EAAE,OAAO,OAAO;EAAO,aAAa,OAAO;EAAa,EAAE,CASjH,CAAC;;;EARS,WACf,mBAAmB,KAAK,aAAa;EAAE,OAAO,QAAQ;EAAM,aAAa,QAAQ;EAAa,EAAE,CAU1F"}
1
+ {"version":3,"file":"command-manifest.js","names":[],"sources":["../../../src/cli/command-manifest.ts"],"sourcesContent":["export type RootHelpOption = {\n flags: string;\n description: string;\n};\n\nexport type RootHelpCommand = {\n name: string;\n description: string;\n};\n\nexport const ROOT_COMMAND_DESCRIPTION = 'Ultra-Lightweight Personal AI Assistant';\n\nexport const ROOT_HELP_OPTIONS: RootHelpOption[] = [\n { flags: '-V, --version', description: 'output the version number' },\n { flags: '--verbose', description: 'Enable verbose logging (default: false)' },\n { flags: '--config <path>', description: 'Config file path' },\n { flags: '--workspace <path>', description: 'Workspace directory' },\n { flags: '-h, --help', description: 'display help for command' },\n];\n\nexport const ROOT_HELP_COMMANDS: RootHelpCommand[] = [\n { name: 'init [options]', description: 'Initialize xopc state directories, config, and agent workspace' },\n { name: 'setup [options]', description: 'Initialize config file and workspace directory' },\n { name: 'profile', description: 'Manage xopc state profiles (~/.xopc vs ~/.xopc-<name>)' },\n { name: 'onboard [options]', description: 'Interactive setup wizard for xopc (gateway uses schema defaults)' },\n { name: 'channels', description: 'Messaging channel configuration' },\n { name: 'auth', description: 'Manage authentication credentials' },\n { name: 'agent [options]', description: 'Chat with the AI agent' },\n { name: 'tui [options]', description: 'Interactive terminal UI (pi-tui)' },\n { name: 'tunnel', description: 'Manage FRP remote access tunnel' },\n { name: 'gateway [options]', description: 'Start the xopc gateway server' },\n { name: 'session', description: 'Session management commands' },\n { name: 'doctor [options]', description: 'Check xopc installation health and diagnose common issues' },\n { name: 'update [options]', description: 'Check for and install xopc updates' },\n { name: 'logs', description: 'Manage and query logs' },\n { name: 'cron', description: 'Manage scheduled tasks' },\n { name: 'config [options]', description: 'View and edit configuration' },\n { name: 'image', description: 'Configure image generation and understanding models' },\n { name: 'models [options]', description: 'List and manage models and model auth' },\n { name: 'providers', description: 'Manage LLM provider credentials (user-friendly hub over `xopc auth`)' },\n { name: 'voice', description: 'Configure text-to-speech (TTS) output' },\n { name: 'search', description: 'Manage web-search providers (brave / tavily / bing / searxng)' },\n { name: 'skills', description: 'Manage skills' },\n { name: 'tailscale', description: 'Tailscale status for gateway remote access' },\n { name: 'browser', description: 'Browser automation commands (uses Playwright)' },\n { name: 'agents', description: 'Manage agents (config + workspace)' },\n { name: 'extensions', description: 'Manage extensions' },\n { name: 'help [command]', description: 'display help for command' },\n];\n\nfunction formatRows(rows: Array<{ label: string; description: string }>): string {\n const labelWidth = Math.max(...rows.map((row) => row.label.length)) + 2;\n return rows.map((row) => ` ${row.label.padEnd(labelWidth)}${row.description}`).join('\\n');\n}\n\nexport function formatRootHelp(): string {\n const options = formatRows(ROOT_HELP_OPTIONS.map((option) => ({ label: option.flags, description: option.description })));\n const commands = formatRows(\n ROOT_HELP_COMMANDS.map((command) => ({ label: command.name, description: command.description })),\n );\n return `Usage: xopc [options] [command]\n\n${ROOT_COMMAND_DESCRIPTION}\n\nOptions:\n${options}\n\nCommands:\n${commands}`;\n}\n"],"mappings":";AAUA,MAAa,2BAA2B;AAExC,MAAa,oBAAsC;CACjD;EAAE,OAAO;EAAiB,aAAa;EAA6B;CACpE;EAAE,OAAO;EAAa,aAAa;EAA2C;CAC9E;EAAE,OAAO;EAAmB,aAAa;EAAoB;CAC7D;EAAE,OAAO;EAAsB,aAAa;EAAuB;CACnE;EAAE,OAAO;EAAc,aAAa;EAA4B;CACjE;AAED,MAAa,qBAAwC;CACnD;EAAE,MAAM;EAAkB,aAAa;EAAkE;CACzG;EAAE,MAAM;EAAmB,aAAa;EAAkD;CAC1F;EAAE,MAAM;EAAW,aAAa;EAA0D;CAC1F;EAAE,MAAM;EAAqB,aAAa;EAAoE;CAC9G;EAAE,MAAM;EAAY,aAAa;EAAmC;CACpE;EAAE,MAAM;EAAQ,aAAa;EAAqC;CAClE;EAAE,MAAM;EAAmB,aAAa;EAA0B;CAClE;EAAE,MAAM;EAAiB,aAAa;EAAoC;CAC1E;EAAE,MAAM;EAAU,aAAa;EAAmC;CAClE;EAAE,MAAM;EAAqB,aAAa;EAAiC;CAC3E;EAAE,MAAM;EAAW,aAAa;EAA+B;CAC/D;EAAE,MAAM;EAAoB,aAAa;EAA6D;CACtG;EAAE,MAAM;EAAoB,aAAa;EAAsC;CAC/E;EAAE,MAAM;EAAQ,aAAa;EAAyB;CACtD;EAAE,MAAM;EAAQ,aAAa;EAA0B;CACvD;EAAE,MAAM;EAAoB,aAAa;EAA+B;CACxE;EAAE,MAAM;EAAS,aAAa;EAAuD;CACrF;EAAE,MAAM;EAAoB,aAAa;EAAyC;CAClF;EAAE,MAAM;EAAa,aAAa;EAAwE;CAC1G;EAAE,MAAM;EAAS,aAAa;EAAyC;CACvE;EAAE,MAAM;EAAU,aAAa;EAAiE;CAChG;EAAE,MAAM;EAAU,aAAa;EAAiB;CAChD;EAAE,MAAM;EAAa,aAAa;EAA8C;CAChF;EAAE,MAAM;EAAW,aAAa;EAAiD;CACjF;EAAE,MAAM;EAAU,aAAa;EAAsC;CACrE;EAAE,MAAM;EAAc,aAAa;EAAqB;CACxD;EAAE,MAAM;EAAkB,aAAa;EAA4B;CACpE;AAED,SAAS,WAAW,MAA6D;CAC/E,MAAM,aAAa,KAAK,IAAI,GAAG,KAAK,KAAK,QAAQ,IAAI,MAAM,OAAO,CAAC,GAAG;AACtE,QAAO,KAAK,KAAK,QAAQ,KAAK,IAAI,MAAM,OAAO,WAAW,GAAG,IAAI,cAAc,CAAC,KAAK,KAAK;;AAG5F,SAAgB,iBAAyB;AAKvC,QAAO;;EAEP,yBAAyB;;;EANT,WAAW,kBAAkB,KAAK,YAAY;EAAE,OAAO,OAAO;EAAO,aAAa,OAAO;EAAa,EAAE,CASjH,CAAC;;;EARS,WACf,mBAAmB,KAAK,aAAa;EAAE,OAAO,QAAQ;EAAM,aAAa,QAAQ;EAAa,EAAE,CAU1F"}
@@ -1,7 +1,6 @@
1
1
  import { createLogger } from "../../utils/logger/index.js";
2
2
  import { init_logger } from "../../utils/logger.js";
3
3
  import { loadConfig } from "../../config/loader.js";
4
- import { getWorkspacePath } from "../../config/workspace-path-helpers.js";
5
4
  import { ExtensionLoader } from "../../extensions/loader.js";
6
5
  import "../../extensions/index.js";
7
6
  import { MessageBus, MessageBusShutdownError } from "../../infra/bus/queue.js";
@@ -10,6 +9,7 @@ import { AgentService } from "../../agent/service.js";
10
9
  import "../../agent/index.js";
11
10
  import { formatExamples, register } from "../registry.js";
12
11
  import { getContextWithOpts } from "../context.js";
12
+ import { getWorkspacePath } from "../../config/workspace-path-helpers.js";
13
13
  import "../../config/index.js";
14
14
  import { listSessions } from "./agent/sessions.js";
15
15
  import { renderStreamToTerminal } from "./agent/stream-renderer.js";
@@ -34,7 +34,7 @@ function createAgentCommand(_ctx) {
34
34
  await listSessions();
35
35
  return;
36
36
  }
37
- const modelFromConfig = config.agents?.defaults?.model?.primary;
37
+ const modelFromConfig = config.agents?.defaults?.models?.chat?.primary;
38
38
  const modelId = options.model?.trim() || modelFromConfig;
39
39
  const bus = new MessageBus();
40
40
  if (ctx.isVerbose) log.info({
@@ -1 +1 @@
1
- {"version":3,"file":"agent.js","names":[],"sources":["../../../../src/cli/commands/agent.ts"],"sourcesContent":["import { Command } from 'commander';\nimport { AgentService } from '../../agent/index.js';\nimport { loadConfig, getWorkspacePath } from '../../config/index.js';\nimport { MessageBus, MessageBusShutdownError } from '../../infra/bus/index.js';\nimport { createLogger } from '../../utils/logger.js';\nimport { register, formatExamples, type CLIContext } from '../registry.js';\nimport { getContextWithOpts } from '../context.js';\nimport { ExtensionLoader } from '../../extensions/index.js';\nimport { join } from 'path';\nimport { listSessions } from './agent/sessions.js';\nimport { startInteractiveChat } from './agent/interactive.js';\nimport { renderStreamToTerminal } from './agent/stream-renderer.js';\n\nconst log = createLogger('AgentCommand');\n\ninterface AgentCommandOptions {\n message?: string;\n model?: string;\n interactive?: boolean;\n session?: string;\n list?: boolean;\n}\n\nfunction createAgentCommand(_ctx: CLIContext): Command {\n const cmd = new Command('agent')\n .description('Chat with the AI agent')\n .addHelpText(\n 'after',\n formatExamples([\n 'xopc agent -m \"Hello\" # Single message',\n 'xopc agent --model demo/demo-chat-7b -m \"Hi\" # Override model for one shot',\n 'xopc agent -i # Interactive chat mode',\n 'xopc agent -i --session telegram:dm:123456 # Continue existing session',\n 'xopc agent --list # List available sessions',\n ])\n )\n .option('--model <id>', 'Model ref for this run (e.g. demo/demo-chat-7b, anthropic/claude-sonnet-4-5)')\n .option('-m, --message <text>', 'Single message to send')\n .option('-i, --interactive', 'Interactive chat mode')\n .option('-s, --session <key>', 'Continue an existing session (use --list to see available sessions)')\n .option('-l, --list', 'List available sessions and exit')\n .action(async (options: AgentCommandOptions) => {\n const ctx = getContextWithOpts();\n const config = loadConfig(ctx.configPath);\n const workspace = getWorkspacePath(config) || ctx.workspacePath;\n\n // Handle --list option\n if (options.list) {\n await listSessions();\n return;\n }\n\n const modelFromConfig = config.agents?.defaults?.model?.primary;\n const modelId = (options.model?.trim() || modelFromConfig) as string | undefined;\n const bus = new MessageBus();\n\n if (ctx.isVerbose) {\n log.info({ model: modelId, workspace, session: options.session }, 'Starting agent');\n }\n\n // Validate session key if provided\n let sessionKey = options.session || 'agent:main:main';\n if (options.session) {\n const { getSessionIndex } = await import('../utils/session.js');\n const manager = await getSessionIndex();\n const session = await manager.getSessionMetadata(options.session);\n if (!session) {\n console.error(`❌ Session not found: ${options.session}`);\n console.log('Use --list to see available sessions.');\n process.exit(1);\n }\n console.log(`📂 Continuing session: ${options.session} (${session.messageCount} messages)\\n`);\n }\n\n // Initialize extension loader (manifest-first activation: env, channels, model, extensions.*)\n let extensionLoader: ExtensionLoader | null = null;\n try {\n extensionLoader = new ExtensionLoader({\n workspaceDir: workspace,\n extensionsDir: join(workspace, '.extensions'),\n });\n extensionLoader.setConfig(config as Parameters<ExtensionLoader['setConfig']>[0]);\n extensionLoader.setRuntimeContext({ bus });\n await extensionLoader.loadByActivationPlan();\n const n = extensionLoader.getRegistry().extensions.size;\n if (n > 0) {\n log.info({ count: n }, 'Extensions loaded');\n }\n } catch (error) {\n const em = error instanceof Error ? error.message : String(error);\n log.warn({ err: error, errorMessage: em }, `CLI agent: failed to load extensions: ${em}`);\n }\n\n const { createCliReadlineClarifyRequestFn } = await import('../../agent/tools/cli-clarify.js');\n\n const agent = new AgentService(bus, {\n workspace,\n model: modelId,\n config,\n extensionRegistry: extensionLoader?.getRegistry(),\n gatewayClarify: {\n requestClarification: createCliReadlineClarifyRequestFn(),\n },\n });\n\n // Start agent service in background\n agent.start().catch((err) => {\n const em = err instanceof Error ? err.message : String(err);\n log.error({ err, errorMessage: em }, `CLI agent service exited: ${em}`);\n });\n\n // Start outbound message processor for CLI mode\n let running = true;\n const _outboundProcessor = (async () => {\n while (running) {\n try {\n const msg = await bus.consumeOutbound();\n console.log(`\\n📤 [${msg.channel}] ${msg.chat_id}: ${msg.content.slice(0, 100)}...`);\n } catch (error) {\n if (error instanceof MessageBusShutdownError) {\n break;\n }\n const em = error instanceof Error ? error.message : String(error);\n log.error({ err: error, errorMessage: em }, `CLI outbound processor failed: ${em}`);\n await new Promise((resolve) => setTimeout(resolve, 1000));\n }\n }\n })();\n\n const shutdown = async () => {\n running = false;\n bus.shutdown();\n await agent.stop();\n };\n\n process.on('SIGINT', shutdown);\n process.on('SIGTERM', shutdown);\n\n if (options.message) {\n const oneShotModel = options.model?.trim();\n if (oneShotModel) {\n await agent.switchModelForSession(sessionKey, oneShotModel);\n }\n await renderStreamToTerminal(agent, options.message, sessionKey);\n if (oneShotModel) {\n await agent.resetSessionModelToAgentDefault(sessionKey);\n }\n await shutdown();\n } else if (options.interactive) {\n const interactiveModel = options.model?.trim();\n if (interactiveModel) {\n await agent.switchModelForSession(sessionKey, interactiveModel);\n }\n await startInteractiveChat(agent, {\n workspace,\n sessionKey,\n continuingSession: !!options.session,\n });\n } else {\n await shutdown();\n cmd.help();\n }\n });\n\n return cmd;\n}\n\nregister({\n id: 'agent',\n name: 'agent',\n description: 'Chat with the AI agent',\n factory: createAgentCommand,\n metadata: {\n category: 'runtime',\n examples: [\n 'xopc agent -m \"Hello\"',\n 'xopc agent --model demo/demo-chat-7b -m \"Hello demo!\"',\n 'xopc agent -i',\n ],\n },\n});\n"],"mappings":"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"}
1
+ {"version":3,"file":"agent.js","names":[],"sources":["../../../../src/cli/commands/agent.ts"],"sourcesContent":["import { Command } from 'commander';\nimport { AgentService } from '../../agent/index.js';\nimport { loadConfig, getWorkspacePath } from '../../config/index.js';\nimport { MessageBus, MessageBusShutdownError } from '../../infra/bus/index.js';\nimport { createLogger } from '../../utils/logger.js';\nimport { register, formatExamples, type CLIContext } from '../registry.js';\nimport { getContextWithOpts } from '../context.js';\nimport { ExtensionLoader } from '../../extensions/index.js';\nimport { join } from 'path';\nimport { listSessions } from './agent/sessions.js';\nimport { startInteractiveChat } from './agent/interactive.js';\nimport { renderStreamToTerminal } from './agent/stream-renderer.js';\n\nconst log = createLogger('AgentCommand');\n\ninterface AgentCommandOptions {\n message?: string;\n model?: string;\n interactive?: boolean;\n session?: string;\n list?: boolean;\n}\n\nfunction createAgentCommand(_ctx: CLIContext): Command {\n const cmd = new Command('agent')\n .description('Chat with the AI agent')\n .addHelpText(\n 'after',\n formatExamples([\n 'xopc agent -m \"Hello\" # Single message',\n 'xopc agent --model demo/demo-chat-7b -m \"Hi\" # Override model for one shot',\n 'xopc agent -i # Interactive chat mode',\n 'xopc agent -i --session telegram:dm:123456 # Continue existing session',\n 'xopc agent --list # List available sessions',\n ])\n )\n .option('--model <id>', 'Model ref for this run (e.g. demo/demo-chat-7b, anthropic/claude-sonnet-4-5)')\n .option('-m, --message <text>', 'Single message to send')\n .option('-i, --interactive', 'Interactive chat mode')\n .option('-s, --session <key>', 'Continue an existing session (use --list to see available sessions)')\n .option('-l, --list', 'List available sessions and exit')\n .action(async (options: AgentCommandOptions) => {\n const ctx = getContextWithOpts();\n const config = loadConfig(ctx.configPath);\n const workspace = getWorkspacePath(config) || ctx.workspacePath;\n\n // Handle --list option\n if (options.list) {\n await listSessions();\n return;\n }\n\n const modelFromConfig = config.agents?.defaults?.models?.chat?.primary;\n const modelId = (options.model?.trim() || modelFromConfig) as string | undefined;\n const bus = new MessageBus();\n\n if (ctx.isVerbose) {\n log.info({ model: modelId, workspace, session: options.session }, 'Starting agent');\n }\n\n // Validate session key if provided\n let sessionKey = options.session || 'agent:main:main';\n if (options.session) {\n const { getSessionIndex } = await import('../utils/session.js');\n const manager = await getSessionIndex();\n const session = await manager.getSessionMetadata(options.session);\n if (!session) {\n console.error(`❌ Session not found: ${options.session}`);\n console.log('Use --list to see available sessions.');\n process.exit(1);\n }\n console.log(`📂 Continuing session: ${options.session} (${session.messageCount} messages)\\n`);\n }\n\n // Initialize extension loader (manifest-first activation: env, channels, model, extensions.*)\n let extensionLoader: ExtensionLoader | null = null;\n try {\n extensionLoader = new ExtensionLoader({\n workspaceDir: workspace,\n extensionsDir: join(workspace, '.extensions'),\n });\n extensionLoader.setConfig(config as Parameters<ExtensionLoader['setConfig']>[0]);\n extensionLoader.setRuntimeContext({ bus });\n await extensionLoader.loadByActivationPlan();\n const n = extensionLoader.getRegistry().extensions.size;\n if (n > 0) {\n log.info({ count: n }, 'Extensions loaded');\n }\n } catch (error) {\n const em = error instanceof Error ? error.message : String(error);\n log.warn({ err: error, errorMessage: em }, `CLI agent: failed to load extensions: ${em}`);\n }\n\n const { createCliReadlineClarifyRequestFn } = await import('../../agent/tools/cli-clarify.js');\n\n const agent = new AgentService(bus, {\n workspace,\n model: modelId,\n config,\n extensionRegistry: extensionLoader?.getRegistry(),\n gatewayClarify: {\n requestClarification: createCliReadlineClarifyRequestFn(),\n },\n });\n\n // Start agent service in background\n agent.start().catch((err) => {\n const em = err instanceof Error ? err.message : String(err);\n log.error({ err, errorMessage: em }, `CLI agent service exited: ${em}`);\n });\n\n // Start outbound message processor for CLI mode\n let running = true;\n const _outboundProcessor = (async () => {\n while (running) {\n try {\n const msg = await bus.consumeOutbound();\n console.log(`\\n📤 [${msg.channel}] ${msg.chat_id}: ${msg.content.slice(0, 100)}...`);\n } catch (error) {\n if (error instanceof MessageBusShutdownError) {\n break;\n }\n const em = error instanceof Error ? error.message : String(error);\n log.error({ err: error, errorMessage: em }, `CLI outbound processor failed: ${em}`);\n await new Promise((resolve) => setTimeout(resolve, 1000));\n }\n }\n })();\n\n const shutdown = async () => {\n running = false;\n bus.shutdown();\n await agent.stop();\n };\n\n process.on('SIGINT', shutdown);\n process.on('SIGTERM', shutdown);\n\n if (options.message) {\n const oneShotModel = options.model?.trim();\n if (oneShotModel) {\n await agent.switchModelForSession(sessionKey, oneShotModel);\n }\n await renderStreamToTerminal(agent, options.message, sessionKey);\n if (oneShotModel) {\n await agent.resetSessionModelToAgentDefault(sessionKey);\n }\n await shutdown();\n } else if (options.interactive) {\n const interactiveModel = options.model?.trim();\n if (interactiveModel) {\n await agent.switchModelForSession(sessionKey, interactiveModel);\n }\n await startInteractiveChat(agent, {\n workspace,\n sessionKey,\n continuingSession: !!options.session,\n });\n } else {\n await shutdown();\n cmd.help();\n }\n });\n\n return cmd;\n}\n\nregister({\n id: 'agent',\n name: 'agent',\n description: 'Chat with the AI agent',\n factory: createAgentCommand,\n metadata: {\n category: 'runtime',\n examples: [\n 'xopc agent -m \"Hello\"',\n 'xopc agent --model demo/demo-chat-7b -m \"Hello demo!\"',\n 'xopc agent -i',\n ],\n },\n});\n"],"mappings":"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"}