@xopcai/xopc 0.0.83 → 0.0.85

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (457) hide show
  1. package/README.md +2 -0
  2. package/README.zh-CN.md +3 -1
  3. package/dist/browser-ext/manifest.json +1 -1
  4. package/dist/extensions/feishu/src/outbound/media-load.js +1 -1
  5. package/dist/extensions/feishu/src/plugin.d.ts +2 -0
  6. package/dist/extensions/feishu/src/plugin.js +10 -0
  7. package/dist/extensions/feishu/src/plugin.js.map +1 -1
  8. package/dist/extensions/feishu/src/workflow-progress.d.ts +27 -0
  9. package/dist/extensions/feishu/src/workflow-progress.js +99 -0
  10. package/dist/extensions/feishu/src/workflow-progress.js.map +1 -0
  11. package/dist/extensions/telegram/src/plugin.d.ts +2 -0
  12. package/dist/extensions/telegram/src/plugin.js +11 -1
  13. package/dist/extensions/telegram/src/plugin.js.map +1 -1
  14. package/dist/extensions/telegram/src/routing-integration.js +2 -2
  15. package/dist/extensions/telegram/src/workflow-progress.d.ts +24 -0
  16. package/dist/extensions/telegram/src/workflow-progress.js +73 -0
  17. package/dist/extensions/telegram/src/workflow-progress.js.map +1 -0
  18. package/dist/extensions/telegram/xopc.extension.json +1 -1
  19. package/dist/extensions/weixin/src/__tests__/workflow-progress.test.js +158 -0
  20. package/dist/extensions/weixin/src/__tests__/workflow-progress.test.js.map +1 -0
  21. package/dist/extensions/weixin/src/api/api.js +2 -2
  22. package/dist/extensions/weixin/src/auth/accounts.js +1 -1
  23. package/dist/extensions/weixin/src/cdn/upload.js +1 -1
  24. package/dist/extensions/weixin/src/media/data-url.js +1 -1
  25. package/dist/extensions/weixin/src/messaging/debug-mode.js +1 -1
  26. package/dist/extensions/weixin/src/messaging/inbound.js +1 -1
  27. package/dist/extensions/weixin/src/messaging/process-message.js +1 -1
  28. package/dist/extensions/weixin/src/plugin.d.ts +2 -0
  29. package/dist/extensions/weixin/src/plugin.js +11 -1
  30. package/dist/extensions/weixin/src/plugin.js.map +1 -1
  31. package/dist/extensions/weixin/src/storage/sync-buf.js +1 -1
  32. package/dist/extensions/weixin/src/workflow-progress.d.ts +26 -0
  33. package/dist/extensions/weixin/src/workflow-progress.js +99 -0
  34. package/dist/extensions/weixin/src/workflow-progress.js.map +1 -0
  35. package/dist/gateway/static/root/assets/agents-D3_-kNlZ.js +222 -0
  36. package/dist/gateway/static/root/assets/apps-page-D7v7649T.js +1 -0
  37. package/dist/gateway/static/root/assets/channels-settings-nCaMb0a7.js +1 -0
  38. package/dist/gateway/static/root/assets/channels-status-swr-C1gZBcJV.js +8 -0
  39. package/dist/gateway/static/root/assets/createLucideIcon-DPHK1VkS.js +1 -0
  40. package/dist/gateway/static/root/assets/cron-api-CoYK0hlm.js +1 -0
  41. package/dist/gateway/static/root/assets/cron-page-DeGo-Vjc.js +1 -0
  42. package/dist/gateway/static/root/assets/dist-BTWC-BTN.js +45 -0
  43. package/dist/gateway/static/root/assets/{dist-BpQxde0t.js → dist-DaK4dsss.js} +1 -1
  44. package/dist/gateway/static/root/assets/{extension-debug-page-CY27wj_p.js → extension-debug-page-BZngZWbO.js} +1 -1
  45. package/dist/gateway/static/root/assets/extension-page-D6JSyV27.js +1 -0
  46. package/dist/gateway/static/root/assets/extension-settings-page-8PZcmWI7.js +1 -0
  47. package/dist/gateway/static/root/assets/fetch-B2MYHbWg.js +1 -0
  48. package/dist/gateway/static/root/assets/{field-primitives-fa_hiQcX.js → field-primitives-Zzl22MvN.js} +1 -1
  49. package/dist/gateway/static/root/assets/heartbeat-config-api-BtIcpG0O.js +1 -0
  50. package/dist/gateway/static/root/assets/index-D4vM3-P7.js +4700 -0
  51. package/dist/gateway/static/root/assets/index-ew_2L2We.css +1 -0
  52. package/dist/gateway/static/root/assets/logs-page-_d4UJ-qQ.js +1 -0
  53. package/dist/gateway/static/root/assets/sessions-page-5N4aF2Wk.js +1 -0
  54. package/dist/gateway/static/root/assets/settings-form-section-D_tgb8r2.js +1 -0
  55. package/dist/gateway/static/root/assets/settings-page-C18xBt4X.js +3 -0
  56. package/dist/gateway/static/root/assets/share-preview-page-D4EG_vM1.js +2 -0
  57. package/dist/gateway/static/root/assets/skills-page-sPAXhh8w.js +2 -0
  58. package/dist/gateway/static/root/assets/theme-store-DryYl3qD.js +1 -0
  59. package/dist/gateway/static/root/assets/url-BwNL6Rgk.js +3 -0
  60. package/dist/gateway/static/root/assets/utils-CYO9eTCM.js +1 -0
  61. package/dist/gateway/static/root/assets/voice-api-key-field-Ds51havm.js +1 -0
  62. package/dist/gateway/static/root/index.html +7 -6
  63. package/dist/package.js +1 -1
  64. package/dist/src/agent/agent-manager.js +7 -7
  65. package/dist/src/agent/bootstrap/load-bootstrap-files.js +1 -1
  66. package/dist/src/agent/context/workspace-seed.js +3 -3
  67. package/dist/src/agent/embedded/map-stream-events.js +6 -0
  68. package/dist/src/agent/embedded/map-stream-events.js.map +1 -1
  69. package/dist/src/agent/embedded/subscribe-session.js +24 -0
  70. package/dist/src/agent/embedded/subscribe-session.js.map +1 -1
  71. package/dist/src/agent/embedded/types.d.ts +19 -0
  72. package/dist/src/agent/goals/goal-locale.js +2 -2
  73. package/dist/src/agent/goals/goal-run-store.js +4 -4
  74. package/dist/src/agent/goals/persistent-goal-service.js +1 -1
  75. package/dist/src/agent/goals/post-turn.js +2 -2
  76. package/dist/src/agent/image/load-image-media.js +2 -2
  77. package/dist/src/agent/ipc/bus.js +1 -1
  78. package/dist/src/agent/ipc/inbox.js +2 -2
  79. package/dist/src/agent/ipc/socket.js +1 -1
  80. package/dist/src/agent/memory/builtin-memory-store.js +1 -1
  81. package/dist/src/agent/memory/dreaming/deep-promotion.js +1 -1
  82. package/dist/src/agent/memory/dreaming/events.js +1 -1
  83. package/dist/src/agent/memory/dreaming/last-run.js +1 -1
  84. package/dist/src/agent/memory/dreaming/light-sweep.js +1 -1
  85. package/dist/src/agent/memory/dreaming/preview.js +1 -1
  86. package/dist/src/agent/memory/dreaming/rem-patterns.js +1 -1
  87. package/dist/src/agent/memory/dreaming/short-term-store.js +1 -1
  88. package/dist/src/agent/memory/dreaming/utils.js +1 -1
  89. package/dist/src/agent/memory/plugin-discovery.js +1 -1
  90. package/dist/src/agent/models/manager.js +1 -1
  91. package/dist/src/agent/prompt/service-prompt-builder.js +2 -2
  92. package/dist/src/agent/reply/post-compaction-context.js +1 -1
  93. package/dist/src/agent/reply/startup-context.d.ts +3 -0
  94. package/dist/src/agent/reply/startup-context.js +25 -2
  95. package/dist/src/agent/reply/startup-context.js.map +1 -1
  96. package/dist/src/agent/reply/workspace-boundary-read.js +1 -1
  97. package/dist/src/agent/sandbox/path-policy.js +2 -2
  98. package/dist/src/agent/service/build-direct-message-content.js +1 -1
  99. package/dist/src/agent/service.d.ts +1 -0
  100. package/dist/src/agent/service.js +10 -4
  101. package/dist/src/agent/service.js.map +1 -1
  102. package/dist/src/agent/session/session-inspector.js +1 -1
  103. package/dist/src/agent/skills/config.js +1 -1
  104. package/dist/src/agent/skills/hub-hash.js +2 -2
  105. package/dist/src/agent/skills/hub-lock.js +1 -1
  106. package/dist/src/agent/skills/hub-pull.js +3 -3
  107. package/dist/src/agent/skills/index.js +1 -1
  108. package/dist/src/agent/skills/managed-store.js +1 -1
  109. package/dist/src/agent/skills/scanner.js +1 -1
  110. package/dist/src/agent/skills/skill-manage-ops.js +1 -1
  111. package/dist/src/agent/skills/skill-manager.js +1 -1
  112. package/dist/src/agent/tools/create-share-tool.d.ts +27 -0
  113. package/dist/src/agent/tools/create-share-tool.js +237 -0
  114. package/dist/src/agent/tools/create-share-tool.js.map +1 -0
  115. package/dist/src/agent/tools/dreaming-tool.js +1 -1
  116. package/dist/src/agent/tools/factory.js +35 -1
  117. package/dist/src/agent/tools/factory.js.map +1 -1
  118. package/dist/src/agent/tools/image-generate-tool.js +1 -1
  119. package/dist/src/agent/tools/index.d.ts +2 -0
  120. package/dist/src/agent/tools/index.js +3 -1
  121. package/dist/src/agent/tools/send-media.js +1 -1
  122. package/dist/src/agent/tools/skill-manage-tool.js +1 -1
  123. package/dist/src/agent/tools/workflow-tool.d.ts +41 -0
  124. package/dist/src/agent/tools/workflow-tool.js +271 -0
  125. package/dist/src/agent/tools/workflow-tool.js.map +1 -0
  126. package/dist/src/agent/tools/write.js +1 -1
  127. package/dist/src/agent/workflow/builtins/audit-repo.d.ts +9 -0
  128. package/dist/src/agent/workflow/builtins/audit-repo.js +115 -0
  129. package/dist/src/agent/workflow/builtins/audit-repo.js.map +1 -0
  130. package/dist/src/agent/workflow/builtins/index.d.ts +15 -0
  131. package/dist/src/agent/workflow/builtins/index.js +28 -0
  132. package/dist/src/agent/workflow/builtins/index.js.map +1 -0
  133. package/dist/src/agent/workflow/builtins/multi-perspective-review.d.ts +9 -0
  134. package/dist/src/agent/workflow/builtins/multi-perspective-review.js +113 -0
  135. package/dist/src/agent/workflow/builtins/multi-perspective-review.js.map +1 -0
  136. package/dist/src/agent/workflow/builtins/research.d.ts +9 -0
  137. package/dist/src/agent/workflow/builtins/research.js +129 -0
  138. package/dist/src/agent/workflow/builtins/research.js.map +1 -0
  139. package/dist/src/agent/workflow/catalog.d.ts +51 -0
  140. package/dist/src/agent/workflow/catalog.js +155 -0
  141. package/dist/src/agent/workflow/catalog.js.map +1 -0
  142. package/dist/src/agent/workflow/channel-capability.d.ts +76 -0
  143. package/dist/src/agent/workflow/channel-capability.js +1 -0
  144. package/dist/src/agent/workflow/index.d.ts +11 -0
  145. package/dist/src/agent/workflow/index.js +10 -0
  146. package/dist/src/agent/workflow/last-run-memory.d.ts +42 -0
  147. package/dist/src/agent/workflow/last-run-memory.js +60 -0
  148. package/dist/src/agent/workflow/last-run-memory.js.map +1 -0
  149. package/dist/src/agent/workflow/parser.d.ts +20 -0
  150. package/dist/src/agent/workflow/parser.js +137 -0
  151. package/dist/src/agent/workflow/parser.js.map +1 -0
  152. package/dist/src/agent/workflow/progress-broker.d.ts +80 -0
  153. package/dist/src/agent/workflow/progress-broker.js +263 -0
  154. package/dist/src/agent/workflow/progress-broker.js.map +1 -0
  155. package/dist/src/agent/workflow/runtime.d.ts +31 -0
  156. package/dist/src/agent/workflow/runtime.js +301 -0
  157. package/dist/src/agent/workflow/runtime.js.map +1 -0
  158. package/dist/src/agent/workflow/snapshot.d.ts +18 -0
  159. package/dist/src/agent/workflow/snapshot.js +144 -0
  160. package/dist/src/agent/workflow/snapshot.js.map +1 -0
  161. package/dist/src/agent/workflow/structured-output-tool.d.ts +33 -0
  162. package/dist/src/agent/workflow/structured-output-tool.js +58 -0
  163. package/dist/src/agent/workflow/structured-output-tool.js.map +1 -0
  164. package/dist/src/agent/workflow/subagent-runner.d.ts +42 -0
  165. package/dist/src/agent/workflow/subagent-runner.js +104 -0
  166. package/dist/src/agent/workflow/subagent-runner.js.map +1 -0
  167. package/dist/src/agent/workflow/types.d.ts +137 -0
  168. package/dist/src/agent/workflow/types.js +1 -0
  169. package/dist/src/auth/credentials.js +3 -3
  170. package/dist/src/auth/profiles/store.js +1 -1
  171. package/dist/src/auth/sync-provider-auth.js +1 -1
  172. package/dist/src/browser/cache-dir-policy.js +1 -1
  173. package/dist/src/browser/cdp-local-launcher.js +2 -2
  174. package/dist/src/browser/providers/browser-ext-install.js +4 -4
  175. package/dist/src/browser/providers/cloakbrowser.js +4 -4
  176. package/dist/src/browser/providers/playwright-doctor.js +1 -1
  177. package/dist/src/browser/stealth.js +1 -1
  178. package/dist/src/channels/attachments/inbound-persist.js +1 -1
  179. package/dist/src/channels/attachments/outbound-tts-persist.js +1 -1
  180. package/dist/src/channels/outbound/persist-store.js +1 -1
  181. package/dist/src/channels/pairing/allow-from-file.js +1 -1
  182. package/dist/src/channels/pairing/pairing-store.js +2 -2
  183. package/dist/src/chat-commands/builtins/config.js +2 -2
  184. package/dist/src/chat-commands/builtins/model.js +40 -23
  185. package/dist/src/chat-commands/builtins/model.js.map +1 -1
  186. package/dist/src/chat-commands/builtins/system.js +30 -15
  187. package/dist/src/chat-commands/builtins/system.js.map +1 -1
  188. package/dist/src/chat-commands/builtins/workflow.d.ts +18 -0
  189. package/dist/src/chat-commands/builtins/workflow.js +167 -0
  190. package/dist/src/chat-commands/builtins/workflow.js.map +1 -0
  191. package/dist/src/chat-commands/context.js +1 -1
  192. package/dist/src/chat-commands/format-output.d.ts +28 -0
  193. package/dist/src/chat-commands/format-output.js +45 -0
  194. package/dist/src/chat-commands/format-output.js.map +1 -0
  195. package/dist/src/chat-commands/index.d.ts +1 -0
  196. package/dist/src/chat-commands/index.js +3 -1
  197. package/dist/src/chat-commands/index.js.map +1 -1
  198. package/dist/src/cli/command-catalog.js +110 -8
  199. package/dist/src/cli/command-catalog.js.map +1 -1
  200. package/dist/src/cli/command-loaders.js +2 -0
  201. package/dist/src/cli/command-loaders.js.map +1 -1
  202. package/dist/src/cli/command-manifest.js +9 -1
  203. package/dist/src/cli/command-manifest.js.map +1 -1
  204. package/dist/src/cli/commands/config.js +71 -20
  205. package/dist/src/cli/commands/config.js.map +1 -1
  206. package/dist/src/cli/commands/cron-cli.d.ts +2 -0
  207. package/dist/src/cli/commands/cron-cli.js +15 -0
  208. package/dist/src/cli/commands/cron-cli.js.map +1 -0
  209. package/dist/src/cli/commands/cron.d.ts +4 -1
  210. package/dist/src/cli/commands/cron.js +76 -41
  211. package/dist/src/cli/commands/cron.js.map +1 -1
  212. package/dist/src/cli/commands/doctor/checks/channel-config.js +1 -1
  213. package/dist/src/cli/commands/doctor/checks/channel-config.js.map +1 -1
  214. package/dist/src/cli/commands/doctor/checks/config-health.js +2 -2
  215. package/dist/src/cli/commands/doctor/checks/config-health.js.map +1 -1
  216. package/dist/src/cli/commands/doctor/checks/cron-health.js +1 -1
  217. package/dist/src/cli/commands/doctor/checks/cron-health.js.map +1 -1
  218. package/dist/src/cli/commands/doctor/checks/gateway-health.js +2 -2
  219. package/dist/src/cli/commands/doctor/checks/gateway-health.js.map +1 -1
  220. package/dist/src/cli/commands/doctor/checks/gateway-service.js +2 -2
  221. package/dist/src/cli/commands/doctor/checks/gateway-service.js.map +1 -1
  222. package/dist/src/cli/commands/doctor/checks/provider-auth.js +1 -1
  223. package/dist/src/cli/commands/doctor/checks/session-integrity.js +1 -1
  224. package/dist/src/cli/commands/doctor/checks/state-integrity.js +2 -2
  225. package/dist/src/cli/commands/doctor/checks/state-integrity.js.map +1 -1
  226. package/dist/src/cli/commands/doctor/checks/workspace-status.js +4 -4
  227. package/dist/src/cli/commands/doctor/checks/workspace-status.js.map +1 -1
  228. package/dist/src/cli/commands/extension-dev.js +1 -1
  229. package/dist/src/cli/commands/extension-marketplace.js +1 -1
  230. package/dist/src/cli/commands/extension-pack.js +1 -1
  231. package/dist/src/cli/commands/gateway/index.d.ts +1 -1
  232. package/dist/src/cli/commands/gateway/index.js +2 -2
  233. package/dist/src/cli/commands/gateway/lifecycle.js +10 -4
  234. package/dist/src/cli/commands/gateway/lifecycle.js.map +1 -1
  235. package/dist/src/cli/commands/gateway/service.d.ts +4 -0
  236. package/dist/src/cli/commands/gateway/service.js +17 -2
  237. package/dist/src/cli/commands/gateway/service.js.map +1 -1
  238. package/dist/src/cli/commands/gateway/shared.js +1 -1
  239. package/dist/src/cli/commands/gateway/subcommands.js +1 -4
  240. package/dist/src/cli/commands/gateway/subcommands.js.map +1 -1
  241. package/dist/src/cli/commands/image.js +1 -1
  242. package/dist/src/cli/commands/init.js +31 -4
  243. package/dist/src/cli/commands/init.js.map +1 -1
  244. package/dist/src/cli/commands/models.d.ts +4 -1
  245. package/dist/src/cli/commands/models.js +86 -74
  246. package/dist/src/cli/commands/models.js.map +1 -1
  247. package/dist/src/cli/commands/onboard.js +4 -2
  248. package/dist/src/cli/commands/onboard.js.map +1 -1
  249. package/dist/src/cli/commands/profile.d.ts +3 -5
  250. package/dist/src/cli/commands/profile.js +31 -31
  251. package/dist/src/cli/commands/profile.js.map +1 -1
  252. package/dist/src/cli/commands/setup.js +6 -1
  253. package/dist/src/cli/commands/setup.js.map +1 -1
  254. package/dist/src/cli/commands/tunnel.js +2 -2
  255. package/dist/src/cli/gateway-run-argv.js +15 -5
  256. package/dist/src/cli/gateway-run-argv.js.map +1 -1
  257. package/dist/src/cli/utils/gateway-client.js +1 -1
  258. package/dist/src/cli/utils/init-workspace-core.js +2 -2
  259. package/dist/src/config/agent-profile.js +1 -1
  260. package/dist/src/config/gateway-bind.js +1 -1
  261. package/dist/src/config/index.js +5 -5
  262. package/dist/src/config/loader.js +2 -2
  263. package/dist/src/config/models-json.js +2 -2
  264. package/dist/src/config/paths-state.js +1 -1
  265. package/dist/src/config/profile.js +2 -2
  266. package/dist/src/config/public-url.d.ts +28 -0
  267. package/dist/src/config/public-url.js +103 -0
  268. package/dist/src/config/public-url.js.map +1 -0
  269. package/dist/src/config/schema.d.ts +82 -0
  270. package/dist/src/config/schema.js +130 -1
  271. package/dist/src/config/schema.js.map +1 -1
  272. package/dist/src/config/workspace-path.js +1 -1
  273. package/dist/src/cron/executor.js +2 -2
  274. package/dist/src/cron/persistence.js +1 -1
  275. package/dist/src/cron/run-log-store.js +1 -1
  276. package/dist/src/daemon/constants.js +1 -1
  277. package/dist/src/daemon/install-plan.js +3 -3
  278. package/dist/src/daemon/install-plan.js.map +1 -1
  279. package/dist/src/daemon/launchd.js +2 -2
  280. package/dist/src/daemon/schtasks.js +38 -1
  281. package/dist/src/daemon/schtasks.js.map +1 -1
  282. package/dist/src/daemon/systemd.js +2 -2
  283. package/dist/src/extensions/bundle-mcp.js +1 -1
  284. package/dist/src/extensions/discover-extensions.js +1 -1
  285. package/dist/src/extensions/health.js +1 -1
  286. package/dist/src/extensions/loader.js +1 -1
  287. package/dist/src/extensions/lockfile.js +2 -2
  288. package/dist/src/gateway/agents-admin.js +2 -2
  289. package/dist/src/gateway/file-path-classifier.js +2 -2
  290. package/dist/src/gateway/heartbeat/service.js +1 -1
  291. package/dist/src/gateway/hono/app.js +33 -2
  292. package/dist/src/gateway/hono/app.js.map +1 -1
  293. package/dist/src/gateway/hono/lib/config-payload.js +1 -1
  294. package/dist/src/gateway/hono/lib/extension-store.js +2 -2
  295. package/dist/src/gateway/hono/lib/static-ui.js +2 -2
  296. package/dist/src/gateway/hono/oauth.js +1 -1
  297. package/dist/src/gateway/hono/routes/agents.js +1 -1
  298. package/dist/src/gateway/hono/routes/auth-registry-extensions.js +1 -1
  299. package/dist/src/gateway/hono/routes/config-patch/misc.js +1 -1
  300. package/dist/src/gateway/hono/routes/dreaming.js +1 -1
  301. package/dist/src/gateway/hono/routes/host-fs.js +2 -2
  302. package/dist/src/gateway/hono/routes/lazy-bundles.js +8 -0
  303. package/dist/src/gateway/hono/routes/lazy-bundles.js.map +1 -1
  304. package/dist/src/gateway/hono/routes/models.js +1 -1
  305. package/dist/src/gateway/hono/routes/shares.js +631 -34
  306. package/dist/src/gateway/hono/routes/shares.js.map +1 -1
  307. package/dist/src/gateway/hono/routes/site-shares.d.ts +3 -0
  308. package/dist/src/gateway/hono/routes/site-shares.js +228 -0
  309. package/dist/src/gateway/hono/routes/site-shares.js.map +1 -0
  310. package/dist/src/gateway/hono/routes/tunnel.js +97 -8
  311. package/dist/src/gateway/hono/routes/tunnel.js.map +1 -1
  312. package/dist/src/gateway/hono/routes/workspace.js +5 -5
  313. package/dist/src/gateway/hono/sse.js +2 -2
  314. package/dist/src/gateway/host.d.ts +3 -1
  315. package/dist/src/gateway/host.js +3 -1
  316. package/dist/src/gateway/host.js.map +1 -1
  317. package/dist/src/gateway/lock.js +3 -3
  318. package/dist/src/gateway/ports.d.ts +6 -0
  319. package/dist/src/gateway/ports.js +38 -2
  320. package/dist/src/gateway/ports.js.map +1 -1
  321. package/dist/src/gateway/public-url.d.ts +8 -0
  322. package/dist/src/gateway/public-url.js +10 -0
  323. package/dist/src/gateway/public-url.js.map +1 -0
  324. package/dist/src/gateway/security/origin-check.d.ts +9 -1
  325. package/dist/src/gateway/security/origin-check.js +4 -0
  326. package/dist/src/gateway/security/origin-check.js.map +1 -1
  327. package/dist/src/gateway/server.js +15 -0
  328. package/dist/src/gateway/server.js.map +1 -1
  329. package/dist/src/gateway/service/agent-runner.js +2 -2
  330. package/dist/src/gateway/service/marketplace-service.js +2 -2
  331. package/dist/src/gateway/service/run-gateway-agent.js +2 -2
  332. package/dist/src/gateway/service.js +3 -2
  333. package/dist/src/gateway/service.js.map +1 -1
  334. package/dist/src/gateway/workspace-fs-file-list.js +1 -1
  335. package/dist/src/heartbeat/index.js +1 -1
  336. package/dist/src/i18n/goals-bundle.js +1 -1
  337. package/dist/src/i18n/index.d.ts +1 -0
  338. package/dist/src/i18n/index.js +2 -1
  339. package/dist/src/i18n/locales/share-tool.en.js +15 -0
  340. package/dist/src/i18n/locales/share-tool.en.js.map +1 -0
  341. package/dist/src/i18n/locales/share-tool.zh.js +15 -0
  342. package/dist/src/i18n/locales/share-tool.zh.js.map +1 -0
  343. package/dist/src/i18n/share-tool-bundle.d.ts +20 -0
  344. package/dist/src/i18n/share-tool-bundle.js +56 -0
  345. package/dist/src/i18n/share-tool-bundle.js.map +1 -0
  346. package/dist/src/infra/gateway-processes.js +1 -0
  347. package/dist/src/infra/gateway-processes.js.map +1 -1
  348. package/dist/src/infra/restart.js +2 -2
  349. package/dist/src/infra/update-check.js +1 -1
  350. package/dist/src/infra/update-lock.js +3 -3
  351. package/dist/src/infra/update-runner.js +1 -1
  352. package/dist/src/infra/update-startup.js +2 -2
  353. package/dist/src/infra/write-file-atomic.js +2 -2
  354. package/dist/src/providers/auth-runtime/auth-profile-store.js +1 -1
  355. package/dist/src/providers/index.js +2 -2
  356. package/dist/src/providers/model-registry.js +1 -1
  357. package/dist/src/session/config-store.js +2 -2
  358. package/dist/src/session/parity/jsonl-transcript-io.js +2 -2
  359. package/dist/src/session/parity/sessions-json-file.js +1 -1
  360. package/dist/src/session/parity/transcript-file-lock.js +2 -2
  361. package/dist/src/session/parity/transcript-paths.js +1 -1
  362. package/dist/src/session/search-index-cache.js +1 -1
  363. package/dist/src/session/search-index.js +1 -1
  364. package/dist/src/session/session-title.js +3 -2
  365. package/dist/src/session/session-title.js.map +1 -1
  366. package/dist/src/session/store.js +5 -5
  367. package/dist/src/share/share-auto.d.ts +74 -0
  368. package/dist/src/share/share-auto.js +247 -0
  369. package/dist/src/share/share-auto.js.map +1 -0
  370. package/dist/src/share/share-config.js +63 -4
  371. package/dist/src/share/share-config.js.map +1 -1
  372. package/dist/src/share/share-landing.d.ts +28 -2
  373. package/dist/src/share/share-landing.js +155 -34
  374. package/dist/src/share/share-landing.js.map +1 -1
  375. package/dist/src/share/share-store.d.ts +48 -4
  376. package/dist/src/share/share-store.js +322 -51
  377. package/dist/src/share/share-store.js.map +1 -1
  378. package/dist/src/share/share-thumbnail.d.ts +35 -0
  379. package/dist/src/share/share-thumbnail.js +277 -0
  380. package/dist/src/share/share-thumbnail.js.map +1 -0
  381. package/dist/src/share/share-types.d.ts +68 -10
  382. package/dist/src/share/share-types.js +18 -1
  383. package/dist/src/share/share-types.js.map +1 -1
  384. package/dist/src/share/share-url.js +1 -1
  385. package/dist/src/share/share-zip.d.ts +35 -0
  386. package/dist/src/share/share-zip.js +303 -0
  387. package/dist/src/share/share-zip.js.map +1 -0
  388. package/dist/src/share/site-proxy.d.ts +35 -0
  389. package/dist/src/share/site-proxy.js +234 -0
  390. package/dist/src/share/site-proxy.js.map +1 -0
  391. package/dist/src/share/site-share-config.d.ts +11 -0
  392. package/dist/src/share/site-share-config.js +103 -0
  393. package/dist/src/share/site-share-config.js.map +1 -0
  394. package/dist/src/share/site-share-router.d.ts +23 -0
  395. package/dist/src/share/site-share-router.js +147 -0
  396. package/dist/src/share/site-share-router.js.map +1 -0
  397. package/dist/src/share/site-share-store.d.ts +53 -0
  398. package/dist/src/share/site-share-store.js +400 -0
  399. package/dist/src/share/site-share-store.js.map +1 -0
  400. package/dist/src/share/site-share-types.d.ts +103 -0
  401. package/dist/src/share/site-share-types.js +41 -0
  402. package/dist/src/share/site-share-types.js.map +1 -0
  403. package/dist/src/share/site-static-serve.d.ts +10 -0
  404. package/dist/src/share/site-static-serve.js +145 -0
  405. package/dist/src/share/site-static-serve.js.map +1 -0
  406. package/dist/src/tui/clipboard-image.js +3 -3
  407. package/dist/src/tui/theme-manager.js +1 -1
  408. package/dist/src/tui/tui-commands.js +18 -0
  409. package/dist/src/tui/tui-commands.js.map +1 -1
  410. package/dist/src/tui/tui-keybindings-file.js +1 -1
  411. package/dist/src/tui/tui-scoped-models.js +2 -2
  412. package/dist/src/tui/tui-settings.js +1 -1
  413. package/dist/src/tui/tui-workflow-slash.d.ts +32 -0
  414. package/dist/src/tui/tui-workflow-slash.js +63 -0
  415. package/dist/src/tui/tui-workflow-slash.js.map +1 -0
  416. package/dist/src/tui/tui.js +2 -2
  417. package/dist/src/tunnel/enable-lan-pairing.js +1 -1
  418. package/dist/src/tunnel/frpc-binary.js +3 -3
  419. package/dist/src/tunnel/frpc-config.js +1 -1
  420. package/dist/src/tunnel/frpc-extract.js +1 -1
  421. package/dist/src/tunnel/index.js +2 -2
  422. package/dist/src/tunnel/pair-context.d.ts +7 -1
  423. package/dist/src/tunnel/pair-context.js +25 -9
  424. package/dist/src/tunnel/pair-context.js.map +1 -1
  425. package/dist/src/tunnel/pair-url.d.ts +14 -1
  426. package/dist/src/tunnel/pair-url.js +14 -1
  427. package/dist/src/tunnel/pair-url.js.map +1 -1
  428. package/dist/src/tunnel/tunnel-service.js +2 -2
  429. package/dist/src/tunnel/tunnel-state.js +1 -1
  430. package/dist/src/utils/logger/audit.js +1 -1
  431. package/dist/src/utils/logger/log-store.js +1 -1
  432. package/dist/src/utils/logger/rotation.js +1 -1
  433. package/dist/src/voice/tts/audio.js +1 -1
  434. package/dist/src/voice/tts/providers/edge-speech.js +2 -2
  435. package/package.json +3 -2
  436. package/dist/gateway/static/root/assets/agents-CrpYTHJS.js +0 -222
  437. package/dist/gateway/static/root/assets/apps-page-1mcKh5Rh.js +0 -1
  438. package/dist/gateway/static/root/assets/button-KafIU8dx.js +0 -1
  439. package/dist/gateway/static/root/assets/channels-settings-zd6QNKPx.js +0 -1
  440. package/dist/gateway/static/root/assets/channels-status-swr-uRAuhiUo.js +0 -8
  441. package/dist/gateway/static/root/assets/cron-api-O2Q_ruV6.js +0 -1
  442. package/dist/gateway/static/root/assets/cron-page-By09AQD-.js +0 -1
  443. package/dist/gateway/static/root/assets/dist-C57OMHW8.js +0 -48
  444. package/dist/gateway/static/root/assets/extension-page-C-Ed5ZmP.js +0 -1
  445. package/dist/gateway/static/root/assets/extension-settings-page-raLux7E7.js +0 -1
  446. package/dist/gateway/static/root/assets/fetch-2iRFmd3n.js +0 -3
  447. package/dist/gateway/static/root/assets/heartbeat-config-api-BVl5VHvL.js +0 -1
  448. package/dist/gateway/static/root/assets/index-BuFldCsB.css +0 -1
  449. package/dist/gateway/static/root/assets/index-Y-iqo-gL.js +0 -4693
  450. package/dist/gateway/static/root/assets/logs-page-BdH2n7ZW.js +0 -1
  451. package/dist/gateway/static/root/assets/sessions-page-Vpchzdp-.js +0 -1
  452. package/dist/gateway/static/root/assets/settings-form-section-Kk1yAGBl.js +0 -1
  453. package/dist/gateway/static/root/assets/settings-page-KBm0u6Dz.js +0 -3
  454. package/dist/gateway/static/root/assets/skills-page-BjeXXaOn.js +0 -2
  455. package/dist/gateway/static/root/assets/theme-store-D01dJt95.js +0 -1
  456. package/dist/gateway/static/root/assets/utils-DpTxN4AF.js +0 -1
  457. package/dist/gateway/static/root/assets/voice-api-key-field-CwO8Cf01.js +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"schtasks.js","names":[],"sources":["../../../src/daemon/schtasks.ts"],"sourcesContent":["/**\n * Scheduled Task Service - Windows service management via schtasks\n *\n * Aligned with OpenClaw Windows implementation:\n * - Task with ONLOGON trigger for persistence\n * - RepetitionInterval for keep-alive behavior\n * - Proper start/stop/restart lifecycle\n */\n\nimport { spawn, spawnSync } from 'node:child_process';\nimport { createLogger } from '../utils/logger.js';\nimport { resolveGatewayWindowsTaskName } from './constants.js';\nimport type {\n GatewayService,\n GatewayServiceInstallArgs,\n GatewayServiceControlArgs,\n GatewayServiceEnvArgs,\n GatewayServiceRuntime,\n GatewayServiceCommandConfig,\n GatewayServiceEnv,\n GatewayServiceRestartResult,\n} from './types.js';\n\nconst log = createLogger('SchtasksService');\n\n// ─── Resolution ───\n\nfunction resolveProfileFromEnv(env?: GatewayServiceEnv): string | undefined {\n return env?.XOPC_PROFILE?.trim() || undefined;\n}\n\nfunction resolveTaskName(env?: GatewayServiceEnv): string {\n return resolveGatewayWindowsTaskName(resolveProfileFromEnv(env));\n}\n\n// ─── Command Execution ───\n\ninterface SchtasksResult {\n stdout: string;\n stderr: string;\n exitCode: number | null;\n}\n\nasync function schtasks(args: string[]): Promise<SchtasksResult> {\n return new Promise<SchtasksResult>((resolve, reject) => {\n const child = spawn('schtasks', args, {\n stdio: ['ignore', 'pipe', 'pipe'],\n shell: true,\n });\n\n let stdout = '';\n let stderr = '';\n\n child.stdout?.on('data', (data) => { stdout += data.toString(); });\n child.stderr?.on('data', (data) => { stderr += data.toString(); });\n\n child.on('close', (code) => {\n resolve({ stdout, stderr, exitCode: code });\n });\n child.on('error', (err) => {\n reject(new Error(`schtasks spawn failed: ${err.message}`));\n });\n });\n}\n\nasync function schtasksExec(args: string[]): Promise<string> {\n const result = await schtasks(args);\n if (result.exitCode !== 0) {\n const detail = result.stderr.trim() || result.stdout.trim();\n throw new Error(`schtasks failed (exit ${result.exitCode}): ${detail}`);\n }\n return result.stdout;\n}\n\n// ─── Availability Check ───\n\nexport function isSchtasksAvailable(): boolean {\n if (process.platform !== 'win32') return false;\n try {\n const result = spawnSync('schtasks', ['/query', '/?'], {\n stdio: ['ignore', 'ignore', 'ignore'],\n shell: true,\n timeout: 3000,\n });\n return result.status === 0;\n } catch {\n return false;\n }\n}\n\n// ─── Service Implementation ───\n\nexport const schtasksService: GatewayService = {\n label: resolveGatewayWindowsTaskName(),\n loadedText: 'Scheduled Task (installed)',\n notLoadedText: 'Scheduled Task (not installed)',\n\n async install(args: GatewayServiceInstallArgs): Promise<void> {\n const taskName = resolveTaskName(args.env);\n const program = args.programArguments[0];\n const programArgs = args.programArguments.slice(1).join(' ');\n\n // Delete existing task first (ignore errors)\n try {\n await schtasks(['/delete', '/tn', taskName, '/f']);\n } catch {\n // Ignore\n }\n\n // Create task with ONLOGON trigger\n const createArgs = [\n '/create',\n '/tn', taskName,\n '/tr', `\"${program}\" ${programArgs}`,\n '/sc', 'ONLOGON',\n '/rl', 'LIMITED',\n '/f',\n ];\n\n await schtasksExec(createArgs);\n\n args.stdout?.write(`Created scheduled task: ${taskName}\\n`);\n args.stdout?.write(` Program: ${program}\\n`);\n args.stdout?.write(` Args: ${programArgs}\\n`);\n\n log.info({ taskName }, 'Scheduled task installed');\n },\n\n async uninstall(args: GatewayServiceControlArgs): Promise<void> {\n const taskName = resolveTaskName(args.env);\n\n // Stop if running\n try {\n await schtasks(['/end', '/tn', taskName]);\n } catch {\n // Ignore\n }\n\n // Delete task\n try {\n await schtasksExec(['/delete', '/tn', taskName, '/f']);\n args.stdout?.write(`Deleted scheduled task: ${taskName}\\n`);\n } catch (err) {\n log.debug({ err }, 'Uninstall task not found');\n }\n\n log.info({ taskName }, 'Scheduled task uninstalled');\n },\n\n async stop(args: GatewayServiceControlArgs): Promise<void> {\n const taskName = resolveTaskName(args.env);\n\n try {\n await schtasksExec(['/end', '/tn', taskName]);\n } catch {\n log.debug('Task not running');\n }\n\n if (args.disable) {\n try {\n await schtasksExec(['/change', '/tn', taskName, '/disable']);\n } catch {\n // Ignore\n }\n }\n\n log.info('Scheduled task stopped');\n },\n\n async restart(args: GatewayServiceControlArgs): Promise<GatewayServiceRestartResult> {\n const taskName = resolveTaskName(args.env);\n\n // End current run\n try {\n await schtasks(['/end', '/tn', taskName]);\n } catch {\n // Ignore\n }\n\n // Small delay for process cleanup\n await new Promise((resolve) => setTimeout(resolve, 500));\n\n // Start new run\n await schtasksExec(['/run', '/tn', taskName]);\n\n log.info('Scheduled task restarted');\n return { outcome: 'restarted' };\n },\n\n async isLoaded(args: GatewayServiceEnvArgs): Promise<boolean> {\n const taskName = resolveTaskName(args.env);\n const result = await schtasks(['/query', '/tn', taskName]);\n return result.exitCode === 0;\n },\n\n async readRuntime(env?: GatewayServiceEnv): Promise<GatewayServiceRuntime> {\n const taskName = resolveTaskName(env);\n\n try {\n const result = await schtasks(['/query', '/tn', taskName, '/fo', 'list', '/v']);\n if (result.exitCode !== 0) {\n return { status: 'unknown' };\n }\n\n const output = result.stdout;\n let status: 'running' | 'stopped' | 'unknown' = 'unknown';\n\n const statusMatch = output.match(/Status:\\s*(\\w+)/i);\n if (statusMatch) {\n const statusStr = statusMatch[1].toLowerCase();\n if (statusStr === 'running') {\n status = 'running';\n } else if (statusStr === 'ready' || statusStr === 'disabled') {\n status = 'stopped';\n }\n }\n\n // Parse last result code\n let lastExitStatus: number | undefined;\n const resultMatch = output.match(/Last Result:\\s*(\\d+)/i);\n if (resultMatch) {\n lastExitStatus = parseInt(resultMatch[1], 10);\n }\n\n return { status, lastExitStatus };\n } catch {\n return { status: 'unknown' };\n }\n },\n\n async readCommand(env?: GatewayServiceEnv): Promise<GatewayServiceCommandConfig | null> {\n const taskName = resolveTaskName(env);\n\n try {\n const result = await schtasks(['/query', '/tn', taskName, '/fo', 'list', '/v']);\n if (result.exitCode !== 0) return null;\n\n const output = result.stdout;\n const taskRunMatch = output.match(/Task To Run:\\s*(.+)/i);\n const workDirMatch = output.match(/Start In:\\s*(.+)/i);\n\n if (!taskRunMatch) return null;\n\n const taskRun = taskRunMatch[1].trim();\n // Handle quoted program path\n let programArguments: string[];\n if (taskRun.startsWith('\"')) {\n const closeQuote = taskRun.indexOf('\"', 1);\n if (closeQuote > 0) {\n const program = taskRun.slice(1, closeQuote);\n const rest = taskRun.slice(closeQuote + 1).trim();\n programArguments = [program, ...rest.split(/\\s+/).filter(Boolean)];\n } else {\n programArguments = taskRun.split(/\\s+/);\n }\n } else {\n programArguments = taskRun.split(/\\s+/);\n }\n\n return {\n programArguments,\n workingDirectory: workDirMatch?.[1]?.trim() || undefined,\n };\n } catch {\n return null;\n }\n },\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"schtasks.js","names":[],"sources":["../../../src/daemon/schtasks.ts"],"sourcesContent":["/**\n * Scheduled Task Service - Windows service management via schtasks\n *\n * Aligned with OpenClaw Windows implementation:\n * - Task with ONLOGON trigger for persistence\n * - RepetitionInterval for keep-alive behavior\n * - Proper start/stop/restart lifecycle\n */\n\nimport { spawn, spawnSync } from 'node:child_process';\nimport { mkdirSync, readFileSync, writeFileSync, rmSync } from 'node:fs';\nimport path from 'node:path';\nimport os from 'node:os';\nimport { createLogger } from '../utils/logger.js';\nimport { resolveGatewayWindowsTaskName } from './constants.js';\nimport type {\n GatewayService,\n GatewayServiceInstallArgs,\n GatewayServiceControlArgs,\n GatewayServiceEnvArgs,\n GatewayServiceRuntime,\n GatewayServiceCommandConfig,\n GatewayServiceEnv,\n GatewayServiceRestartResult,\n} from './types.js';\n\nconst log = createLogger('SchtasksService');\n\n// ─── Resolution ───\n\nfunction resolveProfileFromEnv(env?: GatewayServiceEnv): string | undefined {\n return env?.XOPC_PROFILE?.trim() || undefined;\n}\n\nfunction resolveTaskName(env?: GatewayServiceEnv): string {\n return resolveGatewayWindowsTaskName(resolveProfileFromEnv(env));\n}\n\n// ─── Command Execution ───\n\ninterface SchtasksResult {\n stdout: string;\n stderr: string;\n exitCode: number | null;\n}\n\nasync function schtasks(args: string[]): Promise<SchtasksResult> {\n return new Promise<SchtasksResult>((resolve, reject) => {\n const child = spawn('schtasks', args, {\n stdio: ['ignore', 'pipe', 'pipe'],\n shell: true,\n });\n\n let stdout = '';\n let stderr = '';\n\n child.stdout?.on('data', (data) => { stdout += data.toString(); });\n child.stderr?.on('data', (data) => { stderr += data.toString(); });\n\n child.on('close', (code) => {\n resolve({ stdout, stderr, exitCode: code });\n });\n child.on('error', (err) => {\n reject(new Error(`schtasks spawn failed: ${err.message}`));\n });\n });\n}\n\nasync function schtasksExec(args: string[]): Promise<string> {\n const result = await schtasks(args);\n if (result.exitCode !== 0) {\n const detail = result.stderr.trim() || result.stdout.trim();\n throw new Error(`schtasks failed (exit ${result.exitCode}): ${detail}`);\n }\n return result.stdout;\n}\n\n// ─── Environment Sidecar ───\n// schtasks does not natively support per-task environment variables.\n// We persist them in a JSON sidecar so readCommand can return them\n// for version-mismatch detection and other diagnostics.\n\nfunction resolveTaskEnvSidecarPath(taskName: string): string {\n const configDir = path.join(os.homedir(), '.xopc', 'daemon');\n return path.join(configDir, `${taskName}.env.json`);\n}\n\nfunction writeTaskEnvSidecar(taskName: string, environment: Record<string, string>): void {\n const sidecarPath = resolveTaskEnvSidecarPath(taskName);\n try {\n mkdirSync(path.dirname(sidecarPath), { recursive: true });\n writeFileSync(sidecarPath, JSON.stringify(environment, null, 2), 'utf8');\n } catch (err) {\n log.warn({ err, sidecarPath }, 'Failed to write task environment sidecar');\n }\n}\n\nfunction readTaskEnvSidecar(taskName: string): Record<string, string> | undefined {\n const sidecarPath = resolveTaskEnvSidecarPath(taskName);\n try {\n const raw = readFileSync(sidecarPath, 'utf8');\n const parsed = JSON.parse(raw);\n if (parsed && typeof parsed === 'object' && !Array.isArray(parsed)) {\n return parsed as Record<string, string>;\n }\n } catch {\n // Sidecar missing or corrupt — not fatal\n }\n return undefined;\n}\n\nfunction removeTaskEnvSidecar(taskName: string): void {\n const sidecarPath = resolveTaskEnvSidecarPath(taskName);\n try {\n rmSync(sidecarPath, { force: true });\n } catch {\n // Best-effort\n }\n}\n\n// ─── Availability Check ───\n\nexport function isSchtasksAvailable(): boolean {\n if (process.platform !== 'win32') return false;\n try {\n const result = spawnSync('schtasks', ['/query', '/?'], {\n stdio: ['ignore', 'ignore', 'ignore'],\n shell: true,\n timeout: 3000,\n });\n return result.status === 0;\n } catch {\n return false;\n }\n}\n\n// ─── Service Implementation ───\n\nexport const schtasksService: GatewayService = {\n label: resolveGatewayWindowsTaskName(),\n loadedText: 'Scheduled Task (installed)',\n notLoadedText: 'Scheduled Task (not installed)',\n\n async install(args: GatewayServiceInstallArgs): Promise<void> {\n const taskName = resolveTaskName(args.env);\n const program = args.programArguments[0];\n const programArgs = args.programArguments.slice(1).join(' ');\n\n // Delete existing task first (ignore errors)\n try {\n await schtasks(['/delete', '/tn', taskName, '/f']);\n } catch {\n // Ignore\n }\n\n // Create task with ONLOGON trigger\n const createArgs = [\n '/create',\n '/tn', taskName,\n '/tr', `\"${program}\" ${programArgs}`,\n '/sc', 'ONLOGON',\n '/rl', 'LIMITED',\n '/f',\n ];\n\n await schtasksExec(createArgs);\n\n // Persist environment variables in a sidecar file\n // (schtasks does not support per-task env vars natively)\n if (args.environment && Object.keys(args.environment).length > 0) {\n writeTaskEnvSidecar(taskName, args.environment);\n }\n\n args.stdout?.write(`Created scheduled task: ${taskName}\\n`);\n args.stdout?.write(` Program: ${program}\\n`);\n args.stdout?.write(` Args: ${programArgs}\\n`);\n\n log.info({ taskName }, 'Scheduled task installed');\n },\n\n async uninstall(args: GatewayServiceControlArgs): Promise<void> {\n const taskName = resolveTaskName(args.env);\n\n // Stop if running\n try {\n await schtasks(['/end', '/tn', taskName]);\n } catch {\n // Ignore\n }\n\n // Delete task\n try {\n await schtasksExec(['/delete', '/tn', taskName, '/f']);\n args.stdout?.write(`Deleted scheduled task: ${taskName}\\n`);\n } catch (err) {\n log.debug({ err }, 'Uninstall task not found');\n }\n\n // Clean up environment sidecar\n removeTaskEnvSidecar(taskName);\n\n log.info({ taskName }, 'Scheduled task uninstalled');\n },\n\n async stop(args: GatewayServiceControlArgs): Promise<void> {\n const taskName = resolveTaskName(args.env);\n\n try {\n await schtasksExec(['/end', '/tn', taskName]);\n } catch {\n log.debug('Task not running');\n }\n\n if (args.disable) {\n try {\n await schtasksExec(['/change', '/tn', taskName, '/disable']);\n } catch {\n // Ignore\n }\n }\n\n log.info('Scheduled task stopped');\n },\n\n async restart(args: GatewayServiceControlArgs): Promise<GatewayServiceRestartResult> {\n const taskName = resolveTaskName(args.env);\n\n // End current run\n try {\n await schtasks(['/end', '/tn', taskName]);\n } catch {\n // Ignore\n }\n\n // Small delay for process cleanup\n await new Promise((resolve) => setTimeout(resolve, 500));\n\n // Start new run\n await schtasksExec(['/run', '/tn', taskName]);\n\n log.info('Scheduled task restarted');\n return { outcome: 'restarted' };\n },\n\n async isLoaded(args: GatewayServiceEnvArgs): Promise<boolean> {\n const taskName = resolveTaskName(args.env);\n const result = await schtasks(['/query', '/tn', taskName]);\n return result.exitCode === 0;\n },\n\n async readRuntime(env?: GatewayServiceEnv): Promise<GatewayServiceRuntime> {\n const taskName = resolveTaskName(env);\n\n try {\n const result = await schtasks(['/query', '/tn', taskName, '/fo', 'list', '/v']);\n if (result.exitCode !== 0) {\n return { status: 'unknown' };\n }\n\n const output = result.stdout;\n let status: 'running' | 'stopped' | 'unknown' = 'unknown';\n\n const statusMatch = output.match(/Status:\\s*(\\w+)/i);\n if (statusMatch) {\n const statusStr = statusMatch[1].toLowerCase();\n if (statusStr === 'running') {\n status = 'running';\n } else if (statusStr === 'ready' || statusStr === 'disabled') {\n status = 'stopped';\n }\n }\n\n // Parse last result code\n let lastExitStatus: number | undefined;\n const resultMatch = output.match(/Last Result:\\s*(\\d+)/i);\n if (resultMatch) {\n lastExitStatus = parseInt(resultMatch[1], 10);\n }\n\n return { status, lastExitStatus };\n } catch {\n return { status: 'unknown' };\n }\n },\n\n async readCommand(env?: GatewayServiceEnv): Promise<GatewayServiceCommandConfig | null> {\n const taskName = resolveTaskName(env);\n\n try {\n const result = await schtasks(['/query', '/tn', taskName, '/fo', 'list', '/v']);\n if (result.exitCode !== 0) return null;\n\n const output = result.stdout;\n const taskRunMatch = output.match(/Task To Run:\\s*(.+)/i);\n const workDirMatch = output.match(/Start In:\\s*(.+)/i);\n\n if (!taskRunMatch) return null;\n\n const taskRun = taskRunMatch[1].trim();\n // Handle quoted program path\n let programArguments: string[];\n if (taskRun.startsWith('\"')) {\n const closeQuote = taskRun.indexOf('\"', 1);\n if (closeQuote > 0) {\n const program = taskRun.slice(1, closeQuote);\n const rest = taskRun.slice(closeQuote + 1).trim();\n programArguments = [program, ...rest.split(/\\s+/).filter(Boolean)];\n } else {\n programArguments = taskRun.split(/\\s+/);\n }\n } else {\n programArguments = taskRun.split(/\\s+/);\n }\n\n // Read environment from sidecar file (schtasks has no native env support)\n const environment = readTaskEnvSidecar(taskName);\n\n return {\n programArguments,\n workingDirectory: workDirMatch?.[1]?.trim() || undefined,\n environment,\n };\n } catch {\n return null;\n }\n },\n};\n"],"mappings":"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"}
@@ -1,10 +1,10 @@
1
1
  import { createLogger } from "../utils/logger/index.js";
2
2
  import { init_logger } from "../utils/logger.js";
3
3
  import { resolveGatewaySystemdServiceName, resolveSystemdUnitPath } from "./constants.js";
4
+ import os from "node:os";
5
+ import path from "node:path";
4
6
  import { existsSync } from "node:fs";
5
7
  import { access, constants as constants$1, mkdir, readFile, rm, writeFile } from "node:fs/promises";
6
- import path from "node:path";
7
- import os from "node:os";
8
8
  import { spawn, spawnSync } from "node:child_process";
9
9
  //#region src/daemon/systemd.ts
10
10
  /**
@@ -1,8 +1,8 @@
1
1
  import { init_paths, resolveBundledExtensionsDir, resolveExtensionsDir } from "../config/paths.js";
2
2
  import { isRecord } from "../utils/is-record.js";
3
3
  import { normalizeConfiguredMcpServers } from "../config/mcp-config-normalize.js";
4
- import { existsSync, readFileSync, readdirSync } from "node:fs";
5
4
  import { join } from "node:path";
5
+ import { existsSync, readFileSync, readdirSync } from "node:fs";
6
6
  //#region src/extensions/bundle-mcp.ts
7
7
  init_paths();
8
8
  function extractMcpServerMap(raw) {
@@ -1,6 +1,6 @@
1
+ import { init_agent_scope, resolveDefaultAgentId } from "../agent/agent-scope.js";
1
2
  import { createLogger } from "../utils/logger/index.js";
2
3
  import { init_logger } from "../utils/logger.js";
3
- import { init_agent_scope, resolveDefaultAgentId } from "../agent/agent-scope.js";
4
4
  import { init_paths, resolveBundledExtensionsDir, resolveExtensionsDir, resolveWorkspaceExtensionsDir } from "../config/paths.js";
5
5
  import { init_loader, loadConfig } from "../config/loader.js";
6
6
  import { normalizeExtensionManifest } from "./normalize-manifest.js";
@@ -1,8 +1,8 @@
1
1
  import { init_paths, resolveExtensionsDir } from "../config/paths.js";
2
2
  import { getExtensionLockfileManager } from "./lockfile.js";
3
- import { readFile, readdir } from "fs/promises";
4
3
  import { join } from "path";
5
4
  import { existsSync } from "fs";
5
+ import { readFile, readdir } from "fs/promises";
6
6
  //#region src/extensions/health.ts
7
7
  init_paths();
8
8
  var ExtensionHealthChecker = class {
@@ -1,7 +1,7 @@
1
1
  import { PACKAGE_VERSION, init_package_version } from "../package-version.js";
2
+ import { init_agent_scope, resolveAgentWorkspaceDir, resolveDefaultAgentId } from "../agent/agent-scope.js";
2
3
  import { createLogger, createServiceLogger } from "../utils/logger/index.js";
3
4
  import { init_logger } from "../utils/logger.js";
4
- import { init_agent_scope, resolveAgentWorkspaceDir, resolveDefaultAgentId } from "../agent/agent-scope.js";
5
5
  import { init_paths, resolveBundledExtensionsDir, resolveExtensionSdkPath, resolveExtensionsDir, resolveWorkspaceExtensionsDir } from "../config/paths.js";
6
6
  import { init_loader, loadConfig } from "../config/loader.js";
7
7
  import { getProviderRegistry, init_plugin_registry } from "../providers/plugin-registry.js";
@@ -1,10 +1,10 @@
1
- import { init_write_file_atomic, writeTextAtomic } from "../infra/write-file-atomic.js";
2
1
  import { createLogger } from "../utils/logger/index.js";
3
2
  import { init_logger } from "../utils/logger.js";
4
3
  import { init_paths, resolveExtensionsDir, resolveExtensionsLockPath } from "../config/paths.js";
5
- import { mkdir, readFile } from "fs/promises";
4
+ import { init_write_file_atomic, writeTextAtomic } from "../infra/write-file-atomic.js";
6
5
  import { dirname, join } from "path";
7
6
  import { existsSync } from "fs";
7
+ import { mkdir, readFile } from "fs/promises";
8
8
  import { createHash } from "crypto";
9
9
  //#region src/extensions/lockfile.ts
10
10
  init_write_file_atomic();
@@ -1,13 +1,13 @@
1
1
  import { DEFAULT_AGENT_ID, init_agent_scope, listAgentEntries, normalizeAgentId, resolveAgentDir, resolveAgentProfileDir, resolveAgentWorkspaceDir, resolveDefaultAgentId, resolveUserPath, validateAgentIdForNewAgent } from "../agent/agent-scope.js";
2
- import { WORKSPACE_FILES, init_paths } from "../config/paths.js";
3
2
  import { resolveEffectiveAgentProfile } from "../config/agent-profile.js";
3
+ import { WORKSPACE_FILES, init_paths } from "../config/paths.js";
4
4
  import { AGENT_PROFILE_MARKDOWN_SYSTEM_FILES } from "../agent/context/workspace.js";
5
5
  import { isPathUnderWorkspace, resolveWorkspaceSafePath } from "./workspace-editor-path.js";
6
6
  import { applyAgentConfig, findAgentEntryIndex, pruneAgentConfig, removeAgentDirsFromDisk } from "../commands/agents.config.js";
7
7
  import { GATEWAY_BUILTIN_TOOL_IDS } from "./agent-builtin-tools.js";
8
8
  import { seedAgentProfileMarkdownFiles } from "../agent/context/workspace-seed.js";
9
- import { mkdir, readFile, realpath, stat, unlink, writeFile } from "node:fs/promises";
10
9
  import { join, resolve } from "node:path";
10
+ import { mkdir, readFile, realpath, stat, unlink, writeFile } from "node:fs/promises";
11
11
  //#region src/gateway/agents-admin.ts
12
12
  /**
13
13
  * Gateway REST helpers for multi-agent management.
@@ -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 { init_paths, resolveConfigPath, resolveSessionsDir, resolveSkillsDir } from "../config/paths.js";
4
3
  import { extractProfileAgentId } from "../config/agent-profile.js";
4
+ import { init_paths, resolveConfigPath, resolveSessionsDir, resolveSkillsDir } from "../config/paths.js";
5
5
  import { isBareProfileMarkdownFileName, resolveProfileMarkdownPathIfBareName } from "../agent/tools/tool-paths.js";
6
6
  import { isPathUnderWorkspace, resolveWorkspaceSafePath } from "./workspace-editor-path.js";
7
- import { stat } from "node:fs/promises";
8
7
  import { basename, isAbsolute, resolve } from "node:path";
8
+ import { stat } from "node:fs/promises";
9
9
  //#region src/gateway/file-path-classifier.ts
10
10
  init_agent_scope();
11
11
  init_paths();
@@ -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 { shouldSilence, stripHeartbeatToken } from "../../heartbeat/tokens.js";
4
+ import { appendCronEventLines } from "../../heartbeat/event-prompt.js";
4
5
  import { isWithinActiveHours } from "../../heartbeat/active-hours.js";
5
6
  import { isHeartbeatContentEmpty } from "../../heartbeat/content-check.js";
6
- import { appendCronEventLines } from "../../heartbeat/event-prompt.js";
7
7
  import { createHeartbeatWake } from "../../heartbeat/wake.js";
8
8
  import { resolveHeartbeatMdPath } from "../workspace-heartbeat-path.js";
9
9
  import { readFile } from "fs/promises";
@@ -2,10 +2,12 @@ import { createLogger } from "../../utils/logger/index.js";
2
2
  import { init_logger } from "../../utils/logger.js";
3
3
  import { resolveAllowedBrowserOrigins, resolveGatewayServiceListenPort } from "../host.js";
4
4
  import { resolveGatewayEffectiveHost } from "../../config/gateway-bind.js";
5
- import { maxWebchatAgentRequestBodyBytes } from "../chat-limits.js";
6
5
  import { loadTunnelState } from "../../tunnel/tunnel-state.js";
6
+ import { maxWebchatAgentRequestBodyBytes } from "../chat-limits.js";
7
+ import { isLoopbackIpAddress, isTrustedProxyAddress } from "../client-ip.js";
7
8
  import { buildGatewayConsoleCspHeader } from "../security/csp.js";
8
9
  import { checkBrowserOrigin } from "../security/origin-check.js";
10
+ import { resolveReverseProxyPublicUrl } from "../public-url.js";
9
11
  import { auth } from "./middleware/auth.js";
10
12
  import { operatorScopes } from "./middleware/scopes.js";
11
13
  import { createStrictRateLimitMiddleware } from "./middleware/strict-rate-limit.js";
@@ -16,10 +18,12 @@ import { resetLazyRouteBundlesForTests } from "./routes/lazy-fallback.js";
16
18
  import { registerAuthenticatedRoutes } from "./routes/index.js";
17
19
  import { prewarmStaticUiCache } from "./lib/static-ui.js";
18
20
  import { registerPublicGatewayRoutes } from "./routes/public-gateway.js";
21
+ import { registerSiteShareMiddleware } from "../../share/site-share-router.js";
19
22
  import { Hono } from "hono";
20
23
  import { cors } from "hono/cors";
21
24
  import { createMiddleware } from "hono/factory";
22
25
  import { bodyLimit } from "hono/body-limit";
26
+ import { getConnInfo } from "@hono/node-server/conninfo";
23
27
  //#region src/gateway/hono/app.ts
24
28
  init_logger();
25
29
  const log = createLogger("HonoApp");
@@ -40,13 +44,39 @@ function createHonoApp(config) {
40
44
  configuredOrigins: service.currentConfig.gateway.corsOrigins,
41
45
  port: gatewayPort,
42
46
  bindHost: resolveGatewayEffectiveHost(service.currentConfig),
43
- tunnelPublicUrl: loadTunnelState()?.publicUrl
47
+ tunnelPublicUrl: loadTunnelState()?.publicUrl,
48
+ reverseProxyPublicUrl: resolveReverseProxyPublicUrl(service.currentConfig)
44
49
  });
50
+ /**
51
+ * TCP source for the in-flight request, normalized for trusted-proxy checks.
52
+ * Returns undefined when the runtime doesn't expose conninfo (tests, mocks).
53
+ */
54
+ const resolveRequestRemoteAddress = (c) => {
55
+ try {
56
+ return getConnInfo(c).remote.address;
57
+ } catch {
58
+ return;
59
+ }
60
+ };
61
+ /**
62
+ * A request's TCP source qualifies as a "trusted proxy hop" when it's
63
+ * loopback (the user's own machine, where any reverse proxy lives) or
64
+ * listed in `gateway.trustedProxies`. We use this signal to safely
65
+ * auto-allow same-host Origins through CSRF without requiring a manual
66
+ * `corsOrigins` entry for every reverse-proxy hostname.
67
+ */
68
+ const isRequestFromTrustedProxy = (c) => {
69
+ const remote = resolveRequestRemoteAddress(c);
70
+ if (!remote) return false;
71
+ if (isLoopbackIpAddress(remote)) return true;
72
+ return isTrustedProxyAddress(remote, service.currentConfig.gateway?.trustedProxies);
73
+ };
45
74
  app.use(logContextMiddleware());
46
75
  app.use(logger({
47
76
  trustedProxies: service.currentConfig.gateway?.trustedProxies,
48
77
  allowRealIpFallback: service.currentConfig.gateway?.allowRealIpFallback === true
49
78
  }));
79
+ registerSiteShareMiddleware(app, service);
50
80
  app.use(cors({
51
81
  origin: (origin) => {
52
82
  const allowed = resolveBrowserOrigins();
@@ -93,6 +123,7 @@ function createHonoApp(config) {
93
123
  origin,
94
124
  allowedOrigins: resolveBrowserOrigins(),
95
125
  allowHostHeaderOriginFallback,
126
+ autoAllowSameHostFromTrustedProxy: isRequestFromTrustedProxy(c),
96
127
  isLocalClient: false
97
128
  });
98
129
  if (!result.ok) {
@@ -1 +1 @@
1
- {"version":3,"file":"app.js","names":[],"sources":["../../../../src/gateway/hono/app.ts"],"sourcesContent":["import { Hono } from 'hono';\nimport { cors } from 'hono/cors';\nimport { createMiddleware } from 'hono/factory';\nimport { bodyLimit } from 'hono/body-limit';\n\nimport { resolveGatewayEffectiveHost } from '../../config/gateway-bind.js';\nimport { createLogger } from '../../utils/logger.js';\nimport type { GatewayService } from '../service.js';\nimport { resolveAllowedBrowserOrigins, resolveGatewayServiceListenPort } from '../host.js';\nimport { loadTunnelState } from '../../tunnel/tunnel-state.js';\nimport { maxWebchatAgentRequestBodyBytes } from '../chat-limits.js';\nimport { buildGatewayConsoleCspHeader } from '../security/csp.js';\nimport { checkBrowserOrigin } from '../security/origin-check.js';\nimport { auth } from './middleware/auth.js';\nimport { operatorScopes } from './middleware/scopes.js';\nimport { createStrictRateLimitMiddleware } from './middleware/strict-rate-limit.js';\nimport { logContextMiddleware } from './middleware/log-context.js';\nimport { logger } from './middleware/logger.js';\nimport { registerPublicExtensionAssetRoutes } from './routes/auth-registry-extensions.js';\nimport { registerAuthenticatedRoutes } from './routes/index.js';\nimport { registerPublicGatewayRoutes } from './routes/public-gateway.js';\nimport { resetLazyRouteBundlesForTests } from './routes/lazy-fallback.js';\nimport { prewarmStaticUiCache } from './lib/static-ui.js';\nconst log = createLogger('HonoApp');\n\nexport interface HonoAppConfig {\n service: GatewayService;\n token?: string;\n}\n\n/**\n * Extension sandbox HTML under `/api/extensions/:id/assets/*` ships its own CSP\n * (`frame-ancestors 'self'`). The global gateway middleware must not overwrite it\n * with `frame-ancestors 'none'` / `X-Frame-Options: DENY`, or the console cannot embed iframes.\n */\nexport function isExtensionGatewayUiAssetPath(path: string): boolean {\n return /^\\/api\\/extensions\\/[^/]+\\/assets\\//.test(path);\n}\n\nexport function createHonoApp(config: HonoAppConfig): Hono {\n if (process.env.VITEST) {\n resetLazyRouteBundlesForTests();\n }\n const { service, token } = config;\n const app = new Hono();\n\n const gatewayPort = resolveGatewayServiceListenPort(service);\n\n const resolveBrowserOrigins = (): string[] =>\n resolveAllowedBrowserOrigins({\n configuredOrigins: service.currentConfig.gateway.corsOrigins,\n port: gatewayPort,\n bindHost: resolveGatewayEffectiveHost(service.currentConfig),\n tunnelPublicUrl: loadTunnelState()?.publicUrl,\n });\n\n app.use(logContextMiddleware());\n app.use(logger({\n trustedProxies: service.currentConfig.gateway?.trustedProxies,\n allowRealIpFallback: service.currentConfig.gateway?.allowRealIpFallback === true,\n }));\n app.use(\n cors({\n origin: (origin) => {\n const allowed = resolveBrowserOrigins();\n if (!origin) {\n return allowed[0] ?? `http://127.0.0.1:${gatewayPort}`;\n }\n const normalized = origin.toLowerCase();\n const hit = allowed.find((entry) => entry.toLowerCase() === normalized);\n if (hit) return origin;\n return allowed.includes('*') ? '*' : '';\n },\n allowMethods: ['GET', 'POST', 'PATCH', 'DELETE', 'OPTIONS'],\n allowHeaders: ['Content-Type', 'Authorization', 'Accept', 'X-Session-Id', 'Last-Event-ID'],\n credentials: true,\n maxAge: 86400,\n }),\n );\n\n // Build CSP header once at startup (no inline script hashes needed for SPA)\n const gatewayConsoleCsp = buildGatewayConsoleCspHeader();\n\n // Security headers middleware\n app.use(createMiddleware(async (c, next) => {\n await next();\n if (isExtensionGatewayUiAssetPath(c.req.path)) {\n return;\n }\n c.header('X-Frame-Options', 'DENY');\n c.header('X-Content-Type-Options', 'nosniff');\n c.header('Referrer-Policy', 'strict-origin-when-cross-origin');\n c.header('X-XSS-Protection', '1; mode=block');\n // microphone=(self): allow same-origin chat voice (composer). microphone=() breaks packaged Electron loading the gateway SPA.\n c.header('Permissions-Policy', 'camera=(), microphone=(self), geolocation=()');\n c.header('Content-Security-Policy', gatewayConsoleCsp);\n }));\n\n // Browser Origin check middleware for API routes (CSRF protection).\n // Non-browser requests (no Origin header) pass through — they are\n // authenticated by the token middleware instead.\n const allowHostHeaderOriginFallback =\n service.currentConfig.gateway?.dangerouslyAllowHostHeaderOriginFallback === true;\n app.use('/api/*', createMiddleware(async (c, next) => {\n // Sandboxed extension iframes (no allow-same-origin) send `Origin: null`.\n // `checkBrowserOrigin` rejects that; these routes rely on CSP instead\n // (`registerPublicExtensionAssetRoutes`).\n if (isExtensionGatewayUiAssetPath(c.req.path)) {\n return next();\n }\n\n const origin = c.req.header('origin');\n if (!origin || origin.trim().toLowerCase() === 'null') {\n // Native apps / opaque origins — authenticated via Bearer token\n return next();\n }\n\n const result = checkBrowserOrigin({\n requestHost: c.req.header('host'),\n origin,\n allowedOrigins: resolveBrowserOrigins(),\n allowHostHeaderOriginFallback,\n isLocalClient: false,\n });\n\n if (!result.ok) {\n log.warn(\n {\n origin,\n requestHost: c.req.header('host'),\n reason: 'reason' in result ? result.reason : 'unknown',\n path: c.req.path,\n method: c.req.method,\n },\n `Browser origin check failed: ${origin} not in allowed list`,\n );\n return c.json({ error: 'Forbidden', message: 'Origin not allowed' }, 403);\n }\n\n return next();\n }));\n\n app.use('/api/skills/upload', bodyLimit({\n maxSize: 10 * 1024 * 1024,\n onError: (c) => {\n log.warn({ path: c.req.path, maxSizeMb: 10 }, 'Request body too large: skills upload exceeds 10MB limit');\n return c.json({ error: 'Skill package too large', maxSize: '10MB' }, 413);\n },\n }));\n\n const DEFAULT_API_BODY_MAX = 1 * 1024 * 1024;\n const WEBCHAT_AGENT_BODY_MAX = maxWebchatAgentRequestBodyBytes();\n\n app.use('/api/*', async (c, next) => {\n const maxSize = c.req.path === '/api/agent' ? WEBCHAT_AGENT_BODY_MAX : DEFAULT_API_BODY_MAX;\n const maxSizeMb = Math.ceil(maxSize / (1024 * 1024));\n return bodyLimit({\n maxSize,\n onError: (ctx) => {\n log.warn({ path: ctx.req.path, maxSizeMb }, `Request body too large: exceeds ${maxSizeMb}MB limit`);\n return ctx.json({ error: 'Request body too large', maxSize: `${maxSizeMb}MB` }, 413);\n },\n })(c, next);\n });\n\n registerPublicGatewayRoutes(app, service);\n\n // Extension UI assets are served without auth: sandboxed iframes (no allow-same-origin)\n // have an opaque origin of `null` and cannot forward the ?token= from the parent HTML URL.\n // Security is enforced by the strict CSP (frame-ancestors 'self') on every response.\n registerPublicExtensionAssetRoutes(app, service);\n\n const authenticated = new Hono();\n authenticated.use(\n auth({\n token,\n getGatewayAuth: () => service.currentConfig.gateway?.auth,\n getResolvedAuth: () => {\n if (typeof service.getResolvedAuth === 'function') {\n return service.getResolvedAuth();\n }\n return token ? { mode: 'token', token } : { mode: 'none' };\n },\n getTrustedProxyContext: () => ({\n trustedProxies: service.currentConfig.gateway?.trustedProxies,\n allowRealIpFallback: service.currentConfig.gateway?.allowRealIpFallback === true,\n }),\n }),\n );\n authenticated.use(operatorScopes());\n\n const strictRateLimitMiddleware = createStrictRateLimitMiddleware({\n getTrustedProxyContext: () => ({\n trustedProxies: service.currentConfig.gateway?.trustedProxies,\n allowRealIpFallback: service.currentConfig.gateway?.allowRealIpFallback === true,\n }),\n });\n\n const sseConfig = {\n service,\n maxSseConnections: service.currentConfig.gateway.maxSseConnections,\n };\n\n registerAuthenticatedRoutes(app, authenticated, {\n service,\n strictRateLimitMiddleware,\n sseConfig,\n });\n\n const prewarm = prewarmStaticUiCache();\n if (prewarm.loaded > 0) {\n log.debug({ loaded: prewarm.loaded, missing: prewarm.missing }, 'Static UI cache prewarmed');\n }\n\n app.route('/', authenticated);\n\n app.notFound((c) => {\n const isApiRoute = c.req.path.startsWith('/api/');\n const fields = { path: c.req.path, method: c.req.method };\n if (isApiRoute) {\n log.warn(fields, 'Route not found');\n } else {\n log.debug(fields, 'Route not found');\n }\n return c.json({ error: 'Not found' }, 404);\n });\n\n app.onError((err, c) => {\n log.error(\n {\n err,\n path: c.req.path,\n method: c.req.method,\n userAgent: c.req.header('user-agent'),\n },\n `Hono error on ${c.req.method} ${c.req.path}: ${err instanceof Error ? err.message : String(err)}`,\n );\n return c.json({ error: 'Internal server error' }, 500);\n });\n\n return app;\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"app.js","names":[],"sources":["../../../../src/gateway/hono/app.ts"],"sourcesContent":["import { Hono } from 'hono';\nimport type { Context } from 'hono';\nimport { cors } from 'hono/cors';\nimport { createMiddleware } from 'hono/factory';\nimport { bodyLimit } from 'hono/body-limit';\nimport { getConnInfo } from '@hono/node-server/conninfo';\n\nimport { resolveGatewayEffectiveHost } from '../../config/gateway-bind.js';\nimport { createLogger } from '../../utils/logger.js';\nimport type { GatewayService } from '../service.js';\nimport { resolveAllowedBrowserOrigins, resolveGatewayServiceListenPort } from '../host.js';\nimport { loadTunnelState } from '../../tunnel/tunnel-state.js';\nimport { maxWebchatAgentRequestBodyBytes } from '../chat-limits.js';\nimport { buildGatewayConsoleCspHeader } from '../security/csp.js';\nimport { checkBrowserOrigin } from '../security/origin-check.js';\nimport { isLoopbackIpAddress, isTrustedProxyAddress } from '../client-ip.js';\nimport { resolveReverseProxyPublicUrl } from '../public-url.js';\nimport { auth } from './middleware/auth.js';\nimport { operatorScopes } from './middleware/scopes.js';\nimport { createStrictRateLimitMiddleware } from './middleware/strict-rate-limit.js';\nimport { logContextMiddleware } from './middleware/log-context.js';\nimport { logger } from './middleware/logger.js';\nimport { registerPublicExtensionAssetRoutes } from './routes/auth-registry-extensions.js';\nimport { registerAuthenticatedRoutes } from './routes/index.js';\nimport { registerPublicGatewayRoutes } from './routes/public-gateway.js';\nimport { resetLazyRouteBundlesForTests } from './routes/lazy-fallback.js';\nimport { prewarmStaticUiCache } from './lib/static-ui.js';\nimport { registerSiteShareMiddleware } from '../../share/site-share-router.js';\nconst log = createLogger('HonoApp');\n\nexport interface HonoAppConfig {\n service: GatewayService;\n token?: string;\n}\n\n/**\n * Extension sandbox HTML under `/api/extensions/:id/assets/*` ships its own CSP\n * (`frame-ancestors 'self'`). The global gateway middleware must not overwrite it\n * with `frame-ancestors 'none'` / `X-Frame-Options: DENY`, or the console cannot embed iframes.\n */\nexport function isExtensionGatewayUiAssetPath(path: string): boolean {\n return /^\\/api\\/extensions\\/[^/]+\\/assets\\//.test(path);\n}\n\nexport function createHonoApp(config: HonoAppConfig): Hono {\n if (process.env.VITEST) {\n resetLazyRouteBundlesForTests();\n }\n const { service, token } = config;\n const app = new Hono();\n\n const gatewayPort = resolveGatewayServiceListenPort(service);\n\n const resolveBrowserOrigins = (): string[] =>\n resolveAllowedBrowserOrigins({\n configuredOrigins: service.currentConfig.gateway.corsOrigins,\n port: gatewayPort,\n bindHost: resolveGatewayEffectiveHost(service.currentConfig),\n tunnelPublicUrl: loadTunnelState()?.publicUrl,\n reverseProxyPublicUrl: resolveReverseProxyPublicUrl(service.currentConfig),\n });\n\n /**\n * TCP source for the in-flight request, normalized for trusted-proxy checks.\n * Returns undefined when the runtime doesn't expose conninfo (tests, mocks).\n */\n const resolveRequestRemoteAddress = (c: Context): string | undefined => {\n try {\n return getConnInfo(c).remote.address;\n } catch {\n return undefined;\n }\n };\n\n /**\n * A request's TCP source qualifies as a \"trusted proxy hop\" when it's\n * loopback (the user's own machine, where any reverse proxy lives) or\n * listed in `gateway.trustedProxies`. We use this signal to safely\n * auto-allow same-host Origins through CSRF without requiring a manual\n * `corsOrigins` entry for every reverse-proxy hostname.\n */\n const isRequestFromTrustedProxy = (c: Context): boolean => {\n const remote = resolveRequestRemoteAddress(c);\n if (!remote) return false;\n if (isLoopbackIpAddress(remote)) return true;\n return isTrustedProxyAddress(remote, service.currentConfig.gateway?.trustedProxies);\n };\n\n app.use(logContextMiddleware());\n app.use(logger({\n trustedProxies: service.currentConfig.gateway?.trustedProxies,\n allowRealIpFallback: service.currentConfig.gateway?.allowRealIpFallback === true,\n }));\n\n // Site-share middleware runs BEFORE CORS/CSP — it owns the request when the\n // Host header matches `*.<publicHostSuffix>` (default `*.share.xopc.ai`) or\n // the path starts with `/site/:token/`. Otherwise it falls through.\n registerSiteShareMiddleware(app, service);\n app.use(\n cors({\n origin: (origin) => {\n const allowed = resolveBrowserOrigins();\n if (!origin) {\n return allowed[0] ?? `http://127.0.0.1:${gatewayPort}`;\n }\n const normalized = origin.toLowerCase();\n const hit = allowed.find((entry) => entry.toLowerCase() === normalized);\n if (hit) return origin;\n return allowed.includes('*') ? '*' : '';\n },\n allowMethods: ['GET', 'POST', 'PATCH', 'DELETE', 'OPTIONS'],\n allowHeaders: ['Content-Type', 'Authorization', 'Accept', 'X-Session-Id', 'Last-Event-ID'],\n credentials: true,\n maxAge: 86400,\n }),\n );\n\n // Build CSP header once at startup (no inline script hashes needed for SPA)\n const gatewayConsoleCsp = buildGatewayConsoleCspHeader();\n\n // Security headers middleware\n app.use(createMiddleware(async (c, next) => {\n await next();\n if (isExtensionGatewayUiAssetPath(c.req.path)) {\n return;\n }\n c.header('X-Frame-Options', 'DENY');\n c.header('X-Content-Type-Options', 'nosniff');\n c.header('Referrer-Policy', 'strict-origin-when-cross-origin');\n c.header('X-XSS-Protection', '1; mode=block');\n // microphone=(self): allow same-origin chat voice (composer). microphone=() breaks packaged Electron loading the gateway SPA.\n c.header('Permissions-Policy', 'camera=(), microphone=(self), geolocation=()');\n c.header('Content-Security-Policy', gatewayConsoleCsp);\n }));\n\n // Browser Origin check middleware for API routes (CSRF protection).\n // Non-browser requests (no Origin header) pass through — they are\n // authenticated by the token middleware instead.\n const allowHostHeaderOriginFallback =\n service.currentConfig.gateway?.dangerouslyAllowHostHeaderOriginFallback === true;\n app.use('/api/*', createMiddleware(async (c, next) => {\n // Sandboxed extension iframes (no allow-same-origin) send `Origin: null`.\n // `checkBrowserOrigin` rejects that; these routes rely on CSP instead\n // (`registerPublicExtensionAssetRoutes`).\n if (isExtensionGatewayUiAssetPath(c.req.path)) {\n return next();\n }\n\n const origin = c.req.header('origin');\n if (!origin || origin.trim().toLowerCase() === 'null') {\n // Native apps / opaque origins — authenticated via Bearer token\n return next();\n }\n\n const result = checkBrowserOrigin({\n requestHost: c.req.header('host'),\n origin,\n allowedOrigins: resolveBrowserOrigins(),\n allowHostHeaderOriginFallback,\n autoAllowSameHostFromTrustedProxy: isRequestFromTrustedProxy(c),\n isLocalClient: false,\n });\n\n if (!result.ok) {\n log.warn(\n {\n origin,\n requestHost: c.req.header('host'),\n reason: 'reason' in result ? result.reason : 'unknown',\n path: c.req.path,\n method: c.req.method,\n },\n `Browser origin check failed: ${origin} not in allowed list`,\n );\n return c.json({ error: 'Forbidden', message: 'Origin not allowed' }, 403);\n }\n\n return next();\n }));\n\n app.use('/api/skills/upload', bodyLimit({\n maxSize: 10 * 1024 * 1024,\n onError: (c) => {\n log.warn({ path: c.req.path, maxSizeMb: 10 }, 'Request body too large: skills upload exceeds 10MB limit');\n return c.json({ error: 'Skill package too large', maxSize: '10MB' }, 413);\n },\n }));\n\n const DEFAULT_API_BODY_MAX = 1 * 1024 * 1024;\n const WEBCHAT_AGENT_BODY_MAX = maxWebchatAgentRequestBodyBytes();\n\n app.use('/api/*', async (c, next) => {\n const maxSize = c.req.path === '/api/agent' ? WEBCHAT_AGENT_BODY_MAX : DEFAULT_API_BODY_MAX;\n const maxSizeMb = Math.ceil(maxSize / (1024 * 1024));\n return bodyLimit({\n maxSize,\n onError: (ctx) => {\n log.warn({ path: ctx.req.path, maxSizeMb }, `Request body too large: exceeds ${maxSizeMb}MB limit`);\n return ctx.json({ error: 'Request body too large', maxSize: `${maxSizeMb}MB` }, 413);\n },\n })(c, next);\n });\n\n registerPublicGatewayRoutes(app, service);\n\n // Extension UI assets are served without auth: sandboxed iframes (no allow-same-origin)\n // have an opaque origin of `null` and cannot forward the ?token= from the parent HTML URL.\n // Security is enforced by the strict CSP (frame-ancestors 'self') on every response.\n registerPublicExtensionAssetRoutes(app, service);\n\n const authenticated = new Hono();\n authenticated.use(\n auth({\n token,\n getGatewayAuth: () => service.currentConfig.gateway?.auth,\n getResolvedAuth: () => {\n if (typeof service.getResolvedAuth === 'function') {\n return service.getResolvedAuth();\n }\n return token ? { mode: 'token', token } : { mode: 'none' };\n },\n getTrustedProxyContext: () => ({\n trustedProxies: service.currentConfig.gateway?.trustedProxies,\n allowRealIpFallback: service.currentConfig.gateway?.allowRealIpFallback === true,\n }),\n }),\n );\n authenticated.use(operatorScopes());\n\n const strictRateLimitMiddleware = createStrictRateLimitMiddleware({\n getTrustedProxyContext: () => ({\n trustedProxies: service.currentConfig.gateway?.trustedProxies,\n allowRealIpFallback: service.currentConfig.gateway?.allowRealIpFallback === true,\n }),\n });\n\n const sseConfig = {\n service,\n maxSseConnections: service.currentConfig.gateway.maxSseConnections,\n };\n\n registerAuthenticatedRoutes(app, authenticated, {\n service,\n strictRateLimitMiddleware,\n sseConfig,\n });\n\n const prewarm = prewarmStaticUiCache();\n if (prewarm.loaded > 0) {\n log.debug({ loaded: prewarm.loaded, missing: prewarm.missing }, 'Static UI cache prewarmed');\n }\n\n app.route('/', authenticated);\n\n app.notFound((c) => {\n const isApiRoute = c.req.path.startsWith('/api/');\n const fields = { path: c.req.path, method: c.req.method };\n if (isApiRoute) {\n log.warn(fields, 'Route not found');\n } else {\n log.debug(fields, 'Route not found');\n }\n return c.json({ error: 'Not found' }, 404);\n });\n\n app.onError((err, c) => {\n log.error(\n {\n err,\n path: c.req.path,\n method: c.req.method,\n userAgent: c.req.header('user-agent'),\n },\n `Hono error on ${c.req.method} ${c.req.path}: ${err instanceof Error ? err.message : String(err)}`,\n );\n return c.json({ error: 'Internal server error' }, 500);\n });\n\n return app;\n}\n"],"mappings":"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"}
@@ -1,12 +1,12 @@
1
1
  import { init_agent_scope, listAgentEntries, normalizeAgentId, resolveDefaultAgentId } from "../../../agent/agent-scope.js";
2
2
  import { getAllProviders, init_providers, isProviderConfigured } from "../../../providers/index.js";
3
+ import { resolveShareConfig } from "../../../share/share-config.js";
3
4
  import { normalizeConfiguredMcpServers } from "../../../config/mcp-config-normalize.js";
4
5
  import { bundledChannelPlugins } from "../../../generated/bundled-channel-plugins.js";
5
6
  import { listChannelPlugins, syncChannelPluginsFromManager } from "../../../channels/plugins/registry.js";
6
7
  import { resolveCronConfigForWeb, resolveGoalsConfigForWeb, resolveSessionConfigForWeb, resolveUpdateConfigForWeb } from "../../../config/web-patch.js";
7
8
  import { safeToolsWebForGet } from "../../config-tools-web.js";
8
9
  import { maskTunnelSecretForWeb } from "../../../tunnel/env.js";
9
- import { resolveShareConfig } from "../../../share/share-config.js";
10
10
  import { agentImageGenerationModelAutoProviderFallback, agentImageGenerationModelTimeoutMs, agentModelFallbacksToArray, agentModelRefToString } from "./agent-model.js";
11
11
  import { buildSafeProvidersConfigForWeb } from "./safe-providers-config.js";
12
12
  import { maskSttConfigForWeb, maskTtsConfigForWeb } from "./safe-voice-config.js";
@@ -1,7 +1,7 @@
1
1
  import { init_write_file_atomic, writeTextAtomic } from "../../../infra/write-file-atomic.js";
2
- import { readFile } from "node:fs/promises";
3
- import { join } from "node:path";
4
2
  import { homedir } from "node:os";
3
+ import { join } from "node:path";
4
+ import { readFile } from "node:fs/promises";
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 { createHash } from "node:crypto";
2
- import { readFileSync } from "node:fs";
3
1
  import { dirname, resolve } from "node:path";
2
+ import { readFileSync } from "node:fs";
3
+ import { createHash } from "node:crypto";
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,6 +1,6 @@
1
1
  import { CredentialResolver, init_credentials } from "../../auth/credentials.js";
2
- import { anthropicOAuthProvider } from "../../auth/oauth/anthropic.js";
3
2
  import { init_providers, isProviderConfigured } from "../../providers/index.js";
3
+ import { anthropicOAuthProvider } from "../../auth/oauth/anthropic.js";
4
4
  import { minimaxOAuthProvider } from "../../auth/oauth/minimax.js";
5
5
  import { minimaxCnOAuthProvider } from "../../auth/oauth/minimax-cn.js";
6
6
  import { kimiCodingOAuthProvider } from "../../auth/oauth/kimi-coding.js";
@@ -1,5 +1,5 @@
1
- import { init_agent_scope, normalizeAgentId } from "../../../agent/agent-scope.js";
2
1
  import { init_schema, parseModelRef } from "../../../config/schema.js";
2
+ import { init_agent_scope, normalizeAgentId } from "../../../agent/agent-scope.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, prepareCreateAgentsBatch, prepareDeleteAgent, prepareUpdateAgent, readAgentAvatarFile, readAgentProfileFile, runAfterDeletePurge, writeAgentAvatarFromBase64, writeAgentProfileFile } from "../../agents-admin.js";
@@ -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 { existsSync, readFileSync, statSync } from "node:fs";
11
10
  import { relative, resolve } from "node:path";
11
+ import { existsSync, readFileSync, statSync } from "node:fs";
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'";
@@ -1,5 +1,5 @@
1
- import { CredentialResolver, init_credentials } from "../../../../auth/credentials.js";
2
1
  import { BindingsConfigSchema, McpConfigSchema, init_schema } from "../../../../config/schema.js";
2
+ import { CredentialResolver, init_credentials } from "../../../../auth/credentials.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";
@@ -5,8 +5,8 @@ import { getWorkspacePath } from "../../../config/workspace-path-helpers.js";
5
5
  import { parseDreamingLastRunFile } from "../../../agent/memory/dreaming/last-run.js";
6
6
  import { readDreamingEvents } from "../../../agent/memory/dreaming/events.js";
7
7
  import { previewDreamingDeepPromotion } from "../../../agent/memory/dreaming/preview.js";
8
- import fs from "node:fs/promises";
9
8
  import path from "node:path";
9
+ import fs from "node:fs/promises";
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,8 +1,8 @@
1
1
  import { createLogger } from "../../../utils/logger/index.js";
2
2
  import { init_logger } from "../../../utils/logger.js";
3
- import { readdir, realpath, stat } from "node:fs/promises";
4
- import * as path$1 from "node:path";
5
3
  import * as os$1 from "node:os";
4
+ import * as path$1 from "node:path";
5
+ import { readdir, realpath, stat } from "node:fs/promises";
6
6
  //#region src/gateway/hono/routes/host-fs.ts
7
7
  init_logger();
8
8
  const log = createLogger("HostFs");
@@ -142,6 +142,14 @@ const AUTHENTICATED_LAZY_ROUTE_BUNDLES = [
142
142
  return { register: registerShareRoutes };
143
143
  }
144
144
  },
145
+ {
146
+ id: "site-shares",
147
+ match: (path) => startsWithAny(path, ["/api/site-shares"]),
148
+ load: async () => {
149
+ const { registerSiteShareRoutes } = await import("./site-shares.js");
150
+ return { register: registerSiteShareRoutes };
151
+ }
152
+ },
145
153
  {
146
154
  id: "tunnel",
147
155
  match: (path) => startsWithAny(path, ["/api/tunnel"]),
@@ -1 +1 @@
1
- {"version":3,"file":"lazy-bundles.js","names":[],"sources":["../../../../../src/gateway/hono/routes/lazy-bundles.ts"],"sourcesContent":["import type { Hono } from 'hono';\n\nimport type { GatewayService } from '../../service.js';\nimport type { AuthenticatedRouteDeps } from './deps.js';\n\nexport type AuthenticatedLazyRouteBundle = {\n id: string;\n match: (path: string) => boolean;\n load: () => Promise<{ register: (authenticated: Hono, deps: AuthenticatedRouteDeps) => void }>;\n};\n\nexport type AppLazyRouteBundle = {\n id: string;\n prefixes: readonly string[];\n match: (path: string) => boolean;\n load: () => Promise<{\n registerOnApp: (app: Hono, service: GatewayService) => void;\n }>;\n};\n\nfunction startsWithAny(path: string, prefixes: readonly string[]): boolean {\n return prefixes.some((prefix) => path === prefix || path.startsWith(`${prefix}/`));\n}\n\nexport const AUTHENTICATED_LAZY_ROUTE_BUNDLES: readonly AuthenticatedLazyRouteBundle[] = [\n {\n id: 'workspace',\n match: (path) => startsWithAny(path, ['/api/workspace']),\n load: async () => {\n const { registerWorkspaceRoutes } = await import('./workspace.js');\n return { register: registerWorkspaceRoutes };\n },\n },\n {\n id: 'host-fs',\n match: (path) => startsWithAny(path, ['/api/host/fs']),\n load: async () => {\n const { registerHostFsRoutes } = await import('./host-fs.js');\n return { register: registerHostFsRoutes };\n },\n },\n {\n id: 'channels',\n match: (path) => startsWithAny(path, ['/api/channels']),\n load: async () => {\n const { registerChannelRoutes } = await import('./channels.js');\n return { register: registerChannelRoutes };\n },\n },\n {\n id: 'browser-install',\n match: (path) =>\n path === '/api/browser/playwright/install/stream' ||\n path === '/api/browser/cloakbrowser/install/stream',\n load: async () => {\n const { registerBrowserInstallRoutes } = await import('./browser-install.js');\n return { register: registerBrowserInstallRoutes };\n },\n },\n {\n id: 'browser',\n // `browser-install` above already matched the SSE install streams; this\n // catches the remaining /api/browser/* handlers (extension, cdp,\n // cloakbrowser doctor/launch/install, playwright doctor/install, cloud).\n match: (path) => startsWithAny(path, ['/api/browser']),\n load: async () => {\n const { registerBrowserRoutes } = await import('./browser.js');\n return { register: registerBrowserRoutes };\n },\n },\n {\n id: 'config',\n match: (path) =>\n startsWithAny(path, ['/api/config', '/api/heartbeat/trigger']),\n load: async () => {\n const { registerConfigRoutes } = await import('./config.js');\n return { register: registerConfigRoutes };\n },\n },\n {\n id: 'doctor',\n match: (path) => startsWithAny(path, ['/api/doctor']),\n load: async () => {\n const { registerDoctorRoutes } = await import('./doctor.js');\n return { register: registerDoctorRoutes };\n },\n },\n {\n id: 'dreaming',\n match: (path) => startsWithAny(path, ['/api/dreaming']),\n load: async () => {\n const { registerDreamingRoutes } = await import('./dreaming.js');\n return { register: registerDreamingRoutes };\n },\n },\n {\n id: 'agents',\n match: (path) => startsWithAny(path, ['/api/agents', '/api/voice/models']),\n load: async () => {\n const { registerAgentsRoutes } = await import('./agents.js');\n return { register: registerAgentsRoutes };\n },\n },\n {\n id: 'auth-registry-extensions',\n match: (path) =>\n startsWithAny(path, [\n '/api/auth',\n '/api/registry',\n '/api/extensions',\n '/api/context',\n '/api/marketplace',\n ]),\n load: async () => {\n const { registerAuthRegistryExtensionsRoutes } = await import('./auth-registry-extensions.js');\n return { register: registerAuthRegistryExtensionsRoutes };\n },\n },\n {\n id: 'models',\n match: (path) =>\n startsWithAny(path, ['/api/models', '/api/models-json', '/api/providers', '/api/image']),\n load: async () => {\n const { registerModelsRoutes } = await import('./models.js');\n return { register: registerModelsRoutes };\n },\n },\n {\n id: 'commands-skills',\n match: (path) => startsWithAny(path, ['/api/commands', '/api/skills']),\n load: async () => {\n const { registerCommandsSkillsRoutes } = await import('./commands-skills.js');\n return { register: registerCommandsSkillsRoutes };\n },\n },\n {\n id: 'cron',\n match: (path) => startsWithAny(path, ['/api/cron']),\n load: async () => {\n const { registerCronRoutes } = await import('./cron.js');\n return { register: registerCronRoutes };\n },\n },\n {\n id: 'goals',\n match: (path) => startsWithAny(path, ['/api/goals']),\n load: async () => {\n const { registerGoalsRoutes } = await import('./goals.js');\n return { register: registerGoalsRoutes };\n },\n },\n {\n id: 'logs',\n match: (path) => startsWithAny(path, ['/api/logs']),\n load: async () => {\n const { registerLogsRoutes } = await import('./logs.js');\n return { register: registerLogsRoutes };\n },\n },\n {\n id: 'shares',\n match: (path) => startsWithAny(path, ['/api/shares']),\n load: async () => {\n const { registerShareRoutes } = await import('./shares.js');\n return { register: registerShareRoutes };\n },\n },\n {\n id: 'tunnel',\n match: (path) => startsWithAny(path, ['/api/tunnel']),\n load: async () => {\n const { registerTunnelRoutes } = await import('./tunnel.js');\n return { register: registerTunnelRoutes };\n },\n },\n {\n id: 'exposure',\n match: (path) => startsWithAny(path, ['/api/exposure']),\n load: async () => {\n const { registerExposureRoutes } = await import('./exposure.js');\n return { register: registerExposureRoutes };\n },\n },\n {\n id: 'extension-gateway',\n match: (path) => startsWithAny(path, ['/api/gateway']),\n load: async () => {\n const { registerExtensionGatewayRoutes } = await import('./extension-gateway.js');\n return { register: registerExtensionGatewayRoutes };\n },\n },\n {\n id: 'update',\n match: (path) => startsWithAny(path, ['/api/update']),\n load: async () => {\n const { registerUpdateRoutes } = await import('./update.js');\n return { register: registerUpdateRoutes };\n },\n },\n {\n id: 'voice',\n match: (path) => startsWithAny(path, ['/api/voice']) && path !== '/api/voice/models',\n load: async () => {\n const { registerVoiceRoutes } = await import('./voice.js');\n return { register: registerVoiceRoutes };\n },\n },\n {\n id: 'mcp',\n match: (path) => startsWithAny(path, ['/api/mcp']),\n load: async () => {\n const { registerMcpRoutes } = await import('./mcp.js');\n return { register: registerMcpRoutes };\n },\n },\n];\n\nexport const APP_LAZY_ROUTE_BUNDLES: readonly AppLazyRouteBundle[] = [\n {\n id: 'shares-public',\n prefixes: ['/s'],\n match: (path) => startsWithAny(path, ['/s']),\n load: async () => {\n const { registerSharePublicRoutes } = await import('./shares.js');\n return { registerOnApp: registerSharePublicRoutes };\n },\n },\n {\n id: 'tunnel-public',\n prefixes: [\n '/api/tunnel/pair/ping',\n '/api/tunnel/pair/validate-url',\n '/api/tunnel/exchange-token',\n ],\n match: (path) =>\n path === '/api/tunnel/exchange-token' ||\n path === '/api/tunnel/pair/ping' ||\n path === '/api/tunnel/pair/validate-url',\n load: async () => {\n const { registerTunnelPublicRoutes } = await import('./tunnel.js');\n return { registerOnApp: registerTunnelPublicRoutes };\n },\n },\n];\n\nexport function findAuthenticatedLazyRouteBundle(path: string): AuthenticatedLazyRouteBundle | undefined {\n return AUTHENTICATED_LAZY_ROUTE_BUNDLES.find((bundle) => bundle.match(path));\n}\n"],"mappings":";AAoBA,SAAS,cAAc,MAAc,UAAsC;AACzE,QAAO,SAAS,MAAM,WAAW,SAAS,UAAU,KAAK,WAAW,GAAG,OAAO,GAAG,CAAC;;AAGpF,MAAa,mCAA4E;CACvF;EACE,IAAI;EACJ,QAAQ,SAAS,cAAc,MAAM,CAAC,iBAAiB,CAAC;EACxD,MAAM,YAAY;GAChB,MAAM,EAAE,4BAA4B,MAAM,OAAO;AACjD,UAAO,EAAE,UAAU,yBAAyB;;EAE/C;CACD;EACE,IAAI;EACJ,QAAQ,SAAS,cAAc,MAAM,CAAC,eAAe,CAAC;EACtD,MAAM,YAAY;GAChB,MAAM,EAAE,yBAAyB,MAAM,OAAO;AAC9C,UAAO,EAAE,UAAU,sBAAsB;;EAE5C;CACD;EACE,IAAI;EACJ,QAAQ,SAAS,cAAc,MAAM,CAAC,gBAAgB,CAAC;EACvD,MAAM,YAAY;GAChB,MAAM,EAAE,0BAA0B,MAAM,OAAO;AAC/C,UAAO,EAAE,UAAU,uBAAuB;;EAE7C;CACD;EACE,IAAI;EACJ,QAAQ,SACN,SAAS,4CACT,SAAS;EACX,MAAM,YAAY;GAChB,MAAM,EAAE,iCAAiC,MAAM,OAAO;AACtD,UAAO,EAAE,UAAU,8BAA8B;;EAEpD;CACD;EACE,IAAI;EAIJ,QAAQ,SAAS,cAAc,MAAM,CAAC,eAAe,CAAC;EACtD,MAAM,YAAY;GAChB,MAAM,EAAE,0BAA0B,MAAM,OAAO;AAC/C,UAAO,EAAE,UAAU,uBAAuB;;EAE7C;CACD;EACE,IAAI;EACJ,QAAQ,SACN,cAAc,MAAM,CAAC,eAAe,yBAAyB,CAAC;EAChE,MAAM,YAAY;GAChB,MAAM,EAAE,yBAAyB,MAAM,OAAO;AAC9C,UAAO,EAAE,UAAU,sBAAsB;;EAE5C;CACD;EACE,IAAI;EACJ,QAAQ,SAAS,cAAc,MAAM,CAAC,cAAc,CAAC;EACrD,MAAM,YAAY;GAChB,MAAM,EAAE,yBAAyB,MAAM,OAAO;AAC9C,UAAO,EAAE,UAAU,sBAAsB;;EAE5C;CACD;EACE,IAAI;EACJ,QAAQ,SAAS,cAAc,MAAM,CAAC,gBAAgB,CAAC;EACvD,MAAM,YAAY;GAChB,MAAM,EAAE,2BAA2B,MAAM,OAAO;AAChD,UAAO,EAAE,UAAU,wBAAwB;;EAE9C;CACD;EACE,IAAI;EACJ,QAAQ,SAAS,cAAc,MAAM,CAAC,eAAe,oBAAoB,CAAC;EAC1E,MAAM,YAAY;GAChB,MAAM,EAAE,yBAAyB,MAAM,OAAO;AAC9C,UAAO,EAAE,UAAU,sBAAsB;;EAE5C;CACD;EACE,IAAI;EACJ,QAAQ,SACN,cAAc,MAAM;GAClB;GACA;GACA;GACA;GACA;GACD,CAAC;EACJ,MAAM,YAAY;GAChB,MAAM,EAAE,yCAAyC,MAAM,OAAO;AAC9D,UAAO,EAAE,UAAU,sCAAsC;;EAE5D;CACD;EACE,IAAI;EACJ,QAAQ,SACN,cAAc,MAAM;GAAC;GAAe;GAAoB;GAAkB;GAAa,CAAC;EAC1F,MAAM,YAAY;GAChB,MAAM,EAAE,yBAAyB,MAAM,OAAO;AAC9C,UAAO,EAAE,UAAU,sBAAsB;;EAE5C;CACD;EACE,IAAI;EACJ,QAAQ,SAAS,cAAc,MAAM,CAAC,iBAAiB,cAAc,CAAC;EACtE,MAAM,YAAY;GAChB,MAAM,EAAE,iCAAiC,MAAM,OAAO;AACtD,UAAO,EAAE,UAAU,8BAA8B;;EAEpD;CACD;EACE,IAAI;EACJ,QAAQ,SAAS,cAAc,MAAM,CAAC,YAAY,CAAC;EACnD,MAAM,YAAY;GAChB,MAAM,EAAE,uBAAuB,MAAM,OAAO;AAC5C,UAAO,EAAE,UAAU,oBAAoB;;EAE1C;CACD;EACE,IAAI;EACJ,QAAQ,SAAS,cAAc,MAAM,CAAC,aAAa,CAAC;EACpD,MAAM,YAAY;GAChB,MAAM,EAAE,wBAAwB,MAAM,OAAO;AAC7C,UAAO,EAAE,UAAU,qBAAqB;;EAE3C;CACD;EACE,IAAI;EACJ,QAAQ,SAAS,cAAc,MAAM,CAAC,YAAY,CAAC;EACnD,MAAM,YAAY;GAChB,MAAM,EAAE,uBAAuB,MAAM,OAAO;AAC5C,UAAO,EAAE,UAAU,oBAAoB;;EAE1C;CACD;EACE,IAAI;EACJ,QAAQ,SAAS,cAAc,MAAM,CAAC,cAAc,CAAC;EACrD,MAAM,YAAY;GAChB,MAAM,EAAE,wBAAwB,MAAM,OAAO;AAC7C,UAAO,EAAE,UAAU,qBAAqB;;EAE3C;CACD;EACE,IAAI;EACJ,QAAQ,SAAS,cAAc,MAAM,CAAC,cAAc,CAAC;EACrD,MAAM,YAAY;GAChB,MAAM,EAAE,yBAAyB,MAAM,OAAO;AAC9C,UAAO,EAAE,UAAU,sBAAsB;;EAE5C;CACD;EACE,IAAI;EACJ,QAAQ,SAAS,cAAc,MAAM,CAAC,gBAAgB,CAAC;EACvD,MAAM,YAAY;GAChB,MAAM,EAAE,2BAA2B,MAAM,OAAO;AAChD,UAAO,EAAE,UAAU,wBAAwB;;EAE9C;CACD;EACE,IAAI;EACJ,QAAQ,SAAS,cAAc,MAAM,CAAC,eAAe,CAAC;EACtD,MAAM,YAAY;GAChB,MAAM,EAAE,mCAAmC,MAAM,OAAO;AACxD,UAAO,EAAE,UAAU,gCAAgC;;EAEtD;CACD;EACE,IAAI;EACJ,QAAQ,SAAS,cAAc,MAAM,CAAC,cAAc,CAAC;EACrD,MAAM,YAAY;GAChB,MAAM,EAAE,yBAAyB,MAAM,OAAO;AAC9C,UAAO,EAAE,UAAU,sBAAsB;;EAE5C;CACD;EACE,IAAI;EACJ,QAAQ,SAAS,cAAc,MAAM,CAAC,aAAa,CAAC,IAAI,SAAS;EACjE,MAAM,YAAY;GAChB,MAAM,EAAE,wBAAwB,MAAM,OAAO;AAC7C,UAAO,EAAE,UAAU,qBAAqB;;EAE3C;CACD;EACE,IAAI;EACJ,QAAQ,SAAS,cAAc,MAAM,CAAC,WAAW,CAAC;EAClD,MAAM,YAAY;GAChB,MAAM,EAAE,sBAAsB,MAAM,OAAO;AAC3C,UAAO,EAAE,UAAU,mBAAmB;;EAEzC;CACF;AAED,MAAa,yBAAwD,CACnE;CACE,IAAI;CACJ,UAAU,CAAC,KAAK;CAChB,QAAQ,SAAS,cAAc,MAAM,CAAC,KAAK,CAAC;CAC5C,MAAM,YAAY;EAChB,MAAM,EAAE,8BAA8B,MAAM,OAAO;AACnD,SAAO,EAAE,eAAe,2BAA2B;;CAEtD,EACD;CACE,IAAI;CACJ,UAAU;EACR;EACA;EACA;EACD;CACD,QAAQ,SACN,SAAS,gCACT,SAAS,2BACT,SAAS;CACX,MAAM,YAAY;EAChB,MAAM,EAAE,+BAA+B,MAAM,OAAO;AACpD,SAAO,EAAE,eAAe,4BAA4B;;CAEvD,CACF;AAED,SAAgB,iCAAiC,MAAwD;AACvG,QAAO,iCAAiC,MAAM,WAAW,OAAO,MAAM,KAAK,CAAC"}
1
+ {"version":3,"file":"lazy-bundles.js","names":[],"sources":["../../../../../src/gateway/hono/routes/lazy-bundles.ts"],"sourcesContent":["import type { Hono } from 'hono';\n\nimport type { GatewayService } from '../../service.js';\nimport type { AuthenticatedRouteDeps } from './deps.js';\n\nexport type AuthenticatedLazyRouteBundle = {\n id: string;\n match: (path: string) => boolean;\n load: () => Promise<{ register: (authenticated: Hono, deps: AuthenticatedRouteDeps) => void }>;\n};\n\nexport type AppLazyRouteBundle = {\n id: string;\n prefixes: readonly string[];\n match: (path: string) => boolean;\n load: () => Promise<{\n registerOnApp: (app: Hono, service: GatewayService) => void;\n }>;\n};\n\nfunction startsWithAny(path: string, prefixes: readonly string[]): boolean {\n return prefixes.some((prefix) => path === prefix || path.startsWith(`${prefix}/`));\n}\n\nexport const AUTHENTICATED_LAZY_ROUTE_BUNDLES: readonly AuthenticatedLazyRouteBundle[] = [\n {\n id: 'workspace',\n match: (path) => startsWithAny(path, ['/api/workspace']),\n load: async () => {\n const { registerWorkspaceRoutes } = await import('./workspace.js');\n return { register: registerWorkspaceRoutes };\n },\n },\n {\n id: 'host-fs',\n match: (path) => startsWithAny(path, ['/api/host/fs']),\n load: async () => {\n const { registerHostFsRoutes } = await import('./host-fs.js');\n return { register: registerHostFsRoutes };\n },\n },\n {\n id: 'channels',\n match: (path) => startsWithAny(path, ['/api/channels']),\n load: async () => {\n const { registerChannelRoutes } = await import('./channels.js');\n return { register: registerChannelRoutes };\n },\n },\n {\n id: 'browser-install',\n match: (path) =>\n path === '/api/browser/playwright/install/stream' ||\n path === '/api/browser/cloakbrowser/install/stream',\n load: async () => {\n const { registerBrowserInstallRoutes } = await import('./browser-install.js');\n return { register: registerBrowserInstallRoutes };\n },\n },\n {\n id: 'browser',\n // `browser-install` above already matched the SSE install streams; this\n // catches the remaining /api/browser/* handlers (extension, cdp,\n // cloakbrowser doctor/launch/install, playwright doctor/install, cloud).\n match: (path) => startsWithAny(path, ['/api/browser']),\n load: async () => {\n const { registerBrowserRoutes } = await import('./browser.js');\n return { register: registerBrowserRoutes };\n },\n },\n {\n id: 'config',\n match: (path) =>\n startsWithAny(path, ['/api/config', '/api/heartbeat/trigger']),\n load: async () => {\n const { registerConfigRoutes } = await import('./config.js');\n return { register: registerConfigRoutes };\n },\n },\n {\n id: 'doctor',\n match: (path) => startsWithAny(path, ['/api/doctor']),\n load: async () => {\n const { registerDoctorRoutes } = await import('./doctor.js');\n return { register: registerDoctorRoutes };\n },\n },\n {\n id: 'dreaming',\n match: (path) => startsWithAny(path, ['/api/dreaming']),\n load: async () => {\n const { registerDreamingRoutes } = await import('./dreaming.js');\n return { register: registerDreamingRoutes };\n },\n },\n {\n id: 'agents',\n match: (path) => startsWithAny(path, ['/api/agents', '/api/voice/models']),\n load: async () => {\n const { registerAgentsRoutes } = await import('./agents.js');\n return { register: registerAgentsRoutes };\n },\n },\n {\n id: 'auth-registry-extensions',\n match: (path) =>\n startsWithAny(path, [\n '/api/auth',\n '/api/registry',\n '/api/extensions',\n '/api/context',\n '/api/marketplace',\n ]),\n load: async () => {\n const { registerAuthRegistryExtensionsRoutes } = await import('./auth-registry-extensions.js');\n return { register: registerAuthRegistryExtensionsRoutes };\n },\n },\n {\n id: 'models',\n match: (path) =>\n startsWithAny(path, ['/api/models', '/api/models-json', '/api/providers', '/api/image']),\n load: async () => {\n const { registerModelsRoutes } = await import('./models.js');\n return { register: registerModelsRoutes };\n },\n },\n {\n id: 'commands-skills',\n match: (path) => startsWithAny(path, ['/api/commands', '/api/skills']),\n load: async () => {\n const { registerCommandsSkillsRoutes } = await import('./commands-skills.js');\n return { register: registerCommandsSkillsRoutes };\n },\n },\n {\n id: 'cron',\n match: (path) => startsWithAny(path, ['/api/cron']),\n load: async () => {\n const { registerCronRoutes } = await import('./cron.js');\n return { register: registerCronRoutes };\n },\n },\n {\n id: 'goals',\n match: (path) => startsWithAny(path, ['/api/goals']),\n load: async () => {\n const { registerGoalsRoutes } = await import('./goals.js');\n return { register: registerGoalsRoutes };\n },\n },\n {\n id: 'logs',\n match: (path) => startsWithAny(path, ['/api/logs']),\n load: async () => {\n const { registerLogsRoutes } = await import('./logs.js');\n return { register: registerLogsRoutes };\n },\n },\n {\n id: 'shares',\n match: (path) => startsWithAny(path, ['/api/shares']),\n load: async () => {\n const { registerShareRoutes } = await import('./shares.js');\n return { register: registerShareRoutes };\n },\n },\n {\n id: 'site-shares',\n match: (path) => startsWithAny(path, ['/api/site-shares']),\n load: async () => {\n const { registerSiteShareRoutes } = await import('./site-shares.js');\n return { register: registerSiteShareRoutes };\n },\n },\n {\n id: 'tunnel',\n match: (path) => startsWithAny(path, ['/api/tunnel']),\n load: async () => {\n const { registerTunnelRoutes } = await import('./tunnel.js');\n return { register: registerTunnelRoutes };\n },\n },\n {\n id: 'exposure',\n match: (path) => startsWithAny(path, ['/api/exposure']),\n load: async () => {\n const { registerExposureRoutes } = await import('./exposure.js');\n return { register: registerExposureRoutes };\n },\n },\n {\n id: 'extension-gateway',\n match: (path) => startsWithAny(path, ['/api/gateway']),\n load: async () => {\n const { registerExtensionGatewayRoutes } = await import('./extension-gateway.js');\n return { register: registerExtensionGatewayRoutes };\n },\n },\n {\n id: 'update',\n match: (path) => startsWithAny(path, ['/api/update']),\n load: async () => {\n const { registerUpdateRoutes } = await import('./update.js');\n return { register: registerUpdateRoutes };\n },\n },\n {\n id: 'voice',\n match: (path) => startsWithAny(path, ['/api/voice']) && path !== '/api/voice/models',\n load: async () => {\n const { registerVoiceRoutes } = await import('./voice.js');\n return { register: registerVoiceRoutes };\n },\n },\n {\n id: 'mcp',\n match: (path) => startsWithAny(path, ['/api/mcp']),\n load: async () => {\n const { registerMcpRoutes } = await import('./mcp.js');\n return { register: registerMcpRoutes };\n },\n },\n];\n\nexport const APP_LAZY_ROUTE_BUNDLES: readonly AppLazyRouteBundle[] = [\n {\n id: 'shares-public',\n prefixes: ['/s'],\n match: (path) => startsWithAny(path, ['/s']),\n load: async () => {\n const { registerSharePublicRoutes } = await import('./shares.js');\n return { registerOnApp: registerSharePublicRoutes };\n },\n },\n {\n id: 'tunnel-public',\n prefixes: [\n '/api/tunnel/pair/ping',\n '/api/tunnel/pair/validate-url',\n '/api/tunnel/exchange-token',\n ],\n match: (path) =>\n path === '/api/tunnel/exchange-token' ||\n path === '/api/tunnel/pair/ping' ||\n path === '/api/tunnel/pair/validate-url',\n load: async () => {\n const { registerTunnelPublicRoutes } = await import('./tunnel.js');\n return { registerOnApp: registerTunnelPublicRoutes };\n },\n },\n];\n\nexport function findAuthenticatedLazyRouteBundle(path: string): AuthenticatedLazyRouteBundle | undefined {\n return AUTHENTICATED_LAZY_ROUTE_BUNDLES.find((bundle) => bundle.match(path));\n}\n"],"mappings":"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"}
@@ -1,8 +1,8 @@
1
1
  import { resolveModelsJsonPath } from "../../../config/paths.js";
2
- import { CredentialResolver, init_credentials } from "../../../auth/credentials.js";
3
2
  import { init_resolve_config_value, testApiKeyResolution } from "../../../config/resolve-config-value.js";
4
3
  import { init_models_json, loadModelsJson, saveModelsJson, validateModelsConfig } from "../../../config/models-json.js";
5
4
  import { getModelRegistry } from "../../../providers/model-registry.js";
5
+ import { CredentialResolver, init_credentials } from "../../../auth/credentials.js";
6
6
  import { getProviderRegistry, init_plugin_registry } from "../../../providers/plugin-registry.js";
7
7
  import { PROVIDER_META, getAllModels, getAllProviders, getAvailableModels, getProviderActiveKeySource, init_providers, isProviderConfigured } from "../../../providers/index.js";
8
8
  import { getImageGenerationProvider } from "../../../agent/image/generation/provider-registry.js";