@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.
- package/LICENSE +201 -0
- package/README.md +25 -0
- package/package.json +60 -0
- package/src/index.d.ts +21 -0
- package/src/index.js +22 -0
- package/src/index.js.map +1 -0
- package/src/lib/activity/ai-activity-actions.d.ts +106 -0
- package/src/lib/activity/ai-activity-actions.js +209 -0
- package/src/lib/activity/ai-activity-actions.js.map +1 -0
- package/src/lib/activity/ai-activity.d.ts +219 -0
- package/src/lib/activity/ai-activity.js +251 -0
- package/src/lib/activity/ai-activity.js.map +1 -0
- package/src/lib/billing/ai-overage-charge.d.ts +102 -0
- package/src/lib/billing/ai-overage-charge.js +258 -0
- package/src/lib/billing/ai-overage-charge.js.map +1 -0
- package/src/lib/billing/ai-overage-close.d.ts +62 -0
- package/src/lib/billing/ai-overage-close.js +129 -0
- package/src/lib/billing/ai-overage-close.js.map +1 -0
- package/src/lib/billing/ai-overage-cutover.d.ts +63 -0
- package/src/lib/billing/ai-overage-cutover.js +114 -0
- package/src/lib/billing/ai-overage-cutover.js.map +1 -0
- package/src/lib/billing/ai-overage-events.d.ts +77 -0
- package/src/lib/billing/ai-overage-events.js +174 -0
- package/src/lib/billing/ai-overage-events.js.map +1 -0
- package/src/lib/billing/ai-overage-gate.d.ts +147 -0
- package/src/lib/billing/ai-overage-gate.js +177 -0
- package/src/lib/billing/ai-overage-gate.js.map +1 -0
- package/src/lib/billing/ai-overage-ledger.d.ts +135 -0
- package/src/lib/billing/ai-overage-ledger.js +278 -0
- package/src/lib/billing/ai-overage-ledger.js.map +1 -0
- package/src/lib/billing/ai-overage-standing-writes.d.ts +110 -0
- package/src/lib/billing/ai-overage-standing-writes.js +205 -0
- package/src/lib/billing/ai-overage-standing-writes.js.map +1 -0
- package/src/lib/billing/ai-overage-standing.d.ts +168 -0
- package/src/lib/billing/ai-overage-standing.js +215 -0
- package/src/lib/billing/ai-overage-standing.js.map +1 -0
- package/src/lib/billing/ai-overage-trigger.d.ts +30 -0
- package/src/lib/billing/ai-overage-trigger.js +76 -0
- package/src/lib/billing/ai-overage-trigger.js.map +1 -0
- package/src/lib/components/ai-allotment-editor.component.d.ts +40 -0
- package/src/lib/components/ai-allotment-editor.component.js +213 -0
- package/src/lib/components/ai-allotment-editor.component.js.map +1 -0
- package/src/lib/components/ai-assist-actions-context.d.ts +13 -0
- package/src/lib/components/ai-assist-actions-context.js +21 -0
- package/src/lib/components/ai-assist-actions-context.js.map +1 -0
- package/src/lib/components/ai-assist-provider.component.d.ts +51 -0
- package/src/lib/components/ai-assist-provider.component.js +519 -0
- package/src/lib/components/ai-assist-provider.component.js.map +1 -0
- package/src/lib/components/ai-brief-dialog.component.d.ts +56 -0
- package/src/lib/components/ai-brief-dialog.component.js +319 -0
- package/src/lib/components/ai-brief-dialog.component.js.map +1 -0
- package/src/lib/components/ai-collaborator-permissions-column.component.d.ts +32 -0
- package/src/lib/components/ai-collaborator-permissions-column.component.js +132 -0
- package/src/lib/components/ai-collaborator-permissions-column.component.js.map +1 -0
- package/src/lib/components/ai-credits-card.component.d.ts +34 -0
- package/src/lib/components/ai-credits-card.component.js +131 -0
- package/src/lib/components/ai-credits-card.component.js.map +1 -0
- package/src/lib/components/ai-credits-columns.component.d.ts +56 -0
- package/src/lib/components/ai-credits-columns.component.js +118 -0
- package/src/lib/components/ai-credits-columns.component.js.map +1 -0
- package/src/lib/components/ai-crm-email-draft.component.d.ts +17 -0
- package/src/lib/components/ai-crm-email-draft.component.js +159 -0
- package/src/lib/components/ai-crm-email-draft.component.js.map +1 -0
- package/src/lib/components/ai-crm-import-mapping.component.d.ts +20 -0
- package/src/lib/components/ai-crm-import-mapping.component.js +167 -0
- package/src/lib/components/ai-crm-import-mapping.component.js.map +1 -0
- package/src/lib/components/ai-crm-record-card.component.d.ts +27 -0
- package/src/lib/components/ai-crm-record-card.component.js +263 -0
- package/src/lib/components/ai-crm-record-card.component.js.map +1 -0
- package/src/lib/components/ai-describe-automation.component.d.ts +31 -0
- package/src/lib/components/ai-describe-automation.component.js +226 -0
- package/src/lib/components/ai-describe-automation.component.js.map +1 -0
- package/src/lib/components/ai-describe-button.component.d.ts +39 -0
- package/src/lib/components/ai-describe-button.component.js +87 -0
- package/src/lib/components/ai-describe-button.component.js.map +1 -0
- package/src/lib/components/ai-describe-page.component.d.ts +26 -0
- package/src/lib/components/ai-describe-page.component.js +18 -0
- package/src/lib/components/ai-describe-page.component.js.map +1 -0
- package/src/lib/components/ai-experiment-cards.component.d.ts +75 -0
- package/src/lib/components/ai-experiment-cards.component.js +573 -0
- package/src/lib/components/ai-experiment-cards.component.js.map +1 -0
- package/src/lib/components/ai-explain-automation.component.d.ts +31 -0
- package/src/lib/components/ai-explain-automation.component.js +265 -0
- package/src/lib/components/ai-explain-automation.component.js.map +1 -0
- package/src/lib/components/ai-insight-dialog.component.d.ts +37 -0
- package/src/lib/components/ai-insight-dialog.component.js +441 -0
- package/src/lib/components/ai-insight-dialog.component.js.map +1 -0
- package/src/lib/components/ai-job-plan.component.d.ts +46 -0
- package/src/lib/components/ai-job-plan.component.js +192 -0
- package/src/lib/components/ai-job-plan.component.js.map +1 -0
- package/src/lib/components/ai-model-selector.component.d.ts +21 -0
- package/src/lib/components/ai-model-selector.component.js +109 -0
- package/src/lib/components/ai-model-selector.component.js.map +1 -0
- package/src/lib/components/ai-page-brief-dialog.component.d.ts +29 -0
- package/src/lib/components/ai-page-brief-dialog.component.js +27 -0
- package/src/lib/components/ai-page-brief-dialog.component.js.map +1 -0
- package/src/lib/components/ai-permissions-on-host.component.d.ts +55 -0
- package/src/lib/components/ai-permissions-on-host.component.js +91 -0
- package/src/lib/components/ai-permissions-on-host.component.js.map +1 -0
- package/src/lib/components/ai-product-copy-card.component.d.ts +25 -0
- package/src/lib/components/ai-product-copy-card.component.js +328 -0
- package/src/lib/components/ai-product-copy-card.component.js.map +1 -0
- package/src/lib/components/ai-product-import-option.component.d.ts +14 -0
- package/src/lib/components/ai-product-import-option.component.js +58 -0
- package/src/lib/components/ai-product-import-option.component.js.map +1 -0
- package/src/lib/components/ai-products-hub-card.component.d.ts +15 -0
- package/src/lib/components/ai-products-hub-card.component.js +418 -0
- package/src/lib/components/ai-products-hub-card.component.js.map +1 -0
- package/src/lib/components/ai-products-proposals.component.d.ts +19 -0
- package/src/lib/components/ai-products-proposals.component.js +547 -0
- package/src/lib/components/ai-products-proposals.component.js.map +1 -0
- package/src/lib/components/ai-save-as-component.component.d.ts +38 -0
- package/src/lib/components/ai-save-as-component.component.js +231 -0
- package/src/lib/components/ai-save-as-component.component.js.map +1 -0
- package/src/lib/components/ai-seo-audit-card.component.d.ts +9 -0
- package/src/lib/components/ai-seo-audit-card.component.js +620 -0
- package/src/lib/components/ai-seo-audit-card.component.js.map +1 -0
- package/src/lib/components/ai-seo-fields-card.component.d.ts +10 -0
- package/src/lib/components/ai-seo-fields-card.component.js +453 -0
- package/src/lib/components/ai-seo-fields-card.component.js.map +1 -0
- package/src/lib/components/ai-site-batch-card.component.d.ts +32 -0
- package/src/lib/components/ai-site-batch-card.component.js +531 -0
- package/src/lib/components/ai-site-batch-card.component.js.map +1 -0
- package/src/lib/components/ai-site-seo-start-card.component.d.ts +26 -0
- package/src/lib/components/ai-site-seo-start-card.component.js +178 -0
- package/src/lib/components/ai-site-seo-start-card.component.js.map +1 -0
- package/src/lib/components/ai-site-start-card.component.d.ts +19 -0
- package/src/lib/components/ai-site-start-card.component.js +348 -0
- package/src/lib/components/ai-site-start-card.component.js.map +1 -0
- package/src/lib/components/ai-template-collection-field.component.d.ts +32 -0
- package/src/lib/components/ai-template-collection-field.component.js +63 -0
- package/src/lib/components/ai-template-collection-field.component.js.map +1 -0
- package/src/lib/components/ai-theme-proposal-card.component.d.ts +6 -0
- package/src/lib/components/ai-theme-proposal-card.component.js +619 -0
- package/src/lib/components/ai-theme-proposal-card.component.js.map +1 -0
- package/src/lib/components/ai-usage-strip.component.d.ts +27 -0
- package/src/lib/components/ai-usage-strip.component.js +145 -0
- package/src/lib/components/ai-usage-strip.component.js.map +1 -0
- package/src/lib/components/assist-edit-canvas.d.ts +169 -0
- package/src/lib/components/assist-edit-canvas.js +636 -0
- package/src/lib/components/assist-edit-canvas.js.map +1 -0
- package/src/lib/components/assist-edit-card.component.d.ts +16 -0
- package/src/lib/components/assist-edit-card.component.js +181 -0
- package/src/lib/components/assist-edit-card.component.js.map +1 -0
- package/src/lib/components/assist-jobs-drawer.component.d.ts +72 -0
- package/src/lib/components/assist-jobs-drawer.component.js +626 -0
- package/src/lib/components/assist-jobs-drawer.component.js.map +1 -0
- package/src/lib/components/assist-panel.component.d.ts +136 -0
- package/src/lib/components/assist-panel.component.js +1099 -0
- package/src/lib/components/assist-panel.component.js.map +1 -0
- package/src/lib/components/assist-signals-page.component.d.ts +3 -0
- package/src/lib/components/assist-signals-page.component.js +1017 -0
- package/src/lib/components/assist-signals-page.component.js.map +1 -0
- package/src/lib/components/besigner-ai-controls.component.d.ts +29 -0
- package/src/lib/components/besigner-ai-controls.component.js +81 -0
- package/src/lib/components/besigner-ai-controls.component.js.map +1 -0
- package/src/lib/components/billing-ai-allotments.component.d.ts +36 -0
- package/src/lib/components/billing-ai-allotments.component.js +486 -0
- package/src/lib/components/billing-ai-allotments.component.js.map +1 -0
- package/src/lib/components/billing-ai-top-users.component.d.ts +44 -0
- package/src/lib/components/billing-ai-top-users.component.js +304 -0
- package/src/lib/components/billing-ai-top-users.component.js.map +1 -0
- package/src/lib/components/billing-assist-overage-card.component.d.ts +69 -0
- package/src/lib/components/billing-assist-overage-card.component.js +437 -0
- package/src/lib/components/billing-assist-overage-card.component.js.map +1 -0
- package/src/lib/components/host-ai-allotments.component.d.ts +40 -0
- package/src/lib/components/host-ai-allotments.component.js +239 -0
- package/src/lib/components/host-ai-allotments.component.js.map +1 -0
- package/src/lib/components/member-ai-allotment-card.component.d.ts +28 -0
- package/src/lib/components/member-ai-allotment-card.component.js +172 -0
- package/src/lib/components/member-ai-allotment-card.component.js.map +1 -0
- package/src/lib/components/member-ai-usage-card.component.d.ts +28 -0
- package/src/lib/components/member-ai-usage-card.component.js +240 -0
- package/src/lib/components/member-ai-usage-card.component.js.map +1 -0
- package/src/lib/components/staff-org-ai-card.component.d.ts +17 -0
- package/src/lib/components/staff-org-ai-card.component.js +739 -0
- package/src/lib/components/staff-org-ai-card.component.js.map +1 -0
- package/src/lib/components/staff-org-usage-ai-columns.component.d.ts +41 -0
- package/src/lib/components/staff-org-usage-ai-columns.component.js +65 -0
- package/src/lib/components/staff-org-usage-ai-columns.component.js.map +1 -0
- package/src/lib/components/staff-orgs-ai-spend-column.component.d.ts +28 -0
- package/src/lib/components/staff-orgs-ai-spend-column.component.js +89 -0
- package/src/lib/components/staff-orgs-ai-spend-column.component.js.map +1 -0
- package/src/lib/components/staff-user-ai-usage-card.component.d.ts +27 -0
- package/src/lib/components/staff-user-ai-usage-card.component.js +183 -0
- package/src/lib/components/staff-user-ai-usage-card.component.js.map +1 -0
- package/src/lib/components/use-ai-allotments.d.ts +49 -0
- package/src/lib/components/use-ai-allotments.js +171 -0
- package/src/lib/components/use-ai-allotments.js.map +1 -0
- package/src/lib/components/use-ai-crm-answer.d.ts +50 -0
- package/src/lib/components/use-ai-crm-answer.js +220 -0
- package/src/lib/components/use-ai-crm-answer.js.map +1 -0
- package/src/lib/components/use-ai-job-run.d.ts +51 -0
- package/src/lib/components/use-ai-job-run.js +176 -0
- package/src/lib/components/use-ai-job-run.js.map +1 -0
- package/src/lib/components/use-ai-model-choice.d.ts +47 -0
- package/src/lib/components/use-ai-model-choice.js +150 -0
- package/src/lib/components/use-ai-model-choice.js.map +1 -0
- package/src/lib/components/use-ai-products-jobs.d.ts +36 -0
- package/src/lib/components/use-ai-products-jobs.js +190 -0
- package/src/lib/components/use-ai-products-jobs.js.map +1 -0
- package/src/lib/components/use-ai-usage-meter.d.ts +11 -0
- package/src/lib/components/use-ai-usage-meter.js +96 -0
- package/src/lib/components/use-ai-usage-meter.js.map +1 -0
- package/src/lib/components/use-org-ai-usage.d.ts +42 -0
- package/src/lib/components/use-org-ai-usage.js +181 -0
- package/src/lib/components/use-org-ai-usage.js.map +1 -0
- package/src/lib/components/use-staff-orgs-ai-spend.d.ts +18 -0
- package/src/lib/components/use-staff-orgs-ai-spend.js +127 -0
- package/src/lib/components/use-staff-orgs-ai-spend.js.map +1 -0
- package/src/lib/constants.d.ts +24 -0
- package/src/lib/constants.js +23 -0
- package/src/lib/constants.js.map +1 -0
- package/src/lib/declarations.d.ts +48 -0
- package/src/lib/declarations.js +129 -0
- package/src/lib/declarations.js.map +1 -0
- package/src/lib/declarations.server.d.ts +35 -0
- package/src/lib/declarations.server.js +138 -0
- package/src/lib/declarations.server.js.map +1 -0
- package/src/lib/insights/ai-figure-readers.d.ts +90 -0
- package/src/lib/insights/ai-figure-readers.js +863 -0
- package/src/lib/insights/ai-figure-readers.js.map +1 -0
- package/src/lib/insights/ai-insight-digest.d.ts +165 -0
- package/src/lib/insights/ai-insight-digest.js +363 -0
- package/src/lib/insights/ai-insight-digest.js.map +1 -0
- package/src/lib/insights/ai-insight-readers.d.ts +71 -0
- package/src/lib/insights/ai-insight-readers.js +141 -0
- package/src/lib/insights/ai-insight-readers.js.map +1 -0
- package/src/lib/jobs/ai-crm-access.d.ts +61 -0
- package/src/lib/jobs/ai-crm-access.js +94 -0
- package/src/lib/jobs/ai-crm-access.js.map +1 -0
- package/src/lib/jobs/ai-email-bindings.d.ts +97 -0
- package/src/lib/jobs/ai-email-bindings.js +147 -0
- package/src/lib/jobs/ai-email-bindings.js.map +1 -0
- package/src/lib/jobs/ai-job-admission.d.ts +82 -0
- package/src/lib/jobs/ai-job-admission.js +45 -0
- package/src/lib/jobs/ai-job-admission.js.map +1 -0
- package/src/lib/jobs/ai-job-budget.d.ts +167 -0
- package/src/lib/jobs/ai-job-budget.js +161 -0
- package/src/lib/jobs/ai-job-budget.js.map +1 -0
- package/src/lib/jobs/ai-job-campaign-step.d.ts +108 -0
- package/src/lib/jobs/ai-job-campaign-step.js +340 -0
- package/src/lib/jobs/ai-job-campaign-step.js.map +1 -0
- package/src/lib/jobs/ai-job-component-checks.d.ts +74 -0
- package/src/lib/jobs/ai-job-component-checks.js +442 -0
- package/src/lib/jobs/ai-job-component-checks.js.map +1 -0
- package/src/lib/jobs/ai-job-component-step.d.ts +75 -0
- package/src/lib/jobs/ai-job-component-step.js +262 -0
- package/src/lib/jobs/ai-job-component-step.js.map +1 -0
- package/src/lib/jobs/ai-job-crm-step.d.ts +192 -0
- package/src/lib/jobs/ai-job-crm-step.js +734 -0
- package/src/lib/jobs/ai-job-crm-step.js.map +1 -0
- package/src/lib/jobs/ai-job-draft-ids.d.ts +62 -0
- package/src/lib/jobs/ai-job-draft-ids.js +132 -0
- package/src/lib/jobs/ai-job-draft-ids.js.map +1 -0
- package/src/lib/jobs/ai-job-drafts.d.ts +304 -0
- package/src/lib/jobs/ai-job-drafts.js +557 -0
- package/src/lib/jobs/ai-job-drafts.js.map +1 -0
- package/src/lib/jobs/ai-job-email-step.d.ts +195 -0
- package/src/lib/jobs/ai-job-email-step.js +547 -0
- package/src/lib/jobs/ai-job-email-step.js.map +1 -0
- package/src/lib/jobs/ai-job-experiment-step.d.ts +105 -0
- package/src/lib/jobs/ai-job-experiment-step.js +445 -0
- package/src/lib/jobs/ai-job-experiment-step.js.map +1 -0
- package/src/lib/jobs/ai-job-form-step.d.ts +250 -0
- package/src/lib/jobs/ai-job-form-step.js +634 -0
- package/src/lib/jobs/ai-job-form-step.js.map +1 -0
- package/src/lib/jobs/ai-job-generation.d.ts +114 -0
- package/src/lib/jobs/ai-job-generation.js +384 -0
- package/src/lib/jobs/ai-job-generation.js.map +1 -0
- package/src/lib/jobs/ai-job-insight-budget.d.ts +41 -0
- package/src/lib/jobs/ai-job-insight-budget.js +46 -0
- package/src/lib/jobs/ai-job-insight-budget.js.map +1 -0
- package/src/lib/jobs/ai-job-insight-step.d.ts +58 -0
- package/src/lib/jobs/ai-job-insight-step.js +350 -0
- package/src/lib/jobs/ai-job-insight-step.js.map +1 -0
- package/src/lib/jobs/ai-job-layout-step.d.ts +103 -0
- package/src/lib/jobs/ai-job-layout-step.js +340 -0
- package/src/lib/jobs/ai-job-layout-step.js.map +1 -0
- package/src/lib/jobs/ai-job-page-budget.d.ts +57 -0
- package/src/lib/jobs/ai-job-page-budget.js +60 -0
- package/src/lib/jobs/ai-job-page-budget.js.map +1 -0
- package/src/lib/jobs/ai-job-page-sections.d.ts +150 -0
- package/src/lib/jobs/ai-job-page-sections.js +450 -0
- package/src/lib/jobs/ai-job-page-sections.js.map +1 -0
- package/src/lib/jobs/ai-job-page-step.d.ts +198 -0
- package/src/lib/jobs/ai-job-page-step.js +667 -0
- package/src/lib/jobs/ai-job-page-step.js.map +1 -0
- package/src/lib/jobs/ai-job-plan-conformance.d.ts +107 -0
- package/src/lib/jobs/ai-job-plan-conformance.js +164 -0
- package/src/lib/jobs/ai-job-plan-conformance.js.map +1 -0
- package/src/lib/jobs/ai-job-plan-step.d.ts +196 -0
- package/src/lib/jobs/ai-job-plan-step.js +458 -0
- package/src/lib/jobs/ai-job-plan-step.js.map +1 -0
- package/src/lib/jobs/ai-job-plugin-drafts.d.ts +76 -0
- package/src/lib/jobs/ai-job-plugin-drafts.js +91 -0
- package/src/lib/jobs/ai-job-plugin-drafts.js.map +1 -0
- package/src/lib/jobs/ai-job-products-step.d.ts +106 -0
- package/src/lib/jobs/ai-job-products-step.js +436 -0
- package/src/lib/jobs/ai-job-products-step.js.map +1 -0
- package/src/lib/jobs/ai-job-seo-budget.d.ts +52 -0
- package/src/lib/jobs/ai-job-seo-budget.js +63 -0
- package/src/lib/jobs/ai-job-seo-budget.js.map +1 -0
- package/src/lib/jobs/ai-job-seo-step.d.ts +145 -0
- package/src/lib/jobs/ai-job-seo-step.js +809 -0
- package/src/lib/jobs/ai-job-seo-step.js.map +1 -0
- package/src/lib/jobs/ai-job-site-step.d.ts +252 -0
- package/src/lib/jobs/ai-job-site-step.js +538 -0
- package/src/lib/jobs/ai-job-site-step.js.map +1 -0
- package/src/lib/jobs/ai-job-template-step.d.ts +105 -0
- package/src/lib/jobs/ai-job-template-step.js +391 -0
- package/src/lib/jobs/ai-job-template-step.js.map +1 -0
- package/src/lib/jobs/ai-job-text-step.d.ts +125 -0
- package/src/lib/jobs/ai-job-text-step.js +128 -0
- package/src/lib/jobs/ai-job-text-step.js.map +1 -0
- package/src/lib/jobs/ai-job-theme-budget.d.ts +38 -0
- package/src/lib/jobs/ai-job-theme-budget.js +43 -0
- package/src/lib/jobs/ai-job-theme-budget.js.map +1 -0
- package/src/lib/jobs/ai-job-theme-step.d.ts +115 -0
- package/src/lib/jobs/ai-job-theme-step.js +337 -0
- package/src/lib/jobs/ai-job-theme-step.js.map +1 -0
- package/src/lib/jobs/ai-job-workflow-step.d.ts +139 -0
- package/src/lib/jobs/ai-job-workflow-step.js +530 -0
- package/src/lib/jobs/ai-job-workflow-step.js.map +1 -0
- package/src/lib/jobs/ai-jobs-beat.d.ts +78 -0
- package/src/lib/jobs/ai-jobs-beat.js +93 -0
- package/src/lib/jobs/ai-jobs-beat.js.map +1 -0
- package/src/lib/jobs/ai-jobs-pause.d.ts +38 -0
- package/src/lib/jobs/ai-jobs-pause.js +45 -0
- package/src/lib/jobs/ai-jobs-pause.js.map +1 -0
- package/src/lib/jobs/ai-jobs.d.ts +558 -0
- package/src/lib/jobs/ai-jobs.js +1410 -0
- package/src/lib/jobs/ai-jobs.js.map +1 -0
- package/src/lib/jobs/ai-media-asset-server.d.ts +34 -0
- package/src/lib/jobs/ai-media-asset-server.js +34 -0
- package/src/lib/jobs/ai-media-asset-server.js.map +1 -0
- package/src/lib/jobs/ai-media-asset.d.ts +59 -0
- package/src/lib/jobs/ai-media-asset.js +86 -0
- package/src/lib/jobs/ai-media-asset.js.map +1 -0
- package/src/lib/jobs/ai-product-image.d.ts +78 -0
- package/src/lib/jobs/ai-product-image.js +113 -0
- package/src/lib/jobs/ai-product-image.js.map +1 -0
- package/src/lib/jobs/ai-theme-brand-inputs.d.ts +125 -0
- package/src/lib/jobs/ai-theme-brand-inputs.js +378 -0
- package/src/lib/jobs/ai-theme-brand-inputs.js.map +1 -0
- package/src/lib/jobs/ai-theme-brand-server.d.ts +33 -0
- package/src/lib/jobs/ai-theme-brand-server.js +33 -0
- package/src/lib/jobs/ai-theme-brand-server.js.map +1 -0
- package/src/lib/jobs/ai-workflow-records.d.ts +84 -0
- package/src/lib/jobs/ai-workflow-records.js +158 -0
- package/src/lib/jobs/ai-workflow-records.js.map +1 -0
- package/src/lib/jobs/fixtures/ai-free-page-built-recording.d.ts +31 -0
- package/src/lib/jobs/fixtures/ai-free-page-built-recording.js +367 -0
- package/src/lib/jobs/fixtures/ai-free-page-built-recording.js.map +1 -0
- package/src/lib/jobs/fixtures/ai-free-page-recording.d.ts +69 -0
- package/src/lib/jobs/fixtures/ai-free-page-recording.js +442 -0
- package/src/lib/jobs/fixtures/ai-free-page-recording.js.map +1 -0
- package/src/lib/jobs/fixtures/ai-page-briefs.d.ts +146 -0
- package/src/lib/jobs/fixtures/ai-page-briefs.js +1850 -0
- package/src/lib/jobs/fixtures/ai-page-briefs.js.map +1 -0
- package/src/lib/model/ai-allotments.d.ts +208 -0
- package/src/lib/model/ai-allotments.js +269 -0
- package/src/lib/model/ai-allotments.js.map +1 -0
- package/src/lib/model/ai-automation-draft.d.ts +74 -0
- package/src/lib/model/ai-automation-draft.js +310 -0
- package/src/lib/model/ai-automation-draft.js.map +1 -0
- package/src/lib/model/ai-automation-outline.d.ts +50 -0
- package/src/lib/model/ai-automation-outline.js +262 -0
- package/src/lib/model/ai-automation-outline.js.map +1 -0
- package/src/lib/model/ai-build-plan.d.ts +197 -0
- package/src/lib/model/ai-build-plan.js +438 -0
- package/src/lib/model/ai-build-plan.js.map +1 -0
- package/src/lib/model/ai-crm.d.ts +237 -0
- package/src/lib/model/ai-crm.js +225 -0
- package/src/lib/model/ai-crm.js.map +1 -0
- package/src/lib/model/ai-experiment-proposal.d.ts +68 -0
- package/src/lib/model/ai-experiment-proposal.js +146 -0
- package/src/lib/model/ai-experiment-proposal.js.map +1 -0
- package/src/lib/model/ai-experiment.d.ts +309 -0
- package/src/lib/model/ai-experiment.js +395 -0
- package/src/lib/model/ai-experiment.js.map +1 -0
- package/src/lib/model/ai-insight.d.ts +178 -0
- package/src/lib/model/ai-insight.js +201 -0
- package/src/lib/model/ai-insight.js.map +1 -0
- package/src/lib/model/ai-jobs.types.d.ts +412 -0
- package/src/lib/model/ai-jobs.types.js +42 -0
- package/src/lib/model/ai-jobs.types.js.map +1 -0
- package/src/lib/model/ai-page-job.d.ts +92 -0
- package/src/lib/model/ai-page-job.js +159 -0
- package/src/lib/model/ai-page-job.js.map +1 -0
- package/src/lib/model/ai-permissions.d.ts +49 -0
- package/src/lib/model/ai-permissions.js +97 -0
- package/src/lib/model/ai-permissions.js.map +1 -0
- package/src/lib/model/ai-plan-capabilities.d.ts +139 -0
- package/src/lib/model/ai-plan-capabilities.js +149 -0
- package/src/lib/model/ai-plan-capabilities.js.map +1 -0
- package/src/lib/model/ai-products.d.ts +251 -0
- package/src/lib/model/ai-products.js +253 -0
- package/src/lib/model/ai-products.js.map +1 -0
- package/src/lib/model/ai-seo.d.ts +208 -0
- package/src/lib/model/ai-seo.js +150 -0
- package/src/lib/model/ai-seo.js.map +1 -0
- package/src/lib/model/ai-site-inventory.d.ts +164 -0
- package/src/lib/model/ai-site-inventory.js +145 -0
- package/src/lib/model/ai-site-inventory.js.map +1 -0
- package/src/lib/model/ai-site-job.d.ts +247 -0
- package/src/lib/model/ai-site-job.js +314 -0
- package/src/lib/model/ai-site-job.js.map +1 -0
- package/src/lib/model/ai-site-start-seo.d.ts +103 -0
- package/src/lib/model/ai-site-start-seo.js +154 -0
- package/src/lib/model/ai-site-start-seo.js.map +1 -0
- package/src/lib/model/ai-site-start.d.ts +122 -0
- package/src/lib/model/ai-site-start.js +159 -0
- package/src/lib/model/ai-site-start.js.map +1 -0
- package/src/lib/model/ai-site-switch.d.ts +56 -0
- package/src/lib/model/ai-site-switch.js +73 -0
- package/src/lib/model/ai-site-switch.js.map +1 -0
- package/src/lib/model/ai-storefront-claims.d.ts +70 -0
- package/src/lib/model/ai-storefront-claims.js +130 -0
- package/src/lib/model/ai-storefront-claims.js.map +1 -0
- package/src/lib/model/ai-template-subjects.d.ts +82 -0
- package/src/lib/model/ai-template-subjects.js +136 -0
- package/src/lib/model/ai-template-subjects.js.map +1 -0
- package/src/lib/model/ai-theme-proposal.d.ts +210 -0
- package/src/lib/model/ai-theme-proposal.js +506 -0
- package/src/lib/model/ai-theme-proposal.js.map +1 -0
- package/src/lib/model/ai-tokens.d.ts +96 -0
- package/src/lib/model/ai-tokens.js +117 -0
- package/src/lib/model/ai-tokens.js.map +1 -0
- package/src/lib/model/ai-usage-by-user.d.ts +120 -0
- package/src/lib/model/ai-usage-by-user.js +139 -0
- package/src/lib/model/ai-usage-by-user.js.map +1 -0
- package/src/lib/model/ai-workflow-job.d.ts +111 -0
- package/src/lib/model/ai-workflow-job.js +183 -0
- package/src/lib/model/ai-workflow-job.js.map +1 -0
- package/src/lib/model/assist-edit.d.ts +261 -0
- package/src/lib/model/assist-edit.js +175 -0
- package/src/lib/model/assist-edit.js.map +1 -0
- package/src/lib/plugin-config.d.ts +33 -0
- package/src/lib/plugin-config.js +118 -0
- package/src/lib/plugin-config.js.map +1 -0
- package/src/lib/plugin.d.ts +30 -0
- package/src/lib/plugin.js +525 -0
- package/src/lib/plugin.js.map +1 -0
- package/src/lib/providers/anthropic.d.ts +84 -0
- package/src/lib/providers/anthropic.js +432 -0
- package/src/lib/providers/anthropic.js.map +1 -0
- package/src/lib/providers/catalog.d.ts +197 -0
- package/src/lib/providers/catalog.js +312 -0
- package/src/lib/providers/catalog.js.map +1 -0
- package/src/lib/providers/contract.d.ts +464 -0
- package/src/lib/providers/contract.js +274 -0
- package/src/lib/providers/contract.js.map +1 -0
- package/src/lib/providers/model-choice.d.ts +119 -0
- package/src/lib/providers/model-choice.js +416 -0
- package/src/lib/providers/model-choice.js.map +1 -0
- package/src/lib/providers/openai-compatible.d.ts +58 -0
- package/src/lib/providers/openai-compatible.js +361 -0
- package/src/lib/providers/openai-compatible.js.map +1 -0
- package/src/lib/providers/registry.d.ts +49 -0
- package/src/lib/providers/registry.js +71 -0
- package/src/lib/providers/registry.js.map +1 -0
- package/src/lib/providers/routing.d.ts +98 -0
- package/src/lib/providers/routing.js +450 -0
- package/src/lib/providers/routing.js.map +1 -0
- package/src/lib/runtime/ai-abuse-guards.d.ts +113 -0
- package/src/lib/runtime/ai-abuse-guards.js +148 -0
- package/src/lib/runtime/ai-abuse-guards.js.map +1 -0
- package/src/lib/runtime/ai-component-bindings.d.ts +67 -0
- package/src/lib/runtime/ai-component-bindings.js +106 -0
- package/src/lib/runtime/ai-component-bindings.js.map +1 -0
- package/src/lib/runtime/ai-device-audit.d.ts +109 -0
- package/src/lib/runtime/ai-device-audit.js +97 -0
- package/src/lib/runtime/ai-device-audit.js.map +1 -0
- package/src/lib/runtime/ai-doctrine-validators.d.ts +720 -0
- package/src/lib/runtime/ai-doctrine-validators.js +3133 -0
- package/src/lib/runtime/ai-doctrine-validators.js.map +1 -0
- package/src/lib/runtime/ai-doctrine.d.ts +372 -0
- package/src/lib/runtime/ai-doctrine.js +944 -0
- package/src/lib/runtime/ai-doctrine.js.map +1 -0
- package/src/lib/runtime/ai-eval-live.d.ts +321 -0
- package/src/lib/runtime/ai-eval-live.js +1257 -0
- package/src/lib/runtime/ai-eval-live.js.map +1 -0
- package/src/lib/runtime/ai-eval-memory-firestore.d.ts +51 -0
- package/src/lib/runtime/ai-eval-memory-firestore.js +183 -0
- package/src/lib/runtime/ai-eval-memory-firestore.js.map +1 -0
- package/src/lib/runtime/ai-eval.d.ts +441 -0
- package/src/lib/runtime/ai-eval.js +1151 -0
- package/src/lib/runtime/ai-eval.js.map +1 -0
- package/src/lib/runtime/ai-gate.d.ts +130 -0
- package/src/lib/runtime/ai-gate.js +272 -0
- package/src/lib/runtime/ai-gate.js.map +1 -0
- package/src/lib/runtime/ai-generation-bounds.d.ts +24 -0
- package/src/lib/runtime/ai-generation-bounds.js +23 -0
- package/src/lib/runtime/ai-generation-bounds.js.map +1 -0
- package/src/lib/runtime/ai-insight-check.d.ts +76 -0
- package/src/lib/runtime/ai-insight-check.js +281 -0
- package/src/lib/runtime/ai-insight-check.js.map +1 -0
- package/src/lib/runtime/ai-node-tree.d.ts +181 -0
- package/src/lib/runtime/ai-node-tree.js +931 -0
- package/src/lib/runtime/ai-node-tree.js.map +1 -0
- package/src/lib/runtime/ai-page-links.d.ts +79 -0
- package/src/lib/runtime/ai-page-links.js +135 -0
- package/src/lib/runtime/ai-page-links.js.map +1 -0
- package/src/lib/runtime/ai-palette.d.ts +252 -0
- package/src/lib/runtime/ai-palette.generated.d.ts +34 -0
- package/src/lib/runtime/ai-palette.generated.js +5263 -0
- package/src/lib/runtime/ai-palette.generated.js.map +1 -0
- package/src/lib/runtime/ai-palette.js +187 -0
- package/src/lib/runtime/ai-palette.js.map +1 -0
- package/src/lib/runtime/ai-products-generation.d.ts +107 -0
- package/src/lib/runtime/ai-products-generation.js +250 -0
- package/src/lib/runtime/ai-products-generation.js.map +1 -0
- package/src/lib/runtime/ai-repeated-items.d.ts +95 -0
- package/src/lib/runtime/ai-repeated-items.js +397 -0
- package/src/lib/runtime/ai-repeated-items.js.map +1 -0
- package/src/lib/runtime/ai-runtime.d.ts +148 -0
- package/src/lib/runtime/ai-runtime.js +237 -0
- package/src/lib/runtime/ai-runtime.js.map +1 -0
- package/src/lib/runtime/ai-template-examples.d.ts +71 -0
- package/src/lib/runtime/ai-template-examples.js +135 -0
- package/src/lib/runtime/ai-template-examples.js.map +1 -0
- package/src/lib/runtime/assist-answer-cache.d.ts +80 -0
- package/src/lib/runtime/assist-answer-cache.js +184 -0
- package/src/lib/runtime/assist-answer-cache.js.map +1 -0
- package/src/lib/runtime/seo-audit.d.ts +93 -0
- package/src/lib/runtime/seo-audit.js +260 -0
- package/src/lib/runtime/seo-audit.js.map +1 -0
- package/src/lib/runtime/seo-content-fixes.d.ts +41 -0
- package/src/lib/runtime/seo-content-fixes.js +168 -0
- package/src/lib/runtime/seo-content-fixes.js.map +1 -0
- package/src/lib/runtime/seo-fields.d.ts +152 -0
- package/src/lib/runtime/seo-fields.js +215 -0
- package/src/lib/runtime/seo-fields.js.map +1 -0
- package/src/lib/runtime/seo-page-facts.d.ts +61 -0
- package/src/lib/runtime/seo-page-facts.js +150 -0
- package/src/lib/runtime/seo-page-facts.js.map +1 -0
- package/src/lib/runtime/site-inventory.d.ts +63 -0
- package/src/lib/runtime/site-inventory.js +230 -0
- package/src/lib/runtime/site-inventory.js.map +1 -0
- package/src/lib/server/ai-admin-org.d.ts +33 -0
- package/src/lib/server/ai-admin-org.js +381 -0
- package/src/lib/server/ai-admin-org.js.map +1 -0
- package/src/lib/server/ai-admin-orgs-spend.d.ts +40 -0
- package/src/lib/server/ai-admin-orgs-spend.js +129 -0
- package/src/lib/server/ai-admin-orgs-spend.js.map +1 -0
- package/src/lib/server/ai-admin-overage.d.ts +19 -0
- package/src/lib/server/ai-admin-overage.js +246 -0
- package/src/lib/server/ai-admin-overage.js.map +1 -0
- package/src/lib/server/ai-admin-signals.d.ts +34 -0
- package/src/lib/server/ai-admin-signals.js +330 -0
- package/src/lib/server/ai-admin-signals.js.map +1 -0
- package/src/lib/server/ai-admin-user.d.ts +27 -0
- package/src/lib/server/ai-admin-user.js +128 -0
- package/src/lib/server/ai-admin-user.js.map +1 -0
- package/src/lib/server/ai-allotments.d.ts +27 -0
- package/src/lib/server/ai-allotments.js +544 -0
- package/src/lib/server/ai-allotments.js.map +1 -0
- package/src/lib/server/ai-assist-prompts.d.ts +102 -0
- package/src/lib/server/ai-assist-prompts.js +207 -0
- package/src/lib/server/ai-assist-prompts.js.map +1 -0
- package/src/lib/server/ai-assist.d.ts +119 -0
- package/src/lib/server/ai-assist.js +517 -0
- package/src/lib/server/ai-assist.js.map +1 -0
- package/src/lib/server/ai-crm-answer.d.ts +30 -0
- package/src/lib/server/ai-crm-answer.js +98 -0
- package/src/lib/server/ai-crm-answer.js.map +1 -0
- package/src/lib/server/ai-generate-component.d.ts +111 -0
- package/src/lib/server/ai-generate-component.js +643 -0
- package/src/lib/server/ai-generate-component.js.map +1 -0
- package/src/lib/server/ai-host-permissions.d.ts +46 -0
- package/src/lib/server/ai-host-permissions.js +204 -0
- package/src/lib/server/ai-host-permissions.js.map +1 -0
- package/src/lib/server/ai-insight-answer.d.ts +30 -0
- package/src/lib/server/ai-insight-answer.js +83 -0
- package/src/lib/server/ai-insight-answer.js.map +1 -0
- package/src/lib/server/ai-insight-digest-route.d.ts +30 -0
- package/src/lib/server/ai-insight-digest-route.js +156 -0
- package/src/lib/server/ai-insight-digest-route.js.map +1 -0
- package/src/lib/server/ai-jobs-batch.d.ts +48 -0
- package/src/lib/server/ai-jobs-batch.js +306 -0
- package/src/lib/server/ai-jobs-batch.js.map +1 -0
- package/src/lib/server/ai-jobs-beat-route.d.ts +36 -0
- package/src/lib/server/ai-jobs-beat-route.js +86 -0
- package/src/lib/server/ai-jobs-beat-route.js.map +1 -0
- package/src/lib/server/ai-jobs-cancel.d.ts +30 -0
- package/src/lib/server/ai-jobs-cancel.js +74 -0
- package/src/lib/server/ai-jobs-cancel.js.map +1 -0
- package/src/lib/server/ai-jobs-events-route.d.ts +31 -0
- package/src/lib/server/ai-jobs-events-route.js +51 -0
- package/src/lib/server/ai-jobs-events-route.js.map +1 -0
- package/src/lib/server/ai-jobs-events.d.ts +55 -0
- package/src/lib/server/ai-jobs-events.js +144 -0
- package/src/lib/server/ai-jobs-events.js.map +1 -0
- package/src/lib/server/ai-jobs-gate.d.ts +47 -0
- package/src/lib/server/ai-jobs-gate.js +106 -0
- package/src/lib/server/ai-jobs-gate.js.map +1 -0
- package/src/lib/server/ai-jobs-resume.d.ts +23 -0
- package/src/lib/server/ai-jobs-resume.js +209 -0
- package/src/lib/server/ai-jobs-resume.js.map +1 -0
- package/src/lib/server/ai-jobs-route.d.ts +32 -0
- package/src/lib/server/ai-jobs-route.js +307 -0
- package/src/lib/server/ai-jobs-route.js.map +1 -0
- package/src/lib/server/ai-models.d.ts +18 -0
- package/src/lib/server/ai-models.js +134 -0
- package/src/lib/server/ai-models.js.map +1 -0
- package/src/lib/server/ai-seo-apply.d.ts +53 -0
- package/src/lib/server/ai-seo-apply.js +294 -0
- package/src/lib/server/ai-seo-apply.js.map +1 -0
- package/src/lib/server/ai-usage.d.ts +18 -0
- package/src/lib/server/ai-usage.js +220 -0
- package/src/lib/server/ai-usage.js.map +1 -0
- package/src/lib/server/assist-chat.d.ts +234 -0
- package/src/lib/server/assist-chat.js +1446 -0
- package/src/lib/server/assist-chat.js.map +1 -0
- package/src/lib/server/assist-edit-applied.d.ts +22 -0
- package/src/lib/server/assist-edit-applied.js +239 -0
- package/src/lib/server/assist-edit-applied.js.map +1 -0
- package/src/lib/server/assist-edit.d.ts +124 -0
- package/src/lib/server/assist-edit.js +1000 -0
- package/src/lib/server/assist-edit.js.map +1 -0
- package/src/lib/server/assist-feedback.d.ts +31 -0
- package/src/lib/server/assist-feedback.js +115 -0
- package/src/lib/server/assist-feedback.js.map +1 -0
- package/src/lib/server/assist-view-context.d.ts +343 -0
- package/src/lib/server/assist-view-context.js +690 -0
- package/src/lib/server/assist-view-context.js.map +1 -0
- package/src/lib/server/billing-credits.d.ts +59 -0
- package/src/lib/server/billing-credits.js +146 -0
- package/src/lib/server/billing-credits.js.map +1 -0
- package/src/lib/server/billing-overage.d.ts +19 -0
- package/src/lib/server/billing-overage.js +337 -0
- package/src/lib/server/billing-overage.js.map +1 -0
- package/src/lib/server.d.ts +32 -0
- package/src/lib/server.js +265 -0
- package/src/lib/server.js.map +1 -0
- package/src/lib/subprocessors.d.ts +18 -0
- package/src/lib/subprocessors.js +52 -0
- package/src/lib/subprocessors.js.map +1 -0
- package/src/lib/tools/ai-component-tool.d.ts +99 -0
- package/src/lib/tools/ai-component-tool.js +369 -0
- package/src/lib/tools/ai-component-tool.js.map +1 -0
- package/src/lib/tools/ai-crm-tool.d.ts +106 -0
- package/src/lib/tools/ai-crm-tool.js +488 -0
- package/src/lib/tools/ai-crm-tool.js.map +1 -0
- package/src/lib/tools/ai-duplicate-resource-tool.d.ts +71 -0
- package/src/lib/tools/ai-duplicate-resource-tool.js +164 -0
- package/src/lib/tools/ai-duplicate-resource-tool.js.map +1 -0
- package/src/lib/tools/ai-experiment-tool.d.ts +40 -0
- package/src/lib/tools/ai-experiment-tool.js +155 -0
- package/src/lib/tools/ai-experiment-tool.js.map +1 -0
- package/src/lib/tools/ai-insight-tool.d.ts +46 -0
- package/src/lib/tools/ai-insight-tool.js +200 -0
- package/src/lib/tools/ai-insight-tool.js.map +1 -0
- package/src/lib/tools/ai-inventory-lookup-tool.d.ts +86 -0
- package/src/lib/tools/ai-inventory-lookup-tool.js +164 -0
- package/src/lib/tools/ai-inventory-lookup-tool.js.map +1 -0
- package/src/lib/tools/ai-products-tool.d.ts +65 -0
- package/src/lib/tools/ai-products-tool.js +644 -0
- package/src/lib/tools/ai-products-tool.js.map +1 -0
- package/src/lib/tools/ai-seo-tool.d.ts +162 -0
- package/src/lib/tools/ai-seo-tool.js +546 -0
- package/src/lib/tools/ai-seo-tool.js.map +1 -0
- package/src/lib/tools/ai-theme-tool.d.ts +101 -0
- package/src/lib/tools/ai-theme-tool.js +562 -0
- package/src/lib/tools/ai-theme-tool.js.map +1 -0
- package/src/lib/tools/ai-workflow-tool.d.ts +166 -0
- package/src/lib/tools/ai-workflow-tool.js +860 -0
- package/src/lib/tools/ai-workflow-tool.js.map +1 -0
- package/src/lib/usage/ai-allotment-alerts.d.ts +72 -0
- package/src/lib/usage/ai-allotment-alerts.js +157 -0
- package/src/lib/usage/ai-allotment-alerts.js.map +1 -0
- package/src/lib/usage/ai-allotments.d.ts +125 -0
- package/src/lib/usage/ai-allotments.js +239 -0
- package/src/lib/usage/ai-allotments.js.map +1 -0
- package/src/lib/usage/ai-model-sample.d.ts +36 -0
- package/src/lib/usage/ai-model-sample.js +68 -0
- package/src/lib/usage/ai-model-sample.js.map +1 -0
- package/src/lib/usage/ai-usage-alerts.d.ts +55 -0
- package/src/lib/usage/ai-usage-alerts.js +114 -0
- package/src/lib/usage/ai-usage-alerts.js.map +1 -0
- package/src/lib/usage/ai-usage-by-user.d.ts +161 -0
- package/src/lib/usage/ai-usage-by-user.js +211 -0
- package/src/lib/usage/ai-usage-by-user.js.map +1 -0
- package/src/lib/usage/ai-usage-eraser.d.ts +29 -0
- package/src/lib/usage/ai-usage-eraser.js +40 -0
- package/src/lib/usage/ai-usage-eraser.js.map +1 -0
- package/src/lib/usage/ai-usage-meter.d.ts +39 -0
- package/src/lib/usage/ai-usage-meter.js +85 -0
- package/src/lib/usage/ai-usage-meter.js.map +1 -0
- package/src/lib/usage/ai-usage-wire.d.ts +184 -0
- package/src/lib/usage/ai-usage-wire.js +98 -0
- package/src/lib/usage/ai-usage-wire.js.map +1 -0
- package/src/lib/usage/assist-ceiling.d.ts +87 -0
- package/src/lib/usage/assist-ceiling.js +110 -0
- package/src/lib/usage/assist-ceiling.js.map +1 -0
- package/src/lib/usage/assist-free-taste.d.ts +225 -0
- package/src/lib/usage/assist-free-taste.js +308 -0
- package/src/lib/usage/assist-free-taste.js.map +1 -0
- package/src/lib/usage/assist-refusals.d.ts +69 -0
- package/src/lib/usage/assist-refusals.js +79 -0
- package/src/lib/usage/assist-refusals.js.map +1 -0
- package/src/lib/usage/assist-signal-mining.d.ts +375 -0
- package/src/lib/usage/assist-signal-mining.js +344 -0
- package/src/lib/usage/assist-signal-mining.js.map +1 -0
- package/src/lib/usage/assist-usage.d.ts +571 -0
- package/src/lib/usage/assist-usage.js +978 -0
- package/src/lib/usage/assist-usage.js.map +1 -0
- package/src/lib/usage/staff-org-ai.d.ts +242 -0
- package/src/lib/usage/staff-org-ai.js +173 -0
- package/src/lib/usage/staff-org-ai.js.map +1 -0
- package/src/lib/usage/staff-org-usage-ai.d.ts +83 -0
- package/src/lib/usage/staff-org-usage-ai.js +59 -0
- package/src/lib/usage/staff-org-usage-ai.js.map +1 -0
- package/src/lib/usage/staff-orgs-ai-spend.d.ts +83 -0
- package/src/lib/usage/staff-orgs-ai-spend.js +114 -0
- package/src/lib/usage/staff-orgs-ai-spend.js.map +1 -0
|
@@ -0,0 +1,148 @@
|
|
|
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 { resolveEffectivePlan } from "@aglyn/aglyn/app-utils/plan-entitlements";
|
|
17
|
+
import { readClientIp } from "@aglyn/aglyn/app-utils/request-ip";
|
|
18
|
+
import { checkRateLimit } from "@aglyn/tenant-data-admin/server/api-http";
|
|
19
|
+
/**
|
|
20
|
+
* The request-level rungs the Free AI taste adds to every AI door
|
|
21
|
+
* (AGL-2925): a per-address limiter and a minimum account age. Both are
|
|
22
|
+
* small helpers a door calls from its ladder rather than rungs written
|
|
23
|
+
* into each ladder, so the three doors and the shared gate cannot drift
|
|
24
|
+
* into three limits.
|
|
25
|
+
*
|
|
26
|
+
* Neither touches Firestore. The limiter is the same per-instance window
|
|
27
|
+
* as the per-uid one and carries the same caveat — it smooths bursts and is
|
|
28
|
+
* not the spend bound; the reservation is. The account-age rung reads one
|
|
29
|
+
* Auth record, cached per instance, and applies only to a Free workspace.
|
|
30
|
+
*/ /** Requests one client address may make against the AI doors a minute. */ export const AI_IP_RATE_LIMIT = 60;
|
|
31
|
+
export const AI_IP_RATE_WINDOW_MS = 60000;
|
|
32
|
+
/**
|
|
33
|
+
* The per-address window shared by every AI door.
|
|
34
|
+
*
|
|
35
|
+
* Keyed on the TRUSTED-HOP client address (`readClientIp`), never on a
|
|
36
|
+
* header a caller can write, for the reason that module exists: on an
|
|
37
|
+
* appending proxy the leftmost `x-forwarded-for` hop is whatever the caller
|
|
38
|
+
* typed, and a limiter keyed on it hands out a fresh budget per request.
|
|
39
|
+
* `null` when no address is readable — the caller skips the rung, because
|
|
40
|
+
* keying every anonymous request under one placeholder caps the whole
|
|
41
|
+
* install at sixty requests a minute.
|
|
42
|
+
*
|
|
43
|
+
* Sixty a minute is three times the per-uid window (20/min at each door):
|
|
44
|
+
* an office NAT signing in a team of three fits under it, and a farm
|
|
45
|
+
* rotating accounts behind one address does not.
|
|
46
|
+
*/ export function checkAiClientIpRateLimit(headers) {
|
|
47
|
+
const ip = readClientIp(headers);
|
|
48
|
+
if (!ip) return null;
|
|
49
|
+
return checkRateLimit(`ai-ip:${ip}`, {
|
|
50
|
+
limit: AI_IP_RATE_LIMIT,
|
|
51
|
+
windowMs: AI_IP_RATE_WINDOW_MS
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* How old an account must be before a Free workspace it belongs to may
|
|
56
|
+
* generate (`AI_FREE_MIN_ACCOUNT_AGE_HOURS`, default 24).
|
|
57
|
+
*
|
|
58
|
+
* The signup surface already costs a working inbox per account; a day of
|
|
59
|
+
* age costs a day, which is the one thing a script minting accounts cannot
|
|
60
|
+
* buy in bulk. Paid workspaces never consult it. Zero switches the rung
|
|
61
|
+
* off, which a self-hoster running an invite-only deployment may
|
|
62
|
+
* reasonably want; junk and an empty value take the default.
|
|
63
|
+
*/ export function aiFreeMinAccountAgeHours() {
|
|
64
|
+
const raw = process.env.AI_FREE_MIN_ACCOUNT_AGE_HOURS;
|
|
65
|
+
const parsed = raw ? Number(raw) : Number.NaN;
|
|
66
|
+
return Number.isFinite(parsed) && parsed >= 0 ? parsed : 24;
|
|
67
|
+
}
|
|
68
|
+
/** How long one account's creation time is remembered per instance. */ export const ACCOUNT_AGE_CACHE_TTL_MS = 5 * 60 * 1000;
|
|
69
|
+
/**
|
|
70
|
+
* Entries the cache holds before it is dropped whole. A creation time is a
|
|
71
|
+
* few bytes, but a limiter that can be made to remember every uid ever
|
|
72
|
+
* seen is a memory leak with a use case, so the map is bounded and simply
|
|
73
|
+
* forgets everything when it fills — the next request re-reads.
|
|
74
|
+
*/ export const ACCOUNT_AGE_CACHE_MAX_ENTRIES = 5000;
|
|
75
|
+
let accountAgeCache = new Map();
|
|
76
|
+
/** Test seam — drops the per-instance cache. */ export function resetAccountAgeCache() {
|
|
77
|
+
accountAgeCache = new Map();
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* When the account was created, in epoch milliseconds, or `null` when the
|
|
81
|
+
* record carries no usable creation time.
|
|
82
|
+
*
|
|
83
|
+
* Read through the caller's `getUser` — the Auth pool the token was minted
|
|
84
|
+
* in — because the decoded token carries `auth_time` (this sign-in) and
|
|
85
|
+
* not the account's creation, and a fresh account can sign in as often as
|
|
86
|
+
* it likes. Cached per instance for a few minutes: the value never changes,
|
|
87
|
+
* and the doors are called far more often than once per account.
|
|
88
|
+
*/ export async function accountCreationTimeMs(uid, getUser, now = Date.now()) {
|
|
89
|
+
var _ref;
|
|
90
|
+
var _record_metadata;
|
|
91
|
+
const cached = accountAgeCache.get(uid);
|
|
92
|
+
if (cached && now - cached.at < ACCOUNT_AGE_CACHE_TTL_MS) {
|
|
93
|
+
return cached.creationTimeMs;
|
|
94
|
+
}
|
|
95
|
+
const record = await getUser(uid);
|
|
96
|
+
const creationTimeMs = Date.parse((_ref = (_record_metadata = record.metadata) == null ? void 0 : _record_metadata.creationTime) != null ? _ref : '');
|
|
97
|
+
if (!Number.isFinite(creationTimeMs)) return null;
|
|
98
|
+
if (accountAgeCache.size >= ACCOUNT_AGE_CACHE_MAX_ENTRIES) resetAccountAgeCache();
|
|
99
|
+
accountAgeCache.set(uid, {
|
|
100
|
+
creationTimeMs,
|
|
101
|
+
at: now
|
|
102
|
+
});
|
|
103
|
+
return creationTimeMs;
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* The account-age rung: the `Response` to send, or `null` to climb on.
|
|
107
|
+
*
|
|
108
|
+
* Applies to a FREE workspace only — `resolveEffectivePlan`, so a dead
|
|
109
|
+
* subscription is Free here as everywhere — and never to staff, who are
|
|
110
|
+
* the ones verifying the fix during an incident. An account younger than
|
|
111
|
+
* the minimum is a 403 with `reason: 'account-age'`, and the sentence says
|
|
112
|
+
* when to come back rather than hinting at a way around it.
|
|
113
|
+
*
|
|
114
|
+
* Fails CLOSED for a Free workspace: a record that cannot be read is a
|
|
115
|
+
* 503, not an admission. The verifier just accepted this token from the
|
|
116
|
+
* same Auth service, so the read failing is rare, and the rung exists
|
|
117
|
+
* precisely for the request whose age cannot be vouched for. A paid
|
|
118
|
+
* workspace never reaches the read.
|
|
119
|
+
*/ export async function freeAccountAgeRefusal(input) {
|
|
120
|
+
var _input_now;
|
|
121
|
+
if (input.staff) return null;
|
|
122
|
+
if (resolveEffectivePlan(input.org) !== 'free') return null;
|
|
123
|
+
const hours = aiFreeMinAccountAgeHours();
|
|
124
|
+
if (hours <= 0) return null;
|
|
125
|
+
const now = (_input_now = input.now) != null ? _input_now : new Date();
|
|
126
|
+
let createdMs;
|
|
127
|
+
try {
|
|
128
|
+
createdMs = await accountCreationTimeMs(input.uid, input.getUser, now.getTime());
|
|
129
|
+
} catch (error) {
|
|
130
|
+
console.error('[ai-abuse-guards] account age unavailable', error);
|
|
131
|
+
return Response.json({
|
|
132
|
+
error: 'This feature is temporarily unavailable'
|
|
133
|
+
}, {
|
|
134
|
+
status: 503
|
|
135
|
+
});
|
|
136
|
+
}
|
|
137
|
+
const ageMs = createdMs === null ? 0 : now.getTime() - createdMs;
|
|
138
|
+
if (ageMs >= hours * 60 * 60 * 1000) return null;
|
|
139
|
+
const label = hours === 1 ? '1 hour' : `${hours} hours`;
|
|
140
|
+
return Response.json({
|
|
141
|
+
error: `AI generation opens ${label} after an account is created — ` + 'come back then, or upgrade this workspace to use it now.',
|
|
142
|
+
reason: 'account-age'
|
|
143
|
+
}, {
|
|
144
|
+
status: 403
|
|
145
|
+
});
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
//# sourceMappingURL=ai-abuse-guards.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../../../../libs/plugins/ai/src/lib/runtime/ai-abuse-guards.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 { resolveEffectivePlan } from '@aglyn/aglyn/app-utils/plan-entitlements'\nimport {\n readClientIp,\n type ClientIpHeaders,\n} from '@aglyn/aglyn/app-utils/request-ip'\nimport type { AglynOrgBilling } from '@aglyn/aglyn/foundation/definitions/org-billing.types'\nimport { checkRateLimit, type RateLimitResult } from '@aglyn/tenant-data-admin/server/api-http'\n\n/**\n * The request-level rungs the Free AI taste adds to every AI door\n * (AGL-2925): a per-address limiter and a minimum account age. Both are\n * small helpers a door calls from its ladder rather than rungs written\n * into each ladder, so the three doors and the shared gate cannot drift\n * into three limits.\n *\n * Neither touches Firestore. The limiter is the same per-instance window\n * as the per-uid one and carries the same caveat — it smooths bursts and is\n * not the spend bound; the reservation is. The account-age rung reads one\n * Auth record, cached per instance, and applies only to a Free workspace.\n */\n\n/** Requests one client address may make against the AI doors a minute. */\nexport const AI_IP_RATE_LIMIT = 60\nexport const AI_IP_RATE_WINDOW_MS = 60_000\n\n/**\n * The per-address window shared by every AI door.\n *\n * Keyed on the TRUSTED-HOP client address (`readClientIp`), never on a\n * header a caller can write, for the reason that module exists: on an\n * appending proxy the leftmost `x-forwarded-for` hop is whatever the caller\n * typed, and a limiter keyed on it hands out a fresh budget per request.\n * `null` when no address is readable — the caller skips the rung, because\n * keying every anonymous request under one placeholder caps the whole\n * install at sixty requests a minute.\n *\n * Sixty a minute is three times the per-uid window (20/min at each door):\n * an office NAT signing in a team of three fits under it, and a farm\n * rotating accounts behind one address does not.\n */\nexport function checkAiClientIpRateLimit(\n headers: ClientIpHeaders,\n): RateLimitResult | null {\n const ip = readClientIp(headers)\n if (!ip) return null\n return checkRateLimit(`ai-ip:${ip}`, {\n limit: AI_IP_RATE_LIMIT,\n windowMs: AI_IP_RATE_WINDOW_MS,\n })\n}\n\n/**\n * How old an account must be before a Free workspace it belongs to may\n * generate (`AI_FREE_MIN_ACCOUNT_AGE_HOURS`, default 24).\n *\n * The signup surface already costs a working inbox per account; a day of\n * age costs a day, which is the one thing a script minting accounts cannot\n * buy in bulk. Paid workspaces never consult it. Zero switches the rung\n * off, which a self-hoster running an invite-only deployment may\n * reasonably want; junk and an empty value take the default.\n */\nexport function aiFreeMinAccountAgeHours(): number {\n const raw = process.env.AI_FREE_MIN_ACCOUNT_AGE_HOURS\n const parsed = raw ? Number(raw) : Number.NaN\n return Number.isFinite(parsed) && parsed >= 0 ? parsed : 24\n}\n\n/** How long one account's creation time is remembered per instance. */\nexport const ACCOUNT_AGE_CACHE_TTL_MS = 5 * 60 * 1000\n\n/**\n * Entries the cache holds before it is dropped whole. A creation time is a\n * few bytes, but a limiter that can be made to remember every uid ever\n * seen is a memory leak with a use case, so the map is bounded and simply\n * forgets everything when it fills — the next request re-reads.\n */\nexport const ACCOUNT_AGE_CACHE_MAX_ENTRIES = 5_000\n\nlet accountAgeCache = new Map<string, { creationTimeMs: number; at: number }>()\n\n/** Test seam — drops the per-instance cache. */\nexport function resetAccountAgeCache(): void {\n accountAgeCache = new Map()\n}\n\n/** The one thing this rung reads off an Auth record. */\nexport interface AccountAgeLookup {\n (uid: string): Promise<{ metadata: { creationTime?: string | null } }>\n}\n\n/**\n * When the account was created, in epoch milliseconds, or `null` when the\n * record carries no usable creation time.\n *\n * Read through the caller's `getUser` — the Auth pool the token was minted\n * in — because the decoded token carries `auth_time` (this sign-in) and\n * not the account's creation, and a fresh account can sign in as often as\n * it likes. Cached per instance for a few minutes: the value never changes,\n * and the doors are called far more often than once per account.\n */\nexport async function accountCreationTimeMs(\n uid: string,\n getUser: AccountAgeLookup,\n now = Date.now(),\n): Promise<number | null> {\n const cached = accountAgeCache.get(uid)\n if (cached && now - cached.at < ACCOUNT_AGE_CACHE_TTL_MS) {\n return cached.creationTimeMs\n }\n const record = await getUser(uid)\n const creationTimeMs = Date.parse(record.metadata?.creationTime ?? '')\n if (!Number.isFinite(creationTimeMs)) return null\n if (accountAgeCache.size >= ACCOUNT_AGE_CACHE_MAX_ENTRIES) resetAccountAgeCache()\n accountAgeCache.set(uid, { creationTimeMs, at: now })\n return creationTimeMs\n}\n\n/**\n * The account-age rung: the `Response` to send, or `null` to climb on.\n *\n * Applies to a FREE workspace only — `resolveEffectivePlan`, so a dead\n * subscription is Free here as everywhere — and never to staff, who are\n * the ones verifying the fix during an incident. An account younger than\n * the minimum is a 403 with `reason: 'account-age'`, and the sentence says\n * when to come back rather than hinting at a way around it.\n *\n * Fails CLOSED for a Free workspace: a record that cannot be read is a\n * 503, not an admission. The verifier just accepted this token from the\n * same Auth service, so the read failing is rare, and the rung exists\n * precisely for the request whose age cannot be vouched for. A paid\n * workspace never reaches the read.\n */\nexport async function freeAccountAgeRefusal(input: {\n uid: string\n org: Partial<AglynOrgBilling> | null | undefined\n staff: boolean\n getUser: AccountAgeLookup\n now?: Date\n}): Promise<Response | null> {\n if (input.staff) return null\n if (resolveEffectivePlan(input.org) !== 'free') return null\n const hours = aiFreeMinAccountAgeHours()\n if (hours <= 0) return null\n const now = input.now ?? new Date()\n let createdMs: number | null\n try {\n createdMs = await accountCreationTimeMs(input.uid, input.getUser, now.getTime())\n } catch (error) {\n console.error('[ai-abuse-guards] account age unavailable', error)\n return Response.json(\n { error: 'This feature is temporarily unavailable' },\n { status: 503 },\n )\n }\n const ageMs = createdMs === null ? 0 : now.getTime() - createdMs\n if (ageMs >= hours * 60 * 60 * 1000) return null\n const label = hours === 1 ? '1 hour' : `${hours} hours`\n return Response.json(\n {\n error:\n `AI generation opens ${label} after an account is created — ` +\n 'come back then, or upgrade this workspace to use it now.',\n reason: 'account-age',\n },\n { status: 403 },\n )\n}\n"],"names":["resolveEffectivePlan","readClientIp","checkRateLimit","AI_IP_RATE_LIMIT","AI_IP_RATE_WINDOW_MS","checkAiClientIpRateLimit","headers","ip","limit","windowMs","aiFreeMinAccountAgeHours","raw","process","env","AI_FREE_MIN_ACCOUNT_AGE_HOURS","parsed","Number","NaN","isFinite","ACCOUNT_AGE_CACHE_TTL_MS","ACCOUNT_AGE_CACHE_MAX_ENTRIES","accountAgeCache","Map","resetAccountAgeCache","accountCreationTimeMs","uid","getUser","now","Date","record","cached","get","at","creationTimeMs","parse","metadata","creationTime","size","set","freeAccountAgeRefusal","input","staff","org","hours","createdMs","getTime","error","console","Response","json","status","ageMs","label","reason"],"mappings":"AAAA;;;;;;;;;;;;;;;CAeC,GAED,SAASA,oBAAoB,QAAQ,2CAA0C;AAC/E,SACEC,YAAY,QAEP,oCAAmC;AAE1C,SAASC,cAAc,QAA8B,2CAA0C;AAE/F;;;;;;;;;;;CAWC,GAED,wEAAwE,GACxE,OAAO,MAAMC,mBAAmB,GAAE;AAClC,OAAO,MAAMC,uBAAuB,MAAM;AAE1C;;;;;;;;;;;;;;CAcC,GACD,OAAO,SAASC,yBACdC,OAAwB;IAExB,MAAMC,KAAKN,aAAaK;IACxB,IAAI,CAACC,IAAI,OAAO;IAChB,OAAOL,eAAe,CAAC,MAAM,EAAEK,IAAI,EAAE;QACnCC,OAAOL;QACPM,UAAUL;IACZ;AACF;AAEA;;;;;;;;;CASC,GACD,OAAO,SAASM;IACd,MAAMC,MAAMC,QAAQC,GAAG,CAACC,6BAA6B;IACrD,MAAMC,SAASJ,MAAMK,OAAOL,OAAOK,OAAOC,GAAG;IAC7C,OAAOD,OAAOE,QAAQ,CAACH,WAAWA,UAAU,IAAIA,SAAS;AAC3D;AAEA,qEAAqE,GACrE,OAAO,MAAMI,2BAA2B,IAAI,KAAK,KAAI;AAErD;;;;;CAKC,GACD,OAAO,MAAMC,gCAAgC,KAAK;AAElD,IAAIC,kBAAkB,IAAIC;AAE1B,8CAA8C,GAC9C,OAAO,SAASC;IACdF,kBAAkB,IAAIC;AACxB;AAOA;;;;;;;;;CASC,GACD,OAAO,eAAeE,sBACpBC,GAAW,EACXC,OAAyB,EACzBC,MAAMC,KAAKD,GAAG,EAAE;;QAOkBE;IALlC,MAAMC,SAAST,gBAAgBU,GAAG,CAACN;IACnC,IAAIK,UAAUH,MAAMG,OAAOE,EAAE,GAAGb,0BAA0B;QACxD,OAAOW,OAAOG,cAAc;IAC9B;IACA,MAAMJ,SAAS,MAAMH,QAAQD;IAC7B,MAAMQ,iBAAiBL,KAAKM,KAAK,UAACL,mBAAAA,OAAOM,QAAQ,qBAAfN,iBAAiBO,YAAY,mBAAI;IACnE,IAAI,CAACpB,OAAOE,QAAQ,CAACe,iBAAiB,OAAO;IAC7C,IAAIZ,gBAAgBgB,IAAI,IAAIjB,+BAA+BG;IAC3DF,gBAAgBiB,GAAG,CAACb,KAAK;QAAEQ;QAAgBD,IAAIL;IAAI;IACnD,OAAOM;AACT;AAEA;;;;;;;;;;;;;;CAcC,GACD,OAAO,eAAeM,sBAAsBC,KAM3C;QAKaA;IAJZ,IAAIA,MAAMC,KAAK,EAAE,OAAO;IACxB,IAAIzC,qBAAqBwC,MAAME,GAAG,MAAM,QAAQ,OAAO;IACvD,MAAMC,QAAQjC;IACd,IAAIiC,SAAS,GAAG,OAAO;IACvB,MAAMhB,OAAMa,aAAAA,MAAMb,GAAG,YAATa,aAAa,IAAIZ;IAC7B,IAAIgB;IACJ,IAAI;QACFA,YAAY,MAAMpB,sBAAsBgB,MAAMf,GAAG,EAAEe,MAAMd,OAAO,EAAEC,IAAIkB,OAAO;IAC/E,EAAE,OAAOC,OAAO;QACdC,QAAQD,KAAK,CAAC,6CAA6CA;QAC3D,OAAOE,SAASC,IAAI,CAClB;YAAEH,OAAO;QAA0C,GACnD;YAAEI,QAAQ;QAAI;IAElB;IACA,MAAMC,QAAQP,cAAc,OAAO,IAAIjB,IAAIkB,OAAO,KAAKD;IACvD,IAAIO,SAASR,QAAQ,KAAK,KAAK,MAAM,OAAO;IAC5C,MAAMS,QAAQT,UAAU,IAAI,WAAW,GAAGA,MAAM,MAAM,CAAC;IACvD,OAAOK,SAASC,IAAI,CAClB;QACEH,OACE,CAAC,oBAAoB,EAAEM,MAAM,+BAA+B,CAAC,GAC7D;QACFC,QAAQ;IACV,GACA;QAAEH,QAAQ;IAAI;AAElB"}
|
|
@@ -0,0 +1,67 @@
|
|
|
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 { ReusableComponentProp } from '@aglyn/aglyn/foundation/definitions/platform.types';
|
|
18
|
+
import type { AiPaletteEntry } from './ai-palette';
|
|
19
|
+
/**
|
|
20
|
+
* Which field of a generated reusable component may carry which of the
|
|
21
|
+
* component's own properties (AGL-2908).
|
|
22
|
+
*
|
|
23
|
+
* A component's tree reaches its properties through `{{prop.<name>}}` tokens,
|
|
24
|
+
* and the graft hands each field the value its property's kind holds
|
|
25
|
+
* (`resolveComponentPropTokens`). So a binding is right only where the field
|
|
26
|
+
* can show that value:
|
|
27
|
+
*
|
|
28
|
+
* - A field that is not typed into — a switch, a dropdown, a screen picker, a
|
|
29
|
+
* slider — takes exactly the properties the Attributes panel offers it
|
|
30
|
+
* under its `{}` (AGL-2871): `reusablePropBindsToField`, the editor's own
|
|
31
|
+
* judgment, over the field kind the palette records. The token is the
|
|
32
|
+
* field's whole value.
|
|
33
|
+
* - A field that is typed into takes any token in the editor. A generated
|
|
34
|
+
* binding is held to what reads right there: copy in copy (Text, Long text
|
|
35
|
+
* or Number, whole or inside a sentence), a picture as an image's source
|
|
36
|
+
* and a link as an address, each as the whole value.
|
|
37
|
+
* - The visibility directives are switches the graft reads before anything
|
|
38
|
+
* renders: `hideIf` takes a Yes / no, and `hideUnless` a Link, whose
|
|
39
|
+
* absence hides the part.
|
|
40
|
+
*
|
|
41
|
+
* Pure: the palette validator reads it to keep a token as written, and the
|
|
42
|
+
* component step's check reads it to hold each token to its property.
|
|
43
|
+
*/
|
|
44
|
+
/** A declared property, as a binding reads it. */
|
|
45
|
+
export type AiComponentPropBinding = Pick<ReusableComponentProp, 'name' | 'type' | 'options' | 'settings'>;
|
|
46
|
+
/** Where a token sits in a field's value: the whole value, or inside copy. */
|
|
47
|
+
export type AiComponentPropPlacement = 'whole' | 'inside';
|
|
48
|
+
/** The node props a component's tree may bind that no element declares. */
|
|
49
|
+
export declare const AI_COMPONENT_VISIBILITY_PROPS: readonly string[];
|
|
50
|
+
/** Kinds whose value reads as copy, which copy may carry inside a sentence. */
|
|
51
|
+
export declare const AI_COMPONENT_COPY_KINDS: ReadonlySet<string>;
|
|
52
|
+
/** Where a property of a kind is bound, for a finding that names it; copy for a kind with no entry. */
|
|
53
|
+
export declare function aiComponentKindBindsTo(type: string): string;
|
|
54
|
+
/** Whether a value is exactly one component property token. */
|
|
55
|
+
export declare function isAiComponentPropToken(value: unknown): value is string;
|
|
56
|
+
/** The property names a value's tokens name, each once, in order. */
|
|
57
|
+
export declare function aiComponentPropNamesIn(value: unknown): string[];
|
|
58
|
+
type PaletteFields = Pick<AiPaletteEntry, 'propsSchema' | 'propRoles' | 'propFields'>;
|
|
59
|
+
/**
|
|
60
|
+
* Whether a property may be bound to one field of an element, placed as it
|
|
61
|
+
* is. `field` is a prop the palette declares for the element, or one of the
|
|
62
|
+
* visibility directives.
|
|
63
|
+
*/
|
|
64
|
+
export declare function aiComponentPropBindsToField(prop: AiComponentPropBinding, entry: PaletteFields | undefined, field: string, placement: AiComponentPropPlacement): boolean;
|
|
65
|
+
/** The answers of a property that the field it is bound to does not list. */
|
|
66
|
+
export declare function aiComponentUnofferedAnswers(prop: AiComponentPropBinding, entry: PaletteFields | undefined, field: string): string[];
|
|
67
|
+
export {};
|
|
@@ -0,0 +1,106 @@
|
|
|
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 { matchComponentPropToken } from "@aglyn/aglyn/app-utils/compose-reusable-components";
|
|
18
|
+
import { NODE_HIDE_IF_PROP, NODE_HIDE_UNLESS_PROP } from "@aglyn/aglyn/app-utils/reusable-component-keys";
|
|
19
|
+
import { attributeFieldValueShape, reusablePropBindsToField, reusablePropValueShape, unofferedChoiceValues } from "@aglyn/aglyn/foundation/definitions/property-kinds";
|
|
20
|
+
import { aiBindingTokensIn } from "../model/ai-template-subjects.js";
|
|
21
|
+
/** The node props a component's tree may bind that no element declares. */ export const AI_COMPONENT_VISIBILITY_PROPS = [
|
|
22
|
+
NODE_HIDE_IF_PROP,
|
|
23
|
+
NODE_HIDE_UNLESS_PROP
|
|
24
|
+
];
|
|
25
|
+
/** Kinds whose value reads as copy, which copy may carry inside a sentence. */ export const AI_COMPONENT_COPY_KINDS = new Set([
|
|
26
|
+
'text',
|
|
27
|
+
'richText',
|
|
28
|
+
'number'
|
|
29
|
+
]);
|
|
30
|
+
/**
|
|
31
|
+
* Where a property of each offered kind is bound, in the words a re-ask gives
|
|
32
|
+
* a model that declared one and bound it nowhere (AGL-3054): the fields
|
|
33
|
+
* `aiComponentPropBindsToField` admits for the kind, by an example.
|
|
34
|
+
*/ const AI_COMPONENT_KIND_BINDS_TO = {
|
|
35
|
+
text: 'copy, such as a Typography’s children or a Button’s label',
|
|
36
|
+
richText: 'copy, such as a Typography’s children',
|
|
37
|
+
number: 'copy, or a number setting',
|
|
38
|
+
image: 'an Image’s src',
|
|
39
|
+
href: 'a screenId or an href',
|
|
40
|
+
icon: 'an Icon element’s iconId',
|
|
41
|
+
boolean: 'a switch setting such as a Button’s fullWidth, or hideIf on the part it hides',
|
|
42
|
+
choice: 'a setting with fixed options, such as a Button’s variant'
|
|
43
|
+
};
|
|
44
|
+
/** Where a property of a kind is bound, for a finding that names it; copy for a kind with no entry. */ export function aiComponentKindBindsTo(type) {
|
|
45
|
+
var _AI_COMPONENT_KIND_BINDS_TO_type;
|
|
46
|
+
return (_AI_COMPONENT_KIND_BINDS_TO_type = AI_COMPONENT_KIND_BINDS_TO[type]) != null ? _AI_COMPONENT_KIND_BINDS_TO_type : AI_COMPONENT_KIND_BINDS_TO['text'];
|
|
47
|
+
}
|
|
48
|
+
/** Whether a value is exactly one component property token. */ export function isAiComponentPropToken(value) {
|
|
49
|
+
return matchComponentPropToken(value) !== null;
|
|
50
|
+
}
|
|
51
|
+
/** The property names a value's tokens name, each once, in order. */ export function aiComponentPropNamesIn(value) {
|
|
52
|
+
if (typeof value !== 'string' || !value.includes('{{')) return [];
|
|
53
|
+
const names = [];
|
|
54
|
+
for (const token of aiBindingTokensIn(value)){
|
|
55
|
+
const name = matchComponentPropToken(token);
|
|
56
|
+
if (name && !names.includes(name)) names.push(name);
|
|
57
|
+
}
|
|
58
|
+
return names;
|
|
59
|
+
}
|
|
60
|
+
/** A palette prop as the attribute field the editor draws it with. */ function attributeField(entry, field) {
|
|
61
|
+
const schema = entry.propsSchema.properties[field];
|
|
62
|
+
const component = entry.propFields[field];
|
|
63
|
+
if (!schema || !component) return null;
|
|
64
|
+
return _extends({
|
|
65
|
+
component
|
|
66
|
+
}, schema.enum ? {
|
|
67
|
+
options: schema.enum.map((value)=>({
|
|
68
|
+
value
|
|
69
|
+
}))
|
|
70
|
+
} : {});
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Whether a property may be bound to one field of an element, placed as it
|
|
74
|
+
* is. `field` is a prop the palette declares for the element, or one of the
|
|
75
|
+
* visibility directives.
|
|
76
|
+
*/ export function aiComponentPropBindsToField(prop, entry, field, placement) {
|
|
77
|
+
var _prop_type;
|
|
78
|
+
if (field === NODE_HIDE_IF_PROP) {
|
|
79
|
+
return placement === 'whole' && reusablePropValueShape(prop) === 'boolean';
|
|
80
|
+
}
|
|
81
|
+
if (field === NODE_HIDE_UNLESS_PROP) {
|
|
82
|
+
return placement === 'whole' && prop.type === 'href';
|
|
83
|
+
}
|
|
84
|
+
const declared = entry ? attributeField(entry, field) : null;
|
|
85
|
+
if (!entry || !declared) return false;
|
|
86
|
+
if (attributeFieldValueShape(declared) !== undefined) {
|
|
87
|
+
return placement === 'whole' && reusablePropBindsToField(prop, declared);
|
|
88
|
+
}
|
|
89
|
+
const type = (_prop_type = prop.type) != null ? _prop_type : 'text';
|
|
90
|
+
switch(entry.propRoles[field]){
|
|
91
|
+
case 'url':
|
|
92
|
+
return placement === 'whole' && type === 'href';
|
|
93
|
+
case 'media':
|
|
94
|
+
return placement === 'whole' && type === 'image';
|
|
95
|
+
case 'text':
|
|
96
|
+
return AI_COMPONENT_COPY_KINDS.has(type);
|
|
97
|
+
default:
|
|
98
|
+
return false;
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
/** The answers of a property that the field it is bound to does not list. */ export function aiComponentUnofferedAnswers(prop, entry, field) {
|
|
102
|
+
const declared = entry ? attributeField(entry, field) : null;
|
|
103
|
+
return unofferedChoiceValues(prop, declared == null ? void 0 : declared.options);
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
//# sourceMappingURL=ai-component-bindings.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../../../../libs/plugins/ai/src/lib/runtime/ai-component-bindings.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 { matchComponentPropToken } from '@aglyn/aglyn/app-utils/compose-reusable-components'\nimport {\n NODE_HIDE_IF_PROP,\n NODE_HIDE_UNLESS_PROP,\n} from '@aglyn/aglyn/app-utils/reusable-component-keys'\nimport type { ReusableComponentProp } from '@aglyn/aglyn/foundation/definitions/platform.types'\nimport {\n attributeFieldValueShape,\n reusablePropBindsToField,\n reusablePropValueShape,\n unofferedChoiceValues,\n} from '@aglyn/aglyn/foundation/definitions/property-kinds'\nimport { aiBindingTokensIn } from '../model/ai-template-subjects'\nimport type { AiPaletteEntry } from './ai-palette'\n\n/**\n * Which field of a generated reusable component may carry which of the\n * component's own properties (AGL-2908).\n *\n * A component's tree reaches its properties through `{{prop.<name>}}` tokens,\n * and the graft hands each field the value its property's kind holds\n * (`resolveComponentPropTokens`). So a binding is right only where the field\n * can show that value:\n *\n * - A field that is not typed into — a switch, a dropdown, a screen picker, a\n * slider — takes exactly the properties the Attributes panel offers it\n * under its `{}` (AGL-2871): `reusablePropBindsToField`, the editor's own\n * judgment, over the field kind the palette records. The token is the\n * field's whole value.\n * - A field that is typed into takes any token in the editor. A generated\n * binding is held to what reads right there: copy in copy (Text, Long text\n * or Number, whole or inside a sentence), a picture as an image's source\n * and a link as an address, each as the whole value.\n * - The visibility directives are switches the graft reads before anything\n * renders: `hideIf` takes a Yes / no, and `hideUnless` a Link, whose\n * absence hides the part.\n *\n * Pure: the palette validator reads it to keep a token as written, and the\n * component step's check reads it to hold each token to its property.\n */\n\n/** A declared property, as a binding reads it. */\nexport type AiComponentPropBinding = Pick<\n ReusableComponentProp,\n 'name' | 'type' | 'options' | 'settings'\n>\n\n/** Where a token sits in a field's value: the whole value, or inside copy. */\nexport type AiComponentPropPlacement = 'whole' | 'inside'\n\n/** The node props a component's tree may bind that no element declares. */\nexport const AI_COMPONENT_VISIBILITY_PROPS: readonly string[] = [\n NODE_HIDE_IF_PROP,\n NODE_HIDE_UNLESS_PROP,\n]\n\n/** Kinds whose value reads as copy, which copy may carry inside a sentence. */\nexport const AI_COMPONENT_COPY_KINDS: ReadonlySet<string> = new Set(['text', 'richText', 'number'])\n\n/**\n * Where a property of each offered kind is bound, in the words a re-ask gives\n * a model that declared one and bound it nowhere (AGL-3054): the fields\n * `aiComponentPropBindsToField` admits for the kind, by an example.\n */\nconst AI_COMPONENT_KIND_BINDS_TO: Readonly<Record<string, string>> = {\n text: 'copy, such as a Typography’s children or a Button’s label',\n richText: 'copy, such as a Typography’s children',\n number: 'copy, or a number setting',\n image: 'an Image’s src',\n href: 'a screenId or an href',\n icon: 'an Icon element’s iconId',\n boolean: 'a switch setting such as a Button’s fullWidth, or hideIf on the part it hides',\n choice: 'a setting with fixed options, such as a Button’s variant',\n}\n\n/** Where a property of a kind is bound, for a finding that names it; copy for a kind with no entry. */\nexport function aiComponentKindBindsTo(type: string): string {\n return AI_COMPONENT_KIND_BINDS_TO[type] ?? AI_COMPONENT_KIND_BINDS_TO['text']\n}\n\n/** Whether a value is exactly one component property token. */\nexport function isAiComponentPropToken(value: unknown): value is string {\n return matchComponentPropToken(value) !== null\n}\n\n/** The property names a value's tokens name, each once, in order. */\nexport function aiComponentPropNamesIn(value: unknown): string[] {\n if (typeof value !== 'string' || !value.includes('{{')) return []\n const names: string[] = []\n for (const token of aiBindingTokensIn(value)) {\n const name = matchComponentPropToken(token)\n if (name && !names.includes(name)) names.push(name)\n }\n return names\n}\n\ntype PaletteFields = Pick<AiPaletteEntry, 'propsSchema' | 'propRoles' | 'propFields'>\n\n/** A palette prop as the attribute field the editor draws it with. */\nfunction attributeField(\n entry: PaletteFields,\n field: string,\n): { component: string; options?: Array<{ value: string }> } | null {\n const schema = entry.propsSchema.properties[field]\n const component = entry.propFields[field]\n if (!schema || !component) return null\n return {\n component,\n ...(schema.enum ? { options: schema.enum.map((value) => ({ value })) } : {}),\n }\n}\n\n/**\n * Whether a property may be bound to one field of an element, placed as it\n * is. `field` is a prop the palette declares for the element, or one of the\n * visibility directives.\n */\nexport function aiComponentPropBindsToField(\n prop: AiComponentPropBinding,\n entry: PaletteFields | undefined,\n field: string,\n placement: AiComponentPropPlacement,\n): boolean {\n if (field === NODE_HIDE_IF_PROP) {\n return placement === 'whole' && reusablePropValueShape(prop) === 'boolean'\n }\n if (field === NODE_HIDE_UNLESS_PROP) {\n return placement === 'whole' && prop.type === 'href'\n }\n const declared = entry ? attributeField(entry, field) : null\n if (!entry || !declared) return false\n if (attributeFieldValueShape(declared) !== undefined) {\n return placement === 'whole' && reusablePropBindsToField(prop, declared)\n }\n const type = prop.type ?? 'text'\n switch (entry.propRoles[field]) {\n case 'url':\n return placement === 'whole' && type === 'href'\n case 'media':\n return placement === 'whole' && type === 'image'\n case 'text':\n return AI_COMPONENT_COPY_KINDS.has(type)\n default:\n return false\n }\n}\n\n/** The answers of a property that the field it is bound to does not list. */\nexport function aiComponentUnofferedAnswers(\n prop: AiComponentPropBinding,\n entry: PaletteFields | undefined,\n field: string,\n): string[] {\n const declared = entry ? attributeField(entry, field) : null\n return unofferedChoiceValues(prop, declared?.options)\n}\n"],"names":["matchComponentPropToken","NODE_HIDE_IF_PROP","NODE_HIDE_UNLESS_PROP","attributeFieldValueShape","reusablePropBindsToField","reusablePropValueShape","unofferedChoiceValues","aiBindingTokensIn","AI_COMPONENT_VISIBILITY_PROPS","AI_COMPONENT_COPY_KINDS","Set","AI_COMPONENT_KIND_BINDS_TO","text","richText","number","image","href","icon","boolean","choice","aiComponentKindBindsTo","type","isAiComponentPropToken","value","aiComponentPropNamesIn","includes","names","token","name","push","attributeField","entry","field","schema","propsSchema","properties","component","propFields","enum","options","map","aiComponentPropBindsToField","prop","placement","declared","undefined","propRoles","has","aiComponentUnofferedAnswers"],"mappings":";AAAA;;;;;;;;;;;;;;;CAeC,GAED,SAASA,uBAAuB,QAAQ,qDAAoD;AAC5F,SACEC,iBAAiB,EACjBC,qBAAqB,QAChB,iDAAgD;AAEvD,SACEC,wBAAwB,EACxBC,wBAAwB,EACxBC,sBAAsB,EACtBC,qBAAqB,QAChB,qDAAoD;AAC3D,SAASC,iBAAiB,QAAQ,mCAA+B;AAsCjE,yEAAyE,GACzE,OAAO,MAAMC,gCAAmD;IAC9DP;IACAC;CACD,CAAA;AAED,6EAA6E,GAC7E,OAAO,MAAMO,0BAA+C,IAAIC,IAAI;IAAC;IAAQ;IAAY;CAAS,EAAC;AAEnG;;;;CAIC,GACD,MAAMC,6BAA+D;IACnEC,MAAM;IACNC,UAAU;IACVC,QAAQ;IACRC,OAAO;IACPC,MAAM;IACNC,MAAM;IACNC,SAAS;IACTC,QAAQ;AACV;AAEA,qGAAqG,GACrG,OAAO,SAASC,uBAAuBC,IAAY;QAC1CV;IAAP,QAAOA,mCAAAA,0BAA0B,CAACU,KAAK,YAAhCV,mCAAoCA,0BAA0B,CAAC,OAAO;AAC/E;AAEA,6DAA6D,GAC7D,OAAO,SAASW,uBAAuBC,KAAc;IACnD,OAAOvB,wBAAwBuB,WAAW;AAC5C;AAEA,mEAAmE,GACnE,OAAO,SAASC,uBAAuBD,KAAc;IACnD,IAAI,OAAOA,UAAU,YAAY,CAACA,MAAME,QAAQ,CAAC,OAAO,OAAO,EAAE;IACjE,MAAMC,QAAkB,EAAE;IAC1B,KAAK,MAAMC,SAASpB,kBAAkBgB,OAAQ;QAC5C,MAAMK,OAAO5B,wBAAwB2B;QACrC,IAAIC,QAAQ,CAACF,MAAMD,QAAQ,CAACG,OAAOF,MAAMG,IAAI,CAACD;IAChD;IACA,OAAOF;AACT;AAIA,oEAAoE,GACpE,SAASI,eACPC,KAAoB,EACpBC,KAAa;IAEb,MAAMC,SAASF,MAAMG,WAAW,CAACC,UAAU,CAACH,MAAM;IAClD,MAAMI,YAAYL,MAAMM,UAAU,CAACL,MAAM;IACzC,IAAI,CAACC,UAAU,CAACG,WAAW,OAAO;IAClC,OAAO;QACLA;OACIH,OAAOK,IAAI,GAAG;QAAEC,SAASN,OAAOK,IAAI,CAACE,GAAG,CAAC,CAACjB,QAAW,CAAA;gBAAEA;YAAM,CAAA;IAAI,IAAI,CAAC;AAE9E;AAEA;;;;CAIC,GACD,OAAO,SAASkB,4BACdC,IAA4B,EAC5BX,KAAgC,EAChCC,KAAa,EACbW,SAAmC;QAatBD;IAXb,IAAIV,UAAU/B,mBAAmB;QAC/B,OAAO0C,cAAc,WAAWtC,uBAAuBqC,UAAU;IACnE;IACA,IAAIV,UAAU9B,uBAAuB;QACnC,OAAOyC,cAAc,WAAWD,KAAKrB,IAAI,KAAK;IAChD;IACA,MAAMuB,WAAWb,QAAQD,eAAeC,OAAOC,SAAS;IACxD,IAAI,CAACD,SAAS,CAACa,UAAU,OAAO;IAChC,IAAIzC,yBAAyByC,cAAcC,WAAW;QACpD,OAAOF,cAAc,WAAWvC,yBAAyBsC,MAAME;IACjE;IACA,MAAMvB,QAAOqB,aAAAA,KAAKrB,IAAI,YAATqB,aAAa;IAC1B,OAAQX,MAAMe,SAAS,CAACd,MAAM;QAC5B,KAAK;YACH,OAAOW,cAAc,WAAWtB,SAAS;QAC3C,KAAK;YACH,OAAOsB,cAAc,WAAWtB,SAAS;QAC3C,KAAK;YACH,OAAOZ,wBAAwBsC,GAAG,CAAC1B;QACrC;YACE,OAAO;IACX;AACF;AAEA,2EAA2E,GAC3E,OAAO,SAAS2B,4BACdN,IAA4B,EAC5BX,KAAgC,EAChCC,KAAa;IAEb,MAAMY,WAAWb,QAAQD,eAAeC,OAAOC,SAAS;IACxD,OAAO1B,sBAAsBoC,MAAME,4BAAAA,SAAUL,OAAO;AACtD"}
|
|
@@ -0,0 +1,109 @@
|
|
|
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 { HostTheme } from '@aglyn/shared-data-types';
|
|
18
|
+
import type { AiInventoryTheme } from '../model/ai-site-inventory';
|
|
19
|
+
/**
|
|
20
|
+
* THE DEVICE AUDIT (AGL-3020): what a generated document looks like at every
|
|
21
|
+
* width the besigner's device switcher previews, and the rule a recording of
|
|
22
|
+
* it is held to.
|
|
23
|
+
*
|
|
24
|
+
* Rule 12 is held on the tree: no fixed width, and a Grid of columns is a
|
|
25
|
+
* container of items full width on a phone (`detectUnresponsiveGrids`). What a
|
|
26
|
+
* tree cannot show is what renders: a Stack that stays a row on a phone, a
|
|
27
|
+
* line of copy wider than the screen. `tools/scripts/record-ai-page-axe.mts`
|
|
28
|
+
* renders each golden page and each rendered eval answer at the switcher's
|
|
29
|
+
* five devices — through `devicePreviewWidth` and the canvas's own pinned
|
|
30
|
+
* theme, in a real browser — and records what it measured here, in the
|
|
31
|
+
* shapes below. Specs read the recording; nothing here renders.
|
|
32
|
+
*/
|
|
33
|
+
/** The devices the switcher previews, narrowest first, by their flag names. */
|
|
34
|
+
export declare const AI_AUDIT_DEVICES: readonly ["XS", "SM", "MD", "LG", "XL"];
|
|
35
|
+
export type AiAuditDevice = (typeof AI_AUDIT_DEVICES)[number];
|
|
36
|
+
/** One axe-core violation, as a recording keeps it. */
|
|
37
|
+
export interface AiAuditViolation {
|
|
38
|
+
id: string;
|
|
39
|
+
impact: string | null;
|
|
40
|
+
help: string;
|
|
41
|
+
/** How many elements break it. */
|
|
42
|
+
nodes: number;
|
|
43
|
+
}
|
|
44
|
+
/** A document rendered at one device's width. */
|
|
45
|
+
export interface AiDeviceRender {
|
|
46
|
+
device: AiAuditDevice;
|
|
47
|
+
/** The viewport width the switcher previews the device at, in CSS pixels. */
|
|
48
|
+
width: number;
|
|
49
|
+
/**
|
|
50
|
+
* The deepest elements whose box runs past the viewport's edge, in document
|
|
51
|
+
* order; empty when the page is no wider than the screen.
|
|
52
|
+
*/
|
|
53
|
+
overflow: string[];
|
|
54
|
+
/**
|
|
55
|
+
* axe-core's violations, every rule on. Recorded for the golden pages, whose
|
|
56
|
+
* sites author the colors their pages are measured against; an eval answer
|
|
57
|
+
* is recorded for its widths alone.
|
|
58
|
+
*/
|
|
59
|
+
violations?: AiAuditViolation[];
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* A row a layout element draws: a Stack, Grid, Box, Section or Container of
|
|
63
|
+
* the palette (its schema's Layout category) laid out as a flex or grid box.
|
|
64
|
+
*/
|
|
65
|
+
export interface AiLayoutRow {
|
|
66
|
+
/** The element: the id the model wrote for it, or its section and position. */
|
|
67
|
+
node: string;
|
|
68
|
+
component: string;
|
|
69
|
+
/** Whether it is a Grid container, which rule 12 holds to one column on a phone. */
|
|
70
|
+
grid: boolean;
|
|
71
|
+
/**
|
|
72
|
+
* Its children that hold content. A child drawn by an Input or a Navigation
|
|
73
|
+
* element of the palette, or an icon, is a control: a row of buttons, links
|
|
74
|
+
* or an icon beside its label reads as one line on a phone.
|
|
75
|
+
*/
|
|
76
|
+
content: number;
|
|
77
|
+
/** The children on its first line, per device. */
|
|
78
|
+
columns: Record<AiAuditDevice, number>;
|
|
79
|
+
}
|
|
80
|
+
/** What a recording holds for one document. */
|
|
81
|
+
export interface AiDeviceAudit {
|
|
82
|
+
devices: AiDeviceRender[];
|
|
83
|
+
rows: AiLayoutRow[];
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* A band: a row of two or more columns of content at LG, which the palette's
|
|
87
|
+
* own Grid row stacks on a phone ("three columns that stack on mobile").
|
|
88
|
+
*/
|
|
89
|
+
export declare function aiLayoutRowIsBand(row: AiLayoutRow): boolean;
|
|
90
|
+
/**
|
|
91
|
+
* What a recorded document gets wrong at the switcher's widths, as findings:
|
|
92
|
+
*
|
|
93
|
+
* - `widths-missing:<device>`: a device the recording never rendered;
|
|
94
|
+
* - `overflow:<device>:<element>`: an element wider than the device's screen,
|
|
95
|
+
* which scrolls the page sideways;
|
|
96
|
+
* - `band-not-broken-down:<element>`: a band with as many columns on a phone
|
|
97
|
+
* (XS) as on a desktop (LG).
|
|
98
|
+
*
|
|
99
|
+
* Empty when the document works at every width.
|
|
100
|
+
*/
|
|
101
|
+
export declare function aiDeviceAuditFindings(audit: AiDeviceAudit): string[];
|
|
102
|
+
/**
|
|
103
|
+
* The theme document a site inventory's theme summarizes: its light scheme's
|
|
104
|
+
* colors, from the flat `primary.main` paths the inventory lists them by, and
|
|
105
|
+
* its fonts. A golden site has no theme document of its own, so this is the
|
|
106
|
+
* theme its pages were built against and are rendered with; `null` renders
|
|
107
|
+
* the brand base alone, as a site with no theme does.
|
|
108
|
+
*/
|
|
109
|
+
export declare function aiInventoryHostTheme(theme: AiInventoryTheme | null): HostTheme | null;
|
|
@@ -0,0 +1,97 @@
|
|
|
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 { _ as _extends } from "@swc/helpers/_/_extends";
|
|
17
|
+
/**
|
|
18
|
+
* THE DEVICE AUDIT (AGL-3020): what a generated document looks like at every
|
|
19
|
+
* width the besigner's device switcher previews, and the rule a recording of
|
|
20
|
+
* it is held to.
|
|
21
|
+
*
|
|
22
|
+
* Rule 12 is held on the tree: no fixed width, and a Grid of columns is a
|
|
23
|
+
* container of items full width on a phone (`detectUnresponsiveGrids`). What a
|
|
24
|
+
* tree cannot show is what renders: a Stack that stays a row on a phone, a
|
|
25
|
+
* line of copy wider than the screen. `tools/scripts/record-ai-page-axe.mts`
|
|
26
|
+
* renders each golden page and each rendered eval answer at the switcher's
|
|
27
|
+
* five devices — through `devicePreviewWidth` and the canvas's own pinned
|
|
28
|
+
* theme, in a real browser — and records what it measured here, in the
|
|
29
|
+
* shapes below. Specs read the recording; nothing here renders.
|
|
30
|
+
*/ /** The devices the switcher previews, narrowest first, by their flag names. */ export const AI_AUDIT_DEVICES = [
|
|
31
|
+
'XS',
|
|
32
|
+
'SM',
|
|
33
|
+
'MD',
|
|
34
|
+
'LG',
|
|
35
|
+
'XL'
|
|
36
|
+
];
|
|
37
|
+
/**
|
|
38
|
+
* A band: a row of two or more columns of content at LG, which the palette's
|
|
39
|
+
* own Grid row stacks on a phone ("three columns that stack on mobile").
|
|
40
|
+
*/ export function aiLayoutRowIsBand(row) {
|
|
41
|
+
return row.content >= 2 && row.columns.LG >= 2;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* What a recorded document gets wrong at the switcher's widths, as findings:
|
|
45
|
+
*
|
|
46
|
+
* - `widths-missing:<device>`: a device the recording never rendered;
|
|
47
|
+
* - `overflow:<device>:<element>`: an element wider than the device's screen,
|
|
48
|
+
* which scrolls the page sideways;
|
|
49
|
+
* - `band-not-broken-down:<element>`: a band with as many columns on a phone
|
|
50
|
+
* (XS) as on a desktop (LG).
|
|
51
|
+
*
|
|
52
|
+
* Empty when the document works at every width.
|
|
53
|
+
*/ export function aiDeviceAuditFindings(audit) {
|
|
54
|
+
const findings = [];
|
|
55
|
+
for (const device of AI_AUDIT_DEVICES){
|
|
56
|
+
if (!audit.devices.some((render)=>render.device === device)) findings.push(`widths-missing:${device}`);
|
|
57
|
+
}
|
|
58
|
+
for (const render of audit.devices){
|
|
59
|
+
for (const element of render.overflow)findings.push(`overflow:${render.device}:${element}`);
|
|
60
|
+
}
|
|
61
|
+
for (const row of audit.rows){
|
|
62
|
+
if (aiLayoutRowIsBand(row) && row.columns.XS >= row.columns.LG) findings.push(`band-not-broken-down:${row.node}`);
|
|
63
|
+
}
|
|
64
|
+
return findings;
|
|
65
|
+
}
|
|
66
|
+
const isRecord = (value)=>typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
67
|
+
/**
|
|
68
|
+
* The theme document a site inventory's theme summarizes: its light scheme's
|
|
69
|
+
* colors, from the flat `primary.main` paths the inventory lists them by, and
|
|
70
|
+
* its fonts. A golden site has no theme document of its own, so this is the
|
|
71
|
+
* theme its pages were built against and are rendered with; `null` renders
|
|
72
|
+
* the brand base alone, as a site with no theme does.
|
|
73
|
+
*/ export function aiInventoryHostTheme(theme) {
|
|
74
|
+
if (!theme) return null;
|
|
75
|
+
const light = {};
|
|
76
|
+
for (const [path, value] of Object.entries(theme.colors)){
|
|
77
|
+
const keys = path.split('.').filter(Boolean);
|
|
78
|
+
if (!keys.length) continue;
|
|
79
|
+
let cursor = light;
|
|
80
|
+
for (const key of keys.slice(0, -1)){
|
|
81
|
+
if (!isRecord(cursor[key])) cursor[key] = {};
|
|
82
|
+
cursor = cursor[key];
|
|
83
|
+
}
|
|
84
|
+
cursor[keys[keys.length - 1]] = value;
|
|
85
|
+
}
|
|
86
|
+
return _extends({
|
|
87
|
+
colorSchemes: {
|
|
88
|
+
light: light
|
|
89
|
+
}
|
|
90
|
+
}, theme.fonts.length ? {
|
|
91
|
+
fonts: theme.fonts.map((family)=>({
|
|
92
|
+
family
|
|
93
|
+
}))
|
|
94
|
+
} : {});
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
//# sourceMappingURL=ai-device-audit.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../../../../libs/plugins/ai/src/lib/runtime/ai-device-audit.ts"],"sourcesContent":["/**\n * @license\n * Copyright 2026 Aglyn LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport type { HostTheme, HostThemeSchemeColors } from '@aglyn/shared-data-types'\nimport type { AiInventoryTheme } from '../model/ai-site-inventory'\n\n/**\n * THE DEVICE AUDIT (AGL-3020): what a generated document looks like at every\n * width the besigner's device switcher previews, and the rule a recording of\n * it is held to.\n *\n * Rule 12 is held on the tree: no fixed width, and a Grid of columns is a\n * container of items full width on a phone (`detectUnresponsiveGrids`). What a\n * tree cannot show is what renders: a Stack that stays a row on a phone, a\n * line of copy wider than the screen. `tools/scripts/record-ai-page-axe.mts`\n * renders each golden page and each rendered eval answer at the switcher's\n * five devices — through `devicePreviewWidth` and the canvas's own pinned\n * theme, in a real browser — and records what it measured here, in the\n * shapes below. Specs read the recording; nothing here renders.\n */\n\n/** The devices the switcher previews, narrowest first, by their flag names. */\nexport const AI_AUDIT_DEVICES = ['XS', 'SM', 'MD', 'LG', 'XL'] as const\nexport type AiAuditDevice = (typeof AI_AUDIT_DEVICES)[number]\n\n/** One axe-core violation, as a recording keeps it. */\nexport interface AiAuditViolation {\n id: string\n impact: string | null\n help: string\n /** How many elements break it. */\n nodes: number\n}\n\n/** A document rendered at one device's width. */\nexport interface AiDeviceRender {\n device: AiAuditDevice\n /** The viewport width the switcher previews the device at, in CSS pixels. */\n width: number\n /**\n * The deepest elements whose box runs past the viewport's edge, in document\n * order; empty when the page is no wider than the screen.\n */\n overflow: string[]\n /**\n * axe-core's violations, every rule on. Recorded for the golden pages, whose\n * sites author the colors their pages are measured against; an eval answer\n * is recorded for its widths alone.\n */\n violations?: AiAuditViolation[]\n}\n\n/**\n * A row a layout element draws: a Stack, Grid, Box, Section or Container of\n * the palette (its schema's Layout category) laid out as a flex or grid box.\n */\nexport interface AiLayoutRow {\n /** The element: the id the model wrote for it, or its section and position. */\n node: string\n component: string\n /** Whether it is a Grid container, which rule 12 holds to one column on a phone. */\n grid: boolean\n /**\n * Its children that hold content. A child drawn by an Input or a Navigation\n * element of the palette, or an icon, is a control: a row of buttons, links\n * or an icon beside its label reads as one line on a phone.\n */\n content: number\n /** The children on its first line, per device. */\n columns: Record<AiAuditDevice, number>\n}\n\n/** What a recording holds for one document. */\nexport interface AiDeviceAudit {\n devices: AiDeviceRender[]\n rows: AiLayoutRow[]\n}\n\n/**\n * A band: a row of two or more columns of content at LG, which the palette's\n * own Grid row stacks on a phone (\"three columns that stack on mobile\").\n */\nexport function aiLayoutRowIsBand(row: AiLayoutRow): boolean {\n return row.content >= 2 && row.columns.LG >= 2\n}\n\n/**\n * What a recorded document gets wrong at the switcher's widths, as findings:\n *\n * - `widths-missing:<device>`: a device the recording never rendered;\n * - `overflow:<device>:<element>`: an element wider than the device's screen,\n * which scrolls the page sideways;\n * - `band-not-broken-down:<element>`: a band with as many columns on a phone\n * (XS) as on a desktop (LG).\n *\n * Empty when the document works at every width.\n */\nexport function aiDeviceAuditFindings(audit: AiDeviceAudit): string[] {\n const findings: string[] = []\n for (const device of AI_AUDIT_DEVICES) {\n if (!audit.devices.some((render) => render.device === device)) findings.push(`widths-missing:${device}`)\n }\n for (const render of audit.devices) {\n for (const element of render.overflow) findings.push(`overflow:${render.device}:${element}`)\n }\n for (const row of audit.rows) {\n if (aiLayoutRowIsBand(row) && row.columns.XS >= row.columns.LG) findings.push(`band-not-broken-down:${row.node}`)\n }\n return findings\n}\n\nconst isRecord = (value: unknown): value is Record<string, unknown> =>\n typeof value === 'object' && value !== null && !Array.isArray(value)\n\n/**\n * The theme document a site inventory's theme summarizes: its light scheme's\n * colors, from the flat `primary.main` paths the inventory lists them by, and\n * its fonts. A golden site has no theme document of its own, so this is the\n * theme its pages were built against and are rendered with; `null` renders\n * the brand base alone, as a site with no theme does.\n */\nexport function aiInventoryHostTheme(theme: AiInventoryTheme | null): HostTheme | null {\n if (!theme) return null\n const light: Record<string, unknown> = {}\n for (const [path, value] of Object.entries(theme.colors)) {\n const keys = path.split('.').filter(Boolean)\n if (!keys.length) continue\n let cursor = light\n for (const key of keys.slice(0, -1)) {\n if (!isRecord(cursor[key])) cursor[key] = {}\n cursor = cursor[key] as Record<string, unknown>\n }\n cursor[keys[keys.length - 1]] = value\n }\n return {\n colorSchemes: { light: light as HostThemeSchemeColors },\n ...(theme.fonts.length ? { fonts: theme.fonts.map((family) => ({ family })) } : {}),\n }\n}\n"],"names":["AI_AUDIT_DEVICES","aiLayoutRowIsBand","row","content","columns","LG","aiDeviceAuditFindings","audit","findings","device","devices","some","render","push","element","overflow","rows","XS","node","isRecord","value","Array","isArray","aiInventoryHostTheme","theme","light","path","Object","entries","colors","keys","split","filter","Boolean","length","cursor","key","slice","colorSchemes","fonts","map","family"],"mappings":"AAAA;;;;;;;;;;;;;;;CAeC;AAKD;;;;;;;;;;;;;CAaC,GAED,6EAA6E,GAC7E,OAAO,MAAMA,mBAAmB;IAAC;IAAM;IAAM;IAAM;IAAM;CAAK,CAAS;AAwDvE;;;CAGC,GACD,OAAO,SAASC,kBAAkBC,GAAgB;IAChD,OAAOA,IAAIC,OAAO,IAAI,KAAKD,IAAIE,OAAO,CAACC,EAAE,IAAI;AAC/C;AAEA;;;;;;;;;;CAUC,GACD,OAAO,SAASC,sBAAsBC,KAAoB;IACxD,MAAMC,WAAqB,EAAE;IAC7B,KAAK,MAAMC,UAAUT,iBAAkB;QACrC,IAAI,CAACO,MAAMG,OAAO,CAACC,IAAI,CAAC,CAACC,SAAWA,OAAOH,MAAM,KAAKA,SAASD,SAASK,IAAI,CAAC,CAAC,eAAe,EAAEJ,QAAQ;IACzG;IACA,KAAK,MAAMG,UAAUL,MAAMG,OAAO,CAAE;QAClC,KAAK,MAAMI,WAAWF,OAAOG,QAAQ,CAAEP,SAASK,IAAI,CAAC,CAAC,SAAS,EAAED,OAAOH,MAAM,CAAC,CAAC,EAAEK,SAAS;IAC7F;IACA,KAAK,MAAMZ,OAAOK,MAAMS,IAAI,CAAE;QAC5B,IAAIf,kBAAkBC,QAAQA,IAAIE,OAAO,CAACa,EAAE,IAAIf,IAAIE,OAAO,CAACC,EAAE,EAAEG,SAASK,IAAI,CAAC,CAAC,qBAAqB,EAAEX,IAAIgB,IAAI,EAAE;IAClH;IACA,OAAOV;AACT;AAEA,MAAMW,WAAW,CAACC,QAChB,OAAOA,UAAU,YAAYA,UAAU,QAAQ,CAACC,MAAMC,OAAO,CAACF;AAEhE;;;;;;CAMC,GACD,OAAO,SAASG,qBAAqBC,KAA8B;IACjE,IAAI,CAACA,OAAO,OAAO;IACnB,MAAMC,QAAiC,CAAC;IACxC,KAAK,MAAM,CAACC,MAAMN,MAAM,IAAIO,OAAOC,OAAO,CAACJ,MAAMK,MAAM,EAAG;QACxD,MAAMC,OAAOJ,KAAKK,KAAK,CAAC,KAAKC,MAAM,CAACC;QACpC,IAAI,CAACH,KAAKI,MAAM,EAAE;QAClB,IAAIC,SAASV;QACb,KAAK,MAAMW,OAAON,KAAKO,KAAK,CAAC,GAAG,CAAC,GAAI;YACnC,IAAI,CAAClB,SAASgB,MAAM,CAACC,IAAI,GAAGD,MAAM,CAACC,IAAI,GAAG,CAAC;YAC3CD,SAASA,MAAM,CAACC,IAAI;QACtB;QACAD,MAAM,CAACL,IAAI,CAACA,KAAKI,MAAM,GAAG,EAAE,CAAC,GAAGd;IAClC;IACA,OAAO;QACLkB,cAAc;YAAEb,OAAOA;QAA+B;OAClDD,MAAMe,KAAK,CAACL,MAAM,GAAG;QAAEK,OAAOf,MAAMe,KAAK,CAACC,GAAG,CAAC,CAACC,SAAY,CAAA;gBAAEA;YAAO,CAAA;IAAI,IAAI,CAAC;AAErF"}
|