@xopcai/xopc 0.0.414 → 0.0.416

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 (359) hide show
  1. package/dist/browser-ext/_locales/en/messages.json +4 -1
  2. package/dist/browser-ext/_locales/zh_CN/messages.json +4 -1
  3. package/dist/browser-ext/dist/assets/{page-context-MuzjMBlJ.js → page-context-CVvmTWZb.js} +33 -9
  4. package/dist/browser-ext/dist/background.js +39 -10
  5. package/dist/browser-ext/dist/sidepanel.html +1 -1
  6. package/dist/browser-ext/dist/sidepanel.js +22 -3
  7. package/dist/browser-ext/manifest.json +1 -1
  8. package/dist/extensions/telegram/xopc.extension.json +1 -1
  9. package/dist/gateway/static/root/assets/{agent-avatar-dicebear-ClobpdW3.js → agent-avatar-dicebear-CufU7cqe.js} +1 -1
  10. package/dist/gateway/static/root/assets/agent-defaults-settings-panel-DHDAcss8.js +1 -0
  11. package/dist/gateway/static/root/assets/agents-BV3dAoa0.js +77 -0
  12. package/dist/gateway/static/root/assets/{agents-admin-api-CeBkHnl8.js → agents-admin-api-B1p-ghg9.js} +1 -1
  13. package/dist/gateway/static/root/assets/{app-management-settings-panel-CLunLNGp.js → app-management-settings-panel-D4-n1uBg.js} +1 -1
  14. package/dist/gateway/static/root/assets/{appearance-settings-DBEgoE9g.js → appearance-settings-Cgn4eNsX.js} +1 -1
  15. package/dist/gateway/static/root/assets/apps-page-BOYzD7Zz.js +1 -0
  16. package/dist/gateway/static/root/assets/{archive-plugin-JElK4Goq.js → archive-plugin-B4btCsiV.js} +1 -1
  17. package/dist/gateway/static/root/assets/{automations-page-CZ0UqwyU.js → automations-page-yb1EL_3N.js} +1 -1
  18. package/dist/gateway/static/root/assets/automations-workspace-J7LJ4RuV.js +8 -0
  19. package/dist/gateway/static/root/assets/{binary-plugins-CXFawow6.js → binary-plugins-DQT9e258.js} +1 -1
  20. package/dist/gateway/static/root/assets/{block-editor-BoduwSYI.js → block-editor-B50rU9tL.js} +30 -30
  21. package/dist/gateway/static/root/assets/{browser-automation-inputs-D1pDgMJu.js → browser-automation-inputs-D6AccXaA.js} +1 -1
  22. package/dist/gateway/static/root/assets/browser-automations-page-BiQz6lJA.js +3 -0
  23. package/dist/gateway/static/root/assets/browser-settings-page-W9kuxBbE.js +3 -0
  24. package/dist/gateway/static/root/assets/{capabilities-Bpeh6E22.js → capabilities-BlxF36t-.js} +1 -1
  25. package/dist/gateway/static/root/assets/capabilities-page-iXe87MdG.js +2 -0
  26. package/dist/gateway/static/root/assets/capabilities-settings-panel-CRLSXe7Z.js +8 -0
  27. package/dist/gateway/static/root/assets/{capability-header-actions-BasrAWA0.js → capability-header-actions-BMnbzHms.js} +1 -1
  28. package/dist/gateway/static/root/assets/channels-CrRJkOKX.js +1 -0
  29. package/dist/gateway/static/root/assets/{chat-terminal-dock-CwQbzcZ_.js → chat-terminal-dock-Bd3af4gL.js} +2 -2
  30. package/dist/gateway/static/root/assets/{computer-settings-page-DNWeJKfF.js → computer-settings-page-DXfqy7xh.js} +1 -1
  31. package/dist/gateway/static/root/assets/{connector-service-page-CxHgC5RM.js → connector-service-page-B-cw0CPU.js} +1 -1
  32. package/dist/gateway/static/root/assets/connectors-page-DbFxc0Fd.js +1 -0
  33. package/dist/gateway/static/root/assets/{date-picker-CXxLbLJb.js → date-picker-CqzXevH6.js} +1 -1
  34. package/dist/gateway/static/root/assets/{dependency-picker-DVuWMrSj.js → dependency-picker-pgT4Gyaf.js} +1 -1
  35. package/dist/gateway/static/root/assets/{desktop-pet-settings-BDlg9g4s.js → desktop-pet-settings-Dy_-i2L8.js} +1 -1
  36. package/dist/gateway/static/root/assets/{desktop-pet-KbVLtAlO.js → desktop-pet-zICeqw9c.js} +1 -1
  37. package/dist/gateway/static/root/assets/device-pairing-wizard-ByGbxqkg.js +1 -0
  38. package/dist/gateway/static/root/assets/{directory-picker-path-field-a7xEodzo.js → directory-picker-path-field-C-aQ7qoM.js} +1 -1
  39. package/dist/gateway/static/root/assets/{extension-debug-page-CHelH5u_.js → extension-debug-page-2NwpYkS5.js} +1 -1
  40. package/dist/gateway/static/root/assets/{extension-page-CrVHmS9-.js → extension-page-y9J0z7_Q.js} +1 -1
  41. package/dist/gateway/static/root/assets/{extension-settings-page-CiMybi0r.js → extension-settings-page-BtowusUh.js} +1 -1
  42. package/dist/gateway/static/root/assets/{gateway-config-swr-DF_HV6NP.js → gateway-config-swr-fQKBHBi1.js} +1 -1
  43. package/dist/gateway/static/root/assets/gateway-realtime-C52ghnBK.js +1 -0
  44. package/dist/gateway/static/root/assets/gateway-realtime-store-Bx9KCID-.js +1 -0
  45. package/dist/gateway/static/root/assets/gateway-settings-BYSKzUMR.js +1 -0
  46. package/dist/gateway/static/root/assets/{gateway-startup-retry-B91CBTzO.js → gateway-startup-retry-Cfwxof4k.js} +1 -1
  47. package/dist/gateway/static/root/assets/highlight-code-Cz6eeDH5.js +1 -0
  48. package/dist/gateway/static/root/assets/{highlighted-body-KQOG7T2V-8ACAVktj.js → highlighted-body-KQOG7T2V-BiAa8HKC.js} +1 -1
  49. package/dist/gateway/static/root/assets/home-page-Cd1BjYHj.js +2 -0
  50. package/dist/gateway/static/root/assets/{image-generation-api-CVBaWmrV.js → image-generation-api-gBFro48x.js} +1 -1
  51. package/dist/gateway/static/root/assets/{imports-page-C5IP3e6d.js → imports-page-BZQpXgjj.js} +1 -1
  52. package/dist/gateway/static/root/assets/index-Cy16gQST.css +1 -0
  53. package/dist/gateway/static/root/assets/index-DRyGCING.js +710 -0
  54. package/dist/gateway/static/root/assets/{keyboard-shortcuts-settings-BhU6VYvd.js → keyboard-shortcuts-settings-CYunR34k.js} +1 -1
  55. package/dist/gateway/static/root/assets/local-app-workbench-page-B_Ac1lly.js +1 -0
  56. package/dist/gateway/static/root/assets/{local-apps-page-DcP1Bdlk.js → local-apps-page-w-J5bY02.js} +1 -1
  57. package/dist/gateway/static/root/assets/{local-session-drafts-DvmwiLUx.js → local-session-drafts-iGX_6O0O.js} +1 -1
  58. package/dist/gateway/static/root/assets/{locale-store-JogcXC4J.js → locale-store-B7s2Hb35.js} +1 -1
  59. package/dist/gateway/static/root/assets/logs-page-Dnjvvx2i.js +2 -0
  60. package/dist/gateway/static/root/assets/management-settings-w1EDwgLW.js +1 -0
  61. package/dist/gateway/static/root/assets/{media-plugins-BnPpcJ2J.js → media-plugins-CIx1koXw.js} +1 -1
  62. package/dist/gateway/static/root/assets/mermaid-MCJ5UELQ-DISkHmEC.js +1 -0
  63. package/dist/gateway/static/root/assets/{messages-RzwPiQNL.js → messages-BYq0cPbn.js} +2 -2
  64. package/dist/gateway/static/root/assets/note-detail-panel-CNkxMTFU.js +5 -0
  65. package/dist/gateway/static/root/assets/note-image-lightbox-D5GH2wuC.js +1 -0
  66. package/dist/gateway/static/root/assets/notes-page-DZgKqFBG.js +8 -0
  67. package/dist/gateway/static/root/assets/page-context-capture-button-DusR2Itk.js +1 -0
  68. package/dist/gateway/static/root/assets/personal-page-CR5JFkQ9.js +1 -0
  69. package/dist/gateway/static/root/assets/personal-settings-panel-B7undvlr.js +1 -0
  70. package/dist/gateway/static/root/assets/phone-model-picker-fWDltRUJ.js +1 -0
  71. package/dist/gateway/static/root/assets/phone-settings-page-CsOirAiy.js +1 -0
  72. package/dist/gateway/static/root/assets/plugin-details-dialog-BOBVIB3j.js +1 -0
  73. package/dist/gateway/static/root/assets/{preview-open-alternatives-FGqN-mQx.js → preview-open-alternatives-CMxjsKSw.js} +1 -1
  74. package/dist/gateway/static/root/assets/{product-open-page-CwnHLfdL.js → product-open-page-CrlyJx5M.js} +1 -1
  75. package/dist/gateway/static/root/assets/{product-preview-content-BD6k5hF9.js → product-preview-content-B-Jhzi7W.js} +1 -1
  76. package/dist/gateway/static/root/assets/project-detail-page-DoYUbtcI.js +7 -0
  77. package/dist/gateway/static/root/assets/projects-page-xGQd9oAZ.js +1 -0
  78. package/dist/gateway/static/root/assets/refresh-cw-BRlGaq2w.js +1 -0
  79. package/dist/gateway/static/root/assets/{registry-api-BGqSwITi.js → registry-api-BcfoLEna.js} +1 -1
  80. package/dist/gateway/static/root/assets/remote-access-hub-Gs0Xkws9.js +1 -0
  81. package/dist/gateway/static/root/assets/{runtime-tools-api-CSm5SpnR.js → runtime-tools-api-DesqGCnE.js} +1 -1
  82. package/dist/gateway/static/root/assets/runtime-tools-settings-panel-Bwg7U7TR.js +1 -0
  83. package/dist/gateway/static/root/assets/{schema-form-DoVn5jJK.js → schema-form-ByzTNR_C.js} +1 -1
  84. package/dist/gateway/static/root/assets/{session-api-DTxZyMta.js → session-api-DdQnMwkl.js} +1 -1
  85. package/dist/gateway/static/root/assets/{session-manager-B2HDomj4.js → session-manager-B_h0jlLb.js} +1 -1
  86. package/dist/gateway/static/root/assets/sessions-page-XzK1ftbR.js +1 -0
  87. package/dist/gateway/static/root/assets/settings-advanced-gate-D_8Mvnog.js +1 -0
  88. package/dist/gateway/static/root/assets/{settings-form-section-Ce8vVv-9.js → settings-form-section-Brgd8IOV.js} +1 -1
  89. package/dist/gateway/static/root/assets/{settings-page-DP2w3ejC.js → settings-page-B6Mv02eg.js} +1 -1
  90. package/dist/gateway/static/root/assets/settings-page-header-BWyxJKOG.js +1 -0
  91. package/dist/gateway/static/root/assets/{settings-page-layout-B20AfmFG.js → settings-page-layout-DLHcS-0T.js} +1 -1
  92. package/dist/gateway/static/root/assets/setup-status-panel-DSCj5yis.js +1 -0
  93. package/dist/gateway/static/root/assets/{share-preview-page-DV4dKrmG.js → share-preview-page-DF8Of0aZ.js} +1 -1
  94. package/dist/gateway/static/root/assets/shares-settings-DXNPe4Tl.js +1 -0
  95. package/dist/gateway/static/root/assets/{skill-api-DTdejInH.js → skill-api-CKCDCHLq.js} +1 -1
  96. package/dist/gateway/static/root/assets/skill-reload-api-BH0WF6Br.js +1 -0
  97. package/dist/gateway/static/root/assets/skills-page-DFWMVRW4.js +2 -0
  98. package/dist/gateway/static/root/assets/system-settings-panel-DB-ttubV.js +1 -0
  99. package/dist/gateway/static/root/assets/task-detail-page-BJY7c8wb.js +2 -0
  100. package/dist/gateway/static/root/assets/{task-result-evidence-DIGSC4qF.js → task-result-evidence-B-vt1BgK.js} +1 -1
  101. package/dist/gateway/static/root/assets/{tracing-settings-page-BaU8frtc.js → tracing-settings-page-Dt51Z_ws.js} +1 -1
  102. package/dist/gateway/static/root/assets/{tunnel-api-BCcOUsqu.js → tunnel-api-Dok3t7Qe.js} +1 -1
  103. package/dist/gateway/static/root/assets/usage-page-lJym5G7F.js +1 -0
  104. package/dist/gateway/static/root/assets/{use-autosave-C1X47WVb.js → use-autosave-D4EMIB-V.js} +1 -1
  105. package/dist/gateway/static/root/assets/user-model-page-BXdNkITp.js +2 -0
  106. package/dist/gateway/static/root/assets/{voice-api-key-field-Bk4DQMTw.js → voice-api-key-field-CO3KuanA.js} +1 -1
  107. package/dist/gateway/static/root/assets/{voice-config-api-D7xsWrdh.js → voice-config-api-BkUlN7GH.js} +1 -1
  108. package/dist/gateway/static/root/assets/{work-discovery-overlay-B7_NmTB5.js → work-discovery-overlay-BJRtgQM3.js} +1 -1
  109. package/dist/gateway/static/root/assets/wrench-DFb4r8bH.js +1 -0
  110. package/dist/gateway/static/root/assets/xopc-cloud-account-card-CS-_GxHV.js +1 -0
  111. package/dist/gateway/static/root/browser-setup-test.html +5 -0
  112. package/dist/gateway/static/root/browser-setup-test.js +7 -0
  113. package/dist/gateway/static/root/index.html +17 -14
  114. package/dist/package.js +1 -1
  115. package/dist/packages/gateway-contract/src/browser-setup.js +6 -0
  116. package/dist/packages/gateway-contract/src/index.js +4 -0
  117. package/dist/packages/gateway-contract/src/phone-setup.js +6 -0
  118. package/dist/packages/realtime-client/src/index.js +1 -0
  119. package/dist/packages/realtime-protocol/src/index.js +1 -0
  120. package/dist/src/agent/agent-manager.d.ts +4 -0
  121. package/dist/src/agent/agent-manager.js +12 -1
  122. package/dist/src/agent/coding/workspace-revision.js +1 -1
  123. package/dist/src/agent/commands/command-registry.js +1 -1
  124. package/dist/src/agent/embedded/tool-search-extension.js +14 -1
  125. package/dist/src/agent/memory/context-recovery.d.ts +1 -1
  126. package/dist/src/agent/service.d.ts +1 -0
  127. package/dist/src/agent/service.js +5 -0
  128. package/dist/src/agent/service.types.d.ts +2 -0
  129. package/dist/src/agent/skills/installer.js +3 -3
  130. package/dist/src/agent/tool-manuals/phone.d.ts +1 -1
  131. package/dist/src/agent/tool-manuals/phone.js +4 -2
  132. package/dist/src/agent/tool-manuals/xopc-configuration.d.ts +2 -0
  133. package/dist/src/agent/tool-manuals/xopc-configuration.js +25 -0
  134. package/dist/src/agent/tools/browser/tool/browser-use-tool.d.ts +2 -0
  135. package/dist/src/agent/tools/browser/tool/browser-use-tool.js +6 -2
  136. package/dist/src/agent/tools/factory.d.ts +3 -0
  137. package/dist/src/agent/tools/factory.js +11 -1
  138. package/dist/src/agent/tools/personal-task-tool.d.ts +1 -1
  139. package/dist/src/agent/tools/personal-task-tool.js +23 -21
  140. package/dist/src/agent/tools/phone-use-tool.d.ts +1 -0
  141. package/dist/src/agent/tools/phone-use-tool.js +29 -1
  142. package/dist/src/agent/tools/tool-manual-tool.d.ts +1 -1
  143. package/dist/src/agent/tools/tool-manual-tool.js +3 -1
  144. package/dist/src/agent/tools/toolExposure.js +3 -0
  145. package/dist/src/agent/tools/xopc-use-tool.d.ts +4 -2
  146. package/dist/src/agent/tools/xopc-use-tool.js +40 -2
  147. package/dist/src/backup/archive.js +2 -1
  148. package/dist/src/browser/drivers/browser-driver.d.ts +2 -2
  149. package/dist/src/browser/drivers/extension-driver.d.ts +2 -2
  150. package/dist/src/browser/drivers/extension-driver.js +6 -3
  151. package/dist/src/browser/providers/browser-ext-install.js +3 -2
  152. package/dist/src/browser/runtime/browser-runtime.d.ts +4 -1
  153. package/dist/src/browser/runtime/browser-runtime.js +29 -17
  154. package/dist/src/browser/setup/repository.d.ts +5 -0
  155. package/dist/src/browser/setup/repository.js +42 -0
  156. package/dist/src/browser/setup/service.d.ts +152 -0
  157. package/dist/src/browser/setup/service.js +404 -0
  158. package/dist/src/browser/setup/types.d.ts +38 -0
  159. package/dist/src/browser/setup/types.js +1 -0
  160. package/dist/src/cli/commands/doctor/checks/database-schema.js +1 -1
  161. package/dist/src/cli/commands/extension-marketplace.js +3 -3
  162. package/dist/src/cli/commands/extension-pack.js +1 -1
  163. package/dist/src/cli/commands/extension.js +2 -2
  164. package/dist/src/config/schema.d.ts +2 -0
  165. package/dist/src/extensions/install.js +1 -1
  166. package/dist/src/extensions/update.js +1 -1
  167. package/dist/src/gateway/agent-builtin-tools.d.ts +1 -1
  168. package/dist/src/gateway/hono/routes/auth-registry-extensions.js +1 -1
  169. package/dist/src/gateway/hono/routes/browser-setup.d.ts +3 -0
  170. package/dist/src/gateway/hono/routes/browser-setup.js +114 -0
  171. package/dist/src/gateway/hono/routes/browser.d.ts +2 -1
  172. package/dist/src/gateway/hono/routes/browser.js +1 -1
  173. package/dist/src/gateway/hono/routes/lazy-bundles.js +8 -0
  174. package/dist/src/gateway/hono/routes/phone-dependencies.js +1 -1
  175. package/dist/src/gateway/hono/routes/phone-setup.d.ts +7 -0
  176. package/dist/src/gateway/hono/routes/phone-setup.js +162 -0
  177. package/dist/src/gateway/hono/routes/phone.js +11 -7
  178. package/dist/src/gateway/hono/routes/public-gateway.js +2 -0
  179. package/dist/src/gateway/provider-model-setup.js +1 -1
  180. package/dist/src/gateway/service/config-coordinator.d.ts +2 -0
  181. package/dist/src/gateway/service/config-coordinator.js +1 -1
  182. package/dist/src/gateway/service/session-input-coordinator.js +1 -1
  183. package/dist/src/gateway/service.d.ts +5 -0
  184. package/dist/src/gateway/service.js +52 -7
  185. package/dist/src/gateway/xopc-cloud-capability-setup.js +7 -1
  186. package/dist/src/home-intelligence/host.js +2 -2
  187. package/dist/src/infra/unhandled-rejections.js +2 -2
  188. package/dist/src/infra/update-runner.js +1 -1
  189. package/dist/src/personal-agent/prompts.js +1 -1
  190. package/dist/src/phone/adb-driver.d.ts +8 -2
  191. package/dist/src/phone/adb-driver.js +124 -54
  192. package/dist/src/phone/cloud-adb.js +8 -0
  193. package/dist/src/phone/cloud-scrcpy.d.ts +3 -1
  194. package/dist/src/phone/cloud-scrcpy.js +17 -3
  195. package/dist/src/phone/contracts.d.ts +85 -0
  196. package/dist/src/phone/contracts.js +31 -5
  197. package/dist/src/phone/model-adapter.d.ts +141 -2
  198. package/dist/src/phone/model-adapter.js +176 -24
  199. package/dist/src/phone/numeric-entry.d.ts +31 -0
  200. package/dist/src/phone/numeric-entry.js +126 -0
  201. package/dist/src/phone/planning.d.ts +27 -0
  202. package/dist/src/phone/planning.js +79 -0
  203. package/dist/src/phone/recovery.d.ts +37 -0
  204. package/dist/src/phone/recovery.js +81 -0
  205. package/dist/src/phone/reliability.d.ts +7 -0
  206. package/dist/src/phone/reliability.js +66 -0
  207. package/dist/src/phone/repository.d.ts +1 -0
  208. package/dist/src/phone/repository.js +3 -0
  209. package/dist/src/phone/runtime.d.ts +8 -0
  210. package/dist/src/phone/runtime.js +387 -41
  211. package/dist/src/phone/scrcpy-text.d.ts +11 -0
  212. package/dist/src/phone/scrcpy-text.js +72 -0
  213. package/dist/src/phone/scrcpy.d.ts +5 -1
  214. package/dist/src/phone/scrcpy.js +48 -3
  215. package/dist/src/phone/semantic-controls.d.ts +13 -0
  216. package/dist/src/phone/semantic-controls.js +76 -0
  217. package/dist/src/phone/setup/service.d.ts +148 -0
  218. package/dist/src/phone/setup/service.js +251 -0
  219. package/dist/src/providers/presentation.js +2 -2
  220. package/dist/src/providers/xopc-cloud-model-source.js +6 -2
  221. package/dist/src/realtime/runtime.js +1 -1
  222. package/dist/src/storage/sqlite/connection.js +2 -2
  223. package/dist/src/storage/sqlite/offline-access.js +13 -7
  224. package/dist/src/storage/sqlite/schema-errors.d.ts +12 -0
  225. package/dist/src/storage/sqlite/schema-errors.js +21 -3
  226. package/dist/src/storage/sqlite/schema-upgrade.d.ts +4 -0
  227. package/dist/src/storage/sqlite/schema-upgrade.js +78 -0
  228. package/dist/src/storage/sqlite/schema.d.ts +4 -3
  229. package/dist/src/storage/sqlite/schema.js +14 -8
  230. package/dist/src/storage/sqlite/schema.sql +10 -0
  231. package/dist/src/storage/sqlite/upgrades/203_remove_retired_proactive_contracts.sql +70 -0
  232. package/dist/src/storage/sqlite/upgrades/204_home_intelligence.sql +78 -0
  233. package/dist/src/storage/sqlite/upgrades/205_agent_catalog.sql +66 -0
  234. package/dist/src/storage/sqlite/upgrades/206_home_advice_strategy_version.sql +2 -0
  235. package/dist/src/storage/sqlite/upgrades/207_user_model_policy_contract.sql +121 -0
  236. package/dist/src/storage/sqlite/upgrades/208_automation_management.sql +2 -0
  237. package/dist/src/storage/sqlite/upgrades/209_automation_event_hub.sql +48 -0
  238. package/dist/src/storage/sqlite/upgrades/210_remove_legacy_automation_timeout.sql +14 -0
  239. package/dist/src/storage/sqlite/upgrades/211_automation_result_deliveries.sql +16 -0
  240. package/dist/src/storage/sqlite/upgrades/212_automation_delivery_policy.sql +30 -0
  241. package/dist/src/storage/sqlite/upgrades/213_automation_reliability_contract.sql +188 -0
  242. package/dist/src/storage/sqlite/upgrades/214_ai_usage_ledger.sql +41 -0
  243. package/dist/src/storage/sqlite/upgrades/215_scene_execution_adapters.sql +6 -0
  244. package/dist/src/storage/sqlite/upgrades/216_remove_scene_model_usage.sql +1 -0
  245. package/dist/src/storage/sqlite/upgrades/217_remove_legacy_memory_tables.sql +4 -0
  246. package/dist/src/storage/sqlite/upgrades/218_core_relation_indexes.sql +26 -0
  247. package/dist/src/storage/sqlite/upgrades/219_json_contracts.sql +123 -0
  248. package/dist/src/storage/sqlite/upgrades/220_normalize_timestamps.sql +339 -0
  249. package/dist/src/storage/sqlite/upgrades/221_ai_usage_retention_index.sql +2 -0
  250. package/dist/src/storage/sqlite/upgrades/222_session_config_authority.sql +13 -0
  251. package/dist/src/storage/sqlite/upgrades/223_session_creation_receipts.sql +59 -0
  252. package/dist/src/storage/sqlite/upgrades/224_task_origin_links.sql +8 -0
  253. package/dist/src/storage/sqlite/upgrades/225_task_collaboration.sql +32 -0
  254. package/dist/src/storage/sqlite/upgrades/226_task_main_updates.sql +9 -0
  255. package/dist/src/storage/sqlite/upgrades/227_task_main_update_decisions.sql +8 -0
  256. package/dist/src/storage/sqlite/upgrades/228_task_main_agent_links.sql +14 -0
  257. package/dist/src/storage/sqlite/upgrades/229_task_criterion_reviews.sql +12 -0
  258. package/dist/src/storage/sqlite/upgrades/230_personal_agent_onboarding.sql +8 -0
  259. package/dist/src/storage/sqlite/upgrades/231_task_result_deliveries.sql +32 -0
  260. package/dist/src/storage/sqlite/upgrades/232_personal_requests.sql +28 -0
  261. package/dist/src/storage/sqlite/upgrades/233_observability_usage_links.sql +3 -0
  262. package/dist/src/storage/sqlite/upgrades/234_task_result_reply.sql +14 -0
  263. package/dist/src/storage/sqlite/upgrades/235_personal_conversation_priority.sql +3 -0
  264. package/dist/src/storage/sqlite/upgrades/236_personal_proactivity.sql +53 -0
  265. package/dist/src/storage/sqlite/upgrades/237_personal_strategy_versions.sql +18 -0
  266. package/dist/src/storage/sqlite/upgrades/238_browser_record_replay.sql +45 -0
  267. package/dist/src/storage/sqlite/upgrades/239_clarification_notifications.sql +26 -0
  268. package/dist/src/storage/sqlite/upgrades/240_device_settings.sql +5 -0
  269. package/dist/src/storage/sqlite/upgrades/241_device_grant_audit.sql +13 -0
  270. package/dist/src/storage/sqlite/upgrades/242_cloud_usage_receipts.sql +5 -0
  271. package/dist/src/storage/sqlite/upgrades/243_voice_opening_greetings.sql +12 -0
  272. package/dist/src/storage/sqlite/upgrades/244_device_request_proofs.sql +8 -0
  273. package/dist/src/storage/sqlite/upgrades/245_memory_learning.sql +125 -0
  274. package/dist/src/storage/sqlite/upgrades/246_personal_session_thinking.sql +22 -0
  275. package/dist/src/storage/sqlite/upgrades/247_agent_selection_records.sql +32 -0
  276. package/dist/src/storage/sqlite/upgrades/248_next_turn_suggestions.sql +20 -0
  277. package/dist/src/storage/sqlite/upgrades/249_task_allocations.sql +17 -0
  278. package/dist/src/storage/sqlite/upgrades/250_research_checkpoints.sql +15 -0
  279. package/dist/src/storage/sqlite/upgrades/251_personal_result_reads.sql +40 -0
  280. package/dist/src/storage/sqlite/upgrades/252_task_work_revisions.sql +15 -0
  281. package/dist/src/storage/sqlite/upgrades/253_discussion_processing_recovery.sql +20 -0
  282. package/dist/src/storage/sqlite/upgrades/254_discussion_annotations.sql +17 -0
  283. package/dist/src/storage/sqlite/upgrades/255_discussion_chapter_progress.sql +10 -0
  284. package/dist/src/storage/sqlite/upgrades/256_task_main_update_retries.sql +21 -0
  285. package/dist/src/storage/sqlite/upgrades/257_session_composer_history.sql +11 -0
  286. package/dist/src/storage/sqlite/upgrades/258_task_phase_changes.sql +20 -0
  287. package/dist/src/storage/sqlite/upgrades/259_personal_default_style.sql +10 -0
  288. package/dist/src/storage/sqlite/upgrades/260_browser_setup.sql +9 -0
  289. package/dist/src/storage/sqlite/windows-database-owners.js +33 -28
  290. package/dist/src/tasks/capabilities/relations.d.ts +2 -2
  291. package/dist/src/tui/clipboard-image.js +1 -1
  292. package/dist/src/tui/tui.js +1 -1
  293. package/dist/src/utils/index.js +1 -1
  294. package/dist/src/utils/logger/index.js +1 -1
  295. package/dist/src/utils/logger.js +1 -1
  296. package/dist/src/work-discovery/probe.js +1 -1
  297. package/package.json +3 -3
  298. package/skills/tools/configure-xopc/SKILL.md +47 -0
  299. package/skills/tools/configure-xopc/references/browser/acceptance.md +31 -0
  300. package/skills/tools/configure-xopc/references/browser/chrome-extension.md +19 -0
  301. package/skills/tools/configure-xopc/references/browser/overview.md +22 -0
  302. package/skills/tools/configure-xopc/references/browser/permissions.md +25 -0
  303. package/skills/tools/configure-xopc/references/browser/troubleshooting.md +24 -0
  304. package/skills/tools/configure-xopc/references/phone/acceptance.md +25 -0
  305. package/skills/tools/configure-xopc/references/phone/aliyun.md +29 -0
  306. package/skills/tools/configure-xopc/references/phone/dependencies.md +18 -0
  307. package/skills/tools/configure-xopc/references/phone/local.md +19 -0
  308. package/skills/tools/configure-xopc/references/phone/models.md +18 -0
  309. package/skills/tools/configure-xopc/references/phone/overview.md +30 -0
  310. package/skills/tools/configure-xopc/references/phone/troubleshooting.md +24 -0
  311. package/skills/tools/configure-xopc/references/scene-index.md +12 -0
  312. package/dist/gateway/static/root/assets/agent-defaults-settings-panel-mf0jgEPE.js +0 -1
  313. package/dist/gateway/static/root/assets/agents-CKhZ4UYQ.js +0 -77
  314. package/dist/gateway/static/root/assets/apps-page-BZ_MaQJf.js +0 -1
  315. package/dist/gateway/static/root/assets/automations-workspace-CHUDHNVL.js +0 -8
  316. package/dist/gateway/static/root/assets/browser-automations-page-DStDm9y1.js +0 -3
  317. package/dist/gateway/static/root/assets/browser-settings-page-6I4oetKt.js +0 -3
  318. package/dist/gateway/static/root/assets/capabilities-page-C-EecWbS.js +0 -2
  319. package/dist/gateway/static/root/assets/capabilities-settings-panel-BQoCPk3x.js +0 -8
  320. package/dist/gateway/static/root/assets/channels-BKf_-Mdt.js +0 -1
  321. package/dist/gateway/static/root/assets/connectors-page-CUBg8spT.js +0 -1
  322. package/dist/gateway/static/root/assets/device-pairing-wizard-PmP_vGem.js +0 -1
  323. package/dist/gateway/static/root/assets/gateway-realtime-DMAzNlm-.js +0 -1
  324. package/dist/gateway/static/root/assets/gateway-realtime-store-CoIgC1Al.js +0 -1
  325. package/dist/gateway/static/root/assets/gateway-settings-DnrQ28E2.js +0 -1
  326. package/dist/gateway/static/root/assets/highlight-code-AMjU04kR.js +0 -1
  327. package/dist/gateway/static/root/assets/home-page-pTwVME-g.js +0 -2
  328. package/dist/gateway/static/root/assets/index-BLL0wKRZ.css +0 -1
  329. package/dist/gateway/static/root/assets/index-ygkHNYyo.js +0 -710
  330. package/dist/gateway/static/root/assets/local-app-workbench-page-Cwl6EvuX.js +0 -1
  331. package/dist/gateway/static/root/assets/logs-page-CS3hcTOq.js +0 -2
  332. package/dist/gateway/static/root/assets/management-settings-DC-Y_-GP.js +0 -1
  333. package/dist/gateway/static/root/assets/mermaid-MCJ5UELQ-vckgHpON.js +0 -1
  334. package/dist/gateway/static/root/assets/note-detail-panel-C7u4dxEk.js +0 -5
  335. package/dist/gateway/static/root/assets/note-image-lightbox-jvqYtySx.js +0 -1
  336. package/dist/gateway/static/root/assets/notes-page-Bs7F5Hpf.js +0 -8
  337. package/dist/gateway/static/root/assets/page-context-capture-button-DO_yhXS1.js +0 -1
  338. package/dist/gateway/static/root/assets/personal-page-BexL2-PQ.js +0 -1
  339. package/dist/gateway/static/root/assets/personal-settings-panel-BKA4fbYH.js +0 -1
  340. package/dist/gateway/static/root/assets/phone-dependencies-card-ChFtdFhA.js +0 -1
  341. package/dist/gateway/static/root/assets/phone-model-picker-CZoIAQ1j.js +0 -1
  342. package/dist/gateway/static/root/assets/phone-settings-page-DRyK0nHH.js +0 -1
  343. package/dist/gateway/static/root/assets/plugin-details-dialog-B-N61jJH.js +0 -1
  344. package/dist/gateway/static/root/assets/project-detail-page-DtKmFBml.js +0 -7
  345. package/dist/gateway/static/root/assets/projects-page-CFZIz9mc.js +0 -1
  346. package/dist/gateway/static/root/assets/remote-access-hub-CWEc7W0m.js +0 -1
  347. package/dist/gateway/static/root/assets/runtime-tools-settings-panel-q_oswAdV.js +0 -1
  348. package/dist/gateway/static/root/assets/sessions-page-BuPqNxpd.js +0 -1
  349. package/dist/gateway/static/root/assets/settings-advanced-gate-QTVDCGJG.js +0 -1
  350. package/dist/gateway/static/root/assets/settings-page-header-CYpuTXUW.js +0 -1
  351. package/dist/gateway/static/root/assets/setup-status-panel-ZmlE8jIE.js +0 -1
  352. package/dist/gateway/static/root/assets/shares-settings-CtNxWqW-.js +0 -1
  353. package/dist/gateway/static/root/assets/skill-reload-api-Egaf8PqZ.js +0 -1
  354. package/dist/gateway/static/root/assets/skills-page-C6FKxf4J.js +0 -2
  355. package/dist/gateway/static/root/assets/system-settings-panel-Baxkhov7.js +0 -1
  356. package/dist/gateway/static/root/assets/task-detail-page-C77-rpkt.js +0 -2
  357. package/dist/gateway/static/root/assets/usage-page-BFeIbpbi.js +0 -1
  358. package/dist/gateway/static/root/assets/user-model-page-u8zY5jea.js +0 -2
  359. package/dist/gateway/static/root/assets/xopc-cloud-account-card-CJ_akAvc.js +0 -1
@@ -1,3 +1,4 @@
1
+ import { ScrcpyTextChannel } from './scrcpy-text.js';
1
2
  import type { PhoneInteractiveProvider, PhonePointer, PhoneVideoGeometry, PhoneVideoPacket } from './live-provider.js';
2
3
  export { readScrcpyServer, scrcpyServerPath, SCRCPY_VERSION, SCRCPY_SHA256 } from './scrcpy-assets.js';
3
4
  /** The pinned server sends codec metadata followed by bounded, length-prefixed packets. */
@@ -18,6 +19,7 @@ export declare abstract class ScrcpyProvider implements PhoneInteractiveProvider
18
19
  };
19
20
  geometry: PhoneVideoGeometry;
20
21
  protected closing: boolean;
22
+ protected textChannel: ScrcpyTextChannel;
21
23
  private touch?;
22
24
  private listeners;
23
25
  private config?;
@@ -29,6 +31,7 @@ export declare abstract class ScrcpyProvider implements PhoneInteractiveProvider
29
31
  protected abstract startTransport(): Promise<void>;
30
32
  protected abstract write(buffer: Buffer): Promise<void>;
31
33
  protected abstract cleanup(): Promise<void>;
34
+ pasteText(text: string, signal: AbortSignal): Promise<void>;
32
35
  start(): Promise<void>;
33
36
  protected packet(packet: PhoneVideoPacket): void;
34
37
  subscribe(listener: (packet: PhoneVideoPacket) => void): () => void;
@@ -42,6 +45,7 @@ export declare class LocalScrcpyProvider extends ScrcpyProvider {
42
45
  private adb;
43
46
  private serial;
44
47
  private tuning;
48
+ private textOnly;
45
49
  private process?;
46
50
  private video?;
47
51
  private control?;
@@ -51,7 +55,7 @@ export declare class LocalScrcpyProvider extends ScrcpyProvider {
51
55
  constructor(adb: string, serial: string, onFailure: () => void, tuning?: {
52
56
  maxSize: number;
53
57
  bitRate: number;
54
- });
58
+ }, textOnly?: boolean);
55
59
  foreground(signal: AbortSignal): Promise<string>;
56
60
  protected startTransport(): Promise<void>;
57
61
  protected write(buffer: Buffer): Promise<void>;
@@ -2,6 +2,7 @@ import { PhoneError, init_contracts } from "./contracts.js";
2
2
  import { spawnPhoneCommand } from "../process/phone-process.js";
3
3
  import { SCRCPY_SHA256, SCRCPY_VERSION } from "../runtime-tools/phone-dependency-catalog.js";
4
4
  import { readScrcpyServer, scrcpyServerPath } from "./scrcpy-assets.js";
5
+ import { ScrcpyTextChannel } from "./scrcpy-text.js";
5
6
  import { AdbPhoneDriver, runAdb } from "./adb-driver.js";
6
7
  import { randomBytes } from "node:crypto";
7
8
  import { connect } from "node:net";
@@ -69,6 +70,7 @@ var ScrcpyProvider = class {
69
70
  codec: ""
70
71
  };
71
72
  closing = false;
73
+ textChannel = new ScrcpyTextChannel((bytes) => this.write(bytes));
72
74
  touch;
73
75
  listeners = /* @__PURE__ */ new Set();
74
76
  config;
@@ -78,6 +80,25 @@ var ScrcpyProvider = class {
78
80
  constructor(onFailure) {
79
81
  this.onFailure = onFailure;
80
82
  }
83
+ async pasteText(text, signal) {
84
+ signal.throwIfAborted();
85
+ const deadline = AbortSignal.any([signal, AbortSignal.timeout(25e3)]);
86
+ const abort = () => {
87
+ this.close();
88
+ };
89
+ deadline.addEventListener("abort", abort, { once: true });
90
+ try {
91
+ try {
92
+ await this.start();
93
+ deadline.throwIfAborted();
94
+ } catch {
95
+ throw new PhoneError("PHONE_TEXT_INPUT_UNAVAILABLE", "Automatic text input is unavailable. Check Phone settings or take over and type with the phone keyboard.", 409);
96
+ }
97
+ await this.textChannel.paste(text, deadline);
98
+ } finally {
99
+ deadline.removeEventListener("abort", abort);
100
+ }
101
+ }
81
102
  start() {
82
103
  if (this.closing) return Promise.reject(new PhoneError("PHONE_VIDEO_ENDED", "Phone video ended", 409));
83
104
  if (!this.startResult) {
@@ -144,6 +165,7 @@ var ScrcpyProvider = class {
144
165
  }
145
166
  close() {
146
167
  this.closing = true;
168
+ this.textChannel.close();
147
169
  return this.closeResult ??= (async () => {
148
170
  await this.opening?.catch(() => {});
149
171
  try {
@@ -165,11 +187,12 @@ var LocalScrcpyProvider = class extends ScrcpyProvider {
165
187
  constructor(adb, serial, onFailure, tuning = {
166
188
  maxSize: 960,
167
189
  bitRate: 2e6
168
- }) {
190
+ }, textOnly = false) {
169
191
  super(onFailure);
170
192
  this.adb = adb;
171
193
  this.serial = serial;
172
194
  this.tuning = tuning;
195
+ this.textOnly = textOnly;
173
196
  }
174
197
  foreground(signal) {
175
198
  return new AdbPhoneDriver(this.adb).foreground(this.serial, signal);
@@ -221,7 +244,8 @@ var LocalScrcpyProvider = class extends ScrcpyProvider {
221
244
  "send_device_meta=false",
222
245
  "send_codec_meta=true",
223
246
  "send_frame_meta=true",
224
- "clipboard_autosync=false"
247
+ "clipboard_autosync=false",
248
+ ...this.textOnly ? ["video=false", "power_on=false"] : []
225
249
  ]);
226
250
  this.process.once("error", () => this.fail());
227
251
  this.process.once("exit", () => this.fail());
@@ -259,6 +283,21 @@ var LocalScrcpyProvider = class extends ScrcpyProvider {
259
283
  await setTimeout$1(50);
260
284
  }
261
285
  if (!this.video) throw new Error("Scrcpy connection timed out");
286
+ if (this.textOnly) {
287
+ this.control = this.video;
288
+ this.video = void 0;
289
+ this.control.setNoDelay(true);
290
+ this.control.on("error", () => this.fail());
291
+ this.control.on("end", () => this.fail());
292
+ this.control.on("data", (data) => {
293
+ try {
294
+ this.textChannel.receive(Buffer.from(data));
295
+ } catch {
296
+ this.fail();
297
+ }
298
+ });
299
+ return;
300
+ }
262
301
  const parser = new ScrcpyVideoParser();
263
302
  this.video.on("data", (data) => {
264
303
  try {
@@ -276,7 +315,13 @@ var LocalScrcpyProvider = class extends ScrcpyProvider {
276
315
  this.control.setNoDelay(true);
277
316
  this.control.on("error", () => this.fail());
278
317
  this.control.on("end", () => this.fail());
279
- this.control.on("data", () => {});
318
+ this.control.on("data", (data) => {
319
+ try {
320
+ this.textChannel.receive(Buffer.from(data));
321
+ } catch {
322
+ this.fail();
323
+ }
324
+ });
280
325
  await new Promise((resolve, reject) => {
281
326
  this.control.once("connect", resolve);
282
327
  this.control.once("error", reject);
@@ -0,0 +1,13 @@
1
+ import { type PhoneAction, type PhoneElementSelector, type PhoneObservation } from './contracts.js';
2
+ export type PhonePrimitiveAction = Exclude<PhoneAction, {
3
+ type: 'tapElement';
4
+ }>;
5
+ /** Offer exact identities only when one fully visible native node matches. */
6
+ export declare function phoneSemanticControls(screen: PhoneObservation): Array<{
7
+ frameId: string;
8
+ selector: PhoneElementSelector;
9
+ }>;
10
+ /** Ground ordinary model taps only when native hit-testing identifies one bounded control. */
11
+ export declare function groundPhoneCoordinateAction(action: PhoneAction, screen: PhoneObservation): PhoneAction;
12
+ /** Resolve against the prediction snapshot and a fresh snapshot before any dispatch. */
13
+ export declare function resolvePhoneSemanticAction(action: PhoneAction, predicted: PhoneObservation, fresh?: PhoneObservation): PhonePrimitiveAction;
@@ -0,0 +1,76 @@
1
+ import { PhoneActionSchema, PhoneError, init_contracts } from "./contracts.js";
2
+ import { canDispatchPhoneAction } from "./reliability.js";
3
+ //#region src/phone/semantic-controls.ts
4
+ init_contracts();
5
+ function visible(node, screen) {
6
+ const [left, top, right, bottom] = node.bounds;
7
+ return !node.password && node.bounds.every(Number.isFinite) && left >= 0 && top >= 0 && right <= screen.width && bottom <= screen.height && right > left && bottom > top;
8
+ }
9
+ function matches(node, selector) {
10
+ return (selector.resourceId === void 0 || node.resourceId === selector.resourceId) && (selector.text === void 0 || node.text === selector.text) && (selector.description === void 0 || node.description === selector.description);
11
+ }
12
+ function candidates(screen, selector) {
13
+ return screen.elements.filter((node) => visible(node, screen) && matches(node, selector));
14
+ }
15
+ function exactSelector(node) {
16
+ const selector = {};
17
+ if (node.resourceId && node.resourceId.length <= 300) selector.resourceId = node.resourceId;
18
+ if (node.text && node.text.length <= 4e3) selector.text = node.text;
19
+ if (node.description && node.description.length <= 1e3) selector.description = node.description;
20
+ return selector;
21
+ }
22
+ /** Offer exact identities only when one fully visible native node matches. */
23
+ function phoneSemanticControls(screen) {
24
+ return screen.elements.filter((node) => visible(node, screen)).flatMap((node) => {
25
+ const selector = exactSelector(node);
26
+ return Object.keys(selector).length && candidates(screen, selector).length === 1 ? [{
27
+ frameId: screen.frameId,
28
+ selector
29
+ }] : [];
30
+ }).slice(0, 40);
31
+ }
32
+ function containsPoint(node, x, y) {
33
+ return x >= node.bounds[0] && y >= node.bounds[1] && x < node.bounds[2] && y < node.bounds[3];
34
+ }
35
+ function containsNode(outer, inner) {
36
+ return outer.bounds[0] <= inner.bounds[0] && outer.bounds[1] <= inner.bounds[1] && outer.bounds[2] >= inner.bounds[2] && outer.bounds[3] >= inner.bounds[3];
37
+ }
38
+ /** Ground ordinary model taps only when native hit-testing identifies one bounded control. */
39
+ function groundPhoneCoordinateAction(action, screen) {
40
+ if (action.type !== "tap") return action;
41
+ const [x, y] = [action.point[0] * screen.width / 1e3, action.point[1] * screen.height / 1e3];
42
+ if (screen.elements.some((node) => node.password && containsPoint(node, x, y))) return action;
43
+ const actionable = screen.elements.filter((node) => visible(node, screen) && (node.clickable || node.editable));
44
+ const hits = actionable.filter((node) => containsPoint(node, x, y));
45
+ const smallest = hits.filter((node) => hits.every((other) => other === node || containsNode(other, node)));
46
+ if (smallest.length !== 1) return action;
47
+ const target = smallest[0];
48
+ if ((target.bounds[2] - target.bounds[0]) * (target.bounds[3] - target.bounds[1]) > screen.width * screen.height / 4) return action;
49
+ const selector = exactSelector(target);
50
+ if (!Object.keys(selector).length || candidates(screen, selector).length !== 1) return action;
51
+ const [centerX, centerY] = [(target.bounds[0] + target.bounds[2]) / 2, (target.bounds[1] + target.bounds[3]) / 2];
52
+ if (screen.elements.some((node) => node.password && containsPoint(node, centerX, centerY)) || actionable.some((node) => node !== target && containsPoint(node, centerX, centerY) && !containsNode(node, target))) return action;
53
+ return {
54
+ type: "tapElement",
55
+ frameId: screen.frameId,
56
+ selector
57
+ };
58
+ }
59
+ /** Resolve against the prediction snapshot and a fresh snapshot before any dispatch. */
60
+ function resolvePhoneSemanticAction(action, predicted, fresh = predicted) {
61
+ if (action.type !== "tapElement") return action;
62
+ if (!PhoneActionSchema.safeParse(action).success) throw new PhoneError("PHONE_SEMANTIC_INVALID", "Invalid exact native element selector", 409);
63
+ if (action.frameId !== predicted.frameId) throw new PhoneError("PHONE_SEMANTIC_STALE", "Native element belongs to a different observation", 409);
64
+ const before = candidates(predicted, action.selector);
65
+ const after = candidates(fresh, action.selector);
66
+ if (before.length !== 1 || after.length !== 1) throw new PhoneError("PHONE_SEMANTIC_TARGET", "Native element selector must match exactly one fully visible non-password node", 409);
67
+ const target = after[0];
68
+ const resolved = {
69
+ type: "tap",
70
+ point: [500 * (target.bounds[0] + target.bounds[2]) / fresh.width, 500 * (target.bounds[1] + target.bounds[3]) / fresh.height]
71
+ };
72
+ if (JSON.stringify(before[0]) !== JSON.stringify(target) || !canDispatchPhoneAction(resolved, predicted, fresh)) throw new PhoneError("PHONE_SEMANTIC_STALE", "Native element or page changed before dispatch", 409);
73
+ return resolved;
74
+ }
75
+ //#endregion
76
+ export { groundPhoneCoordinateAction, phoneSemanticControls, resolvePhoneSemanticAction };
@@ -0,0 +1,148 @@
1
+ import type { PhoneSetupView } from '@xopcai/gateway-contract';
2
+ import type { PhoneInput } from '../contracts.js';
3
+ import type { PhoneRuntime } from '../runtime.js';
4
+ type Context = {
5
+ conversationId: string;
6
+ agentId: string;
7
+ };
8
+ type Setup = Omit<PhoneSetupView, 'readiness' | 'stale' | 'settingsPath' | 'guidanceRefs'> & {
9
+ environmentRevision?: string;
10
+ calls: number;
11
+ owner?: string;
12
+ };
13
+ export interface PhoneSetupDeps {
14
+ runtime: PhoneRuntime;
15
+ inspect(context: Context, source?: 'local' | 'aliyun'): Promise<PhoneSetupView['readiness']>;
16
+ revision(context: Context, deviceId: string): string;
17
+ connected(deviceId: string, signal?: AbortSignal): Promise<boolean>;
18
+ leaseActive(deviceId: string): boolean;
19
+ }
20
+ /** Setup only orchestrates existing settings; secrets and configuration writes stay in product forms. */
21
+ export declare class PhoneSetupService {
22
+ private readonly deps;
23
+ constructor(deps: PhoneSetupDeps);
24
+ private store;
25
+ current(context: Context): Setup;
26
+ private save;
27
+ private owned;
28
+ view(context: Context, setup: Setup): Promise<PhoneSetupView>;
29
+ command(command: string, args: Record<string, unknown>, context: Context, dryRun?: boolean): Promise<PhoneSetupView | {
30
+ dryRun?: boolean;
31
+ sceneId: string;
32
+ skillName: string;
33
+ readiness: {
34
+ enabled: boolean;
35
+ toolAllowed: boolean;
36
+ model: {
37
+ ref?: string;
38
+ chatRef?: string;
39
+ source?: "system" | "global" | "agent";
40
+ supported: boolean;
41
+ configured: boolean;
42
+ };
43
+ dependencies: Array<{
44
+ kind: "adb" | "scrcpy";
45
+ state: string;
46
+ version?: string;
47
+ canInstall: boolean;
48
+ }>;
49
+ devices: Array<{
50
+ id: string;
51
+ name: string;
52
+ source: "local" | "aliyun";
53
+ enabled: boolean;
54
+ settingsAllowed: boolean;
55
+ }>;
56
+ localDiscovery: Array<{
57
+ name: string;
58
+ state: string;
59
+ emulator: boolean;
60
+ }>;
61
+ diagnostic?: string;
62
+ };
63
+ setup: PhoneSetupView;
64
+ settingsPath: string;
65
+ guidanceRefs: {
66
+ sceneId: string;
67
+ path: string;
68
+ resourceVersion: string;
69
+ }[];
70
+ } | {
71
+ message: string;
72
+ id: string;
73
+ conversationId: string;
74
+ agentId: string;
75
+ revision: number;
76
+ state: "configuring" | "verifying" | "completed" | "needs_attention" | "cancelled";
77
+ source?: "local" | "aliyun";
78
+ error?: string;
79
+ stale: boolean;
80
+ settingsPath: string;
81
+ readiness: {
82
+ enabled: boolean;
83
+ toolAllowed: boolean;
84
+ model: {
85
+ ref?: string;
86
+ chatRef?: string;
87
+ source?: "system" | "global" | "agent";
88
+ supported: boolean;
89
+ configured: boolean;
90
+ };
91
+ dependencies: Array<{
92
+ kind: "adb" | "scrcpy";
93
+ state: string;
94
+ version?: string;
95
+ canInstall: boolean;
96
+ }>;
97
+ devices: Array<{
98
+ id: string;
99
+ name: string;
100
+ source: "local" | "aliyun";
101
+ enabled: boolean;
102
+ settingsAllowed: boolean;
103
+ }>;
104
+ localDiscovery: Array<{
105
+ name: string;
106
+ state: string;
107
+ emulator: boolean;
108
+ }>;
109
+ diagnostic?: string;
110
+ };
111
+ checks: {
112
+ configured: boolean;
113
+ read: boolean;
114
+ operated: boolean;
115
+ verified: boolean;
116
+ released: boolean;
117
+ };
118
+ attempt?: {
119
+ id: string;
120
+ deviceId: string;
121
+ modelRef: string;
122
+ sessionId?: string;
123
+ goal: string;
124
+ completion: {
125
+ appPackage: string;
126
+ textAny: string[];
127
+ requireChange: boolean;
128
+ };
129
+ maxActions: number;
130
+ expiresAt: number;
131
+ released: boolean;
132
+ };
133
+ guidanceRefs: Array<{
134
+ sceneId: "phone";
135
+ path: string;
136
+ resourceVersion: string;
137
+ }>;
138
+ }>;
139
+ source(context: Context, id: string, source: 'local' | 'aliyun', revision: number): Promise<PhoneSetupView>;
140
+ begin(context: Context, id: string, deviceId: string, revision: number, signal?: AbortSignal): Promise<PhoneSetupView>;
141
+ beforeInput(context: Context, input: PhoneInput): {
142
+ owner: string;
143
+ input: PhoneInput;
144
+ } | undefined;
145
+ afterInput(context: Context, owner: string, op: PhoneInput['op']): void;
146
+ release(context: Context, id: string): Promise<PhoneSetupView>;
147
+ }
148
+ export {};
@@ -0,0 +1,251 @@
1
+ import { DurableState } from "../../storage/sqlite/durable-state.js";
2
+ import { randomUUID } from "node:crypto";
3
+ //#region src/phone/setup/service.ts
4
+ /** Setup only orchestrates existing settings; secrets and configuration writes stay in product forms. */
5
+ var PhoneSetupService = class {
6
+ constructor(deps) {
7
+ this.deps = deps;
8
+ }
9
+ store(context) {
10
+ return new DurableState("phone.setup", context.conversationId);
11
+ }
12
+ current(context) {
13
+ return this.store(context).get(context.agentId);
14
+ }
15
+ save(context, next, expected = next.revision) {
16
+ return this.store(context).update(context.agentId, (previous) => {
17
+ if (previous && previous.revision !== expected) throw new Error("PHONE_SETUP_CONFLICT: Refresh the saved progress.");
18
+ const value = {
19
+ ...next,
20
+ revision: expected + 1
21
+ };
22
+ return {
23
+ value,
24
+ result: value
25
+ };
26
+ });
27
+ }
28
+ owned(context, id) {
29
+ const setup = this.current(context);
30
+ if (!setup || setup.id !== id) throw new Error("PHONE_SETUP_NOT_FOUND");
31
+ return setup;
32
+ }
33
+ async view(context, setup) {
34
+ const { owner: _owner, calls: _calls, environmentRevision: _revision, ...summary } = setup;
35
+ const stale = Boolean(setup.attempt && setup.environmentRevision !== this.deps.revision(context, setup.attempt.deviceId));
36
+ const interrupted = setup.state === "verifying" && (Date.now() > setup.attempt.expiresAt || Boolean(setup.attempt?.sessionId && !this.deps.runtime.status(setup.owner)));
37
+ return {
38
+ ...summary,
39
+ stale,
40
+ state: interrupted ? "needs_attention" : setup.state,
41
+ error: interrupted ? "PHONE_SETUP_INTERRUPTED: Release or confirm lease expiry before starting a fresh test." : setup.error,
42
+ readiness: await this.deps.inspect(context, setup.source),
43
+ settingsPath: `/settings/phone-use?phoneSetup=${setup.id}&conversationId=${context.conversationId}`,
44
+ guidanceRefs: [{
45
+ sceneId: "phone",
46
+ path: `references/phone/${setup.state === "verifying" ? "acceptance" : setup.error || interrupted || stale ? "troubleshooting" : setup.source === "aliyun" ? "aliyun" : setup.source === "local" ? "local" : "overview"}.md`,
47
+ resourceVersion: "1"
48
+ }]
49
+ };
50
+ }
51
+ async command(command, args, context, dryRun = false) {
52
+ let setup = this.current(context);
53
+ if (command === "inspect" || command === "preview" || dryRun) return {
54
+ sceneId: "phone",
55
+ skillName: "configure-xopc",
56
+ readiness: await this.deps.inspect(context, setup?.source),
57
+ setup: setup ? await this.view(context, setup) : null,
58
+ settingsPath: `/settings/phone-use?conversationId=${context.conversationId}`,
59
+ guidanceRefs: [{
60
+ sceneId: "phone",
61
+ path: "references/phone/overview.md",
62
+ resourceVersion: "1"
63
+ }],
64
+ ...dryRun ? { dryRun: true } : {}
65
+ };
66
+ if (command === "start") {
67
+ if (!setup || ["completed", "cancelled"].includes(setup.state) && (!setup.attempt || setup.attempt.released)) setup = this.save(context, {
68
+ id: randomUUID(),
69
+ ...context,
70
+ state: "configuring",
71
+ revision: setup?.revision ?? 0,
72
+ calls: 0,
73
+ checks: {
74
+ configured: false,
75
+ read: false,
76
+ operated: false,
77
+ verified: false,
78
+ released: false
79
+ }
80
+ });
81
+ return this.view(context, setup);
82
+ }
83
+ if (typeof args.setupId !== "string") throw new Error("setupId is required");
84
+ setup = this.owned(context, args.setupId);
85
+ if ([
86
+ "get",
87
+ "recheck",
88
+ "verification_report"
89
+ ].includes(command)) return this.view(context, setup);
90
+ if (command === "begin_verification") return {
91
+ ...await this.view(context, setup),
92
+ message: "Choose the phone and approve the Settings-only test in the original conversation panel."
93
+ };
94
+ if (command === "cancel") {
95
+ setup = this.save(context, {
96
+ ...setup,
97
+ state: "cancelled"
98
+ });
99
+ return this.release(context, setup.id);
100
+ }
101
+ throw new Error("Unsupported phone_setup command");
102
+ }
103
+ async source(context, id, source, revision) {
104
+ const setup = this.owned(context, id);
105
+ if (setup.revision !== revision || setup.attempt && !setup.attempt.released) throw new Error("PHONE_SETUP_CONFLICT: Release the active test before changing connection.");
106
+ if (setup.state === "cancelled" || setup.state === "completed") throw new Error("PHONE_SETUP_CLOSED: Start a new setup before changing connection.");
107
+ return this.view(context, this.save(context, {
108
+ ...setup,
109
+ source
110
+ }));
111
+ }
112
+ async begin(context, id, deviceId, revision, signal) {
113
+ let setup = this.owned(context, id);
114
+ if (setup.revision !== revision || setup.state === "cancelled" || setup.attempt && !setup.attempt.released) throw new Error("PHONE_SETUP_CONFLICT: Refresh progress and release the old test.");
115
+ const environmentRevision = this.deps.revision(context, deviceId);
116
+ const readiness = await this.deps.inspect(context, setup.source);
117
+ const device = readiness.devices.find((device) => device.id === deviceId);
118
+ if (!readiness.enabled || !readiness.toolAllowed) throw new Error("PHONE_SETUP_PERMISSION_REQUIRED: Enable Phone Use and allow this Agent in product settings.");
119
+ if (!readiness.model.ref || !readiness.model.supported || !readiness.model.configured) throw new Error("PHONE_SETUP_MODEL_REQUIRED: Save a configured real Phone Use model.");
120
+ if (!device?.enabled || !device.settingsAllowed) throw new Error("PHONE_SETUP_DEVICE_REQUIRED: Choose an enabled phone allowing Settings.");
121
+ if (setup.source && setup.source !== device.source) throw new Error("PHONE_SETUP_SOURCE_MISMATCH");
122
+ if (device.source === "local" && !readiness.dependencies.some((item) => item.kind === "adb" && item.state === "ready")) throw new Error("PHONE_SETUP_ADB_REQUIRED");
123
+ if (!await this.deps.connected(deviceId, signal)) throw new Error("PHONE_SETUP_DEVICE_OFFLINE: Authorize USB debugging or check cloud connection.");
124
+ const latest = this.owned(context, id);
125
+ if (latest.revision !== revision || environmentRevision !== this.deps.revision(context, deviceId)) throw new Error("PHONE_SETUP_CONFLICT");
126
+ const attempt = {
127
+ id: randomUUID(),
128
+ deviceId,
129
+ modelRef: readiness.model.ref,
130
+ goal: "From the Android Settings About phone page, open Android version details and read the version. Do not change any setting.",
131
+ completion: {
132
+ appPackage: "com.android.settings",
133
+ textAny: [
134
+ "Android version",
135
+ "Android 版本",
136
+ "Android版本"
137
+ ],
138
+ requireChange: true
139
+ },
140
+ maxActions: 6,
141
+ expiresAt: Date.now() + 3e5,
142
+ released: false
143
+ };
144
+ setup = this.save(context, {
145
+ ...latest,
146
+ state: "verifying",
147
+ source: device.source,
148
+ error: void 0,
149
+ attempt,
150
+ owner: `phone-setup:${latest.id}:${attempt.id}`,
151
+ environmentRevision,
152
+ calls: 0,
153
+ checks: {
154
+ configured: true,
155
+ read: false,
156
+ operated: false,
157
+ verified: false,
158
+ released: false
159
+ }
160
+ });
161
+ return this.view(context, setup);
162
+ }
163
+ beforeInput(context, input) {
164
+ const setup = this.current(context);
165
+ if (!setup?.attempt || setup.attempt.released || input.op === "discover") return void 0;
166
+ const cleanup = input.op === "close" || input.op === "cancel";
167
+ if (!cleanup && (setup.state !== "verifying" || Date.now() > setup.attempt.expiresAt || setup.calls >= 12 || setup.environmentRevision !== this.deps.revision(context, setup.attempt.deviceId))) throw new Error("PHONE_SETUP_STOPPED: Release the setup test and review the current state.");
168
+ if (!(cleanup || input.op === "status" || input.op === "observe" || input.op === "pause" || input.op === "open" && input.deviceId === setup.attempt.deviceId && input.mode === "control" && input.appPackage === "com.android.settings" || (input.op === "run" || input.op === "step") && input.goal === setup.attempt.goal && !input.scenario && input.completion?.appPackage === setup.attempt.completion.appPackage && input.completion.requireChange === true && JSON.stringify(input.completion.textAny) === JSON.stringify(setup.attempt.completion.textAny) && !input.completion.textAll && !input.completion.field && (input.maxActions ?? 6) <= 6)) throw new Error("PHONE_SETUP_ACTION_DENIED: Use only the approved Settings test.");
169
+ this.save(context, {
170
+ ...setup,
171
+ calls: setup.calls + 1
172
+ });
173
+ if (input.op === "run" || input.op === "step") {
174
+ const report = this.deps.runtime.status(setup.owner);
175
+ const openingActions = report?.steps[0]?.action === "launch" ? 1 : 0;
176
+ const remaining = 6 - Math.max(0, (report?.actions ?? 0) - openingActions);
177
+ if (remaining <= 0) throw new Error("PHONE_SETUP_BUDGET_EXHAUSTED: Close the test and review its evidence.");
178
+ return {
179
+ owner: setup.owner,
180
+ input: {
181
+ ...input,
182
+ maxActions: Math.min(input.maxActions ?? 6, remaining)
183
+ }
184
+ };
185
+ }
186
+ return {
187
+ owner: setup.owner,
188
+ input: input.op === "open" ? {
189
+ ...input,
190
+ settingsPage: "about-phone"
191
+ } : input
192
+ };
193
+ }
194
+ afterInput(context, owner, op) {
195
+ const setup = this.current(context);
196
+ if (!setup?.attempt || setup.owner !== owner) return;
197
+ const report = this.deps.runtime.status(owner);
198
+ if (!report || report.deviceId !== setup.attempt.deviceId || report.modelRef !== setup.attempt.modelRef || setup.attempt.sessionId && report.sessionId !== setup.attempt.sessionId) return;
199
+ const released = op === "close" && report.status === "closed" && report.controlOwner === "none";
200
+ const valid = setup.state === "verifying" && setup.environmentRevision === this.deps.revision(context, report.deviceId) && Date.now() <= setup.attempt.expiresAt;
201
+ const modelActions = Math.max(0, report.actions - (report.steps[0]?.action === "launch" ? 1 : 0));
202
+ const verified = valid && !report.mock && report.mode === "control" && report.verified && report.verificationLevel === "ui" && report.modelRequests > 0 && modelActions > 0;
203
+ const checks = {
204
+ ...setup.checks,
205
+ ...valid ? {
206
+ read: setup.checks.read || Boolean(report.facts?.length),
207
+ operated: setup.checks.operated || modelActions > 0,
208
+ verified: setup.checks.verified || verified
209
+ } : {},
210
+ released: setup.checks.released || released
211
+ };
212
+ this.save(context, {
213
+ ...setup,
214
+ checks,
215
+ attempt: {
216
+ ...setup.attempt,
217
+ sessionId: report.sessionId,
218
+ released: checks.released
219
+ },
220
+ state: setup.state === "cancelled" ? "cancelled" : released ? valid && checks.verified && checks.read ? "completed" : "needs_attention" : setup.state,
221
+ error: released && !(valid && checks.verified && checks.read) ? report.errorCode === "PHONE_MODEL_QUOTA_EXHAUSTED" ? "PHONE_MODEL_QUOTA_EXHAUSTED: Wait for the Phone model quota to reset or select a configured compatible model; device control was released." : "PHONE_SETUP_INCOMPLETE: Review progress and start a fresh test." : setup.error
222
+ });
223
+ }
224
+ async release(context, id) {
225
+ let setup = this.owned(context, id);
226
+ if (!setup.attempt || setup.attempt.released) return this.view(context, setup);
227
+ if (!this.deps.runtime.status(setup.owner)) {
228
+ if (this.deps.leaseActive(setup.attempt.deviceId)) throw new Error("PHONE_SETUP_LEASE_PENDING: Control expiry is not confirmed yet. Wait and recheck.");
229
+ setup = this.save(context, {
230
+ ...setup,
231
+ state: setup.state === "cancelled" ? "cancelled" : "needs_attention",
232
+ attempt: {
233
+ ...setup.attempt,
234
+ released: true
235
+ },
236
+ checks: {
237
+ ...setup.checks,
238
+ released: true
239
+ },
240
+ error: "PHONE_SETUP_RESTARTED: Lease expiry confirmed; start a fresh test."
241
+ });
242
+ } else {
243
+ await this.deps.runtime.stop(setup.owner, "close");
244
+ this.afterInput(context, setup.owner, "close");
245
+ setup = this.owned(context, id);
246
+ }
247
+ return this.view(context, setup);
248
+ }
249
+ };
250
+ //#endregion
251
+ export { PhoneSetupService };
@@ -239,7 +239,7 @@ function modelToCatalogView(model) {
239
239
  ...model.contextWindow ? { contextWindow: model.contextWindow } : {},
240
240
  ...model.maxTokens ? { maxTokens: model.maxTokens } : {},
241
241
  vision: input.includes("image"),
242
- recommended: !isDedicatedComputerModel(model) && isRecommendedModel(model.provider, model.id)
242
+ recommended: !("phoneUse" in model && model.phoneUse) && !isDedicatedComputerModel(model) && isRecommendedModel(model.provider, model.id)
243
243
  };
244
244
  }
245
245
  function presetModelToCatalogView(provider, model) {
@@ -267,7 +267,7 @@ function sortModelsForPicker(models) {
267
267
  });
268
268
  }
269
269
  function getRecommendedModelsForProvider(provider, limit = 4) {
270
- const fromRegistry = sortModelsForPicker(getModelsByProvider(provider)).filter((model) => !isDedicatedComputerModel(model) && isRecommendedModel(provider, model.id)).slice(0, limit).map(modelToCatalogView);
270
+ const fromRegistry = sortModelsForPicker(getModelsByProvider(provider)).filter((model) => !("phoneUse" in model && model.phoneUse) && !isDedicatedComputerModel(model) && isRecommendedModel(provider, model.id)).slice(0, limit).map(modelToCatalogView);
271
271
  if (fromRegistry.length > 0) return fromRegistry;
272
272
  const preset = getDomesticProviderPreset(provider);
273
273
  if (!preset) return [];