@aglyn/plugins-ai 1.0.0-beta.292 → 1.0.0-beta.296

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 (203) hide show
  1. package/package.json +17 -17
  2. package/src/lib/components/ai-job-links.d.ts +15 -2
  3. package/src/lib/components/ai-job-links.js +24 -3
  4. package/src/lib/components/ai-job-links.js.map +1 -1
  5. package/src/lib/components/ai-job-requests.d.ts +9 -0
  6. package/src/lib/components/ai-job-requests.js +34 -0
  7. package/src/lib/components/ai-job-requests.js.map +1 -1
  8. package/src/lib/components/ai-site-build-page.component.js +28 -2
  9. package/src/lib/components/ai-site-build-page.component.js.map +1 -1
  10. package/src/lib/components/ai-site-import-job.component.js +5 -4
  11. package/src/lib/components/ai-site-import-job.component.js.map +1 -1
  12. package/src/lib/components/ai-site-import-start.component.js +3 -3
  13. package/src/lib/components/ai-site-import-start.component.js.map +1 -1
  14. package/src/lib/components/ai-site-start-card.component.d.ts +1 -1
  15. package/src/lib/components/ai-site-start-card.component.js +129 -29
  16. package/src/lib/components/ai-site-start-card.component.js.map +1 -1
  17. package/src/lib/components/ai-site-start-steps.component.d.ts +15 -3
  18. package/src/lib/components/ai-site-start-steps.component.js +42 -25
  19. package/src/lib/components/ai-site-start-steps.component.js.map +1 -1
  20. package/src/lib/components/ai-site-style-previews.d.ts +17 -0
  21. package/src/lib/components/ai-site-style-previews.js +26 -95
  22. package/src/lib/components/ai-site-style-previews.js.map +1 -1
  23. package/src/lib/components/assist-jobs-drawer.component.d.ts +7 -1
  24. package/src/lib/components/assist-jobs-drawer.component.js +20 -6
  25. package/src/lib/components/assist-jobs-drawer.component.js.map +1 -1
  26. package/src/lib/components/assist-page-change-card.component.d.ts +44 -0
  27. package/src/lib/components/assist-page-change-card.component.js +166 -0
  28. package/src/lib/components/assist-page-change-card.component.js.map +1 -0
  29. package/src/lib/components/assist-panel.component.d.ts +105 -1
  30. package/src/lib/components/assist-panel.component.js +224 -29
  31. package/src/lib/components/assist-panel.component.js.map +1 -1
  32. package/src/lib/declarations.server.js +22 -0
  33. package/src/lib/declarations.server.js.map +1 -1
  34. package/src/lib/jobs/ai-job-edit-step.d.ts +62 -16
  35. package/src/lib/jobs/ai-job-edit-step.js +172 -61
  36. package/src/lib/jobs/ai-job-edit-step.js.map +1 -1
  37. package/src/lib/jobs/ai-job-import-step.d.ts +21 -2
  38. package/src/lib/jobs/ai-job-import-step.js +179 -49
  39. package/src/lib/jobs/ai-job-import-step.js.map +1 -1
  40. package/src/lib/jobs/ai-job-layout-language.d.ts +27 -3
  41. package/src/lib/jobs/ai-job-layout-language.js +156 -113
  42. package/src/lib/jobs/ai-job-layout-language.js.map +1 -1
  43. package/src/lib/jobs/ai-job-layout-step.js +56 -17
  44. package/src/lib/jobs/ai-job-layout-step.js.map +1 -1
  45. package/src/lib/jobs/ai-job-navigation-step.js +4 -2
  46. package/src/lib/jobs/ai-job-navigation-step.js.map +1 -1
  47. package/src/lib/jobs/ai-job-page-language.d.ts +25 -15
  48. package/src/lib/jobs/ai-job-page-language.js +120 -66
  49. package/src/lib/jobs/ai-job-page-language.js.map +1 -1
  50. package/src/lib/jobs/ai-job-page-step.js +27 -7
  51. package/src/lib/jobs/ai-job-page-step.js.map +1 -1
  52. package/src/lib/jobs/ai-job-site-datasets.d.ts +12 -4
  53. package/src/lib/jobs/ai-job-site-datasets.js +36 -16
  54. package/src/lib/jobs/ai-job-site-datasets.js.map +1 -1
  55. package/src/lib/jobs/ai-jobs.js +6 -2
  56. package/src/lib/jobs/ai-jobs.js.map +1 -1
  57. package/src/lib/jobs/ai-layout-stock-photos.d.ts +50 -1
  58. package/src/lib/jobs/ai-layout-stock-photos.js +586 -35
  59. package/src/lib/jobs/ai-layout-stock-photos.js.map +1 -1
  60. package/src/lib/jobs/ai-site-import-compile.d.ts +147 -0
  61. package/src/lib/jobs/ai-site-import-compile.js +1143 -0
  62. package/src/lib/jobs/ai-site-import-compile.js.map +1 -0
  63. package/src/lib/jobs/ai-site-import-document.d.ts +9 -36
  64. package/src/lib/jobs/ai-site-import-document.js +23 -489
  65. package/src/lib/jobs/ai-site-import-document.js.map +1 -1
  66. package/src/lib/jobs/ai-site-import-look.d.ts +54 -7
  67. package/src/lib/jobs/ai-site-import-look.js +163 -52
  68. package/src/lib/jobs/ai-site-import-look.js.map +1 -1
  69. package/src/lib/jobs/ai-site-import-publish.d.ts +7 -1
  70. package/src/lib/jobs/ai-site-import-publish.js +19 -5
  71. package/src/lib/jobs/ai-site-import-publish.js.map +1 -1
  72. package/src/lib/jobs/ai-site-late-photos.js +4 -2
  73. package/src/lib/jobs/ai-site-late-photos.js.map +1 -1
  74. package/src/lib/jobs/ai-site-publish.d.ts +10 -1
  75. package/src/lib/jobs/ai-site-publish.js +8 -3
  76. package/src/lib/jobs/ai-site-publish.js.map +1 -1
  77. package/src/lib/jobs/fixtures/ai-stock-photo-agl4092-1029-recordings.d.ts +23 -0
  78. package/src/lib/jobs/fixtures/ai-stock-photo-agl4092-1029-recordings.js +677 -0
  79. package/src/lib/jobs/fixtures/ai-stock-photo-agl4092-1029-recordings.js.map +1 -0
  80. package/src/lib/layout-language/ai-layout-compiler.d.ts +26 -0
  81. package/src/lib/layout-language/ai-layout-compiler.js +677 -33
  82. package/src/lib/layout-language/ai-layout-compiler.js.map +1 -1
  83. package/src/lib/layout-language/ai-layout-frame-hollows.js +5 -1
  84. package/src/lib/layout-language/ai-layout-frame-hollows.js.map +1 -1
  85. package/src/lib/layout-language/ai-layout-frame-source.d.ts +196 -0
  86. package/src/lib/layout-language/ai-layout-frame-source.js +726 -0
  87. package/src/lib/layout-language/ai-layout-frame-source.js.map +1 -0
  88. package/src/lib/layout-language/ai-layout-frame.d.ts +22 -0
  89. package/src/lib/layout-language/ai-layout-frame.js +121 -29
  90. package/src/lib/layout-language/ai-layout-frame.js.map +1 -1
  91. package/src/lib/layout-language/ai-layout-language.d.ts +103 -37
  92. package/src/lib/layout-language/ai-layout-language.js +85 -120
  93. package/src/lib/layout-language/ai-layout-language.js.map +1 -1
  94. package/src/lib/model/ai-credit-estimate.d.ts +11 -7
  95. package/src/lib/model/ai-credit-estimate.js +11 -7
  96. package/src/lib/model/ai-credit-estimate.js.map +1 -1
  97. package/src/lib/model/ai-edit-job.d.ts +33 -16
  98. package/src/lib/model/ai-edit-job.js +50 -34
  99. package/src/lib/model/ai-edit-job.js.map +1 -1
  100. package/src/lib/model/ai-job-activity.d.ts +6 -11
  101. package/src/lib/model/ai-job-activity.js +8 -15
  102. package/src/lib/model/ai-job-activity.js.map +1 -1
  103. package/src/lib/model/ai-jobs.types.d.ts +6 -0
  104. package/src/lib/model/ai-jobs.types.js.map +1 -1
  105. package/src/lib/model/ai-site-import.d.ts +307 -13
  106. package/src/lib/model/ai-site-import.js +227 -19
  107. package/src/lib/model/ai-site-import.js.map +1 -1
  108. package/src/lib/model/ai-site-inventory.d.ts +6 -0
  109. package/src/lib/model/ai-site-inventory.js.map +1 -1
  110. package/src/lib/model/ai-site-look.d.ts +65 -1
  111. package/src/lib/model/ai-site-look.js +141 -23
  112. package/src/lib/model/ai-site-look.js.map +1 -1
  113. package/src/lib/model/ai-site-photos.d.ts +2 -0
  114. package/src/lib/model/ai-site-photos.js.map +1 -1
  115. package/src/lib/model/ai-site-start-steps.d.ts +4 -3
  116. package/src/lib/model/ai-site-start-steps.js +11 -3
  117. package/src/lib/model/ai-site-start-steps.js.map +1 -1
  118. package/src/lib/model/ai-site-start.d.ts +23 -2
  119. package/src/lib/model/ai-site-start.js +25 -3
  120. package/src/lib/model/ai-site-start.js.map +1 -1
  121. package/src/lib/model/assist-edit.d.ts +18 -1
  122. package/src/lib/model/assist-edit.js +7 -0
  123. package/src/lib/model/assist-edit.js.map +1 -1
  124. package/src/lib/model/assist-page-change.d.ts +86 -0
  125. package/src/lib/model/assist-page-change.js +86 -0
  126. package/src/lib/model/assist-page-change.js.map +1 -0
  127. package/src/lib/providers/routing.d.ts +11 -0
  128. package/src/lib/providers/routing.js +23 -0
  129. package/src/lib/providers/routing.js.map +1 -1
  130. package/src/lib/runtime/ai-doctrine-validators.d.ts +4 -2
  131. package/src/lib/runtime/ai-doctrine-validators.js +7 -2
  132. package/src/lib/runtime/ai-doctrine-validators.js.map +1 -1
  133. package/src/lib/runtime/ai-eval.js +3 -1
  134. package/src/lib/runtime/ai-eval.js.map +1 -1
  135. package/src/lib/runtime/ai-icon-library.d.ts +4 -0
  136. package/src/lib/runtime/ai-icon-library.js +4 -0
  137. package/src/lib/runtime/ai-icon-library.js.map +1 -1
  138. package/src/lib/runtime/ai-node-tree.d.ts +5 -0
  139. package/src/lib/runtime/ai-node-tree.js +23 -4
  140. package/src/lib/runtime/ai-node-tree.js.map +1 -1
  141. package/src/lib/runtime/ai-palette.d.ts +2 -0
  142. package/src/lib/runtime/ai-palette.generated.js +19 -3
  143. package/src/lib/runtime/ai-palette.generated.js.map +1 -1
  144. package/src/lib/runtime/ai-palette.js +2 -1
  145. package/src/lib/runtime/ai-palette.js.map +1 -1
  146. package/src/lib/runtime/site-inventory.d.ts +8 -1
  147. package/src/lib/runtime/site-inventory.js +18 -0
  148. package/src/lib/runtime/site-inventory.js.map +1 -1
  149. package/src/lib/server/assist-build.js +2 -0
  150. package/src/lib/server/assist-build.js.map +1 -1
  151. package/src/lib/server/assist-chat.js +51 -2
  152. package/src/lib/server/assist-chat.js.map +1 -1
  153. package/src/lib/server/assist-edit.d.ts +54 -2
  154. package/src/lib/server/assist-edit.js +219 -30
  155. package/src/lib/server/assist-edit.js.map +1 -1
  156. package/src/lib/server/assist-page-change.d.ts +62 -0
  157. package/src/lib/server/assist-page-change.js +140 -0
  158. package/src/lib/server/assist-page-change.js.map +1 -0
  159. package/src/lib/site-import/fixtures/site-layout-recordings.d.ts +50 -0
  160. package/src/lib/site-import/fixtures/site-layout-recordings.js +86 -0
  161. package/src/lib/site-import/fixtures/site-layout-recordings.js.map +1 -0
  162. package/src/lib/site-import/site-import-crawl.d.ts +18 -1
  163. package/src/lib/site-import/site-import-crawl.js +70 -10
  164. package/src/lib/site-import/site-import-crawl.js.map +1 -1
  165. package/src/lib/site-import/site-import-css.d.ts +110 -0
  166. package/src/lib/site-import/site-import-css.js +826 -0
  167. package/src/lib/site-import/site-import-css.js.map +1 -0
  168. package/src/lib/site-import/site-import-html.d.ts +116 -1
  169. package/src/lib/site-import/site-import-html.js +538 -46
  170. package/src/lib/site-import/site-import-html.js.map +1 -1
  171. package/src/lib/site-import/site-import-layout.d.ts +79 -0
  172. package/src/lib/site-import/site-import-layout.js +1608 -0
  173. package/src/lib/site-import/site-import-layout.js.map +1 -0
  174. package/src/lib/site-import/site-import-nav.d.ts +40 -0
  175. package/src/lib/site-import/site-import-nav.js +437 -0
  176. package/src/lib/site-import/site-import-nav.js.map +1 -0
  177. package/src/lib/site-import/site-import-page.d.ts +8 -1
  178. package/src/lib/site-import/site-import-page.js +24 -2
  179. package/src/lib/site-import/site-import-page.js.map +1 -1
  180. package/src/lib/assets/site-styles/beauty.webp +0 -0
  181. package/src/lib/assets/site-styles/blog.webp +0 -0
  182. package/src/lib/assets/site-styles/business.webp +0 -0
  183. package/src/lib/assets/site-styles/coming-soon.webp +0 -0
  184. package/src/lib/assets/site-styles/education.webp +0 -0
  185. package/src/lib/assets/site-styles/events.webp +0 -0
  186. package/src/lib/assets/site-styles/fitness.webp +0 -0
  187. package/src/lib/assets/site-styles/landing.webp +0 -0
  188. package/src/lib/assets/site-styles/music.webp +0 -0
  189. package/src/lib/assets/site-styles/nonprofit.webp +0 -0
  190. package/src/lib/assets/site-styles/personal.webp +0 -0
  191. package/src/lib/assets/site-styles/photography.webp +0 -0
  192. package/src/lib/assets/site-styles/portfolio.webp +0 -0
  193. package/src/lib/assets/site-styles/professional.webp +0 -0
  194. package/src/lib/assets/site-styles/realestate.webp +0 -0
  195. package/src/lib/assets/site-styles/restaurant.webp +0 -0
  196. package/src/lib/assets/site-styles/store.webp +0 -0
  197. package/src/lib/assets/site-styles/studio.webp +0 -0
  198. package/src/lib/assets/site-styles/trades.webp +0 -0
  199. package/src/lib/assets/site-styles/wellness.webp +0 -0
  200. package/src/lib/assets/site-styles/yoga.webp +0 -0
  201. package/src/lib/site-import/site-import-review.d.ts +0 -40
  202. package/src/lib/site-import/site-import-review.js +0 -149
  203. package/src/lib/site-import/site-import-review.js.map +0 -1
@@ -26,9 +26,11 @@ export declare const AI_SITE_IMPORT_WAVE_PAGES = 10;
26
26
  /**
27
27
  * The most pages one import reads, whatever the plan allows: an unlimited
28
28
  * plan is still one crawl's worth, and the crawl's own time budget may stop
29
- * sooner (the inventory then says so).
29
+ * sooner (the inventory then says so). Only pages count: a file a link
30
+ * points at is never fetched as one (AGL-4106), so aglyn.com's 209 pages fit
31
+ * with room where 136 press-kit files once took 136 of 200.
30
32
  */
31
- export declare const AI_SITE_IMPORT_MAX_PAGES = 200;
33
+ export declare const AI_SITE_IMPORT_MAX_PAGES = 400;
32
34
  /** The fewest pages under one address prefix that make it a collection. */
33
35
  export declare const AI_SITE_IMPORT_COLLECTION_MIN = 3;
34
36
  /** The most photos brought in from one page. */
@@ -45,16 +47,21 @@ export declare const AI_SITE_IMPORT_MAX_SECTIONS = 24;
45
47
  export declare const AI_SITE_IMPORT_READ_MAX_BLOCKS = 2000;
46
48
  /** The most characters of one page's blocks a wave's read keeps: a long policy is 40,000. */
47
49
  export declare const AI_SITE_IMPORT_READ_MAX_CHARS = 120000;
50
+ /** The most characters one page's layout keeps on the job document (AGL-4106): its icons' drawings go first. */
51
+ export declare const AI_SITE_IMPORT_LAYOUT_MAX_CHARS = 48000;
48
52
  /**
49
- * The most characters of blocks the reads of one import hold at once: they
53
+ * The most characters of blocks (and their layouts, AGL-4106) the reads of one import hold at once: they
50
54
  * ride the job document, which Firestore caps at 1 MiB, beside the
51
55
  * inventory and the ledger. A wave's later page past it keeps what fits and
52
56
  * says it was cut.
53
57
  */
54
58
  export declare const AI_SITE_IMPORT_WAVE_READ_MAX_CHARS = 400000;
55
59
  /**
56
- * A page with more words of its own than this is copied as it is, never
57
- * arranged (AGL-4083): a policy, an article, a long story.
60
+ * A collection's page longer than this is prose: a policy, an article, a
61
+ * long story (AGL-4083). A collection's page is copied as it is whatever its
62
+ * length, and since AGL-4106 a main page is arranged whatever its length:
63
+ * `/product` at 1,072 words is laid out as its source lays it out, not copied
64
+ * as one column.
58
65
  */
59
66
  export declare const AI_SITE_IMPORT_PROSE_WORDS = 900;
60
67
  /** The answers bot protection and firewalls turn a crawler away with: asked to sign in, refused, or told to slow down. */
@@ -110,7 +117,9 @@ export type AiSiteImportLeftOutReason =
110
117
  /** It sends visitors to another website. */
111
118
  | 'off-site'
112
119
  /** The read stopped (its clock, its bytes, its page count) before it got to it (AGL-4083). */
113
- | 'not-reached';
120
+ | 'not-reached'
121
+ /** A link to a file (a download, a PDF with no extension), not a page (AGL-4106). */
122
+ | 'file';
114
123
  export declare const AI_SITE_IMPORT_LEFT_OUT_REASONS: readonly AiSiteImportLeftOutReason[];
115
124
  /** The reasons that mean the page was there and AglynBot could not read it: the "could not be read" of what was found. */
116
125
  export declare const AI_SITE_IMPORT_UNREAD_REASONS: readonly AiSiteImportLeftOutReason[];
@@ -130,6 +139,250 @@ export interface AiSiteImportPhoto {
130
139
  /** The address on the old site it was read from, where a page that is copied places it (AGL-4084). */
131
140
  from?: string;
132
141
  }
142
+ /**
143
+ * One line of a page, by its index in the page's main-region blocks
144
+ * (`AiSiteImportPageRead.blocks`, 0-based). The layout holds no words of
145
+ * its own: every word is a block's, placed once.
146
+ */
147
+ export type SiteImportLineRef = number;
148
+ /** A section's background, in the layout language's bands. */
149
+ export type SiteImportBand = 'plain' | 'soft' | 'brand' | 'dark';
150
+ /** How the source draws a button: filled, outlined, or as a link with button padding. */
151
+ export type SiteImportButtonStyle = 'primary' | 'secondary' | 'quiet';
152
+ /** What a repeated group of the source is. */
153
+ export type SiteImportGroupKind = 'cards' | 'steps' | 'stats' | 'faq' | 'quotes' | 'logos' | 'pricing' | 'list' | 'text';
154
+ export declare const SITE_IMPORT_GROUP_KINDS: readonly SiteImportGroupKind[];
155
+ /** One line in place. `role` only where the source's own styling says it (an uppercase eyebrow, a large lede, a small note). */
156
+ export interface SiteImportLayoutLine {
157
+ kind: 'line';
158
+ line: SiteImportLineRef;
159
+ role?: 'eyebrow' | 'lede' | 'note';
160
+ /** The source draws this line (a link, or a `<button>`'s words) as a button. Its destination is the link block's `href`. */
161
+ button?: SiteImportButtonStyle;
162
+ }
163
+ /** A picture in place: an image block. */
164
+ export interface SiteImportLayoutPicture {
165
+ kind: 'picture';
166
+ line: SiteImportLineRef;
167
+ /** Where clicking it goes, when it sits in a link. */
168
+ href?: string;
169
+ /** It sits in a `<button>` (a video's poster, a lightbox): the picture is kept, the button is not a destination. */
170
+ button?: true;
171
+ }
172
+ /** An icon standing on its own, by index into `SiteImportLayout.icons`. */
173
+ export interface SiteImportLayoutIcon {
174
+ kind: 'icon';
175
+ icon: number;
176
+ }
177
+ /** Where one of the page's forms sat, by index into `AiSiteImportPageRead.forms`. */
178
+ export interface SiteImportLayoutForm {
179
+ kind: 'form';
180
+ form: number;
181
+ }
182
+ /**
183
+ * A row of columns side by side; `cols` are relative widths in twelfths
184
+ * (`[4, 8]`, `[1, 1, 1]`). Every list of lists is a list of objects: the
185
+ * layout rides a Firestore document, which holds no array inside an array.
186
+ */
187
+ export interface SiteImportLayoutRow {
188
+ kind: 'row';
189
+ cols: number[];
190
+ cells: Array<{
191
+ nodes: SiteImportLayoutNode[];
192
+ }>;
193
+ }
194
+ /**
195
+ * One item of a group. Every line of the item is in `lines`, in order, and
196
+ * in exactly one of the named parts.
197
+ */
198
+ export interface SiteImportLayoutItem {
199
+ lines: SiteImportLineRef[];
200
+ /** The item's name: its heading, its title link, or its first short line. */
201
+ title?: SiteImportLineRef;
202
+ /** A stat's figure, a step's number, a plan's price. */
203
+ figure?: SiteImportLineRef;
204
+ text?: SiteImportLineRef[];
205
+ /** Its bullet points (a plan's features). */
206
+ list?: SiteImportLineRef[];
207
+ /** Its own call to action: a "See … →" link or a button, last in the item. */
208
+ link?: SiteImportLineRef[];
209
+ image?: SiteImportLineRef;
210
+ /** The icon that leads it, by index into `SiteImportLayout.icons`. */
211
+ icon?: number;
212
+ /** The icon each of its bullet points carries (a check mark), when they share one. */
213
+ listIcon?: number;
214
+ /** Where the item goes as a whole: its title link's address. */
215
+ to?: string;
216
+ }
217
+ export interface SiteImportLayoutGroup {
218
+ kind: 'group';
219
+ group: SiteImportGroupKind;
220
+ /** Columns the source lays the items out in on a wide screen. */
221
+ columns: number;
222
+ /** Each item is drawn as a box (a border, a shadow or a fill of its own). */
223
+ boxed: boolean;
224
+ items: SiteImportLayoutItem[];
225
+ }
226
+ /** A table: rows of cells, each cell its lines (objects, not nested arrays, for Firestore). */
227
+ export interface SiteImportLayoutTable {
228
+ kind: 'table';
229
+ /** Whether the first row names the columns. */
230
+ header: boolean;
231
+ rows: Array<{
232
+ cells: Array<{
233
+ lines: SiteImportLineRef[];
234
+ }>;
235
+ }>;
236
+ }
237
+ /** A tab strip and its panels; a panel the source did not draw is empty. */
238
+ export interface SiteImportLayoutTabs {
239
+ kind: 'tabs';
240
+ tabs: Array<{
241
+ label: SiteImportLineRef | null;
242
+ selected?: true;
243
+ panel: SiteImportLayoutNode[];
244
+ }>;
245
+ }
246
+ export type SiteImportLayoutNode = SiteImportLayoutLine | SiteImportLayoutPicture | SiteImportLayoutIcon | SiteImportLayoutForm | SiteImportLayoutRow | SiteImportLayoutGroup | SiteImportLayoutTable | SiteImportLayoutTabs;
247
+ /** Where the hero's picture sits against its words. */
248
+ export type SiteImportHeroPicture = 'beside' | 'behind' | 'below' | 'above';
249
+ export interface SiteImportLayoutSection {
250
+ /** Its `aria-label`, its heading, or "Section n": neutralized, cut to a label. */
251
+ name: string;
252
+ /** How its edges were found: a landmark (`<section>`), a container of its own, or its headings. */
253
+ from: 'landmark' | 'container' | 'heading';
254
+ band: SiteImportBand;
255
+ /** Its background color as `#rrggbb`, when it has one. */
256
+ background: string | null;
257
+ /** A gradient or a photo behind it. */
258
+ backdrop?: {
259
+ kind: 'gradient';
260
+ } | {
261
+ kind: 'picture';
262
+ url: string;
263
+ };
264
+ align: 'start' | 'center';
265
+ /** Set on the section holding the page's first `<h1>`. */
266
+ hero?: {
267
+ picture: SiteImportHeroPicture | null;
268
+ };
269
+ nodes: SiteImportLayoutNode[];
270
+ /** Every line of the section, in order. */
271
+ lines: SiteImportLineRef[];
272
+ }
273
+ /** An icon the page draws, once however often it repeats. */
274
+ export interface SiteImportIconShape {
275
+ viewBox: string;
276
+ /** One path, for the Besigner's icon element (`iconPath`, drawn on a 24-unit square). */
277
+ path?: string;
278
+ /** A small drawing of several shapes, geometry only, for a picture of it. */
279
+ svg?: string;
280
+ }
281
+ /** What the source's look is made of (AGL-4106), read from its stylesheets. */
282
+ export interface SiteImportLookFacts {
283
+ fonts: {
284
+ /** The family its body text is set in, as named, when it is not a system font. */
285
+ body: string | null;
286
+ /** The family its headings are set in. */
287
+ headings: string | null;
288
+ /** The families it loads from Google Fonts, in order. */
289
+ google: string[];
290
+ };
291
+ /** The page's own background, `#rrggbb`. */
292
+ background: string | null;
293
+ /** Its body text color. */
294
+ text: string | null;
295
+ /** The fill of its filled buttons, the most used first. */
296
+ buttonFill: string | null;
297
+ /** The text color on them. */
298
+ buttonText: string | null;
299
+ /** Its buttons' corner radius, px. */
300
+ buttonRadius: number | null;
301
+ /** The color its text links are drawn in. */
302
+ link: string | null;
303
+ /** Its header bar's background. */
304
+ header: string | null;
305
+ }
306
+ /** A page's layout, as the source lays it out (AGL-4106). */
307
+ export interface SiteImportLayout {
308
+ v: 1;
309
+ sections: SiteImportLayoutSection[];
310
+ icons: SiteImportIconShape[];
311
+ look: SiteImportLookFacts;
312
+ }
313
+ /** One entry of a menu, as the source's header shows it. */
314
+ export interface SiteImportNavEntry {
315
+ label: string;
316
+ /** The line under it in a mega menu. */
317
+ text?: string;
318
+ /** Where it goes: absolute http(s), `mailto:` or `tel:`. */
319
+ href: string;
320
+ /** Its icon, when it has a one-path icon. */
321
+ iconPath?: string;
322
+ viewBox?: string;
323
+ /** The heading of the menu's column it sits in ("By team"). */
324
+ column?: string;
325
+ }
326
+ /** A top-level item of the source's menu: a link, or a menu of entries under a name. */
327
+ export interface SiteImportNavGroup {
328
+ label: string;
329
+ /** Where the name itself goes; `null` when it only opens its menu. */
330
+ href: string | null;
331
+ /** Empty for a plain link. */
332
+ items: SiteImportNavEntry[];
333
+ }
334
+ /** A button in the source's header outside its menu ("Sign in", "Start free"). */
335
+ export interface SiteImportNavCta {
336
+ label: string;
337
+ href: string | null;
338
+ style: SiteImportButtonStyle;
339
+ }
340
+ /** The source's header menu (AGL-4106). Untrusted data from the owner's site. */
341
+ export interface SiteImportNavTree {
342
+ items: SiteImportNavGroup[];
343
+ ctas: SiteImportNavCta[];
344
+ /** The source shows a menu button on phones. */
345
+ phoneMenu: boolean;
346
+ /** The header bar's background, `#rrggbb`. */
347
+ background: string | null;
348
+ }
349
+ export interface SiteImportFooterLink {
350
+ label: string;
351
+ href: string;
352
+ }
353
+ /** The source's footer (AGL-4106): its columns, profiles and facts, as written. */
354
+ export interface SiteImportFooter {
355
+ columns: Array<{
356
+ heading: string;
357
+ links: SiteImportFooterLink[];
358
+ }>;
359
+ /** Its links to profiles on other sites. */
360
+ social: Array<SiteImportFooterLink & {
361
+ network: string;
362
+ }>;
363
+ /** Links outside any column and not a profile (Privacy, Terms, Status). */
364
+ links: SiteImportFooterLink[];
365
+ /** Its lines of text outside links (a tagline), as written. */
366
+ text: string[];
367
+ address: string | null;
368
+ phone: string | null;
369
+ email: string | null;
370
+ /** Its © line, word for word. */
371
+ copyright: string | null;
372
+ }
373
+ /** Every line a layout's nodes place, in order. */
374
+ export declare function siteImportLayoutLines(nodes: readonly SiteImportLayoutNode[]): SiteImportLineRef[];
375
+ /** How many characters a layout weighs on the job document. */
376
+ export declare function siteImportLayoutChars(layout: SiteImportLayout | null | undefined): number;
377
+ /**
378
+ * A layout over only the first `count` lines (a read the wave's budget cut
379
+ * short): references past the cut are dropped, and what is left empty goes.
380
+ */
381
+ export declare function siteImportLayoutWithin(layout: SiteImportLayout, count: number): SiteImportLayout;
382
+ /** Nodes with only the lines `keep` keeps; what is left empty goes. */
383
+ export declare function siteImportFilterNodes(list: readonly SiteImportLayoutNode[], keep: (ref: SiteImportLineRef) => boolean): SiteImportLayoutNode[];
384
+ /** A layout with its icons' drawings dropped, for a page that must be lighter. */
385
+ export declare function siteImportLayoutWithoutDrawings(layout: SiteImportLayout): SiteImportLayout;
133
386
  /** What a wave's read found on one page, for its model answer. Never on the wire. */
134
387
  export interface AiSiteImportPageRead {
135
388
  at: string;
@@ -157,6 +410,21 @@ export interface AiSiteImportPageRead {
157
410
  words?: number;
158
411
  /** The forms the page asks visitors to fill in, by their fields. */
159
412
  forms?: SiteImportForm[];
413
+ /**
414
+ * How the source lays the page out (AGL-4106): its sections, bands, rows,
415
+ * groups, pictures, icons and buttons, over `blocks` by index. Absent on a
416
+ * read made before the reader, or when it did not fit the wave's budget.
417
+ */
418
+ layout?: SiteImportLayout | null;
419
+ /**
420
+ * The page's browser title and meta description as the source writes them
421
+ * (AGL-4107), which the new page's listing keeps word for word. Absent on a
422
+ * read made before they were kept.
423
+ */
424
+ meta?: {
425
+ title: string;
426
+ description: string;
427
+ };
160
428
  }
161
429
  /** How a page is built from its old page, as the step chose: its words copied as they are, or arranged by Aglyn AI. */
162
430
  export type AiSiteImportBuild = 'copied' | 'arranged';
@@ -193,7 +461,12 @@ export interface AiSiteImportPage {
193
461
  assets: AiSiteImportPhoto[];
194
462
  } | null;
195
463
  }
196
- export type AiSiteImportWaveStatus = 'waiting' | 'running' | 'review' | 'done';
464
+ /**
465
+ * A wave's place in its import: waiting to start, running, in and waiting for
466
+ * the person's review, in, or `stopped` — the import was canceled before the
467
+ * wave was in, while it ran or before it started (AGL-4107).
468
+ */
469
+ export type AiSiteImportWaveStatus = 'waiting' | 'running' | 'review' | 'done' | 'stopped';
197
470
  export interface AiSiteImportWave {
198
471
  index: number;
199
472
  label: string;
@@ -235,8 +508,6 @@ export interface AiSiteImportState {
235
508
  frame: {
236
509
  draftId: string;
237
510
  } | null;
238
- /** The Trust & Safety row this import is logged under. */
239
- reviewId: string | null;
240
511
  /**
241
512
  * "Start every remaining wave" (AGL-4083): each wave closes and the next
242
513
  * starts with no review between them; the last wave's close is the stop.
@@ -286,7 +557,24 @@ export interface AiSiteImportHome {
286
557
  social: string[];
287
558
  address: string;
288
559
  };
560
+ /**
561
+ * The source's header menu as its home page builds it (AGL-4108): its
562
+ * items, their menus, its buttons. The header and footer are drawn from it
563
+ * with no model; absent on a read made before the reader, or where the home
564
+ * page has no menu the reader can find.
565
+ */
566
+ nav?: SiteImportNavTree | null;
567
+ /** The source's footer as its home page builds it (AGL-4108): its columns, profiles, facts and © line. */
568
+ footer?: SiteImportFooter | null;
569
+ /** What the source's look is made of (AGL-4108): its colors, its button fill and corners, its fonts. */
570
+ look?: SiteImportLookFacts | null;
289
571
  }
572
+ /**
573
+ * Whether the site's header and footer are built from the source's own menu
574
+ * (AGL-4108), with no model: the home page's menu was read. Then the frame
575
+ * costs nothing and is quoted at nothing.
576
+ */
577
+ export declare function aiSiteImportFrameIsRead(state: Pick<AiSiteImportState, 'home'> | null | undefined): boolean;
290
578
  /** What the look pass did (AGL-4084): no model is asked. */
291
579
  export interface AiSiteImportLook {
292
580
  at: string;
@@ -417,7 +705,6 @@ export interface AiSiteImportInventoryInput {
417
705
  existingPages: number;
418
706
  /** Mints one draft id; the inventory names every page's draft before any is written. */
419
707
  mintId: () => string;
420
- reviewId?: string | null;
421
708
  wavePages?: number;
422
709
  }
423
710
  /**
@@ -487,13 +774,20 @@ export declare function aiSiteImportPhotosIn(state: AiSiteImportState, slot: str
487
774
  export declare function aiSiteImportPageSettled(state: AiSiteImportState, slot: string): AiSiteImportState;
488
775
  /** A wave is in: waiting for its review, or done when no wave follows it. */
489
776
  export declare function aiSiteImportWaveClosed(state: AiSiteImportState, index: number, at: string): AiSiteImportState;
777
+ /**
778
+ * The state of an import a person canceled (AGL-4107): every wave settled. A
779
+ * wave that ran, or was waiting to, is stopped; one already in, for review or
780
+ * done, is in. On 10/29 a canceled import still showed its second wave as
781
+ * running, with nothing running it.
782
+ */
783
+ export declare function aiSiteImportCanceled(state: AiSiteImportState, at: string): AiSiteImportState;
490
784
  /** The state as the console reads it: every page's read text left off. */
491
785
  export declare function aiSiteImportWire(state: AiSiteImportState | null | undefined): AiSiteImportState | null;
492
786
  /**
493
787
  * How a page is built (AGL-4083), decided by code: every page of a collection
494
- * (a blog, the legal pages, news) and any page longer than
495
- * `AI_SITE_IMPORT_PROSE_WORDS` is copied as it is; the main pages are
496
- * arranged by Aglyn AI, their words kept as written.
788
+ * (a blog, the legal pages, news) is copied as it is; every main page is
789
+ * arranged by Aglyn AI whatever its length (AGL-4106), its words kept as
790
+ * written. Both are laid out from the source's own layout.
497
791
  */
498
792
  export declare function aiSiteImportPageBuild(page: Pick<AiSiteImportPage, 'group' | 'words'>): AiSiteImportBuild;
499
793
  /**