@aglyn/plugins-ai 1.0.0-beta.143

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 (717) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +25 -0
  3. package/package.json +60 -0
  4. package/src/index.d.ts +21 -0
  5. package/src/index.js +22 -0
  6. package/src/index.js.map +1 -0
  7. package/src/lib/activity/ai-activity-actions.d.ts +106 -0
  8. package/src/lib/activity/ai-activity-actions.js +209 -0
  9. package/src/lib/activity/ai-activity-actions.js.map +1 -0
  10. package/src/lib/activity/ai-activity.d.ts +219 -0
  11. package/src/lib/activity/ai-activity.js +251 -0
  12. package/src/lib/activity/ai-activity.js.map +1 -0
  13. package/src/lib/billing/ai-overage-charge.d.ts +102 -0
  14. package/src/lib/billing/ai-overage-charge.js +258 -0
  15. package/src/lib/billing/ai-overage-charge.js.map +1 -0
  16. package/src/lib/billing/ai-overage-close.d.ts +62 -0
  17. package/src/lib/billing/ai-overage-close.js +129 -0
  18. package/src/lib/billing/ai-overage-close.js.map +1 -0
  19. package/src/lib/billing/ai-overage-cutover.d.ts +63 -0
  20. package/src/lib/billing/ai-overage-cutover.js +114 -0
  21. package/src/lib/billing/ai-overage-cutover.js.map +1 -0
  22. package/src/lib/billing/ai-overage-events.d.ts +77 -0
  23. package/src/lib/billing/ai-overage-events.js +174 -0
  24. package/src/lib/billing/ai-overage-events.js.map +1 -0
  25. package/src/lib/billing/ai-overage-gate.d.ts +147 -0
  26. package/src/lib/billing/ai-overage-gate.js +177 -0
  27. package/src/lib/billing/ai-overage-gate.js.map +1 -0
  28. package/src/lib/billing/ai-overage-ledger.d.ts +135 -0
  29. package/src/lib/billing/ai-overage-ledger.js +278 -0
  30. package/src/lib/billing/ai-overage-ledger.js.map +1 -0
  31. package/src/lib/billing/ai-overage-standing-writes.d.ts +110 -0
  32. package/src/lib/billing/ai-overage-standing-writes.js +205 -0
  33. package/src/lib/billing/ai-overage-standing-writes.js.map +1 -0
  34. package/src/lib/billing/ai-overage-standing.d.ts +168 -0
  35. package/src/lib/billing/ai-overage-standing.js +215 -0
  36. package/src/lib/billing/ai-overage-standing.js.map +1 -0
  37. package/src/lib/billing/ai-overage-trigger.d.ts +30 -0
  38. package/src/lib/billing/ai-overage-trigger.js +76 -0
  39. package/src/lib/billing/ai-overage-trigger.js.map +1 -0
  40. package/src/lib/components/ai-allotment-editor.component.d.ts +40 -0
  41. package/src/lib/components/ai-allotment-editor.component.js +213 -0
  42. package/src/lib/components/ai-allotment-editor.component.js.map +1 -0
  43. package/src/lib/components/ai-assist-actions-context.d.ts +13 -0
  44. package/src/lib/components/ai-assist-actions-context.js +21 -0
  45. package/src/lib/components/ai-assist-actions-context.js.map +1 -0
  46. package/src/lib/components/ai-assist-provider.component.d.ts +51 -0
  47. package/src/lib/components/ai-assist-provider.component.js +519 -0
  48. package/src/lib/components/ai-assist-provider.component.js.map +1 -0
  49. package/src/lib/components/ai-brief-dialog.component.d.ts +56 -0
  50. package/src/lib/components/ai-brief-dialog.component.js +319 -0
  51. package/src/lib/components/ai-brief-dialog.component.js.map +1 -0
  52. package/src/lib/components/ai-collaborator-permissions-column.component.d.ts +32 -0
  53. package/src/lib/components/ai-collaborator-permissions-column.component.js +132 -0
  54. package/src/lib/components/ai-collaborator-permissions-column.component.js.map +1 -0
  55. package/src/lib/components/ai-credits-card.component.d.ts +34 -0
  56. package/src/lib/components/ai-credits-card.component.js +131 -0
  57. package/src/lib/components/ai-credits-card.component.js.map +1 -0
  58. package/src/lib/components/ai-credits-columns.component.d.ts +56 -0
  59. package/src/lib/components/ai-credits-columns.component.js +118 -0
  60. package/src/lib/components/ai-credits-columns.component.js.map +1 -0
  61. package/src/lib/components/ai-crm-email-draft.component.d.ts +17 -0
  62. package/src/lib/components/ai-crm-email-draft.component.js +159 -0
  63. package/src/lib/components/ai-crm-email-draft.component.js.map +1 -0
  64. package/src/lib/components/ai-crm-import-mapping.component.d.ts +20 -0
  65. package/src/lib/components/ai-crm-import-mapping.component.js +167 -0
  66. package/src/lib/components/ai-crm-import-mapping.component.js.map +1 -0
  67. package/src/lib/components/ai-crm-record-card.component.d.ts +27 -0
  68. package/src/lib/components/ai-crm-record-card.component.js +263 -0
  69. package/src/lib/components/ai-crm-record-card.component.js.map +1 -0
  70. package/src/lib/components/ai-describe-automation.component.d.ts +31 -0
  71. package/src/lib/components/ai-describe-automation.component.js +226 -0
  72. package/src/lib/components/ai-describe-automation.component.js.map +1 -0
  73. package/src/lib/components/ai-describe-button.component.d.ts +39 -0
  74. package/src/lib/components/ai-describe-button.component.js +87 -0
  75. package/src/lib/components/ai-describe-button.component.js.map +1 -0
  76. package/src/lib/components/ai-describe-page.component.d.ts +26 -0
  77. package/src/lib/components/ai-describe-page.component.js +18 -0
  78. package/src/lib/components/ai-describe-page.component.js.map +1 -0
  79. package/src/lib/components/ai-experiment-cards.component.d.ts +75 -0
  80. package/src/lib/components/ai-experiment-cards.component.js +573 -0
  81. package/src/lib/components/ai-experiment-cards.component.js.map +1 -0
  82. package/src/lib/components/ai-explain-automation.component.d.ts +31 -0
  83. package/src/lib/components/ai-explain-automation.component.js +265 -0
  84. package/src/lib/components/ai-explain-automation.component.js.map +1 -0
  85. package/src/lib/components/ai-insight-dialog.component.d.ts +37 -0
  86. package/src/lib/components/ai-insight-dialog.component.js +441 -0
  87. package/src/lib/components/ai-insight-dialog.component.js.map +1 -0
  88. package/src/lib/components/ai-job-plan.component.d.ts +46 -0
  89. package/src/lib/components/ai-job-plan.component.js +192 -0
  90. package/src/lib/components/ai-job-plan.component.js.map +1 -0
  91. package/src/lib/components/ai-model-selector.component.d.ts +21 -0
  92. package/src/lib/components/ai-model-selector.component.js +109 -0
  93. package/src/lib/components/ai-model-selector.component.js.map +1 -0
  94. package/src/lib/components/ai-page-brief-dialog.component.d.ts +29 -0
  95. package/src/lib/components/ai-page-brief-dialog.component.js +27 -0
  96. package/src/lib/components/ai-page-brief-dialog.component.js.map +1 -0
  97. package/src/lib/components/ai-permissions-on-host.component.d.ts +55 -0
  98. package/src/lib/components/ai-permissions-on-host.component.js +91 -0
  99. package/src/lib/components/ai-permissions-on-host.component.js.map +1 -0
  100. package/src/lib/components/ai-product-copy-card.component.d.ts +25 -0
  101. package/src/lib/components/ai-product-copy-card.component.js +328 -0
  102. package/src/lib/components/ai-product-copy-card.component.js.map +1 -0
  103. package/src/lib/components/ai-product-import-option.component.d.ts +14 -0
  104. package/src/lib/components/ai-product-import-option.component.js +58 -0
  105. package/src/lib/components/ai-product-import-option.component.js.map +1 -0
  106. package/src/lib/components/ai-products-hub-card.component.d.ts +15 -0
  107. package/src/lib/components/ai-products-hub-card.component.js +418 -0
  108. package/src/lib/components/ai-products-hub-card.component.js.map +1 -0
  109. package/src/lib/components/ai-products-proposals.component.d.ts +19 -0
  110. package/src/lib/components/ai-products-proposals.component.js +547 -0
  111. package/src/lib/components/ai-products-proposals.component.js.map +1 -0
  112. package/src/lib/components/ai-save-as-component.component.d.ts +38 -0
  113. package/src/lib/components/ai-save-as-component.component.js +231 -0
  114. package/src/lib/components/ai-save-as-component.component.js.map +1 -0
  115. package/src/lib/components/ai-seo-audit-card.component.d.ts +9 -0
  116. package/src/lib/components/ai-seo-audit-card.component.js +620 -0
  117. package/src/lib/components/ai-seo-audit-card.component.js.map +1 -0
  118. package/src/lib/components/ai-seo-fields-card.component.d.ts +10 -0
  119. package/src/lib/components/ai-seo-fields-card.component.js +453 -0
  120. package/src/lib/components/ai-seo-fields-card.component.js.map +1 -0
  121. package/src/lib/components/ai-site-batch-card.component.d.ts +32 -0
  122. package/src/lib/components/ai-site-batch-card.component.js +531 -0
  123. package/src/lib/components/ai-site-batch-card.component.js.map +1 -0
  124. package/src/lib/components/ai-site-seo-start-card.component.d.ts +26 -0
  125. package/src/lib/components/ai-site-seo-start-card.component.js +178 -0
  126. package/src/lib/components/ai-site-seo-start-card.component.js.map +1 -0
  127. package/src/lib/components/ai-site-start-card.component.d.ts +19 -0
  128. package/src/lib/components/ai-site-start-card.component.js +348 -0
  129. package/src/lib/components/ai-site-start-card.component.js.map +1 -0
  130. package/src/lib/components/ai-template-collection-field.component.d.ts +32 -0
  131. package/src/lib/components/ai-template-collection-field.component.js +63 -0
  132. package/src/lib/components/ai-template-collection-field.component.js.map +1 -0
  133. package/src/lib/components/ai-theme-proposal-card.component.d.ts +6 -0
  134. package/src/lib/components/ai-theme-proposal-card.component.js +619 -0
  135. package/src/lib/components/ai-theme-proposal-card.component.js.map +1 -0
  136. package/src/lib/components/ai-usage-strip.component.d.ts +27 -0
  137. package/src/lib/components/ai-usage-strip.component.js +145 -0
  138. package/src/lib/components/ai-usage-strip.component.js.map +1 -0
  139. package/src/lib/components/assist-edit-canvas.d.ts +169 -0
  140. package/src/lib/components/assist-edit-canvas.js +636 -0
  141. package/src/lib/components/assist-edit-canvas.js.map +1 -0
  142. package/src/lib/components/assist-edit-card.component.d.ts +16 -0
  143. package/src/lib/components/assist-edit-card.component.js +181 -0
  144. package/src/lib/components/assist-edit-card.component.js.map +1 -0
  145. package/src/lib/components/assist-jobs-drawer.component.d.ts +72 -0
  146. package/src/lib/components/assist-jobs-drawer.component.js +626 -0
  147. package/src/lib/components/assist-jobs-drawer.component.js.map +1 -0
  148. package/src/lib/components/assist-panel.component.d.ts +136 -0
  149. package/src/lib/components/assist-panel.component.js +1099 -0
  150. package/src/lib/components/assist-panel.component.js.map +1 -0
  151. package/src/lib/components/assist-signals-page.component.d.ts +3 -0
  152. package/src/lib/components/assist-signals-page.component.js +1017 -0
  153. package/src/lib/components/assist-signals-page.component.js.map +1 -0
  154. package/src/lib/components/besigner-ai-controls.component.d.ts +29 -0
  155. package/src/lib/components/besigner-ai-controls.component.js +81 -0
  156. package/src/lib/components/besigner-ai-controls.component.js.map +1 -0
  157. package/src/lib/components/billing-ai-allotments.component.d.ts +36 -0
  158. package/src/lib/components/billing-ai-allotments.component.js +486 -0
  159. package/src/lib/components/billing-ai-allotments.component.js.map +1 -0
  160. package/src/lib/components/billing-ai-top-users.component.d.ts +44 -0
  161. package/src/lib/components/billing-ai-top-users.component.js +304 -0
  162. package/src/lib/components/billing-ai-top-users.component.js.map +1 -0
  163. package/src/lib/components/billing-assist-overage-card.component.d.ts +69 -0
  164. package/src/lib/components/billing-assist-overage-card.component.js +437 -0
  165. package/src/lib/components/billing-assist-overage-card.component.js.map +1 -0
  166. package/src/lib/components/host-ai-allotments.component.d.ts +40 -0
  167. package/src/lib/components/host-ai-allotments.component.js +239 -0
  168. package/src/lib/components/host-ai-allotments.component.js.map +1 -0
  169. package/src/lib/components/member-ai-allotment-card.component.d.ts +28 -0
  170. package/src/lib/components/member-ai-allotment-card.component.js +172 -0
  171. package/src/lib/components/member-ai-allotment-card.component.js.map +1 -0
  172. package/src/lib/components/member-ai-usage-card.component.d.ts +28 -0
  173. package/src/lib/components/member-ai-usage-card.component.js +240 -0
  174. package/src/lib/components/member-ai-usage-card.component.js.map +1 -0
  175. package/src/lib/components/staff-org-ai-card.component.d.ts +17 -0
  176. package/src/lib/components/staff-org-ai-card.component.js +739 -0
  177. package/src/lib/components/staff-org-ai-card.component.js.map +1 -0
  178. package/src/lib/components/staff-org-usage-ai-columns.component.d.ts +41 -0
  179. package/src/lib/components/staff-org-usage-ai-columns.component.js +65 -0
  180. package/src/lib/components/staff-org-usage-ai-columns.component.js.map +1 -0
  181. package/src/lib/components/staff-orgs-ai-spend-column.component.d.ts +28 -0
  182. package/src/lib/components/staff-orgs-ai-spend-column.component.js +89 -0
  183. package/src/lib/components/staff-orgs-ai-spend-column.component.js.map +1 -0
  184. package/src/lib/components/staff-user-ai-usage-card.component.d.ts +27 -0
  185. package/src/lib/components/staff-user-ai-usage-card.component.js +183 -0
  186. package/src/lib/components/staff-user-ai-usage-card.component.js.map +1 -0
  187. package/src/lib/components/use-ai-allotments.d.ts +49 -0
  188. package/src/lib/components/use-ai-allotments.js +171 -0
  189. package/src/lib/components/use-ai-allotments.js.map +1 -0
  190. package/src/lib/components/use-ai-crm-answer.d.ts +50 -0
  191. package/src/lib/components/use-ai-crm-answer.js +220 -0
  192. package/src/lib/components/use-ai-crm-answer.js.map +1 -0
  193. package/src/lib/components/use-ai-job-run.d.ts +51 -0
  194. package/src/lib/components/use-ai-job-run.js +176 -0
  195. package/src/lib/components/use-ai-job-run.js.map +1 -0
  196. package/src/lib/components/use-ai-model-choice.d.ts +47 -0
  197. package/src/lib/components/use-ai-model-choice.js +150 -0
  198. package/src/lib/components/use-ai-model-choice.js.map +1 -0
  199. package/src/lib/components/use-ai-products-jobs.d.ts +36 -0
  200. package/src/lib/components/use-ai-products-jobs.js +190 -0
  201. package/src/lib/components/use-ai-products-jobs.js.map +1 -0
  202. package/src/lib/components/use-ai-usage-meter.d.ts +11 -0
  203. package/src/lib/components/use-ai-usage-meter.js +96 -0
  204. package/src/lib/components/use-ai-usage-meter.js.map +1 -0
  205. package/src/lib/components/use-org-ai-usage.d.ts +42 -0
  206. package/src/lib/components/use-org-ai-usage.js +181 -0
  207. package/src/lib/components/use-org-ai-usage.js.map +1 -0
  208. package/src/lib/components/use-staff-orgs-ai-spend.d.ts +18 -0
  209. package/src/lib/components/use-staff-orgs-ai-spend.js +127 -0
  210. package/src/lib/components/use-staff-orgs-ai-spend.js.map +1 -0
  211. package/src/lib/constants.d.ts +24 -0
  212. package/src/lib/constants.js +23 -0
  213. package/src/lib/constants.js.map +1 -0
  214. package/src/lib/declarations.d.ts +48 -0
  215. package/src/lib/declarations.js +129 -0
  216. package/src/lib/declarations.js.map +1 -0
  217. package/src/lib/declarations.server.d.ts +35 -0
  218. package/src/lib/declarations.server.js +138 -0
  219. package/src/lib/declarations.server.js.map +1 -0
  220. package/src/lib/insights/ai-figure-readers.d.ts +90 -0
  221. package/src/lib/insights/ai-figure-readers.js +863 -0
  222. package/src/lib/insights/ai-figure-readers.js.map +1 -0
  223. package/src/lib/insights/ai-insight-digest.d.ts +165 -0
  224. package/src/lib/insights/ai-insight-digest.js +363 -0
  225. package/src/lib/insights/ai-insight-digest.js.map +1 -0
  226. package/src/lib/insights/ai-insight-readers.d.ts +71 -0
  227. package/src/lib/insights/ai-insight-readers.js +141 -0
  228. package/src/lib/insights/ai-insight-readers.js.map +1 -0
  229. package/src/lib/jobs/ai-crm-access.d.ts +61 -0
  230. package/src/lib/jobs/ai-crm-access.js +94 -0
  231. package/src/lib/jobs/ai-crm-access.js.map +1 -0
  232. package/src/lib/jobs/ai-email-bindings.d.ts +97 -0
  233. package/src/lib/jobs/ai-email-bindings.js +147 -0
  234. package/src/lib/jobs/ai-email-bindings.js.map +1 -0
  235. package/src/lib/jobs/ai-job-admission.d.ts +82 -0
  236. package/src/lib/jobs/ai-job-admission.js +45 -0
  237. package/src/lib/jobs/ai-job-admission.js.map +1 -0
  238. package/src/lib/jobs/ai-job-budget.d.ts +167 -0
  239. package/src/lib/jobs/ai-job-budget.js +161 -0
  240. package/src/lib/jobs/ai-job-budget.js.map +1 -0
  241. package/src/lib/jobs/ai-job-campaign-step.d.ts +108 -0
  242. package/src/lib/jobs/ai-job-campaign-step.js +340 -0
  243. package/src/lib/jobs/ai-job-campaign-step.js.map +1 -0
  244. package/src/lib/jobs/ai-job-component-checks.d.ts +74 -0
  245. package/src/lib/jobs/ai-job-component-checks.js +442 -0
  246. package/src/lib/jobs/ai-job-component-checks.js.map +1 -0
  247. package/src/lib/jobs/ai-job-component-step.d.ts +75 -0
  248. package/src/lib/jobs/ai-job-component-step.js +262 -0
  249. package/src/lib/jobs/ai-job-component-step.js.map +1 -0
  250. package/src/lib/jobs/ai-job-crm-step.d.ts +192 -0
  251. package/src/lib/jobs/ai-job-crm-step.js +734 -0
  252. package/src/lib/jobs/ai-job-crm-step.js.map +1 -0
  253. package/src/lib/jobs/ai-job-draft-ids.d.ts +62 -0
  254. package/src/lib/jobs/ai-job-draft-ids.js +132 -0
  255. package/src/lib/jobs/ai-job-draft-ids.js.map +1 -0
  256. package/src/lib/jobs/ai-job-drafts.d.ts +304 -0
  257. package/src/lib/jobs/ai-job-drafts.js +557 -0
  258. package/src/lib/jobs/ai-job-drafts.js.map +1 -0
  259. package/src/lib/jobs/ai-job-email-step.d.ts +195 -0
  260. package/src/lib/jobs/ai-job-email-step.js +547 -0
  261. package/src/lib/jobs/ai-job-email-step.js.map +1 -0
  262. package/src/lib/jobs/ai-job-experiment-step.d.ts +105 -0
  263. package/src/lib/jobs/ai-job-experiment-step.js +445 -0
  264. package/src/lib/jobs/ai-job-experiment-step.js.map +1 -0
  265. package/src/lib/jobs/ai-job-form-step.d.ts +250 -0
  266. package/src/lib/jobs/ai-job-form-step.js +634 -0
  267. package/src/lib/jobs/ai-job-form-step.js.map +1 -0
  268. package/src/lib/jobs/ai-job-generation.d.ts +114 -0
  269. package/src/lib/jobs/ai-job-generation.js +384 -0
  270. package/src/lib/jobs/ai-job-generation.js.map +1 -0
  271. package/src/lib/jobs/ai-job-insight-budget.d.ts +41 -0
  272. package/src/lib/jobs/ai-job-insight-budget.js +46 -0
  273. package/src/lib/jobs/ai-job-insight-budget.js.map +1 -0
  274. package/src/lib/jobs/ai-job-insight-step.d.ts +58 -0
  275. package/src/lib/jobs/ai-job-insight-step.js +350 -0
  276. package/src/lib/jobs/ai-job-insight-step.js.map +1 -0
  277. package/src/lib/jobs/ai-job-layout-step.d.ts +103 -0
  278. package/src/lib/jobs/ai-job-layout-step.js +340 -0
  279. package/src/lib/jobs/ai-job-layout-step.js.map +1 -0
  280. package/src/lib/jobs/ai-job-page-budget.d.ts +57 -0
  281. package/src/lib/jobs/ai-job-page-budget.js +60 -0
  282. package/src/lib/jobs/ai-job-page-budget.js.map +1 -0
  283. package/src/lib/jobs/ai-job-page-sections.d.ts +150 -0
  284. package/src/lib/jobs/ai-job-page-sections.js +450 -0
  285. package/src/lib/jobs/ai-job-page-sections.js.map +1 -0
  286. package/src/lib/jobs/ai-job-page-step.d.ts +198 -0
  287. package/src/lib/jobs/ai-job-page-step.js +667 -0
  288. package/src/lib/jobs/ai-job-page-step.js.map +1 -0
  289. package/src/lib/jobs/ai-job-plan-conformance.d.ts +107 -0
  290. package/src/lib/jobs/ai-job-plan-conformance.js +164 -0
  291. package/src/lib/jobs/ai-job-plan-conformance.js.map +1 -0
  292. package/src/lib/jobs/ai-job-plan-step.d.ts +196 -0
  293. package/src/lib/jobs/ai-job-plan-step.js +458 -0
  294. package/src/lib/jobs/ai-job-plan-step.js.map +1 -0
  295. package/src/lib/jobs/ai-job-plugin-drafts.d.ts +76 -0
  296. package/src/lib/jobs/ai-job-plugin-drafts.js +91 -0
  297. package/src/lib/jobs/ai-job-plugin-drafts.js.map +1 -0
  298. package/src/lib/jobs/ai-job-products-step.d.ts +106 -0
  299. package/src/lib/jobs/ai-job-products-step.js +436 -0
  300. package/src/lib/jobs/ai-job-products-step.js.map +1 -0
  301. package/src/lib/jobs/ai-job-seo-budget.d.ts +52 -0
  302. package/src/lib/jobs/ai-job-seo-budget.js +63 -0
  303. package/src/lib/jobs/ai-job-seo-budget.js.map +1 -0
  304. package/src/lib/jobs/ai-job-seo-step.d.ts +145 -0
  305. package/src/lib/jobs/ai-job-seo-step.js +809 -0
  306. package/src/lib/jobs/ai-job-seo-step.js.map +1 -0
  307. package/src/lib/jobs/ai-job-site-step.d.ts +252 -0
  308. package/src/lib/jobs/ai-job-site-step.js +538 -0
  309. package/src/lib/jobs/ai-job-site-step.js.map +1 -0
  310. package/src/lib/jobs/ai-job-template-step.d.ts +105 -0
  311. package/src/lib/jobs/ai-job-template-step.js +391 -0
  312. package/src/lib/jobs/ai-job-template-step.js.map +1 -0
  313. package/src/lib/jobs/ai-job-text-step.d.ts +125 -0
  314. package/src/lib/jobs/ai-job-text-step.js +128 -0
  315. package/src/lib/jobs/ai-job-text-step.js.map +1 -0
  316. package/src/lib/jobs/ai-job-theme-budget.d.ts +38 -0
  317. package/src/lib/jobs/ai-job-theme-budget.js +43 -0
  318. package/src/lib/jobs/ai-job-theme-budget.js.map +1 -0
  319. package/src/lib/jobs/ai-job-theme-step.d.ts +115 -0
  320. package/src/lib/jobs/ai-job-theme-step.js +337 -0
  321. package/src/lib/jobs/ai-job-theme-step.js.map +1 -0
  322. package/src/lib/jobs/ai-job-workflow-step.d.ts +139 -0
  323. package/src/lib/jobs/ai-job-workflow-step.js +530 -0
  324. package/src/lib/jobs/ai-job-workflow-step.js.map +1 -0
  325. package/src/lib/jobs/ai-jobs-beat.d.ts +78 -0
  326. package/src/lib/jobs/ai-jobs-beat.js +93 -0
  327. package/src/lib/jobs/ai-jobs-beat.js.map +1 -0
  328. package/src/lib/jobs/ai-jobs-pause.d.ts +38 -0
  329. package/src/lib/jobs/ai-jobs-pause.js +45 -0
  330. package/src/lib/jobs/ai-jobs-pause.js.map +1 -0
  331. package/src/lib/jobs/ai-jobs.d.ts +558 -0
  332. package/src/lib/jobs/ai-jobs.js +1410 -0
  333. package/src/lib/jobs/ai-jobs.js.map +1 -0
  334. package/src/lib/jobs/ai-media-asset-server.d.ts +34 -0
  335. package/src/lib/jobs/ai-media-asset-server.js +34 -0
  336. package/src/lib/jobs/ai-media-asset-server.js.map +1 -0
  337. package/src/lib/jobs/ai-media-asset.d.ts +59 -0
  338. package/src/lib/jobs/ai-media-asset.js +86 -0
  339. package/src/lib/jobs/ai-media-asset.js.map +1 -0
  340. package/src/lib/jobs/ai-product-image.d.ts +78 -0
  341. package/src/lib/jobs/ai-product-image.js +113 -0
  342. package/src/lib/jobs/ai-product-image.js.map +1 -0
  343. package/src/lib/jobs/ai-theme-brand-inputs.d.ts +125 -0
  344. package/src/lib/jobs/ai-theme-brand-inputs.js +378 -0
  345. package/src/lib/jobs/ai-theme-brand-inputs.js.map +1 -0
  346. package/src/lib/jobs/ai-theme-brand-server.d.ts +33 -0
  347. package/src/lib/jobs/ai-theme-brand-server.js +33 -0
  348. package/src/lib/jobs/ai-theme-brand-server.js.map +1 -0
  349. package/src/lib/jobs/ai-workflow-records.d.ts +84 -0
  350. package/src/lib/jobs/ai-workflow-records.js +158 -0
  351. package/src/lib/jobs/ai-workflow-records.js.map +1 -0
  352. package/src/lib/jobs/fixtures/ai-free-page-built-recording.d.ts +31 -0
  353. package/src/lib/jobs/fixtures/ai-free-page-built-recording.js +367 -0
  354. package/src/lib/jobs/fixtures/ai-free-page-built-recording.js.map +1 -0
  355. package/src/lib/jobs/fixtures/ai-free-page-recording.d.ts +69 -0
  356. package/src/lib/jobs/fixtures/ai-free-page-recording.js +442 -0
  357. package/src/lib/jobs/fixtures/ai-free-page-recording.js.map +1 -0
  358. package/src/lib/jobs/fixtures/ai-page-briefs.d.ts +146 -0
  359. package/src/lib/jobs/fixtures/ai-page-briefs.js +1850 -0
  360. package/src/lib/jobs/fixtures/ai-page-briefs.js.map +1 -0
  361. package/src/lib/model/ai-allotments.d.ts +208 -0
  362. package/src/lib/model/ai-allotments.js +269 -0
  363. package/src/lib/model/ai-allotments.js.map +1 -0
  364. package/src/lib/model/ai-automation-draft.d.ts +74 -0
  365. package/src/lib/model/ai-automation-draft.js +310 -0
  366. package/src/lib/model/ai-automation-draft.js.map +1 -0
  367. package/src/lib/model/ai-automation-outline.d.ts +50 -0
  368. package/src/lib/model/ai-automation-outline.js +262 -0
  369. package/src/lib/model/ai-automation-outline.js.map +1 -0
  370. package/src/lib/model/ai-build-plan.d.ts +197 -0
  371. package/src/lib/model/ai-build-plan.js +438 -0
  372. package/src/lib/model/ai-build-plan.js.map +1 -0
  373. package/src/lib/model/ai-crm.d.ts +237 -0
  374. package/src/lib/model/ai-crm.js +225 -0
  375. package/src/lib/model/ai-crm.js.map +1 -0
  376. package/src/lib/model/ai-experiment-proposal.d.ts +68 -0
  377. package/src/lib/model/ai-experiment-proposal.js +146 -0
  378. package/src/lib/model/ai-experiment-proposal.js.map +1 -0
  379. package/src/lib/model/ai-experiment.d.ts +309 -0
  380. package/src/lib/model/ai-experiment.js +395 -0
  381. package/src/lib/model/ai-experiment.js.map +1 -0
  382. package/src/lib/model/ai-insight.d.ts +178 -0
  383. package/src/lib/model/ai-insight.js +201 -0
  384. package/src/lib/model/ai-insight.js.map +1 -0
  385. package/src/lib/model/ai-jobs.types.d.ts +412 -0
  386. package/src/lib/model/ai-jobs.types.js +42 -0
  387. package/src/lib/model/ai-jobs.types.js.map +1 -0
  388. package/src/lib/model/ai-page-job.d.ts +92 -0
  389. package/src/lib/model/ai-page-job.js +159 -0
  390. package/src/lib/model/ai-page-job.js.map +1 -0
  391. package/src/lib/model/ai-permissions.d.ts +49 -0
  392. package/src/lib/model/ai-permissions.js +97 -0
  393. package/src/lib/model/ai-permissions.js.map +1 -0
  394. package/src/lib/model/ai-plan-capabilities.d.ts +139 -0
  395. package/src/lib/model/ai-plan-capabilities.js +149 -0
  396. package/src/lib/model/ai-plan-capabilities.js.map +1 -0
  397. package/src/lib/model/ai-products.d.ts +251 -0
  398. package/src/lib/model/ai-products.js +253 -0
  399. package/src/lib/model/ai-products.js.map +1 -0
  400. package/src/lib/model/ai-seo.d.ts +208 -0
  401. package/src/lib/model/ai-seo.js +150 -0
  402. package/src/lib/model/ai-seo.js.map +1 -0
  403. package/src/lib/model/ai-site-inventory.d.ts +164 -0
  404. package/src/lib/model/ai-site-inventory.js +145 -0
  405. package/src/lib/model/ai-site-inventory.js.map +1 -0
  406. package/src/lib/model/ai-site-job.d.ts +247 -0
  407. package/src/lib/model/ai-site-job.js +314 -0
  408. package/src/lib/model/ai-site-job.js.map +1 -0
  409. package/src/lib/model/ai-site-start-seo.d.ts +103 -0
  410. package/src/lib/model/ai-site-start-seo.js +154 -0
  411. package/src/lib/model/ai-site-start-seo.js.map +1 -0
  412. package/src/lib/model/ai-site-start.d.ts +122 -0
  413. package/src/lib/model/ai-site-start.js +159 -0
  414. package/src/lib/model/ai-site-start.js.map +1 -0
  415. package/src/lib/model/ai-site-switch.d.ts +56 -0
  416. package/src/lib/model/ai-site-switch.js +73 -0
  417. package/src/lib/model/ai-site-switch.js.map +1 -0
  418. package/src/lib/model/ai-storefront-claims.d.ts +70 -0
  419. package/src/lib/model/ai-storefront-claims.js +130 -0
  420. package/src/lib/model/ai-storefront-claims.js.map +1 -0
  421. package/src/lib/model/ai-template-subjects.d.ts +82 -0
  422. package/src/lib/model/ai-template-subjects.js +136 -0
  423. package/src/lib/model/ai-template-subjects.js.map +1 -0
  424. package/src/lib/model/ai-theme-proposal.d.ts +210 -0
  425. package/src/lib/model/ai-theme-proposal.js +506 -0
  426. package/src/lib/model/ai-theme-proposal.js.map +1 -0
  427. package/src/lib/model/ai-tokens.d.ts +96 -0
  428. package/src/lib/model/ai-tokens.js +117 -0
  429. package/src/lib/model/ai-tokens.js.map +1 -0
  430. package/src/lib/model/ai-usage-by-user.d.ts +120 -0
  431. package/src/lib/model/ai-usage-by-user.js +139 -0
  432. package/src/lib/model/ai-usage-by-user.js.map +1 -0
  433. package/src/lib/model/ai-workflow-job.d.ts +111 -0
  434. package/src/lib/model/ai-workflow-job.js +183 -0
  435. package/src/lib/model/ai-workflow-job.js.map +1 -0
  436. package/src/lib/model/assist-edit.d.ts +261 -0
  437. package/src/lib/model/assist-edit.js +175 -0
  438. package/src/lib/model/assist-edit.js.map +1 -0
  439. package/src/lib/plugin-config.d.ts +33 -0
  440. package/src/lib/plugin-config.js +118 -0
  441. package/src/lib/plugin-config.js.map +1 -0
  442. package/src/lib/plugin.d.ts +30 -0
  443. package/src/lib/plugin.js +525 -0
  444. package/src/lib/plugin.js.map +1 -0
  445. package/src/lib/providers/anthropic.d.ts +84 -0
  446. package/src/lib/providers/anthropic.js +432 -0
  447. package/src/lib/providers/anthropic.js.map +1 -0
  448. package/src/lib/providers/catalog.d.ts +197 -0
  449. package/src/lib/providers/catalog.js +312 -0
  450. package/src/lib/providers/catalog.js.map +1 -0
  451. package/src/lib/providers/contract.d.ts +464 -0
  452. package/src/lib/providers/contract.js +274 -0
  453. package/src/lib/providers/contract.js.map +1 -0
  454. package/src/lib/providers/model-choice.d.ts +119 -0
  455. package/src/lib/providers/model-choice.js +416 -0
  456. package/src/lib/providers/model-choice.js.map +1 -0
  457. package/src/lib/providers/openai-compatible.d.ts +58 -0
  458. package/src/lib/providers/openai-compatible.js +361 -0
  459. package/src/lib/providers/openai-compatible.js.map +1 -0
  460. package/src/lib/providers/registry.d.ts +49 -0
  461. package/src/lib/providers/registry.js +71 -0
  462. package/src/lib/providers/registry.js.map +1 -0
  463. package/src/lib/providers/routing.d.ts +98 -0
  464. package/src/lib/providers/routing.js +450 -0
  465. package/src/lib/providers/routing.js.map +1 -0
  466. package/src/lib/runtime/ai-abuse-guards.d.ts +113 -0
  467. package/src/lib/runtime/ai-abuse-guards.js +148 -0
  468. package/src/lib/runtime/ai-abuse-guards.js.map +1 -0
  469. package/src/lib/runtime/ai-component-bindings.d.ts +67 -0
  470. package/src/lib/runtime/ai-component-bindings.js +106 -0
  471. package/src/lib/runtime/ai-component-bindings.js.map +1 -0
  472. package/src/lib/runtime/ai-device-audit.d.ts +109 -0
  473. package/src/lib/runtime/ai-device-audit.js +97 -0
  474. package/src/lib/runtime/ai-device-audit.js.map +1 -0
  475. package/src/lib/runtime/ai-doctrine-validators.d.ts +720 -0
  476. package/src/lib/runtime/ai-doctrine-validators.js +3133 -0
  477. package/src/lib/runtime/ai-doctrine-validators.js.map +1 -0
  478. package/src/lib/runtime/ai-doctrine.d.ts +372 -0
  479. package/src/lib/runtime/ai-doctrine.js +944 -0
  480. package/src/lib/runtime/ai-doctrine.js.map +1 -0
  481. package/src/lib/runtime/ai-eval-live.d.ts +321 -0
  482. package/src/lib/runtime/ai-eval-live.js +1257 -0
  483. package/src/lib/runtime/ai-eval-live.js.map +1 -0
  484. package/src/lib/runtime/ai-eval-memory-firestore.d.ts +51 -0
  485. package/src/lib/runtime/ai-eval-memory-firestore.js +183 -0
  486. package/src/lib/runtime/ai-eval-memory-firestore.js.map +1 -0
  487. package/src/lib/runtime/ai-eval.d.ts +441 -0
  488. package/src/lib/runtime/ai-eval.js +1151 -0
  489. package/src/lib/runtime/ai-eval.js.map +1 -0
  490. package/src/lib/runtime/ai-gate.d.ts +130 -0
  491. package/src/lib/runtime/ai-gate.js +272 -0
  492. package/src/lib/runtime/ai-gate.js.map +1 -0
  493. package/src/lib/runtime/ai-generation-bounds.d.ts +24 -0
  494. package/src/lib/runtime/ai-generation-bounds.js +23 -0
  495. package/src/lib/runtime/ai-generation-bounds.js.map +1 -0
  496. package/src/lib/runtime/ai-insight-check.d.ts +76 -0
  497. package/src/lib/runtime/ai-insight-check.js +281 -0
  498. package/src/lib/runtime/ai-insight-check.js.map +1 -0
  499. package/src/lib/runtime/ai-node-tree.d.ts +181 -0
  500. package/src/lib/runtime/ai-node-tree.js +931 -0
  501. package/src/lib/runtime/ai-node-tree.js.map +1 -0
  502. package/src/lib/runtime/ai-page-links.d.ts +79 -0
  503. package/src/lib/runtime/ai-page-links.js +135 -0
  504. package/src/lib/runtime/ai-page-links.js.map +1 -0
  505. package/src/lib/runtime/ai-palette.d.ts +252 -0
  506. package/src/lib/runtime/ai-palette.generated.d.ts +34 -0
  507. package/src/lib/runtime/ai-palette.generated.js +5263 -0
  508. package/src/lib/runtime/ai-palette.generated.js.map +1 -0
  509. package/src/lib/runtime/ai-palette.js +187 -0
  510. package/src/lib/runtime/ai-palette.js.map +1 -0
  511. package/src/lib/runtime/ai-products-generation.d.ts +107 -0
  512. package/src/lib/runtime/ai-products-generation.js +250 -0
  513. package/src/lib/runtime/ai-products-generation.js.map +1 -0
  514. package/src/lib/runtime/ai-repeated-items.d.ts +95 -0
  515. package/src/lib/runtime/ai-repeated-items.js +397 -0
  516. package/src/lib/runtime/ai-repeated-items.js.map +1 -0
  517. package/src/lib/runtime/ai-runtime.d.ts +148 -0
  518. package/src/lib/runtime/ai-runtime.js +237 -0
  519. package/src/lib/runtime/ai-runtime.js.map +1 -0
  520. package/src/lib/runtime/ai-template-examples.d.ts +71 -0
  521. package/src/lib/runtime/ai-template-examples.js +135 -0
  522. package/src/lib/runtime/ai-template-examples.js.map +1 -0
  523. package/src/lib/runtime/assist-answer-cache.d.ts +80 -0
  524. package/src/lib/runtime/assist-answer-cache.js +184 -0
  525. package/src/lib/runtime/assist-answer-cache.js.map +1 -0
  526. package/src/lib/runtime/seo-audit.d.ts +93 -0
  527. package/src/lib/runtime/seo-audit.js +260 -0
  528. package/src/lib/runtime/seo-audit.js.map +1 -0
  529. package/src/lib/runtime/seo-content-fixes.d.ts +41 -0
  530. package/src/lib/runtime/seo-content-fixes.js +168 -0
  531. package/src/lib/runtime/seo-content-fixes.js.map +1 -0
  532. package/src/lib/runtime/seo-fields.d.ts +152 -0
  533. package/src/lib/runtime/seo-fields.js +215 -0
  534. package/src/lib/runtime/seo-fields.js.map +1 -0
  535. package/src/lib/runtime/seo-page-facts.d.ts +61 -0
  536. package/src/lib/runtime/seo-page-facts.js +150 -0
  537. package/src/lib/runtime/seo-page-facts.js.map +1 -0
  538. package/src/lib/runtime/site-inventory.d.ts +63 -0
  539. package/src/lib/runtime/site-inventory.js +230 -0
  540. package/src/lib/runtime/site-inventory.js.map +1 -0
  541. package/src/lib/server/ai-admin-org.d.ts +33 -0
  542. package/src/lib/server/ai-admin-org.js +381 -0
  543. package/src/lib/server/ai-admin-org.js.map +1 -0
  544. package/src/lib/server/ai-admin-orgs-spend.d.ts +40 -0
  545. package/src/lib/server/ai-admin-orgs-spend.js +129 -0
  546. package/src/lib/server/ai-admin-orgs-spend.js.map +1 -0
  547. package/src/lib/server/ai-admin-overage.d.ts +19 -0
  548. package/src/lib/server/ai-admin-overage.js +246 -0
  549. package/src/lib/server/ai-admin-overage.js.map +1 -0
  550. package/src/lib/server/ai-admin-signals.d.ts +34 -0
  551. package/src/lib/server/ai-admin-signals.js +330 -0
  552. package/src/lib/server/ai-admin-signals.js.map +1 -0
  553. package/src/lib/server/ai-admin-user.d.ts +27 -0
  554. package/src/lib/server/ai-admin-user.js +128 -0
  555. package/src/lib/server/ai-admin-user.js.map +1 -0
  556. package/src/lib/server/ai-allotments.d.ts +27 -0
  557. package/src/lib/server/ai-allotments.js +544 -0
  558. package/src/lib/server/ai-allotments.js.map +1 -0
  559. package/src/lib/server/ai-assist-prompts.d.ts +102 -0
  560. package/src/lib/server/ai-assist-prompts.js +207 -0
  561. package/src/lib/server/ai-assist-prompts.js.map +1 -0
  562. package/src/lib/server/ai-assist.d.ts +119 -0
  563. package/src/lib/server/ai-assist.js +517 -0
  564. package/src/lib/server/ai-assist.js.map +1 -0
  565. package/src/lib/server/ai-crm-answer.d.ts +30 -0
  566. package/src/lib/server/ai-crm-answer.js +98 -0
  567. package/src/lib/server/ai-crm-answer.js.map +1 -0
  568. package/src/lib/server/ai-generate-component.d.ts +111 -0
  569. package/src/lib/server/ai-generate-component.js +643 -0
  570. package/src/lib/server/ai-generate-component.js.map +1 -0
  571. package/src/lib/server/ai-host-permissions.d.ts +46 -0
  572. package/src/lib/server/ai-host-permissions.js +204 -0
  573. package/src/lib/server/ai-host-permissions.js.map +1 -0
  574. package/src/lib/server/ai-insight-answer.d.ts +30 -0
  575. package/src/lib/server/ai-insight-answer.js +83 -0
  576. package/src/lib/server/ai-insight-answer.js.map +1 -0
  577. package/src/lib/server/ai-insight-digest-route.d.ts +30 -0
  578. package/src/lib/server/ai-insight-digest-route.js +156 -0
  579. package/src/lib/server/ai-insight-digest-route.js.map +1 -0
  580. package/src/lib/server/ai-jobs-batch.d.ts +48 -0
  581. package/src/lib/server/ai-jobs-batch.js +306 -0
  582. package/src/lib/server/ai-jobs-batch.js.map +1 -0
  583. package/src/lib/server/ai-jobs-beat-route.d.ts +36 -0
  584. package/src/lib/server/ai-jobs-beat-route.js +86 -0
  585. package/src/lib/server/ai-jobs-beat-route.js.map +1 -0
  586. package/src/lib/server/ai-jobs-cancel.d.ts +30 -0
  587. package/src/lib/server/ai-jobs-cancel.js +74 -0
  588. package/src/lib/server/ai-jobs-cancel.js.map +1 -0
  589. package/src/lib/server/ai-jobs-events-route.d.ts +31 -0
  590. package/src/lib/server/ai-jobs-events-route.js +51 -0
  591. package/src/lib/server/ai-jobs-events-route.js.map +1 -0
  592. package/src/lib/server/ai-jobs-events.d.ts +55 -0
  593. package/src/lib/server/ai-jobs-events.js +144 -0
  594. package/src/lib/server/ai-jobs-events.js.map +1 -0
  595. package/src/lib/server/ai-jobs-gate.d.ts +47 -0
  596. package/src/lib/server/ai-jobs-gate.js +106 -0
  597. package/src/lib/server/ai-jobs-gate.js.map +1 -0
  598. package/src/lib/server/ai-jobs-resume.d.ts +23 -0
  599. package/src/lib/server/ai-jobs-resume.js +209 -0
  600. package/src/lib/server/ai-jobs-resume.js.map +1 -0
  601. package/src/lib/server/ai-jobs-route.d.ts +32 -0
  602. package/src/lib/server/ai-jobs-route.js +307 -0
  603. package/src/lib/server/ai-jobs-route.js.map +1 -0
  604. package/src/lib/server/ai-models.d.ts +18 -0
  605. package/src/lib/server/ai-models.js +134 -0
  606. package/src/lib/server/ai-models.js.map +1 -0
  607. package/src/lib/server/ai-seo-apply.d.ts +53 -0
  608. package/src/lib/server/ai-seo-apply.js +294 -0
  609. package/src/lib/server/ai-seo-apply.js.map +1 -0
  610. package/src/lib/server/ai-usage.d.ts +18 -0
  611. package/src/lib/server/ai-usage.js +220 -0
  612. package/src/lib/server/ai-usage.js.map +1 -0
  613. package/src/lib/server/assist-chat.d.ts +234 -0
  614. package/src/lib/server/assist-chat.js +1446 -0
  615. package/src/lib/server/assist-chat.js.map +1 -0
  616. package/src/lib/server/assist-edit-applied.d.ts +22 -0
  617. package/src/lib/server/assist-edit-applied.js +239 -0
  618. package/src/lib/server/assist-edit-applied.js.map +1 -0
  619. package/src/lib/server/assist-edit.d.ts +124 -0
  620. package/src/lib/server/assist-edit.js +1000 -0
  621. package/src/lib/server/assist-edit.js.map +1 -0
  622. package/src/lib/server/assist-feedback.d.ts +31 -0
  623. package/src/lib/server/assist-feedback.js +115 -0
  624. package/src/lib/server/assist-feedback.js.map +1 -0
  625. package/src/lib/server/assist-view-context.d.ts +343 -0
  626. package/src/lib/server/assist-view-context.js +690 -0
  627. package/src/lib/server/assist-view-context.js.map +1 -0
  628. package/src/lib/server/billing-credits.d.ts +59 -0
  629. package/src/lib/server/billing-credits.js +146 -0
  630. package/src/lib/server/billing-credits.js.map +1 -0
  631. package/src/lib/server/billing-overage.d.ts +19 -0
  632. package/src/lib/server/billing-overage.js +337 -0
  633. package/src/lib/server/billing-overage.js.map +1 -0
  634. package/src/lib/server.d.ts +32 -0
  635. package/src/lib/server.js +265 -0
  636. package/src/lib/server.js.map +1 -0
  637. package/src/lib/subprocessors.d.ts +18 -0
  638. package/src/lib/subprocessors.js +52 -0
  639. package/src/lib/subprocessors.js.map +1 -0
  640. package/src/lib/tools/ai-component-tool.d.ts +99 -0
  641. package/src/lib/tools/ai-component-tool.js +369 -0
  642. package/src/lib/tools/ai-component-tool.js.map +1 -0
  643. package/src/lib/tools/ai-crm-tool.d.ts +106 -0
  644. package/src/lib/tools/ai-crm-tool.js +488 -0
  645. package/src/lib/tools/ai-crm-tool.js.map +1 -0
  646. package/src/lib/tools/ai-duplicate-resource-tool.d.ts +71 -0
  647. package/src/lib/tools/ai-duplicate-resource-tool.js +164 -0
  648. package/src/lib/tools/ai-duplicate-resource-tool.js.map +1 -0
  649. package/src/lib/tools/ai-experiment-tool.d.ts +40 -0
  650. package/src/lib/tools/ai-experiment-tool.js +155 -0
  651. package/src/lib/tools/ai-experiment-tool.js.map +1 -0
  652. package/src/lib/tools/ai-insight-tool.d.ts +46 -0
  653. package/src/lib/tools/ai-insight-tool.js +200 -0
  654. package/src/lib/tools/ai-insight-tool.js.map +1 -0
  655. package/src/lib/tools/ai-inventory-lookup-tool.d.ts +86 -0
  656. package/src/lib/tools/ai-inventory-lookup-tool.js +164 -0
  657. package/src/lib/tools/ai-inventory-lookup-tool.js.map +1 -0
  658. package/src/lib/tools/ai-products-tool.d.ts +65 -0
  659. package/src/lib/tools/ai-products-tool.js +644 -0
  660. package/src/lib/tools/ai-products-tool.js.map +1 -0
  661. package/src/lib/tools/ai-seo-tool.d.ts +162 -0
  662. package/src/lib/tools/ai-seo-tool.js +546 -0
  663. package/src/lib/tools/ai-seo-tool.js.map +1 -0
  664. package/src/lib/tools/ai-theme-tool.d.ts +101 -0
  665. package/src/lib/tools/ai-theme-tool.js +562 -0
  666. package/src/lib/tools/ai-theme-tool.js.map +1 -0
  667. package/src/lib/tools/ai-workflow-tool.d.ts +166 -0
  668. package/src/lib/tools/ai-workflow-tool.js +860 -0
  669. package/src/lib/tools/ai-workflow-tool.js.map +1 -0
  670. package/src/lib/usage/ai-allotment-alerts.d.ts +72 -0
  671. package/src/lib/usage/ai-allotment-alerts.js +157 -0
  672. package/src/lib/usage/ai-allotment-alerts.js.map +1 -0
  673. package/src/lib/usage/ai-allotments.d.ts +125 -0
  674. package/src/lib/usage/ai-allotments.js +239 -0
  675. package/src/lib/usage/ai-allotments.js.map +1 -0
  676. package/src/lib/usage/ai-model-sample.d.ts +36 -0
  677. package/src/lib/usage/ai-model-sample.js +68 -0
  678. package/src/lib/usage/ai-model-sample.js.map +1 -0
  679. package/src/lib/usage/ai-usage-alerts.d.ts +55 -0
  680. package/src/lib/usage/ai-usage-alerts.js +114 -0
  681. package/src/lib/usage/ai-usage-alerts.js.map +1 -0
  682. package/src/lib/usage/ai-usage-by-user.d.ts +161 -0
  683. package/src/lib/usage/ai-usage-by-user.js +211 -0
  684. package/src/lib/usage/ai-usage-by-user.js.map +1 -0
  685. package/src/lib/usage/ai-usage-eraser.d.ts +29 -0
  686. package/src/lib/usage/ai-usage-eraser.js +40 -0
  687. package/src/lib/usage/ai-usage-eraser.js.map +1 -0
  688. package/src/lib/usage/ai-usage-meter.d.ts +39 -0
  689. package/src/lib/usage/ai-usage-meter.js +85 -0
  690. package/src/lib/usage/ai-usage-meter.js.map +1 -0
  691. package/src/lib/usage/ai-usage-wire.d.ts +184 -0
  692. package/src/lib/usage/ai-usage-wire.js +98 -0
  693. package/src/lib/usage/ai-usage-wire.js.map +1 -0
  694. package/src/lib/usage/assist-ceiling.d.ts +87 -0
  695. package/src/lib/usage/assist-ceiling.js +110 -0
  696. package/src/lib/usage/assist-ceiling.js.map +1 -0
  697. package/src/lib/usage/assist-free-taste.d.ts +225 -0
  698. package/src/lib/usage/assist-free-taste.js +308 -0
  699. package/src/lib/usage/assist-free-taste.js.map +1 -0
  700. package/src/lib/usage/assist-refusals.d.ts +69 -0
  701. package/src/lib/usage/assist-refusals.js +79 -0
  702. package/src/lib/usage/assist-refusals.js.map +1 -0
  703. package/src/lib/usage/assist-signal-mining.d.ts +375 -0
  704. package/src/lib/usage/assist-signal-mining.js +344 -0
  705. package/src/lib/usage/assist-signal-mining.js.map +1 -0
  706. package/src/lib/usage/assist-usage.d.ts +571 -0
  707. package/src/lib/usage/assist-usage.js +978 -0
  708. package/src/lib/usage/assist-usage.js.map +1 -0
  709. package/src/lib/usage/staff-org-ai.d.ts +242 -0
  710. package/src/lib/usage/staff-org-ai.js +173 -0
  711. package/src/lib/usage/staff-org-ai.js.map +1 -0
  712. package/src/lib/usage/staff-org-usage-ai.d.ts +83 -0
  713. package/src/lib/usage/staff-org-usage-ai.js +59 -0
  714. package/src/lib/usage/staff-org-usage-ai.js.map +1 -0
  715. package/src/lib/usage/staff-orgs-ai-spend.d.ts +83 -0
  716. package/src/lib/usage/staff-orgs-ai-spend.js +114 -0
  717. package/src/lib/usage/staff-orgs-ai-spend.js.map +1 -0
@@ -0,0 +1,260 @@
1
+ import { _ as _extends } from "@swc/helpers/_/_extends";
2
+ /**
3
+ * @license
4
+ * Copyright 2026 Aglyn LLC
5
+ *
6
+ * Licensed under the Apache License, Version 2.0 (the "License");
7
+ * you may not use this file except in compliance with the License.
8
+ * You may obtain a copy of the License at
9
+ *
10
+ * http://www.apache.org/licenses/LICENSE-2.0
11
+ *
12
+ * Unless required by applicable law or agreed to in writing, software
13
+ * distributed under the License is distributed on an "AS IS" BASIS,
14
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ * See the License for the specific language governing permissions and
16
+ * limitations under the License.
17
+ */ import { SEO_LISTING_FIELDS, seoListingFieldTooLong } from "@aglyn/aglyn/app-utils/seo-listing-fields";
18
+ import { aiSeoKeywordCoverage, aiSeoKeywordList } from "../tools/ai-seo-tool.js";
19
+ /**
20
+ * The site SEO audit's scoring (AGL-2910): every audited page held to what a
21
+ * search result and a crawler need, with nothing asked of a model. Pure, so
22
+ * the audit is proved against fixtures and a job only spends tokens on the
23
+ * fixes it cannot make without writing.
24
+ *
25
+ * Per page: a title and a description of its own, within their lengths and
26
+ * used on no other page; one main heading that says something; a description
27
+ * on every image; a link from somewhere else on the site; and the target
28
+ * keywords a person named, reported where the page already says them.
29
+ * Per site: whether search engines are told to stay away, whether the
30
+ * structured data names and describes the publisher, and whether agents get
31
+ * guidance of the author's own.
32
+ *
33
+ * Keyword coverage is reported, never forced. A page that does not say a
34
+ * keyword is told so; the fix a job proposes uses the keyword only where the
35
+ * page is about it, and the listing check refuses a keyword used past its
36
+ * per-field count.
37
+ */ /** Pages one audit covers. A larger site is audited on its first pages by path, and says how many it left. */ export const AI_SEO_AUDIT_MAX_PAGES = 150;
38
+ /** Pages one batch of fixes carries: one model call a batch. */ export const AI_SEO_AUDIT_BATCH_SIZE = 8;
39
+ /** What each severity takes off a page's score. */ const SEVERITY_WEIGHT = {
40
+ high: 25,
41
+ medium: 10,
42
+ low: 3
43
+ };
44
+ /** A main heading this short or this generic says nothing a searcher can use. */ const THIN_H1_MIN_CHARS = 10;
45
+ const GENERIC_H1 = new Set([
46
+ 'home',
47
+ 'homepage',
48
+ 'home page',
49
+ 'welcome',
50
+ 'hello',
51
+ 'untitled',
52
+ 'new page',
53
+ 'page',
54
+ 'title',
55
+ 'heading'
56
+ ]);
57
+ /** The findings a batch of generated fixes answers. */ const GENERATED_FIX_CODES = new Set([
58
+ 'title-missing',
59
+ 'title-too-long',
60
+ 'title-duplicate',
61
+ 'description-missing',
62
+ 'description-too-long',
63
+ 'description-duplicate',
64
+ 'h1-missing',
65
+ 'h1-thin',
66
+ 'image-alt-missing',
67
+ 'keyword-missing'
68
+ ]);
69
+ const blank = (value)=>!String(value != null ? value : '').trim();
70
+ const normalized = (value)=>String(value != null ? value : '').replace(/\s+/g, ' ').trim().toLowerCase();
71
+ /** A path as the keyword lines and the routing map both spell it: leading slash, no trailing one. */ export function aiSeoNormalizePath(path) {
72
+ const trimmed = String(path != null ? path : '').trim();
73
+ if (!trimmed || trimmed === '/') return '/';
74
+ return `/${trimmed.replace(/^\/+/, '').replace(/\/+$/, '')}`;
75
+ }
76
+ /**
77
+ * Target keywords per page, one line a page: `/pricing: plans, pricing`.
78
+ * A line without a path, or with a path the site does not have, names no
79
+ * page; the step reports the paths it could not match.
80
+ */ export function parseAiSeoKeywordLines(raw) {
81
+ const out = {};
82
+ for (const line of String(raw != null ? raw : '').split('\n')){
83
+ var _out_path;
84
+ const at = line.indexOf(':');
85
+ if (at <= 0) continue;
86
+ const path = aiSeoNormalizePath(line.slice(0, at));
87
+ const keywords = aiSeoKeywordList(line.slice(at + 1));
88
+ if (keywords.length) out[path] = aiSeoKeywordList([
89
+ ...(_out_path = out[path]) != null ? _out_path : [],
90
+ ...keywords
91
+ ]);
92
+ }
93
+ return out;
94
+ }
95
+ function finding(code, severity, message, extra = {}) {
96
+ return _extends({
97
+ code,
98
+ severity,
99
+ message
100
+ }, extra);
101
+ }
102
+ /** The pages that share one value, by that value. */ function sharedValues(pages, read) {
103
+ const groups = new Map();
104
+ for (const page of pages){
105
+ var _groups_get;
106
+ const key = normalized(read(page));
107
+ if (!key) continue;
108
+ groups.set(key, [
109
+ ...(_groups_get = groups.get(key)) != null ? _groups_get : [],
110
+ page.screenId
111
+ ]);
112
+ }
113
+ return new Map([
114
+ ...groups
115
+ ].filter(([, ids])=>ids.length > 1));
116
+ }
117
+ function pageFindings(page, titles, descriptions) {
118
+ var _h1s_;
119
+ const out = [];
120
+ const title = page.seo.title;
121
+ if (blank(title)) {
122
+ out.push(finding('title-missing', 'medium', 'This page has no search title, so results show its name beside the site title.'));
123
+ } else {
124
+ var _titles_get;
125
+ if (seoListingFieldTooLong('title', title)) {
126
+ out.push(finding('title-too-long', 'medium', `The search title is over ${SEO_LISTING_FIELDS.title.maxLength} characters and will be cut off in results.`));
127
+ }
128
+ const twins = (_titles_get = titles.get(normalized(title))) == null ? void 0 : _titles_get.filter((id)=>id !== page.screenId);
129
+ if (twins == null ? void 0 : twins.length) {
130
+ out.push(finding('title-duplicate', 'high', 'Another page uses the same search title, so results cannot tell them apart.', {
131
+ screenIds: twins
132
+ }));
133
+ }
134
+ }
135
+ const description = page.seo.description;
136
+ if (blank(description) && blank(page.description)) {
137
+ out.push(finding('description-missing', 'medium', 'This page has no search description, so results show the site’s.'));
138
+ } else if (!blank(description)) {
139
+ var _descriptions_get;
140
+ if (seoListingFieldTooLong('description', description)) {
141
+ out.push(finding('description-too-long', 'low', `The search description is over ${SEO_LISTING_FIELDS.description.maxLength} characters and will be cut off.`));
142
+ }
143
+ const twins = (_descriptions_get = descriptions.get(normalized(description))) == null ? void 0 : _descriptions_get.filter((id)=>id !== page.screenId);
144
+ if (twins == null ? void 0 : twins.length) {
145
+ out.push(finding('description-duplicate', 'medium', 'Another page uses the same search description.', {
146
+ screenIds: twins
147
+ }));
148
+ }
149
+ }
150
+ const { h1s } = page.facts;
151
+ if (!h1s.length) {
152
+ out.push(finding('h1-missing', 'high', 'This page has no main heading.'));
153
+ } else {
154
+ if (h1s.length > 1) {
155
+ out.push(finding('h1-multiple', 'medium', `This page has ${h1s.length} main headings; it should have one.`, {
156
+ nodeIds: h1s.slice(1).map((heading)=>heading.nodeId).filter((id)=>Boolean(id))
157
+ }));
158
+ }
159
+ const first = h1s[0];
160
+ if (first.text.length < THIN_H1_MIN_CHARS || GENERIC_H1.has(normalized(first.text))) {
161
+ out.push(finding('h1-thin', 'medium', `The main heading “${first.text}” says little about the page.`, {
162
+ nodeIds: first.nodeId ? [
163
+ first.nodeId
164
+ ] : []
165
+ }));
166
+ }
167
+ }
168
+ const missingAlt = page.facts.imagesMissingAlt;
169
+ if (missingAlt.length) {
170
+ out.push(finding('image-alt-missing', 'medium', `${missingAlt.length} ${missingAlt.length === 1 ? 'image has' : 'images have'} no description for readers who cannot see ${missingAlt.length === 1 ? 'it' : 'them'}.`, {
171
+ nodeIds: missingAlt.map((image)=>image.nodeId)
172
+ }));
173
+ }
174
+ if (!page.linkedFrom && page.path !== '/') {
175
+ out.push(finding('orphan', 'medium', 'No other page or shared layout links here, so visitors and crawlers may never find it.'));
176
+ }
177
+ const coverage = aiSeoKeywordCoverage(page.keywords, {
178
+ title: page.seo.title,
179
+ description: page.seo.description,
180
+ h1: (_h1s_ = h1s[0]) == null ? void 0 : _h1s_.text,
181
+ body: page.facts.text
182
+ });
183
+ for (const entry of coverage){
184
+ if (!entry.inTitle && !entry.inDescription && !entry.inH1 && !entry.inBody) {
185
+ out.push(finding('keyword-missing', 'low', `The page never says “${entry.keyword}”. Only use it if the page is about it.`, {
186
+ keyword: entry.keyword
187
+ }));
188
+ }
189
+ }
190
+ return out;
191
+ }
192
+ function scoreOf(findings) {
193
+ return Math.max(0, 100 - findings.reduce((sum, entry)=>sum + SEVERITY_WEIGHT[entry.severity], 0));
194
+ }
195
+ /** Audit the pages and the site; nothing here reads, writes or generates. */ export function aiSeoAudit(pages, site, options = {}) {
196
+ var _options_skipped, _options_batchSize;
197
+ const titles = sharedValues(pages, (page)=>page.seo.title);
198
+ const descriptions = sharedValues(pages, (page)=>page.seo.description);
199
+ const reports = pages.map((page)=>{
200
+ var _page_facts_h1s_;
201
+ const findings = pageFindings(page, titles, descriptions);
202
+ return {
203
+ screenId: page.screenId,
204
+ path: page.path,
205
+ name: page.name,
206
+ versionId: page.versionId,
207
+ score: scoreOf(findings),
208
+ findings,
209
+ keywords: aiSeoKeywordCoverage(page.keywords, {
210
+ title: page.seo.title,
211
+ description: page.seo.description,
212
+ h1: (_page_facts_h1s_ = page.facts.h1s[0]) == null ? void 0 : _page_facts_h1s_.text,
213
+ body: page.facts.text
214
+ })
215
+ };
216
+ });
217
+ const siteFindings = [];
218
+ if (site.discouraged) {
219
+ siteFindings.push(finding('search-discouraged', 'high', 'Search engines are asked not to index this site, so none of its pages appear in results.'));
220
+ }
221
+ if (blank(site.entity.name) || blank(site.entity.description)) {
222
+ siteFindings.push(finding('entity-incomplete', 'low', 'The structured data does not name and describe who publishes the site.'));
223
+ }
224
+ if (blank(site.agent.whenToUse)) {
225
+ siteFindings.push(finding('llms-guidance-missing', 'low', '/llms.txt carries no guidance of your own for AI agents.'));
226
+ }
227
+ const queue = reports.filter((report)=>report.findings.some((entry)=>GENERATED_FIX_CODES.has(entry.code))).sort((a, b)=>a.score - b.score || (a.path < b.path ? -1 : a.path > b.path ? 1 : 0)).map((report)=>report.screenId);
228
+ return {
229
+ kind: 'audit',
230
+ pages: reports,
231
+ skipped: Math.max(0, (_options_skipped = options.skipped) != null ? _options_skipped : 0),
232
+ site: siteFindings,
233
+ siteProposal: siteFindings.some((entry)=>entry.code === 'entity-incomplete' || entry.code === 'llms-guidance-missing'),
234
+ queue,
235
+ batchSize: Math.max(1, (_options_batchSize = options.batchSize) != null ? _options_batchSize : AI_SEO_AUDIT_BATCH_SIZE),
236
+ score: reports.length ? Math.round(reports.reduce((sum, report)=>sum + report.score, 0) / reports.length) : 100,
237
+ notes: []
238
+ };
239
+ }
240
+ /**
241
+ * The content fixes that need no model: every main heading after the first
242
+ * editable one becomes an `h2`, so the page keeps one.
243
+ */ export function aiSeoHeadingDemotions(facts) {
244
+ const editable = facts.h1s.filter((heading)=>heading.editable && heading.nodeId);
245
+ if (facts.h1s.length < 2 || !editable.length) return [];
246
+ const keep = editable[0].nodeId;
247
+ return editable.filter((heading)=>heading.nodeId !== keep).map((heading)=>({
248
+ kind: 'h1-demote',
249
+ nodeId: heading.nodeId
250
+ }));
251
+ }
252
+ /** The queue's batches, in order. */ export function aiSeoAuditBatches(report) {
253
+ const batches = [];
254
+ for(let start = 0; start < report.queue.length; start += report.batchSize){
255
+ batches.push(report.queue.slice(start, start + report.batchSize));
256
+ }
257
+ return batches;
258
+ }
259
+
260
+ //# sourceMappingURL=seo-audit.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../../../../libs/plugins/ai/src/lib/runtime/seo-audit.ts"],"sourcesContent":["/**\n * @license\n * Copyright 2026 Aglyn LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n SEO_LISTING_FIELDS,\n seoListingFieldTooLong,\n} from '@aglyn/aglyn/app-utils/seo-listing-fields'\nimport type {\n AiSeoAuditReport,\n AiSeoContentFix,\n AiSeoFinding,\n AiSeoFindingCode,\n AiSeoPageReport,\n AiSeoSeverity,\n} from '../model/ai-seo'\nimport { aiSeoKeywordCoverage, aiSeoKeywordList } from '../tools/ai-seo-tool'\nimport type { AiSeoPageFacts } from './seo-page-facts'\n\n/**\n * The site SEO audit's scoring (AGL-2910): every audited page held to what a\n * search result and a crawler need, with nothing asked of a model. Pure, so\n * the audit is proved against fixtures and a job only spends tokens on the\n * fixes it cannot make without writing.\n *\n * Per page: a title and a description of its own, within their lengths and\n * used on no other page; one main heading that says something; a description\n * on every image; a link from somewhere else on the site; and the target\n * keywords a person named, reported where the page already says them.\n * Per site: whether search engines are told to stay away, whether the\n * structured data names and describes the publisher, and whether agents get\n * guidance of the author's own.\n *\n * Keyword coverage is reported, never forced. A page that does not say a\n * keyword is told so; the fix a job proposes uses the keyword only where the\n * page is about it, and the listing check refuses a keyword used past its\n * per-field count.\n */\n\n/** Pages one audit covers. A larger site is audited on its first pages by path, and says how many it left. */\nexport const AI_SEO_AUDIT_MAX_PAGES = 150\n\n/** Pages one batch of fixes carries: one model call a batch. */\nexport const AI_SEO_AUDIT_BATCH_SIZE = 8\n\n/** What each severity takes off a page's score. */\nconst SEVERITY_WEIGHT: Record<AiSeoSeverity, number> = { high: 25, medium: 10, low: 3 }\n\n/** A main heading this short or this generic says nothing a searcher can use. */\nconst THIN_H1_MIN_CHARS = 10\nconst GENERIC_H1: ReadonlySet<string> = new Set([\n 'home',\n 'homepage',\n 'home page',\n 'welcome',\n 'hello',\n 'untitled',\n 'new page',\n 'page',\n 'title',\n 'heading',\n])\n\n/** The findings a batch of generated fixes answers. */\nconst GENERATED_FIX_CODES: ReadonlySet<AiSeoFindingCode> = new Set([\n 'title-missing',\n 'title-too-long',\n 'title-duplicate',\n 'description-missing',\n 'description-too-long',\n 'description-duplicate',\n 'h1-missing',\n 'h1-thin',\n 'image-alt-missing',\n 'keyword-missing',\n])\n\n/** One page as the audit reads it. */\nexport interface AiSeoAuditPage {\n screenId: string\n /** The public path, `/` for the home page. */\n path: string\n name: string\n versionId: string | null\n seo: {\n title?: string | null\n description?: string | null\n breadcrumb?: string | null\n image?: string | null\n imageAlt?: string | null\n }\n /** The screen's own description, which the head falls back to. */\n description?: string | null\n facts: AiSeoPageFacts\n /** Whether another audited page or a shared layout links here. */\n linkedFrom: boolean\n keywords: readonly string[]\n}\n\n/** The site as the audit reads it. */\nexport interface AiSeoAuditSite {\n discouraged: boolean\n entity: { name?: string | null; description?: string | null }\n agent: { whenToUse?: string | null }\n}\n\nconst blank = (value: string | null | undefined): boolean => !String(value ?? '').trim()\nconst normalized = (value: string | null | undefined): string =>\n String(value ?? '').replace(/\\s+/g, ' ').trim().toLowerCase()\n\n/** A path as the keyword lines and the routing map both spell it: leading slash, no trailing one. */\nexport function aiSeoNormalizePath(path: string): string {\n const trimmed = String(path ?? '').trim()\n if (!trimmed || trimmed === '/') return '/'\n return `/${trimmed.replace(/^\\/+/, '').replace(/\\/+$/, '')}`\n}\n\n/**\n * Target keywords per page, one line a page: `/pricing: plans, pricing`.\n * A line without a path, or with a path the site does not have, names no\n * page; the step reports the paths it could not match.\n */\nexport function parseAiSeoKeywordLines(raw: unknown): Record<string, string[]> {\n const out: Record<string, string[]> = {}\n for (const line of String(raw ?? '').split('\\n')) {\n const at = line.indexOf(':')\n if (at <= 0) continue\n const path = aiSeoNormalizePath(line.slice(0, at))\n const keywords = aiSeoKeywordList(line.slice(at + 1))\n if (keywords.length) out[path] = aiSeoKeywordList([...(out[path] ?? []), ...keywords])\n }\n return out\n}\n\nfunction finding(\n code: AiSeoFindingCode,\n severity: AiSeoSeverity,\n message: string,\n extra: Partial<Pick<AiSeoFinding, 'nodeIds' | 'screenIds' | 'keyword'>> = {},\n): AiSeoFinding {\n return { code, severity, message, ...extra }\n}\n\n/** The pages that share one value, by that value. */\nfunction sharedValues(\n pages: readonly AiSeoAuditPage[],\n read: (page: AiSeoAuditPage) => string | null | undefined,\n): Map<string, string[]> {\n const groups = new Map<string, string[]>()\n for (const page of pages) {\n const key = normalized(read(page))\n if (!key) continue\n groups.set(key, [...(groups.get(key) ?? []), page.screenId])\n }\n return new Map([...groups].filter(([, ids]) => ids.length > 1))\n}\n\nfunction pageFindings(\n page: AiSeoAuditPage,\n titles: Map<string, string[]>,\n descriptions: Map<string, string[]>,\n): AiSeoFinding[] {\n const out: AiSeoFinding[] = []\n const title = page.seo.title\n if (blank(title)) {\n out.push(finding('title-missing', 'medium', 'This page has no search title, so results show its name beside the site title.'))\n } else {\n if (seoListingFieldTooLong('title', title)) {\n out.push(finding('title-too-long', 'medium', `The search title is over ${SEO_LISTING_FIELDS.title.maxLength} characters and will be cut off in results.`))\n }\n const twins = titles.get(normalized(title))?.filter((id) => id !== page.screenId)\n if (twins?.length) {\n out.push(finding('title-duplicate', 'high', 'Another page uses the same search title, so results cannot tell them apart.', { screenIds: twins }))\n }\n }\n\n const description = page.seo.description\n if (blank(description) && blank(page.description)) {\n out.push(finding('description-missing', 'medium', 'This page has no search description, so results show the site’s.'))\n } else if (!blank(description)) {\n if (seoListingFieldTooLong('description', description)) {\n out.push(finding('description-too-long', 'low', `The search description is over ${SEO_LISTING_FIELDS.description.maxLength} characters and will be cut off.`))\n }\n const twins = descriptions.get(normalized(description))?.filter((id) => id !== page.screenId)\n if (twins?.length) {\n out.push(finding('description-duplicate', 'medium', 'Another page uses the same search description.', { screenIds: twins }))\n }\n }\n\n const { h1s } = page.facts\n if (!h1s.length) {\n out.push(finding('h1-missing', 'high', 'This page has no main heading.'))\n } else {\n if (h1s.length > 1) {\n out.push(\n finding('h1-multiple', 'medium', `This page has ${h1s.length} main headings; it should have one.`, {\n nodeIds: h1s.slice(1).map((heading) => heading.nodeId).filter((id): id is string => Boolean(id)),\n }),\n )\n }\n const first = h1s[0]\n if (first.text.length < THIN_H1_MIN_CHARS || GENERIC_H1.has(normalized(first.text))) {\n out.push(\n finding('h1-thin', 'medium', `The main heading “${first.text}” says little about the page.`, {\n nodeIds: first.nodeId ? [first.nodeId] : [],\n }),\n )\n }\n }\n\n const missingAlt = page.facts.imagesMissingAlt\n if (missingAlt.length) {\n out.push(\n finding(\n 'image-alt-missing',\n 'medium',\n `${missingAlt.length} ${missingAlt.length === 1 ? 'image has' : 'images have'} no description for readers who cannot see ${missingAlt.length === 1 ? 'it' : 'them'}.`,\n { nodeIds: missingAlt.map((image) => image.nodeId) },\n ),\n )\n }\n\n if (!page.linkedFrom && page.path !== '/') {\n out.push(finding('orphan', 'medium', 'No other page or shared layout links here, so visitors and crawlers may never find it.'))\n }\n\n const coverage = aiSeoKeywordCoverage(page.keywords, {\n title: page.seo.title,\n description: page.seo.description,\n h1: h1s[0]?.text,\n body: page.facts.text,\n })\n for (const entry of coverage) {\n if (!entry.inTitle && !entry.inDescription && !entry.inH1 && !entry.inBody) {\n out.push(\n finding('keyword-missing', 'low', `The page never says “${entry.keyword}”. Only use it if the page is about it.`, {\n keyword: entry.keyword,\n }),\n )\n }\n }\n return out\n}\n\nfunction scoreOf(findings: readonly AiSeoFinding[]): number {\n return Math.max(0, 100 - findings.reduce((sum, entry) => sum + SEVERITY_WEIGHT[entry.severity], 0))\n}\n\n/** Audit the pages and the site; nothing here reads, writes or generates. */\nexport function aiSeoAudit(\n pages: readonly AiSeoAuditPage[],\n site: AiSeoAuditSite,\n options: { skipped?: number; batchSize?: number } = {},\n): AiSeoAuditReport {\n const titles = sharedValues(pages, (page) => page.seo.title)\n const descriptions = sharedValues(pages, (page) => page.seo.description)\n const reports: AiSeoPageReport[] = pages.map((page) => {\n const findings = pageFindings(page, titles, descriptions)\n return {\n screenId: page.screenId,\n path: page.path,\n name: page.name,\n versionId: page.versionId,\n score: scoreOf(findings),\n findings,\n keywords: aiSeoKeywordCoverage(page.keywords, {\n title: page.seo.title,\n description: page.seo.description,\n h1: page.facts.h1s[0]?.text,\n body: page.facts.text,\n }),\n }\n })\n\n const siteFindings: AiSeoFinding[] = []\n if (site.discouraged) {\n siteFindings.push(finding('search-discouraged', 'high', 'Search engines are asked not to index this site, so none of its pages appear in results.'))\n }\n if (blank(site.entity.name) || blank(site.entity.description)) {\n siteFindings.push(finding('entity-incomplete', 'low', 'The structured data does not name and describe who publishes the site.'))\n }\n if (blank(site.agent.whenToUse)) {\n siteFindings.push(finding('llms-guidance-missing', 'low', '/llms.txt carries no guidance of your own for AI agents.'))\n }\n\n const queue = reports\n .filter((report) => report.findings.some((entry) => GENERATED_FIX_CODES.has(entry.code)))\n .sort((a, b) => a.score - b.score || (a.path < b.path ? -1 : a.path > b.path ? 1 : 0))\n .map((report) => report.screenId)\n\n return {\n kind: 'audit',\n pages: reports,\n skipped: Math.max(0, options.skipped ?? 0),\n site: siteFindings,\n siteProposal: siteFindings.some((entry) => entry.code === 'entity-incomplete' || entry.code === 'llms-guidance-missing'),\n queue,\n batchSize: Math.max(1, options.batchSize ?? AI_SEO_AUDIT_BATCH_SIZE),\n score: reports.length\n ? Math.round(reports.reduce((sum, report) => sum + report.score, 0) / reports.length)\n : 100,\n notes: [],\n }\n}\n\n/**\n * The content fixes that need no model: every main heading after the first\n * editable one becomes an `h2`, so the page keeps one.\n */\nexport function aiSeoHeadingDemotions(facts: AiSeoPageFacts): AiSeoContentFix[] {\n const editable = facts.h1s.filter((heading) => heading.editable && heading.nodeId)\n if (facts.h1s.length < 2 || !editable.length) return []\n const keep = editable[0].nodeId\n return editable\n .filter((heading) => heading.nodeId !== keep)\n .map((heading) => ({ kind: 'h1-demote', nodeId: heading.nodeId as string }))\n}\n\n/** The queue's batches, in order. */\nexport function aiSeoAuditBatches(report: Pick<AiSeoAuditReport, 'queue' | 'batchSize'>): string[][] {\n const batches: string[][] = []\n for (let start = 0; start < report.queue.length; start += report.batchSize) {\n batches.push(report.queue.slice(start, start + report.batchSize))\n }\n return batches\n}\n"],"names":["SEO_LISTING_FIELDS","seoListingFieldTooLong","aiSeoKeywordCoverage","aiSeoKeywordList","AI_SEO_AUDIT_MAX_PAGES","AI_SEO_AUDIT_BATCH_SIZE","SEVERITY_WEIGHT","high","medium","low","THIN_H1_MIN_CHARS","GENERIC_H1","Set","GENERATED_FIX_CODES","blank","value","String","trim","normalized","replace","toLowerCase","aiSeoNormalizePath","path","trimmed","parseAiSeoKeywordLines","raw","out","line","split","at","indexOf","slice","keywords","length","finding","code","severity","message","extra","sharedValues","pages","read","groups","Map","page","key","set","get","screenId","filter","ids","pageFindings","titles","descriptions","h1s","title","seo","push","maxLength","twins","id","screenIds","description","facts","nodeIds","map","heading","nodeId","Boolean","first","text","has","missingAlt","imagesMissingAlt","image","linkedFrom","coverage","h1","body","entry","inTitle","inDescription","inH1","inBody","keyword","scoreOf","findings","Math","max","reduce","sum","aiSeoAudit","site","options","reports","name","versionId","score","siteFindings","discouraged","entity","agent","whenToUse","queue","report","some","sort","a","b","kind","skipped","siteProposal","batchSize","round","notes","aiSeoHeadingDemotions","editable","keep","aiSeoAuditBatches","batches","start"],"mappings":"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"}
@@ -0,0 +1,41 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2026 Aglyn LLC
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */
17
+ import type { AiSeoContentFix } from '../model/ai-seo';
18
+ /**
19
+ * A site audit's content fixes, applied to a COPY of a page's node map
20
+ * (AGL-2910). The caller stores the result as a new unpublished version;
21
+ * nothing here reads or writes a document, and the map it is handed is
22
+ * never changed.
23
+ *
24
+ * Each fix is checked against the page as it is now, not as it was audited:
25
+ * an image that has gained a description keeps it, a heading that has gone
26
+ * is skipped, and every skip is named. A heading's new text and a new
27
+ * heading pass the AI node-tree validator — the one path an AI-emitted node
28
+ * takes into storage — before they touch the copy.
29
+ */
30
+ export interface AiSeoContentFixResult {
31
+ nodes: Record<string, Record<string, unknown>>;
32
+ /** Fixes that changed the copy. */
33
+ applied: AiSeoContentFix[];
34
+ /** Fixes that did not, each with the customer-safe reason. */
35
+ skipped: Array<{
36
+ fix: AiSeoContentFix;
37
+ reason: string;
38
+ }>;
39
+ }
40
+ /** Apply `fixes` to a copy of `nodes`, whose content region starts at `contentRootId`. */
41
+ export declare function applyAiSeoContentFixes(nodes: Record<string, unknown>, fixes: readonly AiSeoContentFix[], contentRootId: string | null): AiSeoContentFixResult;
@@ -0,0 +1,168 @@
1
+ import { _ as _extends } from "@swc/helpers/_/_extends";
2
+ /**
3
+ * @license
4
+ * Copyright 2026 Aglyn LLC
5
+ *
6
+ * Licensed under the Apache License, Version 2.0 (the "License");
7
+ * you may not use this file except in compliance with the License.
8
+ * You may obtain a copy of the License at
9
+ *
10
+ * http://www.apache.org/licenses/LICENSE-2.0
11
+ *
12
+ * Unless required by applicable law or agreed to in writing, software
13
+ * distributed under the License is distributed on an "AS IS" BASIS,
14
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ * See the License for the specific language governing permissions and
16
+ * limitations under the License.
17
+ */ import { MEDIA_ALT_MAX_LENGTH } from "@aglyn/aglyn/app-utils/media-alt";
18
+ import { CANVAS_ROOT_ELEMENT_ID } from "@aglyn/aglyn/foundation/constants/canvas";
19
+ import { validateAiNodeTree } from "./ai-node-tree.js";
20
+ import { AI_TEXT_LIMITS } from "./ai-palette.js";
21
+ const isRecord = (value)=>typeof value === 'object' && value !== null && !Array.isArray(value);
22
+ const TEXT_COMPONENTS = new Set([
23
+ 'muiTypography',
24
+ 'muiInlineText',
25
+ 'muiListItemText'
26
+ ]);
27
+ /**
28
+ * A heading as the validator would store it: the text held to a headline's
29
+ * length and the element to the palette. `null` when the validator refuses
30
+ * it — the text is not something a generated heading may say.
31
+ */ function validatedHeading(level, text) {
32
+ var _ref, _ref1;
33
+ var _root_nodes;
34
+ const result = validateAiNodeTree({
35
+ rootId: CANVAS_ROOT_ELEMENT_ID,
36
+ nodes: {
37
+ [CANVAS_ROOT_ELEMENT_ID]: {
38
+ $id: CANVAS_ROOT_ELEMENT_ID,
39
+ componentId: 'div',
40
+ parentId: null,
41
+ nodes: [
42
+ 'heading'
43
+ ]
44
+ },
45
+ heading: {
46
+ $id: 'heading',
47
+ componentId: 'muiTypography',
48
+ parentId: CANVAS_ROOT_ELEMENT_ID,
49
+ props: {
50
+ variant: `h${level}`,
51
+ children: text.slice(0, AI_TEXT_LIMITS.headline)
52
+ },
53
+ nodes: []
54
+ }
55
+ }
56
+ }, 'screen');
57
+ if (!result.ok) return null;
58
+ const root = result.nodes[result.rootId];
59
+ const node = result.nodes[(_ref = (_root_nodes = root.nodes) == null ? void 0 : _root_nodes[0]) != null ? _ref : ''];
60
+ const props = (_ref1 = node == null ? void 0 : node['props']) != null ? _ref1 : {};
61
+ const children = typeof props['children'] === 'string' ? props['children'].trim() : '';
62
+ return children && node ? {
63
+ text: children,
64
+ node
65
+ } : null;
66
+ }
67
+ const cloneNodes = (nodes)=>JSON.parse(JSON.stringify(nodes));
68
+ /** Apply `fixes` to a copy of `nodes`, whose content region starts at `contentRootId`. */ export function applyAiSeoContentFixes(nodes, fixes, contentRootId) {
69
+ const copy = cloneNodes(nodes);
70
+ const applied = [];
71
+ const skipped = [];
72
+ const skip = (fix, reason)=>skipped.push({
73
+ fix,
74
+ reason
75
+ });
76
+ for (const fix of fixes){
77
+ switch(fix.kind){
78
+ case 'image-alt':
79
+ {
80
+ var _props_alt;
81
+ const node = copy[fix.nodeId];
82
+ if (!node || node['componentId'] !== 'image') {
83
+ skip(fix, 'The image is no longer on the page.');
84
+ break;
85
+ }
86
+ const props = isRecord(node.props) ? node.props : {};
87
+ if (String((_props_alt = props['alt']) != null ? _props_alt : '').trim()) {
88
+ skip(fix, 'The image has been given a description since the audit.');
89
+ break;
90
+ }
91
+ const alt = fix.alt.replace(/\s+/g, ' ').trim().slice(0, MEDIA_ALT_MAX_LENGTH);
92
+ if (!alt) {
93
+ skip(fix, 'The proposed description was empty.');
94
+ break;
95
+ }
96
+ node.props = _extends({}, props, {
97
+ alt
98
+ });
99
+ applied.push(fix);
100
+ break;
101
+ }
102
+ case 'h1-set':
103
+ case 'h1-demote':
104
+ {
105
+ const node = copy[fix.nodeId];
106
+ const props = node && isRecord(node.props) ? node.props : null;
107
+ if (!node || !props || !TEXT_COMPONENTS.has(String(node['componentId']))) {
108
+ skip(fix, 'The heading is no longer on the page.');
109
+ break;
110
+ }
111
+ if (typeof props['html'] === 'string' && props['html'].trim()) {
112
+ skip(fix, 'The heading is rich text, which a fix does not rewrite.');
113
+ break;
114
+ }
115
+ if (fix.kind === 'h1-demote') {
116
+ node.props = _extends({}, props, {
117
+ component: 'h2'
118
+ });
119
+ applied.push(fix);
120
+ break;
121
+ }
122
+ const heading = validatedHeading(1, fix.text);
123
+ if (!heading) {
124
+ skip(fix, 'The proposed heading could not be used.');
125
+ break;
126
+ }
127
+ node.props = _extends({}, props, {
128
+ component: 'h1',
129
+ children: heading.text
130
+ });
131
+ applied.push(fix);
132
+ break;
133
+ }
134
+ case 'h1-insert':
135
+ {
136
+ const parent = contentRootId ? copy[contentRootId] : undefined;
137
+ if (!parent || !contentRootId) {
138
+ skip(fix, 'The page has no content region to add a heading to.');
139
+ break;
140
+ }
141
+ const heading = validatedHeading(1, fix.text);
142
+ if (!heading) {
143
+ skip(fix, 'The proposed heading could not be used.');
144
+ break;
145
+ }
146
+ const id = String(heading.node['$id']);
147
+ copy[id] = _extends({}, heading.node, {
148
+ parentId: contentRootId,
149
+ nodes: []
150
+ });
151
+ const children = Array.isArray(parent.nodes) ? parent.nodes : [];
152
+ parent.nodes = [
153
+ id,
154
+ ...children
155
+ ];
156
+ applied.push(fix);
157
+ break;
158
+ }
159
+ }
160
+ }
161
+ return {
162
+ nodes: copy,
163
+ applied,
164
+ skipped
165
+ };
166
+ }
167
+
168
+ //# sourceMappingURL=seo-content-fixes.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../../../../libs/plugins/ai/src/lib/runtime/seo-content-fixes.ts"],"sourcesContent":["/**\n * @license\n * Copyright 2026 Aglyn LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { MEDIA_ALT_MAX_LENGTH } from '@aglyn/aglyn/app-utils/media-alt'\nimport { CANVAS_ROOT_ELEMENT_ID } from '@aglyn/aglyn/foundation/constants/canvas'\nimport type { AiSeoContentFix } from '../model/ai-seo'\nimport { validateAiNodeTree } from './ai-node-tree'\nimport { AI_TEXT_LIMITS } from './ai-palette'\n\n/**\n * A site audit's content fixes, applied to a COPY of a page's node map\n * (AGL-2910). The caller stores the result as a new unpublished version;\n * nothing here reads or writes a document, and the map it is handed is\n * never changed.\n *\n * Each fix is checked against the page as it is now, not as it was audited:\n * an image that has gained a description keeps it, a heading that has gone\n * is skipped, and every skip is named. A heading's new text and a new\n * heading pass the AI node-tree validator — the one path an AI-emitted node\n * takes into storage — before they touch the copy.\n */\n\nexport interface AiSeoContentFixResult {\n nodes: Record<string, Record<string, unknown>>\n /** Fixes that changed the copy. */\n applied: AiSeoContentFix[]\n /** Fixes that did not, each with the customer-safe reason. */\n skipped: Array<{ fix: AiSeoContentFix; reason: string }>\n}\n\ntype StoredNode = Record<string, unknown> & { props?: Record<string, unknown>; nodes?: unknown }\n\nconst isRecord = (value: unknown): value is Record<string, unknown> =>\n typeof value === 'object' && value !== null && !Array.isArray(value)\n\nconst TEXT_COMPONENTS: ReadonlySet<string> = new Set(['muiTypography', 'muiInlineText', 'muiListItemText'])\n\n/**\n * A heading as the validator would store it: the text held to a headline's\n * length and the element to the palette. `null` when the validator refuses\n * it — the text is not something a generated heading may say.\n */\nfunction validatedHeading(level: 1 | 2, text: string): { text: string; node: Record<string, unknown> } | null {\n const result = validateAiNodeTree(\n {\n rootId: CANVAS_ROOT_ELEMENT_ID,\n nodes: {\n [CANVAS_ROOT_ELEMENT_ID]: {\n $id: CANVAS_ROOT_ELEMENT_ID,\n componentId: 'div',\n parentId: null,\n nodes: ['heading'],\n },\n heading: {\n $id: 'heading',\n componentId: 'muiTypography',\n parentId: CANVAS_ROOT_ELEMENT_ID,\n props: { variant: `h${level}`, children: text.slice(0, AI_TEXT_LIMITS.headline) },\n nodes: [],\n },\n },\n },\n 'screen',\n )\n if (!result.ok) return null\n const root = result.nodes[result.rootId] as { nodes?: string[] }\n const node = result.nodes[root.nodes?.[0] ?? ''] as Record<string, unknown> | undefined\n const props = (node?.['props'] ?? {}) as Record<string, unknown>\n const children = typeof props['children'] === 'string' ? props['children'].trim() : ''\n return children && node ? { text: children, node } : null\n}\n\nconst cloneNodes = (nodes: Record<string, unknown>): Record<string, StoredNode> =>\n JSON.parse(JSON.stringify(nodes)) as Record<string, StoredNode>\n\n/** Apply `fixes` to a copy of `nodes`, whose content region starts at `contentRootId`. */\nexport function applyAiSeoContentFixes(\n nodes: Record<string, unknown>,\n fixes: readonly AiSeoContentFix[],\n contentRootId: string | null,\n): AiSeoContentFixResult {\n const copy = cloneNodes(nodes)\n const applied: AiSeoContentFix[] = []\n const skipped: AiSeoContentFixResult['skipped'] = []\n const skip = (fix: AiSeoContentFix, reason: string) => skipped.push({ fix, reason })\n\n for (const fix of fixes) {\n switch (fix.kind) {\n case 'image-alt': {\n const node = copy[fix.nodeId]\n if (!node || node['componentId'] !== 'image') {\n skip(fix, 'The image is no longer on the page.')\n break\n }\n const props = isRecord(node.props) ? node.props : {}\n if (String(props['alt'] ?? '').trim()) {\n skip(fix, 'The image has been given a description since the audit.')\n break\n }\n const alt = fix.alt.replace(/\\s+/g, ' ').trim().slice(0, MEDIA_ALT_MAX_LENGTH)\n if (!alt) {\n skip(fix, 'The proposed description was empty.')\n break\n }\n node.props = { ...props, alt }\n applied.push(fix)\n break\n }\n case 'h1-set':\n case 'h1-demote': {\n const node = copy[fix.nodeId]\n const props = node && isRecord(node.props) ? node.props : null\n if (!node || !props || !TEXT_COMPONENTS.has(String(node['componentId']))) {\n skip(fix, 'The heading is no longer on the page.')\n break\n }\n if (typeof props['html'] === 'string' && props['html'].trim()) {\n skip(fix, 'The heading is rich text, which a fix does not rewrite.')\n break\n }\n if (fix.kind === 'h1-demote') {\n node.props = { ...props, component: 'h2' }\n applied.push(fix)\n break\n }\n const heading = validatedHeading(1, fix.text)\n if (!heading) {\n skip(fix, 'The proposed heading could not be used.')\n break\n }\n node.props = { ...props, component: 'h1', children: heading.text }\n applied.push(fix)\n break\n }\n case 'h1-insert': {\n const parent = contentRootId ? copy[contentRootId] : undefined\n if (!parent || !contentRootId) {\n skip(fix, 'The page has no content region to add a heading to.')\n break\n }\n const heading = validatedHeading(1, fix.text)\n if (!heading) {\n skip(fix, 'The proposed heading could not be used.')\n break\n }\n const id = String(heading.node['$id'])\n copy[id] = { ...heading.node, parentId: contentRootId, nodes: [] }\n const children = Array.isArray(parent.nodes) ? (parent.nodes as unknown[]) : []\n parent.nodes = [id, ...children]\n applied.push(fix)\n break\n }\n }\n }\n return { nodes: copy, applied, skipped }\n}\n"],"names":["MEDIA_ALT_MAX_LENGTH","CANVAS_ROOT_ELEMENT_ID","validateAiNodeTree","AI_TEXT_LIMITS","isRecord","value","Array","isArray","TEXT_COMPONENTS","Set","validatedHeading","level","text","root","result","rootId","nodes","$id","componentId","parentId","heading","props","variant","children","slice","headline","ok","node","trim","cloneNodes","JSON","parse","stringify","applyAiSeoContentFixes","fixes","contentRootId","copy","applied","skipped","skip","fix","reason","push","kind","nodeId","String","alt","replace","has","component","parent","undefined","id"],"mappings":"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"}