@aglyn/plugins-ai 1.0.0-beta.270 → 1.0.0-beta.272

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 (281) hide show
  1. package/package.json +17 -17
  2. package/src/lib/activity/ai-activity-actions.d.ts +4 -3
  3. package/src/lib/activity/ai-activity-actions.js +4 -0
  4. package/src/lib/activity/ai-activity-actions.js.map +1 -1
  5. package/src/lib/assets/site-styles/beauty.webp +0 -0
  6. package/src/lib/assets/site-styles/blog.webp +0 -0
  7. package/src/lib/assets/site-styles/business.webp +0 -0
  8. package/src/lib/assets/site-styles/coming-soon.webp +0 -0
  9. package/src/lib/assets/site-styles/education.webp +0 -0
  10. package/src/lib/assets/site-styles/events.webp +0 -0
  11. package/src/lib/assets/site-styles/fitness.webp +0 -0
  12. package/src/lib/assets/site-styles/landing.webp +0 -0
  13. package/src/lib/assets/site-styles/music.webp +0 -0
  14. package/src/lib/assets/site-styles/nonprofit.webp +0 -0
  15. package/src/lib/assets/site-styles/personal.webp +0 -0
  16. package/src/lib/assets/site-styles/photography.webp +0 -0
  17. package/src/lib/assets/site-styles/portfolio.webp +0 -0
  18. package/src/lib/assets/site-styles/professional.webp +0 -0
  19. package/src/lib/assets/site-styles/realestate.webp +0 -0
  20. package/src/lib/assets/site-styles/restaurant.webp +0 -0
  21. package/src/lib/assets/site-styles/store.webp +0 -0
  22. package/src/lib/assets/site-styles/studio.webp +0 -0
  23. package/src/lib/assets/site-styles/trades.webp +0 -0
  24. package/src/lib/assets/site-styles/wellness.webp +0 -0
  25. package/src/lib/assets/site-styles/yoga.webp +0 -0
  26. package/src/lib/components/ai-credits-card.component.d.ts +4 -3
  27. package/src/lib/components/ai-credits-card.component.js +15 -15
  28. package/src/lib/components/ai-credits-card.component.js.map +1 -1
  29. package/src/lib/components/ai-job-input-form.component.d.ts +36 -0
  30. package/src/lib/components/ai-job-input-form.component.js +100 -0
  31. package/src/lib/components/ai-job-input-form.component.js.map +1 -0
  32. package/src/lib/components/ai-job-requests.d.ts +4 -0
  33. package/src/lib/components/ai-job-requests.js +4 -0
  34. package/src/lib/components/ai-job-requests.js.map +1 -1
  35. package/src/lib/components/ai-site-build-page.component.js +18 -0
  36. package/src/lib/components/ai-site-build-page.component.js.map +1 -1
  37. package/src/lib/components/ai-site-import-job.component.d.ts +41 -0
  38. package/src/lib/components/ai-site-import-job.component.js +707 -0
  39. package/src/lib/components/ai-site-import-job.component.js.map +1 -0
  40. package/src/lib/components/ai-site-import-start.component.d.ts +64 -0
  41. package/src/lib/components/ai-site-import-start.component.js +335 -0
  42. package/src/lib/components/ai-site-import-start.component.js.map +1 -0
  43. package/src/lib/components/ai-site-ownership-proof.component.d.ts +42 -0
  44. package/src/lib/components/ai-site-ownership-proof.component.js +353 -0
  45. package/src/lib/components/ai-site-ownership-proof.component.js.map +1 -0
  46. package/src/lib/components/ai-site-start-card.component.d.ts +1 -1
  47. package/src/lib/components/ai-site-start-card.component.js +261 -119
  48. package/src/lib/components/ai-site-start-card.component.js.map +1 -1
  49. package/src/lib/components/ai-site-start-steps.component.d.ts +43 -2
  50. package/src/lib/components/ai-site-start-steps.component.js +651 -15
  51. package/src/lib/components/ai-site-start-steps.component.js.map +1 -1
  52. package/src/lib/components/ai-site-start-tracking.d.ts +10 -0
  53. package/src/lib/components/ai-site-start-tracking.js +14 -0
  54. package/src/lib/components/ai-site-start-tracking.js.map +1 -1
  55. package/src/lib/components/ai-site-style-previews.js +26 -22
  56. package/src/lib/components/ai-site-style-previews.js.map +1 -1
  57. package/src/lib/components/ai-upsell-dialog.component.d.ts +7 -5
  58. package/src/lib/components/ai-upsell-dialog.component.js +8 -6
  59. package/src/lib/components/ai-upsell-dialog.component.js.map +1 -1
  60. package/src/lib/components/assist-build-card.component.js +11 -1
  61. package/src/lib/components/assist-build-card.component.js.map +1 -1
  62. package/src/lib/components/assist-jobs-drawer.component.js +9 -1
  63. package/src/lib/components/assist-jobs-drawer.component.js.map +1 -1
  64. package/src/lib/components/assist-panel.component.js +8 -4
  65. package/src/lib/components/assist-panel.component.js.map +1 -1
  66. package/src/lib/components/staff-org-ai-card.component.js +4 -7
  67. package/src/lib/components/staff-org-ai-card.component.js.map +1 -1
  68. package/src/lib/declarations.d.ts +2 -2
  69. package/src/lib/declarations.js +9 -5
  70. package/src/lib/declarations.js.map +1 -1
  71. package/src/lib/jobs/ai-build-capabilities.js +3 -1
  72. package/src/lib/jobs/ai-build-capabilities.js.map +1 -1
  73. package/src/lib/jobs/ai-business-profile-prefill.d.ts +1 -1
  74. package/src/lib/jobs/ai-business-profile-prefill.js +14 -3
  75. package/src/lib/jobs/ai-business-profile-prefill.js.map +1 -1
  76. package/src/lib/jobs/ai-job-build-step.js +5 -3
  77. package/src/lib/jobs/ai-job-build-step.js.map +1 -1
  78. package/src/lib/jobs/ai-job-drafts.d.ts +14 -0
  79. package/src/lib/jobs/ai-job-drafts.js +24 -0
  80. package/src/lib/jobs/ai-job-drafts.js.map +1 -1
  81. package/src/lib/jobs/ai-job-form-step.d.ts +15 -1
  82. package/src/lib/jobs/ai-job-form-step.js +75 -8
  83. package/src/lib/jobs/ai-job-form-step.js.map +1 -1
  84. package/src/lib/jobs/ai-job-import-step.d.ts +136 -0
  85. package/src/lib/jobs/ai-job-import-step.js +809 -0
  86. package/src/lib/jobs/ai-job-import-step.js.map +1 -0
  87. package/src/lib/jobs/ai-job-page-language.d.ts +52 -1
  88. package/src/lib/jobs/ai-job-page-language.js +99 -5
  89. package/src/lib/jobs/ai-job-page-language.js.map +1 -1
  90. package/src/lib/jobs/ai-job-page-step.d.ts +19 -2
  91. package/src/lib/jobs/ai-job-page-step.js +42 -18
  92. package/src/lib/jobs/ai-job-page-step.js.map +1 -1
  93. package/src/lib/jobs/ai-job-plan-step.d.ts +25 -2
  94. package/src/lib/jobs/ai-job-plan-step.js +103 -29
  95. package/src/lib/jobs/ai-job-plan-step.js.map +1 -1
  96. package/src/lib/jobs/ai-job-settings-step.js +4 -3
  97. package/src/lib/jobs/ai-job-settings-step.js.map +1 -1
  98. package/src/lib/jobs/ai-job-site-datasets.d.ts +27 -0
  99. package/src/lib/jobs/ai-job-site-datasets.js +140 -14
  100. package/src/lib/jobs/ai-job-site-datasets.js.map +1 -1
  101. package/src/lib/jobs/ai-job-site-look.js +18 -5
  102. package/src/lib/jobs/ai-job-site-look.js.map +1 -1
  103. package/src/lib/jobs/ai-job-site-step.d.ts +16 -1
  104. package/src/lib/jobs/ai-job-site-step.js +95 -22
  105. package/src/lib/jobs/ai-job-site-step.js.map +1 -1
  106. package/src/lib/jobs/ai-job-text-step.d.ts +15 -1
  107. package/src/lib/jobs/ai-job-text-step.js.map +1 -1
  108. package/src/lib/jobs/ai-job-tracking-step.d.ts +14 -3
  109. package/src/lib/jobs/ai-job-tracking-step.js +28 -5
  110. package/src/lib/jobs/ai-job-tracking-step.js.map +1 -1
  111. package/src/lib/jobs/ai-jobs.d.ts +13 -1
  112. package/src/lib/jobs/ai-jobs.js +77 -10
  113. package/src/lib/jobs/ai-jobs.js.map +1 -1
  114. package/src/lib/jobs/ai-layout-owner-photos.d.ts +16 -1
  115. package/src/lib/jobs/ai-layout-owner-photos.js +47 -0
  116. package/src/lib/jobs/ai-layout-owner-photos.js.map +1 -1
  117. package/src/lib/jobs/ai-layout-stock-photos.d.ts +27 -2
  118. package/src/lib/jobs/ai-layout-stock-photos.js +190 -19
  119. package/src/lib/jobs/ai-layout-stock-photos.js.map +1 -1
  120. package/src/lib/jobs/ai-site-inspiration-signals.d.ts +98 -0
  121. package/src/lib/jobs/ai-site-inspiration-signals.js +585 -0
  122. package/src/lib/jobs/ai-site-inspiration-signals.js.map +1 -0
  123. package/src/lib/jobs/ai-site-inspiration.d.ts +157 -0
  124. package/src/lib/jobs/ai-site-inspiration.js +346 -0
  125. package/src/lib/jobs/ai-site-inspiration.js.map +1 -0
  126. package/src/lib/jobs/ai-site-publish.d.ts +26 -1
  127. package/src/lib/jobs/ai-site-publish.js +162 -13
  128. package/src/lib/jobs/ai-site-publish.js.map +1 -1
  129. package/src/lib/jobs/ai-theme-brand-inputs.d.ts +77 -3
  130. package/src/lib/jobs/ai-theme-brand-inputs.js +135 -31
  131. package/src/lib/jobs/ai-theme-brand-inputs.js.map +1 -1
  132. package/src/lib/jobs/fixtures/ai-candle-shop-free-plan-recording.d.ts +97 -0
  133. package/src/lib/jobs/fixtures/ai-candle-shop-free-plan-recording.js +137 -0
  134. package/src/lib/jobs/fixtures/ai-candle-shop-free-plan-recording.js.map +1 -0
  135. package/src/lib/jobs/fixtures/ai-site-inspiration-pages.d.ts +38 -0
  136. package/src/lib/jobs/fixtures/ai-site-inspiration-pages.js +103 -0
  137. package/src/lib/jobs/fixtures/ai-site-inspiration-pages.js.map +1 -0
  138. package/src/lib/jobs/fixtures/ai-stock-photo-agl3988-recordings.d.ts +25 -0
  139. package/src/lib/jobs/fixtures/ai-stock-photo-agl3988-recordings.js +174 -0
  140. package/src/lib/jobs/fixtures/ai-stock-photo-agl3988-recordings.js.map +1 -0
  141. package/src/lib/layout-language/ai-layout-compiler.d.ts +1 -1
  142. package/src/lib/layout-language/ai-layout-compiler.js +438 -25
  143. package/src/lib/layout-language/ai-layout-compiler.js.map +1 -1
  144. package/src/lib/layout-language/ai-layout-contact.d.ts +57 -0
  145. package/src/lib/layout-language/ai-layout-contact.js +137 -0
  146. package/src/lib/layout-language/ai-layout-contact.js.map +1 -0
  147. package/src/lib/layout-language/ai-layout-copy.d.ts +12 -0
  148. package/src/lib/layout-language/ai-layout-copy.js +34 -2
  149. package/src/lib/layout-language/ai-layout-copy.js.map +1 -1
  150. package/src/lib/layout-language/ai-layout-design.d.ts +65 -8
  151. package/src/lib/layout-language/ai-layout-design.js +411 -97
  152. package/src/lib/layout-language/ai-layout-design.js.map +1 -1
  153. package/src/lib/layout-language/ai-layout-frame.js +23 -0
  154. package/src/lib/layout-language/ai-layout-frame.js.map +1 -1
  155. package/src/lib/layout-language/ai-layout-labels.d.ts +2 -0
  156. package/src/lib/layout-language/ai-layout-labels.js +12 -6
  157. package/src/lib/layout-language/ai-layout-labels.js.map +1 -1
  158. package/src/lib/layout-language/ai-layout-language.d.ts +3 -2
  159. package/src/lib/layout-language/ai-layout-language.js +4 -3
  160. package/src/lib/layout-language/ai-layout-language.js.map +1 -1
  161. package/src/lib/layout-language/ai-layout-links.d.ts +13 -0
  162. package/src/lib/layout-language/ai-layout-links.js +30 -0
  163. package/src/lib/layout-language/ai-layout-links.js.map +1 -1
  164. package/src/lib/layout-language/ai-layout-pictures.d.ts +49 -6
  165. package/src/lib/layout-language/ai-layout-pictures.js +145 -22
  166. package/src/lib/layout-language/ai-layout-pictures.js.map +1 -1
  167. package/src/lib/model/ai-build-job.d.ts +16 -1
  168. package/src/lib/model/ai-build-job.js +40 -0
  169. package/src/lib/model/ai-build-job.js.map +1 -1
  170. package/src/lib/model/ai-credit-estimate.d.ts +20 -0
  171. package/src/lib/model/ai-credit-estimate.js +13 -0
  172. package/src/lib/model/ai-credit-estimate.js.map +1 -1
  173. package/src/lib/model/ai-job-activity.d.ts +2 -2
  174. package/src/lib/model/ai-job-activity.js +6 -4
  175. package/src/lib/model/ai-job-activity.js.map +1 -1
  176. package/src/lib/model/ai-job-input.d.ts +33 -0
  177. package/src/lib/model/ai-job-input.js +59 -0
  178. package/src/lib/model/ai-job-input.js.map +1 -0
  179. package/src/lib/model/ai-job-notice.d.ts +4 -0
  180. package/src/lib/model/ai-job-notice.js +28 -4
  181. package/src/lib/model/ai-job-notice.js.map +1 -1
  182. package/src/lib/model/ai-jobs.types.d.ts +69 -3
  183. package/src/lib/model/ai-jobs.types.js +2 -1
  184. package/src/lib/model/ai-jobs.types.js.map +1 -1
  185. package/src/lib/model/ai-site-details.d.ts +122 -0
  186. package/src/lib/model/ai-site-details.js +300 -0
  187. package/src/lib/model/ai-site-details.js.map +1 -0
  188. package/src/lib/model/ai-site-entity.d.ts +181 -0
  189. package/src/lib/model/ai-site-entity.js +390 -0
  190. package/src/lib/model/ai-site-entity.js.map +1 -0
  191. package/src/lib/model/ai-site-import-view.d.ts +130 -0
  192. package/src/lib/model/ai-site-import-view.js +182 -0
  193. package/src/lib/model/ai-site-import-view.js.map +1 -0
  194. package/src/lib/model/ai-site-import.d.ts +302 -0
  195. package/src/lib/model/ai-site-import.js +526 -0
  196. package/src/lib/model/ai-site-import.js.map +1 -0
  197. package/src/lib/model/ai-site-inspiration.d.ts +72 -0
  198. package/src/lib/model/ai-site-inspiration.js +109 -0
  199. package/src/lib/model/ai-site-inspiration.js.map +1 -0
  200. package/src/lib/model/ai-site-job.d.ts +13 -1
  201. package/src/lib/model/ai-site-job.js +15 -2
  202. package/src/lib/model/ai-site-job.js.map +1 -1
  203. package/src/lib/model/ai-site-kinds.js +109 -21
  204. package/src/lib/model/ai-site-kinds.js.map +1 -1
  205. package/src/lib/model/ai-site-look.d.ts +10 -0
  206. package/src/lib/model/ai-site-look.js +24 -0
  207. package/src/lib/model/ai-site-look.js.map +1 -1
  208. package/src/lib/model/ai-site-start-seo.d.ts +19 -5
  209. package/src/lib/model/ai-site-start-seo.js +25 -7
  210. package/src/lib/model/ai-site-start-seo.js.map +1 -1
  211. package/src/lib/model/ai-site-start-steps.d.ts +9 -3
  212. package/src/lib/model/ai-site-start-steps.js +67 -5
  213. package/src/lib/model/ai-site-start-steps.js.map +1 -1
  214. package/src/lib/model/ai-site-start.d.ts +81 -4
  215. package/src/lib/model/ai-site-start.js +207 -13
  216. package/src/lib/model/ai-site-start.js.map +1 -1
  217. package/src/lib/model/ai-upsell-copy.js +4 -1
  218. package/src/lib/model/ai-upsell-copy.js.map +1 -1
  219. package/src/lib/plan-entitlements.d.ts +4 -3
  220. package/src/lib/plan-entitlements.js +3 -8
  221. package/src/lib/plan-entitlements.js.map +1 -1
  222. package/src/lib/runtime/ai-dataset-generation.d.ts +8 -1
  223. package/src/lib/runtime/ai-dataset-generation.js +12 -2
  224. package/src/lib/runtime/ai-dataset-generation.js.map +1 -1
  225. package/src/lib/runtime/ai-doctrine-validators.d.ts +26 -33
  226. package/src/lib/runtime/ai-doctrine-validators.js +54 -44
  227. package/src/lib/runtime/ai-doctrine-validators.js.map +1 -1
  228. package/src/lib/runtime/ai-doctrine.js +1 -1
  229. package/src/lib/runtime/ai-doctrine.js.map +1 -1
  230. package/src/lib/runtime/ai-node-tree.d.ts +7 -0
  231. package/src/lib/runtime/ai-node-tree.js +9 -1
  232. package/src/lib/runtime/ai-node-tree.js.map +1 -1
  233. package/src/lib/server/ai-create-route.d.ts +1 -1
  234. package/src/lib/server/ai-create-route.js +3 -4
  235. package/src/lib/server/ai-create-route.js.map +1 -1
  236. package/src/lib/server/ai-jobs-resume.js +27 -3
  237. package/src/lib/server/ai-jobs-resume.js.map +1 -1
  238. package/src/lib/server/ai-jobs-route.js +18 -0
  239. package/src/lib/server/ai-jobs-route.js.map +1 -1
  240. package/src/lib/server/ai-site-import-route.d.ts +89 -0
  241. package/src/lib/server/ai-site-import-route.js +356 -0
  242. package/src/lib/server/ai-site-import-route.js.map +1 -0
  243. package/src/lib/server.js +14 -0
  244. package/src/lib/server.js.map +1 -1
  245. package/src/lib/site-import/fixtures/site-import-crawl-recordings.d.ts +45 -0
  246. package/src/lib/site-import/fixtures/site-import-crawl-recordings.js +313 -0
  247. package/src/lib/site-import/fixtures/site-import-crawl-recordings.js.map +1 -0
  248. package/src/lib/site-import/fixtures/site-import-wave-recordings.d.ts +50 -0
  249. package/src/lib/site-import/fixtures/site-import-wave-recordings.js +217 -0
  250. package/src/lib/site-import/fixtures/site-import-wave-recordings.js.map +1 -0
  251. package/src/lib/site-import/site-import-crawl.d.ts +163 -0
  252. package/src/lib/site-import/site-import-crawl.js +467 -0
  253. package/src/lib/site-import/site-import-crawl.js.map +1 -0
  254. package/src/lib/site-import/site-import-flag.d.ts +23 -0
  255. package/src/lib/site-import/site-import-flag.js +23 -0
  256. package/src/lib/site-import/site-import-flag.js.map +1 -0
  257. package/src/lib/site-import/site-import-html.d.ts +94 -0
  258. package/src/lib/site-import/site-import-html.js +462 -0
  259. package/src/lib/site-import/site-import-html.js.map +1 -0
  260. package/src/lib/site-import/site-import-images.d.ts +54 -0
  261. package/src/lib/site-import/site-import-images.js +204 -0
  262. package/src/lib/site-import/site-import-images.js.map +1 -0
  263. package/src/lib/site-import/site-import-page.d.ts +48 -0
  264. package/src/lib/site-import/site-import-page.js +150 -0
  265. package/src/lib/site-import/site-import-page.js.map +1 -0
  266. package/src/lib/site-import/site-import-review.d.ts +40 -0
  267. package/src/lib/site-import/site-import-review.js +149 -0
  268. package/src/lib/site-import/site-import-review.js.map +1 -0
  269. package/src/lib/site-import/site-import-robots.d.ts +52 -0
  270. package/src/lib/site-import/site-import-robots.js +126 -0
  271. package/src/lib/site-import/site-import-robots.js.map +1 -0
  272. package/src/lib/usage/assist-credits.d.ts +4 -4
  273. package/src/lib/usage/assist-credits.js +4 -4
  274. package/src/lib/usage/assist-credits.js.map +1 -1
  275. package/src/lib/usage/staff-org-ai-view.js +6 -3
  276. package/src/lib/usage/staff-org-ai-view.js.map +1 -1
  277. package/src/lib/usage/staff-org-ai.d.ts +4 -2
  278. package/src/lib/usage/staff-org-ai.js +7 -7
  279. package/src/lib/usage/staff-org-ai.js.map +1 -1
  280. package/src/lib/usage/staff-org-usage-ai.js +2 -2
  281. package/src/lib/usage/staff-org-usage-ai.js.map +1 -1
@@ -0,0 +1,72 @@
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
+ /**
18
+ * Sites I like (AGL-3975, part of AGL-3973): the sites a person names in the
19
+ * guided start as inspiration, as the job carries them.
20
+ *
21
+ * Free names one site and a paid plan three. From each the site job takes
22
+ * SIGNALS only — how the sections run, the colors, the type's mood, the shape
23
+ * of buttons and cards, how the pages move and, on a paid plan, which
24
+ * features it offers — each read by code into the site job's own closed sets
25
+ * (`jobs/ai-site-inspiration-signals.ts`). Never a word, a picture or a logo
26
+ * of theirs: nothing a page says reaches a prompt.
27
+ *
28
+ * Behind `release_ai_site_inspiration`, off by default: with it off the
29
+ * guided start asks for no site and a job's inspiration is never read.
30
+ *
31
+ * Pure and console-safe: the input's name, the limits and how an answer is
32
+ * read. No network.
33
+ */
34
+ /** The release flag the whole feature waits behind. */
35
+ export declare const AI_SITE_INSPIRATION_FLAG: "release_ai_site_inspiration";
36
+ /**
37
+ * The job input the sites travel in: one string, the addresses separated by
38
+ * spaces, because a job's inputs are scalars (`parseCreateAiJobBody`).
39
+ */
40
+ export declare const AI_SITE_INSPIRATION_INPUT = "inspiration";
41
+ /** How many sites a plan may name: Free one, every paid plan three. */
42
+ export declare const AI_SITE_INSPIRATION_LIMITS: {
43
+ readonly free: 1;
44
+ readonly paid: 3;
45
+ };
46
+ /** The most any job may carry, whatever its plan. */
47
+ export declare const AI_SITE_INSPIRATION_MAX: 3;
48
+ /** The longest address one site may be given as. */
49
+ export declare const AI_SITE_INSPIRATION_URL_MAX_CHARS = 300;
50
+ /** What the guided start says a paid plan adds, beside a Free workspace's locked fields. */
51
+ export declare const AI_SITE_INSPIRATION_PAID_NOTE: string;
52
+ /** How many sites a workspace may name. */
53
+ export declare function aiSiteInspirationLimit(freeTaste: boolean | null | undefined): number;
54
+ /**
55
+ * One address as the job keeps it: https only, no credentials, the default
56
+ * port, no fragment. `null` for anything else. A bare host ("example.com")
57
+ * is read as its https address, the way a person types one.
58
+ */
59
+ export declare function aiSiteInspirationUrl(value: unknown): string | null;
60
+ /**
61
+ * The sites a job's inputs name, or the sentence the door refuses them with.
62
+ * Absent or empty is none. Each must be an https address; more than
63
+ * {@link AI_SITE_INSPIRATION_MAX} is refused, and the same site twice counts
64
+ * once. The plan's own limit is the door's (`aiSiteInspirationRefusal`).
65
+ */
66
+ export declare function parseAiSiteInspiration(inputs: Readonly<Record<string, unknown>> | null | undefined): string[] | string;
67
+ /** Why a workspace may not name this many sites, in a sentence a member reads; `null` when it may. */
68
+ export declare function aiSiteInspirationRefusal(urls: readonly string[], freeTaste: boolean | null | undefined): string | null;
69
+ /** The sites as the job input carries them; empty for none, which the start leaves out of its inputs. */
70
+ export declare function aiSiteInspirationInput(urls: readonly string[]): string;
71
+ /** A site as the review names it: its host, without `www.`. */
72
+ export declare function aiSiteInspirationHost(url: string): string;
@@ -0,0 +1,109 @@
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
+ * Sites I like (AGL-3975, part of AGL-3973): the sites a person names in the
18
+ * guided start as inspiration, as the job carries them.
19
+ *
20
+ * Free names one site and a paid plan three. From each the site job takes
21
+ * SIGNALS only — how the sections run, the colors, the type's mood, the shape
22
+ * of buttons and cards, how the pages move and, on a paid plan, which
23
+ * features it offers — each read by code into the site job's own closed sets
24
+ * (`jobs/ai-site-inspiration-signals.ts`). Never a word, a picture or a logo
25
+ * of theirs: nothing a page says reaches a prompt.
26
+ *
27
+ * Behind `release_ai_site_inspiration`, off by default: with it off the
28
+ * guided start asks for no site and a job's inspiration is never read.
29
+ *
30
+ * Pure and console-safe: the input's name, the limits and how an answer is
31
+ * read. No network.
32
+ */ /** The release flag the whole feature waits behind. */ export const AI_SITE_INSPIRATION_FLAG = 'release_ai_site_inspiration';
33
+ /**
34
+ * The job input the sites travel in: one string, the addresses separated by
35
+ * spaces, because a job's inputs are scalars (`parseCreateAiJobBody`).
36
+ */ export const AI_SITE_INSPIRATION_INPUT = 'inspiration';
37
+ /** How many sites a plan may name: Free one, every paid plan three. */ export const AI_SITE_INSPIRATION_LIMITS = {
38
+ free: 1,
39
+ paid: 3
40
+ };
41
+ /** The most any job may carry, whatever its plan. */ export const AI_SITE_INSPIRATION_MAX = AI_SITE_INSPIRATION_LIMITS.paid;
42
+ /** The longest address one site may be given as. */ export const AI_SITE_INSPIRATION_URL_MAX_CHARS = 300;
43
+ /** What the guided start says a paid plan adds, beside a Free workspace's locked fields. */ export const AI_SITE_INSPIRATION_PAID_NOTE = `Paid plans can name up to ${AI_SITE_INSPIRATION_LIMITS.paid} sites, and also match the features they offer, like booking, a store or a blog.`;
44
+ /** How many sites a workspace may name. */ export function aiSiteInspirationLimit(freeTaste) {
45
+ return freeTaste ? AI_SITE_INSPIRATION_LIMITS.free : AI_SITE_INSPIRATION_LIMITS.paid;
46
+ }
47
+ /**
48
+ * One address as the job keeps it: https only, no credentials, the default
49
+ * port, no fragment. `null` for anything else. A bare host ("example.com")
50
+ * is read as its https address, the way a person types one.
51
+ */ export function aiSiteInspirationUrl(value) {
52
+ if (typeof value !== 'string') return null;
53
+ const trimmed = value.trim();
54
+ if (!trimmed || trimmed.length > AI_SITE_INSPIRATION_URL_MAX_CHARS) return null;
55
+ const written = /^[a-z][a-z0-9+.-]*:/i.test(trimmed) ? trimmed : `https://${trimmed}`;
56
+ let url;
57
+ try {
58
+ url = new URL(written);
59
+ } catch (unused) {
60
+ return null;
61
+ }
62
+ if (url.protocol !== 'https:' || url.username || url.password) return null;
63
+ if (url.port && url.port !== '443') return null;
64
+ // A host with no dot is a typo or an internal name, never a public site.
65
+ if (!url.hostname.includes('.') || url.hostname.endsWith('.')) return null;
66
+ url.hash = '';
67
+ return url.toString();
68
+ }
69
+ /**
70
+ * The sites a job's inputs name, or the sentence the door refuses them with.
71
+ * Absent or empty is none. Each must be an https address; more than
72
+ * {@link AI_SITE_INSPIRATION_MAX} is refused, and the same site twice counts
73
+ * once. The plan's own limit is the door's (`aiSiteInspirationRefusal`).
74
+ */ export function parseAiSiteInspiration(inputs) {
75
+ const raw = inputs == null ? void 0 : inputs[AI_SITE_INSPIRATION_INPUT];
76
+ if (raw === undefined || raw === null || raw === '') return [];
77
+ if (typeof raw !== 'string') {
78
+ return `${AI_SITE_INSPIRATION_INPUT} must be text: the addresses of the sites you like, separated by spaces`;
79
+ }
80
+ const urls = [];
81
+ for (const word of raw.split(/\s+/).filter(Boolean)){
82
+ const url = aiSiteInspirationUrl(word);
83
+ if (!url) return 'Give each site you like as its https address, like https://example.com.';
84
+ if (!urls.includes(url)) urls.push(url);
85
+ }
86
+ if (urls.length > AI_SITE_INSPIRATION_MAX) return `Name at most ${AI_SITE_INSPIRATION_MAX} sites you like.`;
87
+ return urls;
88
+ }
89
+ /** Why a workspace may not name this many sites, in a sentence a member reads; `null` when it may. */ export function aiSiteInspirationRefusal(urls, freeTaste) {
90
+ const limit = aiSiteInspirationLimit(freeTaste);
91
+ if (urls.length <= limit) return null;
92
+ return freeTaste ? `A Free workspace can name ${AI_SITE_INSPIRATION_LIMITS.free} site you like. ${AI_SITE_INSPIRATION_PAID_NOTE}` : `Name at most ${limit} sites you like.`;
93
+ }
94
+ /** The sites as the job input carries them; empty for none, which the start leaves out of its inputs. */ export function aiSiteInspirationInput(urls) {
95
+ const kept = [];
96
+ for (const url of urls.map(aiSiteInspirationUrl)){
97
+ if (url && !kept.includes(url)) kept.push(url);
98
+ }
99
+ return kept.slice(0, AI_SITE_INSPIRATION_MAX).join(' ');
100
+ }
101
+ /** A site as the review names it: its host, without `www.`. */ export function aiSiteInspirationHost(url) {
102
+ try {
103
+ return new URL(url).hostname.replace(/^www\./, '');
104
+ } catch (unused) {
105
+ return url;
106
+ }
107
+ }
108
+
109
+ //# sourceMappingURL=ai-site-inspiration.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../../../../libs/plugins/ai/src/lib/model/ai-site-inspiration.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\n/**\n * Sites I like (AGL-3975, part of AGL-3973): the sites a person names in the\n * guided start as inspiration, as the job carries them.\n *\n * Free names one site and a paid plan three. From each the site job takes\n * SIGNALS only — how the sections run, the colors, the type's mood, the shape\n * of buttons and cards, how the pages move and, on a paid plan, which\n * features it offers — each read by code into the site job's own closed sets\n * (`jobs/ai-site-inspiration-signals.ts`). Never a word, a picture or a logo\n * of theirs: nothing a page says reaches a prompt.\n *\n * Behind `release_ai_site_inspiration`, off by default: with it off the\n * guided start asks for no site and a job's inspiration is never read.\n *\n * Pure and console-safe: the input's name, the limits and how an answer is\n * read. No network.\n */\n\n/** The release flag the whole feature waits behind. */\nexport const AI_SITE_INSPIRATION_FLAG = 'release_ai_site_inspiration' as const\n\n/**\n * The job input the sites travel in: one string, the addresses separated by\n * spaces, because a job's inputs are scalars (`parseCreateAiJobBody`).\n */\nexport const AI_SITE_INSPIRATION_INPUT = 'inspiration'\n\n/** How many sites a plan may name: Free one, every paid plan three. */\nexport const AI_SITE_INSPIRATION_LIMITS = { free: 1, paid: 3 } as const\n\n/** The most any job may carry, whatever its plan. */\nexport const AI_SITE_INSPIRATION_MAX = AI_SITE_INSPIRATION_LIMITS.paid\n\n/** The longest address one site may be given as. */\nexport const AI_SITE_INSPIRATION_URL_MAX_CHARS = 300\n\n/** What the guided start says a paid plan adds, beside a Free workspace's locked fields. */\nexport const AI_SITE_INSPIRATION_PAID_NOTE = `Paid plans can name up to ${AI_SITE_INSPIRATION_LIMITS.paid} sites, and also match the features they offer, like booking, a store or a blog.`\n\n/** How many sites a workspace may name. */\nexport function aiSiteInspirationLimit(freeTaste: boolean | null | undefined): number {\n return freeTaste ? AI_SITE_INSPIRATION_LIMITS.free : AI_SITE_INSPIRATION_LIMITS.paid\n}\n\n/**\n * One address as the job keeps it: https only, no credentials, the default\n * port, no fragment. `null` for anything else. A bare host (\"example.com\")\n * is read as its https address, the way a person types one.\n */\nexport function aiSiteInspirationUrl(value: unknown): string | null {\n if (typeof value !== 'string') return null\n const trimmed = value.trim()\n if (!trimmed || trimmed.length > AI_SITE_INSPIRATION_URL_MAX_CHARS) return null\n const written = /^[a-z][a-z0-9+.-]*:/i.test(trimmed) ? trimmed : `https://${trimmed}`\n let url: URL\n try {\n url = new URL(written)\n } catch {\n return null\n }\n if (url.protocol !== 'https:' || url.username || url.password) return null\n if (url.port && url.port !== '443') return null\n // A host with no dot is a typo or an internal name, never a public site.\n if (!url.hostname.includes('.') || url.hostname.endsWith('.')) return null\n url.hash = ''\n return url.toString()\n}\n\n/**\n * The sites a job's inputs name, or the sentence the door refuses them with.\n * Absent or empty is none. Each must be an https address; more than\n * {@link AI_SITE_INSPIRATION_MAX} is refused, and the same site twice counts\n * once. The plan's own limit is the door's (`aiSiteInspirationRefusal`).\n */\nexport function parseAiSiteInspiration(\n inputs: Readonly<Record<string, unknown>> | null | undefined,\n): string[] | string {\n const raw = inputs?.[AI_SITE_INSPIRATION_INPUT]\n if (raw === undefined || raw === null || raw === '') return []\n if (typeof raw !== 'string') {\n return `${AI_SITE_INSPIRATION_INPUT} must be text: the addresses of the sites you like, separated by spaces`\n }\n const urls: string[] = []\n for (const word of raw.split(/\\s+/).filter(Boolean)) {\n const url = aiSiteInspirationUrl(word)\n if (!url) return 'Give each site you like as its https address, like https://example.com.'\n if (!urls.includes(url)) urls.push(url)\n }\n if (urls.length > AI_SITE_INSPIRATION_MAX) return `Name at most ${AI_SITE_INSPIRATION_MAX} sites you like.`\n return urls\n}\n\n/** Why a workspace may not name this many sites, in a sentence a member reads; `null` when it may. */\nexport function aiSiteInspirationRefusal(urls: readonly string[], freeTaste: boolean | null | undefined): string | null {\n const limit = aiSiteInspirationLimit(freeTaste)\n if (urls.length <= limit) return null\n return freeTaste\n ? `A Free workspace can name ${AI_SITE_INSPIRATION_LIMITS.free} site you like. ${AI_SITE_INSPIRATION_PAID_NOTE}`\n : `Name at most ${limit} sites you like.`\n}\n\n/** The sites as the job input carries them; empty for none, which the start leaves out of its inputs. */\nexport function aiSiteInspirationInput(urls: readonly string[]): string {\n const kept: string[] = []\n for (const url of urls.map(aiSiteInspirationUrl)) {\n if (url && !kept.includes(url)) kept.push(url)\n }\n return kept.slice(0, AI_SITE_INSPIRATION_MAX).join(' ')\n}\n\n/** A site as the review names it: its host, without `www.`. */\nexport function aiSiteInspirationHost(url: string): string {\n try {\n return new URL(url).hostname.replace(/^www\\./, '')\n } catch {\n return url\n }\n}\n"],"names":["AI_SITE_INSPIRATION_FLAG","AI_SITE_INSPIRATION_INPUT","AI_SITE_INSPIRATION_LIMITS","free","paid","AI_SITE_INSPIRATION_MAX","AI_SITE_INSPIRATION_URL_MAX_CHARS","AI_SITE_INSPIRATION_PAID_NOTE","aiSiteInspirationLimit","freeTaste","aiSiteInspirationUrl","value","trimmed","trim","length","written","test","url","URL","protocol","username","password","port","hostname","includes","endsWith","hash","toString","parseAiSiteInspiration","inputs","raw","undefined","urls","word","split","filter","Boolean","push","aiSiteInspirationRefusal","limit","aiSiteInspirationInput","kept","map","slice","join","aiSiteInspirationHost","replace"],"mappings":"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"}
@@ -14,6 +14,7 @@
14
14
  * See the License for the specific language governing permissions and
15
15
  * limitations under the License.
16
16
  */
17
+ import { type AiSiteDetails } from './ai-site-details';
17
18
  import { type AiBuildPlan, type AiBuildPlanCreateKind } from './ai-build-plan';
18
19
  import { type AiCreditRange, type AiCreditsPrompt, type AiMeasuredCredits } from './ai-credit-estimate';
19
20
  /**
@@ -420,7 +421,12 @@ export declare const AI_SITE_BATCH_MAX = 25;
420
421
  * distinguishes.
421
422
  */
422
423
  export declare const AI_SITE_BATCH_MIN_HOST_LIMIT = 25;
423
- export interface AiSiteJobInputs {
424
+ /**
425
+ * A scaffold's scalar inputs. The business details (AGL-3979, `AiSiteDetails`)
426
+ * are among them, each `''` where nobody gave it: how to reach the business,
427
+ * where it is, when it is open, where it works and its profiles.
428
+ */
429
+ export interface AiSiteJobInputs extends AiSiteDetails {
424
430
  /** What the business is, in a few words: the brief's subject. */
425
431
  businessType: string;
426
432
  /**
@@ -469,6 +475,12 @@ export interface AiSiteJobInputs {
469
475
  submissions: AiSiteSubmissions | null;
470
476
  /** The batch this job was created under (AGL-2911); `null` for a single site. */
471
477
  batchId: string | null;
478
+ /**
479
+ * The sites the person likes (AGL-3975), as https addresses in the order
480
+ * they gave them; empty for none. Read as signals only, behind
481
+ * `release_ai_site_inspiration`, and never put in front of a model.
482
+ */
483
+ inspiration?: string[];
472
484
  }
473
485
  /**
474
486
  * Where a site's contact form sends what a visitor writes.
@@ -15,6 +15,8 @@ import { _ as _extends } from "@swc/helpers/_/_extends";
15
15
  * See the License for the specific language governing permissions and
16
16
  * limitations under the License.
17
17
  */ import { aiSiteKind } from "./ai-site-kinds.js";
18
+ import { parseAiSiteDetails } from "./ai-site-details.js";
19
+ import { parseAiSiteInspiration } from "./ai-site-inspiration.js";
18
20
  import { AI_BUILD_PLAN_CREATION_NOUNS, aiPlanFormDatasetNames, aiPlanUndeclaredRefs } from "./ai-build-plan.js";
19
21
  import { AI_JOB_CREATE_KINDS } from "./ai-job-creations.js";
20
22
  import { AI_PAGE_CREATE_KINDS } from "./ai-page-job.js";
@@ -557,7 +559,16 @@ const ID_CHARS = /^[A-Za-z0-9_-]{1,64}$/;
557
559
  const rawBatch = inputs == null ? void 0 : inputs['batchId'];
558
560
  const batchId = rawBatch === undefined || rawBatch === null || rawBatch === '' ? null : typeof rawBatch === 'string' && ID_CHARS.test(rawBatch) ? rawBatch : undefined;
559
561
  if (batchId === undefined) return 'batchId is not a batch id';
560
- return {
562
+ // The business details, each held to its own rule (AGL-3979): a phone
563
+ // number that reads as one, an email address, https profile links, a year;
564
+ // hours keep only the lines that read, areas and links one a line.
565
+ const details = parseAiSiteDetails(inputs);
566
+ if (typeof details === 'string') return details;
567
+ // https addresses only, at most three; the door holds a workspace to its
568
+ // plan's own limit (`aiSiteInspirationRefusal`).
569
+ const inspiration = parseAiSiteInspiration(inputs);
570
+ if (typeof inspiration === 'string') return inspiration;
571
+ return _extends({}, details, {
561
572
  businessType,
562
573
  audience: audience,
563
574
  starter: starter,
@@ -569,7 +580,9 @@ const ID_CHARS = /^[A-Za-z0-9_-]{1,64}$/;
569
580
  welcomeEmail: (inputs == null ? void 0 : inputs['welcomeEmail']) !== false,
570
581
  submissions,
571
582
  batchId
572
- };
583
+ }, inspiration.length ? {
584
+ inspiration
585
+ } : {});
573
586
  }
574
587
  /**
575
588
  * Why a workspace cannot ask for this many pages (AGL-3594), in a sentence a