@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,246 @@
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
+ */ import { pluginRequestFromWeb } from "@aglyn/aglyn/server";
17
+ import { emailUnverifiedResponse, firebaseAdmin, isImpersonationSession } from "@aglyn/tenant-data-admin";
18
+ import { recordAdminAudit } from "@aglyn/tenant-data-admin/server/admin-audit";
19
+ import { invalidIdTokenResponse } from "@aglyn/tenant-data-admin/server/id-token-refusal";
20
+ import { assistUsageMonth } from "../usage/assist-usage.js";
21
+ import { AI_BILLING_STANDING_DOC, AI_BILLING_SUBCOLLECTION, AI_OVERAGE_CHARGES_SUBCOLLECTION, readAiOverageMonthLedger } from "../billing/ai-overage-ledger.js";
22
+ import { AI_OVERAGE_CEILING_LADDER_USD, AI_OVERAGE_STAFF_CEILING_MAX_USD, AI_OVERAGE_STAFF_CEILING_MIN_USD, AI_OVERAGE_THRESHOLD_USD, AI_OVERAGE_UNPAID_LIMIT_USD, aiOverageCardOnFile, aiOverageEffectiveCeilingUsd, aiOverageStandingCeilingUsd, aiOverageStep, readAiOverageStanding } from "../billing/ai-overage-standing.js";
23
+ import { resetAiOverageStep, resumeAiOverage, setAiOverageStaffOverride } from "../billing/ai-overage-standing-writes.js";
24
+ import { aiOverageBillsByInvoice } from "../billing/ai-overage-cutover.js";
25
+ /**
26
+ * STAFF'S CONTROLS OVER ONE WORKSPACE'S OVERAGE STANDING (AGL-3011).
27
+ *
28
+ * The ladder rises on payment history and a dispute takes it back to the
29
+ * bottom. Both are rules, and a rule that nobody can override is a rule that
30
+ * strands the customer it gets wrong: an enterprise-shaped workspace on its
31
+ * first month, a dispute that turns out to be fraud on the cardholder rather
32
+ * than by them, a failed charge whose cause was ours.
33
+ *
34
+ * So four acts, staff-only, every one of them audited:
35
+ *
36
+ * `get` the standing in full, with the month's charges
37
+ * `setCeiling` a ceiling that outranks the ladder, with a reason and an
38
+ * optional expiry
39
+ * `liftPause` resume accrual, with a reason — the ONLY way a dispute
40
+ * pause comes off
41
+ * `resetStep` put the workspace back at the bottom of the ladder
42
+ *
43
+ * A reason is required on every act that changes something, because the
44
+ * question a month later is never "what was the ceiling" — the document says
45
+ * that — but "why did someone raise it".
46
+ *
47
+ * The emergency stop is not here and does not change: Lockdown, scoped to
48
+ * the organization, which stops AI along with everything else.
49
+ */ /** How many of the month's charge rows the card lists. */ const CHARGES_LISTED = 20;
50
+ /** The longest a staff reason may be, so a paste cannot fill the document. */ const REASON_MAX = 500;
51
+ function badRequest(error, code) {
52
+ return Response.json({
53
+ error,
54
+ code
55
+ }, {
56
+ status: 400
57
+ });
58
+ }
59
+ async function handler(request) {
60
+ var _headers_authorization, _ref, _ref1;
61
+ const { method, body, headers: rawHeaders } = await pluginRequestFromWeb(request);
62
+ const headers = rawHeaders;
63
+ if (method !== 'POST') {
64
+ return Response.json({
65
+ error: 'Method not allowed'
66
+ }, {
67
+ status: 405
68
+ });
69
+ }
70
+ const authorization = (_headers_authorization = headers.authorization) != null ? _headers_authorization : '';
71
+ const idToken = authorization.startsWith('Bearer ') ? authorization.slice('Bearer '.length) : undefined;
72
+ if (!idToken) return Response.json({
73
+ error: 'Unauthenticated'
74
+ }, {
75
+ status: 401
76
+ });
77
+ const orgId = String((_ref = body == null ? void 0 : body.orgId) != null ? _ref : '');
78
+ const action = String((_ref1 = body == null ? void 0 : body.action) != null ? _ref1 : '');
79
+ const actions = [
80
+ 'get',
81
+ 'setCeiling',
82
+ 'liftPause',
83
+ 'resetStep'
84
+ ];
85
+ if (!orgId || !actions.includes(action)) {
86
+ return Response.json({
87
+ error: 'Bad request'
88
+ }, {
89
+ status: 400
90
+ });
91
+ }
92
+ try {
93
+ var _orgSnapshot_data, _ref2, _standingSnapshot_data, _usageSnapshot_data, _standing_paymentMethodType, _aiOverageCardOnFile;
94
+ const decoded = await firebaseAdmin.app().auth().verifyIdToken(idToken);
95
+ if (!decoded.email_verified && !isImpersonationSession(decoded)) {
96
+ return emailUnverifiedResponse();
97
+ }
98
+ // The staff claim, the same test `ai/admin/org` makes. Not a permission
99
+ // on the workspace: these controls are Aglyn's side of the relationship,
100
+ // and a workspace admin raising their own ceiling is the thing the
101
+ // ladder exists to prevent.
102
+ if (!decoded['staff']) {
103
+ return Response.json({
104
+ error: 'Staff only'
105
+ }, {
106
+ status: 403
107
+ });
108
+ }
109
+ const now = new Date();
110
+ const month = assistUsageMonth(now);
111
+ const db = firebaseAdmin.app().firestore();
112
+ const orgRef = db.collection('orgs').doc(orgId);
113
+ const orgSnapshot = await orgRef.get();
114
+ if (!orgSnapshot.exists) {
115
+ return Response.json({
116
+ error: 'No such organization'
117
+ }, {
118
+ status: 404
119
+ });
120
+ }
121
+ const org = (_orgSnapshot_data = orgSnapshot.data()) != null ? _orgSnapshot_data : {};
122
+ const reason = String((_ref2 = body == null ? void 0 : body.reason) != null ? _ref2 : '').trim().slice(0, REASON_MAX);
123
+ if (action === 'setCeiling') {
124
+ const clearing = (body == null ? void 0 : body.ceilingUsd) === null;
125
+ const ceilingUsd = Number(body == null ? void 0 : body.ceilingUsd);
126
+ if (!reason) {
127
+ return badRequest('Say why the ceiling is being changed', 'reason_required');
128
+ }
129
+ if (!clearing && (!Number.isFinite(ceilingUsd) || ceilingUsd < AI_OVERAGE_STAFF_CEILING_MIN_USD || ceilingUsd > AI_OVERAGE_STAFF_CEILING_MAX_USD)) {
130
+ return badRequest(`Set a ceiling between $${AI_OVERAGE_STAFF_CEILING_MIN_USD} and ` + `$${AI_OVERAGE_STAFF_CEILING_MAX_USD.toLocaleString('en-US')}, or clear it.`, 'invalid_ceiling');
131
+ }
132
+ // An expiry that does not parse is refused rather than dropped: a
133
+ // ceiling meant to last a week and stored with no end is the failure
134
+ // this field exists to avoid.
135
+ const rawExpiry = body == null ? void 0 : body.expiresAt;
136
+ const expiresAt = rawExpiry === null || rawExpiry === undefined ? null : String(rawExpiry);
137
+ if (expiresAt !== null && !Number.isFinite(Date.parse(expiresAt))) {
138
+ return badRequest('The expiry is not a date', 'invalid_expiry');
139
+ }
140
+ await setAiOverageStaffOverride(db, orgId, clearing ? null : {
141
+ ceilingUsd,
142
+ reason,
143
+ setBy: decoded.uid,
144
+ expiresAt
145
+ }, now);
146
+ await recordAdminAudit({
147
+ actorUid: decoded.uid,
148
+ action: clearing ? 'ai.overage.clearCeiling' : 'ai.overage.setCeiling',
149
+ target: `orgs/${orgId}/${AI_BILLING_SUBCOLLECTION}/${AI_BILLING_STANDING_DOC}`,
150
+ note: clearing ? reason : `${reason} — ceiling $${ceilingUsd}${expiresAt ? `, until ${expiresAt}` : ''}`
151
+ });
152
+ }
153
+ if (action === 'liftPause') {
154
+ if (!reason) {
155
+ return badRequest('Say why the pause is being lifted', 'reason_required');
156
+ }
157
+ // `force`, because staff lifting a pause is the one path a DISPUTE
158
+ // pause has out. Every other pause lifts on its own when the payment
159
+ // that set it succeeds.
160
+ await resumeAiOverage(db, orgId, {
161
+ force: true
162
+ });
163
+ await recordAdminAudit({
164
+ actorUid: decoded.uid,
165
+ action: 'ai.overage.liftPause',
166
+ target: `orgs/${orgId}/${AI_BILLING_SUBCOLLECTION}/${AI_BILLING_STANDING_DOC}`,
167
+ note: reason
168
+ });
169
+ }
170
+ if (action === 'resetStep') {
171
+ if (!reason) {
172
+ return badRequest('Say why the step is being reset', 'reason_required');
173
+ }
174
+ await resetAiOverageStep(db, orgId);
175
+ await recordAdminAudit({
176
+ actorUid: decoded.uid,
177
+ action: 'ai.overage.resetStep',
178
+ target: `orgs/${orgId}/${AI_BILLING_SUBCOLLECTION}/${AI_BILLING_STANDING_DOC}`,
179
+ note: reason
180
+ });
181
+ }
182
+ // Read AFTER any write, so the answer is the state the act produced
183
+ // rather than the state it found — a staff card that showed the old
184
+ // ceiling after raising it would be read as the raise having failed.
185
+ const [standingSnapshot, usageSnapshot, chargesSnapshot] = await Promise.all([
186
+ orgRef.collection(AI_BILLING_SUBCOLLECTION).doc(AI_BILLING_STANDING_DOC).get(),
187
+ orgRef.collection('assistUsage').doc(month).get(),
188
+ orgRef.collection(AI_OVERAGE_CHARGES_SUBCOLLECTION).where('month', '==', month).limit(CHARGES_LISTED).get()
189
+ ]);
190
+ const standing = readAiOverageStanding(standingSnapshot.exists ? (_standingSnapshot_data = standingSnapshot.data()) != null ? _standingSnapshot_data : null : null);
191
+ const ledger = readAiOverageMonthLedger(usageSnapshot.exists ? (_usageSnapshot_data = usageSnapshot.data()) != null ? _usageSnapshot_data : null : null);
192
+ return Response.json({
193
+ month,
194
+ // Whether any of this is live yet. Staff looking at a standing that
195
+ // nothing consults should be told so rather than left to infer it
196
+ // from a ceiling that never refuses.
197
+ billsByInvoice: aiOverageBillsByInvoice(month),
198
+ standing: {
199
+ paymentMethodType: (_standing_paymentMethodType = standing.paymentMethodType) != null ? _standing_paymentMethodType : null,
200
+ cardOnFile: (_aiOverageCardOnFile = aiOverageCardOnFile(standing)) != null ? _aiOverageCardOnFile : null,
201
+ firstPaidMonth: standing.firstPaidMonth,
202
+ qualifyingMonths: standing.qualifyingMonths,
203
+ step: aiOverageStep(standing),
204
+ staffOverride: standing.staffOverride,
205
+ pause: standing.pause,
206
+ lastDisputeAt: standing.lastDisputeAt
207
+ },
208
+ ceiling: {
209
+ ladderUsd: [
210
+ ...AI_OVERAGE_CEILING_LADDER_USD
211
+ ],
212
+ standingUsd: aiOverageStandingCeilingUsd(standing, now),
213
+ effectiveUsd: aiOverageEffectiveCeilingUsd(org, standing, now),
214
+ thresholdUsd: AI_OVERAGE_THRESHOLD_USD,
215
+ unpaidLimitUsd: AI_OVERAGE_UNPAID_LIMIT_USD
216
+ },
217
+ ledger,
218
+ charges: chargesSnapshot.docs.map((doc)=>{
219
+ var _doc_get, _doc_get1, _doc_get2, _doc_get3, _doc_get4;
220
+ return {
221
+ chargeId: doc.id,
222
+ kind: (_doc_get = doc.get('kind')) != null ? _doc_get : null,
223
+ amountUsd: Number((_doc_get1 = doc.get('amountUsd')) != null ? _doc_get1 : 0),
224
+ credits: Number((_doc_get2 = doc.get('credits')) != null ? _doc_get2 : 0),
225
+ invoiceId: (_doc_get3 = doc.get('invoiceId')) != null ? _doc_get3 : null,
226
+ status: (_doc_get4 = doc.get('status')) != null ? _doc_get4 : null
227
+ };
228
+ })
229
+ }, {
230
+ status: 200
231
+ });
232
+ } catch (error) {
233
+ const unauthenticated = invalidIdTokenResponse(error);
234
+ if (unauthenticated) return unauthenticated;
235
+ console.error(error);
236
+ return Response.json({
237
+ error: 'AI overage standing failed'
238
+ }, {
239
+ status: 500
240
+ });
241
+ }
242
+ }
243
+ export const dynamic = 'force-dynamic';
244
+ export { handler as POST };
245
+
246
+ //# sourceMappingURL=ai-admin-overage.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../../../../libs/plugins/ai/src/lib/server/ai-admin-overage.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 { pluginRequestFromWeb } from '@aglyn/aglyn/server'\nimport {\n emailUnverifiedResponse,\n firebaseAdmin,\n isImpersonationSession,\n} from '@aglyn/tenant-data-admin'\nimport { recordAdminAudit } from '@aglyn/tenant-data-admin/server/admin-audit'\nimport { invalidIdTokenResponse } from '@aglyn/tenant-data-admin/server/id-token-refusal'\nimport { assistUsageMonth } from '../usage/assist-usage'\nimport {\n AI_BILLING_STANDING_DOC,\n AI_BILLING_SUBCOLLECTION,\n AI_OVERAGE_CHARGES_SUBCOLLECTION,\n readAiOverageMonthLedger,\n} from '../billing/ai-overage-ledger'\nimport {\n AI_OVERAGE_CEILING_LADDER_USD,\n AI_OVERAGE_STAFF_CEILING_MAX_USD,\n AI_OVERAGE_STAFF_CEILING_MIN_USD,\n AI_OVERAGE_THRESHOLD_USD,\n AI_OVERAGE_UNPAID_LIMIT_USD,\n aiOverageCardOnFile,\n aiOverageEffectiveCeilingUsd,\n aiOverageStandingCeilingUsd,\n aiOverageStep,\n readAiOverageStanding,\n} from '../billing/ai-overage-standing'\nimport {\n resetAiOverageStep,\n resumeAiOverage,\n setAiOverageStaffOverride,\n} from '../billing/ai-overage-standing-writes'\nimport { aiOverageBillsByInvoice } from '../billing/ai-overage-cutover'\n\n/**\n * STAFF'S CONTROLS OVER ONE WORKSPACE'S OVERAGE STANDING (AGL-3011).\n *\n * The ladder rises on payment history and a dispute takes it back to the\n * bottom. Both are rules, and a rule that nobody can override is a rule that\n * strands the customer it gets wrong: an enterprise-shaped workspace on its\n * first month, a dispute that turns out to be fraud on the cardholder rather\n * than by them, a failed charge whose cause was ours.\n *\n * So four acts, staff-only, every one of them audited:\n *\n * `get` the standing in full, with the month's charges\n * `setCeiling` a ceiling that outranks the ladder, with a reason and an\n * optional expiry\n * `liftPause` resume accrual, with a reason — the ONLY way a dispute\n * pause comes off\n * `resetStep` put the workspace back at the bottom of the ladder\n *\n * A reason is required on every act that changes something, because the\n * question a month later is never \"what was the ceiling\" — the document says\n * that — but \"why did someone raise it\".\n *\n * The emergency stop is not here and does not change: Lockdown, scoped to\n * the organization, which stops AI along with everything else.\n */\n\n/** How many of the month's charge rows the card lists. */\nconst CHARGES_LISTED = 20\n\n/** The longest a staff reason may be, so a paste cannot fill the document. */\nconst REASON_MAX = 500\n\nfunction badRequest(error: string, code: string): Response {\n return Response.json({ error, code }, { status: 400 })\n}\n\nasync function handler(request: Request): Promise<Response> {\n const { method, body, headers: rawHeaders } = await pluginRequestFromWeb(request)\n const headers = rawHeaders as Partial<Record<string, string>>\n if (method !== 'POST') {\n return Response.json({ error: 'Method not allowed' }, { status: 405 })\n }\n const authorization = headers.authorization ?? ''\n const idToken = authorization.startsWith('Bearer ')\n ? authorization.slice('Bearer '.length)\n : undefined\n if (!idToken) return Response.json({ error: 'Unauthenticated' }, { status: 401 })\n const orgId = String(body?.orgId ?? '')\n const action = String(body?.action ?? '')\n const actions = ['get', 'setCeiling', 'liftPause', 'resetStep']\n if (!orgId || !actions.includes(action)) {\n return Response.json({ error: 'Bad request' }, { status: 400 })\n }\n\n try {\n const decoded = await firebaseAdmin.app().auth().verifyIdToken(idToken)\n if (!decoded.email_verified && !isImpersonationSession(decoded)) {\n return emailUnverifiedResponse()\n }\n // The staff claim, the same test `ai/admin/org` makes. Not a permission\n // on the workspace: these controls are Aglyn's side of the relationship,\n // and a workspace admin raising their own ceiling is the thing the\n // ladder exists to prevent.\n if (!decoded['staff']) {\n return Response.json({ error: 'Staff only' }, { status: 403 })\n }\n\n const now = new Date()\n const month = assistUsageMonth(now)\n const db = firebaseAdmin.app().firestore()\n const orgRef = db.collection('orgs').doc(orgId)\n const orgSnapshot = await orgRef.get()\n if (!orgSnapshot.exists) {\n return Response.json({ error: 'No such organization' }, { status: 404 })\n }\n const org = (orgSnapshot.data() ?? {}) as Record<string, unknown>\n const reason = String(body?.reason ?? '').trim().slice(0, REASON_MAX)\n\n if (action === 'setCeiling') {\n const clearing = body?.ceilingUsd === null\n const ceilingUsd = Number(body?.ceilingUsd)\n if (!reason) {\n return badRequest('Say why the ceiling is being changed', 'reason_required')\n }\n if (\n !clearing &&\n (!Number.isFinite(ceilingUsd) ||\n ceilingUsd < AI_OVERAGE_STAFF_CEILING_MIN_USD ||\n ceilingUsd > AI_OVERAGE_STAFF_CEILING_MAX_USD)\n ) {\n return badRequest(\n `Set a ceiling between $${AI_OVERAGE_STAFF_CEILING_MIN_USD} and ` +\n `$${AI_OVERAGE_STAFF_CEILING_MAX_USD.toLocaleString('en-US')}, or clear it.`,\n 'invalid_ceiling',\n )\n }\n // An expiry that does not parse is refused rather than dropped: a\n // ceiling meant to last a week and stored with no end is the failure\n // this field exists to avoid.\n const rawExpiry = body?.expiresAt\n const expiresAt =\n rawExpiry === null || rawExpiry === undefined ? null : String(rawExpiry)\n if (expiresAt !== null && !Number.isFinite(Date.parse(expiresAt))) {\n return badRequest('The expiry is not a date', 'invalid_expiry')\n }\n await setAiOverageStaffOverride(\n db,\n orgId,\n clearing\n ? null\n : { ceilingUsd, reason, setBy: decoded.uid, expiresAt },\n now,\n )\n await recordAdminAudit({\n actorUid: decoded.uid,\n action: clearing\n ? 'ai.overage.clearCeiling'\n : 'ai.overage.setCeiling',\n target: `orgs/${orgId}/${AI_BILLING_SUBCOLLECTION}/${AI_BILLING_STANDING_DOC}`,\n note: clearing\n ? reason\n : `${reason} — ceiling $${ceilingUsd}${expiresAt ? `, until ${expiresAt}` : ''}`,\n })\n }\n\n if (action === 'liftPause') {\n if (!reason) {\n return badRequest('Say why the pause is being lifted', 'reason_required')\n }\n // `force`, because staff lifting a pause is the one path a DISPUTE\n // pause has out. Every other pause lifts on its own when the payment\n // that set it succeeds.\n await resumeAiOverage(db, orgId, { force: true })\n await recordAdminAudit({\n actorUid: decoded.uid,\n action: 'ai.overage.liftPause',\n target: `orgs/${orgId}/${AI_BILLING_SUBCOLLECTION}/${AI_BILLING_STANDING_DOC}`,\n note: reason,\n })\n }\n\n if (action === 'resetStep') {\n if (!reason) {\n return badRequest('Say why the step is being reset', 'reason_required')\n }\n await resetAiOverageStep(db, orgId)\n await recordAdminAudit({\n actorUid: decoded.uid,\n action: 'ai.overage.resetStep',\n target: `orgs/${orgId}/${AI_BILLING_SUBCOLLECTION}/${AI_BILLING_STANDING_DOC}`,\n note: reason,\n })\n }\n\n // Read AFTER any write, so the answer is the state the act produced\n // rather than the state it found — a staff card that showed the old\n // ceiling after raising it would be read as the raise having failed.\n const [standingSnapshot, usageSnapshot, chargesSnapshot] = await Promise.all([\n orgRef.collection(AI_BILLING_SUBCOLLECTION).doc(AI_BILLING_STANDING_DOC).get(),\n orgRef.collection('assistUsage').doc(month).get(),\n orgRef\n .collection(AI_OVERAGE_CHARGES_SUBCOLLECTION)\n .where('month', '==', month)\n .limit(CHARGES_LISTED)\n .get(),\n ])\n const standing = readAiOverageStanding(\n standingSnapshot.exists ? (standingSnapshot.data() ?? null) : null,\n )\n const ledger = readAiOverageMonthLedger(\n usageSnapshot.exists ? (usageSnapshot.data() ?? null) : null,\n )\n return Response.json(\n {\n month,\n // Whether any of this is live yet. Staff looking at a standing that\n // nothing consults should be told so rather than left to infer it\n // from a ceiling that never refuses.\n billsByInvoice: aiOverageBillsByInvoice(month),\n standing: {\n paymentMethodType: standing.paymentMethodType ?? null,\n cardOnFile: aiOverageCardOnFile(standing) ?? null,\n firstPaidMonth: standing.firstPaidMonth,\n qualifyingMonths: standing.qualifyingMonths,\n step: aiOverageStep(standing),\n staffOverride: standing.staffOverride,\n pause: standing.pause,\n lastDisputeAt: standing.lastDisputeAt,\n },\n ceiling: {\n ladderUsd: [...AI_OVERAGE_CEILING_LADDER_USD],\n standingUsd: aiOverageStandingCeilingUsd(standing, now),\n effectiveUsd: aiOverageEffectiveCeilingUsd(org as never, standing, now),\n thresholdUsd: AI_OVERAGE_THRESHOLD_USD,\n unpaidLimitUsd: AI_OVERAGE_UNPAID_LIMIT_USD,\n },\n ledger,\n charges: chargesSnapshot.docs.map((doc) => ({\n chargeId: doc.id,\n kind: doc.get('kind') ?? null,\n amountUsd: Number(doc.get('amountUsd') ?? 0),\n credits: Number(doc.get('credits') ?? 0),\n invoiceId: doc.get('invoiceId') ?? null,\n status: doc.get('status') ?? null,\n })),\n },\n { status: 200 },\n )\n } catch (error) {\n const unauthenticated = invalidIdTokenResponse(error)\n if (unauthenticated) return unauthenticated\n console.error(error)\n return Response.json({ error: 'AI overage standing failed' }, { status: 500 })\n }\n}\n\nexport const dynamic = 'force-dynamic'\nexport { handler as POST }\n"],"names":["pluginRequestFromWeb","emailUnverifiedResponse","firebaseAdmin","isImpersonationSession","recordAdminAudit","invalidIdTokenResponse","assistUsageMonth","AI_BILLING_STANDING_DOC","AI_BILLING_SUBCOLLECTION","AI_OVERAGE_CHARGES_SUBCOLLECTION","readAiOverageMonthLedger","AI_OVERAGE_CEILING_LADDER_USD","AI_OVERAGE_STAFF_CEILING_MAX_USD","AI_OVERAGE_STAFF_CEILING_MIN_USD","AI_OVERAGE_THRESHOLD_USD","AI_OVERAGE_UNPAID_LIMIT_USD","aiOverageCardOnFile","aiOverageEffectiveCeilingUsd","aiOverageStandingCeilingUsd","aiOverageStep","readAiOverageStanding","resetAiOverageStep","resumeAiOverage","setAiOverageStaffOverride","aiOverageBillsByInvoice","CHARGES_LISTED","REASON_MAX","badRequest","error","code","Response","json","status","handler","request","headers","method","body","rawHeaders","authorization","idToken","startsWith","slice","length","undefined","orgId","String","action","actions","includes","orgSnapshot","standingSnapshot","usageSnapshot","standing","decoded","app","auth","verifyIdToken","email_verified","now","Date","month","db","firestore","orgRef","collection","doc","get","exists","org","data","reason","trim","clearing","ceilingUsd","Number","isFinite","toLocaleString","rawExpiry","expiresAt","parse","setBy","uid","actorUid","target","note","force","chargesSnapshot","Promise","all","where","limit","ledger","billsByInvoice","paymentMethodType","cardOnFile","firstPaidMonth","qualifyingMonths","step","staffOverride","pause","lastDisputeAt","ceiling","ladderUsd","standingUsd","effectiveUsd","thresholdUsd","unpaidLimitUsd","charges","docs","map","chargeId","id","kind","amountUsd","credits","invoiceId","unauthenticated","console","dynamic","POST"],"mappings":"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"}
@@ -0,0 +1,34 @@
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 AssistSpendRow } from '../usage/assist-signal-mining';
18
+ export interface AssistSpendLeaderboard {
19
+ month: string;
20
+ rows: AssistSpendRow[];
21
+ /** How many workspaces had a document for the month — the ranked count. */
22
+ ranked: number;
23
+ /** True when the scan hit its ceiling, so the ranking is over a sample. */
24
+ truncated: boolean;
25
+ /**
26
+ * True when the month documents could not be read at all. Reported rather
27
+ * than rendered as an empty table: "no workspace spent anything" and "the
28
+ * read failed" are opposite findings, and the rest of the board — read
29
+ * from a different collection — is still good.
30
+ */
31
+ failed: boolean;
32
+ }
33
+ declare function handler(request: Request): Promise<Response>;
34
+ export { handler as GET };
@@ -0,0 +1,330 @@
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 { ORG_BILLING_DOC_ID, ORG_BILLING_SUBCOLLECTION, pluginRequestFromWeb } from "@aglyn/aglyn/server";
18
+ import { emailUnverifiedResponse, firebaseAdmin, isImpersonationSession } from "@aglyn/tenant-data-admin";
19
+ import { ASSIST_PROVIDER_COST_FIELD, assistCreditsFromUsd, assistProviderCostUsd } from "@aglyn/aglyn/app-utils/assist-credits";
20
+ import { hasAiAddon, resolveEffectivePlan } from "@aglyn/aglyn/app-utils/plan-entitlements";
21
+ import { readPlatformFreeSpend } from "../usage/assist-free-taste.js";
22
+ import { assistRefusalCounts } from "../usage/assist-refusals.js";
23
+ import { assistUsageDay, assistUsageMonth } from "../usage/assist-usage.js";
24
+ import { invalidIdTokenResponse } from "@aglyn/tenant-data-admin/server/id-token-refusal";
25
+ import { assistSignalRow, mineAssistSignals, rankAssistSpend } from "../usage/assist-signal-mining.js";
26
+ /**
27
+ * The Assist docs-gap and cost mining view (AGL-1860, AGL-2252), served at
28
+ * `/api/ai/admin/signals` for the plugin's Assist signal staff page.
29
+ * Staff-gated, read-only, and the only reader `assistSignals` has.
30
+ *
31
+ * ## Why a route and not a client query
32
+ *
33
+ * `assistSignals` is absent from `firebase-firestore.rules` deliberately: the
34
+ * org block matches its subcollections BY NAME and carries no wildcard, so an
35
+ * unlisted name is default-deny for every client. That is the property that
36
+ * lets the collection hold cross-tenant analytics at all. Reading it therefore
37
+ * goes through the Admin SDK behind the staff claim, exactly as every staff
38
+ * route does.
39
+ *
40
+ * ## The collection group, and the index it does not need
41
+ *
42
+ * One `collectionGroup('assistSignals')` read gathers every org's signals in a
43
+ * single query; the owning org is `ref.parent.parent.id`, since the document
44
+ * carries no `orgId` field (it carries no identifiers at all — see AGL-1972).
45
+ * The query has no `where` and no `orderBy`, so it needs no composite index,
46
+ * and adding one later would mean declaring a `COLLECTION_GROUP`-scoped
47
+ * override and deploying it by hand. `/api/admin/overview` reads org billing
48
+ * the same way and for the same reason.
49
+ *
50
+ * ## Truncation is reported, never hidden
51
+ *
52
+ * The read is bounded — an unbounded fleet-wide get is how a staff page
53
+ * becomes an outage — but a ranking cut short looks exactly like a complete
54
+ * one, so the ceiling is fetched PLUS ONE and the extra row sets `truncated`.
55
+ * AGL-2220 is the standing example of the alternative: a sweep that stopped at
56
+ * 500 orgs and reported nothing about the rest, for as long as nobody counted.
57
+ */ /**
58
+ * Rows read in one pass. Each signal is a handful of scalars, so this is a
59
+ * few megabytes at the ceiling — large enough to be worth ranking, small
60
+ * enough that the honest answer to "is it all of them" is usually yes.
61
+ */ const SCAN_CEILING = 20000;
62
+ /**
63
+ * How much of an answer the prose panel shows.
64
+ *
65
+ * Enough to judge whether the answer was wrong, short enough that twenty-five
66
+ * of them are still a page somebody reads.
67
+ */ const ANSWER_PREVIEW_CHARS = 600;
68
+ /**
69
+ * Month documents read in one pass for the spend leaderboard (AGL-2930).
70
+ *
71
+ * `assistUsage` holds one document per org per month, so this is orgs times
72
+ * months — a fraction of the signal count, and the same PLUS-ONE truncation
73
+ * probe the signals read uses. Read as a collection group with NO `where`
74
+ * and NO `orderBy`, for the reason the module note gives: a filter on
75
+ * `month` would need a COLLECTION_GROUP-scoped index deployed by hand, and
76
+ * filtering the month in memory costs nothing at this size.
77
+ */ const SPEND_SCAN_CEILING = 20000;
78
+ /**
79
+ * The month's per-org spend, refusals and plan, dearest first.
80
+ *
81
+ * Plan and add-on come from the org and billing documents of the ranked
82
+ * rows only — bounded by `limit`, never by the fleet — merged org-doc-first
83
+ * exactly as every other staff reader merges them.
84
+ */ async function readAssistSpendLeaderboard(firestore, limit, month) {
85
+ try {
86
+ return await rankAssistSpendForMonth(firestore, limit, month);
87
+ } catch (error) {
88
+ console.error('[ai/admin/signals] spend leaderboard read failed', error);
89
+ return {
90
+ month,
91
+ rows: [],
92
+ ranked: 0,
93
+ truncated: false,
94
+ failed: true
95
+ };
96
+ }
97
+ }
98
+ async function rankAssistSpendForMonth(firestore, limit, month) {
99
+ const snapshot = await firestore.collectionGroup('assistUsage').limit(SPEND_SCAN_CEILING + 1).get();
100
+ const truncated = snapshot.size > SPEND_SCAN_CEILING;
101
+ const docs = truncated ? snapshot.docs.slice(0, SPEND_SCAN_CEILING) : snapshot.docs;
102
+ const unranked = [];
103
+ for (const doc of docs){
104
+ var _doc_get;
105
+ var _doc_ref_parent_parent;
106
+ // The id IS the month; the field is the same value and is what an
107
+ // older document may lack.
108
+ if (doc.id !== month && doc.get('month') !== month) continue;
109
+ const orgId = (_doc_ref_parent_parent = doc.ref.parent.parent) == null ? void 0 : _doc_ref_parent_parent.id;
110
+ if (!orgId) continue;
111
+ // Two figures off one document (AGL-3015): the credits a workspace drew
112
+ // come from what it was BILLED, and the dollars staff rank workspaces by
113
+ // come from what it COST US. Ranking on the billed figure would sort the
114
+ // fleet by our own markup wherever workspaces differ in model mix.
115
+ const billed = Number((_doc_get = doc.get('estCostUsd')) != null ? _doc_get : 0);
116
+ const billedUsd = Number.isFinite(billed) && billed > 0 ? billed : 0;
117
+ unranked.push({
118
+ orgId,
119
+ plan: 'free',
120
+ aiAddon: false,
121
+ credits: assistCreditsFromUsd(billedUsd),
122
+ providerCostUsd: assistProviderCostUsd(billedUsd, doc.get(ASSIST_PROVIDER_COST_FIELD)),
123
+ refusals: assistRefusalCounts(doc.get('refusals'))
124
+ });
125
+ }
126
+ const { rows, ranked } = rankAssistSpend(unranked, limit);
127
+ if (rows.length) {
128
+ const orgRefs = rows.map((row)=>firestore.collection('orgs').doc(row.orgId));
129
+ const [orgSnaps, billingSnaps] = await Promise.all([
130
+ firestore.getAll(...orgRefs),
131
+ firestore.getAll(...orgRefs.map((ref)=>ref.collection(ORG_BILLING_SUBCOLLECTION).doc(ORG_BILLING_DOC_ID)))
132
+ ]);
133
+ rows.forEach((row, index)=>{
134
+ var _orgSnaps_index_data, _ref, _orgData_name;
135
+ var _orgSnaps_index, _billingSnaps_index;
136
+ const orgData = ((_orgSnaps_index = orgSnaps[index]) == null ? void 0 : _orgSnaps_index.exists) ? (_orgSnaps_index_data = orgSnaps[index].data()) != null ? _orgSnaps_index_data : {} : {};
137
+ const org = _extends({}, orgData, ((_billingSnaps_index = billingSnaps[index]) == null ? void 0 : _billingSnaps_index.exists) ? billingSnaps[index].data() : {});
138
+ row.plan = resolveEffectivePlan(org);
139
+ row.aiAddon = hasAiAddon(org);
140
+ const label = (_ref = (_orgData_name = orgData['name']) != null ? _orgData_name : orgData['slug']) != null ? _ref : '';
141
+ row.orgLabel = label || null;
142
+ });
143
+ }
144
+ return {
145
+ month,
146
+ rows,
147
+ ranked,
148
+ truncated,
149
+ failed: false
150
+ };
151
+ }
152
+ async function handler(request) {
153
+ var _headers_authorization;
154
+ const { method, query, headers: rawHeaders } = await pluginRequestFromWeb(request);
155
+ const headers = rawHeaders;
156
+ if (method !== 'GET') {
157
+ return Response.json({
158
+ error: 'Method not allowed'
159
+ }, {
160
+ status: 405
161
+ });
162
+ }
163
+ const authorization = (_headers_authorization = headers.authorization) != null ? _headers_authorization : '';
164
+ const idToken = authorization.startsWith('Bearer ') ? authorization.slice('Bearer '.length) : undefined;
165
+ if (!idToken) return Response.json({
166
+ error: 'Unauthenticated'
167
+ }, {
168
+ status: 401
169
+ });
170
+ try {
171
+ var _query_limit;
172
+ const decoded = await firebaseAdmin.app().auth().verifyIdToken(idToken);
173
+ if (!decoded.email_verified && !isImpersonationSession(decoded)) {
174
+ return emailUnverifiedResponse();
175
+ }
176
+ if (!decoded['staff']) {
177
+ return Response.json({
178
+ error: 'Staff only'
179
+ }, {
180
+ status: 403
181
+ });
182
+ }
183
+ const requested = Number((_query_limit = query.limit) != null ? _query_limit : 25);
184
+ const limit = Number.isFinite(requested) && requested > 0 ? Math.min(Math.floor(requested), 100) : 25;
185
+ const snapshot = await firebaseAdmin.app().firestore().collectionGroup('assistSignals')// Ceiling PLUS ONE: the extra document is what makes truncation
186
+ // detectable rather than assumed.
187
+ .limit(SCAN_CEILING + 1).get();
188
+ const truncated = snapshot.size > SCAN_CEILING;
189
+ const docs = truncated ? snapshot.docs.slice(0, SCAN_CEILING) : snapshot.docs;
190
+ const rows = docs.map((doc)=>{
191
+ var _ref;
192
+ var _doc_ref_parent_parent;
193
+ return assistSignalRow((_ref = (_doc_ref_parent_parent = doc.ref.parent.parent) == null ? void 0 : _doc_ref_parent_parent.id) != null ? _ref : '(unknown)', // The signal id IS the exchange id (AGL-2314) — one id, two halves,
194
+ // minted together by `recordAssistExchange` precisely so the join is
195
+ // possible. Until now nothing carried it this far.
196
+ doc.id, doc.data());
197
+ });
198
+ const report = mineAssistSignals(rows, {
199
+ truncated,
200
+ limit
201
+ });
202
+ // This month's spend, per workspace (AGL-2930) — the board's only
203
+ // month-scoped panel, read off the month documents rather than mined
204
+ // from the all-time signals above.
205
+ const spend = await readAssistSpendLeaderboard(firebaseAdmin.app().firestore(), limit, assistUsageMonth());
206
+ /*==========================================
207
+ * THE VERBATIM HALF (AGL-2314).
208
+ *
209
+ * `assistExchanges` stores the question a customer typed and the answer
210
+ * we gave, for 180 days, and `assist-usage.ts` calls it "the data loop's
211
+ * corpus". NOTHING read it — one write, no reader, no collection group.
212
+ * So we retained customers' words, and committed publicly in the privacy
213
+ * policy to retaining them, for zero product value.
214
+ *
215
+ * Read here rather than in the miner because the miner is pure: it does
216
+ * the arithmetic, the route does the reading.
217
+ *
218
+ * ## Only the turns that FAILED
219
+ *
220
+ * The shortlist is thumbs-down and ungrounded turns only, capped by the
221
+ * same `limit` as every other panel. That is a privacy decision as much
222
+ * as a cost one: the counts already answer "how often", and the words are
223
+ * fetched only where the counts CANNOT say what went wrong. Pulling every
224
+ * exchange would be surveillance with a dashboard on it.
225
+ *
226
+ * `uid` is deliberately not projected. The corpus question is what people
227
+ * asked, never who asked it — and the exchange is the only document that
228
+ * still carries an identifier at all.
229
+ *
230
+ * ## An expired exchange is an ANSWER
231
+ *
232
+ * The 180-day TTL means a signal can outlive its prose, and it is meant
233
+ * to. A missing document therefore reports `expired: true` rather than
234
+ * being dropped: a shortlist silently shorter than the failure count it
235
+ * came from would read as "these are all the failures", which is the
236
+ * AGL-2220 shape.
237
+ *=========================================*/ const firestore = firebaseAdmin.app().firestore();
238
+ const exchanges = report.proseCandidates.length ? await firestore.getAll(...report.proseCandidates.map((candidate)=>firestore.collection('orgs').doc(candidate.orgId).collection('assistExchanges').doc(candidate.exchangeId))) : [];
239
+ const prose = report.proseCandidates.map((candidate, index)=>{
240
+ var _ref;
241
+ const snapshot = exchanges[index];
242
+ const data = (_ref = (snapshot == null ? void 0 : snapshot.exists) ? snapshot.data() : null) != null ? _ref : {};
243
+ return _extends({}, candidate, {
244
+ expired: !(snapshot == null ? void 0 : snapshot.exists),
245
+ question: typeof data['question'] === 'string' ? data['question'] : null,
246
+ // Trimmed, not omitted: judging whether an answer was wrong needs to
247
+ // see it, and a whole answer per row would make the panel unreadable.
248
+ answer: typeof data['answer'] === 'string' ? data['answer'].slice(0, ANSWER_PREVIEW_CHARS) : null,
249
+ answerTruncated: typeof data['answer'] === 'string' && data['answer'].length > ANSWER_PREVIEW_CHARS
250
+ });
251
+ });
252
+ /*==========================================
253
+ * THE WORKSPACE, BY NAME.
254
+ *
255
+ * A staff reader recognizes a customer by name, never by document id,
256
+ * and the cost board's own column header says "Workspace" over a column
257
+ * of generated ids. `/api/admin/overview` fixed the same shape by
258
+ * building a label map from a snapshot it already held; there is no such
259
+ * snapshot here — this route reads `assistSignals` and nothing else — so
260
+ * the labels are fetched, with the same `name` → `slug` → id precedence
261
+ * so one workspace cannot appear under two different labels on two
262
+ * screens.
263
+ *
264
+ * Bounded by what is actually RENDERED, not by the fleet. Both lists the
265
+ * ids come from are already sliced to `limit` (25 by default, 100 at the
266
+ * ceiling), so this is one `getAll` over at most a couple of hundred
267
+ * documents — and it reads the orgs the reader can see rather than
268
+ * scanning a collection to name a handful of rows.
269
+ *
270
+ * An org that has been deleted keeps its id rather than going blank: an
271
+ * unfamiliar id is still a lead a staff member can paste into the org
272
+ * search, and an empty cell is not.
273
+ *=========================================*/ const orgIds = [
274
+ ...new Set([
275
+ ...report.orgs.map((row)=>row.orgId),
276
+ ...report.proseCandidates.map((row)=>row.orgId)
277
+ ].filter((orgId)=>orgId && orgId !== '(unknown)'))
278
+ ];
279
+ const orgLabelById = new Map();
280
+ if (orgIds.length) {
281
+ const orgDocs = await firestore.getAll(...orgIds.map((orgId)=>firestore.collection('orgs').doc(orgId)));
282
+ for (const doc of orgDocs){
283
+ var _doc_data, _ref, _data_name;
284
+ if (!doc.exists) continue;
285
+ const data = (_doc_data = doc.data()) != null ? _doc_data : {};
286
+ const label = (_ref = (_data_name = data['name']) != null ? _data_name : data['slug']) != null ? _ref : '';
287
+ if (label) orgLabelById.set(doc.id, label);
288
+ }
289
+ }
290
+ const orgLabel = (orgId)=>{
291
+ var _orgLabelById_get;
292
+ return (_orgLabelById_get = orgLabelById.get(orgId)) != null ? _orgLabelById_get : orgId;
293
+ };
294
+ // Today's free-tier spend against the platform ceiling (AGL-2925): one
295
+ // document read, and the only place staff can see the taste switching
296
+ // itself off before the email arrives. Best-effort — a readout that
297
+ // cannot be read must not take the rest of the board down with it.
298
+ const freeSpend = await readPlatformFreeSpend(firestore, assistUsageDay()).catch((error)=>{
299
+ console.error('[ai/admin/signals] free spend readout failed', error);
300
+ return undefined;
301
+ });
302
+ return Response.json(_extends({}, report, {
303
+ freeSpend,
304
+ orgs: report.orgs.map((row)=>_extends({}, row, {
305
+ orgLabel: orgLabel(row.orgId)
306
+ })),
307
+ prose: prose.map((row)=>_extends({}, row, {
308
+ orgLabel: orgLabel(row.orgId)
309
+ })),
310
+ spend,
311
+ ceiling: SCAN_CEILING
312
+ }), {
313
+ status: 200
314
+ });
315
+ } catch (error) {
316
+ // An unverifiable credential is a 401, not a fault of ours
317
+ // (AGL-1993). Null for anything else, so a real failure keeps its 500.
318
+ const unauthenticated = invalidIdTokenResponse(error);
319
+ if (unauthenticated) return unauthenticated;
320
+ console.error('[ai/admin/signals]', error);
321
+ return Response.json({
322
+ error: 'Assist signal lookup failed'
323
+ }, {
324
+ status: 500
325
+ });
326
+ }
327
+ }
328
+ export { handler as GET };
329
+
330
+ //# sourceMappingURL=ai-admin-signals.js.map