@xopcai/xopc 0.0.103 → 0.0.105

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 (950) hide show
  1. package/README.md +7 -4
  2. package/README.zh-CN.md +7 -4
  3. package/dist/_virtual/_rolldown/runtime.js +2 -3
  4. package/dist/browser-ext/manifest.json +1 -1
  5. package/dist/extensions/feishu/src/adapters/cli-login.d.ts +1 -1
  6. package/dist/extensions/feishu/src/adapters/cli-login.js +1 -1
  7. package/dist/extensions/feishu/src/adapters/cli-login.js.map +1 -1
  8. package/dist/extensions/feishu/src/adapters/gateway-setup.d.ts +2 -0
  9. package/dist/extensions/feishu/src/adapters/gateway-setup.js +225 -0
  10. package/dist/extensions/feishu/src/adapters/gateway-setup.js.map +1 -0
  11. package/dist/extensions/feishu/src/index.d.ts +8 -1
  12. package/dist/extensions/feishu/src/index.js +14 -1
  13. package/dist/extensions/feishu/src/index.js.map +1 -0
  14. package/dist/extensions/feishu/src/outbound/outbound-adapter.js +1 -1
  15. package/dist/extensions/feishu/src/plugin.d.ts +2 -1
  16. package/dist/extensions/feishu/src/plugin.js +2 -0
  17. package/dist/extensions/feishu/src/plugin.js.map +1 -1
  18. package/dist/extensions/feishu/src/streaming/streaming-adapter.js +1 -1
  19. package/dist/extensions/feishu/src/transport/webhook/monitor.js +1 -1
  20. package/dist/extensions/feishu/xopc.extension.json +66 -1
  21. package/dist/extensions/telegram/src/adapters/gateway-setup.d.ts +2 -0
  22. package/dist/extensions/telegram/src/adapters/gateway-setup.js +146 -0
  23. package/dist/extensions/telegram/src/adapters/gateway-setup.js.map +1 -0
  24. package/dist/extensions/telegram/src/adapters/security-adapter.js +1 -1
  25. package/dist/extensions/telegram/src/command-handler.js +1 -2
  26. package/dist/extensions/telegram/src/command-handler.js.map +1 -1
  27. package/dist/extensions/telegram/src/config-schema.js +2 -2
  28. package/dist/extensions/telegram/src/config-schema.js.map +1 -1
  29. package/dist/extensions/telegram/src/doctor.d.ts +1 -0
  30. package/dist/extensions/telegram/src/doctor.js +68 -0
  31. package/dist/extensions/telegram/src/doctor.js.map +1 -1
  32. package/dist/extensions/telegram/src/index.d.ts +8 -1
  33. package/dist/extensions/telegram/src/index.js +15 -2
  34. package/dist/extensions/telegram/src/index.js.map +1 -0
  35. package/dist/extensions/telegram/src/plugin.d.ts +13 -5
  36. package/dist/extensions/telegram/src/plugin.js +32 -12
  37. package/dist/extensions/telegram/src/plugin.js.map +1 -1
  38. package/dist/extensions/telegram/src/proxy-fetch.js +22 -5
  39. package/dist/extensions/telegram/src/proxy-fetch.js.map +1 -1
  40. package/dist/extensions/telegram/xopc.extension.json +412 -5
  41. package/dist/extensions/weixin/src/adapters/onboard-cli.js +2 -2
  42. package/dist/extensions/weixin/src/adapters/onboard-cli.js.map +1 -1
  43. package/dist/extensions/weixin/src/api/api.js +1 -1
  44. package/dist/extensions/weixin/src/index.d.ts +8 -0
  45. package/dist/extensions/weixin/src/index.js +12 -1
  46. package/dist/extensions/weixin/src/index.js.map +1 -0
  47. package/dist/extensions/weixin/src/messaging/process-message.js +1 -1
  48. package/dist/extensions/weixin/src/plugin.d.ts +2 -1
  49. package/dist/extensions/weixin/src/plugin.js +77 -2
  50. package/dist/extensions/weixin/src/plugin.js.map +1 -1
  51. package/dist/extensions/weixin/xopc.extension.json +52 -0
  52. package/dist/gateway/static/root/assets/agents-XzgIVKcI.js +396 -0
  53. package/dist/gateway/static/root/assets/{apps-page-C5RmwmTT.js → apps-page-B7Us3RMl.js} +1 -1
  54. package/dist/gateway/static/root/assets/browser-BLJWD7WI.js +8 -0
  55. package/dist/gateway/static/root/assets/channels-settings-BgeV6fzw.js +1 -0
  56. package/dist/gateway/static/root/assets/cron-page-DKGHEeAU.js +1 -0
  57. package/dist/gateway/static/root/assets/{dist-CWm8hTXZ.js → dist-DJDkNhu5.js} +1 -1
  58. package/dist/gateway/static/root/assets/{extension-debug-page-BzYgTkS9.js → extension-debug-page-DI1XJTJi.js} +1 -1
  59. package/dist/gateway/static/root/assets/{extension-page-BmTZH6gL.js → extension-page-SuafGTT_.js} +1 -1
  60. package/dist/gateway/static/root/assets/extension-settings-page-cKmGax9v.js +1 -0
  61. package/dist/gateway/static/root/assets/{fetch-CMoWY2Si.js → fetch-CkvRO30i.js} +1 -1
  62. package/dist/gateway/static/root/assets/gateway-startup-retry-BkKyRDrF.js +1 -0
  63. package/dist/gateway/static/root/assets/heartbeat-config-api-CRiDcxtt.js +1 -0
  64. package/dist/gateway/static/root/assets/index-50FVtgXU.js +4845 -0
  65. package/dist/gateway/static/root/assets/index-BPYKW7FB.css +1 -0
  66. package/dist/gateway/static/root/assets/{logs-page-BjdQjHwk.js → logs-page-DM8o5-Bm.js} +2 -2
  67. package/dist/gateway/static/root/assets/{note-detail-page-8Er4197b.js → note-detail-page-j53jtvq9.js} +53 -53
  68. package/dist/gateway/static/root/assets/{note-time-CF3vf1jm.js → note-time-Ck2H2Qpw.js} +1 -1
  69. package/dist/gateway/static/root/assets/notes-page-CsWIw35Q.js +1 -0
  70. package/dist/gateway/static/root/assets/schema-form-BvmGNxiJ.js +1 -0
  71. package/dist/gateway/static/root/assets/sessions-page-CLPsbyOW.js +1 -0
  72. package/dist/gateway/static/root/assets/settings-advanced-gate-DRdayl8P.js +2 -0
  73. package/dist/gateway/static/root/assets/{settings-form-section-C7qA7y0J.js → settings-form-section-BlIYg2gZ.js} +1 -1
  74. package/dist/gateway/static/root/assets/settings-page-CRGHT_bm.js +3 -0
  75. package/dist/gateway/static/root/assets/{share-preview-page-Tvr5Mtq5.js → share-preview-page-BlT6Akvk.js} +1 -1
  76. package/dist/gateway/static/root/assets/skills-page-Ce-RIH2y.js +2 -0
  77. package/dist/gateway/static/root/assets/{theme-store-HTvJlFLL.js → theme-store-DYgVdRB4.js} +1 -1
  78. package/dist/gateway/static/root/assets/url-DPEStU4M.js +3 -0
  79. package/dist/gateway/static/root/assets/voice-api-key-field-CJGTidqc.js +1 -0
  80. package/dist/gateway/static/root/assets/{workflow-page.utils-CeBkAjP7.js → workflow-page.utils-_sjXCMvi.js} +1 -1
  81. package/dist/gateway/static/root/assets/workflows-page-o63aaARK.js +27 -0
  82. package/dist/gateway/static/root/index.html +6 -5
  83. package/dist/package.js +1 -1
  84. package/dist/src/agent/agent-manager.d.ts +18 -6
  85. package/dist/src/agent/agent-manager.js +60 -35
  86. package/dist/src/agent/agent-manager.js.map +1 -1
  87. package/dist/src/agent/builtin-agent-ids.d.ts +2 -0
  88. package/dist/src/agent/builtin-agent-ids.js +17 -0
  89. package/dist/src/agent/builtin-agent-ids.js.map +1 -0
  90. package/dist/src/agent/child-agent-factory.d.ts +4 -0
  91. package/dist/src/agent/child-agent-factory.js +28 -8
  92. package/dist/src/agent/child-agent-factory.js.map +1 -1
  93. package/dist/src/agent/context/workspace-templates/AGENTS.md +23 -184
  94. package/dist/src/agent/embedded/run-turn.js +8 -2
  95. package/dist/src/agent/embedded/run-turn.js.map +1 -1
  96. package/dist/src/agent/embedded/session-tool-result-guard.js +1 -1
  97. package/dist/src/agent/embedded/subscribe-session.js +33 -51
  98. package/dist/src/agent/embedded/subscribe-session.js.map +1 -1
  99. package/dist/src/agent/embedded/types.d.ts +36 -35
  100. package/dist/src/agent/fallback/candidates.js +1 -1
  101. package/dist/src/agent/fallback/candidates.js.map +1 -1
  102. package/dist/src/agent/inbound/inbound-loop.js +1 -1
  103. package/dist/src/agent/inbound/turn-dispatcher.d.ts +3 -0
  104. package/dist/src/agent/inbound/turn-dispatcher.js +25 -5
  105. package/dist/src/agent/inbound/turn-dispatcher.js.map +1 -1
  106. package/dist/src/agent/models/manager.d.ts +1 -1
  107. package/dist/src/agent/models/manager.js +1 -1
  108. package/dist/src/agent/models/manager.js.map +1 -1
  109. package/dist/src/agent/orchestration/run-agent-turn-with-fallbacks.d.ts +1 -1
  110. package/dist/src/agent/orchestration/run-agent-turn-with-fallbacks.js +1 -1
  111. package/dist/src/agent/orchestration/run-agent-turn-with-fallbacks.js.map +1 -1
  112. package/dist/src/agent/prompt/memory/index.js +30 -2
  113. package/dist/src/agent/prompt/memory/index.js.map +1 -1
  114. package/dist/src/agent/prompt/sections/tooling.js +4 -0
  115. package/dist/src/agent/prompt/sections/tooling.js.map +1 -1
  116. package/dist/src/agent/service/direct-turn-helpers.d.ts +3 -0
  117. package/dist/src/agent/service/direct-turn-helpers.js +6 -3
  118. package/dist/src/agent/service/direct-turn-helpers.js.map +1 -1
  119. package/dist/src/agent/service/process-direct-streaming.d.ts +3 -0
  120. package/dist/src/agent/service/process-direct-streaming.js +50 -19
  121. package/dist/src/agent/service/process-direct-streaming.js.map +1 -1
  122. package/dist/src/agent/service-inbound-utils.d.ts +0 -1
  123. package/dist/src/agent/service-inbound-utils.js +1 -17
  124. package/dist/src/agent/service-inbound-utils.js.map +1 -1
  125. package/dist/src/agent/service.d.ts +4 -4
  126. package/dist/src/agent/service.js +29 -16
  127. package/dist/src/agent/service.js.map +1 -1
  128. package/dist/src/agent/service.types.d.ts +3 -0
  129. package/dist/src/agent/session/session-config-service.d.ts +1 -0
  130. package/dist/src/agent/session/session-config-service.js +9 -1
  131. package/dist/src/agent/session/session-config-service.js.map +1 -1
  132. package/dist/src/agent/session/session-inspector.d.ts +2 -1
  133. package/dist/src/agent/session/session-inspector.js +4 -0
  134. package/dist/src/agent/session/session-inspector.js.map +1 -1
  135. package/dist/src/agent/skills/config.js +1 -3
  136. package/dist/src/agent/skills/config.js.map +1 -1
  137. package/dist/src/agent/skills/format-skills-prompt.d.ts +1 -0
  138. package/dist/src/agent/skills/format-skills-prompt.js +3 -2
  139. package/dist/src/agent/skills/format-skills-prompt.js.map +1 -1
  140. package/dist/src/agent/skills/index.js +20 -5
  141. package/dist/src/agent/skills/index.js.map +1 -1
  142. package/dist/src/agent/skills/installer.js +14 -27
  143. package/dist/src/agent/skills/installer.js.map +1 -1
  144. package/dist/src/agent/skills/marketplace/adapters/clawhub/adapter.js +11 -1
  145. package/dist/src/agent/skills/marketplace/adapters/clawhub/adapter.js.map +1 -1
  146. package/dist/src/agent/skills/marketplace/adapters/skillhub/adapter.js +18 -4
  147. package/dist/src/agent/skills/marketplace/adapters/skillhub/adapter.js.map +1 -1
  148. package/dist/src/agent/skills/marketplace/adapters/store/adapter.js +11 -2
  149. package/dist/src/agent/skills/marketplace/adapters/store/adapter.js.map +1 -1
  150. package/dist/src/agent/skills/marketplace/adapters/store/store-api-client.d.ts +2 -2
  151. package/dist/src/agent/skills/marketplace/adapters/store/store-api-client.js.map +1 -1
  152. package/dist/src/agent/skills/skill-manager.d.ts +4 -1
  153. package/dist/src/agent/skills/skill-manager.js +3 -3
  154. package/dist/src/agent/skills/skill-manager.js.map +1 -1
  155. package/dist/src/agent/skills/skill-view-path.d.ts +1 -17
  156. package/dist/src/agent/skills/skill-view-path.js +3 -66
  157. package/dist/src/agent/skills/skill-view-path.js.map +1 -1
  158. package/dist/src/agent/skills/test-framework.js +2 -3
  159. package/dist/src/agent/skills/test-framework.js.map +1 -1
  160. package/dist/src/agent/source-context/index.d.ts +2 -0
  161. package/dist/src/agent/source-context/index.js +3 -0
  162. package/dist/src/agent/source-context/injector.d.ts +3 -0
  163. package/dist/src/agent/source-context/injector.js +36 -0
  164. package/dist/src/agent/source-context/injector.js.map +1 -0
  165. package/dist/src/agent/source-context/types.d.ts +19 -0
  166. package/dist/src/agent/source-context/types.js +10 -0
  167. package/dist/src/agent/source-context/types.js.map +1 -0
  168. package/dist/src/agent/streaming/reasoning-visibility-sse.js +1 -0
  169. package/dist/src/agent/streaming/reasoning-visibility-sse.js.map +1 -1
  170. package/dist/src/agent/tool-manuals/browser.d.ts +1 -0
  171. package/{skills/browser/SKILL.md → dist/src/agent/tool-manuals/browser.js} +51 -54
  172. package/dist/src/agent/tool-manuals/browser.js.map +1 -0
  173. package/dist/src/agent/tool-manuals/index.d.ts +10 -0
  174. package/dist/src/agent/tool-manuals/index.js +28 -0
  175. package/dist/src/agent/tool-manuals/index.js.map +1 -0
  176. package/dist/src/agent/tools/browser/tool/browser-use-tool.js +1 -1
  177. package/dist/src/agent/tools/browser/tool/browser-use-tool.js.map +1 -1
  178. package/dist/src/agent/tools/factory.js +2 -0
  179. package/dist/src/agent/tools/factory.js.map +1 -1
  180. package/dist/src/agent/tools/index.d.ts +1 -0
  181. package/dist/src/agent/tools/index.js +2 -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/workflow/catalog.d.ts +7 -2
  188. package/dist/src/agent/workflow/catalog.js +66 -25
  189. package/dist/src/agent/workflow/catalog.js.map +1 -1
  190. package/dist/src/agent/workflow/subagent-runner.d.ts +3 -0
  191. package/dist/src/agent/workflow/subagent-runner.js +50 -4
  192. package/dist/src/agent/workflow/subagent-runner.js.map +1 -1
  193. package/dist/src/agent/workflow/types.d.ts +10 -0
  194. package/dist/src/auth/credentials.js +10 -5
  195. package/dist/src/auth/credentials.js.map +1 -1
  196. package/dist/src/channels/catalog/channel-catalog-service.d.ts +11 -0
  197. package/dist/src/channels/catalog/channel-catalog-service.js +168 -0
  198. package/dist/src/channels/catalog/channel-catalog-service.js.map +1 -0
  199. package/dist/src/channels/catalog/channel-catalog-types.d.ts +22 -0
  200. package/dist/src/channels/catalog/channel-catalog-types.js +1 -0
  201. package/dist/src/channels/dock.d.ts +0 -7
  202. package/dist/src/channels/dock.js +1 -21
  203. package/dist/src/channels/index.d.ts +1 -3
  204. package/dist/src/channels/index.js +1 -5
  205. package/dist/src/channels/lifecycle-supervisor.d.ts +1 -0
  206. package/dist/src/channels/lifecycle-supervisor.js +11 -0
  207. package/dist/src/channels/lifecycle-supervisor.js.map +1 -1
  208. package/dist/src/channels/manager.d.ts +1 -0
  209. package/dist/src/channels/manager.js +3 -0
  210. package/dist/src/channels/manager.js.map +1 -1
  211. package/dist/src/channels/pairing/pairing-channel.d.ts +2 -3
  212. package/dist/src/channels/pairing/pairing-messages.js +1 -1
  213. package/dist/src/channels/pairing/pairing-messages.js.map +1 -1
  214. package/dist/src/channels/pairing/pairing-service.d.ts +1 -1
  215. package/dist/src/channels/pairing/pairing-service.js +8 -27
  216. package/dist/src/channels/pairing/pairing-service.js.map +1 -1
  217. package/dist/src/channels/plugin-types.d.ts +3 -1
  218. package/dist/src/channels/plugins/types.adapters.d.ts +55 -2
  219. package/dist/src/channels/telegram/index.js +1 -1
  220. package/dist/src/chat-commands/builtins/config.js +4 -4
  221. package/dist/src/chat-commands/builtins/config.js.map +1 -1
  222. package/dist/src/chat-commands/config-paths.js +1 -1
  223. package/dist/src/chat-commands/config-paths.js.map +1 -1
  224. package/dist/src/chat-commands/context.js +1 -1
  225. package/dist/src/chat-commands/context.js.map +1 -1
  226. package/dist/src/cli/bin.js +1 -1
  227. package/dist/src/cli/command-manifest.js +1 -1
  228. package/dist/src/cli/command-manifest.js.map +1 -1
  229. package/dist/src/cli/commands/agent.js +2 -2
  230. package/dist/src/cli/commands/agent.js.map +1 -1
  231. package/dist/src/cli/commands/agents.js +2 -4
  232. package/dist/src/cli/commands/agents.js.map +1 -1
  233. package/dist/src/cli/commands/auth.js +1 -1
  234. package/dist/src/cli/commands/channels.d.ts +1 -5
  235. package/dist/src/cli/commands/channels.js +115 -281
  236. package/dist/src/cli/commands/channels.js.map +1 -1
  237. package/dist/src/cli/commands/config.js +2 -2
  238. package/dist/src/cli/commands/config.js.map +1 -1
  239. package/dist/src/cli/commands/doctor/checks/channel-config.js +16 -69
  240. package/dist/src/cli/commands/doctor/checks/channel-config.js.map +1 -1
  241. package/dist/src/cli/commands/doctor/checks/channel-pairing-pending.js +6 -4
  242. package/dist/src/cli/commands/doctor/checks/channel-pairing-pending.js.map +1 -1
  243. package/dist/src/cli/commands/doctor/checks/channel-plugins.js +2 -2
  244. package/dist/src/cli/commands/doctor/checks/channel-plugins.js.map +1 -1
  245. package/dist/src/cli/commands/doctor/checks/database-schema.js +1 -1
  246. package/dist/src/cli/commands/doctor/checks/provider-auth.js +13 -9
  247. package/dist/src/cli/commands/doctor/checks/provider-auth.js.map +1 -1
  248. package/dist/src/cli/commands/extension-dev.js +2 -1
  249. package/dist/src/cli/commands/extension-dev.js.map +1 -1
  250. package/dist/src/cli/commands/extension-marketplace.js +2 -1
  251. package/dist/src/cli/commands/extension-marketplace.js.map +1 -1
  252. package/dist/src/cli/commands/extension-pack.js +2 -1
  253. package/dist/src/cli/commands/extension-pack.js.map +1 -1
  254. package/dist/src/cli/commands/models.js +7 -4
  255. package/dist/src/cli/commands/models.js.map +1 -1
  256. package/dist/src/cli/commands/onboard/channels/index.js +1 -1
  257. package/dist/src/cli/commands/onboard/channels/index.js.map +1 -1
  258. package/dist/src/cli/commands/onboard/channels/registry.d.ts +2 -1
  259. package/dist/src/cli/commands/onboard/channels/registry.js +32 -8
  260. package/dist/src/cli/commands/onboard/channels/registry.js.map +1 -1
  261. package/dist/src/cli/commands/onboard/model.js +8 -5
  262. package/dist/src/cli/commands/onboard/model.js.map +1 -1
  263. package/dist/src/cli/commands/onboard.js +4 -6
  264. package/dist/src/cli/commands/onboard.js.map +1 -1
  265. package/dist/src/cli/commands/setup-shared/runner.d.ts +1 -1
  266. package/dist/src/cli/commands/setup-shared/runner.js.map +1 -1
  267. package/dist/src/cli/commands/setup-shared/types.d.ts +1 -1
  268. package/dist/src/cli/commands/setup-shared/types.js.map +1 -1
  269. package/dist/src/cli/commands/tui.js +13 -5
  270. package/dist/src/cli/commands/tui.js.map +1 -1
  271. package/dist/src/cli/extension-cli-register.js +1 -1
  272. package/dist/src/commands/agents.config.d.ts +3 -3
  273. package/dist/src/commands/agents.config.js +7 -7
  274. package/dist/src/commands/agents.config.js.map +1 -1
  275. package/dist/src/config/agent-profile.d.ts +1 -1
  276. package/dist/src/config/agent-profile.js +6 -2
  277. package/dist/src/config/agent-profile.js.map +1 -1
  278. package/dist/src/config/agent-typed-models.d.ts +2 -2
  279. package/dist/src/config/agent-typed-models.js +13 -2
  280. package/dist/src/config/agent-typed-models.js.map +1 -1
  281. package/dist/src/config/index.js +3 -3
  282. package/dist/src/config/integration.d.ts +1 -1
  283. package/dist/src/config/loader.d.ts +0 -1
  284. package/dist/src/config/loader.js +4 -9
  285. package/dist/src/config/loader.js.map +1 -1
  286. package/dist/src/config/models-json.d.ts +6 -6
  287. package/dist/src/config/paths.d.ts +1 -0
  288. package/dist/src/config/paths.js +5 -1
  289. package/dist/src/config/paths.js.map +1 -1
  290. package/dist/src/config/rules.js +2 -12
  291. package/dist/src/config/rules.js.map +1 -1
  292. package/dist/src/config/schema.d.ts +74 -47
  293. package/dist/src/config/schema.js +28 -66
  294. package/dist/src/config/schema.js.map +1 -1
  295. package/dist/src/config/validate-channel-configs.d.ts +0 -3
  296. package/dist/src/config/validate-channel-configs.js +29 -10
  297. package/dist/src/config/validate-channel-configs.js.map +1 -1
  298. package/dist/src/cron/executor.js +1 -4
  299. package/dist/src/cron/executor.js.map +1 -1
  300. package/dist/src/document-understanding/extract.d.ts +13 -0
  301. package/dist/src/document-understanding/extract.js +63 -0
  302. package/dist/src/document-understanding/extract.js.map +1 -0
  303. package/dist/src/extensions/activation-context.js +3 -1
  304. package/dist/src/extensions/activation-context.js.map +1 -1
  305. package/dist/src/extensions/activation-planner.js +12 -0
  306. package/dist/src/extensions/activation-planner.js.map +1 -1
  307. package/dist/src/extensions/api.d.ts +5 -1
  308. package/dist/src/extensions/api.js +12 -0
  309. package/dist/src/extensions/api.js.map +1 -1
  310. package/dist/src/extensions/discover-extensions.js +17 -13
  311. package/dist/src/extensions/discover-extensions.js.map +1 -1
  312. package/dist/src/extensions/extension-metadata-snapshot.js +11 -5
  313. package/dist/src/extensions/extension-metadata-snapshot.js.map +1 -1
  314. package/dist/src/extensions/index.js +12 -4
  315. package/dist/src/extensions/index.js.map +1 -0
  316. package/dist/src/extensions/loader.d.ts +5 -1
  317. package/dist/src/extensions/loader.js +12 -11
  318. package/dist/src/extensions/loader.js.map +1 -1
  319. package/dist/src/extensions/manifest-registry.js +98 -93
  320. package/dist/src/extensions/manifest-registry.js.map +1 -1
  321. package/dist/src/extensions/normalize-manifest.js +91 -15
  322. package/dist/src/extensions/normalize-manifest.js.map +1 -1
  323. package/dist/src/extensions/sdk/index.js +1 -1
  324. package/dist/src/extensions/sdk/testing.js +4 -0
  325. package/dist/src/extensions/sdk/testing.js.map +1 -1
  326. package/dist/src/extensions/types/core.d.ts +32 -1
  327. package/dist/src/extensions/types/manifest.d.ts +60 -0
  328. package/dist/src/extensions/types/tui.d.ts +414 -5
  329. package/dist/src/gateway/agent-builtin-tools.d.ts +1 -1
  330. package/dist/src/gateway/agent-builtin-tools.js +16 -0
  331. package/dist/src/gateway/agent-builtin-tools.js.map +1 -1
  332. package/dist/src/gateway/agent-run-relay.d.ts +2 -3
  333. package/dist/src/gateway/agent-run-relay.js +10 -3
  334. package/dist/src/gateway/agent-run-relay.js.map +1 -1
  335. package/dist/src/gateway/agents-admin.d.ts +32 -19
  336. package/dist/src/gateway/agents-admin.js +113 -93
  337. package/dist/src/gateway/agents-admin.js.map +1 -1
  338. package/dist/src/gateway/chat-stream/mapper.d.ts +34 -0
  339. package/dist/src/gateway/chat-stream/mapper.js +244 -0
  340. package/dist/src/gateway/chat-stream/mapper.js.map +1 -0
  341. package/dist/src/gateway/chat-stream/protocol.d.ts +100 -0
  342. package/dist/src/gateway/chat-stream/protocol.js +1 -0
  343. package/dist/src/gateway/heartbeat/service.js +1 -1
  344. package/dist/src/gateway/hono/lib/agent-model.d.ts +4 -4
  345. package/dist/src/gateway/hono/lib/agent-model.js +13 -11
  346. package/dist/src/gateway/hono/lib/agent-model.js.map +1 -1
  347. package/dist/src/gateway/hono/lib/config-payload.d.ts +19 -7
  348. package/dist/src/gateway/hono/lib/config-payload.js +16 -15
  349. package/dist/src/gateway/hono/lib/config-payload.js.map +1 -1
  350. package/dist/src/gateway/hono/routes/agents.js +83 -48
  351. package/dist/src/gateway/hono/routes/agents.js.map +1 -1
  352. package/dist/src/gateway/hono/routes/channels.js +134 -214
  353. package/dist/src/gateway/hono/routes/channels.js.map +1 -1
  354. package/dist/src/gateway/hono/routes/commands-skills.js +10 -4
  355. package/dist/src/gateway/hono/routes/commands-skills.js.map +1 -1
  356. package/dist/src/gateway/hono/routes/config-patch/agents.js +26 -13
  357. package/dist/src/gateway/hono/routes/config-patch/agents.js.map +1 -1
  358. package/dist/src/gateway/hono/routes/config-patch/channels.d.ts +1 -11
  359. package/dist/src/gateway/hono/routes/config-patch/channels.js +18 -165
  360. package/dist/src/gateway/hono/routes/config-patch/channels.js.map +1 -1
  361. package/dist/src/gateway/hono/routes/config.js +5 -2
  362. package/dist/src/gateway/hono/routes/config.js.map +1 -1
  363. package/dist/src/gateway/hono/routes/dreaming.js +1 -1
  364. package/dist/src/gateway/hono/routes/lazy-bundles.js +13 -1
  365. package/dist/src/gateway/hono/routes/lazy-bundles.js.map +1 -1
  366. package/dist/src/gateway/hono/routes/notes.js +46 -27
  367. package/dist/src/gateway/hono/routes/notes.js.map +1 -1
  368. package/dist/src/gateway/hono/routes/public-gateway.js +2 -4
  369. package/dist/src/gateway/hono/routes/public-gateway.js.map +1 -1
  370. package/dist/src/gateway/hono/routes/sessions.js +179 -0
  371. package/dist/src/gateway/hono/routes/sessions.js.map +1 -1
  372. package/dist/src/gateway/hono/routes/tui.d.ts +3 -0
  373. package/dist/src/gateway/hono/routes/tui.js +16 -0
  374. package/dist/src/gateway/hono/routes/tui.js.map +1 -0
  375. package/dist/src/gateway/hono/routes/workflows.js +25 -1
  376. package/dist/src/gateway/hono/routes/workflows.js.map +1 -1
  377. package/dist/src/gateway/hono/sse.d.ts +5 -7
  378. package/dist/src/gateway/hono/sse.js +21 -38
  379. package/dist/src/gateway/hono/sse.js.map +1 -1
  380. package/dist/src/gateway/protocol.js.map +1 -1
  381. package/dist/src/gateway/service/agent-runner.d.ts +2 -4
  382. package/dist/src/gateway/service/agent-runner.js +1 -1
  383. package/dist/src/gateway/service/agent-runner.js.map +1 -1
  384. package/dist/src/gateway/service/marketplace-service.d.ts +4 -3
  385. package/dist/src/gateway/service/marketplace-service.js +7 -4
  386. package/dist/src/gateway/service/marketplace-service.js.map +1 -1
  387. package/dist/src/gateway/service/run-gateway-agent.d.ts +2 -6
  388. package/dist/src/gateway/service/run-gateway-agent.js +63 -36
  389. package/dist/src/gateway/service/run-gateway-agent.js.map +1 -1
  390. package/dist/src/gateway/service/sessions-api.d.ts +19 -0
  391. package/dist/src/gateway/service/sessions-api.js +12 -0
  392. package/dist/src/gateway/service/sessions-api.js.map +1 -1
  393. package/dist/src/gateway/service.d.ts +6 -0
  394. package/dist/src/gateway/service.js +84 -57
  395. package/dist/src/gateway/service.js.map +1 -1
  396. package/dist/src/heartbeat/index.js +1 -1
  397. package/dist/src/notes/agent-context.d.ts +40 -0
  398. package/dist/src/notes/agent-context.js +383 -0
  399. package/dist/src/notes/agent-context.js.map +1 -0
  400. package/dist/src/notes/index.d.ts +2 -0
  401. package/dist/src/notes/index.js +2 -1
  402. package/dist/src/notes/service.d.ts +5 -0
  403. package/dist/src/notes/service.js +22 -0
  404. package/dist/src/notes/service.js.map +1 -1
  405. package/dist/src/notes/store.js +2 -0
  406. package/dist/src/notes/store.js.map +1 -1
  407. package/dist/src/project-trust/trust-store.d.ts +30 -0
  408. package/dist/src/project-trust/trust-store.js +194 -0
  409. package/dist/src/project-trust/trust-store.js.map +1 -0
  410. package/dist/src/providers/index.d.ts +1 -1
  411. package/dist/src/providers/index.js +18 -7
  412. package/dist/src/providers/index.js.map +1 -1
  413. package/dist/src/routing/resolve-route.d.ts +0 -3
  414. package/dist/src/routing/resolve-route.js.map +1 -1
  415. package/dist/src/routing/resolve-tui-session-key.d.ts +2 -0
  416. package/dist/src/routing/resolve-tui-session-key.js +8 -3
  417. package/dist/src/routing/resolve-tui-session-key.js.map +1 -1
  418. package/dist/src/session/client-history.d.ts +32 -0
  419. package/dist/src/session/client-history.js +232 -1
  420. package/dist/src/session/client-history.js.map +1 -1
  421. package/dist/src/session/manager.d.ts +37 -4
  422. package/dist/src/session/manager.js +39 -15
  423. package/dist/src/session/manager.js.map +1 -1
  424. package/dist/src/session/session-context-for-llm.d.ts +93 -1
  425. package/dist/src/session/session-context-for-llm.js +105 -2
  426. package/dist/src/session/session-context-for-llm.js.map +1 -1
  427. package/dist/src/session/store.d.ts +37 -0
  428. package/dist/src/session/store.js +127 -2
  429. package/dist/src/session/store.js.map +1 -1
  430. package/dist/src/session/stored-rows-to-file-entries.js +37 -1
  431. package/dist/src/session/stored-rows-to-file-entries.js.map +1 -1
  432. package/dist/src/session/types.d.ts +14 -1
  433. package/dist/src/session/types.js.map +1 -1
  434. package/dist/src/storage/sqlite/index.d.ts +1 -0
  435. package/dist/src/storage/sqlite/index.js +2 -1
  436. package/dist/src/storage/sqlite/migrations/004_add_session_type_metadata.sql +15 -0
  437. package/dist/src/storage/sqlite/migrations/005_add_note_agent_contexts.sql +10 -0
  438. package/dist/src/storage/sqlite/migrations/runner.d.ts +1 -1
  439. package/dist/src/storage/sqlite/migrations/runner.js +3 -3
  440. package/dist/src/storage/sqlite/migrations/runner.js.map +1 -1
  441. package/dist/src/storage/sqlite/migrations/runner.ts +1 -1
  442. package/dist/src/storage/sqlite/note-agent-context-repository.d.ts +10 -0
  443. package/dist/src/storage/sqlite/note-agent-context-repository.js +35 -0
  444. package/dist/src/storage/sqlite/note-agent-context-repository.js.map +1 -0
  445. package/dist/src/storage/sqlite/row-mappers.d.ts +14 -1
  446. package/dist/src/storage/sqlite/row-mappers.js +14 -1
  447. package/dist/src/storage/sqlite/row-mappers.js.map +1 -1
  448. package/dist/src/storage/sqlite/schema.js +1 -1
  449. package/dist/src/storage/sqlite/session-metadata.js +1 -0
  450. package/dist/src/storage/sqlite/session-metadata.js.map +1 -1
  451. package/dist/src/storage/sqlite/session-repository.js +52 -25
  452. package/dist/src/storage/sqlite/session-repository.js.map +1 -1
  453. package/dist/src/tui/backends/embedded-backend.d.ts +53 -4
  454. package/dist/src/tui/backends/embedded-backend.js +227 -39
  455. package/dist/src/tui/backends/embedded-backend.js.map +1 -1
  456. package/dist/src/tui/backends/gateway-sse-backend.d.ts +59 -3
  457. package/dist/src/tui/backends/gateway-sse-backend.js +416 -26
  458. package/dist/src/tui/backends/gateway-sse-backend.js.map +1 -1
  459. package/dist/src/tui/chat-history.d.ts +5 -1
  460. package/dist/src/tui/chat-history.js +78 -8
  461. package/dist/src/tui/chat-history.js.map +1 -1
  462. package/dist/src/tui/clipboard-text.d.ts +5 -0
  463. package/dist/src/tui/clipboard-text.js +46 -0
  464. package/dist/src/tui/clipboard-text.js.map +1 -0
  465. package/dist/src/tui/components/assistant-message.d.ts +19 -3
  466. package/dist/src/tui/components/assistant-message.js +115 -9
  467. package/dist/src/tui/components/assistant-message.js.map +1 -1
  468. package/dist/src/tui/components/bash-execution.d.ts +3 -2
  469. package/dist/src/tui/components/bash-execution.js +31 -3
  470. package/dist/src/tui/components/bash-execution.js.map +1 -1
  471. package/dist/src/tui/components/bash-summary.d.ts +23 -0
  472. package/dist/src/tui/components/bash-summary.js +87 -0
  473. package/dist/src/tui/components/bash-summary.js.map +1 -0
  474. package/dist/src/tui/components/branch-message-summary.d.ts +17 -0
  475. package/dist/src/tui/components/branch-message-summary.js +43 -0
  476. package/dist/src/tui/components/branch-message-summary.js.map +1 -0
  477. package/dist/src/tui/components/branch-summary.d.ts +13 -0
  478. package/dist/src/tui/components/branch-summary.js +51 -0
  479. package/dist/src/tui/components/branch-summary.js.map +1 -0
  480. package/dist/src/tui/components/chat-log.d.ts +46 -6
  481. package/dist/src/tui/components/chat-log.js +183 -21
  482. package/dist/src/tui/components/chat-log.js.map +1 -1
  483. package/dist/src/tui/components/compaction-summary.d.ts +13 -0
  484. package/dist/src/tui/components/compaction-summary.js +46 -0
  485. package/dist/src/tui/components/compaction-summary.js.map +1 -0
  486. package/dist/src/tui/components/custom-editor.d.ts +1 -0
  487. package/dist/src/tui/components/custom-editor.js +2 -0
  488. package/dist/src/tui/components/custom-editor.js.map +1 -1
  489. package/dist/src/tui/components/custom-message.d.ts +23 -0
  490. package/dist/src/tui/components/custom-message.js +65 -0
  491. package/dist/src/tui/components/custom-message.js.map +1 -0
  492. package/dist/src/tui/components/extension-dialog.d.ts +42 -0
  493. package/dist/src/tui/components/extension-dialog.js +127 -0
  494. package/dist/src/tui/components/extension-dialog.js.map +1 -0
  495. package/dist/src/tui/components/scoped-models-selector.d.ts +7 -2
  496. package/dist/src/tui/components/scoped-models-selector.js +89 -16
  497. package/dist/src/tui/components/scoped-models-selector.js.map +1 -1
  498. package/dist/src/tui/components/searchable-select-list.d.ts +30 -3
  499. package/dist/src/tui/components/searchable-select-list.js +82 -10
  500. package/dist/src/tui/components/searchable-select-list.js.map +1 -1
  501. package/dist/src/tui/components/session-selector.d.ts +18 -4
  502. package/dist/src/tui/components/session-selector.js +207 -40
  503. package/dist/src/tui/components/session-selector.js.map +1 -1
  504. package/dist/src/tui/components/settings-selector.d.ts +6 -2
  505. package/dist/src/tui/components/settings-selector.js +126 -7
  506. package/dist/src/tui/components/settings-selector.js.map +1 -1
  507. package/dist/src/tui/components/thinking-selector.d.ts +12 -0
  508. package/dist/src/tui/components/thinking-selector.js +48 -0
  509. package/dist/src/tui/components/thinking-selector.js.map +1 -0
  510. package/dist/src/tui/components/tool-execution.d.ts +57 -3
  511. package/dist/src/tui/components/tool-execution.js +378 -28
  512. package/dist/src/tui/components/tool-execution.js.map +1 -1
  513. package/dist/src/tui/components/tui-bottom-bar.d.ts +9 -1
  514. package/dist/src/tui/components/tui-bottom-bar.js +56 -11
  515. package/dist/src/tui/components/tui-bottom-bar.js.map +1 -1
  516. package/dist/src/tui/components/tui-header.d.ts +9 -2
  517. package/dist/src/tui/components/tui-header.js +25 -5
  518. package/dist/src/tui/components/tui-header.js.map +1 -1
  519. package/dist/src/tui/components/user-message.d.ts +4 -2
  520. package/dist/src/tui/components/user-message.js +42 -9
  521. package/dist/src/tui/components/user-message.js.map +1 -1
  522. package/dist/src/tui/components/visual-truncate.d.ts +11 -0
  523. package/dist/src/tui/components/visual-truncate.js +27 -0
  524. package/dist/src/tui/components/visual-truncate.js.map +1 -0
  525. package/dist/src/tui/extension-host/autocomplete.d.ts +43 -0
  526. package/dist/src/tui/extension-host/autocomplete.js +116 -0
  527. package/dist/src/tui/extension-host/autocomplete.js.map +1 -0
  528. package/dist/src/tui/extension-host/host.d.ts +31 -1
  529. package/dist/src/tui/extension-host/host.js +123 -6
  530. package/dist/src/tui/extension-host/host.js.map +1 -1
  531. package/dist/src/tui/extension-host/load-extensions.d.ts +6 -1
  532. package/dist/src/tui/extension-host/load-extensions.js +4 -3
  533. package/dist/src/tui/extension-host/load-extensions.js.map +1 -1
  534. package/dist/src/tui/extension-host/runtime-context.d.ts +21 -0
  535. package/dist/src/tui/extension-host/runtime-context.js +152 -0
  536. package/dist/src/tui/extension-host/runtime-context.js.map +1 -0
  537. package/dist/src/tui/extension-host/runtime.d.ts +52 -4
  538. package/dist/src/tui/extension-host/runtime.js +547 -85
  539. package/dist/src/tui/extension-host/runtime.js.map +1 -1
  540. package/dist/src/tui/extension-host/surface.d.ts +20 -0
  541. package/dist/src/tui/extension-host/surface.js +30 -6
  542. package/dist/src/tui/extension-host/surface.js.map +1 -1
  543. package/dist/src/tui/extension-host/tool-renderers.d.ts +6 -3
  544. package/dist/src/tui/extension-host/tool-renderers.js +43 -5
  545. package/dist/src/tui/extension-host/tool-renderers.js.map +1 -1
  546. package/dist/src/tui/format-tui-hotkeys.d.ts +12 -2
  547. package/dist/src/tui/format-tui-hotkeys.js +22 -5
  548. package/dist/src/tui/format-tui-hotkeys.js.map +1 -1
  549. package/dist/src/tui/tui-agent-events.d.ts +8 -6
  550. package/dist/src/tui/tui-agent-events.js +200 -59
  551. package/dist/src/tui/tui-agent-events.js.map +1 -1
  552. package/dist/src/tui/tui-backend.d.ts +169 -3
  553. package/dist/src/tui/tui-command-formatters.d.ts +76 -0
  554. package/dist/src/tui/tui-command-formatters.js +594 -0
  555. package/dist/src/tui/tui-command-formatters.js.map +1 -0
  556. package/dist/src/tui/tui-commands.d.ts +57 -7
  557. package/dist/src/tui/tui-commands.js +639 -43
  558. package/dist/src/tui/tui-commands.js.map +1 -1
  559. package/dist/src/tui/tui-context-usage.d.ts +1 -1
  560. package/dist/src/tui/tui-context-usage.js +9 -1
  561. package/dist/src/tui/tui-context-usage.js.map +1 -1
  562. package/dist/src/tui/tui-extension-user-message.d.ts +8 -0
  563. package/dist/src/tui/tui-extension-user-message.js +32 -0
  564. package/dist/src/tui/tui-extension-user-message.js.map +1 -0
  565. package/dist/src/tui/tui-follow-up-queue.d.ts +9 -0
  566. package/dist/src/tui/tui-follow-up-queue.js +18 -0
  567. package/dist/src/tui/tui-follow-up-queue.js.map +1 -0
  568. package/dist/src/tui/tui-local-shell.d.ts +11 -1
  569. package/dist/src/tui/tui-local-shell.js +50 -8
  570. package/dist/src/tui/tui-local-shell.js.map +1 -1
  571. package/dist/src/tui/tui-model-picker.d.ts +26 -0
  572. package/dist/src/tui/tui-model-picker.js +152 -0
  573. package/dist/src/tui/tui-model-picker.js.map +1 -0
  574. package/dist/src/tui/tui-oauth-login.d.ts +16 -0
  575. package/dist/src/tui/tui-oauth-login.js +189 -0
  576. package/dist/src/tui/tui-oauth-login.js.map +1 -0
  577. package/dist/src/tui/tui-overlays.d.ts +3 -3
  578. package/dist/src/tui/tui-overlays.js +6 -7
  579. package/dist/src/tui/tui-overlays.js.map +1 -1
  580. package/dist/src/tui/tui-picker-overlay.d.ts +27 -32
  581. package/dist/src/tui/tui-picker-overlay.js +340 -30
  582. package/dist/src/tui/tui-picker-overlay.js.map +1 -1
  583. package/dist/src/tui/tui-picker-services.d.ts +41 -0
  584. package/dist/src/tui/tui-picker-services.js +1 -0
  585. package/dist/src/tui/tui-run-state.d.ts +11 -0
  586. package/dist/src/tui/tui-run-state.js +114 -0
  587. package/dist/src/tui/tui-run-state.js.map +1 -0
  588. package/dist/src/tui/tui-runtime-hints.d.ts +4 -0
  589. package/dist/src/tui/tui-runtime-hints.js +18 -0
  590. package/dist/src/tui/tui-runtime-hints.js.map +1 -0
  591. package/dist/src/tui/tui-scoped-models.d.ts +1 -1
  592. package/dist/src/tui/tui-scoped-models.js +2 -2
  593. package/dist/src/tui/tui-scoped-models.js.map +1 -1
  594. package/dist/src/tui/tui-session-actions.d.ts +5 -3
  595. package/dist/src/tui/tui-session-actions.js +21 -9
  596. package/dist/src/tui/tui-session-actions.js.map +1 -1
  597. package/dist/src/tui/tui-session-format.d.ts +4 -1
  598. package/dist/src/tui/tui-session-format.js +17 -3
  599. package/dist/src/tui/tui-session-format.js.map +1 -1
  600. package/dist/src/tui/tui-session-snapshot.d.ts +82 -0
  601. package/dist/src/tui/tui-session-snapshot.js +184 -0
  602. package/dist/src/tui/tui-session-snapshot.js.map +1 -0
  603. package/dist/src/tui/tui-session-stats.d.ts +3 -0
  604. package/dist/src/tui/tui-session-stats.js +59 -0
  605. package/dist/src/tui/tui-session-stats.js.map +1 -0
  606. package/dist/src/tui/tui-settings.d.ts +21 -0
  607. package/dist/src/tui/tui-settings.js +28 -1
  608. package/dist/src/tui/tui-settings.js.map +1 -1
  609. package/dist/src/tui/tui-skills-autocomplete.js +1 -1
  610. package/dist/src/tui/tui-skills-autocomplete.js.map +1 -1
  611. package/dist/src/tui/tui-startup-resources.d.ts +3 -0
  612. package/dist/src/tui/tui-startup-resources.js +39 -0
  613. package/dist/src/tui/tui-startup-resources.js.map +1 -0
  614. package/dist/src/tui/tui-startup-text.d.ts +10 -0
  615. package/dist/src/tui/tui-startup-text.js +58 -0
  616. package/dist/src/tui/tui-startup-text.js.map +1 -0
  617. package/dist/src/tui/tui-stdio-filter.d.ts +1 -0
  618. package/dist/src/tui/tui-stdio-filter.js +11 -7
  619. package/dist/src/tui/tui-stdio-filter.js.map +1 -1
  620. package/dist/src/tui/tui-submit.d.ts +2 -0
  621. package/dist/src/tui/tui-submit.js +2 -1
  622. package/dist/src/tui/tui-submit.js.map +1 -1
  623. package/dist/src/tui/tui-tool-diff.js +61 -7
  624. package/dist/src/tui/tui-tool-diff.js.map +1 -1
  625. package/dist/src/tui/tui-tool-result.d.ts +17 -0
  626. package/dist/src/tui/tui-tool-result.js +74 -0
  627. package/dist/src/tui/tui-tool-result.js.map +1 -0
  628. package/dist/src/tui/tui-transcript-tree-picker.d.ts +57 -0
  629. package/dist/src/tui/tui-transcript-tree-picker.js +604 -0
  630. package/dist/src/tui/tui-transcript-tree-picker.js.map +1 -0
  631. package/dist/src/tui/tui-transcript-tree.d.ts +7 -0
  632. package/dist/src/tui/tui-transcript-tree.js +316 -0
  633. package/dist/src/tui/tui-transcript-tree.js.map +1 -0
  634. package/dist/src/tui/tui-types.d.ts +25 -34
  635. package/dist/src/tui/tui-types.js +12 -0
  636. package/dist/src/tui/tui-types.js.map +1 -1
  637. package/dist/src/tui/tui.js +1288 -112
  638. package/dist/src/tui/tui.js.map +1 -1
  639. package/dist/src/tui/xopc-tui-keybindings.d.ts +127 -2
  640. package/dist/src/tui/xopc-tui-keybindings.js +127 -2
  641. package/dist/src/tui/xopc-tui-keybindings.js.map +1 -1
  642. package/dist/src/workflows/domain/definition-utils.d.ts +2 -1
  643. package/dist/src/workflows/domain/definition-utils.js +18 -8
  644. package/dist/src/workflows/domain/definition-utils.js.map +1 -1
  645. package/dist/src/workflows/domain/definition.d.ts +25 -0
  646. package/dist/src/workflows/domain/event.d.ts +1 -0
  647. package/dist/src/workflows/domain/result.d.ts +15 -0
  648. package/dist/src/workflows/domain/run.d.ts +2 -0
  649. package/dist/src/workflows/domain/run.js.map +1 -1
  650. package/dist/src/workflows/engine/projector.js +4 -0
  651. package/dist/src/workflows/engine/projector.js.map +1 -1
  652. package/dist/src/workflows/engine/workflow-engine.d.ts +37 -1
  653. package/dist/src/workflows/engine/workflow-engine.js +75 -11
  654. package/dist/src/workflows/engine/workflow-engine.js.map +1 -1
  655. package/dist/src/workflows/index.d.ts +1 -0
  656. package/dist/src/workflows/index.js +4 -1
  657. package/dist/src/workflows/registry/catalog-workflow-definition-registry.d.ts +9 -0
  658. package/dist/src/workflows/registry/catalog-workflow-definition-registry.js +40 -0
  659. package/dist/src/workflows/registry/catalog-workflow-definition-registry.js.map +1 -0
  660. package/dist/src/workflows/registry/index.d.ts +2 -0
  661. package/dist/src/workflows/registry/index.js +2 -0
  662. package/dist/src/workflows/registry/workflow-definition-registry.d.ts +15 -0
  663. package/dist/src/workflows/registry/workflow-definition-registry.js +1 -0
  664. package/dist/src/workflows/runtime/index.d.ts +2 -0
  665. package/dist/src/workflows/runtime/index.js +2 -1
  666. package/dist/src/workflows/runtime/script-workflow-runtime.d.ts +5 -0
  667. package/dist/src/workflows/runtime/script-workflow-runtime.js +15 -0
  668. package/dist/src/workflows/runtime/script-workflow-runtime.js.map +1 -0
  669. package/dist/src/workflows/runtime/workflow-runtime-port.d.ts +16 -0
  670. package/dist/src/workflows/runtime/workflow-runtime-port.js +1 -0
  671. package/dist/src/workflows/service/run-view-to-snapshot.js +3 -0
  672. package/dist/src/workflows/service/run-view-to-snapshot.js.map +1 -1
  673. package/dist/src/workflows/service/workflow-run-service.d.ts +3 -0
  674. package/dist/src/workflows/service/workflow-run-service.js +10 -15
  675. package/dist/src/workflows/service/workflow-run-service.js.map +1 -1
  676. package/dist/src/workflows/service/workflow-session-bridge.d.ts +1 -1
  677. package/dist/src/workflows/service/workflow-session-bridge.js +4 -1
  678. package/dist/src/workflows/service/workflow-session-bridge.js.map +1 -1
  679. package/package.json +23 -17
  680. package/skills/creative/frontend-design/SKILL.md +1 -1
  681. package/skills/creative/theme-factory/SKILL.md +1 -1
  682. package/skills/documents/xlsx/SKILL.md +1 -1
  683. package/skills/engineering/diagnose/SKILL.md +2 -2
  684. package/skills/engineering/tdd/SKILL.md +1 -1
  685. package/skills/tools/github/SKILL.md +6 -1
  686. package/skills/tools/webapp-testing/SKILL.md +4 -1
  687. package/dist/extensions/telegram/src/adapters/config-surface.d.ts +0 -2
  688. package/dist/extensions/telegram/src/adapters/config-surface.js +0 -26
  689. package/dist/extensions/telegram/src/adapters/config-surface.js.map +0 -1
  690. package/dist/extensions/weixin/src/__tests__/workflow-progress.test.js +0 -158
  691. package/dist/extensions/weixin/src/__tests__/workflow-progress.test.js.map +0 -1
  692. package/dist/gateway/static/root/assets/agents-BwXkia_W.js +0 -222
  693. package/dist/gateway/static/root/assets/channels-settings-tlOTdaXw.js +0 -1
  694. package/dist/gateway/static/root/assets/channels-status-swr-D4XjqwqC.js +0 -8
  695. package/dist/gateway/static/root/assets/cron-api-DcmfGuj0.js +0 -1
  696. package/dist/gateway/static/root/assets/cron-page-CijJ4G6F.js +0 -1
  697. package/dist/gateway/static/root/assets/extension-settings-page-CyJk_G64.js +0 -1
  698. package/dist/gateway/static/root/assets/field-primitives-C4GpxsDo.js +0 -1
  699. package/dist/gateway/static/root/assets/heartbeat-config-api-CLD0Gpi3.js +0 -1
  700. package/dist/gateway/static/root/assets/index-0HmunJW9.js +0 -4845
  701. package/dist/gateway/static/root/assets/index-Bk75Phrd.css +0 -1
  702. package/dist/gateway/static/root/assets/notes-page-BBnTh0uI.js +0 -1
  703. package/dist/gateway/static/root/assets/sessions-page-B0riYK7j.js +0 -1
  704. package/dist/gateway/static/root/assets/settings-advanced-gate-DiP_WHu_.js +0 -2
  705. package/dist/gateway/static/root/assets/settings-page-1ZPhcCZ9.js +0 -3
  706. package/dist/gateway/static/root/assets/skills-page-BQ1hllKD.js +0 -2
  707. package/dist/gateway/static/root/assets/url-F3_D_6zZ.js +0 -3
  708. package/dist/gateway/static/root/assets/utils-CPr3FBh2.js +0 -1
  709. package/dist/gateway/static/root/assets/voice-api-key-field-BkbDl6dH.js +0 -1
  710. package/dist/gateway/static/root/assets/workflows-page-D059ysoF.js +0 -27
  711. package/dist/src/agent/embedded/map-stream-events.d.ts +0 -9
  712. package/dist/src/agent/embedded/map-stream-events.js +0 -63
  713. package/dist/src/agent/embedded/map-stream-events.js.map +0 -1
  714. package/dist/src/channels/dock.js.map +0 -1
  715. package/dist/src/channels/plugins/bundled.d.ts +0 -11
  716. package/dist/src/channels/plugins/bundled.js +0 -10
  717. package/dist/src/channels/plugins/bundled.js.map +0 -1
  718. package/dist/src/channels/registry.d.ts +0 -25
  719. package/dist/src/channels/registry.js +0 -82
  720. package/dist/src/channels/registry.js.map +0 -1
  721. package/dist/src/config/localized-text.d.ts +0 -6
  722. package/dist/src/config/localized-text.js +0 -42
  723. package/dist/src/config/localized-text.js.map +0 -1
  724. package/dist/src/generated/bundled-channel-plugins.d.ts +0 -10
  725. package/dist/src/generated/bundled-channel-plugins.js +0 -16
  726. package/dist/src/generated/bundled-channel-plugins.js.map +0 -1
  727. package/dist/src/tui/stream-assembler.d.ts +0 -22
  728. package/dist/src/tui/stream-assembler.js +0 -63
  729. package/dist/src/tui/stream-assembler.js.map +0 -1
  730. package/skills/browser/SKILL-zh.md +0 -188
  731. package/skills/business/company-values/SKILL-zh.md +0 -80
  732. package/skills/business/company-values/SKILL.md +0 -80
  733. package/skills/business/find-community/SKILL-zh.md +0 -50
  734. package/skills/business/find-community/SKILL.md +0 -50
  735. package/skills/business/first-customers/SKILL-zh.md +0 -76
  736. package/skills/business/first-customers/SKILL.md +0 -76
  737. package/skills/business/grow-sustainably/SKILL-zh.md +0 -92
  738. package/skills/business/grow-sustainably/SKILL.md +0 -92
  739. package/skills/business/marketing-plan/SKILL-zh.md +0 -100
  740. package/skills/business/marketing-plan/SKILL.md +0 -100
  741. package/skills/business/minimalist-review/SKILL-zh.md +0 -82
  742. package/skills/business/minimalist-review/SKILL.md +0 -82
  743. package/skills/business/mvp/SKILL-zh.md +0 -81
  744. package/skills/business/mvp/SKILL.md +0 -81
  745. package/skills/business/pricing/SKILL-zh.md +0 -64
  746. package/skills/business/pricing/SKILL.md +0 -64
  747. package/skills/business/processize/SKILL-zh.md +0 -91
  748. package/skills/business/processize/SKILL.md +0 -91
  749. package/skills/business/validate-idea/SKILL-zh.md +0 -68
  750. package/skills/business/validate-idea/SKILL.md +0 -68
  751. package/skills/creative/algorithmic-art/LICENSE.txt +0 -202
  752. package/skills/creative/algorithmic-art/SKILL-zh.md +0 -405
  753. package/skills/creative/algorithmic-art/SKILL.md +0 -405
  754. package/skills/creative/algorithmic-art/templates/generator_template.js +0 -223
  755. package/skills/creative/algorithmic-art/templates/viewer.html +0 -599
  756. package/skills/creative/frontend-design/SKILL-zh.md +0 -42
  757. package/skills/creative/theme-factory/SKILL-zh.md +0 -59
  758. package/skills/creative/web-artifacts-builder/LICENSE.txt +0 -202
  759. package/skills/creative/web-artifacts-builder/SKILL-zh.md +0 -74
  760. package/skills/creative/web-artifacts-builder/SKILL.md +0 -74
  761. package/skills/creative/web-artifacts-builder/scripts/bundle-artifact.sh +0 -54
  762. package/skills/creative/web-artifacts-builder/scripts/init-artifact.sh +0 -322
  763. package/skills/creative/web-artifacts-builder/scripts/shadcn-components.tar.gz +0 -0
  764. package/skills/documents/doc-coauthoring/SKILL-zh.md +0 -375
  765. package/skills/documents/doc-coauthoring/SKILL.md +0 -375
  766. package/skills/documents/docx/LICENSE.txt +0 -30
  767. package/skills/documents/docx/SKILL-zh.md +0 -590
  768. package/skills/documents/docx/SKILL.md +0 -590
  769. package/skills/documents/docx/scripts/__init__.py +0 -1
  770. package/skills/documents/docx/scripts/accept_changes.py +0 -135
  771. package/skills/documents/docx/scripts/comment.py +0 -318
  772. package/skills/documents/docx/scripts/office/helpers/__init__.py +0 -0
  773. package/skills/documents/docx/scripts/office/helpers/merge_runs.py +0 -199
  774. package/skills/documents/docx/scripts/office/helpers/simplify_redlines.py +0 -197
  775. package/skills/documents/docx/scripts/office/pack.py +0 -159
  776. package/skills/documents/docx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-chart.xsd +0 -1499
  777. package/skills/documents/docx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-chartDrawing.xsd +0 -146
  778. package/skills/documents/docx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-diagram.xsd +0 -1085
  779. package/skills/documents/docx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-lockedCanvas.xsd +0 -11
  780. package/skills/documents/docx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-main.xsd +0 -3081
  781. package/skills/documents/docx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-picture.xsd +0 -23
  782. package/skills/documents/docx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-spreadsheetDrawing.xsd +0 -185
  783. package/skills/documents/docx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-wordprocessingDrawing.xsd +0 -287
  784. package/skills/documents/docx/scripts/office/schemas/ISO-IEC29500-4_2016/pml.xsd +0 -1676
  785. package/skills/documents/docx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-additionalCharacteristics.xsd +0 -28
  786. package/skills/documents/docx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-bibliography.xsd +0 -144
  787. package/skills/documents/docx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-commonSimpleTypes.xsd +0 -174
  788. package/skills/documents/docx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-customXmlDataProperties.xsd +0 -25
  789. package/skills/documents/docx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-customXmlSchemaProperties.xsd +0 -18
  790. package/skills/documents/docx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesCustom.xsd +0 -59
  791. package/skills/documents/docx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesExtended.xsd +0 -56
  792. package/skills/documents/docx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesVariantTypes.xsd +0 -195
  793. package/skills/documents/docx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-math.xsd +0 -582
  794. package/skills/documents/docx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-relationshipReference.xsd +0 -25
  795. package/skills/documents/docx/scripts/office/schemas/ISO-IEC29500-4_2016/sml.xsd +0 -4439
  796. package/skills/documents/docx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-main.xsd +0 -570
  797. package/skills/documents/docx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-officeDrawing.xsd +0 -509
  798. package/skills/documents/docx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-presentationDrawing.xsd +0 -12
  799. package/skills/documents/docx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-spreadsheetDrawing.xsd +0 -108
  800. package/skills/documents/docx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-wordprocessingDrawing.xsd +0 -96
  801. package/skills/documents/docx/scripts/office/schemas/ISO-IEC29500-4_2016/wml.xsd +0 -3646
  802. package/skills/documents/docx/scripts/office/schemas/ISO-IEC29500-4_2016/xml.xsd +0 -116
  803. package/skills/documents/docx/scripts/office/schemas/ecma/fouth-edition/opc-contentTypes.xsd +0 -42
  804. package/skills/documents/docx/scripts/office/schemas/ecma/fouth-edition/opc-coreProperties.xsd +0 -50
  805. package/skills/documents/docx/scripts/office/schemas/ecma/fouth-edition/opc-digSig.xsd +0 -49
  806. package/skills/documents/docx/scripts/office/schemas/ecma/fouth-edition/opc-relationships.xsd +0 -33
  807. package/skills/documents/docx/scripts/office/schemas/mce/mc.xsd +0 -75
  808. package/skills/documents/docx/scripts/office/schemas/microsoft/wml-2010.xsd +0 -560
  809. package/skills/documents/docx/scripts/office/schemas/microsoft/wml-2012.xsd +0 -67
  810. package/skills/documents/docx/scripts/office/schemas/microsoft/wml-2018.xsd +0 -14
  811. package/skills/documents/docx/scripts/office/schemas/microsoft/wml-cex-2018.xsd +0 -20
  812. package/skills/documents/docx/scripts/office/schemas/microsoft/wml-cid-2016.xsd +0 -13
  813. package/skills/documents/docx/scripts/office/schemas/microsoft/wml-sdtdatahash-2020.xsd +0 -4
  814. package/skills/documents/docx/scripts/office/schemas/microsoft/wml-symex-2015.xsd +0 -8
  815. package/skills/documents/docx/scripts/office/soffice.py +0 -183
  816. package/skills/documents/docx/scripts/office/unpack.py +0 -132
  817. package/skills/documents/docx/scripts/office/validate.py +0 -111
  818. package/skills/documents/docx/scripts/office/validators/__init__.py +0 -15
  819. package/skills/documents/docx/scripts/office/validators/base.py +0 -847
  820. package/skills/documents/docx/scripts/office/validators/docx.py +0 -446
  821. package/skills/documents/docx/scripts/office/validators/pptx.py +0 -275
  822. package/skills/documents/docx/scripts/office/validators/redlining.py +0 -247
  823. package/skills/documents/docx/scripts/templates/comments.xml +0 -3
  824. package/skills/documents/docx/scripts/templates/commentsExtended.xml +0 -3
  825. package/skills/documents/docx/scripts/templates/commentsExtensible.xml +0 -3
  826. package/skills/documents/docx/scripts/templates/commentsIds.xml +0 -3
  827. package/skills/documents/docx/scripts/templates/people.xml +0 -3
  828. package/skills/documents/pdf/LICENSE.txt +0 -30
  829. package/skills/documents/pdf/SKILL-zh.md +0 -314
  830. package/skills/documents/pdf/SKILL.md +0 -314
  831. package/skills/documents/pdf/forms.md +0 -294
  832. package/skills/documents/pdf/reference.md +0 -612
  833. package/skills/documents/pdf/scripts/check_bounding_boxes.py +0 -65
  834. package/skills/documents/pdf/scripts/check_fillable_fields.py +0 -11
  835. package/skills/documents/pdf/scripts/convert_pdf_to_images.py +0 -33
  836. package/skills/documents/pdf/scripts/create_validation_image.py +0 -37
  837. package/skills/documents/pdf/scripts/extract_form_field_info.py +0 -122
  838. package/skills/documents/pdf/scripts/extract_form_structure.py +0 -115
  839. package/skills/documents/pdf/scripts/fill_fillable_fields.py +0 -98
  840. package/skills/documents/pdf/scripts/fill_pdf_form_with_annotations.py +0 -107
  841. package/skills/documents/pptx/LICENSE.txt +0 -30
  842. package/skills/documents/pptx/SKILL-zh.md +0 -232
  843. package/skills/documents/pptx/SKILL.md +0 -232
  844. package/skills/documents/pptx/editing.md +0 -205
  845. package/skills/documents/pptx/pptxgenjs.md +0 -420
  846. package/skills/documents/pptx/scripts/__init__.py +0 -0
  847. package/skills/documents/pptx/scripts/add_slide.py +0 -195
  848. package/skills/documents/pptx/scripts/clean.py +0 -286
  849. package/skills/documents/pptx/scripts/office/helpers/__init__.py +0 -0
  850. package/skills/documents/pptx/scripts/office/helpers/merge_runs.py +0 -199
  851. package/skills/documents/pptx/scripts/office/helpers/simplify_redlines.py +0 -197
  852. package/skills/documents/pptx/scripts/office/pack.py +0 -159
  853. package/skills/documents/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-chart.xsd +0 -1499
  854. package/skills/documents/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-chartDrawing.xsd +0 -146
  855. package/skills/documents/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-diagram.xsd +0 -1085
  856. package/skills/documents/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-lockedCanvas.xsd +0 -11
  857. package/skills/documents/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-main.xsd +0 -3081
  858. package/skills/documents/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-picture.xsd +0 -23
  859. package/skills/documents/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-spreadsheetDrawing.xsd +0 -185
  860. package/skills/documents/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-wordprocessingDrawing.xsd +0 -287
  861. package/skills/documents/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/pml.xsd +0 -1676
  862. package/skills/documents/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-additionalCharacteristics.xsd +0 -28
  863. package/skills/documents/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-bibliography.xsd +0 -144
  864. package/skills/documents/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-commonSimpleTypes.xsd +0 -174
  865. package/skills/documents/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-customXmlDataProperties.xsd +0 -25
  866. package/skills/documents/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-customXmlSchemaProperties.xsd +0 -18
  867. package/skills/documents/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesCustom.xsd +0 -59
  868. package/skills/documents/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesExtended.xsd +0 -56
  869. package/skills/documents/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesVariantTypes.xsd +0 -195
  870. package/skills/documents/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-math.xsd +0 -582
  871. package/skills/documents/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-relationshipReference.xsd +0 -25
  872. package/skills/documents/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/sml.xsd +0 -4439
  873. package/skills/documents/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-main.xsd +0 -570
  874. package/skills/documents/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-officeDrawing.xsd +0 -509
  875. package/skills/documents/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-presentationDrawing.xsd +0 -12
  876. package/skills/documents/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-spreadsheetDrawing.xsd +0 -108
  877. package/skills/documents/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-wordprocessingDrawing.xsd +0 -96
  878. package/skills/documents/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/wml.xsd +0 -3646
  879. package/skills/documents/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/xml.xsd +0 -116
  880. package/skills/documents/pptx/scripts/office/schemas/ecma/fouth-edition/opc-contentTypes.xsd +0 -42
  881. package/skills/documents/pptx/scripts/office/schemas/ecma/fouth-edition/opc-coreProperties.xsd +0 -50
  882. package/skills/documents/pptx/scripts/office/schemas/ecma/fouth-edition/opc-digSig.xsd +0 -49
  883. package/skills/documents/pptx/scripts/office/schemas/ecma/fouth-edition/opc-relationships.xsd +0 -33
  884. package/skills/documents/pptx/scripts/office/schemas/mce/mc.xsd +0 -75
  885. package/skills/documents/pptx/scripts/office/schemas/microsoft/wml-2010.xsd +0 -560
  886. package/skills/documents/pptx/scripts/office/schemas/microsoft/wml-2012.xsd +0 -67
  887. package/skills/documents/pptx/scripts/office/schemas/microsoft/wml-2018.xsd +0 -14
  888. package/skills/documents/pptx/scripts/office/schemas/microsoft/wml-cex-2018.xsd +0 -20
  889. package/skills/documents/pptx/scripts/office/schemas/microsoft/wml-cid-2016.xsd +0 -13
  890. package/skills/documents/pptx/scripts/office/schemas/microsoft/wml-sdtdatahash-2020.xsd +0 -4
  891. package/skills/documents/pptx/scripts/office/schemas/microsoft/wml-symex-2015.xsd +0 -8
  892. package/skills/documents/pptx/scripts/office/soffice.py +0 -183
  893. package/skills/documents/pptx/scripts/office/unpack.py +0 -132
  894. package/skills/documents/pptx/scripts/office/validate.py +0 -111
  895. package/skills/documents/pptx/scripts/office/validators/__init__.py +0 -15
  896. package/skills/documents/pptx/scripts/office/validators/base.py +0 -847
  897. package/skills/documents/pptx/scripts/office/validators/docx.py +0 -446
  898. package/skills/documents/pptx/scripts/office/validators/pptx.py +0 -275
  899. package/skills/documents/pptx/scripts/office/validators/redlining.py +0 -247
  900. package/skills/documents/pptx/scripts/thumbnail.py +0 -289
  901. package/skills/documents/xlsx/SKILL-zh.md +0 -292
  902. package/skills/engineering/diagnose/SKILL-zh.md +0 -117
  903. package/skills/engineering/grill-with-docs/ADR-FORMAT.md +0 -47
  904. package/skills/engineering/grill-with-docs/CONTEXT-FORMAT.md +0 -77
  905. package/skills/engineering/grill-with-docs/SKILL-zh.md +0 -88
  906. package/skills/engineering/grill-with-docs/SKILL.md +0 -88
  907. package/skills/engineering/improve-codebase-architecture/DEEPENING.md +0 -37
  908. package/skills/engineering/improve-codebase-architecture/INTERFACE-DESIGN.md +0 -44
  909. package/skills/engineering/improve-codebase-architecture/LANGUAGE.md +0 -53
  910. package/skills/engineering/improve-codebase-architecture/SKILL-zh.md +0 -71
  911. package/skills/engineering/improve-codebase-architecture/SKILL.md +0 -71
  912. package/skills/engineering/tdd/SKILL-zh.md +0 -109
  913. package/skills/engineering/to-issues/SKILL-zh.md +0 -81
  914. package/skills/engineering/to-issues/SKILL.md +0 -81
  915. package/skills/engineering/to-prd/SKILL-zh.md +0 -76
  916. package/skills/engineering/to-prd/SKILL.md +0 -74
  917. package/skills/engineering/zoom-out/SKILL-zh.md +0 -7
  918. package/skills/engineering/zoom-out/SKILL.md +0 -7
  919. package/skills/tools/find-skills/SKILL-zh.md +0 -440
  920. package/skills/tools/github/SKILL-zh.md +0 -48
  921. package/skills/tools/internal-comms/LICENSE.txt +0 -202
  922. package/skills/tools/internal-comms/SKILL-zh.md +0 -32
  923. package/skills/tools/internal-comms/SKILL.md +0 -32
  924. package/skills/tools/internal-comms/examples/3p-updates.md +0 -47
  925. package/skills/tools/internal-comms/examples/company-newsletter.md +0 -65
  926. package/skills/tools/internal-comms/examples/faq-answers.md +0 -30
  927. package/skills/tools/internal-comms/examples/general-comms.md +0 -16
  928. package/skills/tools/skill-creator/LICENSE.txt +0 -202
  929. package/skills/tools/skill-creator/SKILL-zh.md +0 -483
  930. package/skills/tools/skill-creator/SKILL.md +0 -485
  931. package/skills/tools/skill-creator/agents/analyzer.md +0 -274
  932. package/skills/tools/skill-creator/agents/comparator.md +0 -202
  933. package/skills/tools/skill-creator/agents/grader.md +0 -223
  934. package/skills/tools/skill-creator/assets/eval_review.html +0 -146
  935. package/skills/tools/skill-creator/eval-viewer/generate_review.py +0 -471
  936. package/skills/tools/skill-creator/eval-viewer/viewer.html +0 -1325
  937. package/skills/tools/skill-creator/references/schemas.md +0 -430
  938. package/skills/tools/skill-creator/scripts/__init__.py +0 -0
  939. package/skills/tools/skill-creator/scripts/aggregate_benchmark.py +0 -401
  940. package/skills/tools/skill-creator/scripts/generate_report.py +0 -326
  941. package/skills/tools/skill-creator/scripts/improve_description.py +0 -247
  942. package/skills/tools/skill-creator/scripts/package_skill.py +0 -136
  943. package/skills/tools/skill-creator/scripts/quick_validate.py +0 -103
  944. package/skills/tools/skill-creator/scripts/run_eval.py +0 -310
  945. package/skills/tools/skill-creator/scripts/run_loop.py +0 -328
  946. package/skills/tools/skill-creator/scripts/utils.py +0 -47
  947. package/skills/tools/summarize/SKILL-zh.md +0 -47
  948. package/skills/tools/weather/SKILL-zh.md +0 -46
  949. package/skills/tools/weather/SKILL.md +0 -46
  950. package/skills/tools/webapp-testing/SKILL-zh.md +0 -96
@@ -1 +1 @@
1
- {"version":3,"file":"credentials.js","names":[],"sources":["../../../src/auth/credentials.ts"],"sourcesContent":["import { readFile, mkdir, rm, readdir } from 'fs/promises';\nimport { writeTextAtomic } from '../infra/write-file-atomic.js';\nimport { join, dirname } from 'path';\nimport { createLogger } from '../utils/logger.js';\nimport { getApiKeyFromEnv } from '../providers/env-keys.js';\nimport {\n resolveCredentialsDir,\n resolveAuthProfilesPath,\n resolveAgentAuthProfilesPath,\n resolveOAuthPath,\n} from '../config/paths.js';\nimport type { Config } from '../config/schema.js';\n\nconst log = createLogger('Credentials');\n\n// ============================================\n// Types\n// ============================================\n\nexport type CredentialType = 'api_key' | 'oauth';\n\nexport interface ApiKeyProfile {\n type: 'api_key';\n provider: string;\n profileName?: string;\n envVar?: string | null;\n key: string | null;\n}\n\nexport interface OAuthToken {\n type: 'oauth';\n provider: string;\n access: string;\n refresh?: string;\n expiresAt?: number;\n scope?: string[];\n createdAt: string;\n updatedAt: string;\n}\n\nexport type CredentialProfile = ApiKeyProfile;\n\nexport interface AuthProfilesFile {\n version: number;\n profiles: Record<string, ApiKeyProfile>;\n}\n\n// ============================================\n// Credential Resolver\n// ============================================\n\nexport interface CredentialResolverOptions {\n stateDir?: string;\n /** When set, per-agent auth profiles are read from `resolveAgentAuthProfilesPath(appConfig, agentId)`. */\n agentId?: string;\n /** Required when `agentId` is set. */\n appConfig?: Config;\n}\n\nexport class CredentialResolver {\n private readonly credentialsDir: string;\n private readonly agentId?: string;\n private readonly appConfig?: Config;\n\n constructor(options: CredentialResolverOptions = {}) {\n this.credentialsDir = options.stateDir\n ? join(options.stateDir, 'credentials')\n : resolveCredentialsDir();\n this.agentId = options.agentId;\n this.appConfig = options.appConfig;\n if (this.agentId && !this.appConfig) {\n throw new Error('CredentialResolver: appConfig is required when agentId is set');\n }\n }\n\n /**\n * Resolve API key for a provider\n * Priority: Agent private > Global > OAuth > Environment\n */\n async resolveApiKey(provider: string): Promise<string | null> {\n const normalizedProvider = provider.toLowerCase();\n\n // 1. Try agent private credentials\n if (this.agentId) {\n const agentKey = await this.loadFromAgentCredentials(normalizedProvider);\n if (agentKey) {\n log.debug({ provider, source: 'agent' }, 'Resolved API key from agent credentials');\n return agentKey;\n }\n }\n\n // 2. Try global credentials\n const globalKey = await this.loadFromGlobalCredentials(normalizedProvider);\n if (globalKey) {\n log.debug({ provider, source: 'global' }, 'Resolved API key from global credentials');\n return globalKey;\n }\n\n // 3. Try OAuth token (convert to Bearer)\n const oauthToken = await this.loadOAuthToken(normalizedProvider);\n if (oauthToken) {\n log.debug({ provider, source: 'oauth' }, 'Resolved API key from OAuth token');\n return oauthToken.access;\n }\n\n // 4. Environment variables (see `src/providers/env-keys.ts`)\n const envKey = getApiKeyFromEnv(normalizedProvider);\n if (envKey) {\n log.debug({ provider, source: 'env' }, 'Resolved API key from environment');\n return envKey;\n }\n\n return null;\n }\n\n /**\n * Check if a provider has credentials configured\n */\n async hasCredentials(provider: string): Promise<boolean> {\n const key = await this.resolveApiKey(provider);\n return key !== null;\n }\n\n /**\n * Which step in {@link resolveApiKey} would supply the key (no secret material).\n */\n async resolveApiKeySource(\n provider: string,\n ): Promise<'agent' | 'global' | 'oauth' | 'env' | null> {\n const normalizedProvider = provider.toLowerCase();\n\n if (this.agentId) {\n const agentKey = await this.loadFromAgentCredentials(normalizedProvider);\n if (agentKey) return 'agent';\n }\n\n const globalKey = await this.loadFromGlobalCredentials(normalizedProvider);\n if (globalKey) return 'global';\n\n const oauthToken = await this.loadOAuthToken(normalizedProvider);\n if (oauthToken) return 'oauth';\n\n if (getApiKeyFromEnv(normalizedProvider)) return 'env';\n\n return null;\n }\n\n /**\n * List all available credential profiles\n */\n async listProfiles(): Promise<Array<ApiKeyProfile & { id: string; source: 'agent' | 'global' }>> {\n const profiles: Array<ApiKeyProfile & { id: string; source: 'agent' | 'global' }> = [];\n\n // Global profiles\n const globalProfiles = await this.loadAuthProfilesFile();\n for (const [id, profile] of Object.entries(globalProfiles.profiles)) {\n profiles.push({ ...profile, id, source: 'global' });\n }\n\n // Agent private profiles\n if (this.agentId) {\n const agentProfiles = await this.loadAgentAuthProfilesFile();\n for (const [id, profile] of Object.entries(agentProfiles.profiles)) {\n profiles.push({ ...profile, id, source: 'agent' });\n }\n }\n\n return profiles;\n }\n\n /**\n * Plaintext API key from global auth profiles only (no env/oauth fallback).\n * Used by the gateway console reveal endpoint.\n */\n async revealGatewayStoredApiKey(provider: string): Promise<string | null> {\n const normalizedProvider = provider.toLowerCase();\n const profiles = await this.loadAuthProfilesFile();\n const profile = this.findProfileForProvider(profiles, normalizedProvider);\n const key = profile?.key?.trim();\n return key || null;\n }\n\n /**\n * Save an API key profile\n */\n async saveApiKey(\n provider: string,\n key: string,\n options: {\n profileName?: string;\n envVar?: string | null;\n agentPrivate?: boolean;\n } = {}\n ): Promise<void> {\n const normalizedProvider = provider.toLowerCase();\n const profileId = options.profileName\n ? `${normalizedProvider}:${options.profileName}`\n : `${normalizedProvider}:default`;\n\n const profile: ApiKeyProfile = {\n type: 'api_key',\n provider: normalizedProvider,\n profileName: options.profileName,\n envVar: options.envVar ?? null,\n key,\n };\n\n if (options.agentPrivate && this.agentId) {\n await this.saveAgentAuthProfile(profileId, profile);\n } else {\n await this.saveGlobalAuthProfile(profileId, profile);\n }\n\n log.info({ provider, profileId, agentPrivate: options.agentPrivate }, 'Saved API key');\n }\n\n /**\n * Delete a credential profile\n */\n async deleteProfile(profileId: string, options: { agentPrivate?: boolean } = {}): Promise<void> {\n if (options.agentPrivate && this.agentId) {\n await this.deleteAgentAuthProfile(profileId);\n } else {\n await this.deleteGlobalAuthProfile(profileId);\n }\n\n log.info({ profileId, agentPrivate: options.agentPrivate }, 'Deleted credential profile');\n }\n\n /**\n * Load OAuth token for a provider.\n */\n async loadOAuthToken(provider: string): Promise<OAuthToken | null> {\n const token = await this.loadOAuthTokenRecord(provider);\n if (!token) return null;\n\n if (token.expiresAt && token.expiresAt < Date.now()) {\n log.warn({ provider, expiresAt: token.expiresAt }, 'OAuth token is expired');\n return null;\n }\n\n return token;\n }\n\n /**\n * Load the raw OAuth token record, including expired tokens for status UIs.\n */\n async loadOAuthTokenRecord(provider: string): Promise<OAuthToken | null> {\n const normalizedProvider = provider.toLowerCase();\n const oauthPath = resolveOAuthPath(normalizedProvider);\n\n try {\n const content = await readFile(oauthPath, 'utf-8');\n const token = JSON.parse(content) as OAuthToken;\n return token.provider === normalizedProvider ? token : null;\n } catch {\n return null;\n }\n }\n\n /**\n * List persisted OAuth tokens without exposing access/refresh values.\n */\n async listOAuthTokens(): Promise<Array<Omit<OAuthToken, 'access' | 'refresh'> & { hasAccess: boolean; hasRefresh: boolean }>> {\n const oauthDir = join(this.credentialsDir, 'oauth');\n let files: string[];\n try {\n files = await readdir(oauthDir);\n } catch {\n return [];\n }\n\n const tokens: Array<Omit<OAuthToken, 'access' | 'refresh'> & { hasAccess: boolean; hasRefresh: boolean }> = [];\n for (const file of files) {\n if (!file.endsWith('.json')) continue;\n try {\n const content = await readFile(join(oauthDir, file), 'utf-8');\n const token = JSON.parse(content) as OAuthToken;\n if (token.type !== 'oauth' || !token.provider) continue;\n const { access, refresh, ...safe } = token;\n tokens.push({ ...safe, hasAccess: Boolean(access?.trim()), hasRefresh: Boolean(refresh?.trim()) });\n } catch {\n continue;\n }\n }\n return tokens.sort((a, b) => a.provider.localeCompare(b.provider));\n }\n\n /**\n * Save OAuth token for a provider.\n */\n async saveOAuthToken(provider: string, token: Omit<OAuthToken, 'type' | 'provider' | 'updatedAt'>): Promise<void> {\n const normalizedProvider = provider.toLowerCase();\n const oauthPath = resolveOAuthPath(normalizedProvider);\n\n await mkdir(dirname(oauthPath), { recursive: true });\n\n const fullToken: OAuthToken = {\n ...token,\n type: 'oauth',\n provider: normalizedProvider,\n updatedAt: new Date().toISOString(),\n };\n\n await writeTextAtomic(oauthPath, JSON.stringify(fullToken, null, 2));\n log.info({ provider: normalizedProvider }, 'Saved OAuth token');\n }\n\n /**\n * Delete the OAuth token persisted for a provider.\n */\n async deleteOAuthToken(provider: string): Promise<void> {\n const normalizedProvider = provider.toLowerCase();\n const oauthPath = resolveOAuthPath(normalizedProvider);\n await rm(oauthPath, { force: true });\n log.info({ provider: normalizedProvider }, 'Deleted OAuth token');\n }\n\n /**\n * Disconnect the default credential for a provider from local storage.\n */\n async deleteProviderCredential(provider: string): Promise<void> {\n const normalizedProvider = provider.toLowerCase();\n const file = await this.loadAuthProfilesFile();\n await mkdir(dirname(resolveAuthProfilesPath()), { recursive: true });\n for (const [profileId, profile] of Object.entries(file.profiles)) {\n if (profile.provider === normalizedProvider) {\n delete file.profiles[profileId];\n }\n }\n await writeTextAtomic(resolveAuthProfilesPath(), JSON.stringify(file, null, 2));\n await this.deleteOAuthToken(normalizedProvider);\n }\n\n // ============================================\n // Private Methods\n // ============================================\n\n private async loadFromAgentCredentials(provider: string): Promise<string | null> {\n if (!this.agentId) return null;\n\n const profiles = await this.loadAgentAuthProfilesFile();\n const profile = this.findProfileForProvider(profiles, provider);\n\n if (!profile) return null;\n if (profile.envVar) return this.loadFromEnv(profile.envVar) ?? profile.key;\n return profile.key;\n }\n\n private async loadFromGlobalCredentials(provider: string): Promise<string | null> {\n const profiles = await this.loadAuthProfilesFile();\n const profile = this.findProfileForProvider(profiles, provider);\n\n if (!profile) return null;\n if (profile.envVar) return this.loadFromEnv(profile.envVar) ?? profile.key;\n return profile.key;\n }\n\n private loadFromEnv(envVarName: string): string | null {\n return process.env[envVarName] || null;\n }\n\n private findProfileForProvider(\n file: AuthProfilesFile,\n provider: string\n ): ApiKeyProfile | null {\n const normalizedProvider = provider.toLowerCase();\n\n // Look for exact match first\n for (const [, profile] of Object.entries(file.profiles)) {\n if (profile.provider === normalizedProvider) {\n return profile;\n }\n }\n\n return null;\n }\n\n private async loadAuthProfilesFile(): Promise<AuthProfilesFile> {\n const path = resolveAuthProfilesPath();\n\n try {\n const content = await readFile(path, 'utf-8');\n const data = JSON.parse(content);\n return {\n version: data.version || 1,\n profiles: data.profiles || {},\n };\n } catch {\n return { version: 2, profiles: {} };\n }\n }\n\n private async loadAgentAuthProfilesFile(): Promise<AuthProfilesFile> {\n if (!this.agentId || !this.appConfig) return { version: 2, profiles: {} };\n\n const path = resolveAgentAuthProfilesPath(this.appConfig, this.agentId);\n\n try {\n const content = await readFile(path, 'utf-8');\n const data = JSON.parse(content);\n return {\n version: data.version || 1,\n profiles: data.profiles || {},\n };\n } catch {\n return { version: 2, profiles: {} };\n }\n }\n\n private async saveGlobalAuthProfile(profileId: string, profile: ApiKeyProfile): Promise<void> {\n const path = resolveAuthProfilesPath();\n await mkdir(dirname(path), { recursive: true });\n\n const file = await this.loadAuthProfilesFile();\n file.profiles[profileId] = profile;\n\n await writeTextAtomic(path, JSON.stringify(file, null, 2));\n }\n\n private async saveAgentAuthProfile(profileId: string, profile: ApiKeyProfile): Promise<void> {\n if (!this.agentId || !this.appConfig) throw new Error('Agent ID and appConfig required for agent-private profiles');\n\n const path = resolveAgentAuthProfilesPath(this.appConfig, this.agentId);\n await mkdir(dirname(path), { recursive: true });\n\n const file = await this.loadAgentAuthProfilesFile();\n file.profiles[profileId] = profile;\n\n await writeTextAtomic(path, JSON.stringify(file, null, 2));\n }\n\n private async deleteGlobalAuthProfile(profileId: string): Promise<void> {\n const path = resolveAuthProfilesPath();\n const file = await this.loadAuthProfilesFile();\n\n delete file.profiles[profileId];\n\n await writeTextAtomic(path, JSON.stringify(file, null, 2));\n }\n\n private async deleteAgentAuthProfile(profileId: string): Promise<void> {\n if (!this.agentId || !this.appConfig) throw new Error('Agent ID and appConfig required for agent-private profiles');\n\n const path = resolveAgentAuthProfilesPath(this.appConfig, this.agentId);\n const file = await this.loadAgentAuthProfilesFile();\n\n delete file.profiles[profileId];\n\n await writeTextAtomic(path, JSON.stringify(file, null, 2));\n }\n}\n\n// ============================================\n// Convenience Functions\n// ============================================\n\nlet defaultResolver: CredentialResolver | null = null;\n\nexport function getCredentialResolver(options?: CredentialResolverOptions): CredentialResolver {\n if (!defaultResolver || options) {\n return new CredentialResolver(options);\n }\n return defaultResolver;\n}\n\nexport async function resolveApiKey(provider: string, options?: CredentialResolverOptions): Promise<string | null> {\n const resolver = getCredentialResolver(options);\n return resolver.resolveApiKey(provider);\n}\n\nexport async function hasCredentials(provider: string, options?: CredentialResolverOptions): Promise<boolean> {\n const resolver = getCredentialResolver(options);\n return resolver.hasCredentials(provider);\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"credentials.js","names":[],"sources":["../../../src/auth/credentials.ts"],"sourcesContent":["import { readFile, mkdir, rm, readdir } from 'fs/promises';\nimport { writeTextAtomic } from '../infra/write-file-atomic.js';\nimport { join, dirname } from 'path';\nimport { createLogger } from '../utils/logger.js';\nimport { getApiKeyFromEnv } from '../providers/env-keys.js';\nimport {\n resolveCredentialsDir,\n resolveAuthProfilesPath,\n resolveAgentAuthProfilesPath,\n resolveOAuthPath,\n} from '../config/paths.js';\nimport type { Config } from '../config/schema.js';\n\nconst log = createLogger('Credentials');\nconst warnedExpiredOAuthTokens = new Set<string>();\n\n// ============================================\n// Types\n// ============================================\n\nexport type CredentialType = 'api_key' | 'oauth';\n\nexport interface ApiKeyProfile {\n type: 'api_key';\n provider: string;\n profileName?: string;\n envVar?: string | null;\n key: string | null;\n}\n\nexport interface OAuthToken {\n type: 'oauth';\n provider: string;\n access: string;\n refresh?: string;\n expiresAt?: number;\n scope?: string[];\n createdAt: string;\n updatedAt: string;\n}\n\nexport type CredentialProfile = ApiKeyProfile;\n\nexport interface AuthProfilesFile {\n version: number;\n profiles: Record<string, ApiKeyProfile>;\n}\n\n// ============================================\n// Credential Resolver\n// ============================================\n\nexport interface CredentialResolverOptions {\n stateDir?: string;\n /** When set, per-agent auth profiles are read from `resolveAgentAuthProfilesPath(appConfig, agentId)`. */\n agentId?: string;\n /** Required when `agentId` is set. */\n appConfig?: Config;\n}\n\nexport class CredentialResolver {\n private readonly credentialsDir: string;\n private readonly agentId?: string;\n private readonly appConfig?: Config;\n\n constructor(options: CredentialResolverOptions = {}) {\n this.credentialsDir = options.stateDir\n ? join(options.stateDir, 'credentials')\n : resolveCredentialsDir();\n this.agentId = options.agentId;\n this.appConfig = options.appConfig;\n if (this.agentId && !this.appConfig) {\n throw new Error('CredentialResolver: appConfig is required when agentId is set');\n }\n }\n\n /**\n * Resolve API key for a provider\n * Priority: Agent private > Global > OAuth > Environment\n */\n async resolveApiKey(provider: string): Promise<string | null> {\n const normalizedProvider = provider.toLowerCase();\n\n // 1. Try agent private credentials\n if (this.agentId) {\n const agentKey = await this.loadFromAgentCredentials(normalizedProvider);\n if (agentKey) {\n log.debug({ provider, source: 'agent' }, 'Resolved API key from agent credentials');\n return agentKey;\n }\n }\n\n // 2. Try global credentials\n const globalKey = await this.loadFromGlobalCredentials(normalizedProvider);\n if (globalKey) {\n log.debug({ provider, source: 'global' }, 'Resolved API key from global credentials');\n return globalKey;\n }\n\n // 3. Try OAuth token (convert to Bearer)\n const oauthToken = await this.loadOAuthToken(normalizedProvider);\n if (oauthToken) {\n log.debug({ provider, source: 'oauth' }, 'Resolved API key from OAuth token');\n return oauthToken.access;\n }\n\n // 4. Environment variables (see `src/providers/env-keys.ts`)\n const envKey = getApiKeyFromEnv(normalizedProvider);\n if (envKey) {\n log.debug({ provider, source: 'env' }, 'Resolved API key from environment');\n return envKey;\n }\n\n return null;\n }\n\n /**\n * Check if a provider has credentials configured\n */\n async hasCredentials(provider: string): Promise<boolean> {\n const key = await this.resolveApiKey(provider);\n return key !== null;\n }\n\n /**\n * Which step in {@link resolveApiKey} would supply the key (no secret material).\n */\n async resolveApiKeySource(\n provider: string,\n ): Promise<'agent' | 'global' | 'oauth' | 'env' | null> {\n const normalizedProvider = provider.toLowerCase();\n\n if (this.agentId) {\n const agentKey = await this.loadFromAgentCredentials(normalizedProvider);\n if (agentKey) return 'agent';\n }\n\n const globalKey = await this.loadFromGlobalCredentials(normalizedProvider);\n if (globalKey) return 'global';\n\n const oauthToken = await this.loadOAuthToken(normalizedProvider);\n if (oauthToken) return 'oauth';\n\n if (getApiKeyFromEnv(normalizedProvider)) return 'env';\n\n return null;\n }\n\n /**\n * List all available credential profiles\n */\n async listProfiles(): Promise<Array<ApiKeyProfile & { id: string; source: 'agent' | 'global' }>> {\n const profiles: Array<ApiKeyProfile & { id: string; source: 'agent' | 'global' }> = [];\n\n // Global profiles\n const globalProfiles = await this.loadAuthProfilesFile();\n for (const [id, profile] of Object.entries(globalProfiles.profiles)) {\n profiles.push({ ...profile, id, source: 'global' });\n }\n\n // Agent private profiles\n if (this.agentId) {\n const agentProfiles = await this.loadAgentAuthProfilesFile();\n for (const [id, profile] of Object.entries(agentProfiles.profiles)) {\n profiles.push({ ...profile, id, source: 'agent' });\n }\n }\n\n return profiles;\n }\n\n /**\n * Plaintext API key from global auth profiles only (no env/oauth fallback).\n * Used by the gateway console reveal endpoint.\n */\n async revealGatewayStoredApiKey(provider: string): Promise<string | null> {\n const normalizedProvider = provider.toLowerCase();\n const profiles = await this.loadAuthProfilesFile();\n const profile = this.findProfileForProvider(profiles, normalizedProvider);\n const key = profile?.key?.trim();\n return key || null;\n }\n\n /**\n * Save an API key profile\n */\n async saveApiKey(\n provider: string,\n key: string,\n options: {\n profileName?: string;\n envVar?: string | null;\n agentPrivate?: boolean;\n } = {}\n ): Promise<void> {\n const normalizedProvider = provider.toLowerCase();\n const profileId = options.profileName\n ? `${normalizedProvider}:${options.profileName}`\n : `${normalizedProvider}:default`;\n\n const profile: ApiKeyProfile = {\n type: 'api_key',\n provider: normalizedProvider,\n profileName: options.profileName,\n envVar: options.envVar ?? null,\n key,\n };\n\n if (options.agentPrivate && this.agentId) {\n await this.saveAgentAuthProfile(profileId, profile);\n } else {\n await this.saveGlobalAuthProfile(profileId, profile);\n }\n\n log.info({ provider, profileId, agentPrivate: options.agentPrivate }, 'Saved API key');\n }\n\n /**\n * Delete a credential profile\n */\n async deleteProfile(profileId: string, options: { agentPrivate?: boolean } = {}): Promise<void> {\n if (options.agentPrivate && this.agentId) {\n await this.deleteAgentAuthProfile(profileId);\n } else {\n await this.deleteGlobalAuthProfile(profileId);\n }\n\n log.info({ profileId, agentPrivate: options.agentPrivate }, 'Deleted credential profile');\n }\n\n /**\n * Load OAuth token for a provider.\n */\n async loadOAuthToken(provider: string): Promise<OAuthToken | null> {\n const token = await this.loadOAuthTokenRecord(provider);\n if (!token) return null;\n\n if (token.expiresAt && token.expiresAt < Date.now()) {\n const warnKey = `${provider}:${token.expiresAt}`;\n if (!warnedExpiredOAuthTokens.has(warnKey)) {\n warnedExpiredOAuthTokens.add(warnKey);\n log.warn({ provider, expiresAt: token.expiresAt }, 'OAuth token is expired');\n }\n return null;\n }\n\n return token;\n }\n\n /**\n * Load the raw OAuth token record, including expired tokens for status UIs.\n */\n async loadOAuthTokenRecord(provider: string): Promise<OAuthToken | null> {\n const normalizedProvider = provider.toLowerCase();\n const oauthPath = resolveOAuthPath(normalizedProvider);\n\n try {\n const content = await readFile(oauthPath, 'utf-8');\n const token = JSON.parse(content) as OAuthToken;\n return token.provider === normalizedProvider ? token : null;\n } catch {\n return null;\n }\n }\n\n /**\n * List persisted OAuth tokens without exposing access/refresh values.\n */\n async listOAuthTokens(): Promise<Array<Omit<OAuthToken, 'access' | 'refresh'> & { hasAccess: boolean; hasRefresh: boolean }>> {\n const oauthDir = join(this.credentialsDir, 'oauth');\n let files: string[];\n try {\n files = await readdir(oauthDir);\n } catch {\n return [];\n }\n\n const tokens: Array<Omit<OAuthToken, 'access' | 'refresh'> & { hasAccess: boolean; hasRefresh: boolean }> = [];\n for (const file of files) {\n if (!file.endsWith('.json')) continue;\n try {\n const content = await readFile(join(oauthDir, file), 'utf-8');\n const token = JSON.parse(content) as OAuthToken;\n if (token.type !== 'oauth' || !token.provider) continue;\n const { access, refresh, ...safe } = token;\n tokens.push({ ...safe, hasAccess: Boolean(access?.trim()), hasRefresh: Boolean(refresh?.trim()) });\n } catch {\n continue;\n }\n }\n return tokens.sort((a, b) => a.provider.localeCompare(b.provider));\n }\n\n /**\n * Save OAuth token for a provider.\n */\n async saveOAuthToken(provider: string, token: Omit<OAuthToken, 'type' | 'provider' | 'updatedAt'>): Promise<void> {\n const normalizedProvider = provider.toLowerCase();\n const oauthPath = resolveOAuthPath(normalizedProvider);\n\n await mkdir(dirname(oauthPath), { recursive: true });\n\n const fullToken: OAuthToken = {\n ...token,\n type: 'oauth',\n provider: normalizedProvider,\n updatedAt: new Date().toISOString(),\n };\n\n await writeTextAtomic(oauthPath, JSON.stringify(fullToken, null, 2));\n log.info({ provider: normalizedProvider }, 'Saved OAuth token');\n }\n\n /**\n * Delete the OAuth token persisted for a provider.\n */\n async deleteOAuthToken(provider: string): Promise<void> {\n const normalizedProvider = provider.toLowerCase();\n const oauthPath = resolveOAuthPath(normalizedProvider);\n await rm(oauthPath, { force: true });\n log.info({ provider: normalizedProvider }, 'Deleted OAuth token');\n }\n\n /**\n * Disconnect the default credential for a provider from local storage.\n */\n async deleteProviderCredential(provider: string): Promise<void> {\n const normalizedProvider = provider.toLowerCase();\n const file = await this.loadAuthProfilesFile();\n await mkdir(dirname(resolveAuthProfilesPath()), { recursive: true });\n for (const [profileId, profile] of Object.entries(file.profiles)) {\n if (profile.provider === normalizedProvider) {\n delete file.profiles[profileId];\n }\n }\n await writeTextAtomic(resolveAuthProfilesPath(), JSON.stringify(file, null, 2));\n await this.deleteOAuthToken(normalizedProvider);\n }\n\n // ============================================\n // Private Methods\n // ============================================\n\n private async loadFromAgentCredentials(provider: string): Promise<string | null> {\n if (!this.agentId) return null;\n\n const profiles = await this.loadAgentAuthProfilesFile();\n const profile = this.findProfileForProvider(profiles, provider);\n\n if (!profile) return null;\n if (profile.envVar) return this.loadFromEnv(profile.envVar) ?? profile.key;\n return profile.key;\n }\n\n private async loadFromGlobalCredentials(provider: string): Promise<string | null> {\n const profiles = await this.loadAuthProfilesFile();\n const profile = this.findProfileForProvider(profiles, provider);\n\n if (!profile) return null;\n if (profile.envVar) return this.loadFromEnv(profile.envVar) ?? profile.key;\n return profile.key;\n }\n\n private loadFromEnv(envVarName: string): string | null {\n return process.env[envVarName] || null;\n }\n\n private findProfileForProvider(\n file: AuthProfilesFile,\n provider: string\n ): ApiKeyProfile | null {\n const normalizedProvider = provider.toLowerCase();\n\n // Look for exact match first\n for (const [, profile] of Object.entries(file.profiles)) {\n if (profile.provider === normalizedProvider) {\n return profile;\n }\n }\n\n return null;\n }\n\n private async loadAuthProfilesFile(): Promise<AuthProfilesFile> {\n const path = resolveAuthProfilesPath();\n\n try {\n const content = await readFile(path, 'utf-8');\n const data = JSON.parse(content);\n return {\n version: data.version || 1,\n profiles: data.profiles || {},\n };\n } catch {\n return { version: 2, profiles: {} };\n }\n }\n\n private async loadAgentAuthProfilesFile(): Promise<AuthProfilesFile> {\n if (!this.agentId || !this.appConfig) return { version: 2, profiles: {} };\n\n const path = resolveAgentAuthProfilesPath(this.appConfig, this.agentId);\n\n try {\n const content = await readFile(path, 'utf-8');\n const data = JSON.parse(content);\n return {\n version: data.version || 1,\n profiles: data.profiles || {},\n };\n } catch {\n return { version: 2, profiles: {} };\n }\n }\n\n private async saveGlobalAuthProfile(profileId: string, profile: ApiKeyProfile): Promise<void> {\n const path = resolveAuthProfilesPath();\n await mkdir(dirname(path), { recursive: true });\n\n const file = await this.loadAuthProfilesFile();\n file.profiles[profileId] = profile;\n\n await writeTextAtomic(path, JSON.stringify(file, null, 2));\n }\n\n private async saveAgentAuthProfile(profileId: string, profile: ApiKeyProfile): Promise<void> {\n if (!this.agentId || !this.appConfig) throw new Error('Agent ID and appConfig required for agent-private profiles');\n\n const path = resolveAgentAuthProfilesPath(this.appConfig, this.agentId);\n await mkdir(dirname(path), { recursive: true });\n\n const file = await this.loadAgentAuthProfilesFile();\n file.profiles[profileId] = profile;\n\n await writeTextAtomic(path, JSON.stringify(file, null, 2));\n }\n\n private async deleteGlobalAuthProfile(profileId: string): Promise<void> {\n const path = resolveAuthProfilesPath();\n const file = await this.loadAuthProfilesFile();\n\n delete file.profiles[profileId];\n\n await writeTextAtomic(path, JSON.stringify(file, null, 2));\n }\n\n private async deleteAgentAuthProfile(profileId: string): Promise<void> {\n if (!this.agentId || !this.appConfig) throw new Error('Agent ID and appConfig required for agent-private profiles');\n\n const path = resolveAgentAuthProfilesPath(this.appConfig, this.agentId);\n const file = await this.loadAgentAuthProfilesFile();\n\n delete file.profiles[profileId];\n\n await writeTextAtomic(path, JSON.stringify(file, null, 2));\n }\n}\n\n// ============================================\n// Convenience Functions\n// ============================================\n\nlet defaultResolver: CredentialResolver | null = null;\n\nexport function getCredentialResolver(options?: CredentialResolverOptions): CredentialResolver {\n if (!defaultResolver || options) {\n return new CredentialResolver(options);\n }\n return defaultResolver;\n}\n\nexport async function resolveApiKey(provider: string, options?: CredentialResolverOptions): Promise<string | null> {\n const resolver = getCredentialResolver(options);\n return resolver.resolveApiKey(provider);\n}\n\nexport async function hasCredentials(provider: string, options?: CredentialResolverOptions): Promise<boolean> {\n const resolver = getCredentialResolver(options);\n return resolver.hasCredentials(provider);\n}\n"],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ import type { Config } from '../../config/schema.js';
2
+ import type { ExtensionMetadataSnapshot } from '../../extensions/extension-metadata-snapshot.js';
3
+ import type { ChannelCatalog } from './channel-catalog-types.js';
4
+ type BuildChannelCatalogOptions = {
5
+ locale?: string;
6
+ };
7
+ export declare function buildChannelCatalogFromSnapshot(snapshot: ExtensionMetadataSnapshot, options?: BuildChannelCatalogOptions): ChannelCatalog;
8
+ export declare function buildChannelCatalogForConfig(config: Config, options?: BuildChannelCatalogOptions): ChannelCatalog;
9
+ export declare function isChannelConfigured(config: Config, channelId: string): boolean;
10
+ export declare function getConfiguredChannelIds(config: Config): string[];
11
+ export {};
@@ -0,0 +1,168 @@
1
+ import { __esmMin } from "../../../_virtual/_rolldown/runtime.js";
2
+ import { buildExtensionMetadataSnapshot, init_extension_metadata_snapshot, resolveExtensionLoaderOptionsFromConfig } from "../../extensions/extension-metadata-snapshot.js";
3
+ //#region src/channels/catalog/channel-catalog-service.ts
4
+ function normalizeChannelId(raw) {
5
+ return raw.trim().toLowerCase();
6
+ }
7
+ function normalizeLocale(raw) {
8
+ return raw?.trim().toLowerCase().replace("_", "-") || void 0;
9
+ }
10
+ function localeCandidates(raw) {
11
+ const locale = normalizeLocale(raw);
12
+ if (!locale) return [];
13
+ const base = locale.split("-")[0];
14
+ return base && base !== locale ? [locale, base] : [locale];
15
+ }
16
+ function normalizeConfigPath(channelId, raw) {
17
+ const expected = `channels.${channelId}`;
18
+ if (!raw) return expected;
19
+ const trimmed = raw.trim();
20
+ if (!trimmed.startsWith("channels.")) return expected;
21
+ return trimmed;
22
+ }
23
+ function isRecord(value) {
24
+ return typeof value === "object" && value !== null && !Array.isArray(value);
25
+ }
26
+ function hasNonEmptyString(value) {
27
+ return typeof value === "string" && value.trim().length > 0;
28
+ }
29
+ function hasConfiguredTelegramCredential(raw) {
30
+ if (!isRecord(raw)) return false;
31
+ const accounts = raw.accounts;
32
+ if (!isRecord(accounts)) return false;
33
+ return Object.values(accounts).some((account) => {
34
+ if (!isRecord(account) || account.enabled === false) return false;
35
+ return hasNonEmptyString(account.botToken) || hasNonEmptyString(account.tokenFile);
36
+ });
37
+ }
38
+ function hasConfiguredWeixinAccount(raw) {
39
+ if (!isRecord(raw)) return false;
40
+ if (raw.enabled === true) return true;
41
+ const accounts = raw.accounts;
42
+ if (!isRecord(accounts)) return false;
43
+ return Object.values(accounts).some((account) => isRecord(account) && account.enabled !== false);
44
+ }
45
+ function withoutUndefined(value) {
46
+ return Object.fromEntries(Object.entries(value).filter(([, item]) => item !== void 0));
47
+ }
48
+ function mergeObjectMap(base, override) {
49
+ if (!base && !override) return void 0;
50
+ if (!base) return override ? withoutUndefined(override) : void 0;
51
+ if (!override) return base;
52
+ const out = { ...base };
53
+ for (const [key, value] of Object.entries(override)) {
54
+ if (value === void 0) continue;
55
+ out[key] = isRecord(out[key]) && isRecord(value) ? {
56
+ ...out[key],
57
+ ...withoutUndefined(value)
58
+ } : value;
59
+ }
60
+ return out;
61
+ }
62
+ function mergeRecordDeep(base, override) {
63
+ const out = { ...base };
64
+ for (const [key, value] of Object.entries(override)) {
65
+ if (value === void 0) continue;
66
+ out[key] = isRecord(out[key]) && isRecord(value) ? mergeRecordDeep(out[key], value) : value;
67
+ }
68
+ return out;
69
+ }
70
+ function mergeJsonSchema(base, override) {
71
+ if (!base && !override) return void 0;
72
+ if (!base) return override ? withoutUndefined(override) : void 0;
73
+ if (!override) return base;
74
+ return mergeRecordDeep(base, override);
75
+ }
76
+ function mergeChannelUi(base, override) {
77
+ if (!base && !override) return void 0;
78
+ return {
79
+ ...base ?? {},
80
+ ...override ?? {},
81
+ card: mergeObjectMap(base?.card, override?.card),
82
+ modal: mergeObjectMap(base?.modal, override?.modal)
83
+ };
84
+ }
85
+ function localizeContribution(contribution, locale) {
86
+ const i18n = contribution.i18n;
87
+ if (!i18n) return contribution;
88
+ const override = localeCandidates(locale).map((key) => i18n[key]).find(Boolean);
89
+ if (!override) return contribution;
90
+ return {
91
+ ...contribution,
92
+ label: override.label ?? contribution.label,
93
+ description: override.description ?? contribution.description,
94
+ configSchema: mergeJsonSchema(contribution.configSchema, override.configSchema),
95
+ uiHints: mergeObjectMap(contribution.uiHints, override.uiHints),
96
+ actions: mergeObjectMap(contribution.actions, override.actions),
97
+ ui: mergeChannelUi(contribution.ui, override.ui)
98
+ };
99
+ }
100
+ function toCatalogEntry(params) {
101
+ const contribution = localizeContribution(params.contribution, params.locale);
102
+ const id = normalizeChannelId(params.channelId);
103
+ return {
104
+ id,
105
+ extensionId: params.extension.id,
106
+ source: params.extension.source,
107
+ path: params.extension.path,
108
+ label: contribution.label,
109
+ description: contribution.description,
110
+ docsPath: contribution.docsPath,
111
+ order: contribution.order ?? 999,
112
+ configPath: normalizeConfigPath(id, contribution.configPath),
113
+ capabilities: contribution.capabilities ?? {},
114
+ configSchema: contribution.configSchema ?? DEFAULT_CONFIG_SCHEMA,
115
+ uiHints: contribution.uiHints ?? {},
116
+ actions: contribution.actions ?? {},
117
+ ui: contribution.ui
118
+ };
119
+ }
120
+ function buildChannelCatalogFromSnapshot(snapshot, options = {}) {
121
+ const byId = /* @__PURE__ */ new Map();
122
+ for (const extension of snapshot.manifestRegistry.getAllEntries()) {
123
+ const contributions = extension.manifest.channelContributions ?? {};
124
+ for (const [channelId, contribution] of Object.entries(contributions)) {
125
+ const entry = toCatalogEntry({
126
+ extension,
127
+ channelId,
128
+ contribution,
129
+ locale: options.locale
130
+ });
131
+ byId.set(entry.id, entry);
132
+ }
133
+ }
134
+ return {
135
+ entries: Array.from(byId.values()).toSorted((a, b) => {
136
+ if (a.order !== b.order) return a.order - b.order;
137
+ return a.id.localeCompare(b.id);
138
+ }),
139
+ byId
140
+ };
141
+ }
142
+ function buildChannelCatalogForConfig(config, options = {}) {
143
+ return buildChannelCatalogFromSnapshot(buildExtensionMetadataSnapshot(resolveExtensionLoaderOptionsFromConfig(config), config), options);
144
+ }
145
+ function isChannelConfigured(config, channelId) {
146
+ const id = normalizeChannelId(channelId);
147
+ const raw = config.channels?.[id];
148
+ if (!raw) return false;
149
+ if (id === "telegram") return hasConfiguredTelegramCredential(raw);
150
+ if (id === "weixin") return hasConfiguredWeixinAccount(raw);
151
+ return isRecord(raw) ? raw.enabled === true || Object.keys(raw).length > 0 : true;
152
+ }
153
+ function getConfiguredChannelIds(config) {
154
+ return Object.keys(config.channels ?? {}).map(normalizeChannelId).filter((id) => id && isChannelConfigured(config, id));
155
+ }
156
+ var DEFAULT_CONFIG_SCHEMA;
157
+ var init_channel_catalog_service = __esmMin((() => {
158
+ init_extension_metadata_snapshot();
159
+ DEFAULT_CONFIG_SCHEMA = {
160
+ type: "object",
161
+ additionalProperties: true
162
+ };
163
+ }));
164
+ //#endregion
165
+ init_channel_catalog_service();
166
+ export { buildChannelCatalogForConfig, buildChannelCatalogFromSnapshot, getConfiguredChannelIds, init_channel_catalog_service, isChannelConfigured };
167
+
168
+ //# sourceMappingURL=channel-catalog-service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"channel-catalog-service.js","names":[],"sources":["../../../../src/channels/catalog/channel-catalog-service.ts"],"sourcesContent":["import type { Config } from '../../config/schema.js';\nimport {\n buildExtensionMetadataSnapshot,\n resolveExtensionLoaderOptionsFromConfig,\n} from '../../extensions/extension-metadata-snapshot.js';\nimport type { ExtensionMetadataSnapshot } from '../../extensions/extension-metadata-snapshot.js';\nimport type { ManifestRegistryEntry } from '../../extensions/manifest-registry.js';\nimport type { ChannelContributionDeclaration } from '../../extensions/types/manifest.js';\n\nimport type { ChannelCatalog, ChannelCatalogEntry } from './channel-catalog-types.js';\n\ntype BuildChannelCatalogOptions = {\n locale?: string;\n};\n\nconst DEFAULT_CONFIG_SCHEMA: Record<string, unknown> = {\n type: 'object',\n additionalProperties: true,\n};\n\nfunction normalizeChannelId(raw: string): string {\n return raw.trim().toLowerCase();\n}\n\nfunction normalizeLocale(raw: string | undefined): string | undefined {\n const value = raw?.trim().toLowerCase().replace('_', '-');\n return value || undefined;\n}\n\nfunction localeCandidates(raw: string | undefined): string[] {\n const locale = normalizeLocale(raw);\n if (!locale) return [];\n const base = locale.split('-')[0];\n return base && base !== locale ? [locale, base] : [locale];\n}\n\nfunction normalizeConfigPath(channelId: string, raw: string | undefined): `channels.${string}` {\n const expected = `channels.${channelId}` as const;\n if (!raw) return expected;\n const trimmed = raw.trim();\n if (!trimmed.startsWith('channels.')) return expected;\n return trimmed as `channels.${string}`;\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\nfunction hasNonEmptyString(value: unknown): boolean {\n return typeof value === 'string' && value.trim().length > 0;\n}\n\nfunction hasConfiguredTelegramCredential(raw: unknown): boolean {\n if (!isRecord(raw)) return false;\n const accounts = raw.accounts;\n if (!isRecord(accounts)) return false;\n return Object.values(accounts).some((account) => {\n if (!isRecord(account) || account.enabled === false) return false;\n return hasNonEmptyString(account.botToken) || hasNonEmptyString(account.tokenFile);\n });\n}\n\nfunction hasConfiguredWeixinAccount(raw: unknown): boolean {\n if (!isRecord(raw)) return false;\n if (raw.enabled === true) return true;\n const accounts = raw.accounts;\n if (!isRecord(accounts)) return false;\n return Object.values(accounts).some((account) => isRecord(account) && account.enabled !== false);\n}\n\nfunction withoutUndefined(value: Record<string, unknown>): Record<string, unknown> {\n return Object.fromEntries(Object.entries(value).filter(([, item]) => item !== undefined));\n}\n\nfunction mergeObjectMap<T extends Record<string, unknown>>(base: T | undefined, override: T | undefined): T | undefined {\n if (!base && !override) return undefined;\n if (!base) return override ? withoutUndefined(override) as T : undefined;\n if (!override) return base;\n const out: Record<string, unknown> = { ...base };\n for (const [key, value] of Object.entries(override)) {\n if (value === undefined) continue;\n out[key] = isRecord(out[key]) && isRecord(value)\n ? { ...out[key], ...withoutUndefined(value) }\n : value;\n }\n return out as T;\n}\n\nfunction mergeRecordDeep(base: Record<string, unknown>, override: Record<string, unknown>): Record<string, unknown> {\n const out: Record<string, unknown> = { ...base };\n for (const [key, value] of Object.entries(override)) {\n if (value === undefined) continue;\n out[key] = isRecord(out[key]) && isRecord(value)\n ? mergeRecordDeep(out[key], value)\n : value;\n }\n return out;\n}\n\nfunction mergeJsonSchema(base: Record<string, unknown> | undefined, override: Record<string, unknown> | undefined) {\n if (!base && !override) return undefined;\n if (!base) return override ? withoutUndefined(override) : undefined;\n if (!override) return base;\n return mergeRecordDeep(base, override);\n}\n\nfunction mergeChannelUi(\n base: ChannelContributionDeclaration['ui'],\n override: ChannelContributionDeclaration['ui'],\n): ChannelContributionDeclaration['ui'] {\n if (!base && !override) return undefined;\n return {\n ...(base ?? {}),\n ...(override ?? {}),\n card: mergeObjectMap(base?.card, override?.card),\n modal: mergeObjectMap(base?.modal, override?.modal),\n };\n}\n\nfunction localizeContribution(\n contribution: ChannelContributionDeclaration,\n locale: string | undefined,\n): ChannelContributionDeclaration {\n const i18n = contribution.i18n;\n if (!i18n) return contribution;\n const override = localeCandidates(locale).map((key) => i18n[key]).find(Boolean);\n if (!override) return contribution;\n return {\n ...contribution,\n label: override.label ?? contribution.label,\n description: override.description ?? contribution.description,\n configSchema: mergeJsonSchema(contribution.configSchema, override.configSchema),\n uiHints: mergeObjectMap(contribution.uiHints, override.uiHints),\n actions: mergeObjectMap(contribution.actions, override.actions),\n ui: mergeChannelUi(contribution.ui, override.ui),\n };\n}\n\nfunction toCatalogEntry(params: {\n extension: ManifestRegistryEntry;\n channelId: string;\n contribution: ChannelContributionDeclaration;\n locale?: string;\n}): ChannelCatalogEntry {\n const contribution = localizeContribution(params.contribution, params.locale);\n const id = normalizeChannelId(params.channelId);\n return {\n id,\n extensionId: params.extension.id,\n source: params.extension.source,\n path: params.extension.path,\n label: contribution.label,\n description: contribution.description,\n docsPath: contribution.docsPath,\n order: contribution.order ?? 999,\n configPath: normalizeConfigPath(id, contribution.configPath),\n capabilities: contribution.capabilities ?? {},\n configSchema: contribution.configSchema ?? DEFAULT_CONFIG_SCHEMA,\n uiHints: contribution.uiHints ?? {},\n actions: contribution.actions ?? {},\n ui: contribution.ui,\n };\n}\n\nexport function buildChannelCatalogFromSnapshot(\n snapshot: ExtensionMetadataSnapshot,\n options: BuildChannelCatalogOptions = {},\n): ChannelCatalog {\n const byId = new Map<string, ChannelCatalogEntry>();\n for (const extension of snapshot.manifestRegistry.getAllEntries()) {\n const contributions = extension.manifest.channelContributions ?? {};\n for (const [channelId, contribution] of Object.entries(contributions)) {\n const entry = toCatalogEntry({ extension, channelId, contribution, locale: options.locale });\n byId.set(entry.id, entry);\n }\n }\n const entries = Array.from(byId.values()).toSorted((a, b) => {\n if (a.order !== b.order) return a.order - b.order;\n return a.id.localeCompare(b.id);\n });\n return { entries, byId };\n}\n\nexport function buildChannelCatalogForConfig(config: Config, options: BuildChannelCatalogOptions = {}): ChannelCatalog {\n const snapshot = buildExtensionMetadataSnapshot(resolveExtensionLoaderOptionsFromConfig(config), config);\n return buildChannelCatalogFromSnapshot(snapshot, options);\n}\n\nexport function isChannelConfigured(config: Config, channelId: string): boolean {\n const id = normalizeChannelId(channelId);\n const raw = (config.channels as Record<string, unknown> | undefined)?.[id];\n if (!raw) return false;\n if (id === 'telegram') return hasConfiguredTelegramCredential(raw);\n if (id === 'weixin') return hasConfiguredWeixinAccount(raw);\n return isRecord(raw) ? raw.enabled === true || Object.keys(raw).length > 0 : true;\n}\n\nexport function getConfiguredChannelIds(config: Config): string[] {\n return Object.keys(config.channels ?? {})\n .map(normalizeChannelId)\n .filter((id) => id && isChannelConfigured(config, id));\n}\n"],"mappings":"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"}
@@ -0,0 +1,22 @@
1
+ import type { ChannelActionDescriptor, ChannelConfigUiHint, ChannelContributionCapabilities, ChannelContributionUiDeclaration } from '../../extensions/types/manifest.js';
2
+ export type ChannelCatalogSource = 'workspace' | 'global' | 'bundled' | 'config';
3
+ export interface ChannelCatalogEntry {
4
+ id: string;
5
+ extensionId: string;
6
+ source: ChannelCatalogSource;
7
+ path: string;
8
+ label: string;
9
+ description?: string;
10
+ docsPath?: string;
11
+ order: number;
12
+ configPath: `channels.${string}`;
13
+ capabilities: ChannelContributionCapabilities;
14
+ configSchema: Record<string, unknown>;
15
+ uiHints: Record<string, ChannelConfigUiHint>;
16
+ actions: Record<string, ChannelActionDescriptor>;
17
+ ui?: ChannelContributionUiDeclaration;
18
+ }
19
+ export interface ChannelCatalog {
20
+ entries: ChannelCatalogEntry[];
21
+ byId: Map<string, ChannelCatalogEntry>;
22
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -1,9 +1,4 @@
1
- /**
2
- * Lightweight channel surface for gateway/UI/shared code without importing
3
- * GrammY or full plugin implementations (channel dock pattern).
4
- */
5
1
  import type { ChannelCapabilities } from './plugin-types.js';
6
- import { type ChatChannelId } from './registry.js';
7
2
  export interface ChannelDock {
8
3
  id: string;
9
4
  label: string;
@@ -16,5 +11,3 @@ export interface ChannelDock {
16
11
  debounceMs?: number;
17
12
  };
18
13
  }
19
- export declare function getChannelDock(channelId: string): ChannelDock | undefined;
20
- export declare function getDockForBuiltinChannel(id: ChatChannelId): ChannelDock;
@@ -1,21 +1 @@
1
- import { getChatChannelMeta, isChatChannelId } from "./registry.js";
2
- //#region src/channels/dock.ts
3
- function getChannelDock(channelId) {
4
- if (!isChatChannelId(channelId)) return;
5
- const meta = getChatChannelMeta(channelId);
6
- return {
7
- id: meta.id,
8
- label: meta.label,
9
- description: meta.description,
10
- capabilities: meta.capabilities,
11
- ...meta.dock?.outbound && { outbound: meta.dock.outbound },
12
- ...meta.dock?.queue && { queue: meta.dock.queue }
13
- };
14
- }
15
- function getDockForBuiltinChannel(id) {
16
- return getChannelDock(id);
17
- }
18
- //#endregion
19
- export { getChannelDock, getDockForBuiltinChannel };
20
-
21
- //# sourceMappingURL=dock.js.map
1
+ export {};
@@ -4,13 +4,11 @@
4
4
  * Exports shared channel infrastructure (plugins, pipeline, registry).
5
5
  */
6
6
  export * from './channel-domain.js';
7
- export { CHAT_CHANNEL_ORDER, getChatChannelMeta, isChatChannelId, listChatChannelMeta, type ChatChannelId, type ChatChannelMeta, } from './registry.js';
8
- export { getChannelDock, getDockForBuiltinChannel, type ChannelDock } from './dock.js';
7
+ export { type ChannelDock } from './dock.js';
9
8
  export type { ChannelPlugin, ChannelPluginDefaults, ChannelPluginInitOptions, ChannelPluginSessionModelHooks, ChannelPluginReloadMeta, ChannelPluginStartOptions, ChannelOutboundContext, ChannelOutboundPayloadContext, OutboundDeliveryResult, ChannelStreamHandle, ChannelStatusAdapter, ChannelSecurityAdapter, ChannelConfigAdapter, ChannelStreamingAdapter, ChannelCapabilities, ChannelMeta, ChannelAccountSnapshot, StreamMode, ChannelOutboundMediaType, } from './plugin-types.js';
10
9
  export { compileAllowlist, resolveAllowlistMatch, resolveAllowlistMatchSimple, evaluateAccess, resolveDmPolicy, resolveGroupPolicy, hasBotMention, removeBotMention, } from './security.js';
11
10
  export { MessagePipeline, createPipeline, createEnvelopeTimestampHandler, createFilterSelfHandler, createFilterEmptyHandler, createFilterCommandsHandler, standardPreflightHandlers, standardProcessHandlers, type PipelineMessageContext, type PipelineMediaRef, type PreflightHandler, type ProcessHandler, type DeliveryHandler, type AgentResponse, } from './pipeline.js';
12
11
  export { ChannelManager, createChannelManager, type OutboundChannelHooks } from './manager.js';
13
12
  export { collectSetupWizardChannels } from './setup-wizard-discovery.js';
14
13
  export { listChannelPlugins, getChannelPlugin, getChannelRegistryVersion, syncChannelPluginsFromManager, } from './plugins/registry.js';
15
- export { bundledChannelPlugins } from './plugins/bundled.js';
16
14
  export * from './format.js';
@@ -1,18 +1,14 @@
1
1
  import { parseFrontmatterBlock } from "../markdown/frontmatter.js";
2
2
  import { getChannelPlugin, getChannelRegistryVersion, listChannelPlugins, syncChannelPluginsFromManager } from "./plugins/registry.js";
3
3
  import { compileAllowlist, evaluateAccess, hasBotMention, removeBotMention, resolveAllowlistMatch, resolveAllowlistMatchSimple, resolveDmPolicy, resolveGroupPolicy } from "./security.js";
4
- import { CHAT_CHANNEL_ORDER, getChatChannelMeta, isChatChannelId, listChatChannelMeta } from "./registry.js";
5
4
  import { findFenceSpanAt, isSafeFenceBreak, parseFenceSpans } from "../markdown/fences.js";
6
5
  import { chunkText } from "../markdown/chunk.js";
7
6
  import { chunkMarkdownIR, markdownToIR, markdownToIRWithMeta } from "../markdown/ir.js";
8
7
  import { renderMarkdownWithMarkers } from "../markdown/render.js";
9
8
  import { convertMarkdownTables } from "../markdown/tables.js";
10
9
  import { buildCodeSpanIndex, createInlineCodeState } from "../markdown/code-spans.js";
11
- import { bundledChannelPlugins } from "../generated/bundled-channel-plugins.js";
12
- import "./plugins/bundled.js";
13
- import { getChannelDock, getDockForBuiltinChannel } from "./dock.js";
14
10
  import "./format.js";
15
11
  import { MessagePipeline, createEnvelopeTimestampHandler, createFilterCommandsHandler, createFilterEmptyHandler, createFilterSelfHandler, createPipeline, standardPreflightHandlers, standardProcessHandlers } from "./pipeline.js";
16
12
  import { ChannelManager, createChannelManager } from "./manager.js";
17
13
  import { collectSetupWizardChannels } from "./setup-wizard-discovery.js";
18
- export { CHAT_CHANNEL_ORDER, ChannelManager, MessagePipeline, buildCodeSpanIndex, bundledChannelPlugins, chunkMarkdownIR, chunkText, collectSetupWizardChannels, compileAllowlist, convertMarkdownTables, createChannelManager, createEnvelopeTimestampHandler, createFilterCommandsHandler, createFilterEmptyHandler, createFilterSelfHandler, createInlineCodeState, createPipeline, evaluateAccess, findFenceSpanAt, getChannelDock, getChannelPlugin, getChannelRegistryVersion, getChatChannelMeta, getDockForBuiltinChannel, hasBotMention, isChatChannelId, isSafeFenceBreak, listChannelPlugins, listChatChannelMeta, markdownToIR, markdownToIRWithMeta, parseFenceSpans, parseFrontmatterBlock, removeBotMention, renderMarkdownWithMarkers, resolveAllowlistMatch, resolveAllowlistMatchSimple, resolveDmPolicy, resolveGroupPolicy, standardPreflightHandlers, standardProcessHandlers, syncChannelPluginsFromManager };
14
+ export { ChannelManager, MessagePipeline, buildCodeSpanIndex, chunkMarkdownIR, chunkText, collectSetupWizardChannels, compileAllowlist, convertMarkdownTables, createChannelManager, createEnvelopeTimestampHandler, createFilterCommandsHandler, createFilterEmptyHandler, createFilterSelfHandler, createInlineCodeState, createPipeline, evaluateAccess, findFenceSpanAt, getChannelPlugin, getChannelRegistryVersion, hasBotMention, isSafeFenceBreak, listChannelPlugins, markdownToIR, markdownToIRWithMeta, parseFenceSpans, parseFrontmatterBlock, removeBotMention, renderMarkdownWithMarkers, resolveAllowlistMatch, resolveAllowlistMatchSimple, resolveDmPolicy, resolveGroupPolicy, standardPreflightHandlers, standardProcessHandlers, syncChannelPluginsFromManager };
@@ -55,6 +55,7 @@ export declare class ChannelLifecycleSupervisor {
55
55
  /** Channel ids that would run and declare `meta.deferConnectUntilAfterListen` (for logging / metrics). */
56
56
  listDeferConnectChannelIds(cfg: Config): string[];
57
57
  initialize(): Promise<void>;
58
+ initializeChannel(channelId: string): Promise<boolean>;
58
59
  /** Phase 1: start every enabled channel except those in `deferConnectPluginIds`. */
59
60
  start(options?: {
60
61
  deferConnectPluginIds?: ReadonlySet<string>;
@@ -58,6 +58,17 @@ var ChannelLifecycleSupervisor = class {
58
58
  this.initialized = true;
59
59
  log.info("All channel plugins initialized");
60
60
  }
61
+ async initializeChannel(channelId) {
62
+ const plugin = this.opts.registry.get(channelId);
63
+ if (!plugin) {
64
+ log.warn({ channel: channelId }, "Unknown channel");
65
+ return false;
66
+ }
67
+ if (this.initializedPluginIds.has(channelId)) return true;
68
+ const cfg = this.opts.getConfig();
69
+ await this.initializePlugin(plugin, asChannelConfig(cfg.channels?.[channelId]) ?? {});
70
+ return this.initializedPluginIds.has(channelId);
71
+ }
61
72
  /** Phase 1: start every enabled channel except those in `deferConnectPluginIds`. */
62
73
  async start(options) {
63
74
  if (!this.initialized) throw new Error("Channels not initialized");
@@ -1 +1 @@
1
- {"version":3,"file":"lifecycle-supervisor.js","names":[],"sources":["../../../src/channels/lifecycle-supervisor.ts"],"sourcesContent":["/**\n * ChannelLifecycleSupervisor — owns the start/stop/restart state machine for\n * every channel plugin.\n *\n * Concerns:\n * - `initialize()` — call each plugin's `init(...)` once and remember success\n * - Two-phase `start()` + `startDeferredConnects()` for channels whose\n * `meta.deferConnectUntilAfterListen` is true (HTTP listener has to be up\n * before they dial out)\n * - Per-channel manual stop / start (UI-driven; suppresses auto-restart)\n * - Exponential restart backoff via {@link CHANNEL_RESTART_POLICY}\n * - Soft restart (called from heartbeat) — stop + startPlugin, manual-stop guarded\n *\n * Heartbeat probes themselves live in {@link ChannelHeartbeatScheduler}; this\n * supervisor schedules them via `onPluginStarted` / `onPluginStopped` callbacks\n * passed in by the caller.\n *\n * Extracted from `ChannelManager` so the manager can be a thin composition root.\n */\n\nimport type { Config } from '../config/schema.js';\nimport type { MessageBus } from '../infra/bus/index.js';\n\nimport type {\n ChannelPlugin,\n ChannelPluginInitOptions,\n ChannelPluginSessionModelHooks,\n ChannelPluginStartOptions,\n} from './plugin-types.js';\nimport type { ChannelPluginRegistry } from './plugin-registry.js';\nimport { CHANNEL_RESTART_POLICY, computeBackoff } from './restart-policy.js';\nimport { createLogger } from '../utils/logger.js';\n\nconst log = createLogger('ChannelLifecycleSupervisor');\n\nfunction asChannelConfig(raw: unknown): Record<string, unknown> | undefined {\n if (raw && typeof raw === 'object' && !Array.isArray(raw)) {\n return raw as Record<string, unknown>;\n }\n return undefined;\n}\n\nexport interface ChannelLifecycleSupervisorOptions {\n bus: MessageBus;\n registry: ChannelPluginRegistry;\n /** Effective config snapshot (per-channel `channels.<id>.*`). */\n getConfig: () => Config;\n /** Hooks for sub-classes / external observers: heartbeat scheduling, etc. */\n onPluginStarted?: (plugin: ChannelPlugin) => void;\n onPluginStopped?: (pluginId: string) => void;\n /** Optional session-model hooks forwarded into `plugin.init()`. */\n getSessionModelHooks?: () => ChannelPluginSessionModelHooks | undefined;\n}\n\nexport class ChannelLifecycleSupervisor {\n private readonly opts: ChannelLifecycleSupervisorOptions;\n /** Plugin ids whose `init()` completed (used by start/stop loops). */\n private readonly initializedPluginIds = new Set<string>();\n private readonly restartAttempts = new Map<string, number>();\n /** When set, failed-start auto-restart is suppressed for that channel id. */\n private readonly manuallyStopped = new Set<string>();\n /** Plugins that skipped `start()` until `startDeferredConnects()`. */\n private readonly deferredConnectPending = new Set<string>();\n private initialized = false;\n private running = false;\n\n constructor(opts: ChannelLifecycleSupervisorOptions) {\n this.opts = opts;\n }\n\n isInitialized(pluginId: string): boolean {\n return this.initializedPluginIds.has(pluginId);\n }\n\n snapshot(): {\n initialized: boolean;\n running: boolean;\n initializedPluginIds: string[];\n manuallyStopped: string[];\n restartAttempts: Record<string, number>;\n } {\n return {\n initialized: this.initialized,\n running: this.running,\n initializedPluginIds: [...this.initializedPluginIds],\n manuallyStopped: [...this.manuallyStopped],\n restartAttempts: Object.fromEntries(this.restartAttempts),\n };\n }\n\n /** Channel ids that would run and declare `meta.deferConnectUntilAfterListen` (for logging / metrics). */\n listDeferConnectChannelIds(cfg: Config): string[] {\n const out: string[] = [];\n for (const [id, plugin] of this.opts.registry.entries()) {\n const channelConfig = asChannelConfig(cfg.channels?.[id]);\n if (!this.shouldRunChannelPlugin(plugin, channelConfig)) continue;\n if (plugin.meta.deferConnectUntilAfterListen === true) {\n out.push(id);\n }\n }\n return out;\n }\n\n async initialize(): Promise<void> {\n if (this.initialized) {\n log.warn(\n { pluginCount: this.opts.registry.ids().length },\n 'initialize() called again; channels already initialized — skipping',\n );\n return;\n }\n\n const cfg = this.opts.getConfig();\n const initPromises: Promise<void>[] = [];\n\n for (const [id, plugin] of this.opts.registry.entries()) {\n const channelConfig = asChannelConfig(cfg.channels?.[id]);\n // Always init so `onConfigUpdated` runs on hot reload (e.g. Weixin turned off after QR-login\n // started monitors while the plugin was previously skipped here and had no bus/`initialized` id).\n initPromises.push(this.initializePlugin(plugin, channelConfig ?? {}));\n }\n\n await Promise.allSettled(initPromises);\n this.initialized = true;\n log.info('All channel plugins initialized');\n }\n\n /** Phase 1: start every enabled channel except those in `deferConnectPluginIds`. */\n async start(options?: { deferConnectPluginIds?: ReadonlySet<string> }): Promise<void> {\n if (!this.initialized) {\n throw new Error('Channels not initialized');\n }\n if (this.running) {\n log.warn(\n { pluginCount: this.opts.registry.ids().length },\n 'start() called while channels already running — skipping',\n );\n return;\n }\n\n const deferIds = options?.deferConnectPluginIds ?? new Set<string>();\n this.deferredConnectPending.clear();\n\n const cfg = this.opts.getConfig();\n const startPromises: Promise<void>[] = [];\n\n for (const [id, plugin] of this.opts.registry.entries()) {\n const channelConfig = asChannelConfig(cfg.channels?.[id]);\n if (!this.shouldRunChannelPlugin(plugin, channelConfig)) continue;\n\n if (deferIds.has(id)) {\n this.deferredConnectPending.add(id);\n log.info({ channel: id }, 'Channel connect deferred until HTTP listen');\n continue;\n }\n\n startPromises.push(\n this.startPlugin(plugin, {}).catch((err) => {\n log.error({ channel: id, err }, 'Failed to start channel plugin');\n }),\n );\n }\n\n await Promise.allSettled(startPromises);\n this.running = true;\n log.info(\n { deferred: [...this.deferredConnectPending] },\n this.deferredConnectPending.size > 0\n ? 'Channel plugins started (deferred connects pending)'\n : 'All channel plugins started',\n );\n }\n\n /** Phase 2: `start()` for channels deferred at Phase 1. No-op if none pending. */\n async startDeferredConnects(): Promise<void> {\n if (this.deferredConnectPending.size === 0) return;\n if (!this.running) {\n log.warn('startDeferredConnects called before channel phase-1 start; skipping');\n return;\n }\n const ids = [...this.deferredConnectPending];\n this.deferredConnectPending.clear();\n const cfg = this.opts.getConfig();\n const startPromises: Promise<void>[] = [];\n for (const id of ids) {\n const plugin = this.opts.registry.get(id);\n if (!plugin) continue;\n const channelConfig = asChannelConfig(cfg.channels?.[id]);\n if (!this.shouldRunChannelPlugin(plugin, channelConfig)) continue;\n startPromises.push(\n this.startPlugin(plugin, {}).catch((err) => {\n log.error({ channel: id, err }, 'Failed to start deferred channel plugin');\n }),\n );\n }\n await Promise.allSettled(startPromises);\n log.info({ channels: ids }, 'Deferred channel connects completed');\n }\n\n async stop(): Promise<void> {\n if (!this.running) return;\n\n this.deferredConnectPending.clear();\n\n const stopPromises: Promise<void>[] = [];\n for (const id of this.initializedPluginIds) {\n const plugin = this.opts.registry.get(id);\n if (!plugin) continue;\n stopPromises.push(\n this.stopPlugin(plugin).catch((err) => {\n log.error({ channel: id, err }, 'Failed to stop channel plugin');\n }),\n );\n }\n\n await Promise.allSettled(stopPromises);\n this.running = false;\n log.info('All channel plugins stopped');\n }\n\n /** Stop one channel and suppress automatic restart until `startChannel` is called. */\n async stopChannel(channelId: string): Promise<void> {\n this.manuallyStopped.add(channelId);\n const plugin = this.opts.registry.get(channelId);\n if (!plugin || !this.initializedPluginIds.has(channelId)) {\n return;\n }\n await this.stopPlugin(plugin).catch((err) => {\n log.error({ channel: channelId, err }, 'Failed to stop channel plugin');\n });\n }\n\n /** Clear manual-stop and start one channel (requires prior `initialize()`). */\n async startChannel(channelId: string): Promise<void> {\n this.manuallyStopped.delete(channelId);\n const plugin = this.opts.registry.get(channelId);\n if (!plugin) {\n log.warn({ channel: channelId }, 'Unknown channel');\n return;\n }\n if (!this.initialized) {\n log.warn({ channel: channelId }, 'Channels not initialized');\n return;\n }\n const cfg = this.opts.getConfig();\n const channelConfig = asChannelConfig(cfg.channels?.[channelId]);\n if (!this.shouldRunChannelPlugin(plugin, channelConfig)) {\n log.debug({ channel: channelId }, 'Channel disabled in config, skipping start');\n return;\n }\n if (!this.initializedPluginIds.has(channelId)) {\n log.warn({ channel: channelId }, 'Channel was never initialized; call initialize() first');\n return;\n }\n await this.startPlugin(plugin, {});\n }\n\n /** Called by heartbeat: stop + start without clearing manualStop. No-op if user stopped it. */\n async softRestart(channelId: string): Promise<void> {\n if (this.manuallyStopped.has(channelId)) return;\n const plugin = this.opts.registry.get(channelId);\n if (!plugin || !this.initializedPluginIds.has(channelId)) return;\n try {\n await this.stopPlugin(plugin);\n await this.startPlugin(plugin, {});\n } catch (err) {\n log.error({ channel: channelId, err }, 'Channel soft restart after heartbeat failed');\n }\n }\n\n /** Forward a config snapshot to every initialised plugin's `onConfigUpdated` hook. */\n async forwardConfigUpdate(cfg: Config): Promise<void> {\n for (const id of this.initializedPluginIds) {\n const plugin = this.opts.registry.get(id);\n if (plugin?.onConfigUpdated) {\n await Promise.resolve(plugin.onConfigUpdated(cfg));\n }\n }\n }\n\n // ── Internals ───────────────────────────────────────────────────────────\n\n /**\n * Builtin channels require `channels.<id>.enabled`. Extension-managed channels\n * run unless explicitly disabled.\n */\n private shouldRunChannelPlugin(\n plugin: ChannelPlugin,\n channelConfig: Record<string, unknown> | undefined,\n ): boolean {\n if (plugin.extensionManagedConfig) {\n return channelConfig?.enabled !== false;\n }\n return !!channelConfig?.enabled;\n }\n\n private async initializePlugin(\n plugin: ChannelPlugin,\n channelConfig: Record<string, unknown>,\n ): Promise<void> {\n try {\n const options: ChannelPluginInitOptions = {\n bus: this.opts.bus,\n config: this.opts.getConfig(),\n channelConfig,\n sessionModel: this.opts.getSessionModelHooks?.(),\n };\n await plugin.init(options);\n this.initializedPluginIds.add(plugin.id);\n log.debug({ channel: plugin.id }, 'Channel plugin initialized');\n } catch (err) {\n log.error({ channel: plugin.id, err }, 'Failed to initialize channel plugin');\n }\n }\n\n private async startPlugin(\n plugin: ChannelPlugin,\n opts: { preserveRestartAttempts?: boolean },\n ): Promise<void> {\n const options: ChannelPluginStartOptions = {};\n try {\n await plugin.start(options);\n if (!opts.preserveRestartAttempts) {\n this.restartAttempts.delete(plugin.id);\n }\n this.opts.onPluginStarted?.(plugin);\n log.debug({ channel: plugin.id }, 'Channel plugin started');\n } catch (err) {\n const attempt = (this.restartAttempts.get(plugin.id) ?? 0) + 1;\n this.restartAttempts.set(plugin.id, attempt);\n if (attempt <= CHANNEL_RESTART_POLICY.maxAttempts) {\n const delayMs = computeBackoff(CHANNEL_RESTART_POLICY, attempt);\n log.warn(\n { channel: plugin.id, attempt, delayMs, err },\n 'Channel failed to start, scheduling restart',\n );\n setTimeout(() => {\n if (this.manuallyStopped.has(plugin.id)) {\n log.debug({ channel: plugin.id }, 'Skipping scheduled restart (manual stop)');\n return;\n }\n void this.startPlugin(plugin, { preserveRestartAttempts: true }).catch((e) => {\n log.error({ channel: plugin.id, err: e }, 'Channel restart attempt failed');\n });\n }, delayMs);\n } else {\n log.error({ channel: plugin.id, err }, 'Channel exceeded max restart attempts');\n }\n }\n }\n\n private async stopPlugin(plugin: ChannelPlugin): Promise<void> {\n this.opts.onPluginStopped?.(plugin.id);\n await plugin.stop();\n log.info({ channel: plugin.id }, 'Channel plugin stopped');\n }\n}\n"],"mappings":";;;;aA+BkD;AAElD,MAAM,MAAM,aAAa,6BAA6B;AAEtD,SAAS,gBAAgB,KAAmD;AAC1E,KAAI,OAAO,OAAO,QAAQ,YAAY,CAAC,MAAM,QAAQ,IAAI,CACvD,QAAO;;AAiBX,IAAa,6BAAb,MAAwC;CACtC;;CAEA,uCAAwC,IAAI,KAAa;CACzD,kCAAmC,IAAI,KAAqB;;CAE5D,kCAAmC,IAAI,KAAa;;CAEpD,yCAA0C,IAAI,KAAa;CAC3D,cAAsB;CACtB,UAAkB;CAElB,YAAY,MAAyC;AACnD,OAAK,OAAO;;CAGd,cAAc,UAA2B;AACvC,SAAO,KAAK,qBAAqB,IAAI,SAAS;;CAGhD,WAME;AACA,SAAO;GACL,aAAa,KAAK;GAClB,SAAS,KAAK;GACd,sBAAsB,CAAC,GAAG,KAAK,qBAAqB;GACpD,iBAAiB,CAAC,GAAG,KAAK,gBAAgB;GAC1C,iBAAiB,OAAO,YAAY,KAAK,gBAAgB;GAC1D;;;CAIH,2BAA2B,KAAuB;EAChD,MAAM,MAAgB,EAAE;AACxB,OAAK,MAAM,CAAC,IAAI,WAAW,KAAK,KAAK,SAAS,SAAS,EAAE;GACvD,MAAM,gBAAgB,gBAAgB,IAAI,WAAW,IAAI;AACzD,OAAI,CAAC,KAAK,uBAAuB,QAAQ,cAAc,CAAE;AACzD,OAAI,OAAO,KAAK,iCAAiC,KAC/C,KAAI,KAAK,GAAG;;AAGhB,SAAO;;CAGT,MAAM,aAA4B;AAChC,MAAI,KAAK,aAAa;AACpB,OAAI,KACF,EAAE,aAAa,KAAK,KAAK,SAAS,KAAK,CAAC,QAAQ,EAChD,qEACD;AACD;;EAGF,MAAM,MAAM,KAAK,KAAK,WAAW;EACjC,MAAM,eAAgC,EAAE;AAExC,OAAK,MAAM,CAAC,IAAI,WAAW,KAAK,KAAK,SAAS,SAAS,EAAE;GACvD,MAAM,gBAAgB,gBAAgB,IAAI,WAAW,IAAI;AAGzD,gBAAa,KAAK,KAAK,iBAAiB,QAAQ,iBAAiB,EAAE,CAAC,CAAC;;AAGvE,QAAM,QAAQ,WAAW,aAAa;AACtC,OAAK,cAAc;AACnB,MAAI,KAAK,kCAAkC;;;CAI7C,MAAM,MAAM,SAA0E;AACpF,MAAI,CAAC,KAAK,YACR,OAAM,IAAI,MAAM,2BAA2B;AAE7C,MAAI,KAAK,SAAS;AAChB,OAAI,KACF,EAAE,aAAa,KAAK,KAAK,SAAS,KAAK,CAAC,QAAQ,EAChD,2DACD;AACD;;EAGF,MAAM,WAAW,SAAS,yCAAyB,IAAI,KAAa;AACpE,OAAK,uBAAuB,OAAO;EAEnC,MAAM,MAAM,KAAK,KAAK,WAAW;EACjC,MAAM,gBAAiC,EAAE;AAEzC,OAAK,MAAM,CAAC,IAAI,WAAW,KAAK,KAAK,SAAS,SAAS,EAAE;GACvD,MAAM,gBAAgB,gBAAgB,IAAI,WAAW,IAAI;AACzD,OAAI,CAAC,KAAK,uBAAuB,QAAQ,cAAc,CAAE;AAEzD,OAAI,SAAS,IAAI,GAAG,EAAE;AACpB,SAAK,uBAAuB,IAAI,GAAG;AACnC,QAAI,KAAK,EAAE,SAAS,IAAI,EAAE,6CAA6C;AACvE;;AAGF,iBAAc,KACZ,KAAK,YAAY,QAAQ,EAAE,CAAC,CAAC,OAAO,QAAQ;AAC1C,QAAI,MAAM;KAAE,SAAS;KAAI;KAAK,EAAE,iCAAiC;KACjE,CACH;;AAGH,QAAM,QAAQ,WAAW,cAAc;AACvC,OAAK,UAAU;AACf,MAAI,KACF,EAAE,UAAU,CAAC,GAAG,KAAK,uBAAuB,EAAE,EAC9C,KAAK,uBAAuB,OAAO,IAC/B,wDACA,8BACL;;;CAIH,MAAM,wBAAuC;AAC3C,MAAI,KAAK,uBAAuB,SAAS,EAAG;AAC5C,MAAI,CAAC,KAAK,SAAS;AACjB,OAAI,KAAK,sEAAsE;AAC/E;;EAEF,MAAM,MAAM,CAAC,GAAG,KAAK,uBAAuB;AAC5C,OAAK,uBAAuB,OAAO;EACnC,MAAM,MAAM,KAAK,KAAK,WAAW;EACjC,MAAM,gBAAiC,EAAE;AACzC,OAAK,MAAM,MAAM,KAAK;GACpB,MAAM,SAAS,KAAK,KAAK,SAAS,IAAI,GAAG;AACzC,OAAI,CAAC,OAAQ;GACb,MAAM,gBAAgB,gBAAgB,IAAI,WAAW,IAAI;AACzD,OAAI,CAAC,KAAK,uBAAuB,QAAQ,cAAc,CAAE;AACzD,iBAAc,KACZ,KAAK,YAAY,QAAQ,EAAE,CAAC,CAAC,OAAO,QAAQ;AAC1C,QAAI,MAAM;KAAE,SAAS;KAAI;KAAK,EAAE,0CAA0C;KAC1E,CACH;;AAEH,QAAM,QAAQ,WAAW,cAAc;AACvC,MAAI,KAAK,EAAE,UAAU,KAAK,EAAE,sCAAsC;;CAGpE,MAAM,OAAsB;AAC1B,MAAI,CAAC,KAAK,QAAS;AAEnB,OAAK,uBAAuB,OAAO;EAEnC,MAAM,eAAgC,EAAE;AACxC,OAAK,MAAM,MAAM,KAAK,sBAAsB;GAC1C,MAAM,SAAS,KAAK,KAAK,SAAS,IAAI,GAAG;AACzC,OAAI,CAAC,OAAQ;AACb,gBAAa,KACX,KAAK,WAAW,OAAO,CAAC,OAAO,QAAQ;AACrC,QAAI,MAAM;KAAE,SAAS;KAAI;KAAK,EAAE,gCAAgC;KAChE,CACH;;AAGH,QAAM,QAAQ,WAAW,aAAa;AACtC,OAAK,UAAU;AACf,MAAI,KAAK,8BAA8B;;;CAIzC,MAAM,YAAY,WAAkC;AAClD,OAAK,gBAAgB,IAAI,UAAU;EACnC,MAAM,SAAS,KAAK,KAAK,SAAS,IAAI,UAAU;AAChD,MAAI,CAAC,UAAU,CAAC,KAAK,qBAAqB,IAAI,UAAU,CACtD;AAEF,QAAM,KAAK,WAAW,OAAO,CAAC,OAAO,QAAQ;AAC3C,OAAI,MAAM;IAAE,SAAS;IAAW;IAAK,EAAE,gCAAgC;IACvE;;;CAIJ,MAAM,aAAa,WAAkC;AACnD,OAAK,gBAAgB,OAAO,UAAU;EACtC,MAAM,SAAS,KAAK,KAAK,SAAS,IAAI,UAAU;AAChD,MAAI,CAAC,QAAQ;AACX,OAAI,KAAK,EAAE,SAAS,WAAW,EAAE,kBAAkB;AACnD;;AAEF,MAAI,CAAC,KAAK,aAAa;AACrB,OAAI,KAAK,EAAE,SAAS,WAAW,EAAE,2BAA2B;AAC5D;;EAGF,MAAM,gBAAgB,gBADV,KAAK,KAAK,WACmB,CAAC,WAAW,WAAW;AAChE,MAAI,CAAC,KAAK,uBAAuB,QAAQ,cAAc,EAAE;AACvD,OAAI,MAAM,EAAE,SAAS,WAAW,EAAE,6CAA6C;AAC/E;;AAEF,MAAI,CAAC,KAAK,qBAAqB,IAAI,UAAU,EAAE;AAC7C,OAAI,KAAK,EAAE,SAAS,WAAW,EAAE,yDAAyD;AAC1F;;AAEF,QAAM,KAAK,YAAY,QAAQ,EAAE,CAAC;;;CAIpC,MAAM,YAAY,WAAkC;AAClD,MAAI,KAAK,gBAAgB,IAAI,UAAU,CAAE;EACzC,MAAM,SAAS,KAAK,KAAK,SAAS,IAAI,UAAU;AAChD,MAAI,CAAC,UAAU,CAAC,KAAK,qBAAqB,IAAI,UAAU,CAAE;AAC1D,MAAI;AACF,SAAM,KAAK,WAAW,OAAO;AAC7B,SAAM,KAAK,YAAY,QAAQ,EAAE,CAAC;WAC3B,KAAK;AACZ,OAAI,MAAM;IAAE,SAAS;IAAW;IAAK,EAAE,8CAA8C;;;;CAKzF,MAAM,oBAAoB,KAA4B;AACpD,OAAK,MAAM,MAAM,KAAK,sBAAsB;GAC1C,MAAM,SAAS,KAAK,KAAK,SAAS,IAAI,GAAG;AACzC,OAAI,QAAQ,gBACV,OAAM,QAAQ,QAAQ,OAAO,gBAAgB,IAAI,CAAC;;;;;;;CAWxD,uBACE,QACA,eACS;AACT,MAAI,OAAO,uBACT,QAAO,eAAe,YAAY;AAEpC,SAAO,CAAC,CAAC,eAAe;;CAG1B,MAAc,iBACZ,QACA,eACe;AACf,MAAI;GACF,MAAM,UAAoC;IACxC,KAAK,KAAK,KAAK;IACf,QAAQ,KAAK,KAAK,WAAW;IAC7B;IACA,cAAc,KAAK,KAAK,wBAAwB;IACjD;AACD,SAAM,OAAO,KAAK,QAAQ;AAC1B,QAAK,qBAAqB,IAAI,OAAO,GAAG;AACxC,OAAI,MAAM,EAAE,SAAS,OAAO,IAAI,EAAE,6BAA6B;WACxD,KAAK;AACZ,OAAI,MAAM;IAAE,SAAS,OAAO;IAAI;IAAK,EAAE,sCAAsC;;;CAIjF,MAAc,YACZ,QACA,MACe;EACf,MAAM,UAAqC,EAAE;AAC7C,MAAI;AACF,SAAM,OAAO,MAAM,QAAQ;AAC3B,OAAI,CAAC,KAAK,wBACR,MAAK,gBAAgB,OAAO,OAAO,GAAG;AAExC,QAAK,KAAK,kBAAkB,OAAO;AACnC,OAAI,MAAM,EAAE,SAAS,OAAO,IAAI,EAAE,yBAAyB;WACpD,KAAK;GACZ,MAAM,WAAW,KAAK,gBAAgB,IAAI,OAAO,GAAG,IAAI,KAAK;AAC7D,QAAK,gBAAgB,IAAI,OAAO,IAAI,QAAQ;AAC5C,OAAI,WAAW,uBAAuB,aAAa;IACjD,MAAM,UAAU,eAAe,wBAAwB,QAAQ;AAC/D,QAAI,KACF;KAAE,SAAS,OAAO;KAAI;KAAS;KAAS;KAAK,EAC7C,8CACD;AACD,qBAAiB;AACf,SAAI,KAAK,gBAAgB,IAAI,OAAO,GAAG,EAAE;AACvC,UAAI,MAAM,EAAE,SAAS,OAAO,IAAI,EAAE,2CAA2C;AAC7E;;AAEG,UAAK,YAAY,QAAQ,EAAE,yBAAyB,MAAM,CAAC,CAAC,OAAO,MAAM;AAC5E,UAAI,MAAM;OAAE,SAAS,OAAO;OAAI,KAAK;OAAG,EAAE,iCAAiC;OAC3E;OACD,QAAQ;SAEX,KAAI,MAAM;IAAE,SAAS,OAAO;IAAI;IAAK,EAAE,wCAAwC;;;CAKrF,MAAc,WAAW,QAAsC;AAC7D,OAAK,KAAK,kBAAkB,OAAO,GAAG;AACtC,QAAM,OAAO,MAAM;AACnB,MAAI,KAAK,EAAE,SAAS,OAAO,IAAI,EAAE,yBAAyB"}
1
+ {"version":3,"file":"lifecycle-supervisor.js","names":[],"sources":["../../../src/channels/lifecycle-supervisor.ts"],"sourcesContent":["/**\n * ChannelLifecycleSupervisor — owns the start/stop/restart state machine for\n * every channel plugin.\n *\n * Concerns:\n * - `initialize()` — call each plugin's `init(...)` once and remember success\n * - Two-phase `start()` + `startDeferredConnects()` for channels whose\n * `meta.deferConnectUntilAfterListen` is true (HTTP listener has to be up\n * before they dial out)\n * - Per-channel manual stop / start (UI-driven; suppresses auto-restart)\n * - Exponential restart backoff via {@link CHANNEL_RESTART_POLICY}\n * - Soft restart (called from heartbeat) — stop + startPlugin, manual-stop guarded\n *\n * Heartbeat probes themselves live in {@link ChannelHeartbeatScheduler}; this\n * supervisor schedules them via `onPluginStarted` / `onPluginStopped` callbacks\n * passed in by the caller.\n *\n * Extracted from `ChannelManager` so the manager can be a thin composition root.\n */\n\nimport type { Config } from '../config/schema.js';\nimport type { MessageBus } from '../infra/bus/index.js';\n\nimport type {\n ChannelPlugin,\n ChannelPluginInitOptions,\n ChannelPluginSessionModelHooks,\n ChannelPluginStartOptions,\n} from './plugin-types.js';\nimport type { ChannelPluginRegistry } from './plugin-registry.js';\nimport { CHANNEL_RESTART_POLICY, computeBackoff } from './restart-policy.js';\nimport { createLogger } from '../utils/logger.js';\n\nconst log = createLogger('ChannelLifecycleSupervisor');\n\nfunction asChannelConfig(raw: unknown): Record<string, unknown> | undefined {\n if (raw && typeof raw === 'object' && !Array.isArray(raw)) {\n return raw as Record<string, unknown>;\n }\n return undefined;\n}\n\nexport interface ChannelLifecycleSupervisorOptions {\n bus: MessageBus;\n registry: ChannelPluginRegistry;\n /** Effective config snapshot (per-channel `channels.<id>.*`). */\n getConfig: () => Config;\n /** Hooks for sub-classes / external observers: heartbeat scheduling, etc. */\n onPluginStarted?: (plugin: ChannelPlugin) => void;\n onPluginStopped?: (pluginId: string) => void;\n /** Optional session-model hooks forwarded into `plugin.init()`. */\n getSessionModelHooks?: () => ChannelPluginSessionModelHooks | undefined;\n}\n\nexport class ChannelLifecycleSupervisor {\n private readonly opts: ChannelLifecycleSupervisorOptions;\n /** Plugin ids whose `init()` completed (used by start/stop loops). */\n private readonly initializedPluginIds = new Set<string>();\n private readonly restartAttempts = new Map<string, number>();\n /** When set, failed-start auto-restart is suppressed for that channel id. */\n private readonly manuallyStopped = new Set<string>();\n /** Plugins that skipped `start()` until `startDeferredConnects()`. */\n private readonly deferredConnectPending = new Set<string>();\n private initialized = false;\n private running = false;\n\n constructor(opts: ChannelLifecycleSupervisorOptions) {\n this.opts = opts;\n }\n\n isInitialized(pluginId: string): boolean {\n return this.initializedPluginIds.has(pluginId);\n }\n\n snapshot(): {\n initialized: boolean;\n running: boolean;\n initializedPluginIds: string[];\n manuallyStopped: string[];\n restartAttempts: Record<string, number>;\n } {\n return {\n initialized: this.initialized,\n running: this.running,\n initializedPluginIds: [...this.initializedPluginIds],\n manuallyStopped: [...this.manuallyStopped],\n restartAttempts: Object.fromEntries(this.restartAttempts),\n };\n }\n\n /** Channel ids that would run and declare `meta.deferConnectUntilAfterListen` (for logging / metrics). */\n listDeferConnectChannelIds(cfg: Config): string[] {\n const out: string[] = [];\n for (const [id, plugin] of this.opts.registry.entries()) {\n const channelConfig = asChannelConfig(cfg.channels?.[id]);\n if (!this.shouldRunChannelPlugin(plugin, channelConfig)) continue;\n if (plugin.meta.deferConnectUntilAfterListen === true) {\n out.push(id);\n }\n }\n return out;\n }\n\n async initialize(): Promise<void> {\n if (this.initialized) {\n log.warn(\n { pluginCount: this.opts.registry.ids().length },\n 'initialize() called again; channels already initialized — skipping',\n );\n return;\n }\n\n const cfg = this.opts.getConfig();\n const initPromises: Promise<void>[] = [];\n\n for (const [id, plugin] of this.opts.registry.entries()) {\n const channelConfig = asChannelConfig(cfg.channels?.[id]);\n // Always init so `onConfigUpdated` runs on hot reload (e.g. Weixin turned off after QR-login\n // started monitors while the plugin was previously skipped here and had no bus/`initialized` id).\n initPromises.push(this.initializePlugin(plugin, channelConfig ?? {}));\n }\n\n await Promise.allSettled(initPromises);\n this.initialized = true;\n log.info('All channel plugins initialized');\n }\n\n async initializeChannel(channelId: string): Promise<boolean> {\n const plugin = this.opts.registry.get(channelId);\n if (!plugin) {\n log.warn({ channel: channelId }, 'Unknown channel');\n return false;\n }\n if (this.initializedPluginIds.has(channelId)) {\n return true;\n }\n const cfg = this.opts.getConfig();\n await this.initializePlugin(plugin, asChannelConfig(cfg.channels?.[channelId]) ?? {});\n return this.initializedPluginIds.has(channelId);\n }\n\n /** Phase 1: start every enabled channel except those in `deferConnectPluginIds`. */\n async start(options?: { deferConnectPluginIds?: ReadonlySet<string> }): Promise<void> {\n if (!this.initialized) {\n throw new Error('Channels not initialized');\n }\n if (this.running) {\n log.warn(\n { pluginCount: this.opts.registry.ids().length },\n 'start() called while channels already running — skipping',\n );\n return;\n }\n\n const deferIds = options?.deferConnectPluginIds ?? new Set<string>();\n this.deferredConnectPending.clear();\n\n const cfg = this.opts.getConfig();\n const startPromises: Promise<void>[] = [];\n\n for (const [id, plugin] of this.opts.registry.entries()) {\n const channelConfig = asChannelConfig(cfg.channels?.[id]);\n if (!this.shouldRunChannelPlugin(plugin, channelConfig)) continue;\n\n if (deferIds.has(id)) {\n this.deferredConnectPending.add(id);\n log.info({ channel: id }, 'Channel connect deferred until HTTP listen');\n continue;\n }\n\n startPromises.push(\n this.startPlugin(plugin, {}).catch((err) => {\n log.error({ channel: id, err }, 'Failed to start channel plugin');\n }),\n );\n }\n\n await Promise.allSettled(startPromises);\n this.running = true;\n log.info(\n { deferred: [...this.deferredConnectPending] },\n this.deferredConnectPending.size > 0\n ? 'Channel plugins started (deferred connects pending)'\n : 'All channel plugins started',\n );\n }\n\n /** Phase 2: `start()` for channels deferred at Phase 1. No-op if none pending. */\n async startDeferredConnects(): Promise<void> {\n if (this.deferredConnectPending.size === 0) return;\n if (!this.running) {\n log.warn('startDeferredConnects called before channel phase-1 start; skipping');\n return;\n }\n const ids = [...this.deferredConnectPending];\n this.deferredConnectPending.clear();\n const cfg = this.opts.getConfig();\n const startPromises: Promise<void>[] = [];\n for (const id of ids) {\n const plugin = this.opts.registry.get(id);\n if (!plugin) continue;\n const channelConfig = asChannelConfig(cfg.channels?.[id]);\n if (!this.shouldRunChannelPlugin(plugin, channelConfig)) continue;\n startPromises.push(\n this.startPlugin(plugin, {}).catch((err) => {\n log.error({ channel: id, err }, 'Failed to start deferred channel plugin');\n }),\n );\n }\n await Promise.allSettled(startPromises);\n log.info({ channels: ids }, 'Deferred channel connects completed');\n }\n\n async stop(): Promise<void> {\n if (!this.running) return;\n\n this.deferredConnectPending.clear();\n\n const stopPromises: Promise<void>[] = [];\n for (const id of this.initializedPluginIds) {\n const plugin = this.opts.registry.get(id);\n if (!plugin) continue;\n stopPromises.push(\n this.stopPlugin(plugin).catch((err) => {\n log.error({ channel: id, err }, 'Failed to stop channel plugin');\n }),\n );\n }\n\n await Promise.allSettled(stopPromises);\n this.running = false;\n log.info('All channel plugins stopped');\n }\n\n /** Stop one channel and suppress automatic restart until `startChannel` is called. */\n async stopChannel(channelId: string): Promise<void> {\n this.manuallyStopped.add(channelId);\n const plugin = this.opts.registry.get(channelId);\n if (!plugin || !this.initializedPluginIds.has(channelId)) {\n return;\n }\n await this.stopPlugin(plugin).catch((err) => {\n log.error({ channel: channelId, err }, 'Failed to stop channel plugin');\n });\n }\n\n /** Clear manual-stop and start one channel (requires prior `initialize()`). */\n async startChannel(channelId: string): Promise<void> {\n this.manuallyStopped.delete(channelId);\n const plugin = this.opts.registry.get(channelId);\n if (!plugin) {\n log.warn({ channel: channelId }, 'Unknown channel');\n return;\n }\n if (!this.initialized) {\n log.warn({ channel: channelId }, 'Channels not initialized');\n return;\n }\n const cfg = this.opts.getConfig();\n const channelConfig = asChannelConfig(cfg.channels?.[channelId]);\n if (!this.shouldRunChannelPlugin(plugin, channelConfig)) {\n log.debug({ channel: channelId }, 'Channel disabled in config, skipping start');\n return;\n }\n if (!this.initializedPluginIds.has(channelId)) {\n log.warn({ channel: channelId }, 'Channel was never initialized; call initialize() first');\n return;\n }\n await this.startPlugin(plugin, {});\n }\n\n /** Called by heartbeat: stop + start without clearing manualStop. No-op if user stopped it. */\n async softRestart(channelId: string): Promise<void> {\n if (this.manuallyStopped.has(channelId)) return;\n const plugin = this.opts.registry.get(channelId);\n if (!plugin || !this.initializedPluginIds.has(channelId)) return;\n try {\n await this.stopPlugin(plugin);\n await this.startPlugin(plugin, {});\n } catch (err) {\n log.error({ channel: channelId, err }, 'Channel soft restart after heartbeat failed');\n }\n }\n\n /** Forward a config snapshot to every initialised plugin's `onConfigUpdated` hook. */\n async forwardConfigUpdate(cfg: Config): Promise<void> {\n for (const id of this.initializedPluginIds) {\n const plugin = this.opts.registry.get(id);\n if (plugin?.onConfigUpdated) {\n await Promise.resolve(plugin.onConfigUpdated(cfg));\n }\n }\n }\n\n // ── Internals ───────────────────────────────────────────────────────────\n\n /**\n * Builtin channels require `channels.<id>.enabled`. Extension-managed channels\n * run unless explicitly disabled.\n */\n private shouldRunChannelPlugin(\n plugin: ChannelPlugin,\n channelConfig: Record<string, unknown> | undefined,\n ): boolean {\n if (plugin.extensionManagedConfig) {\n return channelConfig?.enabled !== false;\n }\n return !!channelConfig?.enabled;\n }\n\n private async initializePlugin(\n plugin: ChannelPlugin,\n channelConfig: Record<string, unknown>,\n ): Promise<void> {\n try {\n const options: ChannelPluginInitOptions = {\n bus: this.opts.bus,\n config: this.opts.getConfig(),\n channelConfig,\n sessionModel: this.opts.getSessionModelHooks?.(),\n };\n await plugin.init(options);\n this.initializedPluginIds.add(plugin.id);\n log.debug({ channel: plugin.id }, 'Channel plugin initialized');\n } catch (err) {\n log.error({ channel: plugin.id, err }, 'Failed to initialize channel plugin');\n }\n }\n\n private async startPlugin(\n plugin: ChannelPlugin,\n opts: { preserveRestartAttempts?: boolean },\n ): Promise<void> {\n const options: ChannelPluginStartOptions = {};\n try {\n await plugin.start(options);\n if (!opts.preserveRestartAttempts) {\n this.restartAttempts.delete(plugin.id);\n }\n this.opts.onPluginStarted?.(plugin);\n log.debug({ channel: plugin.id }, 'Channel plugin started');\n } catch (err) {\n const attempt = (this.restartAttempts.get(plugin.id) ?? 0) + 1;\n this.restartAttempts.set(plugin.id, attempt);\n if (attempt <= CHANNEL_RESTART_POLICY.maxAttempts) {\n const delayMs = computeBackoff(CHANNEL_RESTART_POLICY, attempt);\n log.warn(\n { channel: plugin.id, attempt, delayMs, err },\n 'Channel failed to start, scheduling restart',\n );\n setTimeout(() => {\n if (this.manuallyStopped.has(plugin.id)) {\n log.debug({ channel: plugin.id }, 'Skipping scheduled restart (manual stop)');\n return;\n }\n void this.startPlugin(plugin, { preserveRestartAttempts: true }).catch((e) => {\n log.error({ channel: plugin.id, err: e }, 'Channel restart attempt failed');\n });\n }, delayMs);\n } else {\n log.error({ channel: plugin.id, err }, 'Channel exceeded max restart attempts');\n }\n }\n }\n\n private async stopPlugin(plugin: ChannelPlugin): Promise<void> {\n this.opts.onPluginStopped?.(plugin.id);\n await plugin.stop();\n log.info({ channel: plugin.id }, 'Channel plugin stopped');\n }\n}\n"],"mappings":"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"}
@@ -41,6 +41,7 @@ export declare class ChannelManager {
41
41
  /** Channel IDs whose runtime reports connected (e.g. Telegram polling active). */
42
42
  getRunningChannels(): string[];
43
43
  initialize(): Promise<void>;
44
+ initializeChannel(channelId: string): Promise<boolean>;
44
45
  start(options?: {
45
46
  deferConnectPluginIds?: ReadonlySet<string>;
46
47
  }): Promise<void>;
@@ -68,6 +68,9 @@ var ChannelManager = class {
68
68
  initialize() {
69
69
  return this.lifecycle.initialize();
70
70
  }
71
+ initializeChannel(channelId) {
72
+ return this.lifecycle.initializeChannel(channelId);
73
+ }
71
74
  start(options) {
72
75
  return this.lifecycle.start(options);
73
76
  }