@aglyn/plugins-ai 1.0.0-beta.271 → 1.0.0-beta.273

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (132) hide show
  1. package/package.json +17 -17
  2. package/src/lib/activity/ai-activity-actions.d.ts +4 -3
  3. package/src/lib/activity/ai-activity-actions.js +3 -0
  4. package/src/lib/activity/ai-activity-actions.js.map +1 -1
  5. package/src/lib/components/ai-site-build-page.component.js +18 -0
  6. package/src/lib/components/ai-site-build-page.component.js.map +1 -1
  7. package/src/lib/components/ai-site-import-job.component.d.ts +41 -0
  8. package/src/lib/components/ai-site-import-job.component.js +707 -0
  9. package/src/lib/components/ai-site-import-job.component.js.map +1 -0
  10. package/src/lib/components/ai-site-import-start.component.d.ts +64 -0
  11. package/src/lib/components/ai-site-import-start.component.js +335 -0
  12. package/src/lib/components/ai-site-import-start.component.js.map +1 -0
  13. package/src/lib/components/ai-site-ownership-proof.component.d.ts +42 -0
  14. package/src/lib/components/ai-site-ownership-proof.component.js +353 -0
  15. package/src/lib/components/ai-site-ownership-proof.component.js.map +1 -0
  16. package/src/lib/components/ai-site-start-card.component.js +329 -252
  17. package/src/lib/components/ai-site-start-card.component.js.map +1 -1
  18. package/src/lib/jobs/ai-empty-site-sweep.d.ts +12 -1
  19. package/src/lib/jobs/ai-empty-site-sweep.js +15 -3
  20. package/src/lib/jobs/ai-empty-site-sweep.js.map +1 -1
  21. package/src/lib/jobs/ai-job-drafts.d.ts +14 -0
  22. package/src/lib/jobs/ai-job-drafts.js +24 -0
  23. package/src/lib/jobs/ai-job-drafts.js.map +1 -1
  24. package/src/lib/jobs/ai-job-import-step.d.ts +136 -0
  25. package/src/lib/jobs/ai-job-import-step.js +809 -0
  26. package/src/lib/jobs/ai-job-import-step.js.map +1 -0
  27. package/src/lib/jobs/ai-job-page-language.d.ts +39 -1
  28. package/src/lib/jobs/ai-job-page-language.js +62 -4
  29. package/src/lib/jobs/ai-job-page-language.js.map +1 -1
  30. package/src/lib/jobs/ai-job-page-step.d.ts +2 -2
  31. package/src/lib/jobs/ai-job-page-step.js +26 -4
  32. package/src/lib/jobs/ai-job-page-step.js.map +1 -1
  33. package/src/lib/jobs/ai-job-seo-step.js +8 -4
  34. package/src/lib/jobs/ai-job-seo-step.js.map +1 -1
  35. package/src/lib/jobs/ai-job-site-datasets.d.ts +39 -1
  36. package/src/lib/jobs/ai-job-site-datasets.js +111 -15
  37. package/src/lib/jobs/ai-job-site-datasets.js.map +1 -1
  38. package/src/lib/jobs/ai-job-site-step.d.ts +12 -3
  39. package/src/lib/jobs/ai-job-site-step.js +85 -11
  40. package/src/lib/jobs/ai-job-site-step.js.map +1 -1
  41. package/src/lib/jobs/ai-job-text-step.d.ts +15 -0
  42. package/src/lib/jobs/ai-job-text-step.js.map +1 -1
  43. package/src/lib/jobs/ai-jobs.d.ts +8 -0
  44. package/src/lib/jobs/ai-jobs.js +19 -3
  45. package/src/lib/jobs/ai-jobs.js.map +1 -1
  46. package/src/lib/jobs/ai-layout-owner-photos.d.ts +16 -1
  47. package/src/lib/jobs/ai-layout-owner-photos.js +49 -2
  48. package/src/lib/jobs/ai-layout-owner-photos.js.map +1 -1
  49. package/src/lib/jobs/ai-layout-stock-photos.d.ts +35 -0
  50. package/src/lib/jobs/ai-layout-stock-photos.js +114 -43
  51. package/src/lib/jobs/ai-layout-stock-photos.js.map +1 -1
  52. package/src/lib/jobs/ai-site-late-photos.d.ts +143 -0
  53. package/src/lib/jobs/ai-site-late-photos.js +486 -0
  54. package/src/lib/jobs/ai-site-late-photos.js.map +1 -0
  55. package/src/lib/jobs/ai-site-publish.d.ts +18 -0
  56. package/src/lib/jobs/ai-site-publish.js +123 -5
  57. package/src/lib/jobs/ai-site-publish.js.map +1 -1
  58. package/src/lib/jobs/ai-theme-brand-inputs.d.ts +61 -3
  59. package/src/lib/jobs/ai-theme-brand-inputs.js +117 -27
  60. package/src/lib/jobs/ai-theme-brand-inputs.js.map +1 -1
  61. package/src/lib/jobs/fixtures/ai-site-late-photos-laurel-fork.d.ts +83 -0
  62. package/src/lib/jobs/fixtures/ai-site-late-photos-laurel-fork.js +1553 -0
  63. package/src/lib/jobs/fixtures/ai-site-late-photos-laurel-fork.js.map +1 -0
  64. package/src/lib/layout-language/ai-layout-pictures.d.ts +50 -13
  65. package/src/lib/layout-language/ai-layout-pictures.js +81 -19
  66. package/src/lib/layout-language/ai-layout-pictures.js.map +1 -1
  67. package/src/lib/model/ai-credit-estimate.d.ts +20 -0
  68. package/src/lib/model/ai-credit-estimate.js +13 -0
  69. package/src/lib/model/ai-credit-estimate.js.map +1 -1
  70. package/src/lib/model/ai-job-activity.d.ts +2 -2
  71. package/src/lib/model/ai-job-activity.js +6 -4
  72. package/src/lib/model/ai-job-activity.js.map +1 -1
  73. package/src/lib/model/ai-job-notice.js +18 -4
  74. package/src/lib/model/ai-job-notice.js.map +1 -1
  75. package/src/lib/model/ai-jobs.types.d.ts +39 -2
  76. package/src/lib/model/ai-jobs.types.js +2 -1
  77. package/src/lib/model/ai-jobs.types.js.map +1 -1
  78. package/src/lib/model/ai-site-import-view.d.ts +130 -0
  79. package/src/lib/model/ai-site-import-view.js +182 -0
  80. package/src/lib/model/ai-site-import-view.js.map +1 -0
  81. package/src/lib/model/ai-site-import.d.ts +302 -0
  82. package/src/lib/model/ai-site-import.js +526 -0
  83. package/src/lib/model/ai-site-import.js.map +1 -0
  84. package/src/lib/model/ai-site-photos.d.ts +119 -0
  85. package/src/lib/model/ai-site-photos.js +128 -0
  86. package/src/lib/model/ai-site-photos.js.map +1 -0
  87. package/src/lib/model/ai-site-start.d.ts +22 -9
  88. package/src/lib/model/ai-site-start.js +64 -23
  89. package/src/lib/model/ai-site-start.js.map +1 -1
  90. package/src/lib/runtime/ai-doctrine-validators.d.ts +3 -1
  91. package/src/lib/runtime/ai-doctrine-validators.js +3 -1
  92. package/src/lib/runtime/ai-doctrine-validators.js.map +1 -1
  93. package/src/lib/runtime/seo-fields.d.ts +29 -4
  94. package/src/lib/runtime/seo-fields.js +58 -11
  95. package/src/lib/runtime/seo-fields.js.map +1 -1
  96. package/src/lib/server/ai-jobs-route.js +11 -0
  97. package/src/lib/server/ai-jobs-route.js.map +1 -1
  98. package/src/lib/server/ai-site-import-route.d.ts +89 -0
  99. package/src/lib/server/ai-site-import-route.js +356 -0
  100. package/src/lib/server/ai-site-import-route.js.map +1 -0
  101. package/src/lib/server.js +14 -0
  102. package/src/lib/server.js.map +1 -1
  103. package/src/lib/site-import/fixtures/site-import-crawl-recordings.d.ts +45 -0
  104. package/src/lib/site-import/fixtures/site-import-crawl-recordings.js +313 -0
  105. package/src/lib/site-import/fixtures/site-import-crawl-recordings.js.map +1 -0
  106. package/src/lib/site-import/fixtures/site-import-wave-recordings.d.ts +50 -0
  107. package/src/lib/site-import/fixtures/site-import-wave-recordings.js +217 -0
  108. package/src/lib/site-import/fixtures/site-import-wave-recordings.js.map +1 -0
  109. package/src/lib/site-import/site-import-crawl.d.ts +163 -0
  110. package/src/lib/site-import/site-import-crawl.js +467 -0
  111. package/src/lib/site-import/site-import-crawl.js.map +1 -0
  112. package/src/lib/site-import/site-import-flag.d.ts +23 -0
  113. package/src/lib/site-import/site-import-flag.js +23 -0
  114. package/src/lib/site-import/site-import-flag.js.map +1 -0
  115. package/src/lib/site-import/site-import-html.d.ts +94 -0
  116. package/src/lib/site-import/site-import-html.js +462 -0
  117. package/src/lib/site-import/site-import-html.js.map +1 -0
  118. package/src/lib/site-import/site-import-images.d.ts +54 -0
  119. package/src/lib/site-import/site-import-images.js +204 -0
  120. package/src/lib/site-import/site-import-images.js.map +1 -0
  121. package/src/lib/site-import/site-import-page.d.ts +48 -0
  122. package/src/lib/site-import/site-import-page.js +150 -0
  123. package/src/lib/site-import/site-import-page.js.map +1 -0
  124. package/src/lib/site-import/site-import-review.d.ts +40 -0
  125. package/src/lib/site-import/site-import-review.js +149 -0
  126. package/src/lib/site-import/site-import-review.js.map +1 -0
  127. package/src/lib/site-import/site-import-robots.d.ts +52 -0
  128. package/src/lib/site-import/site-import-robots.js +126 -0
  129. package/src/lib/site-import/site-import-robots.js.map +1 -0
  130. package/src/lib/tools/ai-seo-tool.d.ts +25 -1
  131. package/src/lib/tools/ai-seo-tool.js +61 -0
  132. package/src/lib/tools/ai-seo-tool.js.map +1 -1
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../../../../libs/plugins/ai/src/lib/components/ai-site-import-job.component.tsx"],"sourcesContent":["/**\n * @license\n * Copyright 2026 Aglyn LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n'use client'\n\nimport { PageHeaderRecord } from '@aglyn/aglyn/app-utils/page-header-record-context'\nimport { buildRoute, Route } from '@aglyn/aglyn/app-utils/console-routes'\nimport {\n mdiAlertCircle,\n mdiCheckCircle,\n mdiChevronDown,\n mdiClockOutline,\n mdiMinusCircleOutline,\n} from '@aglyn/shared-data-mdi'\nimport { AppLink, HelpTip, MdiIcon } from '@aglyn/shared-ui-jsx'\nimport type { MaybeTokenSource } from '@aglyn/shared-util-http/authorized-token'\nimport {\n Accordion,\n AccordionDetails,\n AccordionSummary,\n Alert,\n Box,\n Button,\n Card,\n CircularProgress,\n Container,\n LinearProgress,\n Stack,\n Typography,\n} from '@mui/material'\nimport { useCallback, useState, type ReactNode } from 'react'\nimport type { AiJobSummary } from '../model/ai-jobs.types'\nimport { aiSiteImportReviewWave, aiSiteImportRunningWave, type AiSiteImportWave } from '../model/ai-site-import'\nimport {\n aiSiteImportFoundText,\n aiSiteImportLeftOutLines,\n aiSiteImportPhaseOf,\n aiSiteImportPlanText,\n aiSiteImportStartAction,\n aiSiteImportWaveRows,\n aiSiteImportWaveSpent,\n type AiSiteImportClaim,\n type AiSiteImportRowState,\n} from '../model/ai-site-import-view'\nimport { AiJobCancelButton } from './ai-job-cancel.component'\nimport { aiCreditsBillingHref, aiJobOutputHref } from './ai-job-links'\nimport { AI_SITE_IMPORT_HELP } from './ai-site-import-start.component'\nimport { AiSiteOwnershipProof, postAiSiteOwnership } from './ai-site-ownership-proof.component'\n\nconst ROW_ICON: Readonly<Record<Exclude<AiSiteImportRowState, 'active'>, { path: string; color: string; label: string }>> = {\n done: { path: mdiCheckCircle.path, color: 'success.main', label: 'In' },\n waiting: { path: mdiClockOutline.path, color: 'text.disabled', label: 'Waiting' },\n failed: { path: mdiAlertCircle.path, color: 'error.main', label: 'Could not be brought in' },\n skipped: { path: mdiMinusCircleOutline.path, color: 'text.disabled', label: 'Left out' },\n}\n\nfunction RowIcon({ state }: { state: AiSiteImportRowState }) {\n if (state === 'active') return <CircularProgress size={20} aria-label=\"In progress\" />\n const icon = ROW_ICON[state]\n return (\n <Box component=\"span\" role=\"img\" aria-label={icon.label} sx={{ color: icon.color, display: 'inline-flex', fontSize: (theme) => theme.spacing(2.5) }}>\n <MdiIcon path={icon.path} aria-hidden />\n </Box>\n )\n}\n\n/** One wave's pages: where each was, where it is now, how it went, and its draft to open. */\nfunction WaveRows({ job, wave, orgSlug }: { job: AiJobSummary; wave: AiSiteImportWave; orgSlug: string }) {\n const rows = aiSiteImportWaveRows(job, wave)\n return (\n <Box component=\"ol\" aria-label={wave.label} sx={{ listStyle: 'none', m: 0, p: { xs: 2, sm: 3 } }}>\n <Stack spacing={2}>\n {rows.map((row) => {\n const output = row.outputId ? job.outputs.find((entry) => entry.id === row.outputId) : undefined\n const href = output ? aiJobOutputHref(output, orgSlug) : null\n return (\n <Stack component=\"li\" key={row.slot} direction=\"row\" spacing={2} sx={{ alignItems: 'flex-start' }}>\n <Box sx={{ width: (theme) => theme.spacing(3), display: 'flex', justifyContent: 'center' }}>\n <RowIcon state={row.state} />\n </Box>\n <Box sx={{ flex: 1, minWidth: 0 }}>\n <Stack direction=\"row\" spacing={1} sx={{ alignItems: 'baseline', justifyContent: 'space-between' }}>\n <Typography variant=\"body1\" color={row.state === 'waiting' || row.state === 'skipped' ? 'text.secondary' : 'text.primary'}>\n {row.title}\n </Typography>\n {href && row.state === 'done' ? (\n <Button size=\"small\" component={AppLink} href={href}>\n {'Open draft'}\n </Button>\n ) : null}\n </Stack>\n <Typography variant=\"body2\" color=\"text.secondary\" sx={{ overflowWrap: 'anywhere' }}>\n {`${row.from} → ${row.to}`}\n </Typography>\n {row.photos ? (\n <Typography variant=\"body2\" color=\"text.secondary\">\n {row.photos}\n </Typography>\n ) : null}\n {row.note && row.state !== 'done' ? (\n <Typography variant=\"body2\" color=\"text.secondary\">\n {row.note}\n </Typography>\n ) : null}\n </Box>\n </Stack>\n )\n })}\n </Stack>\n </Box>\n )\n}\n\nfunction Frame({ siteName, heading, lede, children }: { siteName?: string; heading: string; lede?: string; children?: ReactNode }) {\n return (\n <Container maxWidth=\"sm\" sx={{ py: { xs: 3, sm: 5 }, px: { xs: 2, sm: 3 } }}>\n <PageHeaderRecord title={heading} />\n <Stack spacing={4}>\n <Stack spacing={1}>\n {siteName ? (\n <Typography variant=\"overline\" color=\"text.secondary\">\n {siteName}\n </Typography>\n ) : null}\n <Typography variant=\"h4\" component=\"h1\">\n {heading}\n </Typography>\n {lede ? (\n <Typography variant=\"body1\" color=\"text.secondary\">\n {lede}\n </Typography>\n ) : null}\n </Stack>\n {children}\n </Stack>\n </Container>\n )\n}\n\nexport interface AiSiteImportJobProps {\n job: AiJobSummary\n orgId: string | null\n orgSlug: string\n /** The site's subdomain, which its Pages list is addressed by. */\n host: string | null\n siteName?: string\n user: MaybeTokenSource\n busy: boolean\n notice: string | null\n /** Starts the next wave, or reads the site again: the resume door. */\n onResume: () => void\n onJob: (job: AiJobSummary) => void\n}\n\n/**\n * \"Bring my site\" (AGL-3976), on the import job's own page: the site read\n * and its waves planned with each one's quote, a wave running page by page,\n * a wave in for its review with its drafts to open, and the next wave's\n * button — the only way the next one starts. A wave held for a new proof, the\n * day's limit or a site that could not be read says so and offers the way on.\n */\nexport function AiSiteImportJob({ job, orgId, orgSlug, host, siteName, user, busy, notice, onResume, onJob }: AiSiteImportJobProps) {\n const phase = aiSiteImportPhaseOf(job)\n const state = job.siteImport ?? null\n const start = aiSiteImportStartAction(job)\n const pagesHref = host && orgSlug ? buildRoute(Route.HOST_SCREENS, { orgSlug, host }) : null\n const [claim, setClaim] = useState<AiSiteImportClaim | null>(null)\n const [claimNotice, setClaimNotice] = useState<string | null>(null)\n const verifyAgain = useCallback(async () => {\n if (!orgId || !state) return\n setClaimNotice(null)\n const answer = await postAiSiteOwnership(user, { orgId, action: 'claim', domain: state.domain })\n if (answer.claim) setClaim(answer.claim)\n else setClaimNotice(answer.message)\n }, [orgId, state, user])\n\n const cancel = (\n <Box>\n <AiJobCancelButton job={job} user={user} orgId={orgId} onJob={onJob} variant=\"text\" size=\"small\" />\n </Box>\n )\n const startButton = start ? (\n <Stack spacing={1}>\n <Box>\n <Button variant=\"contained\" size=\"large\" disabled={busy} onClick={onResume}>\n {busy ? 'Starting…' : start.label}\n </Button>\n </Box>\n <Stack direction=\"row\" spacing={0.5} sx={{ alignItems: 'center' }}>\n <Typography variant=\"body2\" color=\"text.secondary\">\n {`${start.quote}, from your AI credits. Every page is a draft until you publish it.`}\n </Typography>\n <HelpTip {...AI_SITE_IMPORT_HELP.waves} ariaLabel=\"How waves work\" />\n </Stack>\n </Stack>\n ) : null\n const waves = state ? (\n <Accordion variant=\"outlined\" disableGutters sx={{ borderRadius: 2, '&::before': { display: 'none' } }}>\n <AccordionSummary expandIcon={<MdiIcon path={mdiChevronDown.path} />}>\n <Typography variant=\"subtitle1\">{`Every wave (${state.waves.length})`}</Typography>\n </AccordionSummary>\n <AccordionDetails>\n <Stack component=\"ol\" spacing={1} sx={{ m: 0, pl: 2.5 }}>\n {state.waves.map((wave) => (\n <Typography component=\"li\" variant=\"body2\" key={wave.index}>\n {`${wave.label}: ${wave.slots.length} ${wave.slots.length === 1 ? 'page' : 'pages'}${wave.frame ? ', with your header and footer' : ''}${\n wave.status === 'done' || wave.status === 'review' ? ' (in)' : wave.status === 'running' ? ' (running)' : ''\n }`}\n </Typography>\n ))}\n </Stack>\n </AccordionDetails>\n </Accordion>\n ) : null\n const leftOut = state ? aiSiteImportLeftOutLines(state) : []\n const leftOutCard = leftOut.length ? (\n <Accordion variant=\"outlined\" disableGutters sx={{ borderRadius: 2, '&::before': { display: 'none' } }}>\n <AccordionSummary expandIcon={<MdiIcon path={mdiChevronDown.path} />}>\n <Typography variant=\"subtitle1\">{`Not brought in (${leftOut.reduce((total, line) => total + line.count, 0)})`}</Typography>\n </AccordionSummary>\n <AccordionDetails>\n <Stack spacing={1.5}>\n {leftOut.map((line) => (\n <Box key={line.reason}>\n <Typography variant=\"body2\">{`${line.count} · ${line.text}`}</Typography>\n {line.paths.length ? (\n <Typography variant=\"body2\" color=\"text.secondary\" sx={{ overflowWrap: 'anywhere' }}>\n {line.paths.slice(0, 8).join(', ')}\n {line.paths.length > 8 || line.count > line.paths.length ? ', …' : ''}\n </Typography>\n ) : null}\n {line.reason === 'plan-limit' && orgSlug ? (\n <Button size=\"small\" component={AppLink} href={aiCreditsBillingHref(orgSlug)} sx={{ mt: 0.5 }}>\n {'See plans'}\n </Button>\n ) : null}\n </Box>\n ))}\n </Stack>\n </AccordionDetails>\n </Accordion>\n ) : null\n\n if (phase === 'reading') {\n return (\n <Frame siteName={siteName} heading=\"Reading your site\" lede=\"AglynBot reads robots.txt first, then your sitemap and your pages. Nothing is built yet, and reading uses no AI credits.\">\n <Card variant=\"outlined\" sx={{ borderRadius: 2 }}>\n <LinearProgress aria-label=\"Reading your site\" />\n <Typography variant=\"body2\" color=\"text.secondary\" sx={{ p: { xs: 2, sm: 3 } }}>\n {'This takes a minute or two. You can leave this page; we tell you when your site is read.'}\n </Typography>\n </Card>\n {cancel}\n </Frame>\n )\n }\n\n if (phase === 'ready' && state) {\n return (\n <Frame siteName={siteName} heading=\"Your site is read\" lede={job.review?.message ?? undefined}>\n {notice && <Alert severity=\"warning\">{notice}</Alert>}\n <Stack spacing={1}>\n <Typography variant=\"body1\">{aiSiteImportFoundText(state)}</Typography>\n <Typography variant=\"body2\" color=\"text.secondary\">\n {aiSiteImportPlanText(state)}\n </Typography>\n </Stack>\n {start ? (\n <Card variant=\"outlined\" sx={{ borderRadius: 2 }}>\n <Typography variant=\"subtitle1\" sx={{ px: { xs: 2, sm: 3 }, pt: { xs: 2, sm: 3 } }}>\n {`First: ${start.wave.label}`}\n </Typography>\n <WaveRows job={job} wave={start.wave} orgSlug={orgSlug} />\n </Card>\n ) : null}\n {startButton}\n {waves}\n {leftOutCard}\n {cancel}\n </Frame>\n )\n }\n\n if ((phase === 'running' || phase === 'starting') && state) {\n const wave = aiSiteImportRunningWave(state) ?? start?.wave ?? null\n const rows = wave ? aiSiteImportWaveRows(job, wave) : []\n const done = rows.filter((row) => row.state !== 'waiting' && row.state !== 'active').length\n return (\n <Frame\n siteName={siteName}\n heading={wave ? `Bringing in ${wave.label}` : 'Bringing in your site'}\n lede=\"Each page is rewritten into your new site’s design with its own words, facts and photos. You review the wave when it is in.\"\n >\n <Card variant=\"outlined\" sx={{ borderRadius: 2 }}>\n {rows.length ? (\n <LinearProgress variant=\"determinate\" value={Math.round((done / rows.length) * 100)} aria-label={`${done} of ${rows.length} in`} />\n ) : (\n <LinearProgress aria-label=\"Starting the wave\" />\n )}\n {wave ? <WaveRows job={job} wave={wave} orgSlug={orgSlug} /> : null}\n </Card>\n {waves}\n {cancel}\n </Frame>\n )\n }\n\n if (phase === 'review' && state) {\n const wave = aiSiteImportReviewWave(state) as AiSiteImportWave\n const spent = aiSiteImportWaveSpent(job, wave)\n return (\n <Frame siteName={siteName} heading={`${wave.label} is in`} lede=\"Open each page to review it. They are drafts: nothing is published until you publish it.\">\n {notice && <Alert severity=\"warning\">{notice}</Alert>}\n <Card variant=\"outlined\" sx={{ borderRadius: 2 }}>\n <WaveRows job={job} wave={wave} orgSlug={orgSlug} />\n </Card>\n <Typography variant=\"body2\" color=\"text.secondary\">\n {`This wave used ${spent.toLocaleString('en-US')} AI ${spent === 1 ? 'credit' : 'credits'}.`}\n </Typography>\n {pagesHref ? (\n <Box>\n <Button variant=\"outlined\" component={AppLink} href={pagesHref}>\n {'Open your draft pages'}\n </Button>\n </Box>\n ) : null}\n {start ? (\n <Card variant=\"outlined\" sx={{ borderRadius: 2 }}>\n <Typography variant=\"subtitle1\" sx={{ px: { xs: 2, sm: 3 }, pt: { xs: 2, sm: 3 } }}>\n {`Next: ${start.wave.label}`}\n </Typography>\n <WaveRows job={job} wave={start.wave} orgSlug={orgSlug} />\n </Card>\n ) : null}\n {startButton}\n {waves}\n {leftOutCard}\n {cancel}\n </Frame>\n )\n }\n\n if (phase === 'held' || phase === 'paused') {\n const ownership = job.review?.reason === 'ownership'\n return (\n <Frame siteName={siteName} heading={ownership ? 'Verify your site again' : phase === 'paused' ? 'Your site import is paused' : 'Your site import is waiting'}>\n {notice && <Alert severity=\"warning\">{notice}</Alert>}\n <Alert severity=\"info\">{job.review?.message ?? job.error ?? 'It stopped for your decision.'}</Alert>\n {ownership && orgId ? (\n claim ? (\n <AiSiteOwnershipProof orgId={orgId} user={user} claim={claim} onClaim={setClaim} />\n ) : (\n <Box>\n <Button variant=\"outlined\" onClick={() => void verifyAgain()}>\n {'Verify again'}\n </Button>\n {claimNotice ? <Alert severity=\"warning\" sx={{ mt: 1 }}>{claimNotice}</Alert> : null}\n </Box>\n )\n ) : null}\n <Stack direction={{ xs: 'column', sm: 'row' }} spacing={2} sx={{ alignItems: { sm: 'center' } }}>\n <Button variant=\"contained\" disabled={busy || (ownership && !claim?.current)} onClick={onResume}>\n {busy ? 'Starting…' : phase === 'paused' ? 'Resume' : start ? `${start.label} again` : 'Read the site again'}\n </Button>\n {phase === 'paused' && orgSlug ? (\n <Button variant=\"outlined\" component={AppLink} href={aiCreditsBillingHref(orgSlug)}>\n {'Get more AI credits'}\n </Button>\n ) : null}\n </Stack>\n {waves}\n {cancel}\n </Frame>\n )\n }\n\n if (phase === 'done' && state) {\n const brought = (job.items ?? []).filter((row) => row.op === 'page' && (row.status === 'succeeded' || row.status === 'degraded')).length\n return (\n <Frame\n siteName={siteName}\n heading=\"Your site is in\"\n lede={`${brought} ${brought === 1 ? 'page was' : 'pages were'} brought in from ${state.domain}. They are drafts: review them, then publish them when you are ready.`}\n >\n {pagesHref ? (\n <Box>\n <Button variant=\"contained\" size=\"large\" component={AppLink} href={pagesHref}>\n {'Open your draft pages'}\n </Button>\n </Box>\n ) : null}\n {state.waves.map((wave) => (\n <Card key={wave.index} variant=\"outlined\" sx={{ borderRadius: 2 }}>\n <Typography variant=\"subtitle1\" sx={{ px: { xs: 2, sm: 3 }, pt: { xs: 2, sm: 3 } }}>\n {wave.label}\n </Typography>\n <WaveRows job={job} wave={wave} orgSlug={orgSlug} />\n </Card>\n ))}\n {leftOutCard}\n </Frame>\n )\n }\n\n return (\n <Frame siteName={siteName} heading={job.status === 'canceled' ? 'Your site import was stopped' : 'Your site import stopped'}>\n <Alert severity=\"info\">\n {job.error ??\n (job.status === 'canceled'\n ? 'Nothing more is brought in. The pages already in stay as drafts.'\n : 'It could not go on. The pages already in stay as drafts.')}\n </Alert>\n {pagesHref ? (\n <Box>\n <Button variant=\"outlined\" component={AppLink} href={pagesHref}>\n {'Open your draft pages'}\n </Button>\n </Box>\n ) : null}\n </Frame>\n )\n}\n\nexport default AiSiteImportJob\n"],"names":["PageHeaderRecord","buildRoute","Route","mdiAlertCircle","mdiCheckCircle","mdiChevronDown","mdiClockOutline","mdiMinusCircleOutline","AppLink","HelpTip","MdiIcon","Accordion","AccordionDetails","AccordionSummary","Alert","Box","Button","Card","CircularProgress","Container","LinearProgress","Stack","Typography","useCallback","useState","aiSiteImportReviewWave","aiSiteImportRunningWave","aiSiteImportFoundText","aiSiteImportLeftOutLines","aiSiteImportPhaseOf","aiSiteImportPlanText","aiSiteImportStartAction","aiSiteImportWaveRows","aiSiteImportWaveSpent","AiJobCancelButton","aiCreditsBillingHref","aiJobOutputHref","AI_SITE_IMPORT_HELP","AiSiteOwnershipProof","postAiSiteOwnership","ROW_ICON","done","path","color","label","waiting","failed","skipped","RowIcon","state","size","aria-label","icon","component","role","sx","display","fontSize","theme","spacing","aria-hidden","WaveRows","job","wave","orgSlug","rows","listStyle","m","p","xs","sm","map","row","output","outputId","outputs","find","entry","id","undefined","href","direction","alignItems","width","justifyContent","flex","minWidth","variant","title","overflowWrap","from","to","photos","note","slot","Frame","siteName","heading","lede","children","maxWidth","py","px","AiSiteImportJob","orgId","host","user","busy","notice","onResume","onJob","phase","siteImport","start","pagesHref","HOST_SCREENS","claim","setClaim","claimNotice","setClaimNotice","verifyAgain","answer","action","domain","message","cancel","startButton","disabled","onClick","quote","waves","ariaLabel","disableGutters","borderRadius","expandIcon","length","pl","slots","frame","status","index","leftOut","leftOutCard","reduce","total","line","count","text","paths","slice","join","reason","mt","review","severity","pt","filter","value","Math","round","spent","toLocaleString","ownership","error","onClaim","current","brought","items","op"],"mappings":"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"}
@@ -0,0 +1,64 @@
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 { ConsolePendingSite } from '@aglyn/aglyn/plugin-manager/feature-plugins';
18
+ import { type MaybeTokenSource } from '@aglyn/shared-util-http/authorized-token';
19
+ /** Each part of the flow links its own section of the Bring my site guide. */
20
+ export declare const AI_SITE_IMPORT_HELP: {
21
+ address: {
22
+ title: string;
23
+ excerpt: import("react").ReactNode;
24
+ excerptText: string;
25
+ href: string;
26
+ };
27
+ prove: {
28
+ title: string;
29
+ excerpt: import("react").ReactNode;
30
+ excerptText: string;
31
+ href: string;
32
+ };
33
+ waves: {
34
+ title: string;
35
+ excerpt: import("react").ReactNode;
36
+ excerptText: string;
37
+ href: string;
38
+ };
39
+ };
40
+ export interface AiSiteImportStartProps {
41
+ orgId: string;
42
+ orgSlug: string | null;
43
+ hostId: string | null;
44
+ host: string | null;
45
+ user: MaybeTokenSource;
46
+ /** The site being created by "Create site", when it does not exist yet (AGL-3761). */
47
+ pendingSite?: ConsolePendingSite;
48
+ /** Back to how the site starts. */
49
+ onBack: () => void;
50
+ /** The dialog closes before the job's page opens. */
51
+ leave?: () => void;
52
+ }
53
+ /**
54
+ * "Bring my site" (AGL-3976): the address of the site the person has now,
55
+ * the proof that it is theirs, and what happens next — then the site is read
56
+ * and its waves planned, nothing built, on the import job's own page.
57
+ *
58
+ * Nothing is created until "Read my site": the site in Create site is made
59
+ * then, empty, and the import job is started on it. The job reads the site
60
+ * and waits for the person to start its first wave, so even this costs no
61
+ * AI credits.
62
+ */
63
+ export declare function AiSiteImportStart({ orgId, orgSlug, hostId, host, user, pendingSite, onBack, leave }: AiSiteImportStartProps): import("react").JSX.Element;
64
+ export default AiSiteImportStart;
@@ -0,0 +1,335 @@
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
+ */ 'use client';
17
+ import { _ as _extends } from "@swc/helpers/_/_extends";
18
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
19
+ import { lockdownRefusalText, parseLockdownRefusal, PLATFORM_BRAND_NAME } from "@aglyn/aglyn";
20
+ import { pluginDocsHelp } from "@aglyn/aglyn/app-utils/docs-help";
21
+ import { mdiWebSync } from "@aglyn/shared-data-mdi";
22
+ import { HelpTip, MdiIcon } from "@aglyn/shared-ui-jsx";
23
+ import { authorizedFetch } from "@aglyn/shared-util-http/authorized-token";
24
+ import { Alert, Box, Button, Stack, TextField, Typography } from "@mui/material";
25
+ import { useRouter } from "next/navigation";
26
+ import { useCallback, useRef, useState } from "react";
27
+ import { AI_SITE_IMPORT_DOMAIN_INPUT, AI_SITE_IMPORT_KIND, AI_SITE_IMPORT_WAVE_PAGES } from "../model/ai-site-import.js";
28
+ import { aiSiteBuildHref } from "./ai-job-links.js";
29
+ import { publishAiJob } from "./ai-jobs-store.js";
30
+ import { AiSiteOwnershipProof, postAiSiteOwnership } from "./ai-site-ownership-proof.component.js";
31
+ /** Each part of the flow links its own section of the Bring my site guide. */ export const AI_SITE_IMPORT_HELP = {
32
+ address: pluginDocsHelp('aiImport', {
33
+ anchor: '#your-current-website',
34
+ excerpt: 'The address people type to reach your site today. You prove it is yours next, so only a site you own can be brought in.'
35
+ }),
36
+ prove: pluginDocsHelp('aiImport', {
37
+ anchor: '#prove-it-is-yours',
38
+ excerpt: 'Add a DNS record, add a tag to your home page, or get a code at an address at your domain. Any one is enough.'
39
+ }),
40
+ waves: pluginDocsHelp('aiImport', {
41
+ anchor: '#waves',
42
+ excerpt: 'Your main pages come in first, then each collection, such as blog posts, ten pages at a time. You review each wave and start the next yourself.'
43
+ })
44
+ };
45
+ /**
46
+ * "Bring my site" (AGL-3976): the address of the site the person has now,
47
+ * the proof that it is theirs, and what happens next — then the site is read
48
+ * and its waves planned, nothing built, on the import job's own page.
49
+ *
50
+ * Nothing is created until "Read my site": the site in Create site is made
51
+ * then, empty, and the import job is started on it. The job reads the site
52
+ * and waits for the person to start its first wave, so even this costs no
53
+ * AI credits.
54
+ */ export function AiSiteImportStart({ orgId, orgSlug, hostId, host, user, pendingSite, onBack, leave }) {
55
+ const router = useRouter();
56
+ const userRef = useRef(user);
57
+ userRef.current = user;
58
+ const [step, setStep] = useState('address');
59
+ const [address, setAddress] = useState('');
60
+ const [claim, setClaim] = useState(null);
61
+ const [notice, setNotice] = useState(null);
62
+ const [busy, setBusy] = useState(false);
63
+ // A site already verified skips the proof step, and Back skips it too.
64
+ const [proved, setProved] = useState(false);
65
+ const claimIt = useCallback(async ()=>{
66
+ setBusy(true);
67
+ setNotice(null);
68
+ const answer = await postAiSiteOwnership(userRef.current, {
69
+ orgId,
70
+ action: 'claim',
71
+ domain: address
72
+ });
73
+ setBusy(false);
74
+ if (!answer.claim) {
75
+ var _answer_message;
76
+ setNotice((_answer_message = answer.message) != null ? _answer_message : 'That address could not be used.');
77
+ return;
78
+ }
79
+ setClaim(answer.claim);
80
+ setProved(!answer.claim.current);
81
+ setStep(answer.claim.current ? 'read' : 'prove');
82
+ }, [
83
+ orgId,
84
+ address
85
+ ]);
86
+ const read = useCallback(async ()=>{
87
+ if (!(claim == null ? void 0 : claim.current)) return;
88
+ setBusy(true);
89
+ setNotice(null);
90
+ try {
91
+ var _ref;
92
+ const requestJob = (siteId, check)=>authorizedFetch(userRef.current, '/api/ai/jobs', {
93
+ method: 'POST',
94
+ headers: {
95
+ 'Content-Type': 'application/json'
96
+ },
97
+ body: JSON.stringify(_extends({
98
+ orgId,
99
+ hostId: siteId,
100
+ kind: AI_SITE_IMPORT_KIND,
101
+ brief: `Bring in ${claim.domain}`,
102
+ inputs: {
103
+ [AI_SITE_IMPORT_DOMAIN_INPUT]: claim.domain
104
+ }
105
+ }, check ? {
106
+ check: true
107
+ } : {}))
108
+ });
109
+ const refused = async (response)=>{
110
+ var _ref;
111
+ const payload = await response.json().catch(()=>null);
112
+ if (response.ok) return payload != null ? payload : {};
113
+ const locked = parseLockdownRefusal(response.status, payload);
114
+ setNotice(locked ? lockdownRefusalText(locked) : String((_ref = payload == null ? void 0 : payload['error']) != null ? _ref : 'Your site could not be read. Try again.'));
115
+ return null;
116
+ };
117
+ let site = {
118
+ hostId,
119
+ host,
120
+ orgSlug
121
+ };
122
+ if (!hostId && pendingSite) {
123
+ // Asked before the site exists, so a refusal creates nothing (AGL-3859).
124
+ if (!pendingSite.created && !await refused(await requestJob(null, true))) return;
125
+ const made = await pendingSite.create();
126
+ if ('error' in made) {
127
+ setNotice(made.error);
128
+ if (made.address) onBack();
129
+ return;
130
+ }
131
+ site = {
132
+ hostId: made.hostId,
133
+ host: made.host,
134
+ orgSlug: made.orgSlug || orgSlug
135
+ };
136
+ }
137
+ if (!site.hostId) return;
138
+ const payload = await refused(await requestJob(site.hostId, false));
139
+ const job = (_ref = payload == null ? void 0 : payload['job']) != null ? _ref : null;
140
+ if (!job) {
141
+ if (payload) setNotice('Your site could not be read. Try again.');
142
+ return;
143
+ }
144
+ publishAiJob(job);
145
+ const href = aiSiteBuildHref(site.orgSlug, site.host, job.id);
146
+ if (href) {
147
+ leave == null ? void 0 : leave();
148
+ router.push(href);
149
+ }
150
+ } catch (unused) {
151
+ setNotice('Your site could not be read. Try again.');
152
+ } finally{
153
+ setBusy(false);
154
+ }
155
+ }, [
156
+ claim,
157
+ orgId,
158
+ hostId,
159
+ host,
160
+ orgSlug,
161
+ pendingSite,
162
+ onBack,
163
+ leave,
164
+ router
165
+ ]);
166
+ const back = ()=>{
167
+ setNotice(null);
168
+ if (step === 'address') onBack();
169
+ else if (step === 'prove') setStep('address');
170
+ else setStep(proved ? 'prove' : 'address');
171
+ };
172
+ return /*#__PURE__*/ _jsxs(Stack, {
173
+ spacing: 3,
174
+ component: "section",
175
+ "aria-label": "Bring my site",
176
+ "data-start-area": "import",
177
+ children: [
178
+ notice && /*#__PURE__*/ _jsx(Alert, {
179
+ severity: "info",
180
+ children: notice
181
+ }),
182
+ step === 'address' && /*#__PURE__*/ _jsxs(Stack, {
183
+ spacing: 2,
184
+ children: [
185
+ /*#__PURE__*/ _jsxs(Stack, {
186
+ direction: "row",
187
+ spacing: 0.5,
188
+ sx: {
189
+ alignItems: 'center'
190
+ },
191
+ children: [
192
+ /*#__PURE__*/ _jsx(Typography, {
193
+ variant: "subtitle1",
194
+ component: "h2",
195
+ children: 'Your current website'
196
+ }),
197
+ /*#__PURE__*/ _jsx(HelpTip, _extends({}, AI_SITE_IMPORT_HELP.address))
198
+ ]
199
+ }),
200
+ /*#__PURE__*/ _jsx(TextField, {
201
+ label: "Website address",
202
+ placeholder: "example.com",
203
+ value: address,
204
+ autoFocus: true,
205
+ onChange: (event)=>setAddress(event.target.value),
206
+ onKeyDown: (event)=>{
207
+ if (event.key === 'Enter' && address.trim() && !busy) {
208
+ event.preventDefault();
209
+ void claimIt();
210
+ }
211
+ },
212
+ helperText: "The address people type to reach your site today. You prove it is yours next."
213
+ })
214
+ ]
215
+ }),
216
+ step === 'prove' && claim && /*#__PURE__*/ _jsxs(Stack, {
217
+ spacing: 2,
218
+ children: [
219
+ /*#__PURE__*/ _jsxs(Stack, {
220
+ direction: "row",
221
+ spacing: 0.5,
222
+ sx: {
223
+ alignItems: 'center'
224
+ },
225
+ children: [
226
+ /*#__PURE__*/ _jsx(Typography, {
227
+ variant: "subtitle1",
228
+ component: "h2",
229
+ children: 'Prove it is yours'
230
+ }),
231
+ /*#__PURE__*/ _jsx(HelpTip, _extends({}, AI_SITE_IMPORT_HELP.prove))
232
+ ]
233
+ }),
234
+ /*#__PURE__*/ _jsx(AiSiteOwnershipProof, {
235
+ orgId: orgId,
236
+ user: user,
237
+ claim: claim,
238
+ onClaim: setClaim
239
+ })
240
+ ]
241
+ }),
242
+ step === 'read' && claim && /*#__PURE__*/ _jsxs(Stack, {
243
+ spacing: 2,
244
+ children: [
245
+ /*#__PURE__*/ _jsxs(Stack, {
246
+ direction: "row",
247
+ spacing: 0.5,
248
+ sx: {
249
+ alignItems: 'center'
250
+ },
251
+ children: [
252
+ /*#__PURE__*/ _jsx(Typography, {
253
+ variant: "subtitle1",
254
+ component: "h2",
255
+ children: `Bring in ${claim.domain}`
256
+ }),
257
+ /*#__PURE__*/ _jsx(HelpTip, _extends({}, AI_SITE_IMPORT_HELP.waves))
258
+ ]
259
+ }),
260
+ /*#__PURE__*/ _jsxs(Box, {
261
+ component: "ul",
262
+ sx: {
263
+ m: 0,
264
+ pl: 3,
265
+ '& li': {
266
+ mb: 1
267
+ }
268
+ },
269
+ children: [
270
+ /*#__PURE__*/ _jsx(Typography, {
271
+ component: "li",
272
+ variant: "body2",
273
+ children: `AglynBot reads your site, as many pages as your plan includes: your main pages first, then collections such as blog posts.`
274
+ }),
275
+ /*#__PURE__*/ _jsx(Typography, {
276
+ component: "li",
277
+ variant: "body2",
278
+ children: `You see what was found and what each wave of up to ${AI_SITE_IMPORT_WAVE_PAGES} pages costs before anything is built. Reading your site uses no AI credits.`
279
+ }),
280
+ /*#__PURE__*/ _jsx(Typography, {
281
+ component: "li",
282
+ variant: "body2",
283
+ children: `${PLATFORM_BRAND_NAME} AI rewrites each page into your new site’s design, with its words, facts and photos. You review each wave and start the next yourself.`
284
+ }),
285
+ /*#__PURE__*/ _jsx(Typography, {
286
+ component: "li",
287
+ variant: "body2",
288
+ children: 'Every page is a draft. Nothing is published until you publish it, and your current site is not changed.'
289
+ })
290
+ ]
291
+ })
292
+ ]
293
+ }),
294
+ /*#__PURE__*/ _jsxs(Stack, {
295
+ direction: "row",
296
+ spacing: 1,
297
+ sx: {
298
+ justifyContent: 'space-between'
299
+ },
300
+ children: [
301
+ /*#__PURE__*/ _jsx(Button, {
302
+ onClick: back,
303
+ disabled: busy,
304
+ children: 'Back'
305
+ }),
306
+ step === 'address' && /*#__PURE__*/ _jsx(Button, {
307
+ variant: "contained",
308
+ disabled: busy || !address.trim(),
309
+ onClick: ()=>void claimIt(),
310
+ children: busy ? 'Checking…' : 'Next'
311
+ }),
312
+ step === 'prove' && /*#__PURE__*/ _jsx(Button, {
313
+ variant: "contained",
314
+ disabled: !(claim == null ? void 0 : claim.current),
315
+ onClick: ()=>setStep('read'),
316
+ children: 'Next'
317
+ }),
318
+ step === 'read' && /*#__PURE__*/ _jsx(Button, {
319
+ variant: "contained",
320
+ size: "large",
321
+ disabled: busy || !(claim == null ? void 0 : claim.current),
322
+ onClick: ()=>void read(),
323
+ startIcon: /*#__PURE__*/ _jsx(MdiIcon, {
324
+ path: mdiWebSync.path
325
+ }),
326
+ children: busy ? 'Starting…' : 'Read my site'
327
+ })
328
+ ]
329
+ })
330
+ ]
331
+ });
332
+ }
333
+ export default AiSiteImportStart;
334
+
335
+ //# sourceMappingURL=ai-site-import-start.component.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../../../../libs/plugins/ai/src/lib/components/ai-site-import-start.component.tsx"],"sourcesContent":["/**\n * @license\n * Copyright 2026 Aglyn LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n'use client'\n\nimport { lockdownRefusalText, parseLockdownRefusal, PLATFORM_BRAND_NAME } from '@aglyn/aglyn'\nimport type { ConsolePendingSite } from '@aglyn/aglyn/plugin-manager/feature-plugins'\nimport { pluginDocsHelp } from '@aglyn/aglyn/app-utils/docs-help'\nimport { mdiWebSync } from '@aglyn/shared-data-mdi'\nimport { HelpTip, MdiIcon } from '@aglyn/shared-ui-jsx'\nimport { authorizedFetch, type MaybeTokenSource } from '@aglyn/shared-util-http/authorized-token'\nimport { Alert, Box, Button, Stack, TextField, Typography } from '@mui/material'\nimport { useRouter } from 'next/navigation'\nimport { useCallback, useRef, useState } from 'react'\nimport type { AiJobSummary } from '../model/ai-jobs.types'\nimport { AI_SITE_IMPORT_DOMAIN_INPUT, AI_SITE_IMPORT_KIND, AI_SITE_IMPORT_WAVE_PAGES } from '../model/ai-site-import'\nimport type { AiSiteImportClaim } from '../model/ai-site-import-view'\nimport { aiSiteBuildHref } from './ai-job-links'\nimport { publishAiJob } from './ai-jobs-store'\nimport { AiSiteOwnershipProof, postAiSiteOwnership } from './ai-site-ownership-proof.component'\n\n/** Each part of the flow links its own section of the Bring my site guide. */\nexport const AI_SITE_IMPORT_HELP = {\n address: pluginDocsHelp('aiImport', {\n anchor: '#your-current-website',\n excerpt: 'The address people type to reach your site today. You prove it is yours next, so only a site you own can be brought in.',\n }),\n prove: pluginDocsHelp('aiImport', {\n anchor: '#prove-it-is-yours',\n excerpt: 'Add a DNS record, add a tag to your home page, or get a code at an address at your domain. Any one is enough.',\n }),\n waves: pluginDocsHelp('aiImport', {\n anchor: '#waves',\n excerpt: 'Your main pages come in first, then each collection, such as blog posts, ten pages at a time. You review each wave and start the next yourself.',\n }),\n}\n\ntype Step = 'address' | 'prove' | 'read'\n\nexport interface AiSiteImportStartProps {\n orgId: string\n orgSlug: string | null\n hostId: string | null\n host: string | null\n user: MaybeTokenSource\n /** The site being created by \"Create site\", when it does not exist yet (AGL-3761). */\n pendingSite?: ConsolePendingSite\n /** Back to how the site starts. */\n onBack: () => void\n /** The dialog closes before the job's page opens. */\n leave?: () => void\n}\n\n/**\n * \"Bring my site\" (AGL-3976): the address of the site the person has now,\n * the proof that it is theirs, and what happens next — then the site is read\n * and its waves planned, nothing built, on the import job's own page.\n *\n * Nothing is created until \"Read my site\": the site in Create site is made\n * then, empty, and the import job is started on it. The job reads the site\n * and waits for the person to start its first wave, so even this costs no\n * AI credits.\n */\nexport function AiSiteImportStart({ orgId, orgSlug, hostId, host, user, pendingSite, onBack, leave }: AiSiteImportStartProps) {\n const router = useRouter()\n const userRef = useRef(user)\n userRef.current = user\n const [step, setStep] = useState<Step>('address')\n const [address, setAddress] = useState('')\n const [claim, setClaim] = useState<AiSiteImportClaim | null>(null)\n const [notice, setNotice] = useState<string | null>(null)\n const [busy, setBusy] = useState(false)\n // A site already verified skips the proof step, and Back skips it too.\n const [proved, setProved] = useState(false)\n\n const claimIt = useCallback(async () => {\n setBusy(true)\n setNotice(null)\n const answer = await postAiSiteOwnership(userRef.current, { orgId, action: 'claim', domain: address })\n setBusy(false)\n if (!answer.claim) {\n setNotice(answer.message ?? 'That address could not be used.')\n return\n }\n setClaim(answer.claim)\n setProved(!answer.claim.current)\n setStep(answer.claim.current ? 'read' : 'prove')\n }, [orgId, address])\n\n const read = useCallback(async () => {\n if (!claim?.current) return\n setBusy(true)\n setNotice(null)\n try {\n const requestJob = (siteId: string | null, check: boolean) =>\n authorizedFetch(userRef.current, '/api/ai/jobs', {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n orgId,\n hostId: siteId,\n kind: AI_SITE_IMPORT_KIND,\n brief: `Bring in ${claim.domain}`,\n inputs: { [AI_SITE_IMPORT_DOMAIN_INPUT]: claim.domain },\n ...(check ? { check: true } : {}),\n }),\n })\n const refused = async (response: Response): Promise<Record<string, unknown> | null> => {\n const payload = (await response.json().catch(() => null)) as Record<string, unknown> | null\n if (response.ok) return payload ?? {}\n const locked = parseLockdownRefusal(response.status, payload)\n setNotice(locked ? lockdownRefusalText(locked) : String(payload?.['error'] ?? 'Your site could not be read. Try again.'))\n return null\n }\n let site = { hostId, host, orgSlug }\n if (!hostId && pendingSite) {\n // Asked before the site exists, so a refusal creates nothing (AGL-3859).\n if (!pendingSite.created && !(await refused(await requestJob(null, true)))) return\n const made = await pendingSite.create()\n if ('error' in made) {\n setNotice(made.error)\n if (made.address) onBack()\n return\n }\n site = { hostId: made.hostId, host: made.host, orgSlug: made.orgSlug || orgSlug }\n }\n if (!site.hostId) return\n const payload = await refused(await requestJob(site.hostId, false))\n const job = (payload?.['job'] as AiJobSummary | undefined) ?? null\n if (!job) {\n if (payload) setNotice('Your site could not be read. Try again.')\n return\n }\n publishAiJob(job)\n const href = aiSiteBuildHref(site.orgSlug, site.host, job.id)\n if (href) {\n leave?.()\n router.push(href)\n }\n } catch {\n setNotice('Your site could not be read. Try again.')\n } finally {\n setBusy(false)\n }\n }, [claim, orgId, hostId, host, orgSlug, pendingSite, onBack, leave, router])\n\n const back = () => {\n setNotice(null)\n if (step === 'address') onBack()\n else if (step === 'prove') setStep('address')\n else setStep(proved ? 'prove' : 'address')\n }\n\n return (\n <Stack spacing={3} component=\"section\" aria-label=\"Bring my site\" data-start-area=\"import\">\n {notice && <Alert severity=\"info\">{notice}</Alert>}\n {step === 'address' && (\n <Stack spacing={2}>\n <Stack direction=\"row\" spacing={0.5} sx={{ alignItems: 'center' }}>\n <Typography variant=\"subtitle1\" component=\"h2\">\n {'Your current website'}\n </Typography>\n <HelpTip {...AI_SITE_IMPORT_HELP.address} />\n </Stack>\n <TextField\n label=\"Website address\"\n placeholder=\"example.com\"\n value={address}\n autoFocus\n onChange={(event) => setAddress(event.target.value)}\n onKeyDown={(event) => {\n if (event.key === 'Enter' && address.trim() && !busy) {\n event.preventDefault()\n void claimIt()\n }\n }}\n helperText=\"The address people type to reach your site today. You prove it is yours next.\"\n />\n </Stack>\n )}\n {step === 'prove' && claim && (\n <Stack spacing={2}>\n <Stack direction=\"row\" spacing={0.5} sx={{ alignItems: 'center' }}>\n <Typography variant=\"subtitle1\" component=\"h2\">\n {'Prove it is yours'}\n </Typography>\n <HelpTip {...AI_SITE_IMPORT_HELP.prove} />\n </Stack>\n <AiSiteOwnershipProof orgId={orgId} user={user} claim={claim} onClaim={setClaim} />\n </Stack>\n )}\n {step === 'read' && claim && (\n <Stack spacing={2}>\n <Stack direction=\"row\" spacing={0.5} sx={{ alignItems: 'center' }}>\n <Typography variant=\"subtitle1\" component=\"h2\">\n {`Bring in ${claim.domain}`}\n </Typography>\n <HelpTip {...AI_SITE_IMPORT_HELP.waves} />\n </Stack>\n <Box component=\"ul\" sx={{ m: 0, pl: 3, '& li': { mb: 1 } }}>\n <Typography component=\"li\" variant=\"body2\">\n {`AglynBot reads your site, as many pages as your plan includes: your main pages first, then collections such as blog posts.`}\n </Typography>\n <Typography component=\"li\" variant=\"body2\">\n {`You see what was found and what each wave of up to ${AI_SITE_IMPORT_WAVE_PAGES} pages costs before anything is built. Reading your site uses no AI credits.`}\n </Typography>\n <Typography component=\"li\" variant=\"body2\">\n {`${PLATFORM_BRAND_NAME} AI rewrites each page into your new site’s design, with its words, facts and photos. You review each wave and start the next yourself.`}\n </Typography>\n <Typography component=\"li\" variant=\"body2\">\n {'Every page is a draft. Nothing is published until you publish it, and your current site is not changed.'}\n </Typography>\n </Box>\n </Stack>\n )}\n <Stack direction=\"row\" spacing={1} sx={{ justifyContent: 'space-between' }}>\n <Button onClick={back} disabled={busy}>\n {'Back'}\n </Button>\n {step === 'address' && (\n <Button variant=\"contained\" disabled={busy || !address.trim()} onClick={() => void claimIt()}>\n {busy ? 'Checking…' : 'Next'}\n </Button>\n )}\n {step === 'prove' && (\n <Button variant=\"contained\" disabled={!claim?.current} onClick={() => setStep('read')}>\n {'Next'}\n </Button>\n )}\n {step === 'read' && (\n <Button\n variant=\"contained\"\n size=\"large\"\n disabled={busy || !claim?.current}\n onClick={() => void read()}\n startIcon={<MdiIcon path={mdiWebSync.path} />}\n >\n {busy ? 'Starting…' : 'Read my site'}\n </Button>\n )}\n </Stack>\n </Stack>\n )\n}\n\nexport default AiSiteImportStart\n"],"names":["lockdownRefusalText","parseLockdownRefusal","PLATFORM_BRAND_NAME","pluginDocsHelp","mdiWebSync","HelpTip","MdiIcon","authorizedFetch","Alert","Box","Button","Stack","TextField","Typography","useRouter","useCallback","useRef","useState","AI_SITE_IMPORT_DOMAIN_INPUT","AI_SITE_IMPORT_KIND","AI_SITE_IMPORT_WAVE_PAGES","aiSiteBuildHref","publishAiJob","AiSiteOwnershipProof","postAiSiteOwnership","AI_SITE_IMPORT_HELP","address","anchor","excerpt","prove","waves","AiSiteImportStart","orgId","orgSlug","hostId","host","user","pendingSite","onBack","leave","router","userRef","current","step","setStep","setAddress","claim","setClaim","notice","setNotice","busy","setBusy","proved","setProved","claimIt","answer","action","domain","message","read","requestJob","siteId","check","method","headers","body","JSON","stringify","kind","brief","inputs","refused","response","payload","json","catch","ok","locked","status","String","site","created","made","create","error","job","href","id","push","back","spacing","component","aria-label","data-start-area","severity","direction","sx","alignItems","variant","label","placeholder","value","autoFocus","onChange","event","target","onKeyDown","key","trim","preventDefault","helperText","onClaim","m","pl","mb","justifyContent","onClick","disabled","size","startIcon","path"],"mappings":"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"}
@@ -0,0 +1,42 @@
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 MaybeTokenSource } from '@aglyn/shared-util-http/authorized-token';
18
+ import type { AiSiteImportClaim } from '../model/ai-site-import-view';
19
+ /** The ownership door, as the console calls it (AGL-3974). */
20
+ export declare const AI_SITE_IMPORT_OWNERSHIP_PATH = "/api/ai/site-import/ownership";
21
+ /** One answer of the ownership door: the claim it left, and the sentence for the person. */
22
+ export interface AiSiteOwnershipAnswer {
23
+ claim: AiSiteImportClaim | null;
24
+ message: string | null;
25
+ ok: boolean;
26
+ }
27
+ /** Posts one action to the ownership door. Never throws. */
28
+ export declare function postAiSiteOwnership(user: MaybeTokenSource, body: Record<string, unknown>): Promise<AiSiteOwnershipAnswer>;
29
+ export interface AiSiteOwnershipProofProps {
30
+ orgId: string;
31
+ user: MaybeTokenSource;
32
+ claim: AiSiteImportClaim;
33
+ onClaim: (claim: AiSiteImportClaim) => void;
34
+ }
35
+ /**
36
+ * Proving the site is yours (AGL-3974, AGL-3976): any ONE of three ways, each
37
+ * a card with what to do where and a button that checks it now. The status
38
+ * at the top says whether the site is verified, by which way and when, or
39
+ * that it is not yet. Nothing is read from the site until it is.
40
+ */
41
+ export declare function AiSiteOwnershipProof({ orgId, user, claim, onClaim }: AiSiteOwnershipProofProps): import("react").JSX.Element;
42
+ export default AiSiteOwnershipProof;