opendevbrowser 0.0.16 → 0.0.18

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 (616) hide show
  1. package/README.md +201 -79
  2. package/dist/annotate/agent-inbox-store.d.ts +58 -0
  3. package/dist/annotate/agent-inbox-store.d.ts.map +1 -0
  4. package/dist/annotate/agent-inbox.d.ts +25 -0
  5. package/dist/annotate/agent-inbox.d.ts.map +1 -0
  6. package/dist/annotate/direct-annotator.d.ts.map +1 -1
  7. package/dist/annotate/timeout-messages.d.ts +4 -0
  8. package/dist/annotate/timeout-messages.d.ts.map +1 -0
  9. package/dist/automation/coordinator.d.ts +55 -0
  10. package/dist/automation/coordinator.d.ts.map +1 -0
  11. package/dist/browser/annotation-manager.d.ts +7 -1
  12. package/dist/browser/annotation-manager.d.ts.map +1 -1
  13. package/dist/browser/browser-manager.d.ts +153 -48
  14. package/dist/browser/browser-manager.d.ts.map +1 -1
  15. package/dist/browser/canvas-client.d.ts +54 -0
  16. package/dist/browser/canvas-client.d.ts.map +1 -0
  17. package/dist/browser/canvas-code-sync-manager.d.ts +87 -0
  18. package/dist/browser/canvas-code-sync-manager.d.ts.map +1 -0
  19. package/dist/browser/canvas-manager.d.ts +122 -0
  20. package/dist/browser/canvas-manager.d.ts.map +1 -0
  21. package/dist/browser/canvas-runtime-preview-bridge.d.ts +20 -0
  22. package/dist/browser/canvas-runtime-preview-bridge.d.ts.map +1 -0
  23. package/dist/browser/canvas-session-sync-manager.d.ts +21 -0
  24. package/dist/browser/canvas-session-sync-manager.d.ts.map +1 -0
  25. package/dist/browser/global-challenge-coordinator.d.ts +27 -0
  26. package/dist/browser/global-challenge-coordinator.d.ts.map +1 -0
  27. package/dist/browser/manager-types.d.ts +179 -1
  28. package/dist/browser/manager-types.d.ts.map +1 -1
  29. package/dist/browser/ops-browser-manager.d.ts +114 -4
  30. package/dist/browser/ops-browser-manager.d.ts.map +1 -1
  31. package/dist/browser/ops-client.d.ts +17 -1
  32. package/dist/browser/ops-client.d.ts.map +1 -1
  33. package/dist/browser/playwright-runtime.d.ts +4 -0
  34. package/dist/browser/playwright-runtime.d.ts.map +1 -0
  35. package/dist/browser/review-surface.d.ts +9 -0
  36. package/dist/browser/review-surface.d.ts.map +1 -0
  37. package/dist/browser/screencast-recorder.d.ts +57 -0
  38. package/dist/browser/screencast-recorder.d.ts.map +1 -0
  39. package/dist/browser/session-inspector.d.ts +71 -0
  40. package/dist/browser/session-inspector.d.ts.map +1 -0
  41. package/dist/browser/session-store.d.ts +5 -1
  42. package/dist/browser/session-store.d.ts.map +1 -1
  43. package/dist/browser/system-chrome-cookies.d.ts +46 -0
  44. package/dist/browser/system-chrome-cookies.d.ts.map +1 -0
  45. package/dist/browser/target-manager.d.ts +1 -0
  46. package/dist/browser/target-manager.d.ts.map +1 -1
  47. package/dist/cache/chrome-locator.d.ts.map +1 -1
  48. package/dist/cache/chrome-user-data.d.ts +17 -0
  49. package/dist/cache/chrome-user-data.d.ts.map +1 -0
  50. package/dist/canvas/adapter-plugins/loader.d.ts +13 -0
  51. package/dist/canvas/adapter-plugins/loader.d.ts.map +1 -0
  52. package/dist/canvas/adapter-plugins/manifest.d.ts +146 -0
  53. package/dist/canvas/adapter-plugins/manifest.d.ts.map +1 -0
  54. package/dist/canvas/adapter-plugins/types.d.ts +83 -0
  55. package/dist/canvas/adapter-plugins/types.d.ts.map +1 -0
  56. package/dist/canvas/adapter-plugins/validator.d.ts +10 -0
  57. package/dist/canvas/adapter-plugins/validator.d.ts.map +1 -0
  58. package/dist/canvas/code-sync/apply-tsx.d.ts +25 -0
  59. package/dist/canvas/code-sync/apply-tsx.d.ts.map +1 -0
  60. package/dist/canvas/code-sync/graph.d.ts +5 -0
  61. package/dist/canvas/code-sync/graph.d.ts.map +1 -0
  62. package/dist/canvas/code-sync/hash.d.ts +3 -0
  63. package/dist/canvas/code-sync/hash.d.ts.map +1 -0
  64. package/dist/canvas/code-sync/import.d.ts +19 -0
  65. package/dist/canvas/code-sync/import.d.ts.map +1 -0
  66. package/dist/canvas/code-sync/manifest.d.ts +6 -0
  67. package/dist/canvas/code-sync/manifest.d.ts.map +1 -0
  68. package/dist/canvas/code-sync/tsx-adapter.d.ts +8 -0
  69. package/dist/canvas/code-sync/tsx-adapter.d.ts.map +1 -0
  70. package/dist/canvas/code-sync/types.d.ts +244 -0
  71. package/dist/canvas/code-sync/types.d.ts.map +1 -0
  72. package/dist/canvas/code-sync/write.d.ts +9 -0
  73. package/dist/canvas/code-sync/write.d.ts.map +1 -0
  74. package/dist/canvas/document-store.d.ts +91 -0
  75. package/dist/canvas/document-store.d.ts.map +1 -0
  76. package/dist/canvas/export.d.ts +12 -0
  77. package/dist/canvas/export.d.ts.map +1 -0
  78. package/dist/canvas/framework-adapters/custom-elements-v1.d.ts +3 -0
  79. package/dist/canvas/framework-adapters/custom-elements-v1.d.ts.map +1 -0
  80. package/dist/canvas/framework-adapters/html-static-v1.d.ts +3 -0
  81. package/dist/canvas/framework-adapters/html-static-v1.d.ts.map +1 -0
  82. package/dist/canvas/framework-adapters/markup.d.ts +9 -0
  83. package/dist/canvas/framework-adapters/markup.d.ts.map +1 -0
  84. package/dist/canvas/framework-adapters/react-tsx-v2.d.ts +3 -0
  85. package/dist/canvas/framework-adapters/react-tsx-v2.d.ts.map +1 -0
  86. package/dist/canvas/framework-adapters/registry.d.ts +12 -0
  87. package/dist/canvas/framework-adapters/registry.d.ts.map +1 -0
  88. package/dist/canvas/framework-adapters/svelte-sfc-v1.d.ts +3 -0
  89. package/dist/canvas/framework-adapters/svelte-sfc-v1.d.ts.map +1 -0
  90. package/dist/canvas/framework-adapters/types.d.ts +57 -0
  91. package/dist/canvas/framework-adapters/types.d.ts.map +1 -0
  92. package/dist/canvas/framework-adapters/vue-sfc-v1.d.ts +3 -0
  93. package/dist/canvas/framework-adapters/vue-sfc-v1.d.ts.map +1 -0
  94. package/dist/canvas/kits/catalog.d.ts +5 -0
  95. package/dist/canvas/kits/catalog.d.ts.map +1 -0
  96. package/dist/canvas/library-adapters/react/index.d.ts +3 -0
  97. package/dist/canvas/library-adapters/react/index.d.ts.map +1 -0
  98. package/dist/canvas/library-adapters/registry.d.ts +11 -0
  99. package/dist/canvas/library-adapters/registry.d.ts.map +1 -0
  100. package/dist/canvas/library-adapters/types.d.ts +43 -0
  101. package/dist/canvas/library-adapters/types.d.ts.map +1 -0
  102. package/dist/canvas/repo-store.d.ts +12 -0
  103. package/dist/canvas/repo-store.d.ts.map +1 -0
  104. package/dist/canvas/starters/catalog.d.ts +34 -0
  105. package/dist/canvas/starters/catalog.d.ts.map +1 -0
  106. package/dist/canvas/surface-palette.d.ts +15 -0
  107. package/dist/canvas/surface-palette.d.ts.map +1 -0
  108. package/dist/canvas/token-references.d.ts +22 -0
  109. package/dist/canvas/token-references.d.ts.map +1 -0
  110. package/dist/canvas/types.d.ts +594 -0
  111. package/dist/canvas/types.d.ts.map +1 -0
  112. package/dist/canvas-runtime-preview-bridge-HBEHXM4T.js +7 -0
  113. package/dist/canvas-runtime-preview-bridge-HBEHXM4T.js.map +1 -0
  114. package/dist/challenges/action-loop.d.ts +13 -0
  115. package/dist/challenges/action-loop.d.ts.map +1 -0
  116. package/dist/challenges/capability-matrix.d.ts +3 -0
  117. package/dist/challenges/capability-matrix.d.ts.map +1 -0
  118. package/dist/challenges/evidence-bundle.d.ts +48 -0
  119. package/dist/challenges/evidence-bundle.d.ts.map +1 -0
  120. package/dist/challenges/governed-adapter-gateway.d.ts +4 -0
  121. package/dist/challenges/governed-adapter-gateway.d.ts.map +1 -0
  122. package/dist/challenges/human-yield-gate.d.ts +20 -0
  123. package/dist/challenges/human-yield-gate.d.ts.map +1 -0
  124. package/dist/challenges/index.d.ts +15 -0
  125. package/dist/challenges/index.d.ts.map +1 -0
  126. package/dist/challenges/interpreter.d.ts +3 -0
  127. package/dist/challenges/interpreter.d.ts.map +1 -0
  128. package/dist/challenges/optional-computer-use-bridge.d.ts +9 -0
  129. package/dist/challenges/optional-computer-use-bridge.d.ts.map +1 -0
  130. package/dist/challenges/orchestrator.d.ts +32 -0
  131. package/dist/challenges/orchestrator.d.ts.map +1 -0
  132. package/dist/challenges/outcome-recorder.d.ts +8 -0
  133. package/dist/challenges/outcome-recorder.d.ts.map +1 -0
  134. package/dist/challenges/owned-environment-lane.d.ts +3 -0
  135. package/dist/challenges/owned-environment-lane.d.ts.map +1 -0
  136. package/dist/challenges/policy-gate.d.ts +9 -0
  137. package/dist/challenges/policy-gate.d.ts.map +1 -0
  138. package/dist/challenges/sanctioned-identity-lane.d.ts +3 -0
  139. package/dist/challenges/sanctioned-identity-lane.d.ts.map +1 -0
  140. package/dist/challenges/service-adapter-lane.d.ts +3 -0
  141. package/dist/challenges/service-adapter-lane.d.ts.map +1 -0
  142. package/dist/challenges/strategy-selector.d.ts +10 -0
  143. package/dist/challenges/strategy-selector.d.ts.map +1 -0
  144. package/dist/challenges/types.d.ts +277 -0
  145. package/dist/challenges/types.d.ts.map +1 -0
  146. package/dist/challenges/verification-gate.d.ts +15 -0
  147. package/dist/challenges/verification-gate.d.ts.map +1 -0
  148. package/dist/chunk-5FZQJRBQ.js +15256 -0
  149. package/dist/chunk-5FZQJRBQ.js.map +1 -0
  150. package/dist/{chunk-7W3SPXIB.js → chunk-FUSXMW3G.js} +4 -1
  151. package/dist/chunk-L57D35TB.js +33513 -0
  152. package/dist/chunk-L57D35TB.js.map +1 -0
  153. package/dist/chunk-TBUCZX4A.js +34 -0
  154. package/dist/chunk-TBUCZX4A.js.map +1 -0
  155. package/dist/chunk-Y2KL55OG.js +59 -0
  156. package/dist/chunk-Y2KL55OG.js.map +1 -0
  157. package/dist/chunk-YBQECXZX.js +409 -0
  158. package/dist/chunk-YBQECXZX.js.map +1 -0
  159. package/dist/cli/args.d.ts +4 -4
  160. package/dist/cli/args.d.ts.map +1 -1
  161. package/dist/cli/commands/annotate.d.ts +11 -0
  162. package/dist/cli/commands/annotate.d.ts.map +1 -1
  163. package/dist/cli/commands/artifacts.d.ts.map +1 -1
  164. package/dist/cli/commands/canvas.d.ts +45 -0
  165. package/dist/cli/commands/canvas.d.ts.map +1 -0
  166. package/dist/cli/commands/daemon.d.ts +7 -0
  167. package/dist/cli/commands/daemon.d.ts.map +1 -1
  168. package/dist/cli/commands/desktop/accessibility-snapshot.d.ts +3 -0
  169. package/dist/cli/commands/desktop/accessibility-snapshot.d.ts.map +1 -0
  170. package/dist/cli/commands/desktop/active-window.d.ts +3 -0
  171. package/dist/cli/commands/desktop/active-window.d.ts.map +1 -0
  172. package/dist/cli/commands/desktop/capture-desktop.d.ts +3 -0
  173. package/dist/cli/commands/desktop/capture-desktop.d.ts.map +1 -0
  174. package/dist/cli/commands/desktop/capture-window.d.ts +3 -0
  175. package/dist/cli/commands/desktop/capture-window.d.ts.map +1 -0
  176. package/dist/cli/commands/desktop/shared.d.ts +19 -0
  177. package/dist/cli/commands/desktop/shared.d.ts.map +1 -0
  178. package/dist/cli/commands/desktop/status.d.ts +3 -0
  179. package/dist/cli/commands/desktop/status.d.ts.map +1 -0
  180. package/dist/cli/commands/desktop/windows.d.ts +3 -0
  181. package/dist/cli/commands/desktop/windows.d.ts.map +1 -0
  182. package/dist/cli/commands/devtools/dialog.d.ts +19 -0
  183. package/dist/cli/commands/devtools/dialog.d.ts.map +1 -0
  184. package/dist/cli/commands/devtools/perf.d.ts.map +1 -1
  185. package/dist/cli/commands/devtools/screencast-start.d.ts +20 -0
  186. package/dist/cli/commands/devtools/screencast-start.d.ts.map +1 -0
  187. package/dist/cli/commands/devtools/screencast-stop.d.ts +17 -0
  188. package/dist/cli/commands/devtools/screencast-stop.d.ts.map +1 -0
  189. package/dist/cli/commands/devtools/screenshot.d.ts +3 -0
  190. package/dist/cli/commands/devtools/screenshot.d.ts.map +1 -1
  191. package/dist/cli/commands/dom/attr.d.ts.map +1 -1
  192. package/dist/cli/commands/dom/checked.d.ts.map +1 -1
  193. package/dist/cli/commands/dom/enabled.d.ts.map +1 -1
  194. package/dist/cli/commands/dom/html.d.ts.map +1 -1
  195. package/dist/cli/commands/dom/text.d.ts.map +1 -1
  196. package/dist/cli/commands/dom/value.d.ts.map +1 -1
  197. package/dist/cli/commands/dom/visible.d.ts.map +1 -1
  198. package/dist/cli/commands/export/clone-component.d.ts +9 -0
  199. package/dist/cli/commands/export/clone-component.d.ts.map +1 -1
  200. package/dist/cli/commands/export/clone-page.d.ts +8 -0
  201. package/dist/cli/commands/export/clone-page.d.ts.map +1 -1
  202. package/dist/cli/commands/interact/check.d.ts.map +1 -1
  203. package/dist/cli/commands/interact/click.d.ts.map +1 -1
  204. package/dist/cli/commands/interact/hover.d.ts.map +1 -1
  205. package/dist/cli/commands/interact/pointer-down.d.ts +7 -0
  206. package/dist/cli/commands/interact/pointer-down.d.ts.map +1 -0
  207. package/dist/cli/commands/interact/pointer-drag.d.ts +7 -0
  208. package/dist/cli/commands/interact/pointer-drag.d.ts.map +1 -0
  209. package/dist/cli/commands/interact/pointer-move.d.ts +7 -0
  210. package/dist/cli/commands/interact/pointer-move.d.ts.map +1 -0
  211. package/dist/cli/commands/interact/pointer-shared.d.ts +6 -0
  212. package/dist/cli/commands/interact/pointer-shared.d.ts.map +1 -0
  213. package/dist/cli/commands/interact/pointer-up.d.ts +7 -0
  214. package/dist/cli/commands/interact/pointer-up.d.ts.map +1 -0
  215. package/dist/cli/commands/interact/press.d.ts.map +1 -1
  216. package/dist/cli/commands/interact/scroll-into-view.d.ts.map +1 -1
  217. package/dist/cli/commands/interact/scroll.d.ts.map +1 -1
  218. package/dist/cli/commands/interact/select.d.ts.map +1 -1
  219. package/dist/cli/commands/interact/type.d.ts.map +1 -1
  220. package/dist/cli/commands/interact/uncheck.d.ts.map +1 -1
  221. package/dist/cli/commands/interact/upload.d.ts +18 -0
  222. package/dist/cli/commands/interact/upload.d.ts.map +1 -0
  223. package/dist/cli/commands/macro-resolve.d.ts +2 -0
  224. package/dist/cli/commands/macro-resolve.d.ts.map +1 -1
  225. package/dist/cli/commands/native.d.ts +22 -8
  226. package/dist/cli/commands/native.d.ts.map +1 -1
  227. package/dist/cli/commands/nav/goto.d.ts.map +1 -1
  228. package/dist/cli/commands/nav/review.d.ts +7 -0
  229. package/dist/cli/commands/nav/review.d.ts.map +1 -0
  230. package/dist/cli/commands/nav/snapshot.d.ts.map +1 -1
  231. package/dist/cli/commands/nav/wait.d.ts.map +1 -1
  232. package/dist/cli/commands/pages/open.d.ts.map +1 -1
  233. package/dist/cli/commands/product-video.d.ts +2 -0
  234. package/dist/cli/commands/product-video.d.ts.map +1 -1
  235. package/dist/cli/commands/research.d.ts +3 -0
  236. package/dist/cli/commands/research.d.ts.map +1 -1
  237. package/dist/cli/commands/run.d.ts +14 -0
  238. package/dist/cli/commands/run.d.ts.map +1 -1
  239. package/dist/cli/commands/serve.d.ts +1 -21
  240. package/dist/cli/commands/serve.d.ts.map +1 -1
  241. package/dist/cli/commands/session/connect.d.ts.map +1 -1
  242. package/dist/cli/commands/session/disconnect.d.ts.map +1 -1
  243. package/dist/cli/commands/session/inspector.d.ts +21 -0
  244. package/dist/cli/commands/session/inspector.d.ts.map +1 -0
  245. package/dist/cli/commands/session/launch.d.ts.map +1 -1
  246. package/dist/cli/commands/shopping.d.ts +5 -0
  247. package/dist/cli/commands/shopping.d.ts.map +1 -1
  248. package/dist/cli/commands/status.d.ts +2 -9
  249. package/dist/cli/commands/status.d.ts.map +1 -1
  250. package/dist/cli/commands/targets/new.d.ts.map +1 -1
  251. package/dist/cli/daemon-autostart.d.ts +11 -0
  252. package/dist/cli/daemon-autostart.d.ts.map +1 -1
  253. package/dist/cli/daemon-client.d.ts +3 -0
  254. package/dist/cli/daemon-client.d.ts.map +1 -1
  255. package/dist/cli/daemon-commands.d.ts.map +1 -1
  256. package/dist/cli/daemon-state.d.ts +16 -0
  257. package/dist/cli/daemon-state.d.ts.map +1 -1
  258. package/dist/cli/daemon-status.d.ts +7 -2
  259. package/dist/cli/daemon-status.d.ts.map +1 -1
  260. package/dist/cli/daemon.d.ts +1 -0
  261. package/dist/cli/daemon.d.ts.map +1 -1
  262. package/dist/cli/help.d.ts +19 -3
  263. package/dist/cli/help.d.ts.map +1 -1
  264. package/dist/cli/index.js +2927 -932
  265. package/dist/cli/index.js.map +1 -1
  266. package/dist/cli/install-autostart-output.d.ts +6 -0
  267. package/dist/cli/install-autostart-output.d.ts.map +1 -0
  268. package/dist/cli/install-autostart-reconciliation.d.ts +23 -0
  269. package/dist/cli/install-autostart-reconciliation.d.ts.map +1 -0
  270. package/dist/cli/installers/skills.d.ts +42 -6
  271. package/dist/cli/installers/skills.d.ts.map +1 -1
  272. package/dist/cli/output.d.ts +3 -0
  273. package/dist/cli/output.d.ts.map +1 -1
  274. package/dist/cli/remote-canvas-manager.d.ts +8 -0
  275. package/dist/cli/remote-canvas-manager.d.ts.map +1 -0
  276. package/dist/cli/remote-desktop-runtime.d.ts +15 -0
  277. package/dist/cli/remote-desktop-runtime.d.ts.map +1 -0
  278. package/dist/cli/remote-manager.d.ts +27 -3
  279. package/dist/cli/remote-manager.d.ts.map +1 -1
  280. package/dist/cli/remote-relay.d.ts +2 -0
  281. package/dist/cli/remote-relay.d.ts.map +1 -1
  282. package/dist/cli/transport-timeouts.d.ts +8 -0
  283. package/dist/cli/transport-timeouts.d.ts.map +1 -0
  284. package/dist/cli/utils/http.d.ts +9 -0
  285. package/dist/cli/utils/http.d.ts.map +1 -1
  286. package/dist/cli/utils/parse.d.ts +3 -0
  287. package/dist/cli/utils/parse.d.ts.map +1 -1
  288. package/dist/cli/utils/skills.d.ts +1 -2
  289. package/dist/cli/utils/skills.d.ts.map +1 -1
  290. package/dist/cli/utils/workflow-message.d.ts +2 -0
  291. package/dist/cli/utils/workflow-message.d.ts.map +1 -0
  292. package/dist/config.d.ts +47 -0
  293. package/dist/config.d.ts.map +1 -1
  294. package/dist/core/bootstrap.d.ts.map +1 -1
  295. package/dist/core/index.d.ts +1 -0
  296. package/dist/core/index.d.ts.map +1 -1
  297. package/dist/core/logging.d.ts +3 -1
  298. package/dist/core/logging.d.ts.map +1 -1
  299. package/dist/core/runtime-assemblies.d.ts +22 -0
  300. package/dist/core/runtime-assemblies.d.ts.map +1 -0
  301. package/dist/core/types.d.ts +17 -0
  302. package/dist/core/types.d.ts.map +1 -1
  303. package/dist/desktop/audit.d.ts +37 -0
  304. package/dist/desktop/audit.d.ts.map +1 -0
  305. package/dist/desktop/errors.d.ts +7 -0
  306. package/dist/desktop/errors.d.ts.map +1 -0
  307. package/dist/desktop/index.d.ts +6 -0
  308. package/dist/desktop/index.d.ts.map +1 -0
  309. package/dist/desktop/runtime.d.ts +26 -0
  310. package/dist/desktop/runtime.d.ts.map +1 -0
  311. package/dist/desktop/types.d.ts +76 -0
  312. package/dist/desktop/types.d.ts.map +1 -0
  313. package/dist/extension-extractor.d.ts +6 -0
  314. package/dist/extension-extractor.d.ts.map +1 -1
  315. package/dist/fs-UMRKOBNN.js +7 -0
  316. package/dist/fs-UMRKOBNN.js.map +1 -0
  317. package/dist/index.d.ts.map +1 -1
  318. package/dist/index.js +1221 -460
  319. package/dist/index.js.map +1 -1
  320. package/dist/integrations/figma/assets.d.ts +13 -0
  321. package/dist/integrations/figma/assets.d.ts.map +1 -0
  322. package/dist/integrations/figma/auth.d.ts +3 -0
  323. package/dist/integrations/figma/auth.d.ts.map +1 -0
  324. package/dist/integrations/figma/client.d.ts +42 -0
  325. package/dist/integrations/figma/client.d.ts.map +1 -0
  326. package/dist/integrations/figma/mappers.d.ts +23 -0
  327. package/dist/integrations/figma/mappers.d.ts.map +1 -0
  328. package/dist/integrations/figma/normalize.d.ts +99 -0
  329. package/dist/integrations/figma/normalize.d.ts.map +1 -0
  330. package/dist/integrations/figma/url.d.ts +17 -0
  331. package/dist/integrations/figma/url.d.ts.map +1 -0
  332. package/dist/integrations/figma/variables.d.ts +21 -0
  333. package/dist/integrations/figma/variables.d.ts.map +1 -0
  334. package/dist/macros/execute-runtime.d.ts +19 -0
  335. package/dist/macros/execute-runtime.d.ts.map +1 -0
  336. package/dist/macros/execute.d.ts +3 -1
  337. package/dist/macros/execute.d.ts.map +1 -1
  338. package/dist/{macros-NUBRM44Y.js → macros-ND2M7LWU.js} +2 -2
  339. package/dist/opendevbrowser.d.ts.map +1 -1
  340. package/dist/opendevbrowser.js +1221 -460
  341. package/dist/opendevbrowser.js.map +1 -1
  342. package/dist/providers/blocker.d.ts.map +1 -1
  343. package/dist/providers/browser-fallback.d.ts +30 -0
  344. package/dist/providers/browser-fallback.d.ts.map +1 -0
  345. package/dist/providers/constraint.d.ts +45 -0
  346. package/dist/providers/constraint.d.ts.map +1 -0
  347. package/dist/providers/index.d.ts +11 -2
  348. package/dist/providers/index.d.ts.map +1 -1
  349. package/dist/providers/policy.d.ts.map +1 -1
  350. package/dist/providers/product-video-compiler.d.ts +92 -0
  351. package/dist/providers/product-video-compiler.d.ts.map +1 -0
  352. package/dist/providers/registry.d.ts +37 -1
  353. package/dist/providers/registry.d.ts.map +1 -1
  354. package/dist/providers/renderer.d.ts.map +1 -1
  355. package/dist/providers/research-compiler.d.ts +64 -0
  356. package/dist/providers/research-compiler.d.ts.map +1 -0
  357. package/dist/providers/research-executor.d.ts +27 -0
  358. package/dist/providers/research-executor.d.ts.map +1 -0
  359. package/dist/providers/runtime-bundle.d.ts +26 -0
  360. package/dist/providers/runtime-bundle.d.ts.map +1 -0
  361. package/dist/providers/runtime-factory.d.ts +6 -1
  362. package/dist/providers/runtime-factory.d.ts.map +1 -1
  363. package/dist/providers/runtime-policy.d.ts +24 -0
  364. package/dist/providers/runtime-policy.d.ts.map +1 -0
  365. package/dist/providers/shared/anti-bot-policy.d.ts +3 -2
  366. package/dist/providers/shared/anti-bot-policy.d.ts.map +1 -1
  367. package/dist/providers/shopping/index.d.ts +11 -1
  368. package/dist/providers/shopping/index.d.ts.map +1 -1
  369. package/dist/providers/shopping-compiler.d.ts +51 -0
  370. package/dist/providers/shopping-compiler.d.ts.map +1 -0
  371. package/dist/providers/shopping-executor.d.ts +18 -0
  372. package/dist/providers/shopping-executor.d.ts.map +1 -0
  373. package/dist/providers/shopping-postprocess.d.ts +46 -0
  374. package/dist/providers/shopping-postprocess.d.ts.map +1 -0
  375. package/dist/providers/shopping-workflow.d.ts +33 -0
  376. package/dist/providers/shopping-workflow.d.ts.map +1 -0
  377. package/dist/providers/social/platform.d.ts +2 -1
  378. package/dist/providers/social/platform.d.ts.map +1 -1
  379. package/dist/providers/social/search-quality.d.ts +16 -0
  380. package/dist/providers/social/search-quality.d.ts.map +1 -0
  381. package/dist/providers/social/youtube-resolver.d.ts +2 -1
  382. package/dist/providers/social/youtube-resolver.d.ts.map +1 -1
  383. package/dist/providers/social/youtube.d.ts.map +1 -1
  384. package/dist/providers/types.d.ts +116 -4
  385. package/dist/providers/types.d.ts.map +1 -1
  386. package/dist/providers/web/crawl-worker.d.ts.map +1 -1
  387. package/dist/providers/web/extract.d.ts +16 -0
  388. package/dist/providers/web/extract.d.ts.map +1 -1
  389. package/dist/providers/web/index.d.ts.map +1 -1
  390. package/dist/providers/workflow-contracts.d.ts +53 -0
  391. package/dist/providers/workflow-contracts.d.ts.map +1 -0
  392. package/dist/providers/workflows.d.ts +30 -6
  393. package/dist/providers/workflows.d.ts.map +1 -1
  394. package/dist/providers-G36AM3Z2.js +121 -0
  395. package/dist/providers-G36AM3Z2.js.map +1 -0
  396. package/dist/public-surface/generated-manifest.d.ts +1168 -0
  397. package/dist/public-surface/generated-manifest.d.ts.map +1 -0
  398. package/dist/public-surface/source.d.ts +437 -0
  399. package/dist/public-surface/source.d.ts.map +1 -0
  400. package/dist/relay/protocol.d.ts +108 -4
  401. package/dist/relay/protocol.d.ts.map +1 -1
  402. package/dist/relay/relay-endpoints.d.ts +21 -0
  403. package/dist/relay/relay-endpoints.d.ts.map +1 -1
  404. package/dist/relay/relay-server.d.ts +32 -1
  405. package/dist/relay/relay-server.d.ts.map +1 -1
  406. package/dist/relay/relay-types.d.ts +3 -0
  407. package/dist/relay/relay-types.d.ts.map +1 -1
  408. package/dist/skills/bundled-skill-directories.d.ts +8 -0
  409. package/dist/skills/bundled-skill-directories.d.ts.map +1 -0
  410. package/dist/skills/skill-loader.d.ts +9 -1
  411. package/dist/skills/skill-loader.d.ts.map +1 -1
  412. package/dist/skills/skill-loader.js +7 -0
  413. package/dist/skills/skill-loader.js.map +1 -0
  414. package/dist/skills/skill-nudge.d.ts.map +1 -1
  415. package/dist/skills/types.d.ts +31 -0
  416. package/dist/skills/types.d.ts.map +1 -1
  417. package/dist/snapshot/ops-snapshot.d.ts +1 -1
  418. package/dist/snapshot/ops-snapshot.d.ts.map +1 -1
  419. package/dist/snapshot/refs.d.ts +6 -1
  420. package/dist/snapshot/refs.d.ts.map +1 -1
  421. package/dist/snapshot/snapshotter.d.ts.map +1 -1
  422. package/dist/tools/annotate.d.ts.map +1 -1
  423. package/dist/tools/canvas.d.ts +4 -0
  424. package/dist/tools/canvas.d.ts.map +1 -0
  425. package/dist/tools/check.d.ts.map +1 -1
  426. package/dist/tools/click.d.ts.map +1 -1
  427. package/dist/tools/clone_component.d.ts.map +1 -1
  428. package/dist/tools/clone_page.d.ts.map +1 -1
  429. package/dist/tools/connect.d.ts.map +1 -1
  430. package/dist/tools/deps.d.ts +6 -0
  431. package/dist/tools/deps.d.ts.map +1 -1
  432. package/dist/tools/desktop-shared.d.ts +6 -0
  433. package/dist/tools/desktop-shared.d.ts.map +1 -0
  434. package/dist/tools/desktop_accessibility_snapshot.d.ts +4 -0
  435. package/dist/tools/desktop_accessibility_snapshot.d.ts.map +1 -0
  436. package/dist/tools/desktop_active_window.d.ts +4 -0
  437. package/dist/tools/desktop_active_window.d.ts.map +1 -0
  438. package/dist/tools/desktop_capture_desktop.d.ts +4 -0
  439. package/dist/tools/desktop_capture_desktop.d.ts.map +1 -0
  440. package/dist/tools/desktop_capture_window.d.ts +4 -0
  441. package/dist/tools/desktop_capture_window.d.ts.map +1 -0
  442. package/dist/tools/desktop_status.d.ts +4 -0
  443. package/dist/tools/desktop_status.d.ts.map +1 -0
  444. package/dist/tools/desktop_windows.d.ts +4 -0
  445. package/dist/tools/desktop_windows.d.ts.map +1 -0
  446. package/dist/tools/dialog.d.ts +4 -0
  447. package/dist/tools/dialog.d.ts.map +1 -0
  448. package/dist/tools/dom_get_html.d.ts.map +1 -1
  449. package/dist/tools/dom_get_text.d.ts.map +1 -1
  450. package/dist/tools/get_attr.d.ts.map +1 -1
  451. package/dist/tools/get_value.d.ts.map +1 -1
  452. package/dist/tools/goto.d.ts.map +1 -1
  453. package/dist/tools/hover.d.ts.map +1 -1
  454. package/dist/tools/index.d.ts +3 -0
  455. package/dist/tools/index.d.ts.map +1 -1
  456. package/dist/tools/is_checked.d.ts.map +1 -1
  457. package/dist/tools/is_enabled.d.ts.map +1 -1
  458. package/dist/tools/is_visible.d.ts.map +1 -1
  459. package/dist/tools/launch.d.ts.map +1 -1
  460. package/dist/tools/macro_resolve.d.ts.map +1 -1
  461. package/dist/tools/perf.d.ts.map +1 -1
  462. package/dist/tools/pointer_down.d.ts +4 -0
  463. package/dist/tools/pointer_down.d.ts.map +1 -0
  464. package/dist/tools/pointer_drag.d.ts +4 -0
  465. package/dist/tools/pointer_drag.d.ts.map +1 -0
  466. package/dist/tools/pointer_move.d.ts +4 -0
  467. package/dist/tools/pointer_move.d.ts.map +1 -0
  468. package/dist/tools/pointer_up.d.ts +4 -0
  469. package/dist/tools/pointer_up.d.ts.map +1 -0
  470. package/dist/tools/press.d.ts.map +1 -1
  471. package/dist/tools/product_video_run.d.ts.map +1 -1
  472. package/dist/tools/prompting_guide.d.ts.map +1 -1
  473. package/dist/tools/research_run.d.ts.map +1 -1
  474. package/dist/tools/response.d.ts +4 -1
  475. package/dist/tools/response.d.ts.map +1 -1
  476. package/dist/tools/review.d.ts +4 -0
  477. package/dist/tools/review.d.ts.map +1 -0
  478. package/dist/tools/screencast_start.d.ts +4 -0
  479. package/dist/tools/screencast_start.d.ts.map +1 -0
  480. package/dist/tools/screencast_stop.d.ts +4 -0
  481. package/dist/tools/screencast_stop.d.ts.map +1 -0
  482. package/dist/tools/screenshot.d.ts.map +1 -1
  483. package/dist/tools/scroll.d.ts.map +1 -1
  484. package/dist/tools/scroll_into_view.d.ts.map +1 -1
  485. package/dist/tools/select.d.ts.map +1 -1
  486. package/dist/tools/session_inspector.d.ts +4 -0
  487. package/dist/tools/session_inspector.d.ts.map +1 -0
  488. package/dist/tools/shopping_run.d.ts.map +1 -1
  489. package/dist/tools/skill_list.d.ts.map +1 -1
  490. package/dist/tools/skill_load.d.ts.map +1 -1
  491. package/dist/tools/snapshot.d.ts.map +1 -1
  492. package/dist/tools/type.d.ts.map +1 -1
  493. package/dist/tools/uncheck.d.ts.map +1 -1
  494. package/dist/tools/upload.d.ts +4 -0
  495. package/dist/tools/upload.d.ts.map +1 -0
  496. package/dist/tools/wait.d.ts.map +1 -1
  497. package/dist/tools/workflow-runtime.d.ts +4 -2
  498. package/dist/tools/workflow-runtime.d.ts.map +1 -1
  499. package/dist/utils/package-assets.d.ts +4 -0
  500. package/dist/utils/package-assets.d.ts.map +1 -0
  501. package/extension/canvas.html +1006 -0
  502. package/extension/dist/annotate-content.css +15 -6
  503. package/extension/dist/annotate-content.js +175 -35
  504. package/extension/dist/annotation-payload.js +199 -0
  505. package/extension/dist/background.js +544 -69
  506. package/extension/dist/canvas/canvas-runtime.js +1490 -0
  507. package/extension/dist/canvas/model.js +341 -0
  508. package/extension/dist/canvas/viewport-fit.js +67 -0
  509. package/extension/dist/canvas-page.js +3609 -0
  510. package/extension/dist/ops/dom-bridge.js +255 -3
  511. package/extension/dist/ops/ops-runtime.js +3324 -301
  512. package/extension/dist/ops/ops-session-store.js +97 -112
  513. package/extension/dist/ops/snapshot-builder.js +2 -2
  514. package/extension/dist/ops/snapshot-shared.js +2 -2
  515. package/extension/dist/ops/target-session-coordinator.js +159 -0
  516. package/extension/dist/popup.js +201 -42
  517. package/extension/dist/services/CDPRouter.js +1567 -63
  518. package/extension/dist/services/ConnectionManager.js +453 -78
  519. package/extension/dist/services/RelayClient.js +79 -30
  520. package/extension/dist/services/TabManager.js +118 -22
  521. package/extension/dist/services/TargetSessionMap.js +127 -3
  522. package/extension/dist/services/attach-errors.js +20 -0
  523. package/extension/dist/services/cdp-router-commands.js +135 -8
  524. package/extension/dist/services/url-restrictions.js +9 -13
  525. package/extension/dist/types.js +2 -0
  526. package/extension/manifest.json +2 -2
  527. package/extension/popup.html +59 -6
  528. package/package.json +19 -9
  529. package/skills/AGENTS.md +8 -4
  530. package/skills/opendevbrowser-best-practices/SKILL.md +183 -6
  531. package/skills/opendevbrowser-best-practices/artifacts/browser-agent-known-issues-matrix.md +1 -0
  532. package/skills/opendevbrowser-best-practices/artifacts/canvas-governance-playbook.md +141 -0
  533. package/skills/opendevbrowser-best-practices/artifacts/command-channel-reference.md +129 -19
  534. package/skills/opendevbrowser-best-practices/artifacts/parity-gates.md +9 -2
  535. package/skills/opendevbrowser-best-practices/artifacts/provider-workflows.md +6 -0
  536. package/skills/opendevbrowser-best-practices/artifacts/skill-runtime-surface-matrix.md +58 -0
  537. package/skills/opendevbrowser-best-practices/assets/templates/canvas-blocker-checklist.json +70 -0
  538. package/skills/opendevbrowser-best-practices/assets/templates/canvas-feedback-eval.json +73 -0
  539. package/skills/opendevbrowser-best-practices/assets/templates/canvas-generation-plan.v1.json +67 -0
  540. package/skills/opendevbrowser-best-practices/assets/templates/canvas-handshake-example.json +126 -0
  541. package/skills/opendevbrowser-best-practices/assets/templates/robustness-checklist.json +57 -0
  542. package/skills/opendevbrowser-best-practices/assets/templates/skill-runtime-pack-matrix.json +674 -0
  543. package/skills/opendevbrowser-best-practices/assets/templates/surface-audit-checklist.json +12 -3
  544. package/skills/opendevbrowser-best-practices/scripts/odb-workflow.sh +107 -12
  545. package/skills/opendevbrowser-best-practices/scripts/resolve-odb-cli.sh +100 -0
  546. package/skills/opendevbrowser-best-practices/scripts/run-robustness-audit.sh +83 -1
  547. package/skills/opendevbrowser-best-practices/scripts/validate-skill-assets.sh +365 -84
  548. package/skills/opendevbrowser-best-practices/scripts/validator-fixture-cli.sh +208 -0
  549. package/skills/opendevbrowser-continuity-ledger/SKILL.md +14 -1
  550. package/skills/opendevbrowser-continuity-ledger/scripts/validate-skill-assets.sh +61 -0
  551. package/skills/opendevbrowser-data-extraction/SKILL.md +6 -0
  552. package/skills/opendevbrowser-data-extraction/scripts/validate-skill-assets.sh +112 -0
  553. package/skills/opendevbrowser-design-agent/SKILL.md +275 -0
  554. package/skills/opendevbrowser-design-agent/artifacts/app-shell-and-state-wiring.md +84 -0
  555. package/skills/opendevbrowser-design-agent/artifacts/async-search-state-ownership.md +58 -0
  556. package/skills/opendevbrowser-design-agent/artifacts/component-pattern-index.md +130 -0
  557. package/skills/opendevbrowser-design-agent/artifacts/design-contract-playbook.md +157 -0
  558. package/skills/opendevbrowser-design-agent/artifacts/design-release-gate.md +40 -0
  559. package/skills/opendevbrowser-design-agent/artifacts/design-workflows.md +153 -0
  560. package/skills/opendevbrowser-design-agent/artifacts/existing-surface-adaptation.md +56 -0
  561. package/skills/opendevbrowser-design-agent/artifacts/external-pattern-synthesis.md +103 -0
  562. package/skills/opendevbrowser-design-agent/artifacts/frontend-evaluation-rubric.md +61 -0
  563. package/skills/opendevbrowser-design-agent/artifacts/implementation-anti-patterns.md +163 -0
  564. package/skills/opendevbrowser-design-agent/artifacts/isolated-preview-validation.md +68 -0
  565. package/skills/opendevbrowser-design-agent/artifacts/loading-and-feedback-surfaces.md +56 -0
  566. package/skills/opendevbrowser-design-agent/artifacts/opendevbrowser-ui-example-map.md +44 -0
  567. package/skills/opendevbrowser-design-agent/artifacts/performance-audit-playbook.md +70 -0
  568. package/skills/opendevbrowser-design-agent/artifacts/research-harvest-workflow.md +81 -0
  569. package/skills/opendevbrowser-design-agent/artifacts/scroll-reveal-surface-planning.md +64 -0
  570. package/skills/opendevbrowser-design-agent/artifacts/state-ownership-matrix.md +36 -0
  571. package/skills/opendevbrowser-design-agent/artifacts/theming-and-token-ownership.md +43 -0
  572. package/skills/opendevbrowser-design-agent/assets/templates/canvas-generation-plan.design.v1.json +58 -0
  573. package/skills/opendevbrowser-design-agent/assets/templates/design-audit-report.v1.md +34 -0
  574. package/skills/opendevbrowser-design-agent/assets/templates/design-brief.v1.md +40 -0
  575. package/skills/opendevbrowser-design-agent/assets/templates/design-contract.v1.json +226 -0
  576. package/skills/opendevbrowser-design-agent/assets/templates/design-release-gate.v1.json +35 -0
  577. package/skills/opendevbrowser-design-agent/assets/templates/design-review-checklist.json +57 -0
  578. package/skills/opendevbrowser-design-agent/assets/templates/real-surface-design-matrix.json +32 -0
  579. package/skills/opendevbrowser-design-agent/assets/templates/reference-pattern-board.v1.json +31 -0
  580. package/skills/opendevbrowser-design-agent/scripts/design-workflow.sh +171 -0
  581. package/skills/opendevbrowser-design-agent/scripts/extract-canvas-plan.sh +56 -0
  582. package/skills/opendevbrowser-design-agent/scripts/validate-skill-assets.sh +223 -0
  583. package/skills/opendevbrowser-form-testing/SKILL.md +19 -3
  584. package/skills/opendevbrowser-form-testing/artifacts/form-workflows.md +5 -4
  585. package/skills/opendevbrowser-form-testing/assets/templates/challenge-decision-tree.json +2 -0
  586. package/skills/opendevbrowser-form-testing/scripts/validate-skill-assets.sh +109 -0
  587. package/skills/opendevbrowser-login-automation/SKILL.md +21 -3
  588. package/skills/opendevbrowser-login-automation/artifacts/login-workflows.md +5 -4
  589. package/skills/opendevbrowser-login-automation/assets/templates/auth-signals.json +5 -0
  590. package/skills/opendevbrowser-login-automation/assets/templates/login-scenario-matrix.json +3 -2
  591. package/skills/opendevbrowser-login-automation/scripts/run-login-workflow.sh +17 -1
  592. package/skills/opendevbrowser-login-automation/scripts/validate-skill-assets.sh +133 -0
  593. package/skills/opendevbrowser-product-presentation-asset/SKILL.md +23 -11
  594. package/skills/opendevbrowser-product-presentation-asset/artifacts/asset-pack-assembly.md +5 -3
  595. package/skills/opendevbrowser-product-presentation-asset/assets/templates/shot-list.md +2 -0
  596. package/skills/opendevbrowser-product-presentation-asset/assets/templates/video-assembly.md +3 -2
  597. package/skills/opendevbrowser-product-presentation-asset/scripts/capture-screenshots.sh +5 -1
  598. package/skills/opendevbrowser-product-presentation-asset/scripts/collect-product.sh +6 -2
  599. package/skills/opendevbrowser-product-presentation-asset/scripts/download-images.sh +5 -1
  600. package/skills/opendevbrowser-product-presentation-asset/scripts/render-video-brief.sh +20 -7
  601. package/skills/opendevbrowser-product-presentation-asset/scripts/validate-skill-assets.sh +39 -0
  602. package/skills/opendevbrowser-product-presentation-asset/scripts/write-manifest.sh +5 -1
  603. package/skills/opendevbrowser-research/SKILL.md +14 -6
  604. package/skills/opendevbrowser-research/scripts/render-output.sh +5 -1
  605. package/skills/opendevbrowser-research/scripts/run-research.sh +5 -1
  606. package/skills/opendevbrowser-research/scripts/validate-skill-assets.sh +45 -0
  607. package/skills/opendevbrowser-research/scripts/write-artifacts.sh +5 -1
  608. package/skills/opendevbrowser-shopping/SKILL.md +20 -1
  609. package/skills/opendevbrowser-shopping/scripts/normalize-offers.sh +6 -2
  610. package/skills/opendevbrowser-shopping/scripts/run-deal-hunt.sh +5 -1
  611. package/skills/opendevbrowser-shopping/scripts/run-shopping.sh +5 -1
  612. package/skills/opendevbrowser-shopping/scripts/validate-skill-assets.sh +54 -0
  613. package/dist/chunk-ST7CO5FA.js +0 -18668
  614. package/dist/chunk-ST7CO5FA.js.map +0 -1
  615. /package/dist/{chunk-7W3SPXIB.js.map → chunk-FUSXMW3G.js.map} +0 -0
  616. /package/dist/{macros-NUBRM44Y.js.map → macros-ND2M7LWU.js.map} +0 -0
@@ -3,10 +3,21 @@ import { NativePortManager } from "./services/NativePortManager.js";
3
3
  import { DEFAULT_AUTO_CONNECT, DEFAULT_AUTO_PAIR, DEFAULT_DISCOVERY_PORT, DEFAULT_NATIVE_ENABLED, DEFAULT_PAIRING_ENABLED, DEFAULT_RELAY_PORT } from "./relay-settings.js";
4
4
  import { logError } from "./logging.js";
5
5
  import { OpsRuntime } from "./ops/ops-runtime.js";
6
+ import { CanvasRuntime } from "./canvas/canvas-runtime.js";
7
+ import { formatDispatchSourceLabel, stripAnnotationPayloadScreenshots } from "./annotation-payload.js";
8
+ import { getRestrictionMessage } from "./services/url-restrictions.js";
6
9
  const connection = new ConnectionManager();
10
+ let canvasRuntime;
7
11
  const opsRuntime = new OpsRuntime({
8
12
  send: (message) => connection.sendOpsMessage(message),
9
- cdp: connection.getCdpRouter()
13
+ cdp: connection.getCdpRouter(),
14
+ getCanvasPageState: (targetId) => canvasRuntime.getPageStateByTargetId(targetId),
15
+ performCanvasPageAction: (targetId, action, selector) => canvasRuntime.performPageAction(targetId, action, selector)
16
+ });
17
+ canvasRuntime = new CanvasRuntime({
18
+ send: (message) => connection.sendCanvasMessage(message),
19
+ registerOpsCanvasTarget: (browserSessionId, targetId) => opsRuntime.registerCanvasTargetForSession(browserSessionId, targetId),
20
+ unregisterOpsCanvasTarget: (browserSessionId, targetId) => opsRuntime.unregisterCanvasTargetForSession(browserSessionId, targetId)
10
21
  });
11
22
  const nativePort = new NativePortManager({
12
23
  onMessage: (payload) => {
@@ -22,6 +33,7 @@ let autoConnectInFlight = false;
22
33
  let statusNoteOverride = null;
23
34
  let retryScheduled = false;
24
35
  let retryDelayMs = 5000;
36
+ let autoConnectEnabled = DEFAULT_AUTO_CONNECT;
25
37
  let nativeEnabled = DEFAULT_NATIVE_ENABLED;
26
38
  const RETRY_ALARM_NAME = "opendevbrowser-auto-connect";
27
39
  const RETRY_MAX_MS = 60_000;
@@ -29,12 +41,20 @@ const ANNOTATION_CONTENT_SCRIPT = "dist/annotate-content.js";
29
41
  const ANNOTATION_CONTENT_STYLE = "dist/annotate-content.css";
30
42
  const ANNOTATION_MAX_PAYLOAD_BYTES = 10 * 1024 * 1024;
31
43
  const ANNOTATION_REQUEST_TIMEOUT_MS = 120_000;
44
+ const ANNOTATION_RECEIVER_UNAVAILABLE_MESSAGE = "Annotation UI did not load in the page. Reload the tab and retry.";
32
45
  const LAST_ANNOTATION_META_KEY = "annotationLastMeta";
33
46
  const LAST_ANNOTATION_PAYLOAD_KEY = "annotationLastPayloadSansScreenshots";
47
+ const LAST_AGENT_ANNOTATION_META_KEY = "annotationAgentMeta";
48
+ const LAST_AGENT_ANNOTATION_PAYLOAD_KEY = "annotationAgentPayloadSansScreenshots";
49
+ const LAST_ANNOTATABLE_TAB_ID_KEY = "annotationLastTabId";
50
+ const POPUP_ANNOTATION_TARGET_TTL_MS = 10_000;
34
51
  const BADGE_CONNECTED_DOT_COLOR = "#16a34a";
35
52
  const BADGE_DISCONNECTED_DOT_COLOR = "#dc2626";
36
53
  const annotationSessions = new Map();
37
54
  let lastAnnotationFull = null;
55
+ let lastAgentAnnotationFull = null;
56
+ let lastAnnotatableTabId = null;
57
+ let lastPopupAnnotationTarget = null;
38
58
  connection.onAnnotationCommand((command) => {
39
59
  handleRelayAnnotationCommand(command).catch((error) => {
40
60
  logError("annotation.relay_command", error, { code: "annotation_command_failed" });
@@ -43,16 +63,9 @@ connection.onAnnotationCommand((command) => {
43
63
  connection.onOpsMessage((message) => {
44
64
  opsRuntime.handleMessage(message);
45
65
  });
46
- const RESTRICTED_PROTOCOLS = new Set([
47
- "chrome:",
48
- "chrome-extension:",
49
- "chrome-search:",
50
- "chrome-untrusted:",
51
- "devtools:",
52
- "chrome-devtools:",
53
- "edge:",
54
- "brave:"
55
- ]);
66
+ connection.onCanvasMessage((message) => {
67
+ canvasRuntime.handleMessage(message);
68
+ });
56
69
  const updateBadge = (status) => {
57
70
  const isConnected = status === "connected";
58
71
  const dotColor = isConnected ? BADGE_CONNECTED_DOT_COLOR : BADGE_DISCONNECTED_DOT_COLOR;
@@ -139,6 +152,16 @@ const setStorage = (items) => {
139
152
  const setStatusNoteOverride = (note) => {
140
153
  statusNoteOverride = note;
141
154
  };
155
+ const loadStoredAnnotatableTabId = async () => {
156
+ const data = await new Promise((resolve) => {
157
+ chrome.storage.local.get([LAST_ANNOTATABLE_TAB_ID_KEY], (items) => resolve(items));
158
+ });
159
+ const value = data[LAST_ANNOTATABLE_TAB_ID_KEY];
160
+ return typeof value === "number" && Number.isInteger(value) ? value : null;
161
+ };
162
+ const persistAnnotatableTabId = async (tabId) => {
163
+ await setStorage({ [LAST_ANNOTATABLE_TAB_ID_KEY]: tabId });
164
+ };
142
165
  const buildRelayHealthNote = (health) => {
143
166
  if (!health) {
144
167
  return "Relay unreachable. Start the daemon and retry.";
@@ -149,13 +172,15 @@ const buildRelayHealthNote = (health) => {
149
172
  case "pairing_required":
150
173
  return "Pairing required. Enable auto-pair or set the token.";
151
174
  case "handshake_incomplete":
152
- return "Extension handshake pending. Keep the relay running and retry.";
175
+ return "Extension websocket is up but the daemon-extension handshake is incomplete. Open the popup and click Connect again to re-establish a clean handshake, then confirm `status --daemon` shows ext=on and handshake=on.";
153
176
  case "extension_disconnected":
154
177
  return "Extension not connected to relay. Click Connect.";
155
178
  case "annotation_disconnected":
156
179
  return "Annotation channel disconnected. Keep the extension open and retry.";
157
180
  case "ops_disconnected":
158
181
  return "Ops channel disconnected. Start a new session and retry.";
182
+ case "canvas_disconnected":
183
+ return "Canvas channel disconnected. Reopen the design canvas command and retry.";
159
184
  case "cdp_disconnected":
160
185
  return "No CDP clients connected. Start a session and retry.";
161
186
  case "relay_down":
@@ -243,23 +268,11 @@ const parseEpoch = (value) => {
243
268
  }
244
269
  return null;
245
270
  };
246
- const isWebStoreUrl = (url) => {
247
- if (url.hostname === "chromewebstore.google.com") {
248
- return true;
249
- }
250
- if (url.hostname === "chrome.google.com" && url.pathname.startsWith("/webstore")) {
251
- return true;
252
- }
253
- return false;
254
- };
255
- const getRestrictionMessage = (url) => {
256
- if (RESTRICTED_PROTOCOLS.has(url.protocol)) {
257
- return "Active tab uses a restricted URL scheme. Open a normal http(s) page and retry.";
258
- }
259
- if (isWebStoreUrl(url)) {
260
- return "Chrome Web Store tabs cannot be annotated. Open a normal tab and retry.";
261
- }
262
- return null;
271
+ const getAnnotationRestrictionMessage = (url) => {
272
+ return getRestrictionMessage(url, {
273
+ restrictedSchemeMessage: "Active tab uses a restricted URL scheme. Open a normal http(s) page and retry.",
274
+ webStoreMessage: "Chrome Web Store tabs cannot be annotated. Open a normal tab and retry."
275
+ });
263
276
  };
264
277
  const fetchRelayConfig = async (port) => {
265
278
  try {
@@ -303,6 +316,7 @@ const fetchRelayHealth = async (port) => {
303
316
  const cdpConnected = data.cdpConnected === true;
304
317
  const annotationConnected = data.annotationConnected === true;
305
318
  const opsConnected = data.opsConnected === true;
319
+ const canvasConnected = data.canvasConnected === true;
306
320
  const pairingRequired = data.pairingRequired === true;
307
321
  const ok = extensionConnected && handshake;
308
322
  return {
@@ -313,6 +327,7 @@ const fetchRelayHealth = async (port) => {
313
327
  cdpConnected,
314
328
  annotationConnected,
315
329
  opsConnected,
330
+ canvasConnected,
316
331
  pairingRequired
317
332
  };
318
333
  }
@@ -432,10 +447,166 @@ const waitForTabComplete = async (tabId, timeoutMs = 10000) => {
432
447
  chrome.tabs.onUpdated.addListener(listener);
433
448
  });
434
449
  };
450
+ const waitForAnnotationTabReady = async (tabId) => {
451
+ const tab = await getTab(tabId);
452
+ if (!tab || tab.status === "complete") {
453
+ return;
454
+ }
455
+ try {
456
+ await waitForTabComplete(tabId);
457
+ }
458
+ catch (error) {
459
+ if (error instanceof Error && error.message === "Tab load timeout") {
460
+ throw new Error("Active tab is still loading. Wait for it to finish and retry.");
461
+ }
462
+ throw error;
463
+ }
464
+ };
435
465
  const getActiveTab = async () => {
436
466
  const tabs = await chrome.tabs.query({ active: true, lastFocusedWindow: true });
437
467
  return tabs[0] ?? null;
438
468
  };
469
+ const getTabRecency = (tab) => {
470
+ return typeof tab.lastAccessed === "number" ? tab.lastAccessed : -1;
471
+ };
472
+ const rememberAnnotatableTab = (tab) => {
473
+ if (!tab || typeof tab.id !== "number") {
474
+ return;
475
+ }
476
+ if (isRestrictedTab(tab) !== null) {
477
+ if (lastAnnotatableTabId === tab.id) {
478
+ lastAnnotatableTabId = null;
479
+ void persistAnnotatableTabId(null).catch((error) => {
480
+ logError("annotation.persist_tab", error, { code: "annotation_tab_persist_failed", extra: { tabId: null } });
481
+ });
482
+ }
483
+ return;
484
+ }
485
+ lastAnnotatableTabId = tab.id;
486
+ void persistAnnotatableTabId(tab.id).catch((error) => {
487
+ logError("annotation.persist_tab", error, { code: "annotation_tab_persist_failed", extra: { tabId: tab.id } });
488
+ });
489
+ };
490
+ const getRememberedAnnotatableTab = async (excludeTabId) => {
491
+ if (typeof lastAnnotatableTabId !== "number") {
492
+ lastAnnotatableTabId = await loadStoredAnnotatableTabId();
493
+ }
494
+ if (typeof lastAnnotatableTabId !== "number") {
495
+ return null;
496
+ }
497
+ if (typeof excludeTabId === "number" && lastAnnotatableTabId === excludeTabId) {
498
+ return null;
499
+ }
500
+ const tabId = lastAnnotatableTabId;
501
+ const tab = await getTab(tabId);
502
+ if (!tab || isRestrictedTab(tab) !== null) {
503
+ if (lastAnnotatableTabId === tabId) {
504
+ lastAnnotatableTabId = null;
505
+ void persistAnnotatableTabId(null).catch((error) => {
506
+ logError("annotation.persist_tab", error, { code: "annotation_tab_persist_failed", extra: { tabId: null } });
507
+ });
508
+ }
509
+ return null;
510
+ }
511
+ return tab;
512
+ };
513
+ const clearPopupAnnotationTarget = (tabId) => {
514
+ if (!lastPopupAnnotationTarget) {
515
+ return;
516
+ }
517
+ if (typeof tabId === "number" && lastPopupAnnotationTarget.tabId !== tabId) {
518
+ return;
519
+ }
520
+ lastPopupAnnotationTarget = null;
521
+ };
522
+ const rememberPopupAnnotationTarget = (tabId, bootId) => {
523
+ const previousBootId = lastPopupAnnotationTarget?.tabId === tabId
524
+ ? lastPopupAnnotationTarget.bootId
525
+ : null;
526
+ lastPopupAnnotationTarget = {
527
+ tabId,
528
+ bootId: typeof bootId === "string" ? bootId : previousBootId,
529
+ resolvedAt: Date.now()
530
+ };
531
+ };
532
+ const getCachedPopupAnnotationTab = async () => {
533
+ const cached = lastPopupAnnotationTarget;
534
+ if (!cached) {
535
+ return null;
536
+ }
537
+ if (Date.now() - cached.resolvedAt > POPUP_ANNOTATION_TARGET_TTL_MS) {
538
+ clearPopupAnnotationTarget(cached.tabId);
539
+ return null;
540
+ }
541
+ const tab = await getTab(cached.tabId);
542
+ if (!tab || isRestrictedTab(tab) !== null) {
543
+ clearPopupAnnotationTarget(cached.tabId);
544
+ return null;
545
+ }
546
+ return tab;
547
+ };
548
+ const getPopupAnnotationTab = async (tabIdHint) => {
549
+ const cached = await getCachedPopupAnnotationTab();
550
+ if (cached) {
551
+ rememberAnnotatableTab(cached);
552
+ return cached;
553
+ }
554
+ if (typeof tabIdHint === "number") {
555
+ const hinted = await getTab(tabIdHint);
556
+ if (hinted && isRestrictedTab(hinted) === null) {
557
+ rememberAnnotatableTab(hinted);
558
+ if (typeof hinted.id === "number") {
559
+ rememberPopupAnnotationTarget(hinted.id);
560
+ }
561
+ return hinted;
562
+ }
563
+ }
564
+ const preferred = await getPreferredAnnotationTab();
565
+ if (preferred && typeof preferred.id === "number") {
566
+ rememberPopupAnnotationTarget(preferred.id);
567
+ }
568
+ return preferred;
569
+ };
570
+ const getMostRecentAnnotatableTab = async (excludeTabId) => {
571
+ const tabs = await chrome.tabs.query({});
572
+ const candidates = tabs
573
+ .filter((tab) => {
574
+ if (typeof tab.id !== "number") {
575
+ return false;
576
+ }
577
+ if (typeof excludeTabId === "number" && tab.id === excludeTabId) {
578
+ return false;
579
+ }
580
+ return isRestrictedTab(tab) === null;
581
+ })
582
+ .sort((left, right) => {
583
+ const recencyDelta = getTabRecency(right) - getTabRecency(left);
584
+ if (recencyDelta !== 0) {
585
+ return recencyDelta;
586
+ }
587
+ const activeDelta = Number(Boolean(right.active)) - Number(Boolean(left.active));
588
+ if (activeDelta !== 0) {
589
+ return activeDelta;
590
+ }
591
+ return (right.id ?? 0) - (left.id ?? 0);
592
+ });
593
+ return candidates[0] ?? null;
594
+ };
595
+ const getPreferredAnnotationTab = async () => {
596
+ const active = await getActiveTab();
597
+ if (active && isRestrictedTab(active) === null) {
598
+ rememberAnnotatableTab(active);
599
+ return active;
600
+ }
601
+ const excludeTabId = active && typeof active.id === "number" ? active.id : undefined;
602
+ const remembered = await getRememberedAnnotatableTab(excludeTabId);
603
+ if (remembered) {
604
+ return remembered;
605
+ }
606
+ const fallback = await getMostRecentAnnotatableTab(excludeTabId);
607
+ rememberAnnotatableTab(fallback);
608
+ return fallback ?? active;
609
+ };
439
610
  const resolveAnnotationTab = async (command) => {
440
611
  if (typeof command.tabId === "number") {
441
612
  if (command.url) {
@@ -456,7 +627,7 @@ const resolveAnnotationTab = async (command) => {
456
627
  }
457
628
  return created;
458
629
  }
459
- const active = await getActiveTab();
630
+ const active = await getPreferredAnnotationTab();
460
631
  if (!active) {
461
632
  throw new Error("No active tab available");
462
633
  }
@@ -474,7 +645,7 @@ const isRestrictedTab = (tab) => {
474
645
  logError("annotation.parse_tab_url", error, { code: "tab_url_parse_failed" });
475
646
  return "Active tab URL is invalid.";
476
647
  }
477
- return getRestrictionMessage(parsed);
648
+ return getAnnotationRestrictionMessage(parsed);
478
649
  };
479
650
  const injectAnnotationAssets = async (tabId) => {
480
651
  await new Promise((resolve, reject) => {
@@ -516,20 +687,56 @@ const isMissingAnnotationReceiverError = (error) => {
516
687
  }
517
688
  return error.message.includes("Receiving end does not exist");
518
689
  };
690
+ const readAnnotationBridgeStatus = (response) => {
691
+ if (typeof response !== "object" || response === null) {
692
+ return null;
693
+ }
694
+ const candidate = response;
695
+ if (candidate.ok !== true || typeof candidate.bootId !== "string" || typeof candidate.active !== "boolean") {
696
+ return null;
697
+ }
698
+ return {
699
+ ok: true,
700
+ bootId: candidate.bootId,
701
+ active: candidate.active
702
+ };
703
+ };
704
+ const sendAnnotationMessageToTab = async (tabId, message) => {
705
+ try {
706
+ return await sendMessageToTab(tabId, message);
707
+ }
708
+ catch (error) {
709
+ if (!isMissingAnnotationReceiverError(error)) {
710
+ throw error;
711
+ }
712
+ await ensureAnnotationInjected(tabId);
713
+ try {
714
+ return await sendMessageToTab(tabId, message);
715
+ }
716
+ catch (retryError) {
717
+ if (isMissingAnnotationReceiverError(retryError)) {
718
+ throw new Error(ANNOTATION_RECEIVER_UNAVAILABLE_MESSAGE);
719
+ }
720
+ throw retryError;
721
+ }
722
+ }
723
+ };
519
724
  const sleep = async (ms) => {
520
725
  await new Promise((resolve) => setTimeout(resolve, ms));
521
726
  };
522
727
  const pingAnnotation = async (tabId) => {
523
728
  const response = await sendMessageToTab(tabId, { type: "annotation:ping" });
524
- const ok = typeof response === "object" && response !== null && response.ok === true;
525
- if (!ok) {
729
+ const ready = readAnnotationBridgeStatus(response);
730
+ if (!ready) {
526
731
  throw new Error("Annotation ping failed");
527
732
  }
733
+ rememberPopupAnnotationTarget(tabId, ready.bootId);
734
+ return ready;
528
735
  };
529
736
  const ensureAnnotationInjected = async (tabId) => {
737
+ await waitForAnnotationTabReady(tabId);
530
738
  try {
531
- await pingAnnotation(tabId);
532
- return;
739
+ return await pingAnnotation(tabId);
533
740
  }
534
741
  catch (error) {
535
742
  // Initial ping can fail before content script injection; avoid noisy logs for missing receivers.
@@ -541,9 +748,9 @@ const ensureAnnotationInjected = async (tabId) => {
541
748
  let lastError = null;
542
749
  for (let attempt = 0; attempt <= backoff.length; attempt += 1) {
543
750
  try {
751
+ await waitForAnnotationTabReady(tabId);
544
752
  await injectAnnotationAssets(tabId);
545
- await pingAnnotation(tabId);
546
- return;
753
+ return await pingAnnotation(tabId);
547
754
  }
548
755
  catch (error) {
549
756
  lastError = error;
@@ -554,13 +761,55 @@ const ensureAnnotationInjected = async (tabId) => {
554
761
  }
555
762
  }
556
763
  }
764
+ if (isMissingAnnotationReceiverError(lastError)) {
765
+ throw new Error(ANNOTATION_RECEIVER_UNAVAILABLE_MESSAGE);
766
+ }
557
767
  if (lastError instanceof Error) {
558
768
  throw lastError;
559
769
  }
560
770
  throw new Error("Annotation injection failed");
561
771
  };
562
- const probeAnnotationInjected = async () => {
563
- const active = await getActiveTab();
772
+ const refreshAnnotationInjected = async (tabId) => {
773
+ await waitForAnnotationTabReady(tabId);
774
+ await injectAnnotationAssets(tabId);
775
+ return await pingAnnotation(tabId);
776
+ };
777
+ const startAnnotationUi = async (tabId, requestId, options, url) => {
778
+ let lastError = null;
779
+ for (let attempt = 0; attempt < 2; attempt += 1) {
780
+ try {
781
+ const response = await sendAnnotationMessageToTab(tabId, {
782
+ type: "annotation:start",
783
+ requestId,
784
+ options: options ?? {},
785
+ url
786
+ });
787
+ const ready = readAnnotationBridgeStatus(response);
788
+ if (ready?.active) {
789
+ rememberPopupAnnotationTarget(tabId, ready.bootId);
790
+ return ready;
791
+ }
792
+ throw new Error("Annotation start acknowledgement missing active bridge.");
793
+ }
794
+ catch (error) {
795
+ lastError = error;
796
+ if (attempt === 0) {
797
+ await refreshAnnotationInjected(tabId);
798
+ continue;
799
+ }
800
+ }
801
+ }
802
+ if (isMissingAnnotationReceiverError(lastError)
803
+ || (lastError instanceof Error && lastError.message.includes("active bridge"))) {
804
+ throw new Error(ANNOTATION_RECEIVER_UNAVAILABLE_MESSAGE);
805
+ }
806
+ if (lastError instanceof Error) {
807
+ throw lastError;
808
+ }
809
+ throw new Error("Annotation start failed");
810
+ };
811
+ const probeAnnotationInjected = async (tabIdHint) => {
812
+ const active = await getPopupAnnotationTab(tabIdHint);
564
813
  if (!active || typeof active.id !== "number") {
565
814
  return { injected: false, detail: "No active tab available." };
566
815
  }
@@ -568,8 +817,12 @@ const probeAnnotationInjected = async () => {
568
817
  if (restricted) {
569
818
  return { injected: false, detail: restricted };
570
819
  }
820
+ if (active.status && active.status !== "complete") {
821
+ return { injected: false, detail: "Active tab is still loading." };
822
+ }
571
823
  try {
572
- await pingAnnotation(active.id);
824
+ const ready = await pingAnnotation(active.id);
825
+ rememberPopupAnnotationTarget(active.id, ready.bootId);
573
826
  return { injected: true };
574
827
  }
575
828
  catch (error) {
@@ -578,7 +831,7 @@ const probeAnnotationInjected = async () => {
578
831
  }
579
832
  };
580
833
  const toggleAnnotationUi = async () => {
581
- const tab = await getActiveTab();
834
+ const tab = await getPreferredAnnotationTab();
582
835
  if (!tab || typeof tab.id !== "number") {
583
836
  return;
584
837
  }
@@ -587,7 +840,7 @@ const toggleAnnotationUi = async () => {
587
840
  return;
588
841
  }
589
842
  await ensureAnnotationInjected(tab.id);
590
- await sendMessageToTab(tab.id, { type: "annotation:toggle" });
843
+ await sendAnnotationMessageToTab(tab.id, { type: "annotation:toggle" });
591
844
  };
592
845
  const startAnnotationSession = async (command, transport) => {
593
846
  const requestId = command.requestId;
@@ -620,9 +873,11 @@ const startAnnotationSession = async (command, transport) => {
620
873
  }, transport);
621
874
  return;
622
875
  }
876
+ rememberAnnotatableTab(tab);
623
877
  let timeoutId = null;
624
878
  try {
625
- await ensureAnnotationInjected(tab.id);
879
+ const initialBridge = await ensureAnnotationInjected(tab.id);
880
+ rememberPopupAnnotationTarget(tab.id, initialBridge.bootId);
626
881
  timeoutId = startAnnotationTimeout(requestId, transport);
627
882
  annotationSessions.set(requestId, {
628
883
  requestId,
@@ -632,18 +887,15 @@ const startAnnotationSession = async (command, transport) => {
632
887
  timeoutId,
633
888
  transport
634
889
  });
635
- await sendMessageToTab(tab.id, {
636
- type: "annotation:start",
637
- requestId,
638
- options: command.options ?? {},
639
- url: command.url
640
- });
890
+ const startedBridge = await startAnnotationUi(tab.id, requestId, command.options, command.url);
891
+ rememberPopupAnnotationTarget(tab.id, startedBridge.bootId);
641
892
  }
642
893
  catch (error) {
643
894
  if (timeoutId !== null) {
644
895
  clearTimeout(timeoutId);
645
896
  }
646
897
  annotationSessions.delete(requestId);
898
+ clearPopupAnnotationTarget(tab.id);
647
899
  throw error instanceof Error ? error : new Error("Annotation injection failed");
648
900
  }
649
901
  };
@@ -660,7 +912,7 @@ const cancelAnnotationSession = async (requestId, transport) => {
660
912
  }
661
913
  clearTimeout(session.timeoutId);
662
914
  annotationSessions.delete(requestId);
663
- await sendMessageToTab(session.tabId, { type: "annotation:cancel", requestId });
915
+ await sendAnnotationMessageToTab(session.tabId, { type: "annotation:cancel", requestId });
664
916
  sendAnnotationResponse({
665
917
  version: 1,
666
918
  requestId,
@@ -675,19 +927,7 @@ const validatePayloadSize = (payload) => {
675
927
  const generateAnnotationRequestId = () => {
676
928
  return crypto.randomUUID();
677
929
  };
678
- const stripScreenshots = (payload) => {
679
- const { screenshots, annotations, ...rest } = payload;
680
- void screenshots;
681
- return {
682
- ...rest,
683
- annotations: annotations.map((item) => {
684
- const { screenshotId, ...restItem } = item;
685
- void screenshotId;
686
- return restItem;
687
- })
688
- };
689
- };
690
- const buildLastAnnotationMeta = (requestId, response, hasFullPayloadInMemory) => {
930
+ const buildLastAnnotationMeta = (requestId, response, hasFullPayloadInMemory, extras = {}) => {
691
931
  const payload = response.payload;
692
932
  const annotationCount = payload ? payload.annotations.length : undefined;
693
933
  const screenshotCount = payload?.screenshots?.length ?? 0;
@@ -695,6 +935,9 @@ const buildLastAnnotationMeta = (requestId, response, hasFullPayloadInMemory) =>
695
935
  requestId,
696
936
  status: response.status,
697
937
  error: response.error,
938
+ receipt: extras.receipt ?? response.receipt,
939
+ source: extras.source,
940
+ label: extras.label,
698
941
  url: payload?.url,
699
942
  title: payload?.title,
700
943
  timestamp: payload?.timestamp,
@@ -712,6 +955,12 @@ const persistLastAnnotation = async (meta, payload) => {
712
955
  [LAST_ANNOTATION_PAYLOAD_KEY]: payload
713
956
  });
714
957
  };
958
+ const persistAgentAnnotation = async (meta, payload) => {
959
+ await setStorage({
960
+ [LAST_AGENT_ANNOTATION_META_KEY]: meta,
961
+ [LAST_AGENT_ANNOTATION_PAYLOAD_KEY]: payload
962
+ });
963
+ };
715
964
  const loadPersistedLastAnnotation = async () => {
716
965
  const data = await new Promise((resolve) => {
717
966
  chrome.storage.local.get([LAST_ANNOTATION_META_KEY, LAST_ANNOTATION_PAYLOAD_KEY], (items) => resolve(items));
@@ -722,6 +971,108 @@ const loadPersistedLastAnnotation = async () => {
722
971
  const payload = payloadRecord && typeof payloadRecord === "object" ? payloadRecord : null;
723
972
  return { meta, payload };
724
973
  };
974
+ const loadPersistedAgentAnnotation = async () => {
975
+ const data = await new Promise((resolve) => {
976
+ chrome.storage.local.get([LAST_AGENT_ANNOTATION_META_KEY, LAST_AGENT_ANNOTATION_PAYLOAD_KEY], (items) => resolve(items));
977
+ });
978
+ const metaRecord = data[LAST_AGENT_ANNOTATION_META_KEY];
979
+ const payloadRecord = data[LAST_AGENT_ANNOTATION_PAYLOAD_KEY];
980
+ const meta = metaRecord && typeof metaRecord === "object" ? metaRecord : null;
981
+ const payload = payloadRecord && typeof payloadRecord === "object" ? payloadRecord : null;
982
+ return { meta, payload };
983
+ };
984
+ const isAnnotationPayload = (value) => {
985
+ if (!value || typeof value !== "object") {
986
+ return false;
987
+ }
988
+ const payload = value;
989
+ return typeof payload.url === "string"
990
+ && typeof payload.timestamp === "string"
991
+ && typeof payload.screenshotMode === "string"
992
+ && Array.isArray(payload.annotations);
993
+ };
994
+ const storeAgentAnnotationPayload = async (payload, source, label, receipt) => {
995
+ if (!validatePayloadSize(payload)) {
996
+ throw new Error("Annotation payload exceeded size limits.");
997
+ }
998
+ const response = {
999
+ version: 1,
1000
+ requestId: receipt?.receiptId ?? crypto.randomUUID(),
1001
+ status: "ok",
1002
+ payload,
1003
+ receipt
1004
+ };
1005
+ const meta = buildLastAnnotationMeta(response.requestId, response, true, {
1006
+ source,
1007
+ label: label?.trim().length ? label.trim() : formatDispatchSourceLabel(source),
1008
+ receipt
1009
+ });
1010
+ lastAgentAnnotationFull = { meta, payload };
1011
+ await persistAgentAnnotation({ ...meta, hasFullPayloadInMemory: false }, stripAnnotationPayloadScreenshots(payload));
1012
+ return meta;
1013
+ };
1014
+ const buildStoredOnlyReceipt = (payload, source, label, reason) => {
1015
+ const sanitizedPayload = stripAnnotationPayloadScreenshots(payload);
1016
+ return {
1017
+ receiptId: crypto.randomUUID(),
1018
+ deliveryState: "stored_only",
1019
+ storedFallback: true,
1020
+ reason,
1021
+ chatScopeKey: null,
1022
+ createdAt: new Date().toISOString(),
1023
+ itemCount: sanitizedPayload.annotations.length,
1024
+ byteLength: new TextEncoder().encode(JSON.stringify(sanitizedPayload)).length,
1025
+ source,
1026
+ label: label?.trim().length ? label.trim() : formatDispatchSourceLabel(source)
1027
+ };
1028
+ };
1029
+ const enqueueAgentPayload = async (payload, source, label) => {
1030
+ const response = await connection.sendAnnotationCommand({
1031
+ version: 1,
1032
+ requestId: crypto.randomUUID(),
1033
+ command: "store_agent_payload",
1034
+ payload,
1035
+ source,
1036
+ label
1037
+ });
1038
+ if (response.status !== "ok" || !response.receipt) {
1039
+ throw new Error(response.error?.code ?? response.error?.message ?? "relay_unavailable");
1040
+ }
1041
+ return response.receipt;
1042
+ };
1043
+ const loadAgentAnnotationPayload = async (includeScreenshots) => {
1044
+ if (includeScreenshots && lastAgentAnnotationFull) {
1045
+ return {
1046
+ version: 1,
1047
+ requestId: crypto.randomUUID(),
1048
+ status: "ok",
1049
+ payload: lastAgentAnnotationFull.payload
1050
+ };
1051
+ }
1052
+ if (lastAgentAnnotationFull) {
1053
+ return {
1054
+ version: 1,
1055
+ requestId: crypto.randomUUID(),
1056
+ status: "ok",
1057
+ payload: stripAnnotationPayloadScreenshots(lastAgentAnnotationFull.payload)
1058
+ };
1059
+ }
1060
+ const stored = await loadPersistedAgentAnnotation();
1061
+ if (stored.payload) {
1062
+ return {
1063
+ version: 1,
1064
+ requestId: crypto.randomUUID(),
1065
+ status: "ok",
1066
+ payload: stored.payload
1067
+ };
1068
+ }
1069
+ return {
1070
+ version: 1,
1071
+ requestId: crypto.randomUUID(),
1072
+ status: "error",
1073
+ error: { code: "payload_unavailable", message: "No agent-dispatched annotation payload available." }
1074
+ };
1075
+ };
725
1076
  async function handleNativePortMessage(payload) {
726
1077
  if (!payload || typeof payload !== "object") {
727
1078
  return;
@@ -746,6 +1097,14 @@ const handleRelayAnnotationCommand = async (command, transport = "relay") => {
746
1097
  await cancelAnnotationSession(payload.requestId, transport);
747
1098
  return;
748
1099
  }
1100
+ if (payload.command === "fetch_stored") {
1101
+ const stored = await loadAgentAnnotationPayload(payload.options?.includeScreenshots === true);
1102
+ sendAnnotationResponse({
1103
+ ...stored,
1104
+ requestId: payload.requestId
1105
+ }, transport);
1106
+ return;
1107
+ }
749
1108
  try {
750
1109
  await startAnnotationSession(payload, transport);
751
1110
  sendAnnotationEvent({
@@ -805,7 +1164,7 @@ const handleAnnotationComplete = (requestId, payload) => {
805
1164
  const meta = buildLastAnnotationMeta(requestId, response, true);
806
1165
  lastAnnotationFull = { meta, payload };
807
1166
  const storageMeta = { ...meta, hasFullPayloadInMemory: false };
808
- const sanitizedPayload = stripScreenshots(payload);
1167
+ const sanitizedPayload = stripAnnotationPayloadScreenshots(payload);
809
1168
  persistLastAnnotation(storageMeta, sanitizedPayload).catch((error) => {
810
1169
  logError("annotation.persist_sanitized_payload", error, { code: "annotation_persist_failed" });
811
1170
  });
@@ -911,6 +1270,7 @@ const attemptAutoConnect = async () => {
911
1270
  });
912
1271
  });
913
1272
  const autoConnect = typeof data.autoConnect === "boolean" ? data.autoConnect : DEFAULT_AUTO_CONNECT;
1273
+ autoConnectEnabled = autoConnect;
914
1274
  if (!autoConnect || connection.getStatus() === "connected") {
915
1275
  clearRetry();
916
1276
  return;
@@ -976,6 +1336,7 @@ const attemptAutoConnect = async () => {
976
1336
  if (config.instanceId && fetched.instanceId && config.instanceId !== fetched.instanceId) {
977
1337
  console.warn("[opendevbrowser] Relay instance mismatch during auto-pair. Retrying later.");
978
1338
  setStatusNoteOverride("Relay instance mismatch. Open the popup and click Connect.");
1339
+ scheduleRetry();
979
1340
  return;
980
1341
  }
981
1342
  const tokenEpoch = fetched.epoch ?? configEpoch;
@@ -1031,6 +1392,9 @@ connection.onStatus((status) => {
1031
1392
  clearTimeout(session.timeoutId);
1032
1393
  }
1033
1394
  annotationSessions.clear();
1395
+ if (autoConnectEnabled) {
1396
+ scheduleRetry();
1397
+ }
1034
1398
  }
1035
1399
  });
1036
1400
  updateBadge(getEffectiveStatus());
@@ -1066,6 +1430,37 @@ if (chrome.commands?.onCommand) {
1066
1430
  autoConnect().catch((error) => {
1067
1431
  logError("auto_connect.startup", error, { code: "auto_connect_failed" });
1068
1432
  });
1433
+ void getActiveTab()
1434
+ .then((tab) => {
1435
+ rememberAnnotatableTab(tab);
1436
+ })
1437
+ .catch((error) => {
1438
+ logError("annotation.initial_tab", error, { code: "annotation_tab_resolution_failed" });
1439
+ });
1440
+ chrome.tabs.onActivated.addListener((activeInfo) => {
1441
+ void getTab(activeInfo.tabId)
1442
+ .then((tab) => {
1443
+ rememberAnnotatableTab(tab);
1444
+ })
1445
+ .catch((error) => {
1446
+ logError("annotation.tab_activated", error, { code: "annotation_tab_resolution_failed", extra: { tabId: activeInfo.tabId } });
1447
+ });
1448
+ });
1449
+ chrome.tabs.onUpdated.addListener((tabId, _changeInfo, tab) => {
1450
+ if (!tab.active && tabId !== lastAnnotatableTabId) {
1451
+ return;
1452
+ }
1453
+ rememberAnnotatableTab(tab);
1454
+ });
1455
+ chrome.tabs.onRemoved.addListener((tabId) => {
1456
+ if (lastAnnotatableTabId === tabId) {
1457
+ lastAnnotatableTabId = null;
1458
+ void persistAnnotatableTabId(null).catch((error) => {
1459
+ logError("annotation.persist_tab", error, { code: "annotation_tab_persist_failed", extra: { tabId: null } });
1460
+ });
1461
+ }
1462
+ clearPopupAnnotationTarget(tabId);
1463
+ });
1069
1464
  chrome.storage.onChanged.addListener((changes, area) => {
1070
1465
  if (area !== "local") {
1071
1466
  return;
@@ -1077,11 +1472,18 @@ chrome.storage.onChanged.addListener((changes, area) => {
1077
1472
  }
1078
1473
  updateBadge(getEffectiveStatus());
1079
1474
  }
1475
+ if (changes.autoConnect) {
1476
+ autoConnectEnabled =
1477
+ typeof changes.autoConnect.newValue === "boolean" ? changes.autoConnect.newValue : DEFAULT_AUTO_CONNECT;
1478
+ }
1080
1479
  if (changes.autoConnect?.newValue === true) {
1081
1480
  autoConnect().catch((error) => {
1082
1481
  logError("auto_connect.setting", error, { code: "auto_connect_failed" });
1083
1482
  });
1084
1483
  }
1484
+ else if (changes.autoConnect?.newValue === false) {
1485
+ clearRetry();
1486
+ }
1085
1487
  if (changes.pairingToken) {
1086
1488
  autoConnect().catch((error) => {
1087
1489
  logError("auto_connect.pairing_token", error, { code: "auto_connect_failed" });
@@ -1152,7 +1554,7 @@ chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
1152
1554
  ok: false
1153
1555
  };
1154
1556
  try {
1155
- const active = await getActiveTab();
1557
+ const active = await getPopupAnnotationTab(message.tabId);
1156
1558
  if (!active) {
1157
1559
  response.error = { code: "invalid_request", message: "No active tab available." };
1158
1560
  sendResponse(response);
@@ -1212,7 +1614,7 @@ chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
1212
1614
  }
1213
1615
  if (message.type === "annotation:probe") {
1214
1616
  (async () => {
1215
- const result = await probeAnnotationInjected();
1617
+ const result = await probeAnnotationInjected(message.tabId);
1216
1618
  sendResponse({ type: "annotation:probeResult", ...result });
1217
1619
  })().catch((error) => {
1218
1620
  logError("annotation.probe", error, { code: "annotation_probe_failed" });
@@ -1237,9 +1639,9 @@ chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
1237
1639
  if (message.includeScreenshots) {
1238
1640
  const response = {
1239
1641
  type: "annotation:payloadResult",
1240
- payload: null,
1642
+ payload: stored.payload,
1241
1643
  meta: storedMeta,
1242
- source: "none",
1644
+ source: stored.payload ? "storage" : "none",
1243
1645
  warning: "Full payload not available; screenshots may have been dropped."
1244
1646
  };
1245
1647
  sendResponse(response);
@@ -1248,7 +1650,7 @@ chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
1248
1650
  if (lastAnnotationFull) {
1249
1651
  const response = {
1250
1652
  type: "annotation:payloadResult",
1251
- payload: stripScreenshots(lastAnnotationFull.payload),
1653
+ payload: stripAnnotationPayloadScreenshots(lastAnnotationFull.payload),
1252
1654
  meta: { ...lastAnnotationFull.meta, hasFullPayloadInMemory: true },
1253
1655
  source: "memory"
1254
1656
  };
@@ -1285,6 +1687,74 @@ chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
1285
1687
  });
1286
1688
  return true;
1287
1689
  }
1690
+ if (message.type === "annotation:sendPayload") {
1691
+ (async () => {
1692
+ if (!isAnnotationPayload(message.payload)) {
1693
+ const response = {
1694
+ type: "annotation:sendPayloadResult",
1695
+ ok: false,
1696
+ meta: null,
1697
+ receipt: null,
1698
+ error: { code: "invalid_request", message: "Invalid annotation payload." }
1699
+ };
1700
+ sendResponse(response);
1701
+ return;
1702
+ }
1703
+ const source = message.source ?? "popup_all";
1704
+ let receipt;
1705
+ try {
1706
+ receipt = await enqueueAgentPayload(message.payload, source, message.label);
1707
+ }
1708
+ catch (error) {
1709
+ const reason = error instanceof Error && error.message.trim().length > 0
1710
+ ? error.message.trim()
1711
+ : "relay_unavailable";
1712
+ receipt = buildStoredOnlyReceipt(message.payload, source, message.label, reason);
1713
+ }
1714
+ let meta;
1715
+ try {
1716
+ meta = await storeAgentAnnotationPayload(message.payload, source, message.label, receipt);
1717
+ }
1718
+ catch (error) {
1719
+ if (receipt.deliveryState !== "delivered") {
1720
+ throw error;
1721
+ }
1722
+ const response = {
1723
+ version: 1,
1724
+ requestId: receipt.receiptId,
1725
+ status: "ok",
1726
+ payload: message.payload,
1727
+ receipt
1728
+ };
1729
+ meta = buildLastAnnotationMeta(receipt.receiptId, response, true, {
1730
+ source,
1731
+ label: message.label?.trim().length ? message.label.trim() : formatDispatchSourceLabel(source),
1732
+ receipt
1733
+ });
1734
+ logError("annotation.store_agent_payload_optional", error, { code: "annotation_persist_failed" });
1735
+ }
1736
+ const response = {
1737
+ type: "annotation:sendPayloadResult",
1738
+ ok: true,
1739
+ meta: { ...meta, hasFullPayloadInMemory: true },
1740
+ receipt
1741
+ };
1742
+ sendResponse(response);
1743
+ })().catch((error) => {
1744
+ const response = {
1745
+ type: "annotation:sendPayloadResult",
1746
+ ok: false,
1747
+ meta: null,
1748
+ receipt: null,
1749
+ error: {
1750
+ code: "payload_too_large",
1751
+ message: error instanceof Error ? error.message : "Annotation dispatch failed."
1752
+ }
1753
+ };
1754
+ sendResponse(response);
1755
+ });
1756
+ return true;
1757
+ }
1288
1758
  if (message.type === "annotation:capture") {
1289
1759
  (async () => {
1290
1760
  const tab = sender.tab;
@@ -1319,3 +1789,8 @@ chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
1319
1789
  }
1320
1790
  return false;
1321
1791
  });
1792
+ chrome.runtime.onConnect.addListener((port) => {
1793
+ if (port.name === "canvas-page") {
1794
+ canvasRuntime.attachPort(port);
1795
+ }
1796
+ });