@xopcai/xopc 0.0.111 → 0.0.113

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 (443) hide show
  1. package/dist/browser-ext/icons/icon-128.png +0 -0
  2. package/dist/browser-ext/icons/icon-16.png +0 -0
  3. package/dist/browser-ext/icons/icon-32.png +0 -0
  4. package/dist/browser-ext/icons/icon-48.png +0 -0
  5. package/dist/browser-ext/manifest.json +1 -1
  6. package/dist/extensions/feishu/src/outbound/media-load.js +1 -1
  7. package/dist/extensions/feishu/src/workflow-progress.js +1 -1
  8. package/dist/extensions/telegram/src/adapters/streaming-adapter.js +1 -1
  9. package/dist/extensions/telegram/src/inbound-processor.js +1 -1
  10. package/dist/extensions/telegram/src/plugin.js +1 -1
  11. package/dist/extensions/telegram/src/routing-integration.js +2 -2
  12. package/dist/extensions/telegram/src/update-offset-store.js +1 -1
  13. package/dist/extensions/telegram/src/workflow-progress.js +1 -1
  14. package/dist/extensions/telegram/xopc.extension.json +1 -1
  15. package/dist/extensions/weixin/src/api/api.js +2 -2
  16. package/dist/extensions/weixin/src/auth/accounts.js +1 -1
  17. package/dist/extensions/weixin/src/cdn/upload.js +1 -1
  18. package/dist/extensions/weixin/src/delivery-to.d.ts +3 -3
  19. package/dist/extensions/weixin/src/delivery-to.js.map +1 -1
  20. package/dist/extensions/weixin/src/media/data-url.js +1 -1
  21. package/dist/extensions/weixin/src/messaging/debug-mode.js +1 -1
  22. package/dist/extensions/weixin/src/messaging/inbound.js +1 -1
  23. package/dist/extensions/weixin/src/messaging/process-message.js +1 -1
  24. package/dist/extensions/weixin/src/plugin.js +1 -1
  25. package/dist/extensions/weixin/src/storage/sync-buf.js +1 -1
  26. package/dist/extensions/weixin/src/workflow-progress.js +1 -1
  27. package/dist/gateway/static/root/apple-touch-icon.png +0 -0
  28. package/dist/gateway/static/root/assets/{agent-avatar-dicebear-zlx9l5Yp.js → agent-avatar-dicebear-CBlklyNr.js} +1 -1
  29. package/dist/gateway/static/root/assets/agent-browser-settings-page-rGbKc2Hh.js +6 -0
  30. package/dist/gateway/static/root/assets/{agent-defaults-tabbed-page-Bz7JWjRM.js → agent-defaults-tabbed-page-CtwVbjOA.js} +1 -1
  31. package/dist/gateway/static/root/assets/agents-CCBmGcwc.js +71 -0
  32. package/dist/gateway/static/root/assets/{app-management-settings-panel-DaQwdeCq.js → app-management-settings-panel-28E_WfMe.js} +1 -1
  33. package/dist/gateway/static/root/assets/{appearance-settings-D2zv6r3P.js → appearance-settings-Do1z0XgJ.js} +1 -1
  34. package/dist/gateway/static/root/assets/{apps-page-BIppe_jj.js → apps-page-xwCsJS15.js} +1 -1
  35. package/dist/gateway/static/root/assets/{archive-plugin-DEmu8eH7.js → archive-plugin-BAFlsov_.js} +1 -1
  36. package/dist/gateway/static/root/assets/{attachment-load-B98lJoN5.js → attachment-load-V3qGPC3x.js} +1 -1
  37. package/dist/gateway/static/root/assets/{binary-plugins-CL9QKmyo.js → binary-plugins-DT8NvA6W.js} +1 -1
  38. package/dist/gateway/static/root/assets/{block-editor-BOAhMAhT.js → block-editor-CdLMEcHd.js} +1 -1
  39. package/dist/gateway/static/root/assets/{channels-settings-Br8iRnXp.js → channels-settings-C044DcYk.js} +1 -1
  40. package/dist/gateway/static/root/assets/{config-api-0o1WYdz2.js → config-api-Bf5mjpu7.js} +1 -1
  41. package/dist/gateway/static/root/assets/config-reload-event-Bjh2zoKp.js +1 -0
  42. package/dist/gateway/static/root/assets/connectors-settings-8VEWUOTj.js +2 -0
  43. package/dist/gateway/static/root/assets/cron-api--pAB_rps.js +1 -0
  44. package/dist/gateway/static/root/assets/cron-page-DqmNGNOy.js +3 -0
  45. package/dist/gateway/static/root/assets/dreaming-settings-6UZE1FSK.js +1 -0
  46. package/dist/gateway/static/root/assets/{extension-debug-page-Cjx6pZVz.js → extension-debug-page-BGhE7msg.js} +1 -1
  47. package/dist/gateway/static/root/assets/{extension-page-BSPNL90V.js → extension-page-CvpI45WG.js} +1 -1
  48. package/dist/gateway/static/root/assets/extension-settings-page-DAmR5FUe.js +1 -0
  49. package/dist/gateway/static/root/assets/{fetch-Bs7in_4F.js → fetch-NZmjSXLl.js} +1 -1
  50. package/dist/gateway/static/root/assets/format-cron-label-BsotZDO5.js +2 -0
  51. package/dist/gateway/static/root/assets/{format-interval-label-CftJ5uXu.js → format-interval-label-qhth3BMV.js} +1 -1
  52. package/dist/gateway/static/root/assets/{gateway-config-api-Clfck-hW.js → gateway-config-api-CaXBt-9R.js} +1 -1
  53. package/dist/gateway/static/root/assets/gateway-settings-DphpbLBc.js +1 -0
  54. package/dist/gateway/static/root/assets/{gateway-startup-retry-BkjVJc38.js → gateway-startup-retry-Be1omjh3.js} +1 -1
  55. package/dist/gateway/static/root/assets/{goal-detail-page-kqJue0sE.js → goal-detail-page-bv0VRDaf.js} +1 -1
  56. package/dist/gateway/static/root/assets/goals-page-1Ywnt4Cb.js +2 -0
  57. package/dist/gateway/static/root/assets/{goals-settings-CJnzNSDo.js → goals-settings-ceEBjnfc.js} +1 -1
  58. package/dist/gateway/static/root/assets/{heartbeat-config-api-Cp7CPuIn.js → heartbeat-config-api-BzO6G4fD.js} +1 -1
  59. package/dist/gateway/static/root/assets/{heartbeat-settings-ifSI1Wbh.js → heartbeat-settings-DCST9-du.js} +1 -1
  60. package/dist/gateway/static/root/assets/index-Cxm6xsps.js +122 -0
  61. package/dist/gateway/static/root/assets/index-b_R4tKqt.css +1 -0
  62. package/dist/gateway/static/root/assets/interval-presets-DJmshV8n.js +1 -0
  63. package/dist/gateway/static/root/assets/{keyboard-shortcuts-settings--MI1rYl7.js → keyboard-shortcuts-settings-9AUUlQ5Q.js} +1 -1
  64. package/dist/gateway/static/root/assets/{logs-page-BwrVNlyW.js → logs-page-B_wrxhee.js} +1 -1
  65. package/dist/gateway/static/root/assets/{markdown-split-B_oc9lJe.js → markdown-split-CYYELqAr.js} +1 -1
  66. package/dist/gateway/static/root/assets/{media-plugins-DLPvB5H3.js → media-plugins-BEcMR2M8.js} +1 -1
  67. package/dist/gateway/static/root/assets/messages-CkT-lcgP.js +3 -0
  68. package/dist/gateway/static/root/assets/models-hub-panel-D0JDSbNu.js +2 -0
  69. package/dist/gateway/static/root/assets/note-detail-page-DpFV-EO6.js +2 -0
  70. package/dist/gateway/static/root/assets/{note-image-lightbox-rSqAgOi9.js → note-image-lightbox-DNAoPcmm.js} +1 -1
  71. package/dist/gateway/static/root/assets/{notes-page-C9ACGEty.js → notes-page-CdkjTch8.js} +1 -1
  72. package/dist/gateway/static/root/assets/{preview-open-alternatives-Bw_N2oZi.js → preview-open-alternatives-BPLz0AIv.js} +1 -1
  73. package/dist/gateway/static/root/assets/{remote-access-hub-BhcWIKuM.js → remote-access-hub-DSYVAi96.js} +1 -1
  74. package/dist/gateway/static/root/assets/{save-bar-controls-CNP2jmw0.js → save-bar-controls-CrWwWRVK.js} +1 -1
  75. package/dist/gateway/static/root/assets/schedule-field-CF2sadvN.js +1 -0
  76. package/dist/gateway/static/root/assets/{schema-form-CDPzua9q.js → schema-form-Di5cKjYE.js} +1 -1
  77. package/dist/gateway/static/root/assets/{sessions-page-DzkpSDZr.js → sessions-page-CenkcVjF.js} +1 -1
  78. package/dist/gateway/static/root/assets/settings-advanced-gate-D9sva86V.js +1 -0
  79. package/dist/gateway/static/root/assets/{settings-collapsible-section-C9bff85B.js → settings-collapsible-section-Chh282jW.js} +1 -1
  80. package/dist/gateway/static/root/assets/settings-form-section-Dq-83cQd.js +1 -0
  81. package/dist/gateway/static/root/assets/{settings-page-DWK4Zo7s.js → settings-page-DL35U0x0.js} +1 -1
  82. package/dist/gateway/static/root/assets/setup-status-panel-Ctwbp9Er.js +1 -0
  83. package/dist/gateway/static/root/assets/{share-preview-page-DnutoY_S.js → share-preview-page-0FXYnSUA.js} +1 -1
  84. package/dist/gateway/static/root/assets/{shares-settings-6oRgJMpn.js → shares-settings-DIM3JNsr.js} +1 -1
  85. package/dist/gateway/static/root/assets/skill-reload-api-DAlNaNzL.js +1 -0
  86. package/dist/gateway/static/root/assets/skills-page-CLrHVzAt.js +2 -0
  87. package/dist/gateway/static/root/assets/{system-settings-panel-qP1JDtDd.js → system-settings-panel-W1pTcojB.js} +1 -1
  88. package/dist/gateway/static/root/assets/use-agent-defaults-form-BVRvkK7m.js +1 -0
  89. package/dist/gateway/static/root/assets/{use-channel-catalog-C4mg1hjD.js → use-channel-catalog-CgJibfMM.js} +1 -1
  90. package/dist/gateway/static/root/assets/{use-settings-tab-guard-F6C0mpJt.js → use-settings-tab-guard-Bw_qkRQE.js} +1 -1
  91. package/dist/gateway/static/root/assets/{voice-api-key-field-BnDDb6qO.js → voice-api-key-field-vYAO71Gn.js} +1 -1
  92. package/dist/gateway/static/root/assets/{voice-player-store-B2EwIhtY.js → voice-player-store-C7lziaAx.js} +1 -1
  93. package/dist/gateway/static/root/assets/{workflow-page.utils-CRB7WX9l.js → workflow-page.utils-sgHjOXOm.js} +1 -1
  94. package/dist/gateway/static/root/assets/{workflows-page-2Fptr0je.js → workflows-page-DYyOTmFx.js} +1 -1
  95. package/dist/gateway/static/root/favicon-16x16.png +0 -0
  96. package/dist/gateway/static/root/favicon-32x32.png +0 -0
  97. package/dist/gateway/static/root/favicon-icon.svg +1 -0
  98. package/dist/gateway/static/root/favicon.ico +0 -0
  99. package/dist/gateway/static/root/favicon.png +0 -0
  100. package/dist/gateway/static/root/favicon.svg +24 -15
  101. package/dist/gateway/static/root/index.html +11 -10
  102. package/dist/gateway/static/root/logo-dark.svg +23 -15
  103. package/dist/gateway/static/root/logo.svg +23 -16
  104. package/dist/package.js +1 -1
  105. package/dist/src/agent/agent-manager.d.ts +28 -2
  106. package/dist/src/agent/agent-manager.js +82 -11
  107. package/dist/src/agent/agent-manager.js.map +1 -1
  108. package/dist/src/agent/agent-scope.js +1 -1
  109. package/dist/src/agent/bootstrap/load-bootstrap-files.js +1 -1
  110. package/dist/src/agent/context/workspace-seed.js +2 -2
  111. package/dist/src/agent/context/workspace-state.js +1 -1
  112. package/dist/src/agent/context/workspace.js +1 -1
  113. package/dist/src/agent/goals/goal-locale.js +2 -2
  114. package/dist/src/agent/goals/persistent-goal-service.js +1 -1
  115. package/dist/src/agent/goals/post-turn.js +3 -3
  116. package/dist/src/agent/image/load-image-media.js +2 -2
  117. package/dist/src/agent/ipc/inbox.js +3 -3
  118. package/dist/src/agent/ipc/socket.js +1 -1
  119. package/dist/src/agent/mcp/bundle-mcp-materialize.js +1 -1
  120. package/dist/src/agent/mcp/bundle-mcp-runtime.js +1 -1
  121. package/dist/src/agent/mcp/mcp-transport-config.js +1 -1
  122. package/dist/src/agent/mcp/mcp-transport.js +1 -1
  123. package/dist/src/agent/memory/builtin-memory-store.js +1 -1
  124. package/dist/src/agent/memory/dreaming/deep-promotion.js +1 -1
  125. package/dist/src/agent/memory/dreaming/events.js +1 -1
  126. package/dist/src/agent/memory/dreaming/last-run.js +1 -1
  127. package/dist/src/agent/memory/dreaming/light-sweep.js +1 -1
  128. package/dist/src/agent/memory/dreaming/preview.js +1 -1
  129. package/dist/src/agent/memory/dreaming/rem-patterns.js +1 -1
  130. package/dist/src/agent/memory/dreaming/short-term-store.js +1 -1
  131. package/dist/src/agent/memory/dreaming/utils.js +1 -1
  132. package/dist/src/agent/memory/memory-flush.js +1 -1
  133. package/dist/src/agent/memory/plugin-discovery.js +1 -1
  134. package/dist/src/agent/messaging/command-handler.d.ts +3 -0
  135. package/dist/src/agent/messaging/command-handler.js +5 -0
  136. package/dist/src/agent/messaging/command-handler.js.map +1 -1
  137. package/dist/src/agent/models/manager.js +1 -1
  138. package/dist/src/agent/prompt/memory/index.js +1 -1
  139. package/dist/src/agent/prompt/service-prompt-builder.js +2 -2
  140. package/dist/src/agent/reply/post-compaction-context.js +1 -1
  141. package/dist/src/agent/reply/workspace-boundary-read.js +1 -1
  142. package/dist/src/agent/sandbox/path-policy.js +2 -2
  143. package/dist/src/agent/service/process-direct-streaming.js +9 -4
  144. package/dist/src/agent/service/process-direct-streaming.js.map +1 -1
  145. package/dist/src/agent/service/reconcile-dreaming-cron.js +8 -5
  146. package/dist/src/agent/service/reconcile-dreaming-cron.js.map +1 -1
  147. package/dist/src/agent/service.d.ts +2 -1
  148. package/dist/src/agent/service.js +10 -5
  149. package/dist/src/agent/service.js.map +1 -1
  150. package/dist/src/agent/service.types.d.ts +4 -0
  151. package/dist/src/agent/session/session-config-service.d.ts +8 -0
  152. package/dist/src/agent/session/session-config-service.js +20 -0
  153. package/dist/src/agent/session/session-config-service.js.map +1 -1
  154. package/dist/src/agent/session/session-inspector.js +1 -1
  155. package/dist/src/agent/skills/config.js +2 -2
  156. package/dist/src/agent/skills/filesystem-watcher.d.ts +19 -0
  157. package/dist/src/agent/skills/filesystem-watcher.js +182 -0
  158. package/dist/src/agent/skills/filesystem-watcher.js.map +1 -0
  159. package/dist/src/agent/skills/hub-hash.js +2 -2
  160. package/dist/src/agent/skills/hub-lock.js +1 -1
  161. package/dist/src/agent/skills/hub-pull.js +30 -36
  162. package/dist/src/agent/skills/hub-pull.js.map +1 -1
  163. package/dist/src/agent/skills/index.js +82 -38
  164. package/dist/src/agent/skills/index.js.map +1 -1
  165. package/dist/src/agent/skills/installer.js +2 -2
  166. package/dist/src/agent/skills/managed-store.d.ts +19 -0
  167. package/dist/src/agent/skills/managed-store.js +97 -38
  168. package/dist/src/agent/skills/managed-store.js.map +1 -1
  169. package/dist/src/agent/skills/skill-manage-ops.js +1 -1
  170. package/dist/src/agent/skills/skill-manager.d.ts +16 -6
  171. package/dist/src/agent/skills/skill-manager.js +79 -24
  172. package/dist/src/agent/skills/skill-manager.js.map +1 -1
  173. package/dist/src/agent/skills/skill-view-path.js +1 -1
  174. package/dist/src/agent/skills/test-framework.js +1 -1
  175. package/dist/src/agent/skills/types.d.ts +11 -0
  176. package/dist/src/agent/skills/watcher.js +1 -1
  177. package/dist/src/agent/starter-agents.js +1 -1
  178. package/dist/src/agent/tools/cronjob-tool.d.ts +6 -3
  179. package/dist/src/agent/tools/cronjob-tool.js +58 -23
  180. package/dist/src/agent/tools/cronjob-tool.js.map +1 -1
  181. package/dist/src/agent/tools/dreaming-tool.js +1 -1
  182. package/dist/src/agent/tools/factory.js +1 -1
  183. package/dist/src/agent/tools/find.js +1 -1
  184. package/dist/src/agent/tools/grep.js +1 -1
  185. package/dist/src/agent/tools/image-generate-tool.js +1 -1
  186. package/dist/src/agent/tools/skill-manage-tool.js +1 -1
  187. package/dist/src/agent/tools/workflow-tool.js +1 -1
  188. package/dist/src/agent/workflow/catalog.js +1 -1
  189. package/dist/src/agent/workspace-runtime/registry.d.ts +5 -0
  190. package/dist/src/agent/workspace-runtime/registry.js +7 -0
  191. package/dist/src/agent/workspace-runtime/registry.js.map +1 -1
  192. package/dist/src/ai-assist/text-assist.d.ts +42 -0
  193. package/dist/src/ai-assist/text-assist.js +252 -0
  194. package/dist/src/ai-assist/text-assist.js.map +1 -0
  195. package/dist/src/auth/credentials.js +2 -2
  196. package/dist/src/auth/profiles/store.js +2 -2
  197. package/dist/src/auth/sync-provider-auth.js +1 -1
  198. package/dist/src/browser/cache-dir-policy.js +1 -1
  199. package/dist/src/browser/cdp-local-launcher.js +2 -2
  200. package/dist/src/browser/providers/browser-ext-install.js +4 -4
  201. package/dist/src/browser/providers/cloakbrowser.js +5 -5
  202. package/dist/src/browser/providers/playwright-doctor.js +1 -1
  203. package/dist/src/browser/stealth.js +1 -1
  204. package/dist/src/channels/outbound/persist-store.js +1 -1
  205. package/dist/src/channels/pairing/allow-from-file.js +1 -1
  206. package/dist/src/channels/pairing/pairing-store.js +2 -2
  207. package/dist/src/channels/plugins/types.adapters.d.ts +2 -2
  208. package/dist/src/chat-commands/agent-edit.js +2 -2
  209. package/dist/src/chat-commands/builtins/config.js +3 -3
  210. package/dist/src/chat-commands/builtins/system.js +11 -4
  211. package/dist/src/chat-commands/builtins/system.js.map +1 -1
  212. package/dist/src/chat-commands/context.d.ts +3 -0
  213. package/dist/src/chat-commands/context.js +7 -0
  214. package/dist/src/chat-commands/context.js.map +1 -1
  215. package/dist/src/chat-commands/types.d.ts +2 -0
  216. package/dist/src/cli/commands/config.js +1 -1
  217. package/dist/src/cli/commands/cron.js +55 -16
  218. package/dist/src/cli/commands/cron.js.map +1 -1
  219. package/dist/src/cli/commands/doctor/checks/config-health.js +1 -1
  220. package/dist/src/cli/commands/doctor/checks/cron-health.js +2 -83
  221. package/dist/src/cli/commands/doctor/checks/cron-health.js.map +1 -1
  222. package/dist/src/cli/commands/doctor/checks/database-schema.js +1 -1
  223. package/dist/src/cli/commands/doctor/checks/provider-auth.js +1 -1
  224. package/dist/src/cli/commands/doctor/checks/state-integrity.js +1 -1
  225. package/dist/src/cli/commands/doctor/checks/workspace-status.js +1 -1
  226. package/dist/src/cli/commands/extension-create.js +1 -1
  227. package/dist/src/cli/commands/extension-dev.js +2 -2
  228. package/dist/src/cli/commands/extension-marketplace.js +2 -2
  229. package/dist/src/cli/commands/extension-pack.js +2 -2
  230. package/dist/src/cli/commands/extension.js +3 -3
  231. package/dist/src/cli/commands/gateway/logs.js +1 -1
  232. package/dist/src/cli/commands/image.js +1 -1
  233. package/dist/src/cli/commands/init.js +2 -2
  234. package/dist/src/cli/commands/models.js +1 -1
  235. package/dist/src/cli/commands/skills-test.js +1 -1
  236. package/dist/src/cli/templates.js +1 -1
  237. package/dist/src/cli/utils/gateway-client.js +1 -1
  238. package/dist/src/cli/utils/init-workspace-core.js +2 -2
  239. package/dist/src/config/agent-profile.js +1 -1
  240. package/dist/src/config/agent-typed-models.js +1 -1
  241. package/dist/src/config/gateway-bind.js +1 -1
  242. package/dist/src/config/index.js +7 -7
  243. package/dist/src/config/loader.js +4 -4
  244. package/dist/src/config/models-json.js +2 -2
  245. package/dist/src/config/paths-state.js +1 -1
  246. package/dist/src/config/paths.js +1 -1
  247. package/dist/src/config/profile.js +1 -1
  248. package/dist/src/config/reload.js +1 -1
  249. package/dist/src/config/schema.d.ts +0 -2
  250. package/dist/src/config/schema.js +0 -3
  251. package/dist/src/config/schema.js.map +1 -1
  252. package/dist/src/config/web-patch.d.ts +0 -1
  253. package/dist/src/config/web-patch.js +0 -2
  254. package/dist/src/config/web-patch.js.map +1 -1
  255. package/dist/src/config/workspace-path.js +1 -1
  256. package/dist/src/cron/executor.js +102 -71
  257. package/dist/src/cron/executor.js.map +1 -1
  258. package/dist/src/cron/index.d.ts +1 -1
  259. package/dist/src/cron/index.js +3 -3
  260. package/dist/src/cron/run-log-store.d.ts +1 -0
  261. package/dist/src/cron/run-log-store.js +4 -2
  262. package/dist/src/cron/run-log-store.js.map +1 -1
  263. package/dist/src/cron/schedule.d.ts +10 -0
  264. package/dist/src/cron/schedule.js +85 -0
  265. package/dist/src/cron/schedule.js.map +1 -0
  266. package/dist/src/cron/service.d.ts +34 -77
  267. package/dist/src/cron/service.js +327 -264
  268. package/dist/src/cron/service.js.map +1 -1
  269. package/dist/src/cron/types.d.ts +80 -50
  270. package/dist/src/cron/validation.d.ts +358 -90
  271. package/dist/src/cron/validation.js +152 -132
  272. package/dist/src/cron/validation.js.map +1 -1
  273. package/dist/src/cron/workflow-run-completion.js +1 -1
  274. package/dist/src/daemon/constants.js +1 -1
  275. package/dist/src/daemon/install-plan.js +2 -2
  276. package/dist/src/daemon/launchd.js +2 -2
  277. package/dist/src/daemon/schtasks.js +2 -2
  278. package/dist/src/daemon/systemd.js +2 -2
  279. package/dist/src/extensions/bundle-mcp.js +1 -1
  280. package/dist/src/extensions/discover-extensions.js +2 -2
  281. package/dist/src/extensions/health.js +1 -1
  282. package/dist/src/extensions/install.js +2 -2
  283. package/dist/src/extensions/loader.js +2 -2
  284. package/dist/src/extensions/lockfile.js +3 -3
  285. package/dist/src/extensions/security.js +1 -1
  286. package/dist/src/extensions/update.js +2 -2
  287. package/dist/src/gateway/agents-admin.js +2 -2
  288. package/dist/src/gateway/chat-stream/mapper.d.ts +1 -0
  289. package/dist/src/gateway/chat-stream/mapper.js +6 -2
  290. package/dist/src/gateway/chat-stream/mapper.js.map +1 -1
  291. package/dist/src/gateway/chat-stream/protocol.d.ts +2 -0
  292. package/dist/src/gateway/file-path-classifier.js +2 -2
  293. package/dist/src/gateway/hono/lib/config-payload.d.ts +0 -1
  294. package/dist/src/gateway/hono/lib/config-payload.js +1 -1
  295. package/dist/src/gateway/hono/lib/extension-store.js +2 -2
  296. package/dist/src/gateway/hono/lib/static-ui.js +2 -2
  297. package/dist/src/gateway/hono/oauth-async.js +1 -1
  298. package/dist/src/gateway/hono/routes/agents.js +1 -1
  299. package/dist/src/gateway/hono/routes/ai-assist.d.ts +3 -0
  300. package/dist/src/gateway/hono/routes/ai-assist.js +66 -0
  301. package/dist/src/gateway/hono/routes/ai-assist.js.map +1 -0
  302. package/dist/src/gateway/hono/routes/auth-registry-extensions.js +1 -1
  303. package/dist/src/gateway/hono/routes/commands-skills.js +7 -0
  304. package/dist/src/gateway/hono/routes/commands-skills.js.map +1 -1
  305. package/dist/src/gateway/hono/routes/config-patch/misc.js +1 -1
  306. package/dist/src/gateway/hono/routes/cron.js +24 -5
  307. package/dist/src/gateway/hono/routes/cron.js.map +1 -1
  308. package/dist/src/gateway/hono/routes/dreaming.js +1 -1
  309. package/dist/src/gateway/hono/routes/home.js +5 -3
  310. package/dist/src/gateway/hono/routes/home.js.map +1 -1
  311. package/dist/src/gateway/hono/routes/host-fs.js +2 -2
  312. package/dist/src/gateway/hono/routes/lazy-bundles.js +8 -0
  313. package/dist/src/gateway/hono/routes/lazy-bundles.js.map +1 -1
  314. package/dist/src/gateway/hono/routes/models.js +1 -1
  315. package/dist/src/gateway/hono/routes/shares.js +1 -1
  316. package/dist/src/gateway/hono/routes/workflows.js +2 -2
  317. package/dist/src/gateway/hono/routes/workspace.js +2 -2
  318. package/dist/src/gateway/lock.js +3 -3
  319. package/dist/src/gateway/ports.js +1 -1
  320. package/dist/src/gateway/service/agent-runner.js +2 -2
  321. package/dist/src/gateway/service/config-coordinator.js +1 -1
  322. package/dist/src/gateway/service/marketplace-service.d.ts +22 -10
  323. package/dist/src/gateway/service/marketplace-service.js +46 -5
  324. package/dist/src/gateway/service/marketplace-service.js.map +1 -1
  325. package/dist/src/gateway/service.js +11 -5
  326. package/dist/src/gateway/service.js.map +1 -1
  327. package/dist/src/gateway/workspace-fs-file-list.js +1 -1
  328. package/dist/src/goals/goal-notifications.js +1 -1
  329. package/dist/src/goals/goal-workflow-judge.js +3 -3
  330. package/dist/src/i18n/goals-bundle.js +1 -1
  331. package/dist/src/i18n/index.js +1 -1
  332. package/dist/src/i18n/share-tool-bundle.js +2 -2
  333. package/dist/src/infra/brew.js +1 -1
  334. package/dist/src/infra/package-json.js +1 -1
  335. package/dist/src/infra/package-update-steps.js +1 -1
  336. package/dist/src/infra/path-env.js +2 -2
  337. package/dist/src/infra/restart.js +1 -1
  338. package/dist/src/infra/stable-node-path.js +1 -1
  339. package/dist/src/infra/update-check.js +1 -1
  340. package/dist/src/infra/update-global.js +1 -1
  341. package/dist/src/infra/update-lock.js +2 -2
  342. package/dist/src/infra/update-restart.js +1 -1
  343. package/dist/src/infra/update-runner.js +1 -1
  344. package/dist/src/infra/update-startup.js +1 -1
  345. package/dist/src/infra/write-file-atomic.js +2 -2
  346. package/dist/src/media/store.js +1 -1
  347. package/dist/src/notes/agent-context.js +1 -1
  348. package/dist/src/notes/service.js +1 -1
  349. package/dist/src/notes/store.js +2 -2
  350. package/dist/src/project-trust/trust-store.js +2 -2
  351. package/dist/src/providers/auth-runtime/auth-profile-store.js +1 -1
  352. package/dist/src/providers/index.js +1 -1
  353. package/dist/src/providers/model-registry.js +4 -4
  354. package/dist/src/session/init-session-turn.js +2 -2
  355. package/dist/src/session/resolve-session.js +3 -3
  356. package/dist/src/session/session-title.js +2 -2
  357. package/dist/src/session/store-reader.d.ts +5 -0
  358. package/dist/src/session/store-reader.js +1 -0
  359. package/dist/src/session/store.js +1 -1
  360. package/dist/src/share/share-auto.js +2 -2
  361. package/dist/src/share/share-store.js +3 -3
  362. package/dist/src/share/share-thumbnail.js +2 -2
  363. package/dist/src/share/share-zip.js +1 -1
  364. package/dist/src/share/site-share-store.js +3 -3
  365. package/dist/src/share/site-static-serve.js +1 -1
  366. package/dist/src/storage/sqlite/connection.js +1 -1
  367. package/dist/src/storage/sqlite/cron-job-repository.d.ts +6 -0
  368. package/dist/src/storage/sqlite/cron-job-repository.js +70 -0
  369. package/dist/src/storage/sqlite/cron-job-repository.js.map +1 -0
  370. package/dist/src/storage/sqlite/cron-run-repository.js +0 -1
  371. package/dist/src/storage/sqlite/cron-run-repository.js.map +1 -1
  372. package/dist/src/storage/sqlite/index.d.ts +1 -0
  373. package/dist/src/storage/sqlite/index.js +2 -1
  374. package/dist/src/storage/sqlite/memory-index-repository.js +2 -2
  375. package/dist/src/storage/sqlite/migrations/009_cron_jobs.sql +24 -0
  376. package/dist/src/storage/sqlite/migrations/discover.js +1 -1
  377. package/dist/src/storage/sqlite/migrations/runner.d.ts +1 -1
  378. package/dist/src/storage/sqlite/migrations/runner.js +4 -4
  379. package/dist/src/storage/sqlite/migrations/runner.js.map +1 -1
  380. package/dist/src/storage/sqlite/migrations/runner.ts +1 -1
  381. package/dist/src/storage/sqlite/schema.js +2 -2
  382. package/dist/src/storage/sqlite/schema.sql +25 -0
  383. package/dist/src/tui/clipboard-image.js +3 -3
  384. package/dist/src/tui/extension-host/load-extensions.js +1 -1
  385. package/dist/src/tui/theme-manager.js +1 -1
  386. package/dist/src/tui/tui-command-formatters.js +4 -4
  387. package/dist/src/tui/tui-commands.js +2 -2
  388. package/dist/src/tui/tui-keybindings-file.js +1 -1
  389. package/dist/src/tui/tui-scoped-models.js +2 -2
  390. package/dist/src/tui/tui-settings.js +1 -1
  391. package/dist/src/tui/tui-startup-resources.js +1 -1
  392. package/dist/src/tui/tui.js +6 -6
  393. package/dist/src/tunnel/frpc-binary.js +4 -4
  394. package/dist/src/tunnel/frpc-config.js +1 -1
  395. package/dist/src/tunnel/frpc-extract.js +1 -1
  396. package/dist/src/tunnel/tunnel-state.js +1 -1
  397. package/dist/src/utils/logger/audit.js +1 -1
  398. package/dist/src/utils/logger/log-store.js +1 -1
  399. package/dist/src/utils/logger/rotation.js +1 -1
  400. package/dist/src/utils/logger/streams.js +1 -1
  401. package/dist/src/voice/tts/audio.js +1 -1
  402. package/dist/src/voice/tts/providers/edge-speech.js +2 -2
  403. package/dist/src/workflows/draft/workflow-draft-service.js +1 -1
  404. package/dist/src/workflows/engine/projector.js +23 -14
  405. package/dist/src/workflows/engine/projector.js.map +1 -1
  406. package/dist/src/workflows/engine/workflow-engine.d.ts +1 -0
  407. package/dist/src/workflows/engine/workflow-engine.js +36 -0
  408. package/dist/src/workflows/engine/workflow-engine.js.map +1 -1
  409. package/dist/src/workflows/index.js +1 -1
  410. package/dist/src/workflows/service/workflow-run-service.js +2 -2
  411. package/dist/src/workflows/service/workflow-session-bridge.js +2 -2
  412. package/dist/src/workflows/store/event-store.js +1 -1
  413. package/dist/src/workflows/store/run-store.js +1 -1
  414. package/package.json +2 -3
  415. package/dist/gateway/static/root/assets/agent-browser-settings-page-B-0zGjt8.js +0 -6
  416. package/dist/gateway/static/root/assets/agents-DwDnJlXT.js +0 -71
  417. package/dist/gateway/static/root/assets/connectors-settings-DDvHo9in.js +0 -2
  418. package/dist/gateway/static/root/assets/cron-api-Dj_UZKST.js +0 -1
  419. package/dist/gateway/static/root/assets/cron-page-Dv7GII9G.js +0 -1
  420. package/dist/gateway/static/root/assets/cron-schedule-picker-DH10KgD6.js +0 -1
  421. package/dist/gateway/static/root/assets/dreaming-settings-L2rgZDQl.js +0 -1
  422. package/dist/gateway/static/root/assets/extension-settings-page-m_UQYkVc.js +0 -1
  423. package/dist/gateway/static/root/assets/gateway-settings-CS177xni.js +0 -1
  424. package/dist/gateway/static/root/assets/goals-page-C0FujUB5.js +0 -2
  425. package/dist/gateway/static/root/assets/index-COkF54xv.js +0 -121
  426. package/dist/gateway/static/root/assets/index-DIaSNGEO.css +0 -1
  427. package/dist/gateway/static/root/assets/interval-presets-B29Ss_2y.js +0 -2
  428. package/dist/gateway/static/root/assets/messages-Csef1aW7.js +0 -3
  429. package/dist/gateway/static/root/assets/models-hub-panel-DHGiTIvf.js +0 -2
  430. package/dist/gateway/static/root/assets/note-detail-page-BM7zlDiT.js +0 -2
  431. package/dist/gateway/static/root/assets/schedule-field-BPAWui3P.js +0 -1
  432. package/dist/gateway/static/root/assets/schedule-summary-B-hdSRdR.js +0 -1
  433. package/dist/gateway/static/root/assets/settings-advanced-gate-BYS-rpzn.js +0 -1
  434. package/dist/gateway/static/root/assets/settings-form-section-BsrK7TBF.js +0 -1
  435. package/dist/gateway/static/root/assets/setup-status-panel-DJiksNu4.js +0 -1
  436. package/dist/gateway/static/root/assets/skill-reload-api-CU9i0nJV.js +0 -1
  437. package/dist/gateway/static/root/assets/skills-page-ERbdWENm.js +0 -2
  438. package/dist/gateway/static/root/assets/use-agent-defaults-form-D3FGVLZb.js +0 -1
  439. package/dist/gateway/static/root/favicon-16.png +0 -0
  440. package/dist/gateway/static/root/favicon-32.png +0 -0
  441. package/dist/src/cron/persistence.d.ts +0 -62
  442. package/dist/src/cron/persistence.js +0 -188
  443. package/dist/src/cron/persistence.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"mapper.js","names":["message"],"sources":["../../../../src/gateway/chat-stream/mapper.ts"],"sourcesContent":["import type { AgentMessage } from '@earendil-works/pi-agent-core';\n\nimport type { EmbeddedStreamEvent } from '../../agent/embedded/types.js';\nimport type { ChatStreamEvent, ChatStreamStatus } from './protocol.js';\n\nexport type RuntimeStreamEvent = EmbeddedStreamEvent | { type: string; [key: string]: unknown };\n\nexport interface ChatStreamMapperOptions {\n runId: string;\n sessionKey: string;\n channel: string;\n}\n\ntype ToolResultEnvelope = { content?: unknown[]; details?: unknown; text?: string };\n\nexport class ChatStreamMapper {\n private assistantIndex = 0;\n private currentAssistantMessageId: string | undefined;\n private currentAssistantText = '';\n private toolCallToMessageId = new Map<string, string>();\n private started = false;\n private ended = false;\n\n constructor(private readonly opts: ChatStreamMapperOptions) {}\n\n map(input: RuntimeStreamEvent): ChatStreamEvent[] {\n const event = input as { type: string; [key: string]: unknown };\n switch (event.type) {\n case 'agent_start':\n return this.start();\n case 'agent_end':\n return this.end('success');\n case 'message_start':\n return this.mapMessageStart(event.message);\n case 'message_update':\n return this.mapMessageUpdate(event);\n case 'message_end':\n return this.mapMessageEnd(event.message);\n case 'tool_execution_start':\n return this.mapToolStart(event);\n case 'tool_execution_update':\n return this.mapToolUpdate(event);\n case 'tool_execution_end':\n return this.mapToolEnd(event);\n case 'user_message':\n return [this.make('user_message', { message: userMessageFromLegacyEvent(event) })];\n case 'user_transcript':\n return [this.make('user_transcript', { text: String(event.text ?? ''), media: event.media })];\n case 'progress':\n return [this.make('progress', { stage: String(event.stage ?? ''), message: String(event.message ?? '') })];\n case 'compaction':\n return [\n this.make('compaction', {\n status: event.status === 'completed' || event.status === 'skipped' ? event.status : 'started',\n tokensBefore: typeof event.tokensBefore === 'number' ? event.tokensBefore : undefined,\n tokensAfter: typeof event.tokensAfter === 'number' ? event.tokensAfter : undefined,\n summary: typeof event.summary === 'string' ? event.summary : undefined,\n }),\n ];\n case 'tts_audio':\n return [\n this.make('tts_audio', {\n uri: String(event.uri ?? ''),\n mimeType: String(event.mimeType ?? 'audio/mpeg'),\n name: String(event.name ?? 'voice.mp3'),\n }),\n ];\n case 'clarify_request':\n return [\n this.make('clarify_request', {\n requestId: String(event.requestId ?? ''),\n question: String(event.question ?? ''),\n choices: Array.isArray(event.choices) ? event.choices.filter((x): x is string => typeof x === 'string') : undefined,\n default: typeof event.default === 'string' ? event.default : undefined,\n }),\n ];\n case 'error':\n return [this.make('error', { code: 'AGENT_RUN_ERROR', message: String(event.content ?? event.message ?? 'Unknown error') })];\n default:\n return [];\n }\n }\n\n start(): ChatStreamEvent[] {\n if (this.started) return [];\n this.started = true;\n return [this.make('run_start', { channel: this.opts.channel })];\n }\n\n end(status: ChatStreamStatus, summary?: string): ChatStreamEvent[] {\n if (this.ended) return [];\n this.ended = true;\n return [this.make('run_end', { status, summary })];\n }\n\n error(message: string, code = 'AGENT_RUN_ERROR'): ChatStreamEvent[] {\n return [this.make('error', { code, message })];\n }\n\n private mapMessageStart(raw: unknown): ChatStreamEvent[] {\n const message = raw as AgentMessage | undefined;\n if (message?.role !== 'assistant') return [];\n const messageId = this.nextAssistantMessageId();\n this.currentAssistantMessageId = messageId;\n this.currentAssistantText = '';\n return [this.make('assistant_message_start', { messageId })];\n }\n\n private mapMessageUpdate(event: { [key: string]: unknown }): ChatStreamEvent[] {\n const message = event.message as AgentMessage | undefined;\n if (message?.role !== 'assistant') return [];\n const messageId = this.ensureAssistantMessageId();\n const delta = event.assistantMessageEvent as { type?: unknown; delta?: unknown } | undefined;\n if (delta?.type === 'text_delta' && typeof delta.delta === 'string' && delta.delta) {\n this.currentAssistantText += delta.delta;\n return [this.make('assistant_delta', { messageId, delta: delta.delta })];\n }\n if (delta?.type === 'thinking_delta' && typeof delta.delta === 'string' && delta.delta) {\n return [this.make('thinking_delta', { messageId, delta: delta.delta })];\n }\n\n const text = extractTextFromMessage(message);\n const suffix = appendSuffix(this.currentAssistantText, text);\n this.currentAssistantText = text || this.currentAssistantText;\n return suffix ? [this.make('assistant_delta', { messageId, delta: suffix })] : [];\n }\n\n private mapMessageEnd(raw: unknown): ChatStreamEvent[] {\n const message = raw as AgentMessage | undefined;\n if (message?.role !== 'assistant') return [];\n const messageId = this.ensureAssistantMessageId();\n const events: ChatStreamEvent[] = [];\n const text = extractTextFromMessage(message);\n const suffix = appendSuffix(this.currentAssistantText, text);\n if (suffix) events.push(this.make('assistant_delta', { messageId, delta: suffix }));\n this.currentAssistantText = text || this.currentAssistantText;\n events.push(this.make('thinking_end', { messageId }));\n events.push(this.make('assistant_message_end', { messageId, usage: extractUsage(message) }));\n this.currentAssistantMessageId = undefined;\n this.currentAssistantText = '';\n return events;\n }\n\n private mapToolStart(event: { [key: string]: unknown }): ChatStreamEvent[] {\n const toolCallId = String(event.toolCallId ?? '');\n if (!toolCallId) return [];\n const messageId = this.ensureAssistantMessageId();\n this.toolCallToMessageId.set(toolCallId, messageId);\n return [\n this.make('tool_start', {\n messageId,\n toolCallId,\n toolName: String(event.toolName ?? 'unknown'),\n args: event.args,\n }),\n ];\n }\n\n private mapToolUpdate(event: { [key: string]: unknown }): ChatStreamEvent[] {\n const toolCallId = String(event.toolCallId ?? '');\n if (!toolCallId) return [];\n const messageId = this.toolCallToMessageId.get(toolCallId) ?? this.ensureAssistantMessageId();\n const partial = event.partialResult;\n const details = extractDetails(partial);\n const textDelta = extractText(partial);\n return [\n this.make('tool_update', {\n messageId,\n toolCallId,\n toolName: String(event.toolName ?? 'unknown'),\n details,\n textDelta,\n }),\n ];\n }\n\n private mapToolEnd(event: { [key: string]: unknown }): ChatStreamEvent[] {\n const toolCallId = String(event.toolCallId ?? '');\n if (!toolCallId) return [];\n const messageId = this.toolCallToMessageId.get(toolCallId) ?? this.ensureAssistantMessageId();\n const result = normalizeToolResult(event.result);\n return [\n this.make('tool_end', {\n messageId,\n toolCallId,\n toolName: String(event.toolName ?? 'unknown'),\n status: event.isError ? 'error' : 'success',\n result,\n errorMessage: event.isError ? result?.text : undefined,\n }),\n ];\n }\n\n private ensureAssistantMessageId(): string {\n if (!this.currentAssistantMessageId) {\n this.currentAssistantMessageId = this.nextAssistantMessageId();\n }\n return this.currentAssistantMessageId;\n }\n\n private nextAssistantMessageId(): string {\n this.assistantIndex += 1;\n return `msg_${this.opts.runId.replace(/[^a-zA-Z0-9_-]/g, '_')}_${this.assistantIndex}`;\n }\n\n private make<T extends ChatStreamEvent['type']>(\n type: T,\n payload: Extract<ChatStreamEvent, { type: T }>['payload'],\n ): Extract<ChatStreamEvent, { type: T }> {\n return {\n type,\n runId: this.opts.runId,\n sessionKey: this.opts.sessionKey,\n timestamp: Date.now(),\n payload,\n } as Extract<ChatStreamEvent, { type: T }>;\n }\n}\n\nfunction userMessageFromLegacyEvent(event: { [key: string]: unknown }): unknown {\n return {\n role: 'user',\n content: event.content ?? [],\n attachments: event.media,\n timestamp: typeof event.timestamp === 'number' ? event.timestamp : Date.now(),\n };\n}\n\nfunction extractTextFromMessage(message: AgentMessage): string {\n return extractText((message as { content?: unknown }).content);\n}\n\nfunction extractText(value: unknown): string | undefined {\n if (typeof value === 'string') return value;\n if (!Array.isArray(value)) return undefined;\n const text = value\n .map((block) => {\n if (!block || typeof block !== 'object') return '';\n const rec = block as { type?: unknown; text?: unknown };\n return rec.type === 'text' && typeof rec.text === 'string' ? rec.text : '';\n })\n .join('');\n return text || undefined;\n}\n\nfunction appendSuffix(base: string, next: string | undefined): string {\n if (!next) return '';\n if (!base) return next;\n if (next === base || base.endsWith(next)) return '';\n if (next.startsWith(base)) return next.slice(base.length);\n const max = Math.min(base.length, next.length, 512);\n for (let overlap = max; overlap > 0; overlap--) {\n if (base.slice(-overlap) === next.slice(0, overlap)) return next.slice(overlap);\n }\n return next;\n}\n\nfunction extractUsage(message: AgentMessage): AssistantMessageEndEventPayload['usage'] {\n const usage = (message as { usage?: unknown }).usage;\n if (!usage || typeof usage !== 'object') return undefined;\n const rec = usage as Record<string, unknown>;\n return {\n inputTokens: typeof rec.inputTokens === 'number' ? rec.inputTokens : undefined,\n outputTokens: typeof rec.outputTokens === 'number' ? rec.outputTokens : undefined,\n totalTokens: typeof rec.totalTokens === 'number' ? rec.totalTokens : undefined,\n cost: typeof rec.cost === 'number' ? rec.cost : undefined,\n };\n}\n\ntype AssistantMessageEndEventPayload = Extract<ChatStreamEvent, { type: 'assistant_message_end' }>['payload'];\n\nfunction extractDetails(value: unknown): unknown {\n if (!value || typeof value !== 'object') return undefined;\n return (value as Record<string, unknown>).details;\n}\n\nfunction normalizeToolResult(value: unknown): ToolResultEnvelope | undefined {\n if (value == null) return undefined;\n if (typeof value === 'string') return { text: value };\n if (typeof value !== 'object') return { text: String(value) };\n const rec = value as Record<string, unknown>;\n return {\n content: Array.isArray(rec.content) ? rec.content : undefined,\n details: rec.details,\n text: extractText(rec.content) ?? (typeof rec.text === 'string' ? rec.text : undefined),\n };\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"mapper.js","names":["message"],"sources":["../../../../src/gateway/chat-stream/mapper.ts"],"sourcesContent":["import type { AgentMessage } from '@earendil-works/pi-agent-core';\n\nimport type { EmbeddedStreamEvent } from '../../agent/embedded/types.js';\nimport type { ChatStreamEvent, ChatStreamStatus } from './protocol.js';\n\nexport type RuntimeStreamEvent = EmbeddedStreamEvent | { type: string; [key: string]: unknown };\n\nexport interface ChatStreamMapperOptions {\n runId: string;\n sessionKey: string;\n channel: string;\n}\n\ntype ToolResultEnvelope = { content?: unknown[]; details?: unknown; text?: string };\n\nexport class ChatStreamMapper {\n private assistantIndex = 0;\n private currentAssistantMessageId: string | undefined;\n private lastAssistantMessageId: string | undefined;\n private currentAssistantText = '';\n private toolCallToMessageId = new Map<string, string>();\n private started = false;\n private ended = false;\n\n constructor(private readonly opts: ChatStreamMapperOptions) {}\n\n map(input: RuntimeStreamEvent): ChatStreamEvent[] {\n const event = input as { type: string; [key: string]: unknown };\n switch (event.type) {\n case 'agent_start':\n return this.start();\n case 'agent_end':\n return [];\n case 'message_start':\n return this.mapMessageStart(event.message);\n case 'message_update':\n return this.mapMessageUpdate(event);\n case 'message_end':\n return this.mapMessageEnd(event.message);\n case 'tool_execution_start':\n return this.mapToolStart(event);\n case 'tool_execution_update':\n return this.mapToolUpdate(event);\n case 'tool_execution_end':\n return this.mapToolEnd(event);\n case 'user_message':\n return [this.make('user_message', { message: userMessageFromLegacyEvent(event) })];\n case 'user_transcript':\n return [this.make('user_transcript', { text: String(event.text ?? ''), media: event.media })];\n case 'progress':\n return [this.make('progress', { stage: String(event.stage ?? ''), message: String(event.message ?? '') })];\n case 'compaction':\n return [\n this.make('compaction', {\n status: event.status === 'completed' || event.status === 'skipped' ? event.status : 'started',\n tokensBefore: typeof event.tokensBefore === 'number' ? event.tokensBefore : undefined,\n tokensAfter: typeof event.tokensAfter === 'number' ? event.tokensAfter : undefined,\n summary: typeof event.summary === 'string' ? event.summary : undefined,\n }),\n ];\n case 'tts_audio':\n return [\n this.make('tts_audio', {\n uri: String(event.uri ?? ''),\n mimeType: String(event.mimeType ?? 'audio/mpeg'),\n name: String(event.name ?? 'voice.mp3'),\n attachTo: 'last_assistant',\n ...(this.lastAssistantMessageId ? { messageId: this.lastAssistantMessageId } : {}),\n }),\n ];\n case 'clarify_request':\n return [\n this.make('clarify_request', {\n requestId: String(event.requestId ?? ''),\n question: String(event.question ?? ''),\n choices: Array.isArray(event.choices) ? event.choices.filter((x): x is string => typeof x === 'string') : undefined,\n default: typeof event.default === 'string' ? event.default : undefined,\n }),\n ];\n case 'error':\n return [this.make('error', { code: 'AGENT_RUN_ERROR', message: String(event.content ?? event.message ?? 'Unknown error') })];\n default:\n return [];\n }\n }\n\n start(): ChatStreamEvent[] {\n if (this.started) return [];\n this.started = true;\n return [this.make('run_start', { channel: this.opts.channel })];\n }\n\n end(status: ChatStreamStatus, summary?: string): ChatStreamEvent[] {\n if (this.ended) return [];\n this.ended = true;\n return [this.make('run_end', { status, summary })];\n }\n\n error(message: string, code = 'AGENT_RUN_ERROR'): ChatStreamEvent[] {\n return [this.make('error', { code, message })];\n }\n\n private mapMessageStart(raw: unknown): ChatStreamEvent[] {\n const message = raw as AgentMessage | undefined;\n if (message?.role !== 'assistant') return [];\n const messageId = this.nextAssistantMessageId();\n this.currentAssistantMessageId = messageId;\n this.currentAssistantText = '';\n return [this.make('assistant_message_start', { messageId })];\n }\n\n private mapMessageUpdate(event: { [key: string]: unknown }): ChatStreamEvent[] {\n const message = event.message as AgentMessage | undefined;\n if (message?.role !== 'assistant') return [];\n const messageId = this.ensureAssistantMessageId();\n const delta = event.assistantMessageEvent as { type?: unknown; delta?: unknown } | undefined;\n if (delta?.type === 'text_delta' && typeof delta.delta === 'string' && delta.delta) {\n this.currentAssistantText += delta.delta;\n return [this.make('assistant_delta', { messageId, delta: delta.delta })];\n }\n if (delta?.type === 'thinking_delta' && typeof delta.delta === 'string' && delta.delta) {\n return [this.make('thinking_delta', { messageId, delta: delta.delta })];\n }\n\n const text = extractTextFromMessage(message);\n const suffix = appendSuffix(this.currentAssistantText, text);\n this.currentAssistantText = text || this.currentAssistantText;\n return suffix ? [this.make('assistant_delta', { messageId, delta: suffix })] : [];\n }\n\n private mapMessageEnd(raw: unknown): ChatStreamEvent[] {\n const message = raw as AgentMessage | undefined;\n if (message?.role !== 'assistant') return [];\n const messageId = this.ensureAssistantMessageId();\n const events: ChatStreamEvent[] = [];\n const text = extractTextFromMessage(message);\n const suffix = appendSuffix(this.currentAssistantText, text);\n if (suffix) events.push(this.make('assistant_delta', { messageId, delta: suffix }));\n this.currentAssistantText = text || this.currentAssistantText;\n events.push(this.make('thinking_end', { messageId }));\n events.push(this.make('assistant_message_end', { messageId, usage: extractUsage(message) }));\n this.lastAssistantMessageId = messageId;\n this.currentAssistantMessageId = undefined;\n this.currentAssistantText = '';\n return events;\n }\n\n private mapToolStart(event: { [key: string]: unknown }): ChatStreamEvent[] {\n const toolCallId = String(event.toolCallId ?? '');\n if (!toolCallId) return [];\n const messageId = this.ensureAssistantMessageId();\n this.toolCallToMessageId.set(toolCallId, messageId);\n return [\n this.make('tool_start', {\n messageId,\n toolCallId,\n toolName: String(event.toolName ?? 'unknown'),\n args: event.args,\n }),\n ];\n }\n\n private mapToolUpdate(event: { [key: string]: unknown }): ChatStreamEvent[] {\n const toolCallId = String(event.toolCallId ?? '');\n if (!toolCallId) return [];\n const messageId = this.toolCallToMessageId.get(toolCallId) ?? this.ensureAssistantMessageId();\n const partial = event.partialResult;\n const details = extractDetails(partial);\n const textDelta = extractText(partial);\n return [\n this.make('tool_update', {\n messageId,\n toolCallId,\n toolName: String(event.toolName ?? 'unknown'),\n details,\n textDelta,\n }),\n ];\n }\n\n private mapToolEnd(event: { [key: string]: unknown }): ChatStreamEvent[] {\n const toolCallId = String(event.toolCallId ?? '');\n if (!toolCallId) return [];\n const messageId = this.toolCallToMessageId.get(toolCallId) ?? this.ensureAssistantMessageId();\n const result = normalizeToolResult(event.result);\n return [\n this.make('tool_end', {\n messageId,\n toolCallId,\n toolName: String(event.toolName ?? 'unknown'),\n status: event.isError ? 'error' : 'success',\n result,\n errorMessage: event.isError ? result?.text : undefined,\n }),\n ];\n }\n\n private ensureAssistantMessageId(): string {\n if (!this.currentAssistantMessageId) {\n this.currentAssistantMessageId = this.nextAssistantMessageId();\n }\n return this.currentAssistantMessageId;\n }\n\n private nextAssistantMessageId(): string {\n this.assistantIndex += 1;\n return `msg_${this.opts.runId.replace(/[^a-zA-Z0-9_-]/g, '_')}_${this.assistantIndex}`;\n }\n\n private make<T extends ChatStreamEvent['type']>(\n type: T,\n payload: Extract<ChatStreamEvent, { type: T }>['payload'],\n ): Extract<ChatStreamEvent, { type: T }> {\n return {\n type,\n runId: this.opts.runId,\n sessionKey: this.opts.sessionKey,\n timestamp: Date.now(),\n payload,\n } as Extract<ChatStreamEvent, { type: T }>;\n }\n}\n\nfunction userMessageFromLegacyEvent(event: { [key: string]: unknown }): unknown {\n return {\n role: 'user',\n content: event.content ?? [],\n attachments: event.media,\n timestamp: typeof event.timestamp === 'number' ? event.timestamp : Date.now(),\n };\n}\n\nfunction extractTextFromMessage(message: AgentMessage): string {\n return extractText((message as { content?: unknown }).content);\n}\n\nfunction extractText(value: unknown): string | undefined {\n if (typeof value === 'string') return value;\n if (!Array.isArray(value)) return undefined;\n const text = value\n .map((block) => {\n if (!block || typeof block !== 'object') return '';\n const rec = block as { type?: unknown; text?: unknown };\n return rec.type === 'text' && typeof rec.text === 'string' ? rec.text : '';\n })\n .join('');\n return text || undefined;\n}\n\nfunction appendSuffix(base: string, next: string | undefined): string {\n if (!next) return '';\n if (!base) return next;\n if (next === base || base.endsWith(next)) return '';\n if (next.startsWith(base)) return next.slice(base.length);\n const max = Math.min(base.length, next.length, 512);\n for (let overlap = max; overlap > 0; overlap--) {\n if (base.slice(-overlap) === next.slice(0, overlap)) return next.slice(overlap);\n }\n return next;\n}\n\nfunction extractUsage(message: AgentMessage): AssistantMessageEndEventPayload['usage'] {\n const usage = (message as { usage?: unknown }).usage;\n if (!usage || typeof usage !== 'object') return undefined;\n const rec = usage as Record<string, unknown>;\n return {\n inputTokens: typeof rec.inputTokens === 'number' ? rec.inputTokens : undefined,\n outputTokens: typeof rec.outputTokens === 'number' ? rec.outputTokens : undefined,\n totalTokens: typeof rec.totalTokens === 'number' ? rec.totalTokens : undefined,\n cost: typeof rec.cost === 'number' ? rec.cost : undefined,\n };\n}\n\ntype AssistantMessageEndEventPayload = Extract<ChatStreamEvent, { type: 'assistant_message_end' }>['payload'];\n\nfunction extractDetails(value: unknown): unknown {\n if (!value || typeof value !== 'object') return undefined;\n return (value as Record<string, unknown>).details;\n}\n\nfunction normalizeToolResult(value: unknown): ToolResultEnvelope | undefined {\n if (value == null) return undefined;\n if (typeof value === 'string') return { text: value };\n if (typeof value !== 'object') return { text: String(value) };\n const rec = value as Record<string, unknown>;\n return {\n content: Array.isArray(rec.content) ? rec.content : undefined,\n details: rec.details,\n text: extractText(rec.content) ?? (typeof rec.text === 'string' ? rec.text : undefined),\n };\n}\n"],"mappings":";AAeA,IAAa,mBAAb,MAA8B;CAC5B,iBAAyB;CACzB;CACA;CACA,uBAA+B;CAC/B,sCAA8B,IAAI,KAAqB;CACvD,UAAkB;CAClB,QAAgB;CAEhB,YAAY,MAAgD;AAA/B,OAAA,OAAA;;CAE7B,IAAI,OAA8C;EAChD,MAAM,QAAQ;AACd,UAAQ,MAAM,MAAd;GACE,KAAK,cACH,QAAO,KAAK,OAAO;GACrB,KAAK,YACH,QAAO,EAAE;GACX,KAAK,gBACH,QAAO,KAAK,gBAAgB,MAAM,QAAQ;GAC5C,KAAK,iBACH,QAAO,KAAK,iBAAiB,MAAM;GACrC,KAAK,cACH,QAAO,KAAK,cAAc,MAAM,QAAQ;GAC1C,KAAK,uBACH,QAAO,KAAK,aAAa,MAAM;GACjC,KAAK,wBACH,QAAO,KAAK,cAAc,MAAM;GAClC,KAAK,qBACH,QAAO,KAAK,WAAW,MAAM;GAC/B,KAAK,eACH,QAAO,CAAC,KAAK,KAAK,gBAAgB,EAAE,SAAS,2BAA2B,MAAM,EAAE,CAAC,CAAC;GACpF,KAAK,kBACH,QAAO,CAAC,KAAK,KAAK,mBAAmB;IAAE,MAAM,OAAO,MAAM,QAAQ,GAAG;IAAE,OAAO,MAAM;IAAO,CAAC,CAAC;GAC/F,KAAK,WACH,QAAO,CAAC,KAAK,KAAK,YAAY;IAAE,OAAO,OAAO,MAAM,SAAS,GAAG;IAAE,SAAS,OAAO,MAAM,WAAW,GAAG;IAAE,CAAC,CAAC;GAC5G,KAAK,aACH,QAAO,CACL,KAAK,KAAK,cAAc;IACtB,QAAQ,MAAM,WAAW,eAAe,MAAM,WAAW,YAAY,MAAM,SAAS;IACpF,cAAc,OAAO,MAAM,iBAAiB,WAAW,MAAM,eAAe,KAAA;IAC5E,aAAa,OAAO,MAAM,gBAAgB,WAAW,MAAM,cAAc,KAAA;IACzE,SAAS,OAAO,MAAM,YAAY,WAAW,MAAM,UAAU,KAAA;IAC9D,CAAC,CACH;GACH,KAAK,YACH,QAAO,CACL,KAAK,KAAK,aAAa;IACrB,KAAK,OAAO,MAAM,OAAO,GAAG;IAC5B,UAAU,OAAO,MAAM,YAAY,aAAa;IAChD,MAAM,OAAO,MAAM,QAAQ,YAAY;IACvC,UAAU;IACV,GAAI,KAAK,yBAAyB,EAAE,WAAW,KAAK,wBAAwB,GAAG,EAAE;IAClF,CAAC,CACH;GACH,KAAK,kBACH,QAAO,CACL,KAAK,KAAK,mBAAmB;IAC3B,WAAW,OAAO,MAAM,aAAa,GAAG;IACxC,UAAU,OAAO,MAAM,YAAY,GAAG;IACtC,SAAS,MAAM,QAAQ,MAAM,QAAQ,GAAG,MAAM,QAAQ,QAAQ,MAAmB,OAAO,MAAM,SAAS,GAAG,KAAA;IAC1G,SAAS,OAAO,MAAM,YAAY,WAAW,MAAM,UAAU,KAAA;IAC9D,CAAC,CACH;GACH,KAAK,QACH,QAAO,CAAC,KAAK,KAAK,SAAS;IAAE,MAAM;IAAmB,SAAS,OAAO,MAAM,WAAW,MAAM,WAAW,gBAAgB;IAAE,CAAC,CAAC;GAC9H,QACE,QAAO,EAAE;;;CAIf,QAA2B;AACzB,MAAI,KAAK,QAAS,QAAO,EAAE;AAC3B,OAAK,UAAU;AACf,SAAO,CAAC,KAAK,KAAK,aAAa,EAAE,SAAS,KAAK,KAAK,SAAS,CAAC,CAAC;;CAGjE,IAAI,QAA0B,SAAqC;AACjE,MAAI,KAAK,MAAO,QAAO,EAAE;AACzB,OAAK,QAAQ;AACb,SAAO,CAAC,KAAK,KAAK,WAAW;GAAE;GAAQ;GAAS,CAAC,CAAC;;CAGpD,MAAM,SAAiB,OAAO,mBAAsC;AAClE,SAAO,CAAC,KAAK,KAAK,SAAS;GAAE;GAAM;GAAS,CAAC,CAAC;;CAGhD,gBAAwB,KAAiC;AAEvD,MAAIA,KAAS,SAAS,YAAa,QAAO,EAAE;EAC5C,MAAM,YAAY,KAAK,wBAAwB;AAC/C,OAAK,4BAA4B;AACjC,OAAK,uBAAuB;AAC5B,SAAO,CAAC,KAAK,KAAK,2BAA2B,EAAE,WAAW,CAAC,CAAC;;CAG9D,iBAAyB,OAAsD;EAC7E,MAAM,UAAU,MAAM;AACtB,MAAI,SAAS,SAAS,YAAa,QAAO,EAAE;EAC5C,MAAM,YAAY,KAAK,0BAA0B;EACjD,MAAM,QAAQ,MAAM;AACpB,MAAI,OAAO,SAAS,gBAAgB,OAAO,MAAM,UAAU,YAAY,MAAM,OAAO;AAClF,QAAK,wBAAwB,MAAM;AACnC,UAAO,CAAC,KAAK,KAAK,mBAAmB;IAAE;IAAW,OAAO,MAAM;IAAO,CAAC,CAAC;;AAE1E,MAAI,OAAO,SAAS,oBAAoB,OAAO,MAAM,UAAU,YAAY,MAAM,MAC/E,QAAO,CAAC,KAAK,KAAK,kBAAkB;GAAE;GAAW,OAAO,MAAM;GAAO,CAAC,CAAC;EAGzE,MAAM,OAAO,uBAAuB,QAAQ;EAC5C,MAAM,SAAS,aAAa,KAAK,sBAAsB,KAAK;AAC5D,OAAK,uBAAuB,QAAQ,KAAK;AACzC,SAAO,SAAS,CAAC,KAAK,KAAK,mBAAmB;GAAE;GAAW,OAAO;GAAQ,CAAC,CAAC,GAAG,EAAE;;CAGnF,cAAsB,KAAiC;EACrD,MAAM,UAAU;AAChB,MAAI,SAAS,SAAS,YAAa,QAAO,EAAE;EAC5C,MAAM,YAAY,KAAK,0BAA0B;EACjD,MAAM,SAA4B,EAAE;EACpC,MAAM,OAAO,uBAAuB,QAAQ;EAC5C,MAAM,SAAS,aAAa,KAAK,sBAAsB,KAAK;AAC5D,MAAI,OAAQ,QAAO,KAAK,KAAK,KAAK,mBAAmB;GAAE;GAAW,OAAO;GAAQ,CAAC,CAAC;AACnF,OAAK,uBAAuB,QAAQ,KAAK;AACzC,SAAO,KAAK,KAAK,KAAK,gBAAgB,EAAE,WAAW,CAAC,CAAC;AACrD,SAAO,KAAK,KAAK,KAAK,yBAAyB;GAAE;GAAW,OAAO,aAAa,QAAQ;GAAE,CAAC,CAAC;AAC5F,OAAK,yBAAyB;AAC9B,OAAK,4BAA4B,KAAA;AACjC,OAAK,uBAAuB;AAC5B,SAAO;;CAGT,aAAqB,OAAsD;EACzE,MAAM,aAAa,OAAO,MAAM,cAAc,GAAG;AACjD,MAAI,CAAC,WAAY,QAAO,EAAE;EAC1B,MAAM,YAAY,KAAK,0BAA0B;AACjD,OAAK,oBAAoB,IAAI,YAAY,UAAU;AACnD,SAAO,CACL,KAAK,KAAK,cAAc;GACtB;GACA;GACA,UAAU,OAAO,MAAM,YAAY,UAAU;GAC7C,MAAM,MAAM;GACb,CAAC,CACH;;CAGH,cAAsB,OAAsD;EAC1E,MAAM,aAAa,OAAO,MAAM,cAAc,GAAG;AACjD,MAAI,CAAC,WAAY,QAAO,EAAE;EAC1B,MAAM,YAAY,KAAK,oBAAoB,IAAI,WAAW,IAAI,KAAK,0BAA0B;EAC7F,MAAM,UAAU,MAAM;EACtB,MAAM,UAAU,eAAe,QAAQ;EACvC,MAAM,YAAY,YAAY,QAAQ;AACtC,SAAO,CACL,KAAK,KAAK,eAAe;GACvB;GACA;GACA,UAAU,OAAO,MAAM,YAAY,UAAU;GAC7C;GACA;GACD,CAAC,CACH;;CAGH,WAAmB,OAAsD;EACvE,MAAM,aAAa,OAAO,MAAM,cAAc,GAAG;AACjD,MAAI,CAAC,WAAY,QAAO,EAAE;EAC1B,MAAM,YAAY,KAAK,oBAAoB,IAAI,WAAW,IAAI,KAAK,0BAA0B;EAC7F,MAAM,SAAS,oBAAoB,MAAM,OAAO;AAChD,SAAO,CACL,KAAK,KAAK,YAAY;GACpB;GACA;GACA,UAAU,OAAO,MAAM,YAAY,UAAU;GAC7C,QAAQ,MAAM,UAAU,UAAU;GAClC;GACA,cAAc,MAAM,UAAU,QAAQ,OAAO,KAAA;GAC9C,CAAC,CACH;;CAGH,2BAA2C;AACzC,MAAI,CAAC,KAAK,0BACR,MAAK,4BAA4B,KAAK,wBAAwB;AAEhE,SAAO,KAAK;;CAGd,yBAAyC;AACvC,OAAK,kBAAkB;AACvB,SAAO,OAAO,KAAK,KAAK,MAAM,QAAQ,mBAAmB,IAAI,CAAC,GAAG,KAAK;;CAGxE,KACE,MACA,SACuC;AACvC,SAAO;GACL;GACA,OAAO,KAAK,KAAK;GACjB,YAAY,KAAK,KAAK;GACtB,WAAW,KAAK,KAAK;GACrB;GACD;;;AAIL,SAAS,2BAA2B,OAA4C;AAC9E,QAAO;EACL,MAAM;EACN,SAAS,MAAM,WAAW,EAAE;EAC5B,aAAa,MAAM;EACnB,WAAW,OAAO,MAAM,cAAc,WAAW,MAAM,YAAY,KAAK,KAAK;EAC9E;;AAGH,SAAS,uBAAuB,SAA+B;AAC7D,QAAO,YAAa,QAAkC,QAAQ;;AAGhE,SAAS,YAAY,OAAoC;AACvD,KAAI,OAAO,UAAU,SAAU,QAAO;AACtC,KAAI,CAAC,MAAM,QAAQ,MAAM,CAAE,QAAO,KAAA;AAQlC,QAPa,MACV,KAAK,UAAU;AACd,MAAI,CAAC,SAAS,OAAO,UAAU,SAAU,QAAO;EAChD,MAAM,MAAM;AACZ,SAAO,IAAI,SAAS,UAAU,OAAO,IAAI,SAAS,WAAW,IAAI,OAAO;GACxE,CACD,KAAK,GACG,IAAI,KAAA;;AAGjB,SAAS,aAAa,MAAc,MAAkC;AACpE,KAAI,CAAC,KAAM,QAAO;AAClB,KAAI,CAAC,KAAM,QAAO;AAClB,KAAI,SAAS,QAAQ,KAAK,SAAS,KAAK,CAAE,QAAO;AACjD,KAAI,KAAK,WAAW,KAAK,CAAE,QAAO,KAAK,MAAM,KAAK,OAAO;CACzD,MAAM,MAAM,KAAK,IAAI,KAAK,QAAQ,KAAK,QAAQ,IAAI;AACnD,MAAK,IAAI,UAAU,KAAK,UAAU,GAAG,UACnC,KAAI,KAAK,MAAM,CAAC,QAAQ,KAAK,KAAK,MAAM,GAAG,QAAQ,CAAE,QAAO,KAAK,MAAM,QAAQ;AAEjF,QAAO;;AAGT,SAAS,aAAa,SAAiE;CACrF,MAAM,QAAS,QAAgC;AAC/C,KAAI,CAAC,SAAS,OAAO,UAAU,SAAU,QAAO,KAAA;CAChD,MAAM,MAAM;AACZ,QAAO;EACL,aAAa,OAAO,IAAI,gBAAgB,WAAW,IAAI,cAAc,KAAA;EACrE,cAAc,OAAO,IAAI,iBAAiB,WAAW,IAAI,eAAe,KAAA;EACxE,aAAa,OAAO,IAAI,gBAAgB,WAAW,IAAI,cAAc,KAAA;EACrE,MAAM,OAAO,IAAI,SAAS,WAAW,IAAI,OAAO,KAAA;EACjD;;AAKH,SAAS,eAAe,OAAyB;AAC/C,KAAI,CAAC,SAAS,OAAO,UAAU,SAAU,QAAO,KAAA;AAChD,QAAQ,MAAkC;;AAG5C,SAAS,oBAAoB,OAAgD;AAC3E,KAAI,SAAS,KAAM,QAAO,KAAA;AAC1B,KAAI,OAAO,UAAU,SAAU,QAAO,EAAE,MAAM,OAAO;AACrD,KAAI,OAAO,UAAU,SAAU,QAAO,EAAE,MAAM,OAAO,MAAM,EAAE;CAC7D,MAAM,MAAM;AACZ,QAAO;EACL,SAAS,MAAM,QAAQ,IAAI,QAAQ,GAAG,IAAI,UAAU,KAAA;EACpD,SAAS,IAAI;EACb,MAAM,YAAY,IAAI,QAAQ,KAAK,OAAO,IAAI,SAAS,WAAW,IAAI,OAAO,KAAA;EAC9E"}
@@ -81,6 +81,8 @@ export type TtsAudioEvent = ChatStreamEnvelope<'tts_audio', {
81
81
  uri: string;
82
82
  mimeType: string;
83
83
  name: string;
84
+ attachTo?: 'last_assistant';
85
+ messageId?: string;
84
86
  }>;
85
87
  export type ClarifyRequestEvent = ChatStreamEnvelope<'clarify_request', {
86
88
  requestId: string;
@@ -1,11 +1,11 @@
1
1
  import { init_paths_state, resolveStateDir } from "../config/paths-state.js";
2
2
  import { init_agent_scope, resolveAgentProfileDir } from "../agent/agent-scope.js";
3
- import { extractProfileAgentId } from "../config/agent-profile.js";
4
3
  import { init_paths, resolveConfigPath, resolveSkillsDir } from "../config/paths.js";
4
+ import { extractProfileAgentId } from "../config/agent-profile.js";
5
5
  import { isBareProfileMarkdownFileName, resolveProfileMarkdownPathIfBareName } from "../agent/tools/tool-paths.js";
6
6
  import { isPathUnderWorkspace, resolveWorkspaceSafePath } from "./workspace-editor-path.js";
7
- import { basename, isAbsolute, resolve } from "node:path";
8
7
  import { stat } from "node:fs/promises";
8
+ import { basename, isAbsolute, resolve } from "node:path";
9
9
  //#region src/gateway/file-path-classifier.ts
10
10
  init_agent_scope();
11
11
  init_paths();
@@ -260,7 +260,6 @@ export declare function buildSafeWebConfigPayload(service: GatewayService, optio
260
260
  cron: {
261
261
  enabled: boolean;
262
262
  maxConcurrentJobs: number;
263
- defaultTimezone: string;
264
263
  historyRetentionDays: number;
265
264
  enableMetrics: boolean;
266
265
  };
@@ -1,8 +1,8 @@
1
1
  import { init_agent_scope, listAgentEntries, normalizeAgentId, resolveDefaultAgentId } from "../../../agent/agent-scope.js";
2
2
  import { resolveModelsJsonPath } from "../../../config/paths.js";
3
- import { buildChannelCatalogForConfig, buildChannelCatalogFromSnapshot, init_channel_catalog_service, isChannelConfigured } from "../../../channels/catalog/channel-catalog-service.js";
4
3
  import { init_models_json, loadModelsJson } from "../../../config/models-json.js";
5
4
  import { CredentialResolver, init_credentials } from "../../../auth/credentials.js";
5
+ import { buildChannelCatalogForConfig, buildChannelCatalogFromSnapshot, init_channel_catalog_service, isChannelConfigured } from "../../../channels/catalog/channel-catalog-service.js";
6
6
  import { getProviderRegistry, init_plugin_registry } from "../../../providers/plugin-registry.js";
7
7
  import { getAllProviders, init_providers, isProviderConfigured } from "../../../providers/index.js";
8
8
  import { resolveShareConfig } from "../../../share/share-config.js";
@@ -1,7 +1,7 @@
1
1
  import { init_write_file_atomic, writeTextAtomic } from "../../../infra/write-file-atomic.js";
2
- import { homedir } from "node:os";
3
- import { join } from "node:path";
4
2
  import { readFile } from "node:fs/promises";
3
+ import { join } from "node:path";
4
+ import { homedir } from "node:os";
5
5
  //#region src/gateway/hono/lib/extension-store.ts
6
6
  init_write_file_atomic();
7
7
  /** Extension UI: write-through JSON KV per namespace under ~/.xopc/extensions/{namespace}/storage.json */
@@ -1,6 +1,6 @@
1
- import { dirname, resolve } from "node:path";
2
- import { readFileSync } from "node:fs";
3
1
  import { createHash } from "node:crypto";
2
+ import { readFileSync } from "node:fs";
3
+ import { dirname, resolve } from "node:path";
4
4
  import { fileURLToPath } from "node:url";
5
5
  //#region src/gateway/hono/lib/static-ui.ts
6
6
  const __dirname = dirname(fileURLToPath(import.meta.url));
@@ -1,9 +1,9 @@
1
1
  import { createLogger } from "../../utils/logger/index.js";
2
2
  import { init_logger } from "../../utils/logger.js";
3
3
  import { CredentialResolver, init_credentials } from "../../auth/credentials.js";
4
+ import { anthropicOAuthProvider } from "../../auth/oauth/anthropic.js";
4
5
  import { isLoopbackHost } from "../host.js";
5
6
  import { resolveReverseProxyPublicUrl } from "../public-url.js";
6
- import { anthropicOAuthProvider } from "../../auth/oauth/anthropic.js";
7
7
  import { minimaxOAuthProvider } from "../../auth/oauth/minimax.js";
8
8
  import { minimaxCnOAuthProvider } from "../../auth/oauth/minimax-cn.js";
9
9
  import { kimiCodingOAuthProvider } from "../../auth/oauth/kimi-coding.js";
@@ -1,5 +1,5 @@
1
- import { AgentModelsSchema, init_schema, parseModelRef } from "../../../config/schema.js";
2
1
  import { init_agent_scope, normalizeAgentId } from "../../../agent/agent-scope.js";
2
+ import { AgentModelsSchema, init_schema, parseModelRef } from "../../../config/schema.js";
3
3
  import { init_providers, isProviderConfigured, resolveModel } from "../../../providers/index.js";
4
4
  import { getVoiceModelsConfig } from "../../../config/voice.js";
5
5
  import { deleteAgentAvatarFile, finalizeCreateAgentDirs, listAgentProfileFiles, listGatewayAgents, prepareCreateAgent, prepareDeleteAgent, prepareUpdateAgent, readAgentAvatarFile, readAgentProfileFile, runAfterDeletePurge, writeAgentAvatarFromBase64, writeAgentProfileFile } from "../../agents-admin.js";
@@ -0,0 +1,3 @@
1
+ import type { Hono } from 'hono';
2
+ import type { AuthenticatedRouteDeps } from './deps.js';
3
+ export declare function registerAiAssistRoutes(authenticated: Hono, deps: AuthenticatedRouteDeps): void;
@@ -0,0 +1,66 @@
1
+ import { assistText, streamTextAssist } from "../../../ai-assist/text-assist.js";
2
+ import { createGatewayRouteLogger, logRouteError } from "../lib/route-logger.js";
3
+ import { stringifySSEData } from "../sse-json.js";
4
+ import { streamSSE } from "hono/streaming";
5
+ //#region src/gateway/hono/routes/ai-assist.ts
6
+ const log = createGatewayRouteLogger("AiAssist");
7
+ function isTextAssistIntent(value) {
8
+ return value === void 0 || value === "improve" || value === "expand" || value === "shorten" || value === "fix";
9
+ }
10
+ function registerAiAssistRoutes(authenticated, deps) {
11
+ const { service, strictRateLimitMiddleware } = deps;
12
+ authenticated.post("/api/ai/text-assist", strictRateLimitMiddleware, async (c) => {
13
+ const body = await c.req.json().catch(() => null);
14
+ if (!body || typeof body !== "object") return c.json({ error: {
15
+ code: "BAD_REQUEST",
16
+ message: "Invalid JSON body"
17
+ } }, 400);
18
+ const request = body;
19
+ if (!isTextAssistIntent(request.intent)) return c.json({ error: {
20
+ code: "BAD_REQUEST",
21
+ message: "Invalid intent"
22
+ } }, 400);
23
+ if (request.input !== void 0 && typeof request.input !== "string") return c.json({ error: {
24
+ code: "BAD_REQUEST",
25
+ message: "Invalid input"
26
+ } }, 400);
27
+ if ((c.req.header("Accept") || "").includes("text/event-stream")) {
28
+ c.header("X-Accel-Buffering", "no");
29
+ return streamSSE(c, async (stream) => {
30
+ let eventId = 0;
31
+ const generator = streamTextAssist(request, service.currentConfig, c.req.raw.signal);
32
+ try {
33
+ for await (const event of generator) await stream.writeSSE({
34
+ id: String(++eventId),
35
+ event: event.type,
36
+ data: stringifySSEData(event)
37
+ });
38
+ } catch (err) {
39
+ logRouteError(log, c, err, "gateway.route.ai_assist", { operation: "textAssistStream" });
40
+ await stream.writeSSE({
41
+ id: String(++eventId),
42
+ event: "error",
43
+ data: stringifySSEData({
44
+ type: "error",
45
+ message: err instanceof Error ? err.message : "AI text assist failed"
46
+ })
47
+ });
48
+ }
49
+ });
50
+ }
51
+ try {
52
+ const result = await assistText(request, service.currentConfig, c.req.raw.signal);
53
+ return c.json(result);
54
+ } catch (err) {
55
+ logRouteError(log, c, err, "gateway.route.ai_assist", { operation: "textAssist" });
56
+ return c.json({ error: {
57
+ code: "AI_ASSIST_FAILED",
58
+ message: err instanceof Error ? err.message : "AI text assist failed"
59
+ } }, 500);
60
+ }
61
+ });
62
+ }
63
+ //#endregion
64
+ export { registerAiAssistRoutes };
65
+
66
+ //# sourceMappingURL=ai-assist.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ai-assist.js","names":[],"sources":["../../../../../src/gateway/hono/routes/ai-assist.ts"],"sourcesContent":["import type { Hono } from 'hono';\nimport { streamSSE } from 'hono/streaming';\n\nimport { assistText, streamTextAssist, type TextAssistRequest } from '../../../ai-assist/text-assist.js';\nimport type { AuthenticatedRouteDeps } from './deps.js';\nimport { createGatewayRouteLogger, logRouteError } from '../lib/route-logger.js';\nimport { stringifySSEData } from '../sse-json.js';\n\nconst log = createGatewayRouteLogger('AiAssist');\n\nfunction isTextAssistIntent(value: unknown): boolean {\n return value === undefined || value === 'improve' || value === 'expand' || value === 'shorten' || value === 'fix';\n}\n\nexport function registerAiAssistRoutes(authenticated: Hono, deps: AuthenticatedRouteDeps): void {\n const { service, strictRateLimitMiddleware } = deps;\n\n authenticated.post('/api/ai/text-assist', strictRateLimitMiddleware, async (c) => {\n const body = await c.req.json().catch(() => null);\n if (!body || typeof body !== 'object') {\n return c.json({ error: { code: 'BAD_REQUEST', message: 'Invalid JSON body' } }, 400);\n }\n\n const request = body as TextAssistRequest;\n if (!isTextAssistIntent(request.intent)) {\n return c.json({ error: { code: 'BAD_REQUEST', message: 'Invalid intent' } }, 400);\n }\n if (request.input !== undefined && typeof request.input !== 'string') {\n return c.json({ error: { code: 'BAD_REQUEST', message: 'Invalid input' } }, 400);\n }\n\n const accept = c.req.header('Accept') || '';\n const wantSSE = accept.includes('text/event-stream');\n if (wantSSE) {\n c.header('X-Accel-Buffering', 'no');\n return streamSSE(c, async (stream) => {\n let eventId = 0;\n const generator = streamTextAssist(request, service.currentConfig, c.req.raw.signal);\n try {\n for await (const event of generator) {\n await stream.writeSSE({\n id: String(++eventId),\n event: event.type,\n data: stringifySSEData(event),\n });\n }\n } catch (err) {\n logRouteError(log, c, err, 'gateway.route.ai_assist', { operation: 'textAssistStream' });\n await stream.writeSSE({\n id: String(++eventId),\n event: 'error',\n data: stringifySSEData({\n type: 'error',\n message: err instanceof Error ? err.message : 'AI text assist failed',\n }),\n });\n }\n });\n }\n\n try {\n const result = await assistText(request, service.currentConfig, c.req.raw.signal);\n return c.json(result);\n } catch (err) {\n logRouteError(log, c, err, 'gateway.route.ai_assist', { operation: 'textAssist' });\n return c.json(\n {\n error: {\n code: 'AI_ASSIST_FAILED',\n message: err instanceof Error ? err.message : 'AI text assist failed',\n },\n },\n 500,\n );\n }\n });\n}\n"],"mappings":";;;;;AAQA,MAAM,MAAM,yBAAyB,WAAW;AAEhD,SAAS,mBAAmB,OAAyB;AACnD,QAAO,UAAU,KAAA,KAAa,UAAU,aAAa,UAAU,YAAY,UAAU,aAAa,UAAU;;AAG9G,SAAgB,uBAAuB,eAAqB,MAAoC;CAC9F,MAAM,EAAE,SAAS,8BAA8B;AAE/C,eAAc,KAAK,uBAAuB,2BAA2B,OAAO,MAAM;EAChF,MAAM,OAAO,MAAM,EAAE,IAAI,MAAM,CAAC,YAAY,KAAK;AACjD,MAAI,CAAC,QAAQ,OAAO,SAAS,SAC3B,QAAO,EAAE,KAAK,EAAE,OAAO;GAAE,MAAM;GAAe,SAAS;GAAqB,EAAE,EAAE,IAAI;EAGtF,MAAM,UAAU;AAChB,MAAI,CAAC,mBAAmB,QAAQ,OAAO,CACrC,QAAO,EAAE,KAAK,EAAE,OAAO;GAAE,MAAM;GAAe,SAAS;GAAkB,EAAE,EAAE,IAAI;AAEnF,MAAI,QAAQ,UAAU,KAAA,KAAa,OAAO,QAAQ,UAAU,SAC1D,QAAO,EAAE,KAAK,EAAE,OAAO;GAAE,MAAM;GAAe,SAAS;GAAiB,EAAE,EAAE,IAAI;AAKlF,OAFe,EAAE,IAAI,OAAO,SAAS,IAAI,IAClB,SAAS,oBACrB,EAAE;AACX,KAAE,OAAO,qBAAqB,KAAK;AACnC,UAAO,UAAU,GAAG,OAAO,WAAW;IACpC,IAAI,UAAU;IACd,MAAM,YAAY,iBAAiB,SAAS,QAAQ,eAAe,EAAE,IAAI,IAAI,OAAO;AACpF,QAAI;AACF,gBAAW,MAAM,SAAS,UACxB,OAAM,OAAO,SAAS;MACpB,IAAI,OAAO,EAAE,QAAQ;MACrB,OAAO,MAAM;MACb,MAAM,iBAAiB,MAAM;MAC9B,CAAC;aAEG,KAAK;AACZ,mBAAc,KAAK,GAAG,KAAK,2BAA2B,EAAE,WAAW,oBAAoB,CAAC;AACxF,WAAM,OAAO,SAAS;MACpB,IAAI,OAAO,EAAE,QAAQ;MACrB,OAAO;MACP,MAAM,iBAAiB;OACrB,MAAM;OACN,SAAS,eAAe,QAAQ,IAAI,UAAU;OAC/C,CAAC;MACH,CAAC;;KAEJ;;AAGJ,MAAI;GACF,MAAM,SAAS,MAAM,WAAW,SAAS,QAAQ,eAAe,EAAE,IAAI,IAAI,OAAO;AACjF,UAAO,EAAE,KAAK,OAAO;WACd,KAAK;AACZ,iBAAc,KAAK,GAAG,KAAK,2BAA2B,EAAE,WAAW,cAAc,CAAC;AAClF,UAAO,EAAE,KACP,EACE,OAAO;IACL,MAAM;IACN,SAAS,eAAe,QAAQ,IAAI,UAAU;IAC/C,EACF,EACD,IACD;;GAEH"}
@@ -7,8 +7,8 @@ import { createOAuthHandler } from "../oauth.js";
7
7
  import { createOAuthAsyncHandler } from "../oauth-async.js";
8
8
  import { extensionAssetMimeType } from "../lib/extension-assets.js";
9
9
  import { loadExtensionStore, saveExtensionStore } from "../lib/extension-store.js";
10
- import { relative, resolve } from "node:path";
11
10
  import { existsSync, readFileSync, statSync } from "node:fs";
11
+ import { relative, resolve } from "node:path";
12
12
  //#region src/gateway/hono/routes/auth-registry-extensions.ts
13
13
  init_providers();
14
14
  const EXTENSION_ASSET_CSP = "default-src 'self'; script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline'; img-src 'self' data: blob:; connect-src 'none'; frame-ancestors 'self'; frame-src 'none'; base-uri 'none'; object-src 'none'; form-action 'none'";
@@ -50,6 +50,13 @@ function registerCommandsSkillsRoutes(authenticated, deps) {
50
50
  payload
51
51
  });
52
52
  });
53
+ authenticated.get("/api/skills/status", (c) => {
54
+ const payload = service.marketplace.getSkillsStatusApi();
55
+ return c.json({
56
+ ok: true,
57
+ payload
58
+ });
59
+ });
53
60
  authenticated.get("/api/skills/:skillName/content", (c) => {
54
61
  const raw = c.req.param("skillName");
55
62
  if (!raw) return c.json({
@@ -1 +1 @@
1
- {"version":3,"file":"commands-skills.js","names":[],"sources":["../../../../../src/gateway/hono/routes/commands-skills.ts"],"sourcesContent":["import type { Hono } from 'hono';\n\nimport { commandRegistry } from '../../../chat-commands/index.js';\nimport { isRegisteredProvider } from '../../../agent/skills/skills-marketplace.js';\nimport type { AuthenticatedRouteDeps } from './deps.js';\n\nfunction parseMarketplaceProviderQuery(raw: string | undefined): string | undefined {\n const v = raw?.trim().toLowerCase();\n if (v && isRegisteredProvider(v)) return v;\n return undefined;\n}\n\nexport function registerCommandsSkillsRoutes(authenticated: Hono, deps: AuthenticatedRouteDeps): void {\n const { service } = deps;\n\n // ========== Chat slash commands (CommandRegistry) ==========\n\n authenticated.get('/api/commands', (c) => {\n const all = commandRegistry.list();\n const commands = all\n .filter((cmd) => cmd.scope.includes('global') || cmd.scope.includes('private'))\n .map((cmd) => ({\n id: cmd.id,\n name: cmd.name,\n aliases: cmd.aliases ?? [],\n description: cmd.description,\n category: cmd.category,\n scope: cmd.scope,\n acceptsArgs: cmd.acceptsArgs ?? false,\n examples: cmd.examples ?? [],\n }));\n const extensionCommands = all\n .filter((cmd) => cmd.category === 'extension')\n .map((cmd) => ({\n id: cmd.id,\n name: cmd.name,\n description: cmd.description,\n extensionId: cmd.id.startsWith('ext.') ? cmd.id.split('.')[1] : undefined,\n }));\n return c.json({ ok: true, payload: { commands, extensionCommands } });\n });\n\n // ========== Skills (managed global skills under ~/.xopc/skills) ==========\n\n authenticated.get('/api/chat/skills', (c) => {\n const agentId = c.req.query('agentId')?.trim() || service.getConfig().agents?.default || 'main';\n const payload = service.marketplace.getAgentSkillsApi(agentId);\n return c.json({ ok: true, payload });\n });\n\n authenticated.get('/api/skills', (c) => {\n const payload = service.marketplace.getSkillsApi();\n return c.json({ ok: true, payload });\n });\n\n authenticated.get('/api/skills/:skillName/content', (c) => {\n const raw = c.req.param('skillName');\n if (!raw) {\n return c.json({ ok: false, error: 'Missing skill name' }, 400);\n }\n let skillName: string;\n try {\n skillName = decodeURIComponent(raw);\n } catch {\n return c.json({ ok: false, error: 'Invalid skill name' }, 400);\n }\n const data = service.marketplace.getSkillMarkdownSource(skillName);\n if (!data) {\n return c.json({ ok: false, error: 'Skill not found' }, 404);\n }\n return c.json({ ok: true, payload: data });\n });\n\n authenticated.post('/api/skills/reload', (c) => {\n service.marketplace.reloadSkills();\n return c.json({ ok: true });\n });\n\n authenticated.patch('/api/skills/enabled', async (c) => {\n let body: { skillName?: unknown; enabled?: unknown };\n try {\n body = (await c.req.json()) as { skillName?: unknown; enabled?: unknown };\n } catch {\n return c.json({ ok: false, error: 'Invalid JSON' }, 400);\n }\n const skillName = typeof body.skillName === 'string' ? body.skillName.trim() : '';\n const enabled = body.enabled;\n if (!skillName || typeof enabled !== 'boolean') {\n return c.json({ ok: false, error: 'Expected { skillName: string, enabled: boolean }' }, 400);\n }\n try {\n service.marketplace.patchSkillEnabled(skillName, enabled);\n return c.json({ ok: true });\n } catch (err) {\n return c.json(\n { ok: false, error: err instanceof Error ? err.message : 'Update failed' },\n 400,\n );\n }\n });\n\n authenticated.get('/api/skills/marketplace', async (c) => {\n const q = c.req.query('q')?.trim() ?? '';\n const pageRaw = c.req.query('page');\n const pageSizeRaw = c.req.query('pageSize');\n const sortRaw = c.req.query('sort');\n const page = pageRaw != null && pageRaw !== '' ? Math.max(1, Number(pageRaw) || 1) : undefined;\n const pageSize =\n pageSizeRaw != null && pageSizeRaw !== ''\n ? Math.min(50, Math.max(1, Number(pageSizeRaw) || 20))\n : undefined;\n const sort =\n sortRaw === 'newest' || sortRaw === 'downloads' ? sortRaw : undefined;\n const category = c.req.query('category')?.trim() ?? '';\n const provider = parseMarketplaceProviderQuery(c.req.query('provider'));\n try {\n const payload = await service.marketplace.fetchSkillsCatalog(\n {\n q: q || undefined,\n page,\n pageSize,\n sort,\n category: category || undefined,\n },\n provider,\n );\n return c.json({ ok: true, payload });\n } catch (err) {\n return c.json(\n { ok: false, error: err instanceof Error ? err.message : 'Marketplace request failed' },\n 502,\n );\n }\n });\n\n authenticated.get('/api/skills/marketplace/provider', (c) => {\n const info = service.marketplace.getSkillsProvider();\n return c.json({ ok: true, payload: info });\n });\n\n /** All registered marketplace providers (built-in + extension-contributed). */\n authenticated.get('/api/skills/marketplace/providers', (c) => {\n const providers = service.marketplace.getSkillsProviders();\n const current = service.marketplace.getSkillsProvider();\n return c.json({ ok: true, payload: { providers, current: current.provider } });\n });\n\n authenticated.get('/api/skills/marketplace/categories', async (c) => {\n const provider = parseMarketplaceProviderQuery(c.req.query('provider'));\n try {\n const payload = await service.marketplace.fetchSkillsCategories(provider);\n return c.json({ ok: true, payload });\n } catch (err) {\n return c.json(\n { ok: false, error: err instanceof Error ? err.message : 'Marketplace categories failed' },\n 502,\n );\n }\n });\n\n authenticated.get('/api/skills/marketplace/packages/:pkgName', async (c) => {\n const raw = c.req.param('pkgName');\n if (!raw) {\n return c.json({ ok: false, error: 'Missing package name' }, 400);\n }\n let pkgName: string;\n try {\n pkgName = decodeURIComponent(raw);\n } catch {\n return c.json({ ok: false, error: 'Invalid package name' }, 400);\n }\n try {\n const provider = parseMarketplaceProviderQuery(c.req.query('provider'));\n const payload = await service.marketplace.fetchSkillsPackageDetail(pkgName, provider);\n return c.json({ ok: true, payload });\n } catch (err) {\n return c.json(\n { ok: false, error: err instanceof Error ? err.message : 'Marketplace request failed' },\n 502,\n );\n }\n });\n\n authenticated.post('/api/skills/marketplace/install', async (c) => {\n let body: { name?: unknown; version?: unknown; overwrite?: unknown; provider?: unknown };\n try {\n body = (await c.req.json()) as typeof body;\n } catch {\n return c.json({ ok: false, error: 'Invalid JSON' }, 400);\n }\n const name = typeof body.name === 'string' ? body.name.trim() : '';\n const version = typeof body.version === 'string' ? body.version.trim() : undefined;\n const overwrite =\n body.overwrite === true ||\n body.overwrite === 'true' ||\n body.overwrite === '1';\n const provider = parseMarketplaceProviderQuery(\n typeof body.provider === 'string' ? body.provider : undefined,\n );\n if (!name) {\n return c.json({ ok: false, error: 'Expected { name: string, version?: string, overwrite?: boolean }' }, 400);\n }\n try {\n const payload = await service.marketplace.installSkill({ name, version, overwrite, provider });\n return c.json({ ok: true, payload });\n } catch (err) {\n return c.json(\n { ok: false, error: err instanceof Error ? err.message : 'Install failed' },\n 400,\n );\n }\n });\n\n authenticated.post('/api/skills/upload', async (c) => {\n let body: Record<string, unknown>;\n try {\n body = await c.req.parseBody({ all: true });\n } catch {\n return c.json({ ok: false, error: 'Invalid multipart body' }, 400);\n }\n const file = body['file'];\n if (!file || typeof file !== 'object') {\n return c.json({ ok: false, error: 'Missing file field' }, 400);\n }\n let buf: Buffer;\n if (file instanceof File) {\n buf = Buffer.from(await file.arrayBuffer());\n } else if (typeof (file as Blob).arrayBuffer === 'function') {\n buf = Buffer.from(await (file as Blob).arrayBuffer());\n } else {\n return c.json({ ok: false, error: 'Invalid file upload' }, 400);\n }\n const skillIdRaw = body['skillId'];\n const overwriteRaw = body['overwrite'];\n const skillId = typeof skillIdRaw === 'string' && skillIdRaw.trim() ? skillIdRaw.trim() : undefined;\n const overwrite =\n overwriteRaw === 'true' ||\n overwriteRaw === true ||\n overwriteRaw === '1';\n\n try {\n const result = service.marketplace.installSkillZip(buf, { skillId, overwrite });\n return c.json({ ok: true, payload: result });\n } catch (err) {\n return c.json(\n { ok: false, error: err instanceof Error ? err.message : 'Install failed' },\n 400,\n );\n }\n });\n\n authenticated.delete('/api/skills/:id', (c) => {\n const id = c.req.param('id');\n if (!id) {\n return c.json({ ok: false, error: 'Missing id' }, 400);\n }\n try {\n service.marketplace.deleteSkill(id);\n return c.json({ ok: true });\n } catch (err) {\n return c.json(\n { ok: false, error: err instanceof Error ? err.message : 'Delete failed' },\n 400,\n );\n }\n });\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"commands-skills.js","names":[],"sources":["../../../../../src/gateway/hono/routes/commands-skills.ts"],"sourcesContent":["import type { Hono } from 'hono';\n\nimport { commandRegistry } from '../../../chat-commands/index.js';\nimport { isRegisteredProvider } from '../../../agent/skills/skills-marketplace.js';\nimport type { AuthenticatedRouteDeps } from './deps.js';\n\nfunction parseMarketplaceProviderQuery(raw: string | undefined): string | undefined {\n const v = raw?.trim().toLowerCase();\n if (v && isRegisteredProvider(v)) return v;\n return undefined;\n}\n\nexport function registerCommandsSkillsRoutes(authenticated: Hono, deps: AuthenticatedRouteDeps): void {\n const { service } = deps;\n\n // ========== Chat slash commands (CommandRegistry) ==========\n\n authenticated.get('/api/commands', (c) => {\n const all = commandRegistry.list();\n const commands = all\n .filter((cmd) => cmd.scope.includes('global') || cmd.scope.includes('private'))\n .map((cmd) => ({\n id: cmd.id,\n name: cmd.name,\n aliases: cmd.aliases ?? [],\n description: cmd.description,\n category: cmd.category,\n scope: cmd.scope,\n acceptsArgs: cmd.acceptsArgs ?? false,\n examples: cmd.examples ?? [],\n }));\n const extensionCommands = all\n .filter((cmd) => cmd.category === 'extension')\n .map((cmd) => ({\n id: cmd.id,\n name: cmd.name,\n description: cmd.description,\n extensionId: cmd.id.startsWith('ext.') ? cmd.id.split('.')[1] : undefined,\n }));\n return c.json({ ok: true, payload: { commands, extensionCommands } });\n });\n\n // ========== Skills (managed global skills under ~/.xopc/skills) ==========\n\n authenticated.get('/api/chat/skills', (c) => {\n const agentId = c.req.query('agentId')?.trim() || service.getConfig().agents?.default || 'main';\n const payload = service.marketplace.getAgentSkillsApi(agentId);\n return c.json({ ok: true, payload });\n });\n\n authenticated.get('/api/skills', (c) => {\n const payload = service.marketplace.getSkillsApi();\n return c.json({ ok: true, payload });\n });\n\n authenticated.get('/api/skills/status', (c) => {\n const payload = service.marketplace.getSkillsStatusApi();\n return c.json({ ok: true, payload });\n });\n\n authenticated.get('/api/skills/:skillName/content', (c) => {\n const raw = c.req.param('skillName');\n if (!raw) {\n return c.json({ ok: false, error: 'Missing skill name' }, 400);\n }\n let skillName: string;\n try {\n skillName = decodeURIComponent(raw);\n } catch {\n return c.json({ ok: false, error: 'Invalid skill name' }, 400);\n }\n const data = service.marketplace.getSkillMarkdownSource(skillName);\n if (!data) {\n return c.json({ ok: false, error: 'Skill not found' }, 404);\n }\n return c.json({ ok: true, payload: data });\n });\n\n authenticated.post('/api/skills/reload', (c) => {\n service.marketplace.reloadSkills();\n return c.json({ ok: true });\n });\n\n authenticated.patch('/api/skills/enabled', async (c) => {\n let body: { skillName?: unknown; enabled?: unknown };\n try {\n body = (await c.req.json()) as { skillName?: unknown; enabled?: unknown };\n } catch {\n return c.json({ ok: false, error: 'Invalid JSON' }, 400);\n }\n const skillName = typeof body.skillName === 'string' ? body.skillName.trim() : '';\n const enabled = body.enabled;\n if (!skillName || typeof enabled !== 'boolean') {\n return c.json({ ok: false, error: 'Expected { skillName: string, enabled: boolean }' }, 400);\n }\n try {\n service.marketplace.patchSkillEnabled(skillName, enabled);\n return c.json({ ok: true });\n } catch (err) {\n return c.json(\n { ok: false, error: err instanceof Error ? err.message : 'Update failed' },\n 400,\n );\n }\n });\n\n authenticated.get('/api/skills/marketplace', async (c) => {\n const q = c.req.query('q')?.trim() ?? '';\n const pageRaw = c.req.query('page');\n const pageSizeRaw = c.req.query('pageSize');\n const sortRaw = c.req.query('sort');\n const page = pageRaw != null && pageRaw !== '' ? Math.max(1, Number(pageRaw) || 1) : undefined;\n const pageSize =\n pageSizeRaw != null && pageSizeRaw !== ''\n ? Math.min(50, Math.max(1, Number(pageSizeRaw) || 20))\n : undefined;\n const sort =\n sortRaw === 'newest' || sortRaw === 'downloads' ? sortRaw : undefined;\n const category = c.req.query('category')?.trim() ?? '';\n const provider = parseMarketplaceProviderQuery(c.req.query('provider'));\n try {\n const payload = await service.marketplace.fetchSkillsCatalog(\n {\n q: q || undefined,\n page,\n pageSize,\n sort,\n category: category || undefined,\n },\n provider,\n );\n return c.json({ ok: true, payload });\n } catch (err) {\n return c.json(\n { ok: false, error: err instanceof Error ? err.message : 'Marketplace request failed' },\n 502,\n );\n }\n });\n\n authenticated.get('/api/skills/marketplace/provider', (c) => {\n const info = service.marketplace.getSkillsProvider();\n return c.json({ ok: true, payload: info });\n });\n\n /** All registered marketplace providers (built-in + extension-contributed). */\n authenticated.get('/api/skills/marketplace/providers', (c) => {\n const providers = service.marketplace.getSkillsProviders();\n const current = service.marketplace.getSkillsProvider();\n return c.json({ ok: true, payload: { providers, current: current.provider } });\n });\n\n authenticated.get('/api/skills/marketplace/categories', async (c) => {\n const provider = parseMarketplaceProviderQuery(c.req.query('provider'));\n try {\n const payload = await service.marketplace.fetchSkillsCategories(provider);\n return c.json({ ok: true, payload });\n } catch (err) {\n return c.json(\n { ok: false, error: err instanceof Error ? err.message : 'Marketplace categories failed' },\n 502,\n );\n }\n });\n\n authenticated.get('/api/skills/marketplace/packages/:pkgName', async (c) => {\n const raw = c.req.param('pkgName');\n if (!raw) {\n return c.json({ ok: false, error: 'Missing package name' }, 400);\n }\n let pkgName: string;\n try {\n pkgName = decodeURIComponent(raw);\n } catch {\n return c.json({ ok: false, error: 'Invalid package name' }, 400);\n }\n try {\n const provider = parseMarketplaceProviderQuery(c.req.query('provider'));\n const payload = await service.marketplace.fetchSkillsPackageDetail(pkgName, provider);\n return c.json({ ok: true, payload });\n } catch (err) {\n return c.json(\n { ok: false, error: err instanceof Error ? err.message : 'Marketplace request failed' },\n 502,\n );\n }\n });\n\n authenticated.post('/api/skills/marketplace/install', async (c) => {\n let body: { name?: unknown; version?: unknown; overwrite?: unknown; provider?: unknown };\n try {\n body = (await c.req.json()) as typeof body;\n } catch {\n return c.json({ ok: false, error: 'Invalid JSON' }, 400);\n }\n const name = typeof body.name === 'string' ? body.name.trim() : '';\n const version = typeof body.version === 'string' ? body.version.trim() : undefined;\n const overwrite =\n body.overwrite === true ||\n body.overwrite === 'true' ||\n body.overwrite === '1';\n const provider = parseMarketplaceProviderQuery(\n typeof body.provider === 'string' ? body.provider : undefined,\n );\n if (!name) {\n return c.json({ ok: false, error: 'Expected { name: string, version?: string, overwrite?: boolean }' }, 400);\n }\n try {\n const payload = await service.marketplace.installSkill({ name, version, overwrite, provider });\n return c.json({ ok: true, payload });\n } catch (err) {\n return c.json(\n { ok: false, error: err instanceof Error ? err.message : 'Install failed' },\n 400,\n );\n }\n });\n\n authenticated.post('/api/skills/upload', async (c) => {\n let body: Record<string, unknown>;\n try {\n body = await c.req.parseBody({ all: true });\n } catch {\n return c.json({ ok: false, error: 'Invalid multipart body' }, 400);\n }\n const file = body['file'];\n if (!file || typeof file !== 'object') {\n return c.json({ ok: false, error: 'Missing file field' }, 400);\n }\n let buf: Buffer;\n if (file instanceof File) {\n buf = Buffer.from(await file.arrayBuffer());\n } else if (typeof (file as Blob).arrayBuffer === 'function') {\n buf = Buffer.from(await (file as Blob).arrayBuffer());\n } else {\n return c.json({ ok: false, error: 'Invalid file upload' }, 400);\n }\n const skillIdRaw = body['skillId'];\n const overwriteRaw = body['overwrite'];\n const skillId = typeof skillIdRaw === 'string' && skillIdRaw.trim() ? skillIdRaw.trim() : undefined;\n const overwrite =\n overwriteRaw === 'true' ||\n overwriteRaw === true ||\n overwriteRaw === '1';\n\n try {\n const result = service.marketplace.installSkillZip(buf, { skillId, overwrite });\n return c.json({ ok: true, payload: result });\n } catch (err) {\n return c.json(\n { ok: false, error: err instanceof Error ? err.message : 'Install failed' },\n 400,\n );\n }\n });\n\n authenticated.delete('/api/skills/:id', (c) => {\n const id = c.req.param('id');\n if (!id) {\n return c.json({ ok: false, error: 'Missing id' }, 400);\n }\n try {\n service.marketplace.deleteSkill(id);\n return c.json({ ok: true });\n } catch (err) {\n return c.json(\n { ok: false, error: err instanceof Error ? err.message : 'Delete failed' },\n 400,\n );\n }\n });\n}\n"],"mappings":"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"}
@@ -1,5 +1,5 @@
1
- import { BindingsConfigSchema, McpConfigSchema, init_schema } from "../../../../config/schema.js";
2
1
  import { CredentialResolver, init_credentials } from "../../../../auth/credentials.js";
2
+ import { BindingsConfigSchema, McpConfigSchema, init_schema } from "../../../../config/schema.js";
3
3
  import { canonicalizeConfiguredMcpServer } from "../../../../config/mcp-config-normalize.js";
4
4
  import { mergeCronConfigPatch, mergeGatewaySkillsMarketplacePatch, mergeGoalsConfigPatch, mergeSessionConfigPatch, mergeUpdateConfigPatch } from "../../../../config/web-patch.js";
5
5
  import { assertGatewayAuthConfigured, resolveGatewayAuth } from "../../../auth.js";
@@ -1,3 +1,4 @@
1
+ import { CronJobAlreadyRunningError } from "../../../cron/service.js";
1
2
  import { createGatewayRouteLogger, logRouteError } from "../lib/route-logger.js";
2
3
  //#region src/gateway/hono/routes/cron.ts
3
4
  const log = createGatewayRouteLogger("Cron");
@@ -8,17 +9,19 @@ function registerCronRoutes(authenticated, deps) {
8
9
  return c.json({ jobs });
9
10
  });
10
11
  authenticated.post("/api/cron", async (c) => {
11
- const { schedule, name, timezone, sessionTarget, agentId, workingDirectory, model, delivery, payload } = await c.req.json();
12
+ const { schedule, name, description, sessionTarget, wakeMode, agentId, workingDirectory, delivery, payload, failureAlert, deleteAfterRun } = await c.req.json();
12
13
  if (!schedule || !payload) return c.json({ error: "Missing required fields: schedule, payload" }, 400);
13
14
  try {
14
15
  const result = await service.cronServiceInstance.addJob(schedule, {
15
16
  name,
16
- timezone,
17
+ description,
17
18
  sessionTarget,
19
+ wakeMode,
18
20
  ...typeof agentId === "string" && agentId.trim() ? { agentId: agentId.trim() } : {},
19
21
  ...typeof workingDirectory === "string" && workingDirectory.trim() ? { workingDirectory: workingDirectory.trim() } : {},
20
- model,
22
+ ...typeof deleteAfterRun === "boolean" ? { deleteAfterRun } : {},
21
23
  delivery,
24
+ failureAlert,
22
25
  payload
23
26
  });
24
27
  return c.json(result, 201);
@@ -53,9 +56,25 @@ function registerCronRoutes(authenticated, deps) {
53
56
  authenticated.post("/api/cron/:id/run", async (c) => {
54
57
  const id = c.req.param("id");
55
58
  try {
56
- await service.cronServiceInstance.runJobNow(id);
57
- return c.json({ triggered: true });
59
+ const result = await service.cronServiceInstance.runJobNow(id);
60
+ return c.json({
61
+ triggered: true,
62
+ job: result.job,
63
+ history: result.history
64
+ });
58
65
  } catch (err) {
66
+ if (err instanceof CronJobAlreadyRunningError) {
67
+ log.info({
68
+ jobId: err.jobId,
69
+ runningSessionKey: err.runningSessionKey
70
+ }, "Cron job run requested while already running");
71
+ return c.json({
72
+ error: err.message,
73
+ code: "job_already_running",
74
+ jobId: err.jobId,
75
+ runningSessionKey: err.runningSessionKey
76
+ }, 409);
77
+ }
59
78
  logRouteError(log, c, err, "gateway.route.cron", { operation: "runJob" });
60
79
  return c.json({ error: err instanceof Error ? err.message : "Failed to run job" }, 400);
61
80
  }
@@ -1 +1 @@
1
- {"version":3,"file":"cron.js","names":[],"sources":["../../../../../src/gateway/hono/routes/cron.ts"],"sourcesContent":["import type { Hono } from 'hono';\n\nimport type { AuthenticatedRouteDeps } from './deps.js';\nimport { createGatewayRouteLogger, logRouteError } from '../lib/route-logger.js';\n\nconst log = createGatewayRouteLogger('Cron');\n\nexport function registerCronRoutes(authenticated: Hono, deps: AuthenticatedRouteDeps): void {\n const { service } = deps;\n\n // ========== Cron REST API (/api/cron) ==========\n\n // GET /api/cron - List all jobs\n authenticated.get('/api/cron', async (c) => {\n const jobs = await service.cronServiceInstance.listJobs();\n return c.json({ jobs });\n });\n\n // POST /api/cron - Add new job\n authenticated.post('/api/cron', async (c) => {\n const body = await c.req.json();\n const { schedule, name, timezone, sessionTarget, agentId, workingDirectory, model, delivery, payload } = body;\n\n if (!schedule || !payload) {\n return c.json({ error: 'Missing required fields: schedule, payload' }, 400);\n }\n\n try {\n const result = await service.cronServiceInstance.addJob(schedule, {\n name,\n timezone,\n sessionTarget,\n ...(typeof agentId === 'string' && agentId.trim() ? { agentId: agentId.trim() } : {}),\n ...(typeof workingDirectory === 'string' && workingDirectory.trim()\n ? { workingDirectory: workingDirectory.trim() }\n : {}),\n model,\n delivery,\n payload,\n });\n return c.json(result, 201);\n } catch (err) {\n logRouteError(log, c, err, 'gateway.route.cron', { operation: 'addJob' });\n return c.json({ error: err instanceof Error ? err.message : 'Failed to add job' }, 400);\n }\n });\n\n // GET /api/cron/metrics - Get cron metrics (must be before /:id)\n authenticated.get('/api/cron/metrics', async (c) => {\n const metrics = await service.cronServiceInstance.getMetrics();\n return c.json(metrics);\n });\n\n // GET /api/cron/runs/history - Recent runs across all jobs (must be before /:id)\n authenticated.get('/api/cron/runs/history', async (c) => {\n const raw = c.req.query('limit');\n const limit = raw ? parseInt(raw, 10) : 50;\n const runs = await service.cronServiceInstance.getAllRunsHistory(Number.isFinite(limit) ? limit : 50);\n return c.json({ runs });\n });\n\n // GET /api/cron/:id - Get single job (must be after /metrics)\n authenticated.get('/api/cron/:id', async (c) => {\n const id = c.req.param('id');\n const job = await service.cronServiceInstance.getJob(id);\n if (!job) {\n return c.json({ error: 'Job not found' }, 404);\n }\n return c.json({ job });\n });\n\n // POST /api/cron/:id/toggle - Toggle job enabled\n authenticated.post('/api/cron/:id/toggle', async (c) => {\n const id = c.req.param('id');\n const body = await c.req.json();\n const { enabled } = body;\n\n if (typeof enabled !== 'boolean') {\n return c.json({ error: 'Missing required field: enabled' }, 400);\n }\n\n const result = await service.cronServiceInstance.toggleJob(id, enabled);\n return c.json({ toggled: result });\n });\n\n // POST /api/cron/:id/run - Trigger job manually\n authenticated.post('/api/cron/:id/run', async (c) => {\n const id = c.req.param('id');\n\n try {\n await service.cronServiceInstance.runJobNow(id);\n return c.json({ triggered: true });\n } catch (err) {\n logRouteError(log, c, err, 'gateway.route.cron', { operation: 'runJob' });\n return c.json({ error: err instanceof Error ? err.message : 'Failed to run job' }, 400);\n }\n });\n\n // GET /api/cron/:id/history - Get job execution history\n authenticated.get('/api/cron/:id/history', async (c) => {\n const id = c.req.param('id');\n const raw = c.req.query('limit');\n const limit = raw ? parseInt(raw, 10) : 10;\n const history = await service.cronServiceInstance.getJobHistory(id, Number.isFinite(limit) ? limit : 10);\n return c.json({ history });\n });\n\n // PATCH /api/cron/:id - Update job\n authenticated.patch('/api/cron/:id', async (c) => {\n const id = c.req.param('id');\n const body = await c.req.json();\n\n try {\n const result = await service.cronServiceInstance.updateJob(id, body);\n return c.json({ updated: result });\n } catch (err) {\n logRouteError(log, c, err, 'gateway.route.cron', { operation: 'updateJob' });\n return c.json({ error: err instanceof Error ? err.message : 'Failed to update job' }, 400);\n }\n });\n\n // DELETE /api/cron/:id - Remove job\n authenticated.delete('/api/cron/:id', async (c) => {\n const id = c.req.param('id');\n const result = await service.cronServiceInstance.removeJob(id);\n return c.json({ removed: result });\n });\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"cron.js","names":[],"sources":["../../../../../src/gateway/hono/routes/cron.ts"],"sourcesContent":["import type { Hono } from 'hono';\n\nimport { CronJobAlreadyRunningError } from '../../../cron/service.js';\nimport type { AuthenticatedRouteDeps } from './deps.js';\nimport { createGatewayRouteLogger, logRouteError } from '../lib/route-logger.js';\n\nconst log = createGatewayRouteLogger('Cron');\n\nexport function registerCronRoutes(authenticated: Hono, deps: AuthenticatedRouteDeps): void {\n const { service } = deps;\n\n // ========== Cron REST API (/api/cron) ==========\n\n // GET /api/cron - List all jobs\n authenticated.get('/api/cron', async (c) => {\n const jobs = await service.cronServiceInstance.listJobs();\n return c.json({ jobs });\n });\n\n // POST /api/cron - Add new job\n authenticated.post('/api/cron', async (c) => {\n const body = await c.req.json();\n const { schedule, name, description, sessionTarget, wakeMode, agentId, workingDirectory, delivery, payload, failureAlert, deleteAfterRun } = body;\n\n if (!schedule || !payload) {\n return c.json({ error: 'Missing required fields: schedule, payload' }, 400);\n }\n\n try {\n const result = await service.cronServiceInstance.addJob(schedule, {\n name,\n description,\n sessionTarget,\n wakeMode,\n ...(typeof agentId === 'string' && agentId.trim() ? { agentId: agentId.trim() } : {}),\n ...(typeof workingDirectory === 'string' && workingDirectory.trim()\n ? { workingDirectory: workingDirectory.trim() }\n : {}),\n ...(typeof deleteAfterRun === 'boolean' ? { deleteAfterRun } : {}),\n delivery,\n failureAlert,\n payload,\n });\n return c.json(result, 201);\n } catch (err) {\n logRouteError(log, c, err, 'gateway.route.cron', { operation: 'addJob' });\n return c.json({ error: err instanceof Error ? err.message : 'Failed to add job' }, 400);\n }\n });\n\n // GET /api/cron/metrics - Get cron metrics (must be before /:id)\n authenticated.get('/api/cron/metrics', async (c) => {\n const metrics = await service.cronServiceInstance.getMetrics();\n return c.json(metrics);\n });\n\n // GET /api/cron/runs/history - Recent runs across all jobs (must be before /:id)\n authenticated.get('/api/cron/runs/history', async (c) => {\n const raw = c.req.query('limit');\n const limit = raw ? parseInt(raw, 10) : 50;\n const runs = await service.cronServiceInstance.getAllRunsHistory(Number.isFinite(limit) ? limit : 50);\n return c.json({ runs });\n });\n\n // GET /api/cron/:id - Get single job (must be after /metrics)\n authenticated.get('/api/cron/:id', async (c) => {\n const id = c.req.param('id');\n const job = await service.cronServiceInstance.getJob(id);\n if (!job) {\n return c.json({ error: 'Job not found' }, 404);\n }\n return c.json({ job });\n });\n\n // POST /api/cron/:id/toggle - Toggle job enabled\n authenticated.post('/api/cron/:id/toggle', async (c) => {\n const id = c.req.param('id');\n const body = await c.req.json();\n const { enabled } = body;\n\n if (typeof enabled !== 'boolean') {\n return c.json({ error: 'Missing required field: enabled' }, 400);\n }\n\n const result = await service.cronServiceInstance.toggleJob(id, enabled);\n return c.json({ toggled: result });\n });\n\n // POST /api/cron/:id/run - Trigger job manually\n authenticated.post('/api/cron/:id/run', async (c) => {\n const id = c.req.param('id');\n\n try {\n const result = await service.cronServiceInstance.runJobNow(id);\n return c.json({ triggered: true, job: result.job, history: result.history });\n } catch (err) {\n if (err instanceof CronJobAlreadyRunningError) {\n log.info(\n { jobId: err.jobId, runningSessionKey: err.runningSessionKey },\n 'Cron job run requested while already running',\n );\n return c.json(\n {\n error: err.message,\n code: 'job_already_running',\n jobId: err.jobId,\n runningSessionKey: err.runningSessionKey,\n },\n 409,\n );\n }\n logRouteError(log, c, err, 'gateway.route.cron', { operation: 'runJob' });\n return c.json({ error: err instanceof Error ? err.message : 'Failed to run job' }, 400);\n }\n });\n\n // GET /api/cron/:id/history - Get job execution history\n authenticated.get('/api/cron/:id/history', async (c) => {\n const id = c.req.param('id');\n const raw = c.req.query('limit');\n const limit = raw ? parseInt(raw, 10) : 10;\n const history = await service.cronServiceInstance.getJobHistory(id, Number.isFinite(limit) ? limit : 10);\n return c.json({ history });\n });\n\n // PATCH /api/cron/:id - Update job\n authenticated.patch('/api/cron/:id', async (c) => {\n const id = c.req.param('id');\n const body = await c.req.json();\n\n try {\n const result = await service.cronServiceInstance.updateJob(id, body);\n return c.json({ updated: result });\n } catch (err) {\n logRouteError(log, c, err, 'gateway.route.cron', { operation: 'updateJob' });\n return c.json({ error: err instanceof Error ? err.message : 'Failed to update job' }, 400);\n }\n });\n\n // DELETE /api/cron/:id - Remove job\n authenticated.delete('/api/cron/:id', async (c) => {\n const id = c.req.param('id');\n const result = await service.cronServiceInstance.removeJob(id);\n return c.json({ removed: result });\n });\n}\n"],"mappings":"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"}
@@ -5,8 +5,8 @@ import { parseDreamingLastRunFile } from "../../../agent/memory/dreaming/last-ru
5
5
  import { readDreamingEvents } from "../../../agent/memory/dreaming/events.js";
6
6
  import { getWorkspacePath } from "../../../config/workspace-path-helpers.js";
7
7
  import { previewDreamingDeepPromotion } from "../../../agent/memory/dreaming/preview.js";
8
- import path from "node:path";
9
8
  import fs from "node:fs/promises";
9
+ import path from "node:path";
10
10
  //#region src/gateway/hono/routes/dreaming.ts
11
11
  function isRecord(v) {
12
12
  return v !== null && typeof v === "object" && !Array.isArray(v);
@@ -1,3 +1,5 @@
1
+ import { describeSchedule } from "../../../cron/schedule.js";
2
+ import "../../../cron/index.js";
1
3
  import { listGatewayAgents } from "../../agents-admin.js";
2
4
  import { getTunnelService } from "../../../tunnel/tunnel-service.js";
3
5
  import "../../../tunnel/index.js";
@@ -20,12 +22,12 @@ function payloadKind(job) {
20
22
  return typeof payload?.kind === "string" ? payload.kind : "unknown";
21
23
  }
22
24
  function toHomeCronJob(job) {
23
- if (!job.enabled || !job.next_run) return null;
25
+ if (!job.enabled || !job.state.nextRunAtMs) return null;
24
26
  return {
25
27
  id: job.id,
26
28
  name: job.name,
27
- schedule: job.schedule,
28
- nextRunAt: job.next_run,
29
+ schedule: describeSchedule(job.schedule),
30
+ nextRunAt: new Date(job.state.nextRunAtMs).toISOString(),
29
31
  payloadKind: payloadKind(job)
30
32
  };
31
33
  }
@@ -1 +1 @@
1
- {"version":3,"file":"home.js","names":[],"sources":["../../../../../src/gateway/hono/routes/home.ts"],"sourcesContent":["import type { Hono } from 'hono';\n\nimport { listGatewayAgents } from '../../agents-admin.js';\nimport { getTunnelService } from '../../../tunnel/index.js';\nimport type { JobWithNextRun, CronRunHistoryRow } from '../../../cron/types.js';\nimport type { WorkflowRunSummary } from '../../../workflows/domain/index.js';\nimport type { AuthenticatedRouteDeps } from './deps.js';\n\ntype HomeWorkflowRun = {\n id: string;\n definitionId: string;\n title: string;\n status: WorkflowRunSummary['status'];\n sessionKey?: string;\n createdAtMs: number;\n startedAtMs?: number;\n completedAtMs?: number;\n metrics: WorkflowRunSummary['metrics'];\n};\n\ntype HomeCronJob = {\n id: string;\n name?: string;\n schedule: string;\n nextRunAt: string;\n payloadKind: string;\n};\n\ntype HomeCronRun = {\n id: string;\n jobId: string;\n jobName?: string;\n status: CronRunHistoryRow['status'];\n startedAt: string;\n endedAt?: string;\n error?: string;\n summary?: string;\n sessionKey?: string;\n workflowRunId?: string;\n};\n\nfunction toHomeWorkflowRun(run: WorkflowRunSummary): HomeWorkflowRun {\n return {\n id: run.id,\n definitionId: run.definitionId,\n title: run.title,\n status: run.status,\n sessionKey: run.metadata?.sessionKey,\n createdAtMs: run.createdAtMs,\n startedAtMs: run.startedAtMs,\n completedAtMs: run.completedAtMs,\n metrics: run.metrics,\n };\n}\n\nfunction payloadKind(job: JobWithNextRun): string {\n const payload = job.payload as { kind?: unknown } | undefined;\n return typeof payload?.kind === 'string' ? payload.kind : 'unknown';\n}\n\nfunction toHomeCronJob(job: JobWithNextRun): HomeCronJob | null {\n if (!job.enabled || !job.next_run) return null;\n return {\n id: job.id,\n name: job.name,\n schedule: job.schedule,\n nextRunAt: job.next_run,\n payloadKind: payloadKind(job),\n };\n}\n\nfunction toHomeCronRun(run: CronRunHistoryRow): HomeCronRun {\n return {\n id: run.id,\n jobId: run.jobId,\n jobName: run.jobName,\n status: run.status,\n startedAt: run.startedAt,\n endedAt: run.endedAt,\n error: run.error,\n summary: run.summary,\n sessionKey: run.sessionKey,\n workflowRunId: run.workflowRunId,\n };\n}\n\n/**\n * GET /api/home — Aggregated home screen data for the mobile app.\n *\n * Returns:\n * - recentlyOpened: notes sorted by lastOpenedAt (continue rail)\n * - inboxCount: number of notes with status === 'inbox'\n * - pendingTasks: task notes where done === false\n * - recentSessions: last 5 active AI sessions (threads)\n * - activeAgent: default agent identity for this gateway\n * - gateway: readiness + public tunnel status\n * - workflowRuns: active / attention / recent workflow runs\n * - nextCronJobs: upcoming enabled schedules\n * - recentCronRuns: latest cron executions\n */\nexport function registerHomeRoutes(authenticated: Hono, deps: AuthenticatedRouteDeps): void {\n const { service } = deps;\n\n authenticated.get('/api/home', async (c) => {\n const notes = service.notesServiceInstance;\n const sessions = service.sessions;\n const agents = await listGatewayAgents(service.currentConfig);\n const defaultAgent = agents.agents.find((agent) => agent.id === agents.defaultId) ?? agents.agents[0];\n const workflowRunService = service.createWorkflowRunService();\n const workflowRunStore = workflowRunService.createRunStore(defaultAgent?.id ?? agents.defaultId);\n const tunnel = getTunnelService().getStatus();\n const health = service.getHealth();\n\n const [\n recentlyOpened,\n inbox,\n pendingTasks,\n recentSessions,\n workflowRuns,\n cronJobs,\n recentCronRuns,\n ] = await Promise.all([\n notes.listNotes({ sortBy: 'lastOpenedAt', sortOrder: 'desc', limit: 10 }),\n notes.listNotes({ status: 'inbox', limit: 0 }),\n notes.listNotes({ pendingTasksOnly: true, sortBy: 'createdAt', sortOrder: 'desc', limit: 10 }),\n sessions.listSessions({ sortBy: 'updatedAt', sortOrder: 'desc', limit: 5 }),\n workflowRunStore.listRunSummaries(20),\n service.cronServiceInstance.listJobs(),\n service.cronServiceInstance.getAllRunsHistory(10),\n ]);\n\n const activeWorkflowRuns = workflowRuns\n .filter((run) => run.status === 'queued' || run.status === 'running')\n .slice(0, 5)\n .map(toHomeWorkflowRun);\n const attentionWorkflowRuns = workflowRuns\n .filter((run) => run.status === 'failed' || run.status === 'timeout')\n .slice(0, 5)\n .map(toHomeWorkflowRun);\n const recentWorkflowRuns = workflowRuns.slice(0, 5).map(toHomeWorkflowRun);\n const nextCronJobs = cronJobs\n .map(toHomeCronJob)\n .filter((job): job is HomeCronJob => Boolean(job))\n .sort((a, b) => Date.parse(a.nextRunAt) - Date.parse(b.nextRunAt))\n .slice(0, 5);\n\n return c.json({\n recentlyOpened: recentlyOpened.items.filter((n) => n.lastOpenedAt),\n inboxCount: inbox.total,\n pendingTasks: pendingTasks.items,\n pendingTaskCount: pendingTasks.total,\n recentSessions: recentSessions.items,\n activeAgent: defaultAgent\n ? {\n id: defaultAgent.id,\n name: defaultAgent.name,\n description: defaultAgent.description,\n }\n : { id: agents.defaultId },\n gateway: {\n status: health.status,\n ready: health.ready,\n httpListening: health.httpListening,\n version: health.version,\n uptime: health.uptime,\n tunnel: {\n state: tunnel.state,\n publicUrl: tunnel.publicUrl,\n connected: tunnel.state === 'connected',\n },\n },\n workflowRuns: {\n active: activeWorkflowRuns,\n attention: attentionWorkflowRuns,\n recent: recentWorkflowRuns,\n },\n nextCronJobs,\n recentCronRuns: recentCronRuns.slice(0, 5).map(toHomeCronRun),\n });\n });\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"home.js","names":[],"sources":["../../../../../src/gateway/hono/routes/home.ts"],"sourcesContent":["import type { Hono } from 'hono';\n\nimport { listGatewayAgents } from '../../agents-admin.js';\nimport { getTunnelService } from '../../../tunnel/index.js';\nimport { describeSchedule } from '../../../cron/index.js';\nimport type { CronRunHistoryRow, JobData } from '../../../cron/types.js';\nimport type { WorkflowRunSummary } from '../../../workflows/domain/index.js';\nimport type { AuthenticatedRouteDeps } from './deps.js';\n\ntype HomeWorkflowRun = {\n id: string;\n definitionId: string;\n title: string;\n status: WorkflowRunSummary['status'];\n sessionKey?: string;\n createdAtMs: number;\n startedAtMs?: number;\n completedAtMs?: number;\n metrics: WorkflowRunSummary['metrics'];\n};\n\ntype HomeCronJob = {\n id: string;\n name?: string;\n schedule: string;\n nextRunAt: string;\n payloadKind: string;\n};\n\ntype HomeCronRun = {\n id: string;\n jobId: string;\n jobName?: string;\n status: CronRunHistoryRow['status'];\n startedAt: string;\n endedAt?: string;\n error?: string;\n summary?: string;\n sessionKey?: string;\n workflowRunId?: string;\n};\n\nfunction toHomeWorkflowRun(run: WorkflowRunSummary): HomeWorkflowRun {\n return {\n id: run.id,\n definitionId: run.definitionId,\n title: run.title,\n status: run.status,\n sessionKey: run.metadata?.sessionKey,\n createdAtMs: run.createdAtMs,\n startedAtMs: run.startedAtMs,\n completedAtMs: run.completedAtMs,\n metrics: run.metrics,\n };\n}\n\nfunction payloadKind(job: JobData): string {\n const payload = job.payload as { kind?: unknown } | undefined;\n return typeof payload?.kind === 'string' ? payload.kind : 'unknown';\n}\n\nfunction toHomeCronJob(job: JobData): HomeCronJob | null {\n if (!job.enabled || !job.state.nextRunAtMs) return null;\n return {\n id: job.id,\n name: job.name,\n schedule: describeSchedule(job.schedule),\n nextRunAt: new Date(job.state.nextRunAtMs).toISOString(),\n payloadKind: payloadKind(job),\n };\n}\n\nfunction toHomeCronRun(run: CronRunHistoryRow): HomeCronRun {\n return {\n id: run.id,\n jobId: run.jobId,\n jobName: run.jobName,\n status: run.status,\n startedAt: run.startedAt,\n endedAt: run.endedAt,\n error: run.error,\n summary: run.summary,\n sessionKey: run.sessionKey,\n workflowRunId: run.workflowRunId,\n };\n}\n\n/**\n * GET /api/home — Aggregated home screen data for the mobile app.\n *\n * Returns:\n * - recentlyOpened: notes sorted by lastOpenedAt (continue rail)\n * - inboxCount: number of notes with status === 'inbox'\n * - pendingTasks: task notes where done === false\n * - recentSessions: last 5 active AI sessions (threads)\n * - activeAgent: default agent identity for this gateway\n * - gateway: readiness + public tunnel status\n * - workflowRuns: active / attention / recent workflow runs\n * - nextCronJobs: upcoming enabled schedules\n * - recentCronRuns: latest cron executions\n */\nexport function registerHomeRoutes(authenticated: Hono, deps: AuthenticatedRouteDeps): void {\n const { service } = deps;\n\n authenticated.get('/api/home', async (c) => {\n const notes = service.notesServiceInstance;\n const sessions = service.sessions;\n const agents = await listGatewayAgents(service.currentConfig);\n const defaultAgent = agents.agents.find((agent) => agent.id === agents.defaultId) ?? agents.agents[0];\n const workflowRunService = service.createWorkflowRunService();\n const workflowRunStore = workflowRunService.createRunStore(defaultAgent?.id ?? agents.defaultId);\n const tunnel = getTunnelService().getStatus();\n const health = service.getHealth();\n\n const [\n recentlyOpened,\n inbox,\n pendingTasks,\n recentSessions,\n workflowRuns,\n cronJobs,\n recentCronRuns,\n ] = await Promise.all([\n notes.listNotes({ sortBy: 'lastOpenedAt', sortOrder: 'desc', limit: 10 }),\n notes.listNotes({ status: 'inbox', limit: 0 }),\n notes.listNotes({ pendingTasksOnly: true, sortBy: 'createdAt', sortOrder: 'desc', limit: 10 }),\n sessions.listSessions({ sortBy: 'updatedAt', sortOrder: 'desc', limit: 5 }),\n workflowRunStore.listRunSummaries(20),\n service.cronServiceInstance.listJobs(),\n service.cronServiceInstance.getAllRunsHistory(10),\n ]);\n\n const activeWorkflowRuns = workflowRuns\n .filter((run) => run.status === 'queued' || run.status === 'running')\n .slice(0, 5)\n .map(toHomeWorkflowRun);\n const attentionWorkflowRuns = workflowRuns\n .filter((run) => run.status === 'failed' || run.status === 'timeout')\n .slice(0, 5)\n .map(toHomeWorkflowRun);\n const recentWorkflowRuns = workflowRuns.slice(0, 5).map(toHomeWorkflowRun);\n const nextCronJobs = cronJobs\n .map(toHomeCronJob)\n .filter((job): job is HomeCronJob => Boolean(job))\n .sort((a, b) => Date.parse(a.nextRunAt) - Date.parse(b.nextRunAt))\n .slice(0, 5);\n\n return c.json({\n recentlyOpened: recentlyOpened.items.filter((n) => n.lastOpenedAt),\n inboxCount: inbox.total,\n pendingTasks: pendingTasks.items,\n pendingTaskCount: pendingTasks.total,\n recentSessions: recentSessions.items,\n activeAgent: defaultAgent\n ? {\n id: defaultAgent.id,\n name: defaultAgent.name,\n description: defaultAgent.description,\n }\n : { id: agents.defaultId },\n gateway: {\n status: health.status,\n ready: health.ready,\n httpListening: health.httpListening,\n version: health.version,\n uptime: health.uptime,\n tunnel: {\n state: tunnel.state,\n publicUrl: tunnel.publicUrl,\n connected: tunnel.state === 'connected',\n },\n },\n workflowRuns: {\n active: activeWorkflowRuns,\n attention: attentionWorkflowRuns,\n recent: recentWorkflowRuns,\n },\n nextCronJobs,\n recentCronRuns: recentCronRuns.slice(0, 5).map(toHomeCronRun),\n });\n });\n}\n"],"mappings":"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"}
@@ -1,7 +1,7 @@
1
1
  import { createGatewayRouteLogger } from "../lib/route-logger.js";
2
- import * as os$1 from "node:os";
3
- import * as path$1 from "node:path";
4
2
  import { readdir, realpath, stat } from "node:fs/promises";
3
+ import * as path$1 from "node:path";
4
+ import * as os$1 from "node:os";
5
5
  //#region src/gateway/hono/routes/host-fs.ts
6
6
  const log = createGatewayRouteLogger("HostFs");
7
7
  function jsonError(status, message) {
@@ -115,6 +115,14 @@ const AUTHENTICATED_LAZY_ROUTE_BUNDLES = [
115
115
  return { register: registerModelsRoutes };
116
116
  }
117
117
  },
118
+ {
119
+ id: "ai-assist",
120
+ match: (path) => startsWithAny(path, ["/api/ai"]),
121
+ load: async () => {
122
+ const { registerAiAssistRoutes } = await import("./ai-assist.js");
123
+ return { register: registerAiAssistRoutes };
124
+ }
125
+ },
118
126
  {
119
127
  id: "commands-skills",
120
128
  match: (path) => startsWithAny(path, [