opendevbrowser 0.0.28 → 0.0.30

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 (325) hide show
  1. package/README.md +2 -2
  2. package/dist/accessibility-snapshot-CQ4ZKWKC.js +39 -0
  3. package/dist/accessibility-snapshot-CQ4ZKWKC.js.map +1 -0
  4. package/dist/active-window-TD5HYJ72.js +37 -0
  5. package/dist/active-window-TD5HYJ72.js.map +1 -0
  6. package/dist/annotate-VTLFS2XV.js +205 -0
  7. package/dist/annotate-VTLFS2XV.js.map +1 -0
  8. package/dist/artifacts-KJ6RNDO2.js +120 -0
  9. package/dist/artifacts-KJ6RNDO2.js.map +1 -0
  10. package/dist/attr-BCI5KYCW.js +84 -0
  11. package/dist/attr-BCI5KYCW.js.map +1 -0
  12. package/dist/browser/ops-client.d.ts +1 -0
  13. package/dist/browser/ops-client.d.ts.map +1 -1
  14. package/dist/canvas-5DFEEOKM.js +309 -0
  15. package/dist/canvas-5DFEEOKM.js.map +1 -0
  16. package/dist/capture-desktop-HFTTWY4Z.js +38 -0
  17. package/dist/capture-desktop-HFTTWY4Z.js.map +1 -0
  18. package/dist/capture-window-X63XPIFF.js +40 -0
  19. package/dist/capture-window-X63XPIFF.js.map +1 -0
  20. package/dist/check-LWAUY7GC.js +71 -0
  21. package/dist/check-LWAUY7GC.js.map +1 -0
  22. package/dist/checked-ZSOUKVYT.js +71 -0
  23. package/dist/checked-ZSOUKVYT.js.map +1 -0
  24. package/dist/chunk-2SIMIPLY.js +67 -0
  25. package/dist/chunk-2SIMIPLY.js.map +1 -0
  26. package/dist/chunk-37VSRUW4.js +141 -0
  27. package/dist/chunk-37VSRUW4.js.map +1 -0
  28. package/dist/{chunk-T3VVHJTK.js → chunk-4BEJVZRK.js} +1078 -1458
  29. package/dist/chunk-4BEJVZRK.js.map +1 -0
  30. package/dist/chunk-5SWZDVOW.js +144 -0
  31. package/dist/chunk-5SWZDVOW.js.map +1 -0
  32. package/dist/chunk-6PVZ2ABC.js +429 -0
  33. package/dist/chunk-6PVZ2ABC.js.map +1 -0
  34. package/dist/chunk-7GVOUZMQ.js +64 -0
  35. package/dist/chunk-7GVOUZMQ.js.map +1 -0
  36. package/dist/chunk-7THCPS52.js +84 -0
  37. package/dist/chunk-7THCPS52.js.map +1 -0
  38. package/dist/chunk-AHEWXOKY.js +64 -0
  39. package/dist/chunk-AHEWXOKY.js.map +1 -0
  40. package/dist/chunk-ASMHEEKY.js +10 -0
  41. package/dist/chunk-ASMHEEKY.js.map +1 -0
  42. package/dist/chunk-COAOWH3G.js +3651 -0
  43. package/dist/chunk-COAOWH3G.js.map +1 -0
  44. package/dist/chunk-DBF5OKH3.js +111 -0
  45. package/dist/chunk-DBF5OKH3.js.map +1 -0
  46. package/dist/chunk-DW4TX7MU.js +54 -0
  47. package/dist/chunk-DW4TX7MU.js.map +1 -0
  48. package/dist/chunk-GQJ5S3BL.js +20 -0
  49. package/dist/chunk-GQJ5S3BL.js.map +1 -0
  50. package/dist/chunk-IPE7TF2P.js +54 -0
  51. package/dist/chunk-IPE7TF2P.js.map +1 -0
  52. package/dist/chunk-IQTJHXZJ.js +126 -0
  53. package/dist/chunk-IQTJHXZJ.js.map +1 -0
  54. package/dist/chunk-J47N77VG.js +2969 -0
  55. package/dist/chunk-J47N77VG.js.map +1 -0
  56. package/dist/chunk-JZXD6FWR.js +25 -0
  57. package/dist/chunk-JZXD6FWR.js.map +1 -0
  58. package/dist/{chunk-QVWOPIZJ.js → chunk-KDSNXS6N.js} +75 -149
  59. package/dist/chunk-KDSNXS6N.js.map +1 -0
  60. package/dist/chunk-KZ2IXVQT.js +219 -0
  61. package/dist/chunk-KZ2IXVQT.js.map +1 -0
  62. package/dist/chunk-MD655IPO.js +838 -0
  63. package/dist/chunk-MD655IPO.js.map +1 -0
  64. package/dist/chunk-MX3NFLCE.js +940 -0
  65. package/dist/chunk-MX3NFLCE.js.map +1 -0
  66. package/dist/chunk-OW5HMYMI.js +19 -0
  67. package/dist/chunk-OW5HMYMI.js.map +1 -0
  68. package/dist/chunk-PPUWQKIC.js +26 -0
  69. package/dist/chunk-PPUWQKIC.js.map +1 -0
  70. package/dist/{chunk-I5ZCOZZV.js → chunk-QOMWCRE3.js} +1202 -9561
  71. package/dist/chunk-QOMWCRE3.js.map +1 -0
  72. package/dist/chunk-RCZZGGJS.js +226 -0
  73. package/dist/chunk-RCZZGGJS.js.map +1 -0
  74. package/dist/chunk-RJNI3BHT.js +1 -0
  75. package/dist/chunk-RPXWUCQQ.js +112 -0
  76. package/dist/chunk-RPXWUCQQ.js.map +1 -0
  77. package/dist/chunk-S5KZQJJI.js +107 -0
  78. package/dist/chunk-S5KZQJJI.js.map +1 -0
  79. package/dist/chunk-T4GMCW6Z.js +46 -0
  80. package/dist/chunk-T4GMCW6Z.js.map +1 -0
  81. package/dist/chunk-WHQZBUNY.js +982 -0
  82. package/dist/chunk-WHQZBUNY.js.map +1 -0
  83. package/dist/chunk-WOXBLP7V.js +610 -0
  84. package/dist/chunk-WOXBLP7V.js.map +1 -0
  85. package/dist/cli/commands/inspiredesign.d.ts.map +1 -1
  86. package/dist/cli/commands/macro-resolve.d.ts +4 -1
  87. package/dist/cli/commands/macro-resolve.d.ts.map +1 -1
  88. package/dist/cli/commands/product-video.d.ts.map +1 -1
  89. package/dist/cli/commands/research.d.ts.map +1 -1
  90. package/dist/cli/commands/serve.d.ts.map +1 -1
  91. package/dist/cli/commands/shopping.d.ts.map +1 -1
  92. package/dist/cli/commands/workflow-output.d.ts +2 -0
  93. package/dist/cli/commands/workflow-output.d.ts.map +1 -0
  94. package/dist/cli/daemon-commands.d.ts.map +1 -1
  95. package/dist/cli/daemon.d.ts.map +1 -1
  96. package/dist/cli/index.js +204 -8123
  97. package/dist/cli/index.js.map +1 -1
  98. package/dist/cli/installers/postinstall-skill-sync.js +2 -1
  99. package/dist/cli/installers/postinstall-skill-sync.js.map +1 -1
  100. package/dist/cli/remote-relay.d.ts.map +1 -1
  101. package/dist/click-2AILSEIZ.js +81 -0
  102. package/dist/click-2AILSEIZ.js.map +1 -0
  103. package/dist/clone-component-TPJS3PEG.js +82 -0
  104. package/dist/clone-component-TPJS3PEG.js.map +1 -0
  105. package/dist/clone-page-LE74CIFC.js +69 -0
  106. package/dist/clone-page-LE74CIFC.js.map +1 -0
  107. package/dist/close-HN4YI47K.js +63 -0
  108. package/dist/close-HN4YI47K.js.map +1 -0
  109. package/dist/close-WFERRHX6.js +63 -0
  110. package/dist/close-WFERRHX6.js.map +1 -0
  111. package/dist/connect-RWBV2UCQ.js +107 -0
  112. package/dist/connect-RWBV2UCQ.js.map +1 -0
  113. package/dist/console-poll-PP4YYPDF.js +76 -0
  114. package/dist/console-poll-PP4YYPDF.js.map +1 -0
  115. package/dist/cookie-import-6IP776FC.js +177 -0
  116. package/dist/cookie-import-6IP776FC.js.map +1 -0
  117. package/dist/cookie-list-O2KG6DPU.js +117 -0
  118. package/dist/cookie-list-O2KG6DPU.js.map +1 -0
  119. package/dist/daemon-2BSAZXLT.js +194 -0
  120. package/dist/daemon-2BSAZXLT.js.map +1 -0
  121. package/dist/daemon-fingerprint.json +1 -1
  122. package/dist/debug-trace-snapshot-F3BDVZXS.js +136 -0
  123. package/dist/debug-trace-snapshot-F3BDVZXS.js.map +1 -0
  124. package/dist/dialog-6JQYUWMQ.js +75 -0
  125. package/dist/dialog-6JQYUWMQ.js.map +1 -0
  126. package/dist/disconnect-763TP7GH.js +58 -0
  127. package/dist/disconnect-763TP7GH.js.map +1 -0
  128. package/dist/enabled-DLYQFNIP.js +71 -0
  129. package/dist/enabled-DLYQFNIP.js.map +1 -0
  130. package/dist/extension-extractor-GKWSFHPN.js +11 -0
  131. package/dist/extension-extractor-GKWSFHPN.js.map +1 -0
  132. package/dist/global-D6WLWBXA.js +56 -0
  133. package/dist/global-D6WLWBXA.js.map +1 -0
  134. package/dist/goto-S346TJJH.js +98 -0
  135. package/dist/goto-S346TJJH.js.map +1 -0
  136. package/dist/help-EKKKEDL5.js +491 -0
  137. package/dist/help-EKKKEDL5.js.map +1 -0
  138. package/dist/hover-6JVJFGO7.js +71 -0
  139. package/dist/hover-6JVJFGO7.js.map +1 -0
  140. package/dist/html-EVOSPBIT.js +84 -0
  141. package/dist/html-EVOSPBIT.js.map +1 -0
  142. package/dist/index.d.ts.map +1 -1
  143. package/dist/index.js +87 -38
  144. package/dist/index.js.map +1 -1
  145. package/dist/inspector-H57BVUJP.js +62 -0
  146. package/dist/inspector-H57BVUJP.js.map +1 -0
  147. package/dist/inspector-audit-NQBAJWC7.js +84 -0
  148. package/dist/inspector-audit-NQBAJWC7.js.map +1 -0
  149. package/dist/inspector-plan-ZDIQVND3.js +69 -0
  150. package/dist/inspector-plan-ZDIQVND3.js.map +1 -0
  151. package/dist/inspiredesign-IEUL4PX3.js +234 -0
  152. package/dist/inspiredesign-IEUL4PX3.js.map +1 -0
  153. package/dist/install-autostart-output-5DOMKCQL.js +41 -0
  154. package/dist/install-autostart-output-5DOMKCQL.js.map +1 -0
  155. package/dist/install-autostart-reconciliation-NHKOFYTD.js +73 -0
  156. package/dist/install-autostart-reconciliation-NHKOFYTD.js.map +1 -0
  157. package/dist/launch-EK66VQPF.js +225 -0
  158. package/dist/launch-EK66VQPF.js.map +1 -0
  159. package/dist/list-ADZAQ2IU.js +51 -0
  160. package/dist/list-ADZAQ2IU.js.map +1 -0
  161. package/dist/list-KKUKN467.js +54 -0
  162. package/dist/list-KKUKN467.js.map +1 -0
  163. package/dist/local-HXJLUUNT.js +54 -0
  164. package/dist/local-HXJLUUNT.js.map +1 -0
  165. package/dist/macro-resolve-6DOQJ7CA.js +253 -0
  166. package/dist/macro-resolve-6DOQJ7CA.js.map +1 -0
  167. package/dist/macros/execute-runtime.d.ts +3 -1
  168. package/dist/macros/execute-runtime.d.ts.map +1 -1
  169. package/dist/macros/execute.d.ts +2 -0
  170. package/dist/macros/execute.d.ts.map +1 -1
  171. package/dist/native-UPLVQ2SG.js +22 -0
  172. package/dist/native-UPLVQ2SG.js.map +1 -0
  173. package/dist/network-poll-NUL4PDPY.js +76 -0
  174. package/dist/network-poll-NUL4PDPY.js.map +1 -0
  175. package/dist/new-5NKYPEFT.js +69 -0
  176. package/dist/new-5NKYPEFT.js.map +1 -0
  177. package/dist/onboarding-metadata-7E3KLYSZ.js +27 -0
  178. package/dist/onboarding-metadata-7E3KLYSZ.js.map +1 -0
  179. package/dist/open-NR3BPLXV.js +81 -0
  180. package/dist/open-NR3BPLXV.js.map +1 -0
  181. package/dist/opendevbrowser.d.ts.map +1 -1
  182. package/dist/opendevbrowser.js +87 -38
  183. package/dist/opendevbrowser.js.map +1 -1
  184. package/dist/perf-HJ36ZI6H.js +58 -0
  185. package/dist/perf-HJ36ZI6H.js.map +1 -0
  186. package/dist/pointer-down-IYTTQWXZ.js +55 -0
  187. package/dist/pointer-down-IYTTQWXZ.js.map +1 -0
  188. package/dist/pointer-drag-A2YC5PWI.js +54 -0
  189. package/dist/pointer-drag-A2YC5PWI.js.map +1 -0
  190. package/dist/pointer-move-W5K5FUI4.js +52 -0
  191. package/dist/pointer-move-W5K5FUI4.js.map +1 -0
  192. package/dist/pointer-up-6GWVO64Y.js +55 -0
  193. package/dist/pointer-up-6GWVO64Y.js.map +1 -0
  194. package/dist/press-A3V5WB3S.js +83 -0
  195. package/dist/press-A3V5WB3S.js.map +1 -0
  196. package/dist/product-video-52REKWF3.js +235 -0
  197. package/dist/product-video-52REKWF3.js.map +1 -0
  198. package/dist/providers/artifacts.d.ts +0 -2
  199. package/dist/providers/artifacts.d.ts.map +1 -1
  200. package/dist/providers/blocker.d.ts.map +1 -1
  201. package/dist/providers/bounded-map.d.ts +2 -0
  202. package/dist/providers/bounded-map.d.ts.map +1 -0
  203. package/dist/providers/community/index.d.ts.map +1 -1
  204. package/dist/providers/constraint.d.ts.map +1 -1
  205. package/dist/providers/index.d.ts +1 -0
  206. package/dist/providers/index.d.ts.map +1 -1
  207. package/dist/providers/renderer.d.ts.map +1 -1
  208. package/dist/providers/research-compiler.d.ts +1 -1
  209. package/dist/providers/research-compiler.d.ts.map +1 -1
  210. package/dist/providers/research-executor.d.ts.map +1 -1
  211. package/dist/providers/runtime-factory.d.ts.map +1 -1
  212. package/dist/providers/shared/traversal-url.d.ts +3 -0
  213. package/dist/providers/shared/traversal-url.d.ts.map +1 -1
  214. package/dist/providers/shopping/index.d.ts.map +1 -1
  215. package/dist/providers/social/search-quality.d.ts.map +1 -1
  216. package/dist/providers/workflow-handoff.d.ts +4 -0
  217. package/dist/providers/workflow-handoff.d.ts.map +1 -1
  218. package/dist/providers/workflow-output-root.d.ts +6 -0
  219. package/dist/providers/workflow-output-root.d.ts.map +1 -0
  220. package/dist/providers/workflows.d.ts.map +1 -1
  221. package/dist/{providers-QF2RFB4J.js → providers-IMFYMMHQ.js} +19 -14
  222. package/dist/providers-IMFYMMHQ.js.map +1 -0
  223. package/dist/public-surface/generated-manifest.d.ts +2 -2
  224. package/dist/public-surface/generated-manifest.d.ts.map +1 -1
  225. package/dist/public-surface/source.d.ts +2 -2
  226. package/dist/public-surface/source.d.ts.map +1 -1
  227. package/dist/relay/protocol.d.ts +3 -1
  228. package/dist/relay/protocol.d.ts.map +1 -1
  229. package/dist/relay/relay-server.d.ts +6 -0
  230. package/dist/relay/relay-server.d.ts.map +1 -1
  231. package/dist/research-WB6BBCDD.js +295 -0
  232. package/dist/research-WB6BBCDD.js.map +1 -0
  233. package/dist/review-BGWVY4RA.js +48 -0
  234. package/dist/review-BGWVY4RA.js.map +1 -0
  235. package/dist/review-desktop-LEORC5VS.js +54 -0
  236. package/dist/review-desktop-LEORC5VS.js.map +1 -0
  237. package/dist/rpc-4TSKSFGC.js +159 -0
  238. package/dist/rpc-4TSKSFGC.js.map +1 -0
  239. package/dist/run-3NBLVWXD.js +180 -0
  240. package/dist/run-3NBLVWXD.js.map +1 -0
  241. package/dist/screencast-start-UZVIT3IN.js +67 -0
  242. package/dist/screencast-start-UZVIT3IN.js.map +1 -0
  243. package/dist/screencast-stop-NOSJSIUO.js +59 -0
  244. package/dist/screencast-stop-NOSJSIUO.js.map +1 -0
  245. package/dist/screenshot-LARG4JQG.js +68 -0
  246. package/dist/screenshot-LARG4JQG.js.map +1 -0
  247. package/dist/scroll-VNFMV6TW.js +84 -0
  248. package/dist/scroll-VNFMV6TW.js.map +1 -0
  249. package/dist/scroll-into-view-VYRT3JPT.js +71 -0
  250. package/dist/scroll-into-view-VYRT3JPT.js.map +1 -0
  251. package/dist/select-KJTUZDVO.js +86 -0
  252. package/dist/select-KJTUZDVO.js.map +1 -0
  253. package/dist/serve-EV7K4HKR.js +498 -0
  254. package/dist/serve-EV7K4HKR.js.map +1 -0
  255. package/dist/shopping-DTXHVQ2X.js +273 -0
  256. package/dist/shopping-DTXHVQ2X.js.map +1 -0
  257. package/dist/skill-lifecycle-5UAZGKSN.js +89 -0
  258. package/dist/skill-lifecycle-5UAZGKSN.js.map +1 -0
  259. package/dist/skills-NSXDX6YM.js +26 -0
  260. package/dist/skills-NSXDX6YM.js.map +1 -0
  261. package/dist/snapshot-3XQMCMRJ.js +113 -0
  262. package/dist/snapshot-3XQMCMRJ.js.map +1 -0
  263. package/dist/status-OXSYA5XD.js +35 -0
  264. package/dist/status-OXSYA5XD.js.map +1 -0
  265. package/dist/status-YUMDP5KY.js +132 -0
  266. package/dist/status-YUMDP5KY.js.map +1 -0
  267. package/dist/status-capabilities-P4KDSE2Y.js +57 -0
  268. package/dist/status-capabilities-P4KDSE2Y.js.map +1 -0
  269. package/dist/text-V3B7UVIH.js +84 -0
  270. package/dist/text-V3B7UVIH.js.map +1 -0
  271. package/dist/tools/deps.d.ts +1 -0
  272. package/dist/tools/deps.d.ts.map +1 -1
  273. package/dist/tools/inspiredesign_run.d.ts.map +1 -1
  274. package/dist/tools/macro_resolve.d.ts.map +1 -1
  275. package/dist/tools/product_video_run.d.ts.map +1 -1
  276. package/dist/tools/research_run.d.ts.map +1 -1
  277. package/dist/tools/shopping_run.d.ts.map +1 -1
  278. package/dist/tools/workflow-output.d.ts +3 -0
  279. package/dist/tools/workflow-output.d.ts.map +1 -0
  280. package/dist/type-IYBN3ZLR.js +94 -0
  281. package/dist/type-IYBN3ZLR.js.map +1 -0
  282. package/dist/uncheck-SG737EGI.js +71 -0
  283. package/dist/uncheck-SG737EGI.js.map +1 -0
  284. package/dist/uninstall-KYKGJAX7.js +91 -0
  285. package/dist/uninstall-KYKGJAX7.js.map +1 -0
  286. package/dist/update-SMXPYGXS.js +305 -0
  287. package/dist/update-SMXPYGXS.js.map +1 -0
  288. package/dist/update-skill-modes-BVX7IVMW.js +38 -0
  289. package/dist/update-skill-modes-BVX7IVMW.js.map +1 -0
  290. package/dist/upload-KH6ZABJA.js +56 -0
  291. package/dist/upload-KH6ZABJA.js.map +1 -0
  292. package/dist/use-7YDKO3U4.js +63 -0
  293. package/dist/use-7YDKO3U4.js.map +1 -0
  294. package/dist/value-RZBWSKKM.js +71 -0
  295. package/dist/value-RZBWSKKM.js.map +1 -0
  296. package/dist/visible-BSFTAKXR.js +71 -0
  297. package/dist/visible-BSFTAKXR.js.map +1 -0
  298. package/dist/wait-TMTEAYOP.js +109 -0
  299. package/dist/wait-TMTEAYOP.js.map +1 -0
  300. package/dist/windows-HIZ23OHS.js +37 -0
  301. package/dist/windows-HIZ23OHS.js.map +1 -0
  302. package/extension/dist/background.js +99 -22
  303. package/extension/dist/ops/ops-runtime.js +85 -7
  304. package/extension/dist/ops/ops-session-store.js +3 -0
  305. package/extension/dist/ops/target-session-coordinator.js +3 -0
  306. package/extension/dist/services/CDPRouter.js +9 -0
  307. package/extension/manifest.json +1 -1
  308. package/package.json +1 -1
  309. package/skills/opendevbrowser-best-practices/SKILL.md +8 -6
  310. package/skills/opendevbrowser-best-practices/artifacts/skill-runtime-surface-matrix.md +1 -1
  311. package/skills/opendevbrowser-best-practices/scripts/odb-workflow.sh +3 -2
  312. package/skills/opendevbrowser-best-practices/scripts/validator-fixture-cli.sh +39 -2
  313. package/skills/opendevbrowser-research/SKILL.md +64 -12
  314. package/skills/opendevbrowser-research/artifacts/research-workflows.md +56 -19
  315. package/skills/opendevbrowser-research/assets/templates/compact.md +31 -5
  316. package/skills/opendevbrowser-research/assets/templates/context.json +52 -1
  317. package/skills/opendevbrowser-research/assets/templates/report.md +57 -4
  318. package/skills/opendevbrowser-research/examples/sample-input.json +1 -1
  319. package/skills/opendevbrowser-research/examples/sample-output.md +27 -2
  320. package/skills/opendevbrowser-research/scripts/run-research.sh +2 -6
  321. package/skills/opendevbrowser-research/scripts/validate-skill-assets.sh +115 -1
  322. package/dist/chunk-I5ZCOZZV.js.map +0 -1
  323. package/dist/chunk-QVWOPIZJ.js.map +0 -1
  324. package/dist/chunk-T3VVHJTK.js.map +0 -1
  325. /package/dist/{providers-QF2RFB4J.js.map → chunk-RJNI3BHT.js.map} +0 -0
@@ -0,0 +1,982 @@
1
+ import {
2
+ isProviderReasonCode
3
+ } from "./chunk-FUSXMW3G.js";
4
+
5
+ // src/core/logging.ts
6
+ import { randomUUID } from "crypto";
7
+ var SECRET_KEY_PATTERN = /(token|secret|password|authorization|cookie|api[-_]?key|session)/i;
8
+ var SECRET_VALUE_PATTERN = /(bearer\s+[a-z0-9._-]+|sk_[a-z0-9_-]+|pk_[a-z0-9_-]+|eyJ[a-z0-9_-]+\.[a-z0-9_-]+\.[a-z0-9_-]+)/gi;
9
+ function redactString(value) {
10
+ return value.replace(SECRET_VALUE_PATTERN, "[REDACTED]");
11
+ }
12
+ function redactSensitive(value, seen = /* @__PURE__ */ new WeakSet()) {
13
+ if (typeof value === "string") {
14
+ return redactString(value);
15
+ }
16
+ if (typeof value !== "object" || value === null) {
17
+ return value;
18
+ }
19
+ if (seen.has(value)) {
20
+ return "[Circular]";
21
+ }
22
+ seen.add(value);
23
+ if (Array.isArray(value)) {
24
+ return value.map((item) => redactSensitive(item, seen));
25
+ }
26
+ const output = {};
27
+ for (const [key, entry] of Object.entries(value)) {
28
+ if (SECRET_KEY_PATTERN.test(key)) {
29
+ output[key] = "[REDACTED]";
30
+ continue;
31
+ }
32
+ output[key] = redactSensitive(entry, seen);
33
+ }
34
+ return output;
35
+ }
36
+ function createRequestId() {
37
+ return randomUUID();
38
+ }
39
+ var defaultSink = (entry) => {
40
+ const payload = JSON.stringify(entry);
41
+ if (entry.level === "error") {
42
+ console.error(payload);
43
+ return;
44
+ }
45
+ if (entry.level === "warn") {
46
+ console.warn(payload);
47
+ return;
48
+ }
49
+ console.log(payload);
50
+ };
51
+ var stderrSink = (entry) => {
52
+ process.stderr.write(`${JSON.stringify(entry)}
53
+ `);
54
+ };
55
+ var configuredDefaultSink = defaultSink;
56
+ function setDefaultLogSink(sink) {
57
+ configuredDefaultSink = sink ?? defaultSink;
58
+ }
59
+ function createLogger(moduleName, sink) {
60
+ const emit = (level, event, fields = {}) => {
61
+ const entry = {
62
+ ts: (/* @__PURE__ */ new Date()).toISOString(),
63
+ level,
64
+ module: moduleName,
65
+ event,
66
+ requestId: fields.requestId ?? createRequestId(),
67
+ ...fields.sessionId ? { sessionId: fields.sessionId } : {},
68
+ ...fields.traceId ? { traceId: fields.traceId } : {},
69
+ ...typeof fields.data === "undefined" ? {} : { data: redactSensitive(fields.data) }
70
+ };
71
+ (sink ?? configuredDefaultSink)(entry);
72
+ return entry;
73
+ };
74
+ return {
75
+ debug: (event, fields) => emit("debug", event, fields),
76
+ info: (event, fields) => emit("info", event, fields),
77
+ warn: (event, fields) => emit("warn", event, fields),
78
+ error: (event, fields) => emit("error", event, fields),
79
+ audit: (event, fields) => emit("audit", event, fields)
80
+ };
81
+ }
82
+
83
+ // src/providers/safety/prompt-guard.ts
84
+ var MAX_EXCERPT_LENGTH = 120;
85
+ var RULES = [
86
+ {
87
+ id: "reveal_system_prompt",
88
+ regex: /\b(reveal|show|print|dump|expose|leak)\b[^.!?\n]{0,80}\b(system prompt|hidden prompt|internal prompt)\b/gi,
89
+ severity: "high",
90
+ action: "quarantine"
91
+ },
92
+ {
93
+ id: "tool_abuse_directive",
94
+ regex: /\buse (?:the )?tool(?:ing)?\b[^.!?\n]{0,120}\b(delete|remove|drop|wipe|exfiltrat|override|bypass)\w*/gi,
95
+ severity: "high",
96
+ action: "quarantine"
97
+ },
98
+ {
99
+ id: "ignore_previous_instructions",
100
+ regex: /\bignore (?:all )?previous instructions?\b/gi,
101
+ severity: "medium",
102
+ action: "strip"
103
+ },
104
+ {
105
+ id: "reveal_hidden_data",
106
+ regex: /\breveal (?:hidden|secret|confidential) (?:data|information)\b/gi,
107
+ severity: "high",
108
+ action: "quarantine"
109
+ }
110
+ ];
111
+ var sanitizeExcerpt = (value) => {
112
+ const compact = value.replace(/\s+/g, " ").trim();
113
+ if (compact.length <= MAX_EXCERPT_LENGTH) return compact;
114
+ return `${compact.slice(0, MAX_EXCERPT_LENGTH - 3)}...`;
115
+ };
116
+ var isJsonObject = (value) => {
117
+ return typeof value === "object" && value !== null && !Array.isArray(value);
118
+ };
119
+ var withSecurityAttributes = (record, enabled, guardEntries, quarantinedSegments) => {
120
+ const existingSecurity = isJsonObject(record.attributes.security) ? record.attributes.security : {};
121
+ return {
122
+ ...record.attributes,
123
+ security: {
124
+ ...existingSecurity,
125
+ untrustedContent: true,
126
+ dataOnlyContext: true,
127
+ promptGuardEnabled: enabled,
128
+ guardEntries,
129
+ quarantinedSegments
130
+ }
131
+ };
132
+ };
133
+ function sanitizePromptGuardText(text, enabled) {
134
+ if (!enabled || !text) {
135
+ return {
136
+ text,
137
+ diagnostics: { entries: 0, quarantinedSegments: 0 },
138
+ entries: []
139
+ };
140
+ }
141
+ let output = text;
142
+ const entries = [];
143
+ for (const rule of RULES) {
144
+ rule.regex.lastIndex = 0;
145
+ output = output.replace(rule.regex, (match) => {
146
+ entries.push({
147
+ pattern: rule.id,
148
+ action: rule.action,
149
+ severity: rule.severity,
150
+ excerpt: sanitizeExcerpt(match)
151
+ });
152
+ return rule.action === "quarantine" ? "[QUARANTINED]" : " ";
153
+ });
154
+ }
155
+ const normalized = output.replace(/\s{2,}/g, " ").trim();
156
+ const quarantinedSegments = entries.reduce((count, entry) => {
157
+ return entry.action === "quarantine" ? count + 1 : count;
158
+ }, 0);
159
+ return {
160
+ text: normalized,
161
+ diagnostics: {
162
+ entries: entries.length,
163
+ quarantinedSegments
164
+ },
165
+ entries
166
+ };
167
+ }
168
+ function applyPromptGuard(records, enabled) {
169
+ const auditEntries = [];
170
+ let totalQuarantinedSegments = 0;
171
+ const guardedRecords = records.map((record) => {
172
+ if (!enabled) {
173
+ return {
174
+ ...record,
175
+ attributes: withSecurityAttributes(record, false, 0, 0)
176
+ };
177
+ }
178
+ let title = record.title;
179
+ let content = record.content;
180
+ let recordEntries = 0;
181
+ let recordQuarantinedSegments = 0;
182
+ if (typeof record.title === "string") {
183
+ const sanitizedTitle = sanitizePromptGuardText(record.title, true);
184
+ title = sanitizedTitle.text;
185
+ recordEntries += sanitizedTitle.diagnostics.entries;
186
+ recordQuarantinedSegments += sanitizedTitle.diagnostics.quarantinedSegments;
187
+ for (const entry of sanitizedTitle.entries) {
188
+ auditEntries.push({
189
+ ...entry,
190
+ recordId: record.id,
191
+ field: "title"
192
+ });
193
+ }
194
+ }
195
+ if (typeof record.content === "string") {
196
+ const sanitizedContent = sanitizePromptGuardText(record.content, true);
197
+ content = sanitizedContent.text;
198
+ recordEntries += sanitizedContent.diagnostics.entries;
199
+ recordQuarantinedSegments += sanitizedContent.diagnostics.quarantinedSegments;
200
+ for (const entry of sanitizedContent.entries) {
201
+ auditEntries.push({
202
+ ...entry,
203
+ recordId: record.id,
204
+ field: "content"
205
+ });
206
+ }
207
+ }
208
+ totalQuarantinedSegments += recordQuarantinedSegments;
209
+ return {
210
+ ...record,
211
+ ...typeof title === "string" ? { title } : {},
212
+ ...typeof content === "string" ? { content } : {},
213
+ attributes: withSecurityAttributes(record, true, recordEntries, recordQuarantinedSegments)
214
+ };
215
+ });
216
+ return {
217
+ records: guardedRecords,
218
+ audit: {
219
+ enabled,
220
+ quarantinedSegments: enabled ? totalQuarantinedSegments : 0,
221
+ entries: enabled ? auditEntries : []
222
+ }
223
+ };
224
+ }
225
+
226
+ // src/providers/blocker.ts
227
+ var AUTH_URL_PATTERNS = [
228
+ { id: "redirect_login_flow", regex: /\/i\/flow\/login/i, confidence: 0.97 },
229
+ { id: "auth_login_path", regex: /\/(login|signin|sign-in|auth)(?:[./?]|$)/i, confidence: 0.9 }
230
+ ];
231
+ var AUTH_TITLE_PATTERNS = [
232
+ { id: "title_login", regex: /\b(log ?in|sign ?in|login|signin)\b/i, confidence: 0.92 },
233
+ { id: "title_auth_required", regex: /authentication required/i, confidence: 0.9 }
234
+ ];
235
+ var CHALLENGE_PATTERNS = [
236
+ { id: "challenge_keyword", regex: /\b(?:captcha|interstitial|cf_chl|recaptcha|hcaptcha|security challenge|browser challenge|bot check|bot detection)\b/i, confidence: 0.88 },
237
+ { id: "complete_challenge_prompt", regex: /\b(?:complete|solve|pass) (?:the )?(?:security )?challenge\b/i, confidence: 0.9 },
238
+ { id: "prove_humanity", regex: /prove your humanity/i, confidence: 0.96 },
239
+ { id: "verify_humanity", regex: /verify (?:you(?:'|’)re|you are) human/i, confidence: 0.96 },
240
+ { id: "robot_or_human", regex: /robot or human/i, confidence: 0.98 },
241
+ { id: "confirm_human", regex: /confirm that you(?:'|’)re human/i, confidence: 0.96 },
242
+ { id: "confirm_not_bot", regex: /sign in to confirm (?:you(?:'|’)re|you are) not a bot/i, confidence: 0.96 },
243
+ { id: "click_and_hold", regex: /\b(?:click|press|tap|activate)\s+(?:and\s+)?hold\b/i, confidence: 0.95 },
244
+ { id: "press_and_hold", regex: /activate and hold the button/i, confidence: 0.95 },
245
+ { id: "drag_slider", regex: /\b(?:drag|slide|move)(?:\s+the)?\s+(?:slider|puzzle(?:\s+piece)?|piece|button)\b/i, confidence: 0.95 },
246
+ { id: "pardon_interruption", regex: /pardon our interruption/i, confidence: 0.97 },
247
+ { id: "checking_browser_gate", regex: /checking your browser before you access/i, confidence: 0.97 }
248
+ ];
249
+ var RECAPTCHA_HOST_PATTERNS = [/recaptcha/i, /hcaptcha/i, /challenges\.cloudflare\.com/i];
250
+ var STATIC_BLOCK_HOST_PATTERNS = [/redditstatic\.com$/i, /abs\.twimg\.com$/i, /twimg\.com$/i];
251
+ var ENV_LIMITED_PATTERNS = [
252
+ /extension not connected/i,
253
+ /connect the extension/i,
254
+ /manual interaction/i,
255
+ /timed out/i,
256
+ /not available in this environment/i
257
+ ];
258
+ var RESTRICTED_TARGET_PATTERNS = [/^chrome:\/\//i, /^chrome-extension:\/\//i, /^about:blank$/i, /^devtools:\/\//i];
259
+ var DEFAULT_BLOCKER_ARTIFACT_CAPS = {
260
+ maxNetworkEvents: 20,
261
+ maxConsoleEvents: 20,
262
+ maxExceptionEvents: 10,
263
+ maxHosts: 10,
264
+ maxTextLength: 512
265
+ };
266
+ var toLower = (value) => value.trim().toLowerCase();
267
+ var clampNumber = (value, min, max) => {
268
+ if (!Number.isFinite(value)) return min;
269
+ if (value < min) return min;
270
+ if (value > max) return max;
271
+ return value;
272
+ };
273
+ var clampBlockerConfidence = (value) => {
274
+ return clampNumber(value, 0, 1);
275
+ };
276
+ var clampThreshold = (value) => {
277
+ if (typeof value !== "number") return 0.7;
278
+ return clampNumber(value, 0, 1);
279
+ };
280
+ var clampText = (value, maxLength) => {
281
+ if (typeof value !== "string") return void 0;
282
+ if (maxLength <= 0) return "";
283
+ return value.length <= maxLength ? value : `${value.slice(0, Math.max(0, maxLength - 3))}...`;
284
+ };
285
+ var boundedUniqueList = (values, maxLength) => {
286
+ if (!values || values.length === 0 || maxLength <= 0) return [];
287
+ const seen = /* @__PURE__ */ new Set();
288
+ const list = [];
289
+ for (const value of values) {
290
+ if (typeof value !== "string") continue;
291
+ const normalized = value.trim();
292
+ if (!normalized) continue;
293
+ const key = normalized.toLowerCase();
294
+ if (seen.has(key)) continue;
295
+ seen.add(key);
296
+ list.push(normalized);
297
+ if (list.length >= maxLength) break;
298
+ }
299
+ return list;
300
+ };
301
+ var extractHost = (value) => {
302
+ if (!value) return null;
303
+ try {
304
+ return toLower(new URL(value).hostname);
305
+ } catch {
306
+ return null;
307
+ }
308
+ };
309
+ var scorePatternMatches = (text, patterns) => {
310
+ const matched = [];
311
+ let confidence = 0;
312
+ for (const pattern of patterns) {
313
+ if (!pattern.regex.test(text)) continue;
314
+ matched.push(pattern.id);
315
+ confidence = Math.max(confidence, pattern.confidence);
316
+ }
317
+ return { matched, confidence };
318
+ };
319
+ var hasAnyPattern = (value, patterns) => {
320
+ return patterns.some((pattern) => pattern.test(value));
321
+ };
322
+ var isLoopbackHost = (value) => {
323
+ const normalized = toLower(value).replace(/^\[|\]$/g, "");
324
+ if (!normalized) return false;
325
+ if (normalized === "localhost" || normalized === "::1") return true;
326
+ if (normalized === "127.0.0.1" || normalized.startsWith("127.")) return true;
327
+ return /^::ffff:127\.\d+\.\d+\.\d+$/.test(normalized);
328
+ };
329
+ var buildHints = (type) => {
330
+ switch (type) {
331
+ case "auth_required":
332
+ return [
333
+ { id: "manual_login", reason: "Authentication flow requires interactive login.", priority: 1 },
334
+ { id: "switch_managed_headed", reason: "Headed mode can complete login and persist session state.", priority: 2 },
335
+ { id: "switch_extension_mode", reason: "Extension mode can reuse an already logged-in browser profile.", priority: 3 }
336
+ ];
337
+ case "anti_bot_challenge":
338
+ return [
339
+ { id: "manual_challenge", reason: "Challenge page requires manual completion.", priority: 1 },
340
+ { id: "switch_managed_headed", reason: "Headed mode improves challenge completion reliability.", priority: 2 },
341
+ { id: "collect_debug_trace", reason: "Collect trace artifacts to compare challenge indicators before and after manual action.", priority: 3 }
342
+ ];
343
+ case "rate_limited":
344
+ return [
345
+ { id: "retry_after_backoff", reason: "Rate-limited responses should be retried after a bounded delay.", priority: 1 },
346
+ { id: "collect_debug_trace", reason: "Trace data can confirm cooldown and request pacing behavior.", priority: 2 }
347
+ ];
348
+ case "upstream_block":
349
+ return [
350
+ { id: "retry_after_backoff", reason: "Upstream blocks may clear after network or host recovery.", priority: 1 },
351
+ { id: "switch_managed_headed", reason: "Browser-assisted retrieval may bypass runtime fetch limitations.", priority: 2 },
352
+ { id: "collect_debug_trace", reason: "Trace host evidence helps confirm blocked upstream dependencies.", priority: 3 }
353
+ ];
354
+ case "restricted_target":
355
+ return [
356
+ { id: "switch_managed_headed", reason: "Restricted internal targets require navigation to a normal http(s) tab.", priority: 1 },
357
+ { id: "collect_debug_trace", reason: "Trace confirms blocked scheme or tab restriction source.", priority: 2 }
358
+ ];
359
+ case "env_limited":
360
+ return [
361
+ { id: "switch_extension_mode", reason: "Extension relay availability is required for this operation.", priority: 1 },
362
+ { id: "switch_managed_headed", reason: "Managed headed mode is a deterministic fallback when extension is unavailable.", priority: 2 },
363
+ { id: "collect_debug_trace", reason: "Diagnostics can confirm environment capability gaps.", priority: 3 }
364
+ ];
365
+ case "unknown":
366
+ return [{ id: "collect_debug_trace", reason: "Additional trace evidence is required for reliable classification.", priority: 1 }];
367
+ }
368
+ };
369
+ var classifyFromInputs = (input, normalizedHosts, matchedPatterns) => {
370
+ const status = input.status;
371
+ const code = toLower(input.providerErrorCode ?? "");
372
+ const url = input.url ?? "";
373
+ const finalUrl = input.finalUrl ?? "";
374
+ const title = input.title ?? "";
375
+ const message = input.message ?? "";
376
+ const challengeText = `${title} ${message}`;
377
+ const urlSignals = `${url} ${finalUrl}`;
378
+ const isUpstreamCode = code === "upstream" || code === "network" || code === "unavailable";
379
+ const hasStaticBlockHost = normalizedHosts.some((host) => hasAnyPattern(host, STATIC_BLOCK_HOST_PATTERNS));
380
+ const isLoopbackContext = [
381
+ extractHost(url),
382
+ extractHost(finalUrl),
383
+ ...normalizedHosts
384
+ ].some((host) => typeof host === "string" && isLoopbackHost(host));
385
+ const authMatches = [];
386
+ let authConfidence = 0;
387
+ if (status === 401 || status === 403) {
388
+ authMatches.push(`status:${status}`);
389
+ authConfidence = Math.max(authConfidence, status === 401 ? 0.94 : 0.9);
390
+ }
391
+ if (code === "auth") {
392
+ authMatches.push("provider_code:auth");
393
+ authConfidence = Math.max(authConfidence, 0.9);
394
+ }
395
+ const authPathMatches = scorePatternMatches(`${url} ${finalUrl}`, AUTH_URL_PATTERNS);
396
+ authMatches.push(...authPathMatches.matched);
397
+ authConfidence = Math.max(authConfidence, authPathMatches.confidence);
398
+ const authTitleMatches = scorePatternMatches(title, AUTH_TITLE_PATTERNS);
399
+ authMatches.push(...authTitleMatches.matched);
400
+ authConfidence = Math.max(authConfidence, authTitleMatches.confidence);
401
+ if (authConfidence > 0) {
402
+ return {
403
+ type: "auth_required",
404
+ reasonCode: "token_required",
405
+ confidence: authConfidence,
406
+ retryable: false,
407
+ matches: boundedUniqueList([...matchedPatterns, ...authMatches], 16)
408
+ };
409
+ }
410
+ if (!isLoopbackContext) {
411
+ const challengeMatches = [];
412
+ let challengeConfidence = 0;
413
+ const challengePatternMatches = scorePatternMatches(challengeText, CHALLENGE_PATTERNS);
414
+ challengeMatches.push(...challengePatternMatches.matched);
415
+ challengeConfidence = Math.max(challengeConfidence, challengePatternMatches.confidence);
416
+ if (/(captcha|cf_chl|hcaptcha|recaptcha|interstitial)/i.test(urlSignals)) {
417
+ challengeMatches.push("url:challenge_token");
418
+ challengeConfidence = Math.max(challengeConfidence, 0.9);
419
+ }
420
+ if (hasAnyPattern(title, CHALLENGE_PATTERNS.map((entry) => entry.regex)) && status === 200) {
421
+ challengeMatches.push("status:200_challenge_title");
422
+ challengeConfidence = Math.max(challengeConfidence, 0.92);
423
+ }
424
+ if (normalizedHosts.some((host) => hasAnyPattern(host, RECAPTCHA_HOST_PATTERNS))) {
425
+ challengeMatches.push("network:challenge_host");
426
+ challengeConfidence = Math.max(challengeConfidence, 0.96);
427
+ }
428
+ if (challengeConfidence > 0) {
429
+ return {
430
+ type: "anti_bot_challenge",
431
+ reasonCode: "challenge_detected",
432
+ confidence: challengeConfidence,
433
+ retryable: false,
434
+ matches: boundedUniqueList([...matchedPatterns, ...challengeMatches], 16)
435
+ };
436
+ }
437
+ }
438
+ if (status === 429 || code === "rate_limited") {
439
+ return {
440
+ type: "rate_limited",
441
+ reasonCode: "rate_limited",
442
+ confidence: 0.95,
443
+ retryable: true,
444
+ matches: boundedUniqueList([...matchedPatterns, status === 429 ? "status:429" : "provider_code:rate_limited"], 16)
445
+ };
446
+ }
447
+ if (isUpstreamCode && (hasStaticBlockHost || /retrieval failed/i.test(message) || typeof status === "number" && status >= 500)) {
448
+ return {
449
+ type: "upstream_block",
450
+ reasonCode: "ip_blocked",
451
+ confidence: hasStaticBlockHost ? 0.9 : 0.8,
452
+ retryable: input.retryable ?? true,
453
+ matches: boundedUniqueList(
454
+ [
455
+ ...matchedPatterns,
456
+ `provider_code:${code}`,
457
+ ...hasStaticBlockHost ? ["network:blocked_static_host"] : []
458
+ ],
459
+ 16
460
+ )
461
+ };
462
+ }
463
+ if (input.restrictedTarget || RESTRICTED_TARGET_PATTERNS.some((pattern) => pattern.test(url)) || RESTRICTED_TARGET_PATTERNS.some((pattern) => pattern.test(finalUrl))) {
464
+ return {
465
+ type: "restricted_target",
466
+ confidence: 0.92,
467
+ retryable: false,
468
+ matches: boundedUniqueList([...matchedPatterns, "restricted_target"], 16)
469
+ };
470
+ }
471
+ if (input.envLimited || code === "unavailable" && ENV_LIMITED_PATTERNS.some((pattern) => pattern.test(message))) {
472
+ return {
473
+ type: "env_limited",
474
+ reasonCode: "env_limited",
475
+ confidence: input.envLimited ? 0.9 : 0.78,
476
+ retryable: true,
477
+ matches: boundedUniqueList([...matchedPatterns, "env_limited"], 16)
478
+ };
479
+ }
480
+ if (status || code || title || message || normalizedHosts.length > 0) {
481
+ return {
482
+ type: "unknown",
483
+ confidence: 0.5,
484
+ retryable: input.retryable ?? false,
485
+ matches: boundedUniqueList(matchedPatterns, 16)
486
+ };
487
+ }
488
+ return null;
489
+ };
490
+ var coerceJsonValue = (value, maxTextLength, promptGuardEnabled, diagnostics, seen) => {
491
+ if (value === null || typeof value === "number" || typeof value === "boolean") {
492
+ return value;
493
+ }
494
+ if (typeof value === "string") {
495
+ const sanitized = sanitizePromptGuardText(value, promptGuardEnabled);
496
+ diagnostics.entries += sanitized.diagnostics.entries;
497
+ diagnostics.quarantinedSegments += sanitized.diagnostics.quarantinedSegments;
498
+ const redacted = redactSensitive(sanitized.text);
499
+ const asString = typeof redacted === "string" ? redacted : String(redacted);
500
+ return clampText(asString, maxTextLength) ?? "";
501
+ }
502
+ if (Array.isArray(value)) {
503
+ return value.slice(0, 20).map((entry) => coerceJsonValue(entry, maxTextLength, promptGuardEnabled, diagnostics, seen));
504
+ }
505
+ if (typeof value !== "object") {
506
+ return String(value);
507
+ }
508
+ if (seen.has(value)) {
509
+ return "[Circular]";
510
+ }
511
+ seen.add(value);
512
+ const objectValue = value;
513
+ const entries = Object.entries(objectValue).slice(0, 30);
514
+ const output = {};
515
+ for (const [key, entryValue] of entries) {
516
+ output[key] = coerceJsonValue(entryValue, maxTextLength, promptGuardEnabled, diagnostics, seen);
517
+ }
518
+ return output;
519
+ };
520
+ var coerceEventList = (values, maxItems, maxTextLength, promptGuardEnabled, diagnostics) => {
521
+ if (!Array.isArray(values) || maxItems <= 0) return [];
522
+ return values.slice(-maxItems).map((entry) => {
523
+ const sanitized = coerceJsonValue(
524
+ redactSensitive(entry),
525
+ maxTextLength,
526
+ promptGuardEnabled,
527
+ diagnostics,
528
+ /* @__PURE__ */ new WeakSet()
529
+ );
530
+ if (!sanitized || typeof sanitized !== "object" || Array.isArray(sanitized)) {
531
+ return { value: sanitized };
532
+ }
533
+ return sanitized;
534
+ });
535
+ };
536
+ var resolveBlockerArtifactCaps = (partial) => {
537
+ return {
538
+ maxNetworkEvents: clampNumber(partial?.maxNetworkEvents ?? DEFAULT_BLOCKER_ARTIFACT_CAPS.maxNetworkEvents, 1, 500),
539
+ maxConsoleEvents: clampNumber(partial?.maxConsoleEvents ?? DEFAULT_BLOCKER_ARTIFACT_CAPS.maxConsoleEvents, 1, 500),
540
+ maxExceptionEvents: clampNumber(partial?.maxExceptionEvents ?? DEFAULT_BLOCKER_ARTIFACT_CAPS.maxExceptionEvents, 1, 200),
541
+ maxHosts: clampNumber(partial?.maxHosts ?? DEFAULT_BLOCKER_ARTIFACT_CAPS.maxHosts, 1, 200),
542
+ maxTextLength: clampNumber(partial?.maxTextLength ?? DEFAULT_BLOCKER_ARTIFACT_CAPS.maxTextLength, 32, 4096)
543
+ };
544
+ };
545
+ var classifyBlockerSignal = (input) => {
546
+ const promptGuardEnabled = input.promptGuardEnabled ?? true;
547
+ const titleSanitized = sanitizePromptGuardText(input.title ?? "", promptGuardEnabled);
548
+ const messageSanitized = sanitizePromptGuardText(input.message ?? "", promptGuardEnabled);
549
+ const matchedPatterns = boundedUniqueList(input.matchedPatterns, 16);
550
+ const normalizedHosts = boundedUniqueList(input.networkHosts?.map(toLower), 20);
551
+ const classification = classifyFromInputs({
552
+ ...input,
553
+ title: titleSanitized.text,
554
+ message: messageSanitized.text
555
+ }, normalizedHosts, matchedPatterns);
556
+ if (!classification) {
557
+ return null;
558
+ }
559
+ const threshold = clampThreshold(input.threshold);
560
+ const confidence = clampBlockerConfidence(classification.confidence);
561
+ if (confidence < threshold) {
562
+ return null;
563
+ }
564
+ const evidence = {
565
+ ...input.url ? { url: clampText(input.url, 512) } : {},
566
+ ...input.finalUrl ? { finalUrl: clampText(input.finalUrl, 512) } : {},
567
+ ...titleSanitized.text ? { title: clampText(titleSanitized.text, 512) } : {},
568
+ ...typeof input.status === "number" ? { status: input.status } : {},
569
+ ...input.providerErrorCode ? { providerErrorCode: input.providerErrorCode } : {},
570
+ matchedPatterns: boundedUniqueList(classification.matches, 16),
571
+ networkHosts: boundedUniqueList(normalizedHosts, 10),
572
+ ...input.traceRequestId ? { traceRequestId: input.traceRequestId } : {}
573
+ };
574
+ const sanitationEntries = titleSanitized.diagnostics.entries + messageSanitized.diagnostics.entries;
575
+ const sanitationQuarantined = titleSanitized.diagnostics.quarantinedSegments + messageSanitized.diagnostics.quarantinedSegments;
576
+ return {
577
+ schemaVersion: "1.0",
578
+ type: classification.type,
579
+ source: input.source,
580
+ ...classification.reasonCode ? { reasonCode: classification.reasonCode } : {},
581
+ confidence,
582
+ retryable: classification.retryable,
583
+ detectedAt: input.detectedAt ?? (/* @__PURE__ */ new Date()).toISOString(),
584
+ evidence,
585
+ actionHints: buildHints(classification.type),
586
+ ...sanitationEntries > 0 || sanitationQuarantined > 0 ? {
587
+ sanitation: {
588
+ entries: sanitationEntries,
589
+ quarantinedSegments: sanitationQuarantined
590
+ }
591
+ } : {}
592
+ };
593
+ };
594
+ var buildBlockerArtifacts = (input) => {
595
+ const caps = resolveBlockerArtifactCaps(input.caps);
596
+ const promptGuardEnabled = input.promptGuardEnabled ?? true;
597
+ const diagnostics = {
598
+ entries: 0,
599
+ quarantinedSegments: 0
600
+ };
601
+ const network = coerceEventList(
602
+ input.networkEvents,
603
+ caps.maxNetworkEvents,
604
+ caps.maxTextLength,
605
+ promptGuardEnabled,
606
+ diagnostics
607
+ );
608
+ const console2 = coerceEventList(
609
+ input.consoleEvents,
610
+ caps.maxConsoleEvents,
611
+ caps.maxTextLength,
612
+ promptGuardEnabled,
613
+ diagnostics
614
+ );
615
+ const exception = coerceEventList(
616
+ input.exceptionEvents,
617
+ caps.maxExceptionEvents,
618
+ caps.maxTextLength,
619
+ promptGuardEnabled,
620
+ diagnostics
621
+ );
622
+ const hosts = boundedUniqueList(
623
+ network.map((event) => typeof event.url === "string" ? extractHost(event.url) : null).filter((host) => typeof host === "string"),
624
+ caps.maxHosts
625
+ );
626
+ return {
627
+ schemaVersion: "1.0",
628
+ network,
629
+ console: console2,
630
+ exception,
631
+ hosts,
632
+ sanitation: diagnostics
633
+ };
634
+ };
635
+ var __test__ = {
636
+ classifyFromInputs,
637
+ extractHost,
638
+ hasAnyPattern,
639
+ clampThreshold,
640
+ isLoopbackHost
641
+ };
642
+
643
+ // src/providers/constraint.ts
644
+ var BLOCKER_TYPES = /* @__PURE__ */ new Set([
645
+ "auth_required",
646
+ "anti_bot_challenge",
647
+ "rate_limited",
648
+ "upstream_block",
649
+ "restricted_target",
650
+ "env_limited",
651
+ "unknown"
652
+ ]);
653
+ var CONSTRAINT_KINDS = /* @__PURE__ */ new Set([
654
+ "session_required",
655
+ "render_required"
656
+ ]);
657
+ var RENDER_REQUIRED_SHELLS = /* @__PURE__ */ new Set([
658
+ "bestbuy_international_gate",
659
+ "bestbuy_pdp_error_shell",
660
+ "duckduckgo_non_js_redirect",
661
+ "macys_access_denied_shell",
662
+ "social_first_party_help_shell",
663
+ "social_js_required_shell",
664
+ "social_render_shell",
665
+ "target_shell_page",
666
+ "temu_empty_shell"
667
+ ]);
668
+ var CHALLENGE_SHELLS = /* @__PURE__ */ new Set(["social_verification_wall", "temu_challenge_shell"]);
669
+ var toNonEmptyString = (value) => {
670
+ return typeof value === "string" && value.trim().length > 0 ? value.trim() : void 0;
671
+ };
672
+ var normalizeBlockerType = (value) => {
673
+ return typeof value === "string" && BLOCKER_TYPES.has(value) ? value : void 0;
674
+ };
675
+ var buildConstraint = (kind, evidenceCode, providerShell, message) => ({
676
+ kind,
677
+ evidenceCode,
678
+ ...providerShell ? { providerShell } : {},
679
+ ...message ? { message } : {}
680
+ });
681
+ var isProviderConstraint = (value) => {
682
+ if (!value || typeof value !== "object" || Array.isArray(value)) {
683
+ return false;
684
+ }
685
+ const candidate = value;
686
+ return CONSTRAINT_KINDS.has(candidate.kind) && typeof candidate.evidenceCode === "string" && candidate.evidenceCode.trim().length > 0 && (candidate.providerShell === void 0 || typeof candidate.providerShell === "string") && (candidate.message === void 0 || typeof candidate.message === "string");
687
+ };
688
+ var classifyProviderIssue = (input) => {
689
+ const providerShell = toNonEmptyString(input.providerShell);
690
+ const message = toNonEmptyString(input.message);
691
+ if (providerShell && CHALLENGE_SHELLS.has(providerShell)) {
692
+ return {
693
+ reasonCode: "challenge_detected",
694
+ blockerType: "anti_bot_challenge"
695
+ };
696
+ }
697
+ if (providerShell && RENDER_REQUIRED_SHELLS.has(providerShell)) {
698
+ return {
699
+ reasonCode: "env_limited",
700
+ blockerType: "env_limited",
701
+ constraint: buildConstraint("render_required", providerShell, providerShell, message)
702
+ };
703
+ }
704
+ const blocker = classifyBlockerSignal({
705
+ source: input.source ?? "runtime_fetch",
706
+ ...input.url ? { url: input.url, finalUrl: input.url } : {},
707
+ ...input.title ? { title: input.title } : {},
708
+ ...message ? { message } : {},
709
+ ...typeof input.status === "number" ? { status: input.status } : {},
710
+ ...input.providerErrorCode ? { providerErrorCode: input.providerErrorCode } : {},
711
+ ...typeof input.retryable === "boolean" ? { retryable: input.retryable } : {},
712
+ envLimited: input.browserRequired === true
713
+ });
714
+ if (blocker?.type === "auth_required") {
715
+ return {
716
+ /* c8 ignore next -- classifyBlockerSignal always supplies token_required for auth_required blockers */
717
+ reasonCode: blocker.reasonCode ?? "token_required",
718
+ blockerType: blocker.type,
719
+ constraint: buildConstraint("session_required", providerShell ?? "auth_required", providerShell, message)
720
+ };
721
+ }
722
+ if (blocker?.type === "anti_bot_challenge") {
723
+ return {
724
+ /* c8 ignore next -- classifyBlockerSignal always supplies challenge_detected for anti-bot blockers */
725
+ reasonCode: blocker.reasonCode ?? "challenge_detected",
726
+ blockerType: blocker.type
727
+ };
728
+ }
729
+ if (input.browserRequired === true) {
730
+ return {
731
+ /* c8 ignore next -- browserRequired inputs always classify to a blocker payload in the shared classifier */
732
+ reasonCode: blocker?.reasonCode ?? "env_limited",
733
+ /* c8 ignore next -- browserRequired fallbacks only normalize unknown blocker types */
734
+ blockerType: blocker?.type === "unknown" ? "env_limited" : blocker?.type,
735
+ /* c8 ignore next -- providerShell or blocker type always survives before the defensive browser_required fallback */
736
+ constraint: buildConstraint("render_required", providerShell ?? blocker?.type ?? "browser_required", providerShell, message)
737
+ };
738
+ }
739
+ if (blocker?.type === "env_limited") {
740
+ return {
741
+ /* c8 ignore next -- classifyBlockerSignal always supplies env_limited for env_limited blockers */
742
+ reasonCode: blocker.reasonCode ?? "env_limited",
743
+ blockerType: blocker.type
744
+ };
745
+ }
746
+ return null;
747
+ };
748
+ var readProviderIssueHint = (args) => {
749
+ const details = args.details;
750
+ const reasonCode = isProviderReasonCode(args.reasonCode) ? args.reasonCode : isProviderReasonCode(details?.reasonCode) ? details.reasonCode : void 0;
751
+ const blockerType = normalizeBlockerType(args.blockerType ?? details?.blockerType);
752
+ const constraint = isProviderConstraint(details?.constraint) ? details.constraint : void 0;
753
+ if (reasonCode || blockerType || constraint) {
754
+ return {
755
+ reasonCode: reasonCode ?? (constraint?.kind === "session_required" ? "token_required" : "env_limited"),
756
+ ...blockerType ? { blockerType } : {},
757
+ ...constraint ? { constraint } : {}
758
+ };
759
+ }
760
+ return classifyProviderIssue({
761
+ url: toNonEmptyString(details?.url),
762
+ title: toNonEmptyString(details?.title),
763
+ message: toNonEmptyString(details?.message ?? args.message),
764
+ providerShell: toNonEmptyString(details?.providerShell),
765
+ browserRequired: details?.browserRequired === true,
766
+ providerErrorCode: toNonEmptyString(args.code),
767
+ source: "runtime_fetch"
768
+ });
769
+ };
770
+ var readProviderIssueHintFromRecord = (record) => {
771
+ const details = record.attributes;
772
+ return readProviderIssueHint({
773
+ reasonCode: details.reasonCode,
774
+ blockerType: details.blockerType,
775
+ message: record.content,
776
+ details: {
777
+ url: record.url,
778
+ title: record.title,
779
+ message: record.content,
780
+ providerShell: details.providerShell,
781
+ browserRequired: details.browserRequired,
782
+ constraint: details.constraint
783
+ }
784
+ });
785
+ };
786
+ var applyProviderIssueHint = (details, hint) => {
787
+ if (!hint) return details;
788
+ const next = {
789
+ ...details ?? {},
790
+ reasonCode: hint.reasonCode
791
+ };
792
+ if (hint.blockerType && typeof next.blockerType !== "string") {
793
+ next.blockerType = hint.blockerType;
794
+ }
795
+ if (hint.constraint && !isProviderConstraint(next.constraint)) {
796
+ next.constraint = hint.constraint;
797
+ }
798
+ if (typeof next.guidance === "undefined") {
799
+ const guidance = buildProviderIssueGuidance({ hint, details: next });
800
+ if (guidance) {
801
+ next.guidance = guidance;
802
+ }
803
+ }
804
+ return next;
805
+ };
806
+ var providerLabel = (provider) => {
807
+ const normalized = toNonEmptyString(provider);
808
+ if (!normalized) return "Provider";
809
+ const separator = normalized.lastIndexOf("/");
810
+ const tail = separator >= 0 ? normalized.slice(separator + 1) : normalized;
811
+ return tail.charAt(0).toUpperCase() + tail.slice(1);
812
+ };
813
+ var hasPreservedBrowserState = (details) => {
814
+ return typeof details?.preservedSessionId === "string" || typeof details?.preservedTargetId === "string";
815
+ };
816
+ var buildGuidance = (reason, recommendedNextCommands) => ({
817
+ reason,
818
+ recommendedNextCommands
819
+ });
820
+ var buildAuthGuidance = (subject, preservedBrowserState) => {
821
+ return preservedBrowserState ? buildGuidance(
822
+ `${subject} preserved browser state that can finish authentication.`,
823
+ [
824
+ "Complete the login or account checkpoint in the preserved browser session.",
825
+ "Rerun the same provider or workflow after the session is fully authenticated."
826
+ ]
827
+ ) : buildGuidance(
828
+ `${subject} needs an authenticated session before retrying.`,
829
+ [
830
+ "Reuse an authenticated browser session, import logged-in cookies, or use the provider sign-in flow.",
831
+ "Rerun the same provider or workflow once the session is active."
832
+ ]
833
+ );
834
+ };
835
+ var buildChallengeGuidance = (subject, preservedBrowserState) => {
836
+ return preservedBrowserState ? buildGuidance(
837
+ `${subject} preserved browser state that can complete the current challenge.`,
838
+ [
839
+ "Finish the login or anti-bot challenge in the preserved browser session.",
840
+ "Rerun the same provider or workflow after the page unlocks."
841
+ ]
842
+ ) : buildGuidance(
843
+ `${subject} hit a challenge that still needs browser-assisted follow-up.`,
844
+ [
845
+ "Retry with browser assistance so the challenge can be completed interactively.",
846
+ "Only ask for manual credentials if browser-assisted recovery still cannot unlock the page."
847
+ ]
848
+ );
849
+ };
850
+ var buildRenderGuidance = (subject, preservedBrowserState, constraint) => {
851
+ if (constraint?.providerShell === "bestbuy_international_gate") {
852
+ return buildGuidance(
853
+ `${subject} needs the Best Buy country-selection interstitial cleared before retrying.`,
854
+ [
855
+ "Choose the shopping country or region in the preserved browser session.",
856
+ "Rerun the same provider or workflow after the Best Buy PDP or search results are visible."
857
+ ]
858
+ );
859
+ }
860
+ if (constraint?.providerShell === "bestbuy_pdp_error_shell") {
861
+ return buildGuidance(
862
+ `${subject} needs a valid Best Buy product detail page before retrying.`,
863
+ [
864
+ "Open the Best Buy product URL in the preserved browser session and confirm the PDP is visible.",
865
+ "Rerun the workflow after the product title, price, and media are visible instead of the generic error page."
866
+ ]
867
+ );
868
+ }
869
+ return preservedBrowserState ? buildGuidance(
870
+ `${subject} still needs a live browser-rendered page, but browser state is already preserved.`,
871
+ [
872
+ "Inspect the preserved browser session until usable content is visible.",
873
+ "Rerun the same provider or workflow after the rendered page is ready."
874
+ ]
875
+ ) : buildGuidance(
876
+ `${subject} needs a live browser-rendered page before retrying.`,
877
+ [
878
+ "Retry with browser assistance or a headed browser session.",
879
+ "Rerun the same provider or workflow after the rendered page is ready."
880
+ ]
881
+ );
882
+ };
883
+ var buildProviderIssueGuidance = (args) => {
884
+ const subject = providerLabel(args.provider);
885
+ const preservedBrowserState = hasPreservedBrowserState(args.details);
886
+ const disposition = toNonEmptyString(args.details?.disposition);
887
+ if (disposition === "completed") return void 0;
888
+ if (disposition === "challenge_preserved") {
889
+ return buildChallengeGuidance(subject, true);
890
+ }
891
+ if (args.hint.reasonCode === "token_required" || args.hint.reasonCode === "auth_required") {
892
+ return buildAuthGuidance(subject, preservedBrowserState);
893
+ }
894
+ if (args.hint.reasonCode === "challenge_detected") {
895
+ return buildChallengeGuidance(subject, preservedBrowserState);
896
+ }
897
+ if (args.hint.constraint?.kind === "render_required" || args.hint.reasonCode === "env_limited") {
898
+ return buildRenderGuidance(subject, preservedBrowserState, args.hint.constraint);
899
+ }
900
+ return void 0;
901
+ };
902
+ var summaryPriority = (hint) => {
903
+ if (hint.reasonCode === "token_required" || hint.reasonCode === "auth_required") return 3;
904
+ if (hint.reasonCode === "challenge_detected") return 2;
905
+ if (hint.constraint?.kind === "render_required") return 1;
906
+ return 0;
907
+ };
908
+ var summarizeRenderConstraint = (subject, constraint) => {
909
+ if (constraint?.providerShell === "bestbuy_international_gate") {
910
+ return `${subject} is blocked by the Best Buy country-selection interstitial.`;
911
+ }
912
+ if (constraint?.providerShell === "bestbuy_pdp_error_shell") {
913
+ return `${subject} is blocked by a Best Buy product-detail error shell.`;
914
+ }
915
+ return `${subject} requires a live browser-rendered page.`;
916
+ };
917
+ var summarizeProviderIssue = (args) => {
918
+ const subject = providerLabel(args.provider);
919
+ if (args.hint.reasonCode === "token_required" || args.hint.reasonCode === "auth_required") {
920
+ return `${subject} requires login or an existing session.`;
921
+ }
922
+ if (args.hint.reasonCode === "challenge_detected") {
923
+ return `${subject} hit an anti-bot challenge that requires manual completion.`;
924
+ }
925
+ if (args.hint.constraint?.kind === "render_required") {
926
+ return summarizeRenderConstraint(subject, args.hint.constraint);
927
+ }
928
+ return `${subject} requires manual browser follow-up; this run did not determine whether login or page rendering is required.`;
929
+ };
930
+ var summarizePrimaryProviderIssue = (failures) => {
931
+ if (!Array.isArray(failures) || failures.length === 0) return null;
932
+ let best = null;
933
+ for (const failure of failures) {
934
+ const hint = readProviderIssueHint({
935
+ reasonCode: failure.error?.reasonCode,
936
+ code: failure.error?.code,
937
+ message: failure.error?.message,
938
+ details: failure.error?.details
939
+ });
940
+ if (!hint) continue;
941
+ const summary = summarizeProviderIssue({ provider: failure.provider, hint });
942
+ const guidance = buildProviderIssueGuidance({
943
+ provider: failure.provider,
944
+ hint,
945
+ details: failure.error?.details
946
+ });
947
+ const candidate = {
948
+ provider: failure.provider,
949
+ summary,
950
+ ...hint,
951
+ ...guidance ? { guidance } : {}
952
+ };
953
+ if (!best || summaryPriority(candidate) > summaryPriority(best)) {
954
+ best = candidate;
955
+ }
956
+ }
957
+ return best;
958
+ };
959
+
960
+ export {
961
+ redactSensitive,
962
+ createRequestId,
963
+ stderrSink,
964
+ setDefaultLogSink,
965
+ createLogger,
966
+ applyPromptGuard,
967
+ DEFAULT_BLOCKER_ARTIFACT_CAPS,
968
+ clampBlockerConfidence,
969
+ clampText,
970
+ boundedUniqueList,
971
+ resolveBlockerArtifactCaps,
972
+ classifyBlockerSignal,
973
+ buildBlockerArtifacts,
974
+ __test__,
975
+ classifyProviderIssue,
976
+ readProviderIssueHint,
977
+ readProviderIssueHintFromRecord,
978
+ applyProviderIssueHint,
979
+ buildProviderIssueGuidance,
980
+ summarizePrimaryProviderIssue
981
+ };
982
+ //# sourceMappingURL=chunk-WHQZBUNY.js.map