@xopcai/xopc 0.0.368 → 0.0.369

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 (244) hide show
  1. package/dist/browser-ext/_locales/en/messages.json +30 -1
  2. package/dist/browser-ext/_locales/zh_CN/messages.json +30 -1
  3. package/dist/browser-ext/dist/assets/{auth-beGtbLPS.js → page-context-BeworyNB.js} +1331 -1355
  4. package/dist/browser-ext/dist/assets/{sidepanel-BT0ojEzG.css → sidepanel-Ccl0eSa1.css} +43 -0
  5. package/dist/browser-ext/dist/background.js +680 -182
  6. package/dist/browser-ext/dist/sidepanel.html +2 -2
  7. package/dist/browser-ext/dist/sidepanel.js +372 -193
  8. package/dist/browser-ext/manifest.json +2 -8
  9. package/dist/extensions/telegram/xopc.extension.json +1 -1
  10. package/dist/gateway/static/root/assets/{activity-store-D9ZMh5ZR.js → activity-store-BQ3PMp2q.js} +1 -1
  11. package/dist/gateway/static/root/assets/{agent-avatar-dicebear-Bj3rvcTm.js → agent-avatar-dicebear-Stj17S9u.js} +1 -1
  12. package/dist/gateway/static/root/assets/agent-defaults-settings-panel-CCRfvuov.js +1 -0
  13. package/dist/gateway/static/root/assets/{agent-plugin-dialog-BjdgKCnk.js → agent-plugin-dialog-CRlzd8El.js} +1 -1
  14. package/dist/gateway/static/root/assets/agents-_ug2LCQb.js +66 -0
  15. package/dist/gateway/static/root/assets/{agents-admin-api-B5QDepbW.js → agents-admin-api-HBZvVyzF.js} +1 -1
  16. package/dist/gateway/static/root/assets/{app-management-settings-panel-2rTEtB_X.js → app-management-settings-panel-pJFe6M6c.js} +1 -1
  17. package/dist/gateway/static/root/assets/{appearance-settings-BPVBS80k.js → appearance-settings-BrxSpBWa.js} +1 -1
  18. package/dist/gateway/static/root/assets/{apps-page-1FuKlZYP.js → apps-page-DegSl5Lh.js} +1 -1
  19. package/dist/gateway/static/root/assets/{archive-plugin-BbT1O7oK.js → archive-plugin-BO3I9zRP.js} +1 -1
  20. package/dist/gateway/static/root/assets/{automations-page-DjwP_h8h.js → automations-page-BZQ_VHjp.js} +1 -1
  21. package/dist/gateway/static/root/assets/automations-workspace-BQywN6nG.js +6 -0
  22. package/dist/gateway/static/root/assets/{binary-plugins-gS7Wg68v.js → binary-plugins-gFD7vH9R.js} +1 -1
  23. package/dist/gateway/static/root/assets/{block-editor-DbwMaivP.js → block-editor-3XjFv3kK.js} +3 -3
  24. package/dist/gateway/static/root/assets/browser-automation-inputs-DxRoKFun.js +1 -0
  25. package/dist/gateway/static/root/assets/browser-automations-page-yiEuG1v7.js +3 -0
  26. package/dist/gateway/static/root/assets/browser-settings-page-ch2_bQF0.js +3 -0
  27. package/dist/gateway/static/root/assets/{capabilities-Dd1PZRQw.js → capabilities-B48r0DDa.js} +1 -1
  28. package/dist/gateway/static/root/assets/{capabilities-Lswa0hv8.js → capabilities-DO-vfNKI.js} +1 -1
  29. package/dist/gateway/static/root/assets/{capabilities-page-djBsC_tG.js → capabilities-page-BEnFt_dj.js} +2 -2
  30. package/dist/gateway/static/root/assets/{capabilities-settings-panel-DTHR1DrJ.js → capabilities-settings-panel-NckMsJ5N.js} +4 -4
  31. package/dist/gateway/static/root/assets/{capability-header-actions-494dnJsj.js → capability-header-actions-CY8KCO9j.js} +1 -1
  32. package/dist/gateway/static/root/assets/channels-CHOS2CGa.js +1 -0
  33. package/dist/gateway/static/root/assets/{chat-terminal-dock-Bl7-Zk-x.js → chat-terminal-dock-Bwknnb4c.js} +2 -2
  34. package/dist/gateway/static/root/assets/{computer-settings-page-ByExKr_6.js → computer-settings-page-B2xeFCSt.js} +1 -1
  35. package/dist/gateway/static/root/assets/{connector-service-page-BK_5aFxO.js → connector-service-page-C83DnAqK.js} +1 -1
  36. package/dist/gateway/static/root/assets/connectors-page-D6wTmWA6.js +2 -0
  37. package/dist/gateway/static/root/assets/{date-picker-BXJv6472.js → date-picker-Bq9GR-DU.js} +1 -1
  38. package/dist/gateway/static/root/assets/{dependency-picker-CWbbhKZa.js → dependency-picker-BTERkA9X.js} +1 -1
  39. package/dist/gateway/static/root/assets/{desktop-pet-DWNEC3mk.js → desktop-pet-BwsbQw8V.js} +1 -1
  40. package/dist/gateway/static/root/assets/{desktop-pet-settings-BYwlxGiN.js → desktop-pet-settings-sL9i44pP.js} +1 -1
  41. package/dist/gateway/static/root/assets/device-pairing-wizard-DI2bqaKO.js +1 -0
  42. package/dist/gateway/static/root/assets/{directory-picker-path-field-D26tSY8Z.js → directory-picker-path-field-BFlDmsS5.js} +1 -1
  43. package/dist/gateway/static/root/assets/{extension-debug-page-xYIGNegB.js → extension-debug-page-7Z1Tp7-w.js} +1 -1
  44. package/dist/gateway/static/root/assets/{extension-page-BoQ1-3AW.js → extension-page-uGqvb8QX.js} +1 -1
  45. package/dist/gateway/static/root/assets/{extension-provider-Cw_JU6RR.js → extension-provider-xlSyz4Z6.js} +1 -1
  46. package/dist/gateway/static/root/assets/{extension-settings-page-BH5TFGPe.js → extension-settings-page-CKHgrjOs.js} +1 -1
  47. package/dist/gateway/static/root/assets/{fallback-models-04Wqmw14.js → fallback-models-BwQg0G1D.js} +1 -1
  48. package/dist/gateway/static/root/assets/{gateway-config-swr-CNf0ZeRw.js → gateway-config-swr-7RKqgU_U.js} +1 -1
  49. package/dist/gateway/static/root/assets/{gateway-realtime-C4KtwMY3.js → gateway-realtime-DDWymi-o.js} +1 -1
  50. package/dist/gateway/static/root/assets/gateway-realtime-store-BheKaO6d.js +1 -0
  51. package/dist/gateway/static/root/assets/{gateway-settings-BqvCJVUC.js → gateway-settings-BAQnSEMJ.js} +1 -1
  52. package/dist/gateway/static/root/assets/{gateway-startup-retry-DIxHacUw.js → gateway-startup-retry-jiV5sbEX.js} +1 -1
  53. package/dist/gateway/static/root/assets/home-page-BZDjvwet.js +2 -0
  54. package/dist/gateway/static/root/assets/{image-generation-api-CS0q0Kto.js → image-generation-api-DO4mXb6I.js} +1 -1
  55. package/dist/gateway/static/root/assets/{imports-page-n_rSLo6b.js → imports-page-re1_Nh64.js} +1 -1
  56. package/dist/gateway/static/root/assets/index-BB1z8QxA.js +106 -0
  57. package/dist/gateway/static/root/assets/index-D9R6tU7r.css +1 -0
  58. package/dist/gateway/static/root/assets/{keyboard-shortcuts-settings-tVkrHbYF.js → keyboard-shortcuts-settings-B_xja9LN.js} +1 -1
  59. package/dist/gateway/static/root/assets/{local-app-workbench-page-L8tYuas0.js → local-app-workbench-page-CErdCrPX.js} +1 -1
  60. package/dist/gateway/static/root/assets/{local-apps-page-SSJ9B1bH.js → local-apps-page-BPL2RXdK.js} +1 -1
  61. package/dist/gateway/static/root/assets/{local-session-drafts-B_McurIj.js → local-session-drafts-DRPsDCj1.js} +1 -1
  62. package/dist/gateway/static/root/assets/{locale-store-D6_rF-qT.js → locale-store-COVscAqC.js} +1 -1
  63. package/dist/gateway/static/root/assets/{logs-page-BWD63eg1.js → logs-page-DL-BM0xq.js} +2 -2
  64. package/dist/gateway/static/root/assets/management-settings-BOVRHhXk.js +1 -0
  65. package/dist/gateway/static/root/assets/{markdown-view-_xwUuKce.js → markdown-view-B_qnAcW2.js} +1 -1
  66. package/dist/gateway/static/root/assets/{media-plugins-C631CDu4.js → media-plugins-C0Pc-wSY.js} +1 -1
  67. package/dist/gateway/static/root/assets/messages-Bb2GK-Nj.js +3 -0
  68. package/dist/gateway/static/root/assets/models-hub-cache-DyPPksMP.js +1 -0
  69. package/dist/gateway/static/root/assets/note-detail-panel-DJJK2yL4.js +5 -0
  70. package/dist/gateway/static/root/assets/{notes-api-vIZWQ9Yt.js → notes-api-sBgBcyLW.js} +1 -1
  71. package/dist/gateway/static/root/assets/notes-page-oCxO7ZTv.js +8 -0
  72. package/dist/gateway/static/root/assets/{page-context-capture-button-BlPDM7GM.js → page-context-capture-button-tf77xIz3.js} +1 -1
  73. package/dist/gateway/static/root/assets/personal-page-DOk9gUK5.js +1 -0
  74. package/dist/gateway/static/root/assets/{product-open-page-BJjWvoER.js → product-open-page-Dc3Y-Y7J.js} +1 -1
  75. package/dist/gateway/static/root/assets/{product-preview-content-CEd4E7Gf.js → product-preview-content-MG_hmVA3.js} +1 -1
  76. package/dist/gateway/static/root/assets/{project-detail-page-DM4_VLNX.js → project-detail-page-3uAzbW4T.js} +1 -1
  77. package/dist/gateway/static/root/assets/{projects-page-lszV8HuS.js → projects-page-MllfNLGA.js} +1 -1
  78. package/dist/gateway/static/root/assets/{registry-api-uJnjqTcn.js → registry-api-Bh9UBb-f.js} +1 -1
  79. package/dist/gateway/static/root/assets/{remote-access-hub-O6j9CWX0.js → remote-access-hub-Bs-C70el.js} +1 -1
  80. package/dist/gateway/static/root/assets/{runtime-tools-settings-panel-CjnNQYW8.js → runtime-tools-settings-panel-DpJ5jNzR.js} +1 -1
  81. package/dist/gateway/static/root/assets/{scenes-page-B3T3dDOR.js → scenes-page-Dpxamkw6.js} +2 -2
  82. package/dist/gateway/static/root/assets/{schema-form-DT3c4Vd_.js → schema-form-DUeyQ1zh.js} +1 -1
  83. package/dist/gateway/static/root/assets/{send-session-input-CICkGwn-.js → send-session-input-Dgn4BRk_.js} +1 -1
  84. package/dist/gateway/static/root/assets/{session-api-BcQodoAu.js → session-api-yjpEz4pP.js} +1 -1
  85. package/dist/gateway/static/root/assets/{session-manager-B0tOE4qz.js → session-manager-LInoZ_Yi.js} +1 -1
  86. package/dist/gateway/static/root/assets/sessions-page-BCVlNHtq.js +1 -0
  87. package/dist/gateway/static/root/assets/settings-advanced-gate-Bz-ue9fZ.js +1 -0
  88. package/dist/gateway/static/root/assets/{settings-page-D-PZjcss.js → settings-page-DouHuBXt.js} +1 -1
  89. package/dist/gateway/static/root/assets/{setup-status-panel-Ce3gTbT3.js → setup-status-panel-B5BoZ-1y.js} +1 -1
  90. package/dist/gateway/static/root/assets/{share-link-dialog-CWS8EkJS.js → share-link-dialog-DJTabLAM.js} +1 -1
  91. package/dist/gateway/static/root/assets/{share-preview-page-23NJAKiq.js → share-preview-page-jw7h4t_B.js} +1 -1
  92. package/dist/gateway/static/root/assets/{shares-api-iKhHbvBD.js → shares-api-c0dfWz6h.js} +1 -1
  93. package/dist/gateway/static/root/assets/shares-settings-BlnlzGjH.js +1 -0
  94. package/dist/gateway/static/root/assets/{skill-api-C-MWdQwl.js → skill-api-CfyX_0zN.js} +1 -1
  95. package/dist/gateway/static/root/assets/{skill-reload-api-iy02aB13.js → skill-reload-api-Ge5XymHa.js} +1 -1
  96. package/dist/gateway/static/root/assets/skills-page-DjdTeYzm.js +2 -0
  97. package/dist/gateway/static/root/assets/system-settings-panel-DWf256TE.js +1 -0
  98. package/dist/gateway/static/root/assets/{task-detail-page-B2SIEyhZ.js → task-detail-page-DE6N1ZQe.js} +2 -2
  99. package/dist/gateway/static/root/assets/{task-expandable-content-D2LRR4BC.js → task-expandable-content-hYcgCEE3.js} +1 -1
  100. package/dist/gateway/static/root/assets/{theme-store-BJfhz-Zq.js → theme-store-BOfCKgl6.js} +1 -1
  101. package/dist/gateway/static/root/assets/{tracing-settings-page-aHD56iaS.js → tracing-settings-page-DDWFXcST.js} +1 -1
  102. package/dist/gateway/static/root/assets/{tunnel-api-BCf8CfTC.js → tunnel-api-BBm9esrY.js} +1 -1
  103. package/dist/gateway/static/root/assets/{usage-page-B4XUkuJd.js → usage-page-C93x89uW.js} +1 -1
  104. package/dist/gateway/static/root/assets/{use-autosave-BnnTw9RE.js → use-autosave-CSckcjFx.js} +1 -1
  105. package/dist/gateway/static/root/assets/{use-composer-attachments-Itczg0y1.js → use-composer-attachments-C7Gaaai1.js} +1 -1
  106. package/dist/gateway/static/root/assets/{use-file-preview-expanded-DJ5vyrvM.js → use-file-preview-expanded-Db2VYg1b.js} +2 -2
  107. package/dist/gateway/static/root/assets/user-model-page-B74LkVbp.js +2 -0
  108. package/dist/gateway/static/root/assets/{voice-api-key-field-BphJku8x.js → voice-api-key-field-GEw5x2fU.js} +1 -1
  109. package/dist/gateway/static/root/assets/{voice-config-api-B4u4coFj.js → voice-config-api-3yyVwXln.js} +1 -1
  110. package/dist/gateway/static/root/assets/{work-discovery-overlay-jgOEP1xw.js → work-discovery-overlay-Bs2MKiTv.js} +1 -1
  111. package/dist/gateway/static/root/assets/{workflow-run-setup-panel-N69crzRu.js → workflow-run-setup-panel-BR_U_snV.js} +2 -2
  112. package/dist/gateway/static/root/assets/workflows-page-Crk4SxtC.js +6 -0
  113. package/dist/gateway/static/root/assets/{workspace-api-Lzv6GDO8.js → workspace-api-Si2o3inw.js} +2 -2
  114. package/dist/gateway/static/root/index.html +27 -27
  115. package/dist/package.js +1 -1
  116. package/dist/packages/browser-control-contract/src/automation.js +213 -0
  117. package/dist/packages/browser-control-contract/src/index.js +43 -12
  118. package/dist/packages/gateway-contract/src/gateway-scopes.js +3 -1
  119. package/dist/packages/gateway-contract/src/notifications.js +1 -0
  120. package/dist/packages/realtime-protocol/src/voice.js +9 -3
  121. package/dist/src/agent/coding/repository-instructions.js +8 -1
  122. package/dist/src/agent/tool-manuals/browser.d.ts +1 -1
  123. package/dist/src/agent/tool-manuals/browser.js +3 -3
  124. package/dist/src/agent/tools/browser/tool/browser-use-tool.js +1 -1
  125. package/dist/src/agent/tools/browser/tool/schemas.d.ts +0 -13
  126. package/dist/src/agent/tools/browser/tool/schemas.js +0 -4
  127. package/dist/src/agent/tools/browser-automation-tool.d.ts +74 -1
  128. package/dist/src/agent/tools/browser-automation-tool.js +52 -6
  129. package/dist/src/automations/capabilities/write.d.ts +2 -0
  130. package/dist/src/automations/domain/types.d.ts +11 -0
  131. package/dist/src/automations/domain/validation.d.ts +4 -0
  132. package/dist/src/automations/domain/validation.js +1 -0
  133. package/dist/src/automations/draft/automation-draft-validator.d.ts +1 -0
  134. package/dist/src/automations/service/action-executor.js +11 -3
  135. package/dist/src/automations/service/automation-service.d.ts +1 -0
  136. package/dist/src/automations/service/automation-service.js +13 -1
  137. package/dist/src/bootstrap/application-state.js +1 -1
  138. package/dist/src/browser/automations/repository.d.ts +4 -0
  139. package/dist/src/browser/automations/repository.js +27 -6
  140. package/dist/src/browser/automations/runner.js +101 -9
  141. package/dist/src/browser/automations/runtime-service.js +4 -3
  142. package/dist/src/browser/automations/schema.d.ts +84 -1
  143. package/dist/src/browser/automations/schema.js +68 -2
  144. package/dist/src/browser/automations/service.d.ts +78 -1
  145. package/dist/src/browser/automations/service.js +36 -4
  146. package/dist/src/browser/automations/types.d.ts +19 -4
  147. package/dist/src/browser/drivers/extension-driver.d.ts +5 -5
  148. package/dist/src/browser/drivers/extension-driver.js +10 -10
  149. package/dist/src/browser/drivers/playwright-driver.js +46 -0
  150. package/dist/src/browser/index.d.ts +1 -2
  151. package/dist/src/browser/index.js +2 -3
  152. package/dist/src/browser/policy/browser-policy.d.ts +0 -1
  153. package/dist/src/browser/policy/browser-policy.js +1 -4
  154. package/dist/src/browser/providers/index.d.ts +1 -1
  155. package/dist/src/browser/providers/index.js +2 -2
  156. package/dist/src/browser/providers/realtime-extension.d.ts +1 -1
  157. package/dist/src/browser/providers/realtime-extension.js +5 -1
  158. package/dist/src/browser/recordings/service.d.ts +22 -0
  159. package/dist/src/browser/recordings/service.js +160 -0
  160. package/dist/src/browser/runtime/browser-runtime.d.ts +1 -1
  161. package/dist/src/browser/runtime/browser-runtime.js +19 -56
  162. package/dist/src/cli/commands/doctor/checks/database-schema.js +1 -1
  163. package/dist/src/computer/runtime.js +2 -2
  164. package/dist/src/config/schema.d.ts +12 -12
  165. package/dist/src/config/schema.js +12 -12
  166. package/dist/src/endpoint-tools/policy.js +4 -3
  167. package/dist/src/gateway/hono/routes/browser-automations.js +23 -7
  168. package/dist/src/gateway/hono/routes/browser-recordings.d.ts +3 -0
  169. package/dist/src/gateway/hono/routes/browser-recordings.js +78 -0
  170. package/dist/src/gateway/hono/routes/browser.js +1 -34
  171. package/dist/src/gateway/hono/routes/device-push.js +1 -0
  172. package/dist/src/gateway/hono/routes/home.js +1 -1
  173. package/dist/src/gateway/hono/routes/lazy-bundles.js +8 -0
  174. package/dist/src/gateway/hono/routes/personal-agent.js +35 -0
  175. package/dist/src/gateway/hono/routes/voice.js +5 -2
  176. package/dist/src/gateway/security/gateway-scopes.js +3 -1
  177. package/dist/src/gateway/service/agent-runner.js +1 -0
  178. package/dist/src/home-intelligence/generator.d.ts +2 -0
  179. package/dist/src/home-intelligence/generator.js +53 -4
  180. package/dist/src/home-intelligence/host.d.ts +2 -1
  181. package/dist/src/home-intelligence/host.js +23 -3
  182. package/dist/src/migrations/cloud-public-models.js +1 -0
  183. package/dist/src/notifications/clarification.d.ts +5 -0
  184. package/dist/src/notifications/clarification.js +66 -0
  185. package/dist/src/notifications/device-store.js +1 -0
  186. package/dist/src/notifications/harmony-push.d.ts +1 -0
  187. package/dist/src/notifications/harmony-push.js +3 -1
  188. package/dist/src/notifications/planner.d.ts +1 -0
  189. package/dist/src/notifications/service.d.ts +2 -2
  190. package/dist/src/notifications/service.js +20 -4
  191. package/dist/src/notifications/store.d.ts +2 -0
  192. package/dist/src/notifications/store.js +7 -1
  193. package/dist/src/notifications/types.d.ts +1 -0
  194. package/dist/src/notifications/types.js +1 -0
  195. package/dist/src/storage/sqlite/clarification-wait-repository.js +1 -0
  196. package/dist/src/storage/sqlite/migrations/238_browser_record_replay.sql +45 -0
  197. package/dist/src/storage/sqlite/migrations/239_clarification_notifications.sql +26 -0
  198. package/dist/src/storage/sqlite/migrations/runner.d.ts +1 -1
  199. package/dist/src/storage/sqlite/migrations/runner.js +3 -3
  200. package/dist/src/storage/sqlite/schema.js +1 -1
  201. package/dist/src/tasks/home-query-service.d.ts +1 -1
  202. package/dist/src/tasks/home-query-service.js +6 -2
  203. package/dist/src/voice/dashscope/streaming-tts-stream.d.ts +2 -1
  204. package/dist/src/voice/dashscope/streaming-tts-stream.js +135 -79
  205. package/dist/src/voice/realtime/agentEngine.js +78 -1
  206. package/dist/src/voice/realtime/speakable-segmenter.d.ts +2 -0
  207. package/dist/src/voice/realtime/speakable-segmenter.js +30 -0
  208. package/dist/src/voice/tts/providers/alibaba-speech.js +17 -1
  209. package/dist/src/voice/tts/speak-core.d.ts +3 -0
  210. package/dist/src/voice/tts/speak-core.js +21 -1
  211. package/dist/src/voice/tts/speech-provider-types.d.ts +8 -0
  212. package/package.json +3 -3
  213. package/dist/gateway/static/root/assets/agent-defaults-settings-panel-D0tD3kCe.js +0 -1
  214. package/dist/gateway/static/root/assets/agents-CWXKzX5L.js +0 -66
  215. package/dist/gateway/static/root/assets/automations-workspace-C9ZT6TAU.js +0 -6
  216. package/dist/gateway/static/root/assets/browser-automation-inputs-CXG_JveC.js +0 -1
  217. package/dist/gateway/static/root/assets/browser-automations-page-CJc7OKR3.js +0 -3
  218. package/dist/gateway/static/root/assets/browser-settings-page-BjaTEUR8.js +0 -3
  219. package/dist/gateway/static/root/assets/channels-BaYRJtz3.js +0 -1
  220. package/dist/gateway/static/root/assets/connectors-page-DyqRwSH2.js +0 -2
  221. package/dist/gateway/static/root/assets/device-pairing-wizard-BAc4F35b.js +0 -1
  222. package/dist/gateway/static/root/assets/gateway-realtime-store-ChZUzVbe.js +0 -1
  223. package/dist/gateway/static/root/assets/home-page-DhPPLbdD.js +0 -2
  224. package/dist/gateway/static/root/assets/index-CK4O2xMa.css +0 -1
  225. package/dist/gateway/static/root/assets/index-DpLD-7Hc.js +0 -106
  226. package/dist/gateway/static/root/assets/management-settings-aKSibklM.js +0 -1
  227. package/dist/gateway/static/root/assets/messages-Bnx3GMDB.js +0 -3
  228. package/dist/gateway/static/root/assets/models-hub-cache-Di83uIPw.js +0 -1
  229. package/dist/gateway/static/root/assets/note-detail-panel-B_fve3_2.js +0 -5
  230. package/dist/gateway/static/root/assets/notes-page-DnChyp8S.js +0 -8
  231. package/dist/gateway/static/root/assets/personal-page-BM2qAgg_.js +0 -1
  232. package/dist/gateway/static/root/assets/sessions-page-BIixHXlQ.js +0 -1
  233. package/dist/gateway/static/root/assets/settings-advanced-gate-49SUEWPh.js +0 -1
  234. package/dist/gateway/static/root/assets/shares-settings-CNEZjF66.js +0 -1
  235. package/dist/gateway/static/root/assets/skills-page-BndNdYsJ.js +0 -2
  236. package/dist/gateway/static/root/assets/system-settings-panel-EpZeMlvp.js +0 -1
  237. package/dist/gateway/static/root/assets/user-model-page-Bz5lkFG9.js +0 -2
  238. package/dist/gateway/static/root/assets/workflows-page-CPCgOfHh.js +0 -6
  239. package/dist/src/browser/policy/approval-store.d.ts +0 -17
  240. package/dist/src/browser/policy/approval-store.js +0 -62
  241. package/dist/src/browser/providers/extension-ws-acquire.d.ts +0 -19
  242. package/dist/src/browser/providers/extension-ws-acquire.js +0 -78
  243. package/dist/src/browser/providers/extension.d.ts +0 -61
  244. package/dist/src/browser/providers/extension.js +0 -378
@@ -1,7 +1,7 @@
1
1
  import type { AgentTool } from '@earendil-works/pi-agent-core';
2
2
  import type { BrowserAutomationService } from '../../browser/automations/index.js';
3
3
  declare const BrowserAutomationToolSchema: import("@sinclair/typebox").TObject<{
4
- action: import("@sinclair/typebox").TUnion<[import("@sinclair/typebox").TLiteral<"list">, import("@sinclair/typebox").TLiteral<"get">, import("@sinclair/typebox").TLiteral<"save">, import("@sinclair/typebox").TLiteral<"enable">, import("@sinclair/typebox").TLiteral<"disable">, import("@sinclair/typebox").TLiteral<"delete">, import("@sinclair/typebox").TLiteral<"run">]>;
4
+ action: import("@sinclair/typebox").TUnion<[import("@sinclair/typebox").TLiteral<"list">, import("@sinclair/typebox").TLiteral<"get">, import("@sinclair/typebox").TLiteral<"save">, import("@sinclair/typebox").TLiteral<"enable">, import("@sinclair/typebox").TLiteral<"disable">, import("@sinclair/typebox").TLiteral<"delete">, import("@sinclair/typebox").TLiteral<"run">, import("@sinclair/typebox").TLiteral<"test">, import("@sinclair/typebox").TLiteral<"validate">]>;
5
5
  automationId: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
6
6
  definition: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TObject<{
7
7
  id: import("@sinclair/typebox").TString;
@@ -32,6 +32,11 @@ declare const BrowserAutomationToolSchema: import("@sinclair/typebox").TObject<{
32
32
  role: import("@sinclair/typebox").TString;
33
33
  name: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
34
34
  nameIncludes: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
35
+ testId: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
36
+ scope: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TObject<{
37
+ role: import("@sinclair/typebox").TString;
38
+ name: import("@sinclair/typebox").TString;
39
+ }>>;
35
40
  }>;
36
41
  expect: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TObject<{
37
42
  urlIncludes: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
@@ -46,6 +51,11 @@ declare const BrowserAutomationToolSchema: import("@sinclair/typebox").TObject<{
46
51
  role: import("@sinclair/typebox").TString;
47
52
  name: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
48
53
  nameIncludes: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
54
+ testId: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
55
+ scope: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TObject<{
56
+ role: import("@sinclair/typebox").TString;
57
+ name: import("@sinclair/typebox").TString;
58
+ }>>;
49
59
  }>;
50
60
  value: import("@sinclair/typebox").TString;
51
61
  submit: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TBoolean>;
@@ -56,12 +66,30 @@ declare const BrowserAutomationToolSchema: import("@sinclair/typebox").TObject<{
56
66
  ref: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
57
67
  state: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TUnion<[import("@sinclair/typebox").TLiteral<"visible">, import("@sinclair/typebox").TLiteral<"hidden">]>>;
58
68
  }>>;
69
+ }>, import("@sinclair/typebox").TObject<{
70
+ action: import("@sinclair/typebox").TLiteral<"check">;
71
+ target: import("@sinclair/typebox").TObject<{
72
+ role: import("@sinclair/typebox").TString;
73
+ name: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
74
+ nameIncludes: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
75
+ testId: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
76
+ scope: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TObject<{
77
+ role: import("@sinclair/typebox").TString;
78
+ name: import("@sinclair/typebox").TString;
79
+ }>>;
80
+ }>;
81
+ checked: import("@sinclair/typebox").TBoolean;
59
82
  }>, import("@sinclair/typebox").TObject<{
60
83
  action: import("@sinclair/typebox").TLiteral<"select">;
61
84
  target: import("@sinclair/typebox").TObject<{
62
85
  role: import("@sinclair/typebox").TString;
63
86
  name: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
64
87
  nameIncludes: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
88
+ testId: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
89
+ scope: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TObject<{
90
+ role: import("@sinclair/typebox").TString;
91
+ name: import("@sinclair/typebox").TString;
92
+ }>>;
65
93
  }>;
66
94
  value: import("@sinclair/typebox").TString;
67
95
  expect: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TObject<{
@@ -77,6 +105,11 @@ declare const BrowserAutomationToolSchema: import("@sinclair/typebox").TObject<{
77
105
  role: import("@sinclair/typebox").TString;
78
106
  name: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
79
107
  nameIncludes: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
108
+ testId: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
109
+ scope: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TObject<{
110
+ role: import("@sinclair/typebox").TString;
111
+ name: import("@sinclair/typebox").TString;
112
+ }>>;
80
113
  }>>;
81
114
  key: import("@sinclair/typebox").TString;
82
115
  expect: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TObject<{
@@ -92,6 +125,11 @@ declare const BrowserAutomationToolSchema: import("@sinclair/typebox").TObject<{
92
125
  role: import("@sinclair/typebox").TString;
93
126
  name: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
94
127
  nameIncludes: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
128
+ testId: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
129
+ scope: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TObject<{
130
+ role: import("@sinclair/typebox").TString;
131
+ name: import("@sinclair/typebox").TString;
132
+ }>>;
95
133
  }>>;
96
134
  deltaY: import("@sinclair/typebox").TNumber;
97
135
  expect: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TObject<{
@@ -109,11 +147,46 @@ declare const BrowserAutomationToolSchema: import("@sinclair/typebox").TObject<{
109
147
  role: import("@sinclair/typebox").TString;
110
148
  name: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
111
149
  nameIncludes: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
150
+ testId: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
151
+ scope: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TObject<{
152
+ role: import("@sinclair/typebox").TString;
153
+ name: import("@sinclair/typebox").TString;
154
+ }>>;
112
155
  }>>;
113
156
  timeoutMs: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TInteger>;
114
157
  }>]>>;
158
+ successCriteria: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TArray<import("@sinclair/typebox").TObject<{
159
+ target: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TObject<{
160
+ role: import("@sinclair/typebox").TString;
161
+ name: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
162
+ nameIncludes: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
163
+ testId: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
164
+ scope: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TObject<{
165
+ role: import("@sinclair/typebox").TString;
166
+ name: import("@sinclair/typebox").TString;
167
+ }>>;
168
+ }>>;
169
+ field: import("@sinclair/typebox").TUnion<import("@sinclair/typebox").TLiteral<string>[]>;
170
+ equals: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TUnion<[import("@sinclair/typebox").TString, import("@sinclair/typebox").TBoolean]>>;
171
+ includes: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
172
+ }>>>;
173
+ outputs: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TRecord<import("@sinclair/typebox").TString, import("@sinclair/typebox").TObject<{
174
+ target: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TObject<{
175
+ role: import("@sinclair/typebox").TString;
176
+ name: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
177
+ nameIncludes: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
178
+ testId: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
179
+ scope: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TObject<{
180
+ role: import("@sinclair/typebox").TString;
181
+ name: import("@sinclair/typebox").TString;
182
+ }>>;
183
+ }>>;
184
+ field: import("@sinclair/typebox").TUnion<import("@sinclair/typebox").TLiteral<string>[]>;
185
+ }>>>;
115
186
  }>>;
116
187
  inputs: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TRecord<import("@sinclair/typebox").TString, import("@sinclair/typebox").TUnknown>>;
188
+ revision: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TInteger>;
189
+ expectedRevision: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TInteger>;
117
190
  }>;
118
191
  export declare function createBrowserAutomationTool(deps: {
119
192
  getBrowserAutomationService: () => BrowserAutomationService | undefined;
@@ -10,7 +10,12 @@ const ExpectationSchema = Type.Object({
10
10
  const TargetSchema = Type.Object({
11
11
  role: Type.String(),
12
12
  name: Type.Optional(Type.String()),
13
- nameIncludes: Type.Optional(Type.String())
13
+ nameIncludes: Type.Optional(Type.String()),
14
+ testId: Type.Optional(Type.String()),
15
+ scope: Type.Optional(Type.Object({
16
+ role: Type.String(),
17
+ name: Type.String()
18
+ }, { additionalProperties: false }))
14
19
  }, { additionalProperties: false });
15
20
  const StepSchema = Type.Union([
16
21
  Type.Object({
@@ -30,6 +35,11 @@ const StepSchema = Type.Union([
30
35
  submit: Type.Optional(Type.Boolean()),
31
36
  expect: Type.Optional(ExpectationSchema)
32
37
  }, { additionalProperties: false }),
38
+ Type.Object({
39
+ action: Type.Literal("check"),
40
+ target: TargetSchema,
41
+ checked: Type.Boolean()
42
+ }, { additionalProperties: false }),
33
43
  Type.Object({
34
44
  action: Type.Literal("select"),
35
45
  target: TargetSchema,
@@ -69,7 +79,9 @@ const BrowserAutomationToolSchema = Type.Object({
69
79
  Type.Literal("enable"),
70
80
  Type.Literal("disable"),
71
81
  Type.Literal("delete"),
72
- Type.Literal("run")
82
+ Type.Literal("run"),
83
+ Type.Literal("test"),
84
+ Type.Literal("validate")
73
85
  ]),
74
86
  automationId: Type.Optional(Type.String()),
75
87
  definition: Type.Optional(Type.Object({
@@ -103,9 +115,33 @@ const BrowserAutomationToolSchema = Type.Object({
103
115
  Type.Boolean()
104
116
  ])))
105
117
  }, { additionalProperties: false })),
106
- steps: Type.Array(StepSchema)
118
+ steps: Type.Array(StepSchema),
119
+ successCriteria: Type.Optional(Type.Array(Type.Object({
120
+ target: Type.Optional(TargetSchema),
121
+ field: Type.Union([
122
+ "text",
123
+ "value",
124
+ "url",
125
+ "title",
126
+ "checked"
127
+ ].map((field) => Type.Literal(field))),
128
+ equals: Type.Optional(Type.Union([Type.String(), Type.Boolean()])),
129
+ includes: Type.Optional(Type.String())
130
+ }, { additionalProperties: false }))),
131
+ outputs: Type.Optional(Type.Record(Type.String(), Type.Object({
132
+ target: Type.Optional(TargetSchema),
133
+ field: Type.Union([
134
+ "text",
135
+ "value",
136
+ "url",
137
+ "title",
138
+ "href"
139
+ ].map((field) => Type.Literal(field)))
140
+ }, { additionalProperties: false })))
107
141
  }, { additionalProperties: false })),
108
- inputs: Type.Optional(Type.Record(Type.String(), Type.Unknown()))
142
+ inputs: Type.Optional(Type.Record(Type.String(), Type.Unknown())),
143
+ revision: Type.Optional(Type.Integer({ minimum: 1 })),
144
+ expectedRevision: Type.Optional(Type.Integer({ minimum: 1 }))
109
145
  }, { additionalProperties: false });
110
146
  function createBrowserAutomationTool(deps) {
111
147
  return {
@@ -123,10 +159,17 @@ function createBrowserAutomationTool(deps) {
123
159
  automations
124
160
  });
125
161
  }
162
+ if (params.action === "validate") {
163
+ const parsed = service.validate(params.definition);
164
+ return output(parsed.success ? "Definition is valid; it has not been executed." : JSON.stringify(parsed.error.issues), { ok: parsed.success });
165
+ }
126
166
  if (params.action === "save") {
127
167
  if (!params.definition) return output("definition is required.", { ok: false });
128
168
  try {
129
- const automation = service.save({ definition: params.definition });
169
+ const automation = service.save({
170
+ definition: params.definition,
171
+ expectedRevision: params.expectedRevision
172
+ });
130
173
  return output(`Saved browser automation: ${automation.definition.name}`, {
131
174
  ok: true,
132
175
  automation
@@ -167,7 +210,10 @@ function createBrowserAutomationTool(deps) {
167
210
  });
168
211
  }
169
212
  try {
170
- const run = await service.runAndWait(id, params.inputs ?? {}, signal);
213
+ const run = await service.runAndWait(id, params.inputs ?? {}, signal, {
214
+ revision: params.revision,
215
+ clientRequestId: _toolCallId
216
+ });
171
217
  return output(run.status === "succeeded" ? `Browser automation ${id} completed.` : `Browser automation ${id} ${run.status}: ${run.error ?? "No details"}`, {
172
218
  ok: run.status === "succeeded",
173
219
  run
@@ -31,6 +31,7 @@ export declare const AutomationCreateCapabilityInputSchema: z.ZodObject<{
31
31
  }, z.core.$strict>, z.ZodObject<{
32
32
  kind: z.ZodLiteral<"browser_automation">;
33
33
  automationId: z.ZodString;
34
+ revision: z.ZodOptional<z.ZodNumber>;
34
35
  inputs: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
35
36
  timeoutSeconds: z.ZodOptional<z.ZodNumber>;
36
37
  }, z.core.$strict>, z.ZodObject<{
@@ -231,6 +232,7 @@ export declare const AutomationUpdatePatchSchema: z.ZodObject<{
231
232
  }, z.core.$strict>, z.ZodObject<{
232
233
  kind: z.ZodLiteral<"browser_automation">;
233
234
  automationId: z.ZodString;
235
+ revision: z.ZodOptional<z.ZodNumber>;
234
236
  inputs: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
235
237
  timeoutSeconds: z.ZodOptional<z.ZodNumber>;
236
238
  }, z.core.$strict>, z.ZodObject<{
@@ -48,6 +48,7 @@ export type AutomationAction = {
48
48
  } | {
49
49
  kind: 'browser_automation';
50
50
  automationId: string;
51
+ revision?: number;
51
52
  inputs?: Record<string, unknown>;
52
53
  timeoutSeconds?: number;
53
54
  } | {
@@ -342,8 +343,18 @@ export interface AutomationDeps {
342
343
  prepareAgentSession?: (input: PrepareAutomationAgentSessionInput) => Promise<void>;
343
344
  workflowRunService?: WorkflowRunServiceLike;
344
345
  browserAutomationService?: {
346
+ get(id: string): {
347
+ revision: number;
348
+ verified: boolean;
349
+ } | null;
350
+ versions(id: string): {
351
+ revision: number;
352
+ verified: boolean;
353
+ }[];
345
354
  runAndWait(automationId: string, inputs: Record<string, unknown>, signal?: AbortSignal, context?: {
346
355
  triggerEvent?: AutomationEvent;
356
+ revision?: number;
357
+ clientRequestId?: string;
347
358
  }): Promise<{
348
359
  id: string;
349
360
  status: 'queued' | 'running' | 'succeeded' | 'failed' | 'cancelled';
@@ -61,6 +61,7 @@ export declare const AutomationActionSchema: z.ZodDiscriminatedUnion<[z.ZodObjec
61
61
  }, z.core.$strict>, z.ZodObject<{
62
62
  kind: z.ZodLiteral<"browser_automation">;
63
63
  automationId: z.ZodString;
64
+ revision: z.ZodOptional<z.ZodNumber>;
64
65
  inputs: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
65
66
  timeoutSeconds: z.ZodOptional<z.ZodNumber>;
66
67
  }, z.core.$strict>, z.ZodObject<{
@@ -281,6 +282,7 @@ export declare const AutomationSchema: z.ZodObject<{
281
282
  }, z.core.$strict>, z.ZodObject<{
282
283
  kind: z.ZodLiteral<"browser_automation">;
283
284
  automationId: z.ZodString;
285
+ revision: z.ZodOptional<z.ZodNumber>;
284
286
  inputs: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
285
287
  timeoutSeconds: z.ZodOptional<z.ZodNumber>;
286
288
  }, z.core.$strict>, z.ZodObject<{
@@ -480,6 +482,7 @@ export declare const CreateAutomationSchema: z.ZodObject<{
480
482
  }, z.core.$strict>, z.ZodObject<{
481
483
  kind: z.ZodLiteral<"browser_automation">;
482
484
  automationId: z.ZodString;
485
+ revision: z.ZodOptional<z.ZodNumber>;
483
486
  inputs: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
484
487
  timeoutSeconds: z.ZodOptional<z.ZodNumber>;
485
488
  }, z.core.$strict>, z.ZodObject<{
@@ -706,6 +709,7 @@ export declare const UpdateAutomationSchema: z.ZodObject<{
706
709
  }, z.core.$strict>, z.ZodObject<{
707
710
  kind: z.ZodLiteral<"browser_automation">;
708
711
  automationId: z.ZodString;
712
+ revision: z.ZodOptional<z.ZodNumber>;
709
713
  inputs: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
710
714
  timeoutSeconds: z.ZodOptional<z.ZodNumber>;
711
715
  }, z.core.$strict>, z.ZodObject<{
@@ -95,6 +95,7 @@ const AutomationActionSchema = z.discriminatedUnion("kind", [
95
95
  z.object({
96
96
  kind: z.literal("browser_automation"),
97
97
  automationId: nonEmptyString.max(100),
98
+ revision: z.number().int().positive().optional(),
98
99
  inputs: z.record(z.string(), z.unknown()).optional(),
99
100
  timeoutSeconds: z.number().int().min(1).max(86400).optional()
100
101
  }).strict(),
@@ -60,6 +60,7 @@ export declare function buildAutomationDraftResponse(draft: GeneratedAutomationD
60
60
  } | {
61
61
  kind: "browser_automation";
62
62
  automationId: string;
63
+ revision?: number;
63
64
  inputs?: Record<string, unknown>;
64
65
  timeoutSeconds?: number;
65
66
  } | {
@@ -77,7 +77,7 @@ var AutomationActionExecutor = class {
77
77
  mode: "idempotent",
78
78
  key: "run_id"
79
79
  }, (input, action) => this.executeWorkflow(input.automation, action, input.run, input.signal, input.hooks, input.context));
80
- this.register("browser_automation", { mode: "never" }, (input, action) => this.executeBrowserAutomation(input.automation, action, input.signal, input.hooks, input.context));
80
+ this.register("browser_automation", { mode: "never" }, (input, action) => this.executeBrowserAutomation(input.automation, action, input.signal, input.hooks, input.context, input.run.id));
81
81
  this.register("task_command", {
82
82
  mode: "idempotent",
83
83
  key: "run_id"
@@ -186,7 +186,7 @@ var AutomationActionExecutor = class {
186
186
  })).summary ?? "System action completed"
187
187
  };
188
188
  }
189
- async executeBrowserAutomation(automation, action, signal, hooks, context) {
189
+ async executeBrowserAutomation(automation, action, signal, hooks, context, executionRunId) {
190
190
  await hooks.onRunPatch?.({ currentPhase: "action" });
191
191
  const safetyMode = automation.safety?.mode ?? "auto_apply";
192
192
  if (safetyMode !== "auto_apply") return {
@@ -198,7 +198,15 @@ var AutomationActionExecutor = class {
198
198
  status: "failed",
199
199
  error: "Browser automation is not available"
200
200
  };
201
- const run = context.triggerEvent ? await service.runAndWait(action.automationId, action.inputs ?? {}, signal, { triggerEvent: context.triggerEvent }) : await service.runAndWait(action.automationId, action.inputs ?? {}, signal);
201
+ if (action.revision === void 0 || !service.versions(action.automationId).some((item) => item.revision === action.revision && item.verified)) return {
202
+ status: "failed",
203
+ error: "The scheduled browser automation version has not been verified."
204
+ };
205
+ const run = await service.runAndWait(action.automationId, action.inputs ?? {}, signal, {
206
+ revision: action.revision,
207
+ clientRequestId: `schedule:${executionRunId}:${action.revision}`,
208
+ ...context.triggerEvent ? { triggerEvent: context.triggerEvent } : {}
209
+ });
202
210
  if (run.status === "succeeded") return {
203
211
  status: "succeeded",
204
212
  summary: `Browser automation ${action.automationId} completed: ${JSON.stringify(run.result ?? null).slice(0, 3500)}`
@@ -31,6 +31,7 @@ export declare class AutomationService {
31
31
  /** SQLite-only creation; scheduling starts after the caller commits. */
32
32
  createAtomically(input: CreateAutomationInput): Automation;
33
33
  private applyCreate;
34
+ private pinBrowserVersion;
34
35
  list(options?: {
35
36
  projectId?: string;
36
37
  }): Promise<Automation[]>;
@@ -114,12 +114,23 @@ var AutomationService = class {
114
114
  createdAtMs: now,
115
115
  updatedAtMs: now
116
116
  });
117
+ this.pinBrowserVersion(automation);
117
118
  if (getAutomation(automation.id)) throw new AutomationAlreadyExistsError(automation.id);
118
119
  automation.updatedAtMs = Math.max(automation.updatedAtMs, (getDeletedAutomationRevision(automation.id) ?? -1) + 1);
119
120
  automation.state.nextRunAtMs = computeNextAutomationRunAtMs(automation, now);
120
121
  saveAutomation(automation);
121
122
  return automation;
122
123
  }
124
+ pinBrowserVersion(automation) {
125
+ if (automation.action.kind !== "browser_automation") return;
126
+ const browser = this.deps.browserAutomationService;
127
+ if (!browser) throw new Error("Browser automation service is unavailable.");
128
+ const action = automation.action;
129
+ const version = action.revision === void 0 ? browser.get(action.automationId) : browser.versions(action.automationId).find((item) => item.revision === action.revision);
130
+ if (!version) throw new Error("Browser automation version not found.");
131
+ if (automation.enabled && !version.verified) throw new Error("Run and verify this browser automation before scheduling it.");
132
+ action.revision = version.revision;
133
+ }
123
134
  async list(options) {
124
135
  return listAutomations(options);
125
136
  }
@@ -154,6 +165,7 @@ var AutomationService = class {
154
165
  ...parsed.state ?? {}
155
166
  }
156
167
  });
168
+ this.pinBrowserVersion(next);
157
169
  if ("enabled" in parsed || "trigger" in parsed) next.state.nextRunAtMs = computeNextAutomationRunAtMs(next, now);
158
170
  saveAutomation(next);
159
171
  return next;
@@ -559,7 +571,7 @@ var AutomationService = class {
559
571
  let artifacts;
560
572
  const triggerEvent = listAutomationRunEvents(run.id).map(readAutomationEventFromRunEvent).find((item) => item !== null);
561
573
  try {
562
- const maxAttempts = Math.max(1, (automation.reliability?.retryCount ?? 0) + 1);
574
+ const maxAttempts = automation.action.kind === "browser_automation" ? 1 : Math.max(1, (automation.reliability?.retryCount ?? 0) + 1);
563
575
  let task;
564
576
  for (let attempt = 1;; attempt += 1) {
565
577
  run = {
@@ -2,9 +2,9 @@ import { requireXopcDatabase } from "../storage/sqlite/connection.js";
2
2
  import { init_sqlite } from "../storage/sqlite/index.js";
3
3
  import { AgentCatalogService } from "../agent-catalog/service.js";
4
4
  import { ensureStarterAgentsInitialized } from "../agent/starter-agents.js";
5
- import { migrateIdentityMarkdownToCatalog } from "../agent-catalog/migrations/identity-markdown-cutover.js";
6
5
  import { cutoverLegacyAgentConfig } from "../agent-catalog/migrations/legacy-config-cutover.js";
7
6
  import "../agent-catalog/index.js";
7
+ import { migrateIdentityMarkdownToCatalog } from "../agent-catalog/migrations/identity-markdown-cutover.js";
8
8
  import { migrateCloudPublicModelsSync } from "../migrations/cloud-public-models.js";
9
9
  import { runBootstrapMigrationsSync } from "../migrations/runner.js";
10
10
  //#region src/bootstrap/application-state.ts
@@ -2,6 +2,10 @@ import type { BrowserAutomation, BrowserAutomationRun, BrowserAutomationRunEvent
2
2
  export declare const listBrowserAutomations: () => BrowserAutomation[];
3
3
  export declare const getBrowserAutomation: (id: string) => BrowserAutomation | null;
4
4
  export declare function saveBrowserAutomation(value: BrowserAutomation): void;
5
+ export declare function getBrowserAutomationVersion(id: string, revision: number): BrowserAutomation | null;
6
+ export declare function listBrowserAutomationVersions(id: string): BrowserAutomation[];
7
+ export declare function verifyBrowserAutomationRun(run: BrowserAutomationRun): void;
8
+ export declare function findBrowserAutomationRunByRequest(requestId: string): BrowserAutomationRun | null;
5
9
  export declare const deleteBrowserAutomation: (id: string) => boolean;
6
10
  export declare function saveBrowserAutomationRun(value: BrowserAutomationRun): void;
7
11
  export declare const getBrowserAutomationRun: (id: string) => BrowserAutomationRun | null;
@@ -2,9 +2,10 @@ import { getSqliteDatabase, runSqliteWriteTransaction } from "../../storage/sqli
2
2
  import { init_sqlite } from "../../storage/sqlite/index.js";
3
3
  //#region src/browser/automations/repository.ts
4
4
  init_sqlite();
5
- const AUTOMATION_SELECT = "SELECT automation_id, revision, status, definition_json, created_at_ms, updated_at_ms FROM browser_automations";
6
- const RUN_SELECT = "SELECT run_id, automation_id, automation_revision, definition_json, status, inputs_json, result_json, error, created_at_ms, started_at_ms, ended_at_ms, duration_ms FROM browser_automation_runs";
5
+ const AUTOMATION_SELECT = "SELECT a.*, EXISTS(SELECT 1 FROM browser_automation_verifications v WHERE v.automation_id=a.automation_id AND v.revision=a.revision) AS verified FROM browser_automations a";
6
+ const RUN_SELECT = "SELECT client_request_id, business_outcome, run_id, automation_id, automation_revision, definition_json, status, inputs_json, result_json, error, created_at_ms, started_at_ms, ended_at_ms, duration_ms FROM browser_automation_runs";
7
7
  const parseAutomation = (row) => ({
8
+ verified: !!row.verified,
8
9
  id: row.automation_id,
9
10
  revision: row.revision,
10
11
  status: row.status,
@@ -13,6 +14,8 @@ const parseAutomation = (row) => ({
13
14
  updatedAtMs: row.updated_at_ms
14
15
  });
15
16
  const parseRun = (row) => ({
17
+ clientRequestId: row.client_request_id ?? void 0,
18
+ businessOutcome: row.business_outcome ?? void 0,
16
19
  id: row.run_id,
17
20
  automationId: row.automation_id,
18
21
  automationRevision: row.automation_revision,
@@ -28,15 +31,33 @@ const parseRun = (row) => ({
28
31
  });
29
32
  const listBrowserAutomations = () => getSqliteDatabase().prepare(`${AUTOMATION_SELECT} ORDER BY updated_at_ms DESC`).all().map(parseAutomation);
30
33
  const getBrowserAutomation = (id) => {
31
- const row = getSqliteDatabase().prepare(`${AUTOMATION_SELECT} WHERE automation_id = ?`).get(id);
34
+ const row = getSqliteDatabase().prepare(`${AUTOMATION_SELECT} WHERE a.automation_id = ?`).get(id);
32
35
  return row ? parseAutomation(row) : null;
33
36
  };
34
37
  function saveBrowserAutomation(value) {
35
- runSqliteWriteTransaction((db) => db.prepare("INSERT INTO browser_automations (automation_id, revision, status, definition_json, created_at_ms, updated_at_ms) VALUES (?, ?, ?, ?, ?, ?) ON CONFLICT(automation_id) DO UPDATE SET revision=excluded.revision, status=excluded.status, definition_json=excluded.definition_json, updated_at_ms=excluded.updated_at_ms").run(value.id, value.revision, value.status, JSON.stringify(value.definition), value.createdAtMs, value.updatedAtMs));
38
+ runSqliteWriteTransaction((db) => {
39
+ db.prepare("INSERT INTO browser_automations (automation_id, revision, status, definition_json, created_at_ms, updated_at_ms) VALUES (?, ?, ?, ?, ?, ?) ON CONFLICT(automation_id) DO UPDATE SET revision=excluded.revision, status=excluded.status, definition_json=excluded.definition_json, updated_at_ms=excluded.updated_at_ms").run(value.id, value.revision, value.status, JSON.stringify(value.definition), value.createdAtMs, value.updatedAtMs);
40
+ db.prepare("INSERT OR IGNORE INTO browser_automation_versions (automation_id, revision, definition_json, created_at_ms) VALUES (?, ?, ?, ?)").run(value.id, value.revision, JSON.stringify(value.definition), value.updatedAtMs);
41
+ });
42
+ }
43
+ function getBrowserAutomationVersion(id, revision) {
44
+ const row = getSqliteDatabase().prepare("SELECT v.*, a.status, a.created_at_ms, v.created_at_ms AS updated_at_ms, EXISTS(SELECT 1 FROM browser_automation_verifications p WHERE p.automation_id=v.automation_id AND p.revision=v.revision) AS verified FROM browser_automation_versions v JOIN browser_automations a USING(automation_id) WHERE v.automation_id=? AND v.revision=?").get(id, revision);
45
+ return row ? parseAutomation(row) : null;
46
+ }
47
+ function listBrowserAutomationVersions(id) {
48
+ return getSqliteDatabase().prepare("SELECT revision FROM browser_automation_versions WHERE automation_id=? ORDER BY revision DESC").all(id).map((row) => getBrowserAutomationVersion(id, row.revision));
49
+ }
50
+ function verifyBrowserAutomationRun(run) {
51
+ if (run.status !== "succeeded" || run.businessOutcome !== "verified") return;
52
+ runSqliteWriteTransaction((db) => db.prepare("INSERT INTO browser_automation_verifications (automation_id, revision, run_id, verified_at_ms) VALUES (?, ?, ?, ?) ON CONFLICT(automation_id, revision) DO UPDATE SET run_id=excluded.run_id, verified_at_ms=excluded.verified_at_ms").run(run.automationId, run.automationRevision, run.id, run.endedAtMs));
53
+ }
54
+ function findBrowserAutomationRunByRequest(requestId) {
55
+ const row = getSqliteDatabase().prepare(`${RUN_SELECT} WHERE client_request_id=?`).get(requestId);
56
+ return row ? parseRun(row) : null;
36
57
  }
37
58
  const deleteBrowserAutomation = (id) => runSqliteWriteTransaction((db) => db.prepare("DELETE FROM browser_automations WHERE automation_id = ?").run(id).changes > 0);
38
59
  function saveBrowserAutomationRun(value) {
39
- runSqliteWriteTransaction((db) => db.prepare("INSERT INTO browser_automation_runs (run_id, automation_id, automation_revision, definition_json, status, inputs_json, result_json, error, created_at_ms, started_at_ms, ended_at_ms, duration_ms) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) ON CONFLICT(run_id) DO UPDATE SET status=excluded.status, result_json=excluded.result_json, error=excluded.error, started_at_ms=excluded.started_at_ms, ended_at_ms=excluded.ended_at_ms, duration_ms=excluded.duration_ms").run(value.id, value.automationId, value.automationRevision, JSON.stringify(value.definition), value.status, JSON.stringify(value.inputs), value.result === void 0 ? null : JSON.stringify(value.result), value.error ?? null, value.createdAtMs, value.startedAtMs ?? null, value.endedAtMs ?? null, value.durationMs ?? null));
60
+ runSqliteWriteTransaction((db) => db.prepare("INSERT INTO browser_automation_runs (run_id, automation_id, automation_revision, definition_json, status, inputs_json, result_json, error, created_at_ms, started_at_ms, ended_at_ms, duration_ms, client_request_id, business_outcome) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) ON CONFLICT(run_id) DO UPDATE SET status=excluded.status, result_json=excluded.result_json, error=excluded.error, started_at_ms=excluded.started_at_ms, ended_at_ms=excluded.ended_at_ms, duration_ms=excluded.duration_ms, business_outcome=excluded.business_outcome").run(value.id, value.automationId, value.automationRevision, JSON.stringify(value.definition), value.status, JSON.stringify(value.inputs), value.result === void 0 ? null : JSON.stringify(value.result), value.error ?? null, value.createdAtMs, value.startedAtMs ?? null, value.endedAtMs ?? null, value.durationMs ?? null, value.clientRequestId ?? null, value.businessOutcome ?? null));
40
61
  }
41
62
  const getBrowserAutomationRun = (id) => {
42
63
  const row = getSqliteDatabase().prepare(`${RUN_SELECT} WHERE run_id = ?`).get(id);
@@ -58,4 +79,4 @@ const listBrowserAutomationRunEvents = (runId) => getSqliteDatabase().prepare("S
58
79
  createdAtMs: row.created_at_ms
59
80
  }));
60
81
  //#endregion
61
- export { appendBrowserAutomationRunEvent, deleteBrowserAutomation, getBrowserAutomation, getBrowserAutomationRun, hasActiveBrowserAutomationRuns, listActiveBrowserAutomationRuns, listBrowserAutomationRunEvents, listBrowserAutomationRuns, listBrowserAutomations, nextBrowserAutomationRunEventSeq, saveBrowserAutomation, saveBrowserAutomationRun };
82
+ export { appendBrowserAutomationRunEvent, deleteBrowserAutomation, findBrowserAutomationRunByRequest, getBrowserAutomation, getBrowserAutomationRun, getBrowserAutomationVersion, hasActiveBrowserAutomationRuns, listActiveBrowserAutomationRuns, listBrowserAutomationRunEvents, listBrowserAutomationRuns, listBrowserAutomationVersions, listBrowserAutomations, nextBrowserAutomationRunEventSeq, saveBrowserAutomation, saveBrowserAutomationRun, verifyBrowserAutomationRun };