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

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 (92) hide show
  1. package/README.md +1 -1
  2. package/package.json +17 -17
  3. package/src/lib/components/ai-brief-dialog.component.js +1 -1
  4. package/src/lib/components/ai-brief-dialog.component.js.map +1 -1
  5. package/src/lib/components/ai-describe-automation.component.js +7 -2
  6. package/src/lib/components/ai-describe-automation.component.js.map +1 -1
  7. package/src/lib/components/ai-describe-button.component.js +6 -1
  8. package/src/lib/components/ai-describe-button.component.js.map +1 -1
  9. package/src/lib/components/ai-describe-page.component.d.ts +1 -1
  10. package/src/lib/components/ai-describe-page.component.js +1 -1
  11. package/src/lib/components/ai-describe-page.component.js.map +1 -1
  12. package/src/lib/components/ai-job-events.d.ts +7 -1
  13. package/src/lib/components/ai-job-events.js +4 -2
  14. package/src/lib/components/ai-job-events.js.map +1 -1
  15. package/src/lib/components/ai-job-site.d.ts +22 -0
  16. package/src/lib/components/ai-job-site.js +73 -0
  17. package/src/lib/components/ai-job-site.js.map +1 -0
  18. package/src/lib/components/ai-jobs-list-page.component.d.ts +23 -0
  19. package/src/lib/components/ai-jobs-list-page.component.js +303 -0
  20. package/src/lib/components/ai-jobs-list-page.component.js.map +1 -0
  21. package/src/lib/components/ai-jobs-page.component.d.ts +7 -0
  22. package/src/lib/components/ai-jobs-page.component.js +30 -0
  23. package/src/lib/components/ai-jobs-page.component.js.map +1 -0
  24. package/src/lib/components/ai-page-brief-dialog.component.d.ts +1 -1
  25. package/src/lib/components/ai-page-brief-dialog.component.js.map +1 -1
  26. package/src/lib/components/ai-site-build-page.component.d.ts +30 -2
  27. package/src/lib/components/ai-site-build-page.component.js +359 -241
  28. package/src/lib/components/ai-site-build-page.component.js.map +1 -1
  29. package/src/lib/components/ai-site-start-card.component.d.ts +8 -0
  30. package/src/lib/components/ai-site-start-card.component.js +20 -11
  31. package/src/lib/components/ai-site-start-card.component.js.map +1 -1
  32. package/src/lib/components/assist-panel.component.js +9 -4
  33. package/src/lib/components/assist-panel.component.js.map +1 -1
  34. package/src/lib/jobs/ai-job-draft-ids.d.ts +6 -0
  35. package/src/lib/jobs/ai-job-draft-ids.js +9 -0
  36. package/src/lib/jobs/ai-job-draft-ids.js.map +1 -1
  37. package/src/lib/jobs/ai-job-drafts.d.ts +7 -0
  38. package/src/lib/jobs/ai-job-drafts.js +16 -7
  39. package/src/lib/jobs/ai-job-drafts.js.map +1 -1
  40. package/src/lib/jobs/ai-job-layout-step.js +2 -1
  41. package/src/lib/jobs/ai-job-layout-step.js.map +1 -1
  42. package/src/lib/jobs/ai-job-page-sections.d.ts +6 -5
  43. package/src/lib/jobs/ai-job-page-sections.js +3 -3
  44. package/src/lib/jobs/ai-job-page-sections.js.map +1 -1
  45. package/src/lib/jobs/ai-job-page-step.d.ts +19 -1
  46. package/src/lib/jobs/ai-job-page-step.js +50 -8
  47. package/src/lib/jobs/ai-job-page-step.js.map +1 -1
  48. package/src/lib/jobs/ai-job-plan-step.js +7 -2
  49. package/src/lib/jobs/ai-job-plan-step.js.map +1 -1
  50. package/src/lib/jobs/ai-job-site-step.d.ts +21 -0
  51. package/src/lib/jobs/ai-job-site-step.js +96 -17
  52. package/src/lib/jobs/ai-job-site-step.js.map +1 -1
  53. package/src/lib/jobs/ai-job-text-step.d.ts +7 -1
  54. package/src/lib/jobs/ai-job-text-step.js.map +1 -1
  55. package/src/lib/jobs/ai-jobs.d.ts +9 -1
  56. package/src/lib/jobs/ai-jobs.js +9 -2
  57. package/src/lib/jobs/ai-jobs.js.map +1 -1
  58. package/src/lib/jobs/ai-site-publish.d.ts +98 -0
  59. package/src/lib/jobs/ai-site-publish.js +372 -0
  60. package/src/lib/jobs/ai-site-publish.js.map +1 -0
  61. package/src/lib/jobs/fixtures/ai-page-briefs.d.ts +7 -6
  62. package/src/lib/jobs/fixtures/ai-page-briefs.js +23 -56
  63. package/src/lib/jobs/fixtures/ai-page-briefs.js.map +1 -1
  64. package/src/lib/model/ai-job-notice.d.ts +3 -1
  65. package/src/lib/model/ai-job-notice.js +18 -1
  66. package/src/lib/model/ai-job-notice.js.map +1 -1
  67. package/src/lib/model/ai-jobs.types.d.ts +27 -0
  68. package/src/lib/model/ai-jobs.types.js.map +1 -1
  69. package/src/lib/model/ai-plan-capabilities.d.ts +25 -10
  70. package/src/lib/model/ai-plan-capabilities.js +15 -2
  71. package/src/lib/model/ai-plan-capabilities.js.map +1 -1
  72. package/src/lib/model/ai-site-build-progress.d.ts +17 -1
  73. package/src/lib/model/ai-site-build-progress.js +64 -4
  74. package/src/lib/model/ai-site-build-progress.js.map +1 -1
  75. package/src/lib/model/ai-site-start-seo.d.ts +19 -0
  76. package/src/lib/model/ai-site-start-seo.js +91 -3
  77. package/src/lib/model/ai-site-start-seo.js.map +1 -1
  78. package/src/lib/plugin.js +18 -10
  79. package/src/lib/plugin.js.map +1 -1
  80. package/src/lib/runtime/ai-doctrine-validators.d.ts +16 -12
  81. package/src/lib/runtime/ai-doctrine-validators.js +19 -36
  82. package/src/lib/runtime/ai-doctrine-validators.js.map +1 -1
  83. package/src/lib/runtime/ai-doctrine.js +1 -1
  84. package/src/lib/runtime/ai-doctrine.js.map +1 -1
  85. package/src/lib/runtime/ai-eval-live.d.ts +1 -1
  86. package/src/lib/runtime/ai-eval-live.js +1 -1
  87. package/src/lib/runtime/ai-eval-live.js.map +1 -1
  88. package/src/lib/server/ai-jobs-live-sites.d.ts +26 -0
  89. package/src/lib/server/ai-jobs-live-sites.js +58 -0
  90. package/src/lib/server/ai-jobs-live-sites.js.map +1 -0
  91. package/src/lib/server/ai-jobs-route.js +22 -3
  92. package/src/lib/server/ai-jobs-route.js.map +1 -1
@@ -14,45 +14,81 @@
14
14
  * See the License for the specific language governing permissions and
15
15
  * limitations under the License.
16
16
  */ 'use client';
17
- import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
17
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
18
18
  import { PLATFORM_BRAND_NAME } from "@aglyn/aglyn";
19
+ import { PageHeaderRecord } from "@aglyn/aglyn/app-utils/page-header-record-context";
19
20
  import { mdiAlertCircle, mdiCheckCircle, mdiChevronDown, mdiClockOutline } from "@aglyn/shared-data-mdi";
20
21
  import { AppLink, MdiIcon } from "@aglyn/shared-ui-jsx";
21
- import { useFirestore, useUser } from "@aglyn/tenant-feature-instance";
22
+ import { useUser } from "@aglyn/tenant-feature-instance";
22
23
  import { Accordion, AccordionDetails, AccordionSummary, Alert, Box, Button, Card, CircularProgress, Container, LinearProgress, Stack, Typography } from "@mui/material";
23
- import { doc, getDoc } from "firebase/firestore";
24
24
  import { useCallback, useEffect, useRef, useState } from "react";
25
- import { aiSiteBuildCreditsLine, aiSiteBuildPhase, aiSiteBuildRows } from "../model/ai-site-build-progress.js";
25
+ import { aiJobPageCopy, aiSiteBuildCreditsLine, aiSiteBuildPhase, aiSiteBuildRows } from "../model/ai-site-build-progress.js";
26
26
  import { aiSiteStarterFallbackOffered } from "../model/ai-job-failure-copy.js";
27
27
  import { followAiJobEvents } from "./ai-job-events.js";
28
28
  import { aiSiteBuildDoneLinks } from "./ai-job-links.js";
29
29
  import { resumeAiJobRequest } from "./ai-job-requests.js";
30
+ import { useAiJobSite } from "./ai-job-site.js";
30
31
  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
+ /**
33
+ * "Building your site" (AGL-3594): one job's page, at `/ai-jobs/{jobId}`
34
+ * under its site — where the guided start sends a person the moment they
35
+ * plan a site, and where a notification about that job opens.
36
+ *
37
+ * A guided site start confirms its own plan (`autoConfirm`), so there is no
38
+ * approval to make here: the page says what is happening, step by step, live
39
+ * from the job's events route; shows what is being built; and, when the job
40
+ * ends, leads with the next thing to do — the live site and the pages to
41
+ * edit, or, where it stopped, the plain sentence for why and what to do
42
+ * about it. It is linkable and survives a reload, because it reads the job by
43
+ * the id in its own address under the site's own route.
44
+ *
45
+ * Every wait ends (AGL-3596): a site that cannot be read, a job the route
46
+ * does not know, a route that fails, and a first state that never arrives
47
+ * each end on a sentence instead of a spinner.
48
+ *
49
+ * Mounted by `AiJobsPage`, the plugin's unlisted `/ai-jobs` route: no tab on
50
+ * the site's strip, an address under it.
51
+ */ /** How long the job's first state may take before the page says it could not be loaded. */ export const AI_JOB_FIRST_STATE_TIMEOUT_MS = 20000;
52
+ /** Follows one job by id. `retry` follows it again after a `'missing'` or `'error'`. */ export function useAiJobById(user, orgId, jobId) {
32
53
  const userRef = useRef(user);
33
54
  userRef.current = user;
34
55
  const [job, setJob] = useState(null);
35
- const status = job && job !== 'missing' ? job.status : null;
56
+ const [attempt, setAttempt] = useState(0);
57
+ const status = job && typeof job === 'object' ? job.status : null;
36
58
  const moving = status === null || status === 'queued' || status === 'running';
37
59
  useEffect(()=>{
38
60
  if (!orgId || !jobId || !moving) return undefined;
39
61
  const controller = new AbortController();
40
62
  let heard = false;
63
+ const timer = setTimeout(()=>{
64
+ if (!heard) setJob((current)=>current != null ? current : 'error');
65
+ }, AI_JOB_FIRST_STATE_TIMEOUT_MS);
41
66
  void followAiJobEvents(()=>userRef.current, orgId, jobId, controller.signal, (next)=>{
42
67
  heard = true;
43
68
  setJob(next);
44
- }).then(()=>{
45
- if (!heard && !controller.signal.aborted) setJob((current)=>current != null ? current : 'missing');
69
+ }).then((end)=>{
70
+ if (heard || controller.signal.aborted) return;
71
+ const unheard = end === 'not-found' ? 'missing' : 'error';
72
+ setJob((current)=>current && typeof current === 'object' ? current : unheard);
46
73
  });
47
- return ()=>controller.abort();
74
+ return ()=>{
75
+ clearTimeout(timer);
76
+ controller.abort();
77
+ };
48
78
  }, [
49
79
  orgId,
50
80
  jobId,
51
- moving
81
+ moving,
82
+ attempt
52
83
  ]);
84
+ const retry = useCallback(()=>{
85
+ setJob(null);
86
+ setAttempt((count)=>count + 1);
87
+ }, []);
53
88
  return [
54
89
  job,
55
- setJob
90
+ setJob,
91
+ retry
56
92
  ];
57
93
  }
58
94
  const ROW_ICON = {
@@ -95,67 +131,7 @@ function RowIcon({ state }) {
95
131
  })
96
132
  });
97
133
  }
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';
134
+ /** The page's frame: the site's name over the heading and its sentence. */ function Frame({ siteName, heading, lede, children }) {
159
135
  return /*#__PURE__*/ _jsx(Container, {
160
136
  maxWidth: "sm",
161
137
  sx: {
@@ -174,202 +150,344 @@ export function AiSiteBuildPage({ hostId, segments, basePath }) {
174
150
  /*#__PURE__*/ _jsxs(Stack, {
175
151
  spacing: 1,
176
152
  children: [
177
- (site == null ? void 0 : site.name) ? /*#__PURE__*/ _jsx(Typography, {
153
+ siteName ? /*#__PURE__*/ _jsx(Typography, {
178
154
  variant: "overline",
179
155
  color: "text.secondary",
180
- children: site.name
156
+ children: siteName
181
157
  }) : null,
182
158
  /*#__PURE__*/ _jsx(Typography, {
183
159
  variant: "h4",
184
160
  component: "h1",
185
161
  children: heading
186
162
  }),
187
- /*#__PURE__*/ _jsx(Typography, {
163
+ lede ? /*#__PURE__*/ _jsx(Typography, {
188
164
  variant: "body1",
189
165
  color: "text.secondary",
190
166
  children: lede
191
- })
167
+ }) : null
192
168
  ]
193
169
  }),
194
- job === 'missing' ? /*#__PURE__*/ _jsx(Alert, {
170
+ children
171
+ ]
172
+ })
173
+ });
174
+ }
175
+ export function AiSiteBuildPage({ hostId, segments, basePath }) {
176
+ var _split_, _ready_sitePublish;
177
+ var _ready_review, _ready_review1;
178
+ const { data: user } = useUser();
179
+ const jobId = (segments == null ? void 0 : segments[0]) ? decodeURIComponent(String(segments[0])) : null;
180
+ const orgSlug = (_split_ = (basePath != null ? basePath : '').split('/')[1]) != null ? _split_ : '';
181
+ const site = useAiJobSite(hostId);
182
+ const orgId = site.status === 'ready' ? site.orgId : null;
183
+ const siteName = site.status === 'ready' ? site.name : undefined;
184
+ const [job, setJob, retry] = useAiJobById(user, orgId, jobId);
185
+ const [busy, setBusy] = useState(false);
186
+ const [notice, setNotice] = useState(null);
187
+ const tryAgain = useCallback(async ()=>{
188
+ if (!orgId || !job || typeof job !== 'object') return;
189
+ setBusy(true);
190
+ setNotice(null);
191
+ const decision = await resumeAiJobRequest(user, orgId, job);
192
+ if (decision.job) setJob(decision.job);
193
+ if (decision.error) setNotice(decision.error);
194
+ setBusy(false);
195
+ }, [
196
+ orgId,
197
+ job,
198
+ user,
199
+ setJob
200
+ ]);
201
+ const ready = job && typeof job === 'object' ? job : null;
202
+ const copy = ready ? aiJobPageCopy(ready, PLATFORM_BRAND_NAME) : null;
203
+ // The shell's header names the job's page as the page does, and its trail
204
+ // walks back to the site's AI jobs.
205
+ const record = /*#__PURE__*/ _jsx(PageHeaderRecord, {
206
+ title: copy == null ? void 0 : copy.heading
207
+ });
208
+ if (site.status === 'error') {
209
+ return /*#__PURE__*/ _jsx(Frame, {
210
+ heading: "This site could not be read",
211
+ children: /*#__PURE__*/ _jsx(Alert, {
212
+ severity: "warning",
213
+ children: 'The site this job belongs to could not be loaded. Check your connection and reload the page.'
214
+ })
215
+ });
216
+ }
217
+ if (job === 'missing') {
218
+ return /*#__PURE__*/ _jsxs(Frame, {
219
+ siteName: siteName,
220
+ heading: "This job could not be found",
221
+ children: [
222
+ /*#__PURE__*/ _jsx(Alert, {
195
223
  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"
224
+ children: 'It may belong to another workspace, or it may have expired.'
225
+ }),
226
+ basePath ? /*#__PURE__*/ _jsx(Box, {
227
+ children: /*#__PURE__*/ _jsx(Button, {
228
+ variant: "outlined",
229
+ component: AppLink,
230
+ href: basePath,
231
+ children: 'See this site’s AI jobs'
204
232
  })
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
- },
233
+ }) : null
234
+ ]
235
+ });
236
+ }
237
+ if (job === 'error') {
238
+ return /*#__PURE__*/ _jsx(Frame, {
239
+ siteName: siteName,
240
+ heading: "This job could not be loaded",
241
+ children: /*#__PURE__*/ _jsx(Alert, {
242
+ severity: "warning",
243
+ action: /*#__PURE__*/ _jsx(Button, {
244
+ color: "inherit",
245
+ size: "small",
246
+ onClick: retry,
247
+ children: 'Try again'
248
+ }),
249
+ children: 'Something went wrong reading it. It may still be running: try again in a moment.'
250
+ })
251
+ });
252
+ }
253
+ if (!ready || !copy) {
254
+ return /*#__PURE__*/ _jsx(Frame, {
255
+ siteName: siteName,
256
+ heading: "Building your site",
257
+ children: /*#__PURE__*/ _jsx(Stack, {
258
+ sx: {
259
+ alignItems: 'center',
260
+ py: 4
261
+ },
262
+ children: /*#__PURE__*/ _jsx(CircularProgress, {
263
+ "aria-label": "Loading the job"
264
+ })
265
+ })
266
+ });
267
+ }
268
+ const phase = aiSiteBuildPhase(ready);
269
+ const rows = aiSiteBuildRows(ready);
270
+ const credits = aiSiteBuildCreditsLine(ready);
271
+ const links = phase === 'done' ? aiSiteBuildDoneLinks(ready, orgSlug) : {
272
+ view: null,
273
+ pages: null
274
+ };
275
+ const sitePublish = ready.kind === 'site' && phase === 'done' ? (_ready_sitePublish = ready.sitePublish) != null ? _ready_sitePublish : null : null;
276
+ const liveUrl = sitePublish && sitePublish.published.length > 0 ? sitePublish.liveUrl : null;
277
+ const retryRefusal = (_ready_review = ready.review) == null ? void 0 : _ready_review.retryRefusal;
278
+ const canRetry = phase === 'stopped' && ((_ready_review1 = ready.review) == null ? void 0 : _ready_review1.reason) === 'doctrine';
279
+ return /*#__PURE__*/ _jsxs(Frame, {
280
+ siteName: siteName,
281
+ heading: copy.heading,
282
+ lede: copy.lede,
283
+ children: [
284
+ record,
285
+ notice && /*#__PURE__*/ _jsx(Alert, {
286
+ severity: "warning",
287
+ children: notice
288
+ }),
289
+ /*#__PURE__*/ _jsxs(Card, {
290
+ variant: "outlined",
291
+ sx: {
292
+ borderRadius: 2
293
+ },
294
+ children: [
295
+ phase === 'working' && /*#__PURE__*/ _jsx(LinearProgress, {
296
+ "aria-label": "Building"
297
+ }),
298
+ /*#__PURE__*/ _jsx(Box, {
299
+ component: "ol",
300
+ "aria-label": "Progress",
301
+ sx: {
302
+ listStyle: 'none',
303
+ m: 0,
304
+ p: {
305
+ xs: 2,
306
+ sm: 3
307
+ }
308
+ },
309
+ children: /*#__PURE__*/ _jsx(Stack, {
272
310
  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
- },
311
+ children: rows.map((row)=>/*#__PURE__*/ _jsxs(Stack, {
312
+ component: "li",
313
+ direction: "row",
303
314
  spacing: 2,
304
315
  sx: {
305
- alignItems: {
306
- sm: 'center'
307
- }
316
+ alignItems: 'center'
308
317
  },
309
318
  children: [
310
- canRetry && /*#__PURE__*/ _jsx(Button, {
311
- variant: "contained",
312
- disabled: busy || Boolean(retryRefusal),
313
- onClick: ()=>void tryAgain(),
314
- children: 'Try again'
319
+ /*#__PURE__*/ _jsx(Box, {
320
+ sx: {
321
+ width: (theme)=>theme.spacing(3),
322
+ display: 'flex',
323
+ justifyContent: 'center'
324
+ },
325
+ children: /*#__PURE__*/ _jsx(RowIcon, {
326
+ state: row.state
327
+ })
315
328
  }),
316
- aiSiteStarterFallbackOffered(ready) && user ? /*#__PURE__*/ _jsx(AiSiteStarterFallback, {
317
- job: ready,
318
- user: user
319
- }) : null
329
+ /*#__PURE__*/ _jsx(Typography, {
330
+ variant: "body1",
331
+ color: row.state === 'waiting' ? 'text.secondary' : 'text.primary',
332
+ children: row.label
333
+ })
320
334
  ]
335
+ }, row.id))
336
+ })
337
+ })
338
+ ]
339
+ }),
340
+ credits && /*#__PURE__*/ _jsx(Typography, {
341
+ variant: "body2",
342
+ color: "text.secondary",
343
+ children: credits
344
+ }),
345
+ sitePublish && sitePublish.drafts.length > 0 && // The pages the publish left as drafts, each with its plain reason;
346
+ // Edit your pages is where they are fixed and published.
347
+ /*#__PURE__*/ _jsxs(Alert, {
348
+ severity: "warning",
349
+ children: [
350
+ /*#__PURE__*/ _jsx(Typography, {
351
+ variant: "body2",
352
+ sx: {
353
+ mb: 1
354
+ },
355
+ children: sitePublish.drafts.length === 1 ? 'This page stayed a draft:' : 'These pages stayed drafts:'
356
+ }),
357
+ /*#__PURE__*/ _jsx(Box, {
358
+ component: "ul",
359
+ sx: {
360
+ m: 0,
361
+ pl: 2.5
362
+ },
363
+ children: sitePublish.drafts.map((draft)=>/*#__PURE__*/ _jsx("li", {
364
+ children: /*#__PURE__*/ _jsx(Typography, {
365
+ variant: "body2",
366
+ children: `${draft.label}: ${draft.reason}`
321
367
  })
322
- ]
368
+ }, draft.id))
369
+ }),
370
+ /*#__PURE__*/ _jsx(Typography, {
371
+ variant: "body2",
372
+ sx: {
373
+ mt: 1
374
+ },
375
+ children: 'Open Edit your pages to fix and publish them.'
376
+ })
377
+ ]
378
+ }),
379
+ phase === 'done' && /*#__PURE__*/ _jsxs(Stack, {
380
+ direction: {
381
+ xs: 'column',
382
+ sm: 'row'
383
+ },
384
+ spacing: 2,
385
+ children: [
386
+ liveUrl ? // The live site, in a tab of its own: the console stays where it is.
387
+ /*#__PURE__*/ _jsx(Button, {
388
+ variant: "contained",
389
+ size: "large",
390
+ component: "a",
391
+ href: liveUrl,
392
+ target: "_blank",
393
+ rel: "noopener noreferrer",
394
+ children: 'View your site'
395
+ }) : links.view ? /*#__PURE__*/ _jsx(Button, {
396
+ variant: "contained",
397
+ size: "large",
398
+ component: AppLink,
399
+ href: links.view,
400
+ children: 'View your site'
401
+ }) : null,
402
+ links.pages && /*#__PURE__*/ _jsx(Button, {
403
+ variant: "outlined",
404
+ size: "large",
405
+ component: AppLink,
406
+ href: links.pages,
407
+ children: 'Edit your pages'
408
+ })
409
+ ]
410
+ }),
411
+ (phase === 'stopped' || phase === 'failed' || phase === 'canceled') && /*#__PURE__*/ _jsxs(Stack, {
412
+ spacing: 1,
413
+ children: [
414
+ retryRefusal && /*#__PURE__*/ _jsx(Typography, {
415
+ variant: "body2",
416
+ color: "text.secondary",
417
+ children: retryRefusal
418
+ }),
419
+ /*#__PURE__*/ _jsxs(Stack, {
420
+ direction: {
421
+ xs: 'column',
422
+ sm: 'row'
423
+ },
424
+ spacing: 2,
425
+ sx: {
426
+ alignItems: {
427
+ sm: 'center'
428
+ }
429
+ },
430
+ children: [
431
+ canRetry && /*#__PURE__*/ _jsx(Button, {
432
+ variant: "contained",
433
+ disabled: busy || Boolean(retryRefusal),
434
+ onClick: ()=>void tryAgain(),
435
+ children: 'Try again'
436
+ }),
437
+ aiSiteStarterFallbackOffered(ready) && user ? /*#__PURE__*/ _jsx(AiSiteStarterFallback, {
438
+ job: ready,
439
+ user: user
440
+ }) : null
441
+ ]
442
+ })
443
+ ]
444
+ }),
445
+ ready.plan && ready.plan.screens.length > 0 && /*#__PURE__*/ _jsxs(Accordion, {
446
+ variant: "outlined",
447
+ disableGutters: true,
448
+ sx: {
449
+ borderRadius: 2,
450
+ '&::before': {
451
+ display: 'none'
452
+ }
453
+ },
454
+ children: [
455
+ /*#__PURE__*/ _jsx(AccordionSummary, {
456
+ expandIcon: /*#__PURE__*/ _jsx(MdiIcon, {
457
+ path: mdiChevronDown.path
323
458
  }),
324
- ready.plan && ready.plan.screens.length > 0 && /*#__PURE__*/ _jsxs(Accordion, {
325
- variant: "outlined",
326
- disableGutters: true,
459
+ children: /*#__PURE__*/ _jsx(Typography, {
460
+ variant: "subtitle1",
461
+ children: 'What we’re building'
462
+ })
463
+ }),
464
+ /*#__PURE__*/ _jsx(AccordionDetails, {
465
+ children: /*#__PURE__*/ _jsx(Stack, {
466
+ component: "ul",
467
+ spacing: 1.5,
327
468
  sx: {
328
- borderRadius: 2,
329
- '&::before': {
330
- display: 'none'
331
- }
469
+ m: 0,
470
+ pl: 2.5
332
471
  },
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
- ]
472
+ children: ready.plan.screens.map((screen, index)=>/*#__PURE__*/ _jsxs(Box, {
473
+ component: "li",
474
+ children: [
475
+ /*#__PURE__*/ _jsx(Typography, {
476
+ variant: "body1",
477
+ children: `${screen.title} — ${screen.slug}`
478
+ }),
479
+ screen.sections.length > 0 && /*#__PURE__*/ _jsx(Typography, {
480
+ variant: "body2",
481
+ color: "text.secondary",
482
+ children: screen.sections.map((section)=>section.name).join(', ')
483
+ })
484
+ ]
485
+ }, `${screen.slug}-${index}`))
368
486
  })
369
- ]
370
- })
371
- ]
372
- })
487
+ })
488
+ ]
489
+ })
490
+ ]
373
491
  });
374
492
  }
375
493
  export default AiSiteBuildPage;