@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 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../../../../libs/plugins/ai/src/lib/model/ai-plan-capabilities.ts"],"sourcesContent":["/**\n * @license\n * Copyright 2026 Aglyn LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n AI_BUILD_PLAN_CREATE_KINDS,\n AI_BUILD_PLAN_CREATION_NOUNS,\n type AiBuildPlan,\n type AiBuildPlanCreateKind,\n} from './ai-build-plan'\n\n/**\n * What a plan may create on one site (AGL-3030): the workspace's plan and the\n * site's counts against its limits, narrowed to what the job itself builds.\n *\n * A plan that names a creation nothing can make is a dead end the member pays\n * for twice: once for the plan, and again for the plan they describe after\n * being told to make the creation by hand — which, on a workspace whose plan\n * does not include it, they cannot. So the plan step is TOLD what may be\n * created before it answers, and the plan rules refuse a creation outside it\n * with the one re-ask every other rule gets.\n *\n * ── Where the doctrine builds inline ─────────────────────────────────────\n *\n * The building doctrine makes a repeat a reusable component and a form a\n * saved form placed by id. A workspace whose plan keeps no reusable\n * components can do neither: the create route refuses a component and a\n * saved form on that entitlement. There, and only there, the doctrine builds\n * inline instead — a form is a Form element the page carries with its fields\n * inside it, which the site's submit route collects like any other, and a\n * list's repeated items are drawn in one section (AGL-3071).\n * `reusableComponents` is the one flag every validator reads for that.\n *\n * ── Kept out of the cached prefix ────────────────────────────────────────\n *\n * The capabilities are per workspace and per site, so they ride the plan's\n * USER turn, never a system block: the doctrine's cached prefix stays one\n * entry for the platform. The doctrine states the rule once — create only\n * what the request says may be created, and build inline where it says the\n * workspace keeps no reusable components — and the request states the facts.\n *\n * This module imports nothing at runtime beyond the plan's own model, so the\n * validators, the plan step, the doors and their specs read one vocabulary.\n * What a workspace's plan and counts come to is read by\n * `readAiPlanCapabilities` in `jobs/ai-job-drafts.ts`, beside the band\n * arithmetic the create route and the draft writer share.\n */\n\n/** One creation kind, as a job on this site may make it or not. */\nexport interface AiPlanCreation {\n allowed: boolean\n /** How many more the site may hold; `null` when the plan counts none. */\n left: number | null\n /**\n * Why not, as a clause a sentence completes: \"this workspace's plan does\n * not include reusable components\". `null` when allowed.\n */\n reason: string | null\n}\n\nexport interface AiPlanCapabilities {\n /**\n * Whether the workspace keeps reusable components and saved forms. Where\n * it does not, the doctrine builds inline: a form is a Form element holding\n * its fields, and a list's repeated items are drawn in one section.\n */\n reusableComponents: boolean\n /** Every creation kind a plan may name, and whether this job may make one here. */\n create: Readonly<Record<AiBuildPlanCreateKind, AiPlanCreation>>\n /**\n * Whether the workspace spends the Free taste, whose monthly credits are a\n * wall (AGL-2925): a plan is then held to the sections the wall's worst\n * case pays for (AGL-3070). Absent is `false`.\n */\n freeTaste?: boolean\n}\n\n/** What a job of one kind builds from its own plan, where it builds only some creations. */\nexport interface AiPlanJobScope {\n /** The job as a refusal names it: \"a page job\". */\n noun: string\n /** The creation kinds the job builds itself; any other is refused before the plan is kept. */\n creates: readonly AiBuildPlanCreateKind[]\n}\n\nconst ALLOWED: AiPlanCreation = { allowed: true, left: null, reason: null }\n\n/**\n * Capabilities that restrict nothing: what a plan is held to when no\n * workspace was read — an org-level job, an eval, a spec about something\n * else. The doctrine applies whole.\n */\nexport function aiUnrestrictedPlanCapabilities(): AiPlanCapabilities {\n return {\n reusableComponents: true,\n create: Object.fromEntries(\n AI_BUILD_PLAN_CREATE_KINDS.map((kind) => [kind, ALLOWED]),\n ) as Record<AiBuildPlanCreateKind, AiPlanCreation>,\n }\n}\n\n/**\n * The workspace's capabilities narrowed to what a job of one kind builds.\n * A creation the workspace itself cannot make keeps the workspace's reason,\n * which is the one a member can act on; one the job does not build says so.\n */\nexport function aiPlanCapabilitiesForJob(\n capabilities: AiPlanCapabilities,\n scope: AiPlanJobScope | null | undefined,\n): AiPlanCapabilities {\n if (!scope) return capabilities\n const create = { ...capabilities.create }\n for (const kind of AI_BUILD_PLAN_CREATE_KINDS) {\n if (!create[kind].allowed || scope.creates.includes(kind)) continue\n create[kind] = { allowed: false, left: null, reason: `${scope.noun} does not build one` }\n }\n return { ...capabilities, create }\n}\n\n/** \"a layout\", \"an email design\": a creation kind with its article. */\nexport function aiCreationNoun(kind: AiBuildPlanCreateKind): string {\n const noun = AI_BUILD_PLAN_CREATION_NOUNS[kind].noun\n return `${/^[aeiou]/.test(noun) ? 'an' : 'a'} ${noun}`\n}\n\n/**\n * The sentence a request states when the workspace keeps no reusable\n * components. It says a list's repeated items go in one section (AGL-3071):\n * \"a repeated item in its own section\" reads just as well as a section for\n * each item, which is how a live About page's four practice areas came to be\n * planned as four sections of one item.\n */\nexport const AI_PLAN_INLINE_SENTENCE =\n \"This workspace keeps no reusable components or saved forms: draw a list's repeated items in one section, and a form as a Form element holding its Form Fields.\"\n\n/**\n * What the plan step's user turn says the job may create here: one line a\n * kind, and the inline sentence where the workspace keeps no reusable\n * components. Per workspace and per site, so it is never a system block.\n */\nexport function aiPlanCapabilityLines(capabilities: AiPlanCapabilities): string[] {\n const lines = ['What this job may create on this site:']\n for (const kind of AI_BUILD_PLAN_CREATE_KINDS) {\n const entry = capabilities.create[kind]\n const noun = AI_BUILD_PLAN_CREATION_NOUNS[kind].noun\n if (entry.allowed) {\n lines.push(`- ${noun}: yes${entry.left === null ? '' : `, ${entry.left} more`}`)\n } else {\n lines.push(`- ${noun}: no, because ${entry.reason ?? 'it cannot be made here'}`)\n }\n }\n if (!capabilities.reusableComponents) lines.push(AI_PLAN_INLINE_SENTENCE)\n return lines\n}\n\n/** What to do instead of a creation the job may not make, for the re-ask and the review. */\nfunction insteadOf(kind: AiBuildPlanCreateKind, capabilities: AiPlanCapabilities): string {\n switch (kind) {\n case 'component':\n return capabilities.reusableComponents\n ? 'Place a component the site already has.'\n : \"Draw a list's repeated items in one section instead.\"\n case 'form':\n return capabilities.reusableComponents\n ? 'Place a form the site already has.'\n : 'Draw the form on the page instead, as a Form element holding its Form Fields.'\n case 'layout':\n return 'Put the page in a layout the site already has.'\n case 'template':\n return 'Build the page without a template.'\n case 'theme-change':\n return \"Use the colors the theme already has.\"\n case 'dataset':\n return 'Bind a dataset or collection the site already has, or keep the list short enough to write out.'\n case 'email':\n return 'Leave the email out of this job.'\n }\n}\n\n/** One creation a plan names that this job may not make here. */\nexport interface AiPlanUncreatable {\n kind: AiBuildPlanCreateKind\n name: string\n /** The plan path of the creation: `create[2]`. */\n path: string\n /** Why not, as a clause: \"this site has room for 1 more\". */\n reason: string\n /** One customer-safe sentence: what was refused, why, and what to do instead. */\n message: string\n}\n\n/**\n * Why the nth creation of a kind may not be made here, as a clause; `null`\n * when it may. A kind the site may make only so many more of refuses the ones\n * past that count, not the first of them.\n */\nfunction refusedReason(capability: AiPlanCreation, nth: number): string | null {\n const overCount = capability.allowed && capability.left !== null && nth > capability.left\n if (capability.allowed && !overCount) return null\n return overCount\n ? `this site has room for ${capability.left} more`\n : (capability.reason ?? 'it cannot be made here')\n}\n\n/** The creations a plan names that the capabilities refuse, in plan order. */\nexport function aiPlanUncreatable(\n plan: Pick<AiBuildPlan, 'create'>,\n capabilities: AiPlanCapabilities,\n): AiPlanUncreatable[] {\n const refused: AiPlanUncreatable[] = []\n const counted = new Map<AiBuildPlanCreateKind, number>()\n plan.create.forEach((entry, index) => {\n const nth = (counted.get(entry.kind) ?? 0) + 1\n counted.set(entry.kind, nth)\n const reason = refusedReason(capabilities.create[entry.kind], nth)\n if (reason === null) return\n refused.push({\n kind: entry.kind,\n name: entry.name,\n path: `create[${index}]`,\n reason,\n message: `The plan creates ${aiCreationNoun(entry.kind)} named \"${entry.name}\", and ${reason}. ${insteadOf(entry.kind, capabilities)}`,\n })\n })\n return refused\n}\n\n/**\n * Why the plan could not add one more creation of a kind here, and what to\n * do instead; `null` when it could (AGL-3040). Counted past the creations of\n * that kind the plan already names, as `aiPlanUncreatable` counts them, so a\n * plan told to declare a creation is never told to declare one the next\n * answer is refused for.\n */\nexport function aiPlanUncreatableKind(\n plan: Pick<AiBuildPlan, 'create'>,\n kind: AiBuildPlanCreateKind,\n capabilities: AiPlanCapabilities,\n): { reason: string; instead: string } | null {\n const planned = plan.create.filter((entry) => entry.kind === kind).length\n const reason = refusedReason(capabilities.create[kind], planned + 1)\n return reason === null ? null : { reason, instead: insteadOf(kind, capabilities) }\n}\n"],"names":["AI_BUILD_PLAN_CREATE_KINDS","AI_BUILD_PLAN_CREATION_NOUNS","ALLOWED","allowed","left","reason","aiUnrestrictedPlanCapabilities","reusableComponents","create","Object","fromEntries","map","kind","aiPlanCapabilitiesForJob","capabilities","scope","creates","includes","noun","aiCreationNoun","test","AI_PLAN_INLINE_SENTENCE","aiPlanCapabilityLines","lines","entry","push","insteadOf","refusedReason","capability","nth","overCount","aiPlanUncreatable","plan","refused","counted","Map","forEach","index","get","set","name","path","message","aiPlanUncreatableKind","planned","filter","length","instead"],"mappings":"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"}
|
|
@@ -0,0 +1,251 @@
|
|
|
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 { AiJobOutput, AiJobSummary } from './ai-jobs.types';
|
|
18
|
+
/**
|
|
19
|
+
* COMMERCE BY AI (AGL-2916): what a `products` job is asked, and what it
|
|
20
|
+
* proposes. Pure, so the step that asks, the console cards that start a job
|
|
21
|
+
* and show its proposals, and the eval harness all read one shape.
|
|
22
|
+
*
|
|
23
|
+
* `inputs.target` names the work:
|
|
24
|
+
*
|
|
25
|
+
* - `product` — one product's copy, from what its editor holds right now:
|
|
26
|
+
* the name, the text, the tags, the categories and options it has, and the
|
|
27
|
+
* first photo. The editor may hold a product nobody has saved yet, so the
|
|
28
|
+
* job never reads a product document for this target.
|
|
29
|
+
* - `bulk` — the copy of up to `AI_PRODUCTS_BULK_MAX` saved products, one
|
|
30
|
+
* product a pass, each read from the catalog as it is reached.
|
|
31
|
+
* - `catalog` — a store's first products from the brief: names, copy, tags
|
|
32
|
+
* and options, and what each photo should show. No price and no picture.
|
|
33
|
+
* - `categories` — store categories and a first set of discounts from the brief.
|
|
34
|
+
*
|
|
35
|
+
* Every output is a PROPOSAL (`resource: 'product'`, with `proposal`), and the
|
|
36
|
+
* job writes nothing. The commerce plugin's own surfaces write what a person
|
|
37
|
+
* accepts, through the doors those surfaces already use.
|
|
38
|
+
*/
|
|
39
|
+
export declare const AI_PRODUCTS_TARGETS: readonly ["product", "bulk", "catalog", "categories"];
|
|
40
|
+
export type AiProductsTarget = (typeof AI_PRODUCTS_TARGETS)[number];
|
|
41
|
+
export declare const AI_PRODUCT_TYPES: readonly ["physical", "digital", "service"];
|
|
42
|
+
export type AiProductType = (typeof AI_PRODUCT_TYPES)[number];
|
|
43
|
+
/** The longest product name the editor saves. */
|
|
44
|
+
export declare const AI_PRODUCT_NAME_MAX_CHARS = 120;
|
|
45
|
+
/** How much of a product's existing description a request carries. */
|
|
46
|
+
export declare const AI_PRODUCT_TEXT_MAX_CHARS = 2000;
|
|
47
|
+
/** The longest description the job proposes. */
|
|
48
|
+
export declare const AI_PRODUCT_DESCRIPTION_MAX_CHARS = 1200;
|
|
49
|
+
export declare const AI_PRODUCT_TAGS_MAX = 8;
|
|
50
|
+
export declare const AI_PRODUCT_TAG_MAX_CHARS = 30;
|
|
51
|
+
/** The most categories one product's proposal names. */
|
|
52
|
+
export declare const AI_PRODUCT_CATEGORIES_MAX = 3;
|
|
53
|
+
/** The most of a site's categories a request lists to choose from. */
|
|
54
|
+
export declare const AI_PRODUCT_CATEGORY_LIST_MAX = 100;
|
|
55
|
+
/** A product's option axes, as the commerce editor bounds them. */
|
|
56
|
+
export declare const AI_PRODUCT_OPTIONS_MAX = 3;
|
|
57
|
+
export declare const AI_PRODUCT_OPTION_VALUES_MAX = 25;
|
|
58
|
+
export declare const AI_PRODUCT_OPTION_NAME_MAX_CHARS = 30;
|
|
59
|
+
/** The most products one bulk job writes the copy of. */
|
|
60
|
+
export declare const AI_PRODUCTS_BULK_MAX = 50;
|
|
61
|
+
/** How many products a catalog proposal holds. */
|
|
62
|
+
export declare const AI_CATALOG_PRODUCTS: {
|
|
63
|
+
readonly min: 1;
|
|
64
|
+
readonly max: 12;
|
|
65
|
+
};
|
|
66
|
+
/**
|
|
67
|
+
* A proposed product is shorter than a written one: its description and tags
|
|
68
|
+
* are a start the owner completes, and twelve of them at every bound still fit
|
|
69
|
+
* one answer (`ai-job-products-step.spec.ts` measures it).
|
|
70
|
+
*/
|
|
71
|
+
export declare const AI_CATALOG_DESCRIPTION_MAX_CHARS = 600;
|
|
72
|
+
export declare const AI_CATALOG_TAGS_MAX = 6;
|
|
73
|
+
/** A proposed product's options: few axes and few short values, so its variants stay a short list. */
|
|
74
|
+
export declare const AI_CATALOG_OPTIONS_MAX = 2;
|
|
75
|
+
export declare const AI_CATALOG_OPTION_VALUES_MAX = 6;
|
|
76
|
+
export declare const AI_CATALOG_OPTION_VALUE_MAX_CHARS = 30;
|
|
77
|
+
/** What a proposed product's photo should show, in one sentence. */
|
|
78
|
+
export declare const AI_CATALOG_PHOTO_MAX_CHARS = 160;
|
|
79
|
+
export declare const AI_CATEGORIES_MAX = 12;
|
|
80
|
+
export declare const AI_DISCOUNTS_MAX = 5;
|
|
81
|
+
export declare const AI_CATEGORY_NAME_MAX_CHARS = 60;
|
|
82
|
+
export declare const AI_PROPOSAL_WHY_MAX_CHARS = 200;
|
|
83
|
+
/** The highest percentage a proposed discount takes off, and the most a fixed one takes, in dollars. */
|
|
84
|
+
export declare const AI_DISCOUNT_MAX_PERCENT = 90;
|
|
85
|
+
export declare const AI_DISCOUNT_MAX_FIXED_USD = 1000;
|
|
86
|
+
/** A discount code: letters, digits, dashes and underscores, stored upper case. */
|
|
87
|
+
export declare const AI_DISCOUNT_CODE: RegExp;
|
|
88
|
+
/** An option axis. */
|
|
89
|
+
export interface AiProductOption {
|
|
90
|
+
name: string;
|
|
91
|
+
values: string[];
|
|
92
|
+
}
|
|
93
|
+
/** One product as its editor hands it to a `product` job. */
|
|
94
|
+
export interface AiProductFacts {
|
|
95
|
+
/** `null` for a product nobody has saved yet. */
|
|
96
|
+
id: string | null;
|
|
97
|
+
name: string;
|
|
98
|
+
type: AiProductType;
|
|
99
|
+
/** The product's current description, cut to `AI_PRODUCT_TEXT_MAX_CHARS`. */
|
|
100
|
+
text: string;
|
|
101
|
+
tags: string[];
|
|
102
|
+
categoryIds: string[];
|
|
103
|
+
options: AiProductOption[];
|
|
104
|
+
/** The first photo's stored media value, or `null`. */
|
|
105
|
+
imageUrl: string | null;
|
|
106
|
+
seoTitle: string;
|
|
107
|
+
seoDescription: string;
|
|
108
|
+
}
|
|
109
|
+
/** A site's product category, as a request lists it to choose from. */
|
|
110
|
+
export interface AiProductCategory {
|
|
111
|
+
id: string;
|
|
112
|
+
name: string;
|
|
113
|
+
}
|
|
114
|
+
/** The merchant's own words about a product, which a claim in its copy may repeat. */
|
|
115
|
+
export declare function aiProductMerchantWords(product: Pick<AiProductFacts, 'name' | 'text' | 'tags'>): string;
|
|
116
|
+
export type AiProductsJobInputs = {
|
|
117
|
+
target: 'product';
|
|
118
|
+
product: AiProductFacts;
|
|
119
|
+
} | {
|
|
120
|
+
target: 'bulk';
|
|
121
|
+
productIds: string[];
|
|
122
|
+
} | {
|
|
123
|
+
target: 'catalog';
|
|
124
|
+
} | {
|
|
125
|
+
target: 'categories';
|
|
126
|
+
};
|
|
127
|
+
/**
|
|
128
|
+
* How large a job's inputs may be once written as JSON: under the 8,000
|
|
129
|
+
* characters the create door admits, with room for the door's own keys.
|
|
130
|
+
*/
|
|
131
|
+
export declare const AI_PRODUCTS_INPUTS_MAX_JSON_CHARS = 7500;
|
|
132
|
+
/**
|
|
133
|
+
* A job's inputs for a target, as the console sends them: every value a
|
|
134
|
+
* scalar, lists as JSON or as comma-separated ids, each bounded, and the
|
|
135
|
+
* product's text shortened last until the whole fits what the create door
|
|
136
|
+
* admits.
|
|
137
|
+
*/
|
|
138
|
+
export declare function aiProductsJobInputs(input: AiProductsJobInputs): Record<string, string>;
|
|
139
|
+
/** Why a `products` job's inputs cannot run, in words a person can act on. */
|
|
140
|
+
export declare const AI_PRODUCTS_NO_TARGET_COPY = "This AI job does not say what to write for your products.";
|
|
141
|
+
export declare const AI_PRODUCTS_NO_NAME_COPY = "Give the product a name before writing its copy.";
|
|
142
|
+
export declare const AI_PRODUCTS_NO_SELECTION_COPY = "Pick the products to write copy for.";
|
|
143
|
+
export declare const AI_PRODUCTS_TOO_MANY_COPY = "Pick at most 50 products at a time.";
|
|
144
|
+
/** A job's inputs read back, or the sentence that says why they cannot run. */
|
|
145
|
+
export declare function parseAiProductsJobInputs(raw: Readonly<Record<string, unknown>> | undefined): AiProductsJobInputs | string;
|
|
146
|
+
/** A product's copy, as proposed. */
|
|
147
|
+
export interface AiProductCopy {
|
|
148
|
+
description: string;
|
|
149
|
+
seoTitle: string;
|
|
150
|
+
seoDescription: string;
|
|
151
|
+
tags: string[];
|
|
152
|
+
categoryIds: string[];
|
|
153
|
+
/** One name per option the product had, in order. */
|
|
154
|
+
optionNames: string[];
|
|
155
|
+
}
|
|
156
|
+
/** What became of the product's photo. */
|
|
157
|
+
export type AiProductPhotoRead =
|
|
158
|
+
/** The photo was read. */
|
|
159
|
+
'read'
|
|
160
|
+
/** The product has no photo. */
|
|
161
|
+
| 'none'
|
|
162
|
+
/** The photo is not an asset of this site's media library, or its org's. */
|
|
163
|
+
| 'not-in-library'
|
|
164
|
+
/** The photo could not be read. */
|
|
165
|
+
| 'unreadable'
|
|
166
|
+
/** The model this job ran on does not read pictures. */
|
|
167
|
+
| 'model';
|
|
168
|
+
export interface AiProductCopyProposal {
|
|
169
|
+
kind: 'copy';
|
|
170
|
+
product: {
|
|
171
|
+
id: string | null;
|
|
172
|
+
name: string;
|
|
173
|
+
};
|
|
174
|
+
/** `null` when there was nothing to propose: see `skipped`. */
|
|
175
|
+
values: AiProductCopy | null;
|
|
176
|
+
/** The categories `values` names, with the names they had when the job read them. */
|
|
177
|
+
categories: Array<{
|
|
178
|
+
id: string;
|
|
179
|
+
name: string;
|
|
180
|
+
}>;
|
|
181
|
+
/** The option names the product had, beside the ones proposed. */
|
|
182
|
+
optionNamesBefore: string[];
|
|
183
|
+
/** The facts the copy marks as missing, in square brackets, for a person to fill in. */
|
|
184
|
+
gaps: string[];
|
|
185
|
+
photo: AiProductPhotoRead;
|
|
186
|
+
/** Why a bulk pass proposed nothing for this product, in customer-safe words. */
|
|
187
|
+
skipped: string | null;
|
|
188
|
+
notes: string[];
|
|
189
|
+
}
|
|
190
|
+
export interface AiCatalogProduct {
|
|
191
|
+
name: string;
|
|
192
|
+
type: AiProductType;
|
|
193
|
+
description: string;
|
|
194
|
+
tags: string[];
|
|
195
|
+
options: AiProductOption[];
|
|
196
|
+
seoTitle: string;
|
|
197
|
+
seoDescription: string;
|
|
198
|
+
/** What the product's photo should show; nothing is uploaded or linked. */
|
|
199
|
+
photo: string;
|
|
200
|
+
}
|
|
201
|
+
export interface AiCatalogProposal {
|
|
202
|
+
kind: 'catalog';
|
|
203
|
+
products: AiCatalogProduct[];
|
|
204
|
+
notes: string[];
|
|
205
|
+
}
|
|
206
|
+
export type AiDiscountKind = 'percent' | 'fixed' | 'free_shipping';
|
|
207
|
+
export interface AiProposedDiscount {
|
|
208
|
+
name: string;
|
|
209
|
+
/** The code a shopper types, upper case; `null` for an automatic discount. */
|
|
210
|
+
code: string | null;
|
|
211
|
+
kind: AiDiscountKind;
|
|
212
|
+
/** A `percent` discount's percentage. */
|
|
213
|
+
valuePct: number | null;
|
|
214
|
+
/** A `fixed` discount's amount off, in cents. */
|
|
215
|
+
valueCents: number | null;
|
|
216
|
+
/** The smallest order it applies to, in cents; `null` for any order. */
|
|
217
|
+
minSubtotalCents: number | null;
|
|
218
|
+
why: string;
|
|
219
|
+
}
|
|
220
|
+
export interface AiCategoriesProposal {
|
|
221
|
+
kind: 'categories';
|
|
222
|
+
categories: Array<{
|
|
223
|
+
name: string;
|
|
224
|
+
why: string;
|
|
225
|
+
}>;
|
|
226
|
+
discounts: AiProposedDiscount[];
|
|
227
|
+
notes: string[];
|
|
228
|
+
}
|
|
229
|
+
export type AiProductsProposal = AiProductCopyProposal | AiCatalogProposal | AiCategoriesProposal;
|
|
230
|
+
/** Output ids, so a pass that runs again finds what it already proposed. */
|
|
231
|
+
export declare const AI_PRODUCTS_OUTPUT_IDS: {
|
|
232
|
+
readonly copy: (productId: string | null) => string;
|
|
233
|
+
readonly catalog: "catalog";
|
|
234
|
+
readonly categories: "categories";
|
|
235
|
+
};
|
|
236
|
+
/** An output's proposal, or `null` for an output that is not a products proposal. */
|
|
237
|
+
export declare function aiProductsProposalOf(output: Pick<AiJobOutput, 'resource' | 'proposal'> | null | undefined): AiProductsProposal | null;
|
|
238
|
+
/** A job's copy proposals, in the order the job made them. */
|
|
239
|
+
export declare function aiProductCopyProposals(job: Pick<AiJobSummary, 'outputs'> | null | undefined): AiProductCopyProposal[];
|
|
240
|
+
/** A job's proposal of one kind, or `null`. */
|
|
241
|
+
export declare function aiProductsProposalOfKind<K extends AiProductsProposal['kind']>(job: Pick<AiJobSummary, 'outputs'> | null | undefined, kind: K): Extract<AiProductsProposal, {
|
|
242
|
+
kind: K;
|
|
243
|
+
}> | null;
|
|
244
|
+
/** The gaps a text marks for a person in square brackets, as `[material]`, each once. */
|
|
245
|
+
export declare function aiProductGaps(...texts: readonly string[]): string[];
|
|
246
|
+
/** The option the import zone sets to write the imported products' copy. */
|
|
247
|
+
export declare const AI_PRODUCTS_IMPORT_WRITE_COPY = "ai.writeCopy";
|
|
248
|
+
/** The brief a bulk copy job carries, which the jobs list shows and a card recognizes it by. */
|
|
249
|
+
export declare const aiProductsBulkBrief: (count: number) => string;
|
|
250
|
+
/** How many products a bulk copy job was asked for, read from its brief; `null` for any other job. */
|
|
251
|
+
export declare function aiProductsBulkCount(job: Pick<AiJobSummary, 'brief'> | null | undefined): number | null;
|
|
@@ -0,0 +1,253 @@
|
|
|
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
|
+
* COMMERCE BY AI (AGL-2916): what a `products` job is asked, and what it
|
|
18
|
+
* proposes. Pure, so the step that asks, the console cards that start a job
|
|
19
|
+
* and show its proposals, and the eval harness all read one shape.
|
|
20
|
+
*
|
|
21
|
+
* `inputs.target` names the work:
|
|
22
|
+
*
|
|
23
|
+
* - `product` — one product's copy, from what its editor holds right now:
|
|
24
|
+
* the name, the text, the tags, the categories and options it has, and the
|
|
25
|
+
* first photo. The editor may hold a product nobody has saved yet, so the
|
|
26
|
+
* job never reads a product document for this target.
|
|
27
|
+
* - `bulk` — the copy of up to `AI_PRODUCTS_BULK_MAX` saved products, one
|
|
28
|
+
* product a pass, each read from the catalog as it is reached.
|
|
29
|
+
* - `catalog` — a store's first products from the brief: names, copy, tags
|
|
30
|
+
* and options, and what each photo should show. No price and no picture.
|
|
31
|
+
* - `categories` — store categories and a first set of discounts from the brief.
|
|
32
|
+
*
|
|
33
|
+
* Every output is a PROPOSAL (`resource: 'product'`, with `proposal`), and the
|
|
34
|
+
* job writes nothing. The commerce plugin's own surfaces write what a person
|
|
35
|
+
* accepts, through the doors those surfaces already use.
|
|
36
|
+
*/ export const AI_PRODUCTS_TARGETS = [
|
|
37
|
+
'product',
|
|
38
|
+
'bulk',
|
|
39
|
+
'catalog',
|
|
40
|
+
'categories'
|
|
41
|
+
];
|
|
42
|
+
export const AI_PRODUCT_TYPES = [
|
|
43
|
+
'physical',
|
|
44
|
+
'digital',
|
|
45
|
+
'service'
|
|
46
|
+
];
|
|
47
|
+
/** The longest product name the editor saves. */ export const AI_PRODUCT_NAME_MAX_CHARS = 120;
|
|
48
|
+
/** How much of a product's existing description a request carries. */ export const AI_PRODUCT_TEXT_MAX_CHARS = 2000;
|
|
49
|
+
/** The longest description the job proposes. */ export const AI_PRODUCT_DESCRIPTION_MAX_CHARS = 1200;
|
|
50
|
+
export const AI_PRODUCT_TAGS_MAX = 8;
|
|
51
|
+
export const AI_PRODUCT_TAG_MAX_CHARS = 30;
|
|
52
|
+
/** The most categories one product's proposal names. */ export const AI_PRODUCT_CATEGORIES_MAX = 3;
|
|
53
|
+
/** The most of a site's categories a request lists to choose from. */ export const AI_PRODUCT_CATEGORY_LIST_MAX = 100;
|
|
54
|
+
/** A product's option axes, as the commerce editor bounds them. */ export const AI_PRODUCT_OPTIONS_MAX = 3;
|
|
55
|
+
export const AI_PRODUCT_OPTION_VALUES_MAX = 25;
|
|
56
|
+
export const AI_PRODUCT_OPTION_NAME_MAX_CHARS = 30;
|
|
57
|
+
/** The most products one bulk job writes the copy of. */ export const AI_PRODUCTS_BULK_MAX = 50;
|
|
58
|
+
/** How many products a catalog proposal holds. */ export const AI_CATALOG_PRODUCTS = {
|
|
59
|
+
min: 1,
|
|
60
|
+
max: 12
|
|
61
|
+
};
|
|
62
|
+
/**
|
|
63
|
+
* A proposed product is shorter than a written one: its description and tags
|
|
64
|
+
* are a start the owner completes, and twelve of them at every bound still fit
|
|
65
|
+
* one answer (`ai-job-products-step.spec.ts` measures it).
|
|
66
|
+
*/ export const AI_CATALOG_DESCRIPTION_MAX_CHARS = 600;
|
|
67
|
+
export const AI_CATALOG_TAGS_MAX = 6;
|
|
68
|
+
/** A proposed product's options: few axes and few short values, so its variants stay a short list. */ export const AI_CATALOG_OPTIONS_MAX = 2;
|
|
69
|
+
export const AI_CATALOG_OPTION_VALUES_MAX = 6;
|
|
70
|
+
export const AI_CATALOG_OPTION_VALUE_MAX_CHARS = 30;
|
|
71
|
+
/** What a proposed product's photo should show, in one sentence. */ export const AI_CATALOG_PHOTO_MAX_CHARS = 160;
|
|
72
|
+
export const AI_CATEGORIES_MAX = 12;
|
|
73
|
+
export const AI_DISCOUNTS_MAX = 5;
|
|
74
|
+
export const AI_CATEGORY_NAME_MAX_CHARS = 60;
|
|
75
|
+
export const AI_PROPOSAL_WHY_MAX_CHARS = 200;
|
|
76
|
+
/** The highest percentage a proposed discount takes off, and the most a fixed one takes, in dollars. */ export const AI_DISCOUNT_MAX_PERCENT = 90;
|
|
77
|
+
export const AI_DISCOUNT_MAX_FIXED_USD = 1000;
|
|
78
|
+
/** A discount code: letters, digits, dashes and underscores, stored upper case. */ export const AI_DISCOUNT_CODE = /^[A-Z0-9_-]{3,20}$/;
|
|
79
|
+
/** The merchant's own words about a product, which a claim in its copy may repeat. */ export function aiProductMerchantWords(product) {
|
|
80
|
+
return [
|
|
81
|
+
product.name,
|
|
82
|
+
product.text,
|
|
83
|
+
...product.tags
|
|
84
|
+
].join('\n');
|
|
85
|
+
}
|
|
86
|
+
const ID = /^[A-Za-z0-9_-]{1,64}$/;
|
|
87
|
+
const text = (value, max)=>typeof value === 'string' ? value.replace(/\s+/g, ' ').trim().slice(0, max) : '';
|
|
88
|
+
/** A list stored as JSON, read defensively: strings only, trimmed, bounded. */ function jsonStrings(value, max, maxChars) {
|
|
89
|
+
if (typeof value !== 'string' || !value.trim()) return [];
|
|
90
|
+
try {
|
|
91
|
+
const parsed = JSON.parse(value);
|
|
92
|
+
if (!Array.isArray(parsed)) return [];
|
|
93
|
+
return parsed.map((entry)=>text(entry, maxChars)).filter(Boolean).slice(0, max);
|
|
94
|
+
} catch (unused) {
|
|
95
|
+
return [];
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
function jsonOptions(value) {
|
|
99
|
+
if (typeof value !== 'string' || !value.trim()) return [];
|
|
100
|
+
try {
|
|
101
|
+
const parsed = JSON.parse(value);
|
|
102
|
+
if (!Array.isArray(parsed)) return [];
|
|
103
|
+
return parsed.map((entry)=>{
|
|
104
|
+
const record = entry != null ? entry : {};
|
|
105
|
+
return {
|
|
106
|
+
name: text(record['name'], AI_PRODUCT_OPTION_NAME_MAX_CHARS),
|
|
107
|
+
values: Array.isArray(record['values']) ? record['values'].map((value)=>text(value, 40)).filter(Boolean).slice(0, AI_PRODUCT_OPTION_VALUES_MAX) : []
|
|
108
|
+
};
|
|
109
|
+
}).slice(0, AI_PRODUCT_OPTIONS_MAX);
|
|
110
|
+
} catch (unused) {
|
|
111
|
+
return [];
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* How large a job's inputs may be once written as JSON: under the 8,000
|
|
116
|
+
* characters the create door admits, with room for the door's own keys.
|
|
117
|
+
*/ export const AI_PRODUCTS_INPUTS_MAX_JSON_CHARS = 7500;
|
|
118
|
+
/**
|
|
119
|
+
* A job's inputs for a target, as the console sends them: every value a
|
|
120
|
+
* scalar, lists as JSON or as comma-separated ids, each bounded, and the
|
|
121
|
+
* product's text shortened last until the whole fits what the create door
|
|
122
|
+
* admits.
|
|
123
|
+
*/ export function aiProductsJobInputs(input) {
|
|
124
|
+
switch(input.target){
|
|
125
|
+
case 'product':
|
|
126
|
+
{
|
|
127
|
+
var _product_id, _product_imageUrl;
|
|
128
|
+
const product = input.product;
|
|
129
|
+
const inputs = {
|
|
130
|
+
target: 'product',
|
|
131
|
+
productId: (_product_id = product.id) != null ? _product_id : '',
|
|
132
|
+
name: text(product.name, AI_PRODUCT_NAME_MAX_CHARS),
|
|
133
|
+
type: product.type,
|
|
134
|
+
text: product.text.slice(0, AI_PRODUCT_TEXT_MAX_CHARS),
|
|
135
|
+
tags: JSON.stringify(product.tags.slice(0, 10).map((tag)=>tag.slice(0, 40))),
|
|
136
|
+
categoryIds: product.categoryIds.filter((id)=>ID.test(id)).slice(0, 10).join(','),
|
|
137
|
+
options: JSON.stringify(product.options.slice(0, AI_PRODUCT_OPTIONS_MAX).map((option)=>({
|
|
138
|
+
name: option.name.slice(0, AI_PRODUCT_OPTION_NAME_MAX_CHARS),
|
|
139
|
+
values: option.values.slice(0, AI_PRODUCT_OPTION_VALUES_MAX).map((value)=>value.slice(0, 40))
|
|
140
|
+
}))),
|
|
141
|
+
imageUrl: ((_product_imageUrl = product.imageUrl) != null ? _product_imageUrl : '').slice(0, 300),
|
|
142
|
+
seoTitle: product.seoTitle.slice(0, 100),
|
|
143
|
+
seoDescription: product.seoDescription.slice(0, 200)
|
|
144
|
+
};
|
|
145
|
+
while(JSON.stringify(inputs).length > AI_PRODUCTS_INPUTS_MAX_JSON_CHARS && inputs['text']){
|
|
146
|
+
inputs['text'] = inputs['text'].slice(0, Math.max(0, inputs['text'].length - 250));
|
|
147
|
+
}
|
|
148
|
+
return inputs;
|
|
149
|
+
}
|
|
150
|
+
case 'bulk':
|
|
151
|
+
return {
|
|
152
|
+
target: 'bulk',
|
|
153
|
+
productIds: [
|
|
154
|
+
...new Set(input.productIds.filter((id)=>ID.test(id)))
|
|
155
|
+
].slice(0, AI_PRODUCTS_BULK_MAX).join(',')
|
|
156
|
+
};
|
|
157
|
+
default:
|
|
158
|
+
return {
|
|
159
|
+
target: input.target
|
|
160
|
+
};
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
/** Why a `products` job's inputs cannot run, in words a person can act on. */ export const AI_PRODUCTS_NO_TARGET_COPY = 'This AI job does not say what to write for your products.';
|
|
164
|
+
export const AI_PRODUCTS_NO_NAME_COPY = 'Give the product a name before writing its copy.';
|
|
165
|
+
export const AI_PRODUCTS_NO_SELECTION_COPY = 'Pick the products to write copy for.';
|
|
166
|
+
export const AI_PRODUCTS_TOO_MANY_COPY = `Pick at most ${AI_PRODUCTS_BULK_MAX} products at a time.`;
|
|
167
|
+
/** A job's inputs read back, or the sentence that says why they cannot run. */ export function parseAiProductsJobInputs(raw) {
|
|
168
|
+
const inputs = raw != null ? raw : {};
|
|
169
|
+
const target = inputs['target'];
|
|
170
|
+
if (!AI_PRODUCTS_TARGETS.includes(target)) return AI_PRODUCTS_NO_TARGET_COPY;
|
|
171
|
+
if (target === 'product') {
|
|
172
|
+
var _inputs_categoryIds;
|
|
173
|
+
const name = text(inputs['name'], AI_PRODUCT_NAME_MAX_CHARS);
|
|
174
|
+
if (!name) return AI_PRODUCTS_NO_NAME_COPY;
|
|
175
|
+
const type = inputs['type'];
|
|
176
|
+
const id = typeof inputs['productId'] === 'string' && ID.test(inputs['productId']) ? inputs['productId'] : null;
|
|
177
|
+
return {
|
|
178
|
+
target,
|
|
179
|
+
product: {
|
|
180
|
+
id,
|
|
181
|
+
name,
|
|
182
|
+
type: AI_PRODUCT_TYPES.includes(type) ? type : 'physical',
|
|
183
|
+
text: typeof inputs['text'] === 'string' ? inputs['text'].trim().slice(0, AI_PRODUCT_TEXT_MAX_CHARS) : '',
|
|
184
|
+
tags: jsonStrings(inputs['tags'], 10, 40),
|
|
185
|
+
categoryIds: String((_inputs_categoryIds = inputs['categoryIds']) != null ? _inputs_categoryIds : '').split(',').map((part)=>part.trim()).filter((part)=>ID.test(part)).slice(0, 10),
|
|
186
|
+
options: jsonOptions(inputs['options']),
|
|
187
|
+
imageUrl: text(inputs['imageUrl'], 300) || null,
|
|
188
|
+
seoTitle: text(inputs['seoTitle'], 100),
|
|
189
|
+
seoDescription: text(inputs['seoDescription'], 200)
|
|
190
|
+
}
|
|
191
|
+
};
|
|
192
|
+
}
|
|
193
|
+
if (target === 'bulk') {
|
|
194
|
+
var _inputs_productIds;
|
|
195
|
+
const ids = String((_inputs_productIds = inputs['productIds']) != null ? _inputs_productIds : '').split(',').map((part)=>part.trim()).filter((part)=>ID.test(part));
|
|
196
|
+
const unique = [
|
|
197
|
+
...new Set(ids)
|
|
198
|
+
];
|
|
199
|
+
if (!unique.length) return AI_PRODUCTS_NO_SELECTION_COPY;
|
|
200
|
+
if (unique.length > AI_PRODUCTS_BULK_MAX) return AI_PRODUCTS_TOO_MANY_COPY;
|
|
201
|
+
return {
|
|
202
|
+
target,
|
|
203
|
+
productIds: unique
|
|
204
|
+
};
|
|
205
|
+
}
|
|
206
|
+
return {
|
|
207
|
+
target: target
|
|
208
|
+
};
|
|
209
|
+
}
|
|
210
|
+
/** Output ids, so a pass that runs again finds what it already proposed. */ export const AI_PRODUCTS_OUTPUT_IDS = {
|
|
211
|
+
copy: (productId)=>`copy:${productId != null ? productId : 'new'}`,
|
|
212
|
+
catalog: 'catalog',
|
|
213
|
+
categories: 'categories'
|
|
214
|
+
};
|
|
215
|
+
const isRecord = (value)=>typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
216
|
+
/** An output's proposal, or `null` for an output that is not a products proposal. */ export function aiProductsProposalOf(output) {
|
|
217
|
+
if (!output || output.resource !== 'product' || !isRecord(output.proposal)) return null;
|
|
218
|
+
const kind = output.proposal['kind'];
|
|
219
|
+
return kind === 'copy' || kind === 'catalog' || kind === 'categories' ? output.proposal : null;
|
|
220
|
+
}
|
|
221
|
+
/** A job's copy proposals, in the order the job made them. */ export function aiProductCopyProposals(job) {
|
|
222
|
+
var _ref;
|
|
223
|
+
return ((_ref = job == null ? void 0 : job.outputs) != null ? _ref : []).map((output)=>aiProductsProposalOf(output)).filter((proposal)=>(proposal == null ? void 0 : proposal.kind) === 'copy');
|
|
224
|
+
}
|
|
225
|
+
/** A job's proposal of one kind, or `null`. */ export function aiProductsProposalOfKind(job, kind) {
|
|
226
|
+
var _ref;
|
|
227
|
+
for (const output of (_ref = job == null ? void 0 : job.outputs) != null ? _ref : []){
|
|
228
|
+
const proposal = aiProductsProposalOf(output);
|
|
229
|
+
if ((proposal == null ? void 0 : proposal.kind) === kind) return proposal;
|
|
230
|
+
}
|
|
231
|
+
return null;
|
|
232
|
+
}
|
|
233
|
+
/** The gaps a text marks for a person in square brackets, as `[material]`, each once. */ export function aiProductGaps(...texts) {
|
|
234
|
+
const found = new Set();
|
|
235
|
+
for (const value of texts){
|
|
236
|
+
for (const match of value.matchAll(/\[([^\]\n]{1,60})\]/g))found.add(match[1].trim());
|
|
237
|
+
}
|
|
238
|
+
return [
|
|
239
|
+
...found
|
|
240
|
+
].filter(Boolean);
|
|
241
|
+
}
|
|
242
|
+
/* ------------------------------------------------------------------------ *
|
|
243
|
+
* The console's cards
|
|
244
|
+
* ------------------------------------------------------------------------ */ /** The option the import zone sets to write the imported products' copy. */ export const AI_PRODUCTS_IMPORT_WRITE_COPY = 'ai.writeCopy';
|
|
245
|
+
/** The brief a bulk copy job carries, which the jobs list shows and a card recognizes it by. */ export const aiProductsBulkBrief = (count)=>`Write storefront copy for ${count} ${count === 1 ? 'product' : 'products'}`;
|
|
246
|
+
const BULK_BRIEF = /^Write storefront copy for (\d+) products?$/;
|
|
247
|
+
/** How many products a bulk copy job was asked for, read from its brief; `null` for any other job. */ export function aiProductsBulkCount(job) {
|
|
248
|
+
var _ref;
|
|
249
|
+
const match = BULK_BRIEF.exec((_ref = job == null ? void 0 : job.brief) != null ? _ref : '');
|
|
250
|
+
return match ? Number(match[1]) : null;
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
//# sourceMappingURL=ai-products.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../../../../libs/plugins/ai/src/lib/model/ai-products.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 { AiJobOutput, AiJobSummary } from './ai-jobs.types'\n\n/**\n * COMMERCE BY AI (AGL-2916): what a `products` job is asked, and what it\n * proposes. Pure, so the step that asks, the console cards that start a job\n * and show its proposals, and the eval harness all read one shape.\n *\n * `inputs.target` names the work:\n *\n * - `product` — one product's copy, from what its editor holds right now:\n * the name, the text, the tags, the categories and options it has, and the\n * first photo. The editor may hold a product nobody has saved yet, so the\n * job never reads a product document for this target.\n * - `bulk` — the copy of up to `AI_PRODUCTS_BULK_MAX` saved products, one\n * product a pass, each read from the catalog as it is reached.\n * - `catalog` — a store's first products from the brief: names, copy, tags\n * and options, and what each photo should show. No price and no picture.\n * - `categories` — store categories and a first set of discounts from the brief.\n *\n * Every output is a PROPOSAL (`resource: 'product'`, with `proposal`), and the\n * job writes nothing. The commerce plugin's own surfaces write what a person\n * accepts, through the doors those surfaces already use.\n */\n\nexport const AI_PRODUCTS_TARGETS = ['product', 'bulk', 'catalog', 'categories'] as const\nexport type AiProductsTarget = (typeof AI_PRODUCTS_TARGETS)[number]\n\nexport const AI_PRODUCT_TYPES = ['physical', 'digital', 'service'] as const\nexport type AiProductType = (typeof AI_PRODUCT_TYPES)[number]\n\n/** The longest product name the editor saves. */\nexport const AI_PRODUCT_NAME_MAX_CHARS = 120\n\n/** How much of a product's existing description a request carries. */\nexport const AI_PRODUCT_TEXT_MAX_CHARS = 2_000\n\n/** The longest description the job proposes. */\nexport const AI_PRODUCT_DESCRIPTION_MAX_CHARS = 1_200\n\nexport const AI_PRODUCT_TAGS_MAX = 8\nexport const AI_PRODUCT_TAG_MAX_CHARS = 30\n\n/** The most categories one product's proposal names. */\nexport const AI_PRODUCT_CATEGORIES_MAX = 3\n\n/** The most of a site's categories a request lists to choose from. */\nexport const AI_PRODUCT_CATEGORY_LIST_MAX = 100\n\n/** A product's option axes, as the commerce editor bounds them. */\nexport const AI_PRODUCT_OPTIONS_MAX = 3\nexport const AI_PRODUCT_OPTION_VALUES_MAX = 25\nexport const AI_PRODUCT_OPTION_NAME_MAX_CHARS = 30\n\n/** The most products one bulk job writes the copy of. */\nexport const AI_PRODUCTS_BULK_MAX = 50\n\n/** How many products a catalog proposal holds. */\nexport const AI_CATALOG_PRODUCTS = { min: 1, max: 12 } as const\n\n/**\n * A proposed product is shorter than a written one: its description and tags\n * are a start the owner completes, and twelve of them at every bound still fit\n * one answer (`ai-job-products-step.spec.ts` measures it).\n */\nexport const AI_CATALOG_DESCRIPTION_MAX_CHARS = 600\nexport const AI_CATALOG_TAGS_MAX = 6\n\n/** A proposed product's options: few axes and few short values, so its variants stay a short list. */\nexport const AI_CATALOG_OPTIONS_MAX = 2\nexport const AI_CATALOG_OPTION_VALUES_MAX = 6\nexport const AI_CATALOG_OPTION_VALUE_MAX_CHARS = 30\n\n/** What a proposed product's photo should show, in one sentence. */\nexport const AI_CATALOG_PHOTO_MAX_CHARS = 160\n\nexport const AI_CATEGORIES_MAX = 12\nexport const AI_DISCOUNTS_MAX = 5\nexport const AI_CATEGORY_NAME_MAX_CHARS = 60\nexport const AI_PROPOSAL_WHY_MAX_CHARS = 200\n\n/** The highest percentage a proposed discount takes off, and the most a fixed one takes, in dollars. */\nexport const AI_DISCOUNT_MAX_PERCENT = 90\nexport const AI_DISCOUNT_MAX_FIXED_USD = 1_000\n\n/** A discount code: letters, digits, dashes and underscores, stored upper case. */\nexport const AI_DISCOUNT_CODE = /^[A-Z0-9_-]{3,20}$/\n\n/** An option axis. */\nexport interface AiProductOption {\n name: string\n values: string[]\n}\n\n/** One product as its editor hands it to a `product` job. */\nexport interface AiProductFacts {\n /** `null` for a product nobody has saved yet. */\n id: string | null\n name: string\n type: AiProductType\n /** The product's current description, cut to `AI_PRODUCT_TEXT_MAX_CHARS`. */\n text: string\n tags: string[]\n categoryIds: string[]\n options: AiProductOption[]\n /** The first photo's stored media value, or `null`. */\n imageUrl: string | null\n seoTitle: string\n seoDescription: string\n}\n\n/** A site's product category, as a request lists it to choose from. */\nexport interface AiProductCategory {\n id: string\n name: string\n}\n\n/** The merchant's own words about a product, which a claim in its copy may repeat. */\nexport function aiProductMerchantWords(product: Pick<AiProductFacts, 'name' | 'text' | 'tags'>): string {\n return [product.name, product.text, ...product.tags].join('\\n')\n}\n\nexport type AiProductsJobInputs =\n | { target: 'product'; product: AiProductFacts }\n | { target: 'bulk'; productIds: string[] }\n | { target: 'catalog' }\n | { target: 'categories' }\n\nconst ID = /^[A-Za-z0-9_-]{1,64}$/\n\nconst text = (value: unknown, max: number): string =>\n typeof value === 'string' ? value.replace(/\\s+/g, ' ').trim().slice(0, max) : ''\n\n/** A list stored as JSON, read defensively: strings only, trimmed, bounded. */\nfunction jsonStrings(value: unknown, max: number, maxChars: number): string[] {\n if (typeof value !== 'string' || !value.trim()) return []\n try {\n const parsed: unknown = JSON.parse(value)\n if (!Array.isArray(parsed)) return []\n return parsed\n .map((entry) => text(entry, maxChars))\n .filter(Boolean)\n .slice(0, max)\n } catch {\n return []\n }\n}\n\nfunction jsonOptions(value: unknown): AiProductOption[] {\n if (typeof value !== 'string' || !value.trim()) return []\n try {\n const parsed: unknown = JSON.parse(value)\n if (!Array.isArray(parsed)) return []\n return parsed\n .map((entry) => {\n const record = (entry ?? {}) as Record<string, unknown>\n return {\n name: text(record['name'], AI_PRODUCT_OPTION_NAME_MAX_CHARS),\n values: Array.isArray(record['values'])\n ? record['values'].map((value) => text(value, 40)).filter(Boolean).slice(0, AI_PRODUCT_OPTION_VALUES_MAX)\n : [],\n }\n })\n .slice(0, AI_PRODUCT_OPTIONS_MAX)\n } catch {\n return []\n }\n}\n\n/**\n * How large a job's inputs may be once written as JSON: under the 8,000\n * characters the create door admits, with room for the door's own keys.\n */\nexport const AI_PRODUCTS_INPUTS_MAX_JSON_CHARS = 7_500\n\n/**\n * A job's inputs for a target, as the console sends them: every value a\n * scalar, lists as JSON or as comma-separated ids, each bounded, and the\n * product's text shortened last until the whole fits what the create door\n * admits.\n */\nexport function aiProductsJobInputs(input: AiProductsJobInputs): Record<string, string> {\n switch (input.target) {\n case 'product': {\n const product = input.product\n const inputs: Record<string, string> = {\n target: 'product',\n productId: product.id ?? '',\n name: text(product.name, AI_PRODUCT_NAME_MAX_CHARS),\n type: product.type,\n text: product.text.slice(0, AI_PRODUCT_TEXT_MAX_CHARS),\n tags: JSON.stringify(product.tags.slice(0, 10).map((tag) => tag.slice(0, 40))),\n categoryIds: product.categoryIds.filter((id) => ID.test(id)).slice(0, 10).join(','),\n options: JSON.stringify(\n product.options.slice(0, AI_PRODUCT_OPTIONS_MAX).map((option) => ({\n name: option.name.slice(0, AI_PRODUCT_OPTION_NAME_MAX_CHARS),\n values: option.values.slice(0, AI_PRODUCT_OPTION_VALUES_MAX).map((value) => value.slice(0, 40)),\n })),\n ),\n imageUrl: (product.imageUrl ?? '').slice(0, 300),\n seoTitle: product.seoTitle.slice(0, 100),\n seoDescription: product.seoDescription.slice(0, 200),\n }\n while (JSON.stringify(inputs).length > AI_PRODUCTS_INPUTS_MAX_JSON_CHARS && inputs['text']) {\n inputs['text'] = inputs['text'].slice(0, Math.max(0, inputs['text'].length - 250))\n }\n return inputs\n }\n case 'bulk':\n return {\n target: 'bulk',\n productIds: [...new Set(input.productIds.filter((id) => ID.test(id)))]\n .slice(0, AI_PRODUCTS_BULK_MAX)\n .join(','),\n }\n default:\n return { target: input.target }\n }\n}\n\n/** Why a `products` job's inputs cannot run, in words a person can act on. */\nexport const AI_PRODUCTS_NO_TARGET_COPY = 'This AI job does not say what to write for your products.'\nexport const AI_PRODUCTS_NO_NAME_COPY = 'Give the product a name before writing its copy.'\nexport const AI_PRODUCTS_NO_SELECTION_COPY = 'Pick the products to write copy for.'\nexport const AI_PRODUCTS_TOO_MANY_COPY = `Pick at most ${AI_PRODUCTS_BULK_MAX} products at a time.`\n\n/** A job's inputs read back, or the sentence that says why they cannot run. */\nexport function parseAiProductsJobInputs(raw: Readonly<Record<string, unknown>> | undefined): AiProductsJobInputs | string {\n const inputs = raw ?? {}\n const target = inputs['target']\n if (!(AI_PRODUCTS_TARGETS as readonly unknown[]).includes(target)) return AI_PRODUCTS_NO_TARGET_COPY\n if (target === 'product') {\n const name = text(inputs['name'], AI_PRODUCT_NAME_MAX_CHARS)\n if (!name) return AI_PRODUCTS_NO_NAME_COPY\n const type = inputs['type']\n const id = typeof inputs['productId'] === 'string' && ID.test(inputs['productId']) ? inputs['productId'] : null\n return {\n target,\n product: {\n id,\n name,\n type: (AI_PRODUCT_TYPES as readonly unknown[]).includes(type) ? (type as AiProductType) : 'physical',\n text: typeof inputs['text'] === 'string' ? inputs['text'].trim().slice(0, AI_PRODUCT_TEXT_MAX_CHARS) : '',\n tags: jsonStrings(inputs['tags'], 10, 40),\n categoryIds: String(inputs['categoryIds'] ?? '')\n .split(',')\n .map((part) => part.trim())\n .filter((part) => ID.test(part))\n .slice(0, 10),\n options: jsonOptions(inputs['options']),\n imageUrl: text(inputs['imageUrl'], 300) || null,\n seoTitle: text(inputs['seoTitle'], 100),\n seoDescription: text(inputs['seoDescription'], 200),\n },\n }\n }\n if (target === 'bulk') {\n const ids = String(inputs['productIds'] ?? '')\n .split(',')\n .map((part) => part.trim())\n .filter((part) => ID.test(part))\n const unique = [...new Set(ids)]\n if (!unique.length) return AI_PRODUCTS_NO_SELECTION_COPY\n if (unique.length > AI_PRODUCTS_BULK_MAX) return AI_PRODUCTS_TOO_MANY_COPY\n return { target, productIds: unique }\n }\n return { target: target as 'catalog' | 'categories' }\n}\n\n/* ------------------------------------------------------------------------ *\n * Proposals\n * ------------------------------------------------------------------------ */\n\n/** A product's copy, as proposed. */\nexport interface AiProductCopy {\n description: string\n seoTitle: string\n seoDescription: string\n tags: string[]\n categoryIds: string[]\n /** One name per option the product had, in order. */\n optionNames: string[]\n}\n\n/** What became of the product's photo. */\nexport type AiProductPhotoRead =\n /** The photo was read. */\n | 'read'\n /** The product has no photo. */\n | 'none'\n /** The photo is not an asset of this site's media library, or its org's. */\n | 'not-in-library'\n /** The photo could not be read. */\n | 'unreadable'\n /** The model this job ran on does not read pictures. */\n | 'model'\n\nexport interface AiProductCopyProposal {\n kind: 'copy'\n product: { id: string | null; name: string }\n /** `null` when there was nothing to propose: see `skipped`. */\n values: AiProductCopy | null\n /** The categories `values` names, with the names they had when the job read them. */\n categories: Array<{ id: string; name: string }>\n /** The option names the product had, beside the ones proposed. */\n optionNamesBefore: string[]\n /** The facts the copy marks as missing, in square brackets, for a person to fill in. */\n gaps: string[]\n photo: AiProductPhotoRead\n /** Why a bulk pass proposed nothing for this product, in customer-safe words. */\n skipped: string | null\n notes: string[]\n}\n\nexport interface AiCatalogProduct {\n name: string\n type: AiProductType\n description: string\n tags: string[]\n options: AiProductOption[]\n seoTitle: string\n seoDescription: string\n /** What the product's photo should show; nothing is uploaded or linked. */\n photo: string\n}\n\nexport interface AiCatalogProposal {\n kind: 'catalog'\n products: AiCatalogProduct[]\n notes: string[]\n}\n\nexport type AiDiscountKind = 'percent' | 'fixed' | 'free_shipping'\n\nexport interface AiProposedDiscount {\n name: string\n /** The code a shopper types, upper case; `null` for an automatic discount. */\n code: string | null\n kind: AiDiscountKind\n /** A `percent` discount's percentage. */\n valuePct: number | null\n /** A `fixed` discount's amount off, in cents. */\n valueCents: number | null\n /** The smallest order it applies to, in cents; `null` for any order. */\n minSubtotalCents: number | null\n why: string\n}\n\nexport interface AiCategoriesProposal {\n kind: 'categories'\n categories: Array<{ name: string; why: string }>\n discounts: AiProposedDiscount[]\n notes: string[]\n}\n\nexport type AiProductsProposal = AiProductCopyProposal | AiCatalogProposal | AiCategoriesProposal\n\n/** Output ids, so a pass that runs again finds what it already proposed. */\nexport const AI_PRODUCTS_OUTPUT_IDS = {\n copy: (productId: string | null) => `copy:${productId ?? 'new'}`,\n catalog: 'catalog',\n categories: 'categories',\n} as const\n\nconst isRecord = (value: unknown): value is Record<string, unknown> =>\n typeof value === 'object' && value !== null && !Array.isArray(value)\n\n/** An output's proposal, or `null` for an output that is not a products proposal. */\nexport function aiProductsProposalOf(output: Pick<AiJobOutput, 'resource' | 'proposal'> | null | undefined): AiProductsProposal | null {\n if (!output || output.resource !== 'product' || !isRecord(output.proposal)) return null\n const kind = output.proposal['kind']\n return kind === 'copy' || kind === 'catalog' || kind === 'categories'\n ? (output.proposal as unknown as AiProductsProposal)\n : null\n}\n\n/** A job's copy proposals, in the order the job made them. */\nexport function aiProductCopyProposals(job: Pick<AiJobSummary, 'outputs'> | null | undefined): AiProductCopyProposal[] {\n return (job?.outputs ?? [])\n .map((output) => aiProductsProposalOf(output))\n .filter((proposal): proposal is AiProductCopyProposal => proposal?.kind === 'copy')\n}\n\n/** A job's proposal of one kind, or `null`. */\nexport function aiProductsProposalOfKind<K extends AiProductsProposal['kind']>(\n job: Pick<AiJobSummary, 'outputs'> | null | undefined,\n kind: K,\n): Extract<AiProductsProposal, { kind: K }> | null {\n for (const output of job?.outputs ?? []) {\n const proposal = aiProductsProposalOf(output)\n if (proposal?.kind === kind) return proposal as Extract<AiProductsProposal, { kind: K }>\n }\n return null\n}\n\n/** The gaps a text marks for a person in square brackets, as `[material]`, each once. */\nexport function aiProductGaps(...texts: readonly string[]): string[] {\n const found = new Set<string>()\n for (const value of texts) {\n for (const match of value.matchAll(/\\[([^\\]\\n]{1,60})\\]/g)) found.add(match[1].trim())\n }\n return [...found].filter(Boolean)\n}\n\n/* ------------------------------------------------------------------------ *\n * The console's cards\n * ------------------------------------------------------------------------ */\n\n/** The option the import zone sets to write the imported products' copy. */\nexport const AI_PRODUCTS_IMPORT_WRITE_COPY = 'ai.writeCopy'\n\n/** The brief a bulk copy job carries, which the jobs list shows and a card recognizes it by. */\nexport const aiProductsBulkBrief = (count: number): string =>\n `Write storefront copy for ${count} ${count === 1 ? 'product' : 'products'}`\n\nconst BULK_BRIEF = /^Write storefront copy for (\\d+) products?$/\n\n/** How many products a bulk copy job was asked for, read from its brief; `null` for any other job. */\nexport function aiProductsBulkCount(job: Pick<AiJobSummary, 'brief'> | null | undefined): number | null {\n const match = BULK_BRIEF.exec(job?.brief ?? '')\n return match ? Number(match[1]) : null\n}\n"],"names":["AI_PRODUCTS_TARGETS","AI_PRODUCT_TYPES","AI_PRODUCT_NAME_MAX_CHARS","AI_PRODUCT_TEXT_MAX_CHARS","AI_PRODUCT_DESCRIPTION_MAX_CHARS","AI_PRODUCT_TAGS_MAX","AI_PRODUCT_TAG_MAX_CHARS","AI_PRODUCT_CATEGORIES_MAX","AI_PRODUCT_CATEGORY_LIST_MAX","AI_PRODUCT_OPTIONS_MAX","AI_PRODUCT_OPTION_VALUES_MAX","AI_PRODUCT_OPTION_NAME_MAX_CHARS","AI_PRODUCTS_BULK_MAX","AI_CATALOG_PRODUCTS","min","max","AI_CATALOG_DESCRIPTION_MAX_CHARS","AI_CATALOG_TAGS_MAX","AI_CATALOG_OPTIONS_MAX","AI_CATALOG_OPTION_VALUES_MAX","AI_CATALOG_OPTION_VALUE_MAX_CHARS","AI_CATALOG_PHOTO_MAX_CHARS","AI_CATEGORIES_MAX","AI_DISCOUNTS_MAX","AI_CATEGORY_NAME_MAX_CHARS","AI_PROPOSAL_WHY_MAX_CHARS","AI_DISCOUNT_MAX_PERCENT","AI_DISCOUNT_MAX_FIXED_USD","AI_DISCOUNT_CODE","aiProductMerchantWords","product","name","text","tags","join","ID","value","replace","trim","slice","jsonStrings","maxChars","parsed","JSON","parse","Array","isArray","map","entry","filter","Boolean","jsonOptions","record","values","AI_PRODUCTS_INPUTS_MAX_JSON_CHARS","aiProductsJobInputs","input","target","inputs","productId","id","type","stringify","tag","categoryIds","test","options","option","imageUrl","seoTitle","seoDescription","length","Math","productIds","Set","AI_PRODUCTS_NO_TARGET_COPY","AI_PRODUCTS_NO_NAME_COPY","AI_PRODUCTS_NO_SELECTION_COPY","AI_PRODUCTS_TOO_MANY_COPY","parseAiProductsJobInputs","raw","includes","String","split","part","ids","unique","AI_PRODUCTS_OUTPUT_IDS","copy","catalog","categories","isRecord","aiProductsProposalOf","output","resource","proposal","kind","aiProductCopyProposals","job","outputs","aiProductsProposalOfKind","aiProductGaps","texts","found","match","matchAll","add","AI_PRODUCTS_IMPORT_WRITE_COPY","aiProductsBulkBrief","count","BULK_BRIEF","aiProductsBulkCount","exec","brief","Number"],"mappings":"AAAA;;;;;;;;;;;;;;;CAeC,GAID;;;;;;;;;;;;;;;;;;;;CAoBC,GAED,OAAO,MAAMA,sBAAsB;IAAC;IAAW;IAAQ;IAAW;CAAa,CAAS;AAGxF,OAAO,MAAMC,mBAAmB;IAAC;IAAY;IAAW;CAAU,CAAS;AAG3E,+CAA+C,GAC/C,OAAO,MAAMC,4BAA4B,IAAG;AAE5C,oEAAoE,GACpE,OAAO,MAAMC,4BAA4B,KAAK;AAE9C,8CAA8C,GAC9C,OAAO,MAAMC,mCAAmC,KAAK;AAErD,OAAO,MAAMC,sBAAsB,EAAC;AACpC,OAAO,MAAMC,2BAA2B,GAAE;AAE1C,sDAAsD,GACtD,OAAO,MAAMC,4BAA4B,EAAC;AAE1C,oEAAoE,GACpE,OAAO,MAAMC,+BAA+B,IAAG;AAE/C,iEAAiE,GACjE,OAAO,MAAMC,yBAAyB,EAAC;AACvC,OAAO,MAAMC,+BAA+B,GAAE;AAC9C,OAAO,MAAMC,mCAAmC,GAAE;AAElD,uDAAuD,GACvD,OAAO,MAAMC,uBAAuB,GAAE;AAEtC,gDAAgD,GAChD,OAAO,MAAMC,sBAAsB;IAAEC,KAAK;IAAGC,KAAK;AAAG,EAAU;AAE/D;;;;CAIC,GACD,OAAO,MAAMC,mCAAmC,IAAG;AACnD,OAAO,MAAMC,sBAAsB,EAAC;AAEpC,oGAAoG,GACpG,OAAO,MAAMC,yBAAyB,EAAC;AACvC,OAAO,MAAMC,+BAA+B,EAAC;AAC7C,OAAO,MAAMC,oCAAoC,GAAE;AAEnD,kEAAkE,GAClE,OAAO,MAAMC,6BAA6B,IAAG;AAE7C,OAAO,MAAMC,oBAAoB,GAAE;AACnC,OAAO,MAAMC,mBAAmB,EAAC;AACjC,OAAO,MAAMC,6BAA6B,GAAE;AAC5C,OAAO,MAAMC,4BAA4B,IAAG;AAE5C,sGAAsG,GACtG,OAAO,MAAMC,0BAA0B,GAAE;AACzC,OAAO,MAAMC,4BAA4B,KAAK;AAE9C,iFAAiF,GACjF,OAAO,MAAMC,mBAAmB,qBAAoB;AA+BpD,oFAAoF,GACpF,OAAO,SAASC,uBAAuBC,OAAuD;IAC5F,OAAO;QAACA,QAAQC,IAAI;QAAED,QAAQE,IAAI;WAAKF,QAAQG,IAAI;KAAC,CAACC,IAAI,CAAC;AAC5D;AAQA,MAAMC,KAAK;AAEX,MAAMH,OAAO,CAACI,OAAgBrB,MAC5B,OAAOqB,UAAU,WAAWA,MAAMC,OAAO,CAAC,QAAQ,KAAKC,IAAI,GAAGC,KAAK,CAAC,GAAGxB,OAAO;AAEhF,6EAA6E,GAC7E,SAASyB,YAAYJ,KAAc,EAAErB,GAAW,EAAE0B,QAAgB;IAChE,IAAI,OAAOL,UAAU,YAAY,CAACA,MAAME,IAAI,IAAI,OAAO,EAAE;IACzD,IAAI;QACF,MAAMI,SAAkBC,KAAKC,KAAK,CAACR;QACnC,IAAI,CAACS,MAAMC,OAAO,CAACJ,SAAS,OAAO,EAAE;QACrC,OAAOA,OACJK,GAAG,CAAC,CAACC,QAAUhB,KAAKgB,OAAOP,WAC3BQ,MAAM,CAACC,SACPX,KAAK,CAAC,GAAGxB;IACd,EAAE,eAAM;QACN,OAAO,EAAE;IACX;AACF;AAEA,SAASoC,YAAYf,KAAc;IACjC,IAAI,OAAOA,UAAU,YAAY,CAACA,MAAME,IAAI,IAAI,OAAO,EAAE;IACzD,IAAI;QACF,MAAMI,SAAkBC,KAAKC,KAAK,CAACR;QACnC,IAAI,CAACS,MAAMC,OAAO,CAACJ,SAAS,OAAO,EAAE;QACrC,OAAOA,OACJK,GAAG,CAAC,CAACC;YACJ,MAAMI,SAAUJ,gBAAAA,QAAS,CAAC;YAC1B,OAAO;gBACLjB,MAAMC,KAAKoB,MAAM,CAAC,OAAO,EAAEzC;gBAC3B0C,QAAQR,MAAMC,OAAO,CAACM,MAAM,CAAC,SAAS,IAClCA,MAAM,CAAC,SAAS,CAACL,GAAG,CAAC,CAACX,QAAUJ,KAAKI,OAAO,KAAKa,MAAM,CAACC,SAASX,KAAK,CAAC,GAAG7B,gCAC1E,EAAE;YACR;QACF,GACC6B,KAAK,CAAC,GAAG9B;IACd,EAAE,eAAM;QACN,OAAO,EAAE;IACX;AACF;AAEA;;;CAGC,GACD,OAAO,MAAM6C,oCAAoC,KAAK;AAEtD;;;;;CAKC,GACD,OAAO,SAASC,oBAAoBC,KAA0B;IAC5D,OAAQA,MAAMC,MAAM;QAClB,KAAK;YAAW;oBAID3B,aAYAA;gBAfb,MAAMA,UAAU0B,MAAM1B,OAAO;gBAC7B,MAAM4B,SAAiC;oBACrCD,QAAQ;oBACRE,SAAS,GAAE7B,cAAAA,QAAQ8B,EAAE,YAAV9B,cAAc;oBACzBC,MAAMC,KAAKF,QAAQC,IAAI,EAAE7B;oBACzB2D,MAAM/B,QAAQ+B,IAAI;oBAClB7B,MAAMF,QAAQE,IAAI,CAACO,KAAK,CAAC,GAAGpC;oBAC5B8B,MAAMU,KAAKmB,SAAS,CAAChC,QAAQG,IAAI,CAACM,KAAK,CAAC,GAAG,IAAIQ,GAAG,CAAC,CAACgB,MAAQA,IAAIxB,KAAK,CAAC,GAAG;oBACzEyB,aAAalC,QAAQkC,WAAW,CAACf,MAAM,CAAC,CAACW,KAAOzB,GAAG8B,IAAI,CAACL,KAAKrB,KAAK,CAAC,GAAG,IAAIL,IAAI,CAAC;oBAC/EgC,SAASvB,KAAKmB,SAAS,CACrBhC,QAAQoC,OAAO,CAAC3B,KAAK,CAAC,GAAG9B,wBAAwBsC,GAAG,CAAC,CAACoB,SAAY,CAAA;4BAChEpC,MAAMoC,OAAOpC,IAAI,CAACQ,KAAK,CAAC,GAAG5B;4BAC3B0C,QAAQc,OAAOd,MAAM,CAACd,KAAK,CAAC,GAAG7B,8BAA8BqC,GAAG,CAAC,CAACX,QAAUA,MAAMG,KAAK,CAAC,GAAG;wBAC7F,CAAA;oBAEF6B,UAAU,EAACtC,oBAAAA,QAAQsC,QAAQ,YAAhBtC,oBAAoB,IAAIS,KAAK,CAAC,GAAG;oBAC5C8B,UAAUvC,QAAQuC,QAAQ,CAAC9B,KAAK,CAAC,GAAG;oBACpC+B,gBAAgBxC,QAAQwC,cAAc,CAAC/B,KAAK,CAAC,GAAG;gBAClD;gBACA,MAAOI,KAAKmB,SAAS,CAACJ,QAAQa,MAAM,GAAGjB,qCAAqCI,MAAM,CAAC,OAAO,CAAE;oBAC1FA,MAAM,CAAC,OAAO,GAAGA,MAAM,CAAC,OAAO,CAACnB,KAAK,CAAC,GAAGiC,KAAKzD,GAAG,CAAC,GAAG2C,MAAM,CAAC,OAAO,CAACa,MAAM,GAAG;gBAC/E;gBACA,OAAOb;YACT;QACA,KAAK;YACH,OAAO;gBACLD,QAAQ;gBACRgB,YAAY;uBAAI,IAAIC,IAAIlB,MAAMiB,UAAU,CAACxB,MAAM,CAAC,CAACW,KAAOzB,GAAG8B,IAAI,CAACL;iBAAM,CACnErB,KAAK,CAAC,GAAG3B,sBACTsB,IAAI,CAAC;YACV;QACF;YACE,OAAO;gBAAEuB,QAAQD,MAAMC,MAAM;YAAC;IAClC;AACF;AAEA,4EAA4E,GAC5E,OAAO,MAAMkB,6BAA6B,4DAA2D;AACrG,OAAO,MAAMC,2BAA2B,mDAAkD;AAC1F,OAAO,MAAMC,gCAAgC,uCAAsC;AACnF,OAAO,MAAMC,4BAA4B,CAAC,aAAa,EAAElE,qBAAqB,oBAAoB,CAAC,CAAA;AAEnG,6EAA6E,GAC7E,OAAO,SAASmE,yBAAyBC,GAAkD;IACzF,MAAMtB,SAASsB,cAAAA,MAAO,CAAC;IACvB,MAAMvB,SAASC,MAAM,CAAC,SAAS;IAC/B,IAAI,CAAC,AAAC1D,oBAA2CiF,QAAQ,CAACxB,SAAS,OAAOkB;IAC1E,IAAIlB,WAAW,WAAW;YAaAC;QAZxB,MAAM3B,OAAOC,KAAK0B,MAAM,CAAC,OAAO,EAAExD;QAClC,IAAI,CAAC6B,MAAM,OAAO6C;QAClB,MAAMf,OAAOH,MAAM,CAAC,OAAO;QAC3B,MAAME,KAAK,OAAOF,MAAM,CAAC,YAAY,KAAK,YAAYvB,GAAG8B,IAAI,CAACP,MAAM,CAAC,YAAY,IAAIA,MAAM,CAAC,YAAY,GAAG;QAC3G,OAAO;YACLD;YACA3B,SAAS;gBACP8B;gBACA7B;gBACA8B,MAAM,AAAC5D,iBAAwCgF,QAAQ,CAACpB,QAASA,OAAyB;gBAC1F7B,MAAM,OAAO0B,MAAM,CAAC,OAAO,KAAK,WAAWA,MAAM,CAAC,OAAO,CAACpB,IAAI,GAAGC,KAAK,CAAC,GAAGpC,6BAA6B;gBACvG8B,MAAMO,YAAYkB,MAAM,CAAC,OAAO,EAAE,IAAI;gBACtCM,aAAakB,QAAOxB,sBAAAA,MAAM,CAAC,cAAc,YAArBA,sBAAyB,IAC1CyB,KAAK,CAAC,KACNpC,GAAG,CAAC,CAACqC,OAASA,KAAK9C,IAAI,IACvBW,MAAM,CAAC,CAACmC,OAASjD,GAAG8B,IAAI,CAACmB,OACzB7C,KAAK,CAAC,GAAG;gBACZ2B,SAASf,YAAYO,MAAM,CAAC,UAAU;gBACtCU,UAAUpC,KAAK0B,MAAM,CAAC,WAAW,EAAE,QAAQ;gBAC3CW,UAAUrC,KAAK0B,MAAM,CAAC,WAAW,EAAE;gBACnCY,gBAAgBtC,KAAK0B,MAAM,CAAC,iBAAiB,EAAE;YACjD;QACF;IACF;IACA,IAAID,WAAW,QAAQ;YACFC;QAAnB,MAAM2B,MAAMH,QAAOxB,qBAAAA,MAAM,CAAC,aAAa,YAApBA,qBAAwB,IACxCyB,KAAK,CAAC,KACNpC,GAAG,CAAC,CAACqC,OAASA,KAAK9C,IAAI,IACvBW,MAAM,CAAC,CAACmC,OAASjD,GAAG8B,IAAI,CAACmB;QAC5B,MAAME,SAAS;eAAI,IAAIZ,IAAIW;SAAK;QAChC,IAAI,CAACC,OAAOf,MAAM,EAAE,OAAOM;QAC3B,IAAIS,OAAOf,MAAM,GAAG3D,sBAAsB,OAAOkE;QACjD,OAAO;YAAErB;YAAQgB,YAAYa;QAAO;IACtC;IACA,OAAO;QAAE7B,QAAQA;IAAmC;AACtD;AA0FA,0EAA0E,GAC1E,OAAO,MAAM8B,yBAAyB;IACpCC,MAAM,CAAC7B,YAA6B,CAAC,KAAK,EAAEA,oBAAAA,YAAa,OAAO;IAChE8B,SAAS;IACTC,YAAY;AACd,EAAU;AAEV,MAAMC,WAAW,CAACvD,QAChB,OAAOA,UAAU,YAAYA,UAAU,QAAQ,CAACS,MAAMC,OAAO,CAACV;AAEhE,mFAAmF,GACnF,OAAO,SAASwD,qBAAqBC,MAAqE;IACxG,IAAI,CAACA,UAAUA,OAAOC,QAAQ,KAAK,aAAa,CAACH,SAASE,OAAOE,QAAQ,GAAG,OAAO;IACnF,MAAMC,OAAOH,OAAOE,QAAQ,CAAC,OAAO;IACpC,OAAOC,SAAS,UAAUA,SAAS,aAAaA,SAAS,eACpDH,OAAOE,QAAQ,GAChB;AACN;AAEA,4DAA4D,GAC5D,OAAO,SAASE,uBAAuBC,GAAqD;;IAC1F,OAAO,SAACA,uBAAAA,IAAKC,OAAO,mBAAI,EAAE,EACvBpD,GAAG,CAAC,CAAC8C,SAAWD,qBAAqBC,SACrC5C,MAAM,CAAC,CAAC8C,WAAgDA,CAAAA,4BAAAA,SAAUC,IAAI,MAAK;AAChF;AAEA,6CAA6C,GAC7C,OAAO,SAASI,yBACdF,GAAqD,EACrDF,IAAO;;IAEP,KAAK,MAAMH,kBAAUK,uBAAAA,IAAKC,OAAO,mBAAI,EAAE,CAAE;QACvC,MAAMJ,WAAWH,qBAAqBC;QACtC,IAAIE,CAAAA,4BAAAA,SAAUC,IAAI,MAAKA,MAAM,OAAOD;IACtC;IACA,OAAO;AACT;AAEA,uFAAuF,GACvF,OAAO,SAASM,cAAc,GAAGC,KAAwB;IACvD,MAAMC,QAAQ,IAAI7B;IAClB,KAAK,MAAMtC,SAASkE,MAAO;QACzB,KAAK,MAAME,SAASpE,MAAMqE,QAAQ,CAAC,wBAAyBF,MAAMG,GAAG,CAACF,KAAK,CAAC,EAAE,CAAClE,IAAI;IACrF;IACA,OAAO;WAAIiE;KAAM,CAACtD,MAAM,CAACC;AAC3B;AAEA;;4EAE4E,GAE5E,0EAA0E,GAC1E,OAAO,MAAMyD,gCAAgC,eAAc;AAE3D,8FAA8F,GAC9F,OAAO,MAAMC,sBAAsB,CAACC,QAClC,CAAC,0BAA0B,EAAEA,MAAM,CAAC,EAAEA,UAAU,IAAI,YAAY,YAAY,CAAA;AAE9E,MAAMC,aAAa;AAEnB,oGAAoG,GACpG,OAAO,SAASC,oBAAoBb,GAAmD;;IACrF,MAAMM,QAAQM,WAAWE,IAAI,SAACd,uBAAAA,IAAKe,KAAK,mBAAI;IAC5C,OAAOT,QAAQU,OAAOV,KAAK,CAAC,EAAE,IAAI;AACpC"}
|