@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 +1 @@
1
- {"version":3,"file":"bundle-mcp-materialize.js","names":[],"sources":["../../../../src/agent/mcp/bundle-mcp-materialize.ts"],"sourcesContent":["import crypto from \"node:crypto\";\nimport type { AgentToolResult } from '@earendil-works/pi-agent-core';\nimport type { AgentTool as AnyAgentTool } from \"@earendil-works/pi-agent-core\";\nimport type { CallToolResult } from \"@modelcontextprotocol/sdk/types.js\";\nimport type { Config } from \"../../config/schema.js\";\nimport { createLogger } from \"../../utils/logger.js\";\nconst log = createLogger(\"BundleMcp\");\nimport { setPluginToolMeta } from \"./mcp-tool-meta.js\";\nimport {\n normalizeLowercaseStringOrEmpty,\n normalizeOptionalString,\n} from \"../../utils/string-coerce.js\";\nimport {\n buildSafeToolName,\n normalizeReservedToolNames,\n TOOL_NAME_SEPARATOR,\n} from \"./bundle-mcp-names.js\";\nimport type { BundleMcpToolRuntime, SessionMcpRuntime } from \"./bundle-mcp-types.js\";\n\nexport type McpGatewayToolEntry = {\n name: string;\n shortName: string;\n description: string;\n};\n\nfunction readMaterializedToolDescription(tool: AnyAgentTool): string {\n const raw = tool as { description?: unknown; label?: unknown };\n return (\n normalizeOptionalString(raw.description) ??\n normalizeOptionalString(raw.label) ??\n tool.name\n );\n}\n\nexport function mapBundleMcpToolsForGateway(\n tools: AnyAgentTool[],\n serverId: string,\n): McpGatewayToolEntry[] {\n const prefix = `${serverId.trim()}${TOOL_NAME_SEPARATOR}`;\n return tools\n .filter((tool) => tool.name.startsWith(prefix))\n .map((tool) => ({\n name: tool.name,\n shortName: tool.name.slice(prefix.length),\n description: readMaterializedToolDescription(tool),\n }));\n}\n\nexport async function listBundleMcpServerToolsForGateway(params: {\n workspaceDir: string;\n cfg?: Config;\n serverId: string;\n}): Promise<McpGatewayToolEntry[]> {\n const runtime = await createBundleMcpToolRuntime({\n workspaceDir: params.workspaceDir,\n cfg: params.cfg,\n });\n try {\n return mapBundleMcpToolsForGateway(runtime.tools, params.serverId);\n } finally {\n await runtime.dispose();\n }\n}\n\nfunction toAgentToolResult(params: {\n serverName: string;\n toolName: string;\n result: CallToolResult;\n}): AgentToolResult<unknown> {\n const content = Array.isArray(params.result.content)\n ? (params.result.content as AgentToolResult<unknown>[\"content\"])\n : [];\n const normalizedContent: AgentToolResult<unknown>[\"content\"] =\n content.length > 0\n ? content\n : params.result.structuredContent !== undefined\n ? [\n {\n type: \"text\",\n text: JSON.stringify(params.result.structuredContent, null, 2),\n },\n ]\n : ([\n {\n type: \"text\",\n text: JSON.stringify(\n {\n status: params.result.isError === true ? \"error\" : \"ok\",\n server: params.serverName,\n tool: params.toolName,\n },\n null,\n 2,\n ),\n },\n ] as AgentToolResult<unknown>[\"content\"]);\n const details: Record<string, unknown> = {\n mcpServer: params.serverName,\n mcpTool: params.toolName,\n };\n if (params.result.structuredContent !== undefined) {\n details.structuredContent = params.result.structuredContent;\n }\n if (params.result.isError === true) {\n details.status = \"error\";\n }\n return {\n content: normalizedContent,\n details,\n };\n}\n\nexport async function materializeBundleMcpToolsForRun(params: {\n runtime: SessionMcpRuntime;\n reservedToolNames?: Iterable<string>;\n disposeRuntime?: () => Promise<void>;\n}): Promise<BundleMcpToolRuntime> {\n let disposed = false;\n const releaseLease = params.runtime.acquireLease?.();\n params.runtime.markUsed();\n let catalog;\n try {\n catalog = await params.runtime.getCatalog();\n } catch (error) {\n releaseLease?.();\n throw error;\n }\n const reservedNames = normalizeReservedToolNames(params.reservedToolNames);\n const tools: BundleMcpToolRuntime[\"tools\"] = [];\n const sortedCatalogTools = [...catalog.tools].toSorted((a, b) => {\n const serverOrder = a.safeServerName.localeCompare(b.safeServerName);\n if (serverOrder !== 0) {\n return serverOrder;\n }\n const toolOrder = a.toolName.localeCompare(b.toolName);\n if (toolOrder !== 0) {\n return toolOrder;\n }\n return a.serverName.localeCompare(b.serverName);\n });\n\n for (const tool of sortedCatalogTools) {\n const originalName = tool.toolName.trim();\n if (!originalName) {\n continue;\n }\n const safeToolName = buildSafeToolName({\n serverName: tool.safeServerName,\n toolName: originalName,\n reservedNames,\n });\n if (safeToolName !== `${tool.safeServerName}${TOOL_NAME_SEPARATOR}${originalName}`) {\n log.warn(\n `bundle-mcp: tool \"${tool.toolName}\" from server \"${tool.serverName}\" registered as \"${safeToolName}\" to keep the tool name provider-safe.`,\n );\n }\n reservedNames.add(normalizeLowercaseStringOrEmpty(safeToolName));\n const agentTool = {\n name: safeToolName,\n label: tool.title ?? tool.toolName,\n description: tool.description || tool.title || tool.fallbackDescription,\n parameters: tool.inputSchema,\n execute: async (_toolCallId: string, input: unknown) => {\n params.runtime.markUsed();\n const result = await params.runtime.callTool(tool.serverName, tool.toolName, input);\n return toAgentToolResult({\n serverName: tool.serverName,\n toolName: tool.toolName,\n result,\n });\n },\n } as unknown as AnyAgentTool;\n setPluginToolMeta(agentTool, {\n pluginId: \"bundle-mcp\",\n optional: false,\n });\n tools.push(agentTool);\n }\n\n // Sort tools deterministically by name so the tools block in API requests is stable across\n // turns (defensive — listTools() order is usually stable but not guaranteed).\n // Cannot fix name collisions: collision suffixes above are order-dependent.\n tools.sort((a, b) => a.name.localeCompare(b.name));\n\n return {\n tools,\n dispose: async () => {\n if (disposed) {\n return;\n }\n disposed = true;\n releaseLease?.();\n await params.disposeRuntime?.();\n },\n };\n}\n\nexport async function createBundleMcpToolRuntime(params: {\n workspaceDir: string;\n cfg?: Config;\n reservedToolNames?: Iterable<string>;\n createRuntime?: (params: {\n sessionId: string;\n workspaceDir: string;\n cfg?: Config;\n }) => SessionMcpRuntime;\n}): Promise<BundleMcpToolRuntime> {\n const createRuntime =\n params.createRuntime ?? (await import(\"./bundle-mcp-runtime.js\")).createSessionMcpRuntime;\n const runtime = createRuntime({\n sessionId: `bundle-mcp:${crypto.randomUUID()}`,\n workspaceDir: params.workspaceDir,\n cfg: params.cfg,\n });\n const materialized = await materializeBundleMcpToolsForRun({\n runtime,\n reservedToolNames: params.reservedToolNames,\n disposeRuntime: async () => {\n await runtime.dispose();\n },\n });\n return materialized;\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"bundle-mcp-materialize.js","names":[],"sources":["../../../../src/agent/mcp/bundle-mcp-materialize.ts"],"sourcesContent":["import crypto from \"node:crypto\";\nimport type { AgentToolResult } from '@earendil-works/pi-agent-core';\nimport type { AgentTool as AnyAgentTool } from \"@earendil-works/pi-agent-core\";\nimport type { CallToolResult } from \"@modelcontextprotocol/sdk/types.js\";\nimport type { Config } from \"../../config/schema.js\";\nimport { createLogger } from \"../../utils/logger.js\";\nconst log = createLogger(\"Mcp:Bundle\");\nimport { setPluginToolMeta } from \"./mcp-tool-meta.js\";\nimport {\n normalizeLowercaseStringOrEmpty,\n normalizeOptionalString,\n} from \"../../utils/string-coerce.js\";\nimport {\n buildSafeToolName,\n normalizeReservedToolNames,\n TOOL_NAME_SEPARATOR,\n} from \"./bundle-mcp-names.js\";\nimport type { BundleMcpToolRuntime, SessionMcpRuntime } from \"./bundle-mcp-types.js\";\n\nexport type McpGatewayToolEntry = {\n name: string;\n shortName: string;\n description: string;\n};\n\nfunction readMaterializedToolDescription(tool: AnyAgentTool): string {\n const raw = tool as { description?: unknown; label?: unknown };\n return (\n normalizeOptionalString(raw.description) ??\n normalizeOptionalString(raw.label) ??\n tool.name\n );\n}\n\nexport function mapBundleMcpToolsForGateway(\n tools: AnyAgentTool[],\n serverId: string,\n): McpGatewayToolEntry[] {\n const prefix = `${serverId.trim()}${TOOL_NAME_SEPARATOR}`;\n return tools\n .filter((tool) => tool.name.startsWith(prefix))\n .map((tool) => ({\n name: tool.name,\n shortName: tool.name.slice(prefix.length),\n description: readMaterializedToolDescription(tool),\n }));\n}\n\nexport async function listBundleMcpServerToolsForGateway(params: {\n workspaceDir: string;\n cfg?: Config;\n serverId: string;\n}): Promise<McpGatewayToolEntry[]> {\n const runtime = await createBundleMcpToolRuntime({\n workspaceDir: params.workspaceDir,\n cfg: params.cfg,\n });\n try {\n return mapBundleMcpToolsForGateway(runtime.tools, params.serverId);\n } finally {\n await runtime.dispose();\n }\n}\n\nfunction toAgentToolResult(params: {\n serverName: string;\n toolName: string;\n result: CallToolResult;\n}): AgentToolResult<unknown> {\n const content = Array.isArray(params.result.content)\n ? (params.result.content as AgentToolResult<unknown>[\"content\"])\n : [];\n const normalizedContent: AgentToolResult<unknown>[\"content\"] =\n content.length > 0\n ? content\n : params.result.structuredContent !== undefined\n ? [\n {\n type: \"text\",\n text: JSON.stringify(params.result.structuredContent, null, 2),\n },\n ]\n : ([\n {\n type: \"text\",\n text: JSON.stringify(\n {\n status: params.result.isError === true ? \"error\" : \"ok\",\n server: params.serverName,\n tool: params.toolName,\n },\n null,\n 2,\n ),\n },\n ] as AgentToolResult<unknown>[\"content\"]);\n const details: Record<string, unknown> = {\n mcpServer: params.serverName,\n mcpTool: params.toolName,\n };\n if (params.result.structuredContent !== undefined) {\n details.structuredContent = params.result.structuredContent;\n }\n if (params.result.isError === true) {\n details.status = \"error\";\n }\n return {\n content: normalizedContent,\n details,\n };\n}\n\nexport async function materializeBundleMcpToolsForRun(params: {\n runtime: SessionMcpRuntime;\n reservedToolNames?: Iterable<string>;\n disposeRuntime?: () => Promise<void>;\n}): Promise<BundleMcpToolRuntime> {\n let disposed = false;\n const releaseLease = params.runtime.acquireLease?.();\n params.runtime.markUsed();\n let catalog;\n try {\n catalog = await params.runtime.getCatalog();\n } catch (error) {\n releaseLease?.();\n throw error;\n }\n const reservedNames = normalizeReservedToolNames(params.reservedToolNames);\n const tools: BundleMcpToolRuntime[\"tools\"] = [];\n const sortedCatalogTools = [...catalog.tools].toSorted((a, b) => {\n const serverOrder = a.safeServerName.localeCompare(b.safeServerName);\n if (serverOrder !== 0) {\n return serverOrder;\n }\n const toolOrder = a.toolName.localeCompare(b.toolName);\n if (toolOrder !== 0) {\n return toolOrder;\n }\n return a.serverName.localeCompare(b.serverName);\n });\n\n for (const tool of sortedCatalogTools) {\n const originalName = tool.toolName.trim();\n if (!originalName) {\n continue;\n }\n const safeToolName = buildSafeToolName({\n serverName: tool.safeServerName,\n toolName: originalName,\n reservedNames,\n });\n if (safeToolName !== `${tool.safeServerName}${TOOL_NAME_SEPARATOR}${originalName}`) {\n log.warn(\n `bundle-mcp: tool \"${tool.toolName}\" from server \"${tool.serverName}\" registered as \"${safeToolName}\" to keep the tool name provider-safe.`,\n );\n }\n reservedNames.add(normalizeLowercaseStringOrEmpty(safeToolName));\n const agentTool = {\n name: safeToolName,\n label: tool.title ?? tool.toolName,\n description: tool.description || tool.title || tool.fallbackDescription,\n parameters: tool.inputSchema,\n execute: async (_toolCallId: string, input: unknown) => {\n params.runtime.markUsed();\n const result = await params.runtime.callTool(tool.serverName, tool.toolName, input);\n return toAgentToolResult({\n serverName: tool.serverName,\n toolName: tool.toolName,\n result,\n });\n },\n } as unknown as AnyAgentTool;\n setPluginToolMeta(agentTool, {\n pluginId: \"bundle-mcp\",\n optional: false,\n });\n tools.push(agentTool);\n }\n\n // Sort tools deterministically by name so the tools block in API requests is stable across\n // turns (defensive — listTools() order is usually stable but not guaranteed).\n // Cannot fix name collisions: collision suffixes above are order-dependent.\n tools.sort((a, b) => a.name.localeCompare(b.name));\n\n return {\n tools,\n dispose: async () => {\n if (disposed) {\n return;\n }\n disposed = true;\n releaseLease?.();\n await params.disposeRuntime?.();\n },\n };\n}\n\nexport async function createBundleMcpToolRuntime(params: {\n workspaceDir: string;\n cfg?: Config;\n reservedToolNames?: Iterable<string>;\n createRuntime?: (params: {\n sessionId: string;\n workspaceDir: string;\n cfg?: Config;\n }) => SessionMcpRuntime;\n}): Promise<BundleMcpToolRuntime> {\n const createRuntime =\n params.createRuntime ?? (await import(\"./bundle-mcp-runtime.js\")).createSessionMcpRuntime;\n const runtime = createRuntime({\n sessionId: `bundle-mcp:${crypto.randomUUID()}`,\n workspaceDir: params.workspaceDir,\n cfg: params.cfg,\n });\n const materialized = await materializeBundleMcpToolsForRun({\n runtime,\n reservedToolNames: params.reservedToolNames,\n disposeRuntime: async () => {\n await runtime.dispose();\n },\n });\n return materialized;\n}\n"],"mappings":"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"}
@@ -1,6 +1,6 @@
1
+ import { init_string_coerce, normalizeOptionalString } from "../../utils/string-coerce.js";
1
2
  import { createLogger } from "../../utils/logger/index.js";
2
3
  import { init_logger } from "../../utils/logger.js";
3
- import { init_string_coerce, normalizeOptionalString } from "../../utils/string-coerce.js";
4
4
  import { sanitizeServerName } from "./bundle-mcp-names.js";
5
5
  import { resolveConnectorSecretReferences } from "../../connectors/secret-store.js";
6
6
  import { resolveGlobalSingleton } from "../../utils/global-singleton.js";
@@ -15,7 +15,7 @@ import { AjvJsonSchemaValidator } from "@modelcontextprotocol/sdk/validation/ajv
15
15
  //#region src/agent/mcp/bundle-mcp-runtime.ts
16
16
  init_logger();
17
17
  init_string_coerce();
18
- const log = createLogger("BundleMcp");
18
+ const log = createLogger("Mcp:Bundle");
19
19
  const SESSION_MCP_RUNTIME_MANAGER_KEY = Symbol.for("xopc.sessionMcpRuntimeManager");
20
20
  const DRAFT_2020_12_SCHEMA = "https://json-schema.org/draft/2020-12/schema";
21
21
  const DEFAULT_SESSION_MCP_RUNTIME_IDLE_TTL_MS = 600 * 1e3;
@@ -87,7 +87,11 @@ function loadSessionMcpConfig(params) {
87
87
  workspaceDir: params.workspaceDir,
88
88
  cfg: params.cfg
89
89
  });
90
- if (params.logDiagnostics !== false) for (const diagnostic of loaded.diagnostics) log.warn(`bundle-mcp: ${diagnostic.extensionId}: ${diagnostic.message}`);
90
+ if (params.logDiagnostics !== false) for (const diagnostic of loaded.diagnostics) log.warn({
91
+ phase: "agent.mcp_connect",
92
+ extensionId: diagnostic.extensionId,
93
+ message: diagnostic.message
94
+ }, `bundle-mcp diagnostic: ${diagnostic.extensionId}: ${diagnostic.message}`);
91
95
  return {
92
96
  loaded,
93
97
  fingerprint: createCatalogFingerprint(loaded.mcpServers)
@@ -137,7 +141,11 @@ function createSessionMcpRuntime(params) {
137
141
  const resolved = resolveMcpTransport(serverName, await resolveConnectorSecretReferences(rawServer));
138
142
  if (!resolved) continue;
139
143
  const safeServerName = sanitizeServerName(serverName, usedServerNames);
140
- if (safeServerName !== serverName) log.warn(`bundle-mcp: server key "${serverName}" registered as "${safeServerName}" for provider-safe tool names.`);
144
+ if (safeServerName !== serverName) log.warn({
145
+ phase: "agent.mcp_connect",
146
+ serverName,
147
+ safeServerName
148
+ }, `bundle-mcp: server key "${serverName}" registered as "${safeServerName}" for provider-safe tool names`);
141
149
  const client = new Client({
142
150
  name: "xopc-bundle-mcp",
143
151
  version: "0.0.0"
@@ -281,7 +289,12 @@ function createSessionMcpRuntimeManager(opts = {}) {
281
289
  const queueIdleSweep = () => {
282
290
  if (idleSweepInFlight) return;
283
291
  idleSweepInFlight = sweepIdleRuntimes().then(() => void 0).catch((error) => {
284
- log.warn(`bundle-mcp: idle runtime sweep failed: ${String(error)}`);
292
+ const em = error instanceof Error ? error.message : String(error);
293
+ log.warn({
294
+ err: error,
295
+ errorMessage: em,
296
+ phase: "agent.mcp_connect"
297
+ }, `bundle-mcp: idle runtime sweep failed: ${em}`);
285
298
  }).finally(() => {
286
299
  idleSweepInFlight = void 0;
287
300
  });
@@ -1 +1 @@
1
- {"version":3,"file":"bundle-mcp-runtime.js","names":[],"sources":["../../../../src/agent/mcp/bundle-mcp-runtime.ts"],"sourcesContent":["import crypto from \"node:crypto\";\nimport Ajv2020 from \"ajv/dist/2020.js\";\nimport { Client } from \"@modelcontextprotocol/sdk/client/index.js\";\nimport { StreamableHTTPClientTransport } from \"@modelcontextprotocol/sdk/client/streamableHttp.js\";\nimport type { Transport } from \"@modelcontextprotocol/sdk/shared/transport.js\";\nimport type { CallToolResult } from \"@modelcontextprotocol/sdk/types.js\";\nimport { AjvJsonSchemaValidator } from \"@modelcontextprotocol/sdk/validation/ajv-provider.js\";\nimport type {\n JsonSchemaType,\n JsonSchemaValidator,\n jsonSchemaValidator,\n} from \"@modelcontextprotocol/sdk/validation/types.js\";\nimport type { Config } from \"../../config/schema.js\";\nimport { createLogger } from \"../../utils/logger.js\";\nconst log = createLogger(\"BundleMcp\");\nimport { resolveGlobalSingleton } from \"../../utils/global-singleton.js\";\nimport { redactSensitiveUrlLikeString } from \"../../utils/redact-sensitive-url.js\";\nimport { normalizeOptionalString } from \"../../utils/string-coerce.js\";\nimport { loadEmbeddedMcpConfig } from \"./embedded-mcp.js\";\nimport { resolveConnectorSecretReferences } from \"../../connectors/secret-store.js\";\nimport { isMcpConfigRecord } from \"./mcp-config-shared.js\";\nimport { resolveMcpTransport } from \"./mcp-transport.js\";\nimport { sanitizeServerName } from \"./bundle-mcp-names.js\";\nimport type {\n McpCatalogTool,\n McpServerCatalog,\n McpToolCatalog,\n SessionMcpRuntime,\n SessionMcpRuntimeManager,\n} from \"./bundle-mcp-types.js\";\n\ntype BundleMcpSession = {\n serverName: string;\n client: Client;\n transport: Transport;\n transportType: \"stdio\" | \"sse\" | \"streamable-http\";\n detachStderr?: () => void;\n};\n\ntype LoadedMcpConfig = ReturnType<typeof loadEmbeddedMcpConfig>;\ntype ListedTool = Awaited<ReturnType<Client[\"listTools\"]>>[\"tools\"][number];\ntype CreateSessionMcpRuntime = (\n params: Parameters<typeof createSessionMcpRuntime>[0] & { configFingerprint?: string },\n) => SessionMcpRuntime;\n\nconst SESSION_MCP_RUNTIME_MANAGER_KEY = Symbol.for(\"xopc.sessionMcpRuntimeManager\");\nconst DRAFT_2020_12_SCHEMA = \"https://json-schema.org/draft/2020-12/schema\";\nconst DEFAULT_SESSION_MCP_RUNTIME_IDLE_TTL_MS = 10 * 60 * 1000;\nconst SESSION_MCP_RUNTIME_SWEEP_INTERVAL_MS = 60 * 1000;\n\nfunction isDraft202012Schema(schema: JsonSchemaType): boolean {\n return (schema as { $schema?: unknown }).$schema === DRAFT_2020_12_SCHEMA;\n}\n\nexport function createBundleMcpJsonSchemaValidator(): jsonSchemaValidator {\n const defaultValidator = new AjvJsonSchemaValidator();\n const ajv2020 = new Ajv2020({\n strict: false,\n validateFormats: false,\n validateSchema: false,\n allErrors: true,\n });\n\n return {\n getValidator<T>(schema: JsonSchemaType): JsonSchemaValidator<T> {\n if (!isDraft202012Schema(schema)) {\n return defaultValidator.getValidator<T>(schema);\n }\n const ajvValidator = ajv2020.compile(schema);\n return (input: unknown) => {\n const valid = ajvValidator(input);\n if (valid) {\n return {\n valid: true,\n data: input as T,\n errorMessage: undefined,\n };\n }\n return {\n valid: false,\n data: undefined,\n errorMessage: ajv2020.errorsText(ajvValidator.errors),\n };\n };\n },\n };\n}\n\nfunction connectWithTimeout(\n client: Client,\n transport: Transport,\n timeoutMs: number,\n): Promise<void> {\n return new Promise<void>((resolve, reject) => {\n const timer = setTimeout(\n () => reject(new Error(`MCP server connection timed out after ${timeoutMs}ms`)),\n timeoutMs,\n );\n client.connect(transport).then(\n (value) => {\n clearTimeout(timer);\n resolve(value);\n },\n (error) => {\n clearTimeout(timer);\n reject(error);\n },\n );\n });\n}\n\nfunction redactErrorUrls(error: unknown): string {\n return redactSensitiveUrlLikeString(String(error));\n}\n\nasync function listAllTools(client: Client) {\n const tools: ListedTool[] = [];\n let cursor: string | undefined;\n do {\n const page = await client.listTools(cursor ? { cursor } : undefined);\n tools.push(...page.tools);\n cursor = page.nextCursor;\n } while (cursor);\n return tools;\n}\n\nasync function disposeSession(session: BundleMcpSession) {\n session.detachStderr?.();\n if (session.transportType === \"streamable-http\") {\n await (session.transport as StreamableHTTPClientTransport).terminateSession().catch(() => {});\n }\n await session.transport.close().catch(() => {});\n await session.client.close().catch(() => {});\n}\n\nfunction createCatalogFingerprint(servers: Record<string, unknown>): string {\n return crypto.createHash(\"sha1\").update(JSON.stringify(servers)).digest(\"hex\");\n}\n\nfunction loadSessionMcpConfig(params: {\n workspaceDir: string;\n cfg?: Config;\n logDiagnostics?: boolean;\n}): {\n loaded: LoadedMcpConfig;\n fingerprint: string;\n} {\n const loaded = loadEmbeddedMcpConfig({\n workspaceDir: params.workspaceDir,\n cfg: params.cfg,\n });\n if (params.logDiagnostics !== false) {\n for (const diagnostic of loaded.diagnostics) {\n log.warn(`bundle-mcp: ${diagnostic.extensionId}: ${diagnostic.message}`);\n }\n }\n return {\n loaded,\n fingerprint: createCatalogFingerprint(loaded.mcpServers),\n };\n}\n\nfunction createDisposedError(sessionId: string): Error {\n return new Error(`bundle-mcp runtime disposed for session ${sessionId}`);\n}\n\nfunction resolveSessionMcpRuntimeIdleTtlMs(cfg?: Config): number {\n const raw = cfg?.mcp?.sessionIdleTtlMs;\n if (typeof raw === \"number\" && Number.isFinite(raw) && raw >= 0) {\n return Math.floor(raw);\n }\n return DEFAULT_SESSION_MCP_RUNTIME_IDLE_TTL_MS;\n}\n\nexport function createSessionMcpRuntime(params: {\n sessionId: string;\n sessionKey?: string;\n workspaceDir: string;\n cfg?: Config;\n}): SessionMcpRuntime {\n const { loaded, fingerprint: configFingerprint } = loadSessionMcpConfig({\n workspaceDir: params.workspaceDir,\n cfg: params.cfg,\n logDiagnostics: true,\n });\n const createdAt = Date.now();\n let lastUsedAt = createdAt;\n let activeLeases = 0;\n let disposed = false;\n let catalog: McpToolCatalog | null = null;\n let catalogInFlight: Promise<McpToolCatalog> | undefined;\n const sessions = new Map<string, BundleMcpSession>();\n const failIfDisposed = () => {\n if (disposed) {\n throw createDisposedError(params.sessionId);\n }\n };\n\n const getCatalog = async (): Promise<McpToolCatalog> => {\n failIfDisposed();\n if (catalog) {\n return catalog;\n }\n if (catalogInFlight) {\n return catalogInFlight;\n }\n catalogInFlight = (async () => {\n if (Object.keys(loaded.mcpServers).length === 0) {\n return {\n version: 1,\n generatedAt: Date.now(),\n servers: {},\n tools: [],\n };\n }\n\n const servers: Record<string, McpServerCatalog> = {};\n const tools: McpCatalogTool[] = [];\n const usedServerNames = new Set<string>();\n\n try {\n for (const [serverName, rawServer] of Object.entries(loaded.mcpServers)) {\n failIfDisposed();\n const resolvedServer = await resolveConnectorSecretReferences(rawServer);\n const resolved = resolveMcpTransport(serverName, resolvedServer);\n if (!resolved) {\n continue;\n }\n const safeServerName = sanitizeServerName(serverName, usedServerNames);\n if (safeServerName !== serverName) {\n log.warn(\n `bundle-mcp: server key \"${serverName}\" registered as \"${safeServerName}\" for provider-safe tool names.`,\n );\n }\n\n const client = new Client(\n {\n name: \"xopc-bundle-mcp\",\n version: \"0.0.0\",\n },\n {\n jsonSchemaValidator: createBundleMcpJsonSchemaValidator(),\n },\n );\n const session: BundleMcpSession = {\n serverName,\n client,\n transport: resolved.transport,\n transportType: resolved.transportType,\n detachStderr: resolved.detachStderr,\n };\n sessions.set(serverName, session);\n\n try {\n failIfDisposed();\n await connectWithTimeout(client, resolved.transport, resolved.connectionTimeoutMs);\n failIfDisposed();\n const listedTools = await listAllTools(client);\n failIfDisposed();\n servers[serverName] = {\n serverName,\n launchSummary: resolved.description,\n toolCount: listedTools.length,\n };\n for (const tool of listedTools) {\n const toolName = tool.name.trim();\n if (!toolName) {\n continue;\n }\n tools.push({\n serverName,\n safeServerName,\n toolName,\n title: tool.title,\n description:\n normalizeOptionalString(tool.description) ?? normalizeOptionalString(tool.title),\n inputSchema: tool.inputSchema,\n fallbackDescription: `Provided by bundle MCP server \"${serverName}\" (${resolved.description}).`,\n });\n }\n } catch (error) {\n if (!disposed) {\n log.warn(\n `bundle-mcp: failed to start server \"${serverName}\" (${resolved.description}): ${redactErrorUrls(error)}`,\n );\n }\n await disposeSession(session);\n sessions.delete(serverName);\n failIfDisposed();\n }\n }\n\n failIfDisposed();\n return {\n version: 1,\n generatedAt: Date.now(),\n servers,\n tools,\n };\n } catch (error) {\n await Promise.allSettled(\n Array.from(sessions.values(), (session) => disposeSession(session)),\n );\n sessions.clear();\n throw error;\n }\n })();\n\n try {\n const nextCatalog = await catalogInFlight;\n failIfDisposed();\n catalog = nextCatalog;\n return nextCatalog;\n } finally {\n catalogInFlight = undefined;\n }\n };\n\n return {\n sessionId: params.sessionId,\n sessionKey: params.sessionKey,\n workspaceDir: params.workspaceDir,\n configFingerprint,\n createdAt,\n get lastUsedAt() {\n return lastUsedAt;\n },\n get activeLeases() {\n return activeLeases;\n },\n acquireLease() {\n activeLeases += 1;\n let released = false;\n return () => {\n if (released) {\n return;\n }\n released = true;\n activeLeases = Math.max(0, activeLeases - 1);\n lastUsedAt = Date.now();\n };\n },\n getCatalog,\n markUsed() {\n lastUsedAt = Date.now();\n },\n async callTool(serverName, toolName, input) {\n failIfDisposed();\n await getCatalog();\n const session = sessions.get(serverName);\n if (!session) {\n throw new Error(`bundle-mcp server \"${serverName}\" is not connected`);\n }\n return (await session.client.callTool({\n name: toolName,\n arguments: isMcpConfigRecord(input) ? input : {},\n })) as CallToolResult;\n },\n async dispose() {\n if (disposed) {\n return;\n }\n disposed = true;\n catalog = null;\n catalogInFlight = undefined;\n const sessionsToClose = Array.from(sessions.values());\n sessions.clear();\n await Promise.allSettled(sessionsToClose.map((session) => disposeSession(session)));\n },\n };\n}\n\nfunction createSessionMcpRuntimeManager(\n opts: {\n createRuntime?: CreateSessionMcpRuntime;\n now?: () => number;\n enableIdleSweepTimer?: boolean;\n idleSweepIntervalMs?: number;\n } = {},\n): SessionMcpRuntimeManager {\n const runtimesBySessionId = new Map<string, SessionMcpRuntime>();\n const sessionIdBySessionKey = new Map<string, string>();\n const idleTtlMsBySessionId = new Map<string, number>();\n const createRuntime = opts.createRuntime ?? createSessionMcpRuntime;\n const now = opts.now ?? Date.now;\n const createInFlight = new Map<\n string,\n {\n promise: Promise<SessionMcpRuntime>;\n workspaceDir: string;\n configFingerprint: string;\n }\n >();\n const idleSweepIntervalMs = opts.idleSweepIntervalMs ?? SESSION_MCP_RUNTIME_SWEEP_INTERVAL_MS;\n let idleSweepTimer: ReturnType<typeof setInterval> | undefined;\n let idleSweepInFlight: Promise<void> | undefined;\n\n const forgetSessionKeysForSessionId = (sessionId: string) => {\n for (const [sessionKey, mappedSessionId] of sessionIdBySessionKey.entries()) {\n if (mappedSessionId === sessionId) {\n sessionIdBySessionKey.delete(sessionKey);\n }\n }\n };\n\n const sweepIdleRuntimes = async (): Promise<number> => {\n const nowMs = now();\n const expired: SessionMcpRuntime[] = [];\n for (const [sessionId, runtime] of runtimesBySessionId.entries()) {\n const idleTtlMs =\n idleTtlMsBySessionId.get(sessionId) ?? DEFAULT_SESSION_MCP_RUNTIME_IDLE_TTL_MS;\n if (idleTtlMs <= 0 || (runtime.activeLeases ?? 0) > 0) {\n continue;\n }\n if (nowMs - runtime.lastUsedAt < idleTtlMs) {\n continue;\n }\n runtimesBySessionId.delete(sessionId);\n idleTtlMsBySessionId.delete(sessionId);\n forgetSessionKeysForSessionId(sessionId);\n expired.push(runtime);\n }\n await Promise.allSettled(expired.map((runtime) => runtime.dispose()));\n return expired.length;\n };\n\n const queueIdleSweep = () => {\n if (idleSweepInFlight) {\n return;\n }\n idleSweepInFlight = sweepIdleRuntimes()\n .then(() => undefined)\n .catch((error: unknown) => {\n log.warn(`bundle-mcp: idle runtime sweep failed: ${String(error)}`);\n })\n .finally(() => {\n idleSweepInFlight = undefined;\n });\n };\n\n const ensureIdleSweepTimer = () => {\n if (opts.enableIdleSweepTimer === false || idleSweepIntervalMs <= 0 || idleSweepTimer) {\n return;\n }\n idleSweepTimer = setInterval(queueIdleSweep, idleSweepIntervalMs);\n idleSweepTimer.unref?.();\n };\n\n const clearIdleSweepTimer = () => {\n if (!idleSweepTimer) {\n return;\n }\n clearInterval(idleSweepTimer);\n idleSweepTimer = undefined;\n };\n\n return {\n async getOrCreate(params) {\n const idleTtlMs = resolveSessionMcpRuntimeIdleTtlMs(params.cfg);\n if (runtimesBySessionId.has(params.sessionId)) {\n idleTtlMsBySessionId.set(params.sessionId, idleTtlMs);\n }\n await sweepIdleRuntimes();\n if (idleTtlMs > 0) {\n ensureIdleSweepTimer();\n }\n if (params.sessionKey) {\n sessionIdBySessionKey.set(params.sessionKey, params.sessionId);\n }\n const { fingerprint: nextFingerprint } = loadSessionMcpConfig({\n workspaceDir: params.workspaceDir,\n cfg: params.cfg,\n logDiagnostics: false,\n });\n const existing = runtimesBySessionId.get(params.sessionId);\n if (existing) {\n if (\n existing.workspaceDir !== params.workspaceDir ||\n existing.configFingerprint !== nextFingerprint\n ) {\n runtimesBySessionId.delete(params.sessionId);\n await existing.dispose();\n } else {\n existing.markUsed();\n idleTtlMsBySessionId.set(params.sessionId, idleTtlMs);\n return existing;\n }\n }\n const inFlight = createInFlight.get(params.sessionId);\n if (inFlight) {\n if (\n inFlight.workspaceDir === params.workspaceDir &&\n inFlight.configFingerprint === nextFingerprint\n ) {\n return inFlight.promise;\n }\n createInFlight.delete(params.sessionId);\n const staleRuntime = await inFlight.promise.catch(() => undefined);\n runtimesBySessionId.delete(params.sessionId);\n idleTtlMsBySessionId.delete(params.sessionId);\n await staleRuntime?.dispose();\n }\n const created = Promise.resolve(\n createRuntime({\n sessionId: params.sessionId,\n sessionKey: params.sessionKey,\n workspaceDir: params.workspaceDir,\n cfg: params.cfg,\n }),\n ).then((runtime) => {\n runtime.markUsed();\n runtimesBySessionId.set(params.sessionId, runtime);\n idleTtlMsBySessionId.set(params.sessionId, idleTtlMs);\n return runtime;\n });\n createInFlight.set(params.sessionId, {\n promise: created,\n workspaceDir: params.workspaceDir,\n configFingerprint: nextFingerprint,\n });\n try {\n return await created;\n } finally {\n createInFlight.delete(params.sessionId);\n }\n },\n bindSessionKey(sessionKey, sessionId) {\n sessionIdBySessionKey.set(sessionKey, sessionId);\n },\n resolveSessionId(sessionKey) {\n return sessionIdBySessionKey.get(sessionKey);\n },\n async disposeSession(sessionId) {\n const inFlight = createInFlight.get(sessionId);\n createInFlight.delete(sessionId);\n let runtime = runtimesBySessionId.get(sessionId);\n if (!runtime && inFlight) {\n runtime = await inFlight.promise.catch(() => undefined);\n }\n runtimesBySessionId.delete(sessionId);\n idleTtlMsBySessionId.delete(sessionId);\n if (!runtime) {\n forgetSessionKeysForSessionId(sessionId);\n return;\n }\n forgetSessionKeysForSessionId(sessionId);\n await runtime.dispose();\n },\n async disposeAll() {\n clearIdleSweepTimer();\n const inFlightRuntimes = Array.from(createInFlight.values());\n createInFlight.clear();\n const runtimes = Array.from(runtimesBySessionId.values());\n runtimesBySessionId.clear();\n sessionIdBySessionKey.clear();\n idleTtlMsBySessionId.clear();\n const lateRuntimes = await Promise.all(\n inFlightRuntimes.map(async ({ promise }) => await promise.catch(() => undefined)),\n );\n const allRuntimes = new Set<SessionMcpRuntime>(runtimes);\n for (const runtime of lateRuntimes) {\n if (runtime) {\n allRuntimes.add(runtime);\n }\n }\n await Promise.allSettled(Array.from(allRuntimes, (runtime) => runtime.dispose()));\n },\n sweepIdleRuntimes,\n listSessionIds() {\n return Array.from(runtimesBySessionId.keys());\n },\n };\n}\n\nexport function getSessionMcpRuntimeManager(): SessionMcpRuntimeManager {\n return resolveGlobalSingleton(SESSION_MCP_RUNTIME_MANAGER_KEY, createSessionMcpRuntimeManager);\n}\n\nexport async function getOrCreateSessionMcpRuntime(params: {\n sessionId: string;\n sessionKey?: string;\n workspaceDir: string;\n cfg?: Config;\n}): Promise<SessionMcpRuntime> {\n return await getSessionMcpRuntimeManager().getOrCreate(params);\n}\n\nexport async function disposeSessionMcpRuntime(sessionId: string): Promise<void> {\n await getSessionMcpRuntimeManager().disposeSession(sessionId);\n}\n\nexport async function retireSessionMcpRuntime(params: {\n sessionId?: string | null;\n reason: string;\n onError?: (error: unknown, sessionId: string, reason: string) => void;\n}): Promise<boolean> {\n const sessionId = normalizeOptionalString(params.sessionId);\n if (!sessionId) {\n return false;\n }\n try {\n await disposeSessionMcpRuntime(sessionId);\n return true;\n } catch (error) {\n params.onError?.(error, sessionId, params.reason);\n return false;\n }\n}\n\nexport async function retireSessionMcpRuntimeForSessionKey(params: {\n sessionKey?: string | null;\n reason: string;\n onError?: (error: unknown, sessionId: string, reason: string) => void;\n}): Promise<boolean> {\n const sessionKey = normalizeOptionalString(params.sessionKey);\n if (!sessionKey) {\n return false;\n }\n const sessionId = getSessionMcpRuntimeManager().resolveSessionId(sessionKey);\n return await retireSessionMcpRuntime({\n sessionId,\n reason: params.reason,\n onError: params.onError,\n });\n}\n\nexport async function disposeAllSessionMcpRuntimes(): Promise<void> {\n await getSessionMcpRuntimeManager().disposeAll();\n}\n\nexport const __testing = {\n createSessionMcpRuntimeManager,\n async resetSessionMcpRuntimeManager() {\n await disposeAllSessionMcpRuntimes();\n },\n getCachedSessionIds() {\n return getSessionMcpRuntimeManager().listSessionIds();\n },\n resolveSessionMcpRuntimeIdleTtlMs,\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"bundle-mcp-runtime.js","names":[],"sources":["../../../../src/agent/mcp/bundle-mcp-runtime.ts"],"sourcesContent":["import crypto from \"node:crypto\";\nimport Ajv2020 from \"ajv/dist/2020.js\";\nimport { Client } from \"@modelcontextprotocol/sdk/client/index.js\";\nimport { StreamableHTTPClientTransport } from \"@modelcontextprotocol/sdk/client/streamableHttp.js\";\nimport type { Transport } from \"@modelcontextprotocol/sdk/shared/transport.js\";\nimport type { CallToolResult } from \"@modelcontextprotocol/sdk/types.js\";\nimport { AjvJsonSchemaValidator } from \"@modelcontextprotocol/sdk/validation/ajv-provider.js\";\nimport type {\n JsonSchemaType,\n JsonSchemaValidator,\n jsonSchemaValidator,\n} from \"@modelcontextprotocol/sdk/validation/types.js\";\nimport type { Config } from \"../../config/schema.js\";\nimport { createLogger } from \"../../utils/logger.js\";\nconst log = createLogger(\"Mcp:Bundle\");\nimport { resolveGlobalSingleton } from \"../../utils/global-singleton.js\";\nimport { redactSensitiveUrlLikeString } from \"../../utils/redact-sensitive-url.js\";\nimport { normalizeOptionalString } from \"../../utils/string-coerce.js\";\nimport { loadEmbeddedMcpConfig } from \"./embedded-mcp.js\";\nimport { resolveConnectorSecretReferences } from \"../../connectors/secret-store.js\";\nimport { isMcpConfigRecord } from \"./mcp-config-shared.js\";\nimport { resolveMcpTransport } from \"./mcp-transport.js\";\nimport { sanitizeServerName } from \"./bundle-mcp-names.js\";\nimport type {\n McpCatalogTool,\n McpServerCatalog,\n McpToolCatalog,\n SessionMcpRuntime,\n SessionMcpRuntimeManager,\n} from \"./bundle-mcp-types.js\";\n\ntype BundleMcpSession = {\n serverName: string;\n client: Client;\n transport: Transport;\n transportType: \"stdio\" | \"sse\" | \"streamable-http\";\n detachStderr?: () => void;\n};\n\ntype LoadedMcpConfig = ReturnType<typeof loadEmbeddedMcpConfig>;\ntype ListedTool = Awaited<ReturnType<Client[\"listTools\"]>>[\"tools\"][number];\ntype CreateSessionMcpRuntime = (\n params: Parameters<typeof createSessionMcpRuntime>[0] & { configFingerprint?: string },\n) => SessionMcpRuntime;\n\nconst SESSION_MCP_RUNTIME_MANAGER_KEY = Symbol.for(\"xopc.sessionMcpRuntimeManager\");\nconst DRAFT_2020_12_SCHEMA = \"https://json-schema.org/draft/2020-12/schema\";\nconst DEFAULT_SESSION_MCP_RUNTIME_IDLE_TTL_MS = 10 * 60 * 1000;\nconst SESSION_MCP_RUNTIME_SWEEP_INTERVAL_MS = 60 * 1000;\n\nfunction isDraft202012Schema(schema: JsonSchemaType): boolean {\n return (schema as { $schema?: unknown }).$schema === DRAFT_2020_12_SCHEMA;\n}\n\nexport function createBundleMcpJsonSchemaValidator(): jsonSchemaValidator {\n const defaultValidator = new AjvJsonSchemaValidator();\n const ajv2020 = new Ajv2020({\n strict: false,\n validateFormats: false,\n validateSchema: false,\n allErrors: true,\n });\n\n return {\n getValidator<T>(schema: JsonSchemaType): JsonSchemaValidator<T> {\n if (!isDraft202012Schema(schema)) {\n return defaultValidator.getValidator<T>(schema);\n }\n const ajvValidator = ajv2020.compile(schema);\n return (input: unknown) => {\n const valid = ajvValidator(input);\n if (valid) {\n return {\n valid: true,\n data: input as T,\n errorMessage: undefined,\n };\n }\n return {\n valid: false,\n data: undefined,\n errorMessage: ajv2020.errorsText(ajvValidator.errors),\n };\n };\n },\n };\n}\n\nfunction connectWithTimeout(\n client: Client,\n transport: Transport,\n timeoutMs: number,\n): Promise<void> {\n return new Promise<void>((resolve, reject) => {\n const timer = setTimeout(\n () => reject(new Error(`MCP server connection timed out after ${timeoutMs}ms`)),\n timeoutMs,\n );\n client.connect(transport).then(\n (value) => {\n clearTimeout(timer);\n resolve(value);\n },\n (error) => {\n clearTimeout(timer);\n reject(error);\n },\n );\n });\n}\n\nfunction redactErrorUrls(error: unknown): string {\n return redactSensitiveUrlLikeString(String(error));\n}\n\nasync function listAllTools(client: Client) {\n const tools: ListedTool[] = [];\n let cursor: string | undefined;\n do {\n const page = await client.listTools(cursor ? { cursor } : undefined);\n tools.push(...page.tools);\n cursor = page.nextCursor;\n } while (cursor);\n return tools;\n}\n\nasync function disposeSession(session: BundleMcpSession) {\n session.detachStderr?.();\n if (session.transportType === \"streamable-http\") {\n await (session.transport as StreamableHTTPClientTransport).terminateSession().catch(() => {});\n }\n await session.transport.close().catch(() => {});\n await session.client.close().catch(() => {});\n}\n\nfunction createCatalogFingerprint(servers: Record<string, unknown>): string {\n return crypto.createHash(\"sha1\").update(JSON.stringify(servers)).digest(\"hex\");\n}\n\nfunction loadSessionMcpConfig(params: {\n workspaceDir: string;\n cfg?: Config;\n logDiagnostics?: boolean;\n}): {\n loaded: LoadedMcpConfig;\n fingerprint: string;\n} {\n const loaded = loadEmbeddedMcpConfig({\n workspaceDir: params.workspaceDir,\n cfg: params.cfg,\n });\n if (params.logDiagnostics !== false) {\n for (const diagnostic of loaded.diagnostics) {\n log.warn(\n {\n phase: 'agent.mcp_connect',\n extensionId: diagnostic.extensionId,\n message: diagnostic.message,\n },\n `bundle-mcp diagnostic: ${diagnostic.extensionId}: ${diagnostic.message}`,\n );\n }\n }\n return {\n loaded,\n fingerprint: createCatalogFingerprint(loaded.mcpServers),\n };\n}\n\nfunction createDisposedError(sessionId: string): Error {\n return new Error(`bundle-mcp runtime disposed for session ${sessionId}`);\n}\n\nfunction resolveSessionMcpRuntimeIdleTtlMs(cfg?: Config): number {\n const raw = cfg?.mcp?.sessionIdleTtlMs;\n if (typeof raw === \"number\" && Number.isFinite(raw) && raw >= 0) {\n return Math.floor(raw);\n }\n return DEFAULT_SESSION_MCP_RUNTIME_IDLE_TTL_MS;\n}\n\nexport function createSessionMcpRuntime(params: {\n sessionId: string;\n sessionKey?: string;\n workspaceDir: string;\n cfg?: Config;\n}): SessionMcpRuntime {\n const { loaded, fingerprint: configFingerprint } = loadSessionMcpConfig({\n workspaceDir: params.workspaceDir,\n cfg: params.cfg,\n logDiagnostics: true,\n });\n const createdAt = Date.now();\n let lastUsedAt = createdAt;\n let activeLeases = 0;\n let disposed = false;\n let catalog: McpToolCatalog | null = null;\n let catalogInFlight: Promise<McpToolCatalog> | undefined;\n const sessions = new Map<string, BundleMcpSession>();\n const failIfDisposed = () => {\n if (disposed) {\n throw createDisposedError(params.sessionId);\n }\n };\n\n const getCatalog = async (): Promise<McpToolCatalog> => {\n failIfDisposed();\n if (catalog) {\n return catalog;\n }\n if (catalogInFlight) {\n return catalogInFlight;\n }\n catalogInFlight = (async () => {\n if (Object.keys(loaded.mcpServers).length === 0) {\n return {\n version: 1,\n generatedAt: Date.now(),\n servers: {},\n tools: [],\n };\n }\n\n const servers: Record<string, McpServerCatalog> = {};\n const tools: McpCatalogTool[] = [];\n const usedServerNames = new Set<string>();\n\n try {\n for (const [serverName, rawServer] of Object.entries(loaded.mcpServers)) {\n failIfDisposed();\n const resolvedServer = await resolveConnectorSecretReferences(rawServer);\n const resolved = resolveMcpTransport(serverName, resolvedServer);\n if (!resolved) {\n continue;\n }\n const safeServerName = sanitizeServerName(serverName, usedServerNames);\n if (safeServerName !== serverName) {\n log.warn(\n {\n phase: 'agent.mcp_connect',\n serverName,\n safeServerName,\n },\n `bundle-mcp: server key \"${serverName}\" registered as \"${safeServerName}\" for provider-safe tool names`,\n );\n }\n\n const client = new Client(\n {\n name: \"xopc-bundle-mcp\",\n version: \"0.0.0\",\n },\n {\n jsonSchemaValidator: createBundleMcpJsonSchemaValidator(),\n },\n );\n const session: BundleMcpSession = {\n serverName,\n client,\n transport: resolved.transport,\n transportType: resolved.transportType,\n detachStderr: resolved.detachStderr,\n };\n sessions.set(serverName, session);\n\n try {\n failIfDisposed();\n await connectWithTimeout(client, resolved.transport, resolved.connectionTimeoutMs);\n failIfDisposed();\n const listedTools = await listAllTools(client);\n failIfDisposed();\n servers[serverName] = {\n serverName,\n launchSummary: resolved.description,\n toolCount: listedTools.length,\n };\n for (const tool of listedTools) {\n const toolName = tool.name.trim();\n if (!toolName) {\n continue;\n }\n tools.push({\n serverName,\n safeServerName,\n toolName,\n title: tool.title,\n description:\n normalizeOptionalString(tool.description) ?? normalizeOptionalString(tool.title),\n inputSchema: tool.inputSchema,\n fallbackDescription: `Provided by bundle MCP server \"${serverName}\" (${resolved.description}).`,\n });\n }\n } catch (error) {\n if (!disposed) {\n log.warn(\n `bundle-mcp: failed to start server \"${serverName}\" (${resolved.description}): ${redactErrorUrls(error)}`,\n );\n }\n await disposeSession(session);\n sessions.delete(serverName);\n failIfDisposed();\n }\n }\n\n failIfDisposed();\n return {\n version: 1,\n generatedAt: Date.now(),\n servers,\n tools,\n };\n } catch (error) {\n await Promise.allSettled(\n Array.from(sessions.values(), (session) => disposeSession(session)),\n );\n sessions.clear();\n throw error;\n }\n })();\n\n try {\n const nextCatalog = await catalogInFlight;\n failIfDisposed();\n catalog = nextCatalog;\n return nextCatalog;\n } finally {\n catalogInFlight = undefined;\n }\n };\n\n return {\n sessionId: params.sessionId,\n sessionKey: params.sessionKey,\n workspaceDir: params.workspaceDir,\n configFingerprint,\n createdAt,\n get lastUsedAt() {\n return lastUsedAt;\n },\n get activeLeases() {\n return activeLeases;\n },\n acquireLease() {\n activeLeases += 1;\n let released = false;\n return () => {\n if (released) {\n return;\n }\n released = true;\n activeLeases = Math.max(0, activeLeases - 1);\n lastUsedAt = Date.now();\n };\n },\n getCatalog,\n markUsed() {\n lastUsedAt = Date.now();\n },\n async callTool(serverName, toolName, input) {\n failIfDisposed();\n await getCatalog();\n const session = sessions.get(serverName);\n if (!session) {\n throw new Error(`bundle-mcp server \"${serverName}\" is not connected`);\n }\n return (await session.client.callTool({\n name: toolName,\n arguments: isMcpConfigRecord(input) ? input : {},\n })) as CallToolResult;\n },\n async dispose() {\n if (disposed) {\n return;\n }\n disposed = true;\n catalog = null;\n catalogInFlight = undefined;\n const sessionsToClose = Array.from(sessions.values());\n sessions.clear();\n await Promise.allSettled(sessionsToClose.map((session) => disposeSession(session)));\n },\n };\n}\n\nfunction createSessionMcpRuntimeManager(\n opts: {\n createRuntime?: CreateSessionMcpRuntime;\n now?: () => number;\n enableIdleSweepTimer?: boolean;\n idleSweepIntervalMs?: number;\n } = {},\n): SessionMcpRuntimeManager {\n const runtimesBySessionId = new Map<string, SessionMcpRuntime>();\n const sessionIdBySessionKey = new Map<string, string>();\n const idleTtlMsBySessionId = new Map<string, number>();\n const createRuntime = opts.createRuntime ?? createSessionMcpRuntime;\n const now = opts.now ?? Date.now;\n const createInFlight = new Map<\n string,\n {\n promise: Promise<SessionMcpRuntime>;\n workspaceDir: string;\n configFingerprint: string;\n }\n >();\n const idleSweepIntervalMs = opts.idleSweepIntervalMs ?? SESSION_MCP_RUNTIME_SWEEP_INTERVAL_MS;\n let idleSweepTimer: ReturnType<typeof setInterval> | undefined;\n let idleSweepInFlight: Promise<void> | undefined;\n\n const forgetSessionKeysForSessionId = (sessionId: string) => {\n for (const [sessionKey, mappedSessionId] of sessionIdBySessionKey.entries()) {\n if (mappedSessionId === sessionId) {\n sessionIdBySessionKey.delete(sessionKey);\n }\n }\n };\n\n const sweepIdleRuntimes = async (): Promise<number> => {\n const nowMs = now();\n const expired: SessionMcpRuntime[] = [];\n for (const [sessionId, runtime] of runtimesBySessionId.entries()) {\n const idleTtlMs =\n idleTtlMsBySessionId.get(sessionId) ?? DEFAULT_SESSION_MCP_RUNTIME_IDLE_TTL_MS;\n if (idleTtlMs <= 0 || (runtime.activeLeases ?? 0) > 0) {\n continue;\n }\n if (nowMs - runtime.lastUsedAt < idleTtlMs) {\n continue;\n }\n runtimesBySessionId.delete(sessionId);\n idleTtlMsBySessionId.delete(sessionId);\n forgetSessionKeysForSessionId(sessionId);\n expired.push(runtime);\n }\n await Promise.allSettled(expired.map((runtime) => runtime.dispose()));\n return expired.length;\n };\n\n const queueIdleSweep = () => {\n if (idleSweepInFlight) {\n return;\n }\n idleSweepInFlight = sweepIdleRuntimes()\n .then(() => undefined)\n .catch((error: unknown) => {\n const em = error instanceof Error ? error.message : String(error);\n log.warn(\n { err: error, errorMessage: em, phase: 'agent.mcp_connect' },\n `bundle-mcp: idle runtime sweep failed: ${em}`,\n );\n })\n .finally(() => {\n idleSweepInFlight = undefined;\n });\n };\n\n const ensureIdleSweepTimer = () => {\n if (opts.enableIdleSweepTimer === false || idleSweepIntervalMs <= 0 || idleSweepTimer) {\n return;\n }\n idleSweepTimer = setInterval(queueIdleSweep, idleSweepIntervalMs);\n idleSweepTimer.unref?.();\n };\n\n const clearIdleSweepTimer = () => {\n if (!idleSweepTimer) {\n return;\n }\n clearInterval(idleSweepTimer);\n idleSweepTimer = undefined;\n };\n\n return {\n async getOrCreate(params) {\n const idleTtlMs = resolveSessionMcpRuntimeIdleTtlMs(params.cfg);\n if (runtimesBySessionId.has(params.sessionId)) {\n idleTtlMsBySessionId.set(params.sessionId, idleTtlMs);\n }\n await sweepIdleRuntimes();\n if (idleTtlMs > 0) {\n ensureIdleSweepTimer();\n }\n if (params.sessionKey) {\n sessionIdBySessionKey.set(params.sessionKey, params.sessionId);\n }\n const { fingerprint: nextFingerprint } = loadSessionMcpConfig({\n workspaceDir: params.workspaceDir,\n cfg: params.cfg,\n logDiagnostics: false,\n });\n const existing = runtimesBySessionId.get(params.sessionId);\n if (existing) {\n if (\n existing.workspaceDir !== params.workspaceDir ||\n existing.configFingerprint !== nextFingerprint\n ) {\n runtimesBySessionId.delete(params.sessionId);\n await existing.dispose();\n } else {\n existing.markUsed();\n idleTtlMsBySessionId.set(params.sessionId, idleTtlMs);\n return existing;\n }\n }\n const inFlight = createInFlight.get(params.sessionId);\n if (inFlight) {\n if (\n inFlight.workspaceDir === params.workspaceDir &&\n inFlight.configFingerprint === nextFingerprint\n ) {\n return inFlight.promise;\n }\n createInFlight.delete(params.sessionId);\n const staleRuntime = await inFlight.promise.catch(() => undefined);\n runtimesBySessionId.delete(params.sessionId);\n idleTtlMsBySessionId.delete(params.sessionId);\n await staleRuntime?.dispose();\n }\n const created = Promise.resolve(\n createRuntime({\n sessionId: params.sessionId,\n sessionKey: params.sessionKey,\n workspaceDir: params.workspaceDir,\n cfg: params.cfg,\n }),\n ).then((runtime) => {\n runtime.markUsed();\n runtimesBySessionId.set(params.sessionId, runtime);\n idleTtlMsBySessionId.set(params.sessionId, idleTtlMs);\n return runtime;\n });\n createInFlight.set(params.sessionId, {\n promise: created,\n workspaceDir: params.workspaceDir,\n configFingerprint: nextFingerprint,\n });\n try {\n return await created;\n } finally {\n createInFlight.delete(params.sessionId);\n }\n },\n bindSessionKey(sessionKey, sessionId) {\n sessionIdBySessionKey.set(sessionKey, sessionId);\n },\n resolveSessionId(sessionKey) {\n return sessionIdBySessionKey.get(sessionKey);\n },\n async disposeSession(sessionId) {\n const inFlight = createInFlight.get(sessionId);\n createInFlight.delete(sessionId);\n let runtime = runtimesBySessionId.get(sessionId);\n if (!runtime && inFlight) {\n runtime = await inFlight.promise.catch(() => undefined);\n }\n runtimesBySessionId.delete(sessionId);\n idleTtlMsBySessionId.delete(sessionId);\n if (!runtime) {\n forgetSessionKeysForSessionId(sessionId);\n return;\n }\n forgetSessionKeysForSessionId(sessionId);\n await runtime.dispose();\n },\n async disposeAll() {\n clearIdleSweepTimer();\n const inFlightRuntimes = Array.from(createInFlight.values());\n createInFlight.clear();\n const runtimes = Array.from(runtimesBySessionId.values());\n runtimesBySessionId.clear();\n sessionIdBySessionKey.clear();\n idleTtlMsBySessionId.clear();\n const lateRuntimes = await Promise.all(\n inFlightRuntimes.map(async ({ promise }) => await promise.catch(() => undefined)),\n );\n const allRuntimes = new Set<SessionMcpRuntime>(runtimes);\n for (const runtime of lateRuntimes) {\n if (runtime) {\n allRuntimes.add(runtime);\n }\n }\n await Promise.allSettled(Array.from(allRuntimes, (runtime) => runtime.dispose()));\n },\n sweepIdleRuntimes,\n listSessionIds() {\n return Array.from(runtimesBySessionId.keys());\n },\n };\n}\n\nexport function getSessionMcpRuntimeManager(): SessionMcpRuntimeManager {\n return resolveGlobalSingleton(SESSION_MCP_RUNTIME_MANAGER_KEY, createSessionMcpRuntimeManager);\n}\n\nexport async function getOrCreateSessionMcpRuntime(params: {\n sessionId: string;\n sessionKey?: string;\n workspaceDir: string;\n cfg?: Config;\n}): Promise<SessionMcpRuntime> {\n return await getSessionMcpRuntimeManager().getOrCreate(params);\n}\n\nexport async function disposeSessionMcpRuntime(sessionId: string): Promise<void> {\n await getSessionMcpRuntimeManager().disposeSession(sessionId);\n}\n\nexport async function retireSessionMcpRuntime(params: {\n sessionId?: string | null;\n reason: string;\n onError?: (error: unknown, sessionId: string, reason: string) => void;\n}): Promise<boolean> {\n const sessionId = normalizeOptionalString(params.sessionId);\n if (!sessionId) {\n return false;\n }\n try {\n await disposeSessionMcpRuntime(sessionId);\n return true;\n } catch (error) {\n params.onError?.(error, sessionId, params.reason);\n return false;\n }\n}\n\nexport async function retireSessionMcpRuntimeForSessionKey(params: {\n sessionKey?: string | null;\n reason: string;\n onError?: (error: unknown, sessionId: string, reason: string) => void;\n}): Promise<boolean> {\n const sessionKey = normalizeOptionalString(params.sessionKey);\n if (!sessionKey) {\n return false;\n }\n const sessionId = getSessionMcpRuntimeManager().resolveSessionId(sessionKey);\n return await retireSessionMcpRuntime({\n sessionId,\n reason: params.reason,\n onError: params.onError,\n });\n}\n\nexport async function disposeAllSessionMcpRuntimes(): Promise<void> {\n await getSessionMcpRuntimeManager().disposeAll();\n}\n\nexport const __testing = {\n createSessionMcpRuntimeManager,\n async resetSessionMcpRuntimeManager() {\n await disposeAllSessionMcpRuntimes();\n },\n getCachedSessionIds() {\n return getSessionMcpRuntimeManager().listSessionIds();\n },\n resolveSessionMcpRuntimeIdleTtlMs,\n};\n"],"mappings":"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"}
@@ -1,6 +1,6 @@
1
+ import { init_string_coerce, normalizeLowercaseStringOrEmpty } from "../../utils/string-coerce.js";
1
2
  import { createLogger } from "../../utils/logger/index.js";
2
3
  import { init_logger } from "../../utils/logger.js";
3
- import { init_string_coerce, normalizeLowercaseStringOrEmpty } from "../../utils/string-coerce.js";
4
4
  import { resolveXopcMcpTransportAlias } from "../../config/mcp-config-normalize.js";
5
5
  import { sanitizeForLog } from "../../utils/sanitize-log.js";
6
6
  import { describeHttpMcpServerLaunchConfig, resolveHttpMcpServerLaunchConfig } from "./mcp-http.js";
@@ -8,7 +8,7 @@ import { describeStdioMcpServerLaunchConfig, resolveStdioMcpServerLaunchConfig }
8
8
  //#region src/agent/mcp/mcp-transport-config.ts
9
9
  init_logger();
10
10
  init_string_coerce();
11
- const log = createLogger("BundleMcp");
11
+ const log = createLogger("Mcp:Bundle");
12
12
  const DEFAULT_CONNECTION_TIMEOUT_MS = 3e4;
13
13
  function getConnectionTimeoutMs(rawServer) {
14
14
  if (rawServer && typeof rawServer === "object" && typeof rawServer.connectionTimeoutMs === "number" && rawServer.connectionTimeoutMs > 0) return rawServer.connectionTimeoutMs;
@@ -26,10 +26,17 @@ function resolveHttpTransportConfig(serverName, rawServer, transportType) {
26
26
  const launch = resolveHttpMcpServerLaunchConfig(rawServer, {
27
27
  transportType,
28
28
  onDroppedHeader: (key) => {
29
- log.warn(`bundle-mcp: server "${serverName}": header "${key}" has an unsupported value type and was ignored.`);
29
+ log.warn({
30
+ phase: "agent.mcp_connect",
31
+ serverName,
32
+ header: key
33
+ }, `bundle-mcp: server "${serverName}": header "${key}" has an unsupported value type and was ignored`);
30
34
  },
31
35
  onMalformedHeaders: () => {
32
- log.warn(`bundle-mcp: server "${serverName}": "headers" must be a JSON object; the value was ignored.`);
36
+ log.warn({
37
+ phase: "agent.mcp_connect",
38
+ serverName
39
+ }, `bundle-mcp: server "${serverName}": "headers" must be a JSON object; the value was ignored`);
33
40
  }
34
41
  });
35
42
  if (!launch.ok) return null;
@@ -1 +1 @@
1
- {"version":3,"file":"mcp-transport-config.js","names":[],"sources":["../../../../src/agent/mcp/mcp-transport-config.ts"],"sourcesContent":["import { resolveXopcMcpTransportAlias } from \"../../config/mcp-config-normalize.js\";\nimport { createLogger } from \"../../utils/logger.js\";\nconst log = createLogger(\"BundleMcp\");\nimport { normalizeLowercaseStringOrEmpty } from \"../../utils/string-coerce.js\";\nimport { sanitizeForLog } from \"../../utils/sanitize-log.js\";\nimport {\n describeHttpMcpServerLaunchConfig,\n resolveHttpMcpServerLaunchConfig,\n type HttpMcpTransportType,\n} from \"./mcp-http.js\";\nimport {\n describeStdioMcpServerLaunchConfig,\n resolveStdioMcpServerLaunchConfig,\n} from \"./mcp-stdio.js\";\n\ntype ResolvedBaseMcpTransportConfig = {\n description: string;\n connectionTimeoutMs: number;\n};\n\nexport type ResolvedStdioMcpTransportConfig = ResolvedBaseMcpTransportConfig & {\n kind: \"stdio\";\n transportType: \"stdio\";\n command: string;\n args?: string[];\n env?: Record<string, string>;\n cwd?: string;\n};\n\nexport type ResolvedHttpMcpTransportConfig = ResolvedBaseMcpTransportConfig & {\n kind: \"http\";\n transportType: HttpMcpTransportType;\n url: string;\n headers?: Record<string, string>;\n};\n\nexport type ResolvedMcpTransportConfig =\n | ResolvedStdioMcpTransportConfig\n | ResolvedHttpMcpTransportConfig;\n\nconst DEFAULT_CONNECTION_TIMEOUT_MS = 30_000;\n\nfunction getConnectionTimeoutMs(rawServer: unknown): number {\n if (\n rawServer &&\n typeof rawServer === \"object\" &&\n typeof (rawServer as { connectionTimeoutMs?: unknown }).connectionTimeoutMs === \"number\" &&\n (rawServer as { connectionTimeoutMs: number }).connectionTimeoutMs > 0\n ) {\n return (rawServer as { connectionTimeoutMs: number }).connectionTimeoutMs;\n }\n return DEFAULT_CONNECTION_TIMEOUT_MS;\n}\n\nfunction getRequestedTransport(rawServer: unknown): string {\n if (\n !rawServer ||\n typeof rawServer !== \"object\" ||\n typeof (rawServer as { transport?: unknown }).transport !== \"string\"\n ) {\n return \"\";\n }\n return normalizeLowercaseStringOrEmpty((rawServer as { transport?: string }).transport);\n}\n\nfunction getRequestedTransportAlias(rawServer: unknown): HttpMcpTransportType | \"\" {\n if (\n !rawServer ||\n typeof rawServer !== \"object\" ||\n typeof (rawServer as { type?: unknown }).type !== \"string\"\n ) {\n return \"\";\n }\n return resolveXopcMcpTransportAlias((rawServer as { type?: string }).type) ?? \"\";\n}\n\nfunction resolveHttpTransportConfig(\n serverName: string,\n rawServer: unknown,\n transportType: HttpMcpTransportType,\n): ResolvedHttpMcpTransportConfig | null {\n const launch = resolveHttpMcpServerLaunchConfig(rawServer, {\n transportType,\n onDroppedHeader: (key) => {\n log.warn(\n `bundle-mcp: server \"${serverName}\": header \"${key}\" has an unsupported value type and was ignored.`,\n );\n },\n onMalformedHeaders: () => {\n log.warn(\n `bundle-mcp: server \"${serverName}\": \"headers\" must be a JSON object; the value was ignored.`,\n );\n },\n });\n if (!launch.ok) {\n return null;\n }\n return {\n kind: \"http\",\n transportType: launch.config.transportType,\n url: launch.config.url,\n headers: launch.config.headers,\n description: describeHttpMcpServerLaunchConfig(launch.config),\n connectionTimeoutMs: getConnectionTimeoutMs(rawServer),\n };\n}\n\nexport function resolveMcpTransportConfig(\n serverName: string,\n rawServer: unknown,\n): ResolvedMcpTransportConfig | null {\n const logServerName = sanitizeForLog(serverName);\n const requestedTransport = getRequestedTransport(rawServer);\n const requestedTransportAlias = requestedTransport ? \"\" : getRequestedTransportAlias(rawServer);\n const effectiveTransport = requestedTransport || requestedTransportAlias;\n const stdioLaunch = resolveStdioMcpServerLaunchConfig(rawServer, {\n onDroppedEnv: (key) => {\n log.warn(\n `bundle-mcp: server \"${logServerName}\": env \"${sanitizeForLog(key)}\" is blocked for stdio startup safety and was ignored.`,\n );\n },\n });\n if (stdioLaunch.ok) {\n return {\n kind: \"stdio\",\n transportType: \"stdio\",\n command: stdioLaunch.config.command,\n args: stdioLaunch.config.args,\n env: stdioLaunch.config.env,\n cwd: stdioLaunch.config.cwd,\n description: describeStdioMcpServerLaunchConfig(stdioLaunch.config),\n connectionTimeoutMs: getConnectionTimeoutMs(rawServer),\n };\n }\n\n if (\n effectiveTransport &&\n effectiveTransport !== \"sse\" &&\n effectiveTransport !== \"streamable-http\"\n ) {\n log.warn(\n `bundle-mcp: skipped server \"${logServerName}\" because transport \"${sanitizeForLog(effectiveTransport)}\" is not supported.`,\n );\n return null;\n }\n\n if (effectiveTransport === \"streamable-http\") {\n const httpTransport = resolveHttpTransportConfig(serverName, rawServer, \"streamable-http\");\n if (httpTransport) {\n return httpTransport;\n }\n }\n\n const sseTransport = resolveHttpTransportConfig(serverName, rawServer, \"sse\");\n if (sseTransport) {\n return sseTransport;\n }\n\n const stdioReason =\n stdioLaunch.ok === false ? stdioLaunch.reason : 'not a stdio server';\n const httpLaunch = resolveHttpMcpServerLaunchConfig(rawServer);\n const httpReason =\n httpLaunch.ok === false ? httpLaunch.reason : 'not an HTTP MCP server';\n log.warn(\n `bundle-mcp: skipped server \"${logServerName}\" because ${stdioReason} and ${httpReason}.`,\n );\n return null;\n}\n"],"mappings":";;;;;;;;aACqD;oBAE0B;AAD/E,MAAM,MAAM,aAAa,YAAY;AAsCrC,MAAM,gCAAgC;AAEtC,SAAS,uBAAuB,WAA4B;AAC1D,KACE,aACA,OAAO,cAAc,YACrB,OAAQ,UAAgD,wBAAwB,YAC/E,UAA8C,sBAAsB,EAErE,QAAQ,UAA8C;AAExD,QAAO;;AAGT,SAAS,sBAAsB,WAA4B;AACzD,KACE,CAAC,aACD,OAAO,cAAc,YACrB,OAAQ,UAAsC,cAAc,SAE5D,QAAO;AAET,QAAO,gCAAiC,UAAqC,UAAU;;AAGzF,SAAS,2BAA2B,WAA+C;AACjF,KACE,CAAC,aACD,OAAO,cAAc,YACrB,OAAQ,UAAiC,SAAS,SAElD,QAAO;AAET,QAAO,6BAA8B,UAAgC,KAAK,IAAI;;AAGhF,SAAS,2BACP,YACA,WACA,eACuC;CACvC,MAAM,SAAS,iCAAiC,WAAW;EACzD;EACA,kBAAkB,QAAQ;AACxB,OAAI,KACF,uBAAuB,WAAW,aAAa,IAAI,kDACpD;;EAEH,0BAA0B;AACxB,OAAI,KACF,uBAAuB,WAAW,4DACnC;;EAEJ,CAAC;AACF,KAAI,CAAC,OAAO,GACV,QAAO;AAET,QAAO;EACL,MAAM;EACN,eAAe,OAAO,OAAO;EAC7B,KAAK,OAAO,OAAO;EACnB,SAAS,OAAO,OAAO;EACvB,aAAa,kCAAkC,OAAO,OAAO;EAC7D,qBAAqB,uBAAuB,UAAU;EACvD;;AAGH,SAAgB,0BACd,YACA,WACmC;CACnC,MAAM,gBAAgB,eAAe,WAAW;CAChD,MAAM,qBAAqB,sBAAsB,UAAU;CAC3D,MAAM,0BAA0B,qBAAqB,KAAK,2BAA2B,UAAU;CAC/F,MAAM,qBAAqB,sBAAsB;CACjD,MAAM,cAAc,kCAAkC,WAAW,EAC/D,eAAe,QAAQ;AACrB,MAAI,KACF,uBAAuB,cAAc,UAAU,eAAe,IAAI,CAAC,wDACpE;IAEJ,CAAC;AACF,KAAI,YAAY,GACd,QAAO;EACL,MAAM;EACN,eAAe;EACf,SAAS,YAAY,OAAO;EAC5B,MAAM,YAAY,OAAO;EACzB,KAAK,YAAY,OAAO;EACxB,KAAK,YAAY,OAAO;EACxB,aAAa,mCAAmC,YAAY,OAAO;EACnE,qBAAqB,uBAAuB,UAAU;EACvD;AAGH,KACE,sBACA,uBAAuB,SACvB,uBAAuB,mBACvB;AACA,MAAI,KACF,+BAA+B,cAAc,uBAAuB,eAAe,mBAAmB,CAAC,qBACxG;AACD,SAAO;;AAGT,KAAI,uBAAuB,mBAAmB;EAC5C,MAAM,gBAAgB,2BAA2B,YAAY,WAAW,kBAAkB;AAC1F,MAAI,cACF,QAAO;;CAIX,MAAM,eAAe,2BAA2B,YAAY,WAAW,MAAM;AAC7E,KAAI,aACF,QAAO;CAGT,MAAM,cACJ,YAAY,OAAO,QAAQ,YAAY,SAAS;CAClD,MAAM,aAAa,iCAAiC,UAAU;CAC9D,MAAM,aACJ,WAAW,OAAO,QAAQ,WAAW,SAAS;AAChD,KAAI,KACF,+BAA+B,cAAc,YAAY,YAAY,OAAO,WAAW,GACxF;AACD,QAAO"}
1
+ {"version":3,"file":"mcp-transport-config.js","names":[],"sources":["../../../../src/agent/mcp/mcp-transport-config.ts"],"sourcesContent":["import { resolveXopcMcpTransportAlias } from \"../../config/mcp-config-normalize.js\";\nimport { createLogger } from \"../../utils/logger.js\";\nconst log = createLogger(\"Mcp:Bundle\");\nimport { normalizeLowercaseStringOrEmpty } from \"../../utils/string-coerce.js\";\nimport { sanitizeForLog } from \"../../utils/sanitize-log.js\";\nimport {\n describeHttpMcpServerLaunchConfig,\n resolveHttpMcpServerLaunchConfig,\n type HttpMcpTransportType,\n} from \"./mcp-http.js\";\nimport {\n describeStdioMcpServerLaunchConfig,\n resolveStdioMcpServerLaunchConfig,\n} from \"./mcp-stdio.js\";\n\ntype ResolvedBaseMcpTransportConfig = {\n description: string;\n connectionTimeoutMs: number;\n};\n\nexport type ResolvedStdioMcpTransportConfig = ResolvedBaseMcpTransportConfig & {\n kind: \"stdio\";\n transportType: \"stdio\";\n command: string;\n args?: string[];\n env?: Record<string, string>;\n cwd?: string;\n};\n\nexport type ResolvedHttpMcpTransportConfig = ResolvedBaseMcpTransportConfig & {\n kind: \"http\";\n transportType: HttpMcpTransportType;\n url: string;\n headers?: Record<string, string>;\n};\n\nexport type ResolvedMcpTransportConfig =\n | ResolvedStdioMcpTransportConfig\n | ResolvedHttpMcpTransportConfig;\n\nconst DEFAULT_CONNECTION_TIMEOUT_MS = 30_000;\n\nfunction getConnectionTimeoutMs(rawServer: unknown): number {\n if (\n rawServer &&\n typeof rawServer === \"object\" &&\n typeof (rawServer as { connectionTimeoutMs?: unknown }).connectionTimeoutMs === \"number\" &&\n (rawServer as { connectionTimeoutMs: number }).connectionTimeoutMs > 0\n ) {\n return (rawServer as { connectionTimeoutMs: number }).connectionTimeoutMs;\n }\n return DEFAULT_CONNECTION_TIMEOUT_MS;\n}\n\nfunction getRequestedTransport(rawServer: unknown): string {\n if (\n !rawServer ||\n typeof rawServer !== \"object\" ||\n typeof (rawServer as { transport?: unknown }).transport !== \"string\"\n ) {\n return \"\";\n }\n return normalizeLowercaseStringOrEmpty((rawServer as { transport?: string }).transport);\n}\n\nfunction getRequestedTransportAlias(rawServer: unknown): HttpMcpTransportType | \"\" {\n if (\n !rawServer ||\n typeof rawServer !== \"object\" ||\n typeof (rawServer as { type?: unknown }).type !== \"string\"\n ) {\n return \"\";\n }\n return resolveXopcMcpTransportAlias((rawServer as { type?: string }).type) ?? \"\";\n}\n\nfunction resolveHttpTransportConfig(\n serverName: string,\n rawServer: unknown,\n transportType: HttpMcpTransportType,\n): ResolvedHttpMcpTransportConfig | null {\n const launch = resolveHttpMcpServerLaunchConfig(rawServer, {\n transportType,\n onDroppedHeader: (key) => {\n log.warn(\n {\n phase: 'agent.mcp_connect',\n serverName,\n header: key,\n },\n `bundle-mcp: server \"${serverName}\": header \"${key}\" has an unsupported value type and was ignored`,\n );\n },\n onMalformedHeaders: () => {\n log.warn(\n { phase: 'agent.mcp_connect', serverName },\n `bundle-mcp: server \"${serverName}\": \"headers\" must be a JSON object; the value was ignored`,\n );\n },\n });\n if (!launch.ok) {\n return null;\n }\n return {\n kind: \"http\",\n transportType: launch.config.transportType,\n url: launch.config.url,\n headers: launch.config.headers,\n description: describeHttpMcpServerLaunchConfig(launch.config),\n connectionTimeoutMs: getConnectionTimeoutMs(rawServer),\n };\n}\n\nexport function resolveMcpTransportConfig(\n serverName: string,\n rawServer: unknown,\n): ResolvedMcpTransportConfig | null {\n const logServerName = sanitizeForLog(serverName);\n const requestedTransport = getRequestedTransport(rawServer);\n const requestedTransportAlias = requestedTransport ? \"\" : getRequestedTransportAlias(rawServer);\n const effectiveTransport = requestedTransport || requestedTransportAlias;\n const stdioLaunch = resolveStdioMcpServerLaunchConfig(rawServer, {\n onDroppedEnv: (key) => {\n log.warn(\n `bundle-mcp: server \"${logServerName}\": env \"${sanitizeForLog(key)}\" is blocked for stdio startup safety and was ignored.`,\n );\n },\n });\n if (stdioLaunch.ok) {\n return {\n kind: \"stdio\",\n transportType: \"stdio\",\n command: stdioLaunch.config.command,\n args: stdioLaunch.config.args,\n env: stdioLaunch.config.env,\n cwd: stdioLaunch.config.cwd,\n description: describeStdioMcpServerLaunchConfig(stdioLaunch.config),\n connectionTimeoutMs: getConnectionTimeoutMs(rawServer),\n };\n }\n\n if (\n effectiveTransport &&\n effectiveTransport !== \"sse\" &&\n effectiveTransport !== \"streamable-http\"\n ) {\n log.warn(\n `bundle-mcp: skipped server \"${logServerName}\" because transport \"${sanitizeForLog(effectiveTransport)}\" is not supported.`,\n );\n return null;\n }\n\n if (effectiveTransport === \"streamable-http\") {\n const httpTransport = resolveHttpTransportConfig(serverName, rawServer, \"streamable-http\");\n if (httpTransport) {\n return httpTransport;\n }\n }\n\n const sseTransport = resolveHttpTransportConfig(serverName, rawServer, \"sse\");\n if (sseTransport) {\n return sseTransport;\n }\n\n const stdioReason =\n stdioLaunch.ok === false ? stdioLaunch.reason : 'not a stdio server';\n const httpLaunch = resolveHttpMcpServerLaunchConfig(rawServer);\n const httpReason =\n httpLaunch.ok === false ? httpLaunch.reason : 'not an HTTP MCP server';\n log.warn(\n `bundle-mcp: skipped server \"${logServerName}\" because ${stdioReason} and ${httpReason}.`,\n );\n return null;\n}\n"],"mappings":";;;;;;;;aACqD;oBAE0B;AAD/E,MAAM,MAAM,aAAa,aAAa;AAsCtC,MAAM,gCAAgC;AAEtC,SAAS,uBAAuB,WAA4B;AAC1D,KACE,aACA,OAAO,cAAc,YACrB,OAAQ,UAAgD,wBAAwB,YAC/E,UAA8C,sBAAsB,EAErE,QAAQ,UAA8C;AAExD,QAAO;;AAGT,SAAS,sBAAsB,WAA4B;AACzD,KACE,CAAC,aACD,OAAO,cAAc,YACrB,OAAQ,UAAsC,cAAc,SAE5D,QAAO;AAET,QAAO,gCAAiC,UAAqC,UAAU;;AAGzF,SAAS,2BAA2B,WAA+C;AACjF,KACE,CAAC,aACD,OAAO,cAAc,YACrB,OAAQ,UAAiC,SAAS,SAElD,QAAO;AAET,QAAO,6BAA8B,UAAgC,KAAK,IAAI;;AAGhF,SAAS,2BACP,YACA,WACA,eACuC;CACvC,MAAM,SAAS,iCAAiC,WAAW;EACzD;EACA,kBAAkB,QAAQ;AACxB,OAAI,KACF;IACE,OAAO;IACP;IACA,QAAQ;IACT,EACD,uBAAuB,WAAW,aAAa,IAAI,iDACpD;;EAEH,0BAA0B;AACxB,OAAI,KACF;IAAE,OAAO;IAAqB;IAAY,EAC1C,uBAAuB,WAAW,2DACnC;;EAEJ,CAAC;AACF,KAAI,CAAC,OAAO,GACV,QAAO;AAET,QAAO;EACL,MAAM;EACN,eAAe,OAAO,OAAO;EAC7B,KAAK,OAAO,OAAO;EACnB,SAAS,OAAO,OAAO;EACvB,aAAa,kCAAkC,OAAO,OAAO;EAC7D,qBAAqB,uBAAuB,UAAU;EACvD;;AAGH,SAAgB,0BACd,YACA,WACmC;CACnC,MAAM,gBAAgB,eAAe,WAAW;CAChD,MAAM,qBAAqB,sBAAsB,UAAU;CAC3D,MAAM,0BAA0B,qBAAqB,KAAK,2BAA2B,UAAU;CAC/F,MAAM,qBAAqB,sBAAsB;CACjD,MAAM,cAAc,kCAAkC,WAAW,EAC/D,eAAe,QAAQ;AACrB,MAAI,KACF,uBAAuB,cAAc,UAAU,eAAe,IAAI,CAAC,wDACpE;IAEJ,CAAC;AACF,KAAI,YAAY,GACd,QAAO;EACL,MAAM;EACN,eAAe;EACf,SAAS,YAAY,OAAO;EAC5B,MAAM,YAAY,OAAO;EACzB,KAAK,YAAY,OAAO;EACxB,KAAK,YAAY,OAAO;EACxB,aAAa,mCAAmC,YAAY,OAAO;EACnE,qBAAqB,uBAAuB,UAAU;EACvD;AAGH,KACE,sBACA,uBAAuB,SACvB,uBAAuB,mBACvB;AACA,MAAI,KACF,+BAA+B,cAAc,uBAAuB,eAAe,mBAAmB,CAAC,qBACxG;AACD,SAAO;;AAGT,KAAI,uBAAuB,mBAAmB;EAC5C,MAAM,gBAAgB,2BAA2B,YAAY,WAAW,kBAAkB;AAC1F,MAAI,cACF,QAAO;;CAIX,MAAM,eAAe,2BAA2B,YAAY,WAAW,MAAM;AAC7E,KAAI,aACF,QAAO;CAGT,MAAM,cACJ,YAAY,OAAO,QAAQ,YAAY,SAAS;CAClD,MAAM,aAAa,iCAAiC,UAAU;CAC9D,MAAM,aACJ,WAAW,OAAO,QAAQ,WAAW,SAAS;AAChD,KAAI,KACF,+BAA+B,cAAc,YAAY,YAAY,OAAO,WAAW,GACxF;AACD,QAAO"}
@@ -1,6 +1,6 @@
1
+ import { init_string_coerce, normalizeOptionalString } from "../../utils/string-coerce.js";
1
2
  import { createLogger } from "../../utils/logger/index.js";
2
3
  import { init_logger } from "../../utils/logger.js";
3
- import { init_string_coerce, normalizeOptionalString } from "../../utils/string-coerce.js";
4
4
  import { XopcStdioClientTransport } from "./mcp-stdio-transport.js";
5
5
  import { resolveMcpTransportConfig } from "./mcp-transport-config.js";
6
6
  import { SSEClientTransport } from "@modelcontextprotocol/sdk/client/sse.js";
@@ -9,7 +9,7 @@ import { fetch } from "undici";
9
9
  //#region src/agent/mcp/mcp-transport.ts
10
10
  init_logger();
11
11
  init_string_coerce();
12
- const log = createLogger("McpTransport");
12
+ const log = createLogger("Mcp:Transport");
13
13
  function attachStderrLogging(serverName, transport) {
14
14
  const stderr = transport.stderr;
15
15
  if (!stderr || typeof stderr.on !== "function") return;
@@ -1 +1 @@
1
- {"version":3,"file":"mcp-transport.js","names":["undiciFetch"],"sources":["../../../../src/agent/mcp/mcp-transport.ts"],"sourcesContent":["import {\n SSEClientTransport,\n type SSEClientTransportOptions,\n} from \"@modelcontextprotocol/sdk/client/sse.js\";\nimport { StreamableHTTPClientTransport } from \"@modelcontextprotocol/sdk/client/streamableHttp.js\";\nimport type { FetchLike, Transport } from \"@modelcontextprotocol/sdk/shared/transport.js\";\nimport { fetch as undiciFetch } from \"undici\";\nimport { createLogger } from \"../../utils/logger.js\";\nconst log = createLogger(\"McpTransport\");\nimport { normalizeOptionalString } from \"../../utils/string-coerce.js\";\nimport { XopcStdioClientTransport } from \"./mcp-stdio-transport.js\";\nimport { resolveMcpTransportConfig } from \"./mcp-transport-config.js\";\n\nexport type ResolvedMcpTransport = {\n transport: Transport;\n description: string;\n transportType: \"stdio\" | \"sse\" | \"streamable-http\";\n connectionTimeoutMs: number;\n detachStderr?: () => void;\n};\n\nfunction attachStderrLogging(serverName: string, transport: XopcStdioClientTransport) {\n const stderr = transport.stderr;\n if (!stderr || typeof stderr.on !== \"function\") {\n return undefined;\n }\n const onData = (chunk: Buffer | string) => {\n const message =\n normalizeOptionalString(typeof chunk === \"string\" ? chunk : String(chunk)) ?? \"\";\n if (!message) {\n return;\n }\n for (const line of message.split(/\\r?\\n/)) {\n const trimmed = line.trim();\n if (trimmed) {\n log.debug(`bundle-mcp:${serverName}: ${trimmed}`);\n }\n }\n };\n stderr.on(\"data\", onData);\n return () => {\n if (typeof stderr.off === \"function\") {\n stderr.off(\"data\", onData);\n } else if (typeof stderr.removeListener === \"function\") {\n stderr.removeListener(\"data\", onData);\n }\n };\n}\n\ntype SseEventSourceFetch = NonNullable<\n NonNullable<SSEClientTransportOptions[\"eventSourceInit\"]>[\"fetch\"]\n>;\n\nconst fetchWithUndici: FetchLike = async (url, init) =>\n (await undiciFetch(url, init as unknown as Parameters<typeof undiciFetch>[1])) as unknown as Response;\n\nfunction buildSseEventSourceFetch(headers: Record<string, string>): SseEventSourceFetch {\n return (url: string | URL, init?: RequestInit) => {\n const sdkHeaders: Record<string, string> = {};\n if (init?.headers) {\n if (init.headers instanceof Headers) {\n init.headers.forEach((value, key) => {\n sdkHeaders[key] = value;\n });\n } else {\n Object.assign(sdkHeaders, init.headers);\n }\n }\n return fetchWithUndici(url, {\n ...(init as RequestInit),\n headers: { ...sdkHeaders, ...headers },\n }) as ReturnType<SseEventSourceFetch>;\n };\n}\n\nexport function resolveMcpTransport(\n serverName: string,\n rawServer: unknown,\n): ResolvedMcpTransport | null {\n const resolved = resolveMcpTransportConfig(serverName, rawServer);\n if (!resolved) {\n return null;\n }\n if (resolved.kind === \"stdio\") {\n const transport = new XopcStdioClientTransport({\n command: resolved.command,\n args: resolved.args,\n env: resolved.env,\n cwd: resolved.cwd,\n stderr: \"pipe\",\n });\n return {\n transport,\n description: resolved.description,\n transportType: \"stdio\",\n connectionTimeoutMs: resolved.connectionTimeoutMs,\n detachStderr: attachStderrLogging(serverName, transport),\n };\n }\n if (resolved.transportType === \"streamable-http\") {\n return {\n transport: new StreamableHTTPClientTransport(new URL(resolved.url), {\n requestInit: resolved.headers ? { headers: resolved.headers } : undefined,\n }),\n description: resolved.description,\n transportType: \"streamable-http\",\n connectionTimeoutMs: resolved.connectionTimeoutMs,\n };\n }\n const headers: Record<string, string> = {\n ...resolved.headers,\n };\n const hasHeaders = Object.keys(headers).length > 0;\n return {\n transport: new SSEClientTransport(new URL(resolved.url), {\n requestInit: hasHeaders ? { headers } : undefined,\n fetch: fetchWithUndici,\n eventSourceInit: { fetch: buildSseEventSourceFetch(headers) },\n }),\n description: resolved.description,\n transportType: \"sse\",\n connectionTimeoutMs: resolved.connectionTimeoutMs,\n };\n}\n"],"mappings":";;;;;;;;;aAOqD;oBAEkB;AADvE,MAAM,MAAM,aAAa,eAAe;AAaxC,SAAS,oBAAoB,YAAoB,WAAqC;CACpF,MAAM,SAAS,UAAU;AACzB,KAAI,CAAC,UAAU,OAAO,OAAO,OAAO,WAClC;CAEF,MAAM,UAAU,UAA2B;EACzC,MAAM,UACJ,wBAAwB,OAAO,UAAU,WAAW,QAAQ,OAAO,MAAM,CAAC,IAAI;AAChF,MAAI,CAAC,QACH;AAEF,OAAK,MAAM,QAAQ,QAAQ,MAAM,QAAQ,EAAE;GACzC,MAAM,UAAU,KAAK,MAAM;AAC3B,OAAI,QACF,KAAI,MAAM,cAAc,WAAW,IAAI,UAAU;;;AAIvD,QAAO,GAAG,QAAQ,OAAO;AACzB,cAAa;AACX,MAAI,OAAO,OAAO,QAAQ,WACxB,QAAO,IAAI,QAAQ,OAAO;WACjB,OAAO,OAAO,mBAAmB,WAC1C,QAAO,eAAe,QAAQ,OAAO;;;AAS3C,MAAM,kBAA6B,OAAO,KAAK,SAC5C,MAAMA,MAAY,KAAK,KAAqD;AAE/E,SAAS,yBAAyB,SAAsD;AACtF,SAAQ,KAAmB,SAAuB;EAChD,MAAM,aAAqC,EAAE;AAC7C,MAAI,MAAM,QACR,KAAI,KAAK,mBAAmB,QAC1B,MAAK,QAAQ,SAAS,OAAO,QAAQ;AACnC,cAAW,OAAO;IAClB;MAEF,QAAO,OAAO,YAAY,KAAK,QAAQ;AAG3C,SAAO,gBAAgB,KAAK;GAC1B,GAAI;GACJ,SAAS;IAAE,GAAG;IAAY,GAAG;IAAS;GACvC,CAAC;;;AAIN,SAAgB,oBACd,YACA,WAC6B;CAC7B,MAAM,WAAW,0BAA0B,YAAY,UAAU;AACjE,KAAI,CAAC,SACH,QAAO;AAET,KAAI,SAAS,SAAS,SAAS;EAC7B,MAAM,YAAY,IAAI,yBAAyB;GAC7C,SAAS,SAAS;GAClB,MAAM,SAAS;GACf,KAAK,SAAS;GACd,KAAK,SAAS;GACd,QAAQ;GACT,CAAC;AACF,SAAO;GACL;GACA,aAAa,SAAS;GACtB,eAAe;GACf,qBAAqB,SAAS;GAC9B,cAAc,oBAAoB,YAAY,UAAU;GACzD;;AAEH,KAAI,SAAS,kBAAkB,kBAC7B,QAAO;EACL,WAAW,IAAI,8BAA8B,IAAI,IAAI,SAAS,IAAI,EAAE,EAClE,aAAa,SAAS,UAAU,EAAE,SAAS,SAAS,SAAS,GAAG,KAAA,GACjE,CAAC;EACF,aAAa,SAAS;EACtB,eAAe;EACf,qBAAqB,SAAS;EAC/B;CAEH,MAAM,UAAkC,EACtC,GAAG,SAAS,SACb;CACD,MAAM,aAAa,OAAO,KAAK,QAAQ,CAAC,SAAS;AACjD,QAAO;EACL,WAAW,IAAI,mBAAmB,IAAI,IAAI,SAAS,IAAI,EAAE;GACvD,aAAa,aAAa,EAAE,SAAS,GAAG,KAAA;GACxC,OAAO;GACP,iBAAiB,EAAE,OAAO,yBAAyB,QAAQ,EAAE;GAC9D,CAAC;EACF,aAAa,SAAS;EACtB,eAAe;EACf,qBAAqB,SAAS;EAC/B"}
1
+ {"version":3,"file":"mcp-transport.js","names":["undiciFetch"],"sources":["../../../../src/agent/mcp/mcp-transport.ts"],"sourcesContent":["import {\n SSEClientTransport,\n type SSEClientTransportOptions,\n} from \"@modelcontextprotocol/sdk/client/sse.js\";\nimport { StreamableHTTPClientTransport } from \"@modelcontextprotocol/sdk/client/streamableHttp.js\";\nimport type { FetchLike, Transport } from \"@modelcontextprotocol/sdk/shared/transport.js\";\nimport { fetch as undiciFetch } from \"undici\";\nimport { createLogger } from \"../../utils/logger.js\";\nconst log = createLogger(\"Mcp:Transport\");\nimport { normalizeOptionalString } from \"../../utils/string-coerce.js\";\nimport { XopcStdioClientTransport } from \"./mcp-stdio-transport.js\";\nimport { resolveMcpTransportConfig } from \"./mcp-transport-config.js\";\n\nexport type ResolvedMcpTransport = {\n transport: Transport;\n description: string;\n transportType: \"stdio\" | \"sse\" | \"streamable-http\";\n connectionTimeoutMs: number;\n detachStderr?: () => void;\n};\n\nfunction attachStderrLogging(serverName: string, transport: XopcStdioClientTransport) {\n const stderr = transport.stderr;\n if (!stderr || typeof stderr.on !== \"function\") {\n return undefined;\n }\n const onData = (chunk: Buffer | string) => {\n const message =\n normalizeOptionalString(typeof chunk === \"string\" ? chunk : String(chunk)) ?? \"\";\n if (!message) {\n return;\n }\n for (const line of message.split(/\\r?\\n/)) {\n const trimmed = line.trim();\n if (trimmed) {\n log.debug(`bundle-mcp:${serverName}: ${trimmed}`);\n }\n }\n };\n stderr.on(\"data\", onData);\n return () => {\n if (typeof stderr.off === \"function\") {\n stderr.off(\"data\", onData);\n } else if (typeof stderr.removeListener === \"function\") {\n stderr.removeListener(\"data\", onData);\n }\n };\n}\n\ntype SseEventSourceFetch = NonNullable<\n NonNullable<SSEClientTransportOptions[\"eventSourceInit\"]>[\"fetch\"]\n>;\n\nconst fetchWithUndici: FetchLike = async (url, init) =>\n (await undiciFetch(url, init as unknown as Parameters<typeof undiciFetch>[1])) as unknown as Response;\n\nfunction buildSseEventSourceFetch(headers: Record<string, string>): SseEventSourceFetch {\n return (url: string | URL, init?: RequestInit) => {\n const sdkHeaders: Record<string, string> = {};\n if (init?.headers) {\n if (init.headers instanceof Headers) {\n init.headers.forEach((value, key) => {\n sdkHeaders[key] = value;\n });\n } else {\n Object.assign(sdkHeaders, init.headers);\n }\n }\n return fetchWithUndici(url, {\n ...(init as RequestInit),\n headers: { ...sdkHeaders, ...headers },\n }) as ReturnType<SseEventSourceFetch>;\n };\n}\n\nexport function resolveMcpTransport(\n serverName: string,\n rawServer: unknown,\n): ResolvedMcpTransport | null {\n const resolved = resolveMcpTransportConfig(serverName, rawServer);\n if (!resolved) {\n return null;\n }\n if (resolved.kind === \"stdio\") {\n const transport = new XopcStdioClientTransport({\n command: resolved.command,\n args: resolved.args,\n env: resolved.env,\n cwd: resolved.cwd,\n stderr: \"pipe\",\n });\n return {\n transport,\n description: resolved.description,\n transportType: \"stdio\",\n connectionTimeoutMs: resolved.connectionTimeoutMs,\n detachStderr: attachStderrLogging(serverName, transport),\n };\n }\n if (resolved.transportType === \"streamable-http\") {\n return {\n transport: new StreamableHTTPClientTransport(new URL(resolved.url), {\n requestInit: resolved.headers ? { headers: resolved.headers } : undefined,\n }),\n description: resolved.description,\n transportType: \"streamable-http\",\n connectionTimeoutMs: resolved.connectionTimeoutMs,\n };\n }\n const headers: Record<string, string> = {\n ...resolved.headers,\n };\n const hasHeaders = Object.keys(headers).length > 0;\n return {\n transport: new SSEClientTransport(new URL(resolved.url), {\n requestInit: hasHeaders ? { headers } : undefined,\n fetch: fetchWithUndici,\n eventSourceInit: { fetch: buildSseEventSourceFetch(headers) },\n }),\n description: resolved.description,\n transportType: \"sse\",\n connectionTimeoutMs: resolved.connectionTimeoutMs,\n };\n}\n"],"mappings":";;;;;;;;;aAOqD;oBAEkB;AADvE,MAAM,MAAM,aAAa,gBAAgB;AAazC,SAAS,oBAAoB,YAAoB,WAAqC;CACpF,MAAM,SAAS,UAAU;AACzB,KAAI,CAAC,UAAU,OAAO,OAAO,OAAO,WAClC;CAEF,MAAM,UAAU,UAA2B;EACzC,MAAM,UACJ,wBAAwB,OAAO,UAAU,WAAW,QAAQ,OAAO,MAAM,CAAC,IAAI;AAChF,MAAI,CAAC,QACH;AAEF,OAAK,MAAM,QAAQ,QAAQ,MAAM,QAAQ,EAAE;GACzC,MAAM,UAAU,KAAK,MAAM;AAC3B,OAAI,QACF,KAAI,MAAM,cAAc,WAAW,IAAI,UAAU;;;AAIvD,QAAO,GAAG,QAAQ,OAAO;AACzB,cAAa;AACX,MAAI,OAAO,OAAO,QAAQ,WACxB,QAAO,IAAI,QAAQ,OAAO;WACjB,OAAO,OAAO,mBAAmB,WAC1C,QAAO,eAAe,QAAQ,OAAO;;;AAS3C,MAAM,kBAA6B,OAAO,KAAK,SAC5C,MAAMA,MAAY,KAAK,KAAqD;AAE/E,SAAS,yBAAyB,SAAsD;AACtF,SAAQ,KAAmB,SAAuB;EAChD,MAAM,aAAqC,EAAE;AAC7C,MAAI,MAAM,QACR,KAAI,KAAK,mBAAmB,QAC1B,MAAK,QAAQ,SAAS,OAAO,QAAQ;AACnC,cAAW,OAAO;IAClB;MAEF,QAAO,OAAO,YAAY,KAAK,QAAQ;AAG3C,SAAO,gBAAgB,KAAK;GAC1B,GAAI;GACJ,SAAS;IAAE,GAAG;IAAY,GAAG;IAAS;GACvC,CAAC;;;AAIN,SAAgB,oBACd,YACA,WAC6B;CAC7B,MAAM,WAAW,0BAA0B,YAAY,UAAU;AACjE,KAAI,CAAC,SACH,QAAO;AAET,KAAI,SAAS,SAAS,SAAS;EAC7B,MAAM,YAAY,IAAI,yBAAyB;GAC7C,SAAS,SAAS;GAClB,MAAM,SAAS;GACf,KAAK,SAAS;GACd,KAAK,SAAS;GACd,QAAQ;GACT,CAAC;AACF,SAAO;GACL;GACA,aAAa,SAAS;GACtB,eAAe;GACf,qBAAqB,SAAS;GAC9B,cAAc,oBAAoB,YAAY,UAAU;GACzD;;AAEH,KAAI,SAAS,kBAAkB,kBAC7B,QAAO;EACL,WAAW,IAAI,8BAA8B,IAAI,IAAI,SAAS,IAAI,EAAE,EAClE,aAAa,SAAS,UAAU,EAAE,SAAS,SAAS,SAAS,GAAG,KAAA,GACjE,CAAC;EACF,aAAa,SAAS;EACtB,eAAe;EACf,qBAAqB,SAAS;EAC/B;CAEH,MAAM,UAAkC,EACtC,GAAG,SAAS,SACb;CACD,MAAM,aAAa,OAAO,KAAK,QAAQ,CAAC,SAAS;AACjD,QAAO;EACL,WAAW,IAAI,mBAAmB,IAAI,IAAI,SAAS,IAAI,EAAE;GACvD,aAAa,aAAa,EAAE,SAAS,GAAG,KAAA;GACxC,OAAO;GACP,iBAAiB,EAAE,OAAO,yBAAyB,QAAQ,EAAE;GAC9D,CAAC;EACF,aAAa,SAAS;EACtB,eAAe;EACf,qBAAqB,SAAS;EAC/B"}
@@ -1,6 +1,6 @@
1
+ import { join } from "node:path";
1
2
  import { existsSync, mkdirSync, readFileSync } from "node:fs";
2
3
  import { mkdir, readFile, rename, writeFile } from "node:fs/promises";
3
- import { join } from "node:path";
4
4
  import lockfile from "proper-lockfile";
5
5
  //#region src/agent/memory/builtin-memory-store.ts
6
6
  /**
@@ -4,8 +4,8 @@ import { MEMORY_MD_FILENAME } from "./constants.js";
4
4
  import { clamp01, compareCandidatesByScore, computeCandidateScore, extractPromotionMarkers, isContaminatedSnippet, isExpiredEntry, isoDay, readFileLines, resolveDeepDefaults, sliceRange, snippetHash } from "./utils.js";
5
5
  import { loadDreamingStore, saveDreamingStore, withDreamingPromotionLock } from "./short-term-store.js";
6
6
  import { emptyDeepPhaseSkipped, writeDreamingDeepLastRun } from "./last-run.js";
7
- import fs from "node:fs/promises";
8
7
  import path from "node:path";
8
+ import fs from "node:fs/promises";
9
9
  //#region src/agent/memory/dreaming/deep-promotion.ts
10
10
  init_logger();
11
11
  const log = createLogger("Dreaming:Deep");
@@ -1,6 +1,6 @@
1
1
  import { DREAMING_DIR_RELATIVE, DREAMING_EVENTS_LOG_RELATIVE } from "./constants.js";
2
- import fs from "node:fs/promises";
3
2
  import path from "node:path";
3
+ import fs from "node:fs/promises";
4
4
  //#region src/agent/memory/dreaming/events.ts
5
5
  /**
6
6
  * Append a single event line to `memory/.dreams/events.jsonl`.
@@ -1,6 +1,6 @@
1
1
  import { DREAMING_LAST_RUN_RELATIVE } from "./constants.js";
2
- import fs from "node:fs/promises";
3
2
  import path from "node:path";
3
+ import fs from "node:fs/promises";
4
4
  //#region src/agent/memory/dreaming/last-run.ts
5
5
  const DREAMING_LAST_RUN_FORMAT_VERSION = 2;
6
6
  function isRecord(v) {
@@ -4,8 +4,8 @@ import { DREAMING_DIR_RELATIVE } from "./constants.js";
4
4
  import { buildEntryKey, isoDay, normalizeMemoryPath, normalizeSnippetForHash, snippetHash } from "./utils.js";
5
5
  import { bumpEntryPhaseSignal, loadDreamingStore, saveDreamingStore } from "./short-term-store.js";
6
6
  import "./last-run.js";
7
- import fs from "node:fs/promises";
8
7
  import path from "node:path";
8
+ import fs from "node:fs/promises";
9
9
  //#region src/agent/memory/dreaming/light-sweep.ts
10
10
  init_logger();
11
11
  const log = createLogger("Dreaming:Light");
@@ -1,8 +1,8 @@
1
1
  import { MEMORY_MD_FILENAME } from "./constants.js";
2
2
  import { clamp01, compareCandidatesByScore, computeCandidateScore, extractPromotionMarkers, isContaminatedSnippet, isExpiredEntry, readFileLines, resolveDeepDefaults, sliceRange, snippetHash } from "./utils.js";
3
3
  import { loadDreamingStore } from "./short-term-store.js";
4
- import fs from "node:fs/promises";
5
4
  import path from "node:path";
5
+ import fs from "node:fs/promises";
6
6
  //#region src/agent/memory/dreaming/preview.ts
7
7
  async function previewDreamingDeepPromotion(params) {
8
8
  const cfg = resolveDeepDefaults(params.config);
@@ -4,8 +4,8 @@ import { DREAMING_DIR_RELATIVE, DREAMS_MD_FILENAME, MS_PER_DAY } from "./constan
4
4
  import { isoDay } from "./utils.js";
5
5
  import { bumpEntryPhaseSignal, loadDreamingStore, saveDreamingStore } from "./short-term-store.js";
6
6
  import "./last-run.js";
7
- import fs from "node:fs/promises";
8
7
  import path from "node:path";
8
+ import fs from "node:fs/promises";
9
9
  //#region src/agent/memory/dreaming/rem-patterns.ts
10
10
  init_logger();
11
11
  const log = createLogger("Dreaming:REM");
@@ -2,9 +2,9 @@ import { createLogger } from "../../../utils/logger/index.js";
2
2
  import { init_logger } from "../../../utils/logger.js";
3
3
  import { SHORT_TERM_PROMOTION_LOCK_RELATIVE, SHORT_TERM_RECALL_STORE_RELATIVE } from "./constants.js";
4
4
  import { buildEntryKey, clamp01, isoDay, normalizeMemoryPath } from "./utils.js";
5
+ import path from "node:path";
5
6
  import { createHash, randomUUID } from "node:crypto";
6
7
  import fs from "node:fs/promises";
7
- import path from "node:path";
8
8
  //#region src/agent/memory/dreaming/short-term-store.ts
9
9
  init_logger();
10
10
  const log = createLogger("Dreaming:Store");
@@ -1,7 +1,7 @@
1
1
  import { DEFAULT_DEEP_CRON, DIVERSITY_WEIGHT, MS_PER_DAY, REINFORCEMENT_WEIGHT } from "./constants.js";
2
+ import path from "node:path";
2
3
  import { createHash } from "node:crypto";
3
4
  import fs from "node:fs/promises";
4
- import path from "node:path";
5
5
  //#region src/agent/memory/dreaming/utils.ts
6
6
  /** Normalize a workspace-relative memory path: forward slashes, no odd ../ escapes at start. */
7
7
  function normalizeMemoryPath(rel) {
@@ -1,5 +1,5 @@
1
- import { readdir, stat } from "node:fs/promises";
2
1
  import { dirname, join } from "node:path";
2
+ import { readdir, stat } from "node:fs/promises";
3
3
  import { fileURLToPath } from "node:url";
4
4
  //#region src/agent/memory/plugin-discovery.ts
5
5
  async function discoverMemoryPlugins() {
@@ -1,6 +1,6 @@
1
+ import { getAgentDefaultModelRef, init_schema } from "../../config/schema.js";
1
2
  import { createLogger } from "../../utils/logger/index.js";
2
3
  import { init_logger } from "../../utils/logger.js";
3
- import { getAgentDefaultModelRef, init_schema } from "../../config/schema.js";
4
4
  import { getAllModels, getDefaultModelSync, init_providers, resolveModel } from "../../providers/index.js";
5
5
  import { resolveAgentTurnTimeoutMs, runAgentTurnWithTimeout } from "../orchestration/run-agent-turn-with-timeout.js";
6
6
  import { isAssistantTurnAborted, isAssistantTurnFailed, maybeRetryTurnAfterTransientLlmFailure } from "../orchestration/llm-turn-retry.js";
@@ -1,6 +1,6 @@
1
+ import { resolveStateDir } from "../../config/paths-state.js";
1
2
  import { createLogger } from "../../utils/logger/index.js";
2
3
  import { init_logger } from "../../utils/logger.js";
3
- import { resolveStateDir } from "../../config/paths-state.js";
4
4
  import { init_paths } from "../../config/paths.js";
5
5
  import { DEFAULT_USER_FILENAME } from "../context/workspace.js";
6
6
  import { createSkillConfigManager } from "../skills/config.js";
@@ -8,8 +8,8 @@ import { buildTtsSystemPromptHint } from "../../voice/tts/directives.js";
8
8
  import { mergeTtsConfigFromAppConfig } from "../../voice/tts/merge-config.js";
9
9
  import { selectSkillsVisibleInPrompt } from "../skills/format-skills-prompt.js";
10
10
  import { buildSystemPrompt } from "./system-prompt.js";
11
- import { existsSync, readFileSync } from "node:fs";
12
11
  import { join } from "node:path";
12
+ import { existsSync, readFileSync } from "node:fs";
13
13
  //#region src/agent/prompt/service-prompt-builder.ts
14
14
  /**
15
15
  * System Prompt Builder - Builds the complete system prompt
@@ -1,7 +1,7 @@
1
1
  import { init_agent_scope, resolveAgentProfileDir } from "../agent-scope.js";
2
2
  import { resolveEffectiveAgentProfileForSession } from "../../config/agent-profile.js";
3
- import { readFileSync } from "node:fs";
4
3
  import { join, resolve } from "node:path";
4
+ import { readFileSync } from "node:fs";
5
5
  //#region src/agent/reply/post-compaction-context.ts
6
6
  init_agent_scope();
7
7
  const MAX_CONTEXT_CHARS = 1800;
@@ -1,5 +1,5 @@
1
- import { readFileSync } from "node:fs";
2
1
  import { resolve } from "node:path";
2
+ import { readFileSync } from "node:fs";
3
3
  //#region src/agent/reply/workspace-boundary-read.ts
4
4
  /**
5
5
  * Read a file relative to workspace root with path traversal guard and byte cap.
@@ -1,6 +1,6 @@
1
- import { realpathSync } from "node:fs";
2
- import { isAbsolute, normalize, resolve, sep } from "node:path";
3
1
  import { homedir } from "node:os";
2
+ import { isAbsolute, normalize, resolve, sep } from "node:path";
3
+ import { realpathSync } from "node:fs";
4
4
  //#region src/agent/sandbox/path-policy.ts
5
5
  /**
6
6
  * Path safety validation for sandbox isolation.
@@ -1,5 +1,5 @@
1
- import { init_agent_scope, resolveAgentHomeDir, resolveDefaultAgentId } from "../agent-scope.js";
2
1
  import { getAgentDefaultModelRef, init_schema } from "../../config/schema.js";
2
+ import { init_agent_scope, resolveAgentHomeDir, resolveDefaultAgentId } from "../agent-scope.js";
3
3
  import { extractProfileAgentId } from "../../config/agent-profile.js";
4
4
  import { getDefaultModelSync, init_providers } from "../../providers/index.js";
5
5
  import { formatInboundFileTextBlock } from "../../channels/attachments/inbound-persist.js";
@@ -53,6 +53,7 @@ export interface ProcessDirectStreamingDeps {
53
53
  skipPersistentGoalPostTurn: boolean;
54
54
  }) => void;
55
55
  onTurnComplete?: (sessionKey: string, lastAssistantText?: string) => void;
56
+ enqueueProvisionalSessionTitle?: (sessionKey: string, userText: string) => void;
56
57
  /** Disk-only transcript sync (slash receipt already streamed as tokens). */
57
58
  reloadWebchatTranscript?: (sessionKey: string) => void;
58
59
  maybeEmitWebchatTts: (sessionKey: string, hadInboundVoice: boolean) => Promise<{
@@ -139,18 +139,21 @@ async function* runProcessDirectStreaming(deps, input) {
139
139
  content: await deps.buildMessageContent(textForAgent, prepared, sessionKey),
140
140
  timestamp: Date.now()
141
141
  };
142
- if (channel === "webchat") pushVisible({
143
- type: "user_message",
144
- timestamp: userMessage.timestamp,
145
- content: userMessage.content,
146
- attachments: prepared?.map((att) => ({
147
- type: att.type,
148
- mimeType: att.mimeType,
149
- name: att.name,
150
- size: att.size,
151
- workspaceRelativePath: att.workspaceRelativePath
152
- }))
153
- });
142
+ if (channel === "webchat") {
143
+ pushVisible({
144
+ type: "user_message",
145
+ timestamp: userMessage.timestamp,
146
+ content: userMessage.content,
147
+ attachments: prepared?.map((att) => ({
148
+ type: att.type,
149
+ mimeType: att.mimeType,
150
+ name: att.name,
151
+ size: att.size,
152
+ workspaceRelativePath: att.workspaceRelativePath
153
+ }))
154
+ });
155
+ if (textForAgent.trim()) deps.enqueueProvisionalSessionTitle?.(sessionKey, textForAgent);
156
+ }
154
157
  const result = await runDirectAgentTurn({
155
158
  sessionStore: deps.sessionStore,
156
159
  agentManager: deps.agentManager,