opendevbrowser 0.0.17 → 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 (529) hide show
  1. package/README.md +171 -73
  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 +4 -1
  12. package/dist/browser/annotation-manager.d.ts.map +1 -1
  13. package/dist/browser/browser-manager.d.ts +147 -47
  14. package/dist/browser/browser-manager.d.ts.map +1 -1
  15. package/dist/browser/canvas-client.d.ts +1 -0
  16. package/dist/browser/canvas-client.d.ts.map +1 -1
  17. package/dist/browser/canvas-code-sync-manager.d.ts +9 -1
  18. package/dist/browser/canvas-code-sync-manager.d.ts.map +1 -1
  19. package/dist/browser/canvas-manager.d.ts +29 -1
  20. package/dist/browser/canvas-manager.d.ts.map +1 -1
  21. package/dist/browser/global-challenge-coordinator.d.ts +27 -0
  22. package/dist/browser/global-challenge-coordinator.d.ts.map +1 -0
  23. package/dist/browser/manager-types.d.ts +167 -1
  24. package/dist/browser/manager-types.d.ts.map +1 -1
  25. package/dist/browser/ops-browser-manager.d.ts +103 -3
  26. package/dist/browser/ops-browser-manager.d.ts.map +1 -1
  27. package/dist/browser/ops-client.d.ts +17 -1
  28. package/dist/browser/ops-client.d.ts.map +1 -1
  29. package/dist/browser/playwright-runtime.d.ts +4 -0
  30. package/dist/browser/playwright-runtime.d.ts.map +1 -0
  31. package/dist/browser/review-surface.d.ts +9 -0
  32. package/dist/browser/review-surface.d.ts.map +1 -0
  33. package/dist/browser/screencast-recorder.d.ts +57 -0
  34. package/dist/browser/screencast-recorder.d.ts.map +1 -0
  35. package/dist/browser/session-inspector.d.ts +71 -0
  36. package/dist/browser/session-inspector.d.ts.map +1 -0
  37. package/dist/browser/session-store.d.ts +5 -1
  38. package/dist/browser/session-store.d.ts.map +1 -1
  39. package/dist/browser/system-chrome-cookies.d.ts +46 -0
  40. package/dist/browser/system-chrome-cookies.d.ts.map +1 -0
  41. package/dist/browser/target-manager.d.ts +1 -0
  42. package/dist/browser/target-manager.d.ts.map +1 -1
  43. package/dist/cache/chrome-locator.d.ts.map +1 -1
  44. package/dist/cache/chrome-user-data.d.ts +17 -0
  45. package/dist/cache/chrome-user-data.d.ts.map +1 -0
  46. package/dist/canvas/adapter-plugins/loader.d.ts +13 -0
  47. package/dist/canvas/adapter-plugins/loader.d.ts.map +1 -0
  48. package/dist/canvas/adapter-plugins/manifest.d.ts +146 -0
  49. package/dist/canvas/adapter-plugins/manifest.d.ts.map +1 -0
  50. package/dist/canvas/adapter-plugins/types.d.ts +83 -0
  51. package/dist/canvas/adapter-plugins/types.d.ts.map +1 -0
  52. package/dist/canvas/adapter-plugins/validator.d.ts +10 -0
  53. package/dist/canvas/adapter-plugins/validator.d.ts.map +1 -0
  54. package/dist/canvas/code-sync/apply-tsx.d.ts +3 -1
  55. package/dist/canvas/code-sync/apply-tsx.d.ts.map +1 -1
  56. package/dist/canvas/code-sync/import.d.ts +1 -0
  57. package/dist/canvas/code-sync/import.d.ts.map +1 -1
  58. package/dist/canvas/code-sync/manifest.d.ts +2 -1
  59. package/dist/canvas/code-sync/manifest.d.ts.map +1 -1
  60. package/dist/canvas/code-sync/tsx-adapter.d.ts.map +1 -1
  61. package/dist/canvas/code-sync/types.d.ts +102 -10
  62. package/dist/canvas/code-sync/types.d.ts.map +1 -1
  63. package/dist/canvas/document-store.d.ts +11 -1
  64. package/dist/canvas/document-store.d.ts.map +1 -1
  65. package/dist/canvas/export.d.ts.map +1 -1
  66. package/dist/canvas/framework-adapters/custom-elements-v1.d.ts +3 -0
  67. package/dist/canvas/framework-adapters/custom-elements-v1.d.ts.map +1 -0
  68. package/dist/canvas/framework-adapters/html-static-v1.d.ts +3 -0
  69. package/dist/canvas/framework-adapters/html-static-v1.d.ts.map +1 -0
  70. package/dist/canvas/framework-adapters/markup.d.ts +9 -0
  71. package/dist/canvas/framework-adapters/markup.d.ts.map +1 -0
  72. package/dist/canvas/framework-adapters/react-tsx-v2.d.ts +3 -0
  73. package/dist/canvas/framework-adapters/react-tsx-v2.d.ts.map +1 -0
  74. package/dist/canvas/framework-adapters/registry.d.ts +12 -0
  75. package/dist/canvas/framework-adapters/registry.d.ts.map +1 -0
  76. package/dist/canvas/framework-adapters/svelte-sfc-v1.d.ts +3 -0
  77. package/dist/canvas/framework-adapters/svelte-sfc-v1.d.ts.map +1 -0
  78. package/dist/canvas/framework-adapters/types.d.ts +57 -0
  79. package/dist/canvas/framework-adapters/types.d.ts.map +1 -0
  80. package/dist/canvas/framework-adapters/vue-sfc-v1.d.ts +3 -0
  81. package/dist/canvas/framework-adapters/vue-sfc-v1.d.ts.map +1 -0
  82. package/dist/canvas/kits/catalog.d.ts +5 -0
  83. package/dist/canvas/kits/catalog.d.ts.map +1 -0
  84. package/dist/canvas/library-adapters/react/index.d.ts +3 -0
  85. package/dist/canvas/library-adapters/react/index.d.ts.map +1 -0
  86. package/dist/canvas/library-adapters/registry.d.ts +11 -0
  87. package/dist/canvas/library-adapters/registry.d.ts.map +1 -0
  88. package/dist/canvas/library-adapters/types.d.ts +43 -0
  89. package/dist/canvas/library-adapters/types.d.ts.map +1 -0
  90. package/dist/canvas/repo-store.d.ts +2 -0
  91. package/dist/canvas/repo-store.d.ts.map +1 -1
  92. package/dist/canvas/starters/catalog.d.ts +34 -0
  93. package/dist/canvas/starters/catalog.d.ts.map +1 -0
  94. package/dist/canvas/token-references.d.ts +22 -0
  95. package/dist/canvas/token-references.d.ts.map +1 -0
  96. package/dist/canvas/types.d.ts +345 -6
  97. package/dist/canvas/types.d.ts.map +1 -1
  98. package/dist/challenges/action-loop.d.ts +13 -0
  99. package/dist/challenges/action-loop.d.ts.map +1 -0
  100. package/dist/challenges/capability-matrix.d.ts +3 -0
  101. package/dist/challenges/capability-matrix.d.ts.map +1 -0
  102. package/dist/challenges/evidence-bundle.d.ts +48 -0
  103. package/dist/challenges/evidence-bundle.d.ts.map +1 -0
  104. package/dist/challenges/governed-adapter-gateway.d.ts +4 -0
  105. package/dist/challenges/governed-adapter-gateway.d.ts.map +1 -0
  106. package/dist/challenges/human-yield-gate.d.ts +20 -0
  107. package/dist/challenges/human-yield-gate.d.ts.map +1 -0
  108. package/dist/challenges/index.d.ts +15 -0
  109. package/dist/challenges/index.d.ts.map +1 -0
  110. package/dist/challenges/interpreter.d.ts +3 -0
  111. package/dist/challenges/interpreter.d.ts.map +1 -0
  112. package/dist/challenges/optional-computer-use-bridge.d.ts +9 -0
  113. package/dist/challenges/optional-computer-use-bridge.d.ts.map +1 -0
  114. package/dist/challenges/orchestrator.d.ts +32 -0
  115. package/dist/challenges/orchestrator.d.ts.map +1 -0
  116. package/dist/challenges/outcome-recorder.d.ts +8 -0
  117. package/dist/challenges/outcome-recorder.d.ts.map +1 -0
  118. package/dist/challenges/owned-environment-lane.d.ts +3 -0
  119. package/dist/challenges/owned-environment-lane.d.ts.map +1 -0
  120. package/dist/challenges/policy-gate.d.ts +9 -0
  121. package/dist/challenges/policy-gate.d.ts.map +1 -0
  122. package/dist/challenges/sanctioned-identity-lane.d.ts +3 -0
  123. package/dist/challenges/sanctioned-identity-lane.d.ts.map +1 -0
  124. package/dist/challenges/service-adapter-lane.d.ts +3 -0
  125. package/dist/challenges/service-adapter-lane.d.ts.map +1 -0
  126. package/dist/challenges/strategy-selector.d.ts +10 -0
  127. package/dist/challenges/strategy-selector.d.ts.map +1 -0
  128. package/dist/challenges/types.d.ts +277 -0
  129. package/dist/challenges/types.d.ts.map +1 -0
  130. package/dist/challenges/verification-gate.d.ts +15 -0
  131. package/dist/challenges/verification-gate.d.ts.map +1 -0
  132. package/dist/chunk-5FZQJRBQ.js +15256 -0
  133. package/dist/chunk-5FZQJRBQ.js.map +1 -0
  134. package/dist/chunk-L57D35TB.js +33513 -0
  135. package/dist/chunk-L57D35TB.js.map +1 -0
  136. package/dist/chunk-YBQECXZX.js +409 -0
  137. package/dist/chunk-YBQECXZX.js.map +1 -0
  138. package/dist/cli/args.d.ts +4 -4
  139. package/dist/cli/args.d.ts.map +1 -1
  140. package/dist/cli/commands/artifacts.d.ts.map +1 -1
  141. package/dist/cli/commands/canvas.d.ts +7 -7
  142. package/dist/cli/commands/canvas.d.ts.map +1 -1
  143. package/dist/cli/commands/daemon.d.ts +7 -0
  144. package/dist/cli/commands/daemon.d.ts.map +1 -1
  145. package/dist/cli/commands/desktop/accessibility-snapshot.d.ts +3 -0
  146. package/dist/cli/commands/desktop/accessibility-snapshot.d.ts.map +1 -0
  147. package/dist/cli/commands/desktop/active-window.d.ts +3 -0
  148. package/dist/cli/commands/desktop/active-window.d.ts.map +1 -0
  149. package/dist/cli/commands/desktop/capture-desktop.d.ts +3 -0
  150. package/dist/cli/commands/desktop/capture-desktop.d.ts.map +1 -0
  151. package/dist/cli/commands/desktop/capture-window.d.ts +3 -0
  152. package/dist/cli/commands/desktop/capture-window.d.ts.map +1 -0
  153. package/dist/cli/commands/desktop/shared.d.ts +19 -0
  154. package/dist/cli/commands/desktop/shared.d.ts.map +1 -0
  155. package/dist/cli/commands/desktop/status.d.ts +3 -0
  156. package/dist/cli/commands/desktop/status.d.ts.map +1 -0
  157. package/dist/cli/commands/desktop/windows.d.ts +3 -0
  158. package/dist/cli/commands/desktop/windows.d.ts.map +1 -0
  159. package/dist/cli/commands/devtools/dialog.d.ts +19 -0
  160. package/dist/cli/commands/devtools/dialog.d.ts.map +1 -0
  161. package/dist/cli/commands/devtools/screencast-start.d.ts +20 -0
  162. package/dist/cli/commands/devtools/screencast-start.d.ts.map +1 -0
  163. package/dist/cli/commands/devtools/screencast-stop.d.ts +17 -0
  164. package/dist/cli/commands/devtools/screencast-stop.d.ts.map +1 -0
  165. package/dist/cli/commands/devtools/screenshot.d.ts +2 -0
  166. package/dist/cli/commands/devtools/screenshot.d.ts.map +1 -1
  167. package/dist/cli/commands/interact/click.d.ts.map +1 -1
  168. package/dist/cli/commands/interact/pointer-down.d.ts +7 -0
  169. package/dist/cli/commands/interact/pointer-down.d.ts.map +1 -0
  170. package/dist/cli/commands/interact/pointer-drag.d.ts +7 -0
  171. package/dist/cli/commands/interact/pointer-drag.d.ts.map +1 -0
  172. package/dist/cli/commands/interact/pointer-move.d.ts +7 -0
  173. package/dist/cli/commands/interact/pointer-move.d.ts.map +1 -0
  174. package/dist/cli/commands/interact/pointer-shared.d.ts +6 -0
  175. package/dist/cli/commands/interact/pointer-shared.d.ts.map +1 -0
  176. package/dist/cli/commands/interact/pointer-up.d.ts +7 -0
  177. package/dist/cli/commands/interact/pointer-up.d.ts.map +1 -0
  178. package/dist/cli/commands/interact/upload.d.ts +18 -0
  179. package/dist/cli/commands/interact/upload.d.ts.map +1 -0
  180. package/dist/cli/commands/macro-resolve.d.ts +2 -0
  181. package/dist/cli/commands/macro-resolve.d.ts.map +1 -1
  182. package/dist/cli/commands/native.d.ts +10 -7
  183. package/dist/cli/commands/native.d.ts.map +1 -1
  184. package/dist/cli/commands/nav/review.d.ts +7 -0
  185. package/dist/cli/commands/nav/review.d.ts.map +1 -0
  186. package/dist/cli/commands/nav/snapshot.d.ts.map +1 -1
  187. package/dist/cli/commands/pages/open.d.ts.map +1 -1
  188. package/dist/cli/commands/product-video.d.ts +2 -0
  189. package/dist/cli/commands/product-video.d.ts.map +1 -1
  190. package/dist/cli/commands/research.d.ts +3 -0
  191. package/dist/cli/commands/research.d.ts.map +1 -1
  192. package/dist/cli/commands/run.d.ts +14 -0
  193. package/dist/cli/commands/run.d.ts.map +1 -1
  194. package/dist/cli/commands/serve.d.ts +1 -26
  195. package/dist/cli/commands/serve.d.ts.map +1 -1
  196. package/dist/cli/commands/session/connect.d.ts.map +1 -1
  197. package/dist/cli/commands/session/disconnect.d.ts.map +1 -1
  198. package/dist/cli/commands/session/inspector.d.ts +21 -0
  199. package/dist/cli/commands/session/inspector.d.ts.map +1 -0
  200. package/dist/cli/commands/session/launch.d.ts.map +1 -1
  201. package/dist/cli/commands/shopping.d.ts +5 -0
  202. package/dist/cli/commands/shopping.d.ts.map +1 -1
  203. package/dist/cli/commands/status.d.ts +2 -14
  204. package/dist/cli/commands/status.d.ts.map +1 -1
  205. package/dist/cli/commands/targets/new.d.ts.map +1 -1
  206. package/dist/cli/daemon-autostart.d.ts +11 -0
  207. package/dist/cli/daemon-autostart.d.ts.map +1 -1
  208. package/dist/cli/daemon-client.d.ts +3 -0
  209. package/dist/cli/daemon-client.d.ts.map +1 -1
  210. package/dist/cli/daemon-commands.d.ts.map +1 -1
  211. package/dist/cli/daemon-state.d.ts +16 -0
  212. package/dist/cli/daemon-state.d.ts.map +1 -1
  213. package/dist/cli/daemon-status.d.ts +7 -2
  214. package/dist/cli/daemon-status.d.ts.map +1 -1
  215. package/dist/cli/daemon.d.ts +1 -0
  216. package/dist/cli/daemon.d.ts.map +1 -1
  217. package/dist/cli/help.d.ts +15 -4
  218. package/dist/cli/help.d.ts.map +1 -1
  219. package/dist/cli/index.js +2467 -1033
  220. package/dist/cli/index.js.map +1 -1
  221. package/dist/cli/install-autostart-output.d.ts +6 -0
  222. package/dist/cli/install-autostart-output.d.ts.map +1 -0
  223. package/dist/cli/install-autostart-reconciliation.d.ts +23 -0
  224. package/dist/cli/install-autostart-reconciliation.d.ts.map +1 -0
  225. package/dist/cli/installers/skills.d.ts +42 -6
  226. package/dist/cli/installers/skills.d.ts.map +1 -1
  227. package/dist/cli/output.d.ts +3 -0
  228. package/dist/cli/output.d.ts.map +1 -1
  229. package/dist/cli/remote-desktop-runtime.d.ts +15 -0
  230. package/dist/cli/remote-desktop-runtime.d.ts.map +1 -0
  231. package/dist/cli/remote-manager.d.ts +24 -2
  232. package/dist/cli/remote-manager.d.ts.map +1 -1
  233. package/dist/cli/transport-timeouts.d.ts +8 -0
  234. package/dist/cli/transport-timeouts.d.ts.map +1 -0
  235. package/dist/cli/utils/http.d.ts +9 -0
  236. package/dist/cli/utils/http.d.ts.map +1 -1
  237. package/dist/cli/utils/parse.d.ts +2 -0
  238. package/dist/cli/utils/parse.d.ts.map +1 -1
  239. package/dist/cli/utils/skills.d.ts +1 -2
  240. package/dist/cli/utils/skills.d.ts.map +1 -1
  241. package/dist/cli/utils/workflow-message.d.ts +2 -0
  242. package/dist/cli/utils/workflow-message.d.ts.map +1 -0
  243. package/dist/config.d.ts +47 -0
  244. package/dist/config.d.ts.map +1 -1
  245. package/dist/core/bootstrap.d.ts.map +1 -1
  246. package/dist/core/index.d.ts +1 -0
  247. package/dist/core/index.d.ts.map +1 -1
  248. package/dist/core/logging.d.ts +3 -1
  249. package/dist/core/logging.d.ts.map +1 -1
  250. package/dist/core/runtime-assemblies.d.ts +22 -0
  251. package/dist/core/runtime-assemblies.d.ts.map +1 -0
  252. package/dist/core/types.d.ts +15 -0
  253. package/dist/core/types.d.ts.map +1 -1
  254. package/dist/desktop/audit.d.ts +37 -0
  255. package/dist/desktop/audit.d.ts.map +1 -0
  256. package/dist/desktop/errors.d.ts +7 -0
  257. package/dist/desktop/errors.d.ts.map +1 -0
  258. package/dist/desktop/index.d.ts +6 -0
  259. package/dist/desktop/index.d.ts.map +1 -0
  260. package/dist/desktop/runtime.d.ts +26 -0
  261. package/dist/desktop/runtime.d.ts.map +1 -0
  262. package/dist/desktop/types.d.ts +76 -0
  263. package/dist/desktop/types.d.ts.map +1 -0
  264. package/dist/extension-extractor.d.ts +6 -0
  265. package/dist/extension-extractor.d.ts.map +1 -1
  266. package/dist/index.d.ts.map +1 -1
  267. package/dist/index.js +1103 -467
  268. package/dist/index.js.map +1 -1
  269. package/dist/integrations/figma/assets.d.ts +13 -0
  270. package/dist/integrations/figma/assets.d.ts.map +1 -0
  271. package/dist/integrations/figma/auth.d.ts +3 -0
  272. package/dist/integrations/figma/auth.d.ts.map +1 -0
  273. package/dist/integrations/figma/client.d.ts +42 -0
  274. package/dist/integrations/figma/client.d.ts.map +1 -0
  275. package/dist/integrations/figma/mappers.d.ts +23 -0
  276. package/dist/integrations/figma/mappers.d.ts.map +1 -0
  277. package/dist/integrations/figma/normalize.d.ts +99 -0
  278. package/dist/integrations/figma/normalize.d.ts.map +1 -0
  279. package/dist/integrations/figma/url.d.ts +17 -0
  280. package/dist/integrations/figma/url.d.ts.map +1 -0
  281. package/dist/integrations/figma/variables.d.ts +21 -0
  282. package/dist/integrations/figma/variables.d.ts.map +1 -0
  283. package/dist/macros/execute-runtime.d.ts +19 -0
  284. package/dist/macros/execute-runtime.d.ts.map +1 -0
  285. package/dist/macros/execute.d.ts +3 -1
  286. package/dist/macros/execute.d.ts.map +1 -1
  287. package/dist/opendevbrowser.d.ts.map +1 -1
  288. package/dist/opendevbrowser.js +1103 -467
  289. package/dist/opendevbrowser.js.map +1 -1
  290. package/dist/providers/blocker.d.ts.map +1 -1
  291. package/dist/providers/browser-fallback.d.ts +30 -0
  292. package/dist/providers/browser-fallback.d.ts.map +1 -0
  293. package/dist/providers/constraint.d.ts +45 -0
  294. package/dist/providers/constraint.d.ts.map +1 -0
  295. package/dist/providers/index.d.ts +11 -2
  296. package/dist/providers/index.d.ts.map +1 -1
  297. package/dist/providers/policy.d.ts.map +1 -1
  298. package/dist/providers/product-video-compiler.d.ts +92 -0
  299. package/dist/providers/product-video-compiler.d.ts.map +1 -0
  300. package/dist/providers/registry.d.ts +37 -1
  301. package/dist/providers/registry.d.ts.map +1 -1
  302. package/dist/providers/renderer.d.ts.map +1 -1
  303. package/dist/providers/research-compiler.d.ts +64 -0
  304. package/dist/providers/research-compiler.d.ts.map +1 -0
  305. package/dist/providers/research-executor.d.ts +27 -0
  306. package/dist/providers/research-executor.d.ts.map +1 -0
  307. package/dist/providers/runtime-bundle.d.ts +26 -0
  308. package/dist/providers/runtime-bundle.d.ts.map +1 -0
  309. package/dist/providers/runtime-factory.d.ts +6 -1
  310. package/dist/providers/runtime-factory.d.ts.map +1 -1
  311. package/dist/providers/runtime-policy.d.ts +24 -0
  312. package/dist/providers/runtime-policy.d.ts.map +1 -0
  313. package/dist/providers/shared/anti-bot-policy.d.ts +3 -2
  314. package/dist/providers/shared/anti-bot-policy.d.ts.map +1 -1
  315. package/dist/providers/shopping/index.d.ts +11 -1
  316. package/dist/providers/shopping/index.d.ts.map +1 -1
  317. package/dist/providers/shopping-compiler.d.ts +51 -0
  318. package/dist/providers/shopping-compiler.d.ts.map +1 -0
  319. package/dist/providers/shopping-executor.d.ts +18 -0
  320. package/dist/providers/shopping-executor.d.ts.map +1 -0
  321. package/dist/providers/shopping-postprocess.d.ts +46 -0
  322. package/dist/providers/shopping-postprocess.d.ts.map +1 -0
  323. package/dist/providers/shopping-workflow.d.ts +33 -0
  324. package/dist/providers/shopping-workflow.d.ts.map +1 -0
  325. package/dist/providers/social/platform.d.ts +2 -1
  326. package/dist/providers/social/platform.d.ts.map +1 -1
  327. package/dist/providers/social/search-quality.d.ts +16 -0
  328. package/dist/providers/social/search-quality.d.ts.map +1 -0
  329. package/dist/providers/social/youtube-resolver.d.ts +2 -1
  330. package/dist/providers/social/youtube-resolver.d.ts.map +1 -1
  331. package/dist/providers/social/youtube.d.ts.map +1 -1
  332. package/dist/providers/types.d.ts +116 -4
  333. package/dist/providers/types.d.ts.map +1 -1
  334. package/dist/providers/web/crawl-worker.d.ts.map +1 -1
  335. package/dist/providers/web/extract.d.ts +16 -0
  336. package/dist/providers/web/extract.d.ts.map +1 -1
  337. package/dist/providers/web/index.d.ts.map +1 -1
  338. package/dist/providers/workflow-contracts.d.ts +53 -0
  339. package/dist/providers/workflow-contracts.d.ts.map +1 -0
  340. package/dist/providers/workflows.d.ts +30 -6
  341. package/dist/providers/workflows.d.ts.map +1 -1
  342. package/dist/{providers-G3LRHQXX.js → providers-G36AM3Z2.js} +2 -2
  343. package/dist/public-surface/generated-manifest.d.ts +1168 -0
  344. package/dist/public-surface/generated-manifest.d.ts.map +1 -0
  345. package/dist/public-surface/source.d.ts +437 -0
  346. package/dist/public-surface/source.d.ts.map +1 -0
  347. package/dist/relay/protocol.d.ts +25 -3
  348. package/dist/relay/protocol.d.ts.map +1 -1
  349. package/dist/relay/relay-endpoints.d.ts +21 -0
  350. package/dist/relay/relay-endpoints.d.ts.map +1 -1
  351. package/dist/relay/relay-server.d.ts +18 -0
  352. package/dist/relay/relay-server.d.ts.map +1 -1
  353. package/dist/skills/bundled-skill-directories.d.ts +8 -0
  354. package/dist/skills/bundled-skill-directories.d.ts.map +1 -0
  355. package/dist/skills/skill-loader.d.ts +9 -1
  356. package/dist/skills/skill-loader.d.ts.map +1 -1
  357. package/dist/skills/skill-loader.js +7 -0
  358. package/dist/skills/skill-nudge.d.ts.map +1 -1
  359. package/dist/skills/types.d.ts +31 -0
  360. package/dist/skills/types.d.ts.map +1 -1
  361. package/dist/snapshot/ops-snapshot.d.ts +1 -1
  362. package/dist/snapshot/ops-snapshot.d.ts.map +1 -1
  363. package/dist/snapshot/refs.d.ts +6 -1
  364. package/dist/snapshot/refs.d.ts.map +1 -1
  365. package/dist/snapshot/snapshotter.d.ts.map +1 -1
  366. package/dist/tools/connect.d.ts.map +1 -1
  367. package/dist/tools/deps.d.ts +4 -0
  368. package/dist/tools/deps.d.ts.map +1 -1
  369. package/dist/tools/desktop-shared.d.ts +6 -0
  370. package/dist/tools/desktop-shared.d.ts.map +1 -0
  371. package/dist/tools/desktop_accessibility_snapshot.d.ts +4 -0
  372. package/dist/tools/desktop_accessibility_snapshot.d.ts.map +1 -0
  373. package/dist/tools/desktop_active_window.d.ts +4 -0
  374. package/dist/tools/desktop_active_window.d.ts.map +1 -0
  375. package/dist/tools/desktop_capture_desktop.d.ts +4 -0
  376. package/dist/tools/desktop_capture_desktop.d.ts.map +1 -0
  377. package/dist/tools/desktop_capture_window.d.ts +4 -0
  378. package/dist/tools/desktop_capture_window.d.ts.map +1 -0
  379. package/dist/tools/desktop_status.d.ts +4 -0
  380. package/dist/tools/desktop_status.d.ts.map +1 -0
  381. package/dist/tools/desktop_windows.d.ts +4 -0
  382. package/dist/tools/desktop_windows.d.ts.map +1 -0
  383. package/dist/tools/dialog.d.ts +4 -0
  384. package/dist/tools/dialog.d.ts.map +1 -0
  385. package/dist/tools/index.d.ts +3 -0
  386. package/dist/tools/index.d.ts.map +1 -1
  387. package/dist/tools/launch.d.ts.map +1 -1
  388. package/dist/tools/macro_resolve.d.ts.map +1 -1
  389. package/dist/tools/pointer_down.d.ts +4 -0
  390. package/dist/tools/pointer_down.d.ts.map +1 -0
  391. package/dist/tools/pointer_drag.d.ts +4 -0
  392. package/dist/tools/pointer_drag.d.ts.map +1 -0
  393. package/dist/tools/pointer_move.d.ts +4 -0
  394. package/dist/tools/pointer_move.d.ts.map +1 -0
  395. package/dist/tools/pointer_up.d.ts +4 -0
  396. package/dist/tools/pointer_up.d.ts.map +1 -0
  397. package/dist/tools/product_video_run.d.ts.map +1 -1
  398. package/dist/tools/prompting_guide.d.ts.map +1 -1
  399. package/dist/tools/research_run.d.ts.map +1 -1
  400. package/dist/tools/review.d.ts +4 -0
  401. package/dist/tools/review.d.ts.map +1 -0
  402. package/dist/tools/screencast_start.d.ts +4 -0
  403. package/dist/tools/screencast_start.d.ts.map +1 -0
  404. package/dist/tools/screencast_stop.d.ts +4 -0
  405. package/dist/tools/screencast_stop.d.ts.map +1 -0
  406. package/dist/tools/screenshot.d.ts.map +1 -1
  407. package/dist/tools/session_inspector.d.ts +4 -0
  408. package/dist/tools/session_inspector.d.ts.map +1 -0
  409. package/dist/tools/shopping_run.d.ts.map +1 -1
  410. package/dist/tools/skill_list.d.ts.map +1 -1
  411. package/dist/tools/skill_load.d.ts.map +1 -1
  412. package/dist/tools/upload.d.ts +4 -0
  413. package/dist/tools/upload.d.ts.map +1 -0
  414. package/dist/tools/workflow-runtime.d.ts +4 -1
  415. package/dist/tools/workflow-runtime.d.ts.map +1 -1
  416. package/dist/utils/package-assets.d.ts +4 -0
  417. package/dist/utils/package-assets.d.ts.map +1 -0
  418. package/extension/canvas.html +379 -9
  419. package/extension/dist/annotate-content.js +62 -32
  420. package/extension/dist/annotation-payload.js +57 -21
  421. package/extension/dist/background.js +406 -61
  422. package/extension/dist/canvas/canvas-runtime.js +481 -52
  423. package/extension/dist/canvas/model.js +129 -1
  424. package/extension/dist/canvas-page.js +1882 -74
  425. package/extension/dist/ops/dom-bridge.js +139 -0
  426. package/extension/dist/ops/ops-runtime.js +2854 -295
  427. package/extension/dist/ops/ops-session-store.js +83 -5
  428. package/extension/dist/ops/snapshot-builder.js +2 -2
  429. package/extension/dist/ops/snapshot-shared.js +2 -2
  430. package/extension/dist/ops/target-session-coordinator.js +5 -3
  431. package/extension/dist/popup.js +50 -15
  432. package/extension/dist/services/CDPRouter.js +1567 -63
  433. package/extension/dist/services/ConnectionManager.js +436 -78
  434. package/extension/dist/services/RelayClient.js +70 -30
  435. package/extension/dist/services/TabManager.js +83 -10
  436. package/extension/dist/services/TargetSessionMap.js +127 -3
  437. package/extension/dist/services/attach-errors.js +20 -0
  438. package/extension/dist/services/cdp-router-commands.js +135 -8
  439. package/extension/dist/services/url-restrictions.js +9 -13
  440. package/extension/manifest.json +2 -2
  441. package/extension/popup.html +7 -6
  442. package/package.json +15 -7
  443. package/skills/AGENTS.md +9 -8
  444. package/skills/opendevbrowser-best-practices/SKILL.md +118 -9
  445. package/skills/opendevbrowser-best-practices/artifacts/browser-agent-known-issues-matrix.md +1 -0
  446. package/skills/opendevbrowser-best-practices/artifacts/command-channel-reference.md +26 -12
  447. package/skills/opendevbrowser-best-practices/artifacts/parity-gates.md +9 -2
  448. package/skills/opendevbrowser-best-practices/artifacts/provider-workflows.md +6 -0
  449. package/skills/opendevbrowser-best-practices/artifacts/skill-runtime-surface-matrix.md +58 -0
  450. package/skills/opendevbrowser-best-practices/assets/templates/skill-runtime-pack-matrix.json +674 -0
  451. package/skills/opendevbrowser-best-practices/assets/templates/surface-audit-checklist.json +9 -4
  452. package/skills/opendevbrowser-best-practices/scripts/odb-workflow.sh +89 -20
  453. package/skills/opendevbrowser-best-practices/scripts/resolve-odb-cli.sh +100 -0
  454. package/skills/opendevbrowser-best-practices/scripts/run-robustness-audit.sh +1 -0
  455. package/skills/opendevbrowser-best-practices/scripts/validate-skill-assets.sh +256 -116
  456. package/skills/opendevbrowser-best-practices/scripts/validator-fixture-cli.sh +208 -0
  457. package/skills/opendevbrowser-continuity-ledger/SKILL.md +14 -1
  458. package/skills/opendevbrowser-continuity-ledger/scripts/validate-skill-assets.sh +61 -0
  459. package/skills/opendevbrowser-data-extraction/SKILL.md +6 -0
  460. package/skills/opendevbrowser-data-extraction/scripts/validate-skill-assets.sh +112 -0
  461. package/skills/opendevbrowser-design-agent/SKILL.md +275 -0
  462. package/skills/opendevbrowser-design-agent/artifacts/app-shell-and-state-wiring.md +84 -0
  463. package/skills/opendevbrowser-design-agent/artifacts/async-search-state-ownership.md +58 -0
  464. package/skills/opendevbrowser-design-agent/artifacts/component-pattern-index.md +130 -0
  465. package/skills/opendevbrowser-design-agent/artifacts/design-contract-playbook.md +157 -0
  466. package/skills/opendevbrowser-design-agent/artifacts/design-release-gate.md +40 -0
  467. package/skills/opendevbrowser-design-agent/artifacts/design-workflows.md +153 -0
  468. package/skills/opendevbrowser-design-agent/artifacts/existing-surface-adaptation.md +56 -0
  469. package/skills/opendevbrowser-design-agent/artifacts/external-pattern-synthesis.md +103 -0
  470. package/skills/opendevbrowser-design-agent/artifacts/frontend-evaluation-rubric.md +61 -0
  471. package/skills/opendevbrowser-design-agent/artifacts/implementation-anti-patterns.md +163 -0
  472. package/skills/opendevbrowser-design-agent/artifacts/isolated-preview-validation.md +68 -0
  473. package/skills/opendevbrowser-design-agent/artifacts/loading-and-feedback-surfaces.md +56 -0
  474. package/skills/opendevbrowser-design-agent/artifacts/opendevbrowser-ui-example-map.md +44 -0
  475. package/skills/opendevbrowser-design-agent/artifacts/performance-audit-playbook.md +70 -0
  476. package/skills/opendevbrowser-design-agent/artifacts/research-harvest-workflow.md +81 -0
  477. package/skills/opendevbrowser-design-agent/artifacts/scroll-reveal-surface-planning.md +64 -0
  478. package/skills/opendevbrowser-design-agent/artifacts/state-ownership-matrix.md +36 -0
  479. package/skills/opendevbrowser-design-agent/artifacts/theming-and-token-ownership.md +43 -0
  480. package/skills/opendevbrowser-design-agent/assets/templates/canvas-generation-plan.design.v1.json +58 -0
  481. package/skills/opendevbrowser-design-agent/assets/templates/design-audit-report.v1.md +34 -0
  482. package/skills/opendevbrowser-design-agent/assets/templates/design-brief.v1.md +40 -0
  483. package/skills/opendevbrowser-design-agent/assets/templates/design-contract.v1.json +226 -0
  484. package/skills/opendevbrowser-design-agent/assets/templates/design-release-gate.v1.json +35 -0
  485. package/skills/opendevbrowser-design-agent/assets/templates/design-review-checklist.json +57 -0
  486. package/skills/opendevbrowser-design-agent/assets/templates/real-surface-design-matrix.json +32 -0
  487. package/skills/opendevbrowser-design-agent/assets/templates/reference-pattern-board.v1.json +31 -0
  488. package/skills/opendevbrowser-design-agent/scripts/design-workflow.sh +171 -0
  489. package/skills/opendevbrowser-design-agent/scripts/extract-canvas-plan.sh +56 -0
  490. package/skills/opendevbrowser-design-agent/scripts/validate-skill-assets.sh +223 -0
  491. package/skills/opendevbrowser-form-testing/SKILL.md +19 -3
  492. package/skills/opendevbrowser-form-testing/artifacts/form-workflows.md +5 -4
  493. package/skills/opendevbrowser-form-testing/assets/templates/challenge-decision-tree.json +2 -0
  494. package/skills/opendevbrowser-form-testing/scripts/validate-skill-assets.sh +109 -0
  495. package/skills/opendevbrowser-login-automation/SKILL.md +21 -3
  496. package/skills/opendevbrowser-login-automation/artifacts/login-workflows.md +5 -4
  497. package/skills/opendevbrowser-login-automation/assets/templates/auth-signals.json +5 -0
  498. package/skills/opendevbrowser-login-automation/assets/templates/login-scenario-matrix.json +3 -2
  499. package/skills/opendevbrowser-login-automation/scripts/run-login-workflow.sh +17 -1
  500. package/skills/opendevbrowser-login-automation/scripts/validate-skill-assets.sh +133 -0
  501. package/skills/opendevbrowser-product-presentation-asset/SKILL.md +23 -11
  502. package/skills/opendevbrowser-product-presentation-asset/artifacts/asset-pack-assembly.md +5 -3
  503. package/skills/opendevbrowser-product-presentation-asset/assets/templates/shot-list.md +2 -0
  504. package/skills/opendevbrowser-product-presentation-asset/assets/templates/video-assembly.md +3 -2
  505. package/skills/opendevbrowser-product-presentation-asset/scripts/capture-screenshots.sh +5 -1
  506. package/skills/opendevbrowser-product-presentation-asset/scripts/collect-product.sh +6 -2
  507. package/skills/opendevbrowser-product-presentation-asset/scripts/download-images.sh +5 -1
  508. package/skills/opendevbrowser-product-presentation-asset/scripts/render-video-brief.sh +20 -7
  509. package/skills/opendevbrowser-product-presentation-asset/scripts/validate-skill-assets.sh +39 -0
  510. package/skills/opendevbrowser-product-presentation-asset/scripts/write-manifest.sh +5 -1
  511. package/skills/opendevbrowser-research/SKILL.md +14 -6
  512. package/skills/opendevbrowser-research/scripts/render-output.sh +5 -1
  513. package/skills/opendevbrowser-research/scripts/run-research.sh +5 -1
  514. package/skills/opendevbrowser-research/scripts/validate-skill-assets.sh +45 -0
  515. package/skills/opendevbrowser-research/scripts/write-artifacts.sh +5 -1
  516. package/skills/opendevbrowser-shopping/SKILL.md +20 -1
  517. package/skills/opendevbrowser-shopping/scripts/normalize-offers.sh +6 -2
  518. package/skills/opendevbrowser-shopping/scripts/run-deal-hunt.sh +5 -1
  519. package/skills/opendevbrowser-shopping/scripts/run-shopping.sh +5 -1
  520. package/skills/opendevbrowser-shopping/scripts/validate-skill-assets.sh +54 -0
  521. package/dist/chunk-5J3IFL3X.js +0 -16706
  522. package/dist/chunk-5J3IFL3X.js.map +0 -1
  523. package/dist/chunk-D633UO34.js +0 -8149
  524. package/dist/chunk-D633UO34.js.map +0 -1
  525. package/dist/chunk-V7KUDHDG.js +0 -276
  526. package/dist/chunk-V7KUDHDG.js.map +0 -1
  527. package/dist/runtime-factory-BICHDPE7.js +0 -13
  528. /package/dist/{providers-G3LRHQXX.js.map → providers-G36AM3Z2.js.map} +0 -0
  529. /package/dist/{runtime-factory-BICHDPE7.js.map → skills/skill-loader.js.map} +0 -0
@@ -29,6 +29,20 @@ const logInfo = (message) => {
29
29
  const logWarn = (message) => {
30
30
  console.warn(`[opendevbrowser] ${message}`);
31
31
  };
32
+ const getTrackedTabUrl = (tab) => {
33
+ if (!tab) {
34
+ return undefined;
35
+ }
36
+ const pendingUrl = typeof tab.pendingUrl === "string" && tab.pendingUrl.length > 0 ? tab.pendingUrl : undefined;
37
+ const currentUrl = typeof tab.url === "string" && tab.url.length > 0 ? tab.url : undefined;
38
+ return pendingUrl ?? currentUrl;
39
+ };
40
+ const getTrackedTabTitle = (tab) => {
41
+ if (!tab || tab.status === "loading") {
42
+ return undefined;
43
+ }
44
+ return typeof tab.title === "string" && tab.title.length > 0 ? tab.title : undefined;
45
+ };
32
46
  const RECONNECT_INITIAL_DELAY_MS = 12_000;
33
47
  const RECONNECT_MAX_DELAY_MS = 30_000;
34
48
  export class ConnectionManager {
@@ -58,6 +72,8 @@ export class ConnectionManager {
58
72
  canvasHandler = null;
59
73
  heartbeatTimer = null;
60
74
  heartbeatInFlight = false;
75
+ handshakeRefreshQueued = false;
76
+ handshakeRefreshPromise = null;
61
77
  heartbeatIntervalMs = 25_000;
62
78
  heartbeatTimeoutMs = 2_000;
63
79
  constructor() {
@@ -143,13 +159,82 @@ export class ConnectionManager {
143
159
  return null;
144
160
  }
145
161
  try {
146
- return await this.relay.sendHealthCheck();
162
+ const health = await this.relay.sendHealthCheck();
163
+ if (health.extensionConnected && !health.extensionHandshakeComplete) {
164
+ this.relayNotice = "Extension websocket is connected but the daemon-extension handshake is unhealthy. Re-establishing a clean handshake.";
165
+ this.refreshHandshake();
166
+ }
167
+ return health;
147
168
  }
148
169
  catch (error) {
149
170
  logError("relay.health_check", error, { code: "relay_health_failed" });
150
171
  return null;
151
172
  }
152
173
  }
174
+ async sendAnnotationCommand(command, timeoutMs = 5000) {
175
+ const socket = new WebSocket(this.buildAnnotationUrl());
176
+ let settled = false;
177
+ return await new Promise((resolve, reject) => {
178
+ const timeoutId = setTimeout(() => {
179
+ finish(() => reject(new Error("Annotation relay request timed out")));
180
+ }, timeoutMs);
181
+ const finish = (callback) => {
182
+ if (settled) {
183
+ return;
184
+ }
185
+ settled = true;
186
+ clearTimeout(timeoutId);
187
+ try {
188
+ if (socket.readyState === WebSocket.OPEN || socket.readyState === WebSocket.CONNECTING) {
189
+ socket.close(1000, "annotation-command-complete");
190
+ }
191
+ }
192
+ catch {
193
+ // Ignore socket close failures during cleanup.
194
+ }
195
+ callback();
196
+ };
197
+ socket.addEventListener("open", () => {
198
+ try {
199
+ socket.send(JSON.stringify({
200
+ type: "annotationCommand",
201
+ payload: command
202
+ }));
203
+ }
204
+ catch (error) {
205
+ finish(() => reject(error instanceof Error ? error : new Error("Annotation relay send failed")));
206
+ }
207
+ }, { once: true });
208
+ socket.addEventListener("message", (event) => {
209
+ if (typeof event.data !== "string") {
210
+ return;
211
+ }
212
+ try {
213
+ const message = JSON.parse(event.data);
214
+ if (message.type !== "annotationResponse") {
215
+ return;
216
+ }
217
+ const payload = message.payload;
218
+ if (!isAnnotationResponse(payload) || payload.requestId !== command.requestId) {
219
+ return;
220
+ }
221
+ finish(() => resolve(payload));
222
+ }
223
+ catch {
224
+ // Ignore malformed one-off annotation responses.
225
+ }
226
+ });
227
+ socket.addEventListener("error", () => {
228
+ finish(() => reject(new Error("Annotation relay unavailable")));
229
+ }, { once: true });
230
+ socket.addEventListener("close", () => {
231
+ if (settled) {
232
+ return;
233
+ }
234
+ finish(() => reject(new Error("Annotation relay closed")));
235
+ }, { once: true });
236
+ });
237
+ }
153
238
  async connect() {
154
239
  if (this.connectPromise) {
155
240
  return await this.connectPromise;
@@ -193,6 +278,7 @@ export class ConnectionManager {
193
278
  this.shouldReconnect = false;
194
279
  this.clearReconnectTimer();
195
280
  this.stopHeartbeat();
281
+ this.handshakeRefreshQueued = false;
196
282
  try {
197
283
  if (this.relay) {
198
284
  this.relay.disconnect();
@@ -228,6 +314,38 @@ export class ConnectionManager {
228
314
  logError(context, error, { code: "relay_send_failed" });
229
315
  }
230
316
  }
317
+ async getFirstHttpFallbackTab(currentTabId) {
318
+ const fallbackTab = await this.tabs.getFirstAttachableTab(currentTabId);
319
+ if (!fallbackTab || typeof fallbackTab.id !== "number" || !fallbackTab.url) {
320
+ return null;
321
+ }
322
+ logInfo("Falling back to first http(s) tab.");
323
+ return fallbackTab;
324
+ }
325
+ async bootstrapRelayAttachTab() {
326
+ try {
327
+ const fallbackTab = await this.tabs.createTab("about:blank", true);
328
+ if (fallbackTab && typeof fallbackTab.id === "number") {
329
+ logInfo("Bootstrapping a fresh browser tab for relay attach.");
330
+ return fallbackTab;
331
+ }
332
+ }
333
+ catch {
334
+ // Ignore tab creation failures and let the caller surface the original error.
335
+ }
336
+ return null;
337
+ }
338
+ async resolveRelayAttachFallback(currentTabId) {
339
+ const httpTab = await this.getFirstHttpFallbackTab(currentTabId);
340
+ if (httpTab) {
341
+ return { tab: httpTab, allowBlankRelayFallback: false };
342
+ }
343
+ const blankTab = await this.bootstrapRelayAttachTab();
344
+ if (blankTab) {
345
+ return { tab: blankTab, allowBlankRelayFallback: true };
346
+ }
347
+ return { tab: null, allowBlankRelayFallback: false };
348
+ }
231
349
  startHeartbeat() {
232
350
  if (this.heartbeatTimer !== null) {
233
351
  return;
@@ -254,7 +372,15 @@ export class ConnectionManager {
254
372
  }
255
373
  this.heartbeatInFlight = true;
256
374
  try {
257
- await this.relay.sendPing(this.heartbeatTimeoutMs);
375
+ const health = await this.relay.sendPing(this.heartbeatTimeoutMs);
376
+ if (health.extensionConnected && !health.extensionHandshakeComplete) {
377
+ this.relayNotice = "Extension websocket is connected but the daemon-extension handshake is incomplete. Re-establishing a clean handshake.";
378
+ this.refreshHandshake();
379
+ return;
380
+ }
381
+ if (health.ok) {
382
+ this.relayNotice = null;
383
+ }
258
384
  }
259
385
  catch (error) {
260
386
  logError("relay.heartbeat", error, { code: "relay_heartbeat_failed" });
@@ -268,29 +394,35 @@ export class ConnectionManager {
268
394
  }
269
395
  async attachToActiveTab() {
270
396
  let tab = await this.tabs.getActiveTab();
397
+ let allowBlankRelayFallback = false;
398
+ let tabUrl = getTrackedTabUrl(tab);
271
399
  if (!tab || typeof tab.id !== "number") {
272
- this.trackedTab = null;
273
- this.setStatus("disconnected");
274
- logWarn("Active tab not found.");
275
- throw new ConnectionError("no_active_tab", "No active browser tab found. Focus a normal tab (not the popup) and retry.");
400
+ const fallback = await this.resolveRelayAttachFallback();
401
+ tab = fallback.tab;
402
+ allowBlankRelayFallback = fallback.allowBlankRelayFallback;
403
+ tabUrl = getTrackedTabUrl(tab);
404
+ if (!tab || typeof tab.id !== "number") {
405
+ this.trackedTab = null;
406
+ this.setStatus("disconnected");
407
+ logWarn("Active tab not found.");
408
+ throw new ConnectionError("no_active_tab", "No active browser page found. Focus the site tab or popup window you want to automate, not the extension popup, and retry.");
409
+ }
276
410
  }
277
- if (!tab.url) {
411
+ if (!tabUrl) {
278
412
  logWarn("Active tab URL missing.");
279
- const fallbackId = await this.tabs.getFirstHttpTabId();
280
- if (fallbackId && fallbackId !== tab.id) {
281
- const fallbackTab = await this.tabs.getTab(fallbackId);
282
- if (fallbackTab && typeof fallbackTab.id === "number" && fallbackTab.url) {
283
- logInfo("Falling back to first http(s) tab.");
284
- tab = fallbackTab;
285
- }
413
+ const fallback = await this.resolveRelayAttachFallback(tab.id);
414
+ if (fallback.tab) {
415
+ tab = fallback.tab;
416
+ allowBlankRelayFallback ||= fallback.allowBlankRelayFallback;
417
+ tabUrl = getTrackedTabUrl(tab);
286
418
  }
287
- if (!tab.url) {
419
+ if (!tabUrl) {
288
420
  throw new ConnectionError("tab_url_missing", "Active tab URL is unavailable. Reload the tab and retry.");
289
421
  }
290
422
  }
291
423
  let parsedUrl = null;
292
424
  try {
293
- parsedUrl = new URL(tab.url);
425
+ parsedUrl = tabUrl ? new URL(tabUrl) : null;
294
426
  }
295
427
  catch (error) {
296
428
  logError("connection.parse_tab_url", error, { code: "tab_url_parse_failed" });
@@ -298,54 +430,48 @@ export class ConnectionManager {
298
430
  }
299
431
  if (!parsedUrl) {
300
432
  logWarn("Active tab URL is invalid.");
301
- const fallbackId = await this.tabs.getFirstHttpTabId();
302
- if (fallbackId && fallbackId !== tab.id) {
303
- const fallbackTab = await this.tabs.getTab(fallbackId);
304
- if (fallbackTab && typeof fallbackTab.id === "number" && fallbackTab.url) {
305
- logInfo("Falling back to first http(s) tab.");
306
- try {
307
- parsedUrl = new URL(fallbackTab.url);
308
- tab = fallbackTab;
309
- }
310
- catch {
311
- parsedUrl = null;
312
- }
433
+ const fallback = await this.resolveRelayAttachFallback(tab.id);
434
+ if (fallback.tab) {
435
+ tab = fallback.tab;
436
+ allowBlankRelayFallback ||= fallback.allowBlankRelayFallback;
437
+ tabUrl = getTrackedTabUrl(tab);
438
+ try {
439
+ parsedUrl = tabUrl ? new URL(tabUrl) : null;
440
+ }
441
+ catch {
442
+ parsedUrl = null;
313
443
  }
314
444
  }
315
445
  if (!parsedUrl) {
316
- throw new ConnectionError("tab_url_restricted", "Active tab URL is unsupported. Focus a normal http(s) tab and retry.");
446
+ throw new ConnectionError("tab_url_restricted", "Active browser page URL is unsupported. Focus an http(s) page or site popup window, not the extension popup, and retry.");
317
447
  }
318
448
  }
319
449
  const restrictionMessage = getRestrictionMessage(parsedUrl);
320
450
  if (restrictionMessage) {
321
- logWarn(`Active tab blocked: ${summarizeProtocol(tab.url)} scheme.`);
322
- const fallbackId = await this.tabs.getFirstHttpTabId();
323
- if (fallbackId && fallbackId !== tab.id) {
324
- const fallbackTab = await this.tabs.getTab(fallbackId);
325
- if (fallbackTab && typeof fallbackTab.id === "number" && fallbackTab.url) {
326
- try {
327
- const fallbackUrl = new URL(fallbackTab.url);
328
- const fallbackRestriction = getRestrictionMessage(fallbackUrl);
329
- if (!fallbackRestriction) {
330
- logInfo("Falling back to first http(s) tab.");
331
- tab = fallbackTab;
332
- parsedUrl = fallbackUrl;
333
- }
334
- }
335
- catch {
336
- // Ignore invalid fallback URL.
337
- }
451
+ logWarn(`Active tab blocked: ${summarizeProtocol(tabUrl)} scheme.`);
452
+ const fallback = await this.resolveRelayAttachFallback(tab.id);
453
+ if (fallback.tab) {
454
+ tab = fallback.tab;
455
+ allowBlankRelayFallback ||= fallback.allowBlankRelayFallback;
456
+ tabUrl = getTrackedTabUrl(tab);
457
+ try {
458
+ parsedUrl = tabUrl ? new URL(tabUrl) : null;
459
+ }
460
+ catch {
461
+ parsedUrl = null;
338
462
  }
339
463
  }
340
- if (restrictionMessage && getRestrictionMessage(parsedUrl)) {
341
- throw new ConnectionError("tab_url_restricted", restrictionMessage);
464
+ if (restrictionMessage && (!parsedUrl || getRestrictionMessage(parsedUrl))) {
465
+ if (!allowBlankRelayFallback) {
466
+ throw new ConnectionError("tab_url_restricted", restrictionMessage);
467
+ }
342
468
  }
343
469
  }
344
470
  const tabId = tab.id;
345
471
  if (typeof tabId !== "number") {
346
472
  this.trackedTab = null;
347
473
  this.setStatus("disconnected");
348
- throw new ConnectionError("no_active_tab", "No active browser tab found. Focus a normal tab (not the popup) and retry.");
474
+ throw new ConnectionError("no_active_tab", "No active browser page found. Focus the site tab or popup window you want to automate, not the extension popup, and retry.");
349
475
  }
350
476
  logInfo("Active tab resolved.");
351
477
  try {
@@ -360,12 +486,7 @@ export class ConnectionManager {
360
486
  : "Debugger attach failed. Close DevTools for the tab and retry.";
361
487
  throw new ConnectionError("debugger_attach_failed", message);
362
488
  }
363
- this.trackedTab = {
364
- id: tabId,
365
- url: tab.url ?? undefined,
366
- title: tab.title ?? undefined,
367
- groupId: typeof tab.groupId === "number" ? tab.groupId : undefined
368
- };
489
+ this.trackedTab = this.toTrackedTab(tab, null);
369
490
  }
370
491
  async connectRelay() {
371
492
  if (!this.trackedTab) {
@@ -378,6 +499,9 @@ export class ConnectionManager {
378
499
  this.handleCdpDetach({ reason: "cdp_command_failed" });
379
500
  });
380
501
  },
502
+ onCdpControl: (message) => {
503
+ this.handleCdpControl(message);
504
+ },
381
505
  onAnnotationCommand: (command) => {
382
506
  this.annotationHandler?.(command);
383
507
  },
@@ -420,6 +544,10 @@ export class ConnectionManager {
420
544
  if (!mismatch) {
421
545
  this.persistRelayIdentity(ack.payload.relayPort, this.relayInstanceId, this.relayEpoch);
422
546
  }
547
+ const handshakeHealthy = await this.verifyHandshakeHealth(relay, "connect");
548
+ if (!handshakeHealthy) {
549
+ return;
550
+ }
423
551
  logInfo("Relay WebSocket connected.");
424
552
  this.setStatus("connected");
425
553
  this.startHeartbeat();
@@ -438,6 +566,7 @@ export class ConnectionManager {
438
566
  handleRelayClose(detail) {
439
567
  this.stopHeartbeat();
440
568
  this.relay = null;
569
+ this.cdp.markClientClosed();
441
570
  if (detail && (detail.code === 1008 || detail.reason?.includes("Invalid pairing token"))) {
442
571
  this.clearStoredPairingToken();
443
572
  }
@@ -465,6 +594,10 @@ export class ConnectionManager {
465
594
  if (this.cdp.getAttachedTabIds().length > 0) {
466
595
  return;
467
596
  }
597
+ if (detail?.reason === "manual_disconnect") {
598
+ void this.recoverFromManualDetach(detail);
599
+ return;
600
+ }
468
601
  this.setStatus("disconnected");
469
602
  if (this.relay?.isConnected()) {
470
603
  this.relay.disconnect();
@@ -472,12 +605,49 @@ export class ConnectionManager {
472
605
  }
473
606
  this.scheduleReconnect();
474
607
  }
608
+ async recoverFromManualDetach(detail) {
609
+ try {
610
+ const preferredTabId = typeof detail?.tabId === "number" ? detail.tabId : this.trackedTab?.id ?? null;
611
+ if (typeof preferredTabId === "number") {
612
+ await this.cdp.attach(preferredTabId);
613
+ const recoveredTabId = this.cdp.getPrimaryTabId() ?? preferredTabId;
614
+ await this.refreshTrackedTab(recoveredTabId, { preserveCurrentOnRestricted: true });
615
+ }
616
+ else {
617
+ await this.attachToActiveTab();
618
+ }
619
+ if (!this.relay?.isConnected()) {
620
+ this.scheduleReconnect();
621
+ return;
622
+ }
623
+ this.setStatus("connected");
624
+ this.refreshHandshake();
625
+ }
626
+ catch (error) {
627
+ logError("connection.manual_detach_recover", error, { code: "tracked_tab_refresh_failed" });
628
+ this.setStatus("disconnected");
629
+ if (this.relay?.isConnected()) {
630
+ this.relay.disconnect();
631
+ return;
632
+ }
633
+ this.scheduleReconnect();
634
+ }
635
+ }
636
+ handleCdpControl(message) {
637
+ if (message.action !== "client_closed") {
638
+ return;
639
+ }
640
+ this.cdp.markClientClosed();
641
+ }
475
642
  scheduleReconnect() {
476
643
  if (this.reconnectTimer !== null) {
477
644
  return;
478
645
  }
479
646
  this.reconnectTimer = setTimeout(() => {
480
647
  this.reconnectTimer = null;
648
+ if (!this.shouldReconnect || this.status === "connected" || this.relay?.isConnected()) {
649
+ return;
650
+ }
481
651
  this.reconnectAttempts += 1;
482
652
  this.reconnectDelayMs = Math.min(this.reconnectDelayMs * 2, this.maxReconnectDelayMs);
483
653
  this.reconnectRelay().catch((error) => {
@@ -487,7 +657,7 @@ export class ConnectionManager {
487
657
  }, this.reconnectDelayMs);
488
658
  }
489
659
  async reconnectRelay() {
490
- if (!this.shouldReconnect) {
660
+ if (!this.shouldReconnect || this.status === "connected" || this.relay?.isConnected()) {
491
661
  return;
492
662
  }
493
663
  const primaryId = this.cdp.getPrimaryTabId();
@@ -544,24 +714,59 @@ export class ConnectionManager {
544
714
  if (!this.trackedTab || this.trackedTab.id !== tabId) {
545
715
  return;
546
716
  }
547
- if (this.cdp.getAttachedTabIds().length <= 1) {
717
+ const attachedTabIds = this.cdp.getAttachedTabIds().filter((attachedId) => attachedId !== tabId);
718
+ if (attachedTabIds.length === 0) {
548
719
  this.disconnect().catch((error) => {
549
720
  logError("connection.tab_removed_disconnect", error, { code: "disconnect_failed" });
550
721
  });
722
+ return;
723
+ }
724
+ const primaryTabId = this.cdp.getPrimaryTabId();
725
+ const nextTrackedTabId = primaryTabId && primaryTabId !== tabId
726
+ ? primaryTabId
727
+ : attachedTabIds[0] ?? null;
728
+ if (!nextTrackedTabId) {
729
+ this.disconnect().catch((error) => {
730
+ logError("connection.tab_removed_disconnect", error, { code: "disconnect_failed" });
731
+ });
732
+ return;
551
733
  }
734
+ this.refreshTrackedTab(nextTrackedTabId, { preserveCurrentOnRestricted: true })
735
+ .then(() => {
736
+ this.refreshHandshake();
737
+ })
738
+ .catch((error) => {
739
+ logError("connection.tab_removed_refresh", error, { code: "tracked_tab_refresh_failed" });
740
+ });
552
741
  };
553
742
  handleTabUpdated = (_tabId, _changeInfo, tab) => {
554
- if (!this.trackedTab || tab.id !== this.trackedTab.id) {
743
+ const updatedTabId = typeof tab.id === "number" ? tab.id : null;
744
+ if (updatedTabId === null) {
555
745
  return;
556
746
  }
557
- this.trackedTab = {
558
- id: tab.id,
559
- url: tab.url ?? this.trackedTab.url,
560
- title: tab.title ?? this.trackedTab.title,
561
- groupId: typeof tab.groupId === "number" ? tab.groupId : this.trackedTab.groupId
562
- };
747
+ const trackedTabId = this.trackedTab?.id ?? null;
748
+ const primaryTabId = this.cdp.getPrimaryTabId();
749
+ if (trackedTabId !== updatedTabId && primaryTabId !== updatedTabId) {
750
+ return;
751
+ }
752
+ if (trackedTabId !== updatedTabId) {
753
+ if (!this.isRestrictedTab(tab)) {
754
+ this.setTrackedTab(tab);
755
+ this.refreshHandshake();
756
+ return;
757
+ }
758
+ this.refreshTrackedTab(updatedTabId, { preserveCurrentOnRestricted: true })
759
+ .then(() => {
760
+ this.refreshHandshake();
761
+ })
762
+ .catch((error) => {
763
+ logError("connection.tab_updated_refresh", error, { code: "tracked_tab_refresh_failed" });
764
+ });
765
+ return;
766
+ }
767
+ this.setTrackedTab(tab);
563
768
  if (this.relay?.isConnected()) {
564
- this.safeRelaySend(() => this.relay?.sendHandshake(this.buildHandshake()), "relay.send_handshake");
769
+ this.refreshHandshake();
565
770
  }
566
771
  };
567
772
  async loadSettings() {
@@ -584,7 +789,7 @@ export class ConnectionManager {
584
789
  }
585
790
  return {
586
791
  code: "unknown",
587
- message: "Connection failed. Focus a normal tab and retry."
792
+ message: "Connection failed. Focus the site tab or popup window you want to automate, not the extension popup, and retry."
588
793
  };
589
794
  }
590
795
  updatePairingToken(value) {
@@ -666,9 +871,9 @@ export class ConnectionManager {
666
871
  this.clearStoredRelayIdentity();
667
872
  this.clearStoredPairingToken(false);
668
873
  this.relayNotice = instanceMismatch
669
- ? "Relay instance changed. Re-pair and reconnect."
670
- : "Relay restarted. Re-pair and reconnect.";
671
- this.safeRelaySend(() => this.relay?.sendHandshake(this.buildHandshake()), "relay.rehandshake");
874
+ ? "Relay instance changed. Re-establishing a clean daemon-extension handshake."
875
+ : "Relay restarted. Re-establishing a clean daemon-extension handshake.";
876
+ this.refreshHandshake();
672
877
  return true;
673
878
  }
674
879
  this.relayNotice = null;
@@ -682,6 +887,13 @@ export class ConnectionManager {
682
887
  buildRelayUrl() {
683
888
  return `ws://127.0.0.1:${this.relayPort}/extension`;
684
889
  }
890
+ buildAnnotationUrl() {
891
+ const port = this.relayConfirmedPort ?? this.relayPort;
892
+ const query = this.pairingEnabled && this.pairingToken
893
+ ? `?token=${encodeURIComponent(this.pairingToken)}`
894
+ : "";
895
+ return `ws://127.0.0.1:${port}/annotation${query}`;
896
+ }
685
897
  async refreshRelay() {
686
898
  if (this.status !== "connected")
687
899
  return;
@@ -690,26 +902,101 @@ export class ConnectionManager {
690
902
  }
691
903
  async handlePrimaryTabChange(tabId) {
692
904
  if (!tabId) {
905
+ const trackedTabId = this.trackedTab?.id;
906
+ if (this.shouldReconnect && !this.disconnecting && typeof trackedTabId === "number") {
907
+ const trackedTab = await this.tabs.getTab(trackedTabId);
908
+ if (trackedTab && typeof trackedTab.id === "number") {
909
+ await this.refreshTrackedTab(trackedTab.id, { preserveCurrentOnRestricted: true });
910
+ this.refreshHandshake();
911
+ return;
912
+ }
913
+ }
693
914
  this.trackedTab = null;
694
915
  if (this.relay?.isConnected()) {
695
916
  this.relay.disconnect();
696
917
  }
697
918
  return;
698
919
  }
699
- await this.refreshTrackedTab(tabId);
920
+ await this.refreshTrackedTab(tabId, { preserveCurrentOnRestricted: true });
700
921
  this.refreshHandshake();
701
922
  }
702
- async refreshTrackedTab(tabId) {
703
- const tab = await this.tabs.getTab(tabId);
923
+ isRestrictedTab(tab) {
924
+ const rawUrl = getTrackedTabUrl(tab);
925
+ if (!rawUrl) {
926
+ return true;
927
+ }
928
+ try {
929
+ return Boolean(getRestrictionMessage(new URL(rawUrl)));
930
+ }
931
+ catch {
932
+ return true;
933
+ }
934
+ }
935
+ async refreshTrackedTab(tabId, options) {
936
+ const previous = this.trackedTab;
937
+ let tab = await this.tabs.getTab(tabId);
938
+ if ((!tab || typeof tab.id !== "number") && options?.preserveCurrentOnRestricted && previous) {
939
+ this.trackedTab = previous;
940
+ return;
941
+ }
704
942
  if (!tab || typeof tab.id !== "number") {
705
943
  this.trackedTab = null;
706
944
  return;
707
945
  }
708
- this.trackedTab = {
709
- id: tab.id,
710
- url: tab.url ?? this.trackedTab?.url,
711
- title: tab.title ?? this.trackedTab?.title,
712
- groupId: typeof tab.groupId === "number" ? tab.groupId : this.trackedTab?.groupId
946
+ if (this.isRestrictedTab(tab)) {
947
+ const httpFallback = await this.getFirstHttpFallbackTab(tab.id);
948
+ if (httpFallback) {
949
+ tab = httpFallback;
950
+ }
951
+ else if (options?.preserveCurrentOnRestricted && previous) {
952
+ this.trackedTab = previous;
953
+ return;
954
+ }
955
+ else {
956
+ const blankFallback = await this.bootstrapRelayAttachTab();
957
+ if (blankFallback) {
958
+ tab = blankFallback;
959
+ }
960
+ else {
961
+ this.trackedTab = null;
962
+ return;
963
+ }
964
+ }
965
+ }
966
+ const nextTrackedTabId = tab.id;
967
+ if (typeof nextTrackedTabId !== "number") {
968
+ if (options?.preserveCurrentOnRestricted && previous) {
969
+ this.trackedTab = previous;
970
+ return;
971
+ }
972
+ this.trackedTab = null;
973
+ return;
974
+ }
975
+ this.setTrackedTab(tab);
976
+ }
977
+ setTrackedTab(tab) {
978
+ const tabId = typeof tab.id === "number" ? tab.id : null;
979
+ if (tabId === null) {
980
+ return;
981
+ }
982
+ this.trackedTab = this.toTrackedTab(tab, this.trackedTab);
983
+ }
984
+ toTrackedTab(tab, previous) {
985
+ const tabId = typeof tab.id === "number" ? tab.id : null;
986
+ if (tabId === null) {
987
+ throw new Error("Tracked tab id is missing");
988
+ }
989
+ const sameTab = previous?.id === tabId;
990
+ const url = getTrackedTabUrl(tab) ?? (sameTab ? previous?.url : undefined);
991
+ const title = getTrackedTabTitle(tab) ?? (sameTab ? previous?.title : undefined);
992
+ const groupId = typeof tab.groupId === "number"
993
+ ? tab.groupId
994
+ : (sameTab ? previous?.groupId : undefined);
995
+ return {
996
+ id: tabId,
997
+ ...(url ? { url } : {}),
998
+ ...(title ? { title } : {}),
999
+ ...(typeof groupId === "number" ? { groupId } : {})
713
1000
  };
714
1001
  }
715
1002
  clearReconnectTimer() {
@@ -718,10 +1005,81 @@ export class ConnectionManager {
718
1005
  this.reconnectTimer = null;
719
1006
  }
720
1007
  }
1008
+ async verifyHandshakeHealth(relay, source) {
1009
+ try {
1010
+ const health = await relay.sendPing(this.heartbeatTimeoutMs);
1011
+ if (health.extensionConnected && health.extensionHandshakeComplete) {
1012
+ if (this.relay === relay) {
1013
+ this.relayNotice = null;
1014
+ }
1015
+ return true;
1016
+ }
1017
+ if (this.relay === relay) {
1018
+ this.relayNotice = "Extension websocket is connected but the daemon-extension handshake is still incomplete. Retrying a clean handshake.";
1019
+ if (this.shouldReconnect && !this.disconnecting) {
1020
+ relay.disconnect();
1021
+ }
1022
+ }
1023
+ }
1024
+ catch (error) {
1025
+ logError(`relay.${source}_handshake_health`, error, { code: "relay_handshake_health_failed" });
1026
+ if (this.relay === relay) {
1027
+ this.relayNotice = "Failed to verify a clean daemon-extension handshake. Retrying the relay connection.";
1028
+ if (this.shouldReconnect && !this.disconnecting) {
1029
+ relay.disconnect();
1030
+ }
1031
+ }
1032
+ }
1033
+ return false;
1034
+ }
721
1035
  refreshHandshake() {
722
1036
  if (!this.trackedTab || !this.relay?.isConnected()) {
723
1037
  return;
724
1038
  }
725
- this.safeRelaySend(() => this.relay?.sendHandshake(this.buildHandshake()), "relay.send_handshake");
1039
+ this.handshakeRefreshQueued = true;
1040
+ if (this.handshakeRefreshPromise) {
1041
+ return;
1042
+ }
1043
+ const run = (async () => {
1044
+ while (this.handshakeRefreshQueued) {
1045
+ this.handshakeRefreshQueued = false;
1046
+ const relay = this.relay;
1047
+ if (!this.trackedTab || !relay || !relay.isConnected()) {
1048
+ return;
1049
+ }
1050
+ try {
1051
+ await relay.sendHandshake(this.buildHandshake());
1052
+ const handshakeHealthy = await this.verifyHandshakeHealth(relay, "refresh");
1053
+ if (!handshakeHealthy) {
1054
+ return;
1055
+ }
1056
+ }
1057
+ catch (error) {
1058
+ logError("relay.refresh_handshake", error, { code: "relay_handshake_refresh_failed" });
1059
+ if (this.relay === relay) {
1060
+ this.relayNotice = "Failed to re-establish a clean daemon-extension handshake. Open the extension popup, click Connect again, confirm `status --daemon` shows ext=on and handshake=on, then retry.";
1061
+ if (this.shouldReconnect && !this.disconnecting) {
1062
+ relay.disconnect();
1063
+ }
1064
+ }
1065
+ return;
1066
+ }
1067
+ }
1068
+ })();
1069
+ const refreshPromise = run.finally(() => {
1070
+ if (this.handshakeRefreshPromise === refreshPromise) {
1071
+ this.handshakeRefreshPromise = null;
1072
+ }
1073
+ });
1074
+ this.handshakeRefreshPromise = refreshPromise;
726
1075
  }
727
1076
  }
1077
+ const isAnnotationResponse = (value) => {
1078
+ if (!value || typeof value !== "object") {
1079
+ return false;
1080
+ }
1081
+ const record = value;
1082
+ return record.version === 1
1083
+ && typeof record.requestId === "string"
1084
+ && (record.status === "ok" || record.status === "cancelled" || record.status === "error");
1085
+ };