@xopcai/xopc 0.0.83 → 0.0.85

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 (457) hide show
  1. package/README.md +2 -0
  2. package/README.zh-CN.md +3 -1
  3. package/dist/browser-ext/manifest.json +1 -1
  4. package/dist/extensions/feishu/src/outbound/media-load.js +1 -1
  5. package/dist/extensions/feishu/src/plugin.d.ts +2 -0
  6. package/dist/extensions/feishu/src/plugin.js +10 -0
  7. package/dist/extensions/feishu/src/plugin.js.map +1 -1
  8. package/dist/extensions/feishu/src/workflow-progress.d.ts +27 -0
  9. package/dist/extensions/feishu/src/workflow-progress.js +99 -0
  10. package/dist/extensions/feishu/src/workflow-progress.js.map +1 -0
  11. package/dist/extensions/telegram/src/plugin.d.ts +2 -0
  12. package/dist/extensions/telegram/src/plugin.js +11 -1
  13. package/dist/extensions/telegram/src/plugin.js.map +1 -1
  14. package/dist/extensions/telegram/src/routing-integration.js +2 -2
  15. package/dist/extensions/telegram/src/workflow-progress.d.ts +24 -0
  16. package/dist/extensions/telegram/src/workflow-progress.js +73 -0
  17. package/dist/extensions/telegram/src/workflow-progress.js.map +1 -0
  18. package/dist/extensions/telegram/xopc.extension.json +1 -1
  19. package/dist/extensions/weixin/src/__tests__/workflow-progress.test.js +158 -0
  20. package/dist/extensions/weixin/src/__tests__/workflow-progress.test.js.map +1 -0
  21. package/dist/extensions/weixin/src/api/api.js +2 -2
  22. package/dist/extensions/weixin/src/auth/accounts.js +1 -1
  23. package/dist/extensions/weixin/src/cdn/upload.js +1 -1
  24. package/dist/extensions/weixin/src/media/data-url.js +1 -1
  25. package/dist/extensions/weixin/src/messaging/debug-mode.js +1 -1
  26. package/dist/extensions/weixin/src/messaging/inbound.js +1 -1
  27. package/dist/extensions/weixin/src/messaging/process-message.js +1 -1
  28. package/dist/extensions/weixin/src/plugin.d.ts +2 -0
  29. package/dist/extensions/weixin/src/plugin.js +11 -1
  30. package/dist/extensions/weixin/src/plugin.js.map +1 -1
  31. package/dist/extensions/weixin/src/storage/sync-buf.js +1 -1
  32. package/dist/extensions/weixin/src/workflow-progress.d.ts +26 -0
  33. package/dist/extensions/weixin/src/workflow-progress.js +99 -0
  34. package/dist/extensions/weixin/src/workflow-progress.js.map +1 -0
  35. package/dist/gateway/static/root/assets/agents-D3_-kNlZ.js +222 -0
  36. package/dist/gateway/static/root/assets/apps-page-D7v7649T.js +1 -0
  37. package/dist/gateway/static/root/assets/channels-settings-nCaMb0a7.js +1 -0
  38. package/dist/gateway/static/root/assets/channels-status-swr-C1gZBcJV.js +8 -0
  39. package/dist/gateway/static/root/assets/createLucideIcon-DPHK1VkS.js +1 -0
  40. package/dist/gateway/static/root/assets/cron-api-CoYK0hlm.js +1 -0
  41. package/dist/gateway/static/root/assets/cron-page-DeGo-Vjc.js +1 -0
  42. package/dist/gateway/static/root/assets/dist-BTWC-BTN.js +45 -0
  43. package/dist/gateway/static/root/assets/{dist-BpQxde0t.js → dist-DaK4dsss.js} +1 -1
  44. package/dist/gateway/static/root/assets/{extension-debug-page-CY27wj_p.js → extension-debug-page-BZngZWbO.js} +1 -1
  45. package/dist/gateway/static/root/assets/extension-page-D6JSyV27.js +1 -0
  46. package/dist/gateway/static/root/assets/extension-settings-page-8PZcmWI7.js +1 -0
  47. package/dist/gateway/static/root/assets/fetch-B2MYHbWg.js +1 -0
  48. package/dist/gateway/static/root/assets/{field-primitives-fa_hiQcX.js → field-primitives-Zzl22MvN.js} +1 -1
  49. package/dist/gateway/static/root/assets/heartbeat-config-api-BtIcpG0O.js +1 -0
  50. package/dist/gateway/static/root/assets/index-D4vM3-P7.js +4700 -0
  51. package/dist/gateway/static/root/assets/index-ew_2L2We.css +1 -0
  52. package/dist/gateway/static/root/assets/logs-page-_d4UJ-qQ.js +1 -0
  53. package/dist/gateway/static/root/assets/sessions-page-5N4aF2Wk.js +1 -0
  54. package/dist/gateway/static/root/assets/settings-form-section-D_tgb8r2.js +1 -0
  55. package/dist/gateway/static/root/assets/settings-page-C18xBt4X.js +3 -0
  56. package/dist/gateway/static/root/assets/share-preview-page-D4EG_vM1.js +2 -0
  57. package/dist/gateway/static/root/assets/skills-page-sPAXhh8w.js +2 -0
  58. package/dist/gateway/static/root/assets/theme-store-DryYl3qD.js +1 -0
  59. package/dist/gateway/static/root/assets/url-BwNL6Rgk.js +3 -0
  60. package/dist/gateway/static/root/assets/utils-CYO9eTCM.js +1 -0
  61. package/dist/gateway/static/root/assets/voice-api-key-field-Ds51havm.js +1 -0
  62. package/dist/gateway/static/root/index.html +7 -6
  63. package/dist/package.js +1 -1
  64. package/dist/src/agent/agent-manager.js +7 -7
  65. package/dist/src/agent/bootstrap/load-bootstrap-files.js +1 -1
  66. package/dist/src/agent/context/workspace-seed.js +3 -3
  67. package/dist/src/agent/embedded/map-stream-events.js +6 -0
  68. package/dist/src/agent/embedded/map-stream-events.js.map +1 -1
  69. package/dist/src/agent/embedded/subscribe-session.js +24 -0
  70. package/dist/src/agent/embedded/subscribe-session.js.map +1 -1
  71. package/dist/src/agent/embedded/types.d.ts +19 -0
  72. package/dist/src/agent/goals/goal-locale.js +2 -2
  73. package/dist/src/agent/goals/goal-run-store.js +4 -4
  74. package/dist/src/agent/goals/persistent-goal-service.js +1 -1
  75. package/dist/src/agent/goals/post-turn.js +2 -2
  76. package/dist/src/agent/image/load-image-media.js +2 -2
  77. package/dist/src/agent/ipc/bus.js +1 -1
  78. package/dist/src/agent/ipc/inbox.js +2 -2
  79. package/dist/src/agent/ipc/socket.js +1 -1
  80. package/dist/src/agent/memory/builtin-memory-store.js +1 -1
  81. package/dist/src/agent/memory/dreaming/deep-promotion.js +1 -1
  82. package/dist/src/agent/memory/dreaming/events.js +1 -1
  83. package/dist/src/agent/memory/dreaming/last-run.js +1 -1
  84. package/dist/src/agent/memory/dreaming/light-sweep.js +1 -1
  85. package/dist/src/agent/memory/dreaming/preview.js +1 -1
  86. package/dist/src/agent/memory/dreaming/rem-patterns.js +1 -1
  87. package/dist/src/agent/memory/dreaming/short-term-store.js +1 -1
  88. package/dist/src/agent/memory/dreaming/utils.js +1 -1
  89. package/dist/src/agent/memory/plugin-discovery.js +1 -1
  90. package/dist/src/agent/models/manager.js +1 -1
  91. package/dist/src/agent/prompt/service-prompt-builder.js +2 -2
  92. package/dist/src/agent/reply/post-compaction-context.js +1 -1
  93. package/dist/src/agent/reply/startup-context.d.ts +3 -0
  94. package/dist/src/agent/reply/startup-context.js +25 -2
  95. package/dist/src/agent/reply/startup-context.js.map +1 -1
  96. package/dist/src/agent/reply/workspace-boundary-read.js +1 -1
  97. package/dist/src/agent/sandbox/path-policy.js +2 -2
  98. package/dist/src/agent/service/build-direct-message-content.js +1 -1
  99. package/dist/src/agent/service.d.ts +1 -0
  100. package/dist/src/agent/service.js +10 -4
  101. package/dist/src/agent/service.js.map +1 -1
  102. package/dist/src/agent/session/session-inspector.js +1 -1
  103. package/dist/src/agent/skills/config.js +1 -1
  104. package/dist/src/agent/skills/hub-hash.js +2 -2
  105. package/dist/src/agent/skills/hub-lock.js +1 -1
  106. package/dist/src/agent/skills/hub-pull.js +3 -3
  107. package/dist/src/agent/skills/index.js +1 -1
  108. package/dist/src/agent/skills/managed-store.js +1 -1
  109. package/dist/src/agent/skills/scanner.js +1 -1
  110. package/dist/src/agent/skills/skill-manage-ops.js +1 -1
  111. package/dist/src/agent/skills/skill-manager.js +1 -1
  112. package/dist/src/agent/tools/create-share-tool.d.ts +27 -0
  113. package/dist/src/agent/tools/create-share-tool.js +237 -0
  114. package/dist/src/agent/tools/create-share-tool.js.map +1 -0
  115. package/dist/src/agent/tools/dreaming-tool.js +1 -1
  116. package/dist/src/agent/tools/factory.js +35 -1
  117. package/dist/src/agent/tools/factory.js.map +1 -1
  118. package/dist/src/agent/tools/image-generate-tool.js +1 -1
  119. package/dist/src/agent/tools/index.d.ts +2 -0
  120. package/dist/src/agent/tools/index.js +3 -1
  121. package/dist/src/agent/tools/send-media.js +1 -1
  122. package/dist/src/agent/tools/skill-manage-tool.js +1 -1
  123. package/dist/src/agent/tools/workflow-tool.d.ts +41 -0
  124. package/dist/src/agent/tools/workflow-tool.js +271 -0
  125. package/dist/src/agent/tools/workflow-tool.js.map +1 -0
  126. package/dist/src/agent/tools/write.js +1 -1
  127. package/dist/src/agent/workflow/builtins/audit-repo.d.ts +9 -0
  128. package/dist/src/agent/workflow/builtins/audit-repo.js +115 -0
  129. package/dist/src/agent/workflow/builtins/audit-repo.js.map +1 -0
  130. package/dist/src/agent/workflow/builtins/index.d.ts +15 -0
  131. package/dist/src/agent/workflow/builtins/index.js +28 -0
  132. package/dist/src/agent/workflow/builtins/index.js.map +1 -0
  133. package/dist/src/agent/workflow/builtins/multi-perspective-review.d.ts +9 -0
  134. package/dist/src/agent/workflow/builtins/multi-perspective-review.js +113 -0
  135. package/dist/src/agent/workflow/builtins/multi-perspective-review.js.map +1 -0
  136. package/dist/src/agent/workflow/builtins/research.d.ts +9 -0
  137. package/dist/src/agent/workflow/builtins/research.js +129 -0
  138. package/dist/src/agent/workflow/builtins/research.js.map +1 -0
  139. package/dist/src/agent/workflow/catalog.d.ts +51 -0
  140. package/dist/src/agent/workflow/catalog.js +155 -0
  141. package/dist/src/agent/workflow/catalog.js.map +1 -0
  142. package/dist/src/agent/workflow/channel-capability.d.ts +76 -0
  143. package/dist/src/agent/workflow/channel-capability.js +1 -0
  144. package/dist/src/agent/workflow/index.d.ts +11 -0
  145. package/dist/src/agent/workflow/index.js +10 -0
  146. package/dist/src/agent/workflow/last-run-memory.d.ts +42 -0
  147. package/dist/src/agent/workflow/last-run-memory.js +60 -0
  148. package/dist/src/agent/workflow/last-run-memory.js.map +1 -0
  149. package/dist/src/agent/workflow/parser.d.ts +20 -0
  150. package/dist/src/agent/workflow/parser.js +137 -0
  151. package/dist/src/agent/workflow/parser.js.map +1 -0
  152. package/dist/src/agent/workflow/progress-broker.d.ts +80 -0
  153. package/dist/src/agent/workflow/progress-broker.js +263 -0
  154. package/dist/src/agent/workflow/progress-broker.js.map +1 -0
  155. package/dist/src/agent/workflow/runtime.d.ts +31 -0
  156. package/dist/src/agent/workflow/runtime.js +301 -0
  157. package/dist/src/agent/workflow/runtime.js.map +1 -0
  158. package/dist/src/agent/workflow/snapshot.d.ts +18 -0
  159. package/dist/src/agent/workflow/snapshot.js +144 -0
  160. package/dist/src/agent/workflow/snapshot.js.map +1 -0
  161. package/dist/src/agent/workflow/structured-output-tool.d.ts +33 -0
  162. package/dist/src/agent/workflow/structured-output-tool.js +58 -0
  163. package/dist/src/agent/workflow/structured-output-tool.js.map +1 -0
  164. package/dist/src/agent/workflow/subagent-runner.d.ts +42 -0
  165. package/dist/src/agent/workflow/subagent-runner.js +104 -0
  166. package/dist/src/agent/workflow/subagent-runner.js.map +1 -0
  167. package/dist/src/agent/workflow/types.d.ts +137 -0
  168. package/dist/src/agent/workflow/types.js +1 -0
  169. package/dist/src/auth/credentials.js +3 -3
  170. package/dist/src/auth/profiles/store.js +1 -1
  171. package/dist/src/auth/sync-provider-auth.js +1 -1
  172. package/dist/src/browser/cache-dir-policy.js +1 -1
  173. package/dist/src/browser/cdp-local-launcher.js +2 -2
  174. package/dist/src/browser/providers/browser-ext-install.js +4 -4
  175. package/dist/src/browser/providers/cloakbrowser.js +4 -4
  176. package/dist/src/browser/providers/playwright-doctor.js +1 -1
  177. package/dist/src/browser/stealth.js +1 -1
  178. package/dist/src/channels/attachments/inbound-persist.js +1 -1
  179. package/dist/src/channels/attachments/outbound-tts-persist.js +1 -1
  180. package/dist/src/channels/outbound/persist-store.js +1 -1
  181. package/dist/src/channels/pairing/allow-from-file.js +1 -1
  182. package/dist/src/channels/pairing/pairing-store.js +2 -2
  183. package/dist/src/chat-commands/builtins/config.js +2 -2
  184. package/dist/src/chat-commands/builtins/model.js +40 -23
  185. package/dist/src/chat-commands/builtins/model.js.map +1 -1
  186. package/dist/src/chat-commands/builtins/system.js +30 -15
  187. package/dist/src/chat-commands/builtins/system.js.map +1 -1
  188. package/dist/src/chat-commands/builtins/workflow.d.ts +18 -0
  189. package/dist/src/chat-commands/builtins/workflow.js +167 -0
  190. package/dist/src/chat-commands/builtins/workflow.js.map +1 -0
  191. package/dist/src/chat-commands/context.js +1 -1
  192. package/dist/src/chat-commands/format-output.d.ts +28 -0
  193. package/dist/src/chat-commands/format-output.js +45 -0
  194. package/dist/src/chat-commands/format-output.js.map +1 -0
  195. package/dist/src/chat-commands/index.d.ts +1 -0
  196. package/dist/src/chat-commands/index.js +3 -1
  197. package/dist/src/chat-commands/index.js.map +1 -1
  198. package/dist/src/cli/command-catalog.js +110 -8
  199. package/dist/src/cli/command-catalog.js.map +1 -1
  200. package/dist/src/cli/command-loaders.js +2 -0
  201. package/dist/src/cli/command-loaders.js.map +1 -1
  202. package/dist/src/cli/command-manifest.js +9 -1
  203. package/dist/src/cli/command-manifest.js.map +1 -1
  204. package/dist/src/cli/commands/config.js +71 -20
  205. package/dist/src/cli/commands/config.js.map +1 -1
  206. package/dist/src/cli/commands/cron-cli.d.ts +2 -0
  207. package/dist/src/cli/commands/cron-cli.js +15 -0
  208. package/dist/src/cli/commands/cron-cli.js.map +1 -0
  209. package/dist/src/cli/commands/cron.d.ts +4 -1
  210. package/dist/src/cli/commands/cron.js +76 -41
  211. package/dist/src/cli/commands/cron.js.map +1 -1
  212. package/dist/src/cli/commands/doctor/checks/channel-config.js +1 -1
  213. package/dist/src/cli/commands/doctor/checks/channel-config.js.map +1 -1
  214. package/dist/src/cli/commands/doctor/checks/config-health.js +2 -2
  215. package/dist/src/cli/commands/doctor/checks/config-health.js.map +1 -1
  216. package/dist/src/cli/commands/doctor/checks/cron-health.js +1 -1
  217. package/dist/src/cli/commands/doctor/checks/cron-health.js.map +1 -1
  218. package/dist/src/cli/commands/doctor/checks/gateway-health.js +2 -2
  219. package/dist/src/cli/commands/doctor/checks/gateway-health.js.map +1 -1
  220. package/dist/src/cli/commands/doctor/checks/gateway-service.js +2 -2
  221. package/dist/src/cli/commands/doctor/checks/gateway-service.js.map +1 -1
  222. package/dist/src/cli/commands/doctor/checks/provider-auth.js +1 -1
  223. package/dist/src/cli/commands/doctor/checks/session-integrity.js +1 -1
  224. package/dist/src/cli/commands/doctor/checks/state-integrity.js +2 -2
  225. package/dist/src/cli/commands/doctor/checks/state-integrity.js.map +1 -1
  226. package/dist/src/cli/commands/doctor/checks/workspace-status.js +4 -4
  227. package/dist/src/cli/commands/doctor/checks/workspace-status.js.map +1 -1
  228. package/dist/src/cli/commands/extension-dev.js +1 -1
  229. package/dist/src/cli/commands/extension-marketplace.js +1 -1
  230. package/dist/src/cli/commands/extension-pack.js +1 -1
  231. package/dist/src/cli/commands/gateway/index.d.ts +1 -1
  232. package/dist/src/cli/commands/gateway/index.js +2 -2
  233. package/dist/src/cli/commands/gateway/lifecycle.js +10 -4
  234. package/dist/src/cli/commands/gateway/lifecycle.js.map +1 -1
  235. package/dist/src/cli/commands/gateway/service.d.ts +4 -0
  236. package/dist/src/cli/commands/gateway/service.js +17 -2
  237. package/dist/src/cli/commands/gateway/service.js.map +1 -1
  238. package/dist/src/cli/commands/gateway/shared.js +1 -1
  239. package/dist/src/cli/commands/gateway/subcommands.js +1 -4
  240. package/dist/src/cli/commands/gateway/subcommands.js.map +1 -1
  241. package/dist/src/cli/commands/image.js +1 -1
  242. package/dist/src/cli/commands/init.js +31 -4
  243. package/dist/src/cli/commands/init.js.map +1 -1
  244. package/dist/src/cli/commands/models.d.ts +4 -1
  245. package/dist/src/cli/commands/models.js +86 -74
  246. package/dist/src/cli/commands/models.js.map +1 -1
  247. package/dist/src/cli/commands/onboard.js +4 -2
  248. package/dist/src/cli/commands/onboard.js.map +1 -1
  249. package/dist/src/cli/commands/profile.d.ts +3 -5
  250. package/dist/src/cli/commands/profile.js +31 -31
  251. package/dist/src/cli/commands/profile.js.map +1 -1
  252. package/dist/src/cli/commands/setup.js +6 -1
  253. package/dist/src/cli/commands/setup.js.map +1 -1
  254. package/dist/src/cli/commands/tunnel.js +2 -2
  255. package/dist/src/cli/gateway-run-argv.js +15 -5
  256. package/dist/src/cli/gateway-run-argv.js.map +1 -1
  257. package/dist/src/cli/utils/gateway-client.js +1 -1
  258. package/dist/src/cli/utils/init-workspace-core.js +2 -2
  259. package/dist/src/config/agent-profile.js +1 -1
  260. package/dist/src/config/gateway-bind.js +1 -1
  261. package/dist/src/config/index.js +5 -5
  262. package/dist/src/config/loader.js +2 -2
  263. package/dist/src/config/models-json.js +2 -2
  264. package/dist/src/config/paths-state.js +1 -1
  265. package/dist/src/config/profile.js +2 -2
  266. package/dist/src/config/public-url.d.ts +28 -0
  267. package/dist/src/config/public-url.js +103 -0
  268. package/dist/src/config/public-url.js.map +1 -0
  269. package/dist/src/config/schema.d.ts +82 -0
  270. package/dist/src/config/schema.js +130 -1
  271. package/dist/src/config/schema.js.map +1 -1
  272. package/dist/src/config/workspace-path.js +1 -1
  273. package/dist/src/cron/executor.js +2 -2
  274. package/dist/src/cron/persistence.js +1 -1
  275. package/dist/src/cron/run-log-store.js +1 -1
  276. package/dist/src/daemon/constants.js +1 -1
  277. package/dist/src/daemon/install-plan.js +3 -3
  278. package/dist/src/daemon/install-plan.js.map +1 -1
  279. package/dist/src/daemon/launchd.js +2 -2
  280. package/dist/src/daemon/schtasks.js +38 -1
  281. package/dist/src/daemon/schtasks.js.map +1 -1
  282. package/dist/src/daemon/systemd.js +2 -2
  283. package/dist/src/extensions/bundle-mcp.js +1 -1
  284. package/dist/src/extensions/discover-extensions.js +1 -1
  285. package/dist/src/extensions/health.js +1 -1
  286. package/dist/src/extensions/loader.js +1 -1
  287. package/dist/src/extensions/lockfile.js +2 -2
  288. package/dist/src/gateway/agents-admin.js +2 -2
  289. package/dist/src/gateway/file-path-classifier.js +2 -2
  290. package/dist/src/gateway/heartbeat/service.js +1 -1
  291. package/dist/src/gateway/hono/app.js +33 -2
  292. package/dist/src/gateway/hono/app.js.map +1 -1
  293. package/dist/src/gateway/hono/lib/config-payload.js +1 -1
  294. package/dist/src/gateway/hono/lib/extension-store.js +2 -2
  295. package/dist/src/gateway/hono/lib/static-ui.js +2 -2
  296. package/dist/src/gateway/hono/oauth.js +1 -1
  297. package/dist/src/gateway/hono/routes/agents.js +1 -1
  298. package/dist/src/gateway/hono/routes/auth-registry-extensions.js +1 -1
  299. package/dist/src/gateway/hono/routes/config-patch/misc.js +1 -1
  300. package/dist/src/gateway/hono/routes/dreaming.js +1 -1
  301. package/dist/src/gateway/hono/routes/host-fs.js +2 -2
  302. package/dist/src/gateway/hono/routes/lazy-bundles.js +8 -0
  303. package/dist/src/gateway/hono/routes/lazy-bundles.js.map +1 -1
  304. package/dist/src/gateway/hono/routes/models.js +1 -1
  305. package/dist/src/gateway/hono/routes/shares.js +631 -34
  306. package/dist/src/gateway/hono/routes/shares.js.map +1 -1
  307. package/dist/src/gateway/hono/routes/site-shares.d.ts +3 -0
  308. package/dist/src/gateway/hono/routes/site-shares.js +228 -0
  309. package/dist/src/gateway/hono/routes/site-shares.js.map +1 -0
  310. package/dist/src/gateway/hono/routes/tunnel.js +97 -8
  311. package/dist/src/gateway/hono/routes/tunnel.js.map +1 -1
  312. package/dist/src/gateway/hono/routes/workspace.js +5 -5
  313. package/dist/src/gateway/hono/sse.js +2 -2
  314. package/dist/src/gateway/host.d.ts +3 -1
  315. package/dist/src/gateway/host.js +3 -1
  316. package/dist/src/gateway/host.js.map +1 -1
  317. package/dist/src/gateway/lock.js +3 -3
  318. package/dist/src/gateway/ports.d.ts +6 -0
  319. package/dist/src/gateway/ports.js +38 -2
  320. package/dist/src/gateway/ports.js.map +1 -1
  321. package/dist/src/gateway/public-url.d.ts +8 -0
  322. package/dist/src/gateway/public-url.js +10 -0
  323. package/dist/src/gateway/public-url.js.map +1 -0
  324. package/dist/src/gateway/security/origin-check.d.ts +9 -1
  325. package/dist/src/gateway/security/origin-check.js +4 -0
  326. package/dist/src/gateway/security/origin-check.js.map +1 -1
  327. package/dist/src/gateway/server.js +15 -0
  328. package/dist/src/gateway/server.js.map +1 -1
  329. package/dist/src/gateway/service/agent-runner.js +2 -2
  330. package/dist/src/gateway/service/marketplace-service.js +2 -2
  331. package/dist/src/gateway/service/run-gateway-agent.js +2 -2
  332. package/dist/src/gateway/service.js +3 -2
  333. package/dist/src/gateway/service.js.map +1 -1
  334. package/dist/src/gateway/workspace-fs-file-list.js +1 -1
  335. package/dist/src/heartbeat/index.js +1 -1
  336. package/dist/src/i18n/goals-bundle.js +1 -1
  337. package/dist/src/i18n/index.d.ts +1 -0
  338. package/dist/src/i18n/index.js +2 -1
  339. package/dist/src/i18n/locales/share-tool.en.js +15 -0
  340. package/dist/src/i18n/locales/share-tool.en.js.map +1 -0
  341. package/dist/src/i18n/locales/share-tool.zh.js +15 -0
  342. package/dist/src/i18n/locales/share-tool.zh.js.map +1 -0
  343. package/dist/src/i18n/share-tool-bundle.d.ts +20 -0
  344. package/dist/src/i18n/share-tool-bundle.js +56 -0
  345. package/dist/src/i18n/share-tool-bundle.js.map +1 -0
  346. package/dist/src/infra/gateway-processes.js +1 -0
  347. package/dist/src/infra/gateway-processes.js.map +1 -1
  348. package/dist/src/infra/restart.js +2 -2
  349. package/dist/src/infra/update-check.js +1 -1
  350. package/dist/src/infra/update-lock.js +3 -3
  351. package/dist/src/infra/update-runner.js +1 -1
  352. package/dist/src/infra/update-startup.js +2 -2
  353. package/dist/src/infra/write-file-atomic.js +2 -2
  354. package/dist/src/providers/auth-runtime/auth-profile-store.js +1 -1
  355. package/dist/src/providers/index.js +2 -2
  356. package/dist/src/providers/model-registry.js +1 -1
  357. package/dist/src/session/config-store.js +2 -2
  358. package/dist/src/session/parity/jsonl-transcript-io.js +2 -2
  359. package/dist/src/session/parity/sessions-json-file.js +1 -1
  360. package/dist/src/session/parity/transcript-file-lock.js +2 -2
  361. package/dist/src/session/parity/transcript-paths.js +1 -1
  362. package/dist/src/session/search-index-cache.js +1 -1
  363. package/dist/src/session/search-index.js +1 -1
  364. package/dist/src/session/session-title.js +3 -2
  365. package/dist/src/session/session-title.js.map +1 -1
  366. package/dist/src/session/store.js +5 -5
  367. package/dist/src/share/share-auto.d.ts +74 -0
  368. package/dist/src/share/share-auto.js +247 -0
  369. package/dist/src/share/share-auto.js.map +1 -0
  370. package/dist/src/share/share-config.js +63 -4
  371. package/dist/src/share/share-config.js.map +1 -1
  372. package/dist/src/share/share-landing.d.ts +28 -2
  373. package/dist/src/share/share-landing.js +155 -34
  374. package/dist/src/share/share-landing.js.map +1 -1
  375. package/dist/src/share/share-store.d.ts +48 -4
  376. package/dist/src/share/share-store.js +322 -51
  377. package/dist/src/share/share-store.js.map +1 -1
  378. package/dist/src/share/share-thumbnail.d.ts +35 -0
  379. package/dist/src/share/share-thumbnail.js +277 -0
  380. package/dist/src/share/share-thumbnail.js.map +1 -0
  381. package/dist/src/share/share-types.d.ts +68 -10
  382. package/dist/src/share/share-types.js +18 -1
  383. package/dist/src/share/share-types.js.map +1 -1
  384. package/dist/src/share/share-url.js +1 -1
  385. package/dist/src/share/share-zip.d.ts +35 -0
  386. package/dist/src/share/share-zip.js +303 -0
  387. package/dist/src/share/share-zip.js.map +1 -0
  388. package/dist/src/share/site-proxy.d.ts +35 -0
  389. package/dist/src/share/site-proxy.js +234 -0
  390. package/dist/src/share/site-proxy.js.map +1 -0
  391. package/dist/src/share/site-share-config.d.ts +11 -0
  392. package/dist/src/share/site-share-config.js +103 -0
  393. package/dist/src/share/site-share-config.js.map +1 -0
  394. package/dist/src/share/site-share-router.d.ts +23 -0
  395. package/dist/src/share/site-share-router.js +147 -0
  396. package/dist/src/share/site-share-router.js.map +1 -0
  397. package/dist/src/share/site-share-store.d.ts +53 -0
  398. package/dist/src/share/site-share-store.js +400 -0
  399. package/dist/src/share/site-share-store.js.map +1 -0
  400. package/dist/src/share/site-share-types.d.ts +103 -0
  401. package/dist/src/share/site-share-types.js +41 -0
  402. package/dist/src/share/site-share-types.js.map +1 -0
  403. package/dist/src/share/site-static-serve.d.ts +10 -0
  404. package/dist/src/share/site-static-serve.js +145 -0
  405. package/dist/src/share/site-static-serve.js.map +1 -0
  406. package/dist/src/tui/clipboard-image.js +3 -3
  407. package/dist/src/tui/theme-manager.js +1 -1
  408. package/dist/src/tui/tui-commands.js +18 -0
  409. package/dist/src/tui/tui-commands.js.map +1 -1
  410. package/dist/src/tui/tui-keybindings-file.js +1 -1
  411. package/dist/src/tui/tui-scoped-models.js +2 -2
  412. package/dist/src/tui/tui-settings.js +1 -1
  413. package/dist/src/tui/tui-workflow-slash.d.ts +32 -0
  414. package/dist/src/tui/tui-workflow-slash.js +63 -0
  415. package/dist/src/tui/tui-workflow-slash.js.map +1 -0
  416. package/dist/src/tui/tui.js +2 -2
  417. package/dist/src/tunnel/enable-lan-pairing.js +1 -1
  418. package/dist/src/tunnel/frpc-binary.js +3 -3
  419. package/dist/src/tunnel/frpc-config.js +1 -1
  420. package/dist/src/tunnel/frpc-extract.js +1 -1
  421. package/dist/src/tunnel/index.js +2 -2
  422. package/dist/src/tunnel/pair-context.d.ts +7 -1
  423. package/dist/src/tunnel/pair-context.js +25 -9
  424. package/dist/src/tunnel/pair-context.js.map +1 -1
  425. package/dist/src/tunnel/pair-url.d.ts +14 -1
  426. package/dist/src/tunnel/pair-url.js +14 -1
  427. package/dist/src/tunnel/pair-url.js.map +1 -1
  428. package/dist/src/tunnel/tunnel-service.js +2 -2
  429. package/dist/src/tunnel/tunnel-state.js +1 -1
  430. package/dist/src/utils/logger/audit.js +1 -1
  431. package/dist/src/utils/logger/log-store.js +1 -1
  432. package/dist/src/utils/logger/rotation.js +1 -1
  433. package/dist/src/voice/tts/audio.js +1 -1
  434. package/dist/src/voice/tts/providers/edge-speech.js +2 -2
  435. package/package.json +3 -2
  436. package/dist/gateway/static/root/assets/agents-CrpYTHJS.js +0 -222
  437. package/dist/gateway/static/root/assets/apps-page-1mcKh5Rh.js +0 -1
  438. package/dist/gateway/static/root/assets/button-KafIU8dx.js +0 -1
  439. package/dist/gateway/static/root/assets/channels-settings-zd6QNKPx.js +0 -1
  440. package/dist/gateway/static/root/assets/channels-status-swr-uRAuhiUo.js +0 -8
  441. package/dist/gateway/static/root/assets/cron-api-O2Q_ruV6.js +0 -1
  442. package/dist/gateway/static/root/assets/cron-page-By09AQD-.js +0 -1
  443. package/dist/gateway/static/root/assets/dist-C57OMHW8.js +0 -48
  444. package/dist/gateway/static/root/assets/extension-page-C-Ed5ZmP.js +0 -1
  445. package/dist/gateway/static/root/assets/extension-settings-page-raLux7E7.js +0 -1
  446. package/dist/gateway/static/root/assets/fetch-2iRFmd3n.js +0 -3
  447. package/dist/gateway/static/root/assets/heartbeat-config-api-BVl5VHvL.js +0 -1
  448. package/dist/gateway/static/root/assets/index-BuFldCsB.css +0 -1
  449. package/dist/gateway/static/root/assets/index-Y-iqo-gL.js +0 -4693
  450. package/dist/gateway/static/root/assets/logs-page-BdH2n7ZW.js +0 -1
  451. package/dist/gateway/static/root/assets/sessions-page-Vpchzdp-.js +0 -1
  452. package/dist/gateway/static/root/assets/settings-form-section-Kk1yAGBl.js +0 -1
  453. package/dist/gateway/static/root/assets/settings-page-KBm0u6Dz.js +0 -3
  454. package/dist/gateway/static/root/assets/skills-page-BjeXXaOn.js +0 -2
  455. package/dist/gateway/static/root/assets/theme-store-D01dJt95.js +0 -1
  456. package/dist/gateway/static/root/assets/utils-DpTxN4AF.js +0 -1
  457. package/dist/gateway/static/root/assets/voice-api-key-field-CwO8Cf01.js +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"command-catalog.js","names":[],"sources":["../../../src/cli/command-catalog.ts"],"sourcesContent":["export type CliExtensionLoadPolicy = 'never' | 'when-configured' | 'always';\nexport type CliGatewaySubcommandPolicy = 'lazy' | 'eager';\n\nexport type CliCommandPathPolicy = {\n loadExtensions: CliExtensionLoadPolicy;\n gatewaySubcommands: CliGatewaySubcommandPolicy;\n};\n\nexport type CliCommandCatalogEntry = {\n commandPath: readonly string[];\n exact?: boolean;\n policy?: Partial<CliCommandPathPolicy>;\n};\n\nexport const cliCommandCatalog: readonly CliCommandCatalogEntry[] = [\n { commandPath: ['setup'], policy: { loadExtensions: 'never' } },\n { commandPath: ['onboard'], policy: { loadExtensions: 'never' } },\n { commandPath: ['config'], policy: { loadExtensions: 'never' } },\n { commandPath: ['doctor'], policy: { loadExtensions: 'never' } },\n { commandPath: ['models'], policy: { loadExtensions: 'never' } },\n { commandPath: ['providers'], policy: { loadExtensions: 'never' } },\n { commandPath: ['auth'], policy: { loadExtensions: 'never' } },\n { commandPath: ['logs'], policy: { loadExtensions: 'never' } },\n { commandPath: ['update'], policy: { loadExtensions: 'never' } },\n { commandPath: ['session'], policy: { loadExtensions: 'never' } },\n { commandPath: ['cron'], policy: { loadExtensions: 'never' } },\n { commandPath: ['mcp'], policy: { loadExtensions: 'never' } },\n { commandPath: ['search'], policy: { loadExtensions: 'never' } },\n { commandPath: ['voice'], policy: { loadExtensions: 'never' } },\n { commandPath: ['image'], policy: { loadExtensions: 'never' } },\n { commandPath: ['skills'], policy: { loadExtensions: 'never' } },\n { commandPath: ['tailscale'], policy: { loadExtensions: 'never' } },\n { commandPath: ['tunnel'], policy: { loadExtensions: 'never' } },\n { commandPath: ['browser'], policy: { loadExtensions: 'never' } },\n { commandPath: ['tui'], policy: { loadExtensions: 'when-configured' } },\n { commandPath: ['agent'], policy: { loadExtensions: 'when-configured' } },\n { commandPath: ['channels'], policy: { loadExtensions: 'always' } },\n { commandPath: ['extensions'], policy: { loadExtensions: 'always' } },\n { commandPath: ['agents'], policy: { loadExtensions: 'when-configured' } },\n {\n commandPath: ['gateway'],\n exact: true,\n policy: { loadExtensions: 'never', gatewaySubcommands: 'lazy' },\n },\n { commandPath: ['gateway', 'token'], exact: true, policy: { loadExtensions: 'never' } },\n { commandPath: ['gateway', 'status'], exact: true, policy: { loadExtensions: 'never' } },\n { commandPath: ['gateway', 'health'], exact: true, policy: { loadExtensions: 'never' } },\n { commandPath: ['gateway', 'call'], exact: true, policy: { loadExtensions: 'never' } },\n { commandPath: ['gateway', 'probe'], exact: true, policy: { loadExtensions: 'never' } },\n { commandPath: ['gateway', 'stop'], exact: true, policy: { loadExtensions: 'never' } },\n { commandPath: ['gateway', 'restart'], exact: true, policy: { loadExtensions: 'never' } },\n { commandPath: ['gateway', 'logs'], exact: true, policy: { loadExtensions: 'never' } },\n { commandPath: ['gateway', 'install'], exact: true, policy: { loadExtensions: 'never' } },\n { commandPath: ['gateway', 'uninstall'], exact: true, policy: { loadExtensions: 'never' } },\n { commandPath: ['gateway', 'start'], exact: true, policy: { loadExtensions: 'never' } },\n { commandPath: ['gateway', 'service-status'], exact: true, policy: { loadExtensions: 'never' } },\n { commandPath: ['gateway', 'ssh-tunnel'], exact: true, policy: { loadExtensions: 'never' } },\n];\n"],"mappings":"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"}
1
+ {"version":3,"file":"command-catalog.js","names":[],"sources":["../../../src/cli/command-catalog.ts"],"sourcesContent":["export type CliExtensionLoadPolicy = 'never' | 'when-configured' | 'always';\nexport type CliGatewaySubcommandPolicy = 'lazy' | 'eager';\n\nexport type CliCommandPathPolicy = {\n loadExtensions: CliExtensionLoadPolicy;\n gatewaySubcommands: CliGatewaySubcommandPolicy;\n};\n\nexport type CliCommandCatalogEntry = {\n commandPath: readonly string[];\n exact?: boolean;\n policy?: Partial<CliCommandPathPolicy>;\n};\n\nexport const cliCommandCatalog: readonly CliCommandCatalogEntry[] = [\n { commandPath: ['init'], policy: { loadExtensions: 'never' } },\n { commandPath: ['profile'], policy: { loadExtensions: 'never' } },\n { commandPath: ['profile', 'list'], exact: true, policy: { loadExtensions: 'never' } },\n { commandPath: ['profile', 'create'], exact: true, policy: { loadExtensions: 'never' } },\n { commandPath: ['profile', 'delete'], exact: true, policy: { loadExtensions: 'never' } },\n { commandPath: ['profile', 'switch'], exact: true, policy: { loadExtensions: 'never' } },\n { commandPath: ['setup'], policy: { loadExtensions: 'never' } },\n { commandPath: ['onboard'], policy: { loadExtensions: 'never' } },\n { commandPath: ['cron'], policy: { loadExtensions: 'never' } },\n { commandPath: ['cron', 'list'], exact: true, policy: { loadExtensions: 'never' } },\n { commandPath: ['cron', 'add'], exact: true, policy: { loadExtensions: 'never' } },\n { commandPath: ['cron', 'remove'], exact: true, policy: { loadExtensions: 'never' } },\n { commandPath: ['cron', 'enable'], exact: true, policy: { loadExtensions: 'never' } },\n { commandPath: ['cron', 'disable'], exact: true, policy: { loadExtensions: 'never' } },\n { commandPath: ['cron', 'run'], exact: true, policy: { loadExtensions: 'never' } },\n { commandPath: ['cron', 'trigger'], exact: true, policy: { loadExtensions: 'never' } },\n { commandPath: ['config'], policy: { loadExtensions: 'never' } },\n { commandPath: ['doctor'], policy: { loadExtensions: 'never' } },\n { commandPath: ['models'], policy: { loadExtensions: 'never' } },\n { commandPath: ['providers'], policy: { loadExtensions: 'never' } },\n { commandPath: ['auth'], policy: { loadExtensions: 'never' } },\n { commandPath: ['logs'], policy: { loadExtensions: 'never' } },\n { commandPath: ['update'], policy: { loadExtensions: 'never' } },\n { commandPath: ['session'], policy: { loadExtensions: 'never' } },\n { commandPath: ['mcp'], policy: { loadExtensions: 'never' } },\n { commandPath: ['search'], policy: { loadExtensions: 'never' } },\n { commandPath: ['voice'], policy: { loadExtensions: 'never' } },\n { commandPath: ['image'], policy: { loadExtensions: 'never' } },\n { commandPath: ['skills'], policy: { loadExtensions: 'never' } },\n { commandPath: ['tailscale'], policy: { loadExtensions: 'never' } },\n { commandPath: ['tunnel'], policy: { loadExtensions: 'never' } },\n { commandPath: ['browser'], policy: { loadExtensions: 'never' } },\n { commandPath: ['tui'], policy: { loadExtensions: 'when-configured' } },\n { commandPath: ['agent'], policy: { loadExtensions: 'when-configured' } },\n { commandPath: ['channels'], policy: { loadExtensions: 'always' } },\n { commandPath: ['extensions'], policy: { loadExtensions: 'always' } },\n { commandPath: ['agents'], policy: { loadExtensions: 'when-configured' } },\n {\n commandPath: ['gateway'],\n exact: true,\n policy: { loadExtensions: 'never', gatewaySubcommands: 'lazy' },\n },\n { commandPath: ['gateway', 'token'], exact: true, policy: { loadExtensions: 'never' } },\n { commandPath: ['gateway', 'status'], exact: true, policy: { loadExtensions: 'never' } },\n { commandPath: ['gateway', 'health'], exact: true, policy: { loadExtensions: 'never' } },\n { commandPath: ['gateway', 'call'], exact: true, policy: { loadExtensions: 'never' } },\n { commandPath: ['gateway', 'probe'], exact: true, policy: { loadExtensions: 'never' } },\n { commandPath: ['gateway', 'stop'], exact: true, policy: { loadExtensions: 'never' } },\n { commandPath: ['gateway', 'restart'], exact: true, policy: { loadExtensions: 'never' } },\n { commandPath: ['gateway', 'logs'], exact: true, policy: { loadExtensions: 'never' } },\n { commandPath: ['gateway', 'service'], exact: true, policy: { loadExtensions: 'never' } },\n { commandPath: ['gateway', 'service', 'install'], exact: true, policy: { loadExtensions: 'never' } },\n { commandPath: ['gateway', 'service', 'uninstall'], exact: true, policy: { loadExtensions: 'never' } },\n { commandPath: ['gateway', 'service', 'start'], exact: true, policy: { loadExtensions: 'never' } },\n { commandPath: ['gateway', 'service', 'status'], exact: true, policy: { loadExtensions: 'never' } },\n { commandPath: ['gateway', 'service', 'stop'], exact: true, policy: { loadExtensions: 'never' } },\n { commandPath: ['gateway', 'service', 'restart'], exact: true, policy: { loadExtensions: 'never' } },\n { commandPath: ['gateway', 'ssh-tunnel'], exact: true, policy: { loadExtensions: 'never' } },\n];\n"],"mappings":"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"}
@@ -3,6 +3,8 @@ import { shouldLoadExtensionCliForCommandPath } from "./command-startup-policy.j
3
3
  import { registry } from "./registry.js";
4
4
  //#region src/cli/command-loaders.ts
5
5
  const REGISTRY_COMMAND_MODULES = {
6
+ init: () => import("./commands/init.js"),
7
+ profile: () => import("./commands/profile.js"),
6
8
  setup: () => import("./commands/setup.js"),
7
9
  onboard: () => import("./commands/onboard.js"),
8
10
  agent: () => import("./commands/agent.js"),
@@ -1 +1 @@
1
- {"version":3,"file":"command-loaders.js","names":[],"sources":["../../../src/cli/command-loaders.ts"],"sourcesContent":["/**\n * Lazy command loaders.\n *\n * Modules here trigger their `register({...})` side effect on import; the\n * caller then mounts the requested command via `registry.installOne` (or via\n * the explicit registrar functions for non-registry commands).\n *\n * Keeping this map static-but-thunked means `bin.ts` short-circuits and\n * `runCli` can resolve a single subcommand without paying for unrelated\n * command modules.\n */\nimport type { Command } from 'commander';\nimport { resolveCliCatalogCommandPath } from './command-path-policy.js';\nimport { shouldLoadExtensionCliForCommandPath } from './command-startup-policy.js';\nimport { registry, type CLIContext } from './registry.js';\n\nexport type CommandLoader = () => Promise<unknown>;\n\nexport const REGISTRY_COMMAND_MODULES: Record<string, CommandLoader> = {\n setup: () => import('./commands/setup.js'),\n onboard: () => import('./commands/onboard.js'),\n agent: () => import('./commands/agent.js'),\n tui: () => import('./commands/tui.js'),\n gateway: () => import('./commands/gateway.js'),\n session: () => import('./commands/session.js'),\n cron: () => import('./commands/cron.js'),\n config: () => import('./commands/config.js'),\n doctor: () => import('./commands/doctor/index.js'),\n image: () => import('./commands/image.js'),\n channels: () => import('./commands/channels.js'),\n models: () => import('./commands/models.js'),\n providers: () => import('./commands/providers.js'),\n voice: () => import('./commands/voice.js'),\n search: () => import('./commands/search.js'),\n auth: () => import('./commands/auth.js'),\n skills: () => import('./commands/skills.js'),\n browser: () => import('./commands/browser.js'),\n update: () => import('./commands/update.js'),\n logs: () => import('./commands/logs.js'),\n tunnel: () => import('./commands/tunnel.js'),\n tailscale: () => import('./commands/tailscale.js'),\n mcp: () => import('./commands/mcp.js'),\n};\n\nexport interface NonRegistryMatcher {\n matches: (name: string) => boolean;\n load: (program: Command) => Promise<void>;\n}\n\nexport const NON_REGISTRY_COMMAND_MATCHERS: NonRegistryMatcher[] = [\n {\n matches: (name) => name === 'agents' || name.startsWith('agents:'),\n load: async (program) => {\n const { registerAgentsCli } = await import('./commands/agents.js');\n registerAgentsCli(program);\n },\n },\n {\n matches: (name) => name === 'extensions',\n load: async (program) => {\n const { registerExtensionCommands } = await import('./commands/extension.js');\n registerExtensionCommands(program);\n const commandPath = resolveCliCatalogCommandPath(process.argv);\n if (shouldLoadExtensionCliForCommandPath(commandPath)) {\n const { registerExtensionCliCommands } = await import('./extension-cli-register.js');\n await registerExtensionCliCommands(program);\n }\n },\n },\n];\n\nconst FLAGS_WITH_VALUE = new Set(['--config', '--workspace']);\n\n/**\n * Resolve which command module to load based on argv. Skips global flags\n * (`--verbose`/`--config <path>`/`--workspace <path>`) and treats\n * `help <cmd>` as if the user had typed `<cmd>`, so that `xopc help gateway`\n * loads only the gateway module.\n */\nexport function resolveCommandName(argv: string[]): string | undefined {\n let i = 2;\n let firstSubcommand: string | undefined;\n while (i < argv.length) {\n const arg = argv[i];\n if (!arg) {\n i += 1;\n continue;\n }\n if (arg.startsWith('-')) {\n i += FLAGS_WITH_VALUE.has(arg) ? 2 : 1;\n continue;\n }\n if (firstSubcommand === undefined) {\n firstSubcommand = arg;\n if (arg === 'help') {\n i += 1;\n continue;\n }\n return arg;\n }\n return arg;\n }\n return firstSubcommand;\n}\n\nexport async function tryLoadCommand(\n program: Command,\n ctx: CLIContext,\n name: string,\n getCtx?: () => CLIContext,\n): Promise<boolean> {\n const moduleLoader = REGISTRY_COMMAND_MODULES[name];\n if (moduleLoader) {\n await moduleLoader();\n const installed = registry.installOne(program, name, ctx, getCtx);\n if (installed && name === 'gateway') {\n const gatewayCmd = program.commands.find((command) => command.name() === 'gateway');\n if (gatewayCmd) {\n const { prepareGatewayCommandForArgv } = await import('./commands/gateway.js');\n await prepareGatewayCommandForArgv(gatewayCmd, ctx);\n }\n }\n return installed;\n }\n const matcher = NON_REGISTRY_COMMAND_MATCHERS.find((m) => m.matches(name));\n if (matcher) {\n await matcher.load(program);\n return true;\n }\n return false;\n}\n\nexport async function loadAllCommands(\n program: Command,\n ctx: CLIContext,\n getCtx?: () => CLIContext,\n): Promise<void> {\n // Sequential to keep registration order deterministic; registry.install\n // sorts by category and is stable within a category.\n for (const loader of Object.values(REGISTRY_COMMAND_MODULES)) {\n await loader();\n }\n registry.install(program, ctx, getCtx);\n for (const matcher of NON_REGISTRY_COMMAND_MATCHERS) {\n await matcher.load(program);\n }\n const gatewayCmd = program.commands.find((command) => command.name() === 'gateway');\n if (gatewayCmd) {\n const { prepareGatewayCommandForArgv } = await import('./commands/gateway.js');\n await prepareGatewayCommandForArgv(gatewayCmd, ctx);\n }\n}\n"],"mappings":";;;;AAkBA,MAAa,2BAA0D;CACrE,aAAa,OAAO;CACpB,eAAe,OAAO;CACtB,aAAa,OAAO;CACpB,WAAW,OAAO;CAClB,eAAe,OAAO;CACtB,eAAe,OAAO;CACtB,YAAY,OAAO;CACnB,cAAc,OAAO;CACrB,cAAc,OAAO;CACrB,aAAa,OAAO;CACpB,gBAAgB,OAAO;CACvB,cAAc,OAAO;CACrB,iBAAiB,OAAO;CACxB,aAAa,OAAO;CACpB,cAAc,OAAO;CACrB,YAAY,OAAO;CACnB,cAAc,OAAO;CACrB,eAAe,OAAO;CACtB,cAAc,OAAO;CACrB,YAAY,OAAO;CACnB,cAAc,OAAO;CACrB,iBAAiB,OAAO;CACxB,WAAW,OAAO;CACnB;AAOD,MAAa,gCAAsD,CACjE;CACE,UAAU,SAAS,SAAS,YAAY,KAAK,WAAW,UAAU;CAClE,MAAM,OAAO,YAAY;EACvB,MAAM,EAAE,sBAAsB,MAAM,OAAO;AAC3C,oBAAkB,QAAQ;;CAE7B,EACD;CACE,UAAU,SAAS,SAAS;CAC5B,MAAM,OAAO,YAAY;EACvB,MAAM,EAAE,8BAA8B,MAAM,OAAO;AACnD,4BAA0B,QAAQ;AAElC,MAAI,qCADgB,6BAA6B,QAAQ,KACL,CAAC,EAAE;GACrD,MAAM,EAAE,iCAAiC,MAAM,OAAO;AACtD,SAAM,6BAA6B,QAAQ;;;CAGhD,CACF;AAED,MAAM,mBAAmB,IAAI,IAAI,CAAC,YAAY,cAAc,CAAC;;;;;;;AAQ7D,SAAgB,mBAAmB,MAAoC;CACrE,IAAI,IAAI;CACR,IAAI;AACJ,QAAO,IAAI,KAAK,QAAQ;EACtB,MAAM,MAAM,KAAK;AACjB,MAAI,CAAC,KAAK;AACR,QAAK;AACL;;AAEF,MAAI,IAAI,WAAW,IAAI,EAAE;AACvB,QAAK,iBAAiB,IAAI,IAAI,GAAG,IAAI;AACrC;;AAEF,MAAI,oBAAoB,KAAA,GAAW;AACjC,qBAAkB;AAClB,OAAI,QAAQ,QAAQ;AAClB,SAAK;AACL;;AAEF,UAAO;;AAET,SAAO;;AAET,QAAO;;AAGT,eAAsB,eACpB,SACA,KACA,MACA,QACkB;CAClB,MAAM,eAAe,yBAAyB;AAC9C,KAAI,cAAc;AAChB,QAAM,cAAc;EACpB,MAAM,YAAY,SAAS,WAAW,SAAS,MAAM,KAAK,OAAO;AACjE,MAAI,aAAa,SAAS,WAAW;GACnC,MAAM,aAAa,QAAQ,SAAS,MAAM,YAAY,QAAQ,MAAM,KAAK,UAAU;AACnF,OAAI,YAAY;IACd,MAAM,EAAE,iCAAiC,MAAM,OAAO;AACtD,UAAM,6BAA6B,YAAY,IAAI;;;AAGvD,SAAO;;CAET,MAAM,UAAU,8BAA8B,MAAM,MAAM,EAAE,QAAQ,KAAK,CAAC;AAC1E,KAAI,SAAS;AACX,QAAM,QAAQ,KAAK,QAAQ;AAC3B,SAAO;;AAET,QAAO;;AAGT,eAAsB,gBACpB,SACA,KACA,QACe;AAGf,MAAK,MAAM,UAAU,OAAO,OAAO,yBAAyB,CAC1D,OAAM,QAAQ;AAEhB,UAAS,QAAQ,SAAS,KAAK,OAAO;AACtC,MAAK,MAAM,WAAW,8BACpB,OAAM,QAAQ,KAAK,QAAQ;CAE7B,MAAM,aAAa,QAAQ,SAAS,MAAM,YAAY,QAAQ,MAAM,KAAK,UAAU;AACnF,KAAI,YAAY;EACd,MAAM,EAAE,iCAAiC,MAAM,OAAO;AACtD,QAAM,6BAA6B,YAAY,IAAI"}
1
+ {"version":3,"file":"command-loaders.js","names":[],"sources":["../../../src/cli/command-loaders.ts"],"sourcesContent":["/**\n * Lazy command loaders.\n *\n * Modules here trigger their `register({...})` side effect on import; the\n * caller then mounts the requested command via `registry.installOne` (or via\n * the explicit registrar functions for non-registry commands).\n *\n * Keeping this map static-but-thunked means `bin.ts` short-circuits and\n * `runCli` can resolve a single subcommand without paying for unrelated\n * command modules.\n */\nimport type { Command } from 'commander';\nimport { resolveCliCatalogCommandPath } from './command-path-policy.js';\nimport { shouldLoadExtensionCliForCommandPath } from './command-startup-policy.js';\nimport { registry, type CLIContext } from './registry.js';\n\nexport type CommandLoader = () => Promise<unknown>;\n\nexport const REGISTRY_COMMAND_MODULES: Record<string, CommandLoader> = {\n init: () => import('./commands/init.js'),\n profile: () => import('./commands/profile.js'),\n setup: () => import('./commands/setup.js'),\n onboard: () => import('./commands/onboard.js'),\n agent: () => import('./commands/agent.js'),\n tui: () => import('./commands/tui.js'),\n gateway: () => import('./commands/gateway.js'),\n session: () => import('./commands/session.js'),\n cron: () => import('./commands/cron.js'),\n config: () => import('./commands/config.js'),\n doctor: () => import('./commands/doctor/index.js'),\n image: () => import('./commands/image.js'),\n channels: () => import('./commands/channels.js'),\n models: () => import('./commands/models.js'),\n providers: () => import('./commands/providers.js'),\n voice: () => import('./commands/voice.js'),\n search: () => import('./commands/search.js'),\n auth: () => import('./commands/auth.js'),\n skills: () => import('./commands/skills.js'),\n browser: () => import('./commands/browser.js'),\n update: () => import('./commands/update.js'),\n logs: () => import('./commands/logs.js'),\n tunnel: () => import('./commands/tunnel.js'),\n tailscale: () => import('./commands/tailscale.js'),\n mcp: () => import('./commands/mcp.js'),\n};\n\nexport interface NonRegistryMatcher {\n matches: (name: string) => boolean;\n load: (program: Command) => Promise<void>;\n}\n\nexport const NON_REGISTRY_COMMAND_MATCHERS: NonRegistryMatcher[] = [\n {\n matches: (name) => name === 'agents' || name.startsWith('agents:'),\n load: async (program) => {\n const { registerAgentsCli } = await import('./commands/agents.js');\n registerAgentsCli(program);\n },\n },\n {\n matches: (name) => name === 'extensions',\n load: async (program) => {\n const { registerExtensionCommands } = await import('./commands/extension.js');\n registerExtensionCommands(program);\n const commandPath = resolveCliCatalogCommandPath(process.argv);\n if (shouldLoadExtensionCliForCommandPath(commandPath)) {\n const { registerExtensionCliCommands } = await import('./extension-cli-register.js');\n await registerExtensionCliCommands(program);\n }\n },\n },\n];\n\nconst FLAGS_WITH_VALUE = new Set(['--config', '--workspace']);\n\n/**\n * Resolve which command module to load based on argv. Skips global flags\n * (`--verbose`/`--config <path>`/`--workspace <path>`) and treats\n * `help <cmd>` as if the user had typed `<cmd>`, so that `xopc help gateway`\n * loads only the gateway module.\n */\nexport function resolveCommandName(argv: string[]): string | undefined {\n let i = 2;\n let firstSubcommand: string | undefined;\n while (i < argv.length) {\n const arg = argv[i];\n if (!arg) {\n i += 1;\n continue;\n }\n if (arg.startsWith('-')) {\n i += FLAGS_WITH_VALUE.has(arg) ? 2 : 1;\n continue;\n }\n if (firstSubcommand === undefined) {\n firstSubcommand = arg;\n if (arg === 'help') {\n i += 1;\n continue;\n }\n return arg;\n }\n return arg;\n }\n return firstSubcommand;\n}\n\nexport async function tryLoadCommand(\n program: Command,\n ctx: CLIContext,\n name: string,\n getCtx?: () => CLIContext,\n): Promise<boolean> {\n const moduleLoader = REGISTRY_COMMAND_MODULES[name];\n if (moduleLoader) {\n await moduleLoader();\n const installed = registry.installOne(program, name, ctx, getCtx);\n if (installed && name === 'gateway') {\n const gatewayCmd = program.commands.find((command) => command.name() === 'gateway');\n if (gatewayCmd) {\n const { prepareGatewayCommandForArgv } = await import('./commands/gateway.js');\n await prepareGatewayCommandForArgv(gatewayCmd, ctx);\n }\n }\n return installed;\n }\n const matcher = NON_REGISTRY_COMMAND_MATCHERS.find((m) => m.matches(name));\n if (matcher) {\n await matcher.load(program);\n return true;\n }\n return false;\n}\n\nexport async function loadAllCommands(\n program: Command,\n ctx: CLIContext,\n getCtx?: () => CLIContext,\n): Promise<void> {\n // Sequential to keep registration order deterministic; registry.install\n // sorts by category and is stable within a category.\n for (const loader of Object.values(REGISTRY_COMMAND_MODULES)) {\n await loader();\n }\n registry.install(program, ctx, getCtx);\n for (const matcher of NON_REGISTRY_COMMAND_MATCHERS) {\n await matcher.load(program);\n }\n const gatewayCmd = program.commands.find((command) => command.name() === 'gateway');\n if (gatewayCmd) {\n const { prepareGatewayCommandForArgv } = await import('./commands/gateway.js');\n await prepareGatewayCommandForArgv(gatewayCmd, ctx);\n }\n}\n"],"mappings":";;;;AAkBA,MAAa,2BAA0D;CACrE,YAAY,OAAO;CACnB,eAAe,OAAO;CACtB,aAAa,OAAO;CACpB,eAAe,OAAO;CACtB,aAAa,OAAO;CACpB,WAAW,OAAO;CAClB,eAAe,OAAO;CACtB,eAAe,OAAO;CACtB,YAAY,OAAO;CACnB,cAAc,OAAO;CACrB,cAAc,OAAO;CACrB,aAAa,OAAO;CACpB,gBAAgB,OAAO;CACvB,cAAc,OAAO;CACrB,iBAAiB,OAAO;CACxB,aAAa,OAAO;CACpB,cAAc,OAAO;CACrB,YAAY,OAAO;CACnB,cAAc,OAAO;CACrB,eAAe,OAAO;CACtB,cAAc,OAAO;CACrB,YAAY,OAAO;CACnB,cAAc,OAAO;CACrB,iBAAiB,OAAO;CACxB,WAAW,OAAO;CACnB;AAOD,MAAa,gCAAsD,CACjE;CACE,UAAU,SAAS,SAAS,YAAY,KAAK,WAAW,UAAU;CAClE,MAAM,OAAO,YAAY;EACvB,MAAM,EAAE,sBAAsB,MAAM,OAAO;AAC3C,oBAAkB,QAAQ;;CAE7B,EACD;CACE,UAAU,SAAS,SAAS;CAC5B,MAAM,OAAO,YAAY;EACvB,MAAM,EAAE,8BAA8B,MAAM,OAAO;AACnD,4BAA0B,QAAQ;AAElC,MAAI,qCADgB,6BAA6B,QAAQ,KACL,CAAC,EAAE;GACrD,MAAM,EAAE,iCAAiC,MAAM,OAAO;AACtD,SAAM,6BAA6B,QAAQ;;;CAGhD,CACF;AAED,MAAM,mBAAmB,IAAI,IAAI,CAAC,YAAY,cAAc,CAAC;;;;;;;AAQ7D,SAAgB,mBAAmB,MAAoC;CACrE,IAAI,IAAI;CACR,IAAI;AACJ,QAAO,IAAI,KAAK,QAAQ;EACtB,MAAM,MAAM,KAAK;AACjB,MAAI,CAAC,KAAK;AACR,QAAK;AACL;;AAEF,MAAI,IAAI,WAAW,IAAI,EAAE;AACvB,QAAK,iBAAiB,IAAI,IAAI,GAAG,IAAI;AACrC;;AAEF,MAAI,oBAAoB,KAAA,GAAW;AACjC,qBAAkB;AAClB,OAAI,QAAQ,QAAQ;AAClB,SAAK;AACL;;AAEF,UAAO;;AAET,SAAO;;AAET,QAAO;;AAGT,eAAsB,eACpB,SACA,KACA,MACA,QACkB;CAClB,MAAM,eAAe,yBAAyB;AAC9C,KAAI,cAAc;AAChB,QAAM,cAAc;EACpB,MAAM,YAAY,SAAS,WAAW,SAAS,MAAM,KAAK,OAAO;AACjE,MAAI,aAAa,SAAS,WAAW;GACnC,MAAM,aAAa,QAAQ,SAAS,MAAM,YAAY,QAAQ,MAAM,KAAK,UAAU;AACnF,OAAI,YAAY;IACd,MAAM,EAAE,iCAAiC,MAAM,OAAO;AACtD,UAAM,6BAA6B,YAAY,IAAI;;;AAGvD,SAAO;;CAET,MAAM,UAAU,8BAA8B,MAAM,MAAM,EAAE,QAAQ,KAAK,CAAC;AAC1E,KAAI,SAAS;AACX,QAAM,QAAQ,KAAK,QAAQ;AAC3B,SAAO;;AAET,QAAO;;AAGT,eAAsB,gBACpB,SACA,KACA,QACe;AAGf,MAAK,MAAM,UAAU,OAAO,OAAO,yBAAyB,CAC1D,OAAM,QAAQ;AAEhB,UAAS,QAAQ,SAAS,KAAK,OAAO;AACtC,MAAK,MAAM,WAAW,8BACpB,OAAM,QAAQ,KAAK,QAAQ;CAE7B,MAAM,aAAa,QAAQ,SAAS,MAAM,YAAY,QAAQ,MAAM,KAAK,UAAU;AACnF,KAAI,YAAY;EACd,MAAM,EAAE,iCAAiC,MAAM,OAAO;AACtD,QAAM,6BAA6B,YAAY,IAAI"}
@@ -23,10 +23,18 @@ const ROOT_HELP_OPTIONS = [
23
23
  }
24
24
  ];
25
25
  const ROOT_HELP_COMMANDS = [
26
+ {
27
+ name: "init [options]",
28
+ description: "Initialize xopc state directories, config, and agent workspace"
29
+ },
26
30
  {
27
31
  name: "setup [options]",
28
32
  description: "Initialize config file and workspace directory"
29
33
  },
34
+ {
35
+ name: "profile",
36
+ description: "Manage xopc state profiles (~/.xopc vs ~/.xopc-<name>)"
37
+ },
30
38
  {
31
39
  name: "onboard [options]",
32
40
  description: "Interactive setup wizard for xopc (gateway uses schema defaults)"
@@ -80,7 +88,7 @@ const ROOT_HELP_COMMANDS = [
80
88
  description: "Manage scheduled tasks"
81
89
  },
82
90
  {
83
- name: "config",
91
+ name: "config [options]",
84
92
  description: "View and edit configuration"
85
93
  },
86
94
  {
@@ -1 +1 @@
1
- {"version":3,"file":"command-manifest.js","names":[],"sources":["../../../src/cli/command-manifest.ts"],"sourcesContent":["export type RootHelpOption = {\n flags: string;\n description: string;\n};\n\nexport type RootHelpCommand = {\n name: string;\n description: string;\n};\n\nexport const ROOT_COMMAND_DESCRIPTION = 'Ultra-Lightweight Personal AI Assistant';\n\nexport const ROOT_HELP_OPTIONS: RootHelpOption[] = [\n { flags: '-V, --version', description: 'output the version number' },\n { flags: '--verbose', description: 'Enable verbose logging (default: false)' },\n { flags: '--config <path>', description: 'Config file path' },\n { flags: '--workspace <path>', description: 'Workspace directory' },\n { flags: '-h, --help', description: 'display help for command' },\n];\n\nexport const ROOT_HELP_COMMANDS: RootHelpCommand[] = [\n { name: 'setup [options]', description: 'Initialize config file and workspace directory' },\n { name: 'onboard [options]', description: 'Interactive setup wizard for xopc (gateway uses schema defaults)' },\n { name: 'channels', description: 'Messaging channel login and credentials' },\n { name: 'auth', description: 'Manage authentication credentials' },\n { name: 'agent [options]', description: 'Chat with the AI agent' },\n { name: 'tui [options]', description: 'Interactive terminal UI (pi-tui)' },\n { name: 'tunnel', description: 'Manage FRP remote access tunnel' },\n { name: 'gateway [options]', description: 'Start the xopc gateway server' },\n { name: 'session', description: 'Session management commands' },\n { name: 'doctor [options]', description: 'Check xopc installation health and diagnose common issues' },\n { name: 'update [options]', description: 'Check for and install xopc updates' },\n { name: 'logs', description: 'Manage and query logs' },\n { name: 'mcp', description: 'Manage xopc MCP config and channel bridge' },\n { name: 'cron', description: 'Manage scheduled tasks' },\n { name: 'config', description: 'View and edit configuration' },\n { name: 'image', description: 'Configure image generation and understanding models' },\n { name: 'models [options]', description: 'List and manage available models' },\n { name: 'providers', description: 'Manage LLM provider credentials (user-friendly hub over `xopc auth`)' },\n { name: 'voice', description: 'Configure text-to-speech (TTS) output' },\n { name: 'search', description: 'Manage web-search providers (brave / tavily / bing / searxng)' },\n { name: 'skills', description: 'Manage skills' },\n { name: 'tailscale', description: 'Tailscale status for gateway remote access' },\n { name: 'browser', description: 'Browser automation commands (uses Playwright)' },\n { name: 'agents', description: 'Manage agents (config + workspace)' },\n { name: 'extensions', description: 'Manage extensions' },\n { name: 'help [command]', description: 'display help for command' },\n];\n\nfunction formatRows(rows: Array<{ label: string; description: string }>): string {\n const labelWidth = Math.max(...rows.map((row) => row.label.length)) + 2;\n return rows.map((row) => ` ${row.label.padEnd(labelWidth)}${row.description}`).join('\\n');\n}\n\nexport function formatRootHelp(): string {\n const options = formatRows(ROOT_HELP_OPTIONS.map((option) => ({ label: option.flags, description: option.description })));\n const commands = formatRows(\n ROOT_HELP_COMMANDS.map((command) => ({ label: command.name, description: command.description })),\n );\n return `Usage: xopc [options] [command]\n\n${ROOT_COMMAND_DESCRIPTION}\n\nOptions:\n${options}\n\nCommands:\n${commands}`;\n}\n"],"mappings":";AAUA,MAAa,2BAA2B;AAExC,MAAa,oBAAsC;CACjD;EAAE,OAAO;EAAiB,aAAa;EAA6B;CACpE;EAAE,OAAO;EAAa,aAAa;EAA2C;CAC9E;EAAE,OAAO;EAAmB,aAAa;EAAoB;CAC7D;EAAE,OAAO;EAAsB,aAAa;EAAuB;CACnE;EAAE,OAAO;EAAc,aAAa;EAA4B;CACjE;AAED,MAAa,qBAAwC;CACnD;EAAE,MAAM;EAAmB,aAAa;EAAkD;CAC1F;EAAE,MAAM;EAAqB,aAAa;EAAoE;CAC9G;EAAE,MAAM;EAAY,aAAa;EAA2C;CAC5E;EAAE,MAAM;EAAQ,aAAa;EAAqC;CAClE;EAAE,MAAM;EAAmB,aAAa;EAA0B;CAClE;EAAE,MAAM;EAAiB,aAAa;EAAoC;CAC1E;EAAE,MAAM;EAAU,aAAa;EAAmC;CAClE;EAAE,MAAM;EAAqB,aAAa;EAAiC;CAC3E;EAAE,MAAM;EAAW,aAAa;EAA+B;CAC/D;EAAE,MAAM;EAAoB,aAAa;EAA6D;CACtG;EAAE,MAAM;EAAoB,aAAa;EAAsC;CAC/E;EAAE,MAAM;EAAQ,aAAa;EAAyB;CACtD;EAAE,MAAM;EAAO,aAAa;EAA6C;CACzE;EAAE,MAAM;EAAQ,aAAa;EAA0B;CACvD;EAAE,MAAM;EAAU,aAAa;EAA+B;CAC9D;EAAE,MAAM;EAAS,aAAa;EAAuD;CACrF;EAAE,MAAM;EAAoB,aAAa;EAAoC;CAC7E;EAAE,MAAM;EAAa,aAAa;EAAwE;CAC1G;EAAE,MAAM;EAAS,aAAa;EAAyC;CACvE;EAAE,MAAM;EAAU,aAAa;EAAiE;CAChG;EAAE,MAAM;EAAU,aAAa;EAAiB;CAChD;EAAE,MAAM;EAAa,aAAa;EAA8C;CAChF;EAAE,MAAM;EAAW,aAAa;EAAiD;CACjF;EAAE,MAAM;EAAU,aAAa;EAAsC;CACrE;EAAE,MAAM;EAAc,aAAa;EAAqB;CACxD;EAAE,MAAM;EAAkB,aAAa;EAA4B;CACpE;AAED,SAAS,WAAW,MAA6D;CAC/E,MAAM,aAAa,KAAK,IAAI,GAAG,KAAK,KAAK,QAAQ,IAAI,MAAM,OAAO,CAAC,GAAG;AACtE,QAAO,KAAK,KAAK,QAAQ,KAAK,IAAI,MAAM,OAAO,WAAW,GAAG,IAAI,cAAc,CAAC,KAAK,KAAK;;AAG5F,SAAgB,iBAAyB;AAKvC,QAAO;;EAEP,yBAAyB;;;EANT,WAAW,kBAAkB,KAAK,YAAY;EAAE,OAAO,OAAO;EAAO,aAAa,OAAO;EAAa,EAAE,CASjH,CAAC;;;EARS,WACf,mBAAmB,KAAK,aAAa;EAAE,OAAO,QAAQ;EAAM,aAAa,QAAQ;EAAa,EAAE,CAU1F"}
1
+ {"version":3,"file":"command-manifest.js","names":[],"sources":["../../../src/cli/command-manifest.ts"],"sourcesContent":["export type RootHelpOption = {\n flags: string;\n description: string;\n};\n\nexport type RootHelpCommand = {\n name: string;\n description: string;\n};\n\nexport const ROOT_COMMAND_DESCRIPTION = 'Ultra-Lightweight Personal AI Assistant';\n\nexport const ROOT_HELP_OPTIONS: RootHelpOption[] = [\n { flags: '-V, --version', description: 'output the version number' },\n { flags: '--verbose', description: 'Enable verbose logging (default: false)' },\n { flags: '--config <path>', description: 'Config file path' },\n { flags: '--workspace <path>', description: 'Workspace directory' },\n { flags: '-h, --help', description: 'display help for command' },\n];\n\nexport const ROOT_HELP_COMMANDS: RootHelpCommand[] = [\n { name: 'init [options]', description: 'Initialize xopc state directories, config, and agent workspace' },\n { name: 'setup [options]', description: 'Initialize config file and workspace directory' },\n { name: 'profile', description: 'Manage xopc state profiles (~/.xopc vs ~/.xopc-<name>)' },\n { name: 'onboard [options]', description: 'Interactive setup wizard for xopc (gateway uses schema defaults)' },\n { name: 'channels', description: 'Messaging channel login and credentials' },\n { name: 'auth', description: 'Manage authentication credentials' },\n { name: 'agent [options]', description: 'Chat with the AI agent' },\n { name: 'tui [options]', description: 'Interactive terminal UI (pi-tui)' },\n { name: 'tunnel', description: 'Manage FRP remote access tunnel' },\n { name: 'gateway [options]', description: 'Start the xopc gateway server' },\n { name: 'session', description: 'Session management commands' },\n { name: 'doctor [options]', description: 'Check xopc installation health and diagnose common issues' },\n { name: 'update [options]', description: 'Check for and install xopc updates' },\n { name: 'logs', description: 'Manage and query logs' },\n { name: 'mcp', description: 'Manage xopc MCP config and channel bridge' },\n { name: 'cron', description: 'Manage scheduled tasks' },\n { name: 'config [options]', description: 'View and edit configuration' },\n { name: 'image', description: 'Configure image generation and understanding models' },\n { name: 'models [options]', description: 'List and manage available models' },\n { name: 'providers', description: 'Manage LLM provider credentials (user-friendly hub over `xopc auth`)' },\n { name: 'voice', description: 'Configure text-to-speech (TTS) output' },\n { name: 'search', description: 'Manage web-search providers (brave / tavily / bing / searxng)' },\n { name: 'skills', description: 'Manage skills' },\n { name: 'tailscale', description: 'Tailscale status for gateway remote access' },\n { name: 'browser', description: 'Browser automation commands (uses Playwright)' },\n { name: 'agents', description: 'Manage agents (config + workspace)' },\n { name: 'extensions', description: 'Manage extensions' },\n { name: 'help [command]', description: 'display help for command' },\n];\n\nfunction formatRows(rows: Array<{ label: string; description: string }>): string {\n const labelWidth = Math.max(...rows.map((row) => row.label.length)) + 2;\n return rows.map((row) => ` ${row.label.padEnd(labelWidth)}${row.description}`).join('\\n');\n}\n\nexport function formatRootHelp(): string {\n const options = formatRows(ROOT_HELP_OPTIONS.map((option) => ({ label: option.flags, description: option.description })));\n const commands = formatRows(\n ROOT_HELP_COMMANDS.map((command) => ({ label: command.name, description: command.description })),\n );\n return `Usage: xopc [options] [command]\n\n${ROOT_COMMAND_DESCRIPTION}\n\nOptions:\n${options}\n\nCommands:\n${commands}`;\n}\n"],"mappings":";AAUA,MAAa,2BAA2B;AAExC,MAAa,oBAAsC;CACjD;EAAE,OAAO;EAAiB,aAAa;EAA6B;CACpE;EAAE,OAAO;EAAa,aAAa;EAA2C;CAC9E;EAAE,OAAO;EAAmB,aAAa;EAAoB;CAC7D;EAAE,OAAO;EAAsB,aAAa;EAAuB;CACnE;EAAE,OAAO;EAAc,aAAa;EAA4B;CACjE;AAED,MAAa,qBAAwC;CACnD;EAAE,MAAM;EAAkB,aAAa;EAAkE;CACzG;EAAE,MAAM;EAAmB,aAAa;EAAkD;CAC1F;EAAE,MAAM;EAAW,aAAa;EAA0D;CAC1F;EAAE,MAAM;EAAqB,aAAa;EAAoE;CAC9G;EAAE,MAAM;EAAY,aAAa;EAA2C;CAC5E;EAAE,MAAM;EAAQ,aAAa;EAAqC;CAClE;EAAE,MAAM;EAAmB,aAAa;EAA0B;CAClE;EAAE,MAAM;EAAiB,aAAa;EAAoC;CAC1E;EAAE,MAAM;EAAU,aAAa;EAAmC;CAClE;EAAE,MAAM;EAAqB,aAAa;EAAiC;CAC3E;EAAE,MAAM;EAAW,aAAa;EAA+B;CAC/D;EAAE,MAAM;EAAoB,aAAa;EAA6D;CACtG;EAAE,MAAM;EAAoB,aAAa;EAAsC;CAC/E;EAAE,MAAM;EAAQ,aAAa;EAAyB;CACtD;EAAE,MAAM;EAAO,aAAa;EAA6C;CACzE;EAAE,MAAM;EAAQ,aAAa;EAA0B;CACvD;EAAE,MAAM;EAAoB,aAAa;EAA+B;CACxE;EAAE,MAAM;EAAS,aAAa;EAAuD;CACrF;EAAE,MAAM;EAAoB,aAAa;EAAoC;CAC7E;EAAE,MAAM;EAAa,aAAa;EAAwE;CAC1G;EAAE,MAAM;EAAS,aAAa;EAAyC;CACvE;EAAE,MAAM;EAAU,aAAa;EAAiE;CAChG;EAAE,MAAM;EAAU,aAAa;EAAiB;CAChD;EAAE,MAAM;EAAa,aAAa;EAA8C;CAChF;EAAE,MAAM;EAAW,aAAa;EAAiD;CACjF;EAAE,MAAM;EAAU,aAAa;EAAsC;CACrE;EAAE,MAAM;EAAc,aAAa;EAAqB;CACxD;EAAE,MAAM;EAAkB,aAAa;EAA4B;CACpE;AAED,SAAS,WAAW,MAA6D;CAC/E,MAAM,aAAa,KAAK,IAAI,GAAG,KAAK,KAAK,QAAQ,IAAI,MAAM,OAAO,CAAC,GAAG;AACtE,QAAO,KAAK,KAAK,QAAQ,KAAK,IAAI,MAAM,OAAO,WAAW,GAAG,IAAI,cAAc,CAAC,KAAK,KAAK;;AAG5F,SAAgB,iBAAyB;AAKvC,QAAO;;EAEP,yBAAyB;;;EANT,WAAW,kBAAkB,KAAK,YAAY;EAAE,OAAO,OAAO;EAAO,aAAa,OAAO;EAAa,EAAE,CASjH,CAAC;;;EARS,WACf,mBAAmB,KAAK,aAAa;EAAE,OAAO,QAAQ;EAAM,aAAa,QAAQ;EAAa,EAAE,CAU1F"}
@@ -1,10 +1,13 @@
1
+ import { ConfigSchema, init_schema } from "../../config/schema.js";
1
2
  import { init_write_file_atomic, writeTextAtomic } from "../../infra/write-file-atomic.js";
2
- import { formatExamples, register } from "../registry.js";
3
3
  import { resolveGatewayLocalClientHost } from "../../config/gateway-bind.js";
4
- import { existsSync } from "fs";
4
+ import { formatExamples, register } from "../registry.js";
5
+ import { existsSync, readFileSync } from "fs";
5
6
  import { Command } from "commander";
6
7
  //#region src/cli/commands/config.ts
7
8
  init_write_file_atomic();
9
+ init_schema();
10
+ const MISSING_CONFIG_HINT = "Run: xopc setup, xopc onboard, or xopc init";
8
11
  async function loadConfigDeps() {
9
12
  const [{ loadConfig }, { createLogger }] = await Promise.all([import("../../config/index.js"), import("../../utils/logger.js")]);
10
13
  return {
@@ -12,6 +15,49 @@ async function loadConfigDeps() {
12
15
  log: createLogger("ConfigCommand")
13
16
  };
14
17
  }
18
+ async function runConfigShow(configPath) {
19
+ const { loadConfig, log } = await loadConfigDeps();
20
+ if (!existsSync(configPath)) {
21
+ log.warn(`No config file found. ${MISSING_CONFIG_HINT}`);
22
+ return;
23
+ }
24
+ const config = loadConfig(configPath);
25
+ const maskedConfig = JSON.stringify(config, (key, value) => {
26
+ if (key === "api_key" || key === "token") return value ? "********" : value;
27
+ return value;
28
+ }, 2);
29
+ console.log(maskedConfig);
30
+ }
31
+ async function runConfigValidate(configPath) {
32
+ const { log } = await loadConfigDeps();
33
+ if (!existsSync(configPath)) {
34
+ log.error("Config file not found. Run: xopc onboard");
35
+ return false;
36
+ }
37
+ let json;
38
+ try {
39
+ json = JSON.parse(readFileSync(configPath, "utf-8"));
40
+ } catch {
41
+ log.error("Config file is not valid JSON.");
42
+ return false;
43
+ }
44
+ const parsed = ConfigSchema.safeParse(json);
45
+ if (!parsed.success) {
46
+ log.error("Config does not match the expected schema.");
47
+ for (const issue of parsed.error.issues) console.error(` - ${issue.path.join(".") || "(root)"}: ${issue.message}`);
48
+ return false;
49
+ }
50
+ const { validateChannelPluginConfigs } = await import("../../config/validate-channel-configs.js");
51
+ const channelErrors = validateChannelPluginConfigs(parsed.data);
52
+ if (channelErrors.length > 0) {
53
+ log.error("Channel configuration failed validation.");
54
+ for (const err of channelErrors) console.error(` - ${err}`);
55
+ return false;
56
+ }
57
+ log.info({ path: configPath }, "Config is valid");
58
+ console.log("✅ Configuration is valid");
59
+ return true;
60
+ }
15
61
  function getNestedValue(obj, path) {
16
62
  return path.split(".").reduce((current, key) => {
17
63
  if (current && typeof current === "object" && key in current) return current[key];
@@ -28,19 +74,30 @@ function setNestedValue(obj, path, value) {
28
74
  return obj;
29
75
  }
30
76
  function createConfigCommand(ctx) {
31
- const cmd = new Command("config").description("View and edit configuration").addHelpText("after", formatExamples([
77
+ const cmd = new Command("config").description("View and edit configuration").option("--show", "Show full configuration (alias for `config show`)").option("--validate", "Validate configuration file (alias for `config validate`)").addHelpText("after", formatExamples([
32
78
  "xopc config get agents.defaults.model",
33
79
  "xopc config set agents.defaults.temperature 0.8",
34
80
  "xopc config unset agents.defaults.max_tokens",
35
81
  "xopc config show",
82
+ "xopc config validate",
36
83
  "xopc config token # Show gateway token info",
37
84
  "xopc config token --show # Show full token",
38
85
  "xopc config token --generate # Generate new token"
39
- ]));
86
+ ])).action(async (options) => {
87
+ if (options.show) {
88
+ await runConfigShow(ctx.configPath);
89
+ return;
90
+ }
91
+ if (options.validate) {
92
+ if (!await runConfigValidate(ctx.configPath)) process.exit(1);
93
+ return;
94
+ }
95
+ cmd.outputHelp();
96
+ });
40
97
  cmd.command("get <path>").description("Get a config value by dot path").action(async (path) => {
41
98
  const { loadConfig, log } = await loadConfigDeps();
42
99
  if (!existsSync(ctx.configPath)) {
43
- log.error("Config file not found. Run: xopc onboard");
100
+ log.error(`Config file not found. ${MISSING_CONFIG_HINT}`);
44
101
  process.exit(1);
45
102
  }
46
103
  const value = getNestedValue(loadConfig(ctx.configPath), path);
@@ -53,7 +110,7 @@ function createConfigCommand(ctx) {
53
110
  cmd.command("set <path> <value>").description("Set a config value by dot path").action(async (path, value) => {
54
111
  const { loadConfig, log } = await loadConfigDeps();
55
112
  if (!existsSync(ctx.configPath)) {
56
- log.error("Config file not found. Run: xopc onboard");
113
+ log.error(`Config file not found. ${MISSING_CONFIG_HINT}`);
57
114
  process.exit(1);
58
115
  }
59
116
  let parsedValue;
@@ -70,7 +127,7 @@ function createConfigCommand(ctx) {
70
127
  cmd.command("unset <path>").description("Remove a config value by dot path").action(async (path) => {
71
128
  const { loadConfig, log } = await loadConfigDeps();
72
129
  if (!existsSync(ctx.configPath)) {
73
- log.error("Config file not found. Run: xopc onboard");
130
+ log.error(`Config file not found. ${MISSING_CONFIG_HINT}`);
74
131
  process.exit(1);
75
132
  }
76
133
  const config = loadConfig(ctx.configPath);
@@ -89,22 +146,15 @@ function createConfigCommand(ctx) {
89
146
  }
90
147
  });
91
148
  cmd.command("show").description("Show full configuration (sensitive values masked)").action(async () => {
92
- const { loadConfig, log } = await loadConfigDeps();
93
- if (!existsSync(ctx.configPath)) {
94
- log.warn("No config file found. Run: xopc onboard");
95
- return;
96
- }
97
- const config = loadConfig(ctx.configPath);
98
- const maskedConfig = JSON.stringify(config, (key, value) => {
99
- if (key === "api_key" || key === "token") return value ? "********" : value;
100
- return value;
101
- }, 2);
102
- console.log(maskedConfig);
149
+ await runConfigShow(ctx.configPath);
150
+ });
151
+ cmd.command("validate").description("Validate configuration file against schema and channel plugins").action(async () => {
152
+ if (!await runConfigValidate(ctx.configPath)) process.exit(1);
103
153
  });
104
154
  cmd.command("token").description("Generate or view the gateway auth token").option("--generate", "Generate a new token").option("--show", "Show the current token (unmasked)").action(async (options) => {
105
155
  const { loadConfig, log } = await loadConfigDeps();
106
156
  if (!existsSync(ctx.configPath)) {
107
- log.error("Config file not found. Run: xopc onboard");
157
+ log.error(`Config file not found. ${MISSING_CONFIG_HINT}`);
108
158
  process.exit(1);
109
159
  }
110
160
  const config = loadConfig(ctx.configPath);
@@ -140,7 +190,7 @@ function createConfigCommand(ctx) {
140
190
  console.log(` Token: ${token.slice(0, 8)}...${token.slice(-8)}`);
141
191
  console.log("\nUse \"xopc config token --show\" to view the full token");
142
192
  console.log("Use \"xopc config token --generate\" to generate a new token");
143
- } else if (mode === "token") console.log(" Token: not set (will be auto-generated on first gateway start)");
193
+ } else if (mode === "token") console.log(" Token: not set (will be auto-generated on first `xopc gateway` run)");
144
194
  });
145
195
  cmd.command("path").description("Show configuration file path").action(() => {
146
196
  console.log(ctx.configPath);
@@ -158,6 +208,7 @@ register({
158
208
  "xopc config get agents.defaults.model",
159
209
  "xopc config set agents.defaults.temperature 0.8",
160
210
  "xopc config show",
211
+ "xopc config validate",
161
212
  "xopc config token",
162
213
  "xopc config token --show",
163
214
  "xopc config token --generate"
@@ -1 +1 @@
1
- {"version":3,"file":"config.js","names":[],"sources":["../../../../src/cli/commands/config.ts"],"sourcesContent":["import { Command } from 'commander';\nimport { existsSync } from 'fs';\nimport { resolveGatewayLocalClientHost } from '../../config/gateway-bind.js';\nimport { writeTextAtomic } from '../../infra/write-file-atomic.js';\nimport { register, formatExamples, type CLIContext } from '../registry.js';\n\nasync function loadConfigDeps() {\n const [{ loadConfig }, { createLogger }] = await Promise.all([\n import('../../config/index.js'),\n import('../../utils/logger.js'),\n ]);\n return { loadConfig, log: createLogger('ConfigCommand') };\n}\n\nfunction getNestedValue(obj: any, path: string): any {\n return path.split('.').reduce((current: any, key: string) => {\n if (current && typeof current === 'object' && key in current) {\n return current[key];\n }\n return undefined;\n }, obj);\n}\n\nfunction setNestedValue(obj: any, path: string, value: any): any {\n const keys = path.split('.');\n const lastKey = keys.pop()!;\n const target = keys.reduce((current: any, key: string) => {\n if (!current[key] || typeof current[key] !== 'object') {\n current[key] = {};\n }\n return current[key];\n }, obj);\n target[lastKey] = value;\n return obj;\n}\n\nfunction createConfigCommand(ctx: CLIContext): Command {\n const cmd = new Command('config')\n .description('View and edit configuration')\n .addHelpText(\n 'after',\n formatExamples([\n 'xopc config get agents.defaults.model',\n 'xopc config set agents.defaults.temperature 0.8',\n 'xopc config unset agents.defaults.max_tokens',\n 'xopc config show',\n 'xopc config token # Show gateway token info',\n 'xopc config token --show # Show full token',\n 'xopc config token --generate # Generate new token',\n ])\n );\n\n cmd\n .command('get <path>')\n .description('Get a config value by dot path')\n .action(async (path: string) => {\n const { loadConfig, log } = await loadConfigDeps();\n if (!existsSync(ctx.configPath)) {\n log.error('Config file not found. Run: xopc onboard');\n process.exit(1);\n }\n\n const config = loadConfig(ctx.configPath);\n const value = getNestedValue(config, path);\n\n if (value === undefined) {\n log.error({ path }, `Config path not found`);\n process.exit(1);\n }\n\n console.log(typeof value === 'object' ? JSON.stringify(value, null, 2) : value);\n });\n\n cmd\n .command('set <path> <value>')\n .description('Set a config value by dot path')\n .action(async (path: string, value: string) => {\n const { loadConfig, log } = await loadConfigDeps();\n if (!existsSync(ctx.configPath)) {\n log.error('Config file not found. Run: xopc onboard');\n process.exit(1);\n }\n\n let parsedValue: any;\n try {\n parsedValue = JSON.parse(value);\n } catch {\n parsedValue = value;\n }\n\n const config = loadConfig(ctx.configPath);\n setNestedValue(config, path, parsedValue);\n\n await writeTextAtomic(ctx.configPath, JSON.stringify(config, null, 2));\n\n log.info({ path }, `Config updated`);\n });\n\n cmd\n .command('unset <path>')\n .description('Remove a config value by dot path')\n .action(async (path: string) => {\n const { loadConfig, log } = await loadConfigDeps();\n if (!existsSync(ctx.configPath)) {\n log.error('Config file not found. Run: xopc onboard');\n process.exit(1);\n }\n\n const config = loadConfig(ctx.configPath);\n const keys = path.split('.');\n const lastKey = keys.pop()!;\n const target = keys.reduce((current: any, key: string) => {\n return current && current[key];\n }, config);\n\n if (target && typeof target === 'object' && lastKey in target) {\n delete target[lastKey];\n await writeTextAtomic(ctx.configPath, JSON.stringify(config, null, 2));\n log.info({ path }, `Config removed`);\n } else {\n log.error({ path }, `Config path not found`);\n process.exit(1);\n }\n });\n\n cmd\n .command('show')\n .description('Show full configuration (sensitive values masked)')\n .action(async () => {\n const { loadConfig, log } = await loadConfigDeps();\n if (!existsSync(ctx.configPath)) {\n log.warn('No config file found. Run: xopc onboard');\n return;\n }\n\n const config = loadConfig(ctx.configPath);\n\n const maskedConfig = JSON.stringify(config, (key, value) => {\n if (key === 'api_key' || key === 'token') {\n return value ? '********' : value;\n }\n return value;\n }, 2);\n\n console.log(maskedConfig);\n });\n\n cmd\n .command('token')\n .description('Generate or view the gateway auth token')\n .option('--generate', 'Generate a new token')\n .option('--show', 'Show the current token (unmasked)')\n .action(async (options) => {\n const { loadConfig, log } = await loadConfigDeps();\n if (!existsSync(ctx.configPath)) {\n log.error('Config file not found. Run: xopc onboard');\n process.exit(1);\n }\n\n const config = loadConfig(ctx.configPath);\n\n if (options.show) {\n const token = config?.gateway?.auth?.token;\n if (token) {\n console.log(token);\n } else {\n console.log('No token configured. Gateway auth mode:', config?.gateway?.auth?.mode || 'not set');\n }\n return;\n }\n\n if (options.generate) {\n const crypto = await import('crypto');\n const newToken = crypto.randomBytes(24).toString('hex');\n\n config.gateway = config.gateway || {};\n config.gateway.auth = {\n mode: 'token',\n token: newToken,\n };\n\n await writeTextAtomic(ctx.configPath, JSON.stringify(config, null, 2));\n log.info('New gateway token generated');\n console.log(`Token: ${newToken.slice(0, 8)}...${newToken.slice(-8)}`);\n console.log('\\nUse \"xopc config token --show\" to view the full token');\n return;\n }\n\n // Default: show masked token info\n const token = config?.gateway?.auth?.token;\n const mode = config?.gateway?.auth?.mode;\n const bind = config?.gateway?.bind ?? 'loopback';\n const port = config?.gateway?.port || 18790;\n const clientHost = config ? resolveGatewayLocalClientHost(config) : '127.0.0.1';\n\n console.log('Gateway Configuration:');\n console.log(` Bind: ${bind}`);\n console.log(` Local URL: http://${clientHost}:${port}`);\n console.log(` Auth Mode: ${mode || 'not set'}`);\n if (token) {\n console.log(` Token: ${token.slice(0, 8)}...${token.slice(-8)}`);\n console.log('\\nUse \"xopc config token --show\" to view the full token');\n console.log('Use \"xopc config token --generate\" to generate a new token');\n } else if (mode === 'token') {\n console.log(' Token: not set (will be auto-generated on first gateway start)');\n }\n });\n\n cmd\n .command('path')\n .description('Show configuration file path')\n .action(() => {\n console.log(ctx.configPath);\n });\n\n return cmd;\n}\n\nregister({\n id: 'config',\n name: 'config',\n description: 'View and edit configuration',\n factory: createConfigCommand,\n metadata: {\n category: 'utility',\n examples: [\n 'xopc config get agents.defaults.model',\n 'xopc config set agents.defaults.temperature 0.8',\n 'xopc config show',\n 'xopc config token',\n 'xopc config token --show',\n 'xopc config token --generate',\n ],\n },\n});\n"],"mappings":";;;;;;wBAGmE;AAGnE,eAAe,iBAAiB;CAC9B,MAAM,CAAC,EAAE,cAAc,EAAE,kBAAkB,MAAM,QAAQ,IAAI,CAC3D,OAAO,0BACP,OAAO,yBACR,CAAC;AACF,QAAO;EAAE;EAAY,KAAK,aAAa,gBAAgB;EAAE;;AAG3D,SAAS,eAAe,KAAU,MAAmB;AACnD,QAAO,KAAK,MAAM,IAAI,CAAC,QAAQ,SAAc,QAAgB;AAC3D,MAAI,WAAW,OAAO,YAAY,YAAY,OAAO,QACnD,QAAO,QAAQ;IAGhB,IAAI;;AAGT,SAAS,eAAe,KAAU,MAAc,OAAiB;CAC/D,MAAM,OAAO,KAAK,MAAM,IAAI;CAC5B,MAAM,UAAU,KAAK,KAAK;CAC1B,MAAM,SAAS,KAAK,QAAQ,SAAc,QAAgB;AACxD,MAAI,CAAC,QAAQ,QAAQ,OAAO,QAAQ,SAAS,SAC3C,SAAQ,OAAO,EAAE;AAEnB,SAAO,QAAQ;IACd,IAAI;AACP,QAAO,WAAW;AAClB,QAAO;;AAGT,SAAS,oBAAoB,KAA0B;CACrD,MAAM,MAAM,IAAI,QAAQ,SAAS,CAC9B,YAAY,8BAA8B,CAC1C,YACC,SACA,eAAe;EACb;EACA;EACA;EACA;EACA;EACA;EACA;EACD,CAAC,CACH;AAEH,KACG,QAAQ,aAAa,CACrB,YAAY,iCAAiC,CAC7C,OAAO,OAAO,SAAiB;EAC9B,MAAM,EAAE,YAAY,QAAQ,MAAM,gBAAgB;AAClD,MAAI,CAAC,WAAW,IAAI,WAAW,EAAE;AAC/B,OAAI,MAAM,2CAA2C;AACrD,WAAQ,KAAK,EAAE;;EAIjB,MAAM,QAAQ,eADC,WAAW,IAAI,WACK,EAAE,KAAK;AAE1C,MAAI,UAAU,KAAA,GAAW;AACvB,OAAI,MAAM,EAAE,MAAM,EAAE,wBAAwB;AAC5C,WAAQ,KAAK,EAAE;;AAGjB,UAAQ,IAAI,OAAO,UAAU,WAAW,KAAK,UAAU,OAAO,MAAM,EAAE,GAAG,MAAM;GAC/E;AAEJ,KACG,QAAQ,qBAAqB,CAC7B,YAAY,iCAAiC,CAC7C,OAAO,OAAO,MAAc,UAAkB;EAC7C,MAAM,EAAE,YAAY,QAAQ,MAAM,gBAAgB;AAClD,MAAI,CAAC,WAAW,IAAI,WAAW,EAAE;AAC/B,OAAI,MAAM,2CAA2C;AACrD,WAAQ,KAAK,EAAE;;EAGjB,IAAI;AACJ,MAAI;AACF,iBAAc,KAAK,MAAM,MAAM;UACzB;AACN,iBAAc;;EAGhB,MAAM,SAAS,WAAW,IAAI,WAAW;AACzC,iBAAe,QAAQ,MAAM,YAAY;AAEzC,QAAM,gBAAgB,IAAI,YAAY,KAAK,UAAU,QAAQ,MAAM,EAAE,CAAC;AAEtE,MAAI,KAAK,EAAE,MAAM,EAAE,iBAAiB;GACpC;AAEJ,KACG,QAAQ,eAAe,CACvB,YAAY,oCAAoC,CAChD,OAAO,OAAO,SAAiB;EAC9B,MAAM,EAAE,YAAY,QAAQ,MAAM,gBAAgB;AAClD,MAAI,CAAC,WAAW,IAAI,WAAW,EAAE;AAC/B,OAAI,MAAM,2CAA2C;AACrD,WAAQ,KAAK,EAAE;;EAGjB,MAAM,SAAS,WAAW,IAAI,WAAW;EACzC,MAAM,OAAO,KAAK,MAAM,IAAI;EAC5B,MAAM,UAAU,KAAK,KAAK;EAC1B,MAAM,SAAS,KAAK,QAAQ,SAAc,QAAgB;AACxD,UAAO,WAAW,QAAQ;KACzB,OAAO;AAEV,MAAI,UAAU,OAAO,WAAW,YAAY,WAAW,QAAQ;AAC7D,UAAO,OAAO;AACd,SAAM,gBAAgB,IAAI,YAAY,KAAK,UAAU,QAAQ,MAAM,EAAE,CAAC;AACtE,OAAI,KAAK,EAAE,MAAM,EAAE,iBAAiB;SAC/B;AACL,OAAI,MAAM,EAAE,MAAM,EAAE,wBAAwB;AAC5C,WAAQ,KAAK,EAAE;;GAEjB;AAEJ,KACG,QAAQ,OAAO,CACf,YAAY,oDAAoD,CAChE,OAAO,YAAY;EAClB,MAAM,EAAE,YAAY,QAAQ,MAAM,gBAAgB;AAClD,MAAI,CAAC,WAAW,IAAI,WAAW,EAAE;AAC/B,OAAI,KAAK,0CAA0C;AACnD;;EAGF,MAAM,SAAS,WAAW,IAAI,WAAW;EAEzC,MAAM,eAAe,KAAK,UAAU,SAAS,KAAK,UAAU;AAC1D,OAAI,QAAQ,aAAa,QAAQ,QAC/B,QAAO,QAAQ,aAAa;AAE9B,UAAO;KACN,EAAE;AAEL,UAAQ,IAAI,aAAa;GACzB;AAEJ,KACG,QAAQ,QAAQ,CAChB,YAAY,0CAA0C,CACtD,OAAO,cAAc,uBAAuB,CAC5C,OAAO,UAAU,oCAAoC,CACrD,OAAO,OAAO,YAAY;EACzB,MAAM,EAAE,YAAY,QAAQ,MAAM,gBAAgB;AAClD,MAAI,CAAC,WAAW,IAAI,WAAW,EAAE;AAC/B,OAAI,MAAM,2CAA2C;AACrD,WAAQ,KAAK,EAAE;;EAGjB,MAAM,SAAS,WAAW,IAAI,WAAW;AAEzC,MAAI,QAAQ,MAAM;GAChB,MAAM,QAAQ,QAAQ,SAAS,MAAM;AACrC,OAAI,MACF,SAAQ,IAAI,MAAM;OAElB,SAAQ,IAAI,2CAA2C,QAAQ,SAAS,MAAM,QAAQ,UAAU;AAElG;;AAGF,MAAI,QAAQ,UAAU;GAEpB,MAAM,YAAW,MADI,OAAO,WACJ,YAAY,GAAG,CAAC,SAAS,MAAM;AAEvD,UAAO,UAAU,OAAO,WAAW,EAAE;AACrC,UAAO,QAAQ,OAAO;IACpB,MAAM;IACN,OAAO;IACR;AAED,SAAM,gBAAgB,IAAI,YAAY,KAAK,UAAU,QAAQ,MAAM,EAAE,CAAC;AACtE,OAAI,KAAK,8BAA8B;AACvC,WAAQ,IAAI,UAAU,SAAS,MAAM,GAAG,EAAE,CAAC,KAAK,SAAS,MAAM,GAAG,GAAG;AACrE,WAAQ,IAAI,4DAA0D;AACtE;;EAIF,MAAM,QAAQ,QAAQ,SAAS,MAAM;EACrC,MAAM,OAAO,QAAQ,SAAS,MAAM;EACpC,MAAM,OAAO,QAAQ,SAAS,QAAQ;EACtC,MAAM,OAAO,QAAQ,SAAS,QAAQ;EACtC,MAAM,aAAa,SAAS,8BAA8B,OAAO,GAAG;AAEpE,UAAQ,IAAI,yBAAyB;AACrC,UAAQ,IAAI,WAAW,OAAO;AAC9B,UAAQ,IAAI,uBAAuB,WAAW,GAAG,OAAO;AACxD,UAAQ,IAAI,gBAAgB,QAAQ,YAAY;AAChD,MAAI,OAAO;AACT,WAAQ,IAAI,YAAY,MAAM,MAAM,GAAG,EAAE,CAAC,KAAK,MAAM,MAAM,GAAG,GAAG;AACjE,WAAQ,IAAI,4DAA0D;AACtE,WAAQ,IAAI,+DAA6D;aAChE,SAAS,QAClB,SAAQ,IAAI,mEAAmE;GAEjF;AAEJ,KACG,QAAQ,OAAO,CACf,YAAY,+BAA+B,CAC3C,aAAa;AACZ,UAAQ,IAAI,IAAI,WAAW;GAC3B;AAEJ,QAAO;;AAGT,SAAS;CACP,IAAI;CACJ,MAAM;CACN,aAAa;CACb,SAAS;CACT,UAAU;EACR,UAAU;EACV,UAAU;GACR;GACA;GACA;GACA;GACA;GACA;GACD;EACF;CACF,CAAC"}
1
+ {"version":3,"file":"config.js","names":[],"sources":["../../../../src/cli/commands/config.ts"],"sourcesContent":["import { Command } from 'commander';\nimport { existsSync, readFileSync } from 'fs';\nimport { resolveGatewayLocalClientHost } from '../../config/gateway-bind.js';\nimport { writeTextAtomic } from '../../infra/write-file-atomic.js';\nimport { ConfigSchema } from '../../config/schema.js';\nimport { register, formatExamples, type CLIContext } from '../registry.js';\n\nconst MISSING_CONFIG_HINT = 'Run: xopc setup, xopc onboard, or xopc init';\n\nasync function loadConfigDeps() {\n const [{ loadConfig }, { createLogger }] = await Promise.all([\n import('../../config/index.js'),\n import('../../utils/logger.js'),\n ]);\n return { loadConfig, log: createLogger('ConfigCommand') };\n}\n\nasync function runConfigShow(configPath: string): Promise<void> {\n const { loadConfig, log } = await loadConfigDeps();\n if (!existsSync(configPath)) {\n log.warn(`No config file found. ${MISSING_CONFIG_HINT}`);\n return;\n }\n\n const config = loadConfig(configPath);\n const maskedConfig = JSON.stringify(\n config,\n (key, value) => {\n if (key === 'api_key' || key === 'token') {\n return value ? '********' : value;\n }\n return value;\n },\n 2,\n );\n console.log(maskedConfig);\n}\n\nasync function runConfigValidate(configPath: string): Promise<boolean> {\n const { log } = await loadConfigDeps();\n if (!existsSync(configPath)) {\n log.error('Config file not found. Run: xopc onboard');\n return false;\n }\n\n let json: unknown;\n try {\n json = JSON.parse(readFileSync(configPath, 'utf-8'));\n } catch {\n log.error('Config file is not valid JSON.');\n return false;\n }\n\n const parsed = ConfigSchema.safeParse(json);\n if (!parsed.success) {\n log.error('Config does not match the expected schema.');\n for (const issue of parsed.error.issues) {\n console.error(` - ${issue.path.join('.') || '(root)'}: ${issue.message}`);\n }\n return false;\n }\n\n const { validateChannelPluginConfigs } = await import('../../config/validate-channel-configs.js');\n const channelErrors = validateChannelPluginConfigs(parsed.data);\n if (channelErrors.length > 0) {\n log.error('Channel configuration failed validation.');\n for (const err of channelErrors) {\n console.error(` - ${err}`);\n }\n return false;\n }\n\n log.info({ path: configPath }, 'Config is valid');\n console.log('✅ Configuration is valid');\n return true;\n}\n\nfunction getNestedValue(obj: any, path: string): any {\n return path.split('.').reduce((current: any, key: string) => {\n if (current && typeof current === 'object' && key in current) {\n return current[key];\n }\n return undefined;\n }, obj);\n}\n\nfunction setNestedValue(obj: any, path: string, value: any): any {\n const keys = path.split('.');\n const lastKey = keys.pop()!;\n const target = keys.reduce((current: any, key: string) => {\n if (!current[key] || typeof current[key] !== 'object') {\n current[key] = {};\n }\n return current[key];\n }, obj);\n target[lastKey] = value;\n return obj;\n}\n\nfunction createConfigCommand(ctx: CLIContext): Command {\n const cmd = new Command('config')\n .description('View and edit configuration')\n .option('--show', 'Show full configuration (alias for `config show`)')\n .option('--validate', 'Validate configuration file (alias for `config validate`)')\n .addHelpText(\n 'after',\n formatExamples([\n 'xopc config get agents.defaults.model',\n 'xopc config set agents.defaults.temperature 0.8',\n 'xopc config unset agents.defaults.max_tokens',\n 'xopc config show',\n 'xopc config validate',\n 'xopc config token # Show gateway token info',\n 'xopc config token --show # Show full token',\n 'xopc config token --generate # Generate new token',\n ]),\n )\n .action(async (options) => {\n if (options.show) {\n await runConfigShow(ctx.configPath);\n return;\n }\n if (options.validate) {\n const ok = await runConfigValidate(ctx.configPath);\n if (!ok) {\n process.exit(1);\n }\n return;\n }\n cmd.outputHelp();\n });\n\n cmd\n .command('get <path>')\n .description('Get a config value by dot path')\n .action(async (path: string) => {\n const { loadConfig, log } = await loadConfigDeps();\n if (!existsSync(ctx.configPath)) {\n log.error(`Config file not found. ${MISSING_CONFIG_HINT}`);\n process.exit(1);\n }\n\n const config = loadConfig(ctx.configPath);\n const value = getNestedValue(config, path);\n\n if (value === undefined) {\n log.error({ path }, `Config path not found`);\n process.exit(1);\n }\n\n console.log(typeof value === 'object' ? JSON.stringify(value, null, 2) : value);\n });\n\n cmd\n .command('set <path> <value>')\n .description('Set a config value by dot path')\n .action(async (path: string, value: string) => {\n const { loadConfig, log } = await loadConfigDeps();\n if (!existsSync(ctx.configPath)) {\n log.error(`Config file not found. ${MISSING_CONFIG_HINT}`);\n process.exit(1);\n }\n\n let parsedValue: any;\n try {\n parsedValue = JSON.parse(value);\n } catch {\n parsedValue = value;\n }\n\n const config = loadConfig(ctx.configPath);\n setNestedValue(config, path, parsedValue);\n\n await writeTextAtomic(ctx.configPath, JSON.stringify(config, null, 2));\n\n log.info({ path }, `Config updated`);\n });\n\n cmd\n .command('unset <path>')\n .description('Remove a config value by dot path')\n .action(async (path: string) => {\n const { loadConfig, log } = await loadConfigDeps();\n if (!existsSync(ctx.configPath)) {\n log.error(`Config file not found. ${MISSING_CONFIG_HINT}`);\n process.exit(1);\n }\n\n const config = loadConfig(ctx.configPath);\n const keys = path.split('.');\n const lastKey = keys.pop()!;\n const target = keys.reduce((current: any, key: string) => {\n return current && current[key];\n }, config);\n\n if (target && typeof target === 'object' && lastKey in target) {\n delete target[lastKey];\n await writeTextAtomic(ctx.configPath, JSON.stringify(config, null, 2));\n log.info({ path }, `Config removed`);\n } else {\n log.error({ path }, `Config path not found`);\n process.exit(1);\n }\n });\n\n cmd\n .command('show')\n .description('Show full configuration (sensitive values masked)')\n .action(async () => {\n await runConfigShow(ctx.configPath);\n });\n\n cmd\n .command('validate')\n .description('Validate configuration file against schema and channel plugins')\n .action(async () => {\n const ok = await runConfigValidate(ctx.configPath);\n if (!ok) {\n process.exit(1);\n }\n });\n\n cmd\n .command('token')\n .description('Generate or view the gateway auth token')\n .option('--generate', 'Generate a new token')\n .option('--show', 'Show the current token (unmasked)')\n .action(async (options) => {\n const { loadConfig, log } = await loadConfigDeps();\n if (!existsSync(ctx.configPath)) {\n log.error(`Config file not found. ${MISSING_CONFIG_HINT}`);\n process.exit(1);\n }\n\n const config = loadConfig(ctx.configPath);\n\n if (options.show) {\n const token = config?.gateway?.auth?.token;\n if (token) {\n console.log(token);\n } else {\n console.log('No token configured. Gateway auth mode:', config?.gateway?.auth?.mode || 'not set');\n }\n return;\n }\n\n if (options.generate) {\n const crypto = await import('crypto');\n const newToken = crypto.randomBytes(24).toString('hex');\n\n config.gateway = config.gateway || {};\n config.gateway.auth = {\n mode: 'token',\n token: newToken,\n };\n\n await writeTextAtomic(ctx.configPath, JSON.stringify(config, null, 2));\n log.info('New gateway token generated');\n console.log(`Token: ${newToken.slice(0, 8)}...${newToken.slice(-8)}`);\n console.log('\\nUse \"xopc config token --show\" to view the full token');\n return;\n }\n\n // Default: show masked token info\n const token = config?.gateway?.auth?.token;\n const mode = config?.gateway?.auth?.mode;\n const bind = config?.gateway?.bind ?? 'loopback';\n const port = config?.gateway?.port || 18790;\n const clientHost = config ? resolveGatewayLocalClientHost(config) : '127.0.0.1';\n\n console.log('Gateway Configuration:');\n console.log(` Bind: ${bind}`);\n console.log(` Local URL: http://${clientHost}:${port}`);\n console.log(` Auth Mode: ${mode || 'not set'}`);\n if (token) {\n console.log(` Token: ${token.slice(0, 8)}...${token.slice(-8)}`);\n console.log('\\nUse \"xopc config token --show\" to view the full token');\n console.log('Use \"xopc config token --generate\" to generate a new token');\n } else if (mode === 'token') {\n console.log(' Token: not set (will be auto-generated on first `xopc gateway` run)');\n }\n });\n\n cmd\n .command('path')\n .description('Show configuration file path')\n .action(() => {\n console.log(ctx.configPath);\n });\n\n return cmd;\n}\n\nregister({\n id: 'config',\n name: 'config',\n description: 'View and edit configuration',\n factory: createConfigCommand,\n metadata: {\n category: 'utility',\n examples: [\n 'xopc config get agents.defaults.model',\n 'xopc config set agents.defaults.temperature 0.8',\n 'xopc config show',\n 'xopc config validate',\n 'xopc config token',\n 'xopc config token --show',\n 'xopc config token --generate',\n ],\n },\n});\n"],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ import type { CronService } from '../../cron/service.js';
2
+ export declare function withCronService<T>(fn: (service: CronService) => Promise<T>): Promise<T>;
@@ -0,0 +1,15 @@
1
+ //#region src/cli/commands/cron-cli.ts
2
+ async function withCronService(fn) {
3
+ const { CronService } = await import("../../cron/index.js");
4
+ const cronService = new CronService();
5
+ await cronService.initialize();
6
+ try {
7
+ return await fn(cronService);
8
+ } finally {
9
+ await cronService.stop();
10
+ }
11
+ }
12
+ //#endregion
13
+ export { withCronService };
14
+
15
+ //# sourceMappingURL=cron-cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cron-cli.js","names":[],"sources":["../../../../src/cli/commands/cron-cli.ts"],"sourcesContent":["import type { CronService } from '../../cron/service.js';\n\nexport async function withCronService<T>(fn: (service: CronService) => Promise<T>): Promise<T> {\n const { CronService } = await import('../../cron/index.js');\n const cronService = new CronService();\n await cronService.initialize();\n try {\n return await fn(cronService);\n } finally {\n await cronService.stop();\n }\n}\n"],"mappings":";AAEA,eAAsB,gBAAmB,IAAsD;CAC7F,MAAM,EAAE,gBAAgB,MAAM,OAAO;CACrC,MAAM,cAAc,IAAI,aAAa;AACrC,OAAM,YAAY,YAAY;AAC9B,KAAI;AACF,SAAO,MAAM,GAAG,YAAY;WACpB;AACR,QAAM,YAAY,MAAM"}
@@ -1 +1,4 @@
1
- export {};
1
+ import { Command } from 'commander';
2
+ import type { CLIContext } from '../registry.js';
3
+ declare function createCronCommand(_ctx: CLIContext): Command;
4
+ export { createCronCommand };
@@ -1,62 +1,92 @@
1
1
  import { formatExamples, register } from "../registry.js";
2
+ import { withCronService } from "./cron-cli.js";
2
3
  import { Command } from "commander";
3
4
  //#region src/cli/commands/cron.ts
4
5
  function createCronCommand(_ctx) {
5
6
  const cmd = new Command("cron").description("Manage scheduled tasks").addHelpText("after", formatExamples([
6
7
  "xopc cron list # List all tasks",
7
8
  "xopc cron add --schedule \"0 9 * * *\" --message \"Good morning\"",
9
+ "xopc cron enable <job-id> # Enable a task",
10
+ "xopc cron disable <job-id> # Disable a task",
11
+ "xopc cron run <job-id> # Run a task now",
8
12
  "xopc cron remove <job-id> # Remove a task"
9
13
  ]));
10
14
  cmd.addCommand(new Command("list").description("List all scheduled tasks").action(async () => {
11
- const { CronService } = await import("../../cron/index.js");
12
- const cronService = new CronService();
13
- await cronService.initialize();
14
- const jobs = await cronService.listJobs();
15
- if (jobs.length === 0) {
16
- console.log("No scheduled tasks.");
17
- return;
18
- }
19
- console.log("Scheduled Tasks:\n");
20
- const { getCronPayloadText } = await import("../../cron/job-content.js");
21
- for (const job of jobs) {
22
- console.log(` ${job.id} - ${job.schedule}`);
23
- console.log(` ${getCronPayloadText({ payload: job.payload })}`);
24
- console.log(` Next: ${job.next_run || "N/A"}`);
25
- console.log();
26
- }
27
- await cronService.stop();
15
+ await withCronService(async (cronService) => {
16
+ const jobs = await cronService.listJobs();
17
+ if (jobs.length === 0) {
18
+ console.log("No scheduled tasks.");
19
+ return;
20
+ }
21
+ console.log("Scheduled Tasks:\n");
22
+ const { getCronPayloadText } = await import("../../cron/job-content.js");
23
+ for (const job of jobs) {
24
+ const state = job.enabled ? "enabled " : "disabled";
25
+ console.log(` ${job.id} [${state}] - ${job.schedule}`);
26
+ console.log(` ${getCronPayloadText({ payload: job.payload })}`);
27
+ console.log(` Next: ${job.next_run || "N/A"}`);
28
+ console.log();
29
+ }
30
+ });
28
31
  }));
29
32
  cmd.addCommand(new Command("add").description("Add a scheduled task").option("--name <text>", "Task name").option("--schedule <cron>", "Cron expression (e.g., \"0 9 * * *\")").option("--message <text>", "Message to send").action(async (options) => {
30
33
  if (!options.schedule || !options.message) {
31
34
  console.error("Error: --schedule and --message are required");
32
35
  process.exit(1);
33
36
  }
34
- const { CronService } = await import("../../cron/index.js");
35
- const cronService = new CronService();
36
- await cronService.initialize();
37
- const result = await cronService.addJob(options.schedule, {
38
- name: options.name,
39
- payload: {
40
- kind: "systemEvent",
41
- text: options.message
42
- }
37
+ await withCronService(async (cronService) => {
38
+ const result = await cronService.addJob(options.schedule, {
39
+ name: options.name,
40
+ payload: {
41
+ kind: "systemEvent",
42
+ text: options.message
43
+ }
44
+ });
45
+ console.log(`✅ Added job ${result.id}`);
46
+ console.log(` Schedule: ${result.schedule}`);
43
47
  });
44
- console.log(`✅ Added job ${result.id}`);
45
- console.log(` Schedule: ${result.schedule}`);
46
- await cronService.stop();
47
48
  }));
48
49
  cmd.addCommand(new Command("remove").description("Remove a scheduled task").argument("<id>", "Job ID").action(async (id) => {
49
- const { CronService } = await import("../../cron/index.js");
50
- const cronService = new CronService();
51
- await cronService.initialize();
52
- const success = await cronService.removeJob(id);
53
- await cronService.stop();
54
- if (success) console.log(`✅ Removed job ${id}`);
55
- else {
56
- console.error(`Job ${id} not found`);
57
- process.exit(1);
58
- }
50
+ await withCronService(async (cronService) => {
51
+ if (await cronService.removeJob(id)) console.log(`✅ Removed job ${id}`);
52
+ else {
53
+ console.error(`Job ${id} not found`);
54
+ process.exit(1);
55
+ }
56
+ });
59
57
  }));
58
+ cmd.addCommand(new Command("enable").description("Enable a scheduled task").argument("<id>", "Job ID").action(async (id) => {
59
+ await withCronService(async (cronService) => {
60
+ if (await cronService.toggleJob(id, true)) console.log(`✅ Enabled job ${id}`);
61
+ else {
62
+ console.error(`Job ${id} not found`);
63
+ process.exit(1);
64
+ }
65
+ });
66
+ }));
67
+ cmd.addCommand(new Command("disable").description("Disable a scheduled task").argument("<id>", "Job ID").action(async (id) => {
68
+ await withCronService(async (cronService) => {
69
+ if (await cronService.toggleJob(id, false)) console.log(`✅ Disabled job ${id}`);
70
+ else {
71
+ console.error(`Job ${id} not found`);
72
+ process.exit(1);
73
+ }
74
+ });
75
+ }));
76
+ const runNowAction = async (id) => {
77
+ await withCronService(async (cronService) => {
78
+ try {
79
+ await cronService.runJobNow(id);
80
+ console.log(`✅ Triggered job ${id}`);
81
+ } catch (err) {
82
+ const message = err instanceof Error ? err.message : String(err);
83
+ console.error(message);
84
+ process.exit(1);
85
+ }
86
+ });
87
+ };
88
+ cmd.addCommand(new Command("run").description("Run a scheduled task immediately").argument("<id>", "Job ID").action(runNowAction));
89
+ cmd.addCommand(new Command("trigger").description("Alias for `cron run`").argument("<id>", "Job ID").action(runNowAction));
60
90
  return cmd;
61
91
  }
62
92
  register({
@@ -66,10 +96,15 @@ register({
66
96
  factory: createCronCommand,
67
97
  metadata: {
68
98
  category: "utility",
69
- examples: ["xopc cron list", "xopc cron add --schedule \"0 9 * * *\" --message \"Hello\""]
99
+ examples: [
100
+ "xopc cron list",
101
+ "xopc cron add --schedule \"0 9 * * *\" --message \"Hello\"",
102
+ "xopc cron enable abc12345",
103
+ "xopc cron run abc12345"
104
+ ]
70
105
  }
71
106
  });
72
107
  //#endregion
73
- export {};
108
+ export { createCronCommand };
74
109
 
75
110
  //# sourceMappingURL=cron.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"cron.js","names":[],"sources":["../../../../src/cli/commands/cron.ts"],"sourcesContent":["import { Command } from 'commander';\nimport { register, formatExamples } from '../registry.js';\nimport type { CLIContext } from '../registry.js';\n\nfunction createCronCommand(_ctx: CLIContext): Command {\n const cmd = new Command('cron')\n .description('Manage scheduled tasks')\n .addHelpText(\n 'after',\n formatExamples([\n 'xopc cron list # List all tasks',\n 'xopc cron add --schedule \"0 9 * * *\" --message \"Good morning\"',\n 'xopc cron remove <job-id> # Remove a task',\n ])\n );\n\n cmd.addCommand(\n new Command('list')\n .description('List all scheduled tasks')\n .action(async () => {\n const { CronService } = await import('../../cron/index.js');\n \n const cronService = new CronService();\n await cronService.initialize();\n \n const jobs = await cronService.listJobs();\n \n if (jobs.length === 0) {\n console.log('No scheduled tasks.');\n return;\n }\n \n console.log('Scheduled Tasks:\\n');\n const { getCronPayloadText } = await import('../../cron/job-content.js');\n for (const job of jobs) {\n console.log(` ${job.id} - ${job.schedule}`);\n console.log(` ${getCronPayloadText({ payload: job.payload })}`);\n console.log(` Next: ${job.next_run || 'N/A'}`);\n console.log();\n }\n \n await cronService.stop();\n })\n );\n\n cmd.addCommand(\n new Command('add')\n .description('Add a scheduled task')\n .option('--name <text>', 'Task name')\n .option('--schedule <cron>', 'Cron expression (e.g., \"0 9 * * *\")')\n .option('--message <text>', 'Message to send')\n .action(async (options) => {\n if (!options.schedule || !options.message) {\n console.error('Error: --schedule and --message are required');\n process.exit(1);\n }\n \n const { CronService } = await import('../../cron/index.js');\n const cronService = new CronService();\n await cronService.initialize();\n \n const result = await cronService.addJob(options.schedule, {\n name: options.name,\n payload: { kind: 'systemEvent', text: options.message },\n });\n \n console.log(`✅ Added job ${result.id}`);\n console.log(` Schedule: ${result.schedule}`);\n \n await cronService.stop();\n })\n );\n\n cmd.addCommand(\n new Command('remove')\n .description('Remove a scheduled task')\n .argument('<id>', 'Job ID')\n .action(async (id) => {\n const { CronService } = await import('../../cron/index.js');\n const cronService = new CronService();\n await cronService.initialize();\n \n const success = await cronService.removeJob(id);\n \n await cronService.stop();\n \n if (success) {\n console.log(`✅ Removed job ${id}`);\n } else {\n console.error(`Job ${id} not found`);\n process.exit(1);\n }\n })\n );\n\n return cmd;\n}\n\nregister({\n id: 'cron',\n name: 'cron',\n description: 'Manage scheduled tasks',\n factory: createCronCommand,\n metadata: {\n category: 'utility',\n examples: [\n 'xopc cron list',\n 'xopc cron add --schedule \"0 9 * * *\" --message \"Hello\"',\n ],\n },\n});\n"],"mappings":";;;AAIA,SAAS,kBAAkB,MAA2B;CACpD,MAAM,MAAM,IAAI,QAAQ,OAAO,CAC5B,YAAY,yBAAyB,CACrC,YACC,SACA,eAAe;EACb;EACA;EACA;EACD,CAAC,CACH;AAEH,KAAI,WACF,IAAI,QAAQ,OAAO,CAChB,YAAY,2BAA2B,CACvC,OAAO,YAAY;EAClB,MAAM,EAAE,gBAAgB,MAAM,OAAO;EAErC,MAAM,cAAc,IAAI,aAAa;AACrC,QAAM,YAAY,YAAY;EAE9B,MAAM,OAAO,MAAM,YAAY,UAAU;AAEzC,MAAI,KAAK,WAAW,GAAG;AACrB,WAAQ,IAAI,sBAAsB;AAClC;;AAGF,UAAQ,IAAI,qBAAqB;EACjC,MAAM,EAAE,uBAAuB,MAAM,OAAO;AAC5C,OAAK,MAAM,OAAO,MAAM;AACtB,WAAQ,IAAI,KAAK,IAAI,GAAG,KAAK,IAAI,WAAW;AAC5C,WAAQ,IAAI,QAAQ,mBAAmB,EAAE,SAAS,IAAI,SAAS,CAAC,GAAG;AACnE,WAAQ,IAAI,cAAc,IAAI,YAAY,QAAQ;AAClD,WAAQ,KAAK;;AAGf,QAAM,YAAY,MAAM;GACxB,CACL;AAED,KAAI,WACF,IAAI,QAAQ,MAAM,CACf,YAAY,uBAAuB,CACnC,OAAO,iBAAiB,YAAY,CACpC,OAAO,qBAAqB,wCAAsC,CAClE,OAAO,oBAAoB,kBAAkB,CAC7C,OAAO,OAAO,YAAY;AACzB,MAAI,CAAC,QAAQ,YAAY,CAAC,QAAQ,SAAS;AACzC,WAAQ,MAAM,+CAA+C;AAC7D,WAAQ,KAAK,EAAE;;EAGjB,MAAM,EAAE,gBAAgB,MAAM,OAAO;EACrC,MAAM,cAAc,IAAI,aAAa;AACrC,QAAM,YAAY,YAAY;EAE9B,MAAM,SAAS,MAAM,YAAY,OAAO,QAAQ,UAAU;GACxD,MAAM,QAAQ;GACd,SAAS;IAAE,MAAM;IAAe,MAAM,QAAQ;IAAS;GACxD,CAAC;AAEF,UAAQ,IAAI,eAAe,OAAO,KAAK;AACvC,UAAQ,IAAI,gBAAgB,OAAO,WAAW;AAE9C,QAAM,YAAY,MAAM;GACxB,CACL;AAED,KAAI,WACF,IAAI,QAAQ,SAAS,CAClB,YAAY,0BAA0B,CACtC,SAAS,QAAQ,SAAS,CAC1B,OAAO,OAAO,OAAO;EACpB,MAAM,EAAE,gBAAgB,MAAM,OAAO;EACrC,MAAM,cAAc,IAAI,aAAa;AACrC,QAAM,YAAY,YAAY;EAE9B,MAAM,UAAU,MAAM,YAAY,UAAU,GAAG;AAE/C,QAAM,YAAY,MAAM;AAExB,MAAI,QACF,SAAQ,IAAI,iBAAiB,KAAK;OAC7B;AACL,WAAQ,MAAM,OAAO,GAAG,YAAY;AACpC,WAAQ,KAAK,EAAE;;GAEjB,CACL;AAED,QAAO;;AAGT,SAAS;CACP,IAAI;CACJ,MAAM;CACN,aAAa;CACb,SAAS;CACT,UAAU;EACR,UAAU;EACV,UAAU,CACR,kBACA,6DACD;EACF;CACF,CAAC"}
1
+ {"version":3,"file":"cron.js","names":[],"sources":["../../../../src/cli/commands/cron.ts"],"sourcesContent":["import { Command } from 'commander';\nimport { register, formatExamples } from '../registry.js';\nimport type { CLIContext } from '../registry.js';\nimport { withCronService } from './cron-cli.js';\n\nfunction createCronCommand(_ctx: CLIContext): Command {\n const cmd = new Command('cron')\n .description('Manage scheduled tasks')\n .addHelpText(\n 'after',\n formatExamples([\n 'xopc cron list # List all tasks',\n 'xopc cron add --schedule \"0 9 * * *\" --message \"Good morning\"',\n 'xopc cron enable <job-id> # Enable a task',\n 'xopc cron disable <job-id> # Disable a task',\n 'xopc cron run <job-id> # Run a task now',\n 'xopc cron remove <job-id> # Remove a task',\n ]),\n );\n\n cmd.addCommand(\n new Command('list')\n .description('List all scheduled tasks')\n .action(async () => {\n await withCronService(async (cronService) => {\n const jobs = await cronService.listJobs();\n\n if (jobs.length === 0) {\n console.log('No scheduled tasks.');\n return;\n }\n\n console.log('Scheduled Tasks:\\n');\n const { getCronPayloadText } = await import('../../cron/job-content.js');\n for (const job of jobs) {\n const state = job.enabled ? 'enabled ' : 'disabled';\n console.log(` ${job.id} [${state}] - ${job.schedule}`);\n console.log(` ${getCronPayloadText({ payload: job.payload })}`);\n console.log(` Next: ${job.next_run || 'N/A'}`);\n console.log();\n }\n });\n }),\n );\n\n cmd.addCommand(\n new Command('add')\n .description('Add a scheduled task')\n .option('--name <text>', 'Task name')\n .option('--schedule <cron>', 'Cron expression (e.g., \"0 9 * * *\")')\n .option('--message <text>', 'Message to send')\n .action(async (options) => {\n if (!options.schedule || !options.message) {\n console.error('Error: --schedule and --message are required');\n process.exit(1);\n }\n\n await withCronService(async (cronService) => {\n const result = await cronService.addJob(options.schedule, {\n name: options.name,\n payload: { kind: 'systemEvent', text: options.message },\n });\n\n console.log(`✅ Added job ${result.id}`);\n console.log(` Schedule: ${result.schedule}`);\n });\n }),\n );\n\n cmd.addCommand(\n new Command('remove')\n .description('Remove a scheduled task')\n .argument('<id>', 'Job ID')\n .action(async (id) => {\n await withCronService(async (cronService) => {\n const success = await cronService.removeJob(id);\n if (success) {\n console.log(`✅ Removed job ${id}`);\n } else {\n console.error(`Job ${id} not found`);\n process.exit(1);\n }\n });\n }),\n );\n\n cmd.addCommand(\n new Command('enable')\n .description('Enable a scheduled task')\n .argument('<id>', 'Job ID')\n .action(async (id) => {\n await withCronService(async (cronService) => {\n const success = await cronService.toggleJob(id, true);\n if (success) {\n console.log(`✅ Enabled job ${id}`);\n } else {\n console.error(`Job ${id} not found`);\n process.exit(1);\n }\n });\n }),\n );\n\n cmd.addCommand(\n new Command('disable')\n .description('Disable a scheduled task')\n .argument('<id>', 'Job ID')\n .action(async (id) => {\n await withCronService(async (cronService) => {\n const success = await cronService.toggleJob(id, false);\n if (success) {\n console.log(`✅ Disabled job ${id}`);\n } else {\n console.error(`Job ${id} not found`);\n process.exit(1);\n }\n });\n }),\n );\n\n const runNowAction = async (id: string) => {\n await withCronService(async (cronService) => {\n try {\n await cronService.runJobNow(id);\n console.log(`✅ Triggered job ${id}`);\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n console.error(message);\n process.exit(1);\n }\n });\n };\n\n cmd.addCommand(\n new Command('run')\n .description('Run a scheduled task immediately')\n .argument('<id>', 'Job ID')\n .action(runNowAction),\n );\n\n cmd.addCommand(\n new Command('trigger')\n .description('Alias for `cron run`')\n .argument('<id>', 'Job ID')\n .action(runNowAction),\n );\n\n return cmd;\n}\n\nregister({\n id: 'cron',\n name: 'cron',\n description: 'Manage scheduled tasks',\n factory: createCronCommand,\n metadata: {\n category: 'utility',\n examples: [\n 'xopc cron list',\n 'xopc cron add --schedule \"0 9 * * *\" --message \"Hello\"',\n 'xopc cron enable abc12345',\n 'xopc cron run abc12345',\n ],\n },\n});\n\nexport { createCronCommand };\n"],"mappings":"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"}
@@ -50,7 +50,7 @@ function checkWeixin(cfg) {
50
50
  const hints = [];
51
51
  if ((wx.accounts ? Object.keys(wx.accounts).filter((k) => k.trim()) : []).length === 0) {
52
52
  messages.push("Weixin is enabled but no accounts are defined in config.");
53
- hints.push("Run: xopc channels weixin login (or add channels.weixin.accounts).");
53
+ hints.push("Run: xopc channels login --channel weixin (or add channels.weixin.accounts).");
54
54
  }
55
55
  return {
56
56
  ok: messages.length === 0,