@xopcai/xopc 0.0.102 → 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 (995) hide show
  1. package/README.md +8 -5
  2. package/README.zh-CN.md +8 -5
  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 +2 -2
  20. package/dist/extensions/feishu/src/transport/webhook/monitor.js.map +1 -1
  21. package/dist/extensions/feishu/xopc.extension.json +66 -1
  22. package/dist/extensions/telegram/src/adapters/gateway-setup.d.ts +2 -0
  23. package/dist/extensions/telegram/src/adapters/gateway-setup.js +146 -0
  24. package/dist/extensions/telegram/src/adapters/gateway-setup.js.map +1 -0
  25. package/dist/extensions/telegram/src/adapters/security-adapter.js +1 -1
  26. package/dist/extensions/telegram/src/command-handler.js +1 -2
  27. package/dist/extensions/telegram/src/command-handler.js.map +1 -1
  28. package/dist/extensions/telegram/src/config-schema.js +2 -2
  29. package/dist/extensions/telegram/src/config-schema.js.map +1 -1
  30. package/dist/extensions/telegram/src/doctor.d.ts +1 -0
  31. package/dist/extensions/telegram/src/doctor.js +68 -0
  32. package/dist/extensions/telegram/src/doctor.js.map +1 -1
  33. package/dist/extensions/telegram/src/index.d.ts +8 -1
  34. package/dist/extensions/telegram/src/index.js +15 -2
  35. package/dist/extensions/telegram/src/index.js.map +1 -0
  36. package/dist/extensions/telegram/src/plugin.d.ts +13 -5
  37. package/dist/extensions/telegram/src/plugin.js +32 -12
  38. package/dist/extensions/telegram/src/plugin.js.map +1 -1
  39. package/dist/extensions/telegram/src/proxy-fetch.js +22 -5
  40. package/dist/extensions/telegram/src/proxy-fetch.js.map +1 -1
  41. package/dist/extensions/telegram/src/send-options.js +8 -5
  42. package/dist/extensions/telegram/src/send-options.js.map +1 -1
  43. package/dist/extensions/telegram/xopc.extension.json +412 -5
  44. package/dist/extensions/weixin/src/adapters/onboard-cli.js +2 -2
  45. package/dist/extensions/weixin/src/adapters/onboard-cli.js.map +1 -1
  46. package/dist/extensions/weixin/src/api/api.js +1 -1
  47. package/dist/extensions/weixin/src/index.d.ts +8 -0
  48. package/dist/extensions/weixin/src/index.js +12 -1
  49. package/dist/extensions/weixin/src/index.js.map +1 -0
  50. package/dist/extensions/weixin/src/messaging/process-message.js +1 -1
  51. package/dist/extensions/weixin/src/plugin.d.ts +2 -1
  52. package/dist/extensions/weixin/src/plugin.js +77 -2
  53. package/dist/extensions/weixin/src/plugin.js.map +1 -1
  54. package/dist/extensions/weixin/xopc.extension.json +52 -0
  55. package/dist/gateway/static/root/assets/agents-CvsBrBfi.js +396 -0
  56. package/dist/gateway/static/root/assets/{apps-page-Uv4kOmDE.js → apps-page-L-IwQTe0.js} +1 -1
  57. package/dist/gateway/static/root/assets/browser-BLJWD7WI.js +8 -0
  58. package/dist/gateway/static/root/assets/channels-settings-D95KuPeP.js +1 -0
  59. package/dist/gateway/static/root/assets/cron-page-CfkWXDAI.js +1 -0
  60. package/dist/gateway/static/root/assets/{dist-DH4IuRV0.js → dist-C6vclgEL.js} +1 -1
  61. package/dist/gateway/static/root/assets/{extension-debug-page-BNkhvRQW.js → extension-debug-page-D4JYAbsX.js} +1 -1
  62. package/dist/gateway/static/root/assets/{extension-page-CcIGQah2.js → extension-page-_T62gi6e.js} +1 -1
  63. package/dist/gateway/static/root/assets/extension-settings-page-CkJbjyM-.js +1 -0
  64. package/dist/gateway/static/root/assets/{fetch-drJUxxKP.js → fetch-B5aiIguv.js} +1 -1
  65. package/dist/gateway/static/root/assets/gateway-startup-retry-DqmLXhs6.js +1 -0
  66. package/dist/gateway/static/root/assets/heartbeat-config-api-HwJV1K_Y.js +1 -0
  67. package/dist/gateway/static/root/assets/index-BPYKW7FB.css +1 -0
  68. package/dist/gateway/static/root/assets/index-DvTb6wNR.js +4845 -0
  69. package/dist/gateway/static/root/assets/{logs-page-CiG0m81R.js → logs-page-DsjtTjBy.js} +2 -2
  70. package/dist/gateway/static/root/assets/{note-detail-page-DG3DVFTf.js → note-detail-page-B2V7RhgD.js} +43 -43
  71. package/dist/gateway/static/root/assets/{note-time-DjlllCF3.js → note-time-BG8GCTr4.js} +1 -1
  72. package/dist/gateway/static/root/assets/notes-page-xrcVBQ6Z.js +1 -0
  73. package/dist/gateway/static/root/assets/schema-form-S-QUvhul.js +1 -0
  74. package/dist/gateway/static/root/assets/sessions-page-CrQer6Au.js +1 -0
  75. package/dist/gateway/static/root/assets/settings-advanced-gate-DujQl9c7.js +2 -0
  76. package/dist/gateway/static/root/assets/{settings-form-section-C3_sEFfD.js → settings-form-section-r1V7dRV6.js} +1 -1
  77. package/dist/gateway/static/root/assets/settings-page-C9nrONQ2.js +3 -0
  78. package/dist/gateway/static/root/assets/share-preview-page-DOFy0FNt.js +2 -0
  79. package/dist/gateway/static/root/assets/skills-page-DmTsrs_a.js +2 -0
  80. package/dist/gateway/static/root/assets/{theme-store-B6KXPHgK.js → theme-store-Bo3j5Ovv.js} +1 -1
  81. package/dist/gateway/static/root/assets/url-WgQIjFZu.js +3 -0
  82. package/dist/gateway/static/root/assets/voice-api-key-field-AjmUAlEQ.js +1 -0
  83. package/dist/gateway/static/root/assets/{workflow-page.utils-g57BRfEd.js → workflow-page.utils-DLEJ92gK.js} +1 -1
  84. package/dist/gateway/static/root/assets/workflows-page-BnjjKrM1.js +27 -0
  85. package/dist/gateway/static/root/index.html +6 -5
  86. package/dist/package.js +1 -1
  87. package/dist/src/agent/agent-manager.d.ts +18 -6
  88. package/dist/src/agent/agent-manager.js +60 -35
  89. package/dist/src/agent/agent-manager.js.map +1 -1
  90. package/dist/src/agent/builtin-agent-ids.d.ts +2 -0
  91. package/dist/src/agent/builtin-agent-ids.js +17 -0
  92. package/dist/src/agent/builtin-agent-ids.js.map +1 -0
  93. package/dist/src/agent/child-agent-factory.d.ts +4 -0
  94. package/dist/src/agent/child-agent-factory.js +28 -8
  95. package/dist/src/agent/child-agent-factory.js.map +1 -1
  96. package/dist/src/agent/context/workspace-seed.js +1 -1
  97. package/dist/src/agent/context/workspace-templates/AGENTS.md +23 -184
  98. package/dist/src/agent/embedded/run-turn.js +8 -2
  99. package/dist/src/agent/embedded/run-turn.js.map +1 -1
  100. package/dist/src/agent/embedded/session-tool-result-guard.js +1 -1
  101. package/dist/src/agent/embedded/subscribe-session.js +33 -51
  102. package/dist/src/agent/embedded/subscribe-session.js.map +1 -1
  103. package/dist/src/agent/embedded/types.d.ts +36 -35
  104. package/dist/src/agent/fallback/candidates.js +1 -1
  105. package/dist/src/agent/fallback/candidates.js.map +1 -1
  106. package/dist/src/agent/inbound/attachment-pipeline.js +2 -2
  107. package/dist/src/agent/inbound/attachment-pipeline.js.map +1 -1
  108. package/dist/src/agent/inbound/inbound-loop.js +1 -1
  109. package/dist/src/agent/inbound/turn-dispatcher.d.ts +1 -0
  110. package/dist/src/agent/inbound/turn-dispatcher.js +24 -5
  111. package/dist/src/agent/inbound/turn-dispatcher.js.map +1 -1
  112. package/dist/src/agent/models/manager.d.ts +1 -1
  113. package/dist/src/agent/models/manager.js +1 -1
  114. package/dist/src/agent/models/manager.js.map +1 -1
  115. package/dist/src/agent/orchestration/run-agent-turn-with-fallbacks.d.ts +1 -1
  116. package/dist/src/agent/orchestration/run-agent-turn-with-fallbacks.js +1 -1
  117. package/dist/src/agent/orchestration/run-agent-turn-with-fallbacks.js.map +1 -1
  118. package/dist/src/agent/prompt/sections/tooling.js +4 -0
  119. package/dist/src/agent/prompt/sections/tooling.js.map +1 -1
  120. package/dist/src/agent/service/direct-turn-helpers.d.ts +1 -0
  121. package/dist/src/agent/service/direct-turn-helpers.js +1 -1
  122. package/dist/src/agent/service/direct-turn-helpers.js.map +1 -1
  123. package/dist/src/agent/service/process-direct-streaming.d.ts +1 -0
  124. package/dist/src/agent/service/process-direct-streaming.js +35 -18
  125. package/dist/src/agent/service/process-direct-streaming.js.map +1 -1
  126. package/dist/src/agent/service-inbound-utils.d.ts +0 -1
  127. package/dist/src/agent/service-inbound-utils.js +1 -17
  128. package/dist/src/agent/service-inbound-utils.js.map +1 -1
  129. package/dist/src/agent/service.d.ts +4 -4
  130. package/dist/src/agent/service.js +27 -15
  131. package/dist/src/agent/service.js.map +1 -1
  132. package/dist/src/agent/session/session-config-service.d.ts +1 -0
  133. package/dist/src/agent/session/session-config-service.js +9 -1
  134. package/dist/src/agent/session/session-config-service.js.map +1 -1
  135. package/dist/src/agent/session/session-inspector.d.ts +2 -1
  136. package/dist/src/agent/session/session-inspector.js +4 -0
  137. package/dist/src/agent/session/session-inspector.js.map +1 -1
  138. package/dist/src/agent/skills/config.js +1 -3
  139. package/dist/src/agent/skills/config.js.map +1 -1
  140. package/dist/src/agent/skills/format-skills-prompt.d.ts +1 -0
  141. package/dist/src/agent/skills/format-skills-prompt.js +3 -2
  142. package/dist/src/agent/skills/format-skills-prompt.js.map +1 -1
  143. package/dist/src/agent/skills/hub-pull.js +1 -1
  144. package/dist/src/agent/skills/index.js +20 -5
  145. package/dist/src/agent/skills/index.js.map +1 -1
  146. package/dist/src/agent/skills/installer.js +14 -27
  147. package/dist/src/agent/skills/installer.js.map +1 -1
  148. package/dist/src/agent/skills/marketplace/adapters/clawhub/adapter.js +11 -1
  149. package/dist/src/agent/skills/marketplace/adapters/clawhub/adapter.js.map +1 -1
  150. package/dist/src/agent/skills/marketplace/adapters/skillhub/adapter.js +18 -4
  151. package/dist/src/agent/skills/marketplace/adapters/skillhub/adapter.js.map +1 -1
  152. package/dist/src/agent/skills/marketplace/adapters/store/adapter.js +11 -2
  153. package/dist/src/agent/skills/marketplace/adapters/store/adapter.js.map +1 -1
  154. package/dist/src/agent/skills/marketplace/adapters/store/store-api-client.d.ts +2 -2
  155. package/dist/src/agent/skills/marketplace/adapters/store/store-api-client.js.map +1 -1
  156. package/dist/src/agent/skills/skill-manager.d.ts +4 -1
  157. package/dist/src/agent/skills/skill-manager.js +3 -3
  158. package/dist/src/agent/skills/skill-manager.js.map +1 -1
  159. package/dist/src/agent/skills/skill-view-path.d.ts +1 -17
  160. package/dist/src/agent/skills/skill-view-path.js +3 -66
  161. package/dist/src/agent/skills/skill-view-path.js.map +1 -1
  162. package/dist/src/agent/skills/test-framework.js +2 -3
  163. package/dist/src/agent/skills/test-framework.js.map +1 -1
  164. package/dist/src/agent/streaming/reasoning-visibility-sse.js +1 -0
  165. package/dist/src/agent/streaming/reasoning-visibility-sse.js.map +1 -1
  166. package/dist/src/agent/tool-manuals/browser.d.ts +1 -0
  167. package/{skills/browser/SKILL.md → dist/src/agent/tool-manuals/browser.js} +51 -54
  168. package/dist/src/agent/tool-manuals/browser.js.map +1 -0
  169. package/dist/src/agent/tool-manuals/index.d.ts +10 -0
  170. package/dist/src/agent/tool-manuals/index.js +28 -0
  171. package/dist/src/agent/tool-manuals/index.js.map +1 -0
  172. package/dist/src/agent/tools/browser/tool/browser-use-tool.js +1 -1
  173. package/dist/src/agent/tools/browser/tool/browser-use-tool.js.map +1 -1
  174. package/dist/src/agent/tools/factory.js +7 -5
  175. package/dist/src/agent/tools/factory.js.map +1 -1
  176. package/dist/src/agent/tools/index.d.ts +1 -0
  177. package/dist/src/agent/tools/index.js +5 -4
  178. package/dist/src/agent/tools/send-media.js +1 -2
  179. package/dist/src/agent/tools/send-media.js.map +1 -1
  180. package/dist/src/agent/tools/session-search-tool.js +1 -1
  181. package/dist/src/agent/tools/shell.js +1 -1
  182. package/dist/src/agent/tools/skills-tools.js +37 -8
  183. package/dist/src/agent/tools/skills-tools.js.map +1 -1
  184. package/dist/src/agent/tools/tool-manual-tool.d.ts +6 -0
  185. package/dist/src/agent/tools/tool-manual-tool.js +34 -0
  186. package/dist/src/agent/tools/tool-manual-tool.js.map +1 -0
  187. package/dist/src/agent/tools/web-extract.js +2 -2
  188. package/dist/src/agent/tools/web.js +1 -1
  189. package/dist/src/agent/workflow/catalog.d.ts +7 -2
  190. package/dist/src/agent/workflow/catalog.js +66 -25
  191. package/dist/src/agent/workflow/catalog.js.map +1 -1
  192. package/dist/src/agent/workflow/subagent-runner.d.ts +3 -0
  193. package/dist/src/agent/workflow/subagent-runner.js +50 -4
  194. package/dist/src/agent/workflow/subagent-runner.js.map +1 -1
  195. package/dist/src/agent/workflow/types.d.ts +10 -0
  196. package/dist/src/auth/credentials.d.ts +7 -0
  197. package/dist/src/auth/credentials.js +45 -7
  198. package/dist/src/auth/credentials.js.map +1 -1
  199. package/dist/src/auth/index.d.ts +1 -1
  200. package/dist/src/auth/index.js.map +1 -1
  201. package/dist/src/auth/oauth/github-copilot.d.ts +1 -1
  202. package/dist/src/auth/oauth/google-antigravity.d.ts +1 -3
  203. package/dist/src/auth/oauth/google-antigravity.js +1 -1
  204. package/dist/src/auth/oauth/google-gemini-cli.d.ts +1 -3
  205. package/dist/src/auth/oauth/google-gemini-cli.js +1 -1
  206. package/dist/src/auth/oauth/{vendor-pi-google → google-oauth}/google-antigravity.js +3 -5
  207. package/dist/src/auth/oauth/google-oauth/google-antigravity.js.map +1 -0
  208. package/dist/src/auth/oauth/{vendor-pi-google → google-oauth}/google-gemini-cli.js +4 -5
  209. package/dist/src/auth/oauth/google-oauth/google-gemini-cli.js.map +1 -0
  210. package/dist/src/auth/oauth/{vendor-pi-google → google-oauth}/oauth-page.js +12 -4
  211. package/dist/src/auth/oauth/google-oauth/oauth-page.js.map +1 -0
  212. package/dist/src/auth/oauth/{vendor-pi-google → google-oauth}/pkce.d.ts +1 -1
  213. package/dist/src/auth/oauth/{vendor-pi-google → google-oauth}/pkce.js +2 -2
  214. package/dist/src/auth/oauth/google-oauth/pkce.js.map +1 -0
  215. package/dist/src/auth/oauth/index.js +2 -2
  216. package/dist/src/auth/oauth/kimi-coding.d.ts +1 -1
  217. package/dist/src/auth/oauth/kimi-coding.js +1 -1
  218. package/dist/src/auth/oauth/kimi-coding.js.map +1 -1
  219. package/dist/src/auth/oauth/minimax-cn.js +1 -1
  220. package/dist/src/auth/oauth/minimax-cn.js.map +1 -1
  221. package/dist/src/auth/oauth/minimax.js +1 -1
  222. package/dist/src/auth/oauth/minimax.js.map +1 -1
  223. package/dist/src/auth/oauth/openai-codex.d.ts +7 -2
  224. package/dist/src/auth/oauth/openai-codex.js +318 -1
  225. package/dist/src/auth/oauth/openai-codex.js.map +1 -0
  226. package/dist/src/auth/profiles/store.js +3 -2
  227. package/dist/src/auth/profiles/store.js.map +1 -1
  228. package/dist/src/browser/actions/extension-registry-bridge.js +1 -1
  229. package/dist/src/browser/actions/registry.js +2 -2
  230. package/dist/src/browser/cdp-local-launcher.js +1 -1
  231. package/dist/src/browser/index.js +3 -3
  232. package/dist/src/browser/providers/browser-ext-install.js +1 -1
  233. package/dist/src/browser/providers/cloakbrowser.js +1 -1
  234. package/dist/src/channels/attachments/attachment-classifiers.d.ts +1 -0
  235. package/dist/src/channels/attachments/attachment-classifiers.js +13 -2
  236. package/dist/src/channels/attachments/attachment-classifiers.js.map +1 -1
  237. package/dist/src/channels/catalog/channel-catalog-service.d.ts +11 -0
  238. package/dist/src/channels/catalog/channel-catalog-service.js +168 -0
  239. package/dist/src/channels/catalog/channel-catalog-service.js.map +1 -0
  240. package/dist/src/channels/catalog/channel-catalog-types.d.ts +22 -0
  241. package/dist/src/channels/catalog/channel-catalog-types.js +1 -0
  242. package/dist/src/channels/dock.d.ts +0 -7
  243. package/dist/src/channels/dock.js +1 -21
  244. package/dist/src/channels/index.d.ts +1 -3
  245. package/dist/src/channels/index.js +1 -5
  246. package/dist/src/channels/lifecycle-supervisor.d.ts +1 -0
  247. package/dist/src/channels/lifecycle-supervisor.js +11 -0
  248. package/dist/src/channels/lifecycle-supervisor.js.map +1 -1
  249. package/dist/src/channels/manager.d.ts +1 -0
  250. package/dist/src/channels/manager.js +3 -0
  251. package/dist/src/channels/manager.js.map +1 -1
  252. package/dist/src/channels/pairing/pairing-channel.d.ts +2 -3
  253. package/dist/src/channels/pairing/pairing-messages.js +1 -1
  254. package/dist/src/channels/pairing/pairing-messages.js.map +1 -1
  255. package/dist/src/channels/pairing/pairing-service.d.ts +1 -1
  256. package/dist/src/channels/pairing/pairing-service.js +8 -27
  257. package/dist/src/channels/pairing/pairing-service.js.map +1 -1
  258. package/dist/src/channels/plugin-types.d.ts +3 -1
  259. package/dist/src/channels/plugins/types.adapters.d.ts +55 -2
  260. package/dist/src/channels/telegram/index.js +1 -1
  261. package/dist/src/chat-commands/builtins/config.js +4 -4
  262. package/dist/src/chat-commands/builtins/config.js.map +1 -1
  263. package/dist/src/chat-commands/builtins/model.js +2 -2
  264. package/dist/src/chat-commands/builtins/model.js.map +1 -1
  265. package/dist/src/chat-commands/config-paths.js +1 -1
  266. package/dist/src/chat-commands/config-paths.js.map +1 -1
  267. package/dist/src/chat-commands/context.js +1 -1
  268. package/dist/src/chat-commands/context.js.map +1 -1
  269. package/dist/src/cli/bin.js +1 -1
  270. package/dist/src/cli/command-manifest.js +2 -2
  271. package/dist/src/cli/command-manifest.js.map +1 -1
  272. package/dist/src/cli/commands/agent.js +2 -2
  273. package/dist/src/cli/commands/agent.js.map +1 -1
  274. package/dist/src/cli/commands/agents.js +2 -4
  275. package/dist/src/cli/commands/agents.js.map +1 -1
  276. package/dist/src/cli/commands/auth.js +40 -52
  277. package/dist/src/cli/commands/auth.js.map +1 -1
  278. package/dist/src/cli/commands/browser-cli-helpers.js +1 -1
  279. package/dist/src/cli/commands/channels.d.ts +1 -5
  280. package/dist/src/cli/commands/channels.js +115 -281
  281. package/dist/src/cli/commands/channels.js.map +1 -1
  282. package/dist/src/cli/commands/config.js +2 -2
  283. package/dist/src/cli/commands/config.js.map +1 -1
  284. package/dist/src/cli/commands/doctor/checks/channel-config.js +16 -69
  285. package/dist/src/cli/commands/doctor/checks/channel-config.js.map +1 -1
  286. package/dist/src/cli/commands/doctor/checks/channel-pairing-pending.js +6 -4
  287. package/dist/src/cli/commands/doctor/checks/channel-pairing-pending.js.map +1 -1
  288. package/dist/src/cli/commands/doctor/checks/channel-plugins.js +2 -2
  289. package/dist/src/cli/commands/doctor/checks/channel-plugins.js.map +1 -1
  290. package/dist/src/cli/commands/doctor/checks/database-schema.js +1 -1
  291. package/dist/src/cli/commands/doctor/checks/provider-auth.js +13 -9
  292. package/dist/src/cli/commands/doctor/checks/provider-auth.js.map +1 -1
  293. package/dist/src/cli/commands/extension-dev.js +2 -1
  294. package/dist/src/cli/commands/extension-dev.js.map +1 -1
  295. package/dist/src/cli/commands/extension-marketplace.js +2 -1
  296. package/dist/src/cli/commands/extension-marketplace.js.map +1 -1
  297. package/dist/src/cli/commands/extension-pack.js +2 -1
  298. package/dist/src/cli/commands/extension-pack.js.map +1 -1
  299. package/dist/src/cli/commands/models.js +192 -54
  300. package/dist/src/cli/commands/models.js.map +1 -1
  301. package/dist/src/cli/commands/onboard/channels/index.js +1 -1
  302. package/dist/src/cli/commands/onboard/channels/index.js.map +1 -1
  303. package/dist/src/cli/commands/onboard/channels/registry.d.ts +2 -1
  304. package/dist/src/cli/commands/onboard/channels/registry.js +32 -8
  305. package/dist/src/cli/commands/onboard/channels/registry.js.map +1 -1
  306. package/dist/src/cli/commands/onboard/model.d.ts +1 -4
  307. package/dist/src/cli/commands/onboard/model.js +257 -184
  308. package/dist/src/cli/commands/onboard/model.js.map +1 -1
  309. package/dist/src/cli/commands/onboard.js +4 -6
  310. package/dist/src/cli/commands/onboard.js.map +1 -1
  311. package/dist/src/cli/commands/setup-shared/runner.d.ts +1 -1
  312. package/dist/src/cli/commands/setup-shared/runner.js.map +1 -1
  313. package/dist/src/cli/commands/setup-shared/types.d.ts +1 -1
  314. package/dist/src/cli/commands/setup-shared/types.js.map +1 -1
  315. package/dist/src/cli/commands/tui.js +13 -5
  316. package/dist/src/cli/commands/tui.js.map +1 -1
  317. package/dist/src/cli/extension-cli-register.js +1 -1
  318. package/dist/src/cli/utils/oauth-login.d.ts +17 -0
  319. package/dist/src/cli/utils/oauth-login.js +93 -0
  320. package/dist/src/cli/utils/oauth-login.js.map +1 -0
  321. package/dist/src/cli/utils/oauth-providers.js +2 -2
  322. package/dist/src/commands/agents.config.d.ts +3 -3
  323. package/dist/src/commands/agents.config.js +7 -7
  324. package/dist/src/commands/agents.config.js.map +1 -1
  325. package/dist/src/config/agent-profile.d.ts +1 -1
  326. package/dist/src/config/agent-profile.js +6 -2
  327. package/dist/src/config/agent-profile.js.map +1 -1
  328. package/dist/src/config/agent-typed-models.d.ts +2 -2
  329. package/dist/src/config/agent-typed-models.js +13 -2
  330. package/dist/src/config/agent-typed-models.js.map +1 -1
  331. package/dist/src/config/index.js +3 -3
  332. package/dist/src/config/integration.d.ts +1 -1
  333. package/dist/src/config/loader.d.ts +0 -1
  334. package/dist/src/config/loader.js +4 -9
  335. package/dist/src/config/loader.js.map +1 -1
  336. package/dist/src/config/models-json.d.ts +6 -6
  337. package/dist/src/config/rules.js +2 -12
  338. package/dist/src/config/rules.js.map +1 -1
  339. package/dist/src/config/schema.d.ts +74 -47
  340. package/dist/src/config/schema.js +28 -66
  341. package/dist/src/config/schema.js.map +1 -1
  342. package/dist/src/config/validate-channel-configs.d.ts +0 -3
  343. package/dist/src/config/validate-channel-configs.js +29 -10
  344. package/dist/src/config/validate-channel-configs.js.map +1 -1
  345. package/dist/src/cron/executor.js +1 -4
  346. package/dist/src/cron/executor.js.map +1 -1
  347. package/dist/src/extensions/activation-context.js +3 -1
  348. package/dist/src/extensions/activation-context.js.map +1 -1
  349. package/dist/src/extensions/activation-planner.js +12 -0
  350. package/dist/src/extensions/activation-planner.js.map +1 -1
  351. package/dist/src/extensions/api.d.ts +5 -1
  352. package/dist/src/extensions/api.js +12 -0
  353. package/dist/src/extensions/api.js.map +1 -1
  354. package/dist/src/extensions/discover-extensions.js +17 -13
  355. package/dist/src/extensions/discover-extensions.js.map +1 -1
  356. package/dist/src/extensions/extension-metadata-snapshot.js +11 -5
  357. package/dist/src/extensions/extension-metadata-snapshot.js.map +1 -1
  358. package/dist/src/extensions/index.js +12 -4
  359. package/dist/src/extensions/index.js.map +1 -0
  360. package/dist/src/extensions/loader.d.ts +5 -1
  361. package/dist/src/extensions/loader.js +12 -11
  362. package/dist/src/extensions/loader.js.map +1 -1
  363. package/dist/src/extensions/manifest-registry.js +98 -93
  364. package/dist/src/extensions/manifest-registry.js.map +1 -1
  365. package/dist/src/extensions/normalize-manifest.js +91 -15
  366. package/dist/src/extensions/normalize-manifest.js.map +1 -1
  367. package/dist/src/extensions/sdk/index.js +1 -1
  368. package/dist/src/extensions/sdk/testing.js +4 -0
  369. package/dist/src/extensions/sdk/testing.js.map +1 -1
  370. package/dist/src/extensions/types/core.d.ts +32 -1
  371. package/dist/src/extensions/types/manifest.d.ts +60 -0
  372. package/dist/src/extensions/types/tui.d.ts +414 -5
  373. package/dist/src/gateway/agent-builtin-tools.d.ts +1 -1
  374. package/dist/src/gateway/agent-builtin-tools.js +16 -0
  375. package/dist/src/gateway/agent-builtin-tools.js.map +1 -1
  376. package/dist/src/gateway/agent-run-relay.d.ts +2 -3
  377. package/dist/src/gateway/agent-run-relay.js +10 -3
  378. package/dist/src/gateway/agent-run-relay.js.map +1 -1
  379. package/dist/src/gateway/agents-admin.d.ts +32 -19
  380. package/dist/src/gateway/agents-admin.js +113 -93
  381. package/dist/src/gateway/agents-admin.js.map +1 -1
  382. package/dist/src/gateway/chat-stream/mapper.d.ts +34 -0
  383. package/dist/src/gateway/chat-stream/mapper.js +244 -0
  384. package/dist/src/gateway/chat-stream/mapper.js.map +1 -0
  385. package/dist/src/gateway/chat-stream/protocol.d.ts +100 -0
  386. package/dist/src/gateway/chat-stream/protocol.js +1 -0
  387. package/dist/src/gateway/hono/lib/agent-model.d.ts +4 -4
  388. package/dist/src/gateway/hono/lib/agent-model.js +13 -11
  389. package/dist/src/gateway/hono/lib/agent-model.js.map +1 -1
  390. package/dist/src/gateway/hono/lib/config-payload.d.ts +19 -7
  391. package/dist/src/gateway/hono/lib/config-payload.js +16 -15
  392. package/dist/src/gateway/hono/lib/config-payload.js.map +1 -1
  393. package/dist/src/gateway/hono/oauth-async.js +2 -2
  394. package/dist/src/gateway/hono/oauth.js +2 -2
  395. package/dist/src/gateway/hono/routes/agents.js +83 -48
  396. package/dist/src/gateway/hono/routes/agents.js.map +1 -1
  397. package/dist/src/gateway/hono/routes/channels.js +134 -214
  398. package/dist/src/gateway/hono/routes/channels.js.map +1 -1
  399. package/dist/src/gateway/hono/routes/commands-skills.js +10 -4
  400. package/dist/src/gateway/hono/routes/commands-skills.js.map +1 -1
  401. package/dist/src/gateway/hono/routes/config-patch/agents.js +26 -13
  402. package/dist/src/gateway/hono/routes/config-patch/agents.js.map +1 -1
  403. package/dist/src/gateway/hono/routes/config-patch/channels.d.ts +1 -11
  404. package/dist/src/gateway/hono/routes/config-patch/channels.js +18 -165
  405. package/dist/src/gateway/hono/routes/config-patch/channels.js.map +1 -1
  406. package/dist/src/gateway/hono/routes/config.js +5 -2
  407. package/dist/src/gateway/hono/routes/config.js.map +1 -1
  408. package/dist/src/gateway/hono/routes/dreaming.js +1 -1
  409. package/dist/src/gateway/hono/routes/lazy-bundles.js +13 -1
  410. package/dist/src/gateway/hono/routes/lazy-bundles.js.map +1 -1
  411. package/dist/src/gateway/hono/routes/models.js +25 -5
  412. package/dist/src/gateway/hono/routes/models.js.map +1 -1
  413. package/dist/src/gateway/hono/routes/public-gateway.js +2 -4
  414. package/dist/src/gateway/hono/routes/public-gateway.js.map +1 -1
  415. package/dist/src/gateway/hono/routes/sessions.js +179 -0
  416. package/dist/src/gateway/hono/routes/sessions.js.map +1 -1
  417. package/dist/src/gateway/hono/routes/tui.d.ts +3 -0
  418. package/dist/src/gateway/hono/routes/tui.js +16 -0
  419. package/dist/src/gateway/hono/routes/tui.js.map +1 -0
  420. package/dist/src/gateway/hono/routes/workflows.js +25 -1
  421. package/dist/src/gateway/hono/routes/workflows.js.map +1 -1
  422. package/dist/src/gateway/hono/sse.d.ts +5 -7
  423. package/dist/src/gateway/hono/sse.js +21 -38
  424. package/dist/src/gateway/hono/sse.js.map +1 -1
  425. package/dist/src/gateway/protocol.js.map +1 -1
  426. package/dist/src/gateway/service/agent-runner.d.ts +2 -4
  427. package/dist/src/gateway/service/agent-runner.js +1 -1
  428. package/dist/src/gateway/service/agent-runner.js.map +1 -1
  429. package/dist/src/gateway/service/marketplace-service.d.ts +4 -3
  430. package/dist/src/gateway/service/marketplace-service.js +7 -4
  431. package/dist/src/gateway/service/marketplace-service.js.map +1 -1
  432. package/dist/src/gateway/service/run-gateway-agent.d.ts +2 -6
  433. package/dist/src/gateway/service/run-gateway-agent.js +63 -36
  434. package/dist/src/gateway/service/run-gateway-agent.js.map +1 -1
  435. package/dist/src/gateway/service/sessions-api.d.ts +19 -0
  436. package/dist/src/gateway/service/sessions-api.js +12 -0
  437. package/dist/src/gateway/service/sessions-api.js.map +1 -1
  438. package/dist/src/gateway/service.d.ts +6 -0
  439. package/dist/src/gateway/service.js +73 -57
  440. package/dist/src/gateway/service.js.map +1 -1
  441. package/dist/src/mcp/channel-bridge.js +1 -1
  442. package/dist/src/media/store.js +3 -0
  443. package/dist/src/media/store.js.map +1 -1
  444. package/dist/src/notes/service.js +1 -1
  445. package/dist/src/notes/service.js.map +1 -1
  446. package/dist/src/project-trust/trust-store.d.ts +30 -0
  447. package/dist/src/project-trust/trust-store.js +194 -0
  448. package/dist/src/project-trust/trust-store.js.map +1 -0
  449. package/dist/src/providers/index.d.ts +4 -4
  450. package/dist/src/providers/index.js +41 -22
  451. package/dist/src/providers/index.js.map +1 -1
  452. package/dist/src/providers/presentation.d.ts +34 -0
  453. package/dist/src/providers/presentation.js +162 -0
  454. package/dist/src/providers/presentation.js.map +1 -0
  455. package/dist/src/routing/resolve-route.d.ts +0 -3
  456. package/dist/src/routing/resolve-route.js.map +1 -1
  457. package/dist/src/routing/resolve-tui-session-key.d.ts +2 -0
  458. package/dist/src/routing/resolve-tui-session-key.js +8 -3
  459. package/dist/src/routing/resolve-tui-session-key.js.map +1 -1
  460. package/dist/src/session/client-history.d.ts +32 -0
  461. package/dist/src/session/client-history.js +232 -1
  462. package/dist/src/session/client-history.js.map +1 -1
  463. package/dist/src/session/manager.d.ts +37 -4
  464. package/dist/src/session/manager.js +39 -15
  465. package/dist/src/session/manager.js.map +1 -1
  466. package/dist/src/session/session-context-for-llm.d.ts +93 -1
  467. package/dist/src/session/session-context-for-llm.js +105 -2
  468. package/dist/src/session/session-context-for-llm.js.map +1 -1
  469. package/dist/src/session/store.d.ts +37 -0
  470. package/dist/src/session/store.js +127 -2
  471. package/dist/src/session/store.js.map +1 -1
  472. package/dist/src/session/stored-rows-to-file-entries.js +37 -1
  473. package/dist/src/session/stored-rows-to-file-entries.js.map +1 -1
  474. package/dist/src/session/types.d.ts +14 -1
  475. package/dist/src/session/types.js.map +1 -1
  476. package/dist/src/share/share-thumbnail.js +1 -1
  477. package/dist/src/storage/sqlite/migrations/004_add_session_type_metadata.sql +15 -0
  478. package/dist/src/storage/sqlite/migrations/runner.d.ts +1 -1
  479. package/dist/src/storage/sqlite/migrations/runner.js +3 -3
  480. package/dist/src/storage/sqlite/migrations/runner.js.map +1 -1
  481. package/dist/src/storage/sqlite/migrations/runner.ts +1 -1
  482. package/dist/src/storage/sqlite/row-mappers.d.ts +14 -1
  483. package/dist/src/storage/sqlite/row-mappers.js +14 -1
  484. package/dist/src/storage/sqlite/row-mappers.js.map +1 -1
  485. package/dist/src/storage/sqlite/schema.js +1 -1
  486. package/dist/src/storage/sqlite/session-metadata.js +1 -0
  487. package/dist/src/storage/sqlite/session-metadata.js.map +1 -1
  488. package/dist/src/storage/sqlite/session-repository.js +52 -25
  489. package/dist/src/storage/sqlite/session-repository.js.map +1 -1
  490. package/dist/src/tui/backends/embedded-backend.d.ts +53 -4
  491. package/dist/src/tui/backends/embedded-backend.js +227 -39
  492. package/dist/src/tui/backends/embedded-backend.js.map +1 -1
  493. package/dist/src/tui/backends/gateway-sse-backend.d.ts +59 -3
  494. package/dist/src/tui/backends/gateway-sse-backend.js +416 -26
  495. package/dist/src/tui/backends/gateway-sse-backend.js.map +1 -1
  496. package/dist/src/tui/chat-history.d.ts +5 -1
  497. package/dist/src/tui/chat-history.js +78 -8
  498. package/dist/src/tui/chat-history.js.map +1 -1
  499. package/dist/src/tui/clipboard-text.d.ts +5 -0
  500. package/dist/src/tui/clipboard-text.js +46 -0
  501. package/dist/src/tui/clipboard-text.js.map +1 -0
  502. package/dist/src/tui/components/assistant-message.d.ts +19 -3
  503. package/dist/src/tui/components/assistant-message.js +115 -9
  504. package/dist/src/tui/components/assistant-message.js.map +1 -1
  505. package/dist/src/tui/components/bash-execution.d.ts +3 -2
  506. package/dist/src/tui/components/bash-execution.js +31 -3
  507. package/dist/src/tui/components/bash-execution.js.map +1 -1
  508. package/dist/src/tui/components/bash-summary.d.ts +23 -0
  509. package/dist/src/tui/components/bash-summary.js +87 -0
  510. package/dist/src/tui/components/bash-summary.js.map +1 -0
  511. package/dist/src/tui/components/branch-message-summary.d.ts +17 -0
  512. package/dist/src/tui/components/branch-message-summary.js +43 -0
  513. package/dist/src/tui/components/branch-message-summary.js.map +1 -0
  514. package/dist/src/tui/components/branch-summary.d.ts +13 -0
  515. package/dist/src/tui/components/branch-summary.js +51 -0
  516. package/dist/src/tui/components/branch-summary.js.map +1 -0
  517. package/dist/src/tui/components/chat-log.d.ts +46 -6
  518. package/dist/src/tui/components/chat-log.js +183 -21
  519. package/dist/src/tui/components/chat-log.js.map +1 -1
  520. package/dist/src/tui/components/compaction-summary.d.ts +13 -0
  521. package/dist/src/tui/components/compaction-summary.js +46 -0
  522. package/dist/src/tui/components/compaction-summary.js.map +1 -0
  523. package/dist/src/tui/components/custom-editor.d.ts +1 -0
  524. package/dist/src/tui/components/custom-editor.js +2 -0
  525. package/dist/src/tui/components/custom-editor.js.map +1 -1
  526. package/dist/src/tui/components/custom-message.d.ts +23 -0
  527. package/dist/src/tui/components/custom-message.js +65 -0
  528. package/dist/src/tui/components/custom-message.js.map +1 -0
  529. package/dist/src/tui/components/extension-dialog.d.ts +42 -0
  530. package/dist/src/tui/components/extension-dialog.js +127 -0
  531. package/dist/src/tui/components/extension-dialog.js.map +1 -0
  532. package/dist/src/tui/components/scoped-models-selector.d.ts +7 -2
  533. package/dist/src/tui/components/scoped-models-selector.js +89 -16
  534. package/dist/src/tui/components/scoped-models-selector.js.map +1 -1
  535. package/dist/src/tui/components/searchable-select-list.d.ts +30 -3
  536. package/dist/src/tui/components/searchable-select-list.js +82 -10
  537. package/dist/src/tui/components/searchable-select-list.js.map +1 -1
  538. package/dist/src/tui/components/session-selector.d.ts +18 -4
  539. package/dist/src/tui/components/session-selector.js +207 -40
  540. package/dist/src/tui/components/session-selector.js.map +1 -1
  541. package/dist/src/tui/components/settings-selector.d.ts +6 -2
  542. package/dist/src/tui/components/settings-selector.js +126 -7
  543. package/dist/src/tui/components/settings-selector.js.map +1 -1
  544. package/dist/src/tui/components/thinking-selector.d.ts +12 -0
  545. package/dist/src/tui/components/thinking-selector.js +48 -0
  546. package/dist/src/tui/components/thinking-selector.js.map +1 -0
  547. package/dist/src/tui/components/tool-execution.d.ts +57 -3
  548. package/dist/src/tui/components/tool-execution.js +378 -28
  549. package/dist/src/tui/components/tool-execution.js.map +1 -1
  550. package/dist/src/tui/components/tui-bottom-bar.d.ts +9 -1
  551. package/dist/src/tui/components/tui-bottom-bar.js +56 -11
  552. package/dist/src/tui/components/tui-bottom-bar.js.map +1 -1
  553. package/dist/src/tui/components/tui-header.d.ts +9 -2
  554. package/dist/src/tui/components/tui-header.js +25 -5
  555. package/dist/src/tui/components/tui-header.js.map +1 -1
  556. package/dist/src/tui/components/user-message.d.ts +4 -2
  557. package/dist/src/tui/components/user-message.js +42 -9
  558. package/dist/src/tui/components/user-message.js.map +1 -1
  559. package/dist/src/tui/components/visual-truncate.d.ts +11 -0
  560. package/dist/src/tui/components/visual-truncate.js +27 -0
  561. package/dist/src/tui/components/visual-truncate.js.map +1 -0
  562. package/dist/src/tui/extension-host/autocomplete.d.ts +43 -0
  563. package/dist/src/tui/extension-host/autocomplete.js +116 -0
  564. package/dist/src/tui/extension-host/autocomplete.js.map +1 -0
  565. package/dist/src/tui/extension-host/host.d.ts +31 -1
  566. package/dist/src/tui/extension-host/host.js +123 -6
  567. package/dist/src/tui/extension-host/host.js.map +1 -1
  568. package/dist/src/tui/extension-host/load-extensions.d.ts +6 -1
  569. package/dist/src/tui/extension-host/load-extensions.js +4 -3
  570. package/dist/src/tui/extension-host/load-extensions.js.map +1 -1
  571. package/dist/src/tui/extension-host/runtime-context.d.ts +21 -0
  572. package/dist/src/tui/extension-host/runtime-context.js +152 -0
  573. package/dist/src/tui/extension-host/runtime-context.js.map +1 -0
  574. package/dist/src/tui/extension-host/runtime.d.ts +52 -4
  575. package/dist/src/tui/extension-host/runtime.js +547 -85
  576. package/dist/src/tui/extension-host/runtime.js.map +1 -1
  577. package/dist/src/tui/extension-host/surface.d.ts +20 -0
  578. package/dist/src/tui/extension-host/surface.js +30 -6
  579. package/dist/src/tui/extension-host/surface.js.map +1 -1
  580. package/dist/src/tui/extension-host/tool-renderers.d.ts +6 -3
  581. package/dist/src/tui/extension-host/tool-renderers.js +43 -5
  582. package/dist/src/tui/extension-host/tool-renderers.js.map +1 -1
  583. package/dist/src/tui/format-tui-hotkeys.d.ts +12 -2
  584. package/dist/src/tui/format-tui-hotkeys.js +22 -5
  585. package/dist/src/tui/format-tui-hotkeys.js.map +1 -1
  586. package/dist/src/tui/tui-agent-events.d.ts +8 -6
  587. package/dist/src/tui/tui-agent-events.js +200 -59
  588. package/dist/src/tui/tui-agent-events.js.map +1 -1
  589. package/dist/src/tui/tui-backend.d.ts +169 -3
  590. package/dist/src/tui/tui-command-formatters.d.ts +76 -0
  591. package/dist/src/tui/tui-command-formatters.js +594 -0
  592. package/dist/src/tui/tui-command-formatters.js.map +1 -0
  593. package/dist/src/tui/tui-commands.d.ts +57 -7
  594. package/dist/src/tui/tui-commands.js +639 -43
  595. package/dist/src/tui/tui-commands.js.map +1 -1
  596. package/dist/src/tui/tui-context-usage.d.ts +1 -1
  597. package/dist/src/tui/tui-context-usage.js +9 -1
  598. package/dist/src/tui/tui-context-usage.js.map +1 -1
  599. package/dist/src/tui/tui-extension-user-message.d.ts +8 -0
  600. package/dist/src/tui/tui-extension-user-message.js +32 -0
  601. package/dist/src/tui/tui-extension-user-message.js.map +1 -0
  602. package/dist/src/tui/tui-follow-up-queue.d.ts +9 -0
  603. package/dist/src/tui/tui-follow-up-queue.js +18 -0
  604. package/dist/src/tui/tui-follow-up-queue.js.map +1 -0
  605. package/dist/src/tui/tui-local-shell.d.ts +11 -1
  606. package/dist/src/tui/tui-local-shell.js +50 -8
  607. package/dist/src/tui/tui-local-shell.js.map +1 -1
  608. package/dist/src/tui/tui-model-picker.d.ts +26 -0
  609. package/dist/src/tui/tui-model-picker.js +152 -0
  610. package/dist/src/tui/tui-model-picker.js.map +1 -0
  611. package/dist/src/tui/tui-oauth-login.d.ts +16 -0
  612. package/dist/src/tui/tui-oauth-login.js +189 -0
  613. package/dist/src/tui/tui-oauth-login.js.map +1 -0
  614. package/dist/src/tui/tui-overlays.d.ts +3 -3
  615. package/dist/src/tui/tui-overlays.js +6 -7
  616. package/dist/src/tui/tui-overlays.js.map +1 -1
  617. package/dist/src/tui/tui-picker-overlay.d.ts +27 -32
  618. package/dist/src/tui/tui-picker-overlay.js +340 -30
  619. package/dist/src/tui/tui-picker-overlay.js.map +1 -1
  620. package/dist/src/tui/tui-picker-services.d.ts +41 -0
  621. package/dist/src/tui/tui-picker-services.js +1 -0
  622. package/dist/src/tui/tui-run-state.d.ts +11 -0
  623. package/dist/src/tui/tui-run-state.js +114 -0
  624. package/dist/src/tui/tui-run-state.js.map +1 -0
  625. package/dist/src/tui/tui-runtime-hints.d.ts +4 -0
  626. package/dist/src/tui/tui-runtime-hints.js +18 -0
  627. package/dist/src/tui/tui-runtime-hints.js.map +1 -0
  628. package/dist/src/tui/tui-scoped-models.d.ts +1 -1
  629. package/dist/src/tui/tui-scoped-models.js +2 -2
  630. package/dist/src/tui/tui-scoped-models.js.map +1 -1
  631. package/dist/src/tui/tui-session-actions.d.ts +5 -3
  632. package/dist/src/tui/tui-session-actions.js +21 -9
  633. package/dist/src/tui/tui-session-actions.js.map +1 -1
  634. package/dist/src/tui/tui-session-format.d.ts +4 -1
  635. package/dist/src/tui/tui-session-format.js +17 -3
  636. package/dist/src/tui/tui-session-format.js.map +1 -1
  637. package/dist/src/tui/tui-session-snapshot.d.ts +82 -0
  638. package/dist/src/tui/tui-session-snapshot.js +184 -0
  639. package/dist/src/tui/tui-session-snapshot.js.map +1 -0
  640. package/dist/src/tui/tui-session-stats.d.ts +3 -0
  641. package/dist/src/tui/tui-session-stats.js +59 -0
  642. package/dist/src/tui/tui-session-stats.js.map +1 -0
  643. package/dist/src/tui/tui-settings.d.ts +21 -0
  644. package/dist/src/tui/tui-settings.js +28 -1
  645. package/dist/src/tui/tui-settings.js.map +1 -1
  646. package/dist/src/tui/tui-skills-autocomplete.js +1 -1
  647. package/dist/src/tui/tui-skills-autocomplete.js.map +1 -1
  648. package/dist/src/tui/tui-startup-resources.d.ts +3 -0
  649. package/dist/src/tui/tui-startup-resources.js +39 -0
  650. package/dist/src/tui/tui-startup-resources.js.map +1 -0
  651. package/dist/src/tui/tui-startup-text.d.ts +10 -0
  652. package/dist/src/tui/tui-startup-text.js +58 -0
  653. package/dist/src/tui/tui-startup-text.js.map +1 -0
  654. package/dist/src/tui/tui-stdio-filter.d.ts +1 -0
  655. package/dist/src/tui/tui-stdio-filter.js +11 -7
  656. package/dist/src/tui/tui-stdio-filter.js.map +1 -1
  657. package/dist/src/tui/tui-submit.d.ts +2 -0
  658. package/dist/src/tui/tui-submit.js +2 -1
  659. package/dist/src/tui/tui-submit.js.map +1 -1
  660. package/dist/src/tui/tui-tool-diff.js +61 -7
  661. package/dist/src/tui/tui-tool-diff.js.map +1 -1
  662. package/dist/src/tui/tui-tool-result.d.ts +17 -0
  663. package/dist/src/tui/tui-tool-result.js +74 -0
  664. package/dist/src/tui/tui-tool-result.js.map +1 -0
  665. package/dist/src/tui/tui-transcript-tree-picker.d.ts +57 -0
  666. package/dist/src/tui/tui-transcript-tree-picker.js +604 -0
  667. package/dist/src/tui/tui-transcript-tree-picker.js.map +1 -0
  668. package/dist/src/tui/tui-transcript-tree.d.ts +7 -0
  669. package/dist/src/tui/tui-transcript-tree.js +316 -0
  670. package/dist/src/tui/tui-transcript-tree.js.map +1 -0
  671. package/dist/src/tui/tui-types.d.ts +25 -34
  672. package/dist/src/tui/tui-types.js +12 -0
  673. package/dist/src/tui/tui-types.js.map +1 -1
  674. package/dist/src/tui/tui.js +1288 -112
  675. package/dist/src/tui/tui.js.map +1 -1
  676. package/dist/src/tui/xopc-tui-keybindings.d.ts +127 -2
  677. package/dist/src/tui/xopc-tui-keybindings.js +127 -2
  678. package/dist/src/tui/xopc-tui-keybindings.js.map +1 -1
  679. package/dist/src/workflows/domain/definition-utils.d.ts +2 -1
  680. package/dist/src/workflows/domain/definition-utils.js +18 -8
  681. package/dist/src/workflows/domain/definition-utils.js.map +1 -1
  682. package/dist/src/workflows/domain/definition.d.ts +25 -0
  683. package/dist/src/workflows/domain/event.d.ts +1 -0
  684. package/dist/src/workflows/domain/result.d.ts +15 -0
  685. package/dist/src/workflows/domain/run.d.ts +2 -0
  686. package/dist/src/workflows/domain/run.js.map +1 -1
  687. package/dist/src/workflows/engine/projector.js +4 -0
  688. package/dist/src/workflows/engine/projector.js.map +1 -1
  689. package/dist/src/workflows/engine/workflow-engine.d.ts +37 -1
  690. package/dist/src/workflows/engine/workflow-engine.js +75 -11
  691. package/dist/src/workflows/engine/workflow-engine.js.map +1 -1
  692. package/dist/src/workflows/index.d.ts +1 -0
  693. package/dist/src/workflows/index.js +4 -1
  694. package/dist/src/workflows/registry/catalog-workflow-definition-registry.d.ts +9 -0
  695. package/dist/src/workflows/registry/catalog-workflow-definition-registry.js +40 -0
  696. package/dist/src/workflows/registry/catalog-workflow-definition-registry.js.map +1 -0
  697. package/dist/src/workflows/registry/index.d.ts +2 -0
  698. package/dist/src/workflows/registry/index.js +2 -0
  699. package/dist/src/workflows/registry/workflow-definition-registry.d.ts +15 -0
  700. package/dist/src/workflows/registry/workflow-definition-registry.js +1 -0
  701. package/dist/src/workflows/runtime/index.d.ts +2 -0
  702. package/dist/src/workflows/runtime/index.js +2 -1
  703. package/dist/src/workflows/runtime/script-workflow-runtime.d.ts +5 -0
  704. package/dist/src/workflows/runtime/script-workflow-runtime.js +15 -0
  705. package/dist/src/workflows/runtime/script-workflow-runtime.js.map +1 -0
  706. package/dist/src/workflows/runtime/workflow-runtime-port.d.ts +16 -0
  707. package/dist/src/workflows/runtime/workflow-runtime-port.js +1 -0
  708. package/dist/src/workflows/service/run-view-to-snapshot.js +3 -0
  709. package/dist/src/workflows/service/run-view-to-snapshot.js.map +1 -1
  710. package/dist/src/workflows/service/workflow-run-service.d.ts +3 -0
  711. package/dist/src/workflows/service/workflow-run-service.js +10 -15
  712. package/dist/src/workflows/service/workflow-run-service.js.map +1 -1
  713. package/dist/src/workflows/service/workflow-session-bridge.d.ts +1 -1
  714. package/dist/src/workflows/service/workflow-session-bridge.js +4 -1
  715. package/dist/src/workflows/service/workflow-session-bridge.js.map +1 -1
  716. package/package.json +21 -15
  717. package/skills/creative/frontend-design/SKILL.md +1 -1
  718. package/skills/creative/theme-factory/SKILL.md +1 -1
  719. package/skills/documents/xlsx/SKILL.md +1 -1
  720. package/skills/engineering/diagnose/SKILL.md +2 -2
  721. package/skills/engineering/tdd/SKILL.md +1 -1
  722. package/skills/tools/github/SKILL.md +6 -1
  723. package/skills/tools/webapp-testing/SKILL.md +4 -1
  724. package/dist/extensions/telegram/src/adapters/config-surface.d.ts +0 -2
  725. package/dist/extensions/telegram/src/adapters/config-surface.js +0 -26
  726. package/dist/extensions/telegram/src/adapters/config-surface.js.map +0 -1
  727. package/dist/extensions/weixin/src/__tests__/workflow-progress.test.js +0 -158
  728. package/dist/extensions/weixin/src/__tests__/workflow-progress.test.js.map +0 -1
  729. package/dist/gateway/static/root/assets/agents-DQ0mQxIA.js +0 -222
  730. package/dist/gateway/static/root/assets/channels-settings-BEtP53V6.js +0 -1
  731. package/dist/gateway/static/root/assets/channels-status-swr-CxTtS1hI.js +0 -8
  732. package/dist/gateway/static/root/assets/cron-api-CznlPIZT.js +0 -1
  733. package/dist/gateway/static/root/assets/cron-page-Dx6dE3eD.js +0 -1
  734. package/dist/gateway/static/root/assets/extension-settings-page-DuDCSb3J.js +0 -1
  735. package/dist/gateway/static/root/assets/field-primitives-BUwUiDf5.js +0 -1
  736. package/dist/gateway/static/root/assets/heartbeat-config-api-BjFW1cl-.js +0 -1
  737. package/dist/gateway/static/root/assets/index-DKgHC1Ta.js +0 -4840
  738. package/dist/gateway/static/root/assets/index-DjNDHzwG.css +0 -1
  739. package/dist/gateway/static/root/assets/notes-page-D40ZpS0Y.js +0 -1
  740. package/dist/gateway/static/root/assets/sessions-page-BvtdbmW8.js +0 -1
  741. package/dist/gateway/static/root/assets/settings-advanced-gate-BQamRjkV.js +0 -2
  742. package/dist/gateway/static/root/assets/settings-page-D972_jaS.js +0 -3
  743. package/dist/gateway/static/root/assets/share-preview-page-CKCTMo0_.js +0 -2
  744. package/dist/gateway/static/root/assets/skills-page-QwFCB4yV.js +0 -2
  745. package/dist/gateway/static/root/assets/url-q28QhI7l.js +0 -3
  746. package/dist/gateway/static/root/assets/utils-DCm11_KW.js +0 -1
  747. package/dist/gateway/static/root/assets/voice-api-key-field-CywiB7Dw.js +0 -1
  748. package/dist/gateway/static/root/assets/workflows-page-Be7l_SWw.js +0 -27
  749. package/dist/src/agent/embedded/map-stream-events.d.ts +0 -9
  750. package/dist/src/agent/embedded/map-stream-events.js +0 -63
  751. package/dist/src/agent/embedded/map-stream-events.js.map +0 -1
  752. package/dist/src/auth/oauth/vendor-pi-google/google-antigravity.js.map +0 -1
  753. package/dist/src/auth/oauth/vendor-pi-google/google-gemini-cli.js.map +0 -1
  754. package/dist/src/auth/oauth/vendor-pi-google/oauth-page.js.map +0 -1
  755. package/dist/src/auth/oauth/vendor-pi-google/pkce.js.map +0 -1
  756. package/dist/src/channels/dock.js.map +0 -1
  757. package/dist/src/channels/plugins/bundled.d.ts +0 -11
  758. package/dist/src/channels/plugins/bundled.js +0 -10
  759. package/dist/src/channels/plugins/bundled.js.map +0 -1
  760. package/dist/src/channels/registry.d.ts +0 -25
  761. package/dist/src/channels/registry.js +0 -82
  762. package/dist/src/channels/registry.js.map +0 -1
  763. package/dist/src/config/localized-text.d.ts +0 -6
  764. package/dist/src/config/localized-text.js +0 -42
  765. package/dist/src/config/localized-text.js.map +0 -1
  766. package/dist/src/generated/bundled-channel-plugins.d.ts +0 -10
  767. package/dist/src/generated/bundled-channel-plugins.js +0 -16
  768. package/dist/src/generated/bundled-channel-plugins.js.map +0 -1
  769. package/dist/src/tui/stream-assembler.d.ts +0 -22
  770. package/dist/src/tui/stream-assembler.js +0 -63
  771. package/dist/src/tui/stream-assembler.js.map +0 -1
  772. package/skills/browser/SKILL-zh.md +0 -188
  773. package/skills/business/company-values/SKILL-zh.md +0 -80
  774. package/skills/business/company-values/SKILL.md +0 -80
  775. package/skills/business/find-community/SKILL-zh.md +0 -50
  776. package/skills/business/find-community/SKILL.md +0 -50
  777. package/skills/business/first-customers/SKILL-zh.md +0 -76
  778. package/skills/business/first-customers/SKILL.md +0 -76
  779. package/skills/business/grow-sustainably/SKILL-zh.md +0 -92
  780. package/skills/business/grow-sustainably/SKILL.md +0 -92
  781. package/skills/business/marketing-plan/SKILL-zh.md +0 -100
  782. package/skills/business/marketing-plan/SKILL.md +0 -100
  783. package/skills/business/minimalist-review/SKILL-zh.md +0 -82
  784. package/skills/business/minimalist-review/SKILL.md +0 -82
  785. package/skills/business/mvp/SKILL-zh.md +0 -81
  786. package/skills/business/mvp/SKILL.md +0 -81
  787. package/skills/business/pricing/SKILL-zh.md +0 -64
  788. package/skills/business/pricing/SKILL.md +0 -64
  789. package/skills/business/processize/SKILL-zh.md +0 -91
  790. package/skills/business/processize/SKILL.md +0 -91
  791. package/skills/business/validate-idea/SKILL-zh.md +0 -68
  792. package/skills/business/validate-idea/SKILL.md +0 -68
  793. package/skills/creative/algorithmic-art/LICENSE.txt +0 -202
  794. package/skills/creative/algorithmic-art/SKILL-zh.md +0 -405
  795. package/skills/creative/algorithmic-art/SKILL.md +0 -405
  796. package/skills/creative/algorithmic-art/templates/generator_template.js +0 -223
  797. package/skills/creative/algorithmic-art/templates/viewer.html +0 -599
  798. package/skills/creative/frontend-design/SKILL-zh.md +0 -42
  799. package/skills/creative/theme-factory/SKILL-zh.md +0 -59
  800. package/skills/creative/web-artifacts-builder/LICENSE.txt +0 -202
  801. package/skills/creative/web-artifacts-builder/SKILL-zh.md +0 -74
  802. package/skills/creative/web-artifacts-builder/SKILL.md +0 -74
  803. package/skills/creative/web-artifacts-builder/scripts/bundle-artifact.sh +0 -54
  804. package/skills/creative/web-artifacts-builder/scripts/init-artifact.sh +0 -322
  805. package/skills/creative/web-artifacts-builder/scripts/shadcn-components.tar.gz +0 -0
  806. package/skills/documents/doc-coauthoring/SKILL-zh.md +0 -375
  807. package/skills/documents/doc-coauthoring/SKILL.md +0 -375
  808. package/skills/documents/docx/LICENSE.txt +0 -30
  809. package/skills/documents/docx/SKILL-zh.md +0 -590
  810. package/skills/documents/docx/SKILL.md +0 -590
  811. package/skills/documents/docx/scripts/__init__.py +0 -1
  812. package/skills/documents/docx/scripts/accept_changes.py +0 -135
  813. package/skills/documents/docx/scripts/comment.py +0 -318
  814. package/skills/documents/docx/scripts/office/helpers/__init__.py +0 -0
  815. package/skills/documents/docx/scripts/office/helpers/merge_runs.py +0 -199
  816. package/skills/documents/docx/scripts/office/helpers/simplify_redlines.py +0 -197
  817. package/skills/documents/docx/scripts/office/pack.py +0 -159
  818. package/skills/documents/docx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-chart.xsd +0 -1499
  819. package/skills/documents/docx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-chartDrawing.xsd +0 -146
  820. package/skills/documents/docx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-diagram.xsd +0 -1085
  821. package/skills/documents/docx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-lockedCanvas.xsd +0 -11
  822. package/skills/documents/docx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-main.xsd +0 -3081
  823. package/skills/documents/docx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-picture.xsd +0 -23
  824. package/skills/documents/docx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-spreadsheetDrawing.xsd +0 -185
  825. package/skills/documents/docx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-wordprocessingDrawing.xsd +0 -287
  826. package/skills/documents/docx/scripts/office/schemas/ISO-IEC29500-4_2016/pml.xsd +0 -1676
  827. package/skills/documents/docx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-additionalCharacteristics.xsd +0 -28
  828. package/skills/documents/docx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-bibliography.xsd +0 -144
  829. package/skills/documents/docx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-commonSimpleTypes.xsd +0 -174
  830. package/skills/documents/docx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-customXmlDataProperties.xsd +0 -25
  831. package/skills/documents/docx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-customXmlSchemaProperties.xsd +0 -18
  832. package/skills/documents/docx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesCustom.xsd +0 -59
  833. package/skills/documents/docx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesExtended.xsd +0 -56
  834. package/skills/documents/docx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesVariantTypes.xsd +0 -195
  835. package/skills/documents/docx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-math.xsd +0 -582
  836. package/skills/documents/docx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-relationshipReference.xsd +0 -25
  837. package/skills/documents/docx/scripts/office/schemas/ISO-IEC29500-4_2016/sml.xsd +0 -4439
  838. package/skills/documents/docx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-main.xsd +0 -570
  839. package/skills/documents/docx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-officeDrawing.xsd +0 -509
  840. package/skills/documents/docx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-presentationDrawing.xsd +0 -12
  841. package/skills/documents/docx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-spreadsheetDrawing.xsd +0 -108
  842. package/skills/documents/docx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-wordprocessingDrawing.xsd +0 -96
  843. package/skills/documents/docx/scripts/office/schemas/ISO-IEC29500-4_2016/wml.xsd +0 -3646
  844. package/skills/documents/docx/scripts/office/schemas/ISO-IEC29500-4_2016/xml.xsd +0 -116
  845. package/skills/documents/docx/scripts/office/schemas/ecma/fouth-edition/opc-contentTypes.xsd +0 -42
  846. package/skills/documents/docx/scripts/office/schemas/ecma/fouth-edition/opc-coreProperties.xsd +0 -50
  847. package/skills/documents/docx/scripts/office/schemas/ecma/fouth-edition/opc-digSig.xsd +0 -49
  848. package/skills/documents/docx/scripts/office/schemas/ecma/fouth-edition/opc-relationships.xsd +0 -33
  849. package/skills/documents/docx/scripts/office/schemas/mce/mc.xsd +0 -75
  850. package/skills/documents/docx/scripts/office/schemas/microsoft/wml-2010.xsd +0 -560
  851. package/skills/documents/docx/scripts/office/schemas/microsoft/wml-2012.xsd +0 -67
  852. package/skills/documents/docx/scripts/office/schemas/microsoft/wml-2018.xsd +0 -14
  853. package/skills/documents/docx/scripts/office/schemas/microsoft/wml-cex-2018.xsd +0 -20
  854. package/skills/documents/docx/scripts/office/schemas/microsoft/wml-cid-2016.xsd +0 -13
  855. package/skills/documents/docx/scripts/office/schemas/microsoft/wml-sdtdatahash-2020.xsd +0 -4
  856. package/skills/documents/docx/scripts/office/schemas/microsoft/wml-symex-2015.xsd +0 -8
  857. package/skills/documents/docx/scripts/office/soffice.py +0 -183
  858. package/skills/documents/docx/scripts/office/unpack.py +0 -132
  859. package/skills/documents/docx/scripts/office/validate.py +0 -111
  860. package/skills/documents/docx/scripts/office/validators/__init__.py +0 -15
  861. package/skills/documents/docx/scripts/office/validators/base.py +0 -847
  862. package/skills/documents/docx/scripts/office/validators/docx.py +0 -446
  863. package/skills/documents/docx/scripts/office/validators/pptx.py +0 -275
  864. package/skills/documents/docx/scripts/office/validators/redlining.py +0 -247
  865. package/skills/documents/docx/scripts/templates/comments.xml +0 -3
  866. package/skills/documents/docx/scripts/templates/commentsExtended.xml +0 -3
  867. package/skills/documents/docx/scripts/templates/commentsExtensible.xml +0 -3
  868. package/skills/documents/docx/scripts/templates/commentsIds.xml +0 -3
  869. package/skills/documents/docx/scripts/templates/people.xml +0 -3
  870. package/skills/documents/pdf/LICENSE.txt +0 -30
  871. package/skills/documents/pdf/SKILL-zh.md +0 -314
  872. package/skills/documents/pdf/SKILL.md +0 -314
  873. package/skills/documents/pdf/forms.md +0 -294
  874. package/skills/documents/pdf/reference.md +0 -612
  875. package/skills/documents/pdf/scripts/check_bounding_boxes.py +0 -65
  876. package/skills/documents/pdf/scripts/check_fillable_fields.py +0 -11
  877. package/skills/documents/pdf/scripts/convert_pdf_to_images.py +0 -33
  878. package/skills/documents/pdf/scripts/create_validation_image.py +0 -37
  879. package/skills/documents/pdf/scripts/extract_form_field_info.py +0 -122
  880. package/skills/documents/pdf/scripts/extract_form_structure.py +0 -115
  881. package/skills/documents/pdf/scripts/fill_fillable_fields.py +0 -98
  882. package/skills/documents/pdf/scripts/fill_pdf_form_with_annotations.py +0 -107
  883. package/skills/documents/pptx/LICENSE.txt +0 -30
  884. package/skills/documents/pptx/SKILL-zh.md +0 -232
  885. package/skills/documents/pptx/SKILL.md +0 -232
  886. package/skills/documents/pptx/editing.md +0 -205
  887. package/skills/documents/pptx/pptxgenjs.md +0 -420
  888. package/skills/documents/pptx/scripts/__init__.py +0 -0
  889. package/skills/documents/pptx/scripts/add_slide.py +0 -195
  890. package/skills/documents/pptx/scripts/clean.py +0 -286
  891. package/skills/documents/pptx/scripts/office/helpers/__init__.py +0 -0
  892. package/skills/documents/pptx/scripts/office/helpers/merge_runs.py +0 -199
  893. package/skills/documents/pptx/scripts/office/helpers/simplify_redlines.py +0 -197
  894. package/skills/documents/pptx/scripts/office/pack.py +0 -159
  895. package/skills/documents/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-chart.xsd +0 -1499
  896. package/skills/documents/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-chartDrawing.xsd +0 -146
  897. package/skills/documents/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-diagram.xsd +0 -1085
  898. package/skills/documents/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-lockedCanvas.xsd +0 -11
  899. package/skills/documents/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-main.xsd +0 -3081
  900. package/skills/documents/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-picture.xsd +0 -23
  901. package/skills/documents/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-spreadsheetDrawing.xsd +0 -185
  902. package/skills/documents/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-wordprocessingDrawing.xsd +0 -287
  903. package/skills/documents/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/pml.xsd +0 -1676
  904. package/skills/documents/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-additionalCharacteristics.xsd +0 -28
  905. package/skills/documents/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-bibliography.xsd +0 -144
  906. package/skills/documents/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-commonSimpleTypes.xsd +0 -174
  907. package/skills/documents/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-customXmlDataProperties.xsd +0 -25
  908. package/skills/documents/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-customXmlSchemaProperties.xsd +0 -18
  909. package/skills/documents/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesCustom.xsd +0 -59
  910. package/skills/documents/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesExtended.xsd +0 -56
  911. package/skills/documents/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesVariantTypes.xsd +0 -195
  912. package/skills/documents/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-math.xsd +0 -582
  913. package/skills/documents/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-relationshipReference.xsd +0 -25
  914. package/skills/documents/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/sml.xsd +0 -4439
  915. package/skills/documents/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-main.xsd +0 -570
  916. package/skills/documents/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-officeDrawing.xsd +0 -509
  917. package/skills/documents/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-presentationDrawing.xsd +0 -12
  918. package/skills/documents/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-spreadsheetDrawing.xsd +0 -108
  919. package/skills/documents/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-wordprocessingDrawing.xsd +0 -96
  920. package/skills/documents/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/wml.xsd +0 -3646
  921. package/skills/documents/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/xml.xsd +0 -116
  922. package/skills/documents/pptx/scripts/office/schemas/ecma/fouth-edition/opc-contentTypes.xsd +0 -42
  923. package/skills/documents/pptx/scripts/office/schemas/ecma/fouth-edition/opc-coreProperties.xsd +0 -50
  924. package/skills/documents/pptx/scripts/office/schemas/ecma/fouth-edition/opc-digSig.xsd +0 -49
  925. package/skills/documents/pptx/scripts/office/schemas/ecma/fouth-edition/opc-relationships.xsd +0 -33
  926. package/skills/documents/pptx/scripts/office/schemas/mce/mc.xsd +0 -75
  927. package/skills/documents/pptx/scripts/office/schemas/microsoft/wml-2010.xsd +0 -560
  928. package/skills/documents/pptx/scripts/office/schemas/microsoft/wml-2012.xsd +0 -67
  929. package/skills/documents/pptx/scripts/office/schemas/microsoft/wml-2018.xsd +0 -14
  930. package/skills/documents/pptx/scripts/office/schemas/microsoft/wml-cex-2018.xsd +0 -20
  931. package/skills/documents/pptx/scripts/office/schemas/microsoft/wml-cid-2016.xsd +0 -13
  932. package/skills/documents/pptx/scripts/office/schemas/microsoft/wml-sdtdatahash-2020.xsd +0 -4
  933. package/skills/documents/pptx/scripts/office/schemas/microsoft/wml-symex-2015.xsd +0 -8
  934. package/skills/documents/pptx/scripts/office/soffice.py +0 -183
  935. package/skills/documents/pptx/scripts/office/unpack.py +0 -132
  936. package/skills/documents/pptx/scripts/office/validate.py +0 -111
  937. package/skills/documents/pptx/scripts/office/validators/__init__.py +0 -15
  938. package/skills/documents/pptx/scripts/office/validators/base.py +0 -847
  939. package/skills/documents/pptx/scripts/office/validators/docx.py +0 -446
  940. package/skills/documents/pptx/scripts/office/validators/pptx.py +0 -275
  941. package/skills/documents/pptx/scripts/office/validators/redlining.py +0 -247
  942. package/skills/documents/pptx/scripts/thumbnail.py +0 -289
  943. package/skills/documents/xlsx/SKILL-zh.md +0 -292
  944. package/skills/engineering/diagnose/SKILL-zh.md +0 -117
  945. package/skills/engineering/grill-with-docs/ADR-FORMAT.md +0 -47
  946. package/skills/engineering/grill-with-docs/CONTEXT-FORMAT.md +0 -77
  947. package/skills/engineering/grill-with-docs/SKILL-zh.md +0 -88
  948. package/skills/engineering/grill-with-docs/SKILL.md +0 -88
  949. package/skills/engineering/improve-codebase-architecture/DEEPENING.md +0 -37
  950. package/skills/engineering/improve-codebase-architecture/INTERFACE-DESIGN.md +0 -44
  951. package/skills/engineering/improve-codebase-architecture/LANGUAGE.md +0 -53
  952. package/skills/engineering/improve-codebase-architecture/SKILL-zh.md +0 -71
  953. package/skills/engineering/improve-codebase-architecture/SKILL.md +0 -71
  954. package/skills/engineering/tdd/SKILL-zh.md +0 -109
  955. package/skills/engineering/to-issues/SKILL-zh.md +0 -81
  956. package/skills/engineering/to-issues/SKILL.md +0 -81
  957. package/skills/engineering/to-prd/SKILL-zh.md +0 -76
  958. package/skills/engineering/to-prd/SKILL.md +0 -74
  959. package/skills/engineering/zoom-out/SKILL-zh.md +0 -7
  960. package/skills/engineering/zoom-out/SKILL.md +0 -7
  961. package/skills/tools/find-skills/SKILL-zh.md +0 -440
  962. package/skills/tools/github/SKILL-zh.md +0 -48
  963. package/skills/tools/internal-comms/LICENSE.txt +0 -202
  964. package/skills/tools/internal-comms/SKILL-zh.md +0 -32
  965. package/skills/tools/internal-comms/SKILL.md +0 -32
  966. package/skills/tools/internal-comms/examples/3p-updates.md +0 -47
  967. package/skills/tools/internal-comms/examples/company-newsletter.md +0 -65
  968. package/skills/tools/internal-comms/examples/faq-answers.md +0 -30
  969. package/skills/tools/internal-comms/examples/general-comms.md +0 -16
  970. package/skills/tools/skill-creator/LICENSE.txt +0 -202
  971. package/skills/tools/skill-creator/SKILL-zh.md +0 -483
  972. package/skills/tools/skill-creator/SKILL.md +0 -485
  973. package/skills/tools/skill-creator/agents/analyzer.md +0 -274
  974. package/skills/tools/skill-creator/agents/comparator.md +0 -202
  975. package/skills/tools/skill-creator/agents/grader.md +0 -223
  976. package/skills/tools/skill-creator/assets/eval_review.html +0 -146
  977. package/skills/tools/skill-creator/eval-viewer/generate_review.py +0 -471
  978. package/skills/tools/skill-creator/eval-viewer/viewer.html +0 -1325
  979. package/skills/tools/skill-creator/references/schemas.md +0 -430
  980. package/skills/tools/skill-creator/scripts/__init__.py +0 -0
  981. package/skills/tools/skill-creator/scripts/aggregate_benchmark.py +0 -401
  982. package/skills/tools/skill-creator/scripts/generate_report.py +0 -326
  983. package/skills/tools/skill-creator/scripts/improve_description.py +0 -247
  984. package/skills/tools/skill-creator/scripts/package_skill.py +0 -136
  985. package/skills/tools/skill-creator/scripts/quick_validate.py +0 -103
  986. package/skills/tools/skill-creator/scripts/run_eval.py +0 -310
  987. package/skills/tools/skill-creator/scripts/run_loop.py +0 -328
  988. package/skills/tools/skill-creator/scripts/utils.py +0 -47
  989. package/skills/tools/summarize/SKILL-zh.md +0 -47
  990. package/skills/tools/weather/SKILL-zh.md +0 -46
  991. package/skills/tools/weather/SKILL.md +0 -46
  992. package/skills/tools/webapp-testing/SKILL-zh.md +0 -96
  993. /package/dist/src/auth/oauth/{vendor-pi-google → google-oauth}/google-antigravity.d.ts +0 -0
  994. /package/dist/src/auth/oauth/{vendor-pi-google → google-oauth}/google-gemini-cli.d.ts +0 -0
  995. /package/dist/src/auth/oauth/{vendor-pi-google → google-oauth}/oauth-page.d.ts +0 -0
@@ -1 +1 @@
1
- {"version":3,"file":"manager.js","names":[],"sources":["../../../src/channels/manager.ts"],"sourcesContent":["/**\n * Channel Manager — thin composition root for the channel subsystem.\n *\n * Wires together the four coordinators that own what used to be the eight\n * concerns of this 707-line class:\n *\n * - {@link ChannelPluginRegistry} — plugins Map, register/get\n * - {@link ChannelLifecycleSupervisor} — init/start/stop/restart-backoff\n * - {@link ChannelHeartbeatScheduler} — per-account heartbeat probes\n * - {@link ChannelOutboundSender} — TTS rewrite + persist + delivery\n *\n * The public surface (`registerPlugin`, `initialize`, `start`, `send`, etc.) is\n * preserved so callers (`GatewayService`, CLI commands, channel plugins) are\n * unchanged.\n */\n\nimport type { Config } from '../config/schema.js';\nimport type { MessageBus } from '../infra/bus/index.js';\n\nimport type { InboundMessage, OutboundMessage } from './transport-types.js';\nimport type {\n ChannelPlugin,\n ChannelPluginSessionModelHooks,\n ChannelStreamHandle,\n} from './plugin-types.js';\nimport { ChannelHealthMonitor, type ChannelHealthState } from './health-monitor.js';\nimport { ChannelPluginRegistry } from './plugin-registry.js';\nimport { ChannelHeartbeatScheduler } from './heartbeat-scheduler.js';\nimport {\n ChannelOutboundSender,\n type OutboundChannelHooks,\n} from './outbound-sender.js';\nimport { ChannelLifecycleSupervisor } from './lifecycle-supervisor.js';\nimport { createLogger } from '../utils/logger.js';\n\nconst log = createLogger('ChannelManager');\n\nexport type { OutboundChannelHooks } from './outbound-sender.js';\n\nexport class ChannelManager {\n private config: Config;\n private readonly registry = new ChannelPluginRegistry();\n private readonly healthMonitor = new ChannelHealthMonitor();\n private readonly lifecycle: ChannelLifecycleSupervisor;\n private readonly heartbeat: ChannelHeartbeatScheduler;\n private readonly outbound: ChannelOutboundSender;\n private sessionModelHooks?: ChannelPluginSessionModelHooks;\n\n constructor(config: Config, bus: MessageBus) {\n this.config = config;\n\n this.heartbeat = new ChannelHeartbeatScheduler({\n getConfig: () => this.config,\n healthMonitor: this.healthMonitor,\n requestSoftRestart: (channelId) => {\n void this.lifecycle.softRestart(channelId);\n },\n });\n\n this.lifecycle = new ChannelLifecycleSupervisor({\n bus,\n registry: this.registry,\n getConfig: () => this.config,\n getSessionModelHooks: () => this.sessionModelHooks,\n onPluginStarted: (plugin) => this.heartbeat.schedule(plugin),\n onPluginStopped: (pluginId) => this.heartbeat.clear(pluginId),\n });\n\n this.outbound = new ChannelOutboundSender({\n registry: this.registry,\n getConfig: () => this.config,\n });\n }\n\n // ── Wiring hooks (called by GatewayService / cli) ─────────────────────\n\n setOutboundHooks(hooks: OutboundChannelHooks): void {\n this.outbound.setHooks(hooks);\n }\n\n /** Call before `initialize()` so plugins can persist per-session model overrides. */\n setSessionModelHooks(hooks: ChannelPluginSessionModelHooks | undefined): void {\n this.sessionModelHooks = hooks;\n }\n\n enableOutboundPersistence(agentDir: string): void {\n this.outbound.enablePersistence(agentDir);\n }\n\n // ── Plugin registry pass-throughs ──────────────────────────────────────\n\n registerPlugin(plugin: ChannelPlugin): void {\n this.registry.register(plugin);\n }\n\n getPlugin(id: string): ChannelPlugin | undefined {\n return this.registry.get(id);\n }\n\n getAllPlugins(): ChannelPlugin[] {\n return this.registry.all();\n }\n\n /** Backward-compat alias for `getAllPlugins`. */\n getAllChannels(): ChannelPlugin[] {\n return this.registry.all();\n }\n\n /** Channel IDs whose runtime reports connected (e.g. Telegram polling active). */\n getRunningChannels(): string[] {\n return this.registry.runningChannelIds(this.config, (id) => this.lifecycle.isInitialized(id));\n }\n\n // ── Lifecycle pass-throughs ────────────────────────────────────────────\n\n initialize(): Promise<void> {\n return this.lifecycle.initialize();\n }\n\n start(options?: { deferConnectPluginIds?: ReadonlySet<string> }): Promise<void> {\n return this.lifecycle.start(options);\n }\n\n startDeferredConnects(): Promise<void> {\n return this.lifecycle.startDeferredConnects();\n }\n\n async stop(): Promise<void> {\n await this.lifecycle.stop();\n this.heartbeat.clearAll();\n }\n\n stopChannel(channelId: string): Promise<void> {\n return this.lifecycle.stopChannel(channelId);\n }\n\n startChannel(channelId: string): Promise<void> {\n return this.lifecycle.startChannel(channelId);\n }\n\n listDeferConnectChannelIds(cfg: Config): string[] {\n return this.lifecycle.listDeferConnectChannelIds(cfg);\n }\n\n // ── Outbound pass-throughs ─────────────────────────────────────────────\n\n send(msg: OutboundMessage, options?: { skipPersist?: boolean }): Promise<void> {\n return this.outbound.send(msg, options);\n }\n\n replayPendingOutboundMessages(): Promise<void> {\n return this.outbound.replayPending();\n }\n\n // ── Streaming + status query (delegated to plugin directly) ────────────\n\n startStream(\n channel: string,\n chatId: string,\n accountId?: string,\n opts?: { threadId?: string; replyToMessageId?: string },\n ): ChannelStreamHandle | null {\n const plugin = this.registry.get(channel);\n if (!plugin) {\n log.error({ channel }, 'Unknown channel');\n return null;\n }\n return (\n plugin.streaming?.startStream?.({\n chatId,\n accountId,\n threadId: opts?.threadId,\n replyToMessageId: opts?.replyToMessageId,\n }) ?? null\n );\n }\n\n async getChannelStatus(channel: string): Promise<Record<string, unknown>> {\n const plugin = this.registry.get(channel);\n if (!plugin) return { error: 'Unknown channel' };\n if (!plugin.status?.buildChannelSummary) return { status: 'unknown' };\n\n try {\n const accountId = plugin.config.listAccountIds(this.config)[0] ?? 'default';\n const account = plugin.config.resolveAccount(this.config, accountId);\n return await plugin.status.buildChannelSummary({\n account,\n cfg: this.config,\n defaultAccountId: accountId,\n snapshot: plugin.status.defaultRuntime ?? { accountId, channelId: channel, enabled: true, configured: true },\n });\n } catch (err) {\n return { error: String(err) };\n }\n }\n\n // ── Inbound action dispatch (Feishu card actions) ──────────────────────\n\n /**\n * Optional channel hook before `AgentService` consumes an inbound message\n * (e.g. Feishu card-action triggers).\n */\n async dispatchInboundMessageAction(msg: InboundMessage): Promise<void> {\n const plugin = this.registry.get(msg.channel);\n const handle = plugin?.actions?.handleAction;\n if (!handle) return;\n\n const meta = msg.metadata as Record<string, unknown> | undefined;\n if (msg.channel !== 'feishu' || meta?.feishuEventType !== 'card.action.trigger') {\n return;\n }\n\n const cardAction = meta.cardAction as Record<string, unknown> | undefined;\n const actionTag =\n cardAction && typeof cardAction.tag === 'string' && cardAction.tag.trim()\n ? cardAction.tag.trim()\n : 'feishu.card_action';\n const cardCtx = meta.cardContext as Record<string, unknown> | undefined;\n const openMsg =\n cardCtx && typeof cardCtx.open_message_id === 'string' ? cardCtx.open_message_id.trim() : '';\n const fallbackMsgId = typeof meta.messageId === 'string' ? meta.messageId.trim() : '';\n const messageId = openMsg || fallbackMsgId;\n const accountId =\n typeof meta.accountId === 'string' && meta.accountId.trim() ? meta.accountId.trim() : 'default';\n\n try {\n await handle({\n action: actionTag,\n data: JSON.stringify({\n cardAction: meta.cardAction,\n cardContext: meta.cardContext,\n cardActionText: meta.cardActionText,\n }),\n messageId,\n senderId: msg.sender_id,\n chatId: msg.chat_id,\n accountId,\n metadata: {\n feishuEventType: meta.feishuEventType,\n raw: meta.raw,\n sessionKey: meta.sessionKey,\n userContent: msg.content,\n },\n });\n } catch (err) {\n const em = err instanceof Error ? err.message : String(err);\n log.error({ err, channel: msg.channel, accountId, em }, 'dispatchInboundMessageAction failed');\n }\n }\n\n // ── Config + introspection ─────────────────────────────────────────────\n\n async updateConfig(config: Config): Promise<void> {\n this.config = config;\n await this.lifecycle.forwardConfigUpdate(config);\n log.info('Channel config updated');\n }\n\n /** Replace in-memory config without running plugin `onConfigUpdated` hooks. */\n setRuntimeConfig(config: Config): void {\n this.config = config;\n }\n\n getRuntimeSnapshot(): {\n initialized: boolean;\n running: boolean;\n pluginIds: string[];\n initializedPluginIds: string[];\n manuallyStopped: string[];\n restartAttempts: Record<string, number>;\n channelHealth: Record<string, ChannelHealthState>;\n } {\n const lifecycleSnap = this.lifecycle.snapshot();\n return {\n ...lifecycleSnap,\n pluginIds: this.registry.ids(),\n channelHealth: this.healthMonitor.toJSON(),\n };\n }\n\n getHealthMonitor(): ChannelHealthMonitor {\n return this.healthMonitor;\n }\n}\n\nexport function createChannelManager(config: Config, bus: MessageBus): ChannelManager {\n return new ChannelManager(config, bus);\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"manager.js","names":[],"sources":["../../../src/channels/manager.ts"],"sourcesContent":["/**\n * Channel Manager — thin composition root for the channel subsystem.\n *\n * Wires together the four coordinators that own what used to be the eight\n * concerns of this 707-line class:\n *\n * - {@link ChannelPluginRegistry} — plugins Map, register/get\n * - {@link ChannelLifecycleSupervisor} — init/start/stop/restart-backoff\n * - {@link ChannelHeartbeatScheduler} — per-account heartbeat probes\n * - {@link ChannelOutboundSender} — TTS rewrite + persist + delivery\n *\n * The public surface (`registerPlugin`, `initialize`, `start`, `send`, etc.) is\n * preserved so callers (`GatewayService`, CLI commands, channel plugins) are\n * unchanged.\n */\n\nimport type { Config } from '../config/schema.js';\nimport type { MessageBus } from '../infra/bus/index.js';\n\nimport type { InboundMessage, OutboundMessage } from './transport-types.js';\nimport type {\n ChannelPlugin,\n ChannelPluginSessionModelHooks,\n ChannelStreamHandle,\n} from './plugin-types.js';\nimport { ChannelHealthMonitor, type ChannelHealthState } from './health-monitor.js';\nimport { ChannelPluginRegistry } from './plugin-registry.js';\nimport { ChannelHeartbeatScheduler } from './heartbeat-scheduler.js';\nimport {\n ChannelOutboundSender,\n type OutboundChannelHooks,\n} from './outbound-sender.js';\nimport { ChannelLifecycleSupervisor } from './lifecycle-supervisor.js';\nimport { createLogger } from '../utils/logger.js';\n\nconst log = createLogger('ChannelManager');\n\nexport type { OutboundChannelHooks } from './outbound-sender.js';\n\nexport class ChannelManager {\n private config: Config;\n private readonly registry = new ChannelPluginRegistry();\n private readonly healthMonitor = new ChannelHealthMonitor();\n private readonly lifecycle: ChannelLifecycleSupervisor;\n private readonly heartbeat: ChannelHeartbeatScheduler;\n private readonly outbound: ChannelOutboundSender;\n private sessionModelHooks?: ChannelPluginSessionModelHooks;\n\n constructor(config: Config, bus: MessageBus) {\n this.config = config;\n\n this.heartbeat = new ChannelHeartbeatScheduler({\n getConfig: () => this.config,\n healthMonitor: this.healthMonitor,\n requestSoftRestart: (channelId) => {\n void this.lifecycle.softRestart(channelId);\n },\n });\n\n this.lifecycle = new ChannelLifecycleSupervisor({\n bus,\n registry: this.registry,\n getConfig: () => this.config,\n getSessionModelHooks: () => this.sessionModelHooks,\n onPluginStarted: (plugin) => this.heartbeat.schedule(plugin),\n onPluginStopped: (pluginId) => this.heartbeat.clear(pluginId),\n });\n\n this.outbound = new ChannelOutboundSender({\n registry: this.registry,\n getConfig: () => this.config,\n });\n }\n\n // ── Wiring hooks (called by GatewayService / cli) ─────────────────────\n\n setOutboundHooks(hooks: OutboundChannelHooks): void {\n this.outbound.setHooks(hooks);\n }\n\n /** Call before `initialize()` so plugins can persist per-session model overrides. */\n setSessionModelHooks(hooks: ChannelPluginSessionModelHooks | undefined): void {\n this.sessionModelHooks = hooks;\n }\n\n enableOutboundPersistence(agentDir: string): void {\n this.outbound.enablePersistence(agentDir);\n }\n\n // ── Plugin registry pass-throughs ──────────────────────────────────────\n\n registerPlugin(plugin: ChannelPlugin): void {\n this.registry.register(plugin);\n }\n\n getPlugin(id: string): ChannelPlugin | undefined {\n return this.registry.get(id);\n }\n\n getAllPlugins(): ChannelPlugin[] {\n return this.registry.all();\n }\n\n /** Backward-compat alias for `getAllPlugins`. */\n getAllChannels(): ChannelPlugin[] {\n return this.registry.all();\n }\n\n /** Channel IDs whose runtime reports connected (e.g. Telegram polling active). */\n getRunningChannels(): string[] {\n return this.registry.runningChannelIds(this.config, (id) => this.lifecycle.isInitialized(id));\n }\n\n // ── Lifecycle pass-throughs ────────────────────────────────────────────\n\n initialize(): Promise<void> {\n return this.lifecycle.initialize();\n }\n\n initializeChannel(channelId: string): Promise<boolean> {\n return this.lifecycle.initializeChannel(channelId);\n }\n\n start(options?: { deferConnectPluginIds?: ReadonlySet<string> }): Promise<void> {\n return this.lifecycle.start(options);\n }\n\n startDeferredConnects(): Promise<void> {\n return this.lifecycle.startDeferredConnects();\n }\n\n async stop(): Promise<void> {\n await this.lifecycle.stop();\n this.heartbeat.clearAll();\n }\n\n stopChannel(channelId: string): Promise<void> {\n return this.lifecycle.stopChannel(channelId);\n }\n\n startChannel(channelId: string): Promise<void> {\n return this.lifecycle.startChannel(channelId);\n }\n\n listDeferConnectChannelIds(cfg: Config): string[] {\n return this.lifecycle.listDeferConnectChannelIds(cfg);\n }\n\n // ── Outbound pass-throughs ─────────────────────────────────────────────\n\n send(msg: OutboundMessage, options?: { skipPersist?: boolean }): Promise<void> {\n return this.outbound.send(msg, options);\n }\n\n replayPendingOutboundMessages(): Promise<void> {\n return this.outbound.replayPending();\n }\n\n // ── Streaming + status query (delegated to plugin directly) ────────────\n\n startStream(\n channel: string,\n chatId: string,\n accountId?: string,\n opts?: { threadId?: string; replyToMessageId?: string },\n ): ChannelStreamHandle | null {\n const plugin = this.registry.get(channel);\n if (!plugin) {\n log.error({ channel }, 'Unknown channel');\n return null;\n }\n return (\n plugin.streaming?.startStream?.({\n chatId,\n accountId,\n threadId: opts?.threadId,\n replyToMessageId: opts?.replyToMessageId,\n }) ?? null\n );\n }\n\n async getChannelStatus(channel: string): Promise<Record<string, unknown>> {\n const plugin = this.registry.get(channel);\n if (!plugin) return { error: 'Unknown channel' };\n if (!plugin.status?.buildChannelSummary) return { status: 'unknown' };\n\n try {\n const accountId = plugin.config.listAccountIds(this.config)[0] ?? 'default';\n const account = plugin.config.resolveAccount(this.config, accountId);\n return await plugin.status.buildChannelSummary({\n account,\n cfg: this.config,\n defaultAccountId: accountId,\n snapshot: plugin.status.defaultRuntime ?? { accountId, channelId: channel, enabled: true, configured: true },\n });\n } catch (err) {\n return { error: String(err) };\n }\n }\n\n // ── Inbound action dispatch (Feishu card actions) ──────────────────────\n\n /**\n * Optional channel hook before `AgentService` consumes an inbound message\n * (e.g. Feishu card-action triggers).\n */\n async dispatchInboundMessageAction(msg: InboundMessage): Promise<void> {\n const plugin = this.registry.get(msg.channel);\n const handle = plugin?.actions?.handleAction;\n if (!handle) return;\n\n const meta = msg.metadata as Record<string, unknown> | undefined;\n if (msg.channel !== 'feishu' || meta?.feishuEventType !== 'card.action.trigger') {\n return;\n }\n\n const cardAction = meta.cardAction as Record<string, unknown> | undefined;\n const actionTag =\n cardAction && typeof cardAction.tag === 'string' && cardAction.tag.trim()\n ? cardAction.tag.trim()\n : 'feishu.card_action';\n const cardCtx = meta.cardContext as Record<string, unknown> | undefined;\n const openMsg =\n cardCtx && typeof cardCtx.open_message_id === 'string' ? cardCtx.open_message_id.trim() : '';\n const fallbackMsgId = typeof meta.messageId === 'string' ? meta.messageId.trim() : '';\n const messageId = openMsg || fallbackMsgId;\n const accountId =\n typeof meta.accountId === 'string' && meta.accountId.trim() ? meta.accountId.trim() : 'default';\n\n try {\n await handle({\n action: actionTag,\n data: JSON.stringify({\n cardAction: meta.cardAction,\n cardContext: meta.cardContext,\n cardActionText: meta.cardActionText,\n }),\n messageId,\n senderId: msg.sender_id,\n chatId: msg.chat_id,\n accountId,\n metadata: {\n feishuEventType: meta.feishuEventType,\n raw: meta.raw,\n sessionKey: meta.sessionKey,\n userContent: msg.content,\n },\n });\n } catch (err) {\n const em = err instanceof Error ? err.message : String(err);\n log.error({ err, channel: msg.channel, accountId, em }, 'dispatchInboundMessageAction failed');\n }\n }\n\n // ── Config + introspection ─────────────────────────────────────────────\n\n async updateConfig(config: Config): Promise<void> {\n this.config = config;\n await this.lifecycle.forwardConfigUpdate(config);\n log.info('Channel config updated');\n }\n\n /** Replace in-memory config without running plugin `onConfigUpdated` hooks. */\n setRuntimeConfig(config: Config): void {\n this.config = config;\n }\n\n getRuntimeSnapshot(): {\n initialized: boolean;\n running: boolean;\n pluginIds: string[];\n initializedPluginIds: string[];\n manuallyStopped: string[];\n restartAttempts: Record<string, number>;\n channelHealth: Record<string, ChannelHealthState>;\n } {\n const lifecycleSnap = this.lifecycle.snapshot();\n return {\n ...lifecycleSnap,\n pluginIds: this.registry.ids(),\n channelHealth: this.healthMonitor.toJSON(),\n };\n }\n\n getHealthMonitor(): ChannelHealthMonitor {\n return this.healthMonitor;\n }\n}\n\nexport function createChannelManager(config: Config, bus: MessageBus): ChannelManager {\n return new ChannelManager(config, bus);\n}\n"],"mappings":"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"}
@@ -1,3 +1,2 @@
1
- /** Channels that use ~/.xopc/credentials pairing + allowFrom files (aligned with Feishu layout). */
2
- export type StandardPairingChannel = 'telegram' | 'feishu';
3
- export type PairingCliChannel = StandardPairingChannel | 'weixin';
1
+ export type StandardPairingChannel = string;
2
+ export type PairingCliChannel = string;
@@ -9,7 +9,7 @@ function buildPairingInstructionText(params) {
9
9
  code,
10
10
  "",
11
11
  "Ask the owner to approve in Settings → Channels → Pairing, or run:",
12
- `xopc channels pairing approve --channel ${channel}${!accountId || accountId.trim().toLowerCase() === "default" ? "" : ` --account ${accountId.trim()}`} ${code}`
12
+ `xopc channels pairing approve ${channel}${!accountId || accountId.trim().toLowerCase() === "default" ? "" : ` --account ${accountId.trim()}`} ${code}`
13
13
  ].join("\n");
14
14
  }
15
15
  //#endregion
@@ -1 +1 @@
1
- {"version":3,"file":"pairing-messages.js","names":[],"sources":["../../../../src/channels/pairing/pairing-messages.ts"],"sourcesContent":["import type { PairingCliChannel } from './pairing-channel.js';\n\nexport function buildPairingInstructionText(params: {\n channel: PairingCliChannel;\n accountId: string;\n code: string;\n senderIdLine: string;\n}): string {\n const { channel, accountId, code, senderIdLine } = params;\n const acc =\n !accountId || accountId.trim().toLowerCase() === 'default' ? '' : ` --account ${accountId.trim()}`;\n const approve = `xopc channels pairing approve --channel ${channel}${acc} ${code}`;\n return [\n 'XOPC: this bot is in pairing mode.',\n '',\n senderIdLine,\n 'Pairing code:',\n code,\n '',\n 'Ask the owner to approve in Settings → Channels → Pairing, or run:',\n approve,\n ].join('\\n');\n}\n"],"mappings":";AAEA,SAAgB,4BAA4B,QAKjC;CACT,MAAM,EAAE,SAAS,WAAW,MAAM,iBAAiB;AAInD,QAAO;EACL;EACA;EACA;EACA;EACA;EACA;EACA;EACA,2CATyD,UADzD,CAAC,aAAa,UAAU,MAAM,CAAC,aAAa,KAAK,YAAY,KAAK,cAAc,UAAU,MAAM,GACzB,GAAG;EAU3E,CAAC,KAAK,KAAK"}
1
+ {"version":3,"file":"pairing-messages.js","names":[],"sources":["../../../../src/channels/pairing/pairing-messages.ts"],"sourcesContent":["import type { PairingCliChannel } from './pairing-channel.js';\n\nexport function buildPairingInstructionText(params: {\n channel: PairingCliChannel;\n accountId: string;\n code: string;\n senderIdLine: string;\n}): string {\n const { channel, accountId, code, senderIdLine } = params;\n const acc =\n !accountId || accountId.trim().toLowerCase() === 'default' ? '' : ` --account ${accountId.trim()}`;\n const approve = `xopc channels pairing approve ${channel}${acc} ${code}`;\n return [\n 'XOPC: this bot is in pairing mode.',\n '',\n senderIdLine,\n 'Pairing code:',\n code,\n '',\n 'Ask the owner to approve in Settings → Channels → Pairing, or run:',\n approve,\n ].join('\\n');\n}\n"],"mappings":";AAEA,SAAgB,4BAA4B,QAKjC;CACT,MAAM,EAAE,SAAS,WAAW,MAAM,iBAAiB;AAInD,QAAO;EACL;EACA;EACA;EACA;EACA;EACA;EACA;EACA,iCAT+C,UAD/C,CAAC,aAAa,UAAU,MAAM,CAAC,aAAa,KAAK,YAAY,KAAK,cAAc,UAAU,MAAM,GACnC,GAAG;EAUjE,CAAC,KAAK,KAAK"}
@@ -18,7 +18,7 @@ export type ChannelPairingSummaryEntry = {
18
18
  stale: number;
19
19
  atCapacity: boolean;
20
20
  };
21
- export type ChannelPairingSummary = Record<PairingCliChannel, ChannelPairingSummaryEntry>;
21
+ export type ChannelPairingSummary = Record<string, ChannelPairingSummaryEntry>;
22
22
  export type PairingPendingIssue = {
23
23
  channel: PairingCliChannel;
24
24
  accountId: string;
@@ -1,9 +1,9 @@
1
+ import { resolveDmPolicy } from "../security.js";
1
2
  import { resolveStandardAllowFromPath, resolveStandardPairingPath, resolveWeixinAllowFromPath, resolveWeixinPairingPath } from "./paths.js";
2
3
  import { readAllowFromIdsSync, removeAllowFromIdSync } from "./allow-from-file.js";
3
4
  import "./pairing-constants.js";
4
5
  import { PAIRING_PENDING_TTL_MS, approvePairingBySenderIdSync, approvePairingCodeSync, dismissPairingBySenderIdSync, listPendingPairingRequestsSync } from "./pairing-store.js";
5
6
  import { broadcastPairingEvent } from "./pairing-events.js";
6
- import { resolveDmPolicy } from "../security.js";
7
7
  //#region src/channels/pairing/pairing-service.ts
8
8
  function normalizeAccountId(accountId) {
9
9
  return (accountId ?? "default").trim().toLowerCase() || "default";
@@ -115,30 +115,15 @@ function resolvePairingAccountIds(config, channel) {
115
115
  return ["default"];
116
116
  }
117
117
  function listChannelPairingSummary(config) {
118
- const channels = [
119
- "telegram",
120
- "feishu",
121
- "weixin"
122
- ];
123
- const summary = {
124
- telegram: {
125
- pending: 0,
126
- stale: 0,
127
- atCapacity: false
128
- },
129
- feishu: {
130
- pending: 0,
131
- stale: 0,
132
- atCapacity: false
133
- },
134
- weixin: {
118
+ const channels = Object.keys(config?.channels ?? {});
119
+ const summary = {};
120
+ for (const channel of channels) {
121
+ if (!resolveChannelEnabled(config, channel)) continue;
122
+ summary[channel] = {
135
123
  pending: 0,
136
124
  stale: 0,
137
125
  atCapacity: false
138
- }
139
- };
140
- for (const channel of channels) {
141
- if (!resolveChannelEnabled(config, channel)) continue;
126
+ };
142
127
  const accountIds = resolvePairingAccountIds(config, channel);
143
128
  for (const accountId of accountIds) {
144
129
  if (!resolveAccountEnabled(config, channel, accountId)) continue;
@@ -154,11 +139,7 @@ function listChannelPairingSummary(config) {
154
139
  }
155
140
  function collectPairingPendingIssues(config) {
156
141
  const issues = [];
157
- for (const channel of [
158
- "telegram",
159
- "feishu",
160
- "weixin"
161
- ]) {
142
+ for (const channel of Object.keys(config?.channels ?? {})) {
162
143
  if (!resolveChannelEnabled(config, channel)) continue;
163
144
  const accountIds = resolvePairingAccountIds(config, channel);
164
145
  for (const accountId of accountIds) {
@@ -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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"}
@@ -66,10 +66,10 @@ const switchCommand = {
66
66
  "group"
67
67
  ],
68
68
  acceptsArgs: true,
69
- examples: ["/switch openai/gpt-4o", "/switch minimax/minimax-m2.1"],
69
+ examples: ["/switch openai/gpt-5.5", "/switch minimax/minimax-m2.7"],
70
70
  handler: async (ctx, args) => {
71
71
  if (!args.trim()) return {
72
- content: joinBlocks("❌ Missing model ref.", "**Usage:** `/switch provider/model-id`", "Run `/models` — each line shows a display name and a `provider/model` ref in backticks. Copy that ref.", "**Example:** `/switch openai/gpt-4o`"),
72
+ content: joinBlocks("❌ Missing model ref.", "**Usage:** `/switch provider/model-id`", "Run `/models` — each line shows a display name and a `provider/model` ref in backticks. Copy that ref.", "**Example:** `/switch openai/gpt-5.5`"),
73
73
  success: false
74
74
  };
75
75
  await ctx.setTyping(true);
@@ -1 +1 @@
1
- {"version":3,"file":"model.js","names":[],"sources":["../../../../src/chat-commands/builtins/model.ts"],"sourcesContent":["/**\n * Model Commands\n *\n * Built-in commands for model management:\n * - /models - List models with display names and `provider/model` refs for /switch\n * - /switch - Switch model using the ref from /models\n * - /usage - Show token usage statistics\n */\n\nimport type { CommandDefinition, CommandContext, UIComponent } from '../types.js';\nimport { commandRegistry } from '../registry.js';\nimport { bulletList, code, hint, joinBlocks, kvList, section } from '../format-output.js';\n\nconst modelsCommand: CommandDefinition = {\n id: 'model.list',\n name: 'models',\n aliases: ['model'],\n description: 'List models with display names and `provider/model` refs for /switch',\n category: 'model',\n scope: ['global', 'private', 'group'],\n handler: async (ctx: CommandContext) => {\n await ctx.setTyping(true);\n\n const models = await ctx.listModels();\n const currentModel = ctx.getCurrentModel();\n\n if (models.length === 0) {\n return {\n content: '🤖 No models available. Please check your configuration.',\n success: true,\n };\n }\n\n // Group by provider\n const byProvider = new Map<string, typeof models>();\n for (const m of models) {\n if (!byProvider.has(m.provider)) {\n byProvider.set(m.provider, []);\n }\n byProvider.get(m.provider)!.push(m);\n }\n\n /** `m.id` from listModels is always `serviceId/modelId` (canonical `/switch` ref). */\n const providerBlocks = Array.from(byProvider.entries()).map(([provider, providerModels]) => {\n const items = providerModels.slice(0, 5).map((m) => {\n const marker = m.id === currentModel ? '▶️ ' : '';\n return `${marker}**${m.name}** — ${code(m.id)}`;\n });\n if (providerModels.length > 5) {\n items.push(hint(`… and ${providerModels.length - 5} more in this provider`));\n }\n return joinBlocks(section(provider), bulletList(items));\n });\n\n const content = joinBlocks(\n '🤖 Available models (use the `provider/model` ref with `/switch`):',\n ...providerBlocks,\n hint('Copy the ref in backticks after each name, then: `/switch provider/model-id`.'),\n );\n\n // Create UI component if supported\n if (ctx.supports('buttons')) {\n const component: UIComponent = {\n type: 'model-picker',\n providers: Array.from(byProvider.entries()).map(([id, models]) => ({\n id,\n name: id,\n models: models.map((m) => ({\n id: m.id,\n name: m.name,\n provider: m.provider,\n })),\n })),\n currentModel,\n };\n\n return {\n content,\n success: true,\n components: [component],\n };\n }\n\n return {\n content,\n success: true,\n };\n },\n};\n\nconst switchCommand: CommandDefinition = {\n id: 'model.switch',\n name: 'switch',\n description: 'Switch model — pass the `provider/model` ref shown by /models',\n category: 'model',\n scope: ['global', 'private', 'group'],\n acceptsArgs: true,\n examples: ['/switch openai/gpt-4o', '/switch minimax/minimax-m2.1'],\n handler: async (ctx: CommandContext, args: string) => {\n if (!args.trim()) {\n return {\n content: joinBlocks(\n '❌ Missing model ref.',\n '**Usage:** `/switch provider/model-id`',\n 'Run `/models` — each line shows a display name and a `provider/model` ref in backticks. Copy that ref.',\n '**Example:** `/switch openai/gpt-4o`',\n ),\n success: false,\n };\n }\n\n await ctx.setTyping(true);\n\n const modelId = args.trim();\n const success = await ctx.switchModel(modelId);\n\n if (success) {\n const modelName = modelId.split('/').pop() || modelId;\n return {\n content: joinBlocks(\n `✅ Switched to ${code(modelId)} (${modelName}).`,\n 'This model will be used for your next message.',\n ),\n success: true,\n };\n }\n\n return {\n content: joinBlocks(\n `❌ Could not switch to ${code(modelId)}.`,\n 'Use the exact `provider/model` ref from `/models` (not only the display name).',\n '**Example:** `/switch anthropic/claude-sonnet-4-20250514`',\n ),\n success: false,\n };\n },\n};\n\nconst usageCommand: CommandDefinition = {\n id: 'model.usage',\n name: 'usage',\n description: 'Show token usage statistics for current session',\n category: 'model',\n scope: ['global', 'private', 'group'],\n handler: async (ctx: CommandContext) => {\n await ctx.setTyping(true);\n\n const stats = await ctx.getUsage();\n const modelName = ctx.getCurrentModel().split('/').pop() || 'Unknown';\n\n const content = joinBlocks(\n section('📊 Session Token Usage'),\n kvList([\n { key: 'Model', value: modelName },\n { key: 'Prompt', value: `${stats.promptTokens.toLocaleString()} tokens` },\n { key: 'Completion', value: `${stats.completionTokens.toLocaleString()} tokens` },\n { key: 'Total', value: `${stats.totalTokens.toLocaleString()} tokens` },\n { key: 'Messages', value: String(stats.messageCount) },\n ]),\n );\n\n // Create UI component if supported\n if (ctx.supports('buttons')) {\n const component: UIComponent = {\n type: 'usage-display',\n stats,\n modelName,\n };\n\n return {\n content,\n success: true,\n components: [component],\n };\n }\n\n return {\n content,\n success: true,\n };\n },\n};\n\n// Register all model commands\nexport function registerModelCommands(): void {\n commandRegistry.register(modelsCommand);\n commandRegistry.register(switchCommand);\n commandRegistry.register(usageCommand);\n}\n"],"mappings":";;;AAaA,MAAM,gBAAmC;CACvC,IAAI;CACJ,MAAM;CACN,SAAS,CAAC,QAAQ;CAClB,aAAa;CACb,UAAU;CACV,OAAO;EAAC;EAAU;EAAW;EAAQ;CACrC,SAAS,OAAO,QAAwB;AACtC,QAAM,IAAI,UAAU,KAAK;EAEzB,MAAM,SAAS,MAAM,IAAI,YAAY;EACrC,MAAM,eAAe,IAAI,iBAAiB;AAE1C,MAAI,OAAO,WAAW,EACpB,QAAO;GACL,SAAS;GACT,SAAS;GACV;EAIH,MAAM,6BAAa,IAAI,KAA4B;AACnD,OAAK,MAAM,KAAK,QAAQ;AACtB,OAAI,CAAC,WAAW,IAAI,EAAE,SAAS,CAC7B,YAAW,IAAI,EAAE,UAAU,EAAE,CAAC;AAEhC,cAAW,IAAI,EAAE,SAAS,CAAE,KAAK,EAAE;;EAerC,MAAM,UAAU,WACd,sEACA,GAbqB,MAAM,KAAK,WAAW,SAAS,CAAC,CAAC,KAAK,CAAC,UAAU,oBAAoB;GAC1F,MAAM,QAAQ,eAAe,MAAM,GAAG,EAAE,CAAC,KAAK,MAAM;AAElD,WAAO,GADQ,EAAE,OAAO,eAAe,QAAQ,GAC9B,IAAI,EAAE,KAAK,OAAO,KAAK,EAAE,GAAG;KAC7C;AACF,OAAI,eAAe,SAAS,EAC1B,OAAM,KAAK,KAAK,SAAS,eAAe,SAAS,EAAE,wBAAwB,CAAC;AAE9E,UAAO,WAAW,QAAQ,SAAS,EAAE,WAAW,MAAM,CAAC;IAKtC,EACjB,KAAK,gFAAgF,CACtF;AAGD,MAAI,IAAI,SAAS,UAAU,CAezB,QAAO;GACL;GACA,SAAS;GACT,YAAY,CAAC;IAhBb,MAAM;IACN,WAAW,MAAM,KAAK,WAAW,SAAS,CAAC,CAAC,KAAK,CAAC,IAAI,aAAa;KACjE;KACA,MAAM;KACN,QAAQ,OAAO,KAAK,OAAO;MACzB,IAAI,EAAE;MACN,MAAM,EAAE;MACR,UAAU,EAAE;MACb,EAAE;KACJ,EAAE;IACH;IAMsB,CAAC;GACxB;AAGH,SAAO;GACL;GACA,SAAS;GACV;;CAEJ;AAED,MAAM,gBAAmC;CACvC,IAAI;CACJ,MAAM;CACN,aAAa;CACb,UAAU;CACV,OAAO;EAAC;EAAU;EAAW;EAAQ;CACrC,aAAa;CACb,UAAU,CAAC,yBAAyB,+BAA+B;CACnE,SAAS,OAAO,KAAqB,SAAiB;AACpD,MAAI,CAAC,KAAK,MAAM,CACd,QAAO;GACL,SAAS,WACP,wBACA,0CACA,0GACA,uCACD;GACD,SAAS;GACV;AAGH,QAAM,IAAI,UAAU,KAAK;EAEzB,MAAM,UAAU,KAAK,MAAM;AAG3B,MAAI,MAFkB,IAAI,YAAY,QAAQ,EAEjC;GACX,MAAM,YAAY,QAAQ,MAAM,IAAI,CAAC,KAAK,IAAI;AAC9C,UAAO;IACL,SAAS,WACP,iBAAiB,KAAK,QAAQ,CAAC,IAAI,UAAU,KAC7C,iDACD;IACD,SAAS;IACV;;AAGH,SAAO;GACL,SAAS,WACP,yBAAyB,KAAK,QAAQ,CAAC,IACvC,kFACA,4DACD;GACD,SAAS;GACV;;CAEJ;AAED,MAAM,eAAkC;CACtC,IAAI;CACJ,MAAM;CACN,aAAa;CACb,UAAU;CACV,OAAO;EAAC;EAAU;EAAW;EAAQ;CACrC,SAAS,OAAO,QAAwB;AACtC,QAAM,IAAI,UAAU,KAAK;EAEzB,MAAM,QAAQ,MAAM,IAAI,UAAU;EAClC,MAAM,YAAY,IAAI,iBAAiB,CAAC,MAAM,IAAI,CAAC,KAAK,IAAI;EAE5D,MAAM,UAAU,WACd,QAAQ,yBAAyB,EACjC,OAAO;GACL;IAAE,KAAK;IAAS,OAAO;IAAW;GAClC;IAAE,KAAK;IAAU,OAAO,GAAG,MAAM,aAAa,gBAAgB,CAAC;IAAU;GACzE;IAAE,KAAK;IAAc,OAAO,GAAG,MAAM,iBAAiB,gBAAgB,CAAC;IAAU;GACjF;IAAE,KAAK;IAAS,OAAO,GAAG,MAAM,YAAY,gBAAgB,CAAC;IAAU;GACvE;IAAE,KAAK;IAAY,OAAO,OAAO,MAAM,aAAa;IAAE;GACvD,CAAC,CACH;AAGD,MAAI,IAAI,SAAS,UAAU,CAOzB,QAAO;GACL;GACA,SAAS;GACT,YAAY,CAAC;IARb,MAAM;IACN;IACA;IAMsB,CAAC;GACxB;AAGH,SAAO;GACL;GACA,SAAS;GACV;;CAEJ;AAGD,SAAgB,wBAA8B;AAC5C,iBAAgB,SAAS,cAAc;AACvC,iBAAgB,SAAS,cAAc;AACvC,iBAAgB,SAAS,aAAa"}
1
+ {"version":3,"file":"model.js","names":[],"sources":["../../../../src/chat-commands/builtins/model.ts"],"sourcesContent":["/**\n * Model Commands\n *\n * Built-in commands for model management:\n * - /models - List models with display names and `provider/model` refs for /switch\n * - /switch - Switch model using the ref from /models\n * - /usage - Show token usage statistics\n */\n\nimport type { CommandDefinition, CommandContext, UIComponent } from '../types.js';\nimport { commandRegistry } from '../registry.js';\nimport { bulletList, code, hint, joinBlocks, kvList, section } from '../format-output.js';\n\nconst modelsCommand: CommandDefinition = {\n id: 'model.list',\n name: 'models',\n aliases: ['model'],\n description: 'List models with display names and `provider/model` refs for /switch',\n category: 'model',\n scope: ['global', 'private', 'group'],\n handler: async (ctx: CommandContext) => {\n await ctx.setTyping(true);\n\n const models = await ctx.listModels();\n const currentModel = ctx.getCurrentModel();\n\n if (models.length === 0) {\n return {\n content: '🤖 No models available. Please check your configuration.',\n success: true,\n };\n }\n\n // Group by provider\n const byProvider = new Map<string, typeof models>();\n for (const m of models) {\n if (!byProvider.has(m.provider)) {\n byProvider.set(m.provider, []);\n }\n byProvider.get(m.provider)!.push(m);\n }\n\n /** `m.id` from listModels is always `serviceId/modelId` (canonical `/switch` ref). */\n const providerBlocks = Array.from(byProvider.entries()).map(([provider, providerModels]) => {\n const items = providerModels.slice(0, 5).map((m) => {\n const marker = m.id === currentModel ? '▶️ ' : '';\n return `${marker}**${m.name}** — ${code(m.id)}`;\n });\n if (providerModels.length > 5) {\n items.push(hint(`… and ${providerModels.length - 5} more in this provider`));\n }\n return joinBlocks(section(provider), bulletList(items));\n });\n\n const content = joinBlocks(\n '🤖 Available models (use the `provider/model` ref with `/switch`):',\n ...providerBlocks,\n hint('Copy the ref in backticks after each name, then: `/switch provider/model-id`.'),\n );\n\n // Create UI component if supported\n if (ctx.supports('buttons')) {\n const component: UIComponent = {\n type: 'model-picker',\n providers: Array.from(byProvider.entries()).map(([id, models]) => ({\n id,\n name: id,\n models: models.map((m) => ({\n id: m.id,\n name: m.name,\n provider: m.provider,\n })),\n })),\n currentModel,\n };\n\n return {\n content,\n success: true,\n components: [component],\n };\n }\n\n return {\n content,\n success: true,\n };\n },\n};\n\nconst switchCommand: CommandDefinition = {\n id: 'model.switch',\n name: 'switch',\n description: 'Switch model — pass the `provider/model` ref shown by /models',\n category: 'model',\n scope: ['global', 'private', 'group'],\n acceptsArgs: true,\n examples: ['/switch openai/gpt-5.5', '/switch minimax/minimax-m2.7'],\n handler: async (ctx: CommandContext, args: string) => {\n if (!args.trim()) {\n return {\n content: joinBlocks(\n '❌ Missing model ref.',\n '**Usage:** `/switch provider/model-id`',\n 'Run `/models` — each line shows a display name and a `provider/model` ref in backticks. Copy that ref.',\n '**Example:** `/switch openai/gpt-5.5`',\n ),\n success: false,\n };\n }\n\n await ctx.setTyping(true);\n\n const modelId = args.trim();\n const success = await ctx.switchModel(modelId);\n\n if (success) {\n const modelName = modelId.split('/').pop() || modelId;\n return {\n content: joinBlocks(\n `✅ Switched to ${code(modelId)} (${modelName}).`,\n 'This model will be used for your next message.',\n ),\n success: true,\n };\n }\n\n return {\n content: joinBlocks(\n `❌ Could not switch to ${code(modelId)}.`,\n 'Use the exact `provider/model` ref from `/models` (not only the display name).',\n '**Example:** `/switch anthropic/claude-sonnet-4-20250514`',\n ),\n success: false,\n };\n },\n};\n\nconst usageCommand: CommandDefinition = {\n id: 'model.usage',\n name: 'usage',\n description: 'Show token usage statistics for current session',\n category: 'model',\n scope: ['global', 'private', 'group'],\n handler: async (ctx: CommandContext) => {\n await ctx.setTyping(true);\n\n const stats = await ctx.getUsage();\n const modelName = ctx.getCurrentModel().split('/').pop() || 'Unknown';\n\n const content = joinBlocks(\n section('📊 Session Token Usage'),\n kvList([\n { key: 'Model', value: modelName },\n { key: 'Prompt', value: `${stats.promptTokens.toLocaleString()} tokens` },\n { key: 'Completion', value: `${stats.completionTokens.toLocaleString()} tokens` },\n { key: 'Total', value: `${stats.totalTokens.toLocaleString()} tokens` },\n { key: 'Messages', value: String(stats.messageCount) },\n ]),\n );\n\n // Create UI component if supported\n if (ctx.supports('buttons')) {\n const component: UIComponent = {\n type: 'usage-display',\n stats,\n modelName,\n };\n\n return {\n content,\n success: true,\n components: [component],\n };\n }\n\n return {\n content,\n success: true,\n };\n },\n};\n\n// Register all model commands\nexport function registerModelCommands(): void {\n commandRegistry.register(modelsCommand);\n commandRegistry.register(switchCommand);\n commandRegistry.register(usageCommand);\n}\n"],"mappings":";;;AAaA,MAAM,gBAAmC;CACvC,IAAI;CACJ,MAAM;CACN,SAAS,CAAC,QAAQ;CAClB,aAAa;CACb,UAAU;CACV,OAAO;EAAC;EAAU;EAAW;EAAQ;CACrC,SAAS,OAAO,QAAwB;AACtC,QAAM,IAAI,UAAU,KAAK;EAEzB,MAAM,SAAS,MAAM,IAAI,YAAY;EACrC,MAAM,eAAe,IAAI,iBAAiB;AAE1C,MAAI,OAAO,WAAW,EACpB,QAAO;GACL,SAAS;GACT,SAAS;GACV;EAIH,MAAM,6BAAa,IAAI,KAA4B;AACnD,OAAK,MAAM,KAAK,QAAQ;AACtB,OAAI,CAAC,WAAW,IAAI,EAAE,SAAS,CAC7B,YAAW,IAAI,EAAE,UAAU,EAAE,CAAC;AAEhC,cAAW,IAAI,EAAE,SAAS,CAAE,KAAK,EAAE;;EAerC,MAAM,UAAU,WACd,sEACA,GAbqB,MAAM,KAAK,WAAW,SAAS,CAAC,CAAC,KAAK,CAAC,UAAU,oBAAoB;GAC1F,MAAM,QAAQ,eAAe,MAAM,GAAG,EAAE,CAAC,KAAK,MAAM;AAElD,WAAO,GADQ,EAAE,OAAO,eAAe,QAAQ,GAC9B,IAAI,EAAE,KAAK,OAAO,KAAK,EAAE,GAAG;KAC7C;AACF,OAAI,eAAe,SAAS,EAC1B,OAAM,KAAK,KAAK,SAAS,eAAe,SAAS,EAAE,wBAAwB,CAAC;AAE9E,UAAO,WAAW,QAAQ,SAAS,EAAE,WAAW,MAAM,CAAC;IAKtC,EACjB,KAAK,gFAAgF,CACtF;AAGD,MAAI,IAAI,SAAS,UAAU,CAezB,QAAO;GACL;GACA,SAAS;GACT,YAAY,CAAC;IAhBb,MAAM;IACN,WAAW,MAAM,KAAK,WAAW,SAAS,CAAC,CAAC,KAAK,CAAC,IAAI,aAAa;KACjE;KACA,MAAM;KACN,QAAQ,OAAO,KAAK,OAAO;MACzB,IAAI,EAAE;MACN,MAAM,EAAE;MACR,UAAU,EAAE;MACb,EAAE;KACJ,EAAE;IACH;IAMsB,CAAC;GACxB;AAGH,SAAO;GACL;GACA,SAAS;GACV;;CAEJ;AAED,MAAM,gBAAmC;CACvC,IAAI;CACJ,MAAM;CACN,aAAa;CACb,UAAU;CACV,OAAO;EAAC;EAAU;EAAW;EAAQ;CACrC,aAAa;CACb,UAAU,CAAC,0BAA0B,+BAA+B;CACpE,SAAS,OAAO,KAAqB,SAAiB;AACpD,MAAI,CAAC,KAAK,MAAM,CACd,QAAO;GACL,SAAS,WACP,wBACA,0CACA,0GACA,wCACD;GACD,SAAS;GACV;AAGH,QAAM,IAAI,UAAU,KAAK;EAEzB,MAAM,UAAU,KAAK,MAAM;AAG3B,MAAI,MAFkB,IAAI,YAAY,QAAQ,EAEjC;GACX,MAAM,YAAY,QAAQ,MAAM,IAAI,CAAC,KAAK,IAAI;AAC9C,UAAO;IACL,SAAS,WACP,iBAAiB,KAAK,QAAQ,CAAC,IAAI,UAAU,KAC7C,iDACD;IACD,SAAS;IACV;;AAGH,SAAO;GACL,SAAS,WACP,yBAAyB,KAAK,QAAQ,CAAC,IACvC,kFACA,4DACD;GACD,SAAS;GACV;;CAEJ;AAED,MAAM,eAAkC;CACtC,IAAI;CACJ,MAAM;CACN,aAAa;CACb,UAAU;CACV,OAAO;EAAC;EAAU;EAAW;EAAQ;CACrC,SAAS,OAAO,QAAwB;AACtC,QAAM,IAAI,UAAU,KAAK;EAEzB,MAAM,QAAQ,MAAM,IAAI,UAAU;EAClC,MAAM,YAAY,IAAI,iBAAiB,CAAC,MAAM,IAAI,CAAC,KAAK,IAAI;EAE5D,MAAM,UAAU,WACd,QAAQ,yBAAyB,EACjC,OAAO;GACL;IAAE,KAAK;IAAS,OAAO;IAAW;GAClC;IAAE,KAAK;IAAU,OAAO,GAAG,MAAM,aAAa,gBAAgB,CAAC;IAAU;GACzE;IAAE,KAAK;IAAc,OAAO,GAAG,MAAM,iBAAiB,gBAAgB,CAAC;IAAU;GACjF;IAAE,KAAK;IAAS,OAAO,GAAG,MAAM,YAAY,gBAAgB,CAAC;IAAU;GACvE;IAAE,KAAK;IAAY,OAAO,OAAO,MAAM,aAAa;IAAE;GACvD,CAAC,CACH;AAGD,MAAI,IAAI,SAAS,UAAU,CAOzB,QAAO;GACL;GACA,SAAS;GACT,YAAY,CAAC;IARb,MAAM;IACN;IACA;IAMsB,CAAC;GACxB;AAGH,SAAO;GACL;GACA,SAAS;GACV;;CAEJ;AAGD,SAAgB,wBAA8B;AAC5C,iBAAgB,SAAS,cAAc;AACvC,iBAAgB,SAAS,cAAc;AACvC,iBAAgB,SAAS,aAAa"}
@@ -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();