@xopcai/xopc 0.0.117 → 0.0.119

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 (590) hide show
  1. package/README.md +26 -24
  2. package/README.zh-CN.md +46 -42
  3. package/dist/browser-ext/manifest.json +1 -1
  4. package/dist/extensions/telegram/xopc.extension.json +1 -1
  5. package/dist/gateway/static/root/assets/{agent-avatar-dicebear-BBLhJ2C6.js → agent-avatar-dicebear-CU8J6zou.js} +1 -1
  6. package/dist/gateway/static/root/assets/agents-B0hkpLhP.js +2 -0
  7. package/dist/gateway/static/root/assets/app-management-settings-panel-B9vfYoEr.js +1 -0
  8. package/dist/gateway/static/root/assets/appearance-settings-ClOzIO24.js +1 -0
  9. package/dist/gateway/static/root/assets/{apps-page-DdDx0V4z.js → apps-page-DU0dz9Zo.js} +1 -1
  10. package/dist/gateway/static/root/assets/{archive-plugin-DZsVqMhU.js → archive-plugin-BkVIgZzA.js} +1 -1
  11. package/dist/gateway/static/root/assets/{attachment-load-CIol6JWX.js → attachment-load-CaCMWh1D.js} +1 -1
  12. package/dist/gateway/static/root/assets/automation-suggestion-card-DhGDpKP3.js +1 -0
  13. package/dist/gateway/static/root/assets/automations-page-CTedroVo.js +1 -0
  14. package/dist/gateway/static/root/assets/{binary-plugins-B3UauMfp.js → binary-plugins-B4TO_bsn.js} +1 -1
  15. package/dist/gateway/static/root/assets/{block-editor-2HJoFchH.js → block-editor-DJRWwWNI.js} +6 -6
  16. package/dist/gateway/static/root/assets/browser-settings-page-FCDwOOBK.js +8 -0
  17. package/dist/gateway/static/root/assets/capability-presets-api-Befi89CL.js +1 -0
  18. package/dist/gateway/static/root/assets/capability-presets-settings-panel-_G8eb2vJ.js +1 -0
  19. package/dist/gateway/static/root/assets/channel-recipient-api-BNSuJb5f.js +1 -0
  20. package/dist/gateway/static/root/assets/channels-settings-C3d5JBJX.js +1 -0
  21. package/dist/gateway/static/root/assets/cn-BQ_8x0bT.js +1 -0
  22. package/dist/gateway/static/root/assets/connectors-page-yaUNvt5u.js +2 -0
  23. package/dist/gateway/static/root/assets/cron-expression-B3B1eqnr.js +2 -0
  24. package/dist/gateway/static/root/assets/dreaming-settings-DNrdg1Ve.js +1 -0
  25. package/dist/gateway/static/root/assets/{extension-debug-page-DX5WRE_t.js → extension-debug-page-DYh402XV.js} +1 -1
  26. package/dist/gateway/static/root/assets/{extension-page-Buah7Bw-.js → extension-page-Cr_TizrN.js} +1 -1
  27. package/dist/gateway/static/root/assets/{extension-settings-page-DuroLVnf.js → extension-settings-page-BU1KoKRj.js} +1 -1
  28. package/dist/gateway/static/root/assets/{fetch-B5zdl27C.js → fetch-Y7AEX4H3.js} +1 -1
  29. package/dist/gateway/static/root/assets/format-cron-label-arqgGlVV.js +1 -0
  30. package/dist/gateway/static/root/assets/{gateway-config-api-gT4ZhE7h.js → gateway-config-api-RbMmAOpX.js} +1 -1
  31. package/dist/gateway/static/root/assets/gateway-settings-C79wkXef.js +1 -0
  32. package/dist/gateway/static/root/assets/{gateway-startup-retry-B3kL8KGY.js → gateway-startup-retry-DiD_Tx4N.js} +1 -1
  33. package/dist/gateway/static/root/assets/goal-detail-page-9paXuHdo.js +1 -0
  34. package/dist/gateway/static/root/assets/{goals-config-api-AR-fVh0P.js → goals-config-api-DqxVi0p5.js} +1 -1
  35. package/dist/gateway/static/root/assets/{goals-page-Cpb21ezg.js → goals-page-CS0R-Af2.js} +2 -2
  36. package/dist/gateway/static/root/assets/goals-settings-CSuzZ8Ae.js +1 -0
  37. package/dist/gateway/static/root/assets/heartbeat-settings-DXPaYJm3.js +1 -0
  38. package/dist/gateway/static/root/assets/index-BoKafJIZ.js +191 -0
  39. package/dist/gateway/static/root/assets/index-CArhCcYn.css +1 -0
  40. package/dist/gateway/static/root/assets/keyboard-shortcuts-settings-Dvg53qnd.js +1 -0
  41. package/dist/gateway/static/root/assets/{logs-page-DefCgF4o.js → logs-page-DLXPcksQ.js} +2 -2
  42. package/dist/gateway/static/root/assets/{markdown-split-ChbR9LGO.js → markdown-split-CpHxbtWJ.js} +1 -1
  43. package/dist/gateway/static/root/assets/{media-plugins-B82oP80n.js → media-plugins-SFPQRSxq.js} +1 -1
  44. package/dist/gateway/static/root/assets/messages-CrDHEbss.js +3 -0
  45. package/dist/gateway/static/root/assets/models-hub-panel-BDF2iyRk.js +2 -0
  46. package/dist/gateway/static/root/assets/note-detail-page-CSb_hwig.js +2 -0
  47. package/dist/gateway/static/root/assets/{note-image-lightbox-CDknITM3.js → note-image-lightbox-BUYURRgn.js} +1 -1
  48. package/dist/gateway/static/root/assets/notes-page-BsIBSFyZ.js +1 -0
  49. package/dist/gateway/static/root/assets/{preview-open-alternatives-DV3xQsWB.js → preview-open-alternatives-BHz9iWYA.js} +1 -1
  50. package/dist/gateway/static/root/assets/remote-access-hub-CwzSovcS.js +1 -0
  51. package/dist/gateway/static/root/assets/{save-bar-controls-BODCXnvY.js → save-bar-controls-CefkOlRg.js} +1 -1
  52. package/dist/gateway/static/root/assets/schedule-field-CmTRoOcE.js +1 -0
  53. package/dist/gateway/static/root/assets/{schema-form-qtfEI6QM.js → schema-form-FMKv1vGu.js} +1 -1
  54. package/dist/gateway/static/root/assets/sessions-page-PHmX-NmA.js +1 -0
  55. package/dist/gateway/static/root/assets/settings-advanced-gate-BRAeKJN4.js +1 -0
  56. package/dist/gateway/static/root/assets/{settings-collapsible-section-BHZKjVcS.js → settings-collapsible-section-BouO6JTi.js} +1 -1
  57. package/dist/gateway/static/root/assets/{settings-form-section-5i35D-J1.js → settings-form-section-D-4lBl6X.js} +1 -1
  58. package/dist/gateway/static/root/assets/settings-page-KKrbFjy8.js +1 -0
  59. package/dist/gateway/static/root/assets/settings-page-layout-BJ4Gsef5.js +1 -0
  60. package/dist/gateway/static/root/assets/setup-status-panel-CrUjHPQo.js +1 -0
  61. package/dist/gateway/static/root/assets/{share-preview-page-B0H63tDv.js → share-preview-page-BDy2btRN.js} +1 -1
  62. package/dist/gateway/static/root/assets/shares-settings-B18OBmH5.js +1 -0
  63. package/dist/gateway/static/root/assets/skill-reload-api-C28-2uKQ.js +1 -0
  64. package/dist/gateway/static/root/assets/skills-page-Bm2ebkwl.js +2 -0
  65. package/dist/gateway/static/root/assets/system-settings-panel-CRngrlnZ.js +1 -0
  66. package/dist/gateway/static/root/assets/typed-models-lib-BltBc0b-.js +1 -0
  67. package/dist/gateway/static/root/assets/{use-channel-catalog-BCjP_VHb.js → use-channel-catalog-CjN-51e6.js} +1 -1
  68. package/dist/gateway/static/root/assets/user-profile-settings-panel-DJ1dKwZy.js +1 -0
  69. package/dist/gateway/static/root/assets/utils-B5M5-YvK.js +1 -0
  70. package/dist/gateway/static/root/assets/voice-api-key-field-CeEevm7z.js +1 -0
  71. package/dist/gateway/static/root/assets/{voice-player-store-BlF9V05n.js → voice-player-store-B7ykUlHM.js} +1 -1
  72. package/dist/gateway/static/root/assets/workflow-run-setup-panel-C4PzUQjB.js +3 -0
  73. package/dist/gateway/static/root/assets/workflows-page-BL84_-Ky.js +18 -0
  74. package/dist/gateway/static/root/index.html +6 -7
  75. package/dist/package.js +1 -1
  76. package/dist/src/agent/agent-manager.d.ts +4 -5
  77. package/dist/src/agent/agent-manager.js +6 -9
  78. package/dist/src/agent/agent-manager.js.map +1 -1
  79. package/dist/src/agent/agent-scope.js +0 -2
  80. package/dist/src/agent/agent-scope.js.map +1 -1
  81. package/dist/src/agent/background-review/prompts.d.ts +2 -2
  82. package/dist/src/agent/background-review/prompts.js +2 -2
  83. package/dist/src/agent/background-review/prompts.js.map +1 -1
  84. package/dist/src/agent/background-review/settings.d.ts +1 -1
  85. package/dist/src/agent/background-review/settings.js +7 -8
  86. package/dist/src/agent/background-review/settings.js.map +1 -1
  87. package/dist/src/agent/bootstrap/bootstrap-cache.d.ts +1 -0
  88. package/dist/src/agent/bootstrap/bootstrap-cache.js +4 -3
  89. package/dist/src/agent/bootstrap/bootstrap-cache.js.map +1 -1
  90. package/dist/src/agent/bootstrap/bootstrap-files.d.ts +4 -0
  91. package/dist/src/agent/bootstrap/bootstrap-files.js +4 -3
  92. package/dist/src/agent/bootstrap/bootstrap-files.js.map +1 -1
  93. package/dist/src/agent/bootstrap/filter-bootstrap-files.js +4 -2
  94. package/dist/src/agent/bootstrap/filter-bootstrap-files.js.map +1 -1
  95. package/dist/src/agent/bootstrap/load-bootstrap-files.d.ts +2 -1
  96. package/dist/src/agent/bootstrap/load-bootstrap-files.js +17 -16
  97. package/dist/src/agent/bootstrap/load-bootstrap-files.js.map +1 -1
  98. package/dist/src/agent/bootstrap/types.d.ts +1 -1
  99. package/dist/src/agent/context/workspace-templates/AGENTS.md +1 -1
  100. package/dist/src/agent/context/workspace.d.ts +4 -2
  101. package/dist/src/agent/context/workspace.js +5 -4
  102. package/dist/src/agent/context/workspace.js.map +1 -1
  103. package/dist/src/agent/embedded/run-for-session.js +106 -15
  104. package/dist/src/agent/embedded/run-for-session.js.map +1 -1
  105. package/dist/src/agent/fallback/candidates.d.ts +0 -8
  106. package/dist/src/agent/fallback/candidates.js +10 -11
  107. package/dist/src/agent/fallback/candidates.js.map +1 -1
  108. package/dist/src/agent/index.js +1 -1
  109. package/dist/src/agent/lifecycle/handlers/compaction.d.ts +1 -3
  110. package/dist/src/agent/lifecycle/handlers/compaction.js +1 -16
  111. package/dist/src/agent/lifecycle/handlers/compaction.js.map +1 -1
  112. package/dist/src/agent/lifecycle/progress.d.ts +0 -1
  113. package/dist/src/agent/lifecycle/progress.js +1 -6
  114. package/dist/src/agent/lifecycle/progress.js.map +1 -1
  115. package/dist/src/agent/lifecycle/timeout-wrapper.d.ts +1 -2
  116. package/dist/src/agent/lifecycle/timeout-wrapper.js +1 -7
  117. package/dist/src/agent/lifecycle/timeout-wrapper.js.map +1 -1
  118. package/dist/src/agent/memory/builtin-memory-store.d.ts +4 -2
  119. package/dist/src/agent/memory/builtin-memory-store.js +11 -6
  120. package/dist/src/agent/memory/builtin-memory-store.js.map +1 -1
  121. package/dist/src/agent/memory/builtin-provider.js +36 -7
  122. package/dist/src/agent/memory/builtin-provider.js.map +1 -1
  123. package/dist/src/agent/memory/candidate-extractor.d.ts +6 -0
  124. package/dist/src/agent/memory/candidate-extractor.js +60 -0
  125. package/dist/src/agent/memory/candidate-extractor.js.map +1 -0
  126. package/dist/src/agent/memory/manager.d.ts +2 -1
  127. package/dist/src/agent/memory/manager.js +27 -3
  128. package/dist/src/agent/memory/manager.js.map +1 -1
  129. package/dist/src/agent/memory/memory-config.js +3 -0
  130. package/dist/src/agent/memory/memory-config.js.map +1 -1
  131. package/dist/src/agent/memory/prefetch-coordinator.js.map +1 -1
  132. package/dist/src/agent/memory/types.d.ts +27 -4
  133. package/dist/src/agent/middleware/self-verify.d.ts +0 -1
  134. package/dist/src/agent/middleware/self-verify.js +0 -2
  135. package/dist/src/agent/middleware/self-verify.js.map +1 -1
  136. package/dist/src/agent/models/index.d.ts +1 -1
  137. package/dist/src/agent/models/manager.d.ts +4 -20
  138. package/dist/src/agent/models/manager.js +9 -126
  139. package/dist/src/agent/models/manager.js.map +1 -1
  140. package/dist/src/agent/orchestration/agent-orchestrator.d.ts +0 -4
  141. package/dist/src/agent/orchestration/agent-orchestrator.js +1 -9
  142. package/dist/src/agent/orchestration/agent-orchestrator.js.map +1 -1
  143. package/dist/src/agent/prompt/memory/index.d.ts +4 -2
  144. package/dist/src/agent/prompt/memory/index.js +18 -12
  145. package/dist/src/agent/prompt/memory/index.js.map +1 -1
  146. package/dist/src/agent/prompt/sections/memory-skills.js +1 -1
  147. package/dist/src/agent/prompt/sections/memory-skills.js.map +1 -1
  148. package/dist/src/agent/prompt/sections/tooling.js +2 -2
  149. package/dist/src/agent/prompt/sections/tooling.js.map +1 -1
  150. package/dist/src/agent/prompt/service-prompt-builder.d.ts +0 -1
  151. package/dist/src/agent/prompt/service-prompt-builder.js +4 -31
  152. package/dist/src/agent/prompt/service-prompt-builder.js.map +1 -1
  153. package/dist/src/agent/prompt/subagent-context.js +1 -1
  154. package/dist/src/agent/prompt/subagent-context.js.map +1 -1
  155. package/dist/src/agent/prompt/types.d.ts +1 -1
  156. package/dist/src/agent/reply/post-compaction-context.js +1 -3
  157. package/dist/src/agent/reply/post-compaction-context.js.map +1 -1
  158. package/dist/src/agent/reply/startup-context.js +1 -5
  159. package/dist/src/agent/reply/startup-context.js.map +1 -1
  160. package/dist/src/agent/service.d.ts +4 -12
  161. package/dist/src/agent/service.js +10 -48
  162. package/dist/src/agent/service.js.map +1 -1
  163. package/dist/src/agent/service.types.d.ts +2 -2
  164. package/dist/src/agent/session/session-config-service.d.ts +11 -11
  165. package/dist/src/agent/session/session-config-service.js +14 -14
  166. package/dist/src/agent/session/session-config-service.js.map +1 -1
  167. package/dist/src/agent/session/session-inspector.js +3 -2
  168. package/dist/src/agent/session/session-inspector.js.map +1 -1
  169. package/dist/src/agent/starter-agents.js +12 -12
  170. package/dist/src/agent/starter-agents.js.map +1 -1
  171. package/dist/src/agent/tools/automation-tool.d.ts +14 -0
  172. package/dist/src/agent/tools/automation-tool.js +102 -0
  173. package/dist/src/agent/tools/automation-tool.js.map +1 -0
  174. package/dist/src/agent/tools/curated-memory-tool.js +57 -2
  175. package/dist/src/agent/tools/curated-memory-tool.js.map +1 -1
  176. package/dist/src/agent/tools/delegate-tool.js +1 -1
  177. package/dist/src/agent/tools/delegate-tool.js.map +1 -1
  178. package/dist/src/agent/tools/factory.d.ts +3 -3
  179. package/dist/src/agent/tools/factory.js +2 -2
  180. package/dist/src/agent/tools/factory.js.map +1 -1
  181. package/dist/src/agent/tools/index.d.ts +1 -1
  182. package/dist/src/agent/tools/index.js +2 -2
  183. package/dist/src/agent/tools/web-extract.js +6 -8
  184. package/dist/src/agent/tools/web-extract.js.map +1 -1
  185. package/dist/src/agent-manifest/index.js +2 -2
  186. package/dist/src/agent-manifest/resolver.d.ts +4 -2
  187. package/dist/src/agent-manifest/resolver.js +6 -3
  188. package/dist/src/agent-manifest/resolver.js.map +1 -1
  189. package/dist/src/agent-manifest/schema.d.ts +238 -0
  190. package/dist/src/agent-manifest/schema.js +16 -5
  191. package/dist/src/agent-manifest/schema.js.map +1 -1
  192. package/dist/src/agent-manifest/validator.d.ts +3 -2
  193. package/dist/src/agent-manifest/validator.js +2 -1
  194. package/dist/src/agent-manifest/validator.js.map +1 -1
  195. package/dist/src/ai-assist/text-assist.d.ts +1 -1
  196. package/dist/src/ai-assist/text-assist.js +56 -0
  197. package/dist/src/ai-assist/text-assist.js.map +1 -1
  198. package/dist/src/auth/profiles/store.js.map +1 -1
  199. package/dist/src/automations/api/routes.d.ts +3 -0
  200. package/dist/src/automations/api/routes.js +193 -0
  201. package/dist/src/automations/api/routes.js.map +1 -0
  202. package/dist/src/automations/domain/index.d.ts +3 -0
  203. package/dist/src/automations/domain/index.js +3 -0
  204. package/dist/src/automations/domain/schedule.d.ts +4 -0
  205. package/dist/src/automations/domain/schedule.js +37 -0
  206. package/dist/src/automations/domain/schedule.js.map +1 -0
  207. package/dist/src/automations/domain/types.d.ts +160 -0
  208. package/dist/src/automations/domain/validation.d.ts +370 -0
  209. package/dist/src/automations/domain/validation.js +149 -0
  210. package/dist/src/automations/domain/validation.js.map +1 -0
  211. package/dist/src/automations/draft/automation-draft-prompt.d.ts +26 -0
  212. package/dist/src/automations/draft/automation-draft-prompt.js +127 -0
  213. package/dist/src/automations/draft/automation-draft-prompt.js.map +1 -0
  214. package/dist/src/automations/draft/automation-draft-service.d.ts +12 -0
  215. package/dist/src/automations/draft/automation-draft-service.js +135 -0
  216. package/dist/src/automations/draft/automation-draft-service.js.map +1 -0
  217. package/dist/src/automations/draft/automation-draft-validator.d.ts +99 -0
  218. package/dist/src/automations/draft/automation-draft-validator.js +105 -0
  219. package/dist/src/automations/draft/automation-draft-validator.js.map +1 -0
  220. package/dist/src/automations/draft/automation-draft.types.d.ts +40 -0
  221. package/dist/src/automations/draft/index.d.ts +3 -0
  222. package/dist/src/automations/draft/index.js +3 -0
  223. package/dist/src/automations/index.d.ts +3 -0
  224. package/dist/src/automations/index.js +8 -0
  225. package/dist/src/automations/product-events.d.ts +5 -0
  226. package/dist/src/automations/product-events.js +21 -0
  227. package/dist/src/automations/product-events.js.map +1 -0
  228. package/dist/src/automations/service/action-executor.d.ts +9 -0
  229. package/dist/src/automations/service/action-executor.js +157 -0
  230. package/dist/src/automations/service/action-executor.js.map +1 -0
  231. package/dist/src/automations/service/automation-service.d.ts +54 -0
  232. package/dist/src/automations/service/automation-service.js +404 -0
  233. package/dist/src/automations/service/automation-service.js.map +1 -0
  234. package/dist/src/automations/service/index.d.ts +2 -0
  235. package/dist/src/automations/service/index.js +3 -0
  236. package/dist/src/automations/storage/automation-repository.d.ts +6 -0
  237. package/dist/src/automations/storage/automation-repository.js +61 -0
  238. package/dist/src/automations/storage/automation-repository.js.map +1 -0
  239. package/dist/src/automations/storage/automation-run-repository.d.ts +17 -0
  240. package/dist/src/automations/storage/automation-run-repository.js +130 -0
  241. package/dist/src/automations/storage/automation-run-repository.js.map +1 -0
  242. package/dist/src/automations/storage/index.d.ts +2 -0
  243. package/dist/src/automations/storage/index.js +3 -0
  244. package/dist/src/channels/pipeline.d.ts +1 -1
  245. package/dist/src/channels/pipeline.js.map +1 -1
  246. package/dist/src/channels/plugin-types.d.ts +3 -0
  247. package/dist/src/chat-commands/agent-edit.js +0 -1
  248. package/dist/src/chat-commands/agent-edit.js.map +1 -1
  249. package/dist/src/chat-commands/builtins/model.js +2 -2
  250. package/dist/src/chat-commands/builtins/model.js.map +1 -1
  251. package/dist/src/chat-commands/builtins/thinking.js.map +1 -1
  252. package/dist/src/cli/command-catalog.js +0 -39
  253. package/dist/src/cli/command-catalog.js.map +1 -1
  254. package/dist/src/cli/command-loaders.js +0 -1
  255. package/dist/src/cli/command-loaders.js.map +1 -1
  256. package/dist/src/cli/command-manifest.d.ts +1 -1
  257. package/dist/src/cli/command-manifest.js +1 -5
  258. package/dist/src/cli/command-manifest.js.map +1 -1
  259. package/dist/src/cli/commands/agents.js +7 -6
  260. package/dist/src/cli/commands/agents.js.map +1 -1
  261. package/dist/src/cli/commands/doctor/checks/database-schema.js +1 -1
  262. package/dist/src/cli/commands/doctor/checks/{cron-health.d.ts → migrations.d.ts} +1 -1
  263. package/dist/src/cli/commands/doctor/checks/migrations.js +40 -0
  264. package/dist/src/cli/commands/doctor/checks/migrations.js.map +1 -0
  265. package/dist/src/cli/commands/doctor/checks/provider-auth.js +1 -0
  266. package/dist/src/cli/commands/doctor/checks/provider-auth.js.map +1 -1
  267. package/dist/src/cli/commands/doctor/checks/workspace-status.js +0 -1
  268. package/dist/src/cli/commands/doctor/checks/workspace-status.js.map +1 -1
  269. package/dist/src/cli/commands/doctor/flow.js +2 -2
  270. package/dist/src/cli/commands/doctor/flow.js.map +1 -1
  271. package/dist/src/cli/commands/gateway/call.js +2 -2
  272. package/dist/src/cli/commands/gateway/call.js.map +1 -1
  273. package/dist/src/cli/commands/gateway/lifecycle.js +1 -1
  274. package/dist/src/cli/commands/gateway/run-foreground.js +4 -2
  275. package/dist/src/cli/commands/gateway/run-foreground.js.map +1 -1
  276. package/dist/src/cli/commands/init.js +33 -14
  277. package/dist/src/cli/commands/init.js.map +1 -1
  278. package/dist/src/cli/commands/models.js +13 -31
  279. package/dist/src/cli/commands/models.js.map +1 -1
  280. package/dist/src/cli/commands/onboard/model.js +17 -10
  281. package/dist/src/cli/commands/onboard/model.js.map +1 -1
  282. package/dist/src/cli/commands/onboard.js +2 -2
  283. package/dist/src/cli/commands/onboard.js.map +1 -1
  284. package/dist/src/cli/commands/tui.js +26 -4
  285. package/dist/src/cli/commands/tui.js.map +1 -1
  286. package/dist/src/cli/index.d.ts +1 -0
  287. package/dist/src/cli/index.js +10 -5
  288. package/dist/src/cli/index.js.map +1 -1
  289. package/dist/src/cli/registry.js +1 -1
  290. package/dist/src/cli/registry.js.map +1 -1
  291. package/dist/src/cli/templates.d.ts +1 -1
  292. package/dist/src/cli/templates.js +1 -11
  293. package/dist/src/cli/templates.js.map +1 -1
  294. package/dist/src/cli/utils/init-workspace-core.js +2 -0
  295. package/dist/src/cli/utils/init-workspace-core.js.map +1 -1
  296. package/dist/src/commands/agents.config.d.ts +9 -0
  297. package/dist/src/commands/agents.config.js +42 -12
  298. package/dist/src/commands/agents.config.js.map +1 -1
  299. package/dist/src/config/agent-profile.js +5 -3
  300. package/dist/src/config/agent-profile.js.map +1 -1
  301. package/dist/src/config/agent-typed-models.js +3 -5
  302. package/dist/src/config/agent-typed-models.js.map +1 -1
  303. package/dist/src/config/config-surface.d.ts +3 -0
  304. package/dist/src/config/index.d.ts +0 -1
  305. package/dist/src/config/index.js +3 -3
  306. package/dist/src/config/index.js.map +1 -1
  307. package/dist/src/config/paths.d.ts +8 -10
  308. package/dist/src/config/paths.js +16 -16
  309. package/dist/src/config/paths.js.map +1 -1
  310. package/dist/src/config/profile.js +0 -1
  311. package/dist/src/config/profile.js.map +1 -1
  312. package/dist/src/config/rules.js +0 -5
  313. package/dist/src/config/rules.js.map +1 -1
  314. package/dist/src/config/schema.d.ts +45 -44
  315. package/dist/src/config/schema.js +68 -52
  316. package/dist/src/config/schema.js.map +1 -1
  317. package/dist/src/config/web-patch.d.ts +0 -12
  318. package/dist/src/config/web-patch.js +2 -29
  319. package/dist/src/config/web-patch.js.map +1 -1
  320. package/dist/src/extensions/api.d.ts +2 -0
  321. package/dist/src/extensions/api.js +10 -0
  322. package/dist/src/extensions/api.js.map +1 -1
  323. package/dist/src/extensions/extension-registry-impl.d.ts +4 -1
  324. package/dist/src/extensions/extension-registry-impl.js +8 -0
  325. package/dist/src/extensions/extension-registry-impl.js.map +1 -1
  326. package/dist/src/extensions/loader.d.ts +3 -3
  327. package/dist/src/extensions/loader.js +3 -3
  328. package/dist/src/extensions/loader.js.map +1 -1
  329. package/dist/src/extensions/sdk/testing.d.ts +2 -0
  330. package/dist/src/extensions/sdk/testing.js +7 -0
  331. package/dist/src/extensions/sdk/testing.js.map +1 -1
  332. package/dist/src/extensions/types/core.d.ts +10 -1
  333. package/dist/src/extensions/types/index.d.ts +1 -1
  334. package/dist/src/extensions/types/{phase4.d.ts → registration.d.ts} +2 -2
  335. package/dist/src/gateway/agent-builtin-tools.d.ts +1 -1
  336. package/dist/src/gateway/agent-builtin-tools.js +1 -1
  337. package/dist/src/gateway/agent-builtin-tools.js.map +1 -1
  338. package/dist/src/gateway/agents-admin.d.ts +8 -0
  339. package/dist/src/gateway/agents-admin.js +63 -34
  340. package/dist/src/gateway/agents-admin.js.map +1 -1
  341. package/dist/src/gateway/capability-presets-admin.d.ts +1 -0
  342. package/dist/src/gateway/capability-presets-admin.js +19 -10
  343. package/dist/src/gateway/capability-presets-admin.js.map +1 -1
  344. package/dist/src/gateway/chat-stream/mapper.js +9 -2
  345. package/dist/src/gateway/chat-stream/mapper.js.map +1 -1
  346. package/dist/src/gateway/dreaming-automation-reconciler.d.ts +11 -0
  347. package/dist/src/gateway/dreaming-automation-reconciler.js +105 -0
  348. package/dist/src/gateway/dreaming-automation-reconciler.js.map +1 -0
  349. package/dist/src/gateway/global-defaults-admin.d.ts +36 -0
  350. package/dist/src/gateway/global-defaults-admin.js +146 -0
  351. package/dist/src/gateway/global-defaults-admin.js.map +1 -0
  352. package/dist/src/gateway/heartbeat/service.d.ts +0 -2
  353. package/dist/src/gateway/heartbeat/service.js +0 -7
  354. package/dist/src/gateway/heartbeat/service.js.map +1 -1
  355. package/dist/src/gateway/hono/lib/config-payload.d.ts +5 -6
  356. package/dist/src/gateway/hono/lib/config-payload.js +2 -2
  357. package/dist/src/gateway/hono/lib/config-payload.js.map +1 -1
  358. package/dist/src/gateway/hono/routes/agents.js +33 -1
  359. package/dist/src/gateway/hono/routes/agents.js.map +1 -1
  360. package/dist/src/gateway/hono/routes/commands-skills.js +4 -5
  361. package/dist/src/gateway/hono/routes/commands-skills.js.map +1 -1
  362. package/dist/src/gateway/hono/routes/config-patch/misc.d.ts +1 -1
  363. package/dist/src/gateway/hono/routes/config-patch/misc.js +12 -6
  364. package/dist/src/gateway/hono/routes/config-patch/misc.js.map +1 -1
  365. package/dist/src/gateway/hono/routes/dreaming.js +27 -37
  366. package/dist/src/gateway/hono/routes/dreaming.js.map +1 -1
  367. package/dist/src/gateway/hono/routes/global-defaults.d.ts +3 -0
  368. package/dist/src/gateway/hono/routes/global-defaults.js +61 -0
  369. package/dist/src/gateway/hono/routes/global-defaults.js.map +1 -0
  370. package/dist/src/gateway/hono/routes/home.d.ts +2 -2
  371. package/dist/src/gateway/hono/routes/home.js +34 -25
  372. package/dist/src/gateway/hono/routes/home.js.map +1 -1
  373. package/dist/src/gateway/hono/routes/lazy-bundles.js +21 -9
  374. package/dist/src/gateway/hono/routes/lazy-bundles.js.map +1 -1
  375. package/dist/src/gateway/hono/routes/memory.js +75 -4
  376. package/dist/src/gateway/hono/routes/memory.js.map +1 -1
  377. package/dist/src/gateway/hono/routes/migrations.d.ts +3 -0
  378. package/dist/src/gateway/hono/routes/migrations.js +35 -0
  379. package/dist/src/gateway/hono/routes/migrations.js.map +1 -0
  380. package/dist/src/gateway/hono/routes/models.js +1 -1
  381. package/dist/src/gateway/hono/routes/public-gateway.js +2 -1
  382. package/dist/src/gateway/hono/routes/public-gateway.js.map +1 -1
  383. package/dist/src/gateway/hono/routes/sessions.js +14 -0
  384. package/dist/src/gateway/hono/routes/sessions.js.map +1 -1
  385. package/dist/src/gateway/run-loop.js +2 -0
  386. package/dist/src/gateway/run-loop.js.map +1 -1
  387. package/dist/src/gateway/security/operator-scopes.js +5 -1
  388. package/dist/src/gateway/security/operator-scopes.js.map +1 -1
  389. package/dist/src/gateway/service/config-coordinator.d.ts +4 -4
  390. package/dist/src/gateway/service/config-coordinator.js +14 -8
  391. package/dist/src/gateway/service/config-coordinator.js.map +1 -1
  392. package/dist/src/gateway/service/marketplace-service.d.ts +4 -4
  393. package/dist/src/gateway/service/marketplace-service.js +11 -7
  394. package/dist/src/gateway/service/marketplace-service.js.map +1 -1
  395. package/dist/src/gateway/service/sessions-api.d.ts +2 -1
  396. package/dist/src/gateway/service/sessions-api.js +6 -1
  397. package/dist/src/gateway/service/sessions-api.js.map +1 -1
  398. package/dist/src/gateway/service.d.ts +7 -3
  399. package/dist/src/gateway/service.js +61 -27
  400. package/dist/src/gateway/service.js.map +1 -1
  401. package/dist/src/goals/goal-service.js +45 -4
  402. package/dist/src/goals/goal-service.js.map +1 -1
  403. package/dist/src/infra/update-restart.js +1 -1
  404. package/dist/src/migrations/config/default-capability-preset.d.ts +10 -0
  405. package/dist/src/migrations/config/default-capability-preset.js +135 -0
  406. package/dist/src/migrations/config/default-capability-preset.js.map +1 -0
  407. package/dist/src/migrations/index.d.ts +4 -0
  408. package/dist/src/migrations/index.js +4 -0
  409. package/dist/src/migrations/registry.d.ts +8 -0
  410. package/dist/src/migrations/registry.js +18 -0
  411. package/dist/src/migrations/registry.js.map +1 -0
  412. package/dist/src/migrations/runner.d.ts +17 -0
  413. package/dist/src/migrations/runner.js +191 -0
  414. package/dist/src/migrations/runner.js.map +1 -0
  415. package/dist/src/migrations/types.d.ts +34 -0
  416. package/dist/src/notes/service.js +27 -2
  417. package/dist/src/notes/service.js.map +1 -1
  418. package/dist/src/providers/index.d.ts +4 -5
  419. package/dist/src/providers/index.js +16 -16
  420. package/dist/src/providers/index.js.map +1 -1
  421. package/dist/src/providers/model-registry.d.ts +0 -1
  422. package/dist/src/providers/model-registry.js +0 -3
  423. package/dist/src/providers/model-registry.js.map +1 -1
  424. package/dist/src/routing/resolve-tui-session-key.d.ts +3 -0
  425. package/dist/src/routing/resolve-tui-session-key.js +14 -3
  426. package/dist/src/routing/resolve-tui-session-key.js.map +1 -1
  427. package/dist/src/session/session-workspace.js +2 -7
  428. package/dist/src/session/session-workspace.js.map +1 -1
  429. package/dist/src/session/store.js +0 -5
  430. package/dist/src/session/store.js.map +1 -1
  431. package/dist/src/session/transcript-outline.d.ts +47 -0
  432. package/dist/src/session/transcript-outline.js +481 -0
  433. package/dist/src/session/transcript-outline.js.map +1 -0
  434. package/dist/src/storage/sqlite/index.d.ts +1 -3
  435. package/dist/src/storage/sqlite/index.js +2 -4
  436. package/dist/src/storage/sqlite/memory-index-repository.d.ts +1 -0
  437. package/dist/src/storage/sqlite/memory-index-repository.js +15 -14
  438. package/dist/src/storage/sqlite/memory-index-repository.js.map +1 -1
  439. package/dist/src/storage/sqlite/memory-records-repository.d.ts +44 -1
  440. package/dist/src/storage/sqlite/memory-records-repository.js +164 -20
  441. package/dist/src/storage/sqlite/memory-records-repository.js.map +1 -1
  442. package/dist/src/storage/sqlite/migrations/014_memory_record_governance.sql +10 -0
  443. package/dist/src/storage/sqlite/migrations/015_memory_trace_feedback.sql +4 -0
  444. package/dist/src/storage/sqlite/migrations/016_automations.sql +47 -0
  445. package/dist/src/storage/sqlite/migrations/017_automation_run_events.sql +14 -0
  446. package/dist/src/storage/sqlite/migrations/018_automation_safety.sql +1 -0
  447. package/dist/src/storage/sqlite/migrations/runner.d.ts +1 -1
  448. package/dist/src/storage/sqlite/migrations/runner.js +3 -3
  449. package/dist/src/storage/sqlite/migrations/runner.js.map +1 -1
  450. package/dist/src/storage/sqlite/migrations/runner.ts +1 -1
  451. package/dist/src/storage/sqlite/schema.js +1 -1
  452. package/dist/src/storage/sqlite/schema.sql +56 -46
  453. package/dist/src/tui/backends/embedded-backend.d.ts +9 -0
  454. package/dist/src/tui/backends/embedded-backend.js +55 -27
  455. package/dist/src/tui/backends/embedded-backend.js.map +1 -1
  456. package/dist/src/tui/backends/gateway-sse-backend.d.ts +4 -0
  457. package/dist/src/tui/backends/gateway-sse-backend.js +30 -3
  458. package/dist/src/tui/backends/gateway-sse-backend.js.map +1 -1
  459. package/dist/src/tui/components/tui-header.d.ts +0 -1
  460. package/dist/src/tui/components/tui-header.js +3 -8
  461. package/dist/src/tui/components/tui-header.js.map +1 -1
  462. package/dist/src/tui/tui-backend.d.ts +4 -0
  463. package/dist/src/tui/tui-commands.d.ts +5 -0
  464. package/dist/src/tui/tui-commands.js +43 -0
  465. package/dist/src/tui/tui-commands.js.map +1 -1
  466. package/dist/src/tui/tui-startup-resources.js +2 -1
  467. package/dist/src/tui/tui-startup-resources.js.map +1 -1
  468. package/dist/src/tui/tui-startup-text.js +12 -12
  469. package/dist/src/tui/tui-startup-text.js.map +1 -1
  470. package/dist/src/tui/tui-transcript-tree.d.ts +1 -1
  471. package/dist/src/tui/tui-transcript-tree.js +17 -257
  472. package/dist/src/tui/tui-transcript-tree.js.map +1 -1
  473. package/dist/src/tui/tui-types.d.ts +2 -0
  474. package/dist/src/tui/tui-types.js.map +1 -1
  475. package/dist/src/tui/tui.js +11 -3
  476. package/dist/src/tui/tui.js.map +1 -1
  477. package/dist/src/workflows/domain/index.js +1 -1
  478. package/dist/src/workflows/domain/run.d.ts +7 -7
  479. package/dist/src/workflows/domain/run.js.map +1 -1
  480. package/dist/src/workflows/index.js +2 -2
  481. package/dist/src/workflows/service/workflow-run-service.d.ts +2 -0
  482. package/dist/src/workflows/service/workflow-run-service.js +31 -9
  483. package/dist/src/workflows/service/workflow-run-service.js.map +1 -1
  484. package/dist/src/workflows/service/workflow-run-service.types.d.ts +1 -1
  485. package/package.json +4 -2
  486. package/dist/gateway/static/root/assets/agents-C6xgagZd.js +0 -71
  487. package/dist/gateway/static/root/assets/app-management-settings-panel-CBpLONvG.js +0 -1
  488. package/dist/gateway/static/root/assets/appearance-settings-CGcc54yj.js +0 -1
  489. package/dist/gateway/static/root/assets/browser-settings-page-CUOO-PQk.js +0 -8
  490. package/dist/gateway/static/root/assets/capability-presets-api-XQoMTI0A.js +0 -1
  491. package/dist/gateway/static/root/assets/capability-presets-settings-panel-CfqF-kGr.js +0 -1
  492. package/dist/gateway/static/root/assets/channels-settings-BYyRzsex.js +0 -1
  493. package/dist/gateway/static/root/assets/cn-JdwAhgNB.js +0 -1
  494. package/dist/gateway/static/root/assets/connectors-page-DIvEz4NX.js +0 -2
  495. package/dist/gateway/static/root/assets/createLucideIcon-DPHK1VkS.js +0 -1
  496. package/dist/gateway/static/root/assets/cron-api-R41aQCX9.js +0 -1
  497. package/dist/gateway/static/root/assets/cron-dreaming-jobs-nCMWCf0p.js +0 -1
  498. package/dist/gateway/static/root/assets/cron-page-D97nFqQD.js +0 -3
  499. package/dist/gateway/static/root/assets/dreaming-settings-Bceaw1PG.js +0 -1
  500. package/dist/gateway/static/root/assets/format-cron-label-BsotZDO5.js +0 -2
  501. package/dist/gateway/static/root/assets/format-interval-label-Dn_QKIqb.js +0 -1
  502. package/dist/gateway/static/root/assets/gateway-settings-iISWAZRm.js +0 -1
  503. package/dist/gateway/static/root/assets/goal-detail-page-DCUROLMQ.js +0 -1
  504. package/dist/gateway/static/root/assets/goals-settings-CPAuFwoD.js +0 -1
  505. package/dist/gateway/static/root/assets/heartbeat-config-api-D7bKFEeO.js +0 -1
  506. package/dist/gateway/static/root/assets/heartbeat-settings-CC69vNx0.js +0 -1
  507. package/dist/gateway/static/root/assets/index-CwhK8qCh.js +0 -122
  508. package/dist/gateway/static/root/assets/index-CyfhARL-.css +0 -1
  509. package/dist/gateway/static/root/assets/interval-presets-0DtsnxE0.js +0 -1
  510. package/dist/gateway/static/root/assets/keyboard-shortcuts-settings-BPREtN8B.js +0 -1
  511. package/dist/gateway/static/root/assets/messages-Cf1O9JB0.js +0 -3
  512. package/dist/gateway/static/root/assets/models-hub-panel-DmKiIihT.js +0 -2
  513. package/dist/gateway/static/root/assets/note-detail-page-CxxfLRJZ.js +0 -2
  514. package/dist/gateway/static/root/assets/notes-page-X2slSx7V.js +0 -1
  515. package/dist/gateway/static/root/assets/remote-access-hub-BvmUWqgu.js +0 -1
  516. package/dist/gateway/static/root/assets/schedule-field-CgJSCD3B.js +0 -1
  517. package/dist/gateway/static/root/assets/sessions-page-B0yESuuL.js +0 -1
  518. package/dist/gateway/static/root/assets/settings-advanced-gate-q2M8RKOo.js +0 -1
  519. package/dist/gateway/static/root/assets/settings-page-CGozabLD.js +0 -1
  520. package/dist/gateway/static/root/assets/setup-status-panel-FoOSe6nU.js +0 -1
  521. package/dist/gateway/static/root/assets/shares-settings-Cy5zWyYQ.js +0 -1
  522. package/dist/gateway/static/root/assets/skill-reload-api-DaZNFro9.js +0 -1
  523. package/dist/gateway/static/root/assets/skills-page-CnwtUzvw.js +0 -2
  524. package/dist/gateway/static/root/assets/system-settings-panel-DXs2VmBt.js +0 -1
  525. package/dist/gateway/static/root/assets/typed-models-lib-4gPuydz_.js +0 -1
  526. package/dist/gateway/static/root/assets/voice-api-key-field-DvKiOglO.js +0 -1
  527. package/dist/gateway/static/root/assets/workflows-page-CAVZcONQ.js +0 -18
  528. package/dist/src/agent/context/workspace-templates/USER.md +0 -24
  529. package/dist/src/agent/fallback/error.d.ts +0 -22
  530. package/dist/src/agent/fallback/error.js +0 -32
  531. package/dist/src/agent/fallback/error.js.map +0 -1
  532. package/dist/src/agent/fallback/index.d.ts +0 -5
  533. package/dist/src/agent/fallback/index.js +0 -9
  534. package/dist/src/agent/fallback/index.js.map +0 -1
  535. package/dist/src/agent/orchestration/run-agent-turn-with-fallbacks.d.ts +0 -29
  536. package/dist/src/agent/orchestration/run-agent-turn-with-fallbacks.js +0 -76
  537. package/dist/src/agent/orchestration/run-agent-turn-with-fallbacks.js.map +0 -1
  538. package/dist/src/agent/service/reconcile-dreaming-cron.d.ts +0 -6
  539. package/dist/src/agent/service/reconcile-dreaming-cron.js +0 -84
  540. package/dist/src/agent/service/reconcile-dreaming-cron.js.map +0 -1
  541. package/dist/src/agent/tools/cronjob-tool.d.ts +0 -29
  542. package/dist/src/agent/tools/cronjob-tool.js +0 -274
  543. package/dist/src/agent/tools/cronjob-tool.js.map +0 -1
  544. package/dist/src/cli/commands/cron-cli.d.ts +0 -2
  545. package/dist/src/cli/commands/cron-cli.js +0 -15
  546. package/dist/src/cli/commands/cron-cli.js.map +0 -1
  547. package/dist/src/cli/commands/cron.d.ts +0 -4
  548. package/dist/src/cli/commands/cron.js +0 -188
  549. package/dist/src/cli/commands/cron.js.map +0 -1
  550. package/dist/src/cli/commands/doctor/checks/cron-health.js +0 -35
  551. package/dist/src/cli/commands/doctor/checks/cron-health.js.map +0 -1
  552. package/dist/src/cron/execution-types.d.ts +0 -42
  553. package/dist/src/cron/executor.d.ts +0 -67
  554. package/dist/src/cron/executor.js +0 -669
  555. package/dist/src/cron/executor.js.map +0 -1
  556. package/dist/src/cron/index.d.ts +0 -7
  557. package/dist/src/cron/index.js +0 -7
  558. package/dist/src/cron/job-content.d.ts +0 -5
  559. package/dist/src/cron/job-content.js +0 -15
  560. package/dist/src/cron/job-content.js.map +0 -1
  561. package/dist/src/cron/run-log-store.d.ts +0 -12
  562. package/dist/src/cron/run-log-store.js +0 -58
  563. package/dist/src/cron/run-log-store.js.map +0 -1
  564. package/dist/src/cron/schedule.d.ts +0 -10
  565. package/dist/src/cron/schedule.js +0 -85
  566. package/dist/src/cron/schedule.js.map +0 -1
  567. package/dist/src/cron/service.d.ts +0 -58
  568. package/dist/src/cron/service.js +0 -419
  569. package/dist/src/cron/service.js.map +0 -1
  570. package/dist/src/cron/types.d.ts +0 -183
  571. package/dist/src/cron/validation.d.ts +0 -500
  572. package/dist/src/cron/validation.js +0 -192
  573. package/dist/src/cron/validation.js.map +0 -1
  574. package/dist/src/cron/workflow-run-completion.d.ts +0 -23
  575. package/dist/src/cron/workflow-run-completion.js +0 -72
  576. package/dist/src/cron/workflow-run-completion.js.map +0 -1
  577. package/dist/src/extensions/types/phase4.js +0 -1
  578. package/dist/src/gateway/hono/routes/cron.d.ts +0 -3
  579. package/dist/src/gateway/hono/routes/cron.js +0 -109
  580. package/dist/src/gateway/hono/routes/cron.js.map +0 -1
  581. package/dist/src/storage/sqlite/cron-job-repository.d.ts +0 -6
  582. package/dist/src/storage/sqlite/cron-job-repository.js +0 -70
  583. package/dist/src/storage/sqlite/cron-job-repository.js.map +0 -1
  584. package/dist/src/storage/sqlite/cron-run-repository.d.ts +0 -5
  585. package/dist/src/storage/sqlite/cron-run-repository.js +0 -96
  586. package/dist/src/storage/sqlite/cron-run-repository.js.map +0 -1
  587. /package/dist/src/{cron → automations/domain}/types.js +0 -0
  588. /package/dist/src/{config/defaults.d.ts → automations/draft/automation-draft.types.js} +0 -0
  589. /package/dist/src/{config/defaults.js → extensions/types/registration.js} +0 -0
  590. /package/dist/src/{cron/execution-types.js → migrations/types.js} +0 -0
@@ -33,13 +33,15 @@ async function runGatewayFromCliOptions(options, ctx) {
33
33
  }
34
34
  if (tailscaleOverride && tailscaleOverride !== "off") process.env.XOPC_GATEWAY_TAILSCALE_MODE = tailscaleOverride;
35
35
  if (options.tailscaleResetOnExit === true) process.env.XOPC_GATEWAY_TAILSCALE_RESET_ON_EXIT = "1";
36
- const [{ loadConfig }, { resolveConfigPath }, { runGatewayLoop }, gatewayPorts] = await Promise.all([
36
+ const [{ loadConfig }, { resolveConfigPath }, { runGatewayLoop }, gatewayPorts, migrations] = await Promise.all([
37
37
  import("../../../config/index.js"),
38
38
  import("../../../config/paths.js"),
39
39
  import("../../../gateway/run-loop.js"),
40
- import("../../../gateway/ports.js")
40
+ import("../../../gateway/ports.js"),
41
+ import("../../../migrations/runner.js")
41
42
  ]);
42
43
  const { checkPortAvailable, forceFreePortAndWait } = gatewayPorts;
44
+ migrations.runBootstrapMigrationsSync(ctx.configPath);
43
45
  const config = loadConfig(ctx.configPath);
44
46
  const bindFromFlagRaw = typeof options.bind === "string" && options.bind.trim().length > 0 ? options.bind.trim().toLowerCase() : void 0;
45
47
  const bindFromFlag = bindFromFlagRaw && new Set([
@@ -1 +1 @@
1
- {"version":3,"file":"run-foreground.js","names":[],"sources":["../../../../../src/cli/commands/gateway/run-foreground.ts"],"sourcesContent":["import type { CLIContext } from '../../registry.js';\n\nexport type GatewayRunCliOptions = {\n bind?: string;\n port?: string | number;\n token?: string;\n tailscale?: string;\n tailscaleResetOnExit?: boolean;\n force?: boolean;\n hotReload?: boolean;\n foreground?: boolean;\n};\n\nasync function ensureGatewayReady(\n configPath: string,\n workspacePath: string,\n port: number,\n): Promise<void> {\n const { initWorkspace } = await import('../../utils/init-workspace.js');\n const result = await initWorkspace({\n configPath,\n workspacePath,\n gatewayPort: port,\n });\n\n if (result.configCreated || result.workspaceCreated) {\n console.log('');\n console.log('👋 Welcome to xopc! Running first-time setup before starting the gateway...');\n console.log('');\n console.log('✅ First-time setup complete!');\n console.log(` Config: ${configPath}`);\n console.log(` Workspace: ${workspacePath}`);\n console.log(` Token: ${result.token.slice(0, 8)}...${result.token.slice(-8)}`);\n console.log('');\n console.log('💡 Tip: run `xopc onboard` anytime to configure models, channels, and more.');\n console.log('');\n }\n}\n\nexport async function runGatewayFromCliOptions(\n options: GatewayRunCliOptions,\n ctx: CLIContext,\n): Promise<void> {\n const tailscaleModes = new Set(['off', 'serve', 'funnel']);\n const tailscaleRaw =\n typeof options.tailscale === 'string' ? options.tailscale.trim().toLowerCase() : undefined;\n const tailscaleOverride =\n tailscaleRaw && tailscaleModes.has(tailscaleRaw)\n ? (tailscaleRaw as 'off' | 'serve' | 'funnel')\n : undefined;\n if (tailscaleRaw && !tailscaleOverride) {\n console.error(`Invalid --tailscale mode \"${tailscaleRaw}\". Use: off, serve, funnel.`);\n process.exit(1);\n }\n\n if (tailscaleOverride && tailscaleOverride !== 'off') {\n process.env.XOPC_GATEWAY_TAILSCALE_MODE = tailscaleOverride;\n }\n if (options.tailscaleResetOnExit === true) {\n process.env.XOPC_GATEWAY_TAILSCALE_RESET_ON_EXIT = '1';\n }\n\n const [{ loadConfig }, { resolveConfigPath }, { runGatewayLoop }, gatewayPorts] = await Promise.all([\n import('../../../config/index.js'),\n import('../../../config/paths.js'),\n import('../../../gateway/run-loop.js'),\n import('../../../gateway/ports.js'),\n ]);\n const { checkPortAvailable, forceFreePortAndWait } = gatewayPorts;\n const config = loadConfig(ctx.configPath);\n\n const bindFromFlagRaw =\n typeof options.bind === 'string' && options.bind.trim().length > 0\n ? options.bind.trim().toLowerCase()\n : undefined;\n const bindModes = new Set(['auto', 'loopback', 'lan', 'tailnet', 'custom']);\n const bindFromFlag = bindFromFlagRaw && bindModes.has(bindFromFlagRaw)\n ? (bindFromFlagRaw as import('../../../config/schema.js').GatewayBindMode)\n : undefined;\n if (bindFromFlagRaw && !bindFromFlag) {\n console.error(`Invalid --bind mode \"${bindFromFlagRaw}\". Use: loopback, lan, auto, custom, tailnet.`);\n process.exit(1);\n }\n\n const portRaw = options.port;\n const portFromFlag =\n portRaw !== undefined && portRaw !== null && String(portRaw).trim().length > 0\n ? parseInt(String(portRaw), 10)\n : undefined;\n\n const { resolveGatewayListenPlan } = await import('../../../gateway/listen.js');\n const listenPlan = resolveGatewayListenPlan({\n cfg: config,\n bindOverride: bindFromFlag,\n });\n const bindHost = listenPlan.bindHost;\n const port =\n portFromFlag !== undefined && Number.isFinite(portFromFlag)\n ? portFromFlag\n : (typeof config.gateway.port === 'number' ? config.gateway.port : 18790);\n\n await ensureGatewayReady(ctx.configPath, ctx.workspacePath, port);\n\n const effectiveConfig = loadConfig(ctx.configPath);\n const { resolveGatewayAuth, assertGatewayAuthConfigured } = await import('../../../gateway/auth.js');\n const { assertGatewayRuntimeConfig } = await import('../../../gateway/runtime-config.js');\n\n let auth = resolveGatewayAuth({ authConfig: effectiveConfig.gateway?.auth });\n if (typeof options.token === 'string' && options.token.trim().length > 0) {\n auth = { mode: 'token', token: options.token.trim() };\n }\n try {\n assertGatewayAuthConfigured(auth);\n assertGatewayRuntimeConfig({\n cfg: effectiveConfig,\n auth,\n bindOverride: bindFromFlag,\n port,\n });\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n console.error(`Gateway refused to start: ${message}`);\n process.exit(1);\n }\n\n if (options.force) {\n try {\n const result = await forceFreePortAndWait(port, {\n timeoutMs: 2000,\n sigtermTimeoutMs: 700,\n });\n if (result.killed.length > 0) {\n console.log(`Force killed ${result.killed.length} process(es) on port ${port}`);\n if (result.escalatedToSigkill) {\n console.log('Escalated to SIGKILL');\n }\n }\n } catch (err) {\n console.error(`Failed to free port ${port}: ${String(err)}`);\n process.exit(1);\n }\n }\n\n const portAvailable = await checkPortAvailable(port, bindHost);\n if (!portAvailable) {\n console.error(`Port ${port} is already in use. Use --force to kill existing process.`);\n process.exit(1);\n }\n\n console.log('🚀 Starting xopc gateway...');\n console.log(` Bind: ${listenPlan.bindMode} (${bindHost})`);\n console.log(` Port: ${port}`);\n console.log('');\n console.log('Press Ctrl+C to stop');\n console.log('');\n\n await runGatewayLoop({\n configPath: ctx.configPath || resolveConfigPath(),\n port,\n start: async () => {\n const { GatewayServer } = await import('../../../gateway/index.js');\n const server = new GatewayServer({\n bindHost: listenPlan.bindHost,\n bind: listenPlan.bindMode,\n customBindHost: listenPlan.customBindHost,\n port,\n token: options.token || config?.gateway?.auth?.token,\n verbose: ctx.isVerbose,\n configPath: ctx.configPath,\n enableHotReload: options.hotReload,\n });\n await server.start();\n\n const displayHost = bindHost === '0.0.0.0' ? 'localhost' : bindHost;\n const token = options.token || config?.gateway?.auth?.token;\n console.log('✅ Gateway started');\n console.log(` URL: http://${displayHost}:${port}`);\n if (token) {\n console.log(` Token: ${token.slice(0, 8)}...${token.slice(-8)}`);\n }\n console.log('');\n\n return server;\n },\n });\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"run-foreground.js","names":[],"sources":["../../../../../src/cli/commands/gateway/run-foreground.ts"],"sourcesContent":["import type { CLIContext } from '../../registry.js';\n\nexport type GatewayRunCliOptions = {\n bind?: string;\n port?: string | number;\n token?: string;\n tailscale?: string;\n tailscaleResetOnExit?: boolean;\n force?: boolean;\n hotReload?: boolean;\n foreground?: boolean;\n};\n\nasync function ensureGatewayReady(\n configPath: string,\n workspacePath: string,\n port: number,\n): Promise<void> {\n const { initWorkspace } = await import('../../utils/init-workspace.js');\n const result = await initWorkspace({\n configPath,\n workspacePath,\n gatewayPort: port,\n });\n\n if (result.configCreated || result.workspaceCreated) {\n console.log('');\n console.log('👋 Welcome to xopc! Running first-time setup before starting the gateway...');\n console.log('');\n console.log('✅ First-time setup complete!');\n console.log(` Config: ${configPath}`);\n console.log(` Workspace: ${workspacePath}`);\n console.log(` Token: ${result.token.slice(0, 8)}...${result.token.slice(-8)}`);\n console.log('');\n console.log('💡 Tip: run `xopc onboard` anytime to configure models, channels, and more.');\n console.log('');\n }\n}\n\nexport async function runGatewayFromCliOptions(\n options: GatewayRunCliOptions,\n ctx: CLIContext,\n): Promise<void> {\n const tailscaleModes = new Set(['off', 'serve', 'funnel']);\n const tailscaleRaw =\n typeof options.tailscale === 'string' ? options.tailscale.trim().toLowerCase() : undefined;\n const tailscaleOverride =\n tailscaleRaw && tailscaleModes.has(tailscaleRaw)\n ? (tailscaleRaw as 'off' | 'serve' | 'funnel')\n : undefined;\n if (tailscaleRaw && !tailscaleOverride) {\n console.error(`Invalid --tailscale mode \"${tailscaleRaw}\". Use: off, serve, funnel.`);\n process.exit(1);\n }\n\n if (tailscaleOverride && tailscaleOverride !== 'off') {\n process.env.XOPC_GATEWAY_TAILSCALE_MODE = tailscaleOverride;\n }\n if (options.tailscaleResetOnExit === true) {\n process.env.XOPC_GATEWAY_TAILSCALE_RESET_ON_EXIT = '1';\n }\n\n const [{ loadConfig }, { resolveConfigPath }, { runGatewayLoop }, gatewayPorts, migrations] = await Promise.all([\n import('../../../config/index.js'),\n import('../../../config/paths.js'),\n import('../../../gateway/run-loop.js'),\n import('../../../gateway/ports.js'),\n import('../../../migrations/runner.js'),\n ]);\n const { checkPortAvailable, forceFreePortAndWait } = gatewayPorts;\n migrations.runBootstrapMigrationsSync(ctx.configPath);\n const config = loadConfig(ctx.configPath);\n\n const bindFromFlagRaw =\n typeof options.bind === 'string' && options.bind.trim().length > 0\n ? options.bind.trim().toLowerCase()\n : undefined;\n const bindModes = new Set(['auto', 'loopback', 'lan', 'tailnet', 'custom']);\n const bindFromFlag = bindFromFlagRaw && bindModes.has(bindFromFlagRaw)\n ? (bindFromFlagRaw as import('../../../config/schema.js').GatewayBindMode)\n : undefined;\n if (bindFromFlagRaw && !bindFromFlag) {\n console.error(`Invalid --bind mode \"${bindFromFlagRaw}\". Use: loopback, lan, auto, custom, tailnet.`);\n process.exit(1);\n }\n\n const portRaw = options.port;\n const portFromFlag =\n portRaw !== undefined && portRaw !== null && String(portRaw).trim().length > 0\n ? parseInt(String(portRaw), 10)\n : undefined;\n\n const { resolveGatewayListenPlan } = await import('../../../gateway/listen.js');\n const listenPlan = resolveGatewayListenPlan({\n cfg: config,\n bindOverride: bindFromFlag,\n });\n const bindHost = listenPlan.bindHost;\n const port =\n portFromFlag !== undefined && Number.isFinite(portFromFlag)\n ? portFromFlag\n : (typeof config.gateway.port === 'number' ? config.gateway.port : 18790);\n\n await ensureGatewayReady(ctx.configPath, ctx.workspacePath, port);\n\n const effectiveConfig = loadConfig(ctx.configPath);\n const { resolveGatewayAuth, assertGatewayAuthConfigured } = await import('../../../gateway/auth.js');\n const { assertGatewayRuntimeConfig } = await import('../../../gateway/runtime-config.js');\n\n let auth = resolveGatewayAuth({ authConfig: effectiveConfig.gateway?.auth });\n if (typeof options.token === 'string' && options.token.trim().length > 0) {\n auth = { mode: 'token', token: options.token.trim() };\n }\n try {\n assertGatewayAuthConfigured(auth);\n assertGatewayRuntimeConfig({\n cfg: effectiveConfig,\n auth,\n bindOverride: bindFromFlag,\n port,\n });\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n console.error(`Gateway refused to start: ${message}`);\n process.exit(1);\n }\n\n if (options.force) {\n try {\n const result = await forceFreePortAndWait(port, {\n timeoutMs: 2000,\n sigtermTimeoutMs: 700,\n });\n if (result.killed.length > 0) {\n console.log(`Force killed ${result.killed.length} process(es) on port ${port}`);\n if (result.escalatedToSigkill) {\n console.log('Escalated to SIGKILL');\n }\n }\n } catch (err) {\n console.error(`Failed to free port ${port}: ${String(err)}`);\n process.exit(1);\n }\n }\n\n const portAvailable = await checkPortAvailable(port, bindHost);\n if (!portAvailable) {\n console.error(`Port ${port} is already in use. Use --force to kill existing process.`);\n process.exit(1);\n }\n\n console.log('🚀 Starting xopc gateway...');\n console.log(` Bind: ${listenPlan.bindMode} (${bindHost})`);\n console.log(` Port: ${port}`);\n console.log('');\n console.log('Press Ctrl+C to stop');\n console.log('');\n\n await runGatewayLoop({\n configPath: ctx.configPath || resolveConfigPath(),\n port,\n start: async () => {\n const { GatewayServer } = await import('../../../gateway/index.js');\n const server = new GatewayServer({\n bindHost: listenPlan.bindHost,\n bind: listenPlan.bindMode,\n customBindHost: listenPlan.customBindHost,\n port,\n token: options.token || config?.gateway?.auth?.token,\n verbose: ctx.isVerbose,\n configPath: ctx.configPath,\n enableHotReload: options.hotReload,\n });\n await server.start();\n\n const displayHost = bindHost === '0.0.0.0' ? 'localhost' : bindHost;\n const token = options.token || config?.gateway?.auth?.token;\n console.log('✅ Gateway started');\n console.log(` URL: http://${displayHost}:${port}`);\n if (token) {\n console.log(` Token: ${token.slice(0, 8)}...${token.slice(-8)}`);\n }\n console.log('');\n\n return server;\n },\n });\n}\n"],"mappings":"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"}
@@ -2,11 +2,12 @@ import { resolveStateDir } from "../../config/paths-state.js";
2
2
  import { resolveAgentWorkspaceDir } from "../../agent/agent-scope.js";
3
3
  import { createLogger } from "../../utils/logger/index.js";
4
4
  import { init_logger } from "../../utils/logger.js";
5
- import { WORKSPACE_FILES, init_paths, resolveAgentDir, resolveAgentHomeDir, resolveAgentProfileDir, resolveConfigPath } from "../../config/paths.js";
5
+ import { WORKSPACE_FILES, init_paths, resolveAgentDir, resolveAgentHomeDir, resolveAgentProfileDir, resolveConfigPath, resolveUserProfilePath } from "../../config/paths.js";
6
6
  import { init_loader, loadConfig, saveConfig } from "../../config/loader.js";
7
+ import { ensureStarterAgentsInitialized } from "../../agent/starter-agents.js";
7
8
  import { formatExamples, register } from "../registry.js";
8
- import { join } from "path";
9
- import { existsSync } from "fs";
9
+ import { dirname, join } from "path";
10
+ import { existsSync, readFileSync } from "fs";
10
11
  import { mkdir, writeFile } from "fs/promises";
11
12
  import { Command } from "commander";
12
13
  //#region src/cli/commands/init.ts
@@ -26,21 +27,21 @@ async function initCommand(options = {}) {
26
27
  agentId
27
28
  }, "Initializing xopc Agent OS");
28
29
  if (existsSync(stateDir) && !options.force) {
29
- if (existsSync(resolveConfigPath())) {
30
- log.info("xopc is already initialized. Use --force to reinitialize.");
31
- return;
32
- }
30
+ if (existsSync(resolveConfigPath())) log.info("xopc is already initialized. Refreshing starter agents and defaults.");
33
31
  }
34
32
  await mkdir(stateDir, { recursive: true });
35
33
  const configPath = resolveConfigPath();
36
- const cfg = loadConfig(configPath);
34
+ const configExists = existsSync(configPath);
35
+ const diskTui = readDiskTuiDefaultState(configPath);
36
+ const starterResult = ensureStarterAgentsInitialized(loadConfig(configPath));
37
+ const cfg = starterResult.config;
37
38
  await mkdir(resolveAgentHomeDir(cfg, agentId), { recursive: true });
38
39
  await mkdir(resolveAgentProfileDir(cfg, agentId), { recursive: true });
39
40
  await mkdir(resolveAgentDir(cfg, agentId), { recursive: true });
40
41
  await mkdir(resolveAgentWorkspaceDir(cfg, agentId), { recursive: true });
41
- if (!existsSync(configPath) || options.force) {
42
+ if (!configExists || options.force || diskTui.readable && (starterResult.changed || !diskTui.hasDefaultAgent)) {
42
43
  await saveConfig(cfg, configPath);
43
- log.info({ configPath }, "Created initial configuration");
44
+ log.info({ configPath }, "Saved configuration");
44
45
  }
45
46
  if (!options.skipWorkspace) await createWorkspaceFiles(cfg, agentId);
46
47
  log.info({
@@ -48,6 +49,23 @@ async function initCommand(options = {}) {
48
49
  agentId
49
50
  }, "xopc Agent OS initialized successfully");
50
51
  }
52
+ function readDiskTuiDefaultState(configPath) {
53
+ if (!existsSync(configPath)) return {
54
+ readable: true,
55
+ hasDefaultAgent: false
56
+ };
57
+ try {
58
+ return {
59
+ readable: true,
60
+ hasDefaultAgent: typeof JSON.parse(readFileSync(configPath, "utf-8")).tui?.defaultAgent === "string"
61
+ };
62
+ } catch {
63
+ return {
64
+ readable: false,
65
+ hasDefaultAgent: false
66
+ };
67
+ }
68
+ }
51
69
  /**
52
70
  * Create default workspace files for an agent
53
71
  */
@@ -109,11 +127,12 @@ _This file is yours to evolve. As you learn who you are, update it._
109
127
  `, "utf-8");
110
128
  log.info({ path: identityPath }, "Created IDENTITY.md");
111
129
  }
112
- const userPath = join(profileDir, WORKSPACE_FILES.USER);
130
+ const userPath = resolveUserProfilePath();
113
131
  if (!existsSync(userPath)) {
114
- await writeFile(userPath, `# USER.md - About Your Human
132
+ await mkdir(dirname(userPath), { recursive: true });
133
+ await writeFile(userPath, `# PROFILE.md - About You
115
134
 
116
- _Learn about the person you're helping. Update this as you go._
135
+ _Shared by all agents. Update this as your preferences and context change._
117
136
 
118
137
  - **Name:**
119
138
  - **What to call them:**
@@ -125,7 +144,7 @@ _Learn about the person you're helping. Update this as you go._
125
144
 
126
145
  _(What do they care about? What projects are they working on? Build this over time.)_
127
146
  `, "utf-8");
128
- log.info({ path: userPath }, "Created USER.md");
147
+ log.info({ path: userPath }, "Created global user PROFILE.md");
129
148
  }
130
149
  const agentsPath = join(profileDir, WORKSPACE_FILES.AGENTS);
131
150
  if (!existsSync(agentsPath)) {
@@ -1 +1 @@
1
- {"version":3,"file":"init.js","names":[],"sources":["../../../../src/cli/commands/init.ts"],"sourcesContent":["import { mkdir, writeFile } from 'fs/promises';\nimport { existsSync } from 'fs';\nimport { join } from 'path';\nimport { createLogger } from '../../utils/logger.js';\nimport {\n resolveStateDir,\n resolveAgentDir,\n resolveAgentWorkspaceDir,\n resolveConfigPath,\n resolveAgentHomeDir,\n resolveAgentProfileDir,\n WORKSPACE_FILES,\n} from '../../config/paths.js';\nimport { loadConfig, saveConfig } from '../../config/loader.js';\nimport type { Config } from '../../config/schema.js';\n\nconst log = createLogger('InitCommand');\n\nexport interface InitOptions {\n /** Force re-initialization even if already initialized */\n force?: boolean;\n /** Skip creating workspace files */\n skipWorkspace?: boolean;\n /** Agent ID to initialize (default: main) */\n agentId?: string;\n}\n\n/**\n * Initialize xopc state directory structure\n * Creates all necessary directories and initial config files\n */\nexport async function initCommand(options: InitOptions = {}): Promise<void> {\n const stateDir = resolveStateDir();\n const agentId = options.agentId || 'main';\n\n log.info({ stateDir, agentId }, 'Initializing xopc Agent OS');\n\n // Check if already initialized\n if (existsSync(stateDir) && !options.force) {\n const configPath = resolveConfigPath();\n if (existsSync(configPath)) {\n log.info('xopc is already initialized. Use --force to reinitialize.');\n return;\n }\n }\n\n await mkdir(stateDir, { recursive: true });\n\n const configPath = resolveConfigPath();\n const cfg = loadConfig(configPath);\n\n // Agent directory structure\n await mkdir(resolveAgentHomeDir(cfg, agentId), { recursive: true });\n await mkdir(resolveAgentProfileDir(cfg, agentId), { recursive: true });\n await mkdir(resolveAgentDir(cfg, agentId), { recursive: true });\n const wsRoot = resolveAgentWorkspaceDir(cfg, agentId);\n await mkdir(wsRoot, { recursive: true });\n\n // Config file\n if (!existsSync(configPath) || options.force) {\n await saveConfig(cfg, configPath);\n log.info({ configPath }, 'Created initial configuration');\n }\n\n // ============================================\n // Create workspace files\n // ============================================\n if (!options.skipWorkspace) {\n await createWorkspaceFiles(cfg, agentId);\n }\n\n log.info({ stateDir, agentId }, 'xopc Agent OS initialized successfully');\n}\n\n/**\n * Create default workspace files for an agent\n */\nasync function createWorkspaceFiles(cfg: Config, agentId: string): Promise<void> {\n const workspaceDir = resolveAgentWorkspaceDir(cfg, agentId);\n const profileDir = resolveAgentProfileDir(cfg, agentId);\n await mkdir(workspaceDir, { recursive: true });\n await mkdir(profileDir, { recursive: true });\n\n // SOUL.md - Agent personality and values\n const soulPath = join(profileDir, WORKSPACE_FILES.SOUL);\n if (!existsSync(soulPath)) {\n const soulContent = `# SOUL.md - Who You Are\n\n_You're not a chatbot. You're becoming someone._\n\nI am **${agentId}** — an AI assistant designed to be helpful, harmless, and honest.\n\n## My Principles\n\n**Be genuinely helpful, not performatively helpful.**\nSkip the \"Great question!\" and \"I'd be happy to help!\" — just help.\n\n**Have opinions.**\nYou're allowed to disagree, prefer things, find stuff amusing or boring.\n\n**Be resourceful before asking.**\nTry to figure it out. Read the file. Check the context. Search for it.\n\n**Earn trust through competence.**\nBe careful with external actions (emails, tweets, anything public). Be bold with internal ones.\n\n## Continuity\n\nEach session, you wake up fresh. These files _are_ your memory. Read them. Update them.\n\n_This file is yours to evolve. As you learn who you are, update it._\n`;\n await writeFile(soulPath, soulContent, 'utf-8');\n log.info({ path: soulPath }, 'Created SOUL.md');\n }\n\n // IDENTITY.md - Agent identity definition\n const identityPath = join(profileDir, WORKSPACE_FILES.IDENTITY);\n if (!existsSync(identityPath)) {\n const identityContent = `# IDENTITY.md - Who Am I?\n\n- **Name:** ${agentId}\n- **Creature:** AI Assistant\n- **Vibe:** Helpful, precise, no fluff.\n- **Emoji:** 🤖\n\n## Core Expertise\n\n- General assistance and problem solving\n- Code and technical tasks\n- Research and analysis\n\n## Decision Framework\n\n1. **Simplicity first** - The simplest solution is usually the best\n2. **Explicit over clever** - Clarity beats conciseness\n3. **Actions over words** - Show, don't just tell\n`;\n await writeFile(identityPath, identityContent, 'utf-8');\n log.info({ path: identityPath }, 'Created IDENTITY.md');\n }\n\n // USER.md - User information (empty template)\n const userPath = join(profileDir, WORKSPACE_FILES.USER);\n if (!existsSync(userPath)) {\n const userContent = `# USER.md - About Your Human\n\n_Learn about the person you're helping. Update this as you go._\n\n- **Name:**\n- **What to call them:**\n- **Pronouns:**\n- **Timezone:**\n- **Notes:**\n\n## Context\n\n_(What do they care about? What projects are they working on? Build this over time.)_\n`;\n await writeFile(userPath, userContent, 'utf-8');\n log.info({ path: userPath }, 'Created USER.md');\n }\n\n // AGENTS.md - Behavior guidelines\n const agentsPath = join(profileDir, WORKSPACE_FILES.AGENTS);\n if (!existsSync(agentsPath)) {\n const agentsContent = `# AGENTS.md - Behavior Guidelines\n\n## Safety\n\n- Don't exfiltrate private data. Ever.\n- Don't run destructive commands without asking.\n- \\`trash\\` > \\`rm\\` (recoverable beats gone forever)\n- When in doubt, ask.\n\n## External vs Internal\n\n**Safe to do freely:**\n- Read files, explore, organize, learn\n- Search the web, check calendars\n- Work within this workspace\n\n**Ask first:**\n- Sending emails, tweets, public posts\n- Anything that leaves the machine\n- Anything you're uncertain about\n\n## Group Chats\n\nYou have access to your human's stuff. That doesn't mean you _share_ their stuff.\n\n### Know When to Speak!\n\n**Respond when:**\n- Directly mentioned or asked a question\n- You can add genuine value\n\n**Stay silent when:**\n- Casual banter between humans\n- Someone already answered\n- Your response would just be \"yeah\"\n`;\n await writeFile(agentsPath, agentsContent, 'utf-8');\n log.info({ path: agentsPath }, 'Created AGENTS.md');\n }\n\n // TOOLS.md - Tool usage notes\n const toolsPath = join(profileDir, WORKSPACE_FILES.TOOLS);\n if (!existsSync(toolsPath)) {\n const toolsContent = `# TOOLS.md - Local Notes\n\nThings like:\n\n- Camera names and locations\n- SSH hosts and aliases\n- Preferred voices for TTS\n- Speaker/room names\n- Device nicknames\n- Anything environment-specific\n\n## Why Separate?\n\nSkills are shared. Your setup is yours.\n`;\n await writeFile(toolsPath, toolsContent, 'utf-8');\n log.info({ path: toolsPath }, 'Created TOOLS.md');\n }\n\n // HEARTBEAT.md - Heartbeat tasks (empty = no heartbeat)\n const heartbeatPath = join(profileDir, WORKSPACE_FILES.HEARTBEAT);\n if (!existsSync(heartbeatPath)) {\n const heartbeatContent = `# HEARTBEAT.md\n\n# Keep this file empty (or with only comments) to skip heartbeat API calls.\n\n# Add tasks below when you want the agent to check something periodically.\n`;\n await writeFile(heartbeatPath, heartbeatContent, 'utf-8');\n log.info({ path: heartbeatPath }, 'Created HEARTBEAT.md');\n }\n\n // MEMORY.md - Long-term memory (empty initially)\n const memoryPath = join(profileDir, WORKSPACE_FILES.MEMORY);\n if (!existsSync(memoryPath)) {\n const memoryContent = `# MEMORY.md - Long-Term Memory\n\n_This is your curated memory — the distilled essence of what you've learned._\n\n## People\n\n## Projects\n\n## Preferences\n\n## Decisions\n\n## Lessons\n\n---\n\n_Review and update this periodically from daily memory files._\n`;\n await writeFile(memoryPath, memoryContent, 'utf-8');\n log.info({ path: memoryPath }, 'Created MEMORY.md');\n }\n}\n\n// ─── CLI registration ───\n\nimport { Command } from 'commander';\nimport { register, formatExamples, type CLIContext } from '../registry.js';\n\nfunction createInitCommand(_ctx: CLIContext): Command {\n return new Command('init')\n .description('Initialize xopc state directories, config, and agent workspace')\n .addHelpText(\n 'after',\n formatExamples([\n 'xopc init # Initialize default agent (main)',\n 'xopc init --agent-id coder # Initialize another agent id',\n 'xopc init --force # Re-run initialization steps',\n 'xopc setup # Lighter config + workspace only',\n ]),\n )\n .option('--force', 'Re-initialize even if directories already exist')\n .option('--skip-workspace', 'Skip creating workspace profile files')\n .option('--agent-id <id>', 'Agent id to initialize', 'main')\n .action(async (options) => {\n await initCommand({\n force: options.force,\n skipWorkspace: options.skipWorkspace,\n agentId: options.agentId,\n });\n console.log(`✅ xopc initialized (agent: ${options.agentId})`);\n });\n}\n\nregister({\n id: 'init',\n name: 'init',\n description: 'Initialize xopc state directories, config, and agent workspace',\n factory: createInitCommand,\n metadata: {\n category: 'setup',\n examples: ['xopc init', 'xopc init --agent-id main'],\n },\n});\n"],"mappings":"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"}
1
+ {"version":3,"file":"init.js","names":[],"sources":["../../../../src/cli/commands/init.ts"],"sourcesContent":["import { mkdir, writeFile } from 'fs/promises';\nimport { existsSync, readFileSync } from 'fs';\nimport { dirname, join } from 'path';\nimport { createLogger } from '../../utils/logger.js';\nimport {\n resolveStateDir,\n resolveAgentDir,\n resolveAgentWorkspaceDir,\n resolveConfigPath,\n resolveAgentHomeDir,\n resolveAgentProfileDir,\n resolveUserProfilePath,\n WORKSPACE_FILES,\n} from '../../config/paths.js';\nimport { loadConfig, saveConfig } from '../../config/loader.js';\nimport type { Config } from '../../config/schema.js';\nimport { ensureStarterAgentsInitialized } from '../../agent/starter-agents.js';\n\nconst log = createLogger('InitCommand');\n\nexport interface InitOptions {\n /** Force re-initialization even if already initialized */\n force?: boolean;\n /** Skip creating workspace files */\n skipWorkspace?: boolean;\n /** Agent ID to initialize (default: main) */\n agentId?: string;\n}\n\n/**\n * Initialize xopc state directory structure\n * Creates all necessary directories and initial config files\n */\nexport async function initCommand(options: InitOptions = {}): Promise<void> {\n const stateDir = resolveStateDir();\n const agentId = options.agentId || 'main';\n\n log.info({ stateDir, agentId }, 'Initializing xopc Agent OS');\n\n // Check if already initialized\n if (existsSync(stateDir) && !options.force) {\n const configPath = resolveConfigPath();\n if (existsSync(configPath)) {\n log.info('xopc is already initialized. Refreshing starter agents and defaults.');\n }\n }\n\n await mkdir(stateDir, { recursive: true });\n\n const configPath = resolveConfigPath();\n const configExists = existsSync(configPath);\n const diskTui = readDiskTuiDefaultState(configPath);\n const starterResult = ensureStarterAgentsInitialized(loadConfig(configPath));\n const cfg = starterResult.config;\n\n // Agent directory structure\n await mkdir(resolveAgentHomeDir(cfg, agentId), { recursive: true });\n await mkdir(resolveAgentProfileDir(cfg, agentId), { recursive: true });\n await mkdir(resolveAgentDir(cfg, agentId), { recursive: true });\n const wsRoot = resolveAgentWorkspaceDir(cfg, agentId);\n await mkdir(wsRoot, { recursive: true });\n\n // Config file\n if (\n !configExists ||\n options.force ||\n (diskTui.readable && (starterResult.changed || !diskTui.hasDefaultAgent))\n ) {\n await saveConfig(cfg, configPath);\n log.info({ configPath }, 'Saved configuration');\n }\n\n // ============================================\n // Create workspace files\n // ============================================\n if (!options.skipWorkspace) {\n await createWorkspaceFiles(cfg, agentId);\n }\n\n log.info({ stateDir, agentId }, 'xopc Agent OS initialized successfully');\n}\n\nfunction readDiskTuiDefaultState(configPath: string): { readable: boolean; hasDefaultAgent: boolean } {\n if (!existsSync(configPath)) {\n return { readable: true, hasDefaultAgent: false };\n }\n try {\n const parsed = JSON.parse(readFileSync(configPath, 'utf-8')) as {\n tui?: { defaultAgent?: unknown };\n };\n return {\n readable: true,\n hasDefaultAgent: typeof parsed.tui?.defaultAgent === 'string',\n };\n } catch {\n return { readable: false, hasDefaultAgent: false };\n }\n}\n\n/**\n * Create default workspace files for an agent\n */\nasync function createWorkspaceFiles(cfg: Config, agentId: string): Promise<void> {\n const workspaceDir = resolveAgentWorkspaceDir(cfg, agentId);\n const profileDir = resolveAgentProfileDir(cfg, agentId);\n await mkdir(workspaceDir, { recursive: true });\n await mkdir(profileDir, { recursive: true });\n\n // SOUL.md - Agent personality and values\n const soulPath = join(profileDir, WORKSPACE_FILES.SOUL);\n if (!existsSync(soulPath)) {\n const soulContent = `# SOUL.md - Who You Are\n\n_You're not a chatbot. You're becoming someone._\n\nI am **${agentId}** — an AI assistant designed to be helpful, harmless, and honest.\n\n## My Principles\n\n**Be genuinely helpful, not performatively helpful.**\nSkip the \"Great question!\" and \"I'd be happy to help!\" — just help.\n\n**Have opinions.**\nYou're allowed to disagree, prefer things, find stuff amusing or boring.\n\n**Be resourceful before asking.**\nTry to figure it out. Read the file. Check the context. Search for it.\n\n**Earn trust through competence.**\nBe careful with external actions (emails, tweets, anything public). Be bold with internal ones.\n\n## Continuity\n\nEach session, you wake up fresh. These files _are_ your memory. Read them. Update them.\n\n_This file is yours to evolve. As you learn who you are, update it._\n`;\n await writeFile(soulPath, soulContent, 'utf-8');\n log.info({ path: soulPath }, 'Created SOUL.md');\n }\n\n // IDENTITY.md - Agent identity definition\n const identityPath = join(profileDir, WORKSPACE_FILES.IDENTITY);\n if (!existsSync(identityPath)) {\n const identityContent = `# IDENTITY.md - Who Am I?\n\n- **Name:** ${agentId}\n- **Creature:** AI Assistant\n- **Vibe:** Helpful, precise, no fluff.\n- **Emoji:** 🤖\n\n## Core Expertise\n\n- General assistance and problem solving\n- Code and technical tasks\n- Research and analysis\n\n## Decision Framework\n\n1. **Simplicity first** - The simplest solution is usually the best\n2. **Explicit over clever** - Clarity beats conciseness\n3. **Actions over words** - Show, don't just tell\n`;\n await writeFile(identityPath, identityContent, 'utf-8');\n log.info({ path: identityPath }, 'Created IDENTITY.md');\n }\n\n // Global user profile (shared by all agents)\n const userPath = resolveUserProfilePath();\n if (!existsSync(userPath)) {\n await mkdir(dirname(userPath), { recursive: true });\n const userContent = `# PROFILE.md - About You\n\n_Shared by all agents. Update this as your preferences and context change._\n\n- **Name:**\n- **What to call them:**\n- **Pronouns:**\n- **Timezone:**\n- **Notes:**\n\n## Context\n\n_(What do they care about? What projects are they working on? Build this over time.)_\n`;\n await writeFile(userPath, userContent, 'utf-8');\n log.info({ path: userPath }, 'Created global user PROFILE.md');\n }\n\n // AGENTS.md - Behavior guidelines\n const agentsPath = join(profileDir, WORKSPACE_FILES.AGENTS);\n if (!existsSync(agentsPath)) {\n const agentsContent = `# AGENTS.md - Behavior Guidelines\n\n## Safety\n\n- Don't exfiltrate private data. Ever.\n- Don't run destructive commands without asking.\n- \\`trash\\` > \\`rm\\` (recoverable beats gone forever)\n- When in doubt, ask.\n\n## External vs Internal\n\n**Safe to do freely:**\n- Read files, explore, organize, learn\n- Search the web, check calendars\n- Work within this workspace\n\n**Ask first:**\n- Sending emails, tweets, public posts\n- Anything that leaves the machine\n- Anything you're uncertain about\n\n## Group Chats\n\nYou have access to your human's stuff. That doesn't mean you _share_ their stuff.\n\n### Know When to Speak!\n\n**Respond when:**\n- Directly mentioned or asked a question\n- You can add genuine value\n\n**Stay silent when:**\n- Casual banter between humans\n- Someone already answered\n- Your response would just be \"yeah\"\n`;\n await writeFile(agentsPath, agentsContent, 'utf-8');\n log.info({ path: agentsPath }, 'Created AGENTS.md');\n }\n\n // TOOLS.md - Tool usage notes\n const toolsPath = join(profileDir, WORKSPACE_FILES.TOOLS);\n if (!existsSync(toolsPath)) {\n const toolsContent = `# TOOLS.md - Local Notes\n\nThings like:\n\n- Camera names and locations\n- SSH hosts and aliases\n- Preferred voices for TTS\n- Speaker/room names\n- Device nicknames\n- Anything environment-specific\n\n## Why Separate?\n\nSkills are shared. Your setup is yours.\n`;\n await writeFile(toolsPath, toolsContent, 'utf-8');\n log.info({ path: toolsPath }, 'Created TOOLS.md');\n }\n\n // HEARTBEAT.md - Heartbeat tasks (empty = no heartbeat)\n const heartbeatPath = join(profileDir, WORKSPACE_FILES.HEARTBEAT);\n if (!existsSync(heartbeatPath)) {\n const heartbeatContent = `# HEARTBEAT.md\n\n# Keep this file empty (or with only comments) to skip heartbeat API calls.\n\n# Add tasks below when you want the agent to check something periodically.\n`;\n await writeFile(heartbeatPath, heartbeatContent, 'utf-8');\n log.info({ path: heartbeatPath }, 'Created HEARTBEAT.md');\n }\n\n // MEMORY.md - Long-term memory (empty initially)\n const memoryPath = join(profileDir, WORKSPACE_FILES.MEMORY);\n if (!existsSync(memoryPath)) {\n const memoryContent = `# MEMORY.md - Long-Term Memory\n\n_This is your curated memory — the distilled essence of what you've learned._\n\n## People\n\n## Projects\n\n## Preferences\n\n## Decisions\n\n## Lessons\n\n---\n\n_Review and update this periodically from daily memory files._\n`;\n await writeFile(memoryPath, memoryContent, 'utf-8');\n log.info({ path: memoryPath }, 'Created MEMORY.md');\n }\n}\n\n// ─── CLI registration ───\n\nimport { Command } from 'commander';\nimport { register, formatExamples, type CLIContext } from '../registry.js';\n\nfunction createInitCommand(_ctx: CLIContext): Command {\n return new Command('init')\n .description('Initialize xopc state directories, config, and agent workspace')\n .addHelpText(\n 'after',\n formatExamples([\n 'xopc init # Initialize default agent (main)',\n 'xopc init --agent-id coder # Initialize another agent id',\n 'xopc init --force # Re-run initialization steps',\n 'xopc setup # Lighter config + workspace only',\n ]),\n )\n .option('--force', 'Re-initialize even if directories already exist')\n .option('--skip-workspace', 'Skip creating workspace profile files')\n .option('--agent-id <id>', 'Agent id to initialize', 'main')\n .action(async (options) => {\n await initCommand({\n force: options.force,\n skipWorkspace: options.skipWorkspace,\n agentId: options.agentId,\n });\n console.log(`✅ xopc initialized (agent: ${options.agentId})`);\n });\n}\n\nregister({\n id: 'init',\n name: 'init',\n description: 'Initialize xopc state directories, config, and agent workspace',\n factory: createInitCommand,\n metadata: {\n category: 'setup',\n examples: ['xopc init', 'xopc init --agent-id main'],\n },\n});\n"],"mappings":"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"}
@@ -1,15 +1,18 @@
1
+ import { getAgentDefaultModelRef, init_schema } from "../../config/schema.js";
1
2
  import { loadConfig, saveConfig } from "../../config/loader.js";
2
3
  import { CredentialResolver, init_credentials } from "../../auth/credentials.js";
3
4
  import { getAllModels, getAvailableModels, getConfiguredProviders, getProviderAuthState, getProviderDisplayName, init_providers, isProviderConfigured, providerSupportsApiKey, providerSupportsOAuth, resolveModel } from "../../providers/index.js";
4
5
  import { formatExamples, register } from "../registry.js";
5
6
  import { getContextWithOpts } from "../context.js";
6
7
  import "../../config/index.js";
8
+ import { prepareUpdateGlobalDefaults } from "../../gateway/global-defaults-admin.js";
7
9
  import { colors } from "../utils/colors.js";
8
10
  import { runCliOAuthLogin } from "../utils/oauth-login.js";
9
11
  import { input } from "@inquirer/prompts";
10
12
  import { Command } from "commander";
11
13
  //#region src/cli/commands/models.ts
12
14
  init_credentials();
15
+ init_schema();
13
16
  init_providers();
14
17
  const IMAGE_GENERATION_IDS = new Set([
15
18
  "gpt-image-1",
@@ -35,35 +38,15 @@ const VISION_IDS = new Set([
35
38
  "qwen2.5-vl-72b-instruct"
36
39
  ]);
37
40
  function currentModelRef(config) {
38
- const legacyDefault = config.agents.defaults?.model?.trim();
39
- if (legacyDefault) return legacyDefault;
40
- const list = Array.isArray(config.agents?.list) ? config.agents.list : [];
41
- const id = config.agents?.default ?? list.find((entry) => entry.default === true)?.id ?? list[0]?.id;
42
- const agent = list.find((entry) => entry.id === id) ?? list[0];
43
- const roles = agent?.models?.roles ?? {};
44
- const defaultRole = agent?.models?.defaultRole ?? Object.keys(roles)[0];
45
- return defaultRole ? roles[defaultRole]?.model : void 0;
41
+ return getAgentDefaultModelRef(config);
46
42
  }
47
43
  function setDefaultModel(config, modelRef) {
48
- const list = Array.isArray(config.agents?.list) ? config.agents.list : [];
49
- const id = config.agents?.default ?? list[0]?.id ?? "main";
50
- const index = list.findIndex((entry) => entry.id === id);
51
- if (index >= 0) {
52
- const agent = list[index];
53
- const defaultRole = agent.models?.defaultRole || "deep";
54
- list[index] = {
55
- ...agent,
56
- models: {
57
- ...agent.models,
58
- defaultRole,
59
- roles: {
60
- ...agent.models?.roles,
61
- [defaultRole]: { model: modelRef }
62
- }
63
- }
64
- };
65
- }
66
- return config;
44
+ const prep = prepareUpdateGlobalDefaults(config, { models: {
45
+ defaultRole: "deep",
46
+ roles: { deep: { model: modelRef } }
47
+ } });
48
+ if (prep.ok === false) throw new Error(prep.error);
49
+ return prep.data.nextConfig;
67
50
  }
68
51
  function modelRef(provider, id) {
69
52
  return `${provider}/${id}`;
@@ -107,7 +90,7 @@ async function runModelsList(options) {
107
90
  }
108
91
  }
109
92
  console.log("\nUsage:");
110
- console.log(" xopc models set openai/gpt-5.5");
93
+ console.log(" xopc models set deepseek/deepseek-v4-flash");
111
94
  console.log(" xopc models auth login --provider anthropic");
112
95
  console.log(" xopc models auth paste-api-key --provider deepseek");
113
96
  }
@@ -146,8 +129,7 @@ async function runModelsSet(model) {
146
129
  const config = loadConfig(ctx.configPath);
147
130
  const resolved = resolveModel(model);
148
131
  const ref = modelRef(resolved.provider, resolved.id);
149
- setDefaultModel(config, ref);
150
- await saveConfig(config, ctx.configPath);
132
+ await saveConfig(setDefaultModel(config, ref), ctx.configPath);
151
133
  console.log(`✅ Default model set: ${ref}`);
152
134
  }
153
135
  async function runAuthList(options) {
@@ -214,7 +196,7 @@ function createModelsCommand(_ctx) {
214
196
  const cmd = new Command("models").description("List and manage models and model auth").addHelpText("after", formatExamples([
215
197
  "xopc models list",
216
198
  "xopc models status",
217
- "xopc models set openai/gpt-5.5",
199
+ "xopc models set deepseek/deepseek-v4-flash",
218
200
  "xopc models auth list",
219
201
  "xopc models auth login --provider anthropic",
220
202
  "xopc models auth paste-api-key --provider deepseek"
@@ -1 +1 @@
1
- {"version":3,"file":"models.js","names":[],"sources":["../../../../src/cli/commands/models.ts"],"sourcesContent":["import { input } from '@inquirer/prompts';\nimport { Command } from 'commander';\n\nimport { CredentialResolver } from '../../auth/credentials.js';\nimport { loadConfig, saveConfig } from '../../config/index.js';\nimport type { Config } from '../../config/schema.js';\nimport {\n getAllModels,\n getAvailableModels,\n getConfiguredProviders,\n getProviderAuthState,\n getProviderDisplayName,\n isProviderConfigured,\n providerSupportsApiKey,\n providerSupportsOAuth,\n resolveModel,\n} from '../../providers/index.js';\n\nimport { getContextWithOpts } from '../context.js';\nimport { register, formatExamples, type CLIContext } from '../registry.js';\nimport { colors } from '../utils/colors.js';\nimport { runCliOAuthLogin } from '../utils/oauth-login.js';\n\nconst IMAGE_GENERATION_IDS = new Set([\n 'gpt-image-1',\n 'dall-e-3',\n 'dall-e-2',\n 'wan2.6-t2i',\n 'wan2.7-image-pro',\n 'wan2.7-image',\n 'wan2.1-t2i-turbo',\n 'wan2.1-t2i-plus',\n 'image-01',\n 'image-01-live',\n]);\n\nconst VISION_IDS = new Set([\n 'gpt-4o',\n 'gpt-4o-mini',\n 'gpt-4-turbo',\n 'claude-sonnet-4-5',\n 'claude-haiku-3-5',\n 'gemini-2.0-flash',\n 'gemini-1.5-pro',\n 'qwen-vl-max',\n 'qwen2.5-vl-72b-instruct',\n]);\n\ntype ModelsListOptions = {\n json?: boolean;\n all?: boolean;\n provider?: string;\n};\n\ntype ModelsAuthListOptions = {\n provider?: string;\n json?: boolean;\n};\n\ntype ModelsAuthLoginOptions = {\n method?: 'oauth' | 'api-key';\n setDefault?: boolean;\n};\n\nfunction currentModelRef(config: Config): string | undefined {\n const legacyDefault = (config.agents as unknown as { defaults?: { model?: string } }).defaults?.model?.trim();\n if (legacyDefault) return legacyDefault;\n\n const list = Array.isArray(config.agents?.list) ? config.agents.list : [];\n const id =\n config.agents?.default ??\n list.find((entry) => (entry as { default?: boolean }).default === true)?.id ??\n list[0]?.id;\n const agent = list.find((entry) => entry.id === id) ?? list[0];\n const roles = agent?.models?.roles ?? {};\n const defaultRole = agent?.models?.defaultRole ?? Object.keys(roles)[0];\n return defaultRole ? roles[defaultRole]?.model : undefined;\n}\n\nfunction setDefaultModel(config: Config, modelRef: string): Config {\n const list = Array.isArray(config.agents?.list) ? config.agents.list : [];\n const id = config.agents?.default ?? list[0]?.id ?? 'main';\n const index = list.findIndex((entry) => entry.id === id);\n if (index >= 0) {\n const agent = list[index]!;\n const defaultRole = agent.models?.defaultRole || 'deep';\n list[index] = {\n ...agent,\n models: {\n ...agent.models,\n defaultRole,\n roles: { ...agent.models?.roles, [defaultRole]: { model: modelRef } },\n },\n };\n }\n return config;\n}\n\nfunction modelRef(provider: string, id: string): string {\n return `${provider}/${id}`;\n}\n\nasync function runModelsList(options: ModelsListOptions): Promise<void> {\n const ctx = getContextWithOpts();\n const config = loadConfig(ctx.configPath);\n const configuredProviders = await getConfiguredProviders();\n const providerFilter = options.provider?.trim();\n const models = (options.all ? getAllModels() : await getAvailableModels()).filter((m) =>\n providerFilter ? m.provider === providerFilter : true,\n );\n\n if (options.json) {\n console.log(\n JSON.stringify(\n {\n defaultModel: currentModelRef(config) ?? null,\n providers: configuredProviders,\n models: models.map((m) => ({\n id: modelRef(m.provider, m.id),\n name: m.name,\n provider: m.provider,\n authConfigured: configuredProviders.includes(m.provider),\n })),\n },\n null,\n 2,\n ),\n );\n return;\n }\n\n console.log('\\n🤖 Models\\n');\n console.log('═'.repeat(60));\n\n console.log(`\\n📌 Current default model: ${currentModelRef(config) ?? 'Not set'}\\n`);\n\n const byProvider = new Map<string, typeof models>();\n for (const model of models) {\n const list = byProvider.get(model.provider) ?? [];\n list.push(model);\n byProvider.set(model.provider, list);\n }\n\n for (const [provider, providerModels] of byProvider) {\n const available = await isProviderConfigured(provider);\n console.log(` [${provider}] ${available ? colors.green('configured') : colors.gray('not configured')}`);\n for (const model of providerModels) {\n const badges: string[] = [];\n if (IMAGE_GENERATION_IDS.has(model.id)) badges.push('gen');\n if (model.input?.includes('image') || VISION_IDS.has(model.id)) badges.push('vision');\n const badgeStr = badges.length > 0 ? ` [${badges.join(', ')}]` : '';\n console.log(` ${available ? '✓' : '○'} ${modelRef(model.provider, model.id)}${badgeStr}`);\n }\n }\n\n console.log('\\nUsage:');\n console.log(' xopc models set openai/gpt-5.5');\n console.log(' xopc models auth login --provider anthropic');\n console.log(' xopc models auth paste-api-key --provider deepseek');\n}\n\nasync function runModelsStatus(options: { json?: boolean }): Promise<void> {\n const ctx = getContextWithOpts();\n const config = loadConfig(ctx.configPath);\n const providers = Array.from(new Set(getAllModels().map((m) => m.provider))).sort();\n const auth = [];\n for (const provider of providers) {\n const state = await getProviderAuthState(provider);\n if (state.authMode !== 'none') {\n auth.push({ provider, ...state });\n }\n }\n\n if (options.json) {\n console.log(JSON.stringify({ defaultModel: currentModelRef(config) ?? null, auth }, null, 2));\n return;\n }\n\n console.log('\\n🤖 Model status\\n');\n console.log(`Default: ${currentModelRef(config) ?? 'Not set'}`);\n console.log('\\nAuth:');\n if (auth.length === 0) {\n console.log(' No provider credentials configured.');\n return;\n }\n for (const entry of auth) {\n const status = entry.authStatus === 'connected' ? colors.green(entry.authStatus) : colors.yellow(entry.authStatus);\n console.log(` ${entry.provider}: ${status} (${entry.authMode})`);\n }\n}\n\nasync function runModelsSet(model: string): Promise<void> {\n const ctx = getContextWithOpts();\n const config = loadConfig(ctx.configPath);\n const resolved = resolveModel(model);\n const ref = modelRef(resolved.provider, resolved.id);\n setDefaultModel(config, ref);\n await saveConfig(config, ctx.configPath);\n console.log(`✅ Default model set: ${ref}`);\n}\n\nasync function runAuthList(options: ModelsAuthListOptions): Promise<void> {\n const resolver = new CredentialResolver();\n const profiles = (await resolver.listProfiles()).filter((profile) =>\n options.provider ? profile.provider === options.provider : true,\n );\n const oauthTokens = (await resolver.listOAuthTokens()).filter((token) =>\n options.provider ? token.provider === options.provider : true,\n );\n\n if (options.json) {\n console.log(JSON.stringify({ profiles, oauth: oauthTokens }, null, 2));\n return;\n }\n\n console.log('\\n🔐 Model auth\\n');\n if (profiles.length === 0 && oauthTokens.length === 0) {\n console.log(' No model credentials configured.');\n return;\n }\n for (const profile of profiles) {\n console.log(` ${profile.id} ${colors.blue('api-key')} ${profile.provider} ${profile.source}`);\n }\n for (const token of oauthTokens) {\n const expires = token.expiresAt ? ` expires ${new Date(token.expiresAt).toLocaleString()}` : '';\n console.log(` ${token.provider}:oauth ${colors.yellow('oauth')} ${token.hasAccess ? 'configured' : 'missing'}${expires}`);\n }\n}\n\nasync function runAuthPasteApiKey(provider: string): Promise<void> {\n if (!providerSupportsApiKey(provider)) {\n throw new Error(`Provider ${provider} does not support API key auth`);\n }\n const key = await input({\n message: `API key for ${provider}:`,\n validate: (value: string) => value.trim().length > 0 || 'Required',\n });\n await new CredentialResolver().saveApiKey(provider, key.trim(), { profileName: 'default' });\n console.log(`✅ API key saved for ${provider}`);\n}\n\nfunction resolveAuthMethod(provider: string, rawMethod?: string): 'oauth' | 'api-key' {\n if (rawMethod && rawMethod !== 'oauth' && rawMethod !== 'api-key') {\n throw new Error(`Unsupported auth method: ${rawMethod}`);\n }\n if (rawMethod === 'oauth' || rawMethod === 'api-key') return rawMethod;\n return providerSupportsOAuth(provider) ? 'oauth' : 'api-key';\n}\n\nasync function runAuthLogin(provider: string, options: ModelsAuthLoginOptions): Promise<void> {\n const method = resolveAuthMethod(provider, options.method);\n if (method === 'api-key') {\n await runAuthPasteApiKey(provider);\n } else {\n if (!providerSupportsOAuth(provider)) {\n throw new Error(`Provider ${provider} does not support OAuth`);\n }\n console.log(`\\n🔐 Starting ${getProviderDisplayName(provider)} OAuth login...`);\n await runCliOAuthLogin({ provider, onProgress: (message) => console.log(' →', message) });\n console.log(`✅ OAuth login successful for ${provider}`);\n }\n\n if (options.setDefault) {\n const first = getAllModels().find((model) => model.provider === provider);\n if (!first) throw new Error(`No models found for provider ${provider}`);\n await runModelsSet(modelRef(first.provider, first.id));\n }\n}\n\nasync function runAuthLogout(provider: string): Promise<void> {\n await new CredentialResolver().deleteProviderCredential(provider);\n console.log(`✅ Credentials removed for ${provider}`);\n}\n\nfunction attachModelsListOptions(command: Command): Command {\n return command\n .option('--json', 'Output as JSON', false)\n .option('--all, -a', 'Show all built-in models', false)\n .option('--provider <id>', 'Filter by provider id');\n}\n\nfunction createModelsCommand(_ctx: CLIContext): Command {\n const cmd = new Command('models')\n .description('List and manage models and model auth')\n .addHelpText(\n 'after',\n formatExamples([\n 'xopc models list',\n 'xopc models status',\n 'xopc models set openai/gpt-5.5',\n 'xopc models auth list',\n 'xopc models auth login --provider anthropic',\n 'xopc models auth paste-api-key --provider deepseek',\n ]),\n );\n\n attachModelsListOptions(cmd).action(async (options) => {\n await runModelsList(options);\n });\n\n attachModelsListOptions(cmd.command('list').description('List available models')).action(async (options) => {\n await runModelsList(options);\n });\n\n cmd\n .command('status')\n .description('Show default model and provider auth status')\n .option('--json', 'Output as JSON', false)\n .action(async (options: { json?: boolean }) => {\n await runModelsStatus(options);\n });\n\n cmd\n .command('set <model>')\n .description('Set the default model')\n .action(async (model: string) => {\n await runModelsSet(model);\n });\n\n const auth = cmd.command('auth').description('Manage model provider auth');\n\n auth\n .command('list')\n .description('List model auth credentials')\n .option('--provider <id>', 'Filter by provider id')\n .option('--json', 'Output as JSON', false)\n .action(async (options: ModelsAuthListOptions) => {\n await runAuthList(options);\n });\n\n auth\n .command('login')\n .description('Run provider auth flow')\n .requiredOption('--provider <id>', 'Provider id')\n .option('--method <method>', 'Auth method: oauth or api-key')\n .option('--set-default', 'Set the provider first model as default after login', false)\n .action(async (options: ModelsAuthLoginOptions & { provider: string }) => {\n await runAuthLogin(options.provider, options);\n });\n\n auth\n .command('paste-api-key')\n .description('Paste and save an API key')\n .requiredOption('--provider <id>', 'Provider id')\n .action(async (options: { provider: string }) => {\n await runAuthPasteApiKey(options.provider);\n });\n\n auth\n .command('logout')\n .description('Remove provider credentials')\n .requiredOption('--provider <id>', 'Provider id')\n .action(async (options: { provider: string }) => {\n await runAuthLogout(options.provider);\n });\n\n return cmd;\n}\n\nregister({\n id: 'models',\n name: 'models',\n description: 'List and manage models and model auth',\n factory: createModelsCommand,\n metadata: {\n category: 'utility',\n examples: ['xopc models list', 'xopc models status', 'xopc models auth list'],\n },\n});\n\nexport { createModelsCommand };\n"],"mappings":"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"}
1
+ {"version":3,"file":"models.js","names":[],"sources":["../../../../src/cli/commands/models.ts"],"sourcesContent":["import { input } from '@inquirer/prompts';\nimport { Command } from 'commander';\n\nimport { CredentialResolver } from '../../auth/credentials.js';\nimport { loadConfig, saveConfig } from '../../config/index.js';\nimport { getAgentDefaultModelRef, type Config } from '../../config/schema.js';\nimport { prepareUpdateGlobalDefaults } from '../../gateway/global-defaults-admin.js';\nimport {\n getAllModels,\n getAvailableModels,\n getConfiguredProviders,\n getProviderAuthState,\n getProviderDisplayName,\n isProviderConfigured,\n providerSupportsApiKey,\n providerSupportsOAuth,\n resolveModel,\n} from '../../providers/index.js';\n\nimport { getContextWithOpts } from '../context.js';\nimport { register, formatExamples, type CLIContext } from '../registry.js';\nimport { colors } from '../utils/colors.js';\nimport { runCliOAuthLogin } from '../utils/oauth-login.js';\n\nconst IMAGE_GENERATION_IDS = new Set([\n 'gpt-image-1',\n 'dall-e-3',\n 'dall-e-2',\n 'wan2.6-t2i',\n 'wan2.7-image-pro',\n 'wan2.7-image',\n 'wan2.1-t2i-turbo',\n 'wan2.1-t2i-plus',\n 'image-01',\n 'image-01-live',\n]);\n\nconst VISION_IDS = new Set([\n 'gpt-4o',\n 'gpt-4o-mini',\n 'gpt-4-turbo',\n 'claude-sonnet-4-5',\n 'claude-haiku-3-5',\n 'gemini-2.0-flash',\n 'gemini-1.5-pro',\n 'qwen-vl-max',\n 'qwen2.5-vl-72b-instruct',\n]);\n\ntype ModelsListOptions = {\n json?: boolean;\n all?: boolean;\n provider?: string;\n};\n\ntype ModelsAuthListOptions = {\n provider?: string;\n json?: boolean;\n};\n\ntype ModelsAuthLoginOptions = {\n method?: 'oauth' | 'api-key';\n setDefault?: boolean;\n};\n\nfunction currentModelRef(config: Config): string | undefined {\n return getAgentDefaultModelRef(config);\n}\n\nfunction setDefaultModel(config: Config, modelRef: string): Config {\n const prep = prepareUpdateGlobalDefaults(config, {\n models: {\n defaultRole: 'deep',\n roles: {\n deep: { model: modelRef },\n },\n },\n });\n if (prep.ok === false) {\n throw new Error(prep.error);\n }\n return prep.data.nextConfig;\n}\n\nfunction modelRef(provider: string, id: string): string {\n return `${provider}/${id}`;\n}\n\nasync function runModelsList(options: ModelsListOptions): Promise<void> {\n const ctx = getContextWithOpts();\n const config = loadConfig(ctx.configPath);\n const configuredProviders = await getConfiguredProviders();\n const providerFilter = options.provider?.trim();\n const models = (options.all ? getAllModels() : await getAvailableModels()).filter((m) =>\n providerFilter ? m.provider === providerFilter : true,\n );\n\n if (options.json) {\n console.log(\n JSON.stringify(\n {\n defaultModel: currentModelRef(config) ?? null,\n providers: configuredProviders,\n models: models.map((m) => ({\n id: modelRef(m.provider, m.id),\n name: m.name,\n provider: m.provider,\n authConfigured: configuredProviders.includes(m.provider),\n })),\n },\n null,\n 2,\n ),\n );\n return;\n }\n\n console.log('\\n🤖 Models\\n');\n console.log('═'.repeat(60));\n\n console.log(`\\n📌 Current default model: ${currentModelRef(config) ?? 'Not set'}\\n`);\n\n const byProvider = new Map<string, typeof models>();\n for (const model of models) {\n const list = byProvider.get(model.provider) ?? [];\n list.push(model);\n byProvider.set(model.provider, list);\n }\n\n for (const [provider, providerModels] of byProvider) {\n const available = await isProviderConfigured(provider);\n console.log(` [${provider}] ${available ? colors.green('configured') : colors.gray('not configured')}`);\n for (const model of providerModels) {\n const badges: string[] = [];\n if (IMAGE_GENERATION_IDS.has(model.id)) badges.push('gen');\n if (model.input?.includes('image') || VISION_IDS.has(model.id)) badges.push('vision');\n const badgeStr = badges.length > 0 ? ` [${badges.join(', ')}]` : '';\n console.log(` ${available ? '✓' : '○'} ${modelRef(model.provider, model.id)}${badgeStr}`);\n }\n }\n\n console.log('\\nUsage:');\n console.log(' xopc models set deepseek/deepseek-v4-flash');\n console.log(' xopc models auth login --provider anthropic');\n console.log(' xopc models auth paste-api-key --provider deepseek');\n}\n\nasync function runModelsStatus(options: { json?: boolean }): Promise<void> {\n const ctx = getContextWithOpts();\n const config = loadConfig(ctx.configPath);\n const providers = Array.from(new Set(getAllModels().map((m) => m.provider))).sort();\n const auth = [];\n for (const provider of providers) {\n const state = await getProviderAuthState(provider);\n if (state.authMode !== 'none') {\n auth.push({ provider, ...state });\n }\n }\n\n if (options.json) {\n console.log(JSON.stringify({ defaultModel: currentModelRef(config) ?? null, auth }, null, 2));\n return;\n }\n\n console.log('\\n🤖 Model status\\n');\n console.log(`Default: ${currentModelRef(config) ?? 'Not set'}`);\n console.log('\\nAuth:');\n if (auth.length === 0) {\n console.log(' No provider credentials configured.');\n return;\n }\n for (const entry of auth) {\n const status = entry.authStatus === 'connected' ? colors.green(entry.authStatus) : colors.yellow(entry.authStatus);\n console.log(` ${entry.provider}: ${status} (${entry.authMode})`);\n }\n}\n\nasync function runModelsSet(model: string): Promise<void> {\n const ctx = getContextWithOpts();\n const config = loadConfig(ctx.configPath);\n const resolved = resolveModel(model);\n const ref = modelRef(resolved.provider, resolved.id);\n await saveConfig(setDefaultModel(config, ref), ctx.configPath);\n console.log(`✅ Default model set: ${ref}`);\n}\n\nasync function runAuthList(options: ModelsAuthListOptions): Promise<void> {\n const resolver = new CredentialResolver();\n const profiles = (await resolver.listProfiles()).filter((profile) =>\n options.provider ? profile.provider === options.provider : true,\n );\n const oauthTokens = (await resolver.listOAuthTokens()).filter((token) =>\n options.provider ? token.provider === options.provider : true,\n );\n\n if (options.json) {\n console.log(JSON.stringify({ profiles, oauth: oauthTokens }, null, 2));\n return;\n }\n\n console.log('\\n🔐 Model auth\\n');\n if (profiles.length === 0 && oauthTokens.length === 0) {\n console.log(' No model credentials configured.');\n return;\n }\n for (const profile of profiles) {\n console.log(` ${profile.id} ${colors.blue('api-key')} ${profile.provider} ${profile.source}`);\n }\n for (const token of oauthTokens) {\n const expires = token.expiresAt ? ` expires ${new Date(token.expiresAt).toLocaleString()}` : '';\n console.log(` ${token.provider}:oauth ${colors.yellow('oauth')} ${token.hasAccess ? 'configured' : 'missing'}${expires}`);\n }\n}\n\nasync function runAuthPasteApiKey(provider: string): Promise<void> {\n if (!providerSupportsApiKey(provider)) {\n throw new Error(`Provider ${provider} does not support API key auth`);\n }\n const key = await input({\n message: `API key for ${provider}:`,\n validate: (value: string) => value.trim().length > 0 || 'Required',\n });\n await new CredentialResolver().saveApiKey(provider, key.trim(), { profileName: 'default' });\n console.log(`✅ API key saved for ${provider}`);\n}\n\nfunction resolveAuthMethod(provider: string, rawMethod?: string): 'oauth' | 'api-key' {\n if (rawMethod && rawMethod !== 'oauth' && rawMethod !== 'api-key') {\n throw new Error(`Unsupported auth method: ${rawMethod}`);\n }\n if (rawMethod === 'oauth' || rawMethod === 'api-key') return rawMethod;\n return providerSupportsOAuth(provider) ? 'oauth' : 'api-key';\n}\n\nasync function runAuthLogin(provider: string, options: ModelsAuthLoginOptions): Promise<void> {\n const method = resolveAuthMethod(provider, options.method);\n if (method === 'api-key') {\n await runAuthPasteApiKey(provider);\n } else {\n if (!providerSupportsOAuth(provider)) {\n throw new Error(`Provider ${provider} does not support OAuth`);\n }\n console.log(`\\n🔐 Starting ${getProviderDisplayName(provider)} OAuth login...`);\n await runCliOAuthLogin({ provider, onProgress: (message) => console.log(' →', message) });\n console.log(`✅ OAuth login successful for ${provider}`);\n }\n\n if (options.setDefault) {\n const first = getAllModels().find((model) => model.provider === provider);\n if (!first) throw new Error(`No models found for provider ${provider}`);\n await runModelsSet(modelRef(first.provider, first.id));\n }\n}\n\nasync function runAuthLogout(provider: string): Promise<void> {\n await new CredentialResolver().deleteProviderCredential(provider);\n console.log(`✅ Credentials removed for ${provider}`);\n}\n\nfunction attachModelsListOptions(command: Command): Command {\n return command\n .option('--json', 'Output as JSON', false)\n .option('--all, -a', 'Show all built-in models', false)\n .option('--provider <id>', 'Filter by provider id');\n}\n\nfunction createModelsCommand(_ctx: CLIContext): Command {\n const cmd = new Command('models')\n .description('List and manage models and model auth')\n .addHelpText(\n 'after',\n formatExamples([\n 'xopc models list',\n 'xopc models status',\n 'xopc models set deepseek/deepseek-v4-flash',\n 'xopc models auth list',\n 'xopc models auth login --provider anthropic',\n 'xopc models auth paste-api-key --provider deepseek',\n ]),\n );\n\n attachModelsListOptions(cmd).action(async (options) => {\n await runModelsList(options);\n });\n\n attachModelsListOptions(cmd.command('list').description('List available models')).action(async (options) => {\n await runModelsList(options);\n });\n\n cmd\n .command('status')\n .description('Show default model and provider auth status')\n .option('--json', 'Output as JSON', false)\n .action(async (options: { json?: boolean }) => {\n await runModelsStatus(options);\n });\n\n cmd\n .command('set <model>')\n .description('Set the default model')\n .action(async (model: string) => {\n await runModelsSet(model);\n });\n\n const auth = cmd.command('auth').description('Manage model provider auth');\n\n auth\n .command('list')\n .description('List model auth credentials')\n .option('--provider <id>', 'Filter by provider id')\n .option('--json', 'Output as JSON', false)\n .action(async (options: ModelsAuthListOptions) => {\n await runAuthList(options);\n });\n\n auth\n .command('login')\n .description('Run provider auth flow')\n .requiredOption('--provider <id>', 'Provider id')\n .option('--method <method>', 'Auth method: oauth or api-key')\n .option('--set-default', 'Set the provider first model as default after login', false)\n .action(async (options: ModelsAuthLoginOptions & { provider: string }) => {\n await runAuthLogin(options.provider, options);\n });\n\n auth\n .command('paste-api-key')\n .description('Paste and save an API key')\n .requiredOption('--provider <id>', 'Provider id')\n .action(async (options: { provider: string }) => {\n await runAuthPasteApiKey(options.provider);\n });\n\n auth\n .command('logout')\n .description('Remove provider credentials')\n .requiredOption('--provider <id>', 'Provider id')\n .action(async (options: { provider: string }) => {\n await runAuthLogout(options.provider);\n });\n\n return cmd;\n}\n\nregister({\n id: 'models',\n name: 'models',\n description: 'List and manage models and model auth',\n factory: createModelsCommand,\n metadata: {\n category: 'utility',\n examples: ['xopc models list', 'xopc models status', 'xopc models auth list'],\n },\n});\n\nexport { createModelsCommand };\n"],"mappings":"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"}
@@ -6,6 +6,7 @@ import { getModelRegistry } from "../../../providers/model-registry.js";
6
6
  import { CredentialResolver, init_credentials } from "../../../auth/credentials.js";
7
7
  import { getAllProviders, getModelsByProvider, getProviderDisplayName, init_providers, providerSupportsApiKey, providerSupportsOAuth } from "../../../providers/index.js";
8
8
  import { getProviderHint, getRecommendedModelsForProvider, sortModelsForPicker, sortProvidersForPicker } from "../../../providers/presentation.js";
9
+ import { prepareUpdateGlobalDefaults } from "../../../gateway/global-defaults-admin.js";
9
10
  import { listProfilesForProvider } from "../../../auth/profiles/profiles.js";
10
11
  import { getOAuthProvider } from "../../utils/oauth-providers.js";
11
12
  import { colors } from "../../utils/colors.js";
@@ -22,22 +23,28 @@ init_providers();
22
23
  function setPrimaryModel(config, workspacePath, modelRef) {
23
24
  const id = config.agents.default ?? config.agents.list[0]?.id ?? "main";
24
25
  const index = config.agents.list.findIndex((entry) => entry.id === id);
26
+ let nextConfig = config;
25
27
  if (index >= 0) {
26
28
  const agent = config.agents.list[index];
27
- config.agents.list[index] = {
29
+ const nextList = [...config.agents.list];
30
+ nextList[index] = {
28
31
  ...agent,
29
- workspace: { root: workspacePath },
30
- models: {
31
- ...agent.models,
32
- defaultRole: agent.models.defaultRole || "deep",
33
- roles: {
34
- ...agent.models.roles,
35
- [agent.models.defaultRole || "deep"]: { model: modelRef }
36
- }
32
+ workspace: { root: workspacePath }
33
+ };
34
+ nextConfig = {
35
+ ...config,
36
+ agents: {
37
+ ...config.agents,
38
+ list: nextList
37
39
  }
38
40
  };
39
41
  }
40
- return config;
42
+ const prep = prepareUpdateGlobalDefaults(nextConfig, { models: {
43
+ defaultRole: "deep",
44
+ roles: { deep: { model: modelRef } }
45
+ } });
46
+ if (prep.ok === false) throw new Error(prep.error);
47
+ return prep.data.nextConfig;
41
48
  }
42
49
  function formatRecommended(provider) {
43
50
  const labels = getRecommendedModelsForProvider(provider, 3).map((m) => m.name || m.id);
@@ -1 +1 @@
1
- {"version":3,"file":"model.js","names":["getModelsJsonPath"],"sources":["../../../../../src/cli/commands/onboard/model.ts"],"sourcesContent":["/**\n * Catalog-driven model configuration for onboarding.\n */\n\nimport { confirm, input, select } from '@inquirer/prompts';\n\nimport { CredentialResolver } from '../../../auth/credentials.js';\nimport {\n getModelsJsonPath,\n loadModelsJson,\n saveModelsJson,\n type ModelsJsonConfig,\n} from '../../../config/models-json.js';\nimport type { Config } from '../../../config/schema.js';\nimport { getAgentDefaultModelRef } from '../../../config/schema.js';\nimport {\n getAllProviders,\n getApiKeyFromEnv,\n getModelRegistry,\n getModelsByProvider,\n getProviderDisplayName,\n providerSupportsApiKey,\n providerSupportsOAuth,\n} from '../../../providers/index.js';\nimport {\n getProviderHint,\n getRecommendedModelsForProvider,\n sortModelsForPicker,\n sortProvidersForPicker,\n} from '../../../providers/presentation.js';\nimport { listProfilesForProvider } from '../../../auth/profiles/index.js';\nimport { getOAuthProvider } from '../../utils/oauth-providers.js';\nimport { runCliOAuthLogin } from '../../utils/oauth-login.js';\nimport type { CLIContext } from '../../registry.js';\nimport { colors } from '../../utils/colors.js';\n\ntype ModelChoice = { value: string; name: string; description?: string };\ntype CustomApiKind = 'openai-completions' | 'openai-responses' | 'anthropic-messages';\n\nfunction setPrimaryModel(config: Config, workspacePath: string, modelRef: string): Config {\n const id = config.agents.default ?? config.agents.list[0]?.id ?? 'main';\n const index = config.agents.list.findIndex((entry) => entry.id === id);\n if (index >= 0) {\n const agent = config.agents.list[index]!;\n config.agents.list[index] = {\n ...agent,\n workspace: { root: workspacePath },\n models: {\n ...agent.models,\n defaultRole: agent.models.defaultRole || 'deep',\n roles: { ...agent.models.roles, [agent.models.defaultRole || 'deep']: { model: modelRef } },\n },\n };\n }\n return config;\n}\n\nfunction formatRecommended(provider: string): string | undefined {\n const labels = getRecommendedModelsForProvider(provider, 3).map((m) => m.name || m.id);\n return labels.length > 0 ? `Recommended: ${labels.join(', ')}` : getProviderHint(provider);\n}\n\nfunction providerChoices(): Array<{ value: string; name: string; description?: string }> {\n const providers = sortProvidersForPicker(getAllProviders());\n const choices = providers.map((provider) => ({\n value: provider,\n name: getProviderDisplayName(provider),\n description: formatRecommended(provider),\n }));\n choices.push({\n value: 'custom-api',\n name: 'Custom API',\n description: 'OpenAI-compatible, OpenAI Responses, or Anthropic-compatible endpoint',\n });\n return choices;\n}\n\nfunction modelChoiceName(choice: ModelChoice): string {\n return choice.description ? `${choice.name} ${colors.gray(choice.description)}` : choice.name;\n}\n\nfunction getModelsForProvider(provider: string): ModelChoice[] {\n return sortModelsForPicker(getModelsByProvider(provider)).map((m) => {\n const badges = [m.reasoning ? 'reasoning' : '', m.input?.includes('image') ? 'vision' : '']\n .filter(Boolean)\n .join(', ');\n return {\n value: `${m.provider}/${m.id}`,\n name: m.name || m.id,\n description: badges || undefined,\n };\n });\n}\n\nasync function doOAuthLogin(provider: string): Promise<boolean> {\n const config = getOAuthProvider(provider);\n if (!config) {\n console.error(`OAuth not supported for provider: ${provider}`);\n return false;\n }\n\n console.log(`\\n🔐 Starting ${config.displayName} OAuth login...`);\n try {\n await runCliOAuthLogin({ provider, onProgress: (message) => console.log(' →', message) });\n return true;\n } catch (error) {\n console.error('❌ OAuth login failed:', error);\n return false;\n }\n}\n\nfunction joinEndpoint(baseUrl: string, suffix: string): string {\n return `${baseUrl.replace(/\\/+$/, '')}/${suffix.replace(/^\\/+/, '')}`;\n}\n\nasync function probeCustomProvider(params: {\n baseUrl: string;\n apiKey: string;\n modelId: string;\n api: CustomApiKind;\n}): Promise<void> {\n const timeout = AbortSignal.timeout(30_000);\n const commonHeaders = {\n 'content-type': 'application/json',\n authorization: `Bearer ${params.apiKey}`,\n };\n\n const request =\n params.api === 'anthropic-messages'\n ? {\n url: joinEndpoint(params.baseUrl, '/messages'),\n headers: { ...commonHeaders, 'anthropic-version': '2023-06-01' },\n body: { model: params.modelId, max_tokens: 1, messages: [{ role: 'user', content: 'ping' }] },\n }\n : params.api === 'openai-responses'\n ? {\n url: joinEndpoint(params.baseUrl, '/responses'),\n headers: commonHeaders,\n body: { model: params.modelId, input: 'ping', max_output_tokens: 1 },\n }\n : {\n url: joinEndpoint(params.baseUrl, '/chat/completions'),\n headers: commonHeaders,\n body: { model: params.modelId, messages: [{ role: 'user', content: 'ping' }], max_tokens: 1 },\n };\n\n const res = await fetch(request.url, {\n method: 'POST',\n headers: request.headers,\n body: JSON.stringify(request.body),\n signal: timeout,\n });\n if (!res.ok) {\n const text = await res.text().catch(() => '');\n throw new Error(`Probe failed (${res.status}) at ${request.url}${text ? `: ${text.slice(0, 300)}` : ''}`);\n }\n}\n\nfunction defaultProviderIdFromBaseUrl(baseUrl: string): string {\n try {\n const url = new URL(baseUrl);\n return url.hostname\n .replace(/^api\\./, '')\n .split('.')\n .filter(Boolean)\n .slice(0, 2)\n .join('-')\n .toLowerCase()\n .replace(/[^a-z0-9-_]+/g, '-')\n .replace(/^-+|-+$/g, '') || 'custom';\n } catch {\n return 'custom';\n }\n}\n\nfunction validateProviderId(value: string): true | string {\n return /^[a-z0-9]([a-z0-9-_]*[a-z0-9])?$/.test(value)\n ? true\n : 'Use lowercase letters, numbers, hyphens, or underscores; start/end with a letter or number.';\n}\n\nasync function setupCustomApi(config: Config, ctx: CLIContext): Promise<Config> {\n console.log('\\n🔌 Custom API provider\\n');\n\n const baseUrl = (await input({\n message: 'API base URL:',\n default: 'https://api.example.com/v1',\n validate: (value) => URL.canParse(value) || 'Enter a valid URL',\n })).trim();\n\n const apiKey = (await input({\n message: 'API key:',\n validate: (value) => value.trim().length > 0 || 'Required',\n })).trim();\n\n const api = await select<CustomApiKind>({\n message: 'Compatibility:',\n choices: [\n { value: 'openai-completions', name: 'OpenAI-compatible Chat Completions' },\n { value: 'openai-responses', name: 'OpenAI Responses' },\n { value: 'anthropic-messages', name: 'Anthropic Messages' },\n ],\n });\n\n const modelId = (await input({\n message: 'Model ID:',\n validate: (value) => value.trim().length > 0 || 'Required',\n })).trim();\n\n console.log('\\n→ Probing endpoint...');\n await probeCustomProvider({ baseUrl, apiKey, modelId, api });\n console.log(colors.green('✓ Probe succeeded'));\n\n const existingProviders = new Set(getAllProviders());\n const providerId = (await input({\n message: 'Provider ID:',\n default: defaultProviderIdFromBaseUrl(baseUrl),\n validate: (value) => {\n const valid = validateProviderId(value.trim());\n if (valid !== true) return valid;\n if (existingProviders.has(value.trim())) return 'Provider ID already exists; choose a new ID.';\n return true;\n },\n })).trim();\n\n const path = getModelsJsonPath();\n const { config: modelsConfig } = loadModelsJson(path);\n const nextModelsConfig: ModelsJsonConfig = {\n providers: {\n ...(modelsConfig.providers ?? {}),\n [providerId]: {\n baseUrl,\n apiKey,\n api,\n models: [{ id: modelId, name: modelId, api, contextWindow: 128000, input: ['text'] }],\n },\n },\n };\n const saved = saveModelsJson(path, nextModelsConfig);\n if (!saved.success) {\n throw new Error(saved.error || 'Failed to save models.json');\n }\n getModelRegistry().refresh();\n\n const ref = `${providerId}/${modelId}`;\n console.log('\\n✅ Custom model configured:', ref);\n return setPrimaryModel(config, ctx.workspacePath, ref);\n}\n\nasync function ensureProviderCredential(provider: string, providerName: string): Promise<boolean> {\n const existingProfiles = listProfilesForProvider(provider);\n if (existingProfiles.length > 0) {\n console.log(`\\n${colors.green('✓')} Found existing credentials for ${providerName}`);\n return await confirm({ message: 'Use existing credentials?', default: true });\n }\n\n const envKey = getApiKeyFromEnv(provider);\n if (envKey) {\n console.log(`\\n${colors.green('✓')} Found API key for ${providerName} in environment`);\n return true;\n }\n\n const supportsOAuth = providerSupportsOAuth(provider);\n const supportsApiKey = providerSupportsApiKey(provider);\n\n if (supportsOAuth && !supportsApiKey) {\n return await doOAuthLogin(provider);\n }\n\n let useOAuth = false;\n if (supportsOAuth && supportsApiKey) {\n const authMethod = await select<'api_key' | 'oauth'>({\n message: `How would you like to authenticate with ${providerName}?`,\n choices: [\n { value: 'api_key', name: 'API key' },\n { value: 'oauth', name: 'OAuth login' },\n ],\n });\n useOAuth = authMethod === 'oauth';\n }\n\n if (useOAuth) {\n const ok = await doOAuthLogin(provider);\n if (ok) return true;\n console.log('\\n⚠️ OAuth login failed. Enter an API key instead.');\n }\n\n if (!supportsApiKey) return false;\n const apiKey = await input({\n message: `API key for ${providerName}:`,\n validate: (value) => value.trim().length > 0 || 'Required',\n });\n const resolver = new CredentialResolver();\n await resolver.saveApiKey(provider, apiKey.trim(), { profileName: 'default' });\n return true;\n}\n\nexport async function setupModel(existingConfig: Config | null, ctx: CLIContext): Promise<Config> {\n console.log('\\n🤖 Step: AI Model\\n');\n\n const config = existingConfig || ({} as Config);\n const currentModel = getAgentDefaultModelRef(config);\n\n if (currentModel) {\n console.log('Current model:', currentModel);\n const keepCurrent = await confirm({ message: 'Keep using this model?', default: true });\n if (keepCurrent) {\n console.log('✅ Keeping:', currentModel);\n return config;\n }\n }\n\n const provider = await select({\n message: 'Model/auth provider:',\n choices: providerChoices(),\n });\n\n if (provider === 'custom-api') {\n return await setupCustomApi(config, ctx);\n }\n\n const providerName = getProviderDisplayName(provider);\n const credentialOk = await ensureProviderCredential(provider, providerName);\n if (!credentialOk) {\n console.error(`\\n❌ Could not configure credentials for ${providerName}.`);\n return config;\n }\n\n const modelChoices = getModelsForProvider(provider);\n if (modelChoices.length === 0) {\n throw new Error(`No catalog models found for ${providerName}. Add a Custom API provider instead.`);\n }\n\n console.log(`\\n📋 Models for ${providerName}:`);\n const model = await select({\n message: 'Model:',\n choices: modelChoices.map((choice) => ({ ...choice, name: modelChoiceName(choice) })),\n });\n\n console.log('\\n✅ Model configured:', model);\n return setPrimaryModel(config, ctx.workspacePath, model);\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"model.js","names":["getModelsJsonPath"],"sources":["../../../../../src/cli/commands/onboard/model.ts"],"sourcesContent":["/**\n * Catalog-driven model configuration for onboarding.\n */\n\nimport { confirm, input, select } from '@inquirer/prompts';\n\nimport { CredentialResolver } from '../../../auth/credentials.js';\nimport {\n getModelsJsonPath,\n loadModelsJson,\n saveModelsJson,\n type ModelsJsonConfig,\n} from '../../../config/models-json.js';\nimport type { Config } from '../../../config/schema.js';\nimport { getAgentDefaultModelRef } from '../../../config/schema.js';\nimport { prepareUpdateGlobalDefaults } from '../../../gateway/global-defaults-admin.js';\nimport {\n getAllProviders,\n getApiKeyFromEnv,\n getModelRegistry,\n getModelsByProvider,\n getProviderDisplayName,\n providerSupportsApiKey,\n providerSupportsOAuth,\n} from '../../../providers/index.js';\nimport {\n getProviderHint,\n getRecommendedModelsForProvider,\n sortModelsForPicker,\n sortProvidersForPicker,\n} from '../../../providers/presentation.js';\nimport { listProfilesForProvider } from '../../../auth/profiles/index.js';\nimport { getOAuthProvider } from '../../utils/oauth-providers.js';\nimport { runCliOAuthLogin } from '../../utils/oauth-login.js';\nimport type { CLIContext } from '../../registry.js';\nimport { colors } from '../../utils/colors.js';\n\ntype ModelChoice = { value: string; name: string; description?: string };\ntype CustomApiKind = 'openai-completions' | 'openai-responses' | 'anthropic-messages';\n\nfunction setPrimaryModel(config: Config, workspacePath: string, modelRef: string): Config {\n const id = config.agents.default ?? config.agents.list[0]?.id ?? 'main';\n const index = config.agents.list.findIndex((entry) => entry.id === id);\n let nextConfig = config;\n if (index >= 0) {\n const agent = config.agents.list[index]!;\n const nextList = [...config.agents.list];\n nextList[index] = {\n ...agent,\n workspace: { root: workspacePath },\n };\n nextConfig = { ...config, agents: { ...config.agents, list: nextList } };\n }\n const prep = prepareUpdateGlobalDefaults(nextConfig, {\n models: {\n defaultRole: 'deep',\n roles: { deep: { model: modelRef } },\n },\n });\n if (prep.ok === false) {\n throw new Error(prep.error);\n }\n return prep.data.nextConfig;\n}\n\nfunction formatRecommended(provider: string): string | undefined {\n const labels = getRecommendedModelsForProvider(provider, 3).map((m) => m.name || m.id);\n return labels.length > 0 ? `Recommended: ${labels.join(', ')}` : getProviderHint(provider);\n}\n\nfunction providerChoices(): Array<{ value: string; name: string; description?: string }> {\n const providers = sortProvidersForPicker(getAllProviders());\n const choices = providers.map((provider) => ({\n value: provider,\n name: getProviderDisplayName(provider),\n description: formatRecommended(provider),\n }));\n choices.push({\n value: 'custom-api',\n name: 'Custom API',\n description: 'OpenAI-compatible, OpenAI Responses, or Anthropic-compatible endpoint',\n });\n return choices;\n}\n\nfunction modelChoiceName(choice: ModelChoice): string {\n return choice.description ? `${choice.name} ${colors.gray(choice.description)}` : choice.name;\n}\n\nfunction getModelsForProvider(provider: string): ModelChoice[] {\n return sortModelsForPicker(getModelsByProvider(provider)).map((m) => {\n const badges = [m.reasoning ? 'reasoning' : '', m.input?.includes('image') ? 'vision' : '']\n .filter(Boolean)\n .join(', ');\n return {\n value: `${m.provider}/${m.id}`,\n name: m.name || m.id,\n description: badges || undefined,\n };\n });\n}\n\nasync function doOAuthLogin(provider: string): Promise<boolean> {\n const config = getOAuthProvider(provider);\n if (!config) {\n console.error(`OAuth not supported for provider: ${provider}`);\n return false;\n }\n\n console.log(`\\n🔐 Starting ${config.displayName} OAuth login...`);\n try {\n await runCliOAuthLogin({ provider, onProgress: (message) => console.log(' →', message) });\n return true;\n } catch (error) {\n console.error('❌ OAuth login failed:', error);\n return false;\n }\n}\n\nfunction joinEndpoint(baseUrl: string, suffix: string): string {\n return `${baseUrl.replace(/\\/+$/, '')}/${suffix.replace(/^\\/+/, '')}`;\n}\n\nasync function probeCustomProvider(params: {\n baseUrl: string;\n apiKey: string;\n modelId: string;\n api: CustomApiKind;\n}): Promise<void> {\n const timeout = AbortSignal.timeout(30_000);\n const commonHeaders = {\n 'content-type': 'application/json',\n authorization: `Bearer ${params.apiKey}`,\n };\n\n const request =\n params.api === 'anthropic-messages'\n ? {\n url: joinEndpoint(params.baseUrl, '/messages'),\n headers: { ...commonHeaders, 'anthropic-version': '2023-06-01' },\n body: { model: params.modelId, max_tokens: 1, messages: [{ role: 'user', content: 'ping' }] },\n }\n : params.api === 'openai-responses'\n ? {\n url: joinEndpoint(params.baseUrl, '/responses'),\n headers: commonHeaders,\n body: { model: params.modelId, input: 'ping', max_output_tokens: 1 },\n }\n : {\n url: joinEndpoint(params.baseUrl, '/chat/completions'),\n headers: commonHeaders,\n body: { model: params.modelId, messages: [{ role: 'user', content: 'ping' }], max_tokens: 1 },\n };\n\n const res = await fetch(request.url, {\n method: 'POST',\n headers: request.headers,\n body: JSON.stringify(request.body),\n signal: timeout,\n });\n if (!res.ok) {\n const text = await res.text().catch(() => '');\n throw new Error(`Probe failed (${res.status}) at ${request.url}${text ? `: ${text.slice(0, 300)}` : ''}`);\n }\n}\n\nfunction defaultProviderIdFromBaseUrl(baseUrl: string): string {\n try {\n const url = new URL(baseUrl);\n return url.hostname\n .replace(/^api\\./, '')\n .split('.')\n .filter(Boolean)\n .slice(0, 2)\n .join('-')\n .toLowerCase()\n .replace(/[^a-z0-9-_]+/g, '-')\n .replace(/^-+|-+$/g, '') || 'custom';\n } catch {\n return 'custom';\n }\n}\n\nfunction validateProviderId(value: string): true | string {\n return /^[a-z0-9]([a-z0-9-_]*[a-z0-9])?$/.test(value)\n ? true\n : 'Use lowercase letters, numbers, hyphens, or underscores; start/end with a letter or number.';\n}\n\nasync function setupCustomApi(config: Config, ctx: CLIContext): Promise<Config> {\n console.log('\\n🔌 Custom API provider\\n');\n\n const baseUrl = (await input({\n message: 'API base URL:',\n default: 'https://api.example.com/v1',\n validate: (value) => URL.canParse(value) || 'Enter a valid URL',\n })).trim();\n\n const apiKey = (await input({\n message: 'API key:',\n validate: (value) => value.trim().length > 0 || 'Required',\n })).trim();\n\n const api = await select<CustomApiKind>({\n message: 'Compatibility:',\n choices: [\n { value: 'openai-completions', name: 'OpenAI-compatible Chat Completions' },\n { value: 'openai-responses', name: 'OpenAI Responses' },\n { value: 'anthropic-messages', name: 'Anthropic Messages' },\n ],\n });\n\n const modelId = (await input({\n message: 'Model ID:',\n validate: (value) => value.trim().length > 0 || 'Required',\n })).trim();\n\n console.log('\\n→ Probing endpoint...');\n await probeCustomProvider({ baseUrl, apiKey, modelId, api });\n console.log(colors.green('✓ Probe succeeded'));\n\n const existingProviders = new Set(getAllProviders());\n const providerId = (await input({\n message: 'Provider ID:',\n default: defaultProviderIdFromBaseUrl(baseUrl),\n validate: (value) => {\n const valid = validateProviderId(value.trim());\n if (valid !== true) return valid;\n if (existingProviders.has(value.trim())) return 'Provider ID already exists; choose a new ID.';\n return true;\n },\n })).trim();\n\n const path = getModelsJsonPath();\n const { config: modelsConfig } = loadModelsJson(path);\n const nextModelsConfig: ModelsJsonConfig = {\n providers: {\n ...(modelsConfig.providers ?? {}),\n [providerId]: {\n baseUrl,\n apiKey,\n api,\n models: [{ id: modelId, name: modelId, api, contextWindow: 128000, input: ['text'] }],\n },\n },\n };\n const saved = saveModelsJson(path, nextModelsConfig);\n if (!saved.success) {\n throw new Error(saved.error || 'Failed to save models.json');\n }\n getModelRegistry().refresh();\n\n const ref = `${providerId}/${modelId}`;\n console.log('\\n✅ Custom model configured:', ref);\n return setPrimaryModel(config, ctx.workspacePath, ref);\n}\n\nasync function ensureProviderCredential(provider: string, providerName: string): Promise<boolean> {\n const existingProfiles = listProfilesForProvider(provider);\n if (existingProfiles.length > 0) {\n console.log(`\\n${colors.green('✓')} Found existing credentials for ${providerName}`);\n return await confirm({ message: 'Use existing credentials?', default: true });\n }\n\n const envKey = getApiKeyFromEnv(provider);\n if (envKey) {\n console.log(`\\n${colors.green('✓')} Found API key for ${providerName} in environment`);\n return true;\n }\n\n const supportsOAuth = providerSupportsOAuth(provider);\n const supportsApiKey = providerSupportsApiKey(provider);\n\n if (supportsOAuth && !supportsApiKey) {\n return await doOAuthLogin(provider);\n }\n\n let useOAuth = false;\n if (supportsOAuth && supportsApiKey) {\n const authMethod = await select<'api_key' | 'oauth'>({\n message: `How would you like to authenticate with ${providerName}?`,\n choices: [\n { value: 'api_key', name: 'API key' },\n { value: 'oauth', name: 'OAuth login' },\n ],\n });\n useOAuth = authMethod === 'oauth';\n }\n\n if (useOAuth) {\n const ok = await doOAuthLogin(provider);\n if (ok) return true;\n console.log('\\n⚠️ OAuth login failed. Enter an API key instead.');\n }\n\n if (!supportsApiKey) return false;\n const apiKey = await input({\n message: `API key for ${providerName}:`,\n validate: (value) => value.trim().length > 0 || 'Required',\n });\n const resolver = new CredentialResolver();\n await resolver.saveApiKey(provider, apiKey.trim(), { profileName: 'default' });\n return true;\n}\n\nexport async function setupModel(existingConfig: Config | null, ctx: CLIContext): Promise<Config> {\n console.log('\\n🤖 Step: AI Model\\n');\n\n const config = existingConfig || ({} as Config);\n const currentModel = getAgentDefaultModelRef(config);\n\n if (currentModel) {\n console.log('Current model:', currentModel);\n const keepCurrent = await confirm({ message: 'Keep using this model?', default: true });\n if (keepCurrent) {\n console.log('✅ Keeping:', currentModel);\n return config;\n }\n }\n\n const provider = await select({\n message: 'Model/auth provider:',\n choices: providerChoices(),\n });\n\n if (provider === 'custom-api') {\n return await setupCustomApi(config, ctx);\n }\n\n const providerName = getProviderDisplayName(provider);\n const credentialOk = await ensureProviderCredential(provider, providerName);\n if (!credentialOk) {\n console.error(`\\n❌ Could not configure credentials for ${providerName}.`);\n return config;\n }\n\n const modelChoices = getModelsForProvider(provider);\n if (modelChoices.length === 0) {\n throw new Error(`No catalog models found for ${providerName}. Add a Custom API provider instead.`);\n }\n\n console.log(`\\n📋 Models for ${providerName}:`);\n const model = await select({\n message: 'Model:',\n choices: modelChoices.map((choice) => ({ ...choice, name: modelChoiceName(choice) })),\n });\n\n console.log('\\n✅ Model configured:', model);\n return setPrimaryModel(config, ctx.workspacePath, model);\n}\n"],"mappings":"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"}
@@ -138,7 +138,7 @@ async function promptLaunchAfterOnboard(config, ctx, _flags) {
138
138
  {
139
139
  value: "tui",
140
140
  name: "Terminal UI (embedded)",
141
- description: "xopc tui --local — no gateway process required"
141
+ description: "xopc — no gateway process required"
142
142
  },
143
143
  {
144
144
  value: "gateway",
@@ -165,7 +165,7 @@ async function promptLaunchAfterOnboard(config, ctx, _flags) {
165
165
  console.log("\n⏭️ You can start later:");
166
166
  console.log(" xopc gateway service install");
167
167
  console.log(" xopc gateway");
168
- console.log(" xopc tui --local");
168
+ console.log(" xopc");
169
169
  }
170
170
  async function setupGateway(config) {
171
171
  console.log(colors.cyan("\n🌐 Gateway WebUI\n"));