@aglyn/plugins-ai 1.0.0-beta.226 → 1.0.0-beta.227

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 (156) hide show
  1. package/README.md +2 -1
  2. package/package.json +17 -17
  3. package/src/lib/billing/ai-month-meter.js +5 -3
  4. package/src/lib/billing/ai-month-meter.js.map +1 -1
  5. package/src/lib/billing/ai-overage-ledger.js +3 -1
  6. package/src/lib/billing/ai-overage-ledger.js.map +1 -1
  7. package/src/lib/components/ai-brief-dialog.component.d.ts +6 -2
  8. package/src/lib/components/ai-brief-dialog.component.js +35 -17
  9. package/src/lib/components/ai-brief-dialog.component.js.map +1 -1
  10. package/src/lib/components/ai-describe-automation.component.js +17 -2
  11. package/src/lib/components/ai-describe-automation.component.js.map +1 -1
  12. package/src/lib/components/ai-insight-dialog.component.js +24 -2
  13. package/src/lib/components/ai-insight-dialog.component.js.map +1 -1
  14. package/src/lib/components/ai-job-events.d.ts +14 -0
  15. package/src/lib/components/ai-job-events.js +76 -0
  16. package/src/lib/components/ai-job-events.js.map +1 -0
  17. package/src/lib/components/ai-job-follow.component.d.ts +49 -0
  18. package/src/lib/components/ai-job-follow.component.js +210 -0
  19. package/src/lib/components/ai-job-follow.component.js.map +1 -0
  20. package/src/lib/components/ai-job-links.d.ts +42 -0
  21. package/src/lib/components/ai-job-links.js +140 -0
  22. package/src/lib/components/ai-job-links.js.map +1 -0
  23. package/src/lib/components/ai-job-plan.component.d.ts +13 -6
  24. package/src/lib/components/ai-job-plan.component.js +29 -3
  25. package/src/lib/components/ai-job-plan.component.js.map +1 -1
  26. package/src/lib/components/ai-job-requests.d.ts +24 -0
  27. package/src/lib/components/ai-job-requests.js +76 -0
  28. package/src/lib/components/ai-job-requests.js.map +1 -0
  29. package/src/lib/components/ai-jobs-indicator.component.d.ts +25 -0
  30. package/src/lib/components/ai-jobs-indicator.component.js +80 -0
  31. package/src/lib/components/ai-jobs-indicator.component.js.map +1 -0
  32. package/src/lib/components/ai-jobs-store.d.ts +81 -0
  33. package/src/lib/components/ai-jobs-store.js +218 -0
  34. package/src/lib/components/ai-jobs-store.js.map +1 -0
  35. package/src/lib/components/ai-page-brief-dialog.component.d.ts +3 -3
  36. package/src/lib/components/ai-page-brief-dialog.component.js.map +1 -1
  37. package/src/lib/components/ai-site-build-page.component.d.ts +23 -0
  38. package/src/lib/components/ai-site-build-page.component.js +377 -0
  39. package/src/lib/components/ai-site-build-page.component.js.map +1 -0
  40. package/src/lib/components/ai-site-start-card.component.d.ts +1 -1
  41. package/src/lib/components/ai-site-start-card.component.js +522 -130
  42. package/src/lib/components/ai-site-start-card.component.js.map +1 -1
  43. package/src/lib/components/ai-site-starter-fallback.component.d.ts +24 -0
  44. package/src/lib/components/ai-site-starter-fallback.component.js +112 -0
  45. package/src/lib/components/ai-site-starter-fallback.component.js.map +1 -0
  46. package/src/lib/components/assist-jobs-drawer.component.d.ts +18 -20
  47. package/src/lib/components/assist-jobs-drawer.component.js +152 -172
  48. package/src/lib/components/assist-jobs-drawer.component.js.map +1 -1
  49. package/src/lib/components/assist-panel.component.js +62 -6
  50. package/src/lib/components/assist-panel.component.js.map +1 -1
  51. package/src/lib/components/staff-ai-credit-return.component.d.ts +55 -0
  52. package/src/lib/components/staff-ai-credit-return.component.js +346 -0
  53. package/src/lib/components/staff-ai-credit-return.component.js.map +1 -0
  54. package/src/lib/components/staff-org-ai-card.component.js +364 -279
  55. package/src/lib/components/staff-org-ai-card.component.js.map +1 -1
  56. package/src/lib/components/staff-user-ai-usage-card.component.d.ts +4 -0
  57. package/src/lib/components/staff-user-ai-usage-card.component.js +83 -28
  58. package/src/lib/components/staff-user-ai-usage-card.component.js.map +1 -1
  59. package/src/lib/components/use-ai-job-run.js +5 -18
  60. package/src/lib/components/use-ai-job-run.js.map +1 -1
  61. package/src/lib/jobs/ai-job-auto-confirm.d.ts +52 -0
  62. package/src/lib/jobs/ai-job-auto-confirm.js +62 -0
  63. package/src/lib/jobs/ai-job-auto-confirm.js.map +1 -0
  64. package/src/lib/jobs/ai-job-plan-step.d.ts +33 -2
  65. package/src/lib/jobs/ai-job-plan-step.js +161 -17
  66. package/src/lib/jobs/ai-job-plan-step.js.map +1 -1
  67. package/src/lib/jobs/ai-job-site-step.d.ts +7 -0
  68. package/src/lib/jobs/ai-job-site-step.js +34 -4
  69. package/src/lib/jobs/ai-job-site-step.js.map +1 -1
  70. package/src/lib/jobs/ai-job-text-step.d.ts +7 -0
  71. package/src/lib/jobs/ai-job-text-step.js.map +1 -1
  72. package/src/lib/jobs/ai-jobs-notify.d.ts +37 -0
  73. package/src/lib/jobs/ai-jobs-notify.js +51 -0
  74. package/src/lib/jobs/ai-jobs-notify.js.map +1 -0
  75. package/src/lib/jobs/ai-jobs.d.ts +31 -4
  76. package/src/lib/jobs/ai-jobs.js +196 -32
  77. package/src/lib/jobs/ai-jobs.js.map +1 -1
  78. package/src/lib/model/ai-job-activity.d.ts +112 -0
  79. package/src/lib/model/ai-job-activity.js +144 -0
  80. package/src/lib/model/ai-job-activity.js.map +1 -0
  81. package/src/lib/model/ai-job-failure-copy.d.ts +69 -0
  82. package/src/lib/model/ai-job-failure-copy.js +78 -0
  83. package/src/lib/model/ai-job-failure-copy.js.map +1 -0
  84. package/src/lib/model/ai-job-notice.d.ts +61 -0
  85. package/src/lib/model/ai-job-notice.js +112 -0
  86. package/src/lib/model/ai-job-notice.js.map +1 -0
  87. package/src/lib/model/ai-jobs.types.d.ts +26 -0
  88. package/src/lib/model/ai-jobs.types.js +1 -0
  89. package/src/lib/model/ai-jobs.types.js.map +1 -1
  90. package/src/lib/model/ai-plan-capabilities.d.ts +7 -0
  91. package/src/lib/model/ai-plan-capabilities.js.map +1 -1
  92. package/src/lib/model/ai-site-build-progress.d.ts +45 -0
  93. package/src/lib/model/ai-site-build-progress.js +76 -0
  94. package/src/lib/model/ai-site-build-progress.js.map +1 -0
  95. package/src/lib/model/ai-site-inventory.d.ts +9 -0
  96. package/src/lib/model/ai-site-inventory.js +7 -2
  97. package/src/lib/model/ai-site-inventory.js.map +1 -1
  98. package/src/lib/model/ai-site-job.d.ts +93 -2
  99. package/src/lib/model/ai-site-job.js +88 -7
  100. package/src/lib/model/ai-site-job.js.map +1 -1
  101. package/src/lib/model/ai-site-start.d.ts +3 -1
  102. package/src/lib/model/ai-site-start.js +6 -4
  103. package/src/lib/model/ai-site-start.js.map +1 -1
  104. package/src/lib/plan-entitlements.d.ts +3 -3
  105. package/src/lib/plan-entitlements.js +3 -3
  106. package/src/lib/plan-entitlements.js.map +1 -1
  107. package/src/lib/plugin.js +28 -0
  108. package/src/lib/plugin.js.map +1 -1
  109. package/src/lib/runtime/ai-abuse-guards.d.ts +9 -6
  110. package/src/lib/runtime/ai-abuse-guards.js +10 -7
  111. package/src/lib/runtime/ai-abuse-guards.js.map +1 -1
  112. package/src/lib/runtime/ai-doctrine-validators.js +31 -4
  113. package/src/lib/runtime/ai-doctrine-validators.js.map +1 -1
  114. package/src/lib/runtime/ai-gate.d.ts +3 -2
  115. package/src/lib/runtime/ai-gate.js +3 -2
  116. package/src/lib/runtime/ai-gate.js.map +1 -1
  117. package/src/lib/runtime/site-inventory.d.ts +16 -1
  118. package/src/lib/runtime/site-inventory.js +43 -3
  119. package/src/lib/runtime/site-inventory.js.map +1 -1
  120. package/src/lib/server/ai-admin-credits.d.ts +21 -0
  121. package/src/lib/server/ai-admin-credits.js +213 -0
  122. package/src/lib/server/ai-admin-credits.js.map +1 -0
  123. package/src/lib/server/ai-admin-org.js +12 -5
  124. package/src/lib/server/ai-admin-org.js.map +1 -1
  125. package/src/lib/server/ai-admin-signals.js +3 -1
  126. package/src/lib/server/ai-admin-signals.js.map +1 -1
  127. package/src/lib/server/ai-admin-user.js +12 -1
  128. package/src/lib/server/ai-admin-user.js.map +1 -1
  129. package/src/lib/server/ai-allotments.js +3 -2
  130. package/src/lib/server/ai-allotments.js.map +1 -1
  131. package/src/lib/server/ai-jobs-route.js +20 -2
  132. package/src/lib/server/ai-jobs-route.js.map +1 -1
  133. package/src/lib/server/assist-chat.js +3 -2
  134. package/src/lib/server/assist-chat.js.map +1 -1
  135. package/src/lib/server/billing-credits.js +4 -3
  136. package/src/lib/server/billing-credits.js.map +1 -1
  137. package/src/lib/server/billing-overage.js +3 -2
  138. package/src/lib/server/billing-overage.js.map +1 -1
  139. package/src/lib/server.js +11 -0
  140. package/src/lib/server.js.map +1 -1
  141. package/src/lib/usage/assist-credit-returns-write.d.ts +75 -0
  142. package/src/lib/usage/assist-credit-returns-write.js +150 -0
  143. package/src/lib/usage/assist-credit-returns-write.js.map +1 -0
  144. package/src/lib/usage/assist-credit-returns.d.ts +68 -0
  145. package/src/lib/usage/assist-credit-returns.js +79 -0
  146. package/src/lib/usage/assist-credit-returns.js.map +1 -0
  147. package/src/lib/usage/assist-free-taste.js +6 -3
  148. package/src/lib/usage/assist-free-taste.js.map +1 -1
  149. package/src/lib/usage/assist-job-refund.d.ts +100 -0
  150. package/src/lib/usage/assist-job-refund.js +109 -0
  151. package/src/lib/usage/assist-job-refund.js.map +1 -0
  152. package/src/lib/usage/assist-usage.js +5 -2
  153. package/src/lib/usage/assist-usage.js.map +1 -1
  154. package/src/lib/usage/staff-org-ai.d.ts +31 -1
  155. package/src/lib/usage/staff-org-ai.js +19 -2
  156. package/src/lib/usage/staff-org-ai.js.map +1 -1
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../../../../libs/plugins/ai/src/lib/components/ai-jobs-store.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'use client'\n\nimport {\n authorizedFetch,\n type MaybeTokenSource,\n type TokenSource,\n} from '@aglyn/shared-util-http/authorized-token'\nimport { useEffect, useMemo, useRef, useSyncExternalStore } from 'react'\nimport { aiJobsActivity, type AiJobsActivity } from '../model/ai-job-activity'\nimport { AI_JOB_TERMINAL_STATUSES, type AiJobSummary } from '../model/ai-jobs.types'\n\n/**\n * WHERE A PERSON FINDS THEIR AI JOBS (AGL-3593).\n *\n * Two things every AI surface in the console shares, kept in this module\n * rather than in any one component because the surfaces that need them — a\n * brief dialog on the Screens page, the guided start's full-screen dialog,\n * the top-bar indicator, the Assist launcher and the drawer inside the\n * panel — are mounted in different zones and know nothing of one another.\n * All of them are this plugin's, so no shell, zone or event bus carries it.\n *\n * ── Opening AI jobs ──────────────────────────────────────────────────────\n *\n * {@link openAiJobs} is the one action every \"Open AI jobs\" button, the\n * indicator and a notification's link take: the Assist panel subscribes, opens\n * itself, expands its AI jobs drawer, and scrolls to and highlights the job\n * named. A request is a sequence number as well as a job, so asking twice for\n * the same job opens it twice.\n *\n * ── The workspace's unsettled jobs ───────────────────────────────────────\n *\n * The indicator, the launcher's badge and the drawer's open-by-default rule\n * read the same list: the workspace's jobs that are not yet settled, from\n * the jobs route's `status=active` (a Firestore `in` query under the\n * (status, createdAt) index, never a filter of a loaded window). ONE list per\n * person and workspace however many surfaces read it, re-read on a timer only\n * while something in it is still moving or waiting and the tab is in view —\n * a workspace with nothing running costs one read per page load and no more.\n *\n * Every surface that learns a job's state some other way — the dialog that\n * created it, the drawer's event stream, the in-dialog confirm — hands it in\n * through {@link publishAiJob}, so the indicator moves the moment the job\n * does rather than on the next read.\n */\n\n// ── Opening AI jobs ───────────────────────────────────────────────────────\n\n/** The latest request to open AI jobs; `seq` is 0 until anything asked. */\nexport interface AiJobsOpenRequest {\n seq: number\n /** The job to scroll to and highlight, or `null` for the drawer alone. */\n jobId: string | null\n}\n\nlet openRequest: AiJobsOpenRequest = { seq: 0, jobId: null }\nconst openListeners = new Set<() => void>()\n\n/**\n * Opens the Assist panel on its AI jobs drawer, expanded, scrolled to\n * `jobId` when one is named. A surface that covers the panel — a dialog —\n * closes itself beside the call; this opens, it does not close anything.\n */\nexport function openAiJobs(options: { jobId?: string | null } = {}): void {\n openRequest = { seq: openRequest.seq + 1, jobId: options.jobId ?? null }\n for (const listener of openListeners) listener()\n}\n\nfunction subscribeOpen(listener: () => void): () => void {\n openListeners.add(listener)\n return () => {\n openListeners.delete(listener)\n }\n}\n\nconst readOpen = (): AiJobsOpenRequest => openRequest\n\n/** The latest open request, for the panel; a new `seq` is a new request. */\nexport function useAiJobsOpenRequest(): AiJobsOpenRequest {\n return useSyncExternalStore(subscribeOpen, readOpen, readOpen)\n}\n\n/**\n * The query parameter a notification's link carries: a console page opened\n * with `?aiJob={id}` opens AI jobs on that job, the way pressing the\n * indicator does.\n */\nexport { AI_JOB_LINK_PARAM } from '../model/ai-job-notice'\n\n// ── The workspace's unsettled jobs ────────────────────────────────────────\n\n/** How often a list with something in it is read again, while the tab is in view. */\nexport const AI_JOBS_ACTIVE_POLL_MS = 15_000\n\n/** The most unsettled jobs one read lists; a glance, not an archive. */\nconst ACTIVE_LIMIT = 20\n\nconst NONE: readonly AiJobSummary[] = Object.freeze([])\n\ninterface Entry {\n jobs: readonly AiJobSummary[]\n /** Who reads it, kept current by whichever surface subscribed last. */\n user: MaybeTokenSource\n orgId: string\n subscribers: number\n inflight: boolean\n timer: ReturnType<typeof setTimeout> | null\n /** The route said the feature is not this workspace's: nothing is read again. */\n closed: boolean\n listeners: Set<() => void>\n}\n\nconst entries = new Map<string, Entry>()\n\nconst keyOf = (uid: string, orgId: string): string => `${uid}\\n${orgId}`\n\nfunction emit(entry: Entry): void {\n for (const listener of entry.listeners) listener()\n}\n\nfunction isSettled(job: AiJobSummary): boolean {\n return AI_JOB_TERMINAL_STATUSES.includes(job.status)\n}\n\nfunction schedule(entry: Entry): void {\n if (entry.timer) clearTimeout(entry.timer)\n entry.timer = null\n if (entry.closed || entry.subscribers === 0 || entry.jobs.length === 0) return\n entry.timer = setTimeout(() => {\n entry.timer = null\n const hidden = typeof document !== 'undefined' && document.visibilityState === 'hidden'\n // A hidden tab reads nothing; coming back into view reads at once.\n if (hidden) return\n void read(entry)\n }, AI_JOBS_ACTIVE_POLL_MS)\n}\n\nasync function read(entry: Entry): Promise<void> {\n if (entry.inflight || entry.closed) return\n entry.inflight = true\n try {\n const response = await authorizedFetch(\n entry.user,\n `/api/ai/jobs?orgId=${encodeURIComponent(entry.orgId)}&status=active&limit=${ACTIVE_LIMIT}`,\n )\n if (response.status === 404 || response.status === 403) {\n // The release flag off, or a plan or member without generation: there\n // is nothing to count, now or on the next tick.\n entry.closed = true\n entry.jobs = NONE\n emit(entry)\n return\n }\n if (!response.ok) return\n const payload = (await response.json().catch(() => null)) as { jobs?: AiJobSummary[] } | null\n entry.jobs = Object.freeze((payload?.jobs ?? []).filter((job) => !isSettled(job)))\n emit(entry)\n } catch {\n // An unreachable route keeps what was last read; the next tick asks again.\n } finally {\n entry.inflight = false\n schedule(entry)\n }\n}\n\nfunction entryFor(uid: string, orgId: string, user: MaybeTokenSource): Entry {\n const key = keyOf(uid, orgId)\n let entry = entries.get(key)\n if (!entry) {\n entry = {\n jobs: NONE,\n user,\n orgId,\n subscribers: 0,\n inflight: false,\n timer: null,\n closed: false,\n listeners: new Set(),\n }\n entries.set(key, entry)\n }\n return entry\n}\n\n/**\n * Hands a job's latest state to every surface counting this workspace's jobs:\n * a new job joins the list, a settled one leaves it. Keyed on the job's own\n * workspace, for every person whose list holds that workspace in this tab.\n */\nexport function publishAiJob(job: AiJobSummary | null | undefined): void {\n if (!job?.orgId) return\n for (const entry of entries.values()) {\n if (entry.orgId !== job.orgId || entry.closed) continue\n const index = entry.jobs.findIndex((known) => known.id === job.id)\n let next: AiJobSummary[]\n if (isSettled(job)) {\n if (index === -1) continue\n next = entry.jobs.filter((known) => known.id !== job.id)\n } else if (index === -1) {\n next = [job, ...entry.jobs]\n } else {\n next = [...entry.jobs]\n next[index] = job\n }\n entry.jobs = Object.freeze(next)\n emit(entry)\n // A list that just gained its first job starts its timer.\n if (!entry.timer && !entry.inflight) schedule(entry)\n }\n}\n\n/** Forget every list and request; specs start each case from nothing. */\nexport function resetAiJobsStoreForTests(): void {\n for (const entry of entries.values()) {\n if (entry.timer) clearTimeout(entry.timer)\n }\n entries.clear()\n openListeners.clear()\n openRequest = { seq: 0, jobId: null }\n}\n\n/**\n * The workspace's jobs that are not yet settled, newest first, for the\n * signed-in person — empty while the first read is in flight, where the\n * route refuses, and when `enabled` is false (a surface whose own gates have\n * not passed reads nothing at all).\n */\nexport function useAiJobsInFlight(\n user: (TokenSource & { uid?: string | null }) | null | undefined,\n orgId: string | null | undefined,\n enabled = true,\n): readonly AiJobSummary[] {\n const uid = user?.uid ?? null\n const userRef = useRef<MaybeTokenSource>(user)\n userRef.current = user\n const entry = useMemo(\n () => (enabled && uid && orgId ? entryFor(uid, orgId, userRef.current) : null),\n [enabled, uid, orgId],\n )\n\n useEffect(() => {\n if (!entry) return undefined\n entry.user = userRef.current\n entry.subscribers += 1\n if (entry.subscribers === 1) void read(entry)\n const onVisible = () => {\n if (document.visibilityState === 'visible' && entry.jobs.length > 0) void read(entry)\n }\n document.addEventListener('visibilitychange', onVisible)\n return () => {\n document.removeEventListener('visibilitychange', onVisible)\n entry.subscribers -= 1\n if (entry.subscribers === 0 && entry.timer) {\n clearTimeout(entry.timer)\n entry.timer = null\n }\n }\n }, [entry])\n\n const subscribe = useMemo(\n () => (listener: () => void) => {\n if (!entry) return () => undefined\n entry.listeners.add(listener)\n return () => {\n entry.listeners.delete(listener)\n }\n },\n [entry],\n )\n const snapshot = (): readonly AiJobSummary[] => entry?.jobs ?? NONE\n return useSyncExternalStore(subscribe, snapshot, snapshot)\n}\n\n/** What the indicator and the launcher show for the workspace, or `null` for nothing. */\nexport function useAiJobsActivity(\n user: (TokenSource & { uid?: string | null }) | null | undefined,\n orgId: string | null | undefined,\n enabled = true,\n): AiJobsActivity<AiJobSummary> | null {\n const jobs = useAiJobsInFlight(user, orgId, enabled)\n return useMemo(() => aiJobsActivity(jobs), [jobs])\n}\n"],"names":["authorizedFetch","useEffect","useMemo","useRef","useSyncExternalStore","aiJobsActivity","AI_JOB_TERMINAL_STATUSES","openRequest","seq","jobId","openListeners","Set","openAiJobs","options","listener","subscribeOpen","add","delete","readOpen","useAiJobsOpenRequest","AI_JOB_LINK_PARAM","AI_JOBS_ACTIVE_POLL_MS","ACTIVE_LIMIT","NONE","Object","freeze","entries","Map","keyOf","uid","orgId","emit","entry","listeners","isSettled","job","includes","status","schedule","timer","clearTimeout","closed","subscribers","jobs","length","setTimeout","hidden","document","visibilityState","read","inflight","response","user","encodeURIComponent","ok","payload","json","catch","filter","entryFor","key","get","set","publishAiJob","values","index","findIndex","known","id","next","resetAiJobsStoreForTests","clear","useAiJobsInFlight","enabled","userRef","current","undefined","onVisible","addEventListener","removeEventListener","subscribe","snapshot","useAiJobsActivity"],"mappings":"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"}
@@ -20,9 +20,9 @@ import { type AiBriefDialogProps } from './ai-brief-dialog.component';
20
20
  * the Screens page's "Describe it" and the Assist panel's AI jobs.
21
21
  *
22
22
  * It is the shared brief dialog for a `page` job (AGL-3043): one text box and
23
- * an optional page type. The job plans first and waits in AI jobs, where the
24
- * member confirms the plan and opens the draft once it is built; nothing here
25
- * builds or writes anything.
23
+ * an optional page type. The job plans first; the dialog then follows it and
24
+ * offers its plan to confirm, as AI jobs does (AGL-3593). Nothing is built
25
+ * until the member confirms.
26
26
  */
27
27
  export type AiPageBriefDialogProps = Omit<AiBriefDialogProps, 'kind'>;
28
28
  export declare function AiPageBriefDialog(props: AiPageBriefDialogProps): import("react").JSX.Element;
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../../../../libs/plugins/ai/src/lib/components/ai-page-brief-dialog.component.tsx"],"sourcesContent":["'use client'\n\n/**\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 { AiBriefDialog, type AiBriefDialogProps } from './ai-brief-dialog.component'\n\n/**\n * \"Describe a page\" (AGL-2907): the brief dialog both page entry points open,\n * the Screens page's \"Describe it\" and the Assist panel's AI jobs.\n *\n * It is the shared brief dialog for a `page` job (AGL-3043): one text box and\n * an optional page type. The job plans first and waits in AI jobs, where the\n * member confirms the plan and opens the draft once it is built; nothing here\n * builds or writes anything.\n */\n\nexport type AiPageBriefDialogProps = Omit<AiBriefDialogProps, 'kind'>\n\nexport function AiPageBriefDialog(props: AiPageBriefDialogProps) {\n return <AiBriefDialog {...props} kind=\"page\" />\n}\n\nexport default AiPageBriefDialog\n"],"names":["AiBriefDialog","AiPageBriefDialog","props","kind"],"mappings":"AAAA;;;AAEA;;;;;;;;;;;;;;;CAeC,GAED,SAASA,aAAa,QAAiC,iCAA6B;AAcpF,OAAO,SAASC,kBAAkBC,KAA6B;IAC7D,qBAAO,KAACF,4BAAkBE;QAAOC,MAAK;;AACxC;AAEA,eAAeF,kBAAiB"}
1
+ {"version":3,"sources":["../../../../../../../libs/plugins/ai/src/lib/components/ai-page-brief-dialog.component.tsx"],"sourcesContent":["'use client'\n\n/**\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 { AiBriefDialog, type AiBriefDialogProps } from './ai-brief-dialog.component'\n\n/**\n * \"Describe a page\" (AGL-2907): the brief dialog both page entry points open,\n * the Screens page's \"Describe it\" and the Assist panel's AI jobs.\n *\n * It is the shared brief dialog for a `page` job (AGL-3043): one text box and\n * an optional page type. The job plans first; the dialog then follows it and\n * offers its plan to confirm, as AI jobs does (AGL-3593). Nothing is built\n * until the member confirms.\n */\n\nexport type AiPageBriefDialogProps = Omit<AiBriefDialogProps, 'kind'>\n\nexport function AiPageBriefDialog(props: AiPageBriefDialogProps) {\n return <AiBriefDialog {...props} kind=\"page\" />\n}\n\nexport default AiPageBriefDialog\n"],"names":["AiBriefDialog","AiPageBriefDialog","props","kind"],"mappings":"AAAA;;;AAEA;;;;;;;;;;;;;;;CAeC,GAED,SAASA,aAAa,QAAiC,iCAA6B;AAcpF,OAAO,SAASC,kBAAkBC,KAA6B;IAC7D,qBAAO,KAACF,4BAAkBE;QAAOC,MAAK;;AACxC;AAEA,eAAeF,kBAAiB"}
@@ -0,0 +1,23 @@
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 { ConsolePluginPageProps } from '@aglyn/aglyn/plugin-manager/feature-plugins';
18
+ import type { MaybeTokenSource } from '@aglyn/shared-util-http/authorized-token';
19
+ import type { AiJobSummary } from '../model/ai-jobs.types';
20
+ /** Follows one job by id: its latest summary, `null` while the first state is out, `'missing'` when the route had none. */
21
+ export declare function useAiJobById(user: MaybeTokenSource, orgId: string | null, jobId: string | null): [AiJobSummary | 'missing' | null, (job: AiJobSummary) => void];
22
+ export declare function AiSiteBuildPage({ hostId, segments, basePath }: ConsolePluginPageProps): import("react").JSX.Element;
23
+ export default AiSiteBuildPage;
@@ -0,0 +1,377 @@
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 { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
18
+ import { PLATFORM_BRAND_NAME } from "@aglyn/aglyn";
19
+ import { mdiAlertCircle, mdiCheckCircle, mdiChevronDown, mdiClockOutline } from "@aglyn/shared-data-mdi";
20
+ import { AppLink, MdiIcon } from "@aglyn/shared-ui-jsx";
21
+ import { useFirestore, useUser } from "@aglyn/tenant-feature-instance";
22
+ import { Accordion, AccordionDetails, AccordionSummary, Alert, Box, Button, Card, CircularProgress, Container, LinearProgress, Stack, Typography } from "@mui/material";
23
+ import { doc, getDoc } from "firebase/firestore";
24
+ import { useCallback, useEffect, useRef, useState } from "react";
25
+ import { aiSiteBuildCreditsLine, aiSiteBuildPhase, aiSiteBuildRows } from "../model/ai-site-build-progress.js";
26
+ import { aiSiteStarterFallbackOffered } from "../model/ai-job-failure-copy.js";
27
+ import { followAiJobEvents } from "./ai-job-events.js";
28
+ import { aiSiteBuildDoneLinks } from "./ai-job-links.js";
29
+ import { resumeAiJobRequest } from "./ai-job-requests.js";
30
+ import { AiSiteStarterFallback } from "./ai-site-starter-fallback.component.js";
31
+ /** Follows one job by id: its latest summary, `null` while the first state is out, `'missing'` when the route had none. */ export function useAiJobById(user, orgId, jobId) {
32
+ const userRef = useRef(user);
33
+ userRef.current = user;
34
+ const [job, setJob] = useState(null);
35
+ const status = job && job !== 'missing' ? job.status : null;
36
+ const moving = status === null || status === 'queued' || status === 'running';
37
+ useEffect(()=>{
38
+ if (!orgId || !jobId || !moving) return undefined;
39
+ const controller = new AbortController();
40
+ let heard = false;
41
+ void followAiJobEvents(()=>userRef.current, orgId, jobId, controller.signal, (next)=>{
42
+ heard = true;
43
+ setJob(next);
44
+ }).then(()=>{
45
+ if (!heard && !controller.signal.aborted) setJob((current)=>current != null ? current : 'missing');
46
+ });
47
+ return ()=>controller.abort();
48
+ }, [
49
+ orgId,
50
+ jobId,
51
+ moving
52
+ ]);
53
+ return [
54
+ job,
55
+ setJob
56
+ ];
57
+ }
58
+ const ROW_ICON = {
59
+ done: {
60
+ path: mdiCheckCircle.path,
61
+ color: 'success.main',
62
+ label: 'Done'
63
+ },
64
+ waiting: {
65
+ path: mdiClockOutline.path,
66
+ color: 'text.disabled',
67
+ label: 'Waiting'
68
+ },
69
+ failed: {
70
+ path: mdiAlertCircle.path,
71
+ color: 'error.main',
72
+ label: 'Stopped'
73
+ }
74
+ };
75
+ function RowIcon({ state }) {
76
+ if (state === 'active') {
77
+ return /*#__PURE__*/ _jsx(CircularProgress, {
78
+ size: 20,
79
+ "aria-label": "In progress"
80
+ });
81
+ }
82
+ const icon = ROW_ICON[state];
83
+ return /*#__PURE__*/ _jsx(Box, {
84
+ component: "span",
85
+ role: "img",
86
+ "aria-label": icon.label,
87
+ sx: {
88
+ color: icon.color,
89
+ display: 'inline-flex',
90
+ fontSize: (theme)=>theme.spacing(2.5)
91
+ },
92
+ children: /*#__PURE__*/ _jsx(MdiIcon, {
93
+ path: icon.path,
94
+ "aria-hidden": true
95
+ })
96
+ });
97
+ }
98
+ export function AiSiteBuildPage({ hostId, segments, basePath }) {
99
+ var _split_, _ref, _ref1;
100
+ var _ready_review, _ready_review1, _ready_review2;
101
+ const firestore = useFirestore();
102
+ const { data: user } = useUser();
103
+ const jobId = (segments == null ? void 0 : segments[0]) ? decodeURIComponent(String(segments[0])) : null;
104
+ const orgSlug = (_split_ = (basePath != null ? basePath : '').split('/')[1]) != null ? _split_ : '';
105
+ const [site, setSite] = useState(null);
106
+ useEffect(()=>{
107
+ if (!hostId) return;
108
+ let active = true;
109
+ void getDoc(doc(firestore, 'hosts', hostId)).then((snapshot)=>{
110
+ var _snapshot_data, _data_orgId, _data_displayName;
111
+ if (!active) return;
112
+ const data = (_snapshot_data = snapshot.data()) != null ? _snapshot_data : {};
113
+ setSite({
114
+ orgId: String((_data_orgId = data.orgId) != null ? _data_orgId : ''),
115
+ name: String((_data_displayName = data.displayName) != null ? _data_displayName : '')
116
+ });
117
+ }).catch(()=>{
118
+ if (active) setSite({
119
+ orgId: '',
120
+ name: ''
121
+ });
122
+ });
123
+ return ()=>{
124
+ active = false;
125
+ };
126
+ }, [
127
+ firestore,
128
+ hostId
129
+ ]);
130
+ const [job, setJob] = useAiJobById(user, (site == null ? void 0 : site.orgId) || null, jobId);
131
+ const [busy, setBusy] = useState(false);
132
+ const [notice, setNotice] = useState(null);
133
+ const tryAgain = useCallback(async ()=>{
134
+ if (!(site == null ? void 0 : site.orgId) || !job || job === 'missing') return;
135
+ setBusy(true);
136
+ setNotice(null);
137
+ const decision = await resumeAiJobRequest(user, site.orgId, job);
138
+ if (decision.job) setJob(decision.job);
139
+ if (decision.error) setNotice(decision.error);
140
+ setBusy(false);
141
+ }, [
142
+ site,
143
+ job,
144
+ user,
145
+ setJob
146
+ ]);
147
+ const ready = job && job !== 'missing' ? job : null;
148
+ const phase = ready ? aiSiteBuildPhase(ready) : 'working';
149
+ const heading = phase === 'done' ? 'Your site is ready' : phase === 'working' ? 'Building your site' : 'Your site was not built';
150
+ const lede = phase === 'done' ? 'Your new pages are drafts. Publish them when you’re happy.' : phase === 'working' ? `${PLATFORM_BRAND_NAME} AI is planning your pages and writing each one. You can leave this page; it keeps going.` : phase === 'canceled' ? 'The job was canceled.' : (_ref = (_ref1 = ready == null ? void 0 : (_ready_review = ready.review) == null ? void 0 : _ready_review.message) != null ? _ref1 : ready == null ? void 0 : ready.error) != null ? _ref : 'Something went wrong building your site.';
151
+ const rows = ready ? aiSiteBuildRows(ready) : [];
152
+ const credits = ready ? aiSiteBuildCreditsLine(ready) : null;
153
+ const links = ready && phase === 'done' ? aiSiteBuildDoneLinks(ready, orgSlug) : {
154
+ view: null,
155
+ pages: null
156
+ };
157
+ const retryRefusal = ready == null ? void 0 : (_ready_review1 = ready.review) == null ? void 0 : _ready_review1.retryRefusal;
158
+ const canRetry = phase === 'stopped' && (ready == null ? void 0 : (_ready_review2 = ready.review) == null ? void 0 : _ready_review2.reason) === 'doctrine';
159
+ return /*#__PURE__*/ _jsx(Container, {
160
+ maxWidth: "sm",
161
+ sx: {
162
+ py: {
163
+ xs: 3,
164
+ sm: 5
165
+ },
166
+ px: {
167
+ xs: 2,
168
+ sm: 3
169
+ }
170
+ },
171
+ children: /*#__PURE__*/ _jsxs(Stack, {
172
+ spacing: 4,
173
+ children: [
174
+ /*#__PURE__*/ _jsxs(Stack, {
175
+ spacing: 1,
176
+ children: [
177
+ (site == null ? void 0 : site.name) ? /*#__PURE__*/ _jsx(Typography, {
178
+ variant: "overline",
179
+ color: "text.secondary",
180
+ children: site.name
181
+ }) : null,
182
+ /*#__PURE__*/ _jsx(Typography, {
183
+ variant: "h4",
184
+ component: "h1",
185
+ children: heading
186
+ }),
187
+ /*#__PURE__*/ _jsx(Typography, {
188
+ variant: "body1",
189
+ color: "text.secondary",
190
+ children: lede
191
+ })
192
+ ]
193
+ }),
194
+ job === 'missing' ? /*#__PURE__*/ _jsx(Alert, {
195
+ severity: "info",
196
+ children: 'This job could not be found. It may belong to another workspace.'
197
+ }) : !ready ? /*#__PURE__*/ _jsx(Stack, {
198
+ sx: {
199
+ alignItems: 'center',
200
+ py: 4
201
+ },
202
+ children: /*#__PURE__*/ _jsx(CircularProgress, {
203
+ "aria-label": "Loading the job"
204
+ })
205
+ }) : /*#__PURE__*/ _jsxs(_Fragment, {
206
+ children: [
207
+ notice && /*#__PURE__*/ _jsx(Alert, {
208
+ severity: "warning",
209
+ children: notice
210
+ }),
211
+ /*#__PURE__*/ _jsxs(Card, {
212
+ variant: "outlined",
213
+ sx: {
214
+ borderRadius: 2
215
+ },
216
+ children: [
217
+ phase === 'working' && /*#__PURE__*/ _jsx(LinearProgress, {
218
+ "aria-label": "Building"
219
+ }),
220
+ /*#__PURE__*/ _jsx(Box, {
221
+ component: "ol",
222
+ "aria-label": "Progress",
223
+ sx: {
224
+ listStyle: 'none',
225
+ m: 0,
226
+ p: {
227
+ xs: 2,
228
+ sm: 3
229
+ }
230
+ },
231
+ children: /*#__PURE__*/ _jsx(Stack, {
232
+ spacing: 2,
233
+ children: rows.map((row)=>/*#__PURE__*/ _jsxs(Stack, {
234
+ component: "li",
235
+ direction: "row",
236
+ spacing: 2,
237
+ sx: {
238
+ alignItems: 'center'
239
+ },
240
+ children: [
241
+ /*#__PURE__*/ _jsx(Box, {
242
+ sx: {
243
+ width: (theme)=>theme.spacing(3),
244
+ display: 'flex',
245
+ justifyContent: 'center'
246
+ },
247
+ children: /*#__PURE__*/ _jsx(RowIcon, {
248
+ state: row.state
249
+ })
250
+ }),
251
+ /*#__PURE__*/ _jsx(Typography, {
252
+ variant: "body1",
253
+ color: row.state === 'waiting' ? 'text.secondary' : 'text.primary',
254
+ children: row.label
255
+ })
256
+ ]
257
+ }, row.id))
258
+ })
259
+ })
260
+ ]
261
+ }),
262
+ credits && /*#__PURE__*/ _jsx(Typography, {
263
+ variant: "body2",
264
+ color: "text.secondary",
265
+ children: credits
266
+ }),
267
+ phase === 'done' && /*#__PURE__*/ _jsxs(Stack, {
268
+ direction: {
269
+ xs: 'column',
270
+ sm: 'row'
271
+ },
272
+ spacing: 2,
273
+ children: [
274
+ links.view && /*#__PURE__*/ _jsx(Button, {
275
+ variant: "contained",
276
+ size: "large",
277
+ component: AppLink,
278
+ href: links.view,
279
+ children: 'View your site'
280
+ }),
281
+ links.pages && /*#__PURE__*/ _jsx(Button, {
282
+ variant: "outlined",
283
+ size: "large",
284
+ component: AppLink,
285
+ href: links.pages,
286
+ children: 'Edit your pages'
287
+ })
288
+ ]
289
+ }),
290
+ (phase === 'stopped' || phase === 'failed' || phase === 'canceled') && /*#__PURE__*/ _jsxs(Stack, {
291
+ spacing: 1,
292
+ children: [
293
+ retryRefusal && /*#__PURE__*/ _jsx(Typography, {
294
+ variant: "body2",
295
+ color: "text.secondary",
296
+ children: retryRefusal
297
+ }),
298
+ /*#__PURE__*/ _jsxs(Stack, {
299
+ direction: {
300
+ xs: 'column',
301
+ sm: 'row'
302
+ },
303
+ spacing: 2,
304
+ sx: {
305
+ alignItems: {
306
+ sm: 'center'
307
+ }
308
+ },
309
+ children: [
310
+ canRetry && /*#__PURE__*/ _jsx(Button, {
311
+ variant: "contained",
312
+ disabled: busy || Boolean(retryRefusal),
313
+ onClick: ()=>void tryAgain(),
314
+ children: 'Try again'
315
+ }),
316
+ aiSiteStarterFallbackOffered(ready) && user ? /*#__PURE__*/ _jsx(AiSiteStarterFallback, {
317
+ job: ready,
318
+ user: user
319
+ }) : null
320
+ ]
321
+ })
322
+ ]
323
+ }),
324
+ ready.plan && ready.plan.screens.length > 0 && /*#__PURE__*/ _jsxs(Accordion, {
325
+ variant: "outlined",
326
+ disableGutters: true,
327
+ sx: {
328
+ borderRadius: 2,
329
+ '&::before': {
330
+ display: 'none'
331
+ }
332
+ },
333
+ children: [
334
+ /*#__PURE__*/ _jsx(AccordionSummary, {
335
+ expandIcon: /*#__PURE__*/ _jsx(MdiIcon, {
336
+ path: mdiChevronDown.path
337
+ }),
338
+ children: /*#__PURE__*/ _jsx(Typography, {
339
+ variant: "subtitle1",
340
+ children: 'What we’re building'
341
+ })
342
+ }),
343
+ /*#__PURE__*/ _jsx(AccordionDetails, {
344
+ children: /*#__PURE__*/ _jsx(Stack, {
345
+ component: "ul",
346
+ spacing: 1.5,
347
+ sx: {
348
+ m: 0,
349
+ pl: 2.5
350
+ },
351
+ children: ready.plan.screens.map((screen, index)=>/*#__PURE__*/ _jsxs(Box, {
352
+ component: "li",
353
+ children: [
354
+ /*#__PURE__*/ _jsx(Typography, {
355
+ variant: "body1",
356
+ children: `${screen.title} — ${screen.slug}`
357
+ }),
358
+ screen.sections.length > 0 && /*#__PURE__*/ _jsx(Typography, {
359
+ variant: "body2",
360
+ color: "text.secondary",
361
+ children: screen.sections.map((section)=>section.name).join(', ')
362
+ })
363
+ ]
364
+ }, `${screen.slug}-${index}`))
365
+ })
366
+ })
367
+ ]
368
+ })
369
+ ]
370
+ })
371
+ ]
372
+ })
373
+ });
374
+ }
375
+ export default AiSiteBuildPage;
376
+
377
+ //# sourceMappingURL=ai-site-build-page.component.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../../../../libs/plugins/ai/src/lib/components/ai-site-build-page.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 { PLATFORM_BRAND_NAME } from '@aglyn/aglyn'\nimport type { ConsolePluginPageProps } from '@aglyn/aglyn/plugin-manager/feature-plugins'\nimport {\n mdiAlertCircle,\n mdiCheckCircle,\n mdiChevronDown,\n mdiClockOutline,\n} from '@aglyn/shared-data-mdi'\nimport { AppLink, MdiIcon } from '@aglyn/shared-ui-jsx'\nimport type { MaybeTokenSource } from '@aglyn/shared-util-http/authorized-token'\nimport { useFirestore, useUser } from '@aglyn/tenant-feature-instance'\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 { doc, getDoc } from 'firebase/firestore'\nimport { useCallback, useEffect, useRef, useState } from 'react'\nimport {\n aiSiteBuildCreditsLine,\n aiSiteBuildPhase,\n aiSiteBuildRows,\n type AiSiteBuildRowState,\n} from '../model/ai-site-build-progress'\nimport { aiSiteStarterFallbackOffered } from '../model/ai-job-failure-copy'\nimport type { AiJobSummary } from '../model/ai-jobs.types'\nimport { followAiJobEvents } from './ai-job-events'\nimport { aiSiteBuildDoneLinks } from './ai-job-links'\nimport { resumeAiJobRequest } from './ai-job-requests'\nimport { AiSiteStarterFallback } from './ai-site-starter-fallback.component'\n\n/**\n * \"Building your site\" (AGL-3594): where the guided start sends a person the\n * moment they plan a site, and where a notification about that job opens.\n *\n * A guided site start confirms its own plan (`autoConfirm`), so there is no\n * approval to make here: the page says what is happening, step by step, live\n * from the job's events route; shows what is being built; and, when the job\n * ends, leads with the next thing to do — the site to look at and the pages\n * to edit, or, where it stopped, the plain sentence for why and what to do\n * about it. It is linkable and survives a reload, because it reads the job by\n * the id in its own address under the site's own route.\n *\n * Mounted by the shell's generic plugin route as an unlisted page: no tab on\n * the site's strip, an address under it.\n */\n\n/** The site's name, subdomain and org, read off the site document the reader may already read. */\ninterface SiteFacts {\n orgId: string\n name: string\n}\n\n/** Follows one job by id: its latest summary, `null` while the first state is out, `'missing'` when the route had none. */\nexport function useAiJobById(\n user: MaybeTokenSource,\n orgId: string | null,\n jobId: string | null,\n): [AiJobSummary | 'missing' | null, (job: AiJobSummary) => void] {\n const userRef = useRef(user)\n userRef.current = user\n const [job, setJob] = useState<AiJobSummary | 'missing' | null>(null)\n const status = job && job !== 'missing' ? job.status : null\n const moving = status === null || status === 'queued' || status === 'running'\n useEffect(() => {\n if (!orgId || !jobId || !moving) return undefined\n const controller = new AbortController()\n let heard = false\n void followAiJobEvents(() => userRef.current, orgId, jobId, controller.signal, (next) => {\n heard = true\n setJob(next)\n }).then(() => {\n if (!heard && !controller.signal.aborted) setJob((current) => current ?? 'missing')\n })\n return () => controller.abort()\n }, [orgId, jobId, moving])\n return [job, setJob]\n}\n\nconst ROW_ICON: Readonly<Record<Exclude<AiSiteBuildRowState, 'active'>, { path: string; color: string; label: string }>> = {\n done: { path: mdiCheckCircle.path, color: 'success.main', label: 'Done' },\n waiting: { path: mdiClockOutline.path, color: 'text.disabled', label: 'Waiting' },\n failed: { path: mdiAlertCircle.path, color: 'error.main', label: 'Stopped' },\n}\n\nfunction RowIcon({ state }: { state: AiSiteBuildRowState }) {\n if (state === 'active') {\n return <CircularProgress size={20} aria-label=\"In progress\" />\n }\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\nexport function AiSiteBuildPage({ hostId, segments, basePath }: ConsolePluginPageProps) {\n const firestore = useFirestore()\n const { data: user } = useUser()\n const jobId = segments?.[0] ? decodeURIComponent(String(segments[0])) : null\n const orgSlug = (basePath ?? '').split('/')[1] ?? ''\n const [site, setSite] = useState<SiteFacts | null>(null)\n useEffect(() => {\n if (!hostId) return\n let active = true\n void getDoc(doc(firestore, 'hosts', hostId))\n .then((snapshot) => {\n if (!active) return\n const data = (snapshot.data() ?? {}) as { orgId?: string; displayName?: string }\n setSite({ orgId: String(data.orgId ?? ''), name: String(data.displayName ?? '') })\n })\n .catch(() => {\n if (active) setSite({ orgId: '', name: '' })\n })\n return () => {\n active = false\n }\n }, [firestore, hostId])\n\n const [job, setJob] = useAiJobById(user, site?.orgId || null, jobId)\n const [busy, setBusy] = useState(false)\n const [notice, setNotice] = useState<string | null>(null)\n const tryAgain = useCallback(async () => {\n if (!site?.orgId || !job || job === 'missing') return\n setBusy(true)\n setNotice(null)\n const decision = await resumeAiJobRequest(user, site.orgId, job)\n if (decision.job) setJob(decision.job)\n if (decision.error) setNotice(decision.error)\n setBusy(false)\n }, [site, job, user, setJob])\n\n const ready = job && job !== 'missing' ? job : null\n const phase = ready ? aiSiteBuildPhase(ready) : 'working'\n const heading =\n phase === 'done' ? 'Your site is ready' : phase === 'working' ? 'Building your site' : 'Your site was not built'\n const lede =\n phase === 'done'\n ? 'Your new pages are drafts. Publish them when you’re happy.'\n : phase === 'working'\n ? `${PLATFORM_BRAND_NAME} AI is planning your pages and writing each one. You can leave this page; it keeps going.`\n : phase === 'canceled'\n ? 'The job was canceled.'\n : (ready?.review?.message ?? ready?.error ?? 'Something went wrong building your site.')\n const rows = ready ? aiSiteBuildRows(ready) : []\n const credits = ready ? aiSiteBuildCreditsLine(ready) : null\n const links = ready && phase === 'done' ? aiSiteBuildDoneLinks(ready, orgSlug) : { view: null, pages: null }\n const retryRefusal = ready?.review?.retryRefusal\n const canRetry = phase === 'stopped' && ready?.review?.reason === 'doctrine'\n\n return (\n <Container maxWidth=\"sm\" sx={{ py: { xs: 3, sm: 5 }, px: { xs: 2, sm: 3 } }}>\n <Stack spacing={4}>\n <Stack spacing={1}>\n {site?.name ? (\n <Typography variant=\"overline\" color=\"text.secondary\">\n {site.name}\n </Typography>\n ) : null}\n <Typography variant=\"h4\" component=\"h1\">\n {heading}\n </Typography>\n <Typography variant=\"body1\" color=\"text.secondary\">\n {lede}\n </Typography>\n </Stack>\n {job === 'missing' ? (\n <Alert severity=\"info\">{'This job could not be found. It may belong to another workspace.'}</Alert>\n ) : !ready ? (\n <Stack sx={{ alignItems: 'center', py: 4 }}>\n <CircularProgress aria-label=\"Loading the job\" />\n </Stack>\n ) : (\n <>\n {notice && <Alert severity=\"warning\">{notice}</Alert>}\n <Card variant=\"outlined\" sx={{ borderRadius: 2 }}>\n {phase === 'working' && <LinearProgress aria-label=\"Building\" />}\n <Box component=\"ol\" aria-label=\"Progress\" sx={{ listStyle: 'none', m: 0, p: { xs: 2, sm: 3 } }}>\n <Stack spacing={2}>\n {rows.map((row) => (\n <Stack component=\"li\" key={row.id} direction=\"row\" spacing={2} sx={{ alignItems: 'center' }}>\n <Box sx={{ width: (theme) => theme.spacing(3), display: 'flex', justifyContent: 'center' }}>\n <RowIcon state={row.state} />\n </Box>\n <Typography\n variant=\"body1\"\n color={row.state === 'waiting' ? 'text.secondary' : 'text.primary'}\n >\n {row.label}\n </Typography>\n </Stack>\n ))}\n </Stack>\n </Box>\n </Card>\n {credits && (\n <Typography variant=\"body2\" color=\"text.secondary\">\n {credits}\n </Typography>\n )}\n {phase === 'done' && (\n <Stack direction={{ xs: 'column', sm: 'row' }} spacing={2}>\n {links.view && (\n <Button variant=\"contained\" size=\"large\" component={AppLink} href={links.view}>\n {'View your site'}\n </Button>\n )}\n {links.pages && (\n <Button variant=\"outlined\" size=\"large\" component={AppLink} href={links.pages}>\n {'Edit your pages'}\n </Button>\n )}\n </Stack>\n )}\n {(phase === 'stopped' || phase === 'failed' || phase === 'canceled') && (\n <Stack spacing={1}>\n {retryRefusal && (\n <Typography variant=\"body2\" color=\"text.secondary\">\n {retryRefusal}\n </Typography>\n )}\n <Stack direction={{ xs: 'column', sm: 'row' }} spacing={2} sx={{ alignItems: { sm: 'center' } }}>\n {canRetry && (\n <Button\n variant=\"contained\"\n disabled={busy || Boolean(retryRefusal)}\n onClick={() => void tryAgain()}\n >\n {'Try again'}\n </Button>\n )}\n {aiSiteStarterFallbackOffered(ready) && user ? <AiSiteStarterFallback job={ready} user={user} /> : null}\n </Stack>\n </Stack>\n )}\n {ready.plan && ready.plan.screens.length > 0 && (\n <Accordion variant=\"outlined\" disableGutters sx={{ borderRadius: 2, '&::before': { display: 'none' } }}>\n <AccordionSummary expandIcon={<MdiIcon path={mdiChevronDown.path} />}>\n <Typography variant=\"subtitle1\">{'What we’re building'}</Typography>\n </AccordionSummary>\n <AccordionDetails>\n <Stack component=\"ul\" spacing={1.5} sx={{ m: 0, pl: 2.5 }}>\n {ready.plan.screens.map((screen, index) => (\n <Box component=\"li\" key={`${screen.slug}-${index}`}>\n <Typography variant=\"body1\">{`${screen.title} — ${screen.slug}`}</Typography>\n {screen.sections.length > 0 && (\n <Typography variant=\"body2\" color=\"text.secondary\">\n {screen.sections.map((section) => section.name).join(', ')}\n </Typography>\n )}\n </Box>\n ))}\n </Stack>\n </AccordionDetails>\n </Accordion>\n )}\n </>\n )}\n </Stack>\n </Container>\n )\n}\n\nexport default AiSiteBuildPage\n"],"names":["PLATFORM_BRAND_NAME","mdiAlertCircle","mdiCheckCircle","mdiChevronDown","mdiClockOutline","AppLink","MdiIcon","useFirestore","useUser","Accordion","AccordionDetails","AccordionSummary","Alert","Box","Button","Card","CircularProgress","Container","LinearProgress","Stack","Typography","doc","getDoc","useCallback","useEffect","useRef","useState","aiSiteBuildCreditsLine","aiSiteBuildPhase","aiSiteBuildRows","aiSiteStarterFallbackOffered","followAiJobEvents","aiSiteBuildDoneLinks","resumeAiJobRequest","AiSiteStarterFallback","useAiJobById","user","orgId","jobId","userRef","current","job","setJob","status","moving","undefined","controller","AbortController","heard","signal","next","then","aborted","abort","ROW_ICON","done","path","color","label","waiting","failed","RowIcon","state","size","aria-label","icon","component","role","sx","display","fontSize","theme","spacing","aria-hidden","AiSiteBuildPage","hostId","segments","basePath","ready","firestore","data","decodeURIComponent","String","orgSlug","split","site","setSite","active","snapshot","name","displayName","catch","busy","setBusy","notice","setNotice","tryAgain","decision","error","phase","heading","lede","review","message","rows","credits","links","view","pages","retryRefusal","canRetry","reason","maxWidth","py","xs","sm","px","variant","severity","alignItems","borderRadius","listStyle","m","p","map","row","direction","width","justifyContent","id","href","disabled","Boolean","onClick","plan","screens","length","disableGutters","expandIcon","pl","screen","index","title","slug","sections","section","join"],"mappings":"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"}
@@ -15,5 +15,5 @@
15
15
  * limitations under the License.
16
16
  */
17
17
  import type { ConsoleHostFirstRunZoneProps } from '@aglyn/aglyn/plugin-manager/feature-plugins';
18
- export declare function AiSiteStartCard({ hostId, orgId, startBlank, }: ConsoleHostFirstRunZoneProps): import("react").JSX.Element;
18
+ export declare function AiSiteStartCard({ hostId, orgId, orgSlug, host, startBlank, leave, }: ConsoleHostFirstRunZoneProps): import("react").JSX.Element;
19
19
  export default AiSiteStartCard;