opendevbrowser 0.0.15 → 0.0.17

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 (646) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +262 -43
  3. package/dist/annotate/direct-annotator.d.ts +22 -0
  4. package/dist/annotate/direct-annotator.d.ts.map +1 -0
  5. package/dist/annotate/output.d.ts +10 -0
  6. package/dist/annotate/output.d.ts.map +1 -0
  7. package/dist/browser/annotation-manager.d.ts +33 -0
  8. package/dist/browser/annotation-manager.d.ts.map +1 -0
  9. package/dist/browser/browser-manager.d.ts +402 -0
  10. package/dist/browser/browser-manager.d.ts.map +1 -0
  11. package/dist/browser/canvas-client.d.ts +53 -0
  12. package/dist/browser/canvas-client.d.ts.map +1 -0
  13. package/dist/browser/canvas-code-sync-manager.d.ts +79 -0
  14. package/dist/browser/canvas-code-sync-manager.d.ts.map +1 -0
  15. package/dist/browser/canvas-manager.d.ts +94 -0
  16. package/dist/browser/canvas-manager.d.ts.map +1 -0
  17. package/dist/browser/canvas-runtime-preview-bridge.d.ts +20 -0
  18. package/dist/browser/canvas-runtime-preview-bridge.d.ts.map +1 -0
  19. package/dist/browser/canvas-session-sync-manager.d.ts +21 -0
  20. package/dist/browser/canvas-session-sync-manager.d.ts.map +1 -0
  21. package/dist/browser/fingerprint/adapters.d.ts +26 -0
  22. package/dist/browser/fingerprint/adapters.d.ts.map +1 -0
  23. package/dist/browser/fingerprint/canary.d.ts +25 -0
  24. package/dist/browser/fingerprint/canary.d.ts.map +1 -0
  25. package/dist/browser/fingerprint/profiles.d.ts +16 -0
  26. package/dist/browser/fingerprint/profiles.d.ts.map +1 -0
  27. package/dist/browser/fingerprint/tier1-coherence.d.ts +36 -0
  28. package/dist/browser/fingerprint/tier1-coherence.d.ts.map +1 -0
  29. package/dist/browser/fingerprint/tier2-runtime.d.ts +40 -0
  30. package/dist/browser/fingerprint/tier2-runtime.d.ts.map +1 -0
  31. package/dist/browser/fingerprint/tier3-adaptive.d.ts +30 -0
  32. package/dist/browser/fingerprint/tier3-adaptive.d.ts.map +1 -0
  33. package/dist/browser/manager-types.d.ts +15 -0
  34. package/dist/browser/manager-types.d.ts.map +1 -0
  35. package/dist/browser/ops-browser-manager.d.ts +141 -0
  36. package/dist/browser/ops-browser-manager.d.ts.map +1 -0
  37. package/dist/browser/ops-client.d.ts +56 -0
  38. package/dist/browser/ops-client.d.ts.map +1 -0
  39. package/dist/browser/parallelism-governor.d.ts +31 -0
  40. package/dist/browser/parallelism-governor.d.ts.map +1 -0
  41. package/dist/browser/script-runner.d.ts +23 -0
  42. package/dist/browser/script-runner.d.ts.map +1 -0
  43. package/dist/browser/session-store.d.ts +63 -0
  44. package/dist/browser/session-store.d.ts.map +1 -0
  45. package/dist/browser/target-manager.d.ts +36 -0
  46. package/dist/browser/target-manager.d.ts.map +1 -0
  47. package/dist/cache/chrome-locator.d.ts +2 -0
  48. package/dist/cache/chrome-locator.d.ts.map +1 -0
  49. package/dist/cache/downloader.d.ts +6 -0
  50. package/dist/cache/downloader.d.ts.map +1 -0
  51. package/dist/cache/paths.d.ts +9 -0
  52. package/dist/cache/paths.d.ts.map +1 -0
  53. package/dist/canvas/code-sync/apply-tsx.d.ts +23 -0
  54. package/dist/canvas/code-sync/apply-tsx.d.ts.map +1 -0
  55. package/dist/canvas/code-sync/graph.d.ts +5 -0
  56. package/dist/canvas/code-sync/graph.d.ts.map +1 -0
  57. package/dist/canvas/code-sync/hash.d.ts +3 -0
  58. package/dist/canvas/code-sync/hash.d.ts.map +1 -0
  59. package/dist/canvas/code-sync/import.d.ts +18 -0
  60. package/dist/canvas/code-sync/import.d.ts.map +1 -0
  61. package/dist/canvas/code-sync/manifest.d.ts +5 -0
  62. package/dist/canvas/code-sync/manifest.d.ts.map +1 -0
  63. package/dist/canvas/code-sync/tsx-adapter.d.ts +8 -0
  64. package/dist/canvas/code-sync/tsx-adapter.d.ts.map +1 -0
  65. package/dist/canvas/code-sync/types.d.ts +152 -0
  66. package/dist/canvas/code-sync/types.d.ts.map +1 -0
  67. package/dist/canvas/code-sync/write.d.ts +9 -0
  68. package/dist/canvas/code-sync/write.d.ts.map +1 -0
  69. package/dist/canvas/document-store.d.ts +81 -0
  70. package/dist/canvas/document-store.d.ts.map +1 -0
  71. package/dist/canvas/export.d.ts +12 -0
  72. package/dist/canvas/export.d.ts.map +1 -0
  73. package/dist/canvas/repo-store.d.ts +10 -0
  74. package/dist/canvas/repo-store.d.ts.map +1 -0
  75. package/dist/canvas/surface-palette.d.ts +15 -0
  76. package/dist/canvas/surface-palette.d.ts.map +1 -0
  77. package/dist/canvas/types.d.ts +255 -0
  78. package/dist/canvas/types.d.ts.map +1 -0
  79. package/dist/canvas-runtime-preview-bridge-HBEHXM4T.js +7 -0
  80. package/dist/canvas-runtime-preview-bridge-HBEHXM4T.js.map +1 -0
  81. package/dist/chunk-5J3IFL3X.js +16706 -0
  82. package/dist/chunk-5J3IFL3X.js.map +1 -0
  83. package/dist/chunk-D633UO34.js +8149 -0
  84. package/dist/chunk-D633UO34.js.map +1 -0
  85. package/dist/chunk-FUSXMW3G.js +169 -0
  86. package/dist/chunk-FUSXMW3G.js.map +1 -0
  87. package/dist/chunk-TBUCZX4A.js +34 -0
  88. package/dist/chunk-TBUCZX4A.js.map +1 -0
  89. package/dist/chunk-V7KUDHDG.js +276 -0
  90. package/dist/chunk-V7KUDHDG.js.map +1 -0
  91. package/dist/chunk-Y2KL55OG.js +59 -0
  92. package/dist/chunk-Y2KL55OG.js.map +1 -0
  93. package/dist/cli/args.d.ts +25 -0
  94. package/dist/cli/args.d.ts.map +1 -0
  95. package/dist/cli/client.d.ts +2 -0
  96. package/dist/cli/client.d.ts.map +1 -0
  97. package/dist/cli/commands/annotate.d.ts +38 -0
  98. package/dist/cli/commands/annotate.d.ts.map +1 -0
  99. package/dist/cli/commands/artifacts.d.ts +24 -0
  100. package/dist/cli/commands/artifacts.d.ts.map +1 -0
  101. package/dist/cli/commands/canvas.d.ts +45 -0
  102. package/dist/cli/commands/canvas.d.ts.map +1 -0
  103. package/dist/cli/commands/daemon.d.ts +35 -0
  104. package/dist/cli/commands/daemon.d.ts.map +1 -0
  105. package/dist/cli/commands/devtools/console-poll.d.ts +7 -0
  106. package/dist/cli/commands/devtools/console-poll.d.ts.map +1 -0
  107. package/dist/cli/commands/devtools/debug-trace-snapshot.d.ts +20 -0
  108. package/dist/cli/commands/devtools/debug-trace-snapshot.d.ts.map +1 -0
  109. package/dist/cli/commands/devtools/network-poll.d.ts +7 -0
  110. package/dist/cli/commands/devtools/network-poll.d.ts.map +1 -0
  111. package/dist/cli/commands/devtools/perf.d.ts +7 -0
  112. package/dist/cli/commands/devtools/perf.d.ts.map +1 -0
  113. package/dist/cli/commands/devtools/screenshot.d.ts +18 -0
  114. package/dist/cli/commands/devtools/screenshot.d.ts.map +1 -0
  115. package/dist/cli/commands/dom/attr.d.ts +7 -0
  116. package/dist/cli/commands/dom/attr.d.ts.map +1 -0
  117. package/dist/cli/commands/dom/checked.d.ts +7 -0
  118. package/dist/cli/commands/dom/checked.d.ts.map +1 -0
  119. package/dist/cli/commands/dom/enabled.d.ts +7 -0
  120. package/dist/cli/commands/dom/enabled.d.ts.map +1 -0
  121. package/dist/cli/commands/dom/html.d.ts +7 -0
  122. package/dist/cli/commands/dom/html.d.ts.map +1 -0
  123. package/dist/cli/commands/dom/text.d.ts +7 -0
  124. package/dist/cli/commands/dom/text.d.ts.map +1 -0
  125. package/dist/cli/commands/dom/value.d.ts +7 -0
  126. package/dist/cli/commands/dom/value.d.ts.map +1 -0
  127. package/dist/cli/commands/dom/visible.d.ts +7 -0
  128. package/dist/cli/commands/dom/visible.d.ts.map +1 -0
  129. package/dist/cli/commands/export/clone-component.d.ts +16 -0
  130. package/dist/cli/commands/export/clone-component.d.ts.map +1 -0
  131. package/dist/cli/commands/export/clone-page.d.ts +15 -0
  132. package/dist/cli/commands/export/clone-page.d.ts.map +1 -0
  133. package/dist/cli/commands/interact/check.d.ts +7 -0
  134. package/dist/cli/commands/interact/check.d.ts.map +1 -0
  135. package/dist/cli/commands/interact/click.d.ts +7 -0
  136. package/dist/cli/commands/interact/click.d.ts.map +1 -0
  137. package/dist/cli/commands/interact/hover.d.ts +7 -0
  138. package/dist/cli/commands/interact/hover.d.ts.map +1 -0
  139. package/dist/cli/commands/interact/press.d.ts +7 -0
  140. package/dist/cli/commands/interact/press.d.ts.map +1 -0
  141. package/dist/cli/commands/interact/scroll-into-view.d.ts +7 -0
  142. package/dist/cli/commands/interact/scroll-into-view.d.ts.map +1 -0
  143. package/dist/cli/commands/interact/scroll.d.ts +7 -0
  144. package/dist/cli/commands/interact/scroll.d.ts.map +1 -0
  145. package/dist/cli/commands/interact/select.d.ts +7 -0
  146. package/dist/cli/commands/interact/select.d.ts.map +1 -0
  147. package/dist/cli/commands/interact/type.d.ts +7 -0
  148. package/dist/cli/commands/interact/type.d.ts.map +1 -0
  149. package/dist/cli/commands/interact/uncheck.d.ts +7 -0
  150. package/dist/cli/commands/interact/uncheck.d.ts.map +1 -0
  151. package/dist/cli/commands/macro-resolve.d.ts +18 -0
  152. package/dist/cli/commands/macro-resolve.d.ts.map +1 -0
  153. package/dist/cli/commands/native.d.ts +93 -0
  154. package/dist/cli/commands/native.d.ts.map +1 -0
  155. package/dist/cli/commands/nav/goto.d.ts +7 -0
  156. package/dist/cli/commands/nav/goto.d.ts.map +1 -0
  157. package/dist/cli/commands/nav/snapshot.d.ts +7 -0
  158. package/dist/cli/commands/nav/snapshot.d.ts.map +1 -0
  159. package/dist/cli/commands/nav/wait.d.ts +7 -0
  160. package/dist/cli/commands/nav/wait.d.ts.map +1 -0
  161. package/dist/cli/commands/pages/close.d.ts +6 -0
  162. package/dist/cli/commands/pages/close.d.ts.map +1 -0
  163. package/dist/cli/commands/pages/list.d.ts +7 -0
  164. package/dist/cli/commands/pages/list.d.ts.map +1 -0
  165. package/dist/cli/commands/pages/open.d.ts +7 -0
  166. package/dist/cli/commands/pages/open.d.ts.map +1 -0
  167. package/dist/cli/commands/product-video.d.ts +25 -0
  168. package/dist/cli/commands/product-video.d.ts.map +1 -0
  169. package/dist/cli/commands/registry.d.ts +5 -0
  170. package/dist/cli/commands/registry.d.ts.map +1 -0
  171. package/dist/cli/commands/research.d.ts +27 -0
  172. package/dist/cli/commands/research.d.ts.map +1 -0
  173. package/dist/cli/commands/rpc.d.ts +28 -0
  174. package/dist/cli/commands/rpc.d.ts.map +1 -0
  175. package/dist/cli/commands/run.d.ts +17 -0
  176. package/dist/cli/commands/run.d.ts.map +1 -0
  177. package/dist/cli/commands/serve.d.ts +64 -0
  178. package/dist/cli/commands/serve.d.ts.map +1 -0
  179. package/dist/cli/commands/session/connect.d.ts +9 -0
  180. package/dist/cli/commands/session/connect.d.ts.map +1 -0
  181. package/dist/cli/commands/session/cookie-import.d.ts +31 -0
  182. package/dist/cli/commands/session/cookie-import.d.ts.map +1 -0
  183. package/dist/cli/commands/session/cookie-list.d.ts +17 -0
  184. package/dist/cli/commands/session/cookie-list.d.ts.map +1 -0
  185. package/dist/cli/commands/session/disconnect.d.ts +6 -0
  186. package/dist/cli/commands/session/disconnect.d.ts.map +1 -0
  187. package/dist/cli/commands/session/launch.d.ts +29 -0
  188. package/dist/cli/commands/session/launch.d.ts.map +1 -0
  189. package/dist/cli/commands/session/status.d.ts +7 -0
  190. package/dist/cli/commands/session/status.d.ts.map +1 -0
  191. package/dist/cli/commands/shopping.d.ts +25 -0
  192. package/dist/cli/commands/shopping.d.ts.map +1 -0
  193. package/dist/cli/commands/status.d.ts +24 -0
  194. package/dist/cli/commands/status.d.ts.map +1 -0
  195. package/dist/cli/commands/targets/close.d.ts +6 -0
  196. package/dist/cli/commands/targets/close.d.ts.map +1 -0
  197. package/dist/cli/commands/targets/list.d.ts +7 -0
  198. package/dist/cli/commands/targets/list.d.ts.map +1 -0
  199. package/dist/cli/commands/targets/new.d.ts +7 -0
  200. package/dist/cli/commands/targets/new.d.ts.map +1 -0
  201. package/dist/cli/commands/targets/use.d.ts +7 -0
  202. package/dist/cli/commands/targets/use.d.ts.map +1 -0
  203. package/dist/cli/commands/types.d.ts +13 -0
  204. package/dist/cli/commands/types.d.ts.map +1 -0
  205. package/dist/cli/commands/uninstall.d.ts +14 -0
  206. package/dist/cli/commands/uninstall.d.ts.map +1 -0
  207. package/dist/cli/commands/update.d.ts +7 -0
  208. package/dist/cli/commands/update.d.ts.map +1 -0
  209. package/dist/cli/daemon-autostart.d.ts +46 -0
  210. package/dist/cli/daemon-autostart.d.ts.map +1 -0
  211. package/dist/cli/daemon-client.d.ts +33 -0
  212. package/dist/cli/daemon-client.d.ts.map +1 -0
  213. package/dist/cli/daemon-commands.d.ts +7 -0
  214. package/dist/cli/daemon-commands.d.ts.map +1 -0
  215. package/dist/cli/daemon-state.d.ts +56 -0
  216. package/dist/cli/daemon-state.d.ts.map +1 -0
  217. package/dist/cli/daemon-status.d.ts +19 -0
  218. package/dist/cli/daemon-status.d.ts.map +1 -0
  219. package/dist/cli/daemon.d.ts +29 -0
  220. package/dist/cli/daemon.d.ts.map +1 -0
  221. package/dist/cli/errors.d.ts +20 -0
  222. package/dist/cli/errors.d.ts.map +1 -0
  223. package/dist/cli/help.d.ts +33 -0
  224. package/dist/cli/help.d.ts.map +1 -0
  225. package/dist/cli/index.d.ts +2 -0
  226. package/dist/cli/index.d.ts.map +1 -0
  227. package/dist/cli/index.js +2825 -326
  228. package/dist/cli/index.js.map +1 -1
  229. package/dist/cli/installers/global.d.ts +9 -0
  230. package/dist/cli/installers/global.d.ts.map +1 -0
  231. package/dist/cli/installers/local.d.ts +9 -0
  232. package/dist/cli/installers/local.d.ts.map +1 -0
  233. package/dist/cli/installers/skills.d.ts +19 -0
  234. package/dist/cli/installers/skills.d.ts.map +1 -0
  235. package/dist/cli/output.d.ts +7 -0
  236. package/dist/cli/output.d.ts.map +1 -0
  237. package/dist/cli/remote-canvas-manager.d.ts +8 -0
  238. package/dist/cli/remote-canvas-manager.d.ts.map +1 -0
  239. package/dist/cli/remote-manager.d.ts +98 -0
  240. package/dist/cli/remote-manager.d.ts.map +1 -0
  241. package/dist/cli/remote-relay.d.ts +19 -0
  242. package/dist/cli/remote-relay.d.ts.map +1 -0
  243. package/dist/cli/templates/config.d.ts +7 -0
  244. package/dist/cli/templates/config.d.ts.map +1 -0
  245. package/dist/cli/utils/config.d.ts +20 -0
  246. package/dist/cli/utils/config.d.ts.map +1 -0
  247. package/dist/cli/utils/http.d.ts +5 -0
  248. package/dist/cli/utils/http.d.ts.map +1 -0
  249. package/dist/cli/utils/parse.d.ts +9 -0
  250. package/dist/cli/utils/parse.d.ts.map +1 -0
  251. package/dist/cli/utils/skills.d.ts +12 -0
  252. package/dist/cli/utils/skills.d.ts.map +1 -0
  253. package/dist/config.d.ts +208 -0
  254. package/dist/config.d.ts.map +1 -0
  255. package/dist/core/bootstrap.d.ts +3 -0
  256. package/dist/core/bootstrap.d.ts.map +1 -0
  257. package/dist/core/index.d.ts +3 -0
  258. package/dist/core/index.d.ts.map +1 -0
  259. package/dist/core/logging.d.ts +34 -0
  260. package/dist/core/logging.d.ts.map +1 -0
  261. package/dist/core/types.d.ts +36 -0
  262. package/dist/core/types.d.ts.map +1 -0
  263. package/dist/devtools/console-tracker.d.ts +44 -0
  264. package/dist/devtools/console-tracker.d.ts.map +1 -0
  265. package/dist/devtools/exception-tracker.d.ts +42 -0
  266. package/dist/devtools/exception-tracker.d.ts.map +1 -0
  267. package/dist/devtools/network-tracker.d.ts +34 -0
  268. package/dist/devtools/network-tracker.d.ts.map +1 -0
  269. package/dist/export/css-extract.d.ts +5 -0
  270. package/dist/export/css-extract.d.ts.map +1 -0
  271. package/dist/export/dom-capture.d.ts +15 -0
  272. package/dist/export/dom-capture.d.ts.map +1 -0
  273. package/dist/export/react-emitter.d.ts +11 -0
  274. package/dist/export/react-emitter.d.ts.map +1 -0
  275. package/dist/extension-extractor.d.ts +3 -0
  276. package/dist/extension-extractor.d.ts.map +1 -0
  277. package/dist/fs-UMRKOBNN.js +7 -0
  278. package/dist/fs-UMRKOBNN.js.map +1 -0
  279. package/dist/index.d.ts +3 -4
  280. package/dist/index.d.ts.map +1 -0
  281. package/dist/index.js +1028 -123
  282. package/dist/index.js.map +1 -1
  283. package/dist/macros/execute.d.ts +44 -0
  284. package/dist/macros/execute.d.ts.map +1 -0
  285. package/dist/macros/index.d.ts +9 -0
  286. package/dist/macros/index.d.ts.map +1 -0
  287. package/dist/macros/packs/core.d.ts +3 -0
  288. package/dist/macros/packs/core.d.ts.map +1 -0
  289. package/dist/macros/registry.d.ts +48 -0
  290. package/dist/macros/registry.d.ts.map +1 -0
  291. package/dist/macros-ND2M7LWU.js +399 -0
  292. package/dist/macros-ND2M7LWU.js.map +1 -0
  293. package/dist/opendevbrowser.d.ts +3 -4
  294. package/dist/opendevbrowser.d.ts.map +1 -0
  295. package/dist/opendevbrowser.js +1028 -123
  296. package/dist/opendevbrowser.js.map +1 -1
  297. package/dist/providers/adaptive-concurrency.d.ts +42 -0
  298. package/dist/providers/adaptive-concurrency.d.ts.map +1 -0
  299. package/dist/providers/artifacts.d.ts +34 -0
  300. package/dist/providers/artifacts.d.ts.map +1 -0
  301. package/dist/providers/blocker.d.ts +47 -0
  302. package/dist/providers/blocker.d.ts.map +1 -0
  303. package/dist/providers/community/index.d.ts +44 -0
  304. package/dist/providers/community/index.d.ts.map +1 -0
  305. package/dist/providers/enrichment.d.ts +33 -0
  306. package/dist/providers/enrichment.d.ts.map +1 -0
  307. package/dist/providers/errors.d.ts +41 -0
  308. package/dist/providers/errors.d.ts.map +1 -0
  309. package/dist/providers/index.d.ts +121 -0
  310. package/dist/providers/index.d.ts.map +1 -0
  311. package/dist/providers/normalize.d.ts +39 -0
  312. package/dist/providers/normalize.d.ts.map +1 -0
  313. package/dist/providers/policy.d.ts +5 -0
  314. package/dist/providers/policy.d.ts.map +1 -0
  315. package/dist/providers/registry.d.ts +22 -0
  316. package/dist/providers/registry.d.ts.map +1 -0
  317. package/dist/providers/renderer.d.ts +49 -0
  318. package/dist/providers/renderer.d.ts.map +1 -0
  319. package/dist/providers/runtime-factory.d.ts +20 -0
  320. package/dist/providers/runtime-factory.d.ts.map +1 -0
  321. package/dist/providers/safety/prompt-guard.d.ts +34 -0
  322. package/dist/providers/safety/prompt-guard.d.ts.map +1 -0
  323. package/dist/providers/shared/anti-bot-policy.d.ts +51 -0
  324. package/dist/providers/shared/anti-bot-policy.d.ts.map +1 -0
  325. package/dist/providers/shared/post-policy.d.ts +31 -0
  326. package/dist/providers/shared/post-policy.d.ts.map +1 -0
  327. package/dist/providers/shared/request-headers.d.ts +5 -0
  328. package/dist/providers/shared/request-headers.d.ts.map +1 -0
  329. package/dist/providers/shared/traversal-url.d.ts +2 -0
  330. package/dist/providers/shared/traversal-url.d.ts.map +1 -0
  331. package/dist/providers/shopping/index.d.ts +63 -0
  332. package/dist/providers/shopping/index.d.ts.map +1 -0
  333. package/dist/providers/social/bluesky.d.ts +3 -0
  334. package/dist/providers/social/bluesky.d.ts.map +1 -0
  335. package/dist/providers/social/facebook.d.ts +3 -0
  336. package/dist/providers/social/facebook.d.ts.map +1 -0
  337. package/dist/providers/social/index.d.ts +31 -0
  338. package/dist/providers/social/index.d.ts.map +1 -0
  339. package/dist/providers/social/instagram.d.ts +3 -0
  340. package/dist/providers/social/instagram.d.ts.map +1 -0
  341. package/dist/providers/social/linkedin.d.ts +3 -0
  342. package/dist/providers/social/linkedin.d.ts.map +1 -0
  343. package/dist/providers/social/platform.d.ts +40 -0
  344. package/dist/providers/social/platform.d.ts.map +1 -0
  345. package/dist/providers/social/reddit.d.ts +3 -0
  346. package/dist/providers/social/reddit.d.ts.map +1 -0
  347. package/dist/providers/social/threads.d.ts +3 -0
  348. package/dist/providers/social/threads.d.ts.map +1 -0
  349. package/dist/providers/social/tiktok.d.ts +3 -0
  350. package/dist/providers/social/tiktok.d.ts.map +1 -0
  351. package/dist/providers/social/x.d.ts +3 -0
  352. package/dist/providers/social/x.d.ts.map +1 -0
  353. package/dist/providers/social/youtube-resolver.d.ts +78 -0
  354. package/dist/providers/social/youtube-resolver.d.ts.map +1 -0
  355. package/dist/providers/social/youtube.d.ts +34 -0
  356. package/dist/providers/social/youtube.d.ts.map +1 -0
  357. package/dist/providers/tier-router.d.ts +30 -0
  358. package/dist/providers/tier-router.d.ts.map +1 -0
  359. package/dist/providers/timebox.d.ts +20 -0
  360. package/dist/providers/timebox.d.ts.map +1 -0
  361. package/dist/providers/types.d.ts +344 -0
  362. package/dist/providers/types.d.ts.map +1 -0
  363. package/dist/providers/web/crawl-worker.d.ts +36 -0
  364. package/dist/providers/web/crawl-worker.d.ts.map +1 -0
  365. package/dist/providers/web/crawler.d.ts +101 -0
  366. package/dist/providers/web/crawler.d.ts.map +1 -0
  367. package/dist/providers/web/extract.d.ts +11 -0
  368. package/dist/providers/web/extract.d.ts.map +1 -0
  369. package/dist/providers/web/index.d.ts +24 -0
  370. package/dist/providers/web/index.d.ts.map +1 -0
  371. package/dist/providers/web/policy.d.ts +14 -0
  372. package/dist/providers/web/policy.d.ts.map +1 -0
  373. package/dist/providers/workflows.d.ts +67 -0
  374. package/dist/providers/workflows.d.ts.map +1 -0
  375. package/dist/providers-G3LRHQXX.js +121 -0
  376. package/dist/providers-G3LRHQXX.js.map +1 -0
  377. package/dist/relay/protocol.d.ts +399 -0
  378. package/dist/relay/protocol.d.ts.map +1 -0
  379. package/dist/relay/relay-endpoints.d.ts +16 -0
  380. package/dist/relay/relay-endpoints.d.ts.map +1 -0
  381. package/dist/relay/relay-server.d.ts +124 -0
  382. package/dist/relay/relay-server.d.ts.map +1 -0
  383. package/dist/relay/relay-types.d.ts +12 -0
  384. package/dist/relay/relay-types.d.ts.map +1 -0
  385. package/dist/runtime-factory-BICHDPE7.js +13 -0
  386. package/dist/runtime-factory-BICHDPE7.js.map +1 -0
  387. package/dist/skills/continuity-nudge.d.ts +12 -0
  388. package/dist/skills/continuity-nudge.d.ts.map +1 -0
  389. package/dist/skills/skill-loader.d.ts +20 -0
  390. package/dist/skills/skill-loader.d.ts.map +1 -0
  391. package/dist/skills/skill-nudge.d.ts +18 -0
  392. package/dist/skills/skill-nudge.d.ts.map +1 -0
  393. package/dist/skills/types.d.ts +12 -0
  394. package/dist/skills/types.d.ts.map +1 -0
  395. package/dist/snapshot/ops-snapshot.d.ts +16 -0
  396. package/dist/snapshot/ops-snapshot.d.ts.map +1 -0
  397. package/dist/snapshot/refs.d.ts +23 -0
  398. package/dist/snapshot/refs.d.ts.map +1 -0
  399. package/dist/snapshot/snapshotter.d.ts +27 -0
  400. package/dist/snapshot/snapshotter.d.ts.map +1 -0
  401. package/dist/tools/annotate.d.ts +4 -0
  402. package/dist/tools/annotate.d.ts.map +1 -0
  403. package/dist/tools/canvas.d.ts +4 -0
  404. package/dist/tools/canvas.d.ts.map +1 -0
  405. package/dist/tools/check.d.ts +4 -0
  406. package/dist/tools/check.d.ts.map +1 -0
  407. package/dist/tools/click.d.ts +4 -0
  408. package/dist/tools/click.d.ts.map +1 -0
  409. package/dist/tools/clone_component.d.ts +4 -0
  410. package/dist/tools/clone_component.d.ts.map +1 -0
  411. package/dist/tools/clone_page.d.ts +4 -0
  412. package/dist/tools/clone_page.d.ts.map +1 -0
  413. package/dist/tools/close.d.ts +4 -0
  414. package/dist/tools/close.d.ts.map +1 -0
  415. package/dist/tools/connect.d.ts +4 -0
  416. package/dist/tools/connect.d.ts.map +1 -0
  417. package/dist/tools/console_poll.d.ts +4 -0
  418. package/dist/tools/console_poll.d.ts.map +1 -0
  419. package/dist/tools/cookie_import.d.ts +25 -0
  420. package/dist/tools/cookie_import.d.ts.map +1 -0
  421. package/dist/tools/cookie_list.d.ts +9 -0
  422. package/dist/tools/cookie_list.d.ts.map +1 -0
  423. package/dist/tools/debug_trace_snapshot.d.ts +4 -0
  424. package/dist/tools/debug_trace_snapshot.d.ts.map +1 -0
  425. package/dist/tools/deps.d.ts +28 -0
  426. package/dist/tools/deps.d.ts.map +1 -0
  427. package/dist/tools/disconnect.d.ts +4 -0
  428. package/dist/tools/disconnect.d.ts.map +1 -0
  429. package/dist/tools/dom_get_html.d.ts +4 -0
  430. package/dist/tools/dom_get_html.d.ts.map +1 -0
  431. package/dist/tools/dom_get_text.d.ts +4 -0
  432. package/dist/tools/dom_get_text.d.ts.map +1 -0
  433. package/dist/tools/get_attr.d.ts +4 -0
  434. package/dist/tools/get_attr.d.ts.map +1 -0
  435. package/dist/tools/get_value.d.ts +4 -0
  436. package/dist/tools/get_value.d.ts.map +1 -0
  437. package/dist/tools/goto.d.ts +4 -0
  438. package/dist/tools/goto.d.ts.map +1 -0
  439. package/dist/tools/hover.d.ts +4 -0
  440. package/dist/tools/hover.d.ts.map +1 -0
  441. package/dist/tools/index.d.ts +4 -0
  442. package/dist/tools/index.d.ts.map +1 -0
  443. package/dist/tools/is_checked.d.ts +4 -0
  444. package/dist/tools/is_checked.d.ts.map +1 -0
  445. package/dist/tools/is_enabled.d.ts +4 -0
  446. package/dist/tools/is_enabled.d.ts.map +1 -0
  447. package/dist/tools/is_visible.d.ts +4 -0
  448. package/dist/tools/is_visible.d.ts.map +1 -0
  449. package/dist/tools/launch.d.ts +4 -0
  450. package/dist/tools/launch.d.ts.map +1 -0
  451. package/dist/tools/list.d.ts +4 -0
  452. package/dist/tools/list.d.ts.map +1 -0
  453. package/dist/tools/macro_resolve.d.ts +25 -0
  454. package/dist/tools/macro_resolve.d.ts.map +1 -0
  455. package/dist/tools/network_poll.d.ts +4 -0
  456. package/dist/tools/network_poll.d.ts.map +1 -0
  457. package/dist/tools/page.d.ts +4 -0
  458. package/dist/tools/page.d.ts.map +1 -0
  459. package/dist/tools/perf.d.ts +4 -0
  460. package/dist/tools/perf.d.ts.map +1 -0
  461. package/dist/tools/press.d.ts +4 -0
  462. package/dist/tools/press.d.ts.map +1 -0
  463. package/dist/tools/product_video_run.d.ts +4 -0
  464. package/dist/tools/product_video_run.d.ts.map +1 -0
  465. package/dist/tools/prompting_guide.d.ts +4 -0
  466. package/dist/tools/prompting_guide.d.ts.map +1 -0
  467. package/dist/tools/research_run.d.ts +4 -0
  468. package/dist/tools/research_run.d.ts.map +1 -0
  469. package/dist/tools/response.d.ts +19 -0
  470. package/dist/tools/response.d.ts.map +1 -0
  471. package/dist/tools/run.d.ts +4 -0
  472. package/dist/tools/run.d.ts.map +1 -0
  473. package/dist/tools/screenshot.d.ts +4 -0
  474. package/dist/tools/screenshot.d.ts.map +1 -0
  475. package/dist/tools/scroll.d.ts +4 -0
  476. package/dist/tools/scroll.d.ts.map +1 -0
  477. package/dist/tools/scroll_into_view.d.ts +4 -0
  478. package/dist/tools/scroll_into_view.d.ts.map +1 -0
  479. package/dist/tools/select.d.ts +4 -0
  480. package/dist/tools/select.d.ts.map +1 -0
  481. package/dist/tools/shopping_run.d.ts +4 -0
  482. package/dist/tools/shopping_run.d.ts.map +1 -0
  483. package/dist/tools/skill_list.d.ts +4 -0
  484. package/dist/tools/skill_list.d.ts.map +1 -0
  485. package/dist/tools/skill_load.d.ts +4 -0
  486. package/dist/tools/skill_load.d.ts.map +1 -0
  487. package/dist/tools/snapshot.d.ts +4 -0
  488. package/dist/tools/snapshot.d.ts.map +1 -0
  489. package/dist/tools/status.d.ts +4 -0
  490. package/dist/tools/status.d.ts.map +1 -0
  491. package/dist/tools/target_close.d.ts +4 -0
  492. package/dist/tools/target_close.d.ts.map +1 -0
  493. package/dist/tools/target_new.d.ts +4 -0
  494. package/dist/tools/target_new.d.ts.map +1 -0
  495. package/dist/tools/target_use.d.ts +4 -0
  496. package/dist/tools/target_use.d.ts.map +1 -0
  497. package/dist/tools/targets_list.d.ts +4 -0
  498. package/dist/tools/targets_list.d.ts.map +1 -0
  499. package/dist/tools/type.d.ts +4 -0
  500. package/dist/tools/type.d.ts.map +1 -0
  501. package/dist/tools/uncheck.d.ts +4 -0
  502. package/dist/tools/uncheck.d.ts.map +1 -0
  503. package/dist/tools/wait.d.ts +4 -0
  504. package/dist/tools/wait.d.ts.map +1 -0
  505. package/dist/tools/workflow-runtime.d.ts +3 -0
  506. package/dist/tools/workflow-runtime.d.ts.map +1 -0
  507. package/dist/utils/crypto.d.ts +2 -0
  508. package/dist/utils/crypto.d.ts.map +1 -0
  509. package/dist/utils/endpoint-validation.d.ts +2 -0
  510. package/dist/utils/endpoint-validation.d.ts.map +1 -0
  511. package/dist/utils/fs.d.ts +5 -0
  512. package/dist/utils/fs.d.ts.map +1 -0
  513. package/dist/utils/hub-enabled.d.ts +3 -0
  514. package/dist/utils/hub-enabled.d.ts.map +1 -0
  515. package/extension/canvas.html +636 -0
  516. package/extension/dist/annotate-content.css +15 -6
  517. package/extension/dist/annotate-content.js +119 -9
  518. package/extension/dist/annotation-payload.js +163 -0
  519. package/extension/dist/background.js +158 -22
  520. package/extension/dist/canvas/canvas-runtime.js +1061 -0
  521. package/extension/dist/canvas/model.js +213 -0
  522. package/extension/dist/canvas/viewport-fit.js +67 -0
  523. package/extension/dist/canvas-page.js +1801 -0
  524. package/extension/dist/ops/dom-bridge.js +116 -3
  525. package/extension/dist/ops/ops-runtime.js +1014 -48
  526. package/extension/dist/ops/ops-session-store.js +37 -116
  527. package/extension/dist/ops/parallelism-governor.js +117 -0
  528. package/extension/dist/ops/snapshot-shared.js +21 -5
  529. package/extension/dist/ops/target-session-coordinator.js +157 -0
  530. package/extension/dist/popup.js +155 -31
  531. package/extension/dist/services/CDPRouter.js +70 -5
  532. package/extension/dist/services/ConnectionManager.js +22 -3
  533. package/extension/dist/services/RelayClient.js +9 -0
  534. package/extension/dist/services/TabManager.js +35 -12
  535. package/extension/dist/types.js +2 -0
  536. package/extension/icons/icon128.png +0 -0
  537. package/extension/icons/icon16.png +0 -0
  538. package/extension/icons/icon32.png +0 -0
  539. package/extension/icons/icon48.png +0 -0
  540. package/extension/manifest.json +1 -1
  541. package/extension/popup.html +52 -0
  542. package/package.json +30 -19
  543. package/scripts/native/host.cjs +230 -0
  544. package/scripts/native/install.ps1 +73 -0
  545. package/scripts/native/install.sh +66 -0
  546. package/scripts/native/uninstall.ps1 +25 -0
  547. package/scripts/native/uninstall.sh +26 -0
  548. package/skills/AGENTS.md +20 -8
  549. package/skills/opendevbrowser-best-practices/SKILL.md +248 -74
  550. package/skills/opendevbrowser-best-practices/artifacts/browser-agent-known-issues-matrix.md +44 -0
  551. package/skills/opendevbrowser-best-practices/artifacts/canvas-governance-playbook.md +141 -0
  552. package/skills/opendevbrowser-best-practices/artifacts/command-channel-reference.md +191 -0
  553. package/skills/opendevbrowser-best-practices/artifacts/debug-trace-playbook.md +36 -0
  554. package/skills/opendevbrowser-best-practices/artifacts/fingerprint-tiers.md +36 -0
  555. package/skills/opendevbrowser-best-practices/artifacts/macro-workflows.md +43 -0
  556. package/skills/opendevbrowser-best-practices/artifacts/parity-gates.md +36 -0
  557. package/skills/opendevbrowser-best-practices/artifacts/provider-workflows.md +89 -0
  558. package/skills/opendevbrowser-best-practices/assets/templates/canvas-blocker-checklist.json +70 -0
  559. package/skills/opendevbrowser-best-practices/assets/templates/canvas-feedback-eval.json +73 -0
  560. package/skills/opendevbrowser-best-practices/assets/templates/canvas-generation-plan.v1.json +67 -0
  561. package/skills/opendevbrowser-best-practices/assets/templates/canvas-handshake-example.json +126 -0
  562. package/skills/opendevbrowser-best-practices/assets/templates/cdp-forward-envelope.json +11 -0
  563. package/skills/opendevbrowser-best-practices/assets/templates/mode-flag-matrix.json +56 -0
  564. package/skills/opendevbrowser-best-practices/assets/templates/ops-request-envelope.json +9 -0
  565. package/skills/opendevbrowser-best-practices/assets/templates/robustness-checklist.json +136 -0
  566. package/skills/opendevbrowser-best-practices/assets/templates/surface-audit-checklist.json +28 -0
  567. package/skills/opendevbrowser-best-practices/scripts/odb-workflow.sh +170 -0
  568. package/skills/opendevbrowser-best-practices/scripts/run-robustness-audit.sh +164 -0
  569. package/skills/opendevbrowser-best-practices/scripts/validate-skill-assets.sh +234 -0
  570. package/skills/opendevbrowser-continuity-ledger/SKILL.md +10 -0
  571. package/skills/opendevbrowser-data-extraction/SKILL.md +126 -0
  572. package/skills/opendevbrowser-data-extraction/artifacts/extraction-workflows.md +31 -0
  573. package/skills/opendevbrowser-data-extraction/assets/templates/compliance-checklist.md +7 -0
  574. package/skills/opendevbrowser-data-extraction/assets/templates/extraction-schema.json +17 -0
  575. package/skills/opendevbrowser-data-extraction/assets/templates/pagination-state.json +11 -0
  576. package/skills/opendevbrowser-data-extraction/assets/templates/quality-gates.json +10 -0
  577. package/skills/opendevbrowser-data-extraction/examples/sample-schema.json +19 -0
  578. package/skills/opendevbrowser-data-extraction/scripts/run-extraction-workflow.sh +83 -0
  579. package/skills/opendevbrowser-data-extraction/scripts/validate-skill-assets.sh +49 -0
  580. package/skills/opendevbrowser-form-testing/SKILL.md +143 -0
  581. package/skills/opendevbrowser-form-testing/artifacts/form-workflows.md +37 -0
  582. package/skills/opendevbrowser-form-testing/assets/templates/a11y-assertions.md +7 -0
  583. package/skills/opendevbrowser-form-testing/assets/templates/challenge-decision-tree.json +16 -0
  584. package/skills/opendevbrowser-form-testing/assets/templates/multi-step-state.json +11 -0
  585. package/skills/opendevbrowser-form-testing/assets/templates/validation-matrix.json +24 -0
  586. package/skills/opendevbrowser-form-testing/examples/sample-validation-matrix.json +29 -0
  587. package/skills/opendevbrowser-form-testing/scripts/run-form-workflow.sh +82 -0
  588. package/skills/opendevbrowser-form-testing/scripts/validate-skill-assets.sh +49 -0
  589. package/skills/opendevbrowser-login-automation/SKILL.md +159 -0
  590. package/skills/opendevbrowser-login-automation/artifacts/login-workflows.md +39 -0
  591. package/skills/opendevbrowser-login-automation/assets/templates/auth-signals.json +21 -0
  592. package/skills/opendevbrowser-login-automation/assets/templates/challenge-checkpoint.md +10 -0
  593. package/skills/opendevbrowser-login-automation/assets/templates/login-scenario-matrix.json +26 -0
  594. package/skills/opendevbrowser-login-automation/examples/sample-auth-signals.json +14 -0
  595. package/skills/opendevbrowser-login-automation/scripts/record-auth-signals.sh +18 -0
  596. package/skills/opendevbrowser-login-automation/scripts/run-login-workflow.sh +99 -0
  597. package/skills/opendevbrowser-login-automation/scripts/validate-skill-assets.sh +50 -0
  598. package/skills/opendevbrowser-product-presentation-asset/SKILL.md +98 -0
  599. package/skills/opendevbrowser-product-presentation-asset/artifacts/asset-pack-assembly.md +23 -0
  600. package/skills/opendevbrowser-product-presentation-asset/artifacts/ugc-creative-guide.md +21 -0
  601. package/skills/opendevbrowser-product-presentation-asset/assets/templates/claims-evidence-map.md +5 -0
  602. package/skills/opendevbrowser-product-presentation-asset/assets/templates/copy.md +5 -0
  603. package/skills/opendevbrowser-product-presentation-asset/assets/templates/features.md +4 -0
  604. package/skills/opendevbrowser-product-presentation-asset/assets/templates/manifest.schema.json +14 -0
  605. package/skills/opendevbrowser-product-presentation-asset/assets/templates/shot-list.md +7 -0
  606. package/skills/opendevbrowser-product-presentation-asset/assets/templates/ugc-concepts.md +17 -0
  607. package/skills/opendevbrowser-product-presentation-asset/assets/templates/user-actions.md +7 -0
  608. package/skills/opendevbrowser-product-presentation-asset/assets/templates/video-assembly.md +18 -0
  609. package/skills/opendevbrowser-product-presentation-asset/examples/sample-input.json +6 -0
  610. package/skills/opendevbrowser-product-presentation-asset/examples/sample-manifest.json +18 -0
  611. package/skills/opendevbrowser-product-presentation-asset/scripts/capture-screenshots.sh +9 -0
  612. package/skills/opendevbrowser-product-presentation-asset/scripts/collect-product.sh +14 -0
  613. package/skills/opendevbrowser-product-presentation-asset/scripts/download-images.sh +9 -0
  614. package/skills/opendevbrowser-product-presentation-asset/scripts/render-video-brief.sh +96 -0
  615. package/skills/opendevbrowser-product-presentation-asset/scripts/validate-skill-assets.sh +56 -0
  616. package/skills/opendevbrowser-product-presentation-asset/scripts/write-manifest.sh +43 -0
  617. package/skills/opendevbrowser-research/SKILL.md +73 -0
  618. package/skills/opendevbrowser-research/artifacts/research-workflows.md +29 -0
  619. package/skills/opendevbrowser-research/assets/templates/compact.md +7 -0
  620. package/skills/opendevbrowser-research/assets/templates/context.json +18 -0
  621. package/skills/opendevbrowser-research/assets/templates/report.md +9 -0
  622. package/skills/opendevbrowser-research/examples/sample-input.json +6 -0
  623. package/skills/opendevbrowser-research/examples/sample-output.md +4 -0
  624. package/skills/opendevbrowser-research/scripts/render-output.sh +12 -0
  625. package/skills/opendevbrowser-research/scripts/run-research.sh +23 -0
  626. package/skills/opendevbrowser-research/scripts/validate-skill-assets.sh +48 -0
  627. package/skills/opendevbrowser-research/scripts/write-artifacts.sh +29 -0
  628. package/skills/opendevbrowser-shopping/SKILL.md +118 -0
  629. package/skills/opendevbrowser-shopping/artifacts/deal-hunting-workflows.md +37 -0
  630. package/skills/opendevbrowser-shopping/assets/templates/deal-thresholds.json +8 -0
  631. package/skills/opendevbrowser-shopping/assets/templates/deals-context.json +9 -0
  632. package/skills/opendevbrowser-shopping/assets/templates/deals-table.md +4 -0
  633. package/skills/opendevbrowser-shopping/assets/templates/market-analysis.json +30 -0
  634. package/skills/opendevbrowser-shopping/examples/sample-deals.md +4 -0
  635. package/skills/opendevbrowser-shopping/examples/sample-query.json +5 -0
  636. package/skills/opendevbrowser-shopping/scripts/analyze-market.sh +307 -0
  637. package/skills/opendevbrowser-shopping/scripts/normalize-offers.sh +28 -0
  638. package/skills/opendevbrowser-shopping/scripts/render-deals.sh +13 -0
  639. package/skills/opendevbrowser-shopping/scripts/run-deal-hunt.sh +32 -0
  640. package/skills/opendevbrowser-shopping/scripts/run-shopping.sh +19 -0
  641. package/skills/opendevbrowser-shopping/scripts/validate-skill-assets.sh +53 -0
  642. package/dist/chunk-JVBMT2O5.js +0 -7173
  643. package/dist/chunk-JVBMT2O5.js.map +0 -1
  644. package/skills/data-extraction/SKILL.md +0 -128
  645. package/skills/form-testing/SKILL.md +0 -106
  646. package/skills/login-automation/SKILL.md +0 -108
@@ -0,0 +1,1061 @@
1
+ import { CANVAS_PROTOCOL_VERSION, MAX_CANVAS_PAYLOAD_BYTES } from "../types.js";
2
+ import { logError } from "../logging.js";
3
+ import { TabManager } from "../services/TabManager.js";
4
+ import { TargetSessionCoordinator, createCoordinatorId } from "../ops/target-session-coordinator.js";
5
+ import { normalizeCanvasSessionSummary, normalizeCanvasTargetStateSummaries } from "./model.js";
6
+ const OVERLAY_STYLE = `
7
+ #opendevbrowser-canvas-style,
8
+ .opendevbrowser-canvas-highlight {
9
+ box-sizing: border-box;
10
+ }
11
+ .opendevbrowser-canvas-highlight {
12
+ outline: 2px solid #20d5c6 !important;
13
+ outline-offset: 3px !important;
14
+ }
15
+ .opendevbrowser-canvas-overlay {
16
+ position: fixed;
17
+ top: 16px;
18
+ right: 16px;
19
+ z-index: 2147483647;
20
+ max-width: 320px;
21
+ padding: 12px 14px;
22
+ border-radius: 14px;
23
+ border: 1px solid rgba(255,255,255,0.16);
24
+ background: rgba(7,17,29,0.92);
25
+ color: #f3f6fb;
26
+ font: 12px/1.4 "Segoe UI", sans-serif;
27
+ box-shadow: 0 18px 40px rgba(0,0,0,0.3);
28
+ }
29
+ .opendevbrowser-canvas-overlay strong {
30
+ display: block;
31
+ margin-bottom: 4px;
32
+ }
33
+ `;
34
+ export class CanvasRuntime {
35
+ sendEnvelope;
36
+ tabs = new TabManager();
37
+ sessions = new TargetSessionCoordinator();
38
+ pagePorts = new Map();
39
+ pendingPageActions = new Map();
40
+ constructor(options) {
41
+ this.sendEnvelope = options.send;
42
+ }
43
+ attachPort(port) {
44
+ if (port.name !== "canvas-page") {
45
+ return;
46
+ }
47
+ const tabId = port.sender?.tab?.id;
48
+ if (typeof tabId !== "number") {
49
+ port.disconnect();
50
+ return;
51
+ }
52
+ let ports = this.pagePorts.get(tabId);
53
+ if (!ports) {
54
+ ports = new Set();
55
+ this.pagePorts.set(tabId, ports);
56
+ }
57
+ ports.add(port);
58
+ port.onDisconnect.addListener(() => {
59
+ const current = this.pagePorts.get(tabId);
60
+ current?.delete(port);
61
+ if (current && current.size === 0) {
62
+ this.pagePorts.delete(tabId);
63
+ }
64
+ for (const [requestId, pending] of this.pendingPageActions.entries()) {
65
+ if (pending.tabId !== tabId) {
66
+ continue;
67
+ }
68
+ clearTimeout(pending.timeoutId);
69
+ pending.reject(new Error("Canvas page disconnected before action completed."));
70
+ this.pendingPageActions.delete(requestId);
71
+ }
72
+ });
73
+ port.onMessage.addListener((message) => {
74
+ const record = isRecord(message) ? message : null;
75
+ if (!record) {
76
+ return;
77
+ }
78
+ this.handlePagePortMessage(tabId, record);
79
+ });
80
+ this.postCanvasState(port, this.getPageStateByTabId(tabId), "canvas-page:init");
81
+ }
82
+ getPageStateByTargetId(targetId) {
83
+ try {
84
+ return this.getPageStateByTabId(parseTargetId(targetId));
85
+ }
86
+ catch {
87
+ return null;
88
+ }
89
+ }
90
+ async performPageAction(targetId, action, selector, timeoutMs = 2500) {
91
+ const tabId = parseTargetId(targetId);
92
+ const port = await this.waitForPagePort(tabId, timeoutMs);
93
+ return await new Promise((resolve, reject) => {
94
+ const requestId = crypto.randomUUID();
95
+ const timeoutId = setTimeout(() => {
96
+ this.pendingPageActions.delete(requestId);
97
+ reject(new Error("Canvas page action timed out."));
98
+ }, timeoutMs);
99
+ this.pendingPageActions.set(requestId, { tabId, resolve, reject, timeoutId });
100
+ try {
101
+ port.postMessage({
102
+ type: "canvas-page-action-request",
103
+ requestId,
104
+ selector: selector ?? null,
105
+ action
106
+ });
107
+ }
108
+ catch (error) {
109
+ clearTimeout(timeoutId);
110
+ this.pendingPageActions.delete(requestId);
111
+ reject(error instanceof Error ? error : new Error("Canvas page action failed."));
112
+ }
113
+ });
114
+ }
115
+ handleMessage(message) {
116
+ if (message.type === "canvas_hello") {
117
+ this.handleHello(message);
118
+ return;
119
+ }
120
+ if (message.type === "canvas_ping") {
121
+ this.handlePing(message);
122
+ return;
123
+ }
124
+ if (message.type === "canvas_event" && message.event === "canvas_client_disconnected") {
125
+ this.handleClientDisconnected(message);
126
+ return;
127
+ }
128
+ if (message.type === "canvas_request") {
129
+ void this.handleRequest(message).catch((error) => {
130
+ logError("canvas.handle_request", error, { code: "canvas_request_failed", extra: { command: message.command } });
131
+ this.sendError(message, normalizeCanvasError(error));
132
+ });
133
+ }
134
+ }
135
+ handleHello(message) {
136
+ if (message.version !== CANVAS_PROTOCOL_VERSION) {
137
+ this.sendError({ requestId: "canvas_hello", clientId: message.clientId, canvasSessionId: undefined }, {
138
+ code: "not_supported",
139
+ message: "Unsupported canvas protocol version.",
140
+ retryable: false,
141
+ details: { supported: [CANVAS_PROTOCOL_VERSION], received: message.version }
142
+ });
143
+ return;
144
+ }
145
+ const ack = {
146
+ type: "canvas_hello_ack",
147
+ version: CANVAS_PROTOCOL_VERSION,
148
+ clientId: message.clientId,
149
+ maxPayloadBytes: MAX_CANVAS_PAYLOAD_BYTES,
150
+ capabilities: [
151
+ "canvas.tab.open",
152
+ "canvas.tab.close",
153
+ "canvas.tab.sync",
154
+ "canvas.overlay.mount",
155
+ "canvas.overlay.unmount",
156
+ "canvas.overlay.select",
157
+ "canvas.overlay.sync"
158
+ ]
159
+ };
160
+ this.sendEnvelope(ack);
161
+ }
162
+ handlePing(message) {
163
+ const pong = {
164
+ type: "canvas_pong",
165
+ id: message.id,
166
+ clientId: message.clientId
167
+ };
168
+ this.sendEnvelope(pong);
169
+ }
170
+ handleClientDisconnected(message) {
171
+ const clientId = message.clientId;
172
+ if (!clientId) {
173
+ return;
174
+ }
175
+ for (const session of this.sessions.listOwnedBy(clientId)) {
176
+ void this.closeRuntimeSession(session, "client_disconnected");
177
+ }
178
+ }
179
+ handlePagePortMessage(tabId, message) {
180
+ if (message.type === "canvas-page-action-response") {
181
+ const pending = this.pendingPageActions.get(message.requestId);
182
+ if (!pending) {
183
+ return;
184
+ }
185
+ clearTimeout(pending.timeoutId);
186
+ this.pendingPageActions.delete(message.requestId);
187
+ if (message.ok) {
188
+ pending.resolve(message.value);
189
+ }
190
+ else {
191
+ pending.reject(new Error(message.error || "Canvas page action failed."));
192
+ }
193
+ return;
194
+ }
195
+ const session = this.sessions.getByTabId(tabId);
196
+ if (message.type === "canvas-page-ready" || message.type === "canvas-page-request-state") {
197
+ this.broadcastCanvasState(tabId, "canvas-page:init");
198
+ return;
199
+ }
200
+ if (!session) {
201
+ return;
202
+ }
203
+ if (message.type === "canvas-page-view-state") {
204
+ this.mergeEditorState(session, message.viewport, message.selection);
205
+ this.broadcastCanvasState(tabId, "canvas-page:update");
206
+ return;
207
+ }
208
+ if (message.type === "canvas-page-patch-request") {
209
+ if (!Array.isArray(message.patches) || message.patches.length === 0 || typeof message.baseRevision !== "number") {
210
+ return;
211
+ }
212
+ this.mergeEditorState(session, undefined, message.selection);
213
+ session.pendingMutation = true;
214
+ this.broadcastCanvasState(tabId, "canvas-page:update");
215
+ this.sendEvent({
216
+ type: "canvas_event",
217
+ clientId: session.ownerClientId,
218
+ canvasSessionId: session.id,
219
+ event: "canvas_patch_requested",
220
+ payload: {
221
+ targetId: session.designTabTargetId,
222
+ documentId: session.document.documentId,
223
+ baseRevision: message.baseRevision,
224
+ patches: message.patches,
225
+ selection: session.selection
226
+ }
227
+ });
228
+ }
229
+ }
230
+ async handleRequest(message) {
231
+ switch (message.command) {
232
+ case "canvas.tab.open":
233
+ this.sendResponse(message, await this.openTab(message));
234
+ return;
235
+ case "canvas.tab.close":
236
+ this.sendResponse(message, await this.closeTab(message));
237
+ return;
238
+ case "canvas.tab.sync":
239
+ this.sendResponse(message, await this.syncTab(message));
240
+ return;
241
+ case "canvas.overlay.mount":
242
+ this.sendResponse(message, await this.mountOverlay(message));
243
+ return;
244
+ case "canvas.overlay.unmount":
245
+ this.sendResponse(message, await this.unmountOverlay(message));
246
+ return;
247
+ case "canvas.overlay.select":
248
+ this.sendResponse(message, await this.selectOverlay(message));
249
+ return;
250
+ case "canvas.overlay.sync":
251
+ this.sendResponse(message, await this.syncOverlay(message));
252
+ return;
253
+ default:
254
+ this.sendError(message, {
255
+ code: "not_supported",
256
+ message: `Unsupported canvas command: ${message.command}`,
257
+ retryable: false
258
+ });
259
+ }
260
+ }
261
+ async openTab(message) {
262
+ const record = requireRecord(message.payload, "payload");
263
+ const document = requireCanvasDocument(record.document);
264
+ const previewMode = requireEnum(record.previewMode, "previewMode", ["focused", "pinned", "background"]);
265
+ const tab = await this.createTab(chrome.runtime.getURL("canvas.html"), previewMode);
266
+ const tabId = requireTabId(tab);
267
+ const session = this.createOrReplaceSession(message, tabId, document, previewMode, record);
268
+ this.broadcastCanvasState(tabId, "canvas-page:init");
269
+ this.sendEvent({
270
+ type: "canvas_event",
271
+ clientId: message.clientId,
272
+ canvasSessionId: session.id,
273
+ event: "canvas_session_created",
274
+ payload: { tabId, targetId: session.designTabTargetId }
275
+ });
276
+ return {
277
+ targetId: session.designTabTargetId,
278
+ previewState: session.previewState
279
+ };
280
+ }
281
+ async closeTab(message) {
282
+ const session = this.requireSessionForMessage(message);
283
+ const record = requireRecord(message.payload, "payload");
284
+ const tabId = parseTargetId(requireString(record.targetId, "targetId"));
285
+ const targetId = formatTargetId(tabId);
286
+ this.broadcastCanvasState(tabId, "canvas-page:closed", { reason: "target_closed" });
287
+ session.designTabTargetId = null;
288
+ session.pendingMutation = false;
289
+ this.pagePorts.delete(tabId);
290
+ this.sessions.removeTarget(session.id, targetId);
291
+ await this.tabs.closeTab(tabId);
292
+ this.sendEvent({
293
+ type: "canvas_event",
294
+ clientId: session.ownerClientId,
295
+ canvasSessionId: session.id,
296
+ event: "canvas_target_closed",
297
+ payload: { targetId, tabId }
298
+ });
299
+ if (session.targets.size === 0) {
300
+ this.sessions.delete(session.id);
301
+ this.sendEvent({
302
+ type: "canvas_event",
303
+ clientId: session.ownerClientId,
304
+ canvasSessionId: session.id,
305
+ event: "canvas_session_closed",
306
+ payload: { reason: "target_closed" }
307
+ });
308
+ }
309
+ return {
310
+ ok: true,
311
+ targetId,
312
+ targetIds: [...session.targets.keys()],
313
+ releasedTargetIds: [targetId],
314
+ previewState: "background"
315
+ };
316
+ }
317
+ async syncTab(message) {
318
+ const session = this.requireSessionForMessage(message);
319
+ const record = requireRecord(message.payload, "payload");
320
+ const tabId = parseTargetId(requireString(record.targetId, "targetId"));
321
+ const existingTab = await this.tabs.getTab(tabId);
322
+ if (!existingTab) {
323
+ throw new Error(`Canvas target is unavailable: ${tabId}`);
324
+ }
325
+ const summary = normalizeCanvasSessionSummary(record.summary);
326
+ session.document = requireCanvasDocument(record.document);
327
+ session.documentRevision = optionalNumber(record.documentRevision);
328
+ session.html = requireRenderedHtml(record);
329
+ session.summary = summary;
330
+ session.previewTargets = normalizeCanvasTargetStateSummaries(record.targets ?? summary.targets);
331
+ session.overlayMounts = parseOverlayMounts(record.overlayMounts ?? summary.overlayMounts);
332
+ session.feedback = parseFeedbackEvents(record.feedback);
333
+ session.feedbackCursor = optionalString(record.feedbackCursor) ?? lastFeedbackCursor(session.feedback);
334
+ session.pendingMutation = false;
335
+ this.mergeEditorState(session, normalizeViewport(record.viewport), normalizeSelection(record.selection));
336
+ session.previewState = normalizePreviewState(record.previewState) ?? session.previewState;
337
+ session.previewMode = normalizePreviewState(record.previewMode) ?? session.previewMode;
338
+ this.broadcastCanvasState(tabId, "canvas-page:update");
339
+ return {
340
+ ok: true,
341
+ targetId: formatTargetId(tabId),
342
+ previewState: session.previewState
343
+ };
344
+ }
345
+ async mountOverlay(message) {
346
+ const session = this.requireSessionForMessage(message);
347
+ const record = requireRecord(message.payload, "payload");
348
+ const tabId = parseTargetId(requireString(record.targetId, "targetId"));
349
+ const prototypeId = optionalString(record.prototypeId) ?? "default";
350
+ await insertCss(tabId, OVERLAY_STYLE);
351
+ const mountId = `mount_${crypto.randomUUID()}`;
352
+ const result = await executeInTab(tabId, mountOverlayScript, [{
353
+ mountId,
354
+ cssText: OVERLAY_STYLE,
355
+ title: session.document.title,
356
+ prototypeId,
357
+ selection: session.selection
358
+ }]);
359
+ const mount = {
360
+ mountId,
361
+ targetId: formatTargetId(tabId),
362
+ mountedAt: new Date().toISOString()
363
+ };
364
+ session.overlayMounts = dedupeOverlayMounts([...session.overlayMounts, mount]);
365
+ this.broadcastIfDesignTab(session);
366
+ return {
367
+ mountId,
368
+ targetId: formatTargetId(tabId),
369
+ previewState: "background",
370
+ overlayState: result?.previewState ?? "mounted",
371
+ capabilities: { selection: true, guides: true }
372
+ };
373
+ }
374
+ async unmountOverlay(message) {
375
+ const session = this.requireSessionForMessage(message);
376
+ const record = requireRecord(message.payload, "payload");
377
+ const mountId = requireString(record.mountId, "mountId");
378
+ const tabId = parseTargetId(requireString(record.targetId, "targetId"));
379
+ await executeInTab(tabId, unmountOverlayScript, [mountId]);
380
+ session.overlayMounts = session.overlayMounts.filter((mount) => mount.mountId !== mountId);
381
+ this.broadcastIfDesignTab(session);
382
+ return {
383
+ ok: true,
384
+ mountId,
385
+ previewState: "background",
386
+ overlayState: "idle"
387
+ };
388
+ }
389
+ async selectOverlay(message) {
390
+ const session = this.requireSessionForMessage(message);
391
+ const record = requireRecord(message.payload, "payload");
392
+ const tabId = parseTargetId(requireString(record.targetId, "targetId"));
393
+ const selectionHint = isRecord(record.selectionHint) ? record.selectionHint : {};
394
+ const nodeId = optionalString(record.nodeId);
395
+ const selection = await executeInTab(tabId, selectOverlayScript, [{ selectionHint, nodeId }]);
396
+ if (typeof nodeId === "string") {
397
+ session.selection = {
398
+ pageId: session.document.pages[0]?.id ?? null,
399
+ nodeId,
400
+ targetId: formatTargetId(tabId),
401
+ updatedAt: new Date().toISOString()
402
+ };
403
+ this.broadcastIfDesignTab(session);
404
+ }
405
+ return {
406
+ targetId: formatTargetId(tabId),
407
+ selection
408
+ };
409
+ }
410
+ async syncOverlay(message) {
411
+ const session = this.requireSessionForMessage(message);
412
+ const record = requireRecord(message.payload, "payload");
413
+ const tabId = parseTargetId(requireString(record.targetId, "targetId"));
414
+ const mountId = requireString(record.mountId, "mountId");
415
+ await insertCss(tabId, OVERLAY_STYLE);
416
+ const result = await executeInTab(tabId, syncOverlayScript, [{
417
+ mountId,
418
+ title: session.document.title,
419
+ selection: session.selection
420
+ }]);
421
+ return {
422
+ ok: true,
423
+ mountId,
424
+ targetId: formatTargetId(tabId),
425
+ overlayState: result?.overlayState ?? "mounted"
426
+ };
427
+ }
428
+ createOrReplaceSession(message, tabId, document, previewMode, record) {
429
+ const canvasSessionId = resolveCanvasSessionId(message, record);
430
+ const clientId = requireString(message.clientId, "clientId");
431
+ const requestedLeaseId = optionalString(message.leaseId);
432
+ const summary = normalizeCanvasSessionSummary(record.summary);
433
+ const existing = this.sessions.get(canvasSessionId);
434
+ if (existing) {
435
+ if (existing.ownerClientId !== clientId || (requestedLeaseId && existing.leaseId !== requestedLeaseId)) {
436
+ throw new Error("Canvas session ownership mismatch.");
437
+ }
438
+ if (existing.designTabTargetId && existing.designTabTargetId !== formatTargetId(tabId)) {
439
+ void this.tabs.closeTab(parseTargetId(existing.designTabTargetId)).catch(() => undefined);
440
+ }
441
+ existing.designTabTargetId = formatTargetId(tabId);
442
+ existing.document = document;
443
+ existing.documentRevision = optionalNumber(record.documentRevision);
444
+ existing.html = requireRenderedHtml(record);
445
+ existing.summary = summary;
446
+ existing.previewTargets = normalizeCanvasTargetStateSummaries(record.targets ?? summary.targets);
447
+ existing.overlayMounts = parseOverlayMounts(record.overlayMounts ?? summary.overlayMounts);
448
+ existing.feedback = parseFeedbackEvents(record.feedback);
449
+ existing.feedbackCursor = optionalString(record.feedbackCursor) ?? lastFeedbackCursor(existing.feedback);
450
+ existing.previewMode = previewMode;
451
+ existing.previewState = previewMode;
452
+ existing.pendingMutation = false;
453
+ this.sessions.addTarget(existing.id, tabId, { title: document.title, url: chrome.runtime.getURL("canvas.html") });
454
+ this.sessions.setActiveTarget(existing.id, formatTargetId(tabId));
455
+ return existing;
456
+ }
457
+ const leaseId = requestedLeaseId ?? createCoordinatorId();
458
+ const session = this.sessions.createSession(clientId, tabId, leaseId, {
459
+ title: document.title,
460
+ url: chrome.runtime.getURL("canvas.html")
461
+ }, {
462
+ designTabTargetId: formatTargetId(tabId),
463
+ document,
464
+ documentRevision: optionalNumber(record.documentRevision),
465
+ html: requireRenderedHtml(record),
466
+ summary,
467
+ previewMode,
468
+ previewState: previewMode,
469
+ previewTargets: normalizeCanvasTargetStateSummaries(record.targets ?? summary.targets),
470
+ overlayMounts: parseOverlayMounts(record.overlayMounts ?? summary.overlayMounts),
471
+ feedback: parseFeedbackEvents(record.feedback),
472
+ feedbackCursor: optionalString(record.feedbackCursor) ?? lastFeedbackCursor(parseFeedbackEvents(record.feedback)),
473
+ selection: defaultSelection(document.pages[0]?.id ?? null),
474
+ viewport: { x: 120, y: 96, zoom: 1 },
475
+ pendingMutation: false
476
+ }, canvasSessionId);
477
+ return session;
478
+ }
479
+ requireSessionForMessage(message, record) {
480
+ const payload = record ?? (isRecord(message.payload) ? message.payload : {});
481
+ const session = resolveSessionForMessage(this.sessions, message, payload);
482
+ const clientId = requireString(message.clientId, "clientId");
483
+ const leaseId = optionalString(message.leaseId);
484
+ if (session.ownerClientId !== clientId || (leaseId && session.leaseId !== leaseId)) {
485
+ throw new Error("Canvas session ownership mismatch.");
486
+ }
487
+ return session;
488
+ }
489
+ mergeEditorState(session, viewport, selection) {
490
+ if (viewport) {
491
+ session.viewport = {
492
+ x: typeof viewport.x === "number" ? viewport.x : session.viewport.x,
493
+ y: typeof viewport.y === "number" ? viewport.y : session.viewport.y,
494
+ zoom: typeof viewport.zoom === "number" && Number.isFinite(viewport.zoom) ? viewport.zoom : session.viewport.zoom
495
+ };
496
+ }
497
+ if (selection) {
498
+ session.selection = {
499
+ pageId: typeof selection.pageId === "string" ? selection.pageId : session.selection.pageId,
500
+ nodeId: typeof selection.nodeId === "string" || selection.nodeId === null ? selection.nodeId : session.selection.nodeId,
501
+ targetId: typeof selection.targetId === "string" || selection.targetId === null ? selection.targetId : session.selection.targetId,
502
+ updatedAt: new Date().toISOString()
503
+ };
504
+ }
505
+ }
506
+ getPageStateByTabId(tabId) {
507
+ const session = this.sessions.getByTabId(tabId);
508
+ if (!session || !session.designTabTargetId) {
509
+ return null;
510
+ }
511
+ return buildPageState(session, tabId);
512
+ }
513
+ async waitForPagePort(tabId, timeoutMs) {
514
+ const existing = this.firstConnectedPagePort(tabId);
515
+ if (existing) {
516
+ return existing;
517
+ }
518
+ const startedAt = Date.now();
519
+ while (Date.now() - startedAt < timeoutMs) {
520
+ await delay(50);
521
+ const next = this.firstConnectedPagePort(tabId);
522
+ if (next) {
523
+ return next;
524
+ }
525
+ }
526
+ throw new Error("Canvas page port unavailable.");
527
+ }
528
+ firstConnectedPagePort(tabId) {
529
+ const ports = this.pagePorts.get(tabId);
530
+ if (!ports || ports.size === 0) {
531
+ return null;
532
+ }
533
+ return ports.values().next().value ?? null;
534
+ }
535
+ sendResponse(message, payload) {
536
+ const response = {
537
+ type: "canvas_response",
538
+ requestId: message.requestId,
539
+ clientId: message.clientId,
540
+ canvasSessionId: message.canvasSessionId,
541
+ payload
542
+ };
543
+ this.sendEnvelope(response);
544
+ }
545
+ sendError(message, error) {
546
+ this.sendEnvelope({
547
+ type: "canvas_error",
548
+ requestId: message.requestId,
549
+ clientId: message.clientId,
550
+ canvasSessionId: message.canvasSessionId,
551
+ error
552
+ });
553
+ }
554
+ sendEvent(event) {
555
+ this.sendEnvelope(event);
556
+ }
557
+ postCanvasState(port, state, type, extra = {}) {
558
+ try {
559
+ port.postMessage({
560
+ type,
561
+ state,
562
+ ...extra
563
+ });
564
+ }
565
+ catch {
566
+ // ignore disconnected page ports
567
+ }
568
+ }
569
+ broadcastCanvasState(tabId, type, extra = {}) {
570
+ const ports = this.pagePorts.get(tabId);
571
+ if (!ports || ports.size === 0) {
572
+ return;
573
+ }
574
+ const state = this.getPageStateByTabId(tabId);
575
+ for (const port of ports) {
576
+ this.postCanvasState(port, state, type, extra);
577
+ }
578
+ }
579
+ broadcastIfDesignTab(session) {
580
+ if (!session.designTabTargetId) {
581
+ return;
582
+ }
583
+ this.broadcastCanvasState(parseTargetId(session.designTabTargetId), "canvas-page:update");
584
+ }
585
+ async closeRuntimeSession(session, reason) {
586
+ const released = [...session.targets.values()];
587
+ for (const target of released) {
588
+ this.broadcastCanvasState(target.tabId, "canvas-page:closed", { reason });
589
+ await this.tabs.closeTab(target.tabId).catch(() => undefined);
590
+ this.pagePorts.delete(target.tabId);
591
+ }
592
+ this.sessions.delete(session.id);
593
+ this.sendEvent({
594
+ type: "canvas_event",
595
+ clientId: session.ownerClientId,
596
+ canvasSessionId: session.id,
597
+ event: "canvas_session_expired",
598
+ payload: { reason }
599
+ });
600
+ }
601
+ async createTab(url, previewMode) {
602
+ return await new Promise((resolve, reject) => {
603
+ chrome.tabs.create({ url, active: previewMode === "focused", pinned: previewMode === "pinned" }, (tab) => {
604
+ const lastError = chrome.runtime.lastError;
605
+ if (lastError) {
606
+ reject(new Error(lastError.message));
607
+ return;
608
+ }
609
+ if (!tab || typeof tab.id !== "number") {
610
+ reject(new Error("Canvas tab creation failed"));
611
+ return;
612
+ }
613
+ resolve(tab);
614
+ });
615
+ });
616
+ }
617
+ }
618
+ function buildPageState(session, tabId) {
619
+ return {
620
+ tabId,
621
+ targetId: formatTargetId(tabId),
622
+ canvasSessionId: session.id,
623
+ documentId: session.document.documentId,
624
+ documentRevision: session.documentRevision,
625
+ title: session.document.title,
626
+ document: session.document,
627
+ html: session.html,
628
+ previewMode: session.previewMode,
629
+ previewState: session.previewState,
630
+ updatedAt: new Date().toISOString(),
631
+ summary: session.summary,
632
+ targets: session.previewTargets,
633
+ overlayMounts: session.overlayMounts,
634
+ feedback: session.feedback,
635
+ feedbackCursor: session.feedbackCursor,
636
+ selection: session.selection,
637
+ viewport: session.viewport,
638
+ pendingMutation: session.pendingMutation
639
+ };
640
+ }
641
+ function defaultSelection(pageId) {
642
+ return {
643
+ pageId,
644
+ nodeId: null,
645
+ targetId: null,
646
+ updatedAt: new Date().toISOString()
647
+ };
648
+ }
649
+ function normalizeViewport(value) {
650
+ if (!isRecord(value)) {
651
+ return null;
652
+ }
653
+ return {
654
+ x: typeof value.x === "number" ? value.x : undefined,
655
+ y: typeof value.y === "number" ? value.y : undefined,
656
+ zoom: typeof value.zoom === "number" ? value.zoom : undefined
657
+ };
658
+ }
659
+ function normalizeSelection(value) {
660
+ if (!isRecord(value)) {
661
+ return null;
662
+ }
663
+ return {
664
+ pageId: typeof value.pageId === "string" || value.pageId === null ? value.pageId : undefined,
665
+ nodeId: typeof value.nodeId === "string" || value.nodeId === null ? value.nodeId : undefined,
666
+ targetId: typeof value.targetId === "string" || value.targetId === null ? value.targetId : undefined
667
+ };
668
+ }
669
+ function requireCanvasDocument(value) {
670
+ const document = requireRecord(value, "document");
671
+ const pagesValue = Array.isArray(document.pages) ? document.pages : [];
672
+ return {
673
+ documentId: requireString(document.documentId, "documentId"),
674
+ title: optionalString(document.title) ?? "OpenDevBrowser Canvas",
675
+ updatedAt: optionalString(document.updatedAt) ?? undefined,
676
+ bindings: Array.isArray(document.bindings)
677
+ ? document.bindings.flatMap((bindingValue) => {
678
+ const binding = isRecord(bindingValue) ? bindingValue : null;
679
+ if (!binding || typeof binding.id !== "string" || typeof binding.nodeId !== "string") {
680
+ return [];
681
+ }
682
+ return [{
683
+ id: binding.id,
684
+ nodeId: binding.nodeId,
685
+ kind: optionalString(binding.kind) ?? "component",
686
+ componentName: optionalString(binding.componentName) ?? undefined,
687
+ metadata: isRecord(binding.metadata) ? binding.metadata : {}
688
+ }];
689
+ })
690
+ : [],
691
+ assets: Array.isArray(document.assets)
692
+ ? document.assets.flatMap((assetValue) => {
693
+ const asset = isRecord(assetValue) ? assetValue : null;
694
+ if (!asset || typeof asset.id !== "string") {
695
+ return [];
696
+ }
697
+ return [{
698
+ id: asset.id,
699
+ sourceType: optionalString(asset.sourceType) ?? undefined,
700
+ kind: optionalString(asset.kind) ?? undefined,
701
+ repoPath: optionalString(asset.repoPath),
702
+ url: optionalString(asset.url),
703
+ mime: optionalString(asset.mime) ?? undefined,
704
+ metadata: isRecord(asset.metadata) ? asset.metadata : {}
705
+ }];
706
+ })
707
+ : [],
708
+ componentInventory: Array.isArray(document.componentInventory)
709
+ ? document.componentInventory.filter(isRecord)
710
+ : [],
711
+ pages: pagesValue.map((pageValue) => {
712
+ const page = requireRecord(pageValue, "page");
713
+ const nodesValue = Array.isArray(page.nodes) ? page.nodes : [];
714
+ return {
715
+ id: requireString(page.id, "page.id"),
716
+ name: optionalString(page.name) ?? requireString(page.id, "page.id"),
717
+ path: optionalString(page.path) ?? "/",
718
+ rootNodeId: optionalString(page.rootNodeId) ?? null,
719
+ prototypeIds: Array.isArray(page.prototypeIds) ? page.prototypeIds.filter((entry) => typeof entry === "string") : [],
720
+ nodes: nodesValue.map((nodeValue) => {
721
+ const node = requireRecord(nodeValue, "node");
722
+ return {
723
+ id: requireString(node.id, "node.id"),
724
+ kind: optionalString(node.kind) ?? "frame",
725
+ name: optionalString(node.name) ?? "node",
726
+ pageId: optionalString(node.pageId) ?? undefined,
727
+ parentId: optionalString(node.parentId),
728
+ childIds: Array.isArray(node.childIds) ? node.childIds.filter((entry) => typeof entry === "string") : [],
729
+ rect: normalizeRect(node.rect),
730
+ props: isRecord(node.props) ? node.props : {},
731
+ style: isRecord(node.style) ? node.style : {},
732
+ bindingRefs: isRecord(node.bindingRefs) ? node.bindingRefs : {},
733
+ metadata: isRecord(node.metadata) ? node.metadata : {}
734
+ };
735
+ }),
736
+ metadata: isRecord(page.metadata) ? page.metadata : {}
737
+ };
738
+ })
739
+ };
740
+ }
741
+ function requireRenderedHtml(record) {
742
+ return requireString(record.html, "html");
743
+ }
744
+ function normalizeRect(value) {
745
+ if (!isRecord(value)) {
746
+ return { x: 0, y: 0, width: 320, height: 180 };
747
+ }
748
+ return {
749
+ x: typeof value.x === "number" ? value.x : 0,
750
+ y: typeof value.y === "number" ? value.y : 0,
751
+ width: typeof value.width === "number" ? value.width : 320,
752
+ height: typeof value.height === "number" ? value.height : 180
753
+ };
754
+ }
755
+ function parseOverlayMounts(value) {
756
+ if (!Array.isArray(value)) {
757
+ return [];
758
+ }
759
+ return value.flatMap((entry) => {
760
+ if (!isRecord(entry)) {
761
+ return [];
762
+ }
763
+ const mountId = optionalString(entry.mountId);
764
+ const targetId = optionalString(entry.targetId);
765
+ const mountedAt = optionalString(entry.mountedAt);
766
+ return mountId && targetId && mountedAt
767
+ ? [{ mountId, targetId, mountedAt }]
768
+ : [];
769
+ });
770
+ }
771
+ function parseFeedbackEvents(value) {
772
+ if (!Array.isArray(value)) {
773
+ return [];
774
+ }
775
+ const events = [];
776
+ for (const entry of value) {
777
+ if (!isRecord(entry)) {
778
+ continue;
779
+ }
780
+ if (entry.eventType === "feedback.item" && isRecord(entry.item)) {
781
+ const item = entry.item;
782
+ const id = optionalString(item.id);
783
+ const cursor = optionalString(item.cursor);
784
+ const documentId = optionalString(item.documentId);
785
+ if (!id || !cursor || !documentId) {
786
+ continue;
787
+ }
788
+ events.push({
789
+ eventType: "feedback.item",
790
+ item: {
791
+ id,
792
+ cursor,
793
+ category: optionalString(item.category) ?? "validation",
794
+ class: optionalString(item.class) ?? "feedback",
795
+ severity: optionalString(item.severity) ?? "info",
796
+ message: optionalString(item.message) ?? "",
797
+ documentId,
798
+ documentRevision: typeof item.documentRevision === "number" ? item.documentRevision : 0,
799
+ pageId: optionalString(item.pageId),
800
+ prototypeId: optionalString(item.prototypeId),
801
+ targetId: optionalString(item.targetId),
802
+ evidenceRefs: Array.isArray(item.evidenceRefs) ? item.evidenceRefs.filter((ref) => typeof ref === "string") : [],
803
+ details: isRecord(item.details) ? item.details : {}
804
+ }
805
+ });
806
+ continue;
807
+ }
808
+ if (entry.eventType === "feedback.heartbeat") {
809
+ events.push({
810
+ eventType: "feedback.heartbeat",
811
+ cursor: optionalString(entry.cursor),
812
+ ts: optionalString(entry.ts) ?? new Date().toISOString(),
813
+ activeTargetIds: Array.isArray(entry.activeTargetIds) ? entry.activeTargetIds.filter((id) => typeof id === "string") : []
814
+ });
815
+ continue;
816
+ }
817
+ if (entry.eventType === "feedback.complete") {
818
+ const reason = optionalString(entry.reason);
819
+ if (!reason) {
820
+ continue;
821
+ }
822
+ events.push({
823
+ eventType: "feedback.complete",
824
+ cursor: optionalString(entry.cursor),
825
+ ts: optionalString(entry.ts) ?? new Date().toISOString(),
826
+ reason: reason
827
+ });
828
+ continue;
829
+ }
830
+ }
831
+ return events;
832
+ }
833
+ function lastFeedbackCursor(events) {
834
+ for (let index = events.length - 1; index >= 0; index -= 1) {
835
+ const entry = events[index];
836
+ if (entry?.eventType === "feedback.item") {
837
+ return entry.item.cursor;
838
+ }
839
+ if (entry?.eventType === "feedback.heartbeat" || entry?.eventType === "feedback.complete") {
840
+ return entry.cursor;
841
+ }
842
+ }
843
+ return null;
844
+ }
845
+ function dedupeOverlayMounts(mounts) {
846
+ const byId = new Map();
847
+ for (const mount of mounts) {
848
+ byId.set(mount.mountId, mount);
849
+ }
850
+ return [...byId.values()];
851
+ }
852
+ function requireRecord(value, label) {
853
+ if (!value || typeof value !== "object" || Array.isArray(value)) {
854
+ throw new Error(`Invalid ${label}`);
855
+ }
856
+ return value;
857
+ }
858
+ function resolveCanvasSessionId(message, payload) {
859
+ return optionalString(message.canvasSessionId)
860
+ ?? optionalString(payload.canvasSessionId)
861
+ ?? optionalString(isRecord(payload.summary) ? payload.summary.canvasSessionId : undefined)
862
+ ?? createCoordinatorId();
863
+ }
864
+ function resolveSessionForMessage(sessions, message, payload) {
865
+ const directId = optionalString(message.canvasSessionId)
866
+ ?? optionalString(payload.canvasSessionId)
867
+ ?? optionalString(isRecord(payload.summary) ? payload.summary.canvasSessionId : undefined);
868
+ if (directId) {
869
+ return sessions.requireSession(directId);
870
+ }
871
+ const targetId = optionalString(payload.targetId);
872
+ if (targetId) {
873
+ const session = sessions.getByTabId(parseTargetId(targetId));
874
+ if (session) {
875
+ return session;
876
+ }
877
+ }
878
+ throw missingCanvasSession();
879
+ }
880
+ function missingCanvasSession() {
881
+ return new Error("Missing canvasSessionId");
882
+ }
883
+ function isRecord(value) {
884
+ return Boolean(value) && typeof value === "object" && !Array.isArray(value);
885
+ }
886
+ function requireString(value, label) {
887
+ if (typeof value !== "string" || value.trim().length === 0) {
888
+ throw new Error(`Missing ${label}`);
889
+ }
890
+ return value;
891
+ }
892
+ function optionalString(value) {
893
+ return typeof value === "string" && value.trim().length > 0 ? value : null;
894
+ }
895
+ function optionalNumber(value) {
896
+ return typeof value === "number" && Number.isFinite(value) ? value : null;
897
+ }
898
+ function requireEnum(value, label, allowed) {
899
+ if (typeof value !== "string" || !allowed.includes(value)) {
900
+ throw new Error(`Invalid ${label}`);
901
+ }
902
+ return value;
903
+ }
904
+ function normalizePreviewState(value) {
905
+ return value === "focused" || value === "pinned" || value === "background" || value === "degraded"
906
+ ? value
907
+ : null;
908
+ }
909
+ function parseTargetId(targetId) {
910
+ const raw = targetId.startsWith("tab-") ? targetId.slice(4) : targetId;
911
+ const tabId = Number(raw);
912
+ if (!Number.isInteger(tabId) || tabId <= 0) {
913
+ throw new Error(`Invalid targetId: ${targetId}`);
914
+ }
915
+ return tabId;
916
+ }
917
+ function formatTargetId(tabId) {
918
+ if (!Number.isInteger(tabId)) {
919
+ throw new Error("Tab id unavailable");
920
+ }
921
+ return `tab-${tabId}`;
922
+ }
923
+ function requireTabId(tab) {
924
+ const tabId = tab.id;
925
+ if (typeof tabId !== "number" || !Number.isInteger(tabId)) {
926
+ throw new Error("Canvas tab creation failed");
927
+ }
928
+ return tabId;
929
+ }
930
+ async function insertCss(tabId, css) {
931
+ await new Promise((resolve, reject) => {
932
+ chrome.scripting.insertCSS({ target: { tabId }, css }, () => {
933
+ const lastError = chrome.runtime.lastError;
934
+ if (lastError) {
935
+ reject(new Error(lastError.message));
936
+ return;
937
+ }
938
+ resolve();
939
+ });
940
+ });
941
+ }
942
+ async function executeInTab(tabId, func, args) {
943
+ return await new Promise((resolve, reject) => {
944
+ chrome.scripting.executeScript({ target: { tabId }, func: func, args }, (results) => {
945
+ const lastError = chrome.runtime.lastError;
946
+ if (lastError) {
947
+ reject(new Error(lastError.message));
948
+ return;
949
+ }
950
+ const [first] = results ?? [];
951
+ resolve((first?.result ?? null));
952
+ });
953
+ });
954
+ }
955
+ function mountOverlayScript(input) {
956
+ const styleId = "opendevbrowser-canvas-style";
957
+ if (!document.getElementById(styleId)) {
958
+ const style = document.createElement("style");
959
+ style.id = styleId;
960
+ style.textContent = input.cssText;
961
+ document.head.append(style);
962
+ }
963
+ document.getElementById(input.mountId)?.remove();
964
+ const root = document.createElement("div");
965
+ root.id = input.mountId;
966
+ root.className = "opendevbrowser-canvas-overlay";
967
+ const heading = document.createElement("strong");
968
+ heading.textContent = input.title;
969
+ const detail = document.createElement("div");
970
+ detail.textContent = input.selection.nodeId ? `Selected ${input.selection.nodeId}` : input.prototypeId;
971
+ root.append(heading, detail);
972
+ document.body.append(root);
973
+ if (input.selection.nodeId) {
974
+ const element = document.querySelector(`[data-node-id="${input.selection.nodeId}"]`);
975
+ if (element instanceof HTMLElement) {
976
+ element.classList.add("opendevbrowser-canvas-highlight");
977
+ }
978
+ }
979
+ return { previewState: "overlay_mounted" };
980
+ }
981
+ function unmountOverlayScript(mountId) {
982
+ document.getElementById(mountId)?.remove();
983
+ document.querySelectorAll(".opendevbrowser-canvas-highlight").forEach((element) => {
984
+ element.classList.remove("opendevbrowser-canvas-highlight");
985
+ });
986
+ return true;
987
+ }
988
+ function selectOverlayScript(input) {
989
+ document.querySelectorAll(".opendevbrowser-canvas-highlight").forEach((element) => {
990
+ element.classList.remove("opendevbrowser-canvas-highlight");
991
+ });
992
+ const selector = typeof input.selectionHint.selector === "string"
993
+ ? input.selectionHint.selector
994
+ : (input.nodeId ? `[data-node-id="${input.nodeId}"]` : null);
995
+ const element = selector ? document.querySelector(selector) : null;
996
+ if (!(element instanceof HTMLElement)) {
997
+ return { matched: false };
998
+ }
999
+ element.classList.add("opendevbrowser-canvas-highlight");
1000
+ return {
1001
+ matched: true,
1002
+ selector,
1003
+ tagName: element.tagName.toLowerCase(),
1004
+ text: element.innerText.slice(0, 160),
1005
+ id: element.id || null,
1006
+ className: element.className || null
1007
+ };
1008
+ }
1009
+ function syncOverlayScript(input) {
1010
+ let root = document.getElementById(input.mountId);
1011
+ if (!(root instanceof HTMLElement)) {
1012
+ root = document.createElement("div");
1013
+ root.id = input.mountId;
1014
+ root.className = "opendevbrowser-canvas-overlay";
1015
+ const heading = document.createElement("strong");
1016
+ heading.textContent = input.title;
1017
+ const detail = document.createElement("div");
1018
+ detail.textContent = input.selection.nodeId ? `Selected ${input.selection.nodeId}` : "Canvas overlay synced";
1019
+ root.append(heading, detail);
1020
+ document.body.append(root);
1021
+ }
1022
+ const strong = root.querySelector("strong");
1023
+ if (strong) {
1024
+ strong.textContent = input.title;
1025
+ }
1026
+ const detail = root.querySelector("div");
1027
+ if (detail) {
1028
+ detail.textContent = input.selection.nodeId ? `Selected ${input.selection.nodeId}` : "Canvas overlay synced";
1029
+ }
1030
+ document.querySelectorAll(".opendevbrowser-canvas-highlight").forEach((element) => {
1031
+ element.classList.remove("opendevbrowser-canvas-highlight");
1032
+ });
1033
+ if (input.selection.nodeId) {
1034
+ const element = document.querySelector(`[data-node-id="${input.selection.nodeId}"]`);
1035
+ if (element instanceof HTMLElement) {
1036
+ element.classList.add("opendevbrowser-canvas-highlight");
1037
+ }
1038
+ }
1039
+ return { overlayState: "mounted" };
1040
+ }
1041
+ function normalizeCanvasError(error) {
1042
+ if (error instanceof Error) {
1043
+ const message = error.message;
1044
+ const restricted = message.includes("Cannot access") || message.includes("chrome://") || message.includes("restricted");
1045
+ return {
1046
+ code: restricted ? "restricted_url" : "execution_failed",
1047
+ message,
1048
+ retryable: false
1049
+ };
1050
+ }
1051
+ return {
1052
+ code: "execution_failed",
1053
+ message: "Canvas request failed",
1054
+ retryable: false
1055
+ };
1056
+ }
1057
+ function delay(ms) {
1058
+ return new Promise((resolve) => {
1059
+ setTimeout(resolve, ms);
1060
+ });
1061
+ }