@xopcai/xopc 0.0.369 → 0.0.371

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 (418) hide show
  1. package/README.md +59 -174
  2. package/README.zh-CN.md +59 -174
  3. package/dist/.pnpm/@noble_hashes@1.8.0/node_modules/@noble/hashes/esm/_md.js +131 -0
  4. package/dist/.pnpm/@noble_hashes@1.8.0/node_modules/@noble/hashes/esm/_u64.js +30 -0
  5. package/dist/.pnpm/@noble_hashes@1.8.0/node_modules/@noble/hashes/esm/sha2.js +252 -0
  6. package/dist/.pnpm/@noble_hashes@1.8.0/node_modules/@noble/hashes/esm/sha256.js +16 -0
  7. package/dist/.pnpm/@noble_hashes@1.8.0/node_modules/@noble/hashes/esm/utils.js +66 -0
  8. package/dist/browser-ext/dist/sidepanel.js +21 -1
  9. package/dist/browser-ext/manifest.json +1 -1
  10. package/dist/extensions/telegram/xopc.extension.json +1 -1
  11. package/dist/gateway/static/root/assets/{agent-avatar-dicebear-Stj17S9u.js → agent-avatar-dicebear-C8MqXy6W.js} +1 -1
  12. package/dist/gateway/static/root/assets/agent-defaults-settings-panel-BLaL4law.js +1 -0
  13. package/dist/gateway/static/root/assets/agent-plugin-dialog-BrysdA6F.js +1 -0
  14. package/dist/gateway/static/root/assets/agents-BJRyMNx2.js +66 -0
  15. package/dist/gateway/static/root/assets/{app-management-settings-panel-pJFe6M6c.js → app-management-settings-panel-Bi02swpZ.js} +1 -1
  16. package/dist/gateway/static/root/assets/{appearance-settings-BrxSpBWa.js → appearance-settings-rr0qirDm.js} +1 -1
  17. package/dist/gateway/static/root/assets/{apps-page-DegSl5Lh.js → apps-page-Sz3wl3lV.js} +1 -1
  18. package/dist/gateway/static/root/assets/{automations-page-BZQ_VHjp.js → automations-page-DqdbP0hD.js} +1 -1
  19. package/dist/gateway/static/root/assets/automations-workspace-CxgKlA5d.js +6 -0
  20. package/dist/gateway/static/root/assets/{block-editor-3XjFv3kK.js → block-editor-CfVR1zGa.js} +3 -3
  21. package/dist/gateway/static/root/assets/browser-automations-page-DeYnh3mY.js +3 -0
  22. package/dist/gateway/static/root/assets/{browser-settings-page-ch2_bQF0.js → browser-settings-page-DDZvlGCD.js} +2 -2
  23. package/dist/gateway/static/root/assets/{capabilities-DO-vfNKI.js → capabilities-CY4SiHcP.js} +1 -1
  24. package/dist/gateway/static/root/assets/{capabilities-B48r0DDa.js → capabilities-gjQtMhKu.js} +1 -1
  25. package/dist/gateway/static/root/assets/capabilities-page-Bl6PZqx3.js +2 -0
  26. package/dist/gateway/static/root/assets/{capabilities-settings-panel-NckMsJ5N.js → capabilities-settings-panel-B-MM4LJA.js} +4 -4
  27. package/dist/gateway/static/root/assets/{capability-header-actions-CY8KCO9j.js → capability-header-actions-CAiY7HK1.js} +1 -1
  28. package/dist/gateway/static/root/assets/{channels-CHOS2CGa.js → channels-D1_fDkhu.js} +1 -1
  29. package/dist/gateway/static/root/assets/{chat-terminal-dock-Bwknnb4c.js → chat-terminal-dock-D6slpF2a.js} +2 -2
  30. package/dist/gateway/static/root/assets/{computer-settings-page-B2xeFCSt.js → computer-settings-page-D1n_uQHN.js} +1 -1
  31. package/dist/gateway/static/root/assets/{connector-service-page-C83DnAqK.js → connector-service-page-FvSCyJzn.js} +1 -1
  32. package/dist/gateway/static/root/assets/connectors-page-DroD-gQn.js +1 -0
  33. package/dist/gateway/static/root/assets/copy-text-row-C1gaJwlZ.js +1 -0
  34. package/dist/gateway/static/root/assets/{date-picker-Bq9GR-DU.js → date-picker-Bl-HqvGU.js} +1 -1
  35. package/dist/gateway/static/root/assets/dependency-picker-DY4nU-HL.js +1 -0
  36. package/dist/gateway/static/root/assets/{desktop-pet-BwsbQw8V.js → desktop-pet-_A89B2xw.js} +1 -1
  37. package/dist/gateway/static/root/assets/{desktop-pet-settings-sL9i44pP.js → desktop-pet-settings-BJWkGynu.js} +1 -1
  38. package/dist/gateway/static/root/assets/device-pairing-wizard-DJ_ITvkI.js +1 -0
  39. package/dist/gateway/static/root/assets/{directory-picker-path-field-BFlDmsS5.js → directory-picker-path-field-Bj2Cpmxs.js} +1 -1
  40. package/dist/gateway/static/root/assets/{extension-debug-page-7Z1Tp7-w.js → extension-debug-page-BfAtjhoK.js} +1 -1
  41. package/dist/gateway/static/root/assets/{extension-page-uGqvb8QX.js → extension-page-BFjc1zDp.js} +1 -1
  42. package/dist/gateway/static/root/assets/{extension-provider-xlSyz4Z6.js → extension-provider-Br6LXyIj.js} +1 -1
  43. package/dist/gateway/static/root/assets/{extension-settings-page-CKHgrjOs.js → extension-settings-page-oAwllsMb.js} +1 -1
  44. package/dist/gateway/static/root/assets/{fallback-models-BwQg0G1D.js → fallback-models-KHd6tw_t.js} +1 -1
  45. package/dist/gateway/static/root/assets/gateway-realtime-F6D4A7N5.js +1 -0
  46. package/dist/gateway/static/root/assets/{gateway-settings-BAQnSEMJ.js → gateway-settings-BIyhyiOq.js} +1 -1
  47. package/dist/gateway/static/root/assets/home-page-CEjaIUTF.js +2 -0
  48. package/dist/gateway/static/root/assets/{imports-page-re1_Nh64.js → imports-page-ClFqRiGQ.js} +1 -1
  49. package/dist/gateway/static/root/assets/index-BGBkIIzM.css +1 -0
  50. package/dist/gateway/static/root/assets/index-GBFmI8im.js +106 -0
  51. package/dist/gateway/static/root/assets/{keyboard-shortcuts-settings-B_xja9LN.js → keyboard-shortcuts-settings-Ca9_GJSQ.js} +1 -1
  52. package/dist/gateway/static/root/assets/{local-app-workbench-page-CErdCrPX.js → local-app-workbench-page-BaK9zX1-.js} +1 -1
  53. package/dist/gateway/static/root/assets/{local-apps-page-BPL2RXdK.js → local-apps-page-1CjSftZ3.js} +1 -1
  54. package/dist/gateway/static/root/assets/local-session-drafts-pox8evDV.js +1 -0
  55. package/dist/gateway/static/root/assets/logs-page-6joZBbcx.js +2 -0
  56. package/dist/gateway/static/root/assets/management-settings-Cnubkklb.js +1 -0
  57. package/dist/gateway/static/root/assets/note-detail-panel-B6DHbMzT.js +5 -0
  58. package/dist/gateway/static/root/assets/notes-page-CGZkIKdi.js +8 -0
  59. package/dist/gateway/static/root/assets/{page-context-capture-button-tf77xIz3.js → page-context-capture-button-y3QmhTu2.js} +1 -1
  60. package/dist/gateway/static/root/assets/personal-page-C_roXCJB.js +1 -0
  61. package/dist/gateway/static/root/assets/{product-open-page-Dc3Y-Y7J.js → product-open-page-CSRYWt0f.js} +1 -1
  62. package/dist/gateway/static/root/assets/{product-preview-content-MG_hmVA3.js → product-preview-content-DuOML6gs.js} +1 -1
  63. package/dist/gateway/static/root/assets/project-detail-page-v7xtnvha.js +1 -0
  64. package/dist/gateway/static/root/assets/{projects-page-MllfNLGA.js → projects-page-BuJCBT6n.js} +1 -1
  65. package/dist/gateway/static/root/assets/{remote-access-hub-Bs-C70el.js → remote-access-hub-DpHnyBnG.js} +1 -1
  66. package/dist/gateway/static/root/assets/{runtime-tools-settings-panel-DpJ5jNzR.js → runtime-tools-settings-panel-DTMTL0hy.js} +1 -1
  67. package/dist/gateway/static/root/assets/{scenes-page-Dpxamkw6.js → scenes-page-B0JqO_fM.js} +2 -2
  68. package/dist/gateway/static/root/assets/{schema-form-DUeyQ1zh.js → schema-form-g4z7GH4W.js} +1 -1
  69. package/dist/gateway/static/root/assets/{send-session-input-Dgn4BRk_.js → send-session-input-BW40VHiL.js} +1 -1
  70. package/dist/gateway/static/root/assets/session-manager-BqlvrjPE.js +16 -0
  71. package/dist/gateway/static/root/assets/sessions-page-CftImbH7.js +1 -0
  72. package/dist/gateway/static/root/assets/settings-advanced-gate-BkvbSieZ.js +1 -0
  73. package/dist/gateway/static/root/assets/{settings-page-DouHuBXt.js → settings-page-YD-U8BVw.js} +1 -1
  74. package/dist/gateway/static/root/assets/setup-status-panel-q_X3kxw2.js +1 -0
  75. package/dist/gateway/static/root/assets/{share-link-dialog-DJTabLAM.js → share-link-dialog-HCHM8qnf.js} +1 -1
  76. package/dist/gateway/static/root/assets/{share-preview-page-jw7h4t_B.js → share-preview-page-Ce6FNWt1.js} +1 -1
  77. package/dist/gateway/static/root/assets/shares-settings-KHRg_-03.js +1 -0
  78. package/dist/gateway/static/root/assets/{skill-api-CfyX_0zN.js → skill-api-BpqDMkNB.js} +1 -1
  79. package/dist/gateway/static/root/assets/skills-page-Bnfn51ks.js +2 -0
  80. package/dist/gateway/static/root/assets/{system-settings-panel-DWf256TE.js → system-settings-panel-CncvC2CI.js} +1 -1
  81. package/dist/gateway/static/root/assets/{task-detail-page-DE6N1ZQe.js → task-detail-page-BVJKdnMC.js} +2 -2
  82. package/dist/gateway/static/root/assets/{tunnel-api-BBm9esrY.js → tunnel-api-g7etuoaT.js} +1 -1
  83. package/dist/gateway/static/root/assets/{usage-page-C93x89uW.js → usage-page-Dao1I-5F.js} +1 -1
  84. package/dist/gateway/static/root/assets/{use-composer-attachments-C7Gaaai1.js → use-composer-attachments-DJya1hIL.js} +1 -1
  85. package/dist/gateway/static/root/assets/use-file-preview-expanded-C5ONO7sF.js +2 -0
  86. package/dist/gateway/static/root/assets/user-model-page-jr986ucl.js +2 -0
  87. package/dist/gateway/static/root/assets/{work-discovery-overlay-Bs2MKiTv.js → work-discovery-overlay-CC3mr7tX.js} +1 -1
  88. package/dist/gateway/static/root/assets/{workflow-run-setup-panel-BR_U_snV.js → workflow-run-setup-panel-CqpXZJxs.js} +2 -2
  89. package/dist/gateway/static/root/assets/workflows-page-DOk6tBbK.js +6 -0
  90. package/dist/gateway/static/root/assets/{workspace-api-Si2o3inw.js → workspace-api-WhbMvdBE.js} +2 -2
  91. package/dist/gateway/static/root/index.html +18 -20
  92. package/dist/package.js +1 -1
  93. package/dist/packages/endpoint-tools-client/src/index.js +189 -0
  94. package/dist/packages/endpoint-tools-protocol/src/bridge.js +105 -0
  95. package/dist/packages/endpoint-tools-protocol/src/index.js +95 -2
  96. package/dist/packages/endpoint-tools-protocol/src/location.js +109 -0
  97. package/dist/packages/endpoint-tools-protocol/src/personal.js +149 -0
  98. package/dist/packages/gateway-contract/src/session-input-command.js +30 -5
  99. package/dist/src/agent/agent-manager.js +23 -27
  100. package/dist/src/agent/background-review/run-background-review.js +1 -1
  101. package/dist/src/agent/embedded/codemode-extension.d.ts +7 -0
  102. package/dist/src/agent/embedded/codemode-extension.js +232 -0
  103. package/dist/src/agent/embedded/codemode-output.d.ts +2 -0
  104. package/dist/src/agent/embedded/codemode-output.js +34 -0
  105. package/dist/src/agent/embedded/external-tool-discovery.d.ts +6 -0
  106. package/dist/src/agent/embedded/external-tool-discovery.js +60 -0
  107. package/dist/src/agent/embedded/model-runtime.js +5 -2
  108. package/dist/src/agent/embedded/run-for-session.js +10 -1
  109. package/dist/src/agent/embedded/run-turn.js +10 -3
  110. package/dist/src/agent/embedded/session-runner.d.ts +9 -1
  111. package/dist/src/agent/embedded/session-runner.js +111 -23
  112. package/dist/src/agent/embedded/session-tool-result-guard.d.ts +2 -0
  113. package/dist/src/agent/embedded/session-tool-result-guard.js +17 -0
  114. package/dist/src/agent/embedded/subscribe-session.js +14 -4
  115. package/dist/src/agent/embedded/tool-metadata.d.ts +15 -0
  116. package/dist/src/agent/embedded/tool-metadata.js +38 -0
  117. package/dist/src/agent/embedded/tool-search-extension.d.ts +5 -0
  118. package/dist/src/agent/embedded/tool-search-extension.js +31 -0
  119. package/dist/src/agent/embedded/types.d.ts +7 -0
  120. package/dist/src/agent/embedded/xopc-tools-bridge.js +6 -0
  121. package/dist/src/agent/external-tools/endpoint-provider.d.ts +1 -1
  122. package/dist/src/agent/external-tools/endpoint-provider.js +174 -53
  123. package/dist/src/agent/external-tools/extension-provider.js +8 -1
  124. package/dist/src/agent/external-tools/gateway-tools.d.ts +1 -1
  125. package/dist/src/agent/external-tools/gateway-tools.js +45 -22
  126. package/dist/src/agent/external-tools/index.js +46 -14
  127. package/dist/src/agent/external-tools/memory-provider.js +8 -1
  128. package/dist/src/agent/external-tools/read-policy.js +2 -1
  129. package/dist/src/agent/external-tools/service.d.ts +2 -0
  130. package/dist/src/agent/external-tools/service.js +25 -3
  131. package/dist/src/agent/external-tools/tool-registry.d.ts +14 -0
  132. package/dist/src/agent/external-tools/tool-registry.js +14 -0
  133. package/dist/src/agent/external-tools/types.d.ts +8 -1
  134. package/dist/src/agent/external-tools/types.js +0 -1
  135. package/dist/src/agent/inbound/attachment-pipeline.js +1 -1
  136. package/dist/src/agent/mcp/config.d.ts +18 -0
  137. package/dist/src/agent/mcp/{bundle-mcp-config.js → config.js} +8 -25
  138. package/dist/src/agent/mcp/native-mcp.d.ts +6 -0
  139. package/dist/src/agent/mcp/native-mcp.js +73 -0
  140. package/dist/src/agent/service.js +3 -6
  141. package/dist/src/agent/skills/index.js +1 -1
  142. package/dist/src/agent/skills/installer.js +1 -1
  143. package/dist/src/agent/skills/managed-store.js +1 -1
  144. package/dist/src/agent/skills/skill-manage-ops.js +1 -1
  145. package/dist/src/agent/skills/skill-manager.js +1 -1
  146. package/dist/src/agent/skills/skill-sources.js +1 -1
  147. package/dist/src/agent/source-context/index.d.ts +0 -1
  148. package/dist/src/agent/source-context/index.js +1 -2
  149. package/dist/src/agent/source-context/injector.js +1 -0
  150. package/dist/src/agent/source-context/types.d.ts +2 -2
  151. package/dist/src/agent/source-context/types.js +1 -1
  152. package/dist/src/agent/tools/cli-clarify.js +1 -1
  153. package/dist/src/agent/tools/codemode-permissions.d.ts +4 -0
  154. package/dist/src/agent/tools/codemode-permissions.js +23 -0
  155. package/dist/src/agent/tools/dataBatch.js +3 -1
  156. package/dist/src/agent/tools/delegation-parent-policy.js +1 -4
  157. package/dist/src/agent/tools/factory.js +4 -3
  158. package/dist/src/agent/tools/xopc-use-tool.js +2 -2
  159. package/dist/src/agent/transcript/provider-capabilities.js +0 -1
  160. package/dist/src/agent/transcript/transcript-policy.js +1 -2
  161. package/dist/src/agent-catalog/capabilities.js +2 -2
  162. package/dist/src/agent-catalog/migrations/legacy-config-cutover.js +1 -1
  163. package/dist/src/agent-catalog/repository.js +1 -1
  164. package/dist/src/agent-config/schema.d.ts +28 -0
  165. package/dist/src/agent-config/schema.js +7 -0
  166. package/dist/src/auth/credentials.js +7 -20
  167. package/dist/src/auth/model-credential-store.js +11 -4
  168. package/dist/src/auth/oauth/index.d.ts +1 -1
  169. package/dist/src/auth/oauth/index.js +3 -3
  170. package/dist/src/auth/oauth/openai.d.ts +2 -0
  171. package/dist/src/auth/oauth/openai.js +90 -0
  172. package/dist/src/auth/oauth/registry.js +3 -3
  173. package/dist/src/auth/oauth/types.d.ts +1 -0
  174. package/dist/src/auth/oauth/xopc-cloud.js +1 -1
  175. package/dist/src/auth/sync-provider-auth.js +5 -0
  176. package/dist/src/automations/capabilities/drafts.js +1 -1
  177. package/dist/src/bootstrap/application-state.js +1 -1
  178. package/dist/src/capabilities/runtime/dispatcher.js +1 -1
  179. package/dist/src/capabilities/runtime/product.js +1 -1
  180. package/dist/src/chat-commands/builtins/model.js +2 -2
  181. package/dist/src/cli/command-manifest.js +1 -1
  182. package/dist/src/cli/commands/agents.js +1 -1
  183. package/dist/src/cli/commands/doctor/checks/database-schema.js +1 -1
  184. package/dist/src/cli/commands/doctor/checks/provider-auth.js +1 -1
  185. package/dist/src/cli/commands/extension-agent-plugin.js +0 -19
  186. package/dist/src/cli/commands/mcp.js +36 -2
  187. package/dist/src/cli/commands/models.js +2 -2
  188. package/dist/src/cli/commands/onboard/model.js +2 -2
  189. package/dist/src/cli/utils/init-workspace-core.js +1 -1
  190. package/dist/src/cli/utils/oauth-login.js +2 -2
  191. package/dist/src/config/agent-profile.js +1 -1
  192. package/dist/src/config/index.js +3 -3
  193. package/dist/src/config/mcp-config-normalize.d.ts +0 -3
  194. package/dist/src/config/mcp-config-normalize.js +2 -22
  195. package/dist/src/config/models-json.d.ts +0 -5
  196. package/dist/src/config/models-json.js +13 -4
  197. package/dist/src/config/paths.d.ts +0 -1
  198. package/dist/src/config/paths.js +1 -4
  199. package/dist/src/config/schema.d.ts +130 -36
  200. package/dist/src/config/schema.js +52 -35
  201. package/dist/src/connectors/auth-provider-registry.d.ts +1 -1
  202. package/dist/src/connectors/auth-provider-registry.js +1 -21
  203. package/dist/src/connectors/china-catalog.js +5 -5
  204. package/dist/src/connectors/connection-recovery-service.d.ts +1 -6
  205. package/dist/src/connectors/connection-recovery-service.js +3 -105
  206. package/dist/src/connectors/health.d.ts +1 -2
  207. package/dist/src/connectors/health.js +2 -101
  208. package/dist/src/connectors/types.d.ts +1 -1
  209. package/dist/src/endpoint-tools/binding-service.d.ts +2 -0
  210. package/dist/src/endpoint-tools/binding-service.js +14 -2
  211. package/dist/src/endpoint-tools/bridge-host.d.ts +15 -0
  212. package/dist/src/endpoint-tools/bridge-host.js +166 -0
  213. package/dist/src/endpoint-tools/bridge.d.ts +27 -0
  214. package/dist/src/endpoint-tools/bridge.js +88 -0
  215. package/dist/src/endpoint-tools/capability-catalog.d.ts +2 -0
  216. package/dist/src/endpoint-tools/capability-catalog.js +8 -0
  217. package/dist/src/endpoint-tools/grant-service.d.ts +69 -0
  218. package/dist/src/endpoint-tools/grant-service.js +113 -0
  219. package/dist/src/endpoint-tools/index.js +1 -1
  220. package/dist/src/endpoint-tools/invocation-service.js +21 -4
  221. package/dist/src/endpoint-tools/location-task.d.ts +22 -0
  222. package/dist/src/endpoint-tools/location-task.js +114 -0
  223. package/dist/src/endpoint-tools/policy.js +21 -1
  224. package/dist/src/endpoint-tools/registry.d.ts +2 -0
  225. package/dist/src/endpoint-tools/registry.js +9 -0
  226. package/dist/src/endpoint-tools/result-projector.d.ts +15 -0
  227. package/dist/src/endpoint-tools/result-projector.js +31 -0
  228. package/dist/src/endpoint-tools/runtime.d.ts +2 -0
  229. package/dist/src/endpoint-tools/runtime.js +15 -2
  230. package/dist/src/endpoint-tools/target-resolver.d.ts +12 -0
  231. package/dist/src/endpoint-tools/target-resolver.js +27 -0
  232. package/dist/src/endpoint-tools/turn-context.d.ts +6 -0
  233. package/dist/src/endpoint-tools/turn-context.js +29 -0
  234. package/dist/src/endpoint-tools/upload-service.d.ts +4 -2
  235. package/dist/src/endpoint-tools/upload-service.js +29 -4
  236. package/dist/src/extensions/agent-plugins/auth.d.ts +0 -2
  237. package/dist/src/extensions/agent-plugins/auth.js +2 -19
  238. package/dist/src/extensions/agent-plugins/credentials.js +3 -19
  239. package/dist/src/extensions/agent-plugins/inventory.d.ts +2 -2
  240. package/dist/src/extensions/agent-plugins/mcp-adapter.js +1 -5
  241. package/dist/src/extensions/agent-plugins/source-http-fetch.d.ts +2 -0
  242. package/dist/src/{agent/mcp/plugin-http-fetch.js → extensions/agent-plugins/source-http-fetch.js} +7 -7
  243. package/dist/src/extensions/agent-plugins/sources.js +2 -2
  244. package/dist/src/extensions/agent-plugins/store.js +1 -3
  245. package/dist/src/extensions/agent-plugins/validation.d.ts +0 -4
  246. package/dist/src/extensions/agent-plugins/validation.js +14 -21
  247. package/dist/src/gateway/agents-admin.d.ts +5 -0
  248. package/dist/src/gateway/agents-admin.js +58 -3
  249. package/dist/src/gateway/chat-stream/mapper.js +9 -0
  250. package/dist/src/gateway/chat-stream/protocol.d.ts +4 -4
  251. package/dist/src/gateway/hono/lib/config-payload.d.ts +9 -4
  252. package/dist/src/gateway/hono/lib/config-payload.js +2 -5
  253. package/dist/src/gateway/hono/oauth-async.js +9 -2
  254. package/dist/src/gateway/hono/routes/agent-plugins.js +4 -9
  255. package/dist/src/gateway/hono/routes/agents.js +5 -4
  256. package/dist/src/gateway/hono/routes/config-patch/misc.js +1 -1
  257. package/dist/src/gateway/hono/routes/connection-waits.js +2 -5
  258. package/dist/src/gateway/hono/routes/connectors.js +5 -60
  259. package/dist/src/gateway/hono/routes/device-authorizations.d.ts +3 -0
  260. package/dist/src/gateway/hono/routes/device-authorizations.js +74 -0
  261. package/dist/src/gateway/hono/routes/endpoint-compatibility.js +8 -0
  262. package/dist/src/gateway/hono/routes/endpoint-tools.d.ts +1 -0
  263. package/dist/src/gateway/hono/routes/endpoint-tools.js +70 -3
  264. package/dist/src/gateway/hono/routes/lazy-bundles.js +17 -1
  265. package/dist/src/gateway/hono/routes/mcp.d.ts +1 -1
  266. package/dist/src/gateway/hono/routes/mcp.js +11 -237
  267. package/dist/src/gateway/hono/routes/notes.js +2 -2
  268. package/dist/src/gateway/hono/routes/projects.js +2 -2
  269. package/dist/src/gateway/hono/routes/session-command-handler.js +11 -1
  270. package/dist/src/gateway/hono/routes/session-input-handler.d.ts +8 -2
  271. package/dist/src/gateway/hono/routes/session-input-handler.js +26 -2
  272. package/dist/src/gateway/hono/routes/tasks.js +1 -1
  273. package/dist/src/gateway/image-generation-setup.js +1 -1
  274. package/dist/src/gateway/service/config-coordinator.js +2 -5
  275. package/dist/src/gateway/service/marketplace-service.js +2 -2
  276. package/dist/src/gateway/service/run-gateway-agent.js +13 -5
  277. package/dist/src/gateway/service/session-input-coordinator.d.ts +1 -1
  278. package/dist/src/gateway/service/session-input-coordinator.js +29 -9
  279. package/dist/src/gateway/service/sessions-api.js +0 -6
  280. package/dist/src/gateway/service.js +7 -16
  281. package/dist/src/gateway/session-reset-service.js +0 -6
  282. package/dist/src/gateway/xopc-cloud-capability-setup.js +1 -1
  283. package/dist/src/home-intelligence/host.js +2 -2
  284. package/dist/src/imports/compatibility.js +12 -10
  285. package/dist/src/local-apps/service.js +1 -1
  286. package/dist/src/mcp/channel-bridge.js +1 -1
  287. package/dist/src/notes/agent-context.js +1 -1
  288. package/dist/src/personal-agent/service.js +1 -1
  289. package/dist/src/providers/env-keys.js +1 -1
  290. package/dist/src/providers/index.js +26 -24
  291. package/dist/src/providers/model-call.d.ts +0 -2
  292. package/dist/src/providers/model-call.js +2 -6
  293. package/dist/src/providers/model-registry.js +4 -2
  294. package/dist/src/providers/model-supplements.d.ts +3 -3
  295. package/dist/src/providers/model-supplements.js +6 -27
  296. package/dist/src/providers/presentation.js +3 -8
  297. package/dist/src/providers/prompt-cache-plan.js +1 -1
  298. package/dist/src/providers/provider-auth-service.d.ts +1 -1
  299. package/dist/src/providers/provider-auth-service.js +7 -2
  300. package/dist/src/providers/provider-policy.d.ts +3 -0
  301. package/dist/src/providers/provider-policy.js +14 -0
  302. package/dist/src/providers/register-runtime-providers.js +6 -1
  303. package/dist/src/realtime/runtime.js +1 -1
  304. package/dist/src/session/store.js +7 -1
  305. package/dist/src/session/transcript-events.d.ts +5 -0
  306. package/dist/src/session/transcript-events.js +1 -0
  307. package/dist/src/session/types.d.ts +2 -0
  308. package/dist/src/storage/sqlite/device-grant-audit-repository.d.ts +11 -0
  309. package/dist/src/storage/sqlite/device-grant-audit-repository.js +10 -0
  310. package/dist/src/storage/sqlite/endpoint-device-settings-repository.d.ts +7 -0
  311. package/dist/src/storage/sqlite/endpoint-device-settings-repository.js +17 -0
  312. package/dist/src/storage/sqlite/migrations/240_device_settings.sql +5 -0
  313. package/dist/src/storage/sqlite/migrations/241_device_grant_audit.sql +13 -0
  314. package/dist/src/storage/sqlite/migrations/runner.d.ts +1 -1
  315. package/dist/src/storage/sqlite/migrations/runner.js +3 -3
  316. package/dist/src/storage/sqlite/schema.js +1 -1
  317. package/dist/src/storage/sqlite/session-input-repository.d.ts +1 -0
  318. package/dist/src/storage/sqlite/session-input-repository.js +5 -1
  319. package/dist/src/tasks/capabilities/read.js +2 -2
  320. package/dist/src/tui/backends/embedded-backend.js +1 -1
  321. package/dist/src/tui/backends/gateway-realtime-backend.js +1 -1
  322. package/dist/src/tui/xopc-tui-keybindings.d.ts +4 -4
  323. package/dist/src/voice/realtime/persona-context.js +1 -1
  324. package/package.json +20 -9
  325. package/dist/gateway/static/root/assets/agent-defaults-settings-panel-CCRfvuov.js +0 -1
  326. package/dist/gateway/static/root/assets/agent-plugin-dialog-CRlzd8El.js +0 -1
  327. package/dist/gateway/static/root/assets/agents-_ug2LCQb.js +0 -66
  328. package/dist/gateway/static/root/assets/automations-workspace-BQywN6nG.js +0 -6
  329. package/dist/gateway/static/root/assets/browser-automations-page-yiEuG1v7.js +0 -3
  330. package/dist/gateway/static/root/assets/capabilities-page-BEnFt_dj.js +0 -2
  331. package/dist/gateway/static/root/assets/connectors-page-D6wTmWA6.js +0 -2
  332. package/dist/gateway/static/root/assets/copy-text-row-BHDs3cBa.js +0 -1
  333. package/dist/gateway/static/root/assets/dependency-picker-BTERkA9X.js +0 -1
  334. package/dist/gateway/static/root/assets/device-pairing-wizard-DI2bqaKO.js +0 -1
  335. package/dist/gateway/static/root/assets/dist-Che_jiQF.js +0 -1
  336. package/dist/gateway/static/root/assets/gateway-realtime-DDWymi-o.js +0 -1
  337. package/dist/gateway/static/root/assets/home-page-BZDjvwet.js +0 -2
  338. package/dist/gateway/static/root/assets/index-BB1z8QxA.js +0 -106
  339. package/dist/gateway/static/root/assets/index-D9R6tU7r.css +0 -1
  340. package/dist/gateway/static/root/assets/link-2-D_ZKYUW7.js +0 -1
  341. package/dist/gateway/static/root/assets/local-session-drafts-DRPsDCj1.js +0 -1
  342. package/dist/gateway/static/root/assets/logs-page-DL-BM0xq.js +0 -2
  343. package/dist/gateway/static/root/assets/management-settings-BOVRHhXk.js +0 -1
  344. package/dist/gateway/static/root/assets/note-detail-panel-DJJK2yL4.js +0 -5
  345. package/dist/gateway/static/root/assets/notes-page-oCxO7ZTv.js +0 -8
  346. package/dist/gateway/static/root/assets/personal-page-DOk9gUK5.js +0 -1
  347. package/dist/gateway/static/root/assets/project-detail-page-3uAzbW4T.js +0 -1
  348. package/dist/gateway/static/root/assets/session-manager-LInoZ_Yi.js +0 -16
  349. package/dist/gateway/static/root/assets/sessions-page-BCVlNHtq.js +0 -1
  350. package/dist/gateway/static/root/assets/settings-advanced-gate-Bz-ue9fZ.js +0 -1
  351. package/dist/gateway/static/root/assets/setup-status-panel-B5BoZ-1y.js +0 -1
  352. package/dist/gateway/static/root/assets/shares-settings-BlnlzGjH.js +0 -1
  353. package/dist/gateway/static/root/assets/skills-page-DjdTeYzm.js +0 -2
  354. package/dist/gateway/static/root/assets/use-file-preview-expanded-Db2VYg1b.js +0 -2
  355. package/dist/gateway/static/root/assets/user-model-page-B74LkVbp.js +0 -2
  356. package/dist/gateway/static/root/assets/workflows-page-Crk4SxtC.js +0 -6
  357. package/dist/src/agent/embedded/system-prompt-override.d.ts +0 -2
  358. package/dist/src/agent/embedded/system-prompt-override.js +0 -21
  359. package/dist/src/agent/external-tools/mcp-provider.d.ts +0 -32
  360. package/dist/src/agent/external-tools/mcp-provider.js +0 -208
  361. package/dist/src/agent/mcp/bundle-mcp-config.d.ts +0 -20
  362. package/dist/src/agent/mcp/bundle-mcp-gateway.d.ts +0 -79
  363. package/dist/src/agent/mcp/bundle-mcp-gateway.js +0 -93
  364. package/dist/src/agent/mcp/bundle-mcp-names.d.ts +0 -1
  365. package/dist/src/agent/mcp/bundle-mcp-names.js +0 -25
  366. package/dist/src/agent/mcp/bundle-mcp-policy.d.ts +0 -1
  367. package/dist/src/agent/mcp/bundle-mcp-policy.js +0 -6
  368. package/dist/src/agent/mcp/bundle-mcp-runtime.d.ts +0 -46
  369. package/dist/src/agent/mcp/bundle-mcp-runtime.js +0 -571
  370. package/dist/src/agent/mcp/bundle-mcp-tools.d.ts +0 -2
  371. package/dist/src/agent/mcp/bundle-mcp-tools.js +0 -2
  372. package/dist/src/agent/mcp/bundle-mcp-types.d.ts +0 -76
  373. package/dist/src/agent/mcp/bundle-mcp-types.js +0 -1
  374. package/dist/src/agent/mcp/embedded-mcp.d.ts +0 -10
  375. package/dist/src/agent/mcp/embedded-mcp.js +0 -14
  376. package/dist/src/agent/mcp/index.d.ts +0 -5
  377. package/dist/src/agent/mcp/index.js +0 -12
  378. package/dist/src/agent/mcp/mcp-config-shared.d.ts +0 -8
  379. package/dist/src/agent/mcp/mcp-config-shared.js +0 -39
  380. package/dist/src/agent/mcp/mcp-http.d.ts +0 -23
  381. package/dist/src/agent/mcp/mcp-http.js +0 -67
  382. package/dist/src/agent/mcp/mcp-resource-id.d.ts +0 -6
  383. package/dist/src/agent/mcp/mcp-resource-id.js +0 -19
  384. package/dist/src/agent/mcp/mcp-stdio-transport.d.ts +0 -26
  385. package/dist/src/agent/mcp/mcp-stdio-transport.js +0 -120
  386. package/dist/src/agent/mcp/mcp-stdio.d.ts +0 -18
  387. package/dist/src/agent/mcp/mcp-stdio.js +0 -35
  388. package/dist/src/agent/mcp/mcp-transport-config.d.ts +0 -28
  389. package/dist/src/agent/mcp/mcp-transport-config.js +0 -91
  390. package/dist/src/agent/mcp/mcp-transport.d.ts +0 -17
  391. package/dist/src/agent/mcp/mcp-transport.js +0 -141
  392. package/dist/src/agent/mcp/oauth/index.d.ts +0 -6
  393. package/dist/src/agent/mcp/oauth/index.js +0 -6
  394. package/dist/src/agent/mcp/oauth/mcp-oauth-errors.d.ts +0 -5
  395. package/dist/src/agent/mcp/oauth/mcp-oauth-errors.js +0 -14
  396. package/dist/src/agent/mcp/oauth/mcp-oauth-manager.d.ts +0 -30
  397. package/dist/src/agent/mcp/oauth/mcp-oauth-manager.js +0 -276
  398. package/dist/src/agent/mcp/oauth/mcp-oauth-provider.d.ts +0 -33
  399. package/dist/src/agent/mcp/oauth/mcp-oauth-provider.js +0 -103
  400. package/dist/src/agent/mcp/oauth/mcp-oauth-session.d.ts +0 -31
  401. package/dist/src/agent/mcp/oauth/mcp-oauth-session.js +0 -181
  402. package/dist/src/agent/mcp/oauth/mcp-oauth-store.d.ts +0 -12
  403. package/dist/src/agent/mcp/oauth/mcp-oauth-store.js +0 -91
  404. package/dist/src/agent/mcp/oauth/mcp-oauth-types.d.ts +0 -22
  405. package/dist/src/agent/mcp/oauth/mcp-oauth-types.js +0 -1
  406. package/dist/src/agent/mcp/plugin-http-fetch.d.ts +0 -2
  407. package/dist/src/agent/source-context/mcp-resource-context.d.ts +0 -8
  408. package/dist/src/agent/source-context/mcp-resource-context.js +0 -30
  409. package/dist/src/auth/oauth/openai-codex.d.ts +0 -9
  410. package/dist/src/auth/oauth/openai-codex.js +0 -414
  411. package/dist/src/connectors/plugin-mcp-recovery.d.ts +0 -28
  412. package/dist/src/connectors/plugin-mcp-recovery.js +0 -90
  413. package/dist/src/extensions/agent-plugins/connection.d.ts +0 -8
  414. package/dist/src/extensions/agent-plugins/connection.js +0 -41
  415. package/dist/src/extensions/agent-plugins/health.d.ts +0 -4
  416. package/dist/src/extensions/agent-plugins/health.js +0 -48
  417. package/dist/src/extensions/agent-plugins/plugin-oauth-scope.d.ts +0 -1
  418. package/dist/src/extensions/agent-plugins/plugin-oauth-scope.js +0 -8
@@ -0,0 +1,166 @@
1
+ import { endpointHelloSigningPayload, init_src } from "../../packages/endpoint-tools-protocol/src/index.js";
2
+ import { EndpointToolHostController } from "../../packages/endpoint-tools-client/src/index.js";
3
+ import { RealtimeClient } from "../../packages/realtime-client/src/index.js";
4
+ import { dirname } from "node:path";
5
+ import { generateKeyPairSync, randomUUID, sign } from "node:crypto";
6
+ import { mkdir, readFile, stat, writeFile } from "node:fs/promises";
7
+ import WebSocket from "ws";
8
+ //#region src/endpoint-tools/bridge-host.ts
9
+ init_src();
10
+ async function loadIdentity(path) {
11
+ try {
12
+ const info = await stat(path);
13
+ if (!info.isFile() || process.platform !== "win32" && (info.mode & 63) !== 0) throw new Error("Bridge identity must be a private file (mode 0600)");
14
+ const identity = JSON.parse(await readFile(path, "utf8"));
15
+ if (!identity.principalId || !identity.publicKey || !identity.privateKey) throw new Error("Invalid Bridge identity file");
16
+ return identity;
17
+ } catch (error) {
18
+ if (error.code !== "ENOENT") throw error;
19
+ const pair = generateKeyPairSync("ec", { namedCurve: "prime256v1" });
20
+ const identity = {
21
+ principalId: randomUUID(),
22
+ publicKey: pair.publicKey.export({
23
+ type: "spki",
24
+ format: "der"
25
+ }).toString("base64url"),
26
+ privateKey: pair.privateKey.export({
27
+ type: "pkcs8",
28
+ format: "pem"
29
+ }).toString()
30
+ };
31
+ await mkdir(dirname(path), {
32
+ recursive: true,
33
+ mode: 448
34
+ });
35
+ await writeFile(path, JSON.stringify(identity), {
36
+ mode: 384,
37
+ flag: "wx"
38
+ });
39
+ return identity;
40
+ }
41
+ }
42
+ /** Connects a Node hardware adapter through the existing signed Endpoint v2 transport. */
43
+ async function connectDeviceBridge(options) {
44
+ const url = new URL(options.gatewayUrl);
45
+ if (url.username || url.password || url.search || url.hash || url.pathname !== "/") throw new Error("Use a Gateway origin URL without credentials or path");
46
+ if (url.protocol !== "https:" && !(url.protocol === "http:" && [
47
+ "localhost",
48
+ "127.0.0.1",
49
+ "[::1]"
50
+ ].includes(url.hostname))) throw new Error("Remote Bridge connections require HTTPS");
51
+ const lifetime = new AbortController();
52
+ const request = async (path, body, signal) => {
53
+ const response = await fetch(new URL(path, url), {
54
+ method: body === void 0 ? "GET" : "POST",
55
+ headers: {
56
+ Authorization: `Bearer ${options.token}`,
57
+ "Content-Type": "application/json"
58
+ },
59
+ ...body === void 0 ? {} : { body: JSON.stringify(body) },
60
+ redirect: "error",
61
+ signal: AbortSignal.any([lifetime.signal, signal ?? AbortSignal.timeout(1e4)])
62
+ });
63
+ if (!response.ok) throw new Error(`Bridge Gateway request failed: HTTP ${response.status}`);
64
+ const result = await response.json();
65
+ if (!result.ok) throw new Error("Bridge Gateway request was rejected");
66
+ return result.payload;
67
+ };
68
+ if ((await request("/api/endpoint-tools/compatibility")).hardwareBridgeV1 !== true) throw new Error("Gateway does not support hardwareBridgeV1");
69
+ const identity = await loadIdentity(options.identityPath);
70
+ const endpointId = `${identity.principalId}:bridge`;
71
+ const displayName = options.displayName ?? "xopc Device Bridge";
72
+ if (!displayName.trim() || displayName.length > 80) throw new Error("Bridge name must contain 1–80 characters");
73
+ const register = () => request("/api/endpoint-tools/principals", {
74
+ principalId: identity.principalId,
75
+ publicKey: identity.publicKey,
76
+ kind: "desktop",
77
+ platform: process.platform,
78
+ displayName
79
+ });
80
+ await register();
81
+ const controller = new EndpointToolHostController({
82
+ registry: options.registry,
83
+ getAvailability: () => "background",
84
+ createMessageId: randomUUID,
85
+ confirm: async () => false,
86
+ uploadFile: async () => {
87
+ throw new Error("Bridge sensors cannot upload files");
88
+ }
89
+ });
90
+ const clientId = randomUUID();
91
+ const websocketUrl = new URL("/api/realtime/v1/ws", url);
92
+ websocketUrl.protocol = url.protocol === "https:" ? "wss:" : "ws:";
93
+ const client = new RealtimeClient({
94
+ clientId,
95
+ clientKind: "desktop",
96
+ createMessageId: randomUUID,
97
+ getWebSocketUrl: () => websocketUrl.href,
98
+ issueTicket: (signal) => request("/api/realtime/tickets", {
99
+ clientId,
100
+ clientKind: "desktop",
101
+ protocolVersion: 2
102
+ }, signal),
103
+ createWebSocket: (address) => new WebSocket(address),
104
+ onStateChange: (state) => options.onStateChange?.(state)
105
+ });
106
+ const close = () => {
107
+ lifetime.abort();
108
+ client.disconnect();
109
+ controller.disconnect();
110
+ };
111
+ let resolveReady;
112
+ const ready = new Promise((resolve) => {
113
+ resolveReady = resolve;
114
+ });
115
+ client.setEndpoint({
116
+ createHello: async () => {
117
+ await register();
118
+ const hello = {
119
+ principalId: identity.principalId,
120
+ endpointId,
121
+ connectionInstanceId: randomUUID(),
122
+ displayName,
123
+ kind: "desktop",
124
+ platform: process.platform,
125
+ appVersion: "1",
126
+ availability: "background",
127
+ nonce: randomUUID(),
128
+ signedAt: Date.now(),
129
+ signature: "pending",
130
+ tools: options.registry.descriptors()
131
+ };
132
+ hello.signature = sign("sha256", Buffer.from(endpointHelloSigningPayload(hello)), {
133
+ key: identity.privateKey,
134
+ dsaEncoding: "ieee-p1363"
135
+ }).toString("base64url");
136
+ return hello;
137
+ },
138
+ onReady: () => {
139
+ controller.connect((message) => client.sendEndpointMessage(message));
140
+ resolveReady();
141
+ },
142
+ onMessage: (message) => {
143
+ controller.handleMessage(message);
144
+ },
145
+ onDisconnected: () => controller.disconnect()
146
+ });
147
+ client.connect();
148
+ let timeout;
149
+ try {
150
+ await Promise.race([ready, new Promise((_resolve, reject) => {
151
+ timeout = setTimeout(() => reject(/* @__PURE__ */ new Error("Bridge endpoint did not become ready")), 15e3);
152
+ })]);
153
+ } catch (error) {
154
+ close();
155
+ throw error;
156
+ } finally {
157
+ clearTimeout(timeout);
158
+ }
159
+ return {
160
+ endpointId,
161
+ principalId: identity.principalId,
162
+ close
163
+ };
164
+ }
165
+ //#endregion
166
+ export { connectDeviceBridge };
@@ -0,0 +1,27 @@
1
+ import { EndpointToolRegistry } from '@xopcai/endpoint-tools-client';
2
+ import { z } from 'zod';
3
+ declare const resourceSchema: z.ZodObject<{
4
+ resourceId: z.ZodString;
5
+ name: z.ZodString;
6
+ measurement: z.ZodEnum<{
7
+ temperature: "temperature";
8
+ humidity: "humidity";
9
+ }>;
10
+ unit: z.ZodEnum<{
11
+ celsius: "celsius";
12
+ percent: "percent";
13
+ }>;
14
+ simulated: z.ZodBoolean;
15
+ }, z.core.$strict>;
16
+ export type BridgeResource = z.infer<typeof resourceSchema>;
17
+ export interface BridgeSensorAdapter {
18
+ resource: BridgeResource;
19
+ read(signal: AbortSignal): Promise<{
20
+ value: number | null;
21
+ capturedAt: number;
22
+ }>;
23
+ }
24
+ /** Drivers return one sample; transport, identity, cancellation and policy remain host-owned. */
25
+ export declare function createDeviceBridge(adapters: readonly BridgeSensorAdapter[], now?: () => number): EndpointToolRegistry;
26
+ export declare function simulatedEnvironmentSensors(now?: () => number): BridgeSensorAdapter[];
27
+ export {};
@@ -0,0 +1,88 @@
1
+ import { bridgeDescriptor } from "../../packages/endpoint-tools-protocol/src/bridge.js";
2
+ import { init_src } from "../../packages/endpoint-tools-protocol/src/index.js";
3
+ import { EndpointToolRegistry } from "../../packages/endpoint-tools-client/src/index.js";
4
+ import { z } from "zod";
5
+ //#region src/endpoint-tools/bridge.ts
6
+ init_src();
7
+ const resourceSchema = z.object({
8
+ resourceId: z.string().regex(/^[a-zA-Z0-9._:-]{1,128}$/),
9
+ name: z.string().min(1).max(80),
10
+ measurement: z.enum(["temperature", "humidity"]),
11
+ unit: z.enum(["celsius", "percent"]),
12
+ simulated: z.boolean()
13
+ }).strict().refine((item) => item.unit === (item.measurement === "temperature" ? "celsius" : "percent"), "Unit does not match measurement");
14
+ /** Drivers return one sample; transport, identity, cancellation and policy remain host-owned. */
15
+ function createDeviceBridge(adapters, now = Date.now) {
16
+ if (adapters.length > 100) throw new Error("Bridge supports at most 100 resources");
17
+ const resources = /* @__PURE__ */ new Map();
18
+ for (const adapter of adapters) {
19
+ const resource = resourceSchema.parse(adapter.resource);
20
+ if (resources.has(resource.resourceId)) throw new Error("Duplicate Bridge resource ID");
21
+ resources.set(resource.resourceId, {
22
+ resource,
23
+ read: adapter.read.bind(adapter)
24
+ });
25
+ }
26
+ return new EndpointToolRegistry([{
27
+ descriptor: bridgeDescriptor("list_resources"),
28
+ execute: async (args) => {
29
+ z.object({}).strict().parse(args);
30
+ return { content: [{
31
+ type: "json",
32
+ value: [...resources.values()].map((item) => ({ ...item.resource }))
33
+ }] };
34
+ }
35
+ }, {
36
+ descriptor: bridgeDescriptor("read_sensor"),
37
+ execute: async (args, context) => {
38
+ const { resourceId } = z.object({ resourceId: z.string() }).strict().parse(args);
39
+ const adapter = resources.get(resourceId);
40
+ if (!adapter) throw new TypeError("Unknown Bridge resource");
41
+ context.signal.throwIfAborted();
42
+ const sample = await adapter.read(context.signal);
43
+ context.signal.throwIfAborted();
44
+ const time = now();
45
+ if (!Number.isSafeInteger(sample.capturedAt) || sample.capturedAt > time + 6e4 || sample.capturedAt < time - 3e4) throw new TypeError("Bridge sample has an invalid or stale timestamp");
46
+ const { value } = sample;
47
+ const range = adapter.resource.measurement === "humidity" ? [0, 100] : [-100, 200];
48
+ if (value !== null && (!Number.isFinite(value) || value < range[0] || value > range[1])) throw new TypeError("Invalid Bridge sample value");
49
+ return { content: [{
50
+ type: "json",
51
+ value: {
52
+ ...adapter.resource,
53
+ value,
54
+ capturedAt: sample.capturedAt
55
+ }
56
+ }] };
57
+ }
58
+ }]);
59
+ }
60
+ function simulatedEnvironmentSensors(now = Date.now) {
61
+ return [{
62
+ resource: {
63
+ resourceId: "sim.room.temperature",
64
+ name: "Simulated room temperature",
65
+ measurement: "temperature",
66
+ unit: "celsius",
67
+ simulated: true
68
+ },
69
+ read: async () => ({
70
+ value: 23.5,
71
+ capturedAt: now()
72
+ })
73
+ }, {
74
+ resource: {
75
+ resourceId: "sim.room.humidity",
76
+ name: "Simulated room humidity",
77
+ measurement: "humidity",
78
+ unit: "percent",
79
+ simulated: true
80
+ },
81
+ read: async () => ({
82
+ value: 45,
83
+ capturedAt: now()
84
+ })
85
+ }];
86
+ }
87
+ //#endregion
88
+ export { createDeviceBridge, simulatedEnvironmentSensors };
@@ -0,0 +1,2 @@
1
+ /** Server-owned targeting rules; device descriptors cannot change these defaults. */
2
+ export declare function deviceCapabilityTarget(toolName: string): 'turn_origin' | 'session_bound';
@@ -0,0 +1,8 @@
1
+ //#region src/endpoint-tools/capability-catalog.ts
2
+ /** Server-owned targeting rules; device descriptors cannot change these defaults. */
3
+ function deviceCapabilityTarget(toolName) {
4
+ if (/^(mobile|desktop|web|browser)\.device\./.test(toolName) || /^(mobile|desktop|web)\.(file\.pick|media\.pick|camera\.capture|contacts\.(pick|search|get)|calendar\.query_(events|free_busy))$/.test(toolName) || toolName === "desktop.clipboard.read" || toolName === "web.page.get_selection") return "turn_origin";
5
+ return "session_bound";
6
+ }
7
+ //#endregion
8
+ export { deviceCapabilityTarget };
@@ -0,0 +1,69 @@
1
+ import { type LocationRequest, type TurnOrigin } from '@xopcai/endpoint-tools-protocol';
2
+ import type { DeviceGrantAuditEvent } from '../storage/sqlite/device-grant-audit-repository.js';
3
+ import type { EndpointRegistry } from './registry.js';
4
+ export interface DeviceGrantLease {
5
+ signal: AbortSignal;
6
+ complete: () => void;
7
+ }
8
+ interface DeviceGrant {
9
+ id: string;
10
+ conversationId: string;
11
+ requestorPrincipalId: string;
12
+ targetEndpointId: string;
13
+ targetPrincipalId: string;
14
+ arguments: LocationRequest;
15
+ connectionId: string;
16
+ toolName: string;
17
+ argumentsDigest: string;
18
+ expiresAt: number;
19
+ state: 'ready' | 'running';
20
+ controller: AbortController;
21
+ }
22
+ /** Deliberately non-durable: restart, expiry, disconnect or revoke invalidates single-call consent. */
23
+ export declare class DeviceGrantService {
24
+ private readonly registry;
25
+ private readonly now;
26
+ private readonly audit?;
27
+ private readonly grants;
28
+ constructor(registry: EndpointRegistry, now?: () => number, audit?: (event: DeviceGrantAuditEvent) => void);
29
+ issue(input: {
30
+ conversationId: string;
31
+ requestorPrincipalId: string;
32
+ targetEndpointId: string;
33
+ toolName: string;
34
+ arguments: Record<string, unknown>;
35
+ }): {
36
+ id: string;
37
+ conversationId: string;
38
+ requestorPrincipalId: string;
39
+ targetEndpointId: string;
40
+ targetPrincipalId: string;
41
+ arguments: LocationRequest;
42
+ connectionId: string;
43
+ toolName: string;
44
+ expiresAt: number;
45
+ state: "ready" | "running";
46
+ };
47
+ private requestor;
48
+ candidates(conversationId: string, origin: TurnOrigin): DeviceGrant[];
49
+ find(conversationId: string, origin: TurnOrigin, endpointId: string, toolName: string): DeviceGrant;
50
+ reserve(id: string, args: Record<string, unknown>): DeviceGrantLease;
51
+ list(): {
52
+ id: string;
53
+ conversationId: string;
54
+ requestorPrincipalId: string;
55
+ targetEndpointId: string;
56
+ targetPrincipalId: string;
57
+ arguments: LocationRequest;
58
+ connectionId: string;
59
+ toolName: string;
60
+ expiresAt: number;
61
+ state: "ready" | "running";
62
+ }[];
63
+ revoke(id: string, reason?: 'consumed' | 'revoked' | 'expired'): boolean;
64
+ revokeEndpoint(endpointId: string, principalId?: string): void;
65
+ close(): void;
66
+ private prune;
67
+ private summary;
68
+ }
69
+ export {};
@@ -0,0 +1,113 @@
1
+ import { createLogger } from "../utils/logger/index.js";
2
+ import { init_logger } from "../utils/logger.js";
3
+ import { locationRequestSchema } from "../../packages/endpoint-tools-protocol/src/location.js";
4
+ import { canonicalJson, init_src } from "../../packages/endpoint-tools-protocol/src/index.js";
5
+ import { createHash, randomUUID } from "node:crypto";
6
+ //#region src/endpoint-tools/grant-service.ts
7
+ init_src();
8
+ init_logger();
9
+ const grantLog = createLogger("DeviceGrants");
10
+ const digest = (args) => createHash("sha256").update(canonicalJson(args)).digest("hex");
11
+ /** Deliberately non-durable: restart, expiry, disconnect or revoke invalidates single-call consent. */
12
+ var DeviceGrantService = class {
13
+ grants = /* @__PURE__ */ new Map();
14
+ constructor(registry, now = Date.now, audit) {
15
+ this.registry = registry;
16
+ this.now = now;
17
+ this.audit = audit;
18
+ }
19
+ issue(input) {
20
+ this.prune();
21
+ if (this.grants.size >= 100) throw new Error("Too many outstanding device authorizations");
22
+ const target = this.registry.get(input.targetEndpointId);
23
+ if (!target || target.availability !== "foreground" || !this.registry.list().some((endpoint) => endpoint.principalId === input.requestorPrincipalId)) throw new Error("Device is offline");
24
+ if (!/^(mobile|web|desktop)\.device\.get_location$/.test(input.toolName) || !this.registry.getTool(target.endpointId, input.toolName)) throw new Error("Unsupported device authorization");
25
+ const args = locationRequestSchema.parse(input.arguments);
26
+ for (const grant of this.grants.values()) if (grant.conversationId === input.conversationId && grant.requestorPrincipalId === input.requestorPrincipalId && grant.toolName === input.toolName) this.revoke(grant.id);
27
+ const grant = {
28
+ conversationId: input.conversationId,
29
+ requestorPrincipalId: input.requestorPrincipalId,
30
+ targetEndpointId: input.targetEndpointId,
31
+ toolName: input.toolName,
32
+ arguments: args,
33
+ id: randomUUID(),
34
+ targetPrincipalId: target.principalId,
35
+ connectionId: target.connectionId,
36
+ argumentsDigest: digest(args),
37
+ expiresAt: this.now() + 6e4,
38
+ state: "ready",
39
+ controller: new AbortController()
40
+ };
41
+ this.audit?.({
42
+ ...grant,
43
+ event: "issued"
44
+ });
45
+ this.grants.set(grant.id, grant);
46
+ const timer = setTimeout(() => this.revoke(grant.id, "expired"), 6e4);
47
+ timer.unref();
48
+ grant.controller.signal.addEventListener("abort", () => clearTimeout(timer), { once: true });
49
+ return this.summary(grant);
50
+ }
51
+ requestor(origin) {
52
+ return origin.type === "endpoint" ? this.registry.get(origin.endpointId)?.principalId : void 0;
53
+ }
54
+ candidates(conversationId, origin) {
55
+ this.prune();
56
+ const principal = this.requestor(origin);
57
+ return [...this.grants.values()].filter((grant) => grant.state === "ready" && grant.conversationId === conversationId && grant.requestorPrincipalId === principal);
58
+ }
59
+ find(conversationId, origin, endpointId, toolName) {
60
+ return this.candidates(conversationId, origin).find((grant) => grant.targetEndpointId === endpointId && grant.toolName === toolName);
61
+ }
62
+ reserve(id, args) {
63
+ this.prune();
64
+ const grant = this.grants.get(id);
65
+ if (!grant || grant.state !== "ready" || grant.argumentsDigest !== digest(args)) throw new Error("Device authorization expired, consumed or outside its scope");
66
+ this.audit?.({
67
+ ...grant,
68
+ event: "reserved"
69
+ });
70
+ grant.state = "running";
71
+ return {
72
+ signal: grant.controller.signal,
73
+ complete: () => this.revoke(id, "consumed")
74
+ };
75
+ }
76
+ list() {
77
+ this.prune();
78
+ return [...this.grants.values()].map((grant) => this.summary(grant));
79
+ }
80
+ revoke(id, reason = "revoked") {
81
+ const grant = this.grants.get(id);
82
+ if (!grant) return false;
83
+ this.grants.delete(id);
84
+ grant.controller.abort();
85
+ try {
86
+ this.audit?.({
87
+ ...grant,
88
+ event: reason
89
+ });
90
+ } catch (err) {
91
+ grantLog.error({
92
+ err,
93
+ grantId: id
94
+ }, "Device grant invalidated but audit write failed");
95
+ }
96
+ return true;
97
+ }
98
+ revokeEndpoint(endpointId, principalId = this.registry.get(endpointId)?.principalId) {
99
+ for (const grant of this.grants.values()) if (grant.targetEndpointId === endpointId || grant.requestorPrincipalId === principalId) this.revoke(grant.id);
100
+ }
101
+ close() {
102
+ for (const id of this.grants.keys()) this.revoke(id);
103
+ }
104
+ prune() {
105
+ for (const grant of this.grants.values()) if (grant.expiresAt <= this.now() || this.registry.get(grant.targetEndpointId)?.connectionId !== grant.connectionId || !this.registry.list().some((endpoint) => endpoint.principalId === grant.requestorPrincipalId)) this.revoke(grant.id, grant.expiresAt <= this.now() ? "expired" : "revoked");
106
+ }
107
+ summary(grant) {
108
+ const { controller: _controller, argumentsDigest: _digest, ...summary } = grant;
109
+ return summary;
110
+ }
111
+ };
112
+ //#endregion
113
+ export { DeviceGrantService };
@@ -1,6 +1,6 @@
1
- import { EndpointBindingService } from "./binding-service.js";
2
1
  import { EndpointToolPolicy, EndpointToolPolicyError } from "./policy.js";
3
2
  import { EndpointInvocationService, EndpointToolExecutionError } from "./invocation-service.js";
3
+ import { EndpointBindingService } from "./binding-service.js";
4
4
  import { EndpointRegistry, endpointToolRevision } from "./registry.js";
5
5
  import { ENDPOINT_UPLOAD_MAX_BYTES, EndpointUploadError, EndpointUploadService } from "./upload-service.js";
6
6
  import { EndpointToolRuntime } from "./runtime.js";
@@ -33,6 +33,11 @@ var EndpointInvocationService = class {
33
33
  const tool = this.registry.getTool(params.endpointId, params.toolName);
34
34
  if (!tool) return Promise.reject(this.error("TOOL_NOT_FOUND", "Endpoint tool is unavailable"));
35
35
  if (tool.revision !== params.descriptorRevision) return Promise.reject(this.error("TOOL_REVISION_MISMATCH", "Endpoint tool contract changed"));
36
+ if (!this.ajv.compile(tool.descriptor.inputSchema)(params.arguments)) return Promise.reject(this.error("INVALID_ARGUMENTS", "Invalid endpoint tool arguments"));
37
+ if (params.toolName.startsWith("mobile.calendar.")) {
38
+ const { startAt, endAt } = params.arguments;
39
+ if (typeof startAt !== "number" || typeof endAt !== "number" || endAt <= startAt || endAt - startAt > 7 * 864e5) return Promise.reject(this.error("INVALID_ARGUMENTS", "Calendar range must be positive and at most seven days"));
40
+ }
36
41
  let confirmationRequired;
37
42
  try {
38
43
  confirmationRequired = this.policy.evaluate(tool.descriptor, endpoint.availability).confirmationRequired;
@@ -42,11 +47,12 @@ var EndpointInvocationService = class {
42
47
  }
43
48
  if (params.signal?.aborted) return Promise.reject(this.error("TOOL_CANCELLED", "Endpoint tool call was cancelled"));
44
49
  const endpointPending = [...this.pending.values()].filter((item) => item.endpointId === params.endpointId);
50
+ if (tool.descriptor.sensitivity === "personal" && tool.descriptor.requiresForeground && endpointPending.some((item) => item.descriptor.sensitivity === "personal" && item.descriptor.requiresForeground)) return Promise.reject(this.error("TOOL_BUSY", "A personal device request is already awaiting user participation"));
45
51
  if (endpointPending.length >= 4) return Promise.reject(this.error("TOOL_BUSY", "Endpoint has reached its invocation limit"));
46
52
  if (endpointPending.filter((item) => item.toolName === params.toolName).length >= tool.descriptor.maxConcurrency) return Promise.reject(this.error("TOOL_BUSY", "Endpoint tool has reached its invocation limit"));
47
53
  const invocationId = crypto.randomUUID();
48
54
  const startedAt = Date.now();
49
- const uploadGrant = tool.descriptor.resultKinds.includes("file") ? this.options.uploads?.createGrant(invocationId, params.endpointId, startedAt, params.toolName === "desktop.computer.control" ? "computer-frame" : "durable") : void 0;
55
+ const uploadGrant = tool.descriptor.resultKinds.includes("file") ? this.options.uploads?.createGrant(invocationId, params.endpointId, startedAt, params.toolName === "desktop.computer.control" ? "computer-frame" : params.toolName.startsWith("mobile.") ? "personal" : "durable", endpoint.principalId) : void 0;
50
56
  try {
51
57
  this.options.audit?.started({
52
58
  id: invocationId,
@@ -69,6 +75,7 @@ var EndpointInvocationService = class {
69
75
  endpointId: params.endpointId,
70
76
  toolName: params.toolName,
71
77
  descriptor: tool.descriptor,
78
+ arguments: params.arguments,
72
79
  state: "sent",
73
80
  receiptTimer: setTimeout(() => {
74
81
  this.fail(invocationId, this.error("TOOL_TIMEOUT", "Endpoint did not receive the invocation"));
@@ -113,6 +120,7 @@ var EndpointInvocationService = class {
113
120
  clearTimeout(pending.receiptTimer);
114
121
  return;
115
122
  case "tool.progress":
123
+ if (pending.descriptor.sensitivity === "personal" && pending.descriptor.effect === "read") return;
116
124
  if (pending.state !== "running") return;
117
125
  pending.onProgress?.({
118
126
  ...message.payload.message === void 0 ? {} : { message: message.payload.message },
@@ -124,18 +132,27 @@ var EndpointInvocationService = class {
124
132
  try {
125
133
  const validate = this.ajv.compile(pending.descriptor.outputSchema);
126
134
  if (!validate(message.payload.content)) throw new Error(`Endpoint result does not match its contract: ${this.ajv.errorsText(validate.errors)}`);
135
+ const reading = message.payload.content[0];
136
+ if (pending.toolName.startsWith("mobile.calendar.") && reading?.type === "json") {
137
+ const value = reading.value;
138
+ if (value.startAt !== pending.arguments.startAt || value.endAt !== pending.arguments.endAt || value.events.some((event) => event.endAt <= event.startAt || event.endAt <= value.startAt || event.startAt >= value.endAt) || pending.toolName.endsWith("free_busy") && value.events.some((event) => event.title !== void 0)) throw new Error("Calendar result exceeded the approved scope");
139
+ }
140
+ if (pending.toolName === "mobile.contacts.pick" && reading?.type === "json" && pending.arguments.field) {
141
+ const value = reading.value;
142
+ if (pending.arguments.field === "phone" && (value.phones.length > 1 || value.emails.length) || pending.arguments.field === "email" && (value.emails.length > 1 || value.phones.length)) throw new Error("Contact result exceeded the selected field");
143
+ }
127
144
  this.options.uploads?.validateAndClose(invocationId, message.payload.content);
128
145
  } catch (error) {
129
- this.fail(invocationId, this.error("PROTOCOL_ERROR", error instanceof Error ? error.message : String(error)));
146
+ this.fail(invocationId, this.error("PROTOCOL_ERROR", pending.descriptor.sensitivity === "personal" && pending.descriptor.effect === "read" ? "Invalid personal device result" : error instanceof Error ? error.message : String(error)));
130
147
  return;
131
148
  }
132
149
  this.succeed(invocationId, {
133
150
  content: message.payload.content,
134
- ...message.payload.details === void 0 ? {} : { details: message.payload.details }
151
+ ...message.payload.details === void 0 || pending.descriptor.sensitivity === "personal" && pending.descriptor.effect === "read" ? {} : { details: message.payload.details }
135
152
  });
136
153
  return;
137
154
  case "tool.error":
138
- this.fail(invocationId, this.error(message.payload.code, message.payload.message));
155
+ this.fail(invocationId, this.error(message.payload.code, pending.descriptor.sensitivity === "personal" && pending.descriptor.effect === "read" ? `Personal device request failed: ${message.payload.code}` : message.payload.message));
139
156
  return;
140
157
  case "tool.cancelled": this.fail(invocationId, this.error("TOOL_CANCELLED", "Endpoint cancelled the tool call"));
141
158
  }
@@ -0,0 +1,22 @@
1
+ import { type EndpointToolContent } from '@xopcai/endpoint-tools-protocol';
2
+ /** Sensitive samples never leave this processor as model, stream or persistence content. */
3
+ export declare function processLocationTask(args: Record<string, unknown>, content: EndpointToolContent[], source: {
4
+ endpointId: string;
5
+ principalId: string;
6
+ }, signal?: AbortSignal, request?: typeof fetch, now?: () => number): Promise<{
7
+ version: number;
8
+ source: {
9
+ endpointId: string;
10
+ principalId: string;
11
+ };
12
+ capturedAt: number;
13
+ receivedAt: number;
14
+ validUntil: number;
15
+ cached: boolean;
16
+ retention: string;
17
+ purpose: "weather" | "nearby";
18
+ precision: string;
19
+ accuracyMeters: number;
20
+ status: string;
21
+ data: Record<string, unknown>;
22
+ }>;