opendevbrowser 0.0.34 → 0.0.35

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 (283) hide show
  1. package/README.md +1 -1
  2. package/dist/{accessibility-snapshot-VCBXK47S.js → accessibility-snapshot-TAFPVLZN.js} +8 -8
  3. package/dist/{active-window-7EUN36LZ.js → active-window-MHFMC6NQ.js} +8 -8
  4. package/dist/{annotate-VLBK7YB6.js → annotate-5ZFRFQ4B.js} +7 -7
  5. package/dist/{attr-JNANQKM6.js → attr-MBF2UCRF.js} +7 -7
  6. package/dist/browser/browser-manager.d.ts +6 -1
  7. package/dist/browser/browser-manager.d.ts.map +1 -1
  8. package/dist/browser/manager-types.d.ts +48 -0
  9. package/dist/browser/manager-types.d.ts.map +1 -1
  10. package/dist/browser/ops-browser-manager.d.ts +2 -1
  11. package/dist/browser/ops-browser-manager.d.ts.map +1 -1
  12. package/dist/{canvas-V5LO4JVL.js → canvas-CAMD22YU.js} +7 -7
  13. package/dist/{capture-desktop-FKVDWTVG.js → capture-desktop-TMZSFA5R.js} +8 -8
  14. package/dist/{capture-window-QVPM2DN2.js → capture-window-NZDKD2AE.js} +8 -8
  15. package/dist/{check-V3CWZ56S.js → check-MO33GTQ4.js} +7 -7
  16. package/dist/{checked-Q27Q6YZN.js → checked-3HDF5X2M.js} +7 -7
  17. package/dist/{chunk-VX47SJZM.js → chunk-32ZSOZND.js} +2 -2
  18. package/dist/{chunk-XRDCSHKZ.js → chunk-AHQC4A6P.js} +744 -14
  19. package/dist/chunk-AHQC4A6P.js.map +1 -0
  20. package/dist/{chunk-IBIHDGTZ.js → chunk-B5XIJQXO.js} +32 -4
  21. package/dist/chunk-B5XIJQXO.js.map +1 -0
  22. package/dist/{chunk-OJAUKABV.js → chunk-BHZLEFXW.js} +2 -2
  23. package/dist/{chunk-VY47VKXU.js → chunk-FJZY3Z3X.js} +2 -2
  24. package/dist/{chunk-GC2FWISX.js → chunk-HM4CO3EW.js} +20 -16
  25. package/dist/chunk-HM4CO3EW.js.map +1 -0
  26. package/dist/{chunk-Z3HIX2SE.js → chunk-UEAXTWGT.js} +2 -2
  27. package/dist/{chunk-ZGCTC5YM.js → chunk-UVD34RA2.js} +33 -1
  28. package/dist/chunk-UVD34RA2.js.map +1 -0
  29. package/dist/{chunk-5FDXH4CS.js → chunk-WTWSBEBW.js} +5659 -419
  30. package/dist/chunk-WTWSBEBW.js.map +1 -0
  31. package/dist/{chunk-NX2XYJP5.js → chunk-XSSPNVMS.js} +3 -3
  32. package/dist/{chunk-NX2XYJP5.js.map → chunk-XSSPNVMS.js.map} +1 -1
  33. package/dist/{chunk-QXJDJDSZ.js → chunk-Z3ADLR7I.js} +667 -8
  34. package/dist/chunk-Z3ADLR7I.js.map +1 -0
  35. package/dist/cli/commands/inspiredesign.d.ts +12 -1
  36. package/dist/cli/commands/inspiredesign.d.ts.map +1 -1
  37. package/dist/cli/daemon-commands.d.ts.map +1 -1
  38. package/dist/cli/help.d.ts.map +1 -1
  39. package/dist/cli/index.js +76 -76
  40. package/dist/cli/index.js.map +1 -1
  41. package/dist/cli/utils/workflow-message.d.ts.map +1 -1
  42. package/dist/{click-EQDRSLR3.js → click-SWZPJO2U.js} +7 -7
  43. package/dist/{clone-component-SISUXTJS.js → clone-component-YTB46YU4.js} +7 -7
  44. package/dist/{clone-page-MLDPCBOY.js → clone-page-5FMPHQ3A.js} +7 -7
  45. package/dist/{close-7J7EV237.js → close-22SNMDX3.js} +7 -7
  46. package/dist/{close-2LQMJVOA.js → close-ORQZCZ2E.js} +7 -7
  47. package/dist/{connect-JFRSIW5M.js → connect-EWYITNQU.js} +7 -7
  48. package/dist/{console-poll-NSVVUNEC.js → console-poll-LJR6ZTDK.js} +7 -7
  49. package/dist/{cookie-import-B7IQTGTN.js → cookie-import-PTAIWPEC.js} +7 -7
  50. package/dist/{cookie-list-YHG7JCZZ.js → cookie-list-76C35B5B.js} +7 -7
  51. package/dist/{daemon-ENU4FOV4.js → daemon-UKJMDLCB.js} +6 -6
  52. package/dist/daemon-fingerprint.json +1 -1
  53. package/dist/{debug-trace-snapshot-KLGU2AWY.js → debug-trace-snapshot-PQ5FJART.js} +7 -7
  54. package/dist/{dialog-MUVQIERS.js → dialog-WLJDWJV4.js} +7 -7
  55. package/dist/{disconnect-KELQJ45J.js → disconnect-FNB4JC2U.js} +7 -7
  56. package/dist/{enabled-SF6UU5HG.js → enabled-PYMCOQPC.js} +7 -7
  57. package/dist/{goto-AZQWXYPG.js → goto-UNTEW4VI.js} +7 -7
  58. package/dist/guidance/context.d.ts +10 -0
  59. package/dist/guidance/context.d.ts.map +1 -1
  60. package/dist/guidance/readiness.d.ts.map +1 -1
  61. package/dist/guidance/recipes/generic.d.ts.map +1 -1
  62. package/dist/guidance/recipes/pinterest.d.ts.map +1 -1
  63. package/dist/guidance/types.d.ts +4 -0
  64. package/dist/guidance/types.d.ts.map +1 -1
  65. package/dist/{help-B44IBHXL.js → help-QOLCIB3P.js} +8 -7
  66. package/dist/{help-B44IBHXL.js.map → help-QOLCIB3P.js.map} +1 -1
  67. package/dist/{hover-MQRAKKVU.js → hover-ZWY4YOM4.js} +7 -7
  68. package/dist/{html-PLRTU2WS.js → html-M46YBFT3.js} +7 -7
  69. package/dist/index.js +43 -18
  70. package/dist/index.js.map +1 -1
  71. package/dist/{inspector-IY4GBIT6.js → inspector-6YAOI74U.js} +8 -8
  72. package/dist/{inspector-audit-7MQCRJHD.js → inspector-audit-PF64X6SJ.js} +9 -9
  73. package/dist/{inspector-plan-ZAUDHBET.js → inspector-plan-IUGTQV3Q.js} +9 -9
  74. package/dist/inspiredesign/capture-mode.d.ts +8 -0
  75. package/dist/inspiredesign/capture-mode.d.ts.map +1 -1
  76. package/dist/inspiredesign/capture.d.ts +36 -1
  77. package/dist/inspiredesign/capture.d.ts.map +1 -1
  78. package/dist/inspiredesign/contract.d.ts +24 -0
  79. package/dist/inspiredesign/contract.d.ts.map +1 -1
  80. package/dist/inspiredesign/handoff.d.ts +6 -2
  81. package/dist/inspiredesign/handoff.d.ts.map +1 -1
  82. package/dist/inspiredesign/media-analysis/analyzer.d.ts +13 -0
  83. package/dist/inspiredesign/media-analysis/analyzer.d.ts.map +1 -0
  84. package/dist/inspiredesign/media-analysis/design-guidance.d.ts +11 -0
  85. package/dist/inspiredesign/media-analysis/design-guidance.d.ts.map +1 -0
  86. package/dist/inspiredesign/media-analysis/ffmpeg.d.ts +21 -0
  87. package/dist/inspiredesign/media-analysis/ffmpeg.d.ts.map +1 -0
  88. package/dist/inspiredesign/media-analysis/ffprobe.d.ts +8 -0
  89. package/dist/inspiredesign/media-analysis/ffprobe.d.ts.map +1 -0
  90. package/dist/inspiredesign/media-analysis/index.d.ts +10 -0
  91. package/dist/inspiredesign/media-analysis/index.d.ts.map +1 -0
  92. package/dist/inspiredesign/media-analysis/persist.d.ts +6 -0
  93. package/dist/inspiredesign/media-analysis/persist.d.ts.map +1 -0
  94. package/dist/inspiredesign/media-analysis/pixel.d.ts +9 -0
  95. package/dist/inspiredesign/media-analysis/pixel.d.ts.map +1 -0
  96. package/dist/inspiredesign/media-analysis/types.d.ts +163 -0
  97. package/dist/inspiredesign/media-analysis/types.d.ts.map +1 -0
  98. package/dist/inspiredesign/media-analysis/typography-structure.d.ts +3 -0
  99. package/dist/inspiredesign/media-analysis/typography-structure.d.ts.map +1 -0
  100. package/dist/inspiredesign/meta-prompt.d.ts.map +1 -1
  101. package/dist/inspiredesign/motion-evidence.d.ts +73 -0
  102. package/dist/inspiredesign/motion-evidence.d.ts.map +1 -0
  103. package/dist/inspiredesign/pinterest-media-classification.d.ts +27 -0
  104. package/dist/inspiredesign/pinterest-media-classification.d.ts.map +1 -0
  105. package/dist/inspiredesign/pinterest-pin-media-evidence.d.ts +151 -0
  106. package/dist/inspiredesign/pinterest-pin-media-evidence.d.ts.map +1 -0
  107. package/dist/inspiredesign/product-readiness.d.ts +97 -0
  108. package/dist/inspiredesign/product-readiness.d.ts.map +1 -0
  109. package/dist/inspiredesign/reference-pattern-board.d.ts +27 -2
  110. package/dist/inspiredesign/reference-pattern-board.d.ts.map +1 -1
  111. package/dist/inspiredesign/visual-evidence.d.ts +5 -0
  112. package/dist/inspiredesign/visual-evidence.d.ts.map +1 -1
  113. package/dist/{inspiredesign-VHPEO3UK.js → inspiredesign-GZIEXETS.js} +29 -12
  114. package/dist/inspiredesign-GZIEXETS.js.map +1 -0
  115. package/dist/{launch-OCTWPTV5.js → launch-I7WNLWLY.js} +7 -7
  116. package/dist/{list-HUSYADUS.js → list-BAECFJI7.js} +7 -7
  117. package/dist/{list-JWKAMAUA.js → list-BCF4HZ2K.js} +7 -7
  118. package/dist/{macro-resolve-WOXMPZDQ.js → macro-resolve-4GNZYHHW.js} +8 -8
  119. package/dist/{network-poll-WHB62OEF.js → network-poll-DCZ5ZNLP.js} +7 -7
  120. package/dist/{new-IKZBYBNK.js → new-6KZYJTJG.js} +7 -7
  121. package/dist/{open-UA2VI6ZP.js → open-JPGEAJHJ.js} +7 -7
  122. package/dist/opendevbrowser.js +43 -18
  123. package/dist/opendevbrowser.js.map +1 -1
  124. package/dist/{perf-DICS3VKH.js → perf-5X367PRP.js} +7 -7
  125. package/dist/{pointer-down-2XPRZFJC.js → pointer-down-5OAUDDNR.js} +7 -7
  126. package/dist/{pointer-drag-7NY4BOLH.js → pointer-drag-LIW5PY5P.js} +7 -7
  127. package/dist/{pointer-move-FWEXMH37.js → pointer-move-7AMURLJD.js} +7 -7
  128. package/dist/{pointer-up-VU2OHK5D.js → pointer-up-EY652YWL.js} +7 -7
  129. package/dist/{press-W7IZ3FCX.js → press-UIAE5XEF.js} +7 -7
  130. package/dist/{product-video-XCZ6CHR5.js → product-video-B6TLS7VC.js} +9 -9
  131. package/dist/providers/browser-native-discovery.d.ts.map +1 -1
  132. package/dist/providers/renderer.d.ts +10 -1
  133. package/dist/providers/renderer.d.ts.map +1 -1
  134. package/dist/providers/workflows.d.ts +53 -2
  135. package/dist/providers/workflows.d.ts.map +1 -1
  136. package/dist/{providers-XCNSU3T6.js → providers-AERTX6X4.js} +5 -3
  137. package/dist/public-surface/generated-manifest.d.ts +2 -2
  138. package/dist/public-surface/generated-manifest.d.ts.map +1 -1
  139. package/dist/public-surface/source.d.ts +2 -2
  140. package/dist/public-surface/source.d.ts.map +1 -1
  141. package/dist/{research-AYCKHOWK.js → research-AJH6ECYW.js} +9 -9
  142. package/dist/{review-PP2UNSMJ.js → review-RN6XF2YB.js} +7 -7
  143. package/dist/{review-desktop-3JOJFUEJ.js → review-desktop-UJOUS7K2.js} +7 -7
  144. package/dist/{rpc-7EPTJQQ6.js → rpc-VS5Y5FUT.js} +7 -7
  145. package/dist/{run-P6UJS3D4.js → run-EVRIQW7S.js} +5 -5
  146. package/dist/{screencast-start-ZZYNH2HT.js → screencast-start-U6J4FYU4.js} +7 -7
  147. package/dist/{screencast-stop-Y6ADFOFA.js → screencast-stop-EQUPRGMP.js} +7 -7
  148. package/dist/{screenshot-CJB7PMAF.js → screenshot-BENYGC36.js} +7 -7
  149. package/dist/{scroll-BP5MA4ZT.js → scroll-3OALQLX2.js} +7 -7
  150. package/dist/{scroll-into-view-O3RDWLM2.js → scroll-into-view-SNZKBIVB.js} +7 -7
  151. package/dist/{select-QLCNRI36.js → select-JDZDDC3Y.js} +7 -7
  152. package/dist/{serve-OO2MQWGL.js → serve-LOC6ESJ4.js} +6 -6
  153. package/dist/{shopping-UYHCYPAH.js → shopping-267OAYGM.js} +9 -9
  154. package/dist/{snapshot-SXYZ3CMC.js → snapshot-ASYI5UFR.js} +7 -7
  155. package/dist/{status-AL2AHVA5.js → status-47CI4LJX.js} +7 -7
  156. package/dist/{status-QQW7REK4.js → status-N4O6DJTF.js} +8 -8
  157. package/dist/{status-capabilities-AVHJYQQQ.js → status-capabilities-C777JZG4.js} +8 -8
  158. package/dist/{text-B6Z47EOA.js → text-MS2653MW.js} +7 -7
  159. package/dist/tools/inspiredesign_run.d.ts.map +1 -1
  160. package/dist/{type-LR3F3SQY.js → type-UMPSDACC.js} +7 -7
  161. package/dist/{uncheck-5PJEHR7J.js → uncheck-2OZ56D42.js} +7 -7
  162. package/dist/{upload-HQ3QN2OW.js → upload-CD7PRH54.js} +7 -7
  163. package/dist/{use-KFZLMRUH.js → use-MO67AGG7.js} +7 -7
  164. package/dist/{value-TKUFUK5I.js → value-4GI2LRUY.js} +7 -7
  165. package/dist/{visible-P5Z2N2QR.js → visible-VSUFGRFZ.js} +7 -7
  166. package/dist/{wait-BYSHJPSC.js → wait-OQYMFENT.js} +7 -7
  167. package/dist/{windows-6GTD25EU.js → windows-75W2JCW7.js} +8 -8
  168. package/extension/manifest.json +1 -1
  169. package/package.json +1 -1
  170. package/skills/opendevbrowser-best-practices/SKILL.md +41 -30
  171. package/skills/opendevbrowser-best-practices/artifacts/command-channel-reference.md +12 -8
  172. package/skills/opendevbrowser-best-practices/artifacts/parity-gates.md +1 -0
  173. package/skills/opendevbrowser-best-practices/artifacts/provider-workflows.md +19 -0
  174. package/skills/opendevbrowser-best-practices/assets/templates/mode-flag-matrix.json +23 -13
  175. package/skills/opendevbrowser-best-practices/assets/templates/surface-audit-checklist.json +3 -1
  176. package/skills/opendevbrowser-best-practices/scripts/odb-workflow.sh +62 -21
  177. package/skills/opendevbrowser-best-practices/scripts/resolve-odb-cli.sh +28 -0
  178. package/skills/opendevbrowser-best-practices/scripts/validate-skill-assets.sh +15 -0
  179. package/skills/opendevbrowser-best-practices/scripts/validator-fixture-cli.sh +13 -0
  180. package/skills/opendevbrowser-design-agent/SKILL.md +2 -0
  181. package/skills/opendevbrowser-design-agent/artifacts/design-workflows.md +15 -13
  182. package/skills/opendevbrowser-design-agent/artifacts/isolated-preview-validation.md +1 -1
  183. package/skills/opendevbrowser-design-agent/artifacts/research-harvest-workflow.md +14 -7
  184. package/skills/opendevbrowser-design-agent/assets/templates/reference-pattern-board.v1.json +1 -0
  185. package/skills/opendevbrowser-design-agent/scripts/design-workflow.sh +10 -7
  186. package/skills/opendevbrowser-motion-design/SKILL.md +1 -1
  187. package/skills/opendevbrowser-product-presentation-asset/SKILL.md +5 -4
  188. package/skills/opendevbrowser-product-presentation-asset/scripts/capture-screenshots.sh +1 -0
  189. package/skills/opendevbrowser-product-presentation-asset/scripts/collect-product.sh +1 -0
  190. package/skills/opendevbrowser-product-presentation-asset/scripts/download-images.sh +1 -0
  191. package/skills/opendevbrowser-product-presentation-asset/scripts/validate-skill-assets.sh +4 -0
  192. package/skills/opendevbrowser-product-presentation-asset/scripts/write-manifest.sh +1 -0
  193. package/skills/opendevbrowser-research/SKILL.md +1 -0
  194. package/skills/opendevbrowser-research/scripts/render-output.sh +1 -0
  195. package/skills/opendevbrowser-research/scripts/run-research.sh +1 -0
  196. package/skills/opendevbrowser-research/scripts/validate-skill-assets.sh +4 -0
  197. package/skills/opendevbrowser-research/scripts/write-artifacts.sh +1 -0
  198. package/skills/opendevbrowser-shopping/SKILL.md +1 -0
  199. package/skills/opendevbrowser-shopping/scripts/normalize-offers.sh +1 -0
  200. package/skills/opendevbrowser-shopping/scripts/run-deal-hunt.sh +1 -0
  201. package/skills/opendevbrowser-shopping/scripts/run-shopping.sh +1 -0
  202. package/skills/opendevbrowser-shopping/scripts/validate-skill-assets.sh +4 -0
  203. package/dist/chunk-5FDXH4CS.js.map +0 -1
  204. package/dist/chunk-GC2FWISX.js.map +0 -1
  205. package/dist/chunk-IBIHDGTZ.js.map +0 -1
  206. package/dist/chunk-QXJDJDSZ.js.map +0 -1
  207. package/dist/chunk-XRDCSHKZ.js.map +0 -1
  208. package/dist/chunk-ZGCTC5YM.js.map +0 -1
  209. package/dist/inspiredesign-VHPEO3UK.js.map +0 -1
  210. /package/dist/{accessibility-snapshot-VCBXK47S.js.map → accessibility-snapshot-TAFPVLZN.js.map} +0 -0
  211. /package/dist/{active-window-7EUN36LZ.js.map → active-window-MHFMC6NQ.js.map} +0 -0
  212. /package/dist/{annotate-VLBK7YB6.js.map → annotate-5ZFRFQ4B.js.map} +0 -0
  213. /package/dist/{attr-JNANQKM6.js.map → attr-MBF2UCRF.js.map} +0 -0
  214. /package/dist/{canvas-V5LO4JVL.js.map → canvas-CAMD22YU.js.map} +0 -0
  215. /package/dist/{capture-desktop-FKVDWTVG.js.map → capture-desktop-TMZSFA5R.js.map} +0 -0
  216. /package/dist/{capture-window-QVPM2DN2.js.map → capture-window-NZDKD2AE.js.map} +0 -0
  217. /package/dist/{check-V3CWZ56S.js.map → check-MO33GTQ4.js.map} +0 -0
  218. /package/dist/{checked-Q27Q6YZN.js.map → checked-3HDF5X2M.js.map} +0 -0
  219. /package/dist/{chunk-VX47SJZM.js.map → chunk-32ZSOZND.js.map} +0 -0
  220. /package/dist/{chunk-OJAUKABV.js.map → chunk-BHZLEFXW.js.map} +0 -0
  221. /package/dist/{chunk-VY47VKXU.js.map → chunk-FJZY3Z3X.js.map} +0 -0
  222. /package/dist/{chunk-Z3HIX2SE.js.map → chunk-UEAXTWGT.js.map} +0 -0
  223. /package/dist/{click-EQDRSLR3.js.map → click-SWZPJO2U.js.map} +0 -0
  224. /package/dist/{clone-component-SISUXTJS.js.map → clone-component-YTB46YU4.js.map} +0 -0
  225. /package/dist/{clone-page-MLDPCBOY.js.map → clone-page-5FMPHQ3A.js.map} +0 -0
  226. /package/dist/{close-7J7EV237.js.map → close-22SNMDX3.js.map} +0 -0
  227. /package/dist/{close-2LQMJVOA.js.map → close-ORQZCZ2E.js.map} +0 -0
  228. /package/dist/{connect-JFRSIW5M.js.map → connect-EWYITNQU.js.map} +0 -0
  229. /package/dist/{console-poll-NSVVUNEC.js.map → console-poll-LJR6ZTDK.js.map} +0 -0
  230. /package/dist/{cookie-import-B7IQTGTN.js.map → cookie-import-PTAIWPEC.js.map} +0 -0
  231. /package/dist/{cookie-list-YHG7JCZZ.js.map → cookie-list-76C35B5B.js.map} +0 -0
  232. /package/dist/{daemon-ENU4FOV4.js.map → daemon-UKJMDLCB.js.map} +0 -0
  233. /package/dist/{debug-trace-snapshot-KLGU2AWY.js.map → debug-trace-snapshot-PQ5FJART.js.map} +0 -0
  234. /package/dist/{dialog-MUVQIERS.js.map → dialog-WLJDWJV4.js.map} +0 -0
  235. /package/dist/{disconnect-KELQJ45J.js.map → disconnect-FNB4JC2U.js.map} +0 -0
  236. /package/dist/{enabled-SF6UU5HG.js.map → enabled-PYMCOQPC.js.map} +0 -0
  237. /package/dist/{goto-AZQWXYPG.js.map → goto-UNTEW4VI.js.map} +0 -0
  238. /package/dist/{hover-MQRAKKVU.js.map → hover-ZWY4YOM4.js.map} +0 -0
  239. /package/dist/{html-PLRTU2WS.js.map → html-M46YBFT3.js.map} +0 -0
  240. /package/dist/{inspector-IY4GBIT6.js.map → inspector-6YAOI74U.js.map} +0 -0
  241. /package/dist/{inspector-audit-7MQCRJHD.js.map → inspector-audit-PF64X6SJ.js.map} +0 -0
  242. /package/dist/{inspector-plan-ZAUDHBET.js.map → inspector-plan-IUGTQV3Q.js.map} +0 -0
  243. /package/dist/{launch-OCTWPTV5.js.map → launch-I7WNLWLY.js.map} +0 -0
  244. /package/dist/{list-HUSYADUS.js.map → list-BAECFJI7.js.map} +0 -0
  245. /package/dist/{list-JWKAMAUA.js.map → list-BCF4HZ2K.js.map} +0 -0
  246. /package/dist/{macro-resolve-WOXMPZDQ.js.map → macro-resolve-4GNZYHHW.js.map} +0 -0
  247. /package/dist/{network-poll-WHB62OEF.js.map → network-poll-DCZ5ZNLP.js.map} +0 -0
  248. /package/dist/{new-IKZBYBNK.js.map → new-6KZYJTJG.js.map} +0 -0
  249. /package/dist/{open-UA2VI6ZP.js.map → open-JPGEAJHJ.js.map} +0 -0
  250. /package/dist/{perf-DICS3VKH.js.map → perf-5X367PRP.js.map} +0 -0
  251. /package/dist/{pointer-down-2XPRZFJC.js.map → pointer-down-5OAUDDNR.js.map} +0 -0
  252. /package/dist/{pointer-drag-7NY4BOLH.js.map → pointer-drag-LIW5PY5P.js.map} +0 -0
  253. /package/dist/{pointer-move-FWEXMH37.js.map → pointer-move-7AMURLJD.js.map} +0 -0
  254. /package/dist/{pointer-up-VU2OHK5D.js.map → pointer-up-EY652YWL.js.map} +0 -0
  255. /package/dist/{press-W7IZ3FCX.js.map → press-UIAE5XEF.js.map} +0 -0
  256. /package/dist/{product-video-XCZ6CHR5.js.map → product-video-B6TLS7VC.js.map} +0 -0
  257. /package/dist/{providers-XCNSU3T6.js.map → providers-AERTX6X4.js.map} +0 -0
  258. /package/dist/{research-AYCKHOWK.js.map → research-AJH6ECYW.js.map} +0 -0
  259. /package/dist/{review-PP2UNSMJ.js.map → review-RN6XF2YB.js.map} +0 -0
  260. /package/dist/{review-desktop-3JOJFUEJ.js.map → review-desktop-UJOUS7K2.js.map} +0 -0
  261. /package/dist/{rpc-7EPTJQQ6.js.map → rpc-VS5Y5FUT.js.map} +0 -0
  262. /package/dist/{run-P6UJS3D4.js.map → run-EVRIQW7S.js.map} +0 -0
  263. /package/dist/{screencast-start-ZZYNH2HT.js.map → screencast-start-U6J4FYU4.js.map} +0 -0
  264. /package/dist/{screencast-stop-Y6ADFOFA.js.map → screencast-stop-EQUPRGMP.js.map} +0 -0
  265. /package/dist/{screenshot-CJB7PMAF.js.map → screenshot-BENYGC36.js.map} +0 -0
  266. /package/dist/{scroll-BP5MA4ZT.js.map → scroll-3OALQLX2.js.map} +0 -0
  267. /package/dist/{scroll-into-view-O3RDWLM2.js.map → scroll-into-view-SNZKBIVB.js.map} +0 -0
  268. /package/dist/{select-QLCNRI36.js.map → select-JDZDDC3Y.js.map} +0 -0
  269. /package/dist/{serve-OO2MQWGL.js.map → serve-LOC6ESJ4.js.map} +0 -0
  270. /package/dist/{shopping-UYHCYPAH.js.map → shopping-267OAYGM.js.map} +0 -0
  271. /package/dist/{snapshot-SXYZ3CMC.js.map → snapshot-ASYI5UFR.js.map} +0 -0
  272. /package/dist/{status-AL2AHVA5.js.map → status-47CI4LJX.js.map} +0 -0
  273. /package/dist/{status-QQW7REK4.js.map → status-N4O6DJTF.js.map} +0 -0
  274. /package/dist/{status-capabilities-AVHJYQQQ.js.map → status-capabilities-C777JZG4.js.map} +0 -0
  275. /package/dist/{text-B6Z47EOA.js.map → text-MS2653MW.js.map} +0 -0
  276. /package/dist/{type-LR3F3SQY.js.map → type-UMPSDACC.js.map} +0 -0
  277. /package/dist/{uncheck-5PJEHR7J.js.map → uncheck-2OZ56D42.js.map} +0 -0
  278. /package/dist/{upload-HQ3QN2OW.js.map → upload-CD7PRH54.js.map} +0 -0
  279. /package/dist/{use-KFZLMRUH.js.map → use-MO67AGG7.js.map} +0 -0
  280. /package/dist/{value-TKUFUK5I.js.map → value-4GI2LRUY.js.map} +0 -0
  281. /package/dist/{visible-P5Z2N2QR.js.map → visible-VSUFGRFZ.js.map} +0 -0
  282. /package/dist/{wait-BYSHJPSC.js.map → wait-OQYMFENT.js.map} +0 -0
  283. /package/dist/{windows-6GTD25EU.js.map → windows-75W2JCW7.js.map} +0 -0
@@ -52,11 +52,13 @@ import {
52
52
  createDefaultRuntime,
53
53
  extractStructuredContent,
54
54
  inspectChallengePlanFromRuntime,
55
+ inspectPinterestPinMediaBuffer,
56
+ isPinterestPinMediaEvidenceContentType,
55
57
  resolveChallengeAutomationPolicy,
56
58
  resolveProviderRuntimePolicy,
57
59
  resolveWorkflowArtifactRoot,
58
60
  toSnippet
59
- } from "./chunk-5FDXH4CS.js";
61
+ } from "./chunk-WTWSBEBW.js";
60
62
  import {
61
63
  buildBlockerArtifacts,
62
64
  classifyBlockerSignal,
@@ -3664,8 +3666,9 @@ import { parse, resolve as resolve6 } from "path";
3664
3666
 
3665
3667
  // src/browser/browser-manager.ts
3666
3668
  import { randomUUID as randomUUID11 } from "crypto";
3667
- import { access as access2, mkdir as mkdir5, rm as rm3, writeFile as writeFile3 } from "fs/promises";
3668
- import { join as join10 } from "path";
3669
+ import { constants as fsConstants } from "fs";
3670
+ import { access as access2, mkdir as mkdir5, open, rm as rm3, unlink, writeFile as writeFile3 } from "fs/promises";
3671
+ import { dirname as dirname2, join as join10 } from "path";
3669
3672
  import { freemem, totalmem } from "os";
3670
3673
  import { Mutex } from "async-mutex";
3671
3674
 
@@ -6713,6 +6716,469 @@ var BrowserScreencastRecorder = class {
6713
6716
 
6714
6717
  // src/browser/browser-manager.ts
6715
6718
  var LEGACY_EXTENSION_OPERATION_TIMEOUT_MS = 5e3;
6719
+ var PINTEREST_PIN_MEDIA_DEFAULT_TIMEOUT_MS = 5e3;
6720
+ var PINTEREST_PIN_MEDIA_DOM_INSPECTION_MAX_TIMEOUT_MS = 1e4;
6721
+ var PINTEREST_PIN_MEDIA_CDP_SESSION_MAX_TIMEOUT_MS = 5e3;
6722
+ var PINTEREST_PIN_MEDIA_CDP_DETACH_MAX_TIMEOUT_MS = 1e3;
6723
+ var PINTEREST_PIN_MEDIA_FETCH_MAX_TIMEOUT_MS = 2e4;
6724
+ var PINTEREST_PIN_MEDIA_MAX_BYTES = 2e7;
6725
+ var PINTEREST_PIN_MEDIA_MAX_REDIRECTS = 3;
6726
+ var PINTEREST_PIN_MEDIA_MIN_EDGE_PX = 160;
6727
+ var PINTEREST_PIN_MEDIA_REJECTION_LIMIT = 12;
6728
+ var PINTEREST_PIN_IMAGE_MEDIA_HOST = "i.pinimg.com";
6729
+ var PINTEREST_PIN_VIDEO_MEDIA_HOST = "v.pinimg.com";
6730
+ var PINTEREST_PIN_VIDEO_MEDIA_HOST_PATTERN = /^v\d+(?:-[a-z]+)?\.pinimg\.com$/i;
6731
+ var PINTEREST_PIN_MEDIA_VIDEO_CONTENT_TYPE = "video/mp4";
6732
+ var PINTEREST_PIN_MEDIA_GENERIC_BINARY_CONTENT_TYPES = /* @__PURE__ */ new Set([
6733
+ "application/octet-stream",
6734
+ "application/x-binary",
6735
+ "binary/octet-stream"
6736
+ ]);
6737
+ var MP4_FILE_TYPE_BOX_MIN_BYTES = 12;
6738
+ var MP4_FILE_TYPE_BOX_MARKER_START = 4;
6739
+ var MP4_FILE_TYPE_BOX_MARKER_END = 8;
6740
+ var MP4_FILE_TYPE_BOX_MARKER = "ftyp";
6741
+ var HTTP_REDIRECT_STATUS_MIN = 300;
6742
+ var HTTP_REDIRECT_STATUS_MAX_EXCLUSIVE = 400;
6743
+ var PINTEREST_PIN_MEDIA_NOFOLLOW_FLAG = typeof fsConstants.O_NOFOLLOW === "number" ? fsConstants.O_NOFOLLOW : 0;
6744
+ var PINTEREST_PIN_MEDIA_OUTPUT_OPEN_FLAGS = fsConstants.O_WRONLY | fsConstants.O_CREAT | fsConstants.O_EXCL | PINTEREST_PIN_MEDIA_NOFOLLOW_FLAG;
6745
+ function pinterestPinSourceChanged(pageUrl, extractedSourceUrl) {
6746
+ const pagePinId = extractPinterestPinId(pageUrl);
6747
+ const extractedPinId = extractPinterestPinId(extractedSourceUrl);
6748
+ return Boolean(pagePinId && extractedPinId && pagePinId !== extractedPinId);
6749
+ }
6750
+ function readAuthoritativePinterestSourceUrl(pageUrl, extractedSourceUrl) {
6751
+ return extractPinterestPinId(extractedSourceUrl) ? extractedSourceUrl : pageUrl;
6752
+ }
6753
+ function extractPinterestPinId(value) {
6754
+ if (!value) {
6755
+ return void 0;
6756
+ }
6757
+ const match = value.match(/\/pin\/(\d+)/i);
6758
+ return match?.[1];
6759
+ }
6760
+ function isFirstPartyPinterestMediaUrl(value) {
6761
+ if (!value) {
6762
+ return false;
6763
+ }
6764
+ try {
6765
+ const parsed = new URL(value);
6766
+ const hostname = parsed.hostname.toLowerCase();
6767
+ return parsed.protocol === "https:" && (hostname === PINTEREST_PIN_IMAGE_MEDIA_HOST || hostname === PINTEREST_PIN_VIDEO_MEDIA_HOST || PINTEREST_PIN_VIDEO_MEDIA_HOST_PATTERN.test(hostname));
6768
+ } catch {
6769
+ return false;
6770
+ }
6771
+ }
6772
+ function isFirstPartyPinterestVideoMediaUrl(value) {
6773
+ if (!value) {
6774
+ return false;
6775
+ }
6776
+ try {
6777
+ const parsed = new URL(value);
6778
+ const hostname = parsed.hostname.toLowerCase();
6779
+ return parsed.protocol === "https:" && parsed.pathname.toLowerCase().endsWith(".mp4") && (hostname === PINTEREST_PIN_VIDEO_MEDIA_HOST || PINTEREST_PIN_VIDEO_MEDIA_HOST_PATTERN.test(hostname));
6780
+ } catch {
6781
+ return false;
6782
+ }
6783
+ }
6784
+ function normalizePinterestResponseContentType(contentType) {
6785
+ const normalized = contentType?.split(";")[0]?.trim().toLowerCase();
6786
+ return normalized && normalized.length > 0 ? normalized : void 0;
6787
+ }
6788
+ function isLikelyMp4Bytes(bytes) {
6789
+ return bytes.length >= MP4_FILE_TYPE_BOX_MIN_BYTES && bytes.subarray(MP4_FILE_TYPE_BOX_MARKER_START, MP4_FILE_TYPE_BOX_MARKER_END).toString("ascii") === MP4_FILE_TYPE_BOX_MARKER;
6790
+ }
6791
+ function isCompatiblePinterestVideoContentType(contentType) {
6792
+ return !contentType || contentType === PINTEREST_PIN_MEDIA_VIDEO_CONTENT_TYPE || PINTEREST_PIN_MEDIA_GENERIC_BINARY_CONTENT_TYPES.has(contentType);
6793
+ }
6794
+ function isCompatiblePinterestImageContentType(contentType) {
6795
+ return !contentType || PINTEREST_PIN_MEDIA_GENERIC_BINARY_CONTENT_TYPES.has(contentType) || isPinterestPinMediaEvidenceContentType(contentType) && contentType.startsWith("image/");
6796
+ }
6797
+ function assertFetchedPinterestCandidateMatchesKind(candidate, fetched) {
6798
+ const contentType = normalizePinterestResponseContentType(fetched.contentType);
6799
+ if (candidate.kind === "video") {
6800
+ if (!isFirstPartyPinterestVideoMediaUrl(fetched.finalUrl)) {
6801
+ throw new Error("Pinterest pin media video fetch returned a non-MP4 final URL.");
6802
+ }
6803
+ if (!isCompatiblePinterestVideoContentType(contentType)) {
6804
+ throw new Error("Pinterest pin media video fetch returned non-MP4 content.");
6805
+ }
6806
+ if (!isLikelyMp4Bytes(fetched.bytes)) {
6807
+ throw new Error("Pinterest pin media video fetch returned bytes without an MP4 file type box.");
6808
+ }
6809
+ return;
6810
+ }
6811
+ if (!isCompatiblePinterestImageContentType(contentType)) {
6812
+ throw new Error("Pinterest pin media image fetch returned non-image content.");
6813
+ }
6814
+ const byteInspection = inspectPinterestPinMediaBuffer(fetched.bytes);
6815
+ if (!byteInspection.contentType?.startsWith("image/")) {
6816
+ throw new Error("Pinterest pin media image fetch returned bytes without an image signature.");
6817
+ }
6818
+ if (contentType && !PINTEREST_PIN_MEDIA_GENERIC_BINARY_CONTENT_TYPES.has(contentType) && contentType !== byteInspection.contentType) {
6819
+ throw new Error("Pinterest pin media image fetch returned bytes that do not match the response content type.");
6820
+ }
6821
+ }
6822
+ function pinterestCandidateArea(candidate) {
6823
+ const width = candidate.width ?? candidate.naturalWidth ?? candidate.rect?.width ?? 0;
6824
+ const height = candidate.height ?? candidate.naturalHeight ?? candidate.rect?.height ?? 0;
6825
+ return width * height;
6826
+ }
6827
+ function summarizeRejectedPinterestCandidate(candidate, reasons) {
6828
+ return {
6829
+ kind: candidate.kind,
6830
+ ...candidate.mediaUrl ? { mediaUrl: candidate.mediaUrl } : {},
6831
+ ...candidate.candidateSelector ? { candidateSelector: candidate.candidateSelector } : {},
6832
+ ...candidate.candidateRole ? { candidateRole: candidate.candidateRole } : {},
6833
+ ...candidate.alt ? { alt: candidate.alt } : {},
6834
+ ...candidate.width ? { width: candidate.width } : {},
6835
+ ...candidate.height ? { height: candidate.height } : {},
6836
+ ...candidate.rect ? { rect: candidate.rect } : {},
6837
+ ancestry: candidate.ancestry.slice(0, 6),
6838
+ reasons
6839
+ };
6840
+ }
6841
+ function rejectionReasonsForPinterestCandidate(candidate, sourcePinId) {
6842
+ const reasons = [];
6843
+ if (!isFirstPartyPinterestMediaUrl(candidate.mediaUrl)) {
6844
+ reasons.push("non_first_party_media_url");
6845
+ }
6846
+ if (!candidate.visible) {
6847
+ reasons.push("not_visible");
6848
+ }
6849
+ const width = candidate.width ?? candidate.naturalWidth ?? candidate.rect?.width ?? 0;
6850
+ const height = candidate.height ?? candidate.naturalHeight ?? candidate.rect?.height ?? 0;
6851
+ if (width < PINTEREST_PIN_MEDIA_MIN_EDGE_PX || height < PINTEREST_PIN_MEDIA_MIN_EDGE_PX) {
6852
+ reasons.push("media_too_small");
6853
+ }
6854
+ if (!sourcePinId) {
6855
+ reasons.push("missing_source_pin_id");
6856
+ }
6857
+ if (sourcePinId && candidate.linkedPinId && candidate.linkedPinId !== sourcePinId) {
6858
+ reasons.push("linked_to_different_pin");
6859
+ }
6860
+ if (sourcePinId && !candidate.linkedPinId && !candidate.insideCanonicalMainPinMediaContainer) {
6861
+ reasons.push("missing_pin_source_proof");
6862
+ }
6863
+ const noiseHasCanonicalSourceProof = Boolean(
6864
+ candidate.insideCanonicalMainPinMediaContainer && sourcePinId && (!candidate.linkedPinId || candidate.linkedPinId === sourcePinId)
6865
+ );
6866
+ if (candidate.noiseSignals.length > 0 && !noiseHasCanonicalSourceProof) {
6867
+ reasons.push(`noise_ancestry:${candidate.noiseSignals[0]}`);
6868
+ }
6869
+ return reasons;
6870
+ }
6871
+ function selectPinterestPinMediaCandidate(extraction, pageUrl) {
6872
+ const sourcePinId = extractPinterestPinId(pageUrl);
6873
+ const accepted = [];
6874
+ const rejected = [];
6875
+ for (const candidate of extraction.candidates) {
6876
+ const reasons = rejectionReasonsForPinterestCandidate(candidate, sourcePinId);
6877
+ if (reasons.length === 0) {
6878
+ accepted.push(candidate);
6879
+ } else if (rejected.length < PINTEREST_PIN_MEDIA_REJECTION_LIMIT) {
6880
+ rejected.push(summarizeRejectedPinterestCandidate(candidate, reasons));
6881
+ }
6882
+ }
6883
+ accepted.sort((left, right) => {
6884
+ const scoreDelta = right.score - left.score;
6885
+ return scoreDelta !== 0 ? scoreDelta : pinterestCandidateArea(right) - pinterestCandidateArea(left);
6886
+ });
6887
+ return { selected: accepted[0], acceptedCandidates: accepted, rejectedCandidates: rejected };
6888
+ }
6889
+ function warningsForSelectedPinterestCandidate(candidate) {
6890
+ const warnings = /* @__PURE__ */ new Set();
6891
+ for (const signal of candidate.noiseSignals) {
6892
+ warnings.add(signal === "shopping" ? "pin_media_noise:ad_shopping" : `pin_media_noise:${signal}`);
6893
+ }
6894
+ return Array.from(warnings);
6895
+ }
6896
+ function pinterestCandidateCaptureFailureReason(error) {
6897
+ if (error instanceof Error && error.name === "AbortError") return "selected_candidate_fetch_failed:aborted";
6898
+ return "selected_candidate_fetch_failed";
6899
+ }
6900
+ function clampPinterestPinMediaOperationTimeout(timeoutMs, maxTimeoutMs) {
6901
+ if (!Number.isFinite(timeoutMs)) {
6902
+ return maxTimeoutMs;
6903
+ }
6904
+ return Math.max(1, Math.min(timeoutMs, maxTimeoutMs));
6905
+ }
6906
+ function isPinterestPinMediaDomInspectionTimeout(error) {
6907
+ return error instanceof Error && error.message.startsWith("Pinterest pin media DOM inspection timed out");
6908
+ }
6909
+ function parsePinterestPinMediaCdpExtraction(result) {
6910
+ if (result.exceptionDetails) {
6911
+ const detail = result.exceptionDetails.exception?.description ?? result.exceptionDetails.text;
6912
+ throw new Error(detail ?? "Pinterest pin media CDP inspection failed.");
6913
+ }
6914
+ const value = result.result?.value;
6915
+ if (!value || typeof value.sourceUrl !== "string" || !Array.isArray(value.candidates)) {
6916
+ throw new Error("Pinterest pin media CDP inspection returned an invalid result.");
6917
+ }
6918
+ return value;
6919
+ }
6920
+ async function withPinterestPinMediaOperationTimeout(operation, timeoutMs, message) {
6921
+ let timer = null;
6922
+ try {
6923
+ return await Promise.race([
6924
+ operation,
6925
+ new Promise((_resolve, reject) => {
6926
+ timer = setTimeout(() => reject(new Error(message)), timeoutMs);
6927
+ })
6928
+ ]);
6929
+ } finally {
6930
+ if (timer) {
6931
+ clearTimeout(timer);
6932
+ }
6933
+ }
6934
+ }
6935
+ function detachPinterestPinMediaCdpSession(session) {
6936
+ void withPinterestPinMediaOperationTimeout(
6937
+ session.detach(),
6938
+ PINTEREST_PIN_MEDIA_CDP_DETACH_MAX_TIMEOUT_MS,
6939
+ `Pinterest pin media CDP session detach timed out after ${PINTEREST_PIN_MEDIA_CDP_DETACH_MAX_TIMEOUT_MS}ms.`
6940
+ ).catch(() => void 0);
6941
+ }
6942
+ function readPinterestPinMediaCandidatesInPage() {
6943
+ const maxCandidates = 30;
6944
+ const ancestryLimit = 6;
6945
+ const selectors = [
6946
+ "img.closeup-image-main-MainPinImage",
6947
+ "img[class*='closeup-image-main-MainPinImage']",
6948
+ "img[elementtiming='closeup-image-main-MainPinImage']",
6949
+ "img.StoryPinImageBlock-MainPinImage",
6950
+ "img[class*='StoryPinImageBlock-MainPinImage']",
6951
+ "[data-test-id='closeup-image-main'] img",
6952
+ "[data-test-id='closeup-image'] img",
6953
+ "[id^='closeup-image-container-'] img",
6954
+ "[class*='closeup-image-main-MainPinImage'] img",
6955
+ "[class*='StoryPinImageBlock-MainPinImage'] img",
6956
+ "video",
6957
+ "video[poster]",
6958
+ "[data-test-id*='pin'] video",
6959
+ "[data-test-id*='pin'] video[poster]",
6960
+ "[data-test-id*='closeup'] video",
6961
+ "[data-test-id*='closeup'] video[poster]"
6962
+ ];
6963
+ const elements = [];
6964
+ const seen = /* @__PURE__ */ new Set();
6965
+ for (const selector of selectors) {
6966
+ for (const element of Array.from(document.querySelectorAll(selector))) {
6967
+ if (!seen.has(element) && elements.length < maxCandidates) {
6968
+ seen.add(element);
6969
+ elements.push(element);
6970
+ }
6971
+ }
6972
+ }
6973
+ const describeElement = (element) => {
6974
+ const tag = element.tagName.toLowerCase();
6975
+ const id2 = element.id ? `#${element.id.slice(0, 48)}` : "";
6976
+ const classes = Array.from(element.classList).slice(0, 4).map((value) => `.${value.slice(0, 48)}`).join("");
6977
+ const testId = element.getAttribute("data-test-id");
6978
+ const role = element.getAttribute("role");
6979
+ return [tag + id2 + classes, testId ? `data-test-id=${testId.slice(0, 80)}` : "", role ? `role=${role}` : ""].filter(Boolean).join(" ");
6980
+ };
6981
+ const ancestryFor = (element) => {
6982
+ const ancestry = [];
6983
+ let current = element;
6984
+ while (current && ancestry.length < ancestryLimit) {
6985
+ ancestry.push(describeElement(current));
6986
+ current = current.parentElement;
6987
+ }
6988
+ return { ancestry, combined: ancestry.join(" ").toLowerCase() };
6989
+ };
6990
+ const readPinId = (element) => {
6991
+ const link = element.closest("a[href*='/pin/']");
6992
+ const href = link?.getAttribute("href") ?? "";
6993
+ const match = href.match(/\/pin\/(\d+)/i);
6994
+ return match?.[1];
6995
+ };
6996
+ const isInsideCanonicalMainPinMediaContainer = (element) => {
6997
+ const container = element.closest([
6998
+ "[data-test-id='pin-closeup']",
6999
+ "[data-test-id='story-pin']",
7000
+ "[data-test-id='closeup-layout']",
7001
+ "[data-test-id='closeup-image']",
7002
+ "[data-test-id='closeup-image-main']",
7003
+ "[data-test-id='pdp-container']",
7004
+ "[data-test-id='pin-closeup-image']",
7005
+ "[data-test-id='pin-closeup-image-container']",
7006
+ "[data-test-id='visual-content-container']"
7007
+ ].join(","));
7008
+ if (!container) {
7009
+ return false;
7010
+ }
7011
+ let current = element;
7012
+ while (current && current !== container) {
7013
+ if (readNoiseSignals(describeElement(current).toLowerCase()).length > 0) {
7014
+ return false;
7015
+ }
7016
+ current = current.parentElement;
7017
+ }
7018
+ return true;
7019
+ };
7020
+ const hasDelimitedNoiseToken = (combined, token) => new RegExp(`(^|[^a-z0-9])${token}($|[^a-z0-9])`).test(combined);
7021
+ const readNoiseSignals = (combined) => {
7022
+ const signals = [];
7023
+ const checks = [
7024
+ [(value) => value.includes("related"), "related"],
7025
+ [(value) => value.includes("recommend"), "recommendation"],
7026
+ [(value) => value.includes("rail"), "rail"],
7027
+ [(value) => value.includes("carousel"), "carousel"],
7028
+ [(value) => value.includes("grid"), "grid"],
7029
+ [(value) => value.includes("search"), "search"],
7030
+ [(value) => value.includes("avatar"), "avatar"],
7031
+ [(value) => value.includes("profile"), "profile"],
7032
+ [(value) => value.includes("comment"), "comment"],
7033
+ [(value) => hasDelimitedNoiseToken(value, "ad") || hasDelimitedNoiseToken(value, "ads"), "ad"],
7034
+ [(value) => value.includes("promoted"), "ad"],
7035
+ [(value) => value.includes("sponsor"), "ad"],
7036
+ [(value) => value.includes("shopping"), "shopping"],
7037
+ [(value) => value.includes("shop"), "shopping"],
7038
+ [(value) => value.includes("thumbnail"), "thumbnail"],
7039
+ [(value) => value.includes("thumb"), "thumbnail"]
7040
+ ];
7041
+ for (const [matches, signal] of checks) {
7042
+ if (matches(combined) && !signals.includes(signal)) {
7043
+ signals.push(signal);
7044
+ }
7045
+ }
7046
+ return signals;
7047
+ };
7048
+ const readRect = (element) => {
7049
+ const rect = element.getBoundingClientRect();
7050
+ return { x: rect.x, y: rect.y, width: rect.width, height: rect.height };
7051
+ };
7052
+ const isVisible2 = (element, rect) => {
7053
+ const style = window.getComputedStyle(element);
7054
+ return style.display !== "none" && style.visibility !== "hidden" && style.opacity !== "0" && rect.width > 0 && rect.height > 0;
7055
+ };
7056
+ const pickSrcsetUrl = (srcset) => {
7057
+ const entries = srcset.split(",").map((entry) => entry.trim()).filter(Boolean);
7058
+ const last2 = entries.at(-1);
7059
+ return last2?.split(/\s+/)[0];
7060
+ };
7061
+ const isFirstPartyPinterestVideoHost = (hostname) => hostname === "v.pinimg.com" || /^v\d+(?:-[a-z]+)?\.pinimg\.com$/i.test(hostname);
7062
+ const isFirstPartyPinterestVideoUrl = (value) => {
7063
+ if (!value) return false;
7064
+ try {
7065
+ const parsed = new URL(value);
7066
+ return parsed.protocol === "https:" && isFirstPartyPinterestVideoHost(parsed.hostname.toLowerCase()) && parsed.pathname.toLowerCase().endsWith(".mp4");
7067
+ } catch {
7068
+ return false;
7069
+ }
7070
+ };
7071
+ const derivePinterestMp4UrlFromHls = (value) => {
7072
+ if (!value) return void 0;
7073
+ try {
7074
+ const parsed = new URL(value);
7075
+ const hostname = parsed.hostname.toLowerCase();
7076
+ if (parsed.protocol !== "https:" || !isFirstPartyPinterestVideoHost(hostname)) {
7077
+ return void 0;
7078
+ }
7079
+ const match = parsed.pathname.match(/^\/videos\/([^/]+)\/hls\/([a-f0-9]{2})\/([a-f0-9]{2})\/([a-f0-9]{2})\/([a-f0-9]+)(?:_\d+w)?\.m3u8$/i);
7080
+ if (!match) return void 0;
7081
+ const [, lane, first, second, third, digest] = match;
7082
+ if (!lane || !first || !second || !third || !digest) return void 0;
7083
+ parsed.pathname = `/videos/${lane}/720p/${first}/${second}/${third}/${digest}.mp4`;
7084
+ parsed.search = "";
7085
+ parsed.hash = "";
7086
+ return parsed.toString();
7087
+ } catch {
7088
+ return void 0;
7089
+ }
7090
+ };
7091
+ const readPinterestVideoUrl = (value) => isFirstPartyPinterestVideoUrl(value) ? value : derivePinterestMp4UrlFromHls(value);
7092
+ const readVideoSourceUrl = (video) => {
7093
+ const candidateUrls = [video.currentSrc, video.src];
7094
+ for (const source of Array.from(video.querySelectorAll("source"))) {
7095
+ const sourceUrl = source.src || source.getAttribute("src");
7096
+ candidateUrls.push(sourceUrl ?? "");
7097
+ }
7098
+ const firstPartyDirectUrl = candidateUrls.map(readPinterestVideoUrl).find(Boolean);
7099
+ if (firstPartyDirectUrl) return firstPartyDirectUrl;
7100
+ return candidateUrls.find(Boolean);
7101
+ };
7102
+ const candidates = elements.flatMap((element) => {
7103
+ const tag = element.tagName.toLowerCase();
7104
+ const rect = readRect(element);
7105
+ const { ancestry, combined } = ancestryFor(element);
7106
+ const classText = (element.getAttribute("class") ?? "").toLowerCase();
7107
+ const positiveSignals = [
7108
+ classText.includes("closeup-image-main-mainpinimage") ? "closeup-image-main-MainPinImage" : "",
7109
+ element.getAttribute("elementtiming") === "closeup-image-main-MainPinImage" ? "closeup-image-main-MainPinImage" : "",
7110
+ classText.includes("storypinimageblock-mainpinimage") ? "StoryPinImageBlock-MainPinImage" : "",
7111
+ tag === "video" ? "video" : "",
7112
+ tag === "video" && element.hasAttribute("poster") ? "video[poster]" : ""
7113
+ ].filter(Boolean);
7114
+ if (tag === "video") {
7115
+ const video = element;
7116
+ const sharedVideoCandidate = {
7117
+ poster: video.poster || void 0,
7118
+ candidateRole: element.getAttribute("role") ?? element.closest("[role]")?.getAttribute("role") ?? void 0,
7119
+ width: video.videoWidth || rect.width,
7120
+ height: video.videoHeight || rect.height,
7121
+ rect,
7122
+ visible: isVisible2(element, rect),
7123
+ ancestry,
7124
+ linkedPinId: readPinId(element),
7125
+ noiseSignals: readNoiseSignals(combined),
7126
+ insideCanonicalMainPinMediaContainer: isInsideCanonicalMainPinMediaContainer(element)
7127
+ };
7128
+ const videoCandidates = [];
7129
+ const videoSourceUrl = readVideoSourceUrl(video);
7130
+ if (videoSourceUrl) {
7131
+ videoCandidates.push({
7132
+ ...sharedVideoCandidate,
7133
+ kind: "video",
7134
+ mediaUrl: videoSourceUrl,
7135
+ candidateSelector: "video",
7136
+ positiveSignals: [...positiveSignals, "video[source]"],
7137
+ score: positiveSignals.length * 100 + 250 + rect.width * rect.height / 1e4
7138
+ });
7139
+ }
7140
+ if (video.poster) {
7141
+ videoCandidates.push({
7142
+ ...sharedVideoCandidate,
7143
+ kind: "video_poster",
7144
+ mediaUrl: video.poster,
7145
+ candidateSelector: "video[poster]",
7146
+ positiveSignals,
7147
+ score: positiveSignals.length * 100 + rect.width * rect.height / 1e4
7148
+ });
7149
+ }
7150
+ return videoCandidates;
7151
+ }
7152
+ const image = tag === "img" ? element : element.querySelector("img");
7153
+ if (!image) {
7154
+ return [];
7155
+ }
7156
+ const imageRect = tag === "img" ? rect : readRect(image);
7157
+ const srcset = image.getAttribute("srcset") ?? void 0;
7158
+ const mediaUrl = image.currentSrc || image.src || pickSrcsetUrl(srcset ?? "");
7159
+ return [{
7160
+ kind: "image",
7161
+ mediaUrl,
7162
+ srcset,
7163
+ candidateSelector: positiveSignals[0] ?? describeElement(image),
7164
+ candidateRole: image.getAttribute("role") ?? image.closest("[role]")?.getAttribute("role") ?? void 0,
7165
+ alt: image.getAttribute("alt") ?? void 0,
7166
+ width: image.naturalWidth || imageRect.width,
7167
+ height: image.naturalHeight || imageRect.height,
7168
+ naturalWidth: image.naturalWidth || void 0,
7169
+ naturalHeight: image.naturalHeight || void 0,
7170
+ rect: imageRect,
7171
+ visible: isVisible2(image, imageRect),
7172
+ ancestry,
7173
+ linkedPinId: readPinId(image),
7174
+ positiveSignals,
7175
+ noiseSignals: readNoiseSignals(combined),
7176
+ insideCanonicalMainPinMediaContainer: isInsideCanonicalMainPinMediaContainer(image),
7177
+ score: positiveSignals.length * 100 + imageRect.width * imageRect.height / 1e4
7178
+ }];
7179
+ });
7180
+ return { sourceUrl: document.URL, candidates };
7181
+ }
6716
7182
  var DOM_GET_ATTR_DECLARATION = `
6717
7183
  function(name) {
6718
7184
  /* odb-dom-get-attr */
@@ -6916,6 +7382,104 @@ var DOM_FILE_INPUT_INFO_DECLARATION = `
6916
7382
  };
6917
7383
  }
6918
7384
  `;
7385
+ var assertPinterestPinMediaByteLimit = (byteLength) => {
7386
+ if (byteLength > PINTEREST_PIN_MEDIA_MAX_BYTES) {
7387
+ throw new Error(`Pinterest pin media fetch exceeded ${PINTEREST_PIN_MEDIA_MAX_BYTES} bytes.`);
7388
+ }
7389
+ };
7390
+ var readPinterestPinMediaContentLength = (headers) => {
7391
+ const value = headers.get("content-length");
7392
+ if (!value) return void 0;
7393
+ const parsed = Number(value);
7394
+ return Number.isSafeInteger(parsed) && parsed >= 0 ? parsed : void 0;
7395
+ };
7396
+ var isPinterestPinMediaRedirectStatus = (status) => status >= HTTP_REDIRECT_STATUS_MIN && status < HTTP_REDIRECT_STATUS_MAX_EXCLUSIVE;
7397
+ var readFirstPartyPinterestPinMediaRedirect = (baseUrl, location2) => {
7398
+ if (!location2) {
7399
+ throw new Error("Pinterest pin media fetch redirected without a location header.");
7400
+ }
7401
+ let redirectedUrl;
7402
+ try {
7403
+ redirectedUrl = new URL(location2, baseUrl).href;
7404
+ } catch {
7405
+ throw new Error("Pinterest pin media fetch redirected to an invalid media URL.");
7406
+ }
7407
+ if (!isFirstPartyPinterestMediaUrl(redirectedUrl)) {
7408
+ throw new Error("Pinterest pin media fetch redirected outside first-party media.");
7409
+ }
7410
+ return redirectedUrl;
7411
+ };
7412
+ var discardPinterestPinMediaResponseBody = async (response) => {
7413
+ await response.body?.cancel().catch(() => void 0);
7414
+ };
7415
+ var fetchPinterestPinMediaResponse = async (mediaUrl, signal) => {
7416
+ let nextUrl = mediaUrl;
7417
+ for (let redirectCount = 0; redirectCount <= PINTEREST_PIN_MEDIA_MAX_REDIRECTS; redirectCount += 1) {
7418
+ const response = await fetch(nextUrl, { signal, redirect: "manual" });
7419
+ if (!isPinterestPinMediaRedirectStatus(response.status)) {
7420
+ const finalUrl = response.url || nextUrl;
7421
+ if (!isFirstPartyPinterestMediaUrl(finalUrl)) {
7422
+ await discardPinterestPinMediaResponseBody(response);
7423
+ throw new Error("Pinterest pin media fetch redirected outside first-party media.");
7424
+ }
7425
+ return { response, finalUrl };
7426
+ }
7427
+ let redirectedUrl;
7428
+ try {
7429
+ redirectedUrl = readFirstPartyPinterestPinMediaRedirect(nextUrl, response.headers.get("location"));
7430
+ } catch (error) {
7431
+ await discardPinterestPinMediaResponseBody(response);
7432
+ throw error;
7433
+ }
7434
+ nextUrl = redirectedUrl;
7435
+ await discardPinterestPinMediaResponseBody(response);
7436
+ }
7437
+ throw new Error("Pinterest pin media fetch exceeded the first-party redirect limit.");
7438
+ };
7439
+ var readBoundedPinterestPinMediaBytes = async (response) => {
7440
+ const reader = response.body?.getReader();
7441
+ if (!reader) {
7442
+ throw new Error("Pinterest pin media fetch returned an empty media body.");
7443
+ }
7444
+ const chunks = [];
7445
+ let totalBytes = 0;
7446
+ try {
7447
+ while (true) {
7448
+ const { done, value } = await reader.read();
7449
+ if (done) break;
7450
+ if (!value) continue;
7451
+ totalBytes += value.byteLength;
7452
+ assertPinterestPinMediaByteLimit(totalBytes);
7453
+ chunks.push(Buffer.from(value));
7454
+ }
7455
+ if (totalBytes === 0) {
7456
+ throw new Error("Pinterest pin media fetch returned an empty media body.");
7457
+ }
7458
+ return Buffer.concat(chunks, totalBytes);
7459
+ } catch (error) {
7460
+ await reader.cancel().catch(() => void 0);
7461
+ throw error;
7462
+ }
7463
+ };
7464
+ var writePinterestPinMediaOutput = async (path4, bytes) => {
7465
+ await mkdir5(dirname2(path4), { recursive: true });
7466
+ let handle;
7467
+ let createdOutput = false;
7468
+ let writeFailed = false;
7469
+ try {
7470
+ handle = await open(path4, PINTEREST_PIN_MEDIA_OUTPUT_OPEN_FLAGS, 384);
7471
+ createdOutput = true;
7472
+ await handle.writeFile(bytes);
7473
+ } catch {
7474
+ writeFailed = createdOutput;
7475
+ throw new Error("Pinterest pin media output path could not be opened as a new non-symlink file.");
7476
+ } finally {
7477
+ await handle?.close().catch(() => void 0);
7478
+ if (writeFailed) {
7479
+ await unlink(path4).catch(() => void 0);
7480
+ }
7481
+ }
7482
+ };
6919
7483
  var BrowserManager = class {
6920
7484
  store = new SessionStore();
6921
7485
  sessions = /* @__PURE__ */ new Map();
@@ -8258,6 +8822,166 @@ var BrowserManager = class {
8258
8822
  }
8259
8823
  });
8260
8824
  }
8825
+ async capturePinterestPinMedia(sessionId, options) {
8826
+ if (!options.path) {
8827
+ throw new Error("Pinterest pin media capture requires an output path.");
8828
+ }
8829
+ return this.runTargetScoped(sessionId, options.targetId, async ({ managed, page, targetId }) => {
8830
+ const pageSourceUrl = this.safePageUrl(page, "BrowserManager.capturePinterestPinMedia") ?? "";
8831
+ const extraction = await this.evaluatePinterestPinMediaCandidates(managed, page, options.timeoutMs);
8832
+ const sourceUrl = readAuthoritativePinterestSourceUrl(pageSourceUrl, extraction.sourceUrl);
8833
+ if (pinterestPinSourceChanged(pageSourceUrl, extraction.sourceUrl)) {
8834
+ return {
8835
+ status: "not_found",
8836
+ sourceUrl,
8837
+ targetId,
8838
+ rejectedCandidates: extraction.candidates.slice(0, PINTEREST_PIN_MEDIA_REJECTION_LIMIT).map((candidate) => summarizeRejectedPinterestCandidate(candidate, ["source_url_changed"]))
8839
+ };
8840
+ }
8841
+ const selection = selectPinterestPinMediaCandidate(extraction, sourceUrl);
8842
+ if (!selection.selected) {
8843
+ return {
8844
+ status: "not_found",
8845
+ sourceUrl,
8846
+ targetId,
8847
+ rejectedCandidates: selection.rejectedCandidates
8848
+ };
8849
+ }
8850
+ const rejectedCandidates = [...selection.rejectedCandidates];
8851
+ let lastFailure;
8852
+ const fetchTimeoutMs = clampPinterestPinMediaOperationTimeout(
8853
+ options.timeoutMs ?? PINTEREST_PIN_MEDIA_DEFAULT_TIMEOUT_MS,
8854
+ PINTEREST_PIN_MEDIA_FETCH_MAX_TIMEOUT_MS
8855
+ );
8856
+ for (const candidate of selection.acceptedCandidates) {
8857
+ try {
8858
+ const fetched = await this.fetchPinterestPinMediaBytes(candidate.mediaUrl ?? "", fetchTimeoutMs);
8859
+ assertFetchedPinterestCandidateMatchesKind(candidate, fetched);
8860
+ await writePinterestPinMediaOutput(options.path, fetched.bytes);
8861
+ return this.buildPinterestPinMediaResult(
8862
+ candidate,
8863
+ rejectedCandidates,
8864
+ {
8865
+ contentType: fetched.contentType,
8866
+ byteLength: fetched.bytes.byteLength,
8867
+ path: options.path,
8868
+ sourceUrl,
8869
+ targetId,
8870
+ mediaUrl: fetched.finalUrl
8871
+ }
8872
+ );
8873
+ } catch (error) {
8874
+ lastFailure = error;
8875
+ if (rejectedCandidates.length < PINTEREST_PIN_MEDIA_REJECTION_LIMIT) {
8876
+ rejectedCandidates.push(summarizeRejectedPinterestCandidate(
8877
+ candidate,
8878
+ [pinterestCandidateCaptureFailureReason(error)]
8879
+ ));
8880
+ }
8881
+ }
8882
+ }
8883
+ throw lastFailure instanceof Error ? lastFailure : new Error("Pinterest pin media capture failed.");
8884
+ });
8885
+ }
8886
+ async evaluatePinterestPinMediaCandidates(managed, page, timeoutMs = PINTEREST_PIN_MEDIA_DEFAULT_TIMEOUT_MS) {
8887
+ const inspectionTimeoutMs = clampPinterestPinMediaOperationTimeout(
8888
+ timeoutMs,
8889
+ PINTEREST_PIN_MEDIA_DOM_INSPECTION_MAX_TIMEOUT_MS
8890
+ );
8891
+ try {
8892
+ return await withPinterestPinMediaOperationTimeout(
8893
+ page.evaluate(readPinterestPinMediaCandidatesInPage),
8894
+ inspectionTimeoutMs,
8895
+ `Pinterest pin media DOM inspection timed out after ${inspectionTimeoutMs}ms.`
8896
+ );
8897
+ } catch (error) {
8898
+ if (!isPinterestPinMediaDomInspectionTimeout(error)) {
8899
+ throw error;
8900
+ }
8901
+ return await this.evaluatePinterestPinMediaCandidatesViaCdp(managed, page, inspectionTimeoutMs, error);
8902
+ }
8903
+ }
8904
+ async evaluatePinterestPinMediaCandidatesViaCdp(managed, page, timeoutMs, originalError) {
8905
+ const sessionTimeoutMs = clampPinterestPinMediaOperationTimeout(
8906
+ timeoutMs,
8907
+ PINTEREST_PIN_MEDIA_CDP_SESSION_MAX_TIMEOUT_MS
8908
+ );
8909
+ const session = await withPinterestPinMediaOperationTimeout(
8910
+ managed.context.newCDPSession(page),
8911
+ sessionTimeoutMs,
8912
+ `Pinterest pin media CDP session attach timed out after ${sessionTimeoutMs}ms.`
8913
+ );
8914
+ try {
8915
+ const result = await withPinterestPinMediaOperationTimeout(
8916
+ session.send("Runtime.evaluate", {
8917
+ expression: `(${readPinterestPinMediaCandidatesInPage.toString()})()`,
8918
+ awaitPromise: true,
8919
+ returnByValue: true
8920
+ }),
8921
+ timeoutMs,
8922
+ `Pinterest pin media CDP inspection timed out after ${timeoutMs}ms.`
8923
+ );
8924
+ return parsePinterestPinMediaCdpExtraction(result);
8925
+ } catch {
8926
+ throw originalError;
8927
+ } finally {
8928
+ detachPinterestPinMediaCdpSession(session);
8929
+ }
8930
+ }
8931
+ async fetchPinterestPinMediaBytes(mediaUrl, timeoutMs = PINTEREST_PIN_MEDIA_DEFAULT_TIMEOUT_MS) {
8932
+ if (!isFirstPartyPinterestMediaUrl(mediaUrl)) {
8933
+ throw new Error("Pinterest pin media fetch rejected a non-first-party media URL.");
8934
+ }
8935
+ const controller = new AbortController();
8936
+ const timer = setTimeout(() => controller.abort(), timeoutMs);
8937
+ try {
8938
+ const { response, finalUrl } = await fetchPinterestPinMediaResponse(mediaUrl, controller.signal);
8939
+ if (!response.ok) {
8940
+ await discardPinterestPinMediaResponseBody(response);
8941
+ throw new Error(`Pinterest pin media fetch failed with status ${response.status}.`);
8942
+ }
8943
+ const contentLength = readPinterestPinMediaContentLength(response.headers);
8944
+ if (contentLength !== void 0) {
8945
+ try {
8946
+ assertPinterestPinMediaByteLimit(contentLength);
8947
+ } catch (error) {
8948
+ await discardPinterestPinMediaResponseBody(response);
8949
+ throw error;
8950
+ }
8951
+ }
8952
+ const bytes = await readBoundedPinterestPinMediaBytes(response);
8953
+ const contentType = response.headers.get("content-type") ?? void 0;
8954
+ return { bytes, finalUrl, ...contentType ? { contentType } : {} };
8955
+ } finally {
8956
+ clearTimeout(timer);
8957
+ }
8958
+ }
8959
+ buildPinterestPinMediaResult(candidate, rejectedCandidates, metadata) {
8960
+ const contentType = candidate.kind === "video" ? PINTEREST_PIN_MEDIA_VIDEO_CONTENT_TYPE : normalizePinterestResponseContentType(metadata.contentType);
8961
+ return {
8962
+ status: "captured",
8963
+ sourceUrl: metadata.sourceUrl,
8964
+ targetId: metadata.targetId,
8965
+ kind: candidate.kind,
8966
+ path: metadata.path,
8967
+ mediaUrl: metadata.mediaUrl,
8968
+ bytes: metadata.byteLength,
8969
+ ...contentType ? { contentType } : {},
8970
+ ...candidate.candidateSelector ? { candidateSelector: candidate.candidateSelector } : {},
8971
+ ...candidate.candidateRole ? { candidateRole: candidate.candidateRole } : {},
8972
+ ...candidate.alt ? { alt: candidate.alt } : {},
8973
+ ...candidate.srcset ? { srcset: candidate.srcset } : {},
8974
+ ...candidate.width ? { width: candidate.width } : {},
8975
+ ...candidate.height ? { height: candidate.height } : {},
8976
+ ...candidate.naturalWidth ? { naturalWidth: candidate.naturalWidth } : {},
8977
+ ...candidate.naturalHeight ? { naturalHeight: candidate.naturalHeight } : {},
8978
+ ...candidate.poster ? { poster: candidate.poster } : {},
8979
+ ...candidate.rect ? { rect: candidate.rect } : {},
8980
+ ancestry: candidate.ancestry.slice(0, 6),
8981
+ rejectedCandidates,
8982
+ ...warningsForSelectedPinterestCandidate(candidate).length > 0 ? { warnings: warningsForSelectedPinterestCandidate(candidate) } : {}
8983
+ };
8984
+ }
8261
8985
  async startScreencast(sessionId, options = {}) {
8262
8986
  return await this.runStructural(sessionId, async () => {
8263
8987
  const managed = this.getManaged(sessionId);
@@ -11365,6 +12089,12 @@ var OpsBrowserManager = class {
11365
12089
  ...warnings ? { warnings } : {}
11366
12090
  };
11367
12091
  }
12092
+ async capturePinterestPinMedia(sessionId, options) {
12093
+ if (!this.opsSessions.has(sessionId)) {
12094
+ return await this.base.capturePinterestPinMedia(sessionId, options);
12095
+ }
12096
+ throw new Error("Pinterest pin media capture is not supported through extension ops sessions.");
12097
+ }
11368
12098
  async startScreencast(sessionId, options = {}) {
11369
12099
  if (!this.opsSessions.has(sessionId)) {
11370
12100
  return await this.base.startScreencast(sessionId, options);
@@ -12916,7 +13646,7 @@ var parseJson2 = (data) => {
12916
13646
  // src/browser/canvas-manager.ts
12917
13647
  import { randomUUID as randomUUID19 } from "crypto";
12918
13648
  import { mkdir as mkdir9 } from "fs/promises";
12919
- import { dirname as dirname5 } from "path";
13649
+ import { dirname as dirname6 } from "path";
12920
13650
 
12921
13651
  // src/browser/canvas-client.ts
12922
13652
  import { randomUUID as randomUUID15 } from "crypto";
@@ -24983,7 +25713,7 @@ function listBuiltInCanvasKitIds() {
24983
25713
 
24984
25714
  // src/canvas/repo-store.ts
24985
25715
  import { access as access3, mkdir as mkdir6, readFile as readFile2 } from "fs/promises";
24986
- import { join as join13, dirname as dirname2, isAbsolute as isAbsolute3, resolve as resolve2 } from "path";
25716
+ import { join as join13, dirname as dirname3, isAbsolute as isAbsolute3, resolve as resolve2 } from "path";
24987
25717
 
24988
25718
  // src/canvas/code-sync/manifest.ts
24989
25719
  var isRecord6 = (value) => Boolean(value) && typeof value === "object" && !Array.isArray(value);
@@ -25184,7 +25914,7 @@ function resolveCanvasFigmaAssetPath(worktree, fileKey, assetId, extension) {
25184
25914
  }
25185
25915
  async function saveCanvasDocument(worktree, document2, repoPath) {
25186
25916
  const resolvedPath = resolveCanvasRepoPath(worktree, document2.documentId, repoPath);
25187
- await mkdir6(dirname2(resolvedPath), { recursive: true });
25917
+ await mkdir6(dirname3(resolvedPath), { recursive: true });
25188
25918
  writeFileAtomic(resolvedPath, `${JSON.stringify(stableValue(document2), null, 2)}
25189
25919
  `, { encoding: "utf-8" });
25190
25920
  return resolvedPath;
@@ -25206,7 +25936,7 @@ async function loadCanvasDocumentById(worktree, documentId) {
25206
25936
  }
25207
25937
  async function saveCanvasCodeSyncManifest(worktree, manifest, repoPath) {
25208
25938
  const resolvedPath = resolveCanvasCodeSyncManifestPath(worktree, manifest.documentId, manifest.bindingId, repoPath);
25209
- await mkdir6(dirname2(resolvedPath), { recursive: true });
25939
+ await mkdir6(dirname3(resolvedPath), { recursive: true });
25210
25940
  writeFileAtomic(resolvedPath, `${JSON.stringify(stableValue(manifest), null, 2)}
25211
25941
  `, { encoding: "utf-8" });
25212
25942
  return resolvedPath;
@@ -25588,7 +26318,7 @@ import { resolve as resolve5, isAbsolute as isAbsolute5 } from "path";
25588
26318
  // src/canvas/adapter-plugins/loader.ts
25589
26319
  import { createHash as createHash4 } from "crypto";
25590
26320
  import { access as access4, readFile as readFile3 } from "fs/promises";
25591
- import { dirname as dirname3, isAbsolute as isAbsolute4, join as join14, resolve as resolve4 } from "path";
26321
+ import { dirname as dirname4, isAbsolute as isAbsolute4, join as join14, resolve as resolve4 } from "path";
25592
26322
  import { pathToFileURL } from "url";
25593
26323
 
25594
26324
  // src/canvas/adapter-plugins/manifest.ts
@@ -25734,7 +26464,7 @@ async function resolveDeclarationRef(worktree, ref) {
25734
26464
  if (await exists(direct)) {
25735
26465
  const manifestPath2 = direct.endsWith(".json") ? direct : join14(direct, "canvas-adapter.plugin.json");
25736
26466
  return {
25737
- packageRoot: direct.endsWith(".json") ? dirname3(direct) : direct,
26467
+ packageRoot: direct.endsWith(".json") ? dirname4(direct) : direct,
25738
26468
  manifestPath: manifestPath2
25739
26469
  };
25740
26470
  }
@@ -27384,9 +28114,9 @@ function importCodeSyncGraph(options) {
27384
28114
 
27385
28115
  // src/canvas/code-sync/write.ts
27386
28116
  import { mkdir as mkdir7 } from "fs/promises";
27387
- import { dirname as dirname4 } from "path";
28117
+ import { dirname as dirname5 } from "path";
27388
28118
  async function writeCodeSyncSource(repoPath, sourceText) {
27389
- await mkdir7(dirname4(repoPath), { recursive: true });
28119
+ await mkdir7(dirname5(repoPath), { recursive: true });
27390
28120
  writeFileAtomic(repoPath, sourceText, { encoding: "utf-8" });
27391
28121
  }
27392
28122
  function finalizeCodeSyncManifest(manifest, updates) {
@@ -30458,7 +31188,7 @@ var CanvasManager = class {
30458
31188
  const repoRoot = this.resolveSessionRepoRoot(session, params2);
30459
31189
  const warnings = evaluateCanvasWarnings(document2, { forSave: exportTarget === "design_document" });
30460
31190
  const exportBase = resolveCanvasRepoPath(repoRoot, document2.documentId, ".opendevbrowser/canvas/exports");
30461
- await mkdir9(dirname5(exportBase), { recursive: true });
31191
+ await mkdir9(dirname6(exportBase), { recursive: true });
30462
31192
  if (exportTarget === "design_document") {
30463
31193
  const validation = validateCanvasSave(document2);
30464
31194
  if (validation.missingBlocks.length > 0) {
@@ -33055,7 +33785,7 @@ function toAbsoluteUrl(value) {
33055
33785
  }
33056
33786
  }
33057
33787
  async function saveText(path4, content) {
33058
- await mkdir9(dirname5(path4), { recursive: true });
33788
+ await mkdir9(dirname6(path4), { recursive: true });
33059
33789
  const { writeFileAtomic: writeFileAtomic2 } = await import("./fs-UMRKOBNN.js");
33060
33790
  writeFileAtomic2(path4, `${content}
33061
33791
  `, { encoding: "utf-8" });
@@ -35483,4 +36213,4 @@ export {
35483
36213
  createOpenDevBrowserCore
35484
36214
  };
35485
36215
  /* v8 ignore next -- @preserve */
35486
- //# sourceMappingURL=chunk-XRDCSHKZ.js.map
36216
+ //# sourceMappingURL=chunk-AHQC4A6P.js.map