@xopcai/xopc 0.0.321 → 0.0.323

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 (281) hide show
  1. package/dist/browser-ext/dist/assets/{auth-DKo-NMUY.js → auth-DocRzRlS.js} +95 -21
  2. package/dist/browser-ext/dist/background.js +1 -1
  3. package/dist/browser-ext/dist/sidepanel.html +1 -1
  4. package/dist/browser-ext/dist/sidepanel.js +18 -2
  5. package/dist/browser-ext/manifest.json +1 -1
  6. package/dist/extensions/telegram/xopc.extension.json +1 -1
  7. package/dist/gateway/static/root/assets/{agent-avatar-dicebear-C69p1Gbr.js → agent-avatar-dicebear-DFzmThVi.js} +1 -1
  8. package/dist/gateway/static/root/assets/agent-defaults-settings-panel-CAFHadiy.js +1 -0
  9. package/dist/gateway/static/root/assets/agent-plugin-dialog-DYFYiuig.js +1 -0
  10. package/dist/gateway/static/root/assets/{agents-CWR3p3t3.js → agents-BqIlB5Co.js} +1 -1
  11. package/dist/gateway/static/root/assets/{app-link-nL8iPwEr.js → app-link-C6gA5Nck.js} +1 -1
  12. package/dist/gateway/static/root/assets/{app-management-settings-panel-D98bt40S.js → app-management-settings-panel-BgvMRGWe.js} +1 -1
  13. package/dist/gateway/static/root/assets/{appearance-settings-ChMUELAZ.js → appearance-settings-CliHU03A.js} +1 -1
  14. package/dist/gateway/static/root/assets/apps-page-Drt3Foi9.js +1 -0
  15. package/dist/gateway/static/root/assets/{archive-plugin-BIIiu6uP.js → archive-plugin-DnuPpm0u.js} +1 -1
  16. package/dist/gateway/static/root/assets/{attachment-load-CDJpcsCp.js → attachment-load-BiwaK0ie.js} +1 -1
  17. package/dist/gateway/static/root/assets/{automations-page-Cb5a_WOk.js → automations-page-CJSISGQH.js} +1 -1
  18. package/dist/gateway/static/root/assets/automations-workspace-B-Eduqwz.js +7 -0
  19. package/dist/gateway/static/root/assets/{binary-plugins-zp55zQPu.js → binary-plugins-KDjduQZO.js} +1 -1
  20. package/dist/gateway/static/root/assets/{block-editor-B0CTIZb-.js → block-editor-bclvgove.js} +3 -3
  21. package/dist/gateway/static/root/assets/{browser-automation-inputs-Bx3W4J4H.js → browser-automation-inputs-CfQ2T9t6.js} +1 -1
  22. package/dist/gateway/static/root/assets/{browser-automations-page-D5Lr9b8a.js → browser-automations-page-Cxq38Nnp.js} +2 -2
  23. package/dist/gateway/static/root/assets/browser-settings-page-Dwgir6mu.js +3 -0
  24. package/dist/gateway/static/root/assets/capabilities-settings-panel-H5L5vynP.js +8 -0
  25. package/dist/gateway/static/root/assets/capabilities-uFKh3Hd0.js +1 -0
  26. package/dist/gateway/static/root/assets/channels-settings-RFBRYe5S.js +1 -0
  27. package/dist/gateway/static/root/assets/{chat-terminal-dock-1I1PdIq0.js → chat-terminal-dock-DKQC62nQ.js} +2 -2
  28. package/dist/gateway/static/root/assets/{computer-settings-page-BT-EfoI6.js → computer-settings-page-D1whpIqL.js} +1 -1
  29. package/dist/gateway/static/root/assets/{connector-service-page-mhQ-19tj.js → connector-service-page-BAuYTgf5.js} +1 -1
  30. package/dist/gateway/static/root/assets/connectors-page-Px-v3Q6Q.js +2 -0
  31. package/dist/gateway/static/root/assets/{date-picker-BqcldZoN.js → date-picker-CfCo3lqh.js} +1 -1
  32. package/dist/gateway/static/root/assets/{dependency-picker-DLDLJx3D.js → dependency-picker-DOuVO2M1.js} +1 -1
  33. package/dist/gateway/static/root/assets/{desktop-pet-kSFeHyrt.js → desktop-pet-D9tu6Bhu.js} +1 -1
  34. package/dist/gateway/static/root/assets/{desktop-pet-settings-BjY7DqD7.js → desktop-pet-settings-CQPXub2f.js} +1 -1
  35. package/dist/gateway/static/root/assets/device-pairing-wizard-DxkOYSut.js +1 -0
  36. package/dist/gateway/static/root/assets/{extension-debug-page-DbWJDT4X.js → extension-debug-page-CtWClPz-.js} +1 -1
  37. package/dist/gateway/static/root/assets/{extension-page-lAC_2xWA.js → extension-page-BHh9HLCz.js} +1 -1
  38. package/dist/gateway/static/root/assets/{extension-settings-page-jFy1NJg9.js → extension-settings-page-BdT3v5Uh.js} +1 -1
  39. package/dist/gateway/static/root/assets/{gateway-config-swr-B7WpH3VW.js → gateway-config-swr-1eqyz9vZ.js} +1 -1
  40. package/dist/gateway/static/root/assets/gateway-settings-CZas_Ekx.js +1 -0
  41. package/dist/gateway/static/root/assets/{gateway-startup-retry-C8F_z865.js → gateway-startup-retry-C4rsW6vJ.js} +1 -1
  42. package/dist/gateway/static/root/assets/home-page-w3_aWeNt.js +1 -0
  43. package/dist/gateway/static/root/assets/{image-generation-api-Dc7d0_7q.js → image-generation-api-B5DXMylk.js} +1 -1
  44. package/dist/gateway/static/root/assets/{imports-page-_fMvJvzM.js → imports-page-B1JH0G5j.js} +1 -1
  45. package/dist/gateway/static/root/assets/index--3c0awkr.js +121 -0
  46. package/dist/gateway/static/root/assets/index-CNc4N4TX.css +1 -0
  47. package/dist/gateway/static/root/assets/{keyboard-shortcuts-settings-CHnZYx1U.js → keyboard-shortcuts-settings-DGrLJ8Yh.js} +1 -1
  48. package/dist/gateway/static/root/assets/local-app-workbench-page-BYKrJpFF.js +1 -0
  49. package/dist/gateway/static/root/assets/local-apps-Bpja8nC6.js +1 -0
  50. package/dist/gateway/static/root/assets/local-apps-page-DqjStqbL.js +1 -0
  51. package/dist/gateway/static/root/assets/{locale-store-D9krC43K.js → locale-store-BIkcRr3t.js} +1 -1
  52. package/dist/gateway/static/root/assets/{logs-page-COxOJsgX.js → logs-page-Dl4kM4Na.js} +2 -2
  53. package/dist/gateway/static/root/assets/management-settings-gCfH4cwH.js +1 -0
  54. package/dist/gateway/static/root/assets/{markdown-view-CurpvCbB.js → markdown-view-Ck_5MADq.js} +1 -1
  55. package/dist/gateway/static/root/assets/{media-plugins-CYldyH6K.js → media-plugins-DTsZqgo6.js} +1 -1
  56. package/dist/gateway/static/root/assets/messages-7VAhscYe.js +3 -0
  57. package/dist/gateway/static/root/assets/note-detail-panel-j6sioeL1.js +5 -0
  58. package/dist/gateway/static/root/assets/notes-page-CMvvHv0f.js +8 -0
  59. package/dist/gateway/static/root/assets/{page-context-capture-button-DZOiI84c.js → page-context-capture-button-DTI_g4tz.js} +1 -1
  60. package/dist/gateway/static/root/assets/{page-tabs-C-XCf9cR.js → page-tabs-CfW_Q-K5.js} +1 -1
  61. package/dist/gateway/static/root/assets/{preview-open-alternatives-CvgeoEU8.js → preview-open-alternatives-CuPN-vAn.js} +1 -1
  62. package/dist/gateway/static/root/assets/product-delivery-bv3z8Xkh.js +1 -0
  63. package/dist/gateway/static/root/assets/product-open-page-BHjxRz1E.js +1 -0
  64. package/dist/gateway/static/root/assets/project-detail-page-C9K_e-EV.js +1 -0
  65. package/dist/gateway/static/root/assets/projects-page-Bk-es4i9.js +1 -0
  66. package/dist/gateway/static/root/assets/{registry-api-cK-g8BDq.js → registry-api-BAAZUGnU.js} +1 -1
  67. package/dist/gateway/static/root/assets/remote-access-hub-CLGJNA42.js +1 -0
  68. package/dist/gateway/static/root/assets/{runtime-tools-settings-panel-DlUodTo-.js → runtime-tools-settings-panel-CHJBJKL1.js} +2 -2
  69. package/dist/gateway/static/root/assets/{scenes-page-DO8vGorm.js → scenes-page-ClLAD1pz.js} +2 -2
  70. package/dist/gateway/static/root/assets/{schema-form-BfboLCeN.js → schema-form-FQAit5HL.js} +1 -1
  71. package/dist/gateway/static/root/assets/sessions-page-Xj8MkXN1.js +1 -0
  72. package/dist/gateway/static/root/assets/settings-advanced-gate-DwALV8mi.js +1 -0
  73. package/dist/gateway/static/root/assets/{settings-form-section-BytEfCGo.js → settings-form-section-BDc6bw1q.js} +1 -1
  74. package/dist/gateway/static/root/assets/{settings-page-Da2ql9KX.js → settings-page-DnhxBJjV.js} +1 -1
  75. package/dist/gateway/static/root/assets/{settings-page-layout-CBfB_7yz.js → settings-page-layout-D3KNSQ5g.js} +1 -1
  76. package/dist/gateway/static/root/assets/{setup-status-panel-DElF2sgq.js → setup-status-panel-F0rCQ-2a.js} +1 -1
  77. package/dist/gateway/static/root/assets/{share-preview-page-B8J0Saj5.js → share-preview-page-DVQCRxwK.js} +1 -1
  78. package/dist/gateway/static/root/assets/shares-settings-C7hf6Cov.js +1 -0
  79. package/dist/gateway/static/root/assets/skill-reload-api-xPrFejRE.js +1 -0
  80. package/dist/gateway/static/root/assets/{skills-page-CNQHhsiv.js → skills-page-RdDYu7Yj.js} +1 -1
  81. package/dist/gateway/static/root/assets/{skills-page.utils-B53tyGx5.js → skills-page.utils-mDwC9UJ-.js} +1 -1
  82. package/dist/gateway/static/root/assets/{system-settings-panel-0HAvlVtR.js → system-settings-panel-Bk7GrMij.js} +1 -1
  83. package/dist/gateway/static/root/assets/task-detail-page-2A966jFY.js +1 -0
  84. package/dist/gateway/static/root/assets/{tunnel-api-DJsxU6q_.js → tunnel-api-D3Aquraj.js} +1 -1
  85. package/dist/gateway/static/root/assets/{use-autosave-eIELzAOD.js → use-autosave-C1xQ-sHn.js} +1 -1
  86. package/dist/gateway/static/root/assets/user-model-page-CnBxPBVe.js +2 -0
  87. package/dist/gateway/static/root/assets/{voice-api-key-field-BJ59ZCAn.js → voice-api-key-field-DCNECvcp.js} +1 -1
  88. package/dist/gateway/static/root/assets/{voice-config-api-DBXZJWLS.js → voice-config-api-B-_niUTU.js} +1 -1
  89. package/dist/gateway/static/root/assets/{work-discovery-overlay-BpSxdIgB.js → work-discovery-overlay-BrGx_JS_.js} +1 -1
  90. package/dist/gateway/static/root/assets/{workflow-run-setup-panel-Bhlv3VUX.js → workflow-run-setup-panel-CmmC2Pdr.js} +2 -2
  91. package/dist/gateway/static/root/assets/workflows-page-BZVpqw4T.js +6 -0
  92. package/dist/gateway/static/root/index.html +12 -11
  93. package/dist/package.js +1 -1
  94. package/dist/packages/gateway-contract/src/capabilities.js +4 -110
  95. package/dist/packages/gateway-contract/src/chat-previews.js +73 -0
  96. package/dist/packages/gateway-contract/src/index.js +6 -0
  97. package/dist/packages/gateway-contract/src/local-apps.js +215 -0
  98. package/dist/packages/gateway-contract/src/product-delivery.js +62 -17
  99. package/dist/packages/gateway-contract/src/user-turn-document.js +60 -0
  100. package/dist/src/agent/agent-manager.d.ts +1 -0
  101. package/dist/src/agent/agent-manager.js +1 -0
  102. package/dist/src/agent/embedded/transcript-runtime.d.ts +3 -0
  103. package/dist/src/agent/embedded/transcript-runtime.js +6 -0
  104. package/dist/src/agent/external-tools/cliProvider.js +4 -1
  105. package/dist/src/agent/external-tools/composio-provider.js +9 -3
  106. package/dist/src/agent/external-tools/gateway-tools.js +17 -10
  107. package/dist/src/agent/external-tools/mcp-provider.d.ts +3 -1
  108. package/dist/src/agent/external-tools/mcp-provider.js +91 -6
  109. package/dist/src/agent/external-tools/service.d.ts +2 -1
  110. package/dist/src/agent/external-tools/service.js +8 -3
  111. package/dist/src/agent/external-tools/types.d.ts +9 -0
  112. package/dist/src/agent/mcp/bundle-mcp-config.js +37 -5
  113. package/dist/src/agent/mcp/bundle-mcp-gateway.d.ts +1 -0
  114. package/dist/src/agent/mcp/bundle-mcp-gateway.js +1 -0
  115. package/dist/src/agent/mcp/bundle-mcp-names.js +2 -1
  116. package/dist/src/agent/mcp/bundle-mcp-runtime.js +33 -1
  117. package/dist/src/agent/mcp/bundle-mcp-types.d.ts +4 -0
  118. package/dist/src/agent/mcp/index.js +1 -1
  119. package/dist/src/agent/mcp/mcp-stdio-transport.d.ts +1 -0
  120. package/dist/src/agent/mcp/mcp-stdio-transport.js +10 -0
  121. package/dist/src/agent/mcp/mcp-transport.js +12 -8
  122. package/dist/src/agent/mcp/oauth/index.js +1 -1
  123. package/dist/src/agent/mcp/oauth/mcp-oauth-manager.d.ts +6 -1
  124. package/dist/src/agent/mcp/oauth/mcp-oauth-manager.js +70 -14
  125. package/dist/src/agent/mcp/oauth/mcp-oauth-provider.js +1 -1
  126. package/dist/src/agent/mcp/oauth/mcp-oauth-session.d.ts +2 -0
  127. package/dist/src/agent/mcp/oauth/mcp-oauth-session.js +12 -0
  128. package/dist/src/agent/mcp/oauth/mcp-oauth-store.d.ts +3 -0
  129. package/dist/src/agent/mcp/oauth/mcp-oauth-store.js +13 -1
  130. package/dist/src/agent/mcp/plugin-http-fetch.d.ts +2 -0
  131. package/dist/src/agent/mcp/plugin-http-fetch.js +56 -0
  132. package/dist/src/agent/service/process-direct-streaming.js +27 -12
  133. package/dist/src/agent/service.js +1 -0
  134. package/dist/src/agent/service.types.d.ts +2 -0
  135. package/dist/src/agent/skills/hub-pull.js +1 -1
  136. package/dist/src/agent/skills/index.js +8 -1
  137. package/dist/src/agent/skills/skill-manager.d.ts +2 -0
  138. package/dist/src/agent/skills/skill-manager.js +8 -0
  139. package/dist/src/agent/skills/skill-sources.js +17 -0
  140. package/dist/src/agent/skills/types.d.ts +3 -1
  141. package/dist/src/agent/source-context/injector.js +10 -5
  142. package/dist/src/agent/source-context/types.d.ts +3 -0
  143. package/dist/src/agent/source-context/types.js +8 -2
  144. package/dist/src/agent/tool-manuals/xopc-use.d.ts +1 -1
  145. package/dist/src/agent/tool-manuals/xopc-use.js +12 -2
  146. package/dist/src/agent/tools/automation-tool.js +1 -1
  147. package/dist/src/agent/tools/factory.d.ts +1 -0
  148. package/dist/src/agent/tools/factory.js +2 -1
  149. package/dist/src/agent/tools/workflow-tool.js +1 -1
  150. package/dist/src/agent/tools/write.js +1 -1
  151. package/dist/src/agent/tools/xopc-use-tool.d.ts +4 -2
  152. package/dist/src/agent/tools/xopc-use-tool.js +120 -12
  153. package/dist/src/chat-previews/index.d.ts +2 -0
  154. package/dist/src/chat-previews/index.js +3 -0
  155. package/dist/src/chat-previews/service.d.ts +27 -0
  156. package/dist/src/chat-previews/service.js +106 -0
  157. package/dist/src/chat-previews/store.d.ts +28 -0
  158. package/dist/src/chat-previews/store.js +77 -0
  159. package/dist/src/cli/commands/doctor/checks/database-schema.js +1 -1
  160. package/dist/src/cli/commands/extension-agent-plugin.d.ts +8 -0
  161. package/dist/src/cli/commands/extension-agent-plugin.js +82 -0
  162. package/dist/src/cli/commands/extension-marketplace.js +44 -4
  163. package/dist/src/cli/commands/extension.js +35 -3
  164. package/dist/src/connectors/account-selection.js +1 -1
  165. package/dist/src/connectors/connection-candidates.d.ts +4 -1
  166. package/dist/src/connectors/connection-candidates.js +8 -2
  167. package/dist/src/connectors/connection-capabilities.d.ts +2 -2
  168. package/dist/src/connectors/connection-capabilities.js +3 -1
  169. package/dist/src/connectors/connection-recovery-service.d.ts +6 -1
  170. package/dist/src/connectors/connection-recovery-service.js +138 -26
  171. package/dist/src/connectors/plugin-mcp-recovery.d.ts +28 -0
  172. package/dist/src/connectors/plugin-mcp-recovery.js +90 -0
  173. package/dist/src/extensions/agent-plugins/auth.d.ts +39 -0
  174. package/dist/src/extensions/agent-plugins/auth.js +156 -0
  175. package/dist/src/extensions/agent-plugins/connection.d.ts +8 -0
  176. package/dist/src/extensions/agent-plugins/connection.js +41 -0
  177. package/dist/src/extensions/agent-plugins/health.d.ts +4 -0
  178. package/dist/src/extensions/agent-plugins/health.js +48 -0
  179. package/dist/src/extensions/agent-plugins/inventory.d.ts +53 -0
  180. package/dist/src/extensions/agent-plugins/inventory.js +34 -0
  181. package/dist/src/extensions/agent-plugins/mcp-adapter.d.ts +3 -0
  182. package/dist/src/extensions/agent-plugins/mcp-adapter.js +47 -0
  183. package/dist/src/extensions/agent-plugins/sources.d.ts +5 -0
  184. package/dist/src/extensions/agent-plugins/sources.js +72 -0
  185. package/dist/src/extensions/agent-plugins/store.d.ts +61 -0
  186. package/dist/src/extensions/agent-plugins/store.js +305 -0
  187. package/dist/src/extensions/agent-plugins/validation.d.ts +59 -0
  188. package/dist/src/extensions/agent-plugins/validation.js +211 -0
  189. package/dist/src/extensions/update.js +1 -1
  190. package/dist/src/gateway/chat-stream/mapper.js +10 -3
  191. package/dist/src/gateway/hono/routes/agent-plugins.d.ts +3 -0
  192. package/dist/src/gateway/hono/routes/agent-plugins.js +166 -0
  193. package/dist/src/gateway/hono/routes/agent-stream.js +14 -0
  194. package/dist/src/gateway/hono/routes/auth-registry-extensions.js +4 -2
  195. package/dist/src/gateway/hono/routes/chat-previews.d.ts +3 -0
  196. package/dist/src/gateway/hono/routes/chat-previews.js +41 -0
  197. package/dist/src/gateway/hono/routes/connection-waits.js +4 -2
  198. package/dist/src/gateway/hono/routes/index.js +2 -0
  199. package/dist/src/gateway/hono/routes/lazy-bundles.js +8 -0
  200. package/dist/src/gateway/hono/routes/local-apps.js +71 -39
  201. package/dist/src/gateway/hono/routes/mcp.js +48 -21
  202. package/dist/src/gateway/hono/routes/session-input-handler.d.ts +4 -0
  203. package/dist/src/gateway/hono/routes/session-input-handler.js +22 -0
  204. package/dist/src/gateway/hono/routes/side-chats.js +11 -0
  205. package/dist/src/gateway/service/agent-runner.js +7 -1
  206. package/dist/src/gateway/service/marketplace-service.d.ts +1 -0
  207. package/dist/src/gateway/service/marketplace-service.js +15 -1
  208. package/dist/src/gateway/service/session-input-coordinator.js +3 -3
  209. package/dist/src/gateway/service.d.ts +5 -1
  210. package/dist/src/gateway/service.js +14 -0
  211. package/dist/src/gateway/side-chat/index.d.ts +3 -1
  212. package/dist/src/gateway/side-chat/index.js +2 -1
  213. package/dist/src/gateway/side-chat/manager.d.ts +16 -0
  214. package/dist/src/gateway/side-chat/manager.js +40 -6
  215. package/dist/src/gateway/side-chat/promotion-service.d.ts +19 -0
  216. package/dist/src/gateway/side-chat/promotion-service.js +111 -0
  217. package/dist/src/gateway/side-chat/run-service.js +1 -0
  218. package/dist/src/gateway/side-chat/types.d.ts +1 -1
  219. package/dist/src/local-apps/artifact-files.d.ts +3 -0
  220. package/dist/src/local-apps/artifact-files.js +45 -0
  221. package/dist/src/local-apps/capabilities/write.js +1 -1
  222. package/dist/src/local-apps/fix-guidance.d.ts +3 -0
  223. package/dist/src/local-apps/fix-guidance.js +75 -0
  224. package/dist/src/local-apps/index.d.ts +2 -1
  225. package/dist/src/local-apps/scaffold.d.ts +5 -0
  226. package/dist/src/local-apps/scaffold.js +18 -5
  227. package/dist/src/local-apps/service.d.ts +18 -3
  228. package/dist/src/local-apps/service.js +106 -64
  229. package/dist/src/local-apps/snapshot-store.d.ts +8 -0
  230. package/dist/src/local-apps/snapshot-store.js +68 -0
  231. package/dist/src/local-apps/types.d.ts +4 -87
  232. package/dist/src/session/client-history.d.ts +3 -1
  233. package/dist/src/session/client-history.js +10 -3
  234. package/dist/src/session/index.d.ts +1 -1
  235. package/dist/src/session/manager.d.ts +4 -0
  236. package/dist/src/session/manager.js +6 -0
  237. package/dist/src/session/session-context-for-llm.d.ts +12 -1
  238. package/dist/src/session/session-context-for-llm.js +16 -2
  239. package/dist/src/session/store.d.ts +14 -0
  240. package/dist/src/session/store.js +17 -0
  241. package/dist/src/session/stored-rows-to-file-entries.js +10 -1
  242. package/dist/src/session/transcript-outline.js +10 -3
  243. package/dist/src/storage/sqlite/connection-wait-repository.js +9 -3
  244. package/dist/src/storage/sqlite/migrations/202_chat_previews.sql +26 -0
  245. package/dist/src/storage/sqlite/migrations/runner.d.ts +1 -1
  246. package/dist/src/storage/sqlite/migrations/runner.js +3 -3
  247. package/dist/src/storage/sqlite/row-mappers.js +6 -1
  248. package/dist/src/storage/sqlite/schema.js +1 -1
  249. package/package.json +3 -3
  250. package/dist/gateway/static/root/assets/agent-defaults-settings-panel-DWLXHWXg.js +0 -1
  251. package/dist/gateway/static/root/assets/api-Df2D6d3C.js +0 -1
  252. package/dist/gateway/static/root/assets/apps-page-BzytHIn1.js +0 -1
  253. package/dist/gateway/static/root/assets/automations-workspace-CtSV8tp-.js +0 -7
  254. package/dist/gateway/static/root/assets/browser-settings-page-DrvNA-G2.js +0 -3
  255. package/dist/gateway/static/root/assets/capabilities-D0S3DuAD.js +0 -1
  256. package/dist/gateway/static/root/assets/capabilities-settings-panel-c0k2virA.js +0 -8
  257. package/dist/gateway/static/root/assets/channels-settings-Bkl9fDHc.js +0 -1
  258. package/dist/gateway/static/root/assets/connectors-page-Dw_h-5Qh.js +0 -2
  259. package/dist/gateway/static/root/assets/device-pairing-wizard-C5f4FRpE.js +0 -1
  260. package/dist/gateway/static/root/assets/gateway-settings-D7XbH6Hk.js +0 -1
  261. package/dist/gateway/static/root/assets/home-page-CFJypY6Y.js +0 -1
  262. package/dist/gateway/static/root/assets/index-B4Vwh0H-.css +0 -1
  263. package/dist/gateway/static/root/assets/index-BNubE2Zi.js +0 -89
  264. package/dist/gateway/static/root/assets/local-app-workbench-page-BLKCFXvr.js +0 -2
  265. package/dist/gateway/static/root/assets/local-apps-page-BNFmOkxs.js +0 -1
  266. package/dist/gateway/static/root/assets/management-settings-BX5NtnQ2.js +0 -1
  267. package/dist/gateway/static/root/assets/messages-B1sTgIrE.js +0 -3
  268. package/dist/gateway/static/root/assets/note-detail-panel-DZ0IWx1R.js +0 -5
  269. package/dist/gateway/static/root/assets/notes-page-B9F1uue_.js +0 -8
  270. package/dist/gateway/static/root/assets/product-delivery-chCjIpvu.js +0 -1
  271. package/dist/gateway/static/root/assets/product-open-page-DEYWx__w.js +0 -1
  272. package/dist/gateway/static/root/assets/project-detail-page-9qMDEKVd.js +0 -1
  273. package/dist/gateway/static/root/assets/projects-page-D4UTOpEm.js +0 -1
  274. package/dist/gateway/static/root/assets/remote-access-hub-CPmOucUB.js +0 -1
  275. package/dist/gateway/static/root/assets/sessions-page-zu5P0dk5.js +0 -1
  276. package/dist/gateway/static/root/assets/settings-advanced-gate-ClEw-i1l.js +0 -1
  277. package/dist/gateway/static/root/assets/shares-settings-MLolJfoV.js +0 -1
  278. package/dist/gateway/static/root/assets/skill-reload-api-DTPsW9TY.js +0 -1
  279. package/dist/gateway/static/root/assets/task-detail-page-Dc30oS9J.js +0 -1
  280. package/dist/gateway/static/root/assets/user-model-page-Bq6ab5WJ.js +0 -2
  281. package/dist/gateway/static/root/assets/workflows-page-Ci-4HAYm.js +0 -6
@@ -98,6 +98,7 @@ export interface AgentManagerConfig {
98
98
  getProjectService?: () => ProjectService | undefined;
99
99
  getWorkDiscovery?: () => import('../work-discovery/service.js').WorkDiscoveryService | undefined;
100
100
  getLocalAppService?: () => import('../local-apps/index.js').LocalAppService | undefined;
101
+ getChatPreviewService?: () => import('../chat-previews/index.js').ChatPreviewService | undefined;
101
102
  dispatchTaskEvents?: () => void;
102
103
  dispatchTaskRuns?: () => void;
103
104
  /** Gateway: starts persisted workflow runs (dedicated chat session per run). */
@@ -270,6 +270,7 @@ var AgentManager = class {
270
270
  getProjectService: this.config.getProjectService,
271
271
  getWorkDiscovery: this.config.getWorkDiscovery,
272
272
  getLocalAppService: this.config.getLocalAppService,
273
+ getChatPreviewService: this.config.getChatPreviewService,
273
274
  dispatchTaskEvents: this.config.dispatchTaskEvents,
274
275
  dispatchTaskRuns: this.config.dispatchTaskRuns,
275
276
  getWorkflowRunService: this.config.getWorkflowRunService,
@@ -3,6 +3,7 @@ import { SessionManager } from '@earendil-works/pi-coding-agent';
3
3
  import type { Api, Model } from '@earendil-works/pi-ai';
4
4
  import { type CompactionExecutionOptions, type CompactionResult } from '../memory/compaction.js';
5
5
  import type { SessionStore } from '../../session/store.js';
6
+ import type { TranscriptSourceEntry } from '../../storage/sqlite/transcript-repository.js';
6
7
  export interface EmbeddedTranscriptRuntime {
7
8
  readonly runtimeId: string;
8
9
  readonly transcriptId: string;
@@ -32,6 +33,8 @@ export declare class InMemoryTranscriptRuntime implements EmbeddedTranscriptRunt
32
33
  loadMessages(): Promise<AgentMessage[]>;
33
34
  captureBaseline(): void;
34
35
  loadConversationMessages(): AgentMessage[];
36
+ loadBaselineMessages(): AgentMessage[];
37
+ loadConversationRows(): TranscriptSourceEntry['row'][];
35
38
  private sourceEntries;
36
39
  compact(_messages: AgentMessage[], model: Model<Api>, instructions?: string, force?: boolean, options?: CompactionExecutionOptions): Promise<CompactionResult>;
37
40
  }
@@ -49,6 +49,12 @@ var InMemoryTranscriptRuntime = class {
49
49
  loadConversationMessages() {
50
50
  return this.sessionManager.getBranch().slice(this.baselineEntryCount).flatMap((entry) => entry.type === "message" ? [entry.message] : []);
51
51
  }
52
+ loadBaselineMessages() {
53
+ return buildSessionContextForLlm(this.sourceEntries().slice(0, this.baselineEntryCount).map((entry) => entry.row));
54
+ }
55
+ loadConversationRows() {
56
+ return structuredClone(this.sourceEntries().slice(this.baselineEntryCount).map((entry) => entry.row));
57
+ }
52
58
  sourceEntries() {
53
59
  return this.sessionManager.getBranch().flatMap((entry, index) => {
54
60
  const compaction = this.compactionRows.get(entry.id);
@@ -202,7 +202,10 @@ var CliToolProvider = class {
202
202
  summary: `Confirm ${action.id}`,
203
203
  needs: [{
204
204
  key: `${item.instance.connectorId}:${connection.accountId}`,
205
- connectorId: item.instance.connectorId,
205
+ target: {
206
+ type: "connector",
207
+ connectorId: item.instance.connectorId
208
+ },
206
209
  accountId: connection.accountId,
207
210
  connectionId: connection.id,
208
211
  label: item.instance.displayName,
@@ -260,7 +260,7 @@ var ComposioToolProvider = class {
260
260
  }).filter((connection) => connection.status === "active" && fresh.some((item) => item.id === connection.id) && canAccessConnectorAccount(connection, resolved.installation, available.agentId)));
261
261
  const boundConnection = available.context ? connectionBinding(available.context.conversationId, resolved.installation.connectorId) : void 0;
262
262
  const requestedAccount = typeof executionArgs[CONNECTION_ARGUMENT] === "string" ? executionArgs[CONNECTION_ARGUMENT] : boundConnection ? getConnectorConnection(boundConnection)?.accountId : void 0;
263
- const bindings = available.context ? connectionBindings(available.context.conversationId).filter((need) => need.connectorId === resolved.installation.connectorId) : [];
263
+ const bindings = available.context ? connectionBindings(available.context.conversationId).filter((need) => need.target.type === "connector" && need.target.connectorId === resolved.installation.connectorId) : [];
264
264
  if (bindings.length > 1 && !requestedAccount) return textResult({
265
265
  status: "account_selection_required",
266
266
  accounts: bindings,
@@ -277,7 +277,10 @@ var ComposioToolProvider = class {
277
277
  summary: `Continue ${action.actionId} using ${toolkit}`,
278
278
  needs: [{
279
279
  key: `${resolved.installation.connectorId}:default`,
280
- connectorId: resolved.installation.connectorId,
280
+ target: {
281
+ type: "connector",
282
+ connectorId: resolved.installation.connectorId
283
+ },
281
284
  accountId: requestedAccount,
282
285
  label: getConnectorDefinition(resolved.installation.connectorId)?.displayName ?? toolkit,
283
286
  capabilities: [action.actionId]
@@ -388,7 +391,10 @@ var ComposioToolProvider = class {
388
391
  summary: `Confirm ${action.actionId}`,
389
392
  needs: [{
390
393
  key: `${resolved.installation.connectorId}:${connection.accountId}`,
391
- connectorId: resolved.installation.connectorId,
394
+ target: {
395
+ type: "connector",
396
+ connectorId: resolved.installation.connectorId
397
+ },
392
398
  accountId: connection.accountId,
393
399
  connectionId: connection.id,
394
400
  label: toolkit,
@@ -2,6 +2,7 @@ import { init_connector_repository, listConnectorConnections } from "../../stora
2
2
  import { connectionBindings, getActiveConnectionWait, init_connection_wait_repository, publishConnectionWait, requireSessionConnection, reviseCurrentConnectionObjective } from "../../storage/sqlite/connection-wait-repository.js";
3
3
  import { connectorPrincipalForSession } from "../../connectors/principal.js";
4
4
  import { connectionCandidates, resolveConnectionCandidate } from "../../connectors/connection-candidates.js";
5
+ import { parsePluginMcpCandidateRef, resolvePluginMcpConnectionCandidate } from "../../extensions/agent-plugins/connection.js";
5
6
  import { ExternalToolService } from "./service.js";
6
7
  import { EXTERNAL_TOOL_SOURCES } from "./types.js";
7
8
  import { Type } from "@sinclair/typebox";
@@ -57,13 +58,15 @@ function createExternalToolGatewayTools(providers, getContext) {
57
58
  async execute(_toolCallId, params) {
58
59
  const selectedSources = new Set(params.sources ?? []);
59
60
  const excludedSources = selectedSources.size ? EXTERNAL_TOOL_SOURCES.filter((source) => !selectedSources.has(source)) : [];
61
+ const result = await service.search(params);
62
+ const candidates = [...result.connectionCandidates, ...connectionCandidates(params.query)].filter((candidate, index, all) => all.findIndex((item) => item.candidateRef === candidate.candidateRef) === index);
60
63
  return textResult({
61
- ...await service.search(params),
64
+ ...result,
65
+ connectionCandidates: candidates,
62
66
  ...excludedSources.length ? { searchScope: {
63
67
  excludedSources,
64
68
  instruction: "This search excluded these sources. Results from other apps do not establish that the requested app is unavailable. Retry without sources before declaring a capability unavailable or requesting authorization. Feishu/Lark, WeCom and WPS 365 connectors use cli."
65
69
  } } : {},
66
- connectionCandidates: connectionCandidates(params.query),
67
70
  selectedConnections: getContext?.()?.conversationId ? connectionBindings(getContext().conversationId) : [],
68
71
  waitingObjective: getContext?.()?.conversationId ? getActiveConnectionWait(getContext().conversationId)?.summary : void 0
69
72
  });
@@ -147,10 +150,13 @@ function createExternalToolGatewayTools(providers, getContext) {
147
150
  const principal = connectorPrincipalForSession(context.conversationId);
148
151
  if (!principal.isLocalOwner) throw new Error("Connection recovery is available in the owner chat.");
149
152
  const selected = connectionBindings(context.conversationId);
150
- if (params.requirements.every((item) => selected.some((need) => need.connectorId === item.candidateRef && need.connectionId && (!item.accountId || item.accountId === need.accountId) && (!item.accountSelector || item.accountSelector === need.accountSelector) && listConnectorConnections({
151
- principalId: principal.principalId,
152
- connectorId: need.connectorId
153
- }).some((connection) => connection.id === need.connectionId && connection.status === "active")))) return textResult({
153
+ if (params.requirements.every((item) => {
154
+ const pluginTarget = parsePluginMcpCandidateRef(item.candidateRef);
155
+ return selected.some((need) => need.target.type === "connector" ? need.target.connectorId === item.candidateRef && Boolean(need.connectionId) && (!item.accountId || item.accountId === need.accountId) && (!item.accountSelector || item.accountSelector === need.accountSelector) && listConnectorConnections({
156
+ principalId: principal.principalId,
157
+ connectorId: need.target.connectorId
158
+ }).some((connection) => connection.id === need.connectionId && connection.status === "active") : Boolean(pluginTarget && need.target.pluginId === pluginTarget.pluginId && need.target.serverName === pluginTarget.serverName && need.connectionId === need.target.serverId));
159
+ })) return textResult({
154
160
  status: "already_connected",
155
161
  selectedConnections: selected,
156
162
  instruction: "These accounts were already checked for this objective. Missing tool contracts are a tool availability problem. Do not request authorization again or invent a revision. Explain the unavailable capability and stop retrying the same tools."
@@ -162,16 +168,17 @@ function createExternalToolGatewayTools(providers, getContext) {
162
168
  summary: params.purpose,
163
169
  checkpoint: params.checkpoint,
164
170
  needs: params.requirements.map((item) => {
165
- const need = resolveConnectionCandidate(item.candidateRef);
166
- if (item.accountId && !listConnectorConnections({
171
+ const need = resolvePluginMcpConnectionCandidate(item.candidateRef) ?? resolveConnectionCandidate(item.candidateRef);
172
+ if (item.accountId && need.target.type !== "connector") throw new Error("Plugin MCP connections do not support account selection.");
173
+ if (item.accountId && need.target.type === "connector" && !listConnectorConnections({
167
174
  principalId: principal.principalId,
168
- connectorId: need.connectorId
175
+ connectorId: need.target.connectorId
169
176
  }).some((connection) => connection.accountId === item.accountId)) throw new Error("Unknown account for this app.");
170
177
  return {
171
178
  ...need,
172
179
  accountId: item.accountId,
173
180
  accountSelector: item.accountSelector,
174
- key: `${need.connectorId}:${item.accountId ?? item.accountSelector ?? "default"}`
181
+ key: need.target.type === "connector" ? `${need.target.connectorId}:${item.accountId ?? item.accountSelector ?? "default"}` : need.key
175
182
  };
176
183
  })
177
184
  });
@@ -2,7 +2,7 @@ import type { AgentToolResult } from '@earendil-works/pi-agent-core';
2
2
  import type { Config } from '../../config/schema.js';
3
3
  import type { ExtensionHookRunner } from '../../extensions/index.js';
4
4
  import type { SessionMcpRuntime } from '../mcp/bundle-mcp-types.js';
5
- import type { ExternalToolDescriptor, ExternalToolExecutionContext, ExternalToolProvider, ExternalToolSearchHit } from './types.js';
5
+ import type { ExternalToolDescriptor, ExternalConnectionCandidate, ExternalToolExecutionContext, ExternalToolProvider, ExternalToolSearchHit } from './types.js';
6
6
  export interface McpToolProviderDeps {
7
7
  workspace: string;
8
8
  getConfig: () => Config | undefined;
@@ -21,8 +21,10 @@ export declare class McpToolProvider implements ExternalToolProvider {
21
21
  readonly source: "mcp";
22
22
  constructor(deps: McpToolProviderDeps);
23
23
  search(_query: string): Promise<ExternalToolSearchHit[]>;
24
+ connectionCandidates(query: string): Promise<ExternalConnectionCandidate[]>;
24
25
  describe(toolRef: string): Promise<ExternalToolDescriptor | undefined>;
25
26
  execute(toolRef: string, args: Record<string, unknown>, _approvalId: string | undefined, context: ExternalToolExecutionContext): Promise<AgentToolResult<Record<string, unknown>>>;
27
+ private requestConnection;
26
28
  private resolve;
27
29
  private isAllowed;
28
30
  private executionSignal;
@@ -1,8 +1,13 @@
1
+ import { init_connection_wait_repository, publishConnectionWait, requireSessionConnection } from "../../storage/sqlite/connection-wait-repository.js";
1
2
  import { resolveEffectiveAgentProfileForSession } from "../../config/agent-profile.js";
3
+ import { connectorPrincipalForSession } from "../../connectors/principal.js";
2
4
  import { externalToolRef, parseExternalToolRef } from "./refs.js";
5
+ import { pluginMcpCandidateRef } from "../../extensions/agent-plugins/connection.js";
3
6
  import { mcpToolPolicyId } from "../mcp/bundle-mcp-policy.js";
7
+ import { isMcpAuthorizationError } from "../mcp/oauth/mcp-oauth-errors.js";
4
8
  import { getOrCreateSessionMcpRuntime } from "../mcp/bundle-mcp-runtime.js";
5
9
  //#region src/agent/external-tools/mcp-provider.ts
10
+ init_connection_wait_repository();
6
11
  function policyToolId(tool) {
7
12
  return mcpToolPolicyId(tool.safeServerName, tool.toolName);
8
13
  }
@@ -25,6 +30,10 @@ function toAgentToolResult(params) {
25
30
  }
26
31
  };
27
32
  }
33
+ function hasAuthorizationChallenge(result) {
34
+ const challenge = result._meta?.["mcp/www_authenticate"];
35
+ return typeof challenge === "string" || Array.isArray(challenge) && challenge.some((value) => typeof value === "string");
36
+ }
28
37
  var McpToolProvider = class {
29
38
  source = "mcp";
30
39
  constructor(deps) {
@@ -41,6 +50,30 @@ var McpToolProvider = class {
41
50
  }));
42
51
  });
43
52
  }
53
+ async connectionCandidates(query) {
54
+ return this.withRuntime(async (runtime) => {
55
+ const catalog = await runtime.getCatalog();
56
+ const normalizedQuery = query.toLocaleLowerCase();
57
+ return Object.values(catalog.servers).flatMap((server) => {
58
+ if (!server.serverName.startsWith("plugin/") || server.error?.code !== "MCP_AUTHORIZATION_REQUIRED") return [];
59
+ const [, encodedPluginId, encodedServerName] = server.serverName.split("/");
60
+ if (!encodedPluginId || !encodedServerName) return [];
61
+ const pluginId = decodeURIComponent(encodedPluginId);
62
+ const serverName = decodeURIComponent(encodedServerName);
63
+ const searchable = `${pluginId} ${serverName}`.toLocaleLowerCase();
64
+ const tokens = normalizedQuery.split(/[^\p{L}\p{N}_-]+/u).filter((token) => token.length > 1);
65
+ if (tokens.length && !tokens.some((token) => searchable.includes(token))) return [];
66
+ return [{
67
+ candidateRef: pluginMcpCandidateRef(pluginId, serverName),
68
+ source: this.source,
69
+ label: pluginId,
70
+ summary: `Connect ${pluginId}/${serverName}`,
71
+ capabilities: [`mcp.tools:${server.serverName}`],
72
+ reason: "not_connected"
73
+ }];
74
+ });
75
+ });
76
+ }
44
77
  async describe(toolRef) {
45
78
  return this.withRuntime(async (runtime) => {
46
79
  const tool = await this.resolve(runtime, toolRef);
@@ -71,13 +104,65 @@ var McpToolProvider = class {
71
104
  if (!hook.allowed) throw new Error(hook.reason ?? "MCP tool call blocked by policy hook.");
72
105
  executionArgs = hook.params ?? args;
73
106
  }
74
- const result = await runtime.callTool(tool.serverName, tool.toolName, executionArgs, this.executionSignal(tool, context.signal));
75
- return toAgentToolResult({
76
- serverName: tool.serverName,
77
- toolName: tool.toolName,
78
- result
79
- });
107
+ try {
108
+ const result = await runtime.callTool(tool.serverName, tool.toolName, executionArgs, this.executionSignal(tool, context.signal));
109
+ if (tool.serverName.startsWith("plugin/") && hasAuthorizationChallenge(result)) return this.requestConnection(tool.serverName, tool.toolName);
110
+ return toAgentToolResult({
111
+ serverName: tool.serverName,
112
+ toolName: tool.toolName,
113
+ result
114
+ });
115
+ } catch (error) {
116
+ if (tool.serverName.startsWith("plugin/") && (isMcpAuthorizationError(error) || error?.code === 401)) return this.requestConnection(tool.serverName, tool.toolName);
117
+ throw error;
118
+ }
119
+ });
120
+ }
121
+ requestConnection(serverId, toolName) {
122
+ const [, encodedPluginId, encodedServerName] = serverId.split("/");
123
+ const conversationId = this.deps.getConversationId();
124
+ if (!encodedPluginId || !encodedServerName || !conversationId) return {
125
+ content: [{
126
+ type: "text",
127
+ text: "This MCP tool requires an account connection in xopc."
128
+ }],
129
+ details: { status: "connection_required" }
130
+ };
131
+ const pluginId = decodeURIComponent(encodedPluginId);
132
+ const serverName = decodeURIComponent(encodedServerName);
133
+ const principal = connectorPrincipalForSession(conversationId);
134
+ if (!principal.isLocalOwner) return {
135
+ content: [{
136
+ type: "text",
137
+ text: "This MCP connection must be completed by the xopc owner."
138
+ }],
139
+ details: { status: "connection_required" }
140
+ };
141
+ const result = requireSessionConnection({
142
+ conversationId,
143
+ principalId: principal.principalId,
144
+ agentId: principal.agentId ?? this.deps.agentId ?? "main",
145
+ summary: `Continue ${toolName} using ${pluginId}`,
146
+ needs: [{
147
+ key: serverId,
148
+ target: {
149
+ type: "plugin-mcp",
150
+ pluginId,
151
+ serverId,
152
+ serverName
153
+ },
154
+ label: pluginId,
155
+ capabilities: [`mcp.tool:${serverId}:${toolName}`]
156
+ }]
80
157
  });
158
+ publishConnectionWait(conversationId);
159
+ return {
160
+ content: [{
161
+ type: "text",
162
+ text: "Account connection required. The objective is preserved in xopc."
163
+ }],
164
+ details: result
165
+ };
81
166
  }
82
167
  async resolve(runtime, toolRef) {
83
168
  const parsed = parseExternalToolRef(toolRef, this.source);
@@ -1,5 +1,5 @@
1
1
  import { searchFailureDetails } from './search-error.js';
2
- import type { ExternalToolExecutionContext, ExternalToolProvider, ExternalToolSearchHit, ExternalToolSource, VersionedExternalToolDescriptor } from './types.js';
2
+ import type { ExternalToolExecutionContext, ExternalConnectionCandidate, ExternalToolProvider, ExternalToolSearchHit, ExternalToolSource, VersionedExternalToolDescriptor } from './types.js';
3
3
  export declare class ExternalToolService {
4
4
  private readonly providerBySource;
5
5
  private readonly ajv;
@@ -10,6 +10,7 @@ export declare class ExternalToolService {
10
10
  limit?: number;
11
11
  }): Promise<{
12
12
  tools: ExternalToolSearchHit[];
13
+ connectionCandidates: ExternalConnectionCandidate[];
13
14
  unavailableSources: ExternalToolSource[];
14
15
  sourceErrors?: Array<ReturnType<typeof searchFailureDetails> & {
15
16
  source: ExternalToolSource;
@@ -52,13 +52,17 @@ var ExternalToolService = class {
52
52
  const selected = params.sources?.length ? params.sources.map((source) => this.providerBySource.get(source)).filter((provider) => provider !== void 0) : [...this.providerBySource.values()];
53
53
  const settled = await Promise.allSettled(selected.map(async (provider) => ({
54
54
  provider,
55
- hits: await provider.search(params.query)
55
+ hits: await provider.search(params.query),
56
+ candidates: await provider.connectionCandidates?.(params.query) ?? []
56
57
  })));
57
58
  const unavailableSources = [];
58
59
  const sourceErrors = [];
59
60
  const hits = [];
60
- for (const [index, result] of settled.entries()) if (result.status === "fulfilled") hits.push(...result.value.hits);
61
- else {
61
+ const connectionCandidates = [];
62
+ for (const [index, result] of settled.entries()) if (result.status === "fulfilled") {
63
+ hits.push(...result.value.hits);
64
+ connectionCandidates.push(...result.value.candidates);
65
+ } else {
62
66
  const provider = selected[index];
63
67
  if (provider) {
64
68
  unavailableSources.push(provider.source);
@@ -87,6 +91,7 @@ var ExternalToolService = class {
87
91
  title: hit.title,
88
92
  summary: hit.summary.slice(0, 300)
89
93
  })),
94
+ connectionCandidates: connectionCandidates.filter((candidate, index, all) => all.findIndex((item) => item.candidateRef === candidate.candidateRef) === index).slice(0, limit),
90
95
  unavailableSources,
91
96
  ...sourceErrors.length ? { sourceErrors } : {}
92
97
  };
@@ -9,6 +9,14 @@ export interface ExternalToolSearchHit {
9
9
  title: string;
10
10
  summary: string;
11
11
  }
12
+ export interface ExternalConnectionCandidate {
13
+ candidateRef: string;
14
+ source: ExternalToolSource;
15
+ label: string;
16
+ summary: string;
17
+ capabilities: string[];
18
+ reason: 'not_connected' | 'reauthorize';
19
+ }
12
20
  export interface ExternalToolDescriptor extends ExternalToolSearchHit {
13
21
  description: string;
14
22
  inputSchema: Record<string, unknown>;
@@ -32,6 +40,7 @@ export interface ExternalToolTurnContext {
32
40
  export interface ExternalToolProvider {
33
41
  readonly source: ExternalToolSource;
34
42
  search(query: string): Promise<ExternalToolSearchHit[]>;
43
+ connectionCandidates?(query: string): Promise<ExternalConnectionCandidate[]>;
35
44
  describe(toolRef: string): Promise<ExternalToolDescriptor | undefined>;
36
45
  execute(toolRef: string, args: Record<string, unknown>, approvalId: string | undefined, context: ExternalToolExecutionContext): Promise<AgentToolResult<Record<string, unknown>>>;
37
46
  }
@@ -1,5 +1,7 @@
1
+ import { AgentPluginStore } from "../../extensions/agent-plugins/store.js";
1
2
  import { normalizeConfiguredMcpServers } from "../../config/mcp-config-normalize.js";
2
3
  import { inspectExtensionConnectorDependencies } from "../../extensions/connector-dependencies.js";
4
+ import { materializePluginServers } from "../../extensions/agent-plugins/mcp-adapter.js";
3
5
  //#region src/agent/mcp/bundle-mcp-config.ts
4
6
  function listConfiguredMcpServers(params) {
5
7
  const configuredMcp = normalizeConfiguredMcpServers(params.cfg?.mcp?.servers);
@@ -11,12 +13,42 @@ function listConfiguredMcpServers(params) {
11
13
  function loadMergedBundleMcpConfig(params) {
12
14
  const mapConfiguredServer = params.mapConfiguredServer ?? ((server) => server);
13
15
  params.workspaceDir;
16
+ const configured = listConfiguredMcpServers({
17
+ cfg: params.cfg,
18
+ mapConfiguredServer
19
+ });
20
+ const diagnostics = inspectExtensionConnectorDependencies({ cfg: params.cfg });
21
+ for (const id of Object.keys(configured)) if (id.startsWith("plugin/")) {
22
+ delete configured[id];
23
+ diagnostics.push({
24
+ extensionId: "",
25
+ connectorId: id,
26
+ message: "Configured MCP cannot use the reserved plugin/ namespace"
27
+ });
28
+ }
29
+ const store = new AgentPluginStore();
30
+ const plugins = Object.create(null);
31
+ for (const plugin of store.active()) try {
32
+ const componentDiagnostics = [...plugin.diagnostics];
33
+ for (const [id, server] of Object.entries(materializePluginServers(plugin, store, componentDiagnostics))) plugins[id] = mapConfiguredServer(server, id);
34
+ diagnostics.push(...componentDiagnostics.map((d) => ({
35
+ extensionId: plugin.id,
36
+ connectorId: d.component,
37
+ message: d.message
38
+ })));
39
+ } catch (error) {
40
+ diagnostics.push({
41
+ extensionId: plugin.id,
42
+ connectorId: "mcp",
43
+ message: error instanceof Error ? error.message : String(error)
44
+ });
45
+ }
14
46
  return {
15
- config: { mcpServers: { ...listConfiguredMcpServers({
16
- cfg: params.cfg,
17
- mapConfiguredServer
18
- }) } },
19
- diagnostics: inspectExtensionConnectorDependencies({ cfg: params.cfg })
47
+ config: { mcpServers: {
48
+ ...configured,
49
+ ...plugins
50
+ } },
51
+ diagnostics
20
52
  };
21
53
  }
22
54
  //#endregion
@@ -29,6 +29,7 @@ export type McpGatewayCapabilitySummary = {
29
29
  tools: McpGatewayToolEntry[];
30
30
  resources: McpGatewayResourceEntry[];
31
31
  prompts: McpGatewayPromptEntry[];
32
+ error?: import('./bundle-mcp-types.js').McpServerCatalog['error'];
32
33
  };
33
34
  export declare function listBundleMcpResourcesForGateway(params: {
34
35
  workspaceDir: string;
@@ -80,6 +80,7 @@ async function listBundleMcpServerCapabilitiesForGateway(params) {
80
80
  const prompts = mapPrompts(catalog.prompts, params.serverId);
81
81
  return {
82
82
  serverId: params.serverId,
83
+ error: catalog.servers[params.serverId]?.error,
83
84
  toolCount: tools.length,
84
85
  resourceCount: resources.length,
85
86
  promptCount: prompts.length,
@@ -1,4 +1,5 @@
1
1
  import { init_string_coerce, normalizeLowercaseStringOrEmpty } from "../../utils/string-coerce.js";
2
+ import { createHash } from "node:crypto";
2
3
  //#region src/agent/mcp/bundle-mcp-names.ts
3
4
  init_string_coerce();
4
5
  const TOOL_NAME_SAFE_RE = /[^A-Za-z0-9_-]/g;
@@ -9,7 +10,7 @@ function sanitizeToolFragment(raw, fallback, maxChars) {
9
10
  return normalized.length > maxChars ? normalized.slice(0, maxChars) : normalized;
10
11
  }
11
12
  function sanitizeServerName(raw, usedNames) {
12
- const base = sanitizeToolFragment(raw, "mcp", TOOL_NAME_MAX_PREFIX);
13
+ const base = raw.startsWith("plugin/") ? `plugin-${createHash("sha256").update(raw).digest("hex").slice(0, 20)}` : sanitizeToolFragment(raw, "mcp", TOOL_NAME_MAX_PREFIX);
13
14
  let candidate = base;
14
15
  let n = 2;
15
16
  while (usedNames.has(normalizeLowercaseStringOrEmpty(candidate))) {
@@ -3,9 +3,11 @@ import { init_logger } from "../../utils/logger.js";
3
3
  import { init_global_singleton, resolveGlobalSingleton } from "../../utils/global-singleton.js";
4
4
  import { init_string_coerce, normalizeOptionalString } from "../../utils/string-coerce.js";
5
5
  import { resolveConnectorSecretReferences } from "../../connectors/secret-store.js";
6
+ import { recordPluginMcpHealth } from "../../extensions/agent-plugins/health.js";
6
7
  import { redactSensitiveUrlLikeString } from "../../utils/redact-sensitive-url.js";
7
8
  import { loadEmbeddedMcpConfig } from "./embedded-mcp.js";
8
9
  import { isMcpConfigRecord } from "./mcp-config-shared.js";
10
+ import { isMcpAuthorizationError } from "./oauth/mcp-oauth-errors.js";
9
11
  import { resolveMcpTransport } from "./mcp-transport.js";
10
12
  import { sanitizeServerName } from "./bundle-mcp-names.js";
11
13
  import crypto from "node:crypto";
@@ -176,7 +178,24 @@ function createSessionMcpRuntime(params) {
176
178
  try {
177
179
  for (const [serverName, rawServer] of Object.entries(loaded.mcpServers)) {
178
180
  failIfDisposed();
179
- const resolved = await resolveMcpTransport(serverName, await resolveConnectorSecretReferences(rawServer), params.cfg);
181
+ let resolved;
182
+ try {
183
+ resolved = await resolveMcpTransport(serverName, await resolveConnectorSecretReferences(rawServer), params.cfg);
184
+ } catch (error) {
185
+ recordPluginMcpHealth(rawServer, "error");
186
+ servers[serverName] = {
187
+ serverName,
188
+ launchSummary: "",
189
+ toolCount: 0,
190
+ resourceCount: 0,
191
+ promptCount: 0,
192
+ error: {
193
+ code: "MCP_CONNECTION_FAILED",
194
+ message: redactErrorUrls(error)
195
+ }
196
+ };
197
+ continue;
198
+ }
180
199
  if (!resolved) continue;
181
200
  const safeServerName = sanitizeServerName(serverName, usedServerNames);
182
201
  if (safeServerName !== serverName) log.warn({
@@ -202,6 +221,7 @@ function createSessionMcpRuntime(params) {
202
221
  await connectWithTimeout(client, resolved.transport, resolved.connectionTimeoutMs);
203
222
  failIfDisposed();
204
223
  const listedTools = await listAllTools(client);
224
+ recordPluginMcpHealth(rawServer, "ready");
205
225
  const listedResources = await listOptionalMcpCapability({
206
226
  serverName,
207
227
  capability: "resources",
@@ -259,6 +279,18 @@ function createSessionMcpRuntime(params) {
259
279
  });
260
280
  }
261
281
  } catch (error) {
282
+ servers[serverName] = {
283
+ serverName,
284
+ launchSummary: resolved.description,
285
+ toolCount: 0,
286
+ resourceCount: 0,
287
+ promptCount: 0,
288
+ error: {
289
+ code: isMcpAuthorizationError(error) || error?.code === 401 ? "MCP_AUTHORIZATION_REQUIRED" : "MCP_CONNECTION_FAILED",
290
+ message: redactErrorUrls(error)
291
+ }
292
+ };
293
+ recordPluginMcpHealth(rawServer, servers[serverName].error?.code === "MCP_AUTHORIZATION_REQUIRED" ? "authorization_required" : "error");
262
294
  if (!disposed) log.warn(`bundle-mcp: failed to start server "${serverName}" (${resolved.description}): ${redactErrorUrls(error)}`);
263
295
  await disposeSession(session);
264
296
  sessions.delete(serverName);
@@ -7,6 +7,10 @@ export type McpServerCatalog = {
7
7
  toolCount: number;
8
8
  resourceCount: number;
9
9
  promptCount: number;
10
+ error?: {
11
+ code: 'MCP_AUTHORIZATION_REQUIRED' | 'MCP_CONNECTION_FAILED';
12
+ message: string;
13
+ };
10
14
  };
11
15
  export type McpCatalogTool = {
12
16
  serverName: string;
@@ -1,8 +1,8 @@
1
1
  import { mcpToolPolicyId } from "./bundle-mcp-policy.js";
2
+ import { McpOAuthStore, canonicalMcpServerUrl, mcpOAuthServerKey } from "./oauth/mcp-oauth-store.js";
2
3
  import { loadMergedBundleMcpConfig } from "./bundle-mcp-config.js";
3
4
  import { loadEmbeddedMcpConfig } from "./embedded-mcp.js";
4
5
  import { McpAuthorizationRequiredError, isMcpAuthorizationError } from "./oauth/mcp-oauth-errors.js";
5
- import { McpOAuthStore, canonicalMcpServerUrl, mcpOAuthServerKey } from "./oauth/mcp-oauth-store.js";
6
6
  import { XopcMcpOAuthClientProvider } from "./oauth/mcp-oauth-provider.js";
7
7
  import { __testing, createSessionMcpRuntime, disposeAllSessionMcpRuntimes, disposeSessionMcpRuntime, getOrCreateSessionMcpRuntime, getSessionMcpRuntimeManager, retireSessionMcpRuntime, retireSessionMcpRuntimeForConversationId } from "./bundle-mcp-runtime.js";
8
8
  import "./bundle-mcp-tools.js";
@@ -6,6 +6,7 @@ export type XopcStdioServerParameters = {
6
6
  env?: Record<string, string>;
7
7
  cwd?: string;
8
8
  stderr?: "pipe" | "overlapped" | "inherit" | "ignore";
9
+ pluginDataDir?: string;
9
10
  };
10
11
  export declare class XopcStdioClientTransport implements Transport {
11
12
  private readonly serverParams;
@@ -1,5 +1,7 @@
1
1
  import { terminateProcess } from "../../process/kill-tree.js";
2
+ import { containedPath } from "../../extensions/agent-plugins/validation.js";
2
3
  import { spawn } from "node:child_process";
4
+ import { mkdir } from "node:fs/promises";
3
5
  import { getDefaultEnvironment } from "@modelcontextprotocol/sdk/client/stdio.js";
4
6
  import process from "node:process";
5
7
  import { PassThrough } from "node:stream";
@@ -24,6 +26,14 @@ var XopcStdioClientTransport = class {
24
26
  }
25
27
  async start() {
26
28
  if (this.process) throw new Error("XopcStdioClientTransport already started; Client.connect() starts transports automatically.");
29
+ if (this.serverParams.pluginDataDir) {
30
+ const data = this.serverParams.pluginDataDir;
31
+ await mkdir(data, {
32
+ recursive: true,
33
+ mode: 448
34
+ });
35
+ if (this.serverParams.cwd) containedPath(this.serverParams.cwd.startsWith(data) ? data : this.serverParams.env?.PLUGIN_ROOT ?? data, this.serverParams.cwd);
36
+ }
27
37
  await new Promise((resolve, reject) => {
28
38
  const baseEnv = {
29
39
  ...getDefaultEnvironment(),