@xopcai/xopc 0.0.421 → 0.0.422

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 (279) hide show
  1. package/dist/browser-ext/dist/background.js +184 -2
  2. package/dist/browser-ext/dist/sidepanel.js +9 -0
  3. package/dist/browser-ext/manifest.json +1 -1
  4. package/dist/extensions/telegram/xopc.extension.json +1 -1
  5. package/dist/gateway/static/root/assets/{activity-store-CKrylgib.js → activity-store-CvJ9rdwP.js} +1 -1
  6. package/dist/gateway/static/root/assets/{agent-avatar-dicebear-Dv5Rda4y.js → agent-avatar-dicebear-CFP6g4w7.js} +1 -1
  7. package/dist/gateway/static/root/assets/{agent-avatar-display-B1ycycx2.js → agent-avatar-display-BHBe88Gu.js} +2 -2
  8. package/dist/gateway/static/root/assets/{agent-defaults-settings-panel-D285zy0S.js → agent-defaults-settings-panel-DlGRuKMv.js} +1 -1
  9. package/dist/gateway/static/root/assets/{agent-plugin-dialog-D3yCqVan.js → agent-plugin-dialog-C_Dm-u6_.js} +1 -1
  10. package/dist/gateway/static/root/assets/{agents-DyAuR3rG.js → agents-BdVJHOiK.js} +3 -3
  11. package/dist/gateway/static/root/assets/{agents-admin-api-CASGzvkW.js → agents-admin-api-Do1Pza0R.js} +1 -1
  12. package/dist/gateway/static/root/assets/{api-Uk05lF9i.js → api-BQv5dLcH.js} +1 -1
  13. package/dist/gateway/static/root/assets/{api-C4LxuNzq.js → api-ONg37_fH.js} +1 -1
  14. package/dist/gateway/static/root/assets/app-link-1j40sJ-z.js +1 -0
  15. package/dist/gateway/static/root/assets/{app-management-settings-panel-CDnZNKHt.js → app-management-settings-panel-B4Wqhf4J.js} +1 -1
  16. package/dist/gateway/static/root/assets/{appearance-settings-CmCF7PZ5.js → appearance-settings-Dm1kRzKL.js} +1 -1
  17. package/dist/gateway/static/root/assets/{apps-page-BR9qoA2P.js → apps-page-D1MMk1P7.js} +1 -1
  18. package/dist/gateway/static/root/assets/{archive-plugin-nuHYYVty.js → archive-plugin-p_yLkyaC.js} +1 -1
  19. package/dist/gateway/static/root/assets/{automation-api-DtJfd1QM.js → automation-api-DQaWBR03.js} +1 -1
  20. package/dist/gateway/static/root/assets/automation-result-state-CO_243JM.js +1 -0
  21. package/dist/gateway/static/root/assets/automation-task-card-D2p9qlYE.js +3 -0
  22. package/dist/gateway/static/root/assets/{automations-page-DM4IdUJh.js → automations-page-Ba64H37d.js} +1 -1
  23. package/dist/gateway/static/root/assets/automations-workspace-BkzC3oIM.js +9 -0
  24. package/dist/gateway/static/root/assets/{binary-plugins-CHCAr8jt.js → binary-plugins-B-6kyqtt.js} +1 -1
  25. package/dist/gateway/static/root/assets/{block-editor-B0v8KxsO.js → block-editor-B5ysJ96n.js} +1 -1
  26. package/dist/gateway/static/root/assets/{browser-automation-inputs-DjUW7PEB.js → browser-automation-inputs-C2A3NIt3.js} +1 -1
  27. package/dist/gateway/static/root/assets/{browser-automations-page-Cf8AoQz1.js → browser-automations-page-CnbXFw1_.js} +1 -1
  28. package/dist/gateway/static/root/assets/{browser-control-api-C6NZgaA1.js → browser-control-api-Aj_seKE9.js} +1 -1
  29. package/dist/gateway/static/root/assets/{browser-settings-page-DV2FNEDf.js → browser-settings-page-C7fxPq_z.js} +1 -1
  30. package/dist/gateway/static/root/assets/{capabilities-CwdjWz2r.js → capabilities-BgtCwC_E.js} +1 -1
  31. package/dist/gateway/static/root/assets/{capabilities-D0-HCZ5J.js → capabilities-DOTgaSgA.js} +1 -1
  32. package/dist/gateway/static/root/assets/{capabilities-page-DwDkritH.js → capabilities-page-m3b9sLFG.js} +2 -2
  33. package/dist/gateway/static/root/assets/{capabilities-settings-panel-mme16Fbp.js → capabilities-settings-panel-pYWZtPeU.js} +3 -3
  34. package/dist/gateway/static/root/assets/{channels-lKFLu8p-.js → channels-DGpRM6pj.js} +1 -1
  35. package/dist/gateway/static/root/assets/{chat-agents-api-l80cvSac.js → chat-agents-api-EvJ_Wvuc.js} +1 -1
  36. package/dist/gateway/static/root/assets/{chat-chart-block-BwP5QXEk.js → chat-chart-block-BQDbHLcw.js} +1 -1
  37. package/dist/gateway/static/root/assets/chat-page-GF9NIuZN.js +72 -0
  38. package/dist/gateway/static/root/assets/{chat-terminal-dock-D2bV9YUL.js → chat-terminal-dock-DHFTGoEp.js} +2 -2
  39. package/dist/gateway/static/root/assets/{command-palette-api-CtapG8ck.js → command-palette-api-DPA_yEuy.js} +1 -1
  40. package/dist/gateway/static/root/assets/{composer-payload-handoff-DYuhKZRC.js → composer-payload-handoff-BTjauSNp.js} +1 -1
  41. package/dist/gateway/static/root/assets/{computer-settings-page-DZtMuihL.js → computer-settings-page-BFSSQfcx.js} +1 -1
  42. package/dist/gateway/static/root/assets/{connected-providers-grid-BQH5k3iC.js → connected-providers-grid-DM2glQN3.js} +1 -1
  43. package/dist/gateway/static/root/assets/{connector-service-page-DrvFdP3G.js → connector-service-page-CFvg58qa.js} +1 -1
  44. package/dist/gateway/static/root/assets/{connectors-api-BzkgVBYC.js → connectors-api-CbC6Yht5.js} +1 -1
  45. package/dist/gateway/static/root/assets/{connectors-page-BtRNVCFy.js → connectors-page-D7pipFHA.js} +1 -1
  46. package/dist/gateway/static/root/assets/date-picker-Dd3MbG0x.js +1 -0
  47. package/dist/gateway/static/root/assets/{dependency-picker-Dh8hPmsT.js → dependency-picker-DcsHg2ml.js} +1 -1
  48. package/dist/gateway/static/root/assets/{desktop-pet-CFz8bqyI.js → desktop-pet-DldzQT2h.js} +1 -1
  49. package/dist/gateway/static/root/assets/{desktop-pet-settings-COaboNn1.js → desktop-pet-settings-CYdI4KxB.js} +1 -1
  50. package/dist/gateway/static/root/assets/{dev-view-store-D8XYHVqG.js → dev-view-store-JiJv585f.js} +1 -1
  51. package/dist/gateway/static/root/assets/device-pairing-wizard-D8cLc41G.js +1 -0
  52. package/dist/gateway/static/root/assets/{directory-picker-path-field-Cjv7rdo3.js → directory-picker-path-field-8WOXv8zw.js} +1 -1
  53. package/dist/gateway/static/root/assets/{discussion-annotation-sync-YvlVw17j.js → discussion-annotation-sync-B-grSe0w.js} +1 -1
  54. package/dist/gateway/static/root/assets/{extension-debug-page-CXx3m5-B.js → extension-debug-page-EEQkTNEu.js} +1 -1
  55. package/dist/gateway/static/root/assets/{extension-iframe-host-CnOdNwbo.js → extension-iframe-host-vlZVeMCY.js} +1 -1
  56. package/dist/gateway/static/root/assets/{extension-marketplace-api-BABmUY2s.js → extension-marketplace-api-_o2In_al.js} +1 -1
  57. package/dist/gateway/static/root/assets/{extension-page-C1nGr4DD.js → extension-page-CPrT111s.js} +1 -1
  58. package/dist/gateway/static/root/assets/{extension-provider-BA0Y2Rvs.js → extension-provider-B2Mf3FBu.js} +1 -1
  59. package/dist/gateway/static/root/assets/{extension-settings-page-QIPI8e7k.js → extension-settings-page-CznJEgWV.js} +1 -1
  60. package/dist/gateway/static/root/assets/{file-preview-surface-BsB7bnFH.js → file-preview-surface-7h8_fZul.js} +1 -1
  61. package/dist/gateway/static/root/assets/{gateway-config-swr-Bt8w0Iio.js → gateway-config-swr-DbbNEOKj.js} +1 -1
  62. package/dist/gateway/static/root/assets/{gateway-realtime-CyCCNUxm.js → gateway-realtime-D20ZrAuM.js} +1 -1
  63. package/dist/gateway/static/root/assets/gateway-realtime-store-C6sMzYDT.js +1 -0
  64. package/dist/gateway/static/root/assets/{gateway-restart-Ty4AzDxa.js → gateway-restart-5ut-lhJm.js} +1 -1
  65. package/dist/gateway/static/root/assets/{gateway-settings-BvKq7vuz.js → gateway-settings-BCf_cibp.js} +1 -1
  66. package/dist/gateway/static/root/assets/{gateway-startup-retry-N3k-C7c2.js → gateway-startup-retry-DlHL0DpH.js} +1 -1
  67. package/dist/gateway/static/root/assets/{global-defaults-api-D8EB2vfY.js → global-defaults-api-CmODomcV.js} +1 -1
  68. package/dist/gateway/static/root/assets/{home-page-eRuAzi58.js → home-page-uz22TRB-.js} +2 -2
  69. package/dist/gateway/static/root/assets/{image-generation-api-C99Fsofm.js → image-generation-api-dzPnpUFu.js} +1 -1
  70. package/dist/gateway/static/root/assets/{imports-page-Cp9RquVb.js → imports-page-ChBoNMyE.js} +1 -1
  71. package/dist/gateway/static/root/assets/index-CSIg7V1A.js +11 -0
  72. package/dist/gateway/static/root/assets/index-Dv8mUlNN.css +1 -0
  73. package/dist/gateway/static/root/assets/{install-connector-dialog-CsoAidXp.js → install-connector-dialog-CNcdQDX0.js} +1 -1
  74. package/dist/gateway/static/root/assets/{keyboard-shortcuts-settings-DFhOP2aD.js → keyboard-shortcuts-settings-CRbYq2_g.js} +1 -1
  75. package/dist/gateway/static/root/assets/{local-app-workbench-page-DbtU_A-l.js → local-app-workbench-page-04cX5TJu.js} +1 -1
  76. package/dist/gateway/static/root/assets/{local-apps-page-rjhHfLpe.js → local-apps-page-fWM0FEhN.js} +1 -1
  77. package/dist/gateway/static/root/assets/{local-session-drafts-DHM4vWDO.js → local-session-drafts-ClrSe5mH.js} +1 -1
  78. package/dist/gateway/static/root/assets/{locale-store-5Hf8J8-_.js → locale-store-VNjH18Dj.js} +1 -1
  79. package/dist/gateway/static/root/assets/{logs-page-Dx_JIOpF.js → logs-page-6GanGLrm.js} +1 -1
  80. package/dist/gateway/static/root/assets/management-settings-BxD_lc4E.js +1 -0
  81. package/dist/gateway/static/root/assets/{markdown-view-pzSRu7av.js → markdown-view-DLCBYWtx.js} +2 -2
  82. package/dist/gateway/static/root/assets/{media-plugins-3cJuHbO7.js → media-plugins-BvtNwKFb.js} +1 -1
  83. package/dist/gateway/static/root/assets/{messages-uXxg5p54.js → messages-Btr7C0hF.js} +2 -2
  84. package/dist/gateway/static/root/assets/{model-selector-ksLo-5B_.js → model-selector-DYUnp917.js} +1 -1
  85. package/dist/gateway/static/root/assets/{models-hub-cache-DhZng2nF.js → models-hub-cache-_qE7L-_H.js} +1 -1
  86. package/dist/gateway/static/root/assets/{note-detail-panel-B6RbjwJq.js → note-detail-panel-bjRZesmS.js} +3 -3
  87. package/dist/gateway/static/root/assets/note-image-lightbox-D7Jqb75C.js +1 -0
  88. package/dist/gateway/static/root/assets/{notes-api-DocbsBbT.js → notes-api-Bxa11X3a.js} +1 -1
  89. package/dist/gateway/static/root/assets/{notes-page-B7889s6-.js → notes-page-D2QpJ3WZ.js} +1 -1
  90. package/dist/gateway/static/root/assets/{oauth-api-CCFIPbA0.js → oauth-api-DIE4UpP7.js} +1 -1
  91. package/dist/gateway/static/root/assets/{oauth-provider-connect-GxkF0vWJ.js → oauth-provider-connect-B95tiddN.js} +1 -1
  92. package/dist/gateway/static/root/assets/{page-context-capture-button-CvWLVeRA.js → page-context-capture-button-C-QbbwmN.js} +1 -1
  93. package/dist/gateway/static/root/assets/{page-context-draft-CMRDNv4d.js → page-context-draft-BHmOfksL.js} +1 -1
  94. package/dist/gateway/static/root/assets/page-header-store-bPV8_tKL.js +1 -0
  95. package/dist/gateway/static/root/assets/{personal-avatar-CqNJ48Ge.js → personal-avatar-nXrmMfrV.js} +1 -1
  96. package/dist/gateway/static/root/assets/personal-page-BCwlYT3F.js +1 -0
  97. package/dist/gateway/static/root/assets/{personal-settings-panel-DAcl8DU4.js → personal-settings-panel-vkYmXK8h.js} +1 -1
  98. package/dist/gateway/static/root/assets/{phone-dependencies-card-DLWblGj7.js → phone-dependencies-card-CZDAxTWv.js} +1 -1
  99. package/dist/gateway/static/root/assets/{phone-model-picker-ugrT9GJu.js → phone-model-picker-4Snfs8Hq.js} +1 -1
  100. package/dist/gateway/static/root/assets/{phone-settings-page-DIIt7JOE.js → phone-settings-page-D8HperfA.js} +1 -1
  101. package/dist/gateway/static/root/assets/{phone-workspace-store-mawKT5kV.js → phone-workspace-store-Di9R9Ux5.js} +1 -1
  102. package/dist/gateway/static/root/assets/{plugin-details-dialog-BdueMT3q.js → plugin-details-dialog-DJsDu-_8.js} +1 -1
  103. package/dist/gateway/static/root/assets/{preference-select-fields-CmLZNwbm.js → preference-select-fields-C6abaM3k.js} +1 -1
  104. package/dist/gateway/static/root/assets/{product-automation-feedback-DYwhL37Y.js → product-automation-feedback-C74s9Mjz.js} +1 -1
  105. package/dist/gateway/static/root/assets/product-delivery-DRyD9_Xq.js +1 -0
  106. package/dist/gateway/static/root/assets/{product-open-page-B5G4X71t.js → product-open-page-AbDP5w1c.js} +1 -1
  107. package/dist/gateway/static/root/assets/product-preview-content-CktjvFbc.js +1 -0
  108. package/dist/gateway/static/root/assets/product-preview-modal-CzsqLwB4.js +2 -0
  109. package/dist/gateway/static/root/assets/{project-detail-page-CRJb69vP.js → project-detail-page-Cf3tggGP.js} +2 -2
  110. package/dist/gateway/static/root/assets/{project-understanding-D3w8cZEm.js → project-understanding-jmhFbHch.js} +1 -1
  111. package/dist/gateway/static/root/assets/{projects-page-CkifzKjz.js → projects-page-jMgZiFnO.js} +1 -1
  112. package/dist/gateway/static/root/assets/{providers-api-CKFg2PZQ.js → providers-api-CJBYFKAK.js} +1 -1
  113. package/dist/gateway/static/root/assets/{recording-upload-ZkmRf0GR.js → recording-upload-Dl9a5yOV.js} +1 -1
  114. package/dist/gateway/static/root/assets/{registry-api-B1Mh3bNo.js → registry-api-BwkbPUYu.js} +1 -1
  115. package/dist/gateway/static/root/assets/{remote-access-hub-Dw5rG-aA.js → remote-access-hub-CBQ_bOy9.js} +1 -1
  116. package/dist/gateway/static/root/assets/{resource-unavailable-BUWsH3fp.js → resource-unavailable-35wBZxmz.js} +1 -1
  117. package/dist/gateway/static/root/assets/route-preload-BcA6SPeC.js +2 -0
  118. package/dist/gateway/static/root/assets/{runtime-tools-api-BXvn5ImA.js → runtime-tools-api-BF28JDAO.js} +1 -1
  119. package/dist/gateway/static/root/assets/{runtime-tools-settings-panel-BALcypHp.js → runtime-tools-settings-panel-Bq2xQ2qd.js} +1 -1
  120. package/dist/gateway/static/root/assets/{service-recommendation-list-CpVUnz89.js → service-recommendation-list-CdaS4MPF.js} +1 -1
  121. package/dist/gateway/static/root/assets/{session-api-VquhIBHI.js → session-api-zJXYlRPt.js} +1 -1
  122. package/dist/gateway/static/root/assets/session-manager-wWxpzSo0.js +23 -0
  123. package/dist/gateway/static/root/assets/{sessions-page-DlvPkE5Y.js → sessions-page-BkjD_dUD.js} +1 -1
  124. package/dist/gateway/static/root/assets/settings-advanced-gate-BUMCEtA_.js +1 -0
  125. package/dist/gateway/static/root/assets/{settings-advanced-section-c9_iZ-46.js → settings-advanced-section-C84IghdL.js} +1 -1
  126. package/dist/gateway/static/root/assets/{settings-mode-store-Dem6-TBe.js → settings-mode-store-CtQBJvbO.js} +1 -1
  127. package/dist/gateway/static/root/assets/{settings-page-B_wNfFQe.js → settings-page-eEIz9InP.js} +1 -1
  128. package/dist/gateway/static/root/assets/{settings-page-header-C8a_oOyw.js → settings-page-header-CsPAYlqV.js} +1 -1
  129. package/dist/gateway/static/root/assets/{settings-page-layout-CTSRWljG.js → settings-page-layout-lPLeJQoV.js} +1 -1
  130. package/dist/gateway/static/root/assets/{setup-status-panel-BNZoqF40.js → setup-status-panel-BSU5WpaE.js} +1 -1
  131. package/dist/gateway/static/root/assets/{share-link-dialog-C5JTTxsy.js → share-link-dialog-NaM6jvIz.js} +1 -1
  132. package/dist/gateway/static/root/assets/{share-preview-page-D-KxzXgm.js → share-preview-page-CHjZn27s.js} +1 -1
  133. package/dist/gateway/static/root/assets/{shares-api-CztKbxdd.js → shares-api-B9rVcV1y.js} +1 -1
  134. package/dist/gateway/static/root/assets/{shares-settings-CzR21j6e.js → shares-settings-5sB15V5v.js} +1 -1
  135. package/dist/gateway/static/root/assets/{skill-api-B7kWl6LK.js → skill-api-D6zVfEuK.js} +1 -1
  136. package/dist/gateway/static/root/assets/{skill-list-api-Cn07P6qZ.js → skill-list-api-SLmTBYF5.js} +1 -1
  137. package/dist/gateway/static/root/assets/{skill-reload-api-Bhl0u16_.js → skill-reload-api-UQkq2orI.js} +1 -1
  138. package/dist/gateway/static/root/assets/{skills-page-BmkuxHZe.js → skills-page-Ca0pYZ4i.js} +1 -1
  139. package/dist/gateway/static/root/assets/{system-settings-panel-Ce6zIcki.js → system-settings-panel-BARWbjRN.js} +1 -1
  140. package/dist/gateway/static/root/assets/{task-detail-page-CysJhG3B.js → task-detail-page-roqAsGue.js} +2 -2
  141. package/dist/gateway/static/root/assets/{task-result-evidence-CGZKMnNo.js → task-result-evidence-Bb1F7nAM.js} +1 -1
  142. package/dist/gateway/static/root/assets/{terminal-panel-store-YwLUkuyV.js → terminal-panel-store-DYDeXXAg.js} +1 -1
  143. package/dist/gateway/static/root/assets/{theme-store-DOJ9tu-j.js → theme-store-DbStcH89.js} +1 -1
  144. package/dist/gateway/static/root/assets/{tracing-settings-page-BplBpTdL.js → tracing-settings-page-YfkNCxbP.js} +1 -1
  145. package/dist/gateway/static/root/assets/{tunnel-api-B5-Ypvqa.js → tunnel-api-BK_ivyIb.js} +1 -1
  146. package/dist/gateway/static/root/assets/{understanding-activity-store-CmwtE8Kd.js → understanding-activity-store-p7Z7oq8z.js} +1 -1
  147. package/dist/gateway/static/root/assets/{understanding-refresh-store-9apSmAVL.js → understanding-refresh-store-D-U6rcwZ.js} +1 -1
  148. package/dist/gateway/static/root/assets/{usage-page-cPbirpXX.js → usage-page-URFSiswS.js} +1 -1
  149. package/dist/gateway/static/root/assets/{use-autosave-B3p2QWaF.js → use-autosave-B7cbumro.js} +1 -1
  150. package/dist/gateway/static/root/assets/{use-composer-attachments-D-AEYC85.js → use-composer-attachments-DAtiwLsE.js} +1 -1
  151. package/dist/gateway/static/root/assets/{use-file-preview-expanded-CO4SC-LX.js → use-file-preview-expanded-B8erpWsX.js} +2 -2
  152. package/dist/gateway/static/root/assets/{use-personal-profile-DocmhC9I.js → use-personal-profile-DDW29nm-.js} +1 -1
  153. package/dist/gateway/static/root/assets/{use-workspace-tree-VraTGKx-.js → use-workspace-tree-DCoTf22f.js} +1 -1
  154. package/dist/gateway/static/root/assets/{user-model-page-DuRALzhe.js → user-model-page-DSV5NkNj.js} +1 -1
  155. package/dist/gateway/static/root/assets/{voice-api-key-field-DbSQHZZW.js → voice-api-key-field-DzYdJZN4.js} +1 -1
  156. package/dist/gateway/static/root/assets/{voice-config-api-D9iNJSvm.js → voice-config-api-wotvT6Hw.js} +1 -1
  157. package/dist/gateway/static/root/assets/{voice-input-shortcut-events-hso9_VvT.js → voice-input-shortcut-events-BI6PuiIB.js} +1 -1
  158. package/dist/gateway/static/root/assets/voice-transcribe-api-DAK9eLRr.js +1 -0
  159. package/dist/gateway/static/root/assets/{work-discovery-overlay-fsL9RJqB.js → work-discovery-overlay-BzmB9Rub.js} +1 -1
  160. package/dist/gateway/static/root/assets/{work-discovery-page-DAQPKVDs.js → work-discovery-page-CmGjxUIT.js} +1 -1
  161. package/dist/gateway/static/root/assets/{working-directory-picker-modal-Ta73QrNw.js → working-directory-picker-modal-B-EHm52-.js} +1 -1
  162. package/dist/gateway/static/root/assets/{workspace-api-CgrcNyBc.js → workspace-api-uhiEMPpK.js} +2 -2
  163. package/dist/gateway/static/root/assets/workspace-editor-agent-store-DrPVyikA.js +1 -0
  164. package/dist/gateway/static/root/assets/{workspace-file-preview-dialog-B7uBuPtA.js → workspace-file-preview-dialog-BDm06MZm.js} +1 -1
  165. package/dist/gateway/static/root/assets/{workspace-open-location-menu-Bi2vRvaQ.js → workspace-open-location-menu-Bv83uoqu.js} +1 -1
  166. package/dist/gateway/static/root/assets/{xopc-cloud-account-card-CCOOBG-7.js → xopc-cloud-account-card-Cd5GdpGL.js} +1 -1
  167. package/dist/gateway/static/root/index.html +84 -84
  168. package/dist/gateway/static/root/notification-sw.js +21 -7
  169. package/dist/package.js +1 -1
  170. package/dist/packages/endpoint-tools-protocol/src/context.js +115 -0
  171. package/dist/packages/endpoint-tools-protocol/src/index.js +4 -0
  172. package/dist/packages/endpoint-tools-protocol/src/location-sharing.js +51 -0
  173. package/dist/packages/gateway-contract/src/gateway-scopes.js +5 -1
  174. package/dist/packages/gateway-contract/src/index.js +2 -0
  175. package/dist/packages/gateway-contract/src/phone-workspace.js +6 -0
  176. package/dist/packages/gateway-contract/src/product-delivery.js +9 -3
  177. package/dist/src/agent/embedded/external-tool-discovery.js +1 -1
  178. package/dist/src/agent/embedded/run-for-session.js +2 -2
  179. package/dist/src/agent/embedded/run-turn.js +72 -9
  180. package/dist/src/agent/embedded/session-runner.js +2 -1
  181. package/dist/src/agent/embedded/types.d.ts +1 -1
  182. package/dist/src/agent/prompt/system-prompt.js +1 -0
  183. package/dist/src/agent/service/direct-turn-helpers.d.ts +0 -7
  184. package/dist/src/agent/service/direct-turn-helpers.js +3 -2
  185. package/dist/src/agent/service/process-direct-streaming.js +2 -1
  186. package/dist/src/agent/source-context/device-environment.d.ts +3 -0
  187. package/dist/src/agent/source-context/device-environment.js +38 -0
  188. package/dist/src/agent/source-context/injector.js +2 -1
  189. package/dist/src/agent/tool-manuals/phone.d.ts +1 -1
  190. package/dist/src/agent/tool-manuals/phone.js +1 -1
  191. package/dist/src/agent/tools/automation-tool.js +3 -2
  192. package/dist/src/agent/tools/factory.js +1 -1
  193. package/dist/src/agent/tools/personal-read-tool.js +1 -1
  194. package/dist/src/agent/tools/phone-use-tool.js +46 -2
  195. package/dist/src/agent/tools/xopc-use-tool.js +1 -0
  196. package/dist/src/computer/runtime.d.ts +1 -1
  197. package/dist/src/config/schema.d.ts +1 -0
  198. package/dist/src/endpoint-tools/context-store.d.ts +29 -0
  199. package/dist/src/endpoint-tools/context-store.js +138 -0
  200. package/dist/src/endpoint-tools/location-sharing.d.ts +42 -0
  201. package/dist/src/endpoint-tools/location-sharing.js +203 -0
  202. package/dist/src/endpoint-tools/runtime.d.ts +4 -0
  203. package/dist/src/endpoint-tools/runtime.js +8 -0
  204. package/dist/src/endpoint-tools/turn-context.d.ts +2 -1
  205. package/dist/src/endpoint-tools/turn-context.js +4 -2
  206. package/dist/src/gateway/hono/middleware/auth.js +1 -1
  207. package/dist/src/gateway/hono/routes/devices.js +1 -0
  208. package/dist/src/gateway/hono/routes/endpoint-compatibility.js +4 -0
  209. package/dist/src/gateway/hono/routes/endpoint-environment.d.ts +3 -0
  210. package/dist/src/gateway/hono/routes/endpoint-environment.js +98 -0
  211. package/dist/src/gateway/hono/routes/endpoint-tools.js +1 -0
  212. package/dist/src/gateway/hono/routes/lazy-bundles.js +16 -0
  213. package/dist/src/gateway/hono/routes/location-sharing.d.ts +3 -0
  214. package/dist/src/gateway/hono/routes/location-sharing.js +164 -0
  215. package/dist/src/gateway/hono/routes/phone.js +246 -34
  216. package/dist/src/gateway/hono/routes/session-command-handler.js +1 -1
  217. package/dist/src/gateway/hono/routes/session-input-handler.js +2 -1
  218. package/dist/src/gateway/hono/routes/tunnel.js +10 -0
  219. package/dist/src/gateway/security/gateway-scopes.js +6 -0
  220. package/dist/src/gateway/security/phone-access.d.ts +4 -0
  221. package/dist/src/gateway/security/phone-access.js +20 -0
  222. package/dist/src/gateway/service/agent-runner.js +3 -1
  223. package/dist/src/gateway/service/config-coordinator.d.ts +1 -0
  224. package/dist/src/gateway/service/run-gateway-agent.js +2 -1
  225. package/dist/src/gateway/service/session-input-coordinator.d.ts +3 -0
  226. package/dist/src/gateway/service/session-input-coordinator.js +50 -2
  227. package/dist/src/gateway/service.d.ts +1 -0
  228. package/dist/src/gateway/service.js +8 -0
  229. package/dist/src/gateway/session-reset-service.js +4 -0
  230. package/dist/src/notifications/planner.js +6 -6
  231. package/dist/src/phone/assistance-service.d.ts +6 -0
  232. package/dist/src/phone/assistance-service.js +32 -0
  233. package/dist/src/phone/assistance.d.ts +40 -0
  234. package/dist/src/phone/assistance.js +273 -0
  235. package/dist/src/phone/cloud-phones.d.ts +5 -0
  236. package/dist/src/phone/cloud-phones.js +14 -0
  237. package/dist/src/phone/contracts.d.ts +7 -1
  238. package/dist/src/phone/contracts.js +5 -0
  239. package/dist/src/phone/environment-adapter.d.ts +3 -0
  240. package/dist/src/phone/environment-adapter.js +11 -0
  241. package/dist/src/phone/location-baseline-store.d.ts +9 -0
  242. package/dist/src/phone/location-baseline-store.js +61 -0
  243. package/dist/src/phone/location-environment.d.ts +61 -0
  244. package/dist/src/phone/location-environment.js +157 -0
  245. package/dist/src/phone/model-adapter.js +16 -5
  246. package/dist/src/phone/runtime.d.ts +17 -2
  247. package/dist/src/phone/runtime.js +203 -20
  248. package/dist/src/phone/stream-gateway.d.ts +5 -0
  249. package/dist/src/phone/stream-gateway.js +85 -51
  250. package/dist/src/phone/wuying-location.d.ts +18 -0
  251. package/dist/src/phone/wuying-location.js +86 -0
  252. package/dist/src/storage/sqlite/device-access-repository.d.ts +4 -0
  253. package/dist/src/storage/sqlite/device-access-repository.js +18 -1
  254. package/dist/src/tunnel/broker-client.d.ts +8 -0
  255. package/dist/src/tunnel/broker-client.js +18 -1
  256. package/dist/src/voice/realtime/runtime.js +1 -1
  257. package/package.json +4 -3
  258. package/dist/gateway/static/root/assets/app-link-CytZ5zkp.js +0 -1
  259. package/dist/gateway/static/root/assets/automation-display-BlGt8MAC.js +0 -2
  260. package/dist/gateway/static/root/assets/automation-task-card-Cp3RIw5d.js +0 -2
  261. package/dist/gateway/static/root/assets/automations-workspace-CXLu04I-.js +0 -9
  262. package/dist/gateway/static/root/assets/chat-page-CT3K7lFT.js +0 -71
  263. package/dist/gateway/static/root/assets/date-picker-ByTasrfl.js +0 -1
  264. package/dist/gateway/static/root/assets/device-pairing-wizard-BKMpLdIA.js +0 -1
  265. package/dist/gateway/static/root/assets/gateway-realtime-store-0gmDfPeP.js +0 -1
  266. package/dist/gateway/static/root/assets/index-6vVrWfwM.js +0 -11
  267. package/dist/gateway/static/root/assets/index-DDGK6klk.css +0 -1
  268. package/dist/gateway/static/root/assets/management-settings-CuSzixOw.js +0 -1
  269. package/dist/gateway/static/root/assets/note-image-lightbox-BCjvBqwy.js +0 -1
  270. package/dist/gateway/static/root/assets/page-header-store-reh1es-3.js +0 -1
  271. package/dist/gateway/static/root/assets/personal-page-D95FHaw9.js +0 -1
  272. package/dist/gateway/static/root/assets/product-delivery-BU_H84jL.js +0 -1
  273. package/dist/gateway/static/root/assets/product-preview-content-BUheyLqt.js +0 -1
  274. package/dist/gateway/static/root/assets/product-preview-modal-Cj_Zxu4G.js +0 -2
  275. package/dist/gateway/static/root/assets/route-preload-CRKbVwQ1.js +0 -2
  276. package/dist/gateway/static/root/assets/session-manager-DNMosCtW.js +0 -23
  277. package/dist/gateway/static/root/assets/settings-advanced-gate-Ckc1aCLG.js +0 -1
  278. package/dist/gateway/static/root/assets/voice-transcribe-api-BqIs0jgv.js +0 -1
  279. package/dist/gateway/static/root/assets/workspace-editor-agent-store-Dw6wtadX.js +0 -1
@@ -0,0 +1,29 @@
1
+ import { type EndpointContextView } from '@xopcai/endpoint-tools-protocol';
2
+ import type { EndpointRegistry } from './registry.js';
3
+ export declare class EndpointContextError extends Error {
4
+ readonly code: 'CONTEXT_INVALID' | 'CONTEXT_CONFLICT' | 'SOURCE_UNAVAILABLE';
5
+ constructor(code: 'CONTEXT_INVALID' | 'CONTEXT_CONFLICT' | 'SOURCE_UNAVAILABLE', message: string);
6
+ }
7
+ /** Bounded, process-local observations. Heartbeats never refresh field timestamps. */
8
+ export declare class EndpointContextStore {
9
+ private readonly registry;
10
+ private readonly now;
11
+ private readonly snapshots;
12
+ private readonly unsubscribe;
13
+ constructor(registry: EndpointRegistry, now?: () => number);
14
+ private require;
15
+ connection(endpointId: string): {
16
+ connectionEpoch: string;
17
+ revision: number;
18
+ reportSequence: number;
19
+ heartbeatSequence: number;
20
+ };
21
+ report(endpointId: string, input: unknown): {
22
+ revision: number;
23
+ };
24
+ heartbeat(endpointId: string, input: unknown): {
25
+ revision: number;
26
+ };
27
+ view(endpointId: string): EndpointContextView | undefined;
28
+ close(): void;
29
+ }
@@ -0,0 +1,138 @@
1
+ import { ENDPOINT_CONTEXT_OFFLINE_MS, endpointContextHeartbeatSchema, endpointContextReportSchema } from "../../packages/endpoint-tools-protocol/src/context.js";
2
+ import { canonicalJson, init_src } from "../../packages/endpoint-tools-protocol/src/index.js";
3
+ import { createHash } from "node:crypto";
4
+ //#region src/endpoint-tools/context-store.ts
5
+ init_src();
6
+ var EndpointContextError = class extends Error {
7
+ constructor(code, message) {
8
+ super(message);
9
+ this.code = code;
10
+ }
11
+ };
12
+ /** Bounded, process-local observations. Heartbeats never refresh field timestamps. */
13
+ var EndpointContextStore = class {
14
+ snapshots = /* @__PURE__ */ new Map();
15
+ unsubscribe;
16
+ constructor(registry, now = Date.now) {
17
+ this.registry = registry;
18
+ this.now = now;
19
+ this.unsubscribe = registry.onChange((endpointId, reason) => {
20
+ this.snapshots.delete(endpointId);
21
+ const endpoint = registry.get(endpointId);
22
+ if (reason === "authorization" || !endpoint) return;
23
+ if (this.snapshots.size >= 256) return;
24
+ this.snapshots.set(endpointId, {
25
+ epoch: endpoint.connectionId,
26
+ revision: 0,
27
+ sequence: 0,
28
+ heartbeatSequence: 0,
29
+ lastSeenAt: 0,
30
+ availability: "background",
31
+ fields: /* @__PURE__ */ new Map(),
32
+ receipts: /* @__PURE__ */ new Map()
33
+ });
34
+ });
35
+ }
36
+ require(endpointId) {
37
+ const state = this.snapshots.get(endpointId);
38
+ if (!state || this.registry.get(endpointId)?.connectionId !== state.epoch) throw new EndpointContextError("SOURCE_UNAVAILABLE", "Context source is unavailable");
39
+ return state;
40
+ }
41
+ connection(endpointId) {
42
+ const state = this.require(endpointId);
43
+ return {
44
+ connectionEpoch: state.epoch,
45
+ revision: state.revision,
46
+ reportSequence: state.sequence,
47
+ heartbeatSequence: state.heartbeatSequence
48
+ };
49
+ }
50
+ report(endpointId, input) {
51
+ const parsed = endpointContextReportSchema.safeParse(input);
52
+ if (!parsed.success) throw new EndpointContextError("CONTEXT_INVALID", "Invalid endpoint context report");
53
+ const report = parsed.data;
54
+ const state = this.require(endpointId);
55
+ if (report.connectionEpoch !== state.epoch) throw new EndpointContextError("SOURCE_UNAVAILABLE", "Context connection changed");
56
+ const digest = createHash("sha256").update(canonicalJson(report)).digest("hex");
57
+ const receipt = state.receipts.get(report.reportId);
58
+ if (receipt) {
59
+ if (receipt.digest !== digest) throw new EndpointContextError("CONTEXT_CONFLICT", "Report identity was reused");
60
+ return { revision: receipt.revision };
61
+ }
62
+ if (report.sequence <= state.sequence || report.mode === "patch" && report.baseRevision !== state.revision) throw new EndpointContextError("CONTEXT_CONFLICT", "Context baseline or sequence changed; send a full report");
63
+ const now = this.now();
64
+ if (report.capturedAt > now + 6e4 || report.capturedAt < now - 3e4) throw new EndpointContextError("CONTEXT_INVALID", "Context sample is stale or has an invalid clock");
65
+ const fields = report.mode === "full" ? /* @__PURE__ */ new Map() : new Map(state.fields);
66
+ for (const key of report.cleared) fields.delete(key);
67
+ for (const [key, value] of Object.entries(report.values)) {
68
+ if (value === void 0) continue;
69
+ const field = key;
70
+ const prior = state.fields.get(field);
71
+ if (prior && report.capturedAt < prior.capturedAt) throw new EndpointContextError("CONTEXT_CONFLICT", "Context sample moved backwards");
72
+ if (prior && report.capturedAt === prior.capturedAt) {
73
+ if (canonicalJson(prior.value) !== canonicalJson(value)) throw new EndpointContextError("CONTEXT_CONFLICT", "Context sample identity changed");
74
+ fields.set(field, prior);
75
+ continue;
76
+ }
77
+ fields.set(field, {
78
+ value: structuredClone(value),
79
+ capturedAt: report.capturedAt,
80
+ receivedAt: now,
81
+ validUntil: Math.min(report.capturedAt, now) + (field === "device.power" ? 3e4 : 3e5)
82
+ });
83
+ }
84
+ state.fields = fields;
85
+ state.sequence = report.sequence;
86
+ state.revision += 1;
87
+ state.receipts.set(report.reportId, {
88
+ digest,
89
+ revision: state.revision
90
+ });
91
+ if (state.receipts.size > 64) state.receipts.delete(state.receipts.keys().next().value);
92
+ return { revision: state.revision };
93
+ }
94
+ heartbeat(endpointId, input) {
95
+ const parsed = endpointContextHeartbeatSchema.safeParse(input);
96
+ if (!parsed.success) throw new EndpointContextError("CONTEXT_INVALID", "Invalid context heartbeat");
97
+ const state = this.require(endpointId);
98
+ if (parsed.data.connectionEpoch !== state.epoch || parsed.data.sequence <= state.heartbeatSequence) throw new EndpointContextError("CONTEXT_CONFLICT", "Context heartbeat connection or sequence changed");
99
+ state.heartbeatSequence = parsed.data.sequence;
100
+ state.lastSeenAt = this.now();
101
+ state.availability = parsed.data.availability;
102
+ return { revision: state.revision };
103
+ }
104
+ view(endpointId) {
105
+ let state;
106
+ try {
107
+ state = this.require(endpointId);
108
+ } catch {
109
+ return;
110
+ }
111
+ const now = this.now();
112
+ const availability = state.lastSeenAt === 0 || now - state.lastSeenAt >= 45e3 ? "offline" : this.registry.get(endpointId)?.kind !== "browser" && this.registry.get(endpointId)?.availability === "background" ? "background" : state.availability;
113
+ const fields = {};
114
+ for (const [key, reading] of state.fields) {
115
+ const status = availability !== "foreground" ? "unavailable" : reading.validUntil <= now ? "stale" : "fresh";
116
+ fields[key] = {
117
+ status,
118
+ capturedAt: reading.capturedAt,
119
+ validUntil: reading.validUntil,
120
+ ...status === "fresh" ? { value: structuredClone(reading.value) } : {}
121
+ };
122
+ }
123
+ return {
124
+ version: 1,
125
+ endpointId,
126
+ revision: state.revision,
127
+ availability,
128
+ sourceValidUntil: state.lastSeenAt + ENDPOINT_CONTEXT_OFFLINE_MS,
129
+ fields
130
+ };
131
+ }
132
+ close() {
133
+ this.unsubscribe();
134
+ this.snapshots.clear();
135
+ }
136
+ };
137
+ //#endregion
138
+ export { EndpointContextError, EndpointContextStore };
@@ -0,0 +1,42 @@
1
+ import { type LocationSample, type LocationShareRequest, type LocationShareSummary } from '@xopcai/endpoint-tools-protocol';
2
+ import type { EndpointRegistry } from './registry.js';
3
+ import type { EndpointContextStore } from './context-store.js';
4
+ export declare class LocationSharingError extends Error {
5
+ readonly code: string;
6
+ constructor(code: string, message: string);
7
+ }
8
+ export interface LocationConsumer {
9
+ apply(input: {
10
+ shareId: string;
11
+ conversationId: string;
12
+ phoneId: string;
13
+ sample: LocationSample;
14
+ validUntil: number;
15
+ assertCurrent(): void;
16
+ }, signal: AbortSignal): Promise<void>;
17
+ clear(shareId: string, phoneId: string): Promise<boolean>;
18
+ state?(shareId: string, phoneId: string): LocationShareSummary['sync'];
19
+ }
20
+ /** Explicitly authorized coordinates remain transient and are never part of public context values. */
21
+ export declare class LocationSharingService {
22
+ private readonly registry;
23
+ private readonly contexts;
24
+ private readonly now;
25
+ private readonly shares;
26
+ private consumer?;
27
+ private readonly timer;
28
+ private readonly unsubscribe;
29
+ constructor(registry: EndpointRegistry, contexts: EndpointContextStore, now?: () => number);
30
+ setConsumer(consumer: LocationConsumer): void;
31
+ create(endpointId: string, input: LocationShareRequest): LocationShareSummary;
32
+ private usable;
33
+ sample(id: string, endpointId: string, input: unknown): Promise<LocationShareSummary>;
34
+ private require;
35
+ private summary;
36
+ list(endpointId: string, conversationId?: string): LocationShareSummary[];
37
+ revoke(id: string, endpointId: string): Promise<LocationShareSummary>;
38
+ private invalidate;
39
+ private clear;
40
+ sweep(): Promise<void>;
41
+ close(): Promise<void>;
42
+ }
@@ -0,0 +1,203 @@
1
+ import { locationShareRequestSchema, locationShareSampleSchema } from "../../packages/endpoint-tools-protocol/src/location-sharing.js";
2
+ import { init_src } from "../../packages/endpoint-tools-protocol/src/index.js";
3
+ import { randomUUID } from "node:crypto";
4
+ //#region src/endpoint-tools/location-sharing.ts
5
+ init_src();
6
+ var LocationSharingError = class extends Error {
7
+ constructor(code, message) {
8
+ super(message);
9
+ this.code = code;
10
+ }
11
+ };
12
+ /** Explicitly authorized coordinates remain transient and are never part of public context values. */
13
+ var LocationSharingService = class {
14
+ shares = /* @__PURE__ */ new Map();
15
+ consumer;
16
+ timer;
17
+ unsubscribe;
18
+ constructor(registry, contexts, now = Date.now) {
19
+ this.registry = registry;
20
+ this.contexts = contexts;
21
+ this.now = now;
22
+ this.timer = setInterval(() => {
23
+ this.sweep();
24
+ }, 1e3);
25
+ this.timer.unref();
26
+ this.unsubscribe = registry.onChange((endpointId) => {
27
+ for (const share of this.shares.values()) if (share.summary.endpointId === endpointId) this.invalidate(share, "source_unavailable");
28
+ });
29
+ }
30
+ setConsumer(consumer) {
31
+ this.consumer = consumer;
32
+ }
33
+ create(endpointId, input) {
34
+ const request = locationShareRequestSchema.parse(input);
35
+ const endpoint = this.registry.get(endpointId);
36
+ if (!endpoint || this.contexts.view(endpointId)?.availability !== "foreground") throw new LocationSharingError("SOURCE_UNAVAILABLE", "Open the source device before sharing location");
37
+ for (const [id, share] of this.shares) if ([
38
+ "revoked",
39
+ "expired",
40
+ "source_unavailable"
41
+ ].includes(share.summary.status) && share.summary.sync !== "cleanup_pending") this.shares.delete(id);
42
+ if (this.shares.size >= 64) throw new LocationSharingError("SHARING_CAPACITY", "Too many location shares");
43
+ if ([...this.shares.values()].some((share) => share.summary.endpointId === endpointId && share.summary.conversationId === request.conversationId && ![
44
+ "revoked",
45
+ "expired",
46
+ "source_unavailable"
47
+ ].includes(share.summary.status))) throw new LocationSharingError("SHARING_EXISTS", "Stop the current location share first");
48
+ const summary = {
49
+ ...request,
50
+ id: randomUUID(),
51
+ endpointId,
52
+ expiresAt: this.now() + request.durationMs,
53
+ status: "waiting",
54
+ sync: request.phoneId ? "pending" : "not_requested"
55
+ };
56
+ const share = {
57
+ summary,
58
+ epoch: endpoint.connectionId,
59
+ sequence: 0,
60
+ controller: new AbortController(),
61
+ operation: Promise.resolve()
62
+ };
63
+ this.shares.set(summary.id, share);
64
+ return { ...summary };
65
+ }
66
+ usable(share) {
67
+ return !share.controller.signal.aborted && share.summary.expiresAt > this.now() && this.registry.get(share.summary.endpointId)?.connectionId === share.epoch && this.contexts.view(share.summary.endpointId)?.availability === "foreground";
68
+ }
69
+ async sample(id, endpointId, input) {
70
+ const share = this.require(id, endpointId);
71
+ const parsed = locationShareSampleSchema.safeParse(input);
72
+ if (!parsed.success) throw new LocationSharingError("LOCATION_INVALID", "Invalid location sample");
73
+ if (!this.usable(share)) {
74
+ await this.invalidate(share, share.summary.expiresAt <= this.now() ? "expired" : "source_unavailable");
75
+ throw new LocationSharingError("GRANT_REVOKED", "Location sharing is no longer active");
76
+ }
77
+ const { sequence, sample } = parsed.data;
78
+ if (sequence <= share.sequence || share.summary.mode === "once" && share.sequence > 0) throw new LocationSharingError("LOCATION_REPLAY", "Location sample was already consumed");
79
+ if (sample.capturedAt < this.now() - 3e4 || sample.capturedAt > this.now() + 6e4 || share.sample && sample.capturedAt <= share.sample.capturedAt) throw new LocationSharingError("CONTEXT_STALE", "Acquire a fresh location sample");
80
+ if (share.summary.precision === "precise" && sample.precision !== "precise") throw new LocationSharingError("PRECISION_UNAVAILABLE", "Precise location is unavailable; choose approximate sharing");
81
+ const value = share.summary.precision === "approximate" || sample.precision === "approximate" ? {
82
+ ...sample,
83
+ latitude: Math.round(sample.latitude * 50) / 50,
84
+ longitude: Math.round(sample.longitude * 50) / 50,
85
+ accuracyMeters: Math.max(3e3, sample.accuracyMeters),
86
+ precision: "approximate"
87
+ } : sample;
88
+ share.sequence = sequence;
89
+ share.sample = value;
90
+ share.sampleController?.abort();
91
+ share.sampleController = new AbortController();
92
+ const valueRef = randomUUID();
93
+ Object.assign(share.summary, {
94
+ status: "fresh",
95
+ capturedAt: value.capturedAt,
96
+ accuracyMeters: value.accuracyMeters,
97
+ validUntil: Math.min(value.capturedAt, this.now()) + 3e4,
98
+ valueRef
99
+ });
100
+ share.summary.validUntil = Math.min(share.summary.validUntil, share.summary.expiresAt);
101
+ if (share.summary.phoneId) {
102
+ share.summary.sync = "pending";
103
+ const consumer = this.consumer;
104
+ if (!consumer) throw new LocationSharingError("PHONE_ENV_UNSUPPORTED", "Phone location synchronization is unavailable");
105
+ const validUntil = share.summary.validUntil;
106
+ const signal = AbortSignal.any([
107
+ share.controller.signal,
108
+ share.sampleController.signal,
109
+ AbortSignal.timeout(Math.max(1, validUntil - this.now()))
110
+ ]);
111
+ const assertCurrent = () => {
112
+ if (!this.usable(share) || share.summary.valueRef !== valueRef || validUntil <= this.now()) throw new LocationSharingError("CONTEXT_STALE", "Location authorization or sample expired");
113
+ };
114
+ share.operation = share.operation.catch(() => {}).then(async () => {
115
+ try {
116
+ assertCurrent();
117
+ await consumer.apply({
118
+ shareId: id,
119
+ conversationId: share.summary.conversationId,
120
+ phoneId: share.summary.phoneId,
121
+ sample: value,
122
+ validUntil,
123
+ assertCurrent
124
+ }, signal);
125
+ assertCurrent();
126
+ share.summary.sync = "applied";
127
+ } catch {
128
+ if (share.summary.valueRef === valueRef && share.summary.status === "fresh") share.summary.sync = "failed";
129
+ }
130
+ });
131
+ await share.operation;
132
+ }
133
+ return this.summary(share);
134
+ }
135
+ require(id, endpointId) {
136
+ const share = this.shares.get(id);
137
+ if (!share || share.summary.endpointId !== endpointId) throw new LocationSharingError("SHARE_NOT_FOUND", "Location share is unavailable");
138
+ return share;
139
+ }
140
+ summary(share) {
141
+ const result = { ...share.summary };
142
+ if (result.phoneId && ["applied", "cleanup_pending"].includes(result.sync)) result.sync = this.consumer?.state?.(result.id, result.phoneId) ?? result.sync;
143
+ if (!this.usable(share) || !share.sample || (result.validUntil ?? 0) <= this.now()) {
144
+ delete result.valueRef;
145
+ if (result.status === "fresh") result.status = "stale";
146
+ }
147
+ return result;
148
+ }
149
+ list(endpointId, conversationId) {
150
+ return [...this.shares.values()].filter((share) => share.summary.endpointId === endpointId && (!conversationId || share.summary.conversationId === conversationId)).map((share) => this.summary(share));
151
+ }
152
+ async revoke(id, endpointId) {
153
+ return this.invalidate(this.require(id, endpointId), "revoked");
154
+ }
155
+ async invalidate(share, status) {
156
+ share.controller.abort();
157
+ share.sampleController?.abort();
158
+ share.sample = void 0;
159
+ delete share.summary.valueRef;
160
+ if (![
161
+ "revoked",
162
+ "expired",
163
+ "source_unavailable"
164
+ ].includes(share.summary.status)) share.summary.status = status;
165
+ await this.clear(share);
166
+ return this.summary(share);
167
+ }
168
+ async clear(share) {
169
+ if (!share.summary.phoneId || !this.consumer) return;
170
+ share.summary.sync = "cleanup_pending";
171
+ share.operation = share.operation.catch(() => {}).then(async () => {
172
+ try {
173
+ share.summary.sync = await this.consumer.clear(share.summary.id, share.summary.phoneId) ? "clean" : "cleanup_pending";
174
+ } catch {
175
+ share.summary.sync = "cleanup_pending";
176
+ }
177
+ });
178
+ await share.operation;
179
+ }
180
+ async sweep() {
181
+ const pending = [];
182
+ for (const share of this.shares.values()) {
183
+ if (share.summary.status === "waiting" && share.summary.expiresAt > this.now() && this.registry.get(share.summary.endpointId)?.connectionId === share.epoch) continue;
184
+ if (!share.controller.signal.aborted && !this.usable(share)) pending.push(this.invalidate(share, share.summary.expiresAt <= this.now() ? "expired" : "source_unavailable"));
185
+ else if (share.sample && (share.summary.validUntil ?? 0) <= this.now()) {
186
+ share.sampleController?.abort();
187
+ share.sample = void 0;
188
+ delete share.summary.valueRef;
189
+ share.summary.status = "stale";
190
+ pending.push(this.clear(share));
191
+ }
192
+ }
193
+ await Promise.all(pending);
194
+ }
195
+ async close() {
196
+ clearInterval(this.timer);
197
+ this.unsubscribe();
198
+ await Promise.all([...this.shares.values()].map((share) => this.invalidate(share, "revoked")));
199
+ this.shares.clear();
200
+ }
201
+ };
202
+ //#endregion
203
+ export { LocationSharingError, LocationSharingService };
@@ -5,8 +5,12 @@ import { EndpointBindingService } from './binding-service.js';
5
5
  import { EndpointInvocationService, type EndpointInvocationAuditSink } from './invocation-service.js';
6
6
  import { EndpointRegistry, type EndpointRegistration, type EndpointTransport } from './registry.js';
7
7
  import { EndpointUploadService } from './upload-service.js';
8
+ import { EndpointContextStore } from './context-store.js';
9
+ import { LocationSharingService } from './location-sharing.js';
8
10
  export declare class EndpointToolRuntime {
9
11
  readonly registry: EndpointRegistry;
12
+ readonly contexts: EndpointContextStore;
13
+ readonly locations: LocationSharingService;
10
14
  readonly grants: DeviceGrantService;
11
15
  readonly invocations: EndpointInvocationService;
12
16
  readonly uploads: EndpointUploadService;
@@ -11,10 +11,12 @@ import { EndpointToolPolicy } from "./policy.js";
11
11
  import { EndpointInvocationService } from "./invocation-service.js";
12
12
  import { EndpointAuthenticator } from "./auth.js";
13
13
  import { EndpointBindingService } from "./binding-service.js";
14
+ import { EndpointContextStore } from "./context-store.js";
14
15
  import { DeviceGrantService } from "./grant-service.js";
15
16
  import { recordDeviceGrantEvent } from "../storage/sqlite/device-grant-audit-repository.js";
16
17
  import { EndpointRegistry } from "./registry.js";
17
18
  import { EndpointUploadService } from "./upload-service.js";
19
+ import { LocationSharingService } from "./location-sharing.js";
18
20
  import { join } from "node:path";
19
21
  //#region src/endpoint-tools/runtime.ts
20
22
  init_paths();
@@ -23,6 +25,8 @@ const log = createLogger("EndpointTools");
23
25
  const MAX_MESSAGE_CLOCK_SKEW_MS = 6e4;
24
26
  var EndpointToolRuntime = class {
25
27
  registry;
28
+ contexts;
29
+ locations;
26
30
  grants;
27
31
  invocations;
28
32
  uploads;
@@ -32,6 +36,8 @@ var EndpointToolRuntime = class {
32
36
  constructor(options = {}) {
33
37
  const policy = new EndpointToolPolicy();
34
38
  this.registry = new EndpointRegistry(policy);
39
+ this.contexts = new EndpointContextStore(this.registry);
40
+ this.locations = new LocationSharingService(this.registry, this.contexts);
35
41
  this.grants = new DeviceGrantService(this.registry, Date.now, recordDeviceGrantEvent);
36
42
  this.bindings = new EndpointBindingService(this.registry, {
37
43
  get: getEndpointSessionBinding,
@@ -103,6 +109,8 @@ var EndpointToolRuntime = class {
103
109
  this.grants.close();
104
110
  this.invocations.close();
105
111
  this.uploads.close();
112
+ this.contexts.close();
113
+ this.locations.close();
106
114
  this.registry.closeAll();
107
115
  }
108
116
  };
@@ -1,6 +1,7 @@
1
1
  import type { EndpointContext } from '@xopcai/gateway-contract';
2
+ import type { EndpointContextView, LocationShareSummary } from '@xopcai/endpoint-tools-protocol';
2
3
  import type { AgentSourceContext } from '../agent/source-context/types.js';
3
4
  import type { GatewayPrincipal } from '../gateway/security/gateway-principal.js';
4
5
  import type { EndpointConnectionSnapshot, EndpointRegistry } from './registry.js';
5
6
  export declare function endpointClaimBelongsToPrincipal(registry: EndpointRegistry, endpointId: string, principal: GatewayPrincipal): boolean;
6
- export declare function deviceTurnSourceContext(endpoint: EndpointConnectionSnapshot, environment?: EndpointContext): AgentSourceContext;
7
+ export declare function deviceTurnSourceContext(endpoint: EndpointConnectionSnapshot, environment?: EndpointContext, taskContext?: EndpointContextView, locationShares?: LocationShareSummary[]): AgentSourceContext;
@@ -5,7 +5,7 @@ function endpointClaimBelongsToPrincipal(registry, endpointId, principal) {
5
5
  const endpoint = registry.get(endpointId);
6
6
  return Boolean(endpoint && (principal.kind === "owner" || principal.kind === "device" && endpoint.principalId === principal.deviceId));
7
7
  }
8
- function deviceTurnSourceContext(endpoint, environment) {
8
+ function deviceTurnSourceContext(endpoint, environment, taskContext, locationShares) {
9
9
  const name = getEndpointDeviceSettings(endpoint.principalId)?.nickname ?? endpoint.displayName;
10
10
  const snapshot = {
11
11
  endpointId: endpoint.endpointId,
@@ -13,7 +13,9 @@ function deviceTurnSourceContext(endpoint, environment) {
13
13
  name: name.slice(0, 80),
14
14
  platform: endpoint.platform.slice(0, 40),
15
15
  kind: endpoint.kind,
16
- ...environment ? { environment } : {}
16
+ ...environment ? { environment } : {},
17
+ ...taskContext ? { taskContext } : {},
18
+ ...locationShares?.length ? { locationShares: locationShares.slice(-3) } : {}
17
19
  };
18
20
  const text = JSON.stringify(snapshot).replaceAll("<", "\\u003c").replaceAll(">", "\\u003e");
19
21
  return {
@@ -9,8 +9,8 @@ import { authenticateDeviceAccessToken, getDevice } from "../../../storage/sqlit
9
9
  import { getOrCreateGatewayIdentity } from "../../../storage/sqlite/gateway-identity-repository.js";
10
10
  import { safeEqualSecret } from "../../security/secret-equal.js";
11
11
  import { resolveClientIpFromRequest } from "../../client-ip.js";
12
- import { authenticateBrowserSession } from "../../../storage/sqlite/browser-session-repository.js";
13
12
  import { PROOF_HEADER, acquireProofBodyBudget, consumeRequestNonce, parseRequestProof, proofDigest, requestProofMessage, verifyRequestProofSignature } from "../../security/device-request-proof.js";
13
+ import { authenticateBrowserSession } from "../../../storage/sqlite/browser-session-repository.js";
14
14
  import { isChromeExtensionOrigin } from "../../security/origin-check.js";
15
15
  import { browserCookieRequestAllowed, readBrowserSessionCookie, writeBrowserSessionCookie } from "../../security/browser-session.js";
16
16
  import { authorizeTrustedProxy } from "../../trusted-proxy.js";
@@ -230,6 +230,7 @@ function registerDeviceRoutes(authenticated, deps) {
230
230
  deps.service.endpointTools.registry.revokePrincipal(principal.deviceId);
231
231
  deps.service.realtime.disconnectPrincipal(principal.deviceId);
232
232
  deps.service.voiceRealtime.disconnectPrincipal(principal.deviceId);
233
+ deps.service.phoneStreams.disconnectPrincipal(principal.deviceId);
233
234
  }
234
235
  return c.json({
235
236
  ok: true,
@@ -19,6 +19,10 @@ function registerEndpointCompatibilityRoutes(authenticated) {
19
19
  capabilities: REALTIME_CAPABILITIES
20
20
  },
21
21
  turnDeviceContextV1: true,
22
+ endpointEnvironmentV1: true,
23
+ locationSharingV1: true,
24
+ mobilePhoneWorkspaceV1: true,
25
+ phoneMediaProtocolVersion: 1,
22
26
  deviceStateToolsV1: true,
23
27
  hardwareBridgeV1: true,
24
28
  deviceLocationTasksV1: true,
@@ -0,0 +1,3 @@
1
+ import type { Hono } from 'hono';
2
+ import type { AuthenticatedRouteDeps } from './deps.js';
3
+ export declare function registerEndpointEnvironmentRoutes(app: Hono, deps: AuthenticatedRouteDeps): void;
@@ -0,0 +1,98 @@
1
+ import { endpointTurnClaimSchema, init_src } from "../../../../packages/endpoint-tools-protocol/src/index.js";
2
+ import { EndpointContextError } from "../../../endpoint-tools/context-store.js";
3
+ import { endpointClaimBelongsToPrincipal } from "../../../endpoint-tools/turn-context.js";
4
+ import { getGatewayPrincipal } from "../../security/gateway-principal.js";
5
+ import { z } from "zod";
6
+ import { bodyLimit } from "hono/body-limit";
7
+ //#region src/gateway/hono/routes/endpoint-environment.ts
8
+ init_src();
9
+ const root = "/api/user-context/environment";
10
+ const mutationSchema = z.strictObject({
11
+ origin: endpointTurnClaimSchema,
12
+ report: z.unknown().optional(),
13
+ heartbeat: z.unknown().optional()
14
+ });
15
+ function registerEndpointEnvironmentRoutes(app, deps) {
16
+ const runtime = deps.service.endpointTools;
17
+ app.get(root, (c) => {
18
+ const actor = getGatewayPrincipal(c);
19
+ c.header("Cache-Control", "no-store");
20
+ const snapshots = runtime.registry.list().filter((endpoint) => endpointClaimBelongsToPrincipal(runtime.registry, endpoint.endpointId, actor)).map((endpoint) => runtime.contexts.view(endpoint.endpointId)).filter(Boolean);
21
+ return c.json({
22
+ ok: true,
23
+ payload: snapshots
24
+ });
25
+ });
26
+ app.get(`${root}/endpoints/:endpointId`, (c) => {
27
+ c.header("Cache-Control", "no-store");
28
+ const id = c.req.param("endpointId");
29
+ if (!endpointClaimBelongsToPrincipal(runtime.registry, id, getGatewayPrincipal(c))) return c.json({
30
+ ok: false,
31
+ error: {
32
+ code: "FORBIDDEN",
33
+ message: "Context source is not accessible"
34
+ }
35
+ }, 403);
36
+ try {
37
+ return c.json({
38
+ ok: true,
39
+ payload: {
40
+ ...runtime.contexts.connection(id),
41
+ context: runtime.contexts.view(id)
42
+ }
43
+ });
44
+ } catch {
45
+ return c.json({
46
+ ok: false,
47
+ error: {
48
+ code: "SOURCE_UNAVAILABLE",
49
+ message: "Context source is unavailable"
50
+ }
51
+ }, 409);
52
+ }
53
+ });
54
+ for (const action of ["reports", "heartbeats"]) app.post(`${root}/${action}`, bodyLimit({ maxSize: 16384 }), async (c) => {
55
+ c.header("Cache-Control", "no-store");
56
+ const parsed = mutationSchema.safeParse(await c.req.json().catch(() => null));
57
+ if (!parsed.success || (action === "reports" ? parsed.data.heartbeat !== void 0 || parsed.data.report === void 0 : parsed.data.report !== void 0 || parsed.data.heartbeat === void 0)) return c.json({
58
+ ok: false,
59
+ error: {
60
+ code: "CONTEXT_INVALID",
61
+ message: "Invalid context request"
62
+ }
63
+ }, 400);
64
+ const { origin } = parsed.data;
65
+ if (!endpointClaimBelongsToPrincipal(runtime.registry, origin.endpointId, getGatewayPrincipal(c))) return c.json({
66
+ ok: false,
67
+ error: {
68
+ code: "FORBIDDEN",
69
+ message: "Context source is not accessible"
70
+ }
71
+ }, 403);
72
+ if (!runtime.registry.verifyTurnClaim(origin.endpointId, origin.token)) return c.json({
73
+ ok: false,
74
+ error: {
75
+ code: "SOURCE_UNAVAILABLE",
76
+ message: "Context connection changed"
77
+ }
78
+ }, 409);
79
+ try {
80
+ const payload = action === "reports" ? runtime.contexts.report(origin.endpointId, parsed.data.report) : runtime.contexts.heartbeat(origin.endpointId, parsed.data.heartbeat);
81
+ return c.json({
82
+ ok: true,
83
+ payload
84
+ });
85
+ } catch (error) {
86
+ if (!(error instanceof EndpointContextError)) throw error;
87
+ return c.json({
88
+ ok: false,
89
+ error: {
90
+ code: error.code,
91
+ message: error.message
92
+ }
93
+ }, error.code === "CONTEXT_INVALID" ? 400 : 409);
94
+ }
95
+ });
96
+ }
97
+ //#endregion
98
+ export { registerEndpointEnvironmentRoutes };
@@ -106,6 +106,7 @@ function registerEndpointToolRoutes(authenticated, deps) {
106
106
  if (accessRevoked) {
107
107
  deps.service.realtime.disconnectPrincipal(id);
108
108
  deps.service.voiceRealtime.disconnectPrincipal(id);
109
+ deps.service.phoneStreams.disconnectPrincipal(id);
109
110
  }
110
111
  if (principalRevoked) {
111
112
  for (const endpoint of deps.service.endpointTools.registry.list()) if (endpoint.principalId === id) deps.service.endpointTools.disconnect(endpoint.endpointId, "Device revoked");
@@ -3,6 +3,22 @@ function startsWithAny(path, prefixes) {
3
3
  return prefixes.some((prefix) => path === prefix || path.startsWith(`${prefix}/`));
4
4
  }
5
5
  const AUTHENTICATED_LAZY_ROUTE_BUNDLES = [
6
+ {
7
+ id: "location-sharing",
8
+ match: (path) => /^\/api\/user-context\/environment\/location-shares(?:\/[^/]+(?:\/samples)?)?$/.test(path),
9
+ load: async () => {
10
+ const { registerLocationSharingRoutes } = await import("./location-sharing.js");
11
+ return { register: registerLocationSharingRoutes };
12
+ }
13
+ },
14
+ {
15
+ id: "endpoint-environment",
16
+ match: (path) => /^\/api\/user-context\/environment(?:\/(?:reports|heartbeats|endpoints\/[^/]+))?$/.test(path),
17
+ load: async () => {
18
+ const { registerEndpointEnvironmentRoutes } = await import("./endpoint-environment.js");
19
+ return { register: registerEndpointEnvironmentRoutes };
20
+ }
21
+ },
6
22
  {
7
23
  id: "phone",
8
24
  match: (path) => startsWithAny(path, ["/api/phone"]),