@agent-native/creative-context 0.0.0-beta-20260820202238

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 (695) hide show
  1. package/README.md +154 -0
  2. package/agent-native.eject.json +41 -0
  3. package/agent-native.package.json +119 -0
  4. package/dist/actions/confirm-canonical-logo.d.ts +6 -0
  5. package/dist/actions/confirm-canonical-logo.d.ts.map +1 -0
  6. package/dist/actions/confirm-canonical-logo.js +19 -0
  7. package/dist/actions/confirm-canonical-logo.js.map +1 -0
  8. package/dist/actions/continue-context-import.d.ts +22 -0
  9. package/dist/actions/continue-context-import.d.ts.map +1 -0
  10. package/dist/actions/continue-context-import.js +13 -0
  11. package/dist/actions/continue-context-import.js.map +1 -0
  12. package/dist/actions/creative-context-a2a.d.ts +10 -0
  13. package/dist/actions/creative-context-a2a.d.ts.map +1 -0
  14. package/dist/actions/creative-context-a2a.js +66 -0
  15. package/dist/actions/creative-context-a2a.js.map +1 -0
  16. package/dist/actions/get-brand-profile.d.ts +33 -0
  17. package/dist/actions/get-brand-profile.d.ts.map +1 -0
  18. package/dist/actions/get-brand-profile.js +13 -0
  19. package/dist/actions/get-brand-profile.js.map +1 -0
  20. package/dist/actions/get-context-import-status.d.ts +22 -0
  21. package/dist/actions/get-context-import-status.d.ts.map +1 -0
  22. package/dist/actions/get-context-import-status.js +12 -0
  23. package/dist/actions/get-context-import-status.js.map +1 -0
  24. package/dist/actions/get-context-item.d.ts +2 -0
  25. package/dist/actions/get-context-item.d.ts.map +1 -0
  26. package/dist/actions/get-context-item.js +2 -0
  27. package/dist/actions/get-context-item.js.map +1 -0
  28. package/dist/actions/get-context-pack.d.ts +7 -0
  29. package/dist/actions/get-context-pack.d.ts.map +1 -0
  30. package/dist/actions/get-context-pack.js +12 -0
  31. package/dist/actions/get-context-pack.js.map +1 -0
  32. package/dist/actions/get-creative-context.d.ts +157 -0
  33. package/dist/actions/get-creative-context.d.ts.map +1 -0
  34. package/dist/actions/get-creative-context.js +148 -0
  35. package/dist/actions/get-creative-context.js.map +1 -0
  36. package/dist/actions/get-google-picker-session.d.ts +10 -0
  37. package/dist/actions/get-google-picker-session.d.ts.map +1 -0
  38. package/dist/actions/get-google-picker-session.js +38 -0
  39. package/dist/actions/get-google-picker-session.js.map +1 -0
  40. package/dist/actions/index.d.ts +3 -0
  41. package/dist/actions/index.d.ts.map +1 -0
  42. package/dist/actions/index.js +73 -0
  43. package/dist/actions/index.js.map +1 -0
  44. package/dist/actions/infer-brand-dna.d.ts +52 -0
  45. package/dist/actions/infer-brand-dna.d.ts.map +1 -0
  46. package/dist/actions/infer-brand-dna.js +13 -0
  47. package/dist/actions/infer-brand-dna.js.map +1 -0
  48. package/dist/actions/list-canonical-logo-candidates.d.ts +9 -0
  49. package/dist/actions/list-canonical-logo-candidates.d.ts.map +1 -0
  50. package/dist/actions/list-canonical-logo-candidates.js +82 -0
  51. package/dist/actions/list-canonical-logo-candidates.js.map +1 -0
  52. package/dist/actions/list-context-connections.d.ts +22 -0
  53. package/dist/actions/list-context-connections.d.ts.map +1 -0
  54. package/dist/actions/list-context-connections.js +43 -0
  55. package/dist/actions/list-context-connections.js.map +1 -0
  56. package/dist/actions/list-context-memberships.d.ts +11 -0
  57. package/dist/actions/list-context-memberships.d.ts.map +1 -0
  58. package/dist/actions/list-context-memberships.js +47 -0
  59. package/dist/actions/list-context-memberships.js.map +1 -0
  60. package/dist/actions/list-context-packs.d.ts +10 -0
  61. package/dist/actions/list-context-packs.d.ts.map +1 -0
  62. package/dist/actions/list-context-packs.js +16 -0
  63. package/dist/actions/list-context-packs.js.map +1 -0
  64. package/dist/actions/list-context-sources.d.ts +12 -0
  65. package/dist/actions/list-context-sources.d.ts.map +1 -0
  66. package/dist/actions/list-context-sources.js +20 -0
  67. package/dist/actions/list-context-sources.js.map +1 -0
  68. package/dist/actions/list-context-suggestions.d.ts +13 -0
  69. package/dist/actions/list-context-suggestions.d.ts.map +1 -0
  70. package/dist/actions/list-context-suggestions.js +28 -0
  71. package/dist/actions/list-context-suggestions.js.map +1 -0
  72. package/dist/actions/list-creative-contexts.d.ts +12 -0
  73. package/dist/actions/list-creative-contexts.d.ts.map +1 -0
  74. package/dist/actions/list-creative-contexts.js +28 -0
  75. package/dist/actions/list-creative-contexts.js.map +1 -0
  76. package/dist/actions/manage-brand-profile.d.ts +28 -0
  77. package/dist/actions/manage-brand-profile.d.ts.map +1 -0
  78. package/dist/actions/manage-brand-profile.js +47 -0
  79. package/dist/actions/manage-brand-profile.js.map +1 -0
  80. package/dist/actions/manage-context-membership.d.ts +64 -0
  81. package/dist/actions/manage-context-membership.d.ts.map +1 -0
  82. package/dist/actions/manage-context-membership.js +70 -0
  83. package/dist/actions/manage-context-membership.js.map +1 -0
  84. package/dist/actions/manage-context-pack.d.ts +36 -0
  85. package/dist/actions/manage-context-pack.d.ts.map +1 -0
  86. package/dist/actions/manage-context-pack.js +71 -0
  87. package/dist/actions/manage-context-pack.js.map +1 -0
  88. package/dist/actions/manage-context-source.d.ts +51 -0
  89. package/dist/actions/manage-context-source.d.ts.map +1 -0
  90. package/dist/actions/manage-context-source.js +130 -0
  91. package/dist/actions/manage-context-source.js.map +1 -0
  92. package/dist/actions/manage-creative-context.d.ts +28 -0
  93. package/dist/actions/manage-creative-context.d.ts.map +1 -0
  94. package/dist/actions/manage-creative-context.js +65 -0
  95. package/dist/actions/manage-creative-context.js.map +1 -0
  96. package/dist/actions/manage-layout-template.d.ts +13 -0
  97. package/dist/actions/manage-layout-template.d.ts.map +1 -0
  98. package/dist/actions/manage-layout-template.js +43 -0
  99. package/dist/actions/manage-layout-template.js.map +1 -0
  100. package/dist/actions/preview-context-import.d.ts +23 -0
  101. package/dist/actions/preview-context-import.d.ts.map +1 -0
  102. package/dist/actions/preview-context-import.js +57 -0
  103. package/dist/actions/preview-context-import.js.map +1 -0
  104. package/dist/actions/process-context-purge.d.ts +37 -0
  105. package/dist/actions/process-context-purge.d.ts.map +1 -0
  106. package/dist/actions/process-context-purge.js +20 -0
  107. package/dist/actions/process-context-purge.js.map +1 -0
  108. package/dist/actions/propose-brand-dna.d.ts +15 -0
  109. package/dist/actions/propose-brand-dna.d.ts.map +1 -0
  110. package/dist/actions/propose-brand-dna.js +19 -0
  111. package/dist/actions/propose-brand-dna.js.map +1 -0
  112. package/dist/actions/propose-canonical-logo.d.ts +9 -0
  113. package/dist/actions/propose-canonical-logo.d.ts.map +1 -0
  114. package/dist/actions/propose-canonical-logo.js +16 -0
  115. package/dist/actions/propose-canonical-logo.js.map +1 -0
  116. package/dist/actions/publish-brand-dna.d.ts +13 -0
  117. package/dist/actions/publish-brand-dna.d.ts.map +1 -0
  118. package/dist/actions/publish-brand-dna.js +23 -0
  119. package/dist/actions/publish-brand-dna.js.map +1 -0
  120. package/dist/actions/recommend-context-roots.d.ts +14 -0
  121. package/dist/actions/recommend-context-roots.d.ts.map +1 -0
  122. package/dist/actions/recommend-context-roots.js +22 -0
  123. package/dist/actions/recommend-context-roots.js.map +1 -0
  124. package/dist/actions/record-context-feedback.d.ts +10 -0
  125. package/dist/actions/record-context-feedback.d.ts.map +1 -0
  126. package/dist/actions/record-context-feedback.js +14 -0
  127. package/dist/actions/record-context-feedback.js.map +1 -0
  128. package/dist/actions/review-context-items.d.ts +35 -0
  129. package/dist/actions/review-context-items.d.ts.map +1 -0
  130. package/dist/actions/review-context-items.js +65 -0
  131. package/dist/actions/review-context-items.js.map +1 -0
  132. package/dist/actions/run-embedding-bakeoff.d.ts +15 -0
  133. package/dist/actions/run-embedding-bakeoff.d.ts.map +1 -0
  134. package/dist/actions/run-embedding-bakeoff.js +72 -0
  135. package/dist/actions/run-embedding-bakeoff.js.map +1 -0
  136. package/dist/actions/search-creative-context.d.ts +80 -0
  137. package/dist/actions/search-creative-context.d.ts.map +1 -0
  138. package/dist/actions/search-creative-context.js +42 -0
  139. package/dist/actions/search-creative-context.js.map +1 -0
  140. package/dist/actions/set-brand-dna.d.ts +15 -0
  141. package/dist/actions/set-brand-dna.d.ts.map +1 -0
  142. package/dist/actions/set-brand-dna.js +19 -0
  143. package/dist/actions/set-brand-dna.js.map +1 -0
  144. package/dist/actions/start-context-enrichment.d.ts +25 -0
  145. package/dist/actions/start-context-enrichment.d.ts.map +1 -0
  146. package/dist/actions/start-context-enrichment.js +48 -0
  147. package/dist/actions/start-context-enrichment.js.map +1 -0
  148. package/dist/actions/start-context-import.d.ts +24 -0
  149. package/dist/actions/start-context-import.d.ts.map +1 -0
  150. package/dist/actions/start-context-import.js +37 -0
  151. package/dist/actions/start-context-import.js.map +1 -0
  152. package/dist/client/CreativeContextChip.d.ts +18 -0
  153. package/dist/client/CreativeContextChip.d.ts.map +1 -0
  154. package/dist/client/CreativeContextChip.js +80 -0
  155. package/dist/client/CreativeContextChip.js.map +1 -0
  156. package/dist/client/CreativeContextPanel.d.ts +73 -0
  157. package/dist/client/CreativeContextPanel.d.ts.map +1 -0
  158. package/dist/client/CreativeContextPanel.js +1171 -0
  159. package/dist/client/CreativeContextPanel.js.map +1 -0
  160. package/dist/client/CreativeContextSettingsLink.d.ts +4 -0
  161. package/dist/client/CreativeContextSettingsLink.d.ts.map +1 -0
  162. package/dist/client/CreativeContextSettingsLink.js +8 -0
  163. package/dist/client/CreativeContextSettingsLink.js.map +1 -0
  164. package/dist/client/CreativeContextShareTab.d.ts +56 -0
  165. package/dist/client/CreativeContextShareTab.d.ts.map +1 -0
  166. package/dist/client/CreativeContextShareTab.js +213 -0
  167. package/dist/client/CreativeContextShareTab.js.map +1 -0
  168. package/dist/client/actions.d.ts +474 -0
  169. package/dist/client/actions.d.ts.map +1 -0
  170. package/dist/client/actions.js +411 -0
  171. package/dist/client/actions.js.map +1 -0
  172. package/dist/client/agent-tab.d.ts +10 -0
  173. package/dist/client/agent-tab.d.ts.map +1 -0
  174. package/dist/client/agent-tab.js +32 -0
  175. package/dist/client/agent-tab.js.map +1 -0
  176. package/dist/client/application-state.d.ts +24 -0
  177. package/dist/client/application-state.d.ts.map +1 -0
  178. package/dist/client/application-state.js +111 -0
  179. package/dist/client/application-state.js.map +1 -0
  180. package/dist/client/google-slides-picker.d.ts +19 -0
  181. package/dist/client/google-slides-picker.d.ts.map +1 -0
  182. package/dist/client/google-slides-picker.js +106 -0
  183. package/dist/client/google-slides-picker.js.map +1 -0
  184. package/dist/client/index.d.ts +10 -0
  185. package/dist/client/index.d.ts.map +1 -0
  186. package/dist/client/index.js +10 -0
  187. package/dist/client/index.js.map +1 -0
  188. package/dist/client/messages.d.ts +5 -0
  189. package/dist/client/messages.d.ts.map +1 -0
  190. package/dist/client/messages.js +1158 -0
  191. package/dist/client/messages.js.map +1 -0
  192. package/dist/connectors/context.d.ts +9 -0
  193. package/dist/connectors/context.d.ts.map +1 -0
  194. package/dist/connectors/context.js +59 -0
  195. package/dist/connectors/context.js.map +1 -0
  196. package/dist/connectors/document-parser.d.ts +2 -0
  197. package/dist/connectors/document-parser.d.ts.map +1 -0
  198. package/dist/connectors/document-parser.js +2 -0
  199. package/dist/connectors/document-parser.js.map +1 -0
  200. package/dist/connectors/figma-native.d.ts +18 -0
  201. package/dist/connectors/figma-native.d.ts.map +1 -0
  202. package/dist/connectors/figma-native.js +883 -0
  203. package/dist/connectors/figma-native.js.map +1 -0
  204. package/dist/connectors/figma.d.ts +10 -0
  205. package/dist/connectors/figma.d.ts.map +1 -0
  206. package/dist/connectors/figma.js +166 -0
  207. package/dist/connectors/figma.js.map +1 -0
  208. package/dist/connectors/google-slides-native.d.ts +58 -0
  209. package/dist/connectors/google-slides-native.d.ts.map +1 -0
  210. package/dist/connectors/google-slides-native.js +1118 -0
  211. package/dist/connectors/google-slides-native.js.map +1 -0
  212. package/dist/connectors/google-slides.d.ts +15 -0
  213. package/dist/connectors/google-slides.d.ts.map +1 -0
  214. package/dist/connectors/google-slides.js +895 -0
  215. package/dist/connectors/google-slides.js.map +1 -0
  216. package/dist/connectors/index.d.ts +21 -0
  217. package/dist/connectors/index.d.ts.map +1 -0
  218. package/dist/connectors/index.js +45 -0
  219. package/dist/connectors/index.js.map +1 -0
  220. package/dist/connectors/manual.d.ts +9 -0
  221. package/dist/connectors/manual.d.ts.map +1 -0
  222. package/dist/connectors/manual.js +91 -0
  223. package/dist/connectors/manual.js.map +1 -0
  224. package/dist/connectors/normalize.d.ts +42 -0
  225. package/dist/connectors/normalize.d.ts.map +1 -0
  226. package/dist/connectors/normalize.js +335 -0
  227. package/dist/connectors/normalize.js.map +1 -0
  228. package/dist/connectors/notion.d.ts +10 -0
  229. package/dist/connectors/notion.d.ts.map +1 -0
  230. package/dist/connectors/notion.js +393 -0
  231. package/dist/connectors/notion.js.map +1 -0
  232. package/dist/connectors/private-artifacts.d.ts +39 -0
  233. package/dist/connectors/private-artifacts.d.ts.map +1 -0
  234. package/dist/connectors/private-artifacts.js +175 -0
  235. package/dist/connectors/private-artifacts.js.map +1 -0
  236. package/dist/connectors/provider-response.d.ts +20 -0
  237. package/dist/connectors/provider-response.d.ts.map +1 -0
  238. package/dist/connectors/provider-response.js +98 -0
  239. package/dist/connectors/provider-response.js.map +1 -0
  240. package/dist/connectors/recommendations.d.ts +25 -0
  241. package/dist/connectors/recommendations.d.ts.map +1 -0
  242. package/dist/connectors/recommendations.js +172 -0
  243. package/dist/connectors/recommendations.js.map +1 -0
  244. package/dist/connectors/registry.d.ts +10 -0
  245. package/dist/connectors/registry.d.ts.map +1 -0
  246. package/dist/connectors/registry.js +34 -0
  247. package/dist/connectors/registry.js.map +1 -0
  248. package/dist/connectors/rendered-design.d.ts +68 -0
  249. package/dist/connectors/rendered-design.d.ts.map +1 -0
  250. package/dist/connectors/rendered-design.js +362 -0
  251. package/dist/connectors/rendered-design.js.map +1 -0
  252. package/dist/connectors/rendered-page.d.ts +115 -0
  253. package/dist/connectors/rendered-page.d.ts.map +1 -0
  254. package/dist/connectors/rendered-page.js +1036 -0
  255. package/dist/connectors/rendered-page.js.map +1 -0
  256. package/dist/connectors/smart-defaults.d.ts +9 -0
  257. package/dist/connectors/smart-defaults.d.ts.map +1 -0
  258. package/dist/connectors/smart-defaults.js +72 -0
  259. package/dist/connectors/smart-defaults.js.map +1 -0
  260. package/dist/connectors/types.d.ts +79 -0
  261. package/dist/connectors/types.d.ts.map +1 -0
  262. package/dist/connectors/types.js +2 -0
  263. package/dist/connectors/types.js.map +1 -0
  264. package/dist/connectors/upload.d.ts +9 -0
  265. package/dist/connectors/upload.d.ts.map +1 -0
  266. package/dist/connectors/upload.js +440 -0
  267. package/dist/connectors/upload.js.map +1 -0
  268. package/dist/connectors/website.d.ts +20 -0
  269. package/dist/connectors/website.d.ts.map +1 -0
  270. package/dist/connectors/website.js +616 -0
  271. package/dist/connectors/website.js.map +1 -0
  272. package/dist/embeddings/index.d.ts +3 -0
  273. package/dist/embeddings/index.d.ts.map +1 -0
  274. package/dist/embeddings/index.js +3 -0
  275. package/dist/embeddings/index.js.map +1 -0
  276. package/dist/embeddings/providers.d.ts +2 -0
  277. package/dist/embeddings/providers.d.ts.map +1 -0
  278. package/dist/embeddings/providers.js +2 -0
  279. package/dist/embeddings/providers.js.map +1 -0
  280. package/dist/embeddings/types.d.ts +2 -0
  281. package/dist/embeddings/types.d.ts.map +1 -0
  282. package/dist/embeddings/types.js +2 -0
  283. package/dist/embeddings/types.js.map +1 -0
  284. package/dist/eval/acceptance-fixtures.d.ts +3 -0
  285. package/dist/eval/acceptance-fixtures.d.ts.map +1 -0
  286. package/dist/eval/acceptance-fixtures.js +84 -0
  287. package/dist/eval/acceptance-fixtures.js.map +1 -0
  288. package/dist/eval/acceptance.d.ts +114 -0
  289. package/dist/eval/acceptance.d.ts.map +1 -0
  290. package/dist/eval/acceptance.js +260 -0
  291. package/dist/eval/acceptance.js.map +1 -0
  292. package/dist/eval/fixtures.d.ts +16 -0
  293. package/dist/eval/fixtures.d.ts.map +1 -0
  294. package/dist/eval/fixtures.js +119 -0
  295. package/dist/eval/fixtures.js.map +1 -0
  296. package/dist/eval/index.d.ts +63 -0
  297. package/dist/eval/index.d.ts.map +1 -0
  298. package/dist/eval/index.js +174 -0
  299. package/dist/eval/index.js.map +1 -0
  300. package/dist/index.d.ts +5 -0
  301. package/dist/index.d.ts.map +1 -0
  302. package/dist/index.js +5 -0
  303. package/dist/index.js.map +1 -0
  304. package/dist/jobs/background-worker.d.ts +31 -0
  305. package/dist/jobs/background-worker.d.ts.map +1 -0
  306. package/dist/jobs/background-worker.js +315 -0
  307. package/dist/jobs/background-worker.js.map +1 -0
  308. package/dist/jobs/import-runner.d.ts +3 -0
  309. package/dist/jobs/import-runner.d.ts.map +1 -0
  310. package/dist/jobs/import-runner.js +613 -0
  311. package/dist/jobs/import-runner.js.map +1 -0
  312. package/dist/jobs/index.d.ts +9 -0
  313. package/dist/jobs/index.d.ts.map +1 -0
  314. package/dist/jobs/index.js +8 -0
  315. package/dist/jobs/index.js.map +1 -0
  316. package/dist/jobs/progress.d.ts +3 -0
  317. package/dist/jobs/progress.d.ts.map +1 -0
  318. package/dist/jobs/progress.js +30 -0
  319. package/dist/jobs/progress.js.map +1 -0
  320. package/dist/jobs/rebuild.d.ts +13 -0
  321. package/dist/jobs/rebuild.d.ts.map +1 -0
  322. package/dist/jobs/rebuild.js +178 -0
  323. package/dist/jobs/rebuild.js.map +1 -0
  324. package/dist/jobs/server-worker.d.ts +16 -0
  325. package/dist/jobs/server-worker.d.ts.map +1 -0
  326. package/dist/jobs/server-worker.js +262 -0
  327. package/dist/jobs/server-worker.js.map +1 -0
  328. package/dist/jobs/store-adapter.d.ts +3 -0
  329. package/dist/jobs/store-adapter.d.ts.map +1 -0
  330. package/dist/jobs/store-adapter.js +37 -0
  331. package/dist/jobs/store-adapter.js.map +1 -0
  332. package/dist/jobs/types.d.ts +138 -0
  333. package/dist/jobs/types.d.ts.map +1 -0
  334. package/dist/jobs/types.js +2 -0
  335. package/dist/jobs/types.js.map +1 -0
  336. package/dist/jobs/worker.d.ts +27 -0
  337. package/dist/jobs/worker.d.ts.map +1 -0
  338. package/dist/jobs/worker.js +90 -0
  339. package/dist/jobs/worker.js.map +1 -0
  340. package/dist/media-url.d.ts +7 -0
  341. package/dist/media-url.d.ts.map +1 -0
  342. package/dist/media-url.js +15 -0
  343. package/dist/media-url.js.map +1 -0
  344. package/dist/native-artifact-reassembly.d.ts +25 -0
  345. package/dist/native-artifact-reassembly.d.ts.map +1 -0
  346. package/dist/native-artifact-reassembly.js +262 -0
  347. package/dist/native-artifact-reassembly.js.map +1 -0
  348. package/dist/native-artifact.d.ts +88 -0
  349. package/dist/native-artifact.d.ts.map +1 -0
  350. package/dist/native-artifact.js +86 -0
  351. package/dist/native-artifact.js.map +1 -0
  352. package/dist/schema/index.d.ts +7111 -0
  353. package/dist/schema/index.d.ts.map +1 -0
  354. package/dist/schema/index.js +469 -0
  355. package/dist/schema/index.js.map +1 -0
  356. package/dist/schema/migrations.d.ts +10 -0
  357. package/dist/schema/migrations.d.ts.map +1 -0
  358. package/dist/schema/migrations.js +333 -0
  359. package/dist/schema/migrations.js.map +1 -0
  360. package/dist/search/fusion.d.ts +2 -0
  361. package/dist/search/fusion.d.ts.map +1 -0
  362. package/dist/search/fusion.js +2 -0
  363. package/dist/search/fusion.js.map +1 -0
  364. package/dist/search/mode.d.ts +4 -0
  365. package/dist/search/mode.d.ts.map +1 -0
  366. package/dist/search/mode.js +13 -0
  367. package/dist/search/mode.js.map +1 -0
  368. package/dist/search/postgres-fts.d.ts +2 -0
  369. package/dist/search/postgres-fts.d.ts.map +1 -0
  370. package/dist/search/postgres-fts.js +2 -0
  371. package/dist/search/postgres-fts.js.map +1 -0
  372. package/dist/server/brand-context.d.ts +15 -0
  373. package/dist/server/brand-context.d.ts.map +1 -0
  374. package/dist/server/brand-context.js +149 -0
  375. package/dist/server/brand-context.js.map +1 -0
  376. package/dist/server/context.d.ts +77 -0
  377. package/dist/server/context.d.ts.map +1 -0
  378. package/dist/server/context.js +63 -0
  379. package/dist/server/context.js.map +1 -0
  380. package/dist/server/enrichment.d.ts +24 -0
  381. package/dist/server/enrichment.d.ts.map +1 -0
  382. package/dist/server/enrichment.js +138 -0
  383. package/dist/server/enrichment.js.map +1 -0
  384. package/dist/server/generation-artifact-access.d.ts +21 -0
  385. package/dist/server/generation-artifact-access.d.ts.map +1 -0
  386. package/dist/server/generation-artifact-access.js +113 -0
  387. package/dist/server/generation-artifact-access.js.map +1 -0
  388. package/dist/server/generation-context.d.ts +220 -0
  389. package/dist/server/generation-context.d.ts.map +1 -0
  390. package/dist/server/generation-context.js +432 -0
  391. package/dist/server/generation-context.js.map +1 -0
  392. package/dist/server/index.d.ts +27 -0
  393. package/dist/server/index.d.ts.map +1 -0
  394. package/dist/server/index.js +115 -0
  395. package/dist/server/index.js.map +1 -0
  396. package/dist/server/isolated-a2a.d.ts +175 -0
  397. package/dist/server/isolated-a2a.d.ts.map +1 -0
  398. package/dist/server/isolated-a2a.js +312 -0
  399. package/dist/server/isolated-a2a.js.map +1 -0
  400. package/dist/server/media.d.ts +15 -0
  401. package/dist/server/media.d.ts.map +1 -0
  402. package/dist/server/media.js +108 -0
  403. package/dist/server/media.js.map +1 -0
  404. package/dist/server/native-resource-capture.d.ts +78 -0
  405. package/dist/server/native-resource-capture.d.ts.map +1 -0
  406. package/dist/server/native-resource-capture.js +94 -0
  407. package/dist/server/native-resource-capture.js.map +1 -0
  408. package/dist/server/prompt-provider.d.ts +5 -0
  409. package/dist/server/prompt-provider.d.ts.map +1 -0
  410. package/dist/server/prompt-provider.js +59 -0
  411. package/dist/server/prompt-provider.js.map +1 -0
  412. package/dist/server/public-serialization.d.ts +160 -0
  413. package/dist/server/public-serialization.d.ts.map +1 -0
  414. package/dist/server/public-serialization.js +108 -0
  415. package/dist/server/public-serialization.js.map +1 -0
  416. package/dist/server/resource-paths.d.ts +3 -0
  417. package/dist/server/resource-paths.d.ts.map +1 -0
  418. package/dist/server/resource-paths.js +5 -0
  419. package/dist/server/resource-paths.js.map +1 -0
  420. package/dist/server/retrieval.d.ts +83 -0
  421. package/dist/server/retrieval.d.ts.map +1 -0
  422. package/dist/server/retrieval.js +445 -0
  423. package/dist/server/retrieval.js.map +1 -0
  424. package/dist/server/safe-native-preview.d.ts +15 -0
  425. package/dist/server/safe-native-preview.d.ts.map +1 -0
  426. package/dist/server/safe-native-preview.js +148 -0
  427. package/dist/server/safe-native-preview.js.map +1 -0
  428. package/dist/store/brand.d.ts +47 -0
  429. package/dist/store/brand.d.ts.map +1 -0
  430. package/dist/store/brand.js +346 -0
  431. package/dist/store/brand.js.map +1 -0
  432. package/dist/store/content.d.ts +134 -0
  433. package/dist/store/content.d.ts.map +1 -0
  434. package/dist/store/content.js +1677 -0
  435. package/dist/store/content.js.map +1 -0
  436. package/dist/store/contexts.d.ts +216 -0
  437. package/dist/store/contexts.d.ts.map +1 -0
  438. package/dist/store/contexts.js +1346 -0
  439. package/dist/store/contexts.js.map +1 -0
  440. package/dist/store/generation.d.ts +28 -0
  441. package/dist/store/generation.d.ts.map +1 -0
  442. package/dist/store/generation.js +140 -0
  443. package/dist/store/generation.js.map +1 -0
  444. package/dist/store/helpers.d.ts +12 -0
  445. package/dist/store/helpers.d.ts.map +1 -0
  446. package/dist/store/helpers.js +41 -0
  447. package/dist/store/helpers.js.map +1 -0
  448. package/dist/store/index.d.ts +11 -0
  449. package/dist/store/index.d.ts.map +1 -0
  450. package/dist/store/index.js +11 -0
  451. package/dist/store/index.js.map +1 -0
  452. package/dist/store/inference.d.ts +57 -0
  453. package/dist/store/inference.d.ts.map +1 -0
  454. package/dist/store/inference.js +279 -0
  455. package/dist/store/inference.js.map +1 -0
  456. package/dist/store/jobs.d.ts +80 -0
  457. package/dist/store/jobs.d.ts.map +1 -0
  458. package/dist/store/jobs.js +428 -0
  459. package/dist/store/jobs.js.map +1 -0
  460. package/dist/store/native-artifact-summary.d.ts +7 -0
  461. package/dist/store/native-artifact-summary.d.ts.map +1 -0
  462. package/dist/store/native-artifact-summary.js +10 -0
  463. package/dist/store/native-artifact-summary.js.map +1 -0
  464. package/dist/store/packs.d.ts +36 -0
  465. package/dist/store/packs.d.ts.map +1 -0
  466. package/dist/store/packs.js +438 -0
  467. package/dist/store/packs.js.map +1 -0
  468. package/dist/store/purge.d.ts +16 -0
  469. package/dist/store/purge.d.ts.map +1 -0
  470. package/dist/store/purge.js +354 -0
  471. package/dist/store/purge.js.map +1 -0
  472. package/dist/store/sources.d.ts +76 -0
  473. package/dist/store/sources.d.ts.map +1 -0
  474. package/dist/store/sources.js +525 -0
  475. package/dist/store/sources.js.map +1 -0
  476. package/dist/store/suggestions.d.ts +29 -0
  477. package/dist/store/suggestions.d.ts.map +1 -0
  478. package/dist/store/suggestions.js +270 -0
  479. package/dist/store/suggestions.js.map +1 -0
  480. package/dist/types.d.ts +578 -0
  481. package/dist/types.d.ts.map +1 -0
  482. package/dist/types.js +10 -0
  483. package/dist/types.js.map +1 -0
  484. package/dist/untrusted-reference.d.ts +8 -0
  485. package/dist/untrusted-reference.d.ts.map +1 -0
  486. package/dist/untrusted-reference.js +19 -0
  487. package/dist/untrusted-reference.js.map +1 -0
  488. package/dist/vector/index.d.ts +2 -0
  489. package/dist/vector/index.d.ts.map +1 -0
  490. package/dist/vector/index.js +2 -0
  491. package/dist/vector/index.js.map +1 -0
  492. package/dist/vector/pgvector.d.ts +2 -0
  493. package/dist/vector/pgvector.d.ts.map +1 -0
  494. package/dist/vector/pgvector.js +2 -0
  495. package/dist/vector/pgvector.js.map +1 -0
  496. package/docs/evaluation.md +92 -0
  497. package/docs/llms-full.txt +168 -0
  498. package/docs/llms.txt +76 -0
  499. package/docs/skills/creative-context/SKILL.md +90 -0
  500. package/package.json +100 -0
  501. package/src/actions/agent-input-schemas.spec.ts +46 -0
  502. package/src/actions/confirm-canonical-logo.ts +20 -0
  503. package/src/actions/continue-context-import.ts +15 -0
  504. package/src/actions/creative-context-a2a.spec.ts +162 -0
  505. package/src/actions/creative-context-a2a.ts +88 -0
  506. package/src/actions/get-brand-profile.ts +16 -0
  507. package/src/actions/get-context-import-status.ts +13 -0
  508. package/src/actions/get-context-item.ts +1 -0
  509. package/src/actions/get-context-pack.ts +14 -0
  510. package/src/actions/get-creative-context.spec.ts +435 -0
  511. package/src/actions/get-creative-context.ts +197 -0
  512. package/src/actions/get-google-picker-session.spec.ts +62 -0
  513. package/src/actions/get-google-picker-session.ts +45 -0
  514. package/src/actions/index.ts +75 -0
  515. package/src/actions/infer-brand-dna.ts +15 -0
  516. package/src/actions/job-public-serialization.spec.ts +143 -0
  517. package/src/actions/list-canonical-logo-candidates.ts +121 -0
  518. package/src/actions/list-context-connections.spec.ts +23 -0
  519. package/src/actions/list-context-connections.ts +51 -0
  520. package/src/actions/list-context-memberships.ts +56 -0
  521. package/src/actions/list-context-packs.ts +17 -0
  522. package/src/actions/list-context-sources.ts +21 -0
  523. package/src/actions/list-context-suggestions.ts +30 -0
  524. package/src/actions/list-creative-contexts.spec.ts +38 -0
  525. package/src/actions/list-creative-contexts.ts +32 -0
  526. package/src/actions/manage-brand-profile.ts +58 -0
  527. package/src/actions/manage-context-membership.ts +80 -0
  528. package/src/actions/manage-context-pack.ts +81 -0
  529. package/src/actions/manage-context-source.ts +151 -0
  530. package/src/actions/manage-creative-context.ts +73 -0
  531. package/src/actions/manage-layout-template.ts +51 -0
  532. package/src/actions/preview-context-import.spec.ts +64 -0
  533. package/src/actions/preview-context-import.ts +61 -0
  534. package/src/actions/process-context-purge.ts +28 -0
  535. package/src/actions/propose-brand-dna.ts +22 -0
  536. package/src/actions/propose-canonical-logo.ts +19 -0
  537. package/src/actions/publish-brand-dna.ts +25 -0
  538. package/src/actions/recommend-context-roots.ts +24 -0
  539. package/src/actions/record-context-feedback.ts +16 -0
  540. package/src/actions/review-context-items.ts +69 -0
  541. package/src/actions/run-embedding-bakeoff.ts +90 -0
  542. package/src/actions/search-creative-context.ts +48 -0
  543. package/src/actions/set-brand-dna.ts +22 -0
  544. package/src/actions/start-context-enrichment.ts +52 -0
  545. package/src/actions/start-context-import.ts +38 -0
  546. package/src/client/CreativeContextChip.spec.ts +59 -0
  547. package/src/client/CreativeContextChip.tsx +243 -0
  548. package/src/client/CreativeContextPanel.tsx +3600 -0
  549. package/src/client/CreativeContextSettingsLink.tsx +30 -0
  550. package/src/client/CreativeContextShareTab.spec.ts +70 -0
  551. package/src/client/CreativeContextShareTab.tsx +666 -0
  552. package/src/client/actions.spec.ts +177 -0
  553. package/src/client/actions.ts +1024 -0
  554. package/src/client/agent-tab.tsx +56 -0
  555. package/src/client/application-state.spec.ts +46 -0
  556. package/src/client/application-state.ts +158 -0
  557. package/src/client/google-slides-picker.spec.ts +36 -0
  558. package/src/client/google-slides-picker.ts +146 -0
  559. package/src/client/index.ts +102 -0
  560. package/src/client/messages.ts +1370 -0
  561. package/src/client/source-config.spec.ts +166 -0
  562. package/src/connectors/connectors.spec.ts +778 -0
  563. package/src/connectors/context.ts +83 -0
  564. package/src/connectors/document-parser.ts +5 -0
  565. package/src/connectors/figma-native.ts +1192 -0
  566. package/src/connectors/figma-native.visual.spec.ts +221 -0
  567. package/src/connectors/figma.spec.ts +812 -0
  568. package/src/connectors/figma.ts +257 -0
  569. package/src/connectors/fixtures/google-slides-native.json +353 -0
  570. package/src/connectors/google-slides-native.spec.ts +804 -0
  571. package/src/connectors/google-slides-native.ts +1656 -0
  572. package/src/connectors/google-slides-native.visual.spec.ts +119 -0
  573. package/src/connectors/google-slides.ts +1171 -0
  574. package/src/connectors/index.ts +112 -0
  575. package/src/connectors/manual.ts +132 -0
  576. package/src/connectors/normalize.spec.ts +144 -0
  577. package/src/connectors/normalize.ts +475 -0
  578. package/src/connectors/notion.ts +529 -0
  579. package/src/connectors/private-artifacts.spec.ts +95 -0
  580. package/src/connectors/private-artifacts.ts +248 -0
  581. package/src/connectors/provider-response.ts +144 -0
  582. package/src/connectors/recommendations.ts +237 -0
  583. package/src/connectors/registry.ts +48 -0
  584. package/src/connectors/rendered-design.spec.ts +171 -0
  585. package/src/connectors/rendered-design.ts +495 -0
  586. package/src/connectors/rendered-page.spec.ts +388 -0
  587. package/src/connectors/rendered-page.ts +1387 -0
  588. package/src/connectors/smart-defaults.spec.ts +135 -0
  589. package/src/connectors/smart-defaults.ts +87 -0
  590. package/src/connectors/types.ts +113 -0
  591. package/src/connectors/upload.spec.ts +175 -0
  592. package/src/connectors/upload.ts +548 -0
  593. package/src/connectors/website.spec.ts +465 -0
  594. package/src/connectors/website.ts +777 -0
  595. package/src/embeddings/index.ts +2 -0
  596. package/src/embeddings/providers.spec.ts +73 -0
  597. package/src/embeddings/providers.ts +1 -0
  598. package/src/embeddings/types.ts +6 -0
  599. package/src/eval/acceptance-fixtures.ts +97 -0
  600. package/src/eval/acceptance.spec.ts +92 -0
  601. package/src/eval/acceptance.ts +371 -0
  602. package/src/eval/connectors-golden.spec.ts +421 -0
  603. package/src/eval/eval.spec.ts +166 -0
  604. package/src/eval/fixtures/README.md +17 -0
  605. package/src/eval/fixtures/figma-brand-system-v1.json +140 -0
  606. package/src/eval/fixtures/figma-brand-system-v2.json +127 -0
  607. package/src/eval/fixtures/launch-hero.png +0 -0
  608. package/src/eval/fixtures/launch-system-v1.pptx +0 -0
  609. package/src/eval/fixtures/launch-system-v2.pptx +0 -0
  610. package/src/eval/fixtures/notion-brand-root.json +218 -0
  611. package/src/eval/fixtures/pricing-hero.png +0 -0
  612. package/src/eval/fixtures/rendered-brand-page.html +76 -0
  613. package/src/eval/fixtures.spec.ts +43 -0
  614. package/src/eval/fixtures.ts +136 -0
  615. package/src/eval/index.ts +291 -0
  616. package/src/eval/library-flow.acceptance.spec.tsx +145 -0
  617. package/src/index.ts +4 -0
  618. package/src/jobs/background-worker.ts +423 -0
  619. package/src/jobs/import-runner.spec.ts +582 -0
  620. package/src/jobs/import-runner.ts +791 -0
  621. package/src/jobs/index.ts +40 -0
  622. package/src/jobs/progress.ts +37 -0
  623. package/src/jobs/rebuild.ts +245 -0
  624. package/src/jobs/server-worker.spec.ts +181 -0
  625. package/src/jobs/server-worker.ts +354 -0
  626. package/src/jobs/store-adapter.ts +52 -0
  627. package/src/jobs/types.ts +147 -0
  628. package/src/jobs/worker.ts +152 -0
  629. package/src/manifest.spec.ts +26 -0
  630. package/src/media-url.ts +17 -0
  631. package/src/native-artifact-reassembly.spec.ts +386 -0
  632. package/src/native-artifact-reassembly.ts +406 -0
  633. package/src/native-artifact.ts +102 -0
  634. package/src/schema/index.ts +527 -0
  635. package/src/schema/migrations.spec.ts +41 -0
  636. package/src/schema/migrations.ts +338 -0
  637. package/src/search/fusion.spec.ts +21 -0
  638. package/src/search/fusion.ts +1 -0
  639. package/src/search/mode.spec.ts +28 -0
  640. package/src/search/mode.ts +21 -0
  641. package/src/search/postgres-fts.spec.ts +63 -0
  642. package/src/search/postgres-fts.ts +1 -0
  643. package/src/server/brand-context.spec.ts +43 -0
  644. package/src/server/brand-context.ts +160 -0
  645. package/src/server/context.ts +162 -0
  646. package/src/server/enrichment.spec.ts +94 -0
  647. package/src/server/enrichment.ts +166 -0
  648. package/src/server/generation-artifact-access.spec.ts +104 -0
  649. package/src/server/generation-artifact-access.ts +217 -0
  650. package/src/server/generation-context-a2a.spec.ts +282 -0
  651. package/src/server/generation-context-off.spec.ts +213 -0
  652. package/src/server/generation-context.spec.ts +124 -0
  653. package/src/server/generation-context.ts +639 -0
  654. package/src/server/index.spec.ts +30 -0
  655. package/src/server/index.ts +163 -0
  656. package/src/server/isolated-a2a.spec.ts +184 -0
  657. package/src/server/isolated-a2a.ts +416 -0
  658. package/src/server/media.spec.ts +120 -0
  659. package/src/server/media.ts +136 -0
  660. package/src/server/native-resource-capture.spec.ts +121 -0
  661. package/src/server/native-resource-capture.ts +198 -0
  662. package/src/server/prompt-provider.spec.ts +78 -0
  663. package/src/server/prompt-provider.ts +73 -0
  664. package/src/server/public-serialization.spec.ts +150 -0
  665. package/src/server/public-serialization.ts +130 -0
  666. package/src/server/resource-paths.spec.ts +9 -0
  667. package/src/server/resource-paths.ts +5 -0
  668. package/src/server/retrieval-vector.spec.ts +180 -0
  669. package/src/server/retrieval.ts +590 -0
  670. package/src/server/safe-native-preview.spec.ts +29 -0
  671. package/src/server/safe-native-preview.ts +199 -0
  672. package/src/store/access.integration.spec.ts +3523 -0
  673. package/src/store/brand.ts +458 -0
  674. package/src/store/content.ts +2317 -0
  675. package/src/store/contexts.ts +1840 -0
  676. package/src/store/generation.ts +226 -0
  677. package/src/store/helpers.ts +53 -0
  678. package/src/store/index.ts +10 -0
  679. package/src/store/inference.spec.ts +84 -0
  680. package/src/store/inference.ts +339 -0
  681. package/src/store/invariants.spec.ts +119 -0
  682. package/src/store/jobs.ts +674 -0
  683. package/src/store/native-artifact-summary.ts +13 -0
  684. package/src/store/packs.ts +721 -0
  685. package/src/store/purge.ts +463 -0
  686. package/src/store/sources.spec.ts +102 -0
  687. package/src/store/sources.ts +692 -0
  688. package/src/store/suggestions.ts +361 -0
  689. package/src/types.ts +671 -0
  690. package/src/untrusted-reference.spec.ts +22 -0
  691. package/src/untrusted-reference.ts +24 -0
  692. package/src/vector/index.ts +1 -0
  693. package/src/vector/pgvector.spec.ts +115 -0
  694. package/src/vector/pgvector.ts +1 -0
  695. package/tsconfig.json +31 -0
@@ -0,0 +1,1036 @@
1
+ import { randomUUID } from "node:crypto";
2
+ import { existsSync } from "node:fs";
3
+ import { isBlockedExtensionUrlWithDns, ssrfSafeFetch, } from "@agent-native/core/extensions/url-safety";
4
+ import { extractStaticWebsiteContext, rankColorSamples, readBoundedResponseBytes, } from "@agent-native/core/ingestion";
5
+ import { normalizeWhitespace } from "./normalize.js";
6
+ const MAX_RENDERED_TEXT_CHARS = 2_000_000;
7
+ const MAX_SCREENSHOT_BYTES = 10 * 1024 * 1024;
8
+ const MAX_STATIC_HTML_BYTES = 5 * 1024 * 1024;
9
+ const MAX_EXTRACTED_ASSETS = 500;
10
+ const MAX_INTERNAL_LINKS = 500;
11
+ const MAX_COLORS = 256;
12
+ const MAX_TYPOGRAPHY = 100;
13
+ const MAX_SPACING = 100;
14
+ const MAX_RADII = 64;
15
+ const MAX_CSS_VARIABLES = 128;
16
+ const MAX_COMPONENT_STYLES = 24;
17
+ const FONT_READY_TIMEOUT_MS = 4_000;
18
+ const MAX_BROWSER_RESOURCE_BYTES = 12 * 1024 * 1024;
19
+ const MAX_BROWSER_RESOURCE_COUNT = 400;
20
+ const MAX_BROWSER_RESOURCE_BYTES_TOTAL = 64 * 1024 * 1024;
21
+ const BROWSER_RESOURCE_TIMEOUT_MS = 15_000;
22
+ const BROWSER_REQUEST_HEADERS = new Set([
23
+ "accept",
24
+ "accept-language",
25
+ "if-modified-since",
26
+ "if-none-match",
27
+ "origin",
28
+ "range",
29
+ "referer",
30
+ "user-agent",
31
+ ]);
32
+ const BROWSER_RESPONSE_HEADERS = new Set([
33
+ "connection",
34
+ "content-encoding",
35
+ "content-length",
36
+ "keep-alive",
37
+ "proxy-authenticate",
38
+ "proxy-authorization",
39
+ "set-cookie",
40
+ "set-cookie2",
41
+ "te",
42
+ "trailer",
43
+ "transfer-encoding",
44
+ "upgrade",
45
+ ]);
46
+ export class LayeredRenderedPageProvider {
47
+ #requestBuilderBrowserConnection;
48
+ #loadPlaywright;
49
+ #requestAttachedBrowserConnection;
50
+ #staticFetch;
51
+ constructor(options = {}) {
52
+ this.#requestBuilderBrowserConnection =
53
+ options.requestBuilderBrowserConnection ?? defaultBuilderBrowserRequest;
54
+ this.#loadPlaywright = options.loadPlaywright ?? loadOptionalPlaywright;
55
+ this.#requestAttachedBrowserConnection =
56
+ options.requestAttachedBrowserConnection;
57
+ this.#staticFetch = options.staticFetch ?? ssrfSafeFetch;
58
+ }
59
+ async render(request) {
60
+ await assertPublicBrowserUrl(request.url);
61
+ const warnings = [];
62
+ const playwright = await this.#loadPlaywright().catch((error) => {
63
+ warnings.push(`Playwright unavailable: ${errorMessage(error)}`);
64
+ return null;
65
+ });
66
+ if (request.preferHosted !== false && playwright) {
67
+ try {
68
+ const connection = await this.#requestBuilderBrowserConnection({
69
+ sessionId: `creative-context-${randomUUID()}`,
70
+ });
71
+ const wsUrl = typeof connection.wsUrl === "string" ? connection.wsUrl.trim() : "";
72
+ if (!wsUrl)
73
+ throw new Error("Builder Browser did not return wsUrl.");
74
+ return await renderWithPlaywright(playwright, request, warnings, "builder-browser", wsUrl);
75
+ }
76
+ catch (error) {
77
+ warnings.push(`Builder Browser unavailable: ${errorMessage(error)}`);
78
+ }
79
+ }
80
+ if (playwright) {
81
+ try {
82
+ return await renderWithPlaywright(playwright, request, warnings, "local-playwright");
83
+ }
84
+ catch (error) {
85
+ warnings.push(`Local Playwright unavailable: ${errorMessage(error)}`);
86
+ }
87
+ }
88
+ if (playwright && this.#requestAttachedBrowserConnection) {
89
+ try {
90
+ const connection = await this.#requestAttachedBrowserConnection({
91
+ sessionId: `creative-context-attached-${randomUUID()}`,
92
+ url: request.url,
93
+ });
94
+ if (!connection.wsUrl?.trim()) {
95
+ throw new Error("Approved attached browser did not return wsUrl.");
96
+ }
97
+ return await renderWithPlaywright(playwright, request, warnings, "attached-chrome", connection.wsUrl);
98
+ }
99
+ catch (error) {
100
+ warnings.push(`Attached Chrome unavailable: ${errorMessage(error)}`);
101
+ }
102
+ }
103
+ else {
104
+ warnings.push("Attached Chrome unavailable: no approved browser connection adapter is configured.");
105
+ }
106
+ return renderStatic(request, warnings, this.#staticFetch);
107
+ }
108
+ }
109
+ export async function renderWithPlaywright(playwright, request, warnings, method, wsUrl) {
110
+ const browser = wsUrl
111
+ ? await playwright.chromium.connectOverCDP(wsUrl)
112
+ : await launchChromium(playwright.chromium);
113
+ let isolatedContext;
114
+ try {
115
+ // Never reuse a connected browser's ambient context: it can carry cookies,
116
+ // extensions, or tabs from another workflow. The safe proxy below is only
117
+ // useful when the page itself is isolated from that state.
118
+ if (!browser.newContext) {
119
+ throw new Error("Browser did not provide isolated context support.");
120
+ }
121
+ isolatedContext = await browser.newContext();
122
+ const page = await isolatedContext.newPage();
123
+ const getFinalNavigationUrl = await installNavigationGuard(page, request, warnings);
124
+ await page.setViewportSize({ width: 1440, height: 900 });
125
+ await page.goto(request.url, {
126
+ timeout: boundedTimeout(request.timeoutMs),
127
+ waitUntil: request.waitUntil ?? "domcontentloaded",
128
+ });
129
+ await page
130
+ .waitForLoadState?.("load", {
131
+ timeout: Math.min(8_000, boundedTimeout(request.timeoutMs)),
132
+ })
133
+ .catch((error) => {
134
+ warnings.push(`Browser load stabilization unavailable: ${errorMessage(error)}`);
135
+ });
136
+ // React hydration, CSS-in-JS insertion, and web fonts commonly finish just
137
+ // after `load`. Give those layers a bounded chance to settle, then capture
138
+ // the computed cascade rather than the server HTML.
139
+ await page
140
+ .waitForLoadState?.("networkidle", { timeout: 4_000 })
141
+ .catch((error) => {
142
+ warnings.push(`Browser network-idle stabilization unavailable: ${errorMessage(error)}`);
143
+ });
144
+ await waitForFontReadiness(page, Math.min(FONT_READY_TIMEOUT_MS, boundedTimeout(request.timeoutMs))).catch((error) => {
145
+ warnings.push(`Browser font readiness unavailable: ${errorMessage(error)}`);
146
+ });
147
+ await new Promise((resolve) => setTimeout(resolve, 150));
148
+ await page.evaluate(dismissConsentOverlays).catch(() => undefined);
149
+ const finalUrl = getFinalNavigationUrl() ?? page.url();
150
+ await assertPublicBrowserUrl(finalUrl);
151
+ const [title, text, desktopScreenshot, extraction] = await Promise.all([
152
+ page.title().catch((error) => {
153
+ warnings.push(`Browser title extraction unavailable: ${errorMessage(error)}`);
154
+ return "";
155
+ }),
156
+ page
157
+ .locator("body")
158
+ .innerText()
159
+ .catch((error) => {
160
+ warnings.push(`Browser text extraction unavailable: ${errorMessage(error)}`);
161
+ return "";
162
+ }),
163
+ page
164
+ .screenshot({ type: "png", fullPage: false })
165
+ .then(boundedScreenshot)
166
+ .catch((error) => {
167
+ warnings.push(`Desktop screenshot unavailable: ${errorMessage(error)}`);
168
+ return undefined;
169
+ }),
170
+ page
171
+ .evaluate(browserCaptureExpression())
172
+ .catch((error) => {
173
+ warnings.push(`Browser style extraction unavailable: ${errorMessage(error)}`);
174
+ return emptyExtraction();
175
+ }),
176
+ ]);
177
+ await page.setViewportSize({ width: 390, height: 844 });
178
+ const mobileScreenshot = await page
179
+ .screenshot({ type: "png", fullPage: false })
180
+ .then(boundedScreenshot)
181
+ .catch((error) => {
182
+ warnings.push(`Mobile screenshot unavailable: ${errorMessage(error)}`);
183
+ return undefined;
184
+ });
185
+ const unboundedText = normalizeWhitespace(text);
186
+ const textTruncated = unboundedText.length > MAX_RENDERED_TEXT_CHARS;
187
+ const normalizedText = unboundedText.slice(0, MAX_RENDERED_TEXT_CHARS);
188
+ const resolvedExtraction = boundWebsiteExtraction({
189
+ ...extraction,
190
+ title: normalizeWhitespace(title) || extraction.title,
191
+ text: normalizedText || extraction.text,
192
+ designTokens: {
193
+ ...extraction.designTokens,
194
+ colors: rankColorSamples(extraction.designTokens.colors),
195
+ },
196
+ });
197
+ const diagnostics = [
198
+ ...warnings,
199
+ `Captured ${resolvedExtraction.assets.length} assets and ${resolvedExtraction.internalLinks.length} same-origin links.`,
200
+ ...(desktopScreenshot && mobileScreenshot
201
+ ? []
202
+ : ["One or more viewport screenshots could not be captured."]),
203
+ ...(textTruncated
204
+ ? [`Body text was truncated at ${MAX_RENDERED_TEXT_CHARS} characters.`]
205
+ : []),
206
+ ];
207
+ return {
208
+ url: request.url,
209
+ finalUrl,
210
+ title: normalizeWhitespace(title) || new URL(finalUrl).hostname,
211
+ text: resolvedExtraction.text,
212
+ method,
213
+ rendered: true,
214
+ warnings,
215
+ extraction: resolvedExtraction,
216
+ screenshots: [
217
+ ...(desktopScreenshot
218
+ ? [
219
+ {
220
+ viewport: "desktop",
221
+ width: 1440,
222
+ height: 900,
223
+ data: desktopScreenshot,
224
+ },
225
+ ]
226
+ : []),
227
+ ...(mobileScreenshot
228
+ ? [
229
+ {
230
+ viewport: "mobile",
231
+ width: 390,
232
+ height: 844,
233
+ data: mobileScreenshot,
234
+ },
235
+ ]
236
+ : []),
237
+ ],
238
+ confidence: 0.92,
239
+ classification: classifyWebsite(resolvedExtraction, finalUrl),
240
+ diagnostics,
241
+ metadata: {
242
+ browser: method,
243
+ assetCount: resolvedExtraction.assets.length,
244
+ internalLinkCount: resolvedExtraction.internalLinks.length,
245
+ },
246
+ };
247
+ }
248
+ finally {
249
+ await isolatedContext?.close?.().catch((error) => {
250
+ warnings.push(`Browser context cleanup unavailable: ${errorMessage(error)}`);
251
+ });
252
+ await browser.close().catch(() => undefined);
253
+ }
254
+ }
255
+ async function waitForFontReadiness(page, timeoutMs) {
256
+ let timeout;
257
+ try {
258
+ await Promise.race([
259
+ page.evaluate(async () => {
260
+ if (document.fonts?.ready)
261
+ await document.fonts.ready;
262
+ }),
263
+ new Promise((_, reject) => {
264
+ timeout = setTimeout(() => {
265
+ reject(new Error(`font readiness timed out after ${timeoutMs}ms`));
266
+ }, timeoutMs);
267
+ }),
268
+ ]);
269
+ }
270
+ finally {
271
+ if (timeout !== undefined)
272
+ clearTimeout(timeout);
273
+ }
274
+ }
275
+ async function installNavigationGuard(page, renderRequest, warnings) {
276
+ let finalNavigationUrl;
277
+ let resourceCount = 0;
278
+ let resourceBytes = 0;
279
+ let reservedResourceBytes = 0;
280
+ const bodyBudgetWaiters = [];
281
+ let resourceLimitWarningAdded = false;
282
+ let blockedResourceWarningAdded = false;
283
+ let failedResourceWarningAdded = false;
284
+ const reserveBodyBudget = async () => {
285
+ while (reservedResourceBytes + MAX_BROWSER_RESOURCE_BYTES >
286
+ MAX_BROWSER_RESOURCE_BYTES_TOTAL) {
287
+ await new Promise((resolve) => {
288
+ bodyBudgetWaiters.push(resolve);
289
+ });
290
+ }
291
+ reservedResourceBytes += MAX_BROWSER_RESOURCE_BYTES;
292
+ let released = false;
293
+ return () => {
294
+ if (released)
295
+ return;
296
+ released = true;
297
+ reservedResourceBytes -= MAX_BROWSER_RESOURCE_BYTES;
298
+ bodyBudgetWaiters.shift()?.();
299
+ };
300
+ };
301
+ const addWarning = (value) => {
302
+ if (!warnings.includes(value))
303
+ warnings.push(value);
304
+ };
305
+ await page.route("**/*", async (route) => {
306
+ const browserRequest = route.request();
307
+ let parsed;
308
+ try {
309
+ parsed = new URL(browserRequest.url());
310
+ }
311
+ catch {
312
+ // coercion-ok: an absent optional package means the next compatible probe should run.
313
+ await route.abort("blockedbyclient");
314
+ return;
315
+ }
316
+ if (parsed.protocol === "about:" ||
317
+ parsed.protocol === "data:" ||
318
+ parsed.protocol === "blob:") {
319
+ await route.continue();
320
+ return;
321
+ }
322
+ if (parsed.protocol !== "http:" && parsed.protocol !== "https:") {
323
+ await route.abort("blockedbyclient");
324
+ return;
325
+ }
326
+ const method = (browserRequest.method?.() ?? "GET").toUpperCase();
327
+ if (method !== "GET" && method !== "HEAD") {
328
+ await route.abort("blockedbyclient");
329
+ if (!resourceLimitWarningAdded) {
330
+ resourceLimitWarningAdded = true;
331
+ addWarning("Browser blocked a non-read-only resource request during extraction.");
332
+ }
333
+ return;
334
+ }
335
+ if (resourceCount >= MAX_BROWSER_RESOURCE_COUNT) {
336
+ await route.abort("blockedbyclient");
337
+ if (!resourceLimitWarningAdded) {
338
+ resourceLimitWarningAdded = true;
339
+ addWarning(`Browser resource budget reached (${MAX_BROWSER_RESOURCE_COUNT} requests).`);
340
+ }
341
+ return;
342
+ }
343
+ // Reserve the request slot before the first await. Browser route handlers
344
+ // overlap, so incrementing only after the proxy response arrives lets a
345
+ // burst of requests all pass the limit check.
346
+ resourceCount += 1;
347
+ let bodyBudgetRelease;
348
+ let committedBytes = 0;
349
+ let fulfilled = false;
350
+ try {
351
+ await assertPublicBrowserUrl(parsed.href);
352
+ const response = await ssrfSafeFetch(parsed.href, {
353
+ method,
354
+ headers: browserRequestHeaders(browserRequest),
355
+ signal: AbortSignal.timeout(Math.min(BROWSER_RESOURCE_TIMEOUT_MS, boundedTimeout(renderRequest.timeoutMs))),
356
+ }, { maxRedirects: 5 });
357
+ bodyBudgetRelease = await reserveBodyBudget();
358
+ const body = await readBoundedResponseBytes(response, MAX_BROWSER_RESOURCE_BYTES);
359
+ bodyBudgetRelease();
360
+ bodyBudgetRelease = undefined;
361
+ if (resourceBytes + body.byteLength > MAX_BROWSER_RESOURCE_BYTES_TOTAL) {
362
+ await route.abort("blockedbyclient");
363
+ if (!resourceLimitWarningAdded) {
364
+ resourceLimitWarningAdded = true;
365
+ addWarning(`Browser resource budget reached (${MAX_BROWSER_RESOURCE_BYTES_TOTAL} bytes).`);
366
+ }
367
+ return;
368
+ }
369
+ resourceBytes += body.byteLength;
370
+ committedBytes = body.byteLength;
371
+ if (browserRequest.isNavigationRequest()) {
372
+ finalNavigationUrl = response.url || parsed.href;
373
+ }
374
+ await route.fulfill({
375
+ status: response.status,
376
+ headers: browserResponseHeaders(response),
377
+ body: Buffer.from(body),
378
+ });
379
+ fulfilled = true;
380
+ }
381
+ catch (error) {
382
+ if (committedBytes > 0) {
383
+ resourceBytes -= committedBytes;
384
+ committedBytes = 0;
385
+ }
386
+ await route.abort("blockedbyclient");
387
+ if (isSsrfError(error)) {
388
+ if (!blockedResourceWarningAdded) {
389
+ blockedResourceWarningAdded = true;
390
+ addWarning("Some browser resources were blocked by the SSRF safety policy.");
391
+ }
392
+ }
393
+ else if (!failedResourceWarningAdded) {
394
+ failedResourceWarningAdded = true;
395
+ addWarning("Some browser resources could not be fetched through the safe network proxy.");
396
+ }
397
+ }
398
+ finally {
399
+ bodyBudgetRelease?.();
400
+ if (!fulfilled)
401
+ resourceCount -= 1;
402
+ }
403
+ });
404
+ return () => finalNavigationUrl;
405
+ }
406
+ function browserRequestHeaders(request) {
407
+ const source = request.headers?.() ?? {};
408
+ return Object.fromEntries(Object.entries(source).filter(([name, value]) => {
409
+ return BROWSER_REQUEST_HEADERS.has(name.toLowerCase()) && Boolean(value);
410
+ }));
411
+ }
412
+ function browserResponseHeaders(response) {
413
+ const headers = {};
414
+ response.headers.forEach((value, name) => {
415
+ if (!BROWSER_RESPONSE_HEADERS.has(name.toLowerCase())) {
416
+ headers[name] = value;
417
+ }
418
+ });
419
+ return headers;
420
+ }
421
+ function isSsrfError(error) {
422
+ return /ssrf blocked|private\/internal|connect blocked/i.test(errorMessage(error));
423
+ }
424
+ const SYSTEM_CHROME_EXECUTABLES = [
425
+ "/usr/bin/google-chrome-stable",
426
+ "/usr/bin/google-chrome",
427
+ "/usr/bin/chromium",
428
+ "/usr/bin/chromium-browser",
429
+ ];
430
+ async function launchChromium(chromium) {
431
+ const launchOptions = {
432
+ headless: true,
433
+ args: ["--no-sandbox", "--disable-dev-shm-usage"],
434
+ };
435
+ let missingBrowserError;
436
+ try {
437
+ return await chromium.launch(launchOptions);
438
+ }
439
+ catch (error) {
440
+ if (!isMissingBrowserError(error))
441
+ throw error;
442
+ missingBrowserError = error;
443
+ }
444
+ const serverlessChromium = await loadOptionalServerlessChromium();
445
+ if (serverlessChromium) {
446
+ try {
447
+ const executablePath = await serverlessChromium.executablePath();
448
+ if (executablePath) {
449
+ return await chromium.launch({
450
+ ...launchOptions,
451
+ args: [...launchOptions.args, ...(serverlessChromium.args ?? [])],
452
+ executablePath,
453
+ });
454
+ }
455
+ }
456
+ catch (error) {
457
+ if (!isMissingBrowserError(error))
458
+ throw error;
459
+ missingBrowserError = error;
460
+ }
461
+ }
462
+ for (const executablePath of SYSTEM_CHROME_EXECUTABLES) {
463
+ if (!existsSync(executablePath))
464
+ continue;
465
+ try {
466
+ return await chromium.launch({ ...launchOptions, executablePath });
467
+ }
468
+ catch {
469
+ continue;
470
+ }
471
+ }
472
+ if (missingBrowserError) {
473
+ throw missingBrowserError;
474
+ }
475
+ throw new Error("No Chromium executable is available for browser extraction.");
476
+ }
477
+ async function loadOptionalServerlessChromium() {
478
+ const specifier = "@sparticuz/chromium";
479
+ try {
480
+ const module = (await import(/* @vite-ignore */ specifier));
481
+ const chromium = module.default ?? module;
482
+ return typeof chromium.executablePath === "function"
483
+ ? chromium
484
+ : null;
485
+ }
486
+ catch {
487
+ // coercion-ok: this optional capability is absent in non-serverless installs.
488
+ return null;
489
+ }
490
+ }
491
+ /*
492
+ * Kept separate from Playwright loading so a deployment can omit the large
493
+ * serverless Chromium package and still use Builder Browser or system Chrome.
494
+ */
495
+ async function loadOptionalPlaywright() {
496
+ for (const specifier of [
497
+ "playwright",
498
+ "@playwright/test",
499
+ "playwright-core",
500
+ ]) {
501
+ try {
502
+ const module = (await import(
503
+ /* @vite-ignore */ specifier));
504
+ for (const candidate of [module.default, module]) {
505
+ if (typeof candidate?.chromium?.launch === "function") {
506
+ return candidate;
507
+ }
508
+ }
509
+ // coercion-ok: an absent optional package means the next compatible probe should run.
510
+ }
511
+ catch {
512
+ // Try the next compatible browser package before falling back to HTML.
513
+ }
514
+ }
515
+ // coercion-ok: browser packages are optional in non-Node runtimes.
516
+ return null;
517
+ }
518
+ async function defaultBuilderBrowserRequest(input) {
519
+ const server = (await import("@agent-native/core/server"));
520
+ if (!server.requestBuilderBrowserConnection) {
521
+ throw new Error("@agent-native/core/server does not export requestBuilderBrowserConnection.");
522
+ }
523
+ return server.requestBuilderBrowserConnection(input);
524
+ }
525
+ function isMissingBrowserError(error) {
526
+ const message = error instanceof Error ? error.message : String(error);
527
+ return /Executable doesn't exist|playwright install|browser.*not found|chromium.*not found/i.test(message);
528
+ }
529
+ /** Close common consent banners without accepting tracking or changing page data. */
530
+ function dismissConsentOverlays() {
531
+ const selectors = [
532
+ '[aria-label*="reject" i]',
533
+ '[aria-label*="decline" i]',
534
+ '[aria-label*="close" i]',
535
+ '[data-testid*="reject" i]',
536
+ '[data-testid*="decline" i]',
537
+ '[data-testid*="close" i]',
538
+ 'button[id*="reject" i]',
539
+ 'button[id*="decline" i]',
540
+ 'button[class*="reject" i]',
541
+ 'button[class*="decline" i]',
542
+ ];
543
+ for (const selector of selectors) {
544
+ const element = document.querySelector(selector);
545
+ if (!element)
546
+ continue;
547
+ const rect = element.getBoundingClientRect();
548
+ const style = getComputedStyle(element);
549
+ if (rect.width > 0 &&
550
+ rect.height > 0 &&
551
+ style.visibility !== "hidden" &&
552
+ style.display !== "none") {
553
+ element.click();
554
+ return;
555
+ }
556
+ }
557
+ }
558
+ async function renderStatic(request, warnings, fetcher) {
559
+ const response = await fetcher(request.url, {
560
+ headers: {
561
+ Accept: "text/html,application/xhtml+xml,text/plain;q=0.9,*/*;q=0.1",
562
+ },
563
+ signal: AbortSignal.timeout(boundedTimeout(request.timeoutMs)),
564
+ }, { maxRedirects: 5 });
565
+ if (!response.ok) {
566
+ throw new Error(`Static page fetch failed (${response.status}).`);
567
+ }
568
+ const html = new TextDecoder().decode(await readBoundedResponseBytes(response, MAX_STATIC_HTML_BYTES));
569
+ const finalUrl = response.url || request.url;
570
+ const extraction = extractStaticWebsiteContext(html, finalUrl);
571
+ const title = extraction.title || new URL(finalUrl).hostname;
572
+ warnings.push("Used the SSRF-safe static HTML fallback; client-rendered content may be missing.");
573
+ return {
574
+ url: request.url,
575
+ finalUrl,
576
+ title,
577
+ text: extraction.text,
578
+ method: "static-html",
579
+ rendered: false,
580
+ warnings,
581
+ extraction: { ...extraction, title },
582
+ screenshots: [],
583
+ confidence: 0.45,
584
+ classification: classifyWebsite(extraction, finalUrl),
585
+ diagnostics: [
586
+ ...warnings,
587
+ "Static extraction cannot verify client-rendered layout or viewport behavior.",
588
+ ],
589
+ metadata: {
590
+ contentType: response.headers.get("content-type"),
591
+ etag: response.headers.get("etag"),
592
+ lastModified: response.headers.get("last-modified"),
593
+ staticFallback: true,
594
+ assetCount: extraction.assets.length,
595
+ internalLinkCount: extraction.internalLinks.length,
596
+ },
597
+ };
598
+ }
599
+ async function assertPublicBrowserUrl(value) {
600
+ let parsed;
601
+ try {
602
+ parsed = new URL(value);
603
+ }
604
+ catch {
605
+ throw new Error("Website URL must be an absolute http(s) URL.");
606
+ }
607
+ if (!["http:", "https:"].includes(parsed.protocol)) {
608
+ throw new Error("Website URL must use http or https.");
609
+ }
610
+ if (parsed.username || parsed.password) {
611
+ throw new Error("Website URLs cannot contain credentials.");
612
+ }
613
+ if (await isBlockedExtensionUrlWithDns(parsed.href)) {
614
+ throw new Error("SSRF blocked: website resolved to a private/internal host.");
615
+ }
616
+ }
617
+ function captureRenderedWebsiteContext() {
618
+ const MAX_ASSETS = 500;
619
+ const MAX_LINKS = 500;
620
+ const MAX_COLOR_VALUES = 256;
621
+ const MAX_TYPE_STYLES = 100;
622
+ const MAX_SPACING_VALUES = 100;
623
+ const MAX_RADIUS_VALUES = 64;
624
+ const MAX_SHADOWS = 32;
625
+ const MAX_BACKGROUNDS = 32;
626
+ const MAX_VARIABLES = 128;
627
+ const MAX_TEXT = 2_000_000;
628
+ const MAX_COMPONENT_STYLES = 24;
629
+ const assets = new Map();
630
+ const links = new Set();
631
+ const colors = [];
632
+ const typography = new Map();
633
+ const spacing = new Set();
634
+ const radii = new Set();
635
+ const shadows = new Set();
636
+ const backgrounds = new Set();
637
+ const components = [];
638
+ const cssVariables = {};
639
+ const semanticColors = {};
640
+ function isOpaque(value) {
641
+ const normalized = value.trim().toLowerCase();
642
+ if (!normalized || normalized === "transparent")
643
+ return false;
644
+ const functionBody = normalized.match(/^[a-z-]+\((.*)\)$/)?.[1];
645
+ if (!functionBody)
646
+ return true;
647
+ const alphaValue = functionBody.includes("/")
648
+ ? functionBody.split("/").at(-1)?.trim()
649
+ : functionBody.split(",").length === 4
650
+ ? functionBody.split(",").at(-1)?.trim()
651
+ : undefined;
652
+ if (!alphaValue)
653
+ return true;
654
+ const alpha = alphaValue.endsWith("%")
655
+ ? Number.parseFloat(alphaValue) / 100
656
+ : Number.parseFloat(alphaValue);
657
+ return Number.isNaN(alpha) || alpha > 0.02;
658
+ }
659
+ function addColor(value) {
660
+ if (colors.length >= MAX_COLOR_VALUES || !isOpaque(value))
661
+ return;
662
+ const normalized = value.trim();
663
+ if (!colors.includes(normalized))
664
+ colors.push(normalized);
665
+ }
666
+ function visible(element) {
667
+ const style = getComputedStyle(element);
668
+ const rect = element.getBoundingClientRect();
669
+ return (rect.width > 0 &&
670
+ rect.height > 0 &&
671
+ style.display !== "none" &&
672
+ style.visibility !== "hidden" &&
673
+ Number(style.opacity || 1) > 0.02);
674
+ }
675
+ function firstVisible(selector) {
676
+ return Array.from(document.querySelectorAll(selector)).find(visible);
677
+ }
678
+ function opaqueValue(value) {
679
+ return isOpaque(value) ? value.trim() : undefined;
680
+ }
681
+ function recordComputedStyle(element, role) {
682
+ const style = getComputedStyle(element);
683
+ const values = [
684
+ style.color,
685
+ style.backgroundColor,
686
+ style.borderTopColor,
687
+ style.borderRightColor,
688
+ style.borderBottomColor,
689
+ style.borderLeftColor,
690
+ ];
691
+ values.forEach(addColor);
692
+ if (style.boxShadow && style.boxShadow !== "none") {
693
+ if (shadows.size < MAX_SHADOWS)
694
+ shadows.add(style.boxShadow);
695
+ }
696
+ if (style.backgroundImage && style.backgroundImage !== "none") {
697
+ if (backgrounds.size < MAX_BACKGROUNDS) {
698
+ backgrounds.add(style.backgroundImage);
699
+ }
700
+ }
701
+ for (const value of [
702
+ style.marginTop,
703
+ style.marginRight,
704
+ style.marginBottom,
705
+ style.marginLeft,
706
+ style.paddingTop,
707
+ style.paddingRight,
708
+ style.paddingBottom,
709
+ style.paddingLeft,
710
+ style.gap,
711
+ style.rowGap,
712
+ style.columnGap,
713
+ ]) {
714
+ if (spacing.size < MAX_SPACING_VALUES &&
715
+ value &&
716
+ value !== "0px" &&
717
+ value !== "normal") {
718
+ spacing.add(value);
719
+ }
720
+ }
721
+ for (const value of [
722
+ style.borderTopLeftRadius,
723
+ style.borderTopRightRadius,
724
+ style.borderBottomRightRadius,
725
+ style.borderBottomLeftRadius,
726
+ ]) {
727
+ if (radii.size < MAX_RADIUS_VALUES && value && value !== "0px") {
728
+ radii.add(value);
729
+ }
730
+ }
731
+ const type = {
732
+ family: style.fontFamily,
733
+ size: style.fontSize,
734
+ weight: style.fontWeight,
735
+ lineHeight: style.lineHeight,
736
+ letterSpacing: style.letterSpacing,
737
+ };
738
+ if (typography.size < MAX_TYPE_STYLES && type.family) {
739
+ typography.set(JSON.stringify(type), type);
740
+ }
741
+ if (!role || components.length >= MAX_COMPONENT_STYLES)
742
+ return style;
743
+ components.push({
744
+ role,
745
+ fontFamily: style.fontFamily,
746
+ fontSize: style.fontSize,
747
+ fontWeight: style.fontWeight,
748
+ lineHeight: style.lineHeight,
749
+ letterSpacing: style.letterSpacing,
750
+ color: opaqueValue(style.color),
751
+ backgroundColor: opaqueValue(style.backgroundColor),
752
+ backgroundImage: style.backgroundImage !== "none" ? style.backgroundImage : undefined,
753
+ border: style.borderStyle !== "none" && style.borderWidth !== "0px"
754
+ ? style.border
755
+ : undefined,
756
+ borderRadius: style.borderTopLeftRadius !== "0px" ? style.borderRadius : undefined,
757
+ boxShadow: style.boxShadow !== "none" ? style.boxShadow : undefined,
758
+ padding: style.padding !== "0px" ? style.padding : undefined,
759
+ gap: style.gap !== "normal" ? style.gap : undefined,
760
+ textTransform: style.textTransform !== "none" ? style.textTransform : undefined,
761
+ });
762
+ return style;
763
+ }
764
+ function styleFor(selector, role) {
765
+ const element = firstVisible(selector);
766
+ if (!element)
767
+ return undefined;
768
+ return recordComputedStyle(element, role);
769
+ }
770
+ function addAsset(raw, kind, role) {
771
+ if (!raw || assets.size >= MAX_ASSETS)
772
+ return;
773
+ try {
774
+ const url = new URL(raw, document.baseURI);
775
+ if (url.protocol === "http:" || url.protocol === "https:") {
776
+ url.hash = "";
777
+ assets.set(url.href, {
778
+ url: url.href,
779
+ kind,
780
+ ...(role ? { role } : {}),
781
+ });
782
+ }
783
+ }
784
+ catch {
785
+ return;
786
+ }
787
+ }
788
+ for (const image of document.querySelectorAll("img")) {
789
+ if (assets.size >= MAX_ASSETS)
790
+ break;
791
+ const identity = `${image.getAttribute("alt") ?? ""} ${image.getAttribute("class") ?? ""} ${image.id}`;
792
+ addAsset(image.currentSrc || image.src, "image", /logo|wordmark|brandmark/i.test(identity) ? "logo" : undefined);
793
+ }
794
+ for (const video of document.querySelectorAll("video")) {
795
+ if (assets.size >= MAX_ASSETS)
796
+ break;
797
+ addAsset(video.currentSrc || video.src, "video");
798
+ }
799
+ for (const audio of document.querySelectorAll("audio")) {
800
+ if (assets.size >= MAX_ASSETS)
801
+ break;
802
+ addAsset(audio.currentSrc || audio.src, "audio");
803
+ }
804
+ for (const script of document.querySelectorAll("script[src]")) {
805
+ if (assets.size >= MAX_ASSETS)
806
+ break;
807
+ addAsset(script.getAttribute("src"), "script");
808
+ }
809
+ for (const link of document.querySelectorAll("link[href]")) {
810
+ if (assets.size >= MAX_ASSETS)
811
+ break;
812
+ const rel = link.getAttribute("rel") ?? "";
813
+ const icon = /icon/i.test(rel);
814
+ addAsset(link.getAttribute("href"), icon ? "image" : /font|preload/i.test(rel) ? "font" : "stylesheet", icon ? "logo" : undefined);
815
+ }
816
+ for (const meta of document.querySelectorAll('meta[property="og:image"],meta[property="og:image:url"],meta[name="twitter:image"]')) {
817
+ if (assets.size >= MAX_ASSETS)
818
+ break;
819
+ addAsset(meta.getAttribute("content"), "image", "open-graph");
820
+ }
821
+ for (const anchor of document.querySelectorAll("a[href]")) {
822
+ if (links.size >= MAX_LINKS)
823
+ break;
824
+ try {
825
+ const url = new URL(anchor.getAttribute("href") ?? "", document.baseURI);
826
+ if (url.origin === location.origin) {
827
+ url.hash = "";
828
+ links.add(url.href);
829
+ }
830
+ }
831
+ catch {
832
+ continue;
833
+ }
834
+ }
835
+ const rootStyle = getComputedStyle(document.documentElement);
836
+ let variableCount = 0;
837
+ for (const name of rootStyle) {
838
+ if (name.startsWith("--")) {
839
+ const value = rootStyle.getPropertyValue(name).trim();
840
+ if (value) {
841
+ cssVariables[name] = value;
842
+ variableCount++;
843
+ if (variableCount >= MAX_VARIABLES)
844
+ break;
845
+ }
846
+ }
847
+ }
848
+ const bodyStyle = document.body
849
+ ? recordComputedStyle(document.body)
850
+ : undefined;
851
+ const rootBackground = opaqueValue(rootStyle.backgroundColor);
852
+ const bodyBackground = bodyStyle
853
+ ? opaqueValue(bodyStyle.backgroundColor)
854
+ : undefined;
855
+ const textStyle = styleFor("p, li, label, body", "body");
856
+ const buttonStyle = styleFor('button, [role="button"], input[type="submit"], a[class*="button" i], a[class*="cta" i]', "button");
857
+ const linkStyle = styleFor("a[href]", "link");
858
+ const cardStyle = styleFor('article, [class*="card" i], [class*="panel" i], [class*="surface" i], section', "card");
859
+ styleFor("input, textarea, select", "input");
860
+ styleFor("nav, header", "nav");
861
+ styleFor('main, [class*="hero" i]', "hero");
862
+ function setSemantic(role, value) {
863
+ if (value)
864
+ semanticColors[role] = value;
865
+ }
866
+ setSemantic("background", bodyBackground ?? rootBackground);
867
+ setSemantic("surface", cardStyle ? opaqueValue(cardStyle.backgroundColor) : undefined);
868
+ setSemantic("text", textStyle ? opaqueValue(textStyle.color) : undefined);
869
+ const mutedElement = firstVisible("small, figcaption, [class*='muted' i]");
870
+ setSemantic("textMuted", mutedElement
871
+ ? opaqueValue(getComputedStyle(mutedElement).color)
872
+ : undefined);
873
+ setSemantic("accent", linkStyle
874
+ ? opaqueValue(linkStyle.color)
875
+ : buttonStyle
876
+ ? opaqueValue(buttonStyle.backgroundColor)
877
+ : undefined);
878
+ setSemantic("primary", buttonStyle
879
+ ? (opaqueValue(buttonStyle.backgroundColor) ??
880
+ opaqueValue(buttonStyle.color))
881
+ : colors[0]);
882
+ setSemantic("secondary", semanticColors.surface ?? colors[1] ?? semanticColors.background);
883
+ const layoutElement = firstVisible("main, [role='main'], body > div");
884
+ const layoutStyle = layoutElement
885
+ ? getComputedStyle(layoutElement)
886
+ : undefined;
887
+ const layoutRect = layoutElement?.getBoundingClientRect();
888
+ const layout = {
889
+ contentWidth: layoutStyle?.maxWidth && layoutStyle.maxWidth !== "none"
890
+ ? layoutStyle.maxWidth
891
+ : layoutRect && layoutRect.width > 0
892
+ ? `${Math.round(layoutRect.width)}px`
893
+ : undefined,
894
+ pagePadding: bodyStyle?.padding && bodyStyle.padding !== "0px"
895
+ ? bodyStyle.padding
896
+ : undefined,
897
+ sectionGap: firstVisible("section, article") &&
898
+ getComputedStyle(firstVisible("section, article")).gap !== "normal" &&
899
+ getComputedStyle(firstVisible("section, article")).gap !== "0px"
900
+ ? getComputedStyle(firstVisible("section, article")).gap
901
+ : undefined,
902
+ };
903
+ const elements = Array.from(document.querySelectorAll("body *"))
904
+ .filter(visible)
905
+ .slice(0, 700);
906
+ for (const element of elements) {
907
+ recordComputedStyle(element);
908
+ }
909
+ return {
910
+ title: document.title,
911
+ text: (document.body?.innerText ?? "").slice(0, MAX_TEXT),
912
+ assets: [...assets.values()],
913
+ internalLinks: [...links],
914
+ designTokens: {
915
+ colors,
916
+ typography: [...typography.values()],
917
+ spacing: [...spacing],
918
+ radii: [...radii],
919
+ cssVariables,
920
+ semanticColors,
921
+ shadows: [...shadows],
922
+ backgrounds: [...backgrounds],
923
+ components,
924
+ layout,
925
+ },
926
+ };
927
+ }
928
+ function browserCaptureExpression() {
929
+ // Bundlers can inject a module-scoped `__name` helper into nested functions.
930
+ // Playwright serializes only the function body into Chromium, so provide the
931
+ // tiny identity helper in the browser expression rather than leaking a
932
+ // bundler runtime reference into the page.
933
+ return `(function () {
934
+ const __name = (value) => value;
935
+ return (${captureRenderedWebsiteContext.toString()})();
936
+ })()`;
937
+ }
938
+ export function boundWebsiteExtraction(extraction) {
939
+ const boundedComponents = extraction.designTokens.components
940
+ ?.slice(0, MAX_COMPONENT_STYLES)
941
+ .map((component) => Object.fromEntries(Object.entries(component).map(([key, value]) => [
942
+ key,
943
+ typeof value === "string" ? value.slice(0, 500) : value,
944
+ ])));
945
+ return {
946
+ title: normalizeWhitespace(extraction.title).slice(0, 500),
947
+ text: normalizeWhitespace(extraction.text).slice(0, MAX_RENDERED_TEXT_CHARS),
948
+ assets: extraction.assets.slice(0, MAX_EXTRACTED_ASSETS).map((asset) => ({
949
+ ...asset,
950
+ url: asset.url.slice(0, 4_096),
951
+ })),
952
+ internalLinks: extraction.internalLinks
953
+ .slice(0, MAX_INTERNAL_LINKS)
954
+ .map((url) => url.slice(0, 4_096)),
955
+ designTokens: {
956
+ colors: extraction.designTokens.colors.slice(0, MAX_COLORS),
957
+ typography: extraction.designTokens.typography.slice(0, MAX_TYPOGRAPHY),
958
+ spacing: extraction.designTokens.spacing.slice(0, MAX_SPACING),
959
+ radii: extraction.designTokens.radii.slice(0, MAX_RADII),
960
+ cssVariables: Object.fromEntries(Object.entries(extraction.designTokens.cssVariables)
961
+ .slice(0, MAX_CSS_VARIABLES)
962
+ .map(([name, value]) => [name.slice(0, 500), value.slice(0, 4_096)])),
963
+ ...(extraction.designTokens.semanticColors
964
+ ? {
965
+ semanticColors: Object.fromEntries(Object.entries(extraction.designTokens.semanticColors)
966
+ .filter(([, value]) => typeof value === "string" && value)
967
+ .map(([name, value]) => [name, value.slice(0, 200)])),
968
+ }
969
+ : {}),
970
+ ...(extraction.designTokens.shadows
971
+ ? {
972
+ shadows: extraction.designTokens.shadows
973
+ .slice(0, 32)
974
+ .map((value) => value.slice(0, 500)),
975
+ }
976
+ : {}),
977
+ ...(extraction.designTokens.backgrounds
978
+ ? {
979
+ backgrounds: extraction.designTokens.backgrounds
980
+ .slice(0, 32)
981
+ .map((value) => value.slice(0, 500)),
982
+ }
983
+ : {}),
984
+ ...(boundedComponents ? { components: boundedComponents } : {}),
985
+ ...(extraction.designTokens.layout
986
+ ? {
987
+ layout: Object.fromEntries(Object.entries(extraction.designTokens.layout)
988
+ .filter(([, value]) => typeof value === "string" && value)
989
+ .map(([name, value]) => [name, value.slice(0, 200)])),
990
+ }
991
+ : {}),
992
+ },
993
+ };
994
+ }
995
+ function emptyExtraction() {
996
+ return {
997
+ title: "",
998
+ text: "",
999
+ assets: [],
1000
+ internalLinks: [],
1001
+ designTokens: {
1002
+ colors: [],
1003
+ typography: [],
1004
+ spacing: [],
1005
+ radii: [],
1006
+ cssVariables: {},
1007
+ },
1008
+ };
1009
+ }
1010
+ function classifyWebsite(extraction, finalUrl) {
1011
+ const path = new URL(finalUrl).pathname.replace(/\/+$/, "") || "/";
1012
+ const sample = `${extraction.title} ${extraction.text.slice(0, 2_000)}`.toLowerCase();
1013
+ if (path === "/")
1014
+ return "homepage";
1015
+ if (/\b(api|docs?|guide|reference|tutorial)\b/.test(sample)) {
1016
+ return "documentation";
1017
+ }
1018
+ if (/\b(blog|article|news|author|published)\b/.test(sample))
1019
+ return "content";
1020
+ if (/\b(pricing|features|customers|solutions|product)\b/.test(sample)) {
1021
+ return "marketing";
1022
+ }
1023
+ return "unknown";
1024
+ }
1025
+ function boundedTimeout(value) {
1026
+ return Number.isFinite(value)
1027
+ ? Math.max(1_000, Math.min(120_000, Math.floor(value)))
1028
+ : 30_000;
1029
+ }
1030
+ function boundedScreenshot(value) {
1031
+ return value.byteLength <= MAX_SCREENSHOT_BYTES ? value : undefined;
1032
+ }
1033
+ function errorMessage(error) {
1034
+ return error instanceof Error ? error.message : String(error);
1035
+ }
1036
+ //# sourceMappingURL=rendered-page.js.map