@aglyn/plugins-ai 1.0.0-beta.292 → 1.0.0-beta.296

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 (203) hide show
  1. package/package.json +17 -17
  2. package/src/lib/components/ai-job-links.d.ts +15 -2
  3. package/src/lib/components/ai-job-links.js +24 -3
  4. package/src/lib/components/ai-job-links.js.map +1 -1
  5. package/src/lib/components/ai-job-requests.d.ts +9 -0
  6. package/src/lib/components/ai-job-requests.js +34 -0
  7. package/src/lib/components/ai-job-requests.js.map +1 -1
  8. package/src/lib/components/ai-site-build-page.component.js +28 -2
  9. package/src/lib/components/ai-site-build-page.component.js.map +1 -1
  10. package/src/lib/components/ai-site-import-job.component.js +5 -4
  11. package/src/lib/components/ai-site-import-job.component.js.map +1 -1
  12. package/src/lib/components/ai-site-import-start.component.js +3 -3
  13. package/src/lib/components/ai-site-import-start.component.js.map +1 -1
  14. package/src/lib/components/ai-site-start-card.component.d.ts +1 -1
  15. package/src/lib/components/ai-site-start-card.component.js +129 -29
  16. package/src/lib/components/ai-site-start-card.component.js.map +1 -1
  17. package/src/lib/components/ai-site-start-steps.component.d.ts +15 -3
  18. package/src/lib/components/ai-site-start-steps.component.js +42 -25
  19. package/src/lib/components/ai-site-start-steps.component.js.map +1 -1
  20. package/src/lib/components/ai-site-style-previews.d.ts +17 -0
  21. package/src/lib/components/ai-site-style-previews.js +26 -95
  22. package/src/lib/components/ai-site-style-previews.js.map +1 -1
  23. package/src/lib/components/assist-jobs-drawer.component.d.ts +7 -1
  24. package/src/lib/components/assist-jobs-drawer.component.js +20 -6
  25. package/src/lib/components/assist-jobs-drawer.component.js.map +1 -1
  26. package/src/lib/components/assist-page-change-card.component.d.ts +44 -0
  27. package/src/lib/components/assist-page-change-card.component.js +166 -0
  28. package/src/lib/components/assist-page-change-card.component.js.map +1 -0
  29. package/src/lib/components/assist-panel.component.d.ts +105 -1
  30. package/src/lib/components/assist-panel.component.js +224 -29
  31. package/src/lib/components/assist-panel.component.js.map +1 -1
  32. package/src/lib/declarations.server.js +22 -0
  33. package/src/lib/declarations.server.js.map +1 -1
  34. package/src/lib/jobs/ai-job-edit-step.d.ts +62 -16
  35. package/src/lib/jobs/ai-job-edit-step.js +172 -61
  36. package/src/lib/jobs/ai-job-edit-step.js.map +1 -1
  37. package/src/lib/jobs/ai-job-import-step.d.ts +21 -2
  38. package/src/lib/jobs/ai-job-import-step.js +179 -49
  39. package/src/lib/jobs/ai-job-import-step.js.map +1 -1
  40. package/src/lib/jobs/ai-job-layout-language.d.ts +27 -3
  41. package/src/lib/jobs/ai-job-layout-language.js +156 -113
  42. package/src/lib/jobs/ai-job-layout-language.js.map +1 -1
  43. package/src/lib/jobs/ai-job-layout-step.js +56 -17
  44. package/src/lib/jobs/ai-job-layout-step.js.map +1 -1
  45. package/src/lib/jobs/ai-job-navigation-step.js +4 -2
  46. package/src/lib/jobs/ai-job-navigation-step.js.map +1 -1
  47. package/src/lib/jobs/ai-job-page-language.d.ts +25 -15
  48. package/src/lib/jobs/ai-job-page-language.js +120 -66
  49. package/src/lib/jobs/ai-job-page-language.js.map +1 -1
  50. package/src/lib/jobs/ai-job-page-step.js +27 -7
  51. package/src/lib/jobs/ai-job-page-step.js.map +1 -1
  52. package/src/lib/jobs/ai-job-site-datasets.d.ts +12 -4
  53. package/src/lib/jobs/ai-job-site-datasets.js +36 -16
  54. package/src/lib/jobs/ai-job-site-datasets.js.map +1 -1
  55. package/src/lib/jobs/ai-jobs.js +6 -2
  56. package/src/lib/jobs/ai-jobs.js.map +1 -1
  57. package/src/lib/jobs/ai-layout-stock-photos.d.ts +50 -1
  58. package/src/lib/jobs/ai-layout-stock-photos.js +586 -35
  59. package/src/lib/jobs/ai-layout-stock-photos.js.map +1 -1
  60. package/src/lib/jobs/ai-site-import-compile.d.ts +147 -0
  61. package/src/lib/jobs/ai-site-import-compile.js +1143 -0
  62. package/src/lib/jobs/ai-site-import-compile.js.map +1 -0
  63. package/src/lib/jobs/ai-site-import-document.d.ts +9 -36
  64. package/src/lib/jobs/ai-site-import-document.js +23 -489
  65. package/src/lib/jobs/ai-site-import-document.js.map +1 -1
  66. package/src/lib/jobs/ai-site-import-look.d.ts +54 -7
  67. package/src/lib/jobs/ai-site-import-look.js +163 -52
  68. package/src/lib/jobs/ai-site-import-look.js.map +1 -1
  69. package/src/lib/jobs/ai-site-import-publish.d.ts +7 -1
  70. package/src/lib/jobs/ai-site-import-publish.js +19 -5
  71. package/src/lib/jobs/ai-site-import-publish.js.map +1 -1
  72. package/src/lib/jobs/ai-site-late-photos.js +4 -2
  73. package/src/lib/jobs/ai-site-late-photos.js.map +1 -1
  74. package/src/lib/jobs/ai-site-publish.d.ts +10 -1
  75. package/src/lib/jobs/ai-site-publish.js +8 -3
  76. package/src/lib/jobs/ai-site-publish.js.map +1 -1
  77. package/src/lib/jobs/fixtures/ai-stock-photo-agl4092-1029-recordings.d.ts +23 -0
  78. package/src/lib/jobs/fixtures/ai-stock-photo-agl4092-1029-recordings.js +677 -0
  79. package/src/lib/jobs/fixtures/ai-stock-photo-agl4092-1029-recordings.js.map +1 -0
  80. package/src/lib/layout-language/ai-layout-compiler.d.ts +26 -0
  81. package/src/lib/layout-language/ai-layout-compiler.js +677 -33
  82. package/src/lib/layout-language/ai-layout-compiler.js.map +1 -1
  83. package/src/lib/layout-language/ai-layout-frame-hollows.js +5 -1
  84. package/src/lib/layout-language/ai-layout-frame-hollows.js.map +1 -1
  85. package/src/lib/layout-language/ai-layout-frame-source.d.ts +196 -0
  86. package/src/lib/layout-language/ai-layout-frame-source.js +726 -0
  87. package/src/lib/layout-language/ai-layout-frame-source.js.map +1 -0
  88. package/src/lib/layout-language/ai-layout-frame.d.ts +22 -0
  89. package/src/lib/layout-language/ai-layout-frame.js +121 -29
  90. package/src/lib/layout-language/ai-layout-frame.js.map +1 -1
  91. package/src/lib/layout-language/ai-layout-language.d.ts +103 -37
  92. package/src/lib/layout-language/ai-layout-language.js +85 -120
  93. package/src/lib/layout-language/ai-layout-language.js.map +1 -1
  94. package/src/lib/model/ai-credit-estimate.d.ts +11 -7
  95. package/src/lib/model/ai-credit-estimate.js +11 -7
  96. package/src/lib/model/ai-credit-estimate.js.map +1 -1
  97. package/src/lib/model/ai-edit-job.d.ts +33 -16
  98. package/src/lib/model/ai-edit-job.js +50 -34
  99. package/src/lib/model/ai-edit-job.js.map +1 -1
  100. package/src/lib/model/ai-job-activity.d.ts +6 -11
  101. package/src/lib/model/ai-job-activity.js +8 -15
  102. package/src/lib/model/ai-job-activity.js.map +1 -1
  103. package/src/lib/model/ai-jobs.types.d.ts +6 -0
  104. package/src/lib/model/ai-jobs.types.js.map +1 -1
  105. package/src/lib/model/ai-site-import.d.ts +307 -13
  106. package/src/lib/model/ai-site-import.js +227 -19
  107. package/src/lib/model/ai-site-import.js.map +1 -1
  108. package/src/lib/model/ai-site-inventory.d.ts +6 -0
  109. package/src/lib/model/ai-site-inventory.js.map +1 -1
  110. package/src/lib/model/ai-site-look.d.ts +65 -1
  111. package/src/lib/model/ai-site-look.js +141 -23
  112. package/src/lib/model/ai-site-look.js.map +1 -1
  113. package/src/lib/model/ai-site-photos.d.ts +2 -0
  114. package/src/lib/model/ai-site-photos.js.map +1 -1
  115. package/src/lib/model/ai-site-start-steps.d.ts +4 -3
  116. package/src/lib/model/ai-site-start-steps.js +11 -3
  117. package/src/lib/model/ai-site-start-steps.js.map +1 -1
  118. package/src/lib/model/ai-site-start.d.ts +23 -2
  119. package/src/lib/model/ai-site-start.js +25 -3
  120. package/src/lib/model/ai-site-start.js.map +1 -1
  121. package/src/lib/model/assist-edit.d.ts +18 -1
  122. package/src/lib/model/assist-edit.js +7 -0
  123. package/src/lib/model/assist-edit.js.map +1 -1
  124. package/src/lib/model/assist-page-change.d.ts +86 -0
  125. package/src/lib/model/assist-page-change.js +86 -0
  126. package/src/lib/model/assist-page-change.js.map +1 -0
  127. package/src/lib/providers/routing.d.ts +11 -0
  128. package/src/lib/providers/routing.js +23 -0
  129. package/src/lib/providers/routing.js.map +1 -1
  130. package/src/lib/runtime/ai-doctrine-validators.d.ts +4 -2
  131. package/src/lib/runtime/ai-doctrine-validators.js +7 -2
  132. package/src/lib/runtime/ai-doctrine-validators.js.map +1 -1
  133. package/src/lib/runtime/ai-eval.js +3 -1
  134. package/src/lib/runtime/ai-eval.js.map +1 -1
  135. package/src/lib/runtime/ai-icon-library.d.ts +4 -0
  136. package/src/lib/runtime/ai-icon-library.js +4 -0
  137. package/src/lib/runtime/ai-icon-library.js.map +1 -1
  138. package/src/lib/runtime/ai-node-tree.d.ts +5 -0
  139. package/src/lib/runtime/ai-node-tree.js +23 -4
  140. package/src/lib/runtime/ai-node-tree.js.map +1 -1
  141. package/src/lib/runtime/ai-palette.d.ts +2 -0
  142. package/src/lib/runtime/ai-palette.generated.js +19 -3
  143. package/src/lib/runtime/ai-palette.generated.js.map +1 -1
  144. package/src/lib/runtime/ai-palette.js +2 -1
  145. package/src/lib/runtime/ai-palette.js.map +1 -1
  146. package/src/lib/runtime/site-inventory.d.ts +8 -1
  147. package/src/lib/runtime/site-inventory.js +18 -0
  148. package/src/lib/runtime/site-inventory.js.map +1 -1
  149. package/src/lib/server/assist-build.js +2 -0
  150. package/src/lib/server/assist-build.js.map +1 -1
  151. package/src/lib/server/assist-chat.js +51 -2
  152. package/src/lib/server/assist-chat.js.map +1 -1
  153. package/src/lib/server/assist-edit.d.ts +54 -2
  154. package/src/lib/server/assist-edit.js +219 -30
  155. package/src/lib/server/assist-edit.js.map +1 -1
  156. package/src/lib/server/assist-page-change.d.ts +62 -0
  157. package/src/lib/server/assist-page-change.js +140 -0
  158. package/src/lib/server/assist-page-change.js.map +1 -0
  159. package/src/lib/site-import/fixtures/site-layout-recordings.d.ts +50 -0
  160. package/src/lib/site-import/fixtures/site-layout-recordings.js +86 -0
  161. package/src/lib/site-import/fixtures/site-layout-recordings.js.map +1 -0
  162. package/src/lib/site-import/site-import-crawl.d.ts +18 -1
  163. package/src/lib/site-import/site-import-crawl.js +70 -10
  164. package/src/lib/site-import/site-import-crawl.js.map +1 -1
  165. package/src/lib/site-import/site-import-css.d.ts +110 -0
  166. package/src/lib/site-import/site-import-css.js +826 -0
  167. package/src/lib/site-import/site-import-css.js.map +1 -0
  168. package/src/lib/site-import/site-import-html.d.ts +116 -1
  169. package/src/lib/site-import/site-import-html.js +538 -46
  170. package/src/lib/site-import/site-import-html.js.map +1 -1
  171. package/src/lib/site-import/site-import-layout.d.ts +79 -0
  172. package/src/lib/site-import/site-import-layout.js +1608 -0
  173. package/src/lib/site-import/site-import-layout.js.map +1 -0
  174. package/src/lib/site-import/site-import-nav.d.ts +40 -0
  175. package/src/lib/site-import/site-import-nav.js +437 -0
  176. package/src/lib/site-import/site-import-nav.js.map +1 -0
  177. package/src/lib/site-import/site-import-page.d.ts +8 -1
  178. package/src/lib/site-import/site-import-page.js +24 -2
  179. package/src/lib/site-import/site-import-page.js.map +1 -1
  180. package/src/lib/assets/site-styles/beauty.webp +0 -0
  181. package/src/lib/assets/site-styles/blog.webp +0 -0
  182. package/src/lib/assets/site-styles/business.webp +0 -0
  183. package/src/lib/assets/site-styles/coming-soon.webp +0 -0
  184. package/src/lib/assets/site-styles/education.webp +0 -0
  185. package/src/lib/assets/site-styles/events.webp +0 -0
  186. package/src/lib/assets/site-styles/fitness.webp +0 -0
  187. package/src/lib/assets/site-styles/landing.webp +0 -0
  188. package/src/lib/assets/site-styles/music.webp +0 -0
  189. package/src/lib/assets/site-styles/nonprofit.webp +0 -0
  190. package/src/lib/assets/site-styles/personal.webp +0 -0
  191. package/src/lib/assets/site-styles/photography.webp +0 -0
  192. package/src/lib/assets/site-styles/portfolio.webp +0 -0
  193. package/src/lib/assets/site-styles/professional.webp +0 -0
  194. package/src/lib/assets/site-styles/realestate.webp +0 -0
  195. package/src/lib/assets/site-styles/restaurant.webp +0 -0
  196. package/src/lib/assets/site-styles/store.webp +0 -0
  197. package/src/lib/assets/site-styles/studio.webp +0 -0
  198. package/src/lib/assets/site-styles/trades.webp +0 -0
  199. package/src/lib/assets/site-styles/wellness.webp +0 -0
  200. package/src/lib/assets/site-styles/yoga.webp +0 -0
  201. package/src/lib/site-import/site-import-review.d.ts +0 -40
  202. package/src/lib/site-import/site-import-review.js +0 -149
  203. package/src/lib/site-import/site-import-review.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../../../libs/plugins/ai/src/lib/declarations.server.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\n// Each registry from its own module, not the `@aglyn/aglyn/server` barrel:\n// boot needs three registries rather than the whole server surface, and a\n// suite that stubs that barrel wholesale still loads these declarations\n// against the real registries.\nimport {\n listPluginEventHandlers,\n registerPluginEventHandler,\n} from '@aglyn/aglyn/plugin-manager/plugin-events'\nimport {\n listPluginUserErasers,\n registerPluginUserEraser,\n} from '@aglyn/aglyn/plugin-manager/plugin-user-erasure'\nimport {\n listUsageAlertContributors,\n registerUsageAlertContributor,\n} from '@aglyn/aglyn/plugin-manager/usage-alert-contributors'\nimport { registerPluginUsageMeter } from '@aglyn/aglyn/plugin-manager/plugin-usage-meters'\nimport { registerOperatorAlerts } from '@aglyn/aglyn/plugin-manager/operator-alerts'\nimport { registerStockPhotoPicker } from '@aglyn/aglyn/plugin-manager/stock-photo-provider'\nimport { AI_PLUGIN_ID, AI_USAGE_METER_ID } from './constants'\nimport { AI_BUILD_PARTLY_FAILED, AI_JOB_FAILED, AI_PROVIDER_UNAVAILABLE } from './operator-alerts'\nimport { registerAiDeclarations } from './declarations'\n\n/** The provider-spend staff alerts' contributor id under the plugin. */\nconst AI_USAGE_ALERTS_ID = 'provider-spend'\n\n/**\n * The plugin's SERVER declarations (AGL-2939): what the server must know\n * at boot, before any door of the plugin has been called. The two platform\n * events the plugin writes activity for — the AI add-on bought or dropped,\n * an `ai.*` permission moved — are raised by core billing and membership\n * routes that never load the plugin's API surface, so the subscriptions\n * have to be in place from the first request. So does the eraser: an\n * account erasure is a core route too, and a person's AI usage months sit\n * under each org, keyed by the uid, where no core delete reaches them. So\n * does the usage alert contributor (AGL-2984): the usage-alerts sweep is a\n * core cron, and it evaluates the plugin's staff alerts on provider spend for\n * every org it reads.\n *\n * Light at boot by construction: the writers behind the handlers are\n * imported when the first event arrives, and the alert rules when the sweep\n * first evaluates an org, not when the process starts, so the boot cost is\n * the registration and nothing that touches Firestore.\n */\nexport function registerAiServerDeclarations(): void {\n registerAiDeclarations()\n // Idempotent against each REGISTRY rather than a module flag, so a\n // registry reset (a spec) or a second module instance registers again.\n if (!listPluginEventHandlers('org.seatAddons.changed').includes(AI_PLUGIN_ID)) {\n registerPluginEventHandler(\n 'org.seatAddons.changed',\n async ({ orgId, actor, before, after }) => {\n const { logAiAddonChanged } = await import('./activity/ai-activity')\n await logAiAddonChanged(orgId, actor, { before, after })\n },\n { pluginId: AI_PLUGIN_ID },\n )\n registerPluginEventHandler(\n 'org.permissions.changed',\n async ({ orgId, actor, subject, permission, granted }) => {\n if (!permission.startsWith('ai.')) return\n const { logAiPermissionChanged } = await import('./activity/ai-activity')\n await logAiPermissionChanged(orgId, actor, { subject, permission, granted })\n },\n { pluginId: AI_PLUGIN_ID },\n )\n }\n // THE PLATFORM'S PER-SITE TOGGLE DOOR (AGL-4047). The collaborators card\n // sets every per-site key through the platform's generic door now, so this\n // plugin keeps its display copy (`aiPermissions` on the site's roster row,\n // which the native apps read) in step from the verdict that door wrote.\n if (!listPluginEventHandlers('host.member.permissions.changed').includes(AI_PLUGIN_ID)) {\n registerPluginEventHandler(\n 'host.member.permissions.changed',\n async ({ hostId, memberId, permissions }) => {\n const { recordAiPermissionsOnRoster } = await import('./server/ai-host-permissions-roster')\n await recordAiPermissionsOnRoster(hostId, memberId, permissions)\n },\n { pluginId: AI_PLUGIN_ID },\n )\n }\n // THE PLATFORM'S BILLING EVENTS (AGL-3011). Subscribed at boot for the\n // same reason as the two above: they are raised by the billing webhook,\n // which never loads an AI door, and a workspace's overage standing moving\n // late is a workspace charged or refused against a fact we already had.\n //\n // The handler modules are imported when the first event arrives, so a\n // process that never receives one pays only for the registration.\n if (!listPluginEventHandlers('billing.invoice.paid').includes(AI_PLUGIN_ID)) {\n registerPluginEventHandler(\n 'billing.invoice.paid',\n async (payload) => {\n const { onAiBillingInvoicePaid } = await import('./billing/ai-overage-events')\n await onAiBillingInvoicePaid(payload)\n },\n { pluginId: AI_PLUGIN_ID },\n )\n registerPluginEventHandler(\n 'billing.invoice.failed',\n async (payload) => {\n const { onAiBillingInvoiceFailed } = await import('./billing/ai-overage-events')\n await onAiBillingInvoiceFailed(payload)\n },\n { pluginId: AI_PLUGIN_ID },\n )\n registerPluginEventHandler(\n 'billing.invoice.closed',\n async (payload) => {\n const { onAiBillingInvoiceClosed } = await import('./billing/ai-overage-events')\n await onAiBillingInvoiceClosed(payload)\n },\n { pluginId: AI_PLUGIN_ID },\n )\n registerPluginEventHandler(\n 'billing.dispute.opened',\n async (payload) => {\n const { onAiBillingDisputeOpened } = await import('./billing/ai-overage-events')\n await onAiBillingDisputeOpened(payload)\n },\n { pluginId: AI_PLUGIN_ID },\n )\n registerPluginEventHandler(\n 'billing.paymentMethod.changed',\n async (payload) => {\n const { onAiBillingPaymentMethodChanged } = await import(\n './billing/ai-overage-events'\n )\n await onAiBillingPaymentMethodChanged(payload)\n },\n { pluginId: AI_PLUGIN_ID },\n )\n }\n // The plugin's meter in the monthly usage sweep: the month's provider spend\n // onto the rollup, the credits past the band onto the invoice, and — from\n // the cutover month (AGL-3011) — the close-out of what the plugin invoices\n // itself. Registered at boot because the sweep is a core cron, and declared\n // in `usageAxes` so the sweep refuses to bill a month without it. The same\n // registration again replaces itself.\n registerPluginUsageMeter({\n pluginId: AI_PLUGIN_ID,\n id: AI_USAGE_METER_ID,\n measure: async (context) => {\n const { measureAiMonth } = await import('./billing/ai-month-meter')\n return measureAiMonth(context)\n },\n closeMonth: async (context) => {\n const { closeAiMonth } = await import('./billing/ai-month-meter')\n await closeAiMonth(context)\n },\n })\n if (!listPluginUserErasers().includes(AI_PLUGIN_ID)) {\n registerPluginUserEraser(\n async (request) => {\n const { eraseAiUsageForUser } = await import('./usage/ai-usage-eraser')\n return eraseAiUsageForUser(request)\n },\n { pluginId: AI_PLUGIN_ID },\n )\n }\n // The platform provider account alert (AGL-3377), and a job failing or a\n // build finishing with parts failed on our side (AGL-3683), listed on\n // Staff → Operator alerts before the first one is raised.\n registerOperatorAlerts([AI_PROVIDER_UNAVAILABLE, AI_JOB_FAILED, AI_BUILD_PARTLY_FAILED], {\n pluginId: AI_PLUGIN_ID,\n })\n // The stock photo picker another plugin's draft writer asks for (AGL-3755):\n // an event's cover, chosen as a page's pictures are. The choosing loads on\n // the first pick; registering again replaces it.\n registerStockPhotoPicker(\n {\n pick: async (request) => {\n const { aiStockPhotoPick } = await import('./jobs/ai-stock-photo-picker')\n return aiStockPhotoPick(request)\n },\n },\n { pluginId: AI_PLUGIN_ID },\n )\n if (\n !listUsageAlertContributors().some(\n (contributor) =>\n contributor.pluginId === AI_PLUGIN_ID &&\n contributor.id === AI_USAGE_ALERTS_ID,\n )\n ) {\n registerUsageAlertContributor({\n pluginId: AI_PLUGIN_ID,\n id: AI_USAGE_ALERTS_ID,\n evaluate: async (context) => {\n const { evaluateAiUsageAlerts } = await import('./usage/ai-usage-alerts')\n await evaluateAiUsageAlerts(context)\n },\n quotaChecks: async (context) => {\n const { aiQuotaChecks } = await import('./usage/ai-quota-checks')\n return aiQuotaChecks(context)\n },\n })\n }\n}\n\nregisterAiServerDeclarations()\n"],"names":["listPluginEventHandlers","registerPluginEventHandler","listPluginUserErasers","registerPluginUserEraser","listUsageAlertContributors","registerUsageAlertContributor","registerPluginUsageMeter","registerOperatorAlerts","registerStockPhotoPicker","AI_PLUGIN_ID","AI_USAGE_METER_ID","AI_BUILD_PARTLY_FAILED","AI_JOB_FAILED","AI_PROVIDER_UNAVAILABLE","registerAiDeclarations","AI_USAGE_ALERTS_ID","registerAiServerDeclarations","includes","orgId","actor","before","after","logAiAddonChanged","pluginId","subject","permission","granted","startsWith","logAiPermissionChanged","hostId","memberId","permissions","recordAiPermissionsOnRoster","payload","onAiBillingInvoicePaid","onAiBillingInvoiceFailed","onAiBillingInvoiceClosed","onAiBillingDisputeOpened","onAiBillingPaymentMethodChanged","id","measure","context","measureAiMonth","closeMonth","closeAiMonth","request","eraseAiUsageForUser","pick","aiStockPhotoPick","some","contributor","evaluate","evaluateAiUsageAlerts","quotaChecks","aiQuotaChecks"],"mappings":"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"}
1
+ {"version":3,"sources":["../../../../../../libs/plugins/ai/src/lib/declarations.server.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\n// Each registry from its own module, not the `@aglyn/aglyn/server` barrel:\n// boot needs three registries rather than the whole server surface, and a\n// suite that stubs that barrel wholesale still loads these declarations\n// against the real registries.\nimport {\n listPluginEventHandlers,\n registerPluginEventHandler,\n} from '@aglyn/aglyn/plugin-manager/plugin-events'\nimport {\n listPluginUserErasers,\n registerPluginUserEraser,\n} from '@aglyn/aglyn/plugin-manager/plugin-user-erasure'\nimport {\n listUsageAlertContributors,\n registerUsageAlertContributor,\n} from '@aglyn/aglyn/plugin-manager/usage-alert-contributors'\nimport { registerPluginUsageMeter } from '@aglyn/aglyn/plugin-manager/plugin-usage-meters'\nimport { registerOperatorAlerts } from '@aglyn/aglyn/plugin-manager/operator-alerts'\nimport { registerStockPhotoPicker } from '@aglyn/aglyn/plugin-manager/stock-photo-provider'\nimport { registerPluginSiteStyleLooks } from '@aglyn/aglyn/plugin-manager/plugin-site-style-looks'\nimport { listServerThemePresets } from '@aglyn/aglyn/plugin-manager/plugin-theme-presets'\nimport { AI_PLUGIN_ID, AI_USAGE_METER_ID } from './constants'\nimport { AI_BUILD_PARTLY_FAILED, AI_JOB_FAILED, AI_PROVIDER_UNAVAILABLE } from './operator-alerts'\nimport { registerAiDeclarations } from './declarations'\n\n/** The provider-spend staff alerts' contributor id under the plugin. */\nconst AI_USAGE_ALERTS_ID = 'provider-spend'\n\n/**\n * The plugin's SERVER declarations (AGL-2939): what the server must know\n * at boot, before any door of the plugin has been called. The two platform\n * events the plugin writes activity for — the AI add-on bought or dropped,\n * an `ai.*` permission moved — are raised by core billing and membership\n * routes that never load the plugin's API surface, so the subscriptions\n * have to be in place from the first request. So does the eraser: an\n * account erasure is a core route too, and a person's AI usage months sit\n * under each org, keyed by the uid, where no core delete reaches them. So\n * does the usage alert contributor (AGL-2984): the usage-alerts sweep is a\n * core cron, and it evaluates the plugin's staff alerts on provider spend for\n * every org it reads.\n *\n * Light at boot by construction: the writers behind the handlers are\n * imported when the first event arrives, and the alert rules when the sweep\n * first evaluates an org, not when the process starts, so the boot cost is\n * the registration and nothing that touches Firestore.\n */\nexport function registerAiServerDeclarations(): void {\n registerAiDeclarations()\n // Idempotent against each REGISTRY rather than a module flag, so a\n // registry reset (a spec) or a second module instance registers again.\n if (!listPluginEventHandlers('org.seatAddons.changed').includes(AI_PLUGIN_ID)) {\n registerPluginEventHandler(\n 'org.seatAddons.changed',\n async ({ orgId, actor, before, after }) => {\n const { logAiAddonChanged } = await import('./activity/ai-activity')\n await logAiAddonChanged(orgId, actor, { before, after })\n },\n { pluginId: AI_PLUGIN_ID },\n )\n registerPluginEventHandler(\n 'org.permissions.changed',\n async ({ orgId, actor, subject, permission, granted }) => {\n if (!permission.startsWith('ai.')) return\n const { logAiPermissionChanged } = await import('./activity/ai-activity')\n await logAiPermissionChanged(orgId, actor, { subject, permission, granted })\n },\n { pluginId: AI_PLUGIN_ID },\n )\n }\n // THE PLATFORM'S PER-SITE TOGGLE DOOR (AGL-4047). The collaborators card\n // sets every per-site key through the platform's generic door now, so this\n // plugin keeps its display copy (`aiPermissions` on the site's roster row,\n // which the native apps read) in step from the verdict that door wrote.\n if (!listPluginEventHandlers('host.member.permissions.changed').includes(AI_PLUGIN_ID)) {\n registerPluginEventHandler(\n 'host.member.permissions.changed',\n async ({ hostId, memberId, permissions }) => {\n const { recordAiPermissionsOnRoster } = await import('./server/ai-host-permissions-roster')\n await recordAiPermissionsOnRoster(hostId, memberId, permissions)\n },\n { pluginId: AI_PLUGIN_ID },\n )\n }\n // THE PLATFORM'S BILLING EVENTS (AGL-3011). Subscribed at boot for the\n // same reason as the two above: they are raised by the billing webhook,\n // which never loads an AI door, and a workspace's overage standing moving\n // late is a workspace charged or refused against a fact we already had.\n //\n // The handler modules are imported when the first event arrives, so a\n // process that never receives one pays only for the registration.\n if (!listPluginEventHandlers('billing.invoice.paid').includes(AI_PLUGIN_ID)) {\n registerPluginEventHandler(\n 'billing.invoice.paid',\n async (payload) => {\n const { onAiBillingInvoicePaid } = await import('./billing/ai-overage-events')\n await onAiBillingInvoicePaid(payload)\n },\n { pluginId: AI_PLUGIN_ID },\n )\n registerPluginEventHandler(\n 'billing.invoice.failed',\n async (payload) => {\n const { onAiBillingInvoiceFailed } = await import('./billing/ai-overage-events')\n await onAiBillingInvoiceFailed(payload)\n },\n { pluginId: AI_PLUGIN_ID },\n )\n registerPluginEventHandler(\n 'billing.invoice.closed',\n async (payload) => {\n const { onAiBillingInvoiceClosed } = await import('./billing/ai-overage-events')\n await onAiBillingInvoiceClosed(payload)\n },\n { pluginId: AI_PLUGIN_ID },\n )\n registerPluginEventHandler(\n 'billing.dispute.opened',\n async (payload) => {\n const { onAiBillingDisputeOpened } = await import('./billing/ai-overage-events')\n await onAiBillingDisputeOpened(payload)\n },\n { pluginId: AI_PLUGIN_ID },\n )\n registerPluginEventHandler(\n 'billing.paymentMethod.changed',\n async (payload) => {\n const { onAiBillingPaymentMethodChanged } = await import(\n './billing/ai-overage-events'\n )\n await onAiBillingPaymentMethodChanged(payload)\n },\n { pluginId: AI_PLUGIN_ID },\n )\n }\n // The plugin's meter in the monthly usage sweep: the month's provider spend\n // onto the rollup, the credits past the band onto the invoice, and — from\n // the cutover month (AGL-3011) — the close-out of what the plugin invoices\n // itself. Registered at boot because the sweep is a core cron, and declared\n // in `usageAxes` so the sweep refuses to bill a month without it. The same\n // registration again replaces itself.\n registerPluginUsageMeter({\n pluginId: AI_PLUGIN_ID,\n id: AI_USAGE_METER_ID,\n measure: async (context) => {\n const { measureAiMonth } = await import('./billing/ai-month-meter')\n return measureAiMonth(context)\n },\n closeMonth: async (context) => {\n const { closeAiMonth } = await import('./billing/ai-month-meter')\n await closeAiMonth(context)\n },\n })\n if (!listPluginUserErasers().includes(AI_PLUGIN_ID)) {\n registerPluginUserEraser(\n async (request) => {\n const { eraseAiUsageForUser } = await import('./usage/ai-usage-eraser')\n return eraseAiUsageForUser(request)\n },\n { pluginId: AI_PLUGIN_ID },\n )\n }\n // The platform provider account alert (AGL-3377), and a job failing or a\n // build finishing with parts failed on our side (AGL-3683), listed on\n // Staff → Operator alerts before the first one is raised.\n registerOperatorAlerts([AI_PROVIDER_UNAVAILABLE, AI_JOB_FAILED, AI_BUILD_PARTLY_FAILED], {\n pluginId: AI_PLUGIN_ID,\n })\n // The stock photo picker another plugin's draft writer asks for (AGL-3755):\n // an event's cover, chosen as a page's pictures are. The choosing loads on\n // the first pick; registering again replaces it.\n registerStockPhotoPicker(\n {\n pick: async (request) => {\n const { aiStockPhotoPick } = await import('./jobs/ai-stock-photo-picker')\n return aiStockPhotoPick(request)\n },\n },\n { pluginId: AI_PLUGIN_ID },\n )\n // The look each style starts a new site in (AGL-4049): Create site asks a\n // style before it creates anything, and the 21 styles are this plugin's\n // kinds of site. Asked on the create, so the look module loads then; the\n // built-in themes this deployment has are read at that moment too.\n registerPluginSiteStyleLooks(\n {\n look: async (styleId) => {\n const [{ aiSiteKind }, { aiSiteKindDefaultLook }] = await Promise.all([\n import('./model/ai-site-kinds'),\n import('./model/ai-site-look'),\n ])\n const kind = aiSiteKind(styleId)\n if (!kind) return null\n const presetIds = new Set(listServerThemePresets().map((preset) => preset.id))\n return aiSiteKindDefaultLook(kind, { presetIds }).theme\n },\n },\n { pluginId: AI_PLUGIN_ID },\n )\n if (\n !listUsageAlertContributors().some(\n (contributor) =>\n contributor.pluginId === AI_PLUGIN_ID &&\n contributor.id === AI_USAGE_ALERTS_ID,\n )\n ) {\n registerUsageAlertContributor({\n pluginId: AI_PLUGIN_ID,\n id: AI_USAGE_ALERTS_ID,\n evaluate: async (context) => {\n const { evaluateAiUsageAlerts } = await import('./usage/ai-usage-alerts')\n await evaluateAiUsageAlerts(context)\n },\n quotaChecks: async (context) => {\n const { aiQuotaChecks } = await import('./usage/ai-quota-checks')\n return aiQuotaChecks(context)\n },\n })\n }\n}\n\nregisterAiServerDeclarations()\n"],"names":["listPluginEventHandlers","registerPluginEventHandler","listPluginUserErasers","registerPluginUserEraser","listUsageAlertContributors","registerUsageAlertContributor","registerPluginUsageMeter","registerOperatorAlerts","registerStockPhotoPicker","registerPluginSiteStyleLooks","listServerThemePresets","AI_PLUGIN_ID","AI_USAGE_METER_ID","AI_BUILD_PARTLY_FAILED","AI_JOB_FAILED","AI_PROVIDER_UNAVAILABLE","registerAiDeclarations","AI_USAGE_ALERTS_ID","registerAiServerDeclarations","includes","orgId","actor","before","after","logAiAddonChanged","pluginId","subject","permission","granted","startsWith","logAiPermissionChanged","hostId","memberId","permissions","recordAiPermissionsOnRoster","payload","onAiBillingInvoicePaid","onAiBillingInvoiceFailed","onAiBillingInvoiceClosed","onAiBillingDisputeOpened","onAiBillingPaymentMethodChanged","id","measure","context","measureAiMonth","closeMonth","closeAiMonth","request","eraseAiUsageForUser","pick","aiStockPhotoPick","look","styleId","aiSiteKind","aiSiteKindDefaultLook","Promise","all","kind","presetIds","Set","map","preset","theme","some","contributor","evaluate","evaluateAiUsageAlerts","quotaChecks","aiQuotaChecks"],"mappings":"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"}
@@ -23,6 +23,8 @@ import type { AiJob, AiJobOutput } from '../model/ai-jobs.types';
23
23
  import { type AssistEditCanvasContext, type AssistEditOp, type AssistEditProposal, type AssistEditTarget } from '../model/assist-edit';
24
24
  import { type AiCustomGenerationInput } from '../runtime/ai-doctrine';
25
25
  import type { AiSystemBlock } from '../runtime/ai-runtime';
26
+ import { readAiSiteDatasets } from '../runtime/site-inventory';
27
+ import { type AssistEditDataset, type AssistEditDatasetScope } from '../server/assist-edit';
26
28
  import { type AiJobAdmission } from './ai-job-admission';
27
29
  import { type AiJobStepRunner } from './ai-job-text-step';
28
30
  /**
@@ -39,13 +41,19 @@ import { type AiJobStepRunner } from './ai-job-text-step';
39
41
  *
40
42
  * ── Where the change lands, decided before anything is spent ────────────
41
43
  *
42
- * Never on a version a visitor sees. With version history, a NEW version
43
- * beside the one it started from — a copy of that version's stored fields with
44
- * the changed nodes — which becomes the page's current version only when the
45
- * page is not published; a published page's current version, and a layout's,
46
- * never move. Without it, in place, on a version no visitor reaches: an
47
- * unpublished page's, or one that is not the current version and no schedule
48
- * will publish. Anything else is refused as a plan limit, charged nothing.
44
+ * Never on a version a visitor sees. By default, on every plan, in the
45
+ * WORKING DRAFT of the version it started from (AGL-4116): the one document
46
+ * the Besigner saves to as an author works and offers with Open draft, which
47
+ * publishing moves into the version. The change is built on the draft the
48
+ * author already has, when the Besigner would still offer it, so their work
49
+ * in progress is never thrown away; otherwise on the version's own tree.
50
+ *
51
+ * Only when the request asks for a new version, and the plan keeps version
52
+ * history, a NEW version beside the one it started from — a copy of that
53
+ * version's stored fields with the changed nodes — which becomes the page's
54
+ * current version only when the page is not published; a published page's
55
+ * current version, and a layout's, never move. Asked for without version
56
+ * history, the change goes into the draft and the output says why.
49
57
  *
50
58
  * ── What a job cannot do that the editor can ────────────────────────────
51
59
  *
@@ -59,8 +67,8 @@ import { type AiJobStepRunner } from './ai-job-text-step';
59
67
  *
60
68
  * The new version is named by the job's id — a build's unit is named by its
61
69
  * plan item's id — so a run asked again finds what it wrote and spends
62
- * nothing. A change made in place stamps the version with the job's id for
63
- * the same reason.
70
+ * nothing. A draft the job writes is stamped with the job's id for the same
71
+ * reason.
64
72
  */
65
73
  /** The longest the step may take reading the page and writing it. */
66
74
  export declare const AI_EDIT_READS_MS = 2000;
@@ -76,11 +84,22 @@ export declare function aiJobEditModel(): string;
76
84
  export declare const AI_JOB_EDIT_RULES: AiSystemBlock;
77
85
  /** The system blocks for one kind of document. */
78
86
  export declare function aiJobEditInstructions(kind: AiEditTargetKind): AiSystemBlock[];
79
- /** What the change is asked from: the document's outline, then the request. */
87
+ /**
88
+ * What the change is asked from: the document's outline, the site's datasets
89
+ * an element may show the records of (AGL-3616), then the request.
90
+ */
80
91
  export declare function aiJobEditPrompt(input: {
81
92
  brief: string;
82
93
  context: AssistEditCanvasContext;
94
+ datasets?: readonly AssistEditDataset[];
83
95
  }): string;
96
+ /**
97
+ * The datasets an edit to this document knows (AGL-3616): every one the site
98
+ * holds, and the one whose record page the document is, if it is one.
99
+ */
100
+ export declare function aiEditDatasetScope(datasets: ReadonlyArray<AssistEditDataset & {
101
+ recordScreenId?: string;
102
+ }>, read: Pick<AiEditTargetRead, 'kind' | 'id'>): Required<AssistEditDatasetScope>;
84
103
  /** The edit as the doctrine's loop runs it: the rung's tool, held to the rung's check. */
85
104
  export declare function aiJobEditGeneration(request: {
86
105
  brief: string;
@@ -88,7 +107,7 @@ export declare function aiJobEditGeneration(request: {
88
107
  target: AssistEditTarget;
89
108
  model: string;
90
109
  signal?: AbortSignal;
91
- }): AiCustomGenerationInput<AssistEditProposal>;
110
+ } & AssistEditDatasetScope): AiCustomGenerationInput<AssistEditProposal>;
92
111
  /** A canvas over a stored node map, with the editor's own guarded mutators and no editor. */
93
112
  export declare function aiEditCanvas(nodes: NodesMap): CanvasManager;
94
113
  /**
@@ -115,7 +134,16 @@ export interface AiEditTargetRead {
115
134
  pointerVersionId: string | null;
116
135
  /** The version the change starts from. */
117
136
  sourceVersionId: string;
137
+ /** The version's own tree. */
118
138
  nodes: NodesMap;
139
+ /**
140
+ * The version's working draft, when it has one the Besigner would still
141
+ * offer: an author's saved work in progress, which a change to the draft
142
+ * is built on. Null when there is none, or the version was saved since.
143
+ */
144
+ draft: {
145
+ nodes: NodesMap;
146
+ } | null;
119
147
  /** Whether visitors see the document's current version: a published page, a collection template, any layout. */
120
148
  served: boolean;
121
149
  /** The version a pending publish schedule will make current, if any. */
@@ -152,14 +180,29 @@ export declare function aiEditPlacement(input: {
152
180
  sourceIsPointer: boolean;
153
181
  sourceScheduled: boolean;
154
182
  }): AiEditPlacement | 'refused';
183
+ /**
184
+ * Where an edit job's change lands (AGL-4116): the version's working draft,
185
+ * unless the request asked for a new version and the plan keeps version
186
+ * history — then where {@link aiEditPlacement} puts a new one. Never refused:
187
+ * a draft is on every plan, and no visitor sees it.
188
+ */
189
+ export declare function aiEditJobPlacement(input: {
190
+ newVersion: boolean;
191
+ versioning: boolean;
192
+ served: boolean;
193
+ sourceIsPointer: boolean;
194
+ sourceScheduled: boolean;
195
+ }): AiEditPlacement;
155
196
  export interface AiEditWriteInput {
156
197
  hostId: string;
157
198
  kind: AiEditTargetKind;
158
199
  id: string;
159
200
  sourceVersionId: string;
160
- /** The new version's id, which is the job's; also the stamp a change in place carries. */
201
+ /** The new version's id, which is the job's; also the stamp a draft it writes carries. */
161
202
  jobVersionId: string;
162
203
  versioning: boolean;
204
+ /** The request asked for a new version (see {@link aiEditJobPlacement}). */
205
+ newVersion: boolean;
163
206
  proposal: AssistEditProposal;
164
207
  /** Whether the page's search fields may be written: a page no visitor reaches. */
165
208
  writeSeo: boolean;
@@ -189,12 +232,15 @@ export declare function writeAiEdit(firestore: Firestore, input: AiEditWriteInpu
189
232
  export interface AiJobEditStepDeps {
190
233
  readTarget?: typeof readAiEditTarget;
191
234
  writeEdit?: typeof writeAiEdit;
235
+ readDatasets?: typeof readAiSiteDatasets;
192
236
  }
193
237
  /** What an edit wrote, as the job's output: a link into the Besigner on the version written. */
194
238
  export declare function aiEditOutput(read: Pick<AiEditTargetRead, 'kind' | 'id' | 'name' | 'hostSubdomain'>, hostId: string, written: {
195
239
  versionId: string;
196
240
  placement: AiEditPlacement;
197
- }, leftOut: readonly string[]): AiJobOutput;
241
+ }, leftOut: readonly string[], options?: {
242
+ versionsUnavailable?: boolean;
243
+ }): AiJobOutput;
198
244
  /** The new version's id: the job's own, which a build's unit takes from its plan item. */
199
245
  export declare function aiEditVersionId(job: Pick<AiJob, '$id'>): string;
200
246
  /**
@@ -214,9 +260,9 @@ export interface AiEditJobAdmissionDeps {
214
260
  ownerOf?: typeof resolveOrgIdForHost;
215
261
  }
216
262
  /**
217
- * An edit job is admitted for a page or layout of a site of its own org,
218
- * and only where the change has somewhere to land that no visitor sees on
219
- * this workspace's plan — refused in the plan's words before anything exists.
263
+ * An edit job is admitted for a page or layout of a site of its own org that
264
+ * has a version to start from. Every plan has somewhere to put the change
265
+ * that no visitor sees — the version's draft — so no plan is refused.
220
266
  */
221
267
  export declare function createAiEditJobAdmission(deps?: AiEditJobAdmissionDeps): AiJobAdmission;
222
268
  export declare const aiEditJobAdmission: AiJobAdmission;