@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,113 @@
|
|
|
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 { aiMediaAssetLocation, loadAiMediaSharp, readAiMediaAssetBytes } from "./ai-media-asset.js";
|
|
17
|
+
/**
|
|
18
|
+
* A PRODUCT'S PHOTO, as a `products` job shows it to the model (AGL-2916).
|
|
19
|
+
*
|
|
20
|
+
* Exactly one picture is read for a product: its FIRST media item, the photo
|
|
21
|
+
* the storefront leads with. Nothing else of the media library is read or
|
|
22
|
+
* sent — no other photo of the product, no other asset, no folder, no file
|
|
23
|
+
* name and no alt text.
|
|
24
|
+
*
|
|
25
|
+
* The photo is read the way the media CDN would serve it
|
|
26
|
+
* (`readAiMediaAssetBytes`): only an asset of this site's own library or its
|
|
27
|
+
* org's, live, not private, visible to the site, not locked or quarantined.
|
|
28
|
+
* A photo that is a link to somewhere else, or a raw storage URL, is not an
|
|
29
|
+
* asset of the library and is not read at all; nothing is ever fetched from a
|
|
30
|
+
* URL.
|
|
31
|
+
*
|
|
32
|
+
* What is sent is a new JPEG made from it: turned upright by its own
|
|
33
|
+
* orientation, shrunk to fit inside `AI_PRODUCT_IMAGE_MAX_EDGE_PX` on its
|
|
34
|
+
* longer edge (never enlarged), laid on white where it was transparent, and
|
|
35
|
+
* encoded at `AI_PRODUCT_IMAGE_JPEG_QUALITY`. Encoding a new image carries none
|
|
36
|
+
* of the original's metadata, so no camera, date or location embedded in the
|
|
37
|
+
* file leaves with it. An animated image sends its first frame.
|
|
38
|
+
*/ /** The longer edge of the picture sent, in pixels. */ export const AI_PRODUCT_IMAGE_MAX_EDGE_PX = 768;
|
|
39
|
+
/** The JPEG quality the picture is sent at. */ export const AI_PRODUCT_IMAGE_JPEG_QUALITY = 80;
|
|
40
|
+
/** The largest original read, in bytes. */ export const AI_PRODUCT_IMAGE_MAX_SOURCE_BYTES = 15 * 1024 * 1024;
|
|
41
|
+
/** The formats read; a vector drawing is not a product photo, and is not decoded. */ export const AI_PRODUCT_IMAGE_TYPES = /^image\/(png|jpeg|webp|gif|avif)$/;
|
|
42
|
+
/**
|
|
43
|
+
* ASSUMED: how long the photo read takes — the media document, the CDN's
|
|
44
|
+
* block, the storage download and the resize — which a pass's least time
|
|
45
|
+
* counts (AGL-3035).
|
|
46
|
+
*/ export const AI_PRODUCT_IMAGE_READ_MS = 6000;
|
|
47
|
+
/** The JPEG the model is shown, made from the original's bytes. */ export async function encodeAiProductImage(bytes) {
|
|
48
|
+
const sharp = await loadAiMediaSharp();
|
|
49
|
+
return sharp(bytes, {
|
|
50
|
+
limitInputPixels: 64000000,
|
|
51
|
+
animated: false
|
|
52
|
+
}).rotate().resize({
|
|
53
|
+
width: AI_PRODUCT_IMAGE_MAX_EDGE_PX,
|
|
54
|
+
height: AI_PRODUCT_IMAGE_MAX_EDGE_PX,
|
|
55
|
+
fit: 'inside',
|
|
56
|
+
withoutEnlargement: true
|
|
57
|
+
})// White, as channels: a transparent product shot reads on a white page.
|
|
58
|
+
.flatten({
|
|
59
|
+
background: {
|
|
60
|
+
r: 255,
|
|
61
|
+
g: 255,
|
|
62
|
+
b: 255
|
|
63
|
+
}
|
|
64
|
+
}).jpeg({
|
|
65
|
+
quality: AI_PRODUCT_IMAGE_JPEG_QUALITY
|
|
66
|
+
}).toBuffer();
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* The product's first photo as a picture part, or what kept it from being
|
|
70
|
+
* one. Never throws: a photo that cannot be read leaves the copy to be written
|
|
71
|
+
* from the product's words, and says so.
|
|
72
|
+
*/ export async function readAiProductImage(firestore, input, seams = {}) {
|
|
73
|
+
if (!input.value) return {
|
|
74
|
+
status: 'none'
|
|
75
|
+
};
|
|
76
|
+
const location = aiMediaAssetLocation(input.value, input.hostId, input.orgId);
|
|
77
|
+
if (!location) return {
|
|
78
|
+
status: 'not-in-library'
|
|
79
|
+
};
|
|
80
|
+
try {
|
|
81
|
+
var _seams_readBytes, _seams_encode;
|
|
82
|
+
const read = (_seams_readBytes = seams.readBytes) != null ? _seams_readBytes : (store, where, hostId)=>readAiMediaAssetBytes(store, where, hostId, {
|
|
83
|
+
maxBytes: AI_PRODUCT_IMAGE_MAX_SOURCE_BYTES,
|
|
84
|
+
types: AI_PRODUCT_IMAGE_TYPES
|
|
85
|
+
});
|
|
86
|
+
const asset = await read(firestore, location, input.hostId);
|
|
87
|
+
if (!asset) return {
|
|
88
|
+
status: 'unreadable'
|
|
89
|
+
};
|
|
90
|
+
const jpeg = await ((_seams_encode = seams.encode) != null ? _seams_encode : encodeAiProductImage)(asset.buffer);
|
|
91
|
+
if (!jpeg.length) return {
|
|
92
|
+
status: 'unreadable'
|
|
93
|
+
};
|
|
94
|
+
return {
|
|
95
|
+
status: 'read',
|
|
96
|
+
image: {
|
|
97
|
+
type: 'image',
|
|
98
|
+
mediaType: 'image/jpeg',
|
|
99
|
+
data: jpeg.toString('base64')
|
|
100
|
+
}
|
|
101
|
+
};
|
|
102
|
+
} catch (error) {
|
|
103
|
+
console.error('ai product image read failed', {
|
|
104
|
+
hostId: input.hostId,
|
|
105
|
+
error
|
|
106
|
+
});
|
|
107
|
+
return {
|
|
108
|
+
status: 'unreadable'
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
//# sourceMappingURL=ai-product-image.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../../../../libs/plugins/ai/src/lib/jobs/ai-product-image.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 { AiProductPhotoRead } from '../model/ai-products'\nimport type { AiImagePart } from '../providers/contract'\nimport {\n aiMediaAssetLocation,\n loadAiMediaSharp,\n readAiMediaAssetBytes,\n type AiMediaAssetBytes,\n type AiMediaAssetLocation,\n} from './ai-media-asset'\n\n/**\n * A PRODUCT'S PHOTO, as a `products` job shows it to the model (AGL-2916).\n *\n * Exactly one picture is read for a product: its FIRST media item, the photo\n * the storefront leads with. Nothing else of the media library is read or\n * sent — no other photo of the product, no other asset, no folder, no file\n * name and no alt text.\n *\n * The photo is read the way the media CDN would serve it\n * (`readAiMediaAssetBytes`): only an asset of this site's own library or its\n * org's, live, not private, visible to the site, not locked or quarantined.\n * A photo that is a link to somewhere else, or a raw storage URL, is not an\n * asset of the library and is not read at all; nothing is ever fetched from a\n * URL.\n *\n * What is sent is a new JPEG made from it: turned upright by its own\n * orientation, shrunk to fit inside `AI_PRODUCT_IMAGE_MAX_EDGE_PX` on its\n * longer edge (never enlarged), laid on white where it was transparent, and\n * encoded at `AI_PRODUCT_IMAGE_JPEG_QUALITY`. Encoding a new image carries none\n * of the original's metadata, so no camera, date or location embedded in the\n * file leaves with it. An animated image sends its first frame.\n */\n\n/** The longer edge of the picture sent, in pixels. */\nexport const AI_PRODUCT_IMAGE_MAX_EDGE_PX = 768\n\n/** The JPEG quality the picture is sent at. */\nexport const AI_PRODUCT_IMAGE_JPEG_QUALITY = 80\n\n/** The largest original read, in bytes. */\nexport const AI_PRODUCT_IMAGE_MAX_SOURCE_BYTES = 15 * 1024 * 1024\n\n/** The formats read; a vector drawing is not a product photo, and is not decoded. */\nexport const AI_PRODUCT_IMAGE_TYPES = /^image\\/(png|jpeg|webp|gif|avif)$/\n\n/**\n * ASSUMED: how long the photo read takes — the media document, the CDN's\n * block, the storage download and the resize — which a pass's least time\n * counts (AGL-3035).\n */\nexport const AI_PRODUCT_IMAGE_READ_MS = 6_000\n\n/** The part of `sharp` the photo read uses. */\ninterface SharpJpegPipeline {\n rotate(): SharpJpegPipeline\n resize(options: { width: number; height: number; fit: 'inside'; withoutEnlargement: true }): SharpJpegPipeline\n flatten(options: { background: { r: number; g: number; b: number } }): SharpJpegPipeline\n jpeg(options: { quality: number }): SharpJpegPipeline\n toBuffer(): Promise<Buffer>\n}\ntype SharpJpeg = (input: Buffer, options?: { limitInputPixels?: number; animated?: boolean }) => SharpJpegPipeline\n\n/** The reads that leave the process, replaceable where a spec needs to. */\nexport interface AiProductImageSeams {\n readBytes?: (\n firestore: FirebaseFirestore.Firestore,\n location: AiMediaAssetLocation,\n hostId: string,\n ) => Promise<AiMediaAssetBytes | null>\n encode?: (bytes: Buffer) => Promise<Buffer>\n}\n\nexport type AiProductImage =\n | { status: 'read'; image: AiImagePart }\n | { status: Exclude<AiProductPhotoRead, 'read' | 'model'> }\n\n/** The JPEG the model is shown, made from the original's bytes. */\nexport async function encodeAiProductImage(bytes: Buffer): Promise<Buffer> {\n const sharp = (await loadAiMediaSharp()) as SharpJpeg\n return sharp(bytes, { limitInputPixels: 64_000_000, animated: false })\n .rotate()\n .resize({\n width: AI_PRODUCT_IMAGE_MAX_EDGE_PX,\n height: AI_PRODUCT_IMAGE_MAX_EDGE_PX,\n fit: 'inside',\n withoutEnlargement: true,\n })\n // White, as channels: a transparent product shot reads on a white page.\n .flatten({ background: { r: 255, g: 255, b: 255 } })\n .jpeg({ quality: AI_PRODUCT_IMAGE_JPEG_QUALITY })\n .toBuffer()\n}\n\n/**\n * The product's first photo as a picture part, or what kept it from being\n * one. Never throws: a photo that cannot be read leaves the copy to be written\n * from the product's words, and says so.\n */\nexport async function readAiProductImage(\n firestore: FirebaseFirestore.Firestore,\n input: { value: string | null | undefined; hostId: string; orgId: string },\n seams: AiProductImageSeams = {},\n): Promise<AiProductImage> {\n if (!input.value) return { status: 'none' }\n const location = aiMediaAssetLocation(input.value, input.hostId, input.orgId)\n if (!location) return { status: 'not-in-library' }\n try {\n const read =\n seams.readBytes ??\n ((store, where, hostId) =>\n readAiMediaAssetBytes(store, where, hostId, {\n maxBytes: AI_PRODUCT_IMAGE_MAX_SOURCE_BYTES,\n types: AI_PRODUCT_IMAGE_TYPES,\n }))\n const asset = await read(firestore, location, input.hostId)\n if (!asset) return { status: 'unreadable' }\n const jpeg = await (seams.encode ?? encodeAiProductImage)(asset.buffer)\n if (!jpeg.length) return { status: 'unreadable' }\n return { status: 'read', image: { type: 'image', mediaType: 'image/jpeg', data: jpeg.toString('base64') } }\n } catch (error) {\n console.error('ai product image read failed', { hostId: input.hostId, error })\n return { status: 'unreadable' }\n }\n}\n"],"names":["aiMediaAssetLocation","loadAiMediaSharp","readAiMediaAssetBytes","AI_PRODUCT_IMAGE_MAX_EDGE_PX","AI_PRODUCT_IMAGE_JPEG_QUALITY","AI_PRODUCT_IMAGE_MAX_SOURCE_BYTES","AI_PRODUCT_IMAGE_TYPES","AI_PRODUCT_IMAGE_READ_MS","encodeAiProductImage","bytes","sharp","limitInputPixels","animated","rotate","resize","width","height","fit","withoutEnlargement","flatten","background","r","g","b","jpeg","quality","toBuffer","readAiProductImage","firestore","input","seams","value","status","location","hostId","orgId","read","readBytes","store","where","maxBytes","types","asset","encode","buffer","length","image","type","mediaType","data","toString","error","console"],"mappings":"AAAA;;;;;;;;;;;;;;;CAeC,GAID,SACEA,oBAAoB,EACpBC,gBAAgB,EAChBC,qBAAqB,QAGhB,sBAAkB;AAEzB;;;;;;;;;;;;;;;;;;;;;CAqBC,GAED,oDAAoD,GACpD,OAAO,MAAMC,+BAA+B,IAAG;AAE/C,6CAA6C,GAC7C,OAAO,MAAMC,gCAAgC,GAAE;AAE/C,yCAAyC,GACzC,OAAO,MAAMC,oCAAoC,KAAK,OAAO,KAAI;AAEjE,mFAAmF,GACnF,OAAO,MAAMC,yBAAyB,oCAAmC;AAEzE;;;;CAIC,GACD,OAAO,MAAMC,2BAA2B,KAAK;AA0B7C,iEAAiE,GACjE,OAAO,eAAeC,qBAAqBC,KAAa;IACtD,MAAMC,QAAS,MAAMT;IACrB,OAAOS,MAAMD,OAAO;QAAEE,kBAAkB;QAAYC,UAAU;IAAM,GACjEC,MAAM,GACNC,MAAM,CAAC;QACNC,OAAOZ;QACPa,QAAQb;QACRc,KAAK;QACLC,oBAAoB;IACtB,EACA,wEAAwE;KACvEC,OAAO,CAAC;QAAEC,YAAY;YAAEC,GAAG;YAAKC,GAAG;YAAKC,GAAG;QAAI;IAAE,GACjDC,IAAI,CAAC;QAAEC,SAASrB;IAA8B,GAC9CsB,QAAQ;AACb;AAEA;;;;CAIC,GACD,OAAO,eAAeC,mBACpBC,SAAsC,EACtCC,KAA0E,EAC1EC,QAA6B,CAAC,CAAC;IAE/B,IAAI,CAACD,MAAME,KAAK,EAAE,OAAO;QAAEC,QAAQ;IAAO;IAC1C,MAAMC,WAAWjC,qBAAqB6B,MAAME,KAAK,EAAEF,MAAMK,MAAM,EAAEL,MAAMM,KAAK;IAC5E,IAAI,CAACF,UAAU,OAAO;QAAED,QAAQ;IAAiB;IACjD,IAAI;YAEAF,kBAQkBA;QATpB,MAAMM,QACJN,mBAAAA,MAAMO,SAAS,YAAfP,mBACC,CAACQ,OAAOC,OAAOL,SACdhC,sBAAsBoC,OAAOC,OAAOL,QAAQ;gBAC1CM,UAAUnC;gBACVoC,OAAOnC;YACT;QACJ,MAAMoC,QAAQ,MAAMN,KAAKR,WAAWK,UAAUJ,MAAMK,MAAM;QAC1D,IAAI,CAACQ,OAAO,OAAO;YAAEV,QAAQ;QAAa;QAC1C,MAAMR,OAAO,MAAM,EAACM,gBAAAA,MAAMa,MAAM,YAAZb,gBAAgBtB,sBAAsBkC,MAAME,MAAM;QACtE,IAAI,CAACpB,KAAKqB,MAAM,EAAE,OAAO;YAAEb,QAAQ;QAAa;QAChD,OAAO;YAAEA,QAAQ;YAAQc,OAAO;gBAAEC,MAAM;gBAASC,WAAW;gBAAcC,MAAMzB,KAAK0B,QAAQ,CAAC;YAAU;QAAE;IAC5G,EAAE,OAAOC,OAAO;QACdC,QAAQD,KAAK,CAAC,gCAAgC;YAAEjB,QAAQL,MAAMK,MAAM;YAAEiB;QAAM;QAC5E,OAAO;YAAEnB,QAAQ;QAAa;IAChC;AACF"}
|
|
@@ -0,0 +1,125 @@
|
|
|
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 { AglynOrgBilling } from '@aglyn/aglyn/foundation/definitions/org-billing.types';
|
|
18
|
+
import { AI_THEME_BRAND_BUDGET_MS } from './ai-job-theme-budget';
|
|
19
|
+
import { aiMediaAssetLocation, type AiMediaAssetLocation } from './ai-media-asset';
|
|
20
|
+
/**
|
|
21
|
+
* The brand a theme job builds on (AGL-2938): the colors that belong to the
|
|
22
|
+
* site before anyone describes them.
|
|
23
|
+
*
|
|
24
|
+
* - **The workspace's brand color** — a white-label workspace's, and only
|
|
25
|
+
* theirs: without the entitlement the resolved profile is the platform's,
|
|
26
|
+
* which is no customer's brand.
|
|
27
|
+
* - **The site logo** — when the logo is an asset of the site's own media
|
|
28
|
+
* library or its org's, read from storage and reduced to its dominant
|
|
29
|
+
* colors. Never fetched from a URL: a logo that is not a library asset is
|
|
30
|
+
* left alone.
|
|
31
|
+
* - **A page the brief links to** — fetched through the same SSRF guard the
|
|
32
|
+
* plugin fetch proxy uses (a public address, pinned; https only; every
|
|
33
|
+
* redirect re-validated), capped in bytes and time, and reduced to the
|
|
34
|
+
* colors its markup and stylesheets use.
|
|
35
|
+
*
|
|
36
|
+
* Only hex colors leave this module. Nothing a page or a logo SAYS reaches a
|
|
37
|
+
* prompt, so there is nothing in them to follow. Each source is best effort:
|
|
38
|
+
* one that cannot be read is named in a note and the proposal is made
|
|
39
|
+
* without it.
|
|
40
|
+
*/
|
|
41
|
+
export type AiThemeBrandSource = 'organization' | 'logo' | 'reference';
|
|
42
|
+
/** How the prompt names where each brand color came from. */
|
|
43
|
+
export declare const AI_THEME_BRAND_SOURCE_WORDS: Record<AiThemeBrandSource, string>;
|
|
44
|
+
export interface AiThemeBrandColor {
|
|
45
|
+
hex: string;
|
|
46
|
+
source: AiThemeBrandSource;
|
|
47
|
+
}
|
|
48
|
+
export interface AiThemeBrandInputs {
|
|
49
|
+
colors: AiThemeBrandColor[];
|
|
50
|
+
/** A source that could not be read, in customer-safe words. */
|
|
51
|
+
notes: string[];
|
|
52
|
+
}
|
|
53
|
+
/** The most colors one source contributes. */
|
|
54
|
+
export declare const AI_THEME_BRAND_COLORS_PER_SOURCE = 4;
|
|
55
|
+
/** The largest logo decoded for its colors. */
|
|
56
|
+
export declare const AI_THEME_LOGO_MAX_BYTES: number;
|
|
57
|
+
/** The most of a linked page, and of each of its stylesheets, that is read. */
|
|
58
|
+
export declare const AI_THEME_REFERENCE_MAX_BYTES: number;
|
|
59
|
+
export declare const AI_THEME_STYLESHEET_MAX_BYTES: number;
|
|
60
|
+
/** The stylesheets of a linked page that are read beside it. */
|
|
61
|
+
export declare const AI_THEME_REFERENCE_STYLESHEETS = 2;
|
|
62
|
+
/**
|
|
63
|
+
* The wall clock brand colors may take, declared with the theme step's time
|
|
64
|
+
* (`ai-job-theme-budget.ts`), which counts it (AGL-3035).
|
|
65
|
+
*/
|
|
66
|
+
export { AI_THEME_BRAND_BUDGET_MS };
|
|
67
|
+
/** A white-label workspace's own brand color; nothing for any other workspace. */
|
|
68
|
+
export declare function organizationBrandColors(org: Partial<AglynOrgBilling> | null | undefined): AiThemeBrandColor[];
|
|
69
|
+
export type AiThemeLogoLocation = AiMediaAssetLocation;
|
|
70
|
+
/**
|
|
71
|
+
* Where a site's logo lives in a media library: a media reference or a CDN
|
|
72
|
+
* path naming this site's library, or its org's. Anything else — an external
|
|
73
|
+
* URL, an asset of some other site or org — has no location, and the logo is
|
|
74
|
+
* left alone. The media library's own rule, shared with every job that reads
|
|
75
|
+
* an asset (`ai-media-asset.ts`).
|
|
76
|
+
*/
|
|
77
|
+
export declare const logoMediaLocation: typeof aiMediaAssetLocation;
|
|
78
|
+
/**
|
|
79
|
+
* The dominant colors of an image's pixels: transparent pixels skipped, the
|
|
80
|
+
* rest grouped into coarse buckets, the busiest distinct buckets first, and
|
|
81
|
+
* the near-white and near-black edges a logo sits on dropped while anything
|
|
82
|
+
* else is there.
|
|
83
|
+
*/
|
|
84
|
+
export declare function dominantColorsFromPixels(data: ArrayLike<number>, channels: number, count?: number): string[];
|
|
85
|
+
/** The first https link in a brief, or `null` — an http link is not followed. */
|
|
86
|
+
export declare function referenceUrlOf(brief: string): URL | null;
|
|
87
|
+
/** How much a page's declared `theme-color` counts beside one use of a color. */
|
|
88
|
+
export declare const AI_THEME_THEME_COLOR_WEIGHT = 25;
|
|
89
|
+
/** Every color a page's markup or a stylesheet uses, weighted by how often. */
|
|
90
|
+
export declare function colorsFromMarkup(text: string): Map<string, number>;
|
|
91
|
+
/** The https stylesheets a page links, resolved against it, at most a few. */
|
|
92
|
+
export declare function stylesheetUrlsOf(html: string, pageUrl: string): string[];
|
|
93
|
+
/** The most used distinct colors, the colorful before the greys. */
|
|
94
|
+
export declare function rankBrandColors(weights: ReadonlyMap<string, number>, count?: number): string[];
|
|
95
|
+
/**
|
|
96
|
+
* A public https resource as text, through the plugin fetch proxy's SSRF
|
|
97
|
+
* guard: the host must resolve only to public addresses and the socket is
|
|
98
|
+
* pinned to the address checked; no credentials in the URL and no port but
|
|
99
|
+
* the default; every redirect re-enters the same checks; the body is read to
|
|
100
|
+
* a byte cap under a clock, and only a content type the caller accepts is
|
|
101
|
+
* read at all. `null` for anything that does not hold.
|
|
102
|
+
*/
|
|
103
|
+
export declare function fetchPublicText(url: string, options: {
|
|
104
|
+
maxBytes: number;
|
|
105
|
+
accept: RegExp;
|
|
106
|
+
signal?: AbortSignal;
|
|
107
|
+
timeoutMs?: number;
|
|
108
|
+
}): Promise<{
|
|
109
|
+
text: string;
|
|
110
|
+
url: string;
|
|
111
|
+
} | null>;
|
|
112
|
+
/** The two reads that leave the process, replaceable where a spec needs to. */
|
|
113
|
+
export interface AiThemeBrandSeams {
|
|
114
|
+
logoColors?: (firestore: FirebaseFirestore.Firestore, location: AiThemeLogoLocation, hostId: string) => Promise<string[] | null>;
|
|
115
|
+
referenceColors?: (url: URL, signal: AbortSignal) => Promise<string[] | null>;
|
|
116
|
+
}
|
|
117
|
+
export declare function gatherAiThemeBrandInputs(input: {
|
|
118
|
+
firestore: FirebaseFirestore.Firestore;
|
|
119
|
+
org: Partial<AglynOrgBilling> | null;
|
|
120
|
+
hostId: string;
|
|
121
|
+
/** The site's host document. */
|
|
122
|
+
host: Record<string, unknown>;
|
|
123
|
+
brief: string;
|
|
124
|
+
signal?: AbortSignal;
|
|
125
|
+
}, seams?: AiThemeBrandSeams): Promise<AiThemeBrandInputs>;
|
|
@@ -0,0 +1,378 @@
|
|
|
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 { checkEntitlement } from "@aglyn/aglyn/app-utils/plan-entitlements";
|
|
17
|
+
import { normalizeThemeHex } from "../tools/ai-theme-tool.js";
|
|
18
|
+
import { AI_THEME_BRAND_BUDGET_MS } from "./ai-job-theme-budget.js";
|
|
19
|
+
import { aiMediaAssetLocation, loadAiMediaSharp, readAiMediaAssetBytes } from "./ai-media-asset.js";
|
|
20
|
+
/** How the prompt names where each brand color came from. */ export const AI_THEME_BRAND_SOURCE_WORDS = {
|
|
21
|
+
organization: 'the workspace brand color',
|
|
22
|
+
logo: 'from the site logo',
|
|
23
|
+
reference: 'from the page the brief links to'
|
|
24
|
+
};
|
|
25
|
+
/** The most colors one source contributes. */ export const AI_THEME_BRAND_COLORS_PER_SOURCE = 4;
|
|
26
|
+
/** The largest logo decoded for its colors. */ export const AI_THEME_LOGO_MAX_BYTES = 5 * 1024 * 1024;
|
|
27
|
+
/** The most of a linked page, and of each of its stylesheets, that is read. */ export const AI_THEME_REFERENCE_MAX_BYTES = 512 * 1024;
|
|
28
|
+
export const AI_THEME_STYLESHEET_MAX_BYTES = 256 * 1024;
|
|
29
|
+
/** The stylesheets of a linked page that are read beside it. */ export const AI_THEME_REFERENCE_STYLESHEETS = 2;
|
|
30
|
+
/**
|
|
31
|
+
* The wall clock brand colors may take, declared with the theme step's time
|
|
32
|
+
* (`ai-job-theme-budget.ts`), which counts it (AGL-3035).
|
|
33
|
+
*/ export { AI_THEME_BRAND_BUDGET_MS };
|
|
34
|
+
const FETCH_TIMEOUT_MS = 4000;
|
|
35
|
+
const MAX_REDIRECT_HOPS = 3;
|
|
36
|
+
const REDIRECT_STATUSES = new Set([
|
|
37
|
+
301,
|
|
38
|
+
302,
|
|
39
|
+
303,
|
|
40
|
+
307,
|
|
41
|
+
308
|
|
42
|
+
]);
|
|
43
|
+
const toHex = ([red, green, blue])=>`#${[
|
|
44
|
+
red,
|
|
45
|
+
green,
|
|
46
|
+
blue
|
|
47
|
+
].map((channel)=>Math.round(Math.min(255, Math.max(0, channel))).toString(16).padStart(2, '0')).join('')}`;
|
|
48
|
+
const channelsOf = (hex)=>[
|
|
49
|
+
parseInt(hex.slice(1, 3), 16),
|
|
50
|
+
parseInt(hex.slice(3, 5), 16),
|
|
51
|
+
parseInt(hex.slice(5, 7), 16)
|
|
52
|
+
];
|
|
53
|
+
const distance = (a, b)=>Math.hypot(a[0] - b[0], a[1] - b[1], a[2] - b[2]);
|
|
54
|
+
/** How far a color is from grey: the spread of its channels. */ const chroma = ([red, green, blue])=>Math.max(red, green, blue) - Math.min(red, green, blue);
|
|
55
|
+
/** Colors closer than this read as the same color in a palette. */ const SAME_COLOR_DISTANCE = 40;
|
|
56
|
+
/** A spread under this reads as a grey, which says little about a brand. */ const GREY_CHROMA = 38;
|
|
57
|
+
/** The distinct colors of a ranked list, colorful ones first when there are any. */ function distinctColors(ranked, count) {
|
|
58
|
+
const colorful = ranked.filter((color)=>chroma(color) > GREY_CHROMA);
|
|
59
|
+
const chosen = [];
|
|
60
|
+
for (const color of colorful.length ? colorful : ranked){
|
|
61
|
+
if (chosen.some((other)=>distance(other, color) < SAME_COLOR_DISTANCE)) continue;
|
|
62
|
+
chosen.push(color);
|
|
63
|
+
if (chosen.length === count) break;
|
|
64
|
+
}
|
|
65
|
+
return chosen.map(toHex);
|
|
66
|
+
}
|
|
67
|
+
/* ------------------------------------------------------------------------ *
|
|
68
|
+
* The workspace's brand color
|
|
69
|
+
* ------------------------------------------------------------------------ */ /** A white-label workspace's own brand color; nothing for any other workspace. */ export function organizationBrandColors(org) {
|
|
70
|
+
var _org_brandingProfile;
|
|
71
|
+
if (!checkEntitlement(org, 'whiteLabel')) return [];
|
|
72
|
+
const raw = org == null ? void 0 : (_org_brandingProfile = org.brandingProfile) == null ? void 0 : _org_brandingProfile.primaryColor;
|
|
73
|
+
const hex = typeof raw === 'string' ? normalizeThemeHex(raw) : null;
|
|
74
|
+
return hex ? [
|
|
75
|
+
{
|
|
76
|
+
hex,
|
|
77
|
+
source: 'organization'
|
|
78
|
+
}
|
|
79
|
+
] : [];
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Where a site's logo lives in a media library: a media reference or a CDN
|
|
83
|
+
* path naming this site's library, or its org's. Anything else — an external
|
|
84
|
+
* URL, an asset of some other site or org — has no location, and the logo is
|
|
85
|
+
* left alone. The media library's own rule, shared with every job that reads
|
|
86
|
+
* an asset (`ai-media-asset.ts`).
|
|
87
|
+
*/ export const logoMediaLocation = aiMediaAssetLocation;
|
|
88
|
+
/**
|
|
89
|
+
* The dominant colors of an image's pixels: transparent pixels skipped, the
|
|
90
|
+
* rest grouped into coarse buckets, the busiest distinct buckets first, and
|
|
91
|
+
* the near-white and near-black edges a logo sits on dropped while anything
|
|
92
|
+
* else is there.
|
|
93
|
+
*/ export function dominantColorsFromPixels(data, channels, count = AI_THEME_BRAND_COLORS_PER_SOURCE) {
|
|
94
|
+
const buckets = new Map();
|
|
95
|
+
for(let index = 0; index + channels <= data.length; index += channels){
|
|
96
|
+
var _buckets_get;
|
|
97
|
+
if (channels >= 4 && data[index + 3] < 128) continue;
|
|
98
|
+
const pixel = [
|
|
99
|
+
data[index],
|
|
100
|
+
data[index + 1],
|
|
101
|
+
data[index + 2]
|
|
102
|
+
];
|
|
103
|
+
const key = pixel[0] >> 4 << 8 | pixel[1] >> 4 << 4 | pixel[2] >> 4;
|
|
104
|
+
const bucket = (_buckets_get = buckets.get(key)) != null ? _buckets_get : {
|
|
105
|
+
sum: [
|
|
106
|
+
0,
|
|
107
|
+
0,
|
|
108
|
+
0
|
|
109
|
+
],
|
|
110
|
+
pixels: 0
|
|
111
|
+
};
|
|
112
|
+
bucket.sum = [
|
|
113
|
+
bucket.sum[0] + pixel[0],
|
|
114
|
+
bucket.sum[1] + pixel[1],
|
|
115
|
+
bucket.sum[2] + pixel[2]
|
|
116
|
+
];
|
|
117
|
+
bucket.pixels += 1;
|
|
118
|
+
buckets.set(key, bucket);
|
|
119
|
+
}
|
|
120
|
+
const ranked = [
|
|
121
|
+
...buckets.values()
|
|
122
|
+
].sort((a, b)=>b.pixels - a.pixels).map(({ sum, pixels })=>[
|
|
123
|
+
sum[0] / pixels,
|
|
124
|
+
sum[1] / pixels,
|
|
125
|
+
sum[2] / pixels
|
|
126
|
+
]);
|
|
127
|
+
const edge = (color)=>Math.min(...color) > 235 || Math.max(...color) < 20;
|
|
128
|
+
const inside = ranked.filter((color)=>!edge(color));
|
|
129
|
+
return distinctColors(inside.length ? inside : ranked, count);
|
|
130
|
+
}
|
|
131
|
+
const LOGO_TYPES = /^image\/(png|jpeg|webp|gif|avif|svg\+xml)$/;
|
|
132
|
+
/**
|
|
133
|
+
* A library logo's colors, read the way the media CDN would serve it
|
|
134
|
+
* (`readAiMediaAssetBytes`). `null` when the asset may not be read or the bytes
|
|
135
|
+
* cannot be decoded.
|
|
136
|
+
*/ async function readLogoColors(firestore, location, hostId) {
|
|
137
|
+
const asset = await readAiMediaAssetBytes(firestore, location, hostId, {
|
|
138
|
+
maxBytes: AI_THEME_LOGO_MAX_BYTES,
|
|
139
|
+
types: LOGO_TYPES
|
|
140
|
+
});
|
|
141
|
+
if (!asset) return null;
|
|
142
|
+
const sharp = await loadAiMediaSharp();
|
|
143
|
+
const { data, info } = await sharp(asset.buffer, {
|
|
144
|
+
limitInputPixels: 64000000
|
|
145
|
+
}).resize(48, 48, {
|
|
146
|
+
fit: 'inside'
|
|
147
|
+
}).ensureAlpha().raw().toBuffer({
|
|
148
|
+
resolveWithObject: true
|
|
149
|
+
});
|
|
150
|
+
return dominantColorsFromPixels(data, info.channels);
|
|
151
|
+
}
|
|
152
|
+
/* ------------------------------------------------------------------------ *
|
|
153
|
+
* A page the brief links to
|
|
154
|
+
* ------------------------------------------------------------------------ */ const URL_IN_BRIEF = /\bhttps?:\/\/[^\s<>"'`)\]]+/i;
|
|
155
|
+
/** The first https link in a brief, or `null` — an http link is not followed. */ export function referenceUrlOf(brief) {
|
|
156
|
+
const match = URL_IN_BRIEF.exec(brief);
|
|
157
|
+
if (!match) return null;
|
|
158
|
+
try {
|
|
159
|
+
const url = new URL(match[0].replace(/[.,;:!?]+$/, ''));
|
|
160
|
+
return url.protocol === 'https:' ? url : null;
|
|
161
|
+
} catch (unused) {
|
|
162
|
+
return null;
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
/** How much a page's declared `theme-color` counts beside one use of a color. */ export const AI_THEME_THEME_COLOR_WEIGHT = 25;
|
|
166
|
+
const THEME_COLOR_META = /<meta\b[^>]*\bname\s*=\s*["']?theme-color\b[^>]*>/gi;
|
|
167
|
+
const CONTENT_ATTRIBUTE = /\bcontent\s*=\s*["']?\s*([^"'\s>]+)/i;
|
|
168
|
+
// A `#` after `&` is a character reference (`'`), not a color.
|
|
169
|
+
const HEX_LITERAL = /(?<!&)#(?:[0-9a-f]{6}|[0-9a-f]{3})(?![0-9a-z])/gi;
|
|
170
|
+
const RGB_LITERAL = /rgba?\(\s*(\d{1,3})\s*[,\s]\s*(\d{1,3})\s*[,\s]\s*(\d{1,3})/gi;
|
|
171
|
+
/** Every color a page's markup or a stylesheet uses, weighted by how often. */ export function colorsFromMarkup(text) {
|
|
172
|
+
var _text_match;
|
|
173
|
+
const weights = new Map();
|
|
174
|
+
const add = (hex, weight)=>{
|
|
175
|
+
var _weights_get;
|
|
176
|
+
if (hex) weights.set(hex, ((_weights_get = weights.get(hex)) != null ? _weights_get : 0) + weight);
|
|
177
|
+
};
|
|
178
|
+
for (const tag of (_text_match = text.match(THEME_COLOR_META)) != null ? _text_match : []){
|
|
179
|
+
var _ref;
|
|
180
|
+
var _CONTENT_ATTRIBUTE_exec;
|
|
181
|
+
add(normalizeThemeHex((_ref = (_CONTENT_ATTRIBUTE_exec = CONTENT_ATTRIBUTE.exec(tag)) == null ? void 0 : _CONTENT_ATTRIBUTE_exec[1]) != null ? _ref : ''), AI_THEME_THEME_COLOR_WEIGHT);
|
|
182
|
+
}
|
|
183
|
+
for (const match of text.matchAll(HEX_LITERAL))add(normalizeThemeHex(match[0]), 1);
|
|
184
|
+
for (const match of text.matchAll(RGB_LITERAL)){
|
|
185
|
+
add(toHex([
|
|
186
|
+
Number(match[1]),
|
|
187
|
+
Number(match[2]),
|
|
188
|
+
Number(match[3])
|
|
189
|
+
]), 1);
|
|
190
|
+
}
|
|
191
|
+
return weights;
|
|
192
|
+
}
|
|
193
|
+
const STYLESHEET_LINK = /<link\b[^>]*\brel\s*=\s*["']?stylesheet\b[^>]*>/gi;
|
|
194
|
+
const HREF_ATTRIBUTE = /\bhref\s*=\s*["']?\s*([^"'\s>]+)/i;
|
|
195
|
+
/** The https stylesheets a page links, resolved against it, at most a few. */ export function stylesheetUrlsOf(html, pageUrl) {
|
|
196
|
+
var _html_match;
|
|
197
|
+
const urls = [];
|
|
198
|
+
for (const tag of (_html_match = html.match(STYLESHEET_LINK)) != null ? _html_match : []){
|
|
199
|
+
var _HREF_ATTRIBUTE_exec;
|
|
200
|
+
const href = (_HREF_ATTRIBUTE_exec = HREF_ATTRIBUTE.exec(tag)) == null ? void 0 : _HREF_ATTRIBUTE_exec[1];
|
|
201
|
+
if (!href) continue;
|
|
202
|
+
try {
|
|
203
|
+
const url = new URL(href, pageUrl);
|
|
204
|
+
if (url.protocol === 'https:' && !urls.includes(url.toString())) urls.push(url.toString());
|
|
205
|
+
} catch (unused) {
|
|
206
|
+
continue;
|
|
207
|
+
}
|
|
208
|
+
if (urls.length === AI_THEME_REFERENCE_STYLESHEETS) break;
|
|
209
|
+
}
|
|
210
|
+
return urls;
|
|
211
|
+
}
|
|
212
|
+
/** The most used distinct colors, the colorful before the greys. */ export function rankBrandColors(weights, count = AI_THEME_BRAND_COLORS_PER_SOURCE) {
|
|
213
|
+
const ranked = [
|
|
214
|
+
...weights.entries()
|
|
215
|
+
].sort((a, b)=>b[1] - a[1]).map(([hex])=>channelsOf(hex));
|
|
216
|
+
return distinctColors(ranked, count);
|
|
217
|
+
}
|
|
218
|
+
/** One abort for the caller's signal and a clock, whichever ends first. */ function deadline(signal, ms) {
|
|
219
|
+
const controller = new AbortController();
|
|
220
|
+
const timer = setTimeout(()=>controller.abort(), ms);
|
|
221
|
+
const onAbort = ()=>controller.abort();
|
|
222
|
+
if (signal == null ? void 0 : signal.aborted) controller.abort();
|
|
223
|
+
signal == null ? void 0 : signal.addEventListener('abort', onAbort);
|
|
224
|
+
return {
|
|
225
|
+
signal: controller.signal,
|
|
226
|
+
done: ()=>{
|
|
227
|
+
clearTimeout(timer);
|
|
228
|
+
signal == null ? void 0 : signal.removeEventListener('abort', onAbort);
|
|
229
|
+
}
|
|
230
|
+
};
|
|
231
|
+
}
|
|
232
|
+
async function readCapped(body, maxBytes) {
|
|
233
|
+
const reader = body.getReader();
|
|
234
|
+
const chunks = [];
|
|
235
|
+
let total = 0;
|
|
236
|
+
for(;;){
|
|
237
|
+
const { done, value } = await reader.read();
|
|
238
|
+
if (done || !value) break;
|
|
239
|
+
const room = maxBytes - total;
|
|
240
|
+
if (value.byteLength >= room) {
|
|
241
|
+
chunks.push(value.subarray(0, room));
|
|
242
|
+
await reader.cancel().catch(()=>undefined);
|
|
243
|
+
break;
|
|
244
|
+
}
|
|
245
|
+
chunks.push(value);
|
|
246
|
+
total += value.byteLength;
|
|
247
|
+
}
|
|
248
|
+
const joined = new Uint8Array(chunks.reduce((sum, chunk)=>sum + chunk.byteLength, 0));
|
|
249
|
+
let offset = 0;
|
|
250
|
+
for (const chunk of chunks){
|
|
251
|
+
joined.set(chunk, offset);
|
|
252
|
+
offset += chunk.byteLength;
|
|
253
|
+
}
|
|
254
|
+
return new TextDecoder().decode(joined);
|
|
255
|
+
}
|
|
256
|
+
/**
|
|
257
|
+
* A public https resource as text, through the plugin fetch proxy's SSRF
|
|
258
|
+
* guard: the host must resolve only to public addresses and the socket is
|
|
259
|
+
* pinned to the address checked; no credentials in the URL and no port but
|
|
260
|
+
* the default; every redirect re-enters the same checks; the body is read to
|
|
261
|
+
* a byte cap under a clock, and only a content type the caller accepts is
|
|
262
|
+
* read at all. `null` for anything that does not hold.
|
|
263
|
+
*/ export async function fetchPublicText(url, options) {
|
|
264
|
+
const { createPinnedDispatcher, resolvePublicIp } = await import("./ai-theme-brand-server.js");
|
|
265
|
+
let current = url;
|
|
266
|
+
for(let hop = 0; hop <= MAX_REDIRECT_HOPS; hop += 1){
|
|
267
|
+
var _options_timeoutMs;
|
|
268
|
+
let parsed;
|
|
269
|
+
try {
|
|
270
|
+
parsed = new URL(current);
|
|
271
|
+
} catch (unused) {
|
|
272
|
+
return null;
|
|
273
|
+
}
|
|
274
|
+
if (parsed.protocol !== 'https:' || parsed.username || parsed.password) return null;
|
|
275
|
+
if (parsed.port && parsed.port !== '443') return null;
|
|
276
|
+
const pinned = await resolvePublicIp(parsed.hostname);
|
|
277
|
+
if (!pinned) return null;
|
|
278
|
+
const dispatcher = createPinnedDispatcher(pinned);
|
|
279
|
+
const clock = deadline(options.signal, (_options_timeoutMs = options.timeoutMs) != null ? _options_timeoutMs : FETCH_TIMEOUT_MS);
|
|
280
|
+
try {
|
|
281
|
+
var _response_headers_get;
|
|
282
|
+
// `dispatcher` is undici's, which the global fetch honors; a variable
|
|
283
|
+
// rather than a literal keeps the DOM `RequestInit` check off it.
|
|
284
|
+
const init = {
|
|
285
|
+
method: 'GET',
|
|
286
|
+
redirect: 'manual',
|
|
287
|
+
signal: clock.signal,
|
|
288
|
+
dispatcher,
|
|
289
|
+
headers: {
|
|
290
|
+
Accept: 'text/html, text/css;q=0.9'
|
|
291
|
+
}
|
|
292
|
+
};
|
|
293
|
+
const response = await fetch(parsed.toString(), init);
|
|
294
|
+
if (REDIRECT_STATUSES.has(response.status)) {
|
|
295
|
+
const location = response.headers.get('location');
|
|
296
|
+
if (!location) return null;
|
|
297
|
+
current = new URL(location, parsed).toString();
|
|
298
|
+
continue;
|
|
299
|
+
}
|
|
300
|
+
if (!response.ok || !response.body) return null;
|
|
301
|
+
if (!options.accept.test((_response_headers_get = response.headers.get('content-type')) != null ? _response_headers_get : '')) return null;
|
|
302
|
+
return {
|
|
303
|
+
text: await readCapped(response.body, options.maxBytes),
|
|
304
|
+
url: parsed.toString()
|
|
305
|
+
};
|
|
306
|
+
} catch (unused) {
|
|
307
|
+
return null;
|
|
308
|
+
} finally{
|
|
309
|
+
clock.done();
|
|
310
|
+
await dispatcher.close().catch(()=>undefined);
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
return null;
|
|
314
|
+
}
|
|
315
|
+
/** A linked page's colors, from its markup and its first stylesheets. */ async function readReferenceColors(url, signal) {
|
|
316
|
+
const page = await fetchPublicText(url.toString(), {
|
|
317
|
+
maxBytes: AI_THEME_REFERENCE_MAX_BYTES,
|
|
318
|
+
accept: /text\/html|application\/xhtml\+xml/i,
|
|
319
|
+
signal
|
|
320
|
+
});
|
|
321
|
+
if (!page) return null;
|
|
322
|
+
const weights = colorsFromMarkup(page.text);
|
|
323
|
+
for (const sheet of stylesheetUrlsOf(page.text, page.url)){
|
|
324
|
+
const css = await fetchPublicText(sheet, {
|
|
325
|
+
maxBytes: AI_THEME_STYLESHEET_MAX_BYTES,
|
|
326
|
+
accept: /text\/css/i,
|
|
327
|
+
signal
|
|
328
|
+
});
|
|
329
|
+
if (!css) continue;
|
|
330
|
+
for (const [hex, weight] of colorsFromMarkup(css.text)){
|
|
331
|
+
var _weights_get;
|
|
332
|
+
weights.set(hex, ((_weights_get = weights.get(hex)) != null ? _weights_get : 0) + weight);
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
return rankBrandColors(weights);
|
|
336
|
+
}
|
|
337
|
+
export async function gatherAiThemeBrandInputs(input, seams = {}) {
|
|
338
|
+
const colors = [
|
|
339
|
+
...organizationBrandColors(input.org)
|
|
340
|
+
];
|
|
341
|
+
const notes = [];
|
|
342
|
+
const clock = deadline(input.signal, AI_THEME_BRAND_BUDGET_MS);
|
|
343
|
+
const add = (found, source)=>{
|
|
344
|
+
for (const hex of found.slice(0, AI_THEME_BRAND_COLORS_PER_SOURCE)){
|
|
345
|
+
if (!colors.some((color)=>color.hex === hex)) colors.push({
|
|
346
|
+
hex,
|
|
347
|
+
source
|
|
348
|
+
});
|
|
349
|
+
}
|
|
350
|
+
};
|
|
351
|
+
try {
|
|
352
|
+
var _input_host_orgId;
|
|
353
|
+
const location = logoMediaLocation(input.host['logoUrl'], input.hostId, String((_input_host_orgId = input.host['orgId']) != null ? _input_host_orgId : ''));
|
|
354
|
+
if (location) {
|
|
355
|
+
var _seams_logoColors;
|
|
356
|
+
const found = await ((_seams_logoColors = seams.logoColors) != null ? _seams_logoColors : readLogoColors)(input.firestore, location, input.hostId).catch(()=>null);
|
|
357
|
+
if (found) add(found, 'logo');
|
|
358
|
+
else notes.push("The site logo's colors could not be read, so the proposal does not use them.");
|
|
359
|
+
}
|
|
360
|
+
const reference = referenceUrlOf(input.brief);
|
|
361
|
+
if (reference) {
|
|
362
|
+
var _seams_referenceColors;
|
|
363
|
+
const found = clock.signal.aborted ? null : await ((_seams_referenceColors = seams.referenceColors) != null ? _seams_referenceColors : readReferenceColors)(reference, clock.signal).catch(()=>null);
|
|
364
|
+
if (found == null ? void 0 : found.length) add(found, 'reference');
|
|
365
|
+
else {
|
|
366
|
+
notes.push(`The page at ${reference.hostname} could not be read for its colors, so the proposal does not use them.`);
|
|
367
|
+
}
|
|
368
|
+
}
|
|
369
|
+
} finally{
|
|
370
|
+
clock.done();
|
|
371
|
+
}
|
|
372
|
+
return {
|
|
373
|
+
colors,
|
|
374
|
+
notes
|
|
375
|
+
};
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
//# sourceMappingURL=ai-theme-brand-inputs.js.map
|