@xopcai/xopc 0.0.93 → 0.0.94

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 (356) hide show
  1. package/dist/browser-ext/manifest.json +1 -1
  2. package/dist/extensions/feishu/src/outbound/media-load.js +1 -1
  3. package/dist/extensions/feishu/src/workflow-progress.js +1 -1
  4. package/dist/extensions/telegram/src/plugin.js +1 -1
  5. package/dist/extensions/telegram/src/routing-integration.js +2 -2
  6. package/dist/extensions/telegram/src/workflow-progress.js +1 -1
  7. package/dist/extensions/telegram/xopc.extension.json +1 -1
  8. package/dist/extensions/weixin/src/api/api.js +2 -2
  9. package/dist/extensions/weixin/src/auth/accounts.js +1 -1
  10. package/dist/extensions/weixin/src/cdn/upload.js +1 -1
  11. package/dist/extensions/weixin/src/media/data-url.js +1 -1
  12. package/dist/extensions/weixin/src/messaging/debug-mode.js +1 -1
  13. package/dist/extensions/weixin/src/messaging/inbound.js +1 -1
  14. package/dist/extensions/weixin/src/messaging/process-message.js +1 -1
  15. package/dist/extensions/weixin/src/plugin.js +1 -1
  16. package/dist/extensions/weixin/src/storage/sync-buf.js +1 -1
  17. package/dist/extensions/weixin/src/workflow-progress.js +1 -1
  18. package/dist/gateway/static/root/assets/agents-OqhbJkMf.js +222 -0
  19. package/dist/gateway/static/root/assets/apps-page-OHXW9XP8.js +1 -0
  20. package/dist/gateway/static/root/assets/channels-settings-4N2R-jof.js +1 -0
  21. package/dist/gateway/static/root/assets/{channels-status-swr-CsGkK9h9.js → channels-status-swr-Bv6f9kDq.js} +1 -1
  22. package/dist/gateway/static/root/assets/{cron-api-CyAm0xJT.js → cron-api-BtaQaHJq.js} +1 -1
  23. package/dist/gateway/static/root/assets/cron-page-Dah32HJK.js +1 -0
  24. package/dist/gateway/static/root/assets/{dist-DHwVV8XK.js → dist-BJfD9Qvs.js} +1 -1
  25. package/dist/gateway/static/root/assets/{extension-debug-page-BK8kcc4F.js → extension-debug-page-DnYuMzmH.js} +1 -1
  26. package/dist/gateway/static/root/assets/{extension-page-Cf8X_QUc.js → extension-page-CJfc-6XV.js} +1 -1
  27. package/dist/gateway/static/root/assets/{extension-settings-page-C5-YLMmy.js → extension-settings-page-BxdfYQMG.js} +1 -1
  28. package/dist/gateway/static/root/assets/{fetch-BAPnkYbC.js → fetch-B0aeeY0q.js} +1 -1
  29. package/dist/gateway/static/root/assets/{field-primitives-8p7ucXa1.js → field-primitives-DOLHwowi.js} +1 -1
  30. package/dist/gateway/static/root/assets/{heartbeat-config-api-CpgW2sGp.js → heartbeat-config-api-Bj2INAf5.js} +1 -1
  31. package/dist/gateway/static/root/assets/index-Bj_l8QDp.css +1 -0
  32. package/dist/gateway/static/root/assets/{index-Do52EfZK.js → index-DuQ1XPoA.js} +99 -98
  33. package/dist/gateway/static/root/assets/logs-page-AsOgLNJE.js +2 -0
  34. package/dist/gateway/static/root/assets/{note-detail-page-WLM6FUIi.js → note-detail-page-24J4mVP-.js} +3 -3
  35. package/dist/gateway/static/root/assets/{note-time-EFyIVhec.js → note-time-JBszYV3s.js} +1 -1
  36. package/dist/gateway/static/root/assets/{notes-page-BYPVYcYn.js → notes-page-BApAirFB.js} +1 -1
  37. package/dist/gateway/static/root/assets/sessions-page-DX9huWsA.js +1 -0
  38. package/dist/gateway/static/root/assets/{settings-advanced-gate-CEs8pGh6.js → settings-advanced-gate-DWvhsTuz.js} +1 -1
  39. package/dist/gateway/static/root/assets/{settings-form-section-C6cGTVwK.js → settings-form-section-CxMjaMiy.js} +1 -1
  40. package/dist/gateway/static/root/assets/settings-page-4VmUTzQs.js +3 -0
  41. package/dist/gateway/static/root/assets/{share-preview-page-tnIfJ4K6.js → share-preview-page-IX0TJvRd.js} +1 -1
  42. package/dist/gateway/static/root/assets/skills-page-CGKGKfwe.js +2 -0
  43. package/dist/gateway/static/root/assets/{theme-store-D6EsNTPr.js → theme-store-Cg_SuBw0.js} +1 -1
  44. package/dist/gateway/static/root/assets/{url-CTjpm0Uz.js → url-BHHmdJYc.js} +2 -2
  45. package/dist/gateway/static/root/assets/{utils-C86AVfY-.js → utils-BmlcxR2j.js} +1 -1
  46. package/dist/gateway/static/root/assets/voice-api-key-field-DaGm2N4J.js +1 -0
  47. package/dist/gateway/static/root/assets/{workflow-page.utils-DsEriMFW.js → workflow-page.utils-D0vsIGHD.js} +1 -1
  48. package/dist/gateway/static/root/assets/workflows-page-BFCrD3nw.js +27 -0
  49. package/dist/gateway/static/root/index.html +5 -5
  50. package/dist/package.js +1 -1
  51. package/dist/src/agent/agent-manager.js +7 -7
  52. package/dist/src/agent/agent-scope.js +1 -1
  53. package/dist/src/agent/bootstrap/load-bootstrap-files.js +1 -1
  54. package/dist/src/agent/context/workspace-seed.js +2 -2
  55. package/dist/src/agent/goals/goal-run-store.js +4 -4
  56. package/dist/src/agent/goals/persistent-goal-service.js +1 -1
  57. package/dist/src/agent/goals/post-turn.js +2 -2
  58. package/dist/src/agent/image/load-image-media.js +2 -2
  59. package/dist/src/agent/inbound/turn-dispatcher.d.ts +1 -0
  60. package/dist/src/agent/inbound/turn-dispatcher.js +3 -0
  61. package/dist/src/agent/inbound/turn-dispatcher.js.map +1 -1
  62. package/dist/src/agent/ipc/bus.js +1 -1
  63. package/dist/src/agent/ipc/inbox.js +2 -2
  64. package/dist/src/agent/ipc/socket.js +1 -1
  65. package/dist/src/agent/lifecycle/handlers/compaction.js +1 -1
  66. package/dist/src/agent/lifecycle/handlers/compaction.js.map +1 -1
  67. package/dist/src/agent/mcp/bundle-mcp-materialize.js +2 -2
  68. package/dist/src/agent/mcp/bundle-mcp-materialize.js.map +1 -1
  69. package/dist/src/agent/mcp/bundle-mcp-runtime.js +18 -5
  70. package/dist/src/agent/mcp/bundle-mcp-runtime.js.map +1 -1
  71. package/dist/src/agent/mcp/mcp-transport-config.js +11 -4
  72. package/dist/src/agent/mcp/mcp-transport-config.js.map +1 -1
  73. package/dist/src/agent/mcp/mcp-transport.js +2 -2
  74. package/dist/src/agent/mcp/mcp-transport.js.map +1 -1
  75. package/dist/src/agent/memory/builtin-memory-store.js +1 -1
  76. package/dist/src/agent/memory/dreaming/deep-promotion.js +1 -1
  77. package/dist/src/agent/memory/dreaming/events.js +1 -1
  78. package/dist/src/agent/memory/dreaming/last-run.js +1 -1
  79. package/dist/src/agent/memory/dreaming/light-sweep.js +1 -1
  80. package/dist/src/agent/memory/dreaming/preview.js +1 -1
  81. package/dist/src/agent/memory/dreaming/rem-patterns.js +1 -1
  82. package/dist/src/agent/memory/dreaming/short-term-store.js +1 -1
  83. package/dist/src/agent/memory/dreaming/utils.js +1 -1
  84. package/dist/src/agent/memory/plugin-discovery.js +1 -1
  85. package/dist/src/agent/models/manager.js +1 -1
  86. package/dist/src/agent/prompt/service-prompt-builder.js +2 -2
  87. package/dist/src/agent/reply/post-compaction-context.js +1 -1
  88. package/dist/src/agent/reply/workspace-boundary-read.js +1 -1
  89. package/dist/src/agent/sandbox/path-policy.js +2 -2
  90. package/dist/src/agent/service/build-direct-message-content.js +1 -1
  91. package/dist/src/agent/service/process-direct-streaming.d.ts +1 -0
  92. package/dist/src/agent/service/process-direct-streaming.js +15 -12
  93. package/dist/src/agent/service/process-direct-streaming.js.map +1 -1
  94. package/dist/src/agent/service.d.ts +4 -2
  95. package/dist/src/agent/service.js +24 -8
  96. package/dist/src/agent/service.js.map +1 -1
  97. package/dist/src/agent/service.types.d.ts +3 -1
  98. package/dist/src/agent/session/session-inspector.js +1 -1
  99. package/dist/src/agent/skills/config.js +1 -1
  100. package/dist/src/agent/skills/hub-hash.js +2 -2
  101. package/dist/src/agent/skills/hub-lock.js +1 -1
  102. package/dist/src/agent/skills/hub-pull.js +2 -2
  103. package/dist/src/agent/skills/index.js +1 -1
  104. package/dist/src/agent/skills/managed-store.js +1 -1
  105. package/dist/src/agent/skills/scanner.js +1 -1
  106. package/dist/src/agent/skills/skill-manage-ops.js +1 -1
  107. package/dist/src/agent/skills/skill-manager.js +1 -1
  108. package/dist/src/agent/tools/browser/tool/browser-use-tool.js +1 -1
  109. package/dist/src/agent/tools/browser/tool/browser-use-tool.js.map +1 -1
  110. package/dist/src/agent/tools/dreaming-tool.js +1 -1
  111. package/dist/src/agent/tools/factory.js +1 -1
  112. package/dist/src/agent/tools/image-generate-tool.js +1 -1
  113. package/dist/src/agent/tools/search/registry.js +1 -1
  114. package/dist/src/agent/tools/search/registry.js.map +1 -1
  115. package/dist/src/agent/tools/send-media.js +1 -1
  116. package/dist/src/agent/tools/session-search-tool.js +1 -1
  117. package/dist/src/agent/tools/session-search-tool.js.map +1 -1
  118. package/dist/src/agent/tools/skill-manage-tool.js +1 -1
  119. package/dist/src/agent/tools/workflow-tool.js +2 -2
  120. package/dist/src/agent/tools/workflow-tool.js.map +1 -1
  121. package/dist/src/agent/tools/write.js +1 -1
  122. package/dist/src/agent/workflow/catalog.js +1 -1
  123. package/dist/src/agent/workflow/progress-broker.js +1 -1
  124. package/dist/src/agent/workflow/progress-broker.js.map +1 -1
  125. package/dist/src/agent/workflow/subagent-runner.js +1 -1
  126. package/dist/src/agent/workflow/subagent-runner.js.map +1 -1
  127. package/dist/src/auth/credentials.js +3 -3
  128. package/dist/src/auth/profiles/store.js +1 -1
  129. package/dist/src/auth/sync-provider-auth.js +1 -1
  130. package/dist/src/browser/cache-dir-policy.js +1 -1
  131. package/dist/src/browser/cdp-local-launcher.js +2 -2
  132. package/dist/src/browser/providers/browser-ext-install.js +3 -3
  133. package/dist/src/browser/providers/cloakbrowser.js +4 -4
  134. package/dist/src/browser/providers/playwright-doctor.js +1 -1
  135. package/dist/src/browser/stealth.js +1 -1
  136. package/dist/src/channels/attachments/inbound-persist.js +1 -1
  137. package/dist/src/channels/attachments/outbound-tts-persist.js +1 -1
  138. package/dist/src/channels/outbound/persist-store.js +1 -1
  139. package/dist/src/channels/pairing/allow-from-file.js +1 -1
  140. package/dist/src/channels/pairing/pairing-store.js +2 -2
  141. package/dist/src/channels/pipeline.js +3 -2
  142. package/dist/src/channels/pipeline.js.map +1 -1
  143. package/dist/src/chat-commands/agent-edit.js +2 -2
  144. package/dist/src/chat-commands/builtins/config.js +2 -2
  145. package/dist/src/chat-commands/context.js +1 -1
  146. package/dist/src/cli/cli-log-level-preset.d.ts +1 -1
  147. package/dist/src/cli/cli-log-level-preset.js +2 -2
  148. package/dist/src/cli/cli-log-level-preset.js.map +1 -1
  149. package/dist/src/cli/commands/config.js +1 -1
  150. package/dist/src/cli/commands/doctor/checks/config-health.js +1 -1
  151. package/dist/src/cli/commands/doctor/checks/provider-auth.js +1 -1
  152. package/dist/src/cli/commands/doctor/checks/session-integrity.js +2 -2
  153. package/dist/src/cli/commands/doctor/checks/state-integrity.js +1 -1
  154. package/dist/src/cli/commands/doctor/checks/workspace-status.js +1 -1
  155. package/dist/src/cli/commands/extension-dev.js +1 -1
  156. package/dist/src/cli/commands/extension-marketplace.js +1 -1
  157. package/dist/src/cli/commands/extension-pack.js +1 -1
  158. package/dist/src/cli/commands/gateway/logs.js +1 -1
  159. package/dist/src/cli/commands/image.js +1 -1
  160. package/dist/src/cli/commands/init.js +4 -4
  161. package/dist/src/cli/commands/logs.js +3 -3
  162. package/dist/src/cli/commands/logs.js.map +1 -1
  163. package/dist/src/cli/commands/onboard.js +1 -1
  164. package/dist/src/cli/utils/init-workspace-core.js +2 -2
  165. package/dist/src/commands/agents.config.js +1 -1
  166. package/dist/src/config/agent-profile.js +1 -1
  167. package/dist/src/config/gateway-bind.js +1 -1
  168. package/dist/src/config/index.js +5 -5
  169. package/dist/src/config/loader.js +2 -2
  170. package/dist/src/config/models-json.js +2 -2
  171. package/dist/src/config/paths-state.js +1 -1
  172. package/dist/src/config/profile.js +2 -2
  173. package/dist/src/config/workspace-path.js +1 -1
  174. package/dist/src/cron/executor.js +9 -6
  175. package/dist/src/cron/executor.js.map +1 -1
  176. package/dist/src/cron/persistence.js +1 -1
  177. package/dist/src/cron/run-log-store.js +1 -1
  178. package/dist/src/daemon/constants.js +1 -1
  179. package/dist/src/daemon/install-plan.js +2 -2
  180. package/dist/src/daemon/launchd.js +2 -2
  181. package/dist/src/daemon/schtasks.js +2 -2
  182. package/dist/src/daemon/systemd.js +2 -2
  183. package/dist/src/extensions/bundle-mcp.js +1 -1
  184. package/dist/src/extensions/discover-extensions.js +1 -1
  185. package/dist/src/extensions/health.js +1 -1
  186. package/dist/src/extensions/loader.js +1 -1
  187. package/dist/src/extensions/lockfile.js +2 -2
  188. package/dist/src/extensions/update.js +1 -1
  189. package/dist/src/gateway/agents-admin.js +3 -3
  190. package/dist/src/gateway/file-path-classifier.js +2 -2
  191. package/dist/src/gateway/heartbeat/service.js +1 -1
  192. package/dist/src/gateway/hono/app.js +4 -1
  193. package/dist/src/gateway/hono/app.js.map +1 -1
  194. package/dist/src/gateway/hono/lib/config-payload.js +1 -1
  195. package/dist/src/gateway/hono/lib/extension-store.js +2 -2
  196. package/dist/src/gateway/hono/lib/route-logger.d.ts +6 -0
  197. package/dist/src/gateway/hono/lib/route-logger.js +31 -0
  198. package/dist/src/gateway/hono/lib/route-logger.js.map +1 -0
  199. package/dist/src/gateway/hono/lib/static-ui.js +2 -2
  200. package/dist/src/gateway/hono/middleware/auth.js +16 -3
  201. package/dist/src/gateway/hono/middleware/auth.js.map +1 -1
  202. package/dist/src/gateway/hono/middleware/logger.js +1 -1
  203. package/dist/src/gateway/hono/middleware/logger.js.map +1 -1
  204. package/dist/src/gateway/hono/middleware/route-errors.d.ts +5 -0
  205. package/dist/src/gateway/hono/middleware/route-errors.js +27 -0
  206. package/dist/src/gateway/hono/middleware/route-errors.js.map +1 -0
  207. package/dist/src/gateway/hono/oauth.js +1 -1
  208. package/dist/src/gateway/hono/routes/agent-stream.js +6 -0
  209. package/dist/src/gateway/hono/routes/agent-stream.js.map +1 -1
  210. package/dist/src/gateway/hono/routes/agents.js +1 -1
  211. package/dist/src/gateway/hono/routes/auth-registry-extensions.js +1 -1
  212. package/dist/src/gateway/hono/routes/browser-install.js +2 -4
  213. package/dist/src/gateway/hono/routes/browser-install.js.map +1 -1
  214. package/dist/src/gateway/hono/routes/config-patch/misc.js +1 -1
  215. package/dist/src/gateway/hono/routes/config.js +25 -11
  216. package/dist/src/gateway/hono/routes/config.js.map +1 -1
  217. package/dist/src/gateway/hono/routes/cron.js +5 -0
  218. package/dist/src/gateway/hono/routes/cron.js.map +1 -1
  219. package/dist/src/gateway/hono/routes/dreaming.js +1 -1
  220. package/dist/src/gateway/hono/routes/host-fs.js +4 -6
  221. package/dist/src/gateway/hono/routes/host-fs.js.map +1 -1
  222. package/dist/src/gateway/hono/routes/lazy-bundles.js +14 -1
  223. package/dist/src/gateway/hono/routes/lazy-bundles.js.map +1 -1
  224. package/dist/src/gateway/hono/routes/lazy-fallback.js +3 -0
  225. package/dist/src/gateway/hono/routes/lazy-fallback.js.map +1 -1
  226. package/dist/src/gateway/hono/routes/logs.js +39 -7
  227. package/dist/src/gateway/hono/routes/logs.js.map +1 -1
  228. package/dist/src/gateway/hono/routes/mcp.d.ts +3 -0
  229. package/dist/src/gateway/hono/routes/mcp.js +107 -0
  230. package/dist/src/gateway/hono/routes/mcp.js.map +1 -0
  231. package/dist/src/gateway/hono/routes/models.js +1 -1
  232. package/dist/src/gateway/hono/routes/sessions.js +6 -0
  233. package/dist/src/gateway/hono/routes/sessions.js.map +1 -1
  234. package/dist/src/gateway/hono/routes/shares.js +1 -1
  235. package/dist/src/gateway/hono/routes/update.js +2 -4
  236. package/dist/src/gateway/hono/routes/update.js.map +1 -1
  237. package/dist/src/gateway/hono/routes/voice.js +2 -4
  238. package/dist/src/gateway/hono/routes/voice.js.map +1 -1
  239. package/dist/src/gateway/hono/routes/workspace.js +4 -6
  240. package/dist/src/gateway/hono/routes/workspace.js.map +1 -1
  241. package/dist/src/gateway/hono/sse.js +9 -2
  242. package/dist/src/gateway/hono/sse.js.map +1 -1
  243. package/dist/src/gateway/lock.js +3 -3
  244. package/dist/src/gateway/ports.js +1 -1
  245. package/dist/src/gateway/service/agent-runner.js +3 -3
  246. package/dist/src/gateway/service/agent-runner.js.map +1 -1
  247. package/dist/src/gateway/service/config-coordinator.js +14 -6
  248. package/dist/src/gateway/service/config-coordinator.js.map +1 -1
  249. package/dist/src/gateway/service/marketplace-service.js +3 -3
  250. package/dist/src/gateway/service/marketplace-service.js.map +1 -1
  251. package/dist/src/gateway/service/run-gateway-agent.js +22 -5
  252. package/dist/src/gateway/service/run-gateway-agent.js.map +1 -1
  253. package/dist/src/gateway/service/sse-hub.js +1 -1
  254. package/dist/src/gateway/service/sse-hub.js.map +1 -1
  255. package/dist/src/gateway/service.js +13 -6
  256. package/dist/src/gateway/service.js.map +1 -1
  257. package/dist/src/gateway/workspace-fs-file-list.js +1 -1
  258. package/dist/src/heartbeat/index.js +1 -1
  259. package/dist/src/infra/brew.js +1 -1
  260. package/dist/src/infra/package-json.js +1 -1
  261. package/dist/src/infra/package-update-steps.js +1 -1
  262. package/dist/src/infra/path-env.js +2 -2
  263. package/dist/src/infra/restart.js +2 -2
  264. package/dist/src/infra/stable-node-path.js +1 -1
  265. package/dist/src/infra/update-check.js +1 -1
  266. package/dist/src/infra/update-global.js +1 -1
  267. package/dist/src/infra/update-lock.js +3 -3
  268. package/dist/src/infra/update-runner.js +1 -1
  269. package/dist/src/infra/update-startup.js +2 -2
  270. package/dist/src/infra/write-file-atomic.js +2 -2
  271. package/dist/src/mcp/channel-bridge.js +26 -2
  272. package/dist/src/mcp/channel-bridge.js.map +1 -1
  273. package/dist/src/mcp/gateway-http-client.js +24 -2
  274. package/dist/src/mcp/gateway-http-client.js.map +1 -1
  275. package/dist/src/notes/store.js +2 -2
  276. package/dist/src/providers/auth-runtime/auth-profile-store.js +1 -1
  277. package/dist/src/providers/index.js +2 -2
  278. package/dist/src/providers/model-registry.js +1 -1
  279. package/dist/src/session/config-store.js +12 -6
  280. package/dist/src/session/config-store.js.map +1 -1
  281. package/dist/src/session/index.d.ts +1 -1
  282. package/dist/src/session/index.js +2 -2
  283. package/dist/src/session/init-session-turn.js +2 -2
  284. package/dist/src/session/manager.js +8 -1
  285. package/dist/src/session/manager.js.map +1 -1
  286. package/dist/src/session/parity/jsonl-transcript-io.js +2 -2
  287. package/dist/src/session/parity/sessions-json-file.js +1 -1
  288. package/dist/src/session/parity/transcript-file-lock.js +2 -2
  289. package/dist/src/session/parity/transcript-paths.js +1 -1
  290. package/dist/src/session/resolve-session.js +4 -4
  291. package/dist/src/session/search-index-cache.js +1 -1
  292. package/dist/src/session/search-index.js +1 -1
  293. package/dist/src/session/session-title.d.ts +19 -3
  294. package/dist/src/session/session-title.js +84 -9
  295. package/dist/src/session/session-title.js.map +1 -1
  296. package/dist/src/session/store.js +6 -6
  297. package/dist/src/share/share-auto.js +2 -2
  298. package/dist/src/share/share-store.js +3 -3
  299. package/dist/src/share/share-thumbnail.js +2 -2
  300. package/dist/src/share/share-zip.js +1 -1
  301. package/dist/src/share/site-share-store.js +3 -3
  302. package/dist/src/share/site-static-serve.js +1 -1
  303. package/dist/src/tui/clipboard-image.js +3 -3
  304. package/dist/src/tui/theme-manager.js +1 -1
  305. package/dist/src/tui/tui-keybindings-file.js +1 -1
  306. package/dist/src/tui/tui-scoped-models.js +2 -2
  307. package/dist/src/tui/tui-settings.js +1 -1
  308. package/dist/src/tui/tui.js +3 -3
  309. package/dist/src/tunnel/frpc-binary.js +3 -3
  310. package/dist/src/tunnel/frpc-config.js +1 -1
  311. package/dist/src/tunnel/frpc-extract.js +1 -1
  312. package/dist/src/tunnel/tunnel-state.js +1 -1
  313. package/dist/src/utils/index.js +4 -4
  314. package/dist/src/utils/logger/audit.js +1 -1
  315. package/dist/src/utils/logger/config.js +2 -6
  316. package/dist/src/utils/logger/config.js.map +1 -1
  317. package/dist/src/utils/logger/context.d.ts +3 -22
  318. package/dist/src/utils/logger/context.js +4 -32
  319. package/dist/src/utils/logger/context.js.map +1 -1
  320. package/dist/src/utils/logger/index.d.ts +4 -7
  321. package/dist/src/utils/logger/index.js +9 -28
  322. package/dist/src/utils/logger/index.js.map +1 -1
  323. package/dist/src/utils/logger/log-store.d.ts +14 -32
  324. package/dist/src/utils/logger/log-store.js +68 -119
  325. package/dist/src/utils/logger/log-store.js.map +1 -1
  326. package/dist/src/utils/logger/log-stream.d.ts +5 -70
  327. package/dist/src/utils/logger/log-stream.js +67 -178
  328. package/dist/src/utils/logger/log-stream.js.map +1 -1
  329. package/dist/src/utils/logger/pino-record.d.ts +8 -0
  330. package/dist/src/utils/logger/pino-record.js +83 -0
  331. package/dist/src/utils/logger/pino-record.js.map +1 -0
  332. package/dist/src/utils/logger/rotation.js +1 -1
  333. package/dist/src/utils/logger/stats.d.ts +1 -1
  334. package/dist/src/utils/logger/stats.js +2 -2
  335. package/dist/src/utils/logger/stats.js.map +1 -1
  336. package/dist/src/utils/logger/streams.js +18 -0
  337. package/dist/src/utils/logger/streams.js.map +1 -1
  338. package/dist/src/utils/logger/types.d.ts +0 -9
  339. package/dist/src/utils/logger/types.js.map +1 -1
  340. package/dist/src/utils/logger.js +4 -4
  341. package/dist/src/voice/tts/audio.js +1 -1
  342. package/dist/src/voice/tts/providers/edge-speech.js +2 -2
  343. package/dist/src/workflows/store/event-store.js +1 -1
  344. package/dist/src/workflows/store/run-store.js +1 -1
  345. package/package.json +2 -1
  346. package/dist/gateway/static/root/assets/agents-C7tTJLP9.js +0 -222
  347. package/dist/gateway/static/root/assets/apps-page-BbzdMyrg.js +0 -1
  348. package/dist/gateway/static/root/assets/channels-settings-B49vG2hE.js +0 -1
  349. package/dist/gateway/static/root/assets/cron-page-Bjx7IOdR.js +0 -1
  350. package/dist/gateway/static/root/assets/index-CwDdudZM.css +0 -1
  351. package/dist/gateway/static/root/assets/logs-page-BxukQ-J-.js +0 -1
  352. package/dist/gateway/static/root/assets/sessions-page-BFD2_-Cl.js +0 -1
  353. package/dist/gateway/static/root/assets/settings-page-BiP5iH46.js +0 -2
  354. package/dist/gateway/static/root/assets/skills-page-CNDctFIn.js +0 -2
  355. package/dist/gateway/static/root/assets/voice-api-key-field-CalxUkxm.js +0 -1
  356. package/dist/gateway/static/root/assets/workflows-page-D2fRxXJG.js +0 -27
@@ -1,11 +1,9 @@
1
- import { createLogger } from "../../../utils/logger/index.js";
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";
1
+ import { createGatewayRouteLogger } from "../lib/route-logger.js";
5
2
  import * as os$1 from "node:os";
3
+ import * as path$1 from "node:path";
4
+ import { readdir, realpath, stat } from "node:fs/promises";
6
5
  //#region src/gateway/hono/routes/host-fs.ts
7
- init_logger();
8
- const log = createLogger("HostFs");
6
+ const log = createGatewayRouteLogger("HostFs");
9
7
  function jsonError(status, message) {
10
8
  return Response.json({
11
9
  ok: false,
@@ -1 +1 @@
1
- {"version":3,"file":"host-fs.js","names":["path","os"],"sources":["../../../../../src/gateway/hono/routes/host-fs.ts"],"sourcesContent":["/**\n * Authenticated host filesystem browse API for Web UI (e.g. session working directory).\n * Lists directories the gateway process can read — intended for trusted operators only.\n */\nimport type { Hono } from 'hono';\nimport { readdir, realpath, stat } from 'node:fs/promises';\nimport * as os from 'node:os';\nimport * as path from 'node:path';\n\nimport { createLogger } from '../../../utils/logger.js';\nimport type { AuthenticatedRouteDeps } from './deps.js';\n\nconst log = createLogger('HostFs');\n\nfunction jsonError(status: number, message: string) {\n return Response.json({ ok: false, error: { message } }, { status });\n}\n\nfunction skipDotName(name: string): boolean {\n return name.startsWith('.');\n}\n\n/** Windows: true if `p` is a drive root like `C:\\`. */\nfunction isWindowsDriveRoot(p: string): boolean {\n return /^[A-Za-z]:\\\\?$/.test(path.normalize(p).replace(/\\\\$/, '\\\\'));\n}\n\nfunction parentDirectory(absNormalized: string): string | null {\n if (process.platform === 'win32') {\n const n = path.normalize(absNormalized);\n if (isWindowsDriveRoot(n)) {\n return null;\n }\n const d = path.dirname(n);\n if (d === n) return null;\n return d;\n }\n const n = path.normalize(absNormalized);\n if (n === '/' || n === path.parse(n).root) {\n return null;\n }\n const d = path.dirname(n);\n if (d === n) return null;\n return d;\n}\n\nasync function listWindowsDrives(): Promise<\n { name: string; absolutePath: string; isDirectory: boolean }[]\n> {\n const entries: { name: string; absolutePath: string; isDirectory: boolean }[] = [];\n for (let i = 0; i < 26; i++) {\n const letter = String.fromCharCode(65 + i);\n const root = `${letter}:\\\\`;\n try {\n await stat(root);\n entries.push({ name: root, absolutePath: root, isDirectory: true });\n } catch {\n /* not mounted */\n }\n }\n entries.sort((a, b) => a.name.localeCompare(b.name));\n return entries;\n}\n\nexport function registerHostFsRoutes(authenticated: Hono, _deps: AuthenticatedRouteDeps): void {\n authenticated.get('/api/host/fs/meta', (c) => {\n return c.json({\n ok: true,\n payload: {\n hostname: os.hostname(),\n platform: process.platform,\n pathSeparator: path.sep,\n },\n });\n });\n\n /**\n * GET /api/host/fs/list?path=\n * - Omit or empty `path`: root — `/` on POSIX; drive letters on Windows.\n * - Otherwise: absolute path on the gateway host (URL-encoded).\n */\n authenticated.get('/api/host/fs/list', async (c) => {\n const raw = c.req.query('path');\n const trimmed = typeof raw === 'string' ? raw.trim() : '';\n\n if (!trimmed) {\n if (process.platform === 'win32') {\n try {\n const entries = await listWindowsDrives();\n return c.json({\n ok: true,\n payload: {\n currentPath: '',\n parentPath: null,\n entries,\n },\n });\n } catch (err) {\n log.warn({ err }, 'host fs list drives failed');\n return jsonError(500, 'Failed to list drives');\n }\n }\n\n try {\n const root = await realpath('/');\n const dirents = await readdir(root, { withFileTypes: true });\n const entries: { name: string; absolutePath: string; isDirectory: boolean }[] = [];\n for (const e of dirents) {\n if (skipDotName(e.name)) continue;\n const fullPath = path.join(root, e.name);\n if (e.isDirectory()) {\n entries.push({ name: e.name, absolutePath: fullPath, isDirectory: true });\n } else {\n entries.push({ name: e.name, absolutePath: fullPath, isDirectory: false });\n }\n }\n entries.sort((a, b) => {\n if (a.isDirectory !== b.isDirectory) return a.isDirectory ? -1 : 1;\n return a.name.localeCompare(b.name);\n });\n return c.json({\n ok: true,\n payload: {\n currentPath: root,\n parentPath: null,\n entries,\n },\n });\n } catch (err) {\n log.warn({ err }, 'host fs list root failed');\n const msg = err instanceof Error ? err.message : String(err);\n return jsonError(500, msg || 'Failed to read root');\n }\n }\n\n let resolved: string;\n try {\n const normalized = path.normalize(trimmed);\n resolved = await realpath(normalized);\n } catch (err) {\n log.warn({ err, path: trimmed }, 'host fs realpath failed');\n return jsonError(404, 'Path not found');\n }\n\n let st;\n try {\n st = await stat(resolved);\n } catch (err) {\n log.warn({ err, path: resolved }, 'host fs stat failed');\n return jsonError(404, 'Path not found');\n }\n\n if (!st.isDirectory()) {\n return jsonError(400, 'Not a directory');\n }\n\n const parentPath = parentDirectory(resolved);\n\n try {\n const dirents = await readdir(resolved, { withFileTypes: true });\n const entries: { name: string; absolutePath: string; isDirectory: boolean }[] = [];\n for (const e of dirents) {\n if (skipDotName(e.name)) continue;\n const fullPath = path.join(resolved, e.name);\n entries.push({\n name: e.name,\n absolutePath: fullPath,\n isDirectory: e.isDirectory(),\n });\n }\n entries.sort((a, b) => {\n if (a.isDirectory !== b.isDirectory) return a.isDirectory ? -1 : 1;\n return a.name.localeCompare(b.name);\n });\n return c.json({\n ok: true,\n payload: {\n currentPath: resolved,\n parentPath,\n entries,\n },\n });\n } catch (err) {\n log.warn({ err, path: resolved }, 'host fs readdir failed');\n const msg = err instanceof Error ? err.message : String(err);\n if ((err as NodeJS.ErrnoException)?.code === 'EACCES') {\n return jsonError(403, 'Permission denied');\n }\n return jsonError(500, msg || 'Failed to read directory');\n }\n });\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"host-fs.js","names":["path","os"],"sources":["../../../../../src/gateway/hono/routes/host-fs.ts"],"sourcesContent":["/**\n * Authenticated host filesystem browse API for Web UI (e.g. session working directory).\n * Lists directories the gateway process can read — intended for trusted operators only.\n */\nimport type { Hono } from 'hono';\nimport { readdir, realpath, stat } from 'node:fs/promises';\nimport * as os from 'node:os';\nimport * as path from 'node:path';\n\nimport { createGatewayRouteLogger } from '../lib/route-logger.js';\nimport type { AuthenticatedRouteDeps } from './deps.js';\n\nconst log = createGatewayRouteLogger('HostFs');\n\nfunction jsonError(status: number, message: string) {\n return Response.json({ ok: false, error: { message } }, { status });\n}\n\nfunction skipDotName(name: string): boolean {\n return name.startsWith('.');\n}\n\n/** Windows: true if `p` is a drive root like `C:\\`. */\nfunction isWindowsDriveRoot(p: string): boolean {\n return /^[A-Za-z]:\\\\?$/.test(path.normalize(p).replace(/\\\\$/, '\\\\'));\n}\n\nfunction parentDirectory(absNormalized: string): string | null {\n if (process.platform === 'win32') {\n const n = path.normalize(absNormalized);\n if (isWindowsDriveRoot(n)) {\n return null;\n }\n const d = path.dirname(n);\n if (d === n) return null;\n return d;\n }\n const n = path.normalize(absNormalized);\n if (n === '/' || n === path.parse(n).root) {\n return null;\n }\n const d = path.dirname(n);\n if (d === n) return null;\n return d;\n}\n\nasync function listWindowsDrives(): Promise<\n { name: string; absolutePath: string; isDirectory: boolean }[]\n> {\n const entries: { name: string; absolutePath: string; isDirectory: boolean }[] = [];\n for (let i = 0; i < 26; i++) {\n const letter = String.fromCharCode(65 + i);\n const root = `${letter}:\\\\`;\n try {\n await stat(root);\n entries.push({ name: root, absolutePath: root, isDirectory: true });\n } catch {\n /* not mounted */\n }\n }\n entries.sort((a, b) => a.name.localeCompare(b.name));\n return entries;\n}\n\nexport function registerHostFsRoutes(authenticated: Hono, _deps: AuthenticatedRouteDeps): void {\n authenticated.get('/api/host/fs/meta', (c) => {\n return c.json({\n ok: true,\n payload: {\n hostname: os.hostname(),\n platform: process.platform,\n pathSeparator: path.sep,\n },\n });\n });\n\n /**\n * GET /api/host/fs/list?path=\n * - Omit or empty `path`: root — `/` on POSIX; drive letters on Windows.\n * - Otherwise: absolute path on the gateway host (URL-encoded).\n */\n authenticated.get('/api/host/fs/list', async (c) => {\n const raw = c.req.query('path');\n const trimmed = typeof raw === 'string' ? raw.trim() : '';\n\n if (!trimmed) {\n if (process.platform === 'win32') {\n try {\n const entries = await listWindowsDrives();\n return c.json({\n ok: true,\n payload: {\n currentPath: '',\n parentPath: null,\n entries,\n },\n });\n } catch (err) {\n log.warn({ err }, 'host fs list drives failed');\n return jsonError(500, 'Failed to list drives');\n }\n }\n\n try {\n const root = await realpath('/');\n const dirents = await readdir(root, { withFileTypes: true });\n const entries: { name: string; absolutePath: string; isDirectory: boolean }[] = [];\n for (const e of dirents) {\n if (skipDotName(e.name)) continue;\n const fullPath = path.join(root, e.name);\n if (e.isDirectory()) {\n entries.push({ name: e.name, absolutePath: fullPath, isDirectory: true });\n } else {\n entries.push({ name: e.name, absolutePath: fullPath, isDirectory: false });\n }\n }\n entries.sort((a, b) => {\n if (a.isDirectory !== b.isDirectory) return a.isDirectory ? -1 : 1;\n return a.name.localeCompare(b.name);\n });\n return c.json({\n ok: true,\n payload: {\n currentPath: root,\n parentPath: null,\n entries,\n },\n });\n } catch (err) {\n log.warn({ err }, 'host fs list root failed');\n const msg = err instanceof Error ? err.message : String(err);\n return jsonError(500, msg || 'Failed to read root');\n }\n }\n\n let resolved: string;\n try {\n const normalized = path.normalize(trimmed);\n resolved = await realpath(normalized);\n } catch (err) {\n log.warn({ err, path: trimmed }, 'host fs realpath failed');\n return jsonError(404, 'Path not found');\n }\n\n let st;\n try {\n st = await stat(resolved);\n } catch (err) {\n log.warn({ err, path: resolved }, 'host fs stat failed');\n return jsonError(404, 'Path not found');\n }\n\n if (!st.isDirectory()) {\n return jsonError(400, 'Not a directory');\n }\n\n const parentPath = parentDirectory(resolved);\n\n try {\n const dirents = await readdir(resolved, { withFileTypes: true });\n const entries: { name: string; absolutePath: string; isDirectory: boolean }[] = [];\n for (const e of dirents) {\n if (skipDotName(e.name)) continue;\n const fullPath = path.join(resolved, e.name);\n entries.push({\n name: e.name,\n absolutePath: fullPath,\n isDirectory: e.isDirectory(),\n });\n }\n entries.sort((a, b) => {\n if (a.isDirectory !== b.isDirectory) return a.isDirectory ? -1 : 1;\n return a.name.localeCompare(b.name);\n });\n return c.json({\n ok: true,\n payload: {\n currentPath: resolved,\n parentPath,\n entries,\n },\n });\n } catch (err) {\n log.warn({ err, path: resolved }, 'host fs readdir failed');\n const msg = err instanceof Error ? err.message : String(err);\n if ((err as NodeJS.ErrnoException)?.code === 'EACCES') {\n return jsonError(403, 'Permission denied');\n }\n return jsonError(500, msg || 'Failed to read directory');\n }\n });\n}\n"],"mappings":"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"}
@@ -45,7 +45,12 @@ const AUTHENTICATED_LAZY_ROUTE_BUNDLES = [
45
45
  },
46
46
  {
47
47
  id: "config",
48
- match: (path) => startsWithAny(path, ["/api/config", "/api/heartbeat/trigger"]),
48
+ match: (path) => startsWithAny(path, [
49
+ "/api/config",
50
+ "/api/heartbeat/trigger",
51
+ "/api/gateway/reveal-auth-secret",
52
+ "/api/tools/web/reveal-search-api-key"
53
+ ]),
49
54
  load: async () => {
50
55
  const { registerConfigRoutes } = await import("./config.js");
51
56
  return { register: registerConfigRoutes };
@@ -221,6 +226,14 @@ const AUTHENTICATED_LAZY_ROUTE_BUNDLES = [
221
226
  const { registerConnectorRoutes } = await import("./connectors.js");
222
227
  return { register: registerConnectorRoutes };
223
228
  }
229
+ },
230
+ {
231
+ id: "mcp",
232
+ match: (path) => startsWithAny(path, ["/api/mcp"]),
233
+ load: async () => {
234
+ const { registerMcpRoutes } = await import("./mcp.js");
235
+ return { register: registerMcpRoutes };
236
+ }
224
237
  }
225
238
  ];
226
239
  const APP_LAZY_ROUTE_BUNDLES = [{
@@ -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: 'notes',\n match: (path) => startsWithAny(path, ['/api/notes']),\n load: async () => {\n const { registerNotesRoutes } = await import('./notes.js');\n return { register: registerNotesRoutes };\n },\n },\n {\n id: 'home',\n match: (path) => startsWithAny(path, ['/api/home']),\n load: async () => {\n const { registerHomeRoutes } = await import('./home.js');\n return { register: registerHomeRoutes };\n },\n },\n {\n id: 'workflows',\n match: (path) => startsWithAny(path, ['/api/workflows']),\n load: async () => {\n const { registerWorkflowRoutes } = await import('./workflows.js');\n return { register: registerWorkflowRoutes };\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: 'connectors',\n match: (path) => startsWithAny(path, ['/api/connectors']),\n load: async () => {\n const { registerConnectorRoutes } = await import('./connectors.js');\n return { register: registerConnectorRoutes };\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
+ {"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, [\n '/api/config',\n '/api/heartbeat/trigger',\n // Secret reveal handlers live in config routes but use /api/gateway and\n // /api/tools paths; without these prefixes the extension-gateway bundle\n // matches first and returns 404 (no handler for multi-segment paths).\n '/api/gateway/reveal-auth-secret',\n '/api/tools/web/reveal-search-api-key',\n ]),\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: 'notes',\n match: (path) => startsWithAny(path, ['/api/notes']),\n load: async () => {\n const { registerNotesRoutes } = await import('./notes.js');\n return { register: registerNotesRoutes };\n },\n },\n {\n id: 'home',\n match: (path) => startsWithAny(path, ['/api/home']),\n load: async () => {\n const { registerHomeRoutes } = await import('./home.js');\n return { register: registerHomeRoutes };\n },\n },\n {\n id: 'workflows',\n match: (path) => startsWithAny(path, ['/api/workflows']),\n load: async () => {\n const { registerWorkflowRoutes } = await import('./workflows.js');\n return { register: registerWorkflowRoutes };\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: 'connectors',\n match: (path) => startsWithAny(path, ['/api/connectors']),\n load: async () => {\n const { registerConnectorRoutes } = await import('./connectors.js');\n return { register: registerConnectorRoutes };\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,6 +1,8 @@
1
+ import { createGatewayRouteLogger, logRouteError } from "../lib/route-logger.js";
1
2
  import { APP_LAZY_ROUTE_BUNDLES, AUTHENTICATED_LAZY_ROUTE_BUNDLES, findAuthenticatedLazyRouteBundle } from "./lazy-bundles.js";
2
3
  import { Hono } from "hono";
3
4
  //#region src/gateway/hono/routes/lazy-fallback.ts
5
+ const log = createGatewayRouteLogger("LazyRoutes");
4
6
  const authenticatedSubApps = /* @__PURE__ */ new Map();
5
7
  const appSubApps = /* @__PURE__ */ new Map();
6
8
  const authenticatedLoadPromises = /* @__PURE__ */ new Map();
@@ -60,6 +62,7 @@ async function forwardToSubApp(c, sub) {
60
62
  return await sub.fetch(c.req.raw, c.env, c.executionCtx);
61
63
  } catch (error) {
62
64
  if (error instanceof Error && error.message.includes("ExecutionContext")) return sub.fetch(c.req.raw, c.env);
65
+ logRouteError(log, c, error, "gateway.route.lazy_forward");
63
66
  throw error;
64
67
  }
65
68
  }
@@ -1 +1 @@
1
- {"version":3,"file":"lazy-fallback.js","names":[],"sources":["../../../../../src/gateway/hono/routes/lazy-fallback.ts"],"sourcesContent":["import { Hono, type Context } from 'hono';\n\nimport type { GatewayService } from '../../service.js';\nimport type { AuthenticatedRouteDeps } from './deps.js';\nimport {\n APP_LAZY_ROUTE_BUNDLES,\n AUTHENTICATED_LAZY_ROUTE_BUNDLES,\n findAuthenticatedLazyRouteBundle,\n} from './lazy-bundles.js';\n\nconst authenticatedSubApps = new Map<string, Hono>();\nconst appSubApps = new Map<string, Hono>();\nconst authenticatedLoadPromises = new Map<string, Promise<Hono>>();\nconst appLoadPromises = new Map<string, Promise<Hono>>();\n\nexport function getLoadedLazyRouteBundleIdsForTests(): {\n authenticated: string[];\n app: string[];\n} {\n return {\n authenticated: [...authenticatedSubApps.keys()],\n app: [...appSubApps.keys()],\n };\n}\n\nexport function resetLazyRouteBundlesForTests(): void {\n authenticatedSubApps.clear();\n appSubApps.clear();\n authenticatedLoadPromises.clear();\n appLoadPromises.clear();\n}\n\nasync function ensureAuthenticatedLazyBundle(\n bundleId: string,\n deps: AuthenticatedRouteDeps,\n): Promise<Hono | null> {\n const existing = authenticatedSubApps.get(bundleId);\n if (existing) {\n return existing;\n }\n\n let pending = authenticatedLoadPromises.get(bundleId);\n if (!pending) {\n const bundle = AUTHENTICATED_LAZY_ROUTE_BUNDLES.find((entry) => entry.id === bundleId);\n if (!bundle) {\n return null;\n }\n pending = (async () => {\n const mod = await bundle.load();\n const sub = new Hono();\n mod.register(sub, deps);\n authenticatedSubApps.set(bundleId, sub);\n authenticatedLoadPromises.delete(bundleId);\n return sub;\n })();\n authenticatedLoadPromises.set(bundleId, pending);\n }\n\n return pending;\n}\n\nasync function ensureAppLazyBundle(\n bundleId: string,\n params: { service: GatewayService; deps: AuthenticatedRouteDeps },\n): Promise<Hono | null> {\n const existing = appSubApps.get(bundleId);\n if (existing) {\n return existing;\n }\n\n let pending = appLoadPromises.get(bundleId);\n if (!pending) {\n const bundle = APP_LAZY_ROUTE_BUNDLES.find((entry) => entry.id === bundleId);\n if (!bundle) {\n return null;\n }\n pending = (async () => {\n const mod = await bundle.load();\n const sub = new Hono();\n if (mod.registerOnApp) {\n mod.registerOnApp(sub, params.service);\n }\n appSubApps.set(bundleId, sub);\n appLoadPromises.delete(bundleId);\n return sub;\n })();\n appLoadPromises.set(bundleId, pending);\n }\n\n return pending;\n}\n\nasync function forwardToSubApp(c: Context, sub: Hono): Promise<Response> {\n try {\n return await sub.fetch(c.req.raw, c.env, c.executionCtx);\n } catch (error) {\n if (error instanceof Error && error.message.includes('ExecutionContext')) {\n return sub.fetch(c.req.raw, c.env);\n }\n throw error;\n }\n}\n\nexport function registerAuthenticatedLazyRouteFallback(\n authenticated: Hono,\n deps: AuthenticatedRouteDeps,\n): void {\n authenticated.all('*', async (c) => {\n const bundle = findAuthenticatedLazyRouteBundle(c.req.path);\n if (!bundle) {\n return c.json({ error: 'Not found' }, 404);\n }\n const sub = await ensureAuthenticatedLazyBundle(bundle.id, deps);\n if (!sub) {\n return c.json({ error: 'Not found' }, 404);\n }\n return forwardToSubApp(c, sub);\n });\n}\n\nexport function mountAppLazyRoutePrefixes(\n app: Hono,\n params: { service: GatewayService; deps: AuthenticatedRouteDeps },\n): void {\n for (const bundle of APP_LAZY_ROUTE_BUNDLES) {\n const handler = async (c: Context) => {\n const sub = await ensureAppLazyBundle(bundle.id, params);\n if (!sub) {\n return c.json({ error: 'Not found' }, 404);\n }\n return forwardToSubApp(c, sub);\n };\n\n for (const prefix of bundle.prefixes) {\n app.all(prefix, handler);\n app.all(`${prefix}/*`, handler);\n }\n }\n}\n"],"mappings":";;;AAUA,MAAM,uCAAuB,IAAI,KAAmB;AACpD,MAAM,6BAAa,IAAI,KAAmB;AAC1C,MAAM,4CAA4B,IAAI,KAA4B;AAClE,MAAM,kCAAkB,IAAI,KAA4B;AAExD,SAAgB,sCAGd;AACA,QAAO;EACL,eAAe,CAAC,GAAG,qBAAqB,MAAM,CAAC;EAC/C,KAAK,CAAC,GAAG,WAAW,MAAM,CAAC;EAC5B;;AAGH,SAAgB,gCAAsC;AACpD,sBAAqB,OAAO;AAC5B,YAAW,OAAO;AAClB,2BAA0B,OAAO;AACjC,iBAAgB,OAAO;;AAGzB,eAAe,8BACb,UACA,MACsB;CACtB,MAAM,WAAW,qBAAqB,IAAI,SAAS;AACnD,KAAI,SACF,QAAO;CAGT,IAAI,UAAU,0BAA0B,IAAI,SAAS;AACrD,KAAI,CAAC,SAAS;EACZ,MAAM,SAAS,iCAAiC,MAAM,UAAU,MAAM,OAAO,SAAS;AACtF,MAAI,CAAC,OACH,QAAO;AAET,aAAW,YAAY;GACrB,MAAM,MAAM,MAAM,OAAO,MAAM;GAC/B,MAAM,MAAM,IAAI,MAAM;AACtB,OAAI,SAAS,KAAK,KAAK;AACvB,wBAAqB,IAAI,UAAU,IAAI;AACvC,6BAA0B,OAAO,SAAS;AAC1C,UAAO;MACL;AACJ,4BAA0B,IAAI,UAAU,QAAQ;;AAGlD,QAAO;;AAGT,eAAe,oBACb,UACA,QACsB;CACtB,MAAM,WAAW,WAAW,IAAI,SAAS;AACzC,KAAI,SACF,QAAO;CAGT,IAAI,UAAU,gBAAgB,IAAI,SAAS;AAC3C,KAAI,CAAC,SAAS;EACZ,MAAM,SAAS,uBAAuB,MAAM,UAAU,MAAM,OAAO,SAAS;AAC5E,MAAI,CAAC,OACH,QAAO;AAET,aAAW,YAAY;GACrB,MAAM,MAAM,MAAM,OAAO,MAAM;GAC/B,MAAM,MAAM,IAAI,MAAM;AACtB,OAAI,IAAI,cACN,KAAI,cAAc,KAAK,OAAO,QAAQ;AAExC,cAAW,IAAI,UAAU,IAAI;AAC7B,mBAAgB,OAAO,SAAS;AAChC,UAAO;MACL;AACJ,kBAAgB,IAAI,UAAU,QAAQ;;AAGxC,QAAO;;AAGT,eAAe,gBAAgB,GAAY,KAA8B;AACvE,KAAI;AACF,SAAO,MAAM,IAAI,MAAM,EAAE,IAAI,KAAK,EAAE,KAAK,EAAE,aAAa;UACjD,OAAO;AACd,MAAI,iBAAiB,SAAS,MAAM,QAAQ,SAAS,mBAAmB,CACtE,QAAO,IAAI,MAAM,EAAE,IAAI,KAAK,EAAE,IAAI;AAEpC,QAAM;;;AAIV,SAAgB,uCACd,eACA,MACM;AACN,eAAc,IAAI,KAAK,OAAO,MAAM;EAClC,MAAM,SAAS,iCAAiC,EAAE,IAAI,KAAK;AAC3D,MAAI,CAAC,OACH,QAAO,EAAE,KAAK,EAAE,OAAO,aAAa,EAAE,IAAI;EAE5C,MAAM,MAAM,MAAM,8BAA8B,OAAO,IAAI,KAAK;AAChE,MAAI,CAAC,IACH,QAAO,EAAE,KAAK,EAAE,OAAO,aAAa,EAAE,IAAI;AAE5C,SAAO,gBAAgB,GAAG,IAAI;GAC9B;;AAGJ,SAAgB,0BACd,KACA,QACM;AACN,MAAK,MAAM,UAAU,wBAAwB;EAC3C,MAAM,UAAU,OAAO,MAAe;GACpC,MAAM,MAAM,MAAM,oBAAoB,OAAO,IAAI,OAAO;AACxD,OAAI,CAAC,IACH,QAAO,EAAE,KAAK,EAAE,OAAO,aAAa,EAAE,IAAI;AAE5C,UAAO,gBAAgB,GAAG,IAAI;;AAGhC,OAAK,MAAM,UAAU,OAAO,UAAU;AACpC,OAAI,IAAI,QAAQ,QAAQ;AACxB,OAAI,IAAI,GAAG,OAAO,KAAK,QAAQ"}
1
+ {"version":3,"file":"lazy-fallback.js","names":[],"sources":["../../../../../src/gateway/hono/routes/lazy-fallback.ts"],"sourcesContent":["import { Hono, type Context } from 'hono';\n\nimport type { GatewayService } from '../../service.js';\nimport type { AuthenticatedRouteDeps } from './deps.js';\nimport {\n APP_LAZY_ROUTE_BUNDLES,\n AUTHENTICATED_LAZY_ROUTE_BUNDLES,\n findAuthenticatedLazyRouteBundle,\n} from './lazy-bundles.js';\nimport { createGatewayRouteLogger, logRouteError } from '../lib/route-logger.js';\n\nconst log = createGatewayRouteLogger('LazyRoutes');\n\nconst authenticatedSubApps = new Map<string, Hono>();\nconst appSubApps = new Map<string, Hono>();\nconst authenticatedLoadPromises = new Map<string, Promise<Hono>>();\nconst appLoadPromises = new Map<string, Promise<Hono>>();\n\nexport function getLoadedLazyRouteBundleIdsForTests(): {\n authenticated: string[];\n app: string[];\n} {\n return {\n authenticated: [...authenticatedSubApps.keys()],\n app: [...appSubApps.keys()],\n };\n}\n\nexport function resetLazyRouteBundlesForTests(): void {\n authenticatedSubApps.clear();\n appSubApps.clear();\n authenticatedLoadPromises.clear();\n appLoadPromises.clear();\n}\n\nasync function ensureAuthenticatedLazyBundle(\n bundleId: string,\n deps: AuthenticatedRouteDeps,\n): Promise<Hono | null> {\n const existing = authenticatedSubApps.get(bundleId);\n if (existing) {\n return existing;\n }\n\n let pending = authenticatedLoadPromises.get(bundleId);\n if (!pending) {\n const bundle = AUTHENTICATED_LAZY_ROUTE_BUNDLES.find((entry) => entry.id === bundleId);\n if (!bundle) {\n return null;\n }\n pending = (async () => {\n const mod = await bundle.load();\n const sub = new Hono();\n mod.register(sub, deps);\n authenticatedSubApps.set(bundleId, sub);\n authenticatedLoadPromises.delete(bundleId);\n return sub;\n })();\n authenticatedLoadPromises.set(bundleId, pending);\n }\n\n return pending;\n}\n\nasync function ensureAppLazyBundle(\n bundleId: string,\n params: { service: GatewayService; deps: AuthenticatedRouteDeps },\n): Promise<Hono | null> {\n const existing = appSubApps.get(bundleId);\n if (existing) {\n return existing;\n }\n\n let pending = appLoadPromises.get(bundleId);\n if (!pending) {\n const bundle = APP_LAZY_ROUTE_BUNDLES.find((entry) => entry.id === bundleId);\n if (!bundle) {\n return null;\n }\n pending = (async () => {\n const mod = await bundle.load();\n const sub = new Hono();\n if (mod.registerOnApp) {\n mod.registerOnApp(sub, params.service);\n }\n appSubApps.set(bundleId, sub);\n appLoadPromises.delete(bundleId);\n return sub;\n })();\n appLoadPromises.set(bundleId, pending);\n }\n\n return pending;\n}\n\nasync function forwardToSubApp(c: Context, sub: Hono): Promise<Response> {\n try {\n return await sub.fetch(c.req.raw, c.env, c.executionCtx);\n } catch (error) {\n if (error instanceof Error && error.message.includes('ExecutionContext')) {\n return sub.fetch(c.req.raw, c.env);\n }\n logRouteError(log, c, error, 'gateway.route.lazy_forward');\n throw error;\n }\n}\n\nexport function registerAuthenticatedLazyRouteFallback(\n authenticated: Hono,\n deps: AuthenticatedRouteDeps,\n): void {\n authenticated.all('*', async (c) => {\n const bundle = findAuthenticatedLazyRouteBundle(c.req.path);\n if (!bundle) {\n return c.json({ error: 'Not found' }, 404);\n }\n const sub = await ensureAuthenticatedLazyBundle(bundle.id, deps);\n if (!sub) {\n return c.json({ error: 'Not found' }, 404);\n }\n return forwardToSubApp(c, sub);\n });\n}\n\nexport function mountAppLazyRoutePrefixes(\n app: Hono,\n params: { service: GatewayService; deps: AuthenticatedRouteDeps },\n): void {\n for (const bundle of APP_LAZY_ROUTE_BUNDLES) {\n const handler = async (c: Context) => {\n const sub = await ensureAppLazyBundle(bundle.id, params);\n if (!sub) {\n return c.json({ error: 'Not found' }, 404);\n }\n return forwardToSubApp(c, sub);\n };\n\n for (const prefix of bundle.prefixes) {\n app.all(prefix, handler);\n app.all(`${prefix}/*`, handler);\n }\n }\n}\n"],"mappings":"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"}
@@ -1,5 +1,7 @@
1
- import { LOG_DIR, getLogFiles, getLogLevels, getLogModules, getLogStats, queryLogs } from "../../../utils/logger/log-store.js";
1
+ import { createGatewayRouteLogger } from "../lib/route-logger.js";
2
+ import { LOG_DIR, getFileLogStats, getLogErrorSummary, getLogFiles, getLogLevels, getLogModules, queryLogs } from "../../../utils/logger/log-store.js";
2
3
  //#region src/gateway/hono/routes/logs.ts
4
+ const log = createGatewayRouteLogger("Logs");
3
5
  function registerLogsRoutes(authenticated, _deps) {
4
6
  authenticated.get("/api/logs", async (c) => {
5
7
  const query = c.req.query();
@@ -9,6 +11,8 @@ function registerLogsRoutes(authenticated, _deps) {
9
11
  to: query.to,
10
12
  q: query.q,
11
13
  module: query.module,
14
+ requestId: query.requestId,
15
+ sessionId: query.sessionId,
12
16
  limit: query.limit ? parseInt(query.limit) : 100,
13
17
  offset: query.offset ? parseInt(query.offset) : 0
14
18
  });
@@ -22,8 +26,26 @@ function registerLogsRoutes(authenticated, _deps) {
22
26
  return c.json({ files });
23
27
  });
24
28
  authenticated.get("/api/logs/stats", async (c) => {
25
- const stats = getLogStats();
26
- return c.json(stats);
29
+ const { getRuntimeLogStats } = await import("../../../utils/logger.js");
30
+ const [fileStats, runtimeStats] = await Promise.all([getFileLogStats(), Promise.resolve(getRuntimeLogStats())]);
31
+ return c.json({
32
+ byLevel: fileStats.byLevel,
33
+ runtime: {
34
+ byLevel: runtimeStats.byLevel,
35
+ byModule: runtimeStats.byModule,
36
+ errorsLast24h: runtimeStats.errorsLast24h,
37
+ uptimeMs: runtimeStats.uptimeMs
38
+ }
39
+ });
40
+ });
41
+ authenticated.get("/api/logs/errors/summary", async (c) => {
42
+ const query = c.req.query();
43
+ const items = await getLogErrorSummary({
44
+ from: query.from,
45
+ to: query.to,
46
+ limit: query.limit ? parseInt(query.limit, 10) : 20
47
+ });
48
+ return c.json({ items });
27
49
  });
28
50
  authenticated.get("/api/logs/levels", async (c) => {
29
51
  return c.json({ levels: getLogLevels() });
@@ -36,9 +58,9 @@ function registerLogsRoutes(authenticated, _deps) {
36
58
  return c.json({ dir: LOG_DIR });
37
59
  });
38
60
  authenticated.get("/api/logs/health", async (c) => {
39
- const { getLogDir, getLogStats, isLoggerShuttingDown } = await import("../../../utils/logger.js");
61
+ const { getLogDir, getRuntimeLogStats, isLoggerShuttingDown } = await import("../../../utils/logger.js");
40
62
  const { getLogFiles } = await import("../../../utils/logger/log-store.js");
41
- const stats = getLogStats();
63
+ const stats = getRuntimeLogStats();
42
64
  const files = getLogFiles().slice(0, 5);
43
65
  const isShuttingDown = isLoggerShuttingDown();
44
66
  return c.json({
@@ -78,15 +100,25 @@ function registerLogsRoutes(authenticated, _deps) {
78
100
  setLogLevel(level);
79
101
  let autoRevertAt = null;
80
102
  if (duration) {
81
- const durationMs = parseInt(duration) * 6e4;
103
+ const durationMs = parseInt(duration, 10) * 6e4;
82
104
  if (!isNaN(durationMs) && durationMs > 0) {
83
105
  autoRevertAt = new Date(Date.now() + durationMs).toISOString();
84
106
  setTimeout(() => {
85
107
  setLogLevel(previousLevel);
86
- console.log(`[Logger] Auto-reverted log level to ${previousLevel}`);
108
+ log.info({
109
+ phase: "gateway.logs.level",
110
+ previousLevel,
111
+ reverted: true
112
+ }, `Log level auto-reverted to ${previousLevel}`);
87
113
  }, durationMs);
88
114
  }
89
115
  }
116
+ log.info({
117
+ phase: "gateway.logs.level",
118
+ previousLevel,
119
+ current: level,
120
+ autoRevertAt
121
+ }, `Log level changed to ${level}`);
90
122
  return c.json({
91
123
  previous: previousLevel,
92
124
  current: level,
@@ -1 +1 @@
1
- {"version":3,"file":"logs.js","names":[],"sources":["../../../../../src/gateway/hono/routes/logs.ts"],"sourcesContent":["import type { Hono } from 'hono';\n\nimport type { LogLevel } from '../../../utils/logger.js';\nimport { queryLogs, getLogFiles, getLogLevels, getLogStats, getLogModules, LOG_DIR } from '../../../utils/logger/log-store.js';\nimport type { AuthenticatedRouteDeps } from './deps.js';\n\nexport function registerLogsRoutes(authenticated: Hono, _deps: AuthenticatedRouteDeps): void {\n\n // ========== Logs REST API (/api/logs) ==========\n\n // GET /api/logs - Query logs with filters\n authenticated.get('/api/logs', async (c) => {\n const query = c.req.query();\n const logs = await queryLogs({\n levels: query.level ? query.level.split(',') as LogLevel[] : undefined,\n from: query.from,\n to: query.to,\n q: query.q,\n module: query.module,\n limit: query.limit ? parseInt(query.limit) : 100,\n offset: query.offset ? parseInt(query.offset) : 0,\n });\n return c.json({ logs, count: logs.length });\n });\n\n // GET /api/logs/files - List log files\n authenticated.get('/api/logs/files', async (c) => {\n const files = getLogFiles();\n return c.json({ files });\n });\n\n // GET /api/logs/stats - Get log statistics\n authenticated.get('/api/logs/stats', async (c) => {\n const stats = getLogStats();\n return c.json(stats);\n });\n\n // GET /api/logs/levels - Get available log levels\n authenticated.get('/api/logs/levels', async (c) => {\n return c.json({ levels: getLogLevels() });\n });\n\n // GET /api/logs/modules - Get available modules\n authenticated.get('/api/logs/modules', async (c) => {\n const modules = await getLogModules();\n return c.json({ modules });\n });\n\n // GET /api/logs/dir - Get log directory path\n authenticated.get('/api/logs/dir', async (c) => {\n return c.json({ dir: LOG_DIR });\n });\n\n // GET /api/logs/health - Get log system health status\n authenticated.get('/api/logs/health', async (c) => {\n const { getLogDir, getLogStats, isLoggerShuttingDown } = await import('../../../utils/logger.js');\n const { getLogFiles } = await import('../../../utils/logger/log-store.js');\n \n const stats = getLogStats();\n const files = getLogFiles().slice(0, 5);\n const isShuttingDown = isLoggerShuttingDown();\n \n return c.json({\n status: isShuttingDown ? 'shutting_down' : 'healthy',\n config: {\n dir: getLogDir(),\n uptimeMs: stats.uptimeMs,\n },\n stats: {\n byLevel: stats.byLevel,\n errorsLast24h: stats.errorsLast24h,\n modulesTracked: stats.byModule ? Object.keys(stats.byModule).length : 0,\n },\n files: files.map(f => ({\n name: f.name,\n size: f.size,\n modified: f.modified,\n type: f.type,\n })),\n shuttingDown: isShuttingDown,\n });\n });\n\n // POST /api/logs/level - Set log level dynamically\n authenticated.post('/api/logs/level', async (c) => {\n const { setLogLevel, getLogLevel } = await import('../../../utils/logger.js');\n const body = await c.req.json().catch(() => ({}));\n const { level, duration } = body as { level?: string; duration?: string };\n \n if (!level) {\n return c.json({ error: 'level is required' }, 400);\n }\n \n const validLevels = ['trace', 'debug', 'info', 'warn', 'error', 'fatal'];\n if (!validLevels.includes(level)) {\n return c.json({ error: `Invalid level. Must be one of: ${validLevels.join(', ')}` }, 400);\n }\n \n const previousLevel = getLogLevel();\n setLogLevel(level as any);\n \n // Optional: auto-revert after duration\n let autoRevertAt: string | null = null;\n if (duration) {\n const durationMs = parseInt(duration) * 60000; // minutes to ms\n if (!isNaN(durationMs) && durationMs > 0) {\n autoRevertAt = new Date(Date.now() + durationMs).toISOString();\n setTimeout(() => {\n setLogLevel(previousLevel);\n console.log(`[Logger] Auto-reverted log level to ${previousLevel}`);\n }, durationMs);\n }\n }\n \n return c.json({\n previous: previousLevel,\n current: level,\n autoRevertAt,\n message: `Log level changed from ${previousLevel} to ${level}`,\n });\n });\n\n // GET /api/logs/level - Get current log level\n authenticated.get('/api/logs/level', async (c) => {\n const { getLogLevel } = await import('../../../utils/logger.js');\n return c.json({ level: getLogLevel() });\n });\n\n // ========== Real-time Log Streaming (SSE) ==========\n\n // GET /api/logs/stream - Stream logs in real-time via SSE\n authenticated.get('/api/logs/stream', async (c) => {\n const { createLogSSEHandler } = await import('../../../utils/logger/log-stream.js');\n return createLogSSEHandler()(c);\n });\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"logs.js","names":[],"sources":["../../../../../src/gateway/hono/routes/logs.ts"],"sourcesContent":["import type { Hono } from 'hono';\n\nimport type { LogLevel } from '../../../utils/logger.js';\nimport {\n queryLogs,\n getLogFiles,\n getLogLevels,\n getFileLogStats,\n getLogModules,\n getLogErrorSummary,\n LOG_DIR,\n} from '../../../utils/logger/log-store.js';\nimport { createGatewayRouteLogger } from '../lib/route-logger.js';\n\nconst log = createGatewayRouteLogger('Logs');\nimport type { AuthenticatedRouteDeps } from './deps.js';\n\nexport function registerLogsRoutes(authenticated: Hono, _deps: AuthenticatedRouteDeps): void {\n\n // ========== Logs REST API (/api/logs) ==========\n\n // GET /api/logs - Query logs with filters\n authenticated.get('/api/logs', async (c) => {\n const query = c.req.query();\n const logs = await queryLogs({\n levels: query.level ? query.level.split(',') as LogLevel[] : undefined,\n from: query.from,\n to: query.to,\n q: query.q,\n module: query.module,\n requestId: query.requestId,\n sessionId: query.sessionId,\n limit: query.limit ? parseInt(query.limit) : 100,\n offset: query.offset ? parseInt(query.offset) : 0,\n });\n return c.json({ logs, count: logs.length });\n });\n\n // GET /api/logs/files - List log files\n authenticated.get('/api/logs/files', async (c) => {\n const files = getLogFiles();\n return c.json({ files });\n });\n\n // GET /api/logs/stats - Get log statistics (file sample + runtime counters)\n authenticated.get('/api/logs/stats', async (c) => {\n const { getRuntimeLogStats } = await import('../../../utils/logger.js');\n const [fileStats, runtimeStats] = await Promise.all([\n getFileLogStats(),\n Promise.resolve(getRuntimeLogStats()),\n ]);\n return c.json({\n byLevel: fileStats.byLevel,\n runtime: {\n byLevel: runtimeStats.byLevel,\n byModule: runtimeStats.byModule,\n errorsLast24h: runtimeStats.errorsLast24h,\n uptimeMs: runtimeStats.uptimeMs,\n },\n });\n });\n\n // GET /api/logs/errors/summary - Aggregate recent errors by type/phase/module\n authenticated.get('/api/logs/errors/summary', async (c) => {\n const query = c.req.query();\n const items = await getLogErrorSummary({\n from: query.from,\n to: query.to,\n limit: query.limit ? parseInt(query.limit, 10) : 20,\n });\n return c.json({ items });\n });\n\n // GET /api/logs/levels - Get available log levels\n authenticated.get('/api/logs/levels', async (c) => {\n return c.json({ levels: getLogLevels() });\n });\n\n // GET /api/logs/modules - Get available modules\n authenticated.get('/api/logs/modules', async (c) => {\n const modules = await getLogModules();\n return c.json({ modules });\n });\n\n // GET /api/logs/dir - Get log directory path\n authenticated.get('/api/logs/dir', async (c) => {\n return c.json({ dir: LOG_DIR });\n });\n\n // GET /api/logs/health - Get log system health status\n authenticated.get('/api/logs/health', async (c) => {\n const { getLogDir, getRuntimeLogStats, isLoggerShuttingDown } = await import('../../../utils/logger.js');\n const { getLogFiles } = await import('../../../utils/logger/log-store.js');\n \n const stats = getRuntimeLogStats();\n const files = getLogFiles().slice(0, 5);\n const isShuttingDown = isLoggerShuttingDown();\n \n return c.json({\n status: isShuttingDown ? 'shutting_down' : 'healthy',\n config: {\n dir: getLogDir(),\n uptimeMs: stats.uptimeMs,\n },\n stats: {\n byLevel: stats.byLevel,\n errorsLast24h: stats.errorsLast24h,\n modulesTracked: stats.byModule ? Object.keys(stats.byModule).length : 0,\n },\n files: files.map(f => ({\n name: f.name,\n size: f.size,\n modified: f.modified,\n type: f.type,\n })),\n shuttingDown: isShuttingDown,\n });\n });\n\n // POST /api/logs/level - Set log level dynamically\n authenticated.post('/api/logs/level', async (c) => {\n const { setLogLevel, getLogLevel } = await import('../../../utils/logger.js');\n const body = await c.req.json().catch(() => ({}));\n const { level, duration } = body as { level?: string; duration?: string };\n \n if (!level) {\n return c.json({ error: 'level is required' }, 400);\n }\n \n const validLevels = ['trace', 'debug', 'info', 'warn', 'error', 'fatal'];\n if (!validLevels.includes(level)) {\n return c.json({ error: `Invalid level. Must be one of: ${validLevels.join(', ')}` }, 400);\n }\n \n const previousLevel = getLogLevel();\n setLogLevel(level as LogLevel);\n \n // Optional: auto-revert after duration\n let autoRevertAt: string | null = null;\n if (duration) {\n const durationMs = parseInt(duration, 10) * 60000; // minutes to ms\n if (!isNaN(durationMs) && durationMs > 0) {\n autoRevertAt = new Date(Date.now() + durationMs).toISOString();\n setTimeout(() => {\n setLogLevel(previousLevel);\n log.info({ phase: 'gateway.logs.level', previousLevel, reverted: true }, `Log level auto-reverted to ${previousLevel}`);\n }, durationMs);\n }\n }\n \n log.info({ phase: 'gateway.logs.level', previousLevel, current: level, autoRevertAt }, `Log level changed to ${level}`);\n \n return c.json({\n previous: previousLevel,\n current: level,\n autoRevertAt,\n message: `Log level changed from ${previousLevel} to ${level}`,\n });\n });\n\n // GET /api/logs/level - Get current log level\n authenticated.get('/api/logs/level', async (c) => {\n const { getLogLevel } = await import('../../../utils/logger.js');\n return c.json({ level: getLogLevel() });\n });\n\n // ========== Real-time Log Streaming (SSE) ==========\n\n // GET /api/logs/stream - Stream logs in real-time via SSE\n authenticated.get('/api/logs/stream', async (c) => {\n const { createLogSSEHandler } = await import('../../../utils/logger/log-stream.js');\n return createLogSSEHandler()(c);\n });\n}\n"],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import type { Hono } from 'hono';
2
+ import type { AuthenticatedRouteDeps } from './deps.js';
3
+ export declare function registerMcpRoutes(authenticated: Hono, deps: AuthenticatedRouteDeps): void;
@@ -0,0 +1,107 @@
1
+ import { isManagedConnectorServer } from "../../../connectors/materialize.js";
2
+ import { canonicalizeConfiguredMcpServer, normalizeConfiguredMcpServers } from "../../../config/mcp-config-normalize.js";
3
+ import { loadMergedBundleMcpConfig } from "../../../agent/mcp/bundle-mcp-config.js";
4
+ import { createBundleMcpToolRuntime, listBundleMcpServerToolsForGateway, mapBundleMcpToolsForGateway } from "../../../agent/mcp/bundle-mcp-materialize.js";
5
+ import { getWorkspacePath } from "../../../config/workspace-path-helpers.js";
6
+ //#region src/gateway/hono/routes/mcp.ts
7
+ function registerMcpRoutes(authenticated, deps) {
8
+ authenticated.get("/api/mcp/servers", (c) => {
9
+ const cfg = deps.service.currentConfig;
10
+ const merged = loadMergedBundleMcpConfig({
11
+ workspaceDir: getWorkspacePath(cfg) || "./workspace",
12
+ cfg
13
+ });
14
+ const configured = normalizeConfiguredMcpServers(cfg.mcp?.servers);
15
+ const servers = Object.entries(configured).map(([id, server]) => ({
16
+ id,
17
+ managed: isManagedConnectorServer(server),
18
+ connectorId: isManagedConnectorServer(server) ? server.xopcConnector.connectorId : void 0
19
+ }));
20
+ return c.json({
21
+ ok: true,
22
+ payload: {
23
+ servers: servers.sort((left, right) => left.id.localeCompare(right.id)),
24
+ mergedServerIds: Object.keys(merged.config.mcpServers).sort(),
25
+ configured
26
+ }
27
+ });
28
+ });
29
+ authenticated.get("/api/mcp/servers/:id/tools", async (c) => {
30
+ const id = c.req.param("id");
31
+ const cfg = deps.service.currentConfig;
32
+ const workspaceDir = getWorkspacePath(cfg) || "./workspace";
33
+ try {
34
+ const tools = await listBundleMcpServerToolsForGateway({
35
+ workspaceDir,
36
+ cfg,
37
+ serverId: id
38
+ });
39
+ return c.json({
40
+ ok: true,
41
+ payload: { tools }
42
+ });
43
+ } catch (err) {
44
+ return c.json({
45
+ ok: false,
46
+ error: err instanceof Error ? err.message : String(err)
47
+ }, 500);
48
+ }
49
+ });
50
+ authenticated.post("/api/mcp/servers/:id/test", async (c) => {
51
+ const id = c.req.param("id");
52
+ const cfg = deps.service.currentConfig;
53
+ const workspaceDir = getWorkspacePath(cfg) || "./workspace";
54
+ const body = await c.req.json().catch(() => ({}));
55
+ const inlineServer = body && typeof body === "object" && !Array.isArray(body) && body.server && typeof body.server === "object" ? body.server : void 0;
56
+ const servers = normalizeConfiguredMcpServers(cfg.mcp?.servers);
57
+ const mergedServers = loadMergedBundleMcpConfig({
58
+ workspaceDir,
59
+ cfg
60
+ }).config.mcpServers;
61
+ if (!(inlineServer ?? servers[id] ?? mergedServers[id])) return c.json({
62
+ ok: false,
63
+ error: `Unknown MCP server: ${id}`
64
+ }, 404);
65
+ try {
66
+ const runtime = await createBundleMcpToolRuntime({
67
+ workspaceDir,
68
+ cfg: inlineServer ? {
69
+ ...cfg,
70
+ mcp: {
71
+ ...cfg.mcp,
72
+ servers: { [id]: canonicalizeConfiguredMcpServer(inlineServer) }
73
+ }
74
+ } : cfg
75
+ });
76
+ const tools = mapBundleMcpToolsForGateway(runtime.tools, id);
77
+ await runtime.dispose();
78
+ return c.json({
79
+ ok: true,
80
+ payload: {
81
+ serverId: id,
82
+ toolCount: tools.length,
83
+ tools
84
+ }
85
+ });
86
+ } catch (err) {
87
+ return c.json({
88
+ ok: false,
89
+ error: err instanceof Error ? err.message : String(err)
90
+ }, 500);
91
+ }
92
+ });
93
+ authenticated.post("/api/mcp/approvals/respond", async (c) => {
94
+ const body = await c.req.json().catch(() => ({}));
95
+ return c.json({
96
+ ok: true,
97
+ payload: {
98
+ acknowledged: true,
99
+ body
100
+ }
101
+ });
102
+ });
103
+ }
104
+ //#endregion
105
+ export { registerMcpRoutes };
106
+
107
+ //# sourceMappingURL=mcp.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mcp.js","names":[],"sources":["../../../../../src/gateway/hono/routes/mcp.ts"],"sourcesContent":["import type { Hono } from 'hono';\n\nimport {\n createBundleMcpToolRuntime,\n listBundleMcpServerToolsForGateway,\n mapBundleMcpToolsForGateway,\n} from '../../../agent/mcp/bundle-mcp-materialize.js';\nimport { loadMergedBundleMcpConfig } from '../../../agent/mcp/bundle-mcp-config.js';\nimport { canonicalizeConfiguredMcpServer, normalizeConfiguredMcpServers } from '../../../config/mcp-config-normalize.js';\nimport { getWorkspacePath } from '../../../config/workspace-path-helpers.js';\nimport { isManagedConnectorServer } from '../../../connectors/materialize.js';\nimport type { AuthenticatedRouteDeps } from './deps.js';\n\nexport function registerMcpRoutes(authenticated: Hono, deps: AuthenticatedRouteDeps): void {\n authenticated.get('/api/mcp/servers', (c) => {\n const cfg = deps.service.currentConfig;\n const workspaceDir = getWorkspacePath(cfg) || './workspace';\n const merged = loadMergedBundleMcpConfig({\n workspaceDir,\n cfg,\n });\n const configured = normalizeConfiguredMcpServers(cfg.mcp?.servers);\n const servers = Object.entries(configured).map(([id, server]) => ({\n id,\n managed: isManagedConnectorServer(server),\n connectorId: isManagedConnectorServer(server) ? server.xopcConnector.connectorId : undefined,\n }));\n return c.json({\n ok: true,\n payload: {\n servers: servers.sort((left, right) => left.id.localeCompare(right.id)),\n mergedServerIds: Object.keys(merged.config.mcpServers).sort(),\n configured,\n },\n });\n });\n\n authenticated.get('/api/mcp/servers/:id/tools', async (c) => {\n const id = c.req.param('id');\n const cfg = deps.service.currentConfig;\n const workspaceDir = getWorkspacePath(cfg) || './workspace';\n try {\n const tools = await listBundleMcpServerToolsForGateway({\n workspaceDir,\n cfg,\n serverId: id,\n });\n return c.json({ ok: true, payload: { tools } });\n } catch (err) {\n return c.json(\n { ok: false, error: err instanceof Error ? err.message : String(err) },\n 500,\n );\n }\n });\n\n authenticated.post('/api/mcp/servers/:id/test', async (c) => {\n const id = c.req.param('id');\n const cfg = deps.service.currentConfig;\n const workspaceDir = getWorkspacePath(cfg) || './workspace';\n const body = await c.req.json().catch(() => ({}));\n const inlineServer =\n body && typeof body === 'object' && !Array.isArray(body) && body.server && typeof body.server === 'object'\n ? (body.server as Record<string, unknown>)\n : undefined;\n const servers = normalizeConfiguredMcpServers(cfg.mcp?.servers);\n const mergedServers = loadMergedBundleMcpConfig({ workspaceDir, cfg }).config.mcpServers;\n const knownServer =\n inlineServer ??\n (servers[id] as Record<string, unknown> | undefined) ??\n (mergedServers[id] as Record<string, unknown> | undefined);\n if (!knownServer) {\n return c.json({ ok: false, error: `Unknown MCP server: ${id}` }, 404);\n }\n try {\n const testCfg: typeof cfg = inlineServer\n ? {\n ...cfg,\n mcp: {\n ...cfg.mcp,\n servers: {\n [id]: canonicalizeConfiguredMcpServer(inlineServer),\n },\n },\n }\n : cfg;\n const runtime = await createBundleMcpToolRuntime({\n workspaceDir,\n cfg: testCfg,\n });\n const tools = mapBundleMcpToolsForGateway(runtime.tools, id);\n await runtime.dispose();\n return c.json({ ok: true, payload: { serverId: id, toolCount: tools.length, tools } });\n } catch (err) {\n return c.json(\n { ok: false, error: err instanceof Error ? err.message : String(err) },\n 500,\n );\n }\n });\n\n authenticated.post('/api/mcp/approvals/respond', async (c) => {\n const body = await c.req.json().catch(() => ({}));\n return c.json({ ok: true, payload: { acknowledged: true, body } });\n });\n}\n"],"mappings":";;;;;;AAaA,SAAgB,kBAAkB,eAAqB,MAAoC;AACzF,eAAc,IAAI,qBAAqB,MAAM;EAC3C,MAAM,MAAM,KAAK,QAAQ;EAEzB,MAAM,SAAS,0BAA0B;GACvC,cAFmB,iBAAiB,IAAI,IAAI;GAG5C;GACD,CAAC;EACF,MAAM,aAAa,8BAA8B,IAAI,KAAK,QAAQ;EAClE,MAAM,UAAU,OAAO,QAAQ,WAAW,CAAC,KAAK,CAAC,IAAI,aAAa;GAChE;GACA,SAAS,yBAAyB,OAAO;GACzC,aAAa,yBAAyB,OAAO,GAAG,OAAO,cAAc,cAAc,KAAA;GACpF,EAAE;AACH,SAAO,EAAE,KAAK;GACZ,IAAI;GACJ,SAAS;IACP,SAAS,QAAQ,MAAM,MAAM,UAAU,KAAK,GAAG,cAAc,MAAM,GAAG,CAAC;IACvE,iBAAiB,OAAO,KAAK,OAAO,OAAO,WAAW,CAAC,MAAM;IAC7D;IACD;GACF,CAAC;GACF;AAEF,eAAc,IAAI,8BAA8B,OAAO,MAAM;EAC3D,MAAM,KAAK,EAAE,IAAI,MAAM,KAAK;EAC5B,MAAM,MAAM,KAAK,QAAQ;EACzB,MAAM,eAAe,iBAAiB,IAAI,IAAI;AAC9C,MAAI;GACF,MAAM,QAAQ,MAAM,mCAAmC;IACrD;IACA;IACA,UAAU;IACX,CAAC;AACF,UAAO,EAAE,KAAK;IAAE,IAAI;IAAM,SAAS,EAAE,OAAO;IAAE,CAAC;WACxC,KAAK;AACZ,UAAO,EAAE,KACP;IAAE,IAAI;IAAO,OAAO,eAAe,QAAQ,IAAI,UAAU,OAAO,IAAI;IAAE,EACtE,IACD;;GAEH;AAEF,eAAc,KAAK,6BAA6B,OAAO,MAAM;EAC3D,MAAM,KAAK,EAAE,IAAI,MAAM,KAAK;EAC5B,MAAM,MAAM,KAAK,QAAQ;EACzB,MAAM,eAAe,iBAAiB,IAAI,IAAI;EAC9C,MAAM,OAAO,MAAM,EAAE,IAAI,MAAM,CAAC,aAAa,EAAE,EAAE;EACjD,MAAM,eACJ,QAAQ,OAAO,SAAS,YAAY,CAAC,MAAM,QAAQ,KAAK,IAAI,KAAK,UAAU,OAAO,KAAK,WAAW,WAC7F,KAAK,SACN,KAAA;EACN,MAAM,UAAU,8BAA8B,IAAI,KAAK,QAAQ;EAC/D,MAAM,gBAAgB,0BAA0B;GAAE;GAAc;GAAK,CAAC,CAAC,OAAO;AAK9E,MAAI,EAHF,gBACC,QAAQ,OACR,cAAc,KAEf,QAAO,EAAE,KAAK;GAAE,IAAI;GAAO,OAAO,uBAAuB;GAAM,EAAE,IAAI;AAEvE,MAAI;GAYF,MAAM,UAAU,MAAM,2BAA2B;IAC/C;IACA,KAb0B,eACxB;KACE,GAAG;KACH,KAAK;MACH,GAAG,IAAI;MACP,SAAS,GACN,KAAK,gCAAgC,aAAa,EACpD;MACF;KACF,GACD;IAIH,CAAC;GACF,MAAM,QAAQ,4BAA4B,QAAQ,OAAO,GAAG;AAC5D,SAAM,QAAQ,SAAS;AACvB,UAAO,EAAE,KAAK;IAAE,IAAI;IAAM,SAAS;KAAE,UAAU;KAAI,WAAW,MAAM;KAAQ;KAAO;IAAE,CAAC;WAC/E,KAAK;AACZ,UAAO,EAAE,KACP;IAAE,IAAI;IAAO,OAAO,eAAe,QAAQ,IAAI,UAAU,OAAO,IAAI;IAAE,EACtE,IACD;;GAEH;AAEF,eAAc,KAAK,8BAA8B,OAAO,MAAM;EAC5D,MAAM,OAAO,MAAM,EAAE,IAAI,MAAM,CAAC,aAAa,EAAE,EAAE;AACjD,SAAO,EAAE,KAAK;GAAE,IAAI;GAAM,SAAS;IAAE,cAAc;IAAM;IAAM;GAAE,CAAC;GAClE"}
@@ -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, getProviderAuthState, init_providers, isProviderConfigured } from "../../../providers/index.js";
8
8
  import { getImageGenerationProvider } from "../../../agent/image/generation/provider-registry.js";
@@ -1,11 +1,13 @@
1
1
  import { buildSessionKey, init_session_key, parseSessionKey } from "../../../routing/session-key.js";
2
2
  import { agentExists, getDefaultAgentId, init_resolve_route } from "../../../routing/resolve-route.js";
3
3
  import { messagesToClientHistory } from "../../../session/client-history.js";
4
+ import { createGatewayRouteLogger, logRouteError } from "../lib/route-logger.js";
4
5
  import { computeUserRoundDeleteRange } from "../../../session/user-round-delete.js";
5
6
  import { respondStartupUnavailable } from "../lib/startup-unavailable.js";
6
7
  //#region src/gateway/hono/routes/sessions.ts
7
8
  init_session_key();
8
9
  init_resolve_route();
10
+ const log = createGatewayRouteLogger("Sessions");
9
11
  function ensureGatewayReadyForSessions(c, service, method) {
10
12
  if (service.isGatewayReady()) return null;
11
13
  return respondStartupUnavailable(c, method);
@@ -213,6 +215,10 @@ function registerSessionsRoutes(authenticated, deps) {
213
215
  try {
214
216
  await service.sessions.restoreCompactionCheckpoint(key, checkpointId);
215
217
  } catch (err) {
218
+ logRouteError(log, c, err, "gateway.route.sessions", {
219
+ operation: "restoreCheckpoint",
220
+ sessionKey: key
221
+ });
216
222
  const msg = err instanceof Error ? err.message : String(err);
217
223
  if (msg.includes("not found") || msg.includes("Invalid")) return c.json({
218
224
  ok: false,