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

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 (237) hide show
  1. package/package.json +17 -17
  2. package/src/lib/activity/ai-activity-actions.d.ts +1 -1
  3. package/src/lib/activity/ai-activity-actions.js +1 -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 +8 -6
  27. package/src/lib/components/ai-credits-card.component.js +39 -22
  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-links.d.ts +6 -0
  33. package/src/lib/components/ai-job-links.js +9 -0
  34. package/src/lib/components/ai-job-links.js.map +1 -1
  35. package/src/lib/components/ai-job-requests.d.ts +4 -0
  36. package/src/lib/components/ai-job-requests.js +4 -0
  37. package/src/lib/components/ai-job-requests.js.map +1 -1
  38. package/src/lib/components/ai-products-hub-card.component.d.ts +6 -0
  39. package/src/lib/components/ai-products-hub-card.component.js +21 -6
  40. package/src/lib/components/ai-products-hub-card.component.js.map +1 -1
  41. package/src/lib/components/ai-site-build-page.component.js +3 -2
  42. package/src/lib/components/ai-site-build-page.component.js.map +1 -1
  43. package/src/lib/components/ai-site-start-card.component.d.ts +1 -1
  44. package/src/lib/components/ai-site-start-card.component.js +99 -31
  45. package/src/lib/components/ai-site-start-card.component.js.map +1 -1
  46. package/src/lib/components/ai-site-start-steps.component.d.ts +43 -2
  47. package/src/lib/components/ai-site-start-steps.component.js +651 -15
  48. package/src/lib/components/ai-site-start-steps.component.js.map +1 -1
  49. package/src/lib/components/ai-site-start-tracking.d.ts +10 -0
  50. package/src/lib/components/ai-site-start-tracking.js +14 -0
  51. package/src/lib/components/ai-site-start-tracking.js.map +1 -1
  52. package/src/lib/components/ai-site-style-previews.js +26 -22
  53. package/src/lib/components/ai-site-style-previews.js.map +1 -1
  54. package/src/lib/components/ai-store-finish-card.component.d.ts +14 -3
  55. package/src/lib/components/ai-store-finish-card.component.js +67 -9
  56. package/src/lib/components/ai-store-finish-card.component.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 +14 -3
  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.d.ts +3 -0
  77. package/src/lib/jobs/ai-job-build-step.js +13 -5
  78. package/src/lib/jobs/ai-job-build-step.js.map +1 -1
  79. package/src/lib/jobs/ai-job-form-step.d.ts +24 -1
  80. package/src/lib/jobs/ai-job-form-step.js +93 -7
  81. package/src/lib/jobs/ai-job-form-step.js.map +1 -1
  82. package/src/lib/jobs/ai-job-page-language.d.ts +35 -11
  83. package/src/lib/jobs/ai-job-page-language.js +68 -2
  84. package/src/lib/jobs/ai-job-page-language.js.map +1 -1
  85. package/src/lib/jobs/ai-job-page-step.d.ts +17 -0
  86. package/src/lib/jobs/ai-job-page-step.js +40 -17
  87. package/src/lib/jobs/ai-job-page-step.js.map +1 -1
  88. package/src/lib/jobs/ai-job-plan-step.d.ts +25 -2
  89. package/src/lib/jobs/ai-job-plan-step.js +103 -29
  90. package/src/lib/jobs/ai-job-plan-step.js.map +1 -1
  91. package/src/lib/jobs/ai-job-settings-step.js +4 -3
  92. package/src/lib/jobs/ai-job-settings-step.js.map +1 -1
  93. package/src/lib/jobs/ai-job-site-datasets.d.ts +27 -0
  94. package/src/lib/jobs/ai-job-site-datasets.js +140 -14
  95. package/src/lib/jobs/ai-job-site-datasets.js.map +1 -1
  96. package/src/lib/jobs/ai-job-site-look.js +18 -5
  97. package/src/lib/jobs/ai-job-site-look.js.map +1 -1
  98. package/src/lib/jobs/ai-job-site-step.d.ts +16 -1
  99. package/src/lib/jobs/ai-job-site-step.js +95 -22
  100. package/src/lib/jobs/ai-job-site-step.js.map +1 -1
  101. package/src/lib/jobs/ai-job-text-step.d.ts +8 -1
  102. package/src/lib/jobs/ai-job-text-step.js.map +1 -1
  103. package/src/lib/jobs/ai-job-tracking-step.d.ts +14 -3
  104. package/src/lib/jobs/ai-job-tracking-step.js +28 -5
  105. package/src/lib/jobs/ai-job-tracking-step.js.map +1 -1
  106. package/src/lib/jobs/ai-jobs.d.ts +8 -1
  107. package/src/lib/jobs/ai-jobs.js +63 -8
  108. package/src/lib/jobs/ai-jobs.js.map +1 -1
  109. package/src/lib/jobs/ai-layout-owner-photos.d.ts +57 -0
  110. package/src/lib/jobs/ai-layout-owner-photos.js +110 -0
  111. package/src/lib/jobs/ai-layout-owner-photos.js.map +1 -0
  112. package/src/lib/jobs/ai-layout-stock-photos.d.ts +62 -4
  113. package/src/lib/jobs/ai-layout-stock-photos.js +523 -72
  114. package/src/lib/jobs/ai-layout-stock-photos.js.map +1 -1
  115. package/src/lib/jobs/ai-site-inspiration-signals.d.ts +98 -0
  116. package/src/lib/jobs/ai-site-inspiration-signals.js +585 -0
  117. package/src/lib/jobs/ai-site-inspiration-signals.js.map +1 -0
  118. package/src/lib/jobs/ai-site-inspiration.d.ts +157 -0
  119. package/src/lib/jobs/ai-site-inspiration.js +346 -0
  120. package/src/lib/jobs/ai-site-inspiration.js.map +1 -0
  121. package/src/lib/jobs/ai-site-publish.d.ts +26 -1
  122. package/src/lib/jobs/ai-site-publish.js +162 -13
  123. package/src/lib/jobs/ai-site-publish.js.map +1 -1
  124. package/src/lib/jobs/ai-theme-brand-inputs.d.ts +16 -0
  125. package/src/lib/jobs/ai-theme-brand-inputs.js +18 -4
  126. package/src/lib/jobs/ai-theme-brand-inputs.js.map +1 -1
  127. package/src/lib/jobs/fixtures/ai-candle-shop-free-plan-recording.d.ts +97 -0
  128. package/src/lib/jobs/fixtures/ai-candle-shop-free-plan-recording.js +137 -0
  129. package/src/lib/jobs/fixtures/ai-candle-shop-free-plan-recording.js.map +1 -0
  130. package/src/lib/jobs/fixtures/ai-site-inspiration-pages.d.ts +38 -0
  131. package/src/lib/jobs/fixtures/ai-site-inspiration-pages.js +103 -0
  132. package/src/lib/jobs/fixtures/ai-site-inspiration-pages.js.map +1 -0
  133. package/src/lib/jobs/fixtures/ai-stock-photo-agl3942-recordings.d.ts +29 -0
  134. package/src/lib/jobs/fixtures/ai-stock-photo-agl3942-recordings.js +291 -0
  135. package/src/lib/jobs/fixtures/ai-stock-photo-agl3942-recordings.js.map +1 -0
  136. package/src/lib/jobs/fixtures/ai-stock-photo-agl3988-recordings.d.ts +25 -0
  137. package/src/lib/jobs/fixtures/ai-stock-photo-agl3988-recordings.js +174 -0
  138. package/src/lib/jobs/fixtures/ai-stock-photo-agl3988-recordings.js.map +1 -0
  139. package/src/lib/layout-language/ai-layout-compiler.d.ts +1 -1
  140. package/src/lib/layout-language/ai-layout-compiler.js +438 -25
  141. package/src/lib/layout-language/ai-layout-compiler.js.map +1 -1
  142. package/src/lib/layout-language/ai-layout-contact.d.ts +57 -0
  143. package/src/lib/layout-language/ai-layout-contact.js +137 -0
  144. package/src/lib/layout-language/ai-layout-contact.js.map +1 -0
  145. package/src/lib/layout-language/ai-layout-copy.d.ts +12 -0
  146. package/src/lib/layout-language/ai-layout-copy.js +34 -2
  147. package/src/lib/layout-language/ai-layout-copy.js.map +1 -1
  148. package/src/lib/layout-language/ai-layout-design.d.ts +65 -8
  149. package/src/lib/layout-language/ai-layout-design.js +411 -97
  150. package/src/lib/layout-language/ai-layout-design.js.map +1 -1
  151. package/src/lib/layout-language/ai-layout-frame.js +23 -0
  152. package/src/lib/layout-language/ai-layout-frame.js.map +1 -1
  153. package/src/lib/layout-language/ai-layout-labels.d.ts +2 -0
  154. package/src/lib/layout-language/ai-layout-labels.js +12 -6
  155. package/src/lib/layout-language/ai-layout-labels.js.map +1 -1
  156. package/src/lib/layout-language/ai-layout-language.d.ts +3 -2
  157. package/src/lib/layout-language/ai-layout-language.js +4 -3
  158. package/src/lib/layout-language/ai-layout-language.js.map +1 -1
  159. package/src/lib/layout-language/ai-layout-links.d.ts +13 -0
  160. package/src/lib/layout-language/ai-layout-links.js +30 -0
  161. package/src/lib/layout-language/ai-layout-links.js.map +1 -1
  162. package/src/lib/layout-language/ai-layout-pictures.d.ts +49 -6
  163. package/src/lib/layout-language/ai-layout-pictures.js +145 -22
  164. package/src/lib/layout-language/ai-layout-pictures.js.map +1 -1
  165. package/src/lib/model/ai-build-job.d.ts +16 -1
  166. package/src/lib/model/ai-build-job.js +40 -0
  167. package/src/lib/model/ai-build-job.js.map +1 -1
  168. package/src/lib/model/ai-job-input.d.ts +33 -0
  169. package/src/lib/model/ai-job-input.js +59 -0
  170. package/src/lib/model/ai-job-input.js.map +1 -0
  171. package/src/lib/model/ai-job-notice.d.ts +4 -0
  172. package/src/lib/model/ai-job-notice.js +11 -1
  173. package/src/lib/model/ai-job-notice.js.map +1 -1
  174. package/src/lib/model/ai-jobs.types.d.ts +40 -1
  175. package/src/lib/model/ai-jobs.types.js.map +1 -1
  176. package/src/lib/model/ai-site-details.d.ts +122 -0
  177. package/src/lib/model/ai-site-details.js +300 -0
  178. package/src/lib/model/ai-site-details.js.map +1 -0
  179. package/src/lib/model/ai-site-entity.d.ts +181 -0
  180. package/src/lib/model/ai-site-entity.js +390 -0
  181. package/src/lib/model/ai-site-entity.js.map +1 -0
  182. package/src/lib/model/ai-site-inspiration.d.ts +72 -0
  183. package/src/lib/model/ai-site-inspiration.js +109 -0
  184. package/src/lib/model/ai-site-inspiration.js.map +1 -0
  185. package/src/lib/model/ai-site-job.d.ts +13 -1
  186. package/src/lib/model/ai-site-job.js +15 -2
  187. package/src/lib/model/ai-site-job.js.map +1 -1
  188. package/src/lib/model/ai-site-kinds.js +109 -21
  189. package/src/lib/model/ai-site-kinds.js.map +1 -1
  190. package/src/lib/model/ai-site-look.d.ts +10 -0
  191. package/src/lib/model/ai-site-look.js +24 -0
  192. package/src/lib/model/ai-site-look.js.map +1 -1
  193. package/src/lib/model/ai-site-start-seo.d.ts +19 -5
  194. package/src/lib/model/ai-site-start-seo.js +25 -7
  195. package/src/lib/model/ai-site-start-seo.js.map +1 -1
  196. package/src/lib/model/ai-site-start-steps.d.ts +9 -3
  197. package/src/lib/model/ai-site-start-steps.js +67 -5
  198. package/src/lib/model/ai-site-start-steps.js.map +1 -1
  199. package/src/lib/model/ai-site-start.d.ts +68 -4
  200. package/src/lib/model/ai-site-start.js +166 -13
  201. package/src/lib/model/ai-site-start.js.map +1 -1
  202. package/src/lib/model/ai-upsell-copy.js +4 -1
  203. package/src/lib/model/ai-upsell-copy.js.map +1 -1
  204. package/src/lib/native-nav.d.ts +26 -0
  205. package/src/lib/native-nav.js +58 -0
  206. package/src/lib/native-nav.js.map +1 -0
  207. package/src/lib/plan-entitlements.d.ts +4 -3
  208. package/src/lib/plan-entitlements.js +3 -8
  209. package/src/lib/plan-entitlements.js.map +1 -1
  210. package/src/lib/runtime/ai-dataset-generation.d.ts +8 -1
  211. package/src/lib/runtime/ai-dataset-generation.js +12 -2
  212. package/src/lib/runtime/ai-dataset-generation.js.map +1 -1
  213. package/src/lib/runtime/ai-doctrine-validators.d.ts +26 -33
  214. package/src/lib/runtime/ai-doctrine-validators.js +54 -44
  215. package/src/lib/runtime/ai-doctrine-validators.js.map +1 -1
  216. package/src/lib/runtime/ai-doctrine.js +1 -1
  217. package/src/lib/runtime/ai-doctrine.js.map +1 -1
  218. package/src/lib/runtime/ai-node-tree.d.ts +7 -0
  219. package/src/lib/runtime/ai-node-tree.js +9 -1
  220. package/src/lib/runtime/ai-node-tree.js.map +1 -1
  221. package/src/lib/server/ai-create-route.d.ts +1 -1
  222. package/src/lib/server/ai-create-route.js +3 -4
  223. package/src/lib/server/ai-create-route.js.map +1 -1
  224. package/src/lib/server/ai-jobs-resume.js +27 -3
  225. package/src/lib/server/ai-jobs-resume.js.map +1 -1
  226. package/src/lib/server/ai-jobs-route.js +7 -0
  227. package/src/lib/server/ai-jobs-route.js.map +1 -1
  228. package/src/lib/usage/assist-credits.d.ts +4 -4
  229. package/src/lib/usage/assist-credits.js +4 -4
  230. package/src/lib/usage/assist-credits.js.map +1 -1
  231. package/src/lib/usage/staff-org-ai-view.js +6 -3
  232. package/src/lib/usage/staff-org-ai-view.js.map +1 -1
  233. package/src/lib/usage/staff-org-ai.d.ts +4 -2
  234. package/src/lib/usage/staff-org-ai.js +7 -7
  235. package/src/lib/usage/staff-org-ai.js.map +1 -1
  236. package/src/lib/usage/staff-org-usage-ai.js +2 -2
  237. package/src/lib/usage/staff-org-usage-ai.js.map +1 -1
@@ -14,16 +14,56 @@
14
14
  * See the License for the specific language governing permissions and
15
15
  * limitations under the License.
16
16
  */ 'use client';
17
+ import { _ as _extends } from "@swc/helpers/_/_extends";
17
18
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
18
19
  import { AppLink } from "@aglyn/shared-ui-jsx";
19
- import { Box, Button, Card, Stack, Typography } from "@mui/material";
20
+ import { useMerchantPayments } from "@aglyn/tenant-feature-instance";
21
+ import { Box, Button, Card, Chip, Stack, Typography } from "@mui/material";
20
22
  /**
21
23
  * "Finish your store" (AGL-3676), on a store start's done page: the store,
22
24
  * its account, cart and policy pages are built, so this lists only what the
23
25
  * owner does next — connect payments, review the products and prices, set
24
26
  * shipping and tax, fill in the policies — each with the console page it is
25
27
  * done on.
26
- */ export function AiStoreFinishCard({ steps }) {
28
+ *
29
+ * The Payments step is not a guess (AGL-3982): a workspace whose Stripe
30
+ * account already takes payments sees it done, and one that connected but
31
+ * has not finished sees what Stripe still needs.
32
+ */ export function AiStoreFinishCard({ steps, hostId }) {
33
+ return hostId ? /*#__PURE__*/ _jsx(StoreFinishWithPayments, {
34
+ steps: steps,
35
+ hostId: hostId
36
+ }) : /*#__PURE__*/ _jsx(StoreFinishList, {
37
+ steps: steps,
38
+ payments: null
39
+ });
40
+ }
41
+ function StoreFinishWithPayments({ steps, hostId }) {
42
+ const payments = useMerchantPayments(hostId);
43
+ return /*#__PURE__*/ _jsx(StoreFinishList, {
44
+ steps: steps,
45
+ payments: payments.settled ? payments : null
46
+ });
47
+ }
48
+ /** The Payments step as the workspace's Stripe account stands; any other step as it is. */ function stepAsItStands(step, payments) {
49
+ if (step.id !== 'payments' || !payments) return step;
50
+ if (payments.ready) {
51
+ return _extends({}, step, {
52
+ title: 'Payments connected',
53
+ text: 'Stripe is connected, so your store can take payments and pay you out.',
54
+ action: 'Open Payments',
55
+ done: true
56
+ });
57
+ }
58
+ if (payments.blocked && payments.reason && payments.state !== 'not-connected') {
59
+ return _extends({}, step, {
60
+ text: payments.reason,
61
+ action: 'Open Payments'
62
+ });
63
+ }
64
+ return step;
65
+ }
66
+ function StoreFinishList({ steps, payments }) {
27
67
  return /*#__PURE__*/ _jsxs(Card, {
28
68
  variant: "outlined",
29
69
  component: "section",
@@ -58,7 +98,9 @@ import { Box, Button, Card, Stack, Typography } from "@mui/material";
58
98
  mt: 2,
59
99
  pl: 2.5
60
100
  },
61
- children: steps.map((step)=>/*#__PURE__*/ _jsx(Box, {
101
+ children: steps.map((listed)=>{
102
+ const step = stepAsItStands(listed, payments);
103
+ return /*#__PURE__*/ _jsx(Box, {
62
104
  component: "li",
63
105
  children: /*#__PURE__*/ _jsxs(Stack, {
64
106
  direction: {
@@ -78,10 +120,25 @@ import { Box, Button, Card, Stack, Typography } from "@mui/material";
78
120
  minWidth: 0
79
121
  },
80
122
  children: [
81
- /*#__PURE__*/ _jsx(Typography, {
82
- variant: "subtitle2",
83
- component: "p",
84
- children: step.title
123
+ /*#__PURE__*/ _jsxs(Stack, {
124
+ direction: "row",
125
+ spacing: 1,
126
+ sx: {
127
+ alignItems: 'center'
128
+ },
129
+ children: [
130
+ /*#__PURE__*/ _jsx(Typography, {
131
+ variant: "subtitle2",
132
+ component: "p",
133
+ children: step.title
134
+ }),
135
+ step.done ? /*#__PURE__*/ _jsx(Chip, {
136
+ size: "small",
137
+ color: "success",
138
+ variant: "outlined",
139
+ label: "Done"
140
+ }) : null
141
+ ]
85
142
  }),
86
143
  /*#__PURE__*/ _jsx(Typography, {
87
144
  variant: "body2",
@@ -91,7 +148,7 @@ import { Box, Button, Card, Stack, Typography } from "@mui/material";
91
148
  ]
92
149
  }),
93
150
  step.href ? /*#__PURE__*/ _jsx(Button, {
94
- variant: "outlined",
151
+ variant: step.done ? 'text' : 'outlined',
95
152
  size: "small",
96
153
  component: AppLink,
97
154
  href: step.href,
@@ -106,7 +163,8 @@ import { Box, Button, Card, Stack, Typography } from "@mui/material";
106
163
  }) : null
107
164
  ]
108
165
  })
109
- }, step.id))
166
+ }, step.id);
167
+ })
110
168
  })
111
169
  ]
112
170
  });
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../../../../libs/plugins/ai/src/lib/components/ai-store-finish-card.component.tsx"],"sourcesContent":["/**\n * @license\n * Copyright 2026 Aglyn LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n'use client'\n\nimport { AppLink } from '@aglyn/shared-ui-jsx'\nimport { Box, Button, Card, Stack, Typography } from '@mui/material'\nimport type { AiStoreFinishLink } from './ai-job-links'\n\n/**\n * \"Finish your store\" (AGL-3676), on a store start's done page: the store,\n * its account, cart and policy pages are built, so this lists only what the\n * owner does next — connect payments, review the products and prices, set\n * shipping and tax, fill in the policies — each with the console page it is\n * done on.\n */\nexport function AiStoreFinishCard({ steps }: { steps: readonly AiStoreFinishLink[] }) {\n return (\n <Card variant=\"outlined\" component=\"section\" aria-labelledby=\"ai-store-finish-heading\" sx={{ borderRadius: 2, p: { xs: 2, sm: 3 } }}>\n <Typography id=\"ai-store-finish-heading\" variant=\"h6\" component=\"h2\">\n {'Finish your store'}\n </Typography>\n <Typography variant=\"body2\" color=\"text.secondary\" sx={{ mt: 0.5 }}>\n {'Your storefront, account, cart and policy pages are built. Here is what is left before you sell:'}\n </Typography>\n <Stack component=\"ol\" spacing={2} sx={{ m: 0, mt: 2, pl: 2.5 }}>\n {steps.map((step) => (\n <Box component=\"li\" key={step.id}>\n <Stack direction={{ xs: 'column', sm: 'row' }} spacing={1.5} sx={{ alignItems: { sm: 'center' }, justifyContent: 'space-between' }}>\n <Box sx={{ minWidth: 0 }}>\n <Typography variant=\"subtitle2\" component=\"p\">\n {step.title}\n </Typography>\n <Typography variant=\"body2\" color=\"text.secondary\">\n {step.text}\n </Typography>\n </Box>\n {step.href ? (\n <Button variant=\"outlined\" size=\"small\" component={AppLink} href={step.href} sx={{ flexShrink: 0, alignSelf: { xs: 'flex-start', sm: 'center' } }}>\n {step.action}\n </Button>\n ) : null}\n </Stack>\n </Box>\n ))}\n </Stack>\n </Card>\n )\n}\n\nexport default AiStoreFinishCard\n"],"names":["AppLink","Box","Button","Card","Stack","Typography","AiStoreFinishCard","steps","variant","component","aria-labelledby","sx","borderRadius","p","xs","sm","id","color","mt","spacing","m","pl","map","step","direction","alignItems","justifyContent","minWidth","title","text","href","size","flexShrink","alignSelf","action"],"mappings":"AAAA;;;;;;;;;;;;;;;CAeC,GAED;;AAEA,SAASA,OAAO,QAAQ,uBAAsB;AAC9C,SAASC,GAAG,EAAEC,MAAM,EAAEC,IAAI,EAAEC,KAAK,EAAEC,UAAU,QAAQ,gBAAe;AAGpE;;;;;;CAMC,GACD,OAAO,SAASC,kBAAkB,EAAEC,KAAK,EAA2C;IAClF,qBACE,MAACJ;QAAKK,SAAQ;QAAWC,WAAU;QAAUC,mBAAgB;QAA0BC,IAAI;YAAEC,cAAc;YAAGC,GAAG;gBAAEC,IAAI;gBAAGC,IAAI;YAAE;QAAE;;0BAChI,KAACV;gBAAWW,IAAG;gBAA0BR,SAAQ;gBAAKC,WAAU;0BAC7D;;0BAEH,KAACJ;gBAAWG,SAAQ;gBAAQS,OAAM;gBAAiBN,IAAI;oBAAEO,IAAI;gBAAI;0BAC9D;;0BAEH,KAACd;gBAAMK,WAAU;gBAAKU,SAAS;gBAAGR,IAAI;oBAAES,GAAG;oBAAGF,IAAI;oBAAGG,IAAI;gBAAI;0BAC1Dd,MAAMe,GAAG,CAAC,CAACC,qBACV,KAACtB;wBAAIQ,WAAU;kCACb,cAAA,MAACL;4BAAMoB,WAAW;gCAAEV,IAAI;gCAAUC,IAAI;4BAAM;4BAAGI,SAAS;4BAAKR,IAAI;gCAAEc,YAAY;oCAAEV,IAAI;gCAAS;gCAAGW,gBAAgB;4BAAgB;;8CAC/H,MAACzB;oCAAIU,IAAI;wCAAEgB,UAAU;oCAAE;;sDACrB,KAACtB;4CAAWG,SAAQ;4CAAYC,WAAU;sDACvCc,KAAKK,KAAK;;sDAEb,KAACvB;4CAAWG,SAAQ;4CAAQS,OAAM;sDAC/BM,KAAKM,IAAI;;;;gCAGbN,KAAKO,IAAI,iBACR,KAAC5B;oCAAOM,SAAQ;oCAAWuB,MAAK;oCAAQtB,WAAWT;oCAAS8B,MAAMP,KAAKO,IAAI;oCAAEnB,IAAI;wCAAEqB,YAAY;wCAAGC,WAAW;4CAAEnB,IAAI;4CAAcC,IAAI;wCAAS;oCAAE;8CAC7IQ,KAAKW,MAAM;qCAEZ;;;uBAdiBX,KAAKP,EAAE;;;;AAqB1C;AAEA,eAAeV,kBAAiB"}
1
+ {"version":3,"sources":["../../../../../../../libs/plugins/ai/src/lib/components/ai-store-finish-card.component.tsx"],"sourcesContent":["/**\n * @license\n * Copyright 2026 Aglyn LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n'use client'\n\nimport { AppLink } from '@aglyn/shared-ui-jsx'\nimport { useMerchantPayments, type MerchantPaymentsStatus } from '@aglyn/tenant-feature-instance'\nimport { Box, Button, Card, Chip, Stack, Typography } from '@mui/material'\nimport type { AiStoreFinishLink } from './ai-job-links'\n\n/** What the Payments step says once the workspace's Stripe answer is in. */\ntype PaymentsAnswer = Pick<MerchantPaymentsStatus, 'state' | 'ready' | 'blocked' | 'reason'>\n\nexport interface AiStoreFinishCardProps {\n steps: readonly AiStoreFinishLink[]\n /**\n * The store's site, so the Payments step reads whether its workspace can\n * already take payments (AGL-3982). Without one the step reads as still to\n * do, as it always did.\n */\n hostId?: string | null\n}\n\n/**\n * \"Finish your store\" (AGL-3676), on a store start's done page: the store,\n * its account, cart and policy pages are built, so this lists only what the\n * owner does next — connect payments, review the products and prices, set\n * shipping and tax, fill in the policies — each with the console page it is\n * done on.\n *\n * The Payments step is not a guess (AGL-3982): a workspace whose Stripe\n * account already takes payments sees it done, and one that connected but\n * has not finished sees what Stripe still needs.\n */\nexport function AiStoreFinishCard({ steps, hostId }: AiStoreFinishCardProps) {\n return hostId ? <StoreFinishWithPayments steps={steps} hostId={hostId} /> : <StoreFinishList steps={steps} payments={null} />\n}\n\nfunction StoreFinishWithPayments({ steps, hostId }: { steps: readonly AiStoreFinishLink[]; hostId: string }) {\n const payments = useMerchantPayments(hostId)\n return <StoreFinishList steps={steps} payments={payments.settled ? payments : null} />\n}\n\n/** The Payments step as the workspace's Stripe account stands; any other step as it is. */\nfunction stepAsItStands(step: AiStoreFinishLink, payments: PaymentsAnswer | null): AiStoreFinishLink & { done?: boolean } {\n if (step.id !== 'payments' || !payments) return step\n if (payments.ready) {\n return {\n ...step,\n title: 'Payments connected',\n text: 'Stripe is connected, so your store can take payments and pay you out.',\n action: 'Open Payments',\n done: true,\n }\n }\n if (payments.blocked && payments.reason && payments.state !== 'not-connected') {\n return { ...step, text: payments.reason, action: 'Open Payments' }\n }\n return step\n}\n\nfunction StoreFinishList({ steps, payments }: { steps: readonly AiStoreFinishLink[]; payments: PaymentsAnswer | null }) {\n return (\n <Card variant=\"outlined\" component=\"section\" aria-labelledby=\"ai-store-finish-heading\" sx={{ borderRadius: 2, p: { xs: 2, sm: 3 } }}>\n <Typography id=\"ai-store-finish-heading\" variant=\"h6\" component=\"h2\">\n {'Finish your store'}\n </Typography>\n <Typography variant=\"body2\" color=\"text.secondary\" sx={{ mt: 0.5 }}>\n {'Your storefront, account, cart and policy pages are built. Here is what is left before you sell:'}\n </Typography>\n <Stack component=\"ol\" spacing={2} sx={{ m: 0, mt: 2, pl: 2.5 }}>\n {steps.map((listed) => {\n const step = stepAsItStands(listed, payments)\n return (\n <Box component=\"li\" key={step.id}>\n <Stack direction={{ xs: 'column', sm: 'row' }} spacing={1.5} sx={{ alignItems: { sm: 'center' }, justifyContent: 'space-between' }}>\n <Box sx={{ minWidth: 0 }}>\n <Stack direction=\"row\" spacing={1} sx={{ alignItems: 'center' }}>\n <Typography variant=\"subtitle2\" component=\"p\">\n {step.title}\n </Typography>\n {step.done ? <Chip size=\"small\" color=\"success\" variant=\"outlined\" label=\"Done\" /> : null}\n </Stack>\n <Typography variant=\"body2\" color=\"text.secondary\">\n {step.text}\n </Typography>\n </Box>\n {step.href ? (\n <Button\n variant={step.done ? 'text' : 'outlined'}\n size=\"small\"\n component={AppLink}\n href={step.href}\n sx={{ flexShrink: 0, alignSelf: { xs: 'flex-start', sm: 'center' } }}\n >\n {step.action}\n </Button>\n ) : null}\n </Stack>\n </Box>\n )\n })}\n </Stack>\n </Card>\n )\n}\n\nexport default AiStoreFinishCard\n"],"names":["AppLink","useMerchantPayments","Box","Button","Card","Chip","Stack","Typography","AiStoreFinishCard","steps","hostId","StoreFinishWithPayments","StoreFinishList","payments","settled","stepAsItStands","step","id","ready","title","text","action","done","blocked","reason","state","variant","component","aria-labelledby","sx","borderRadius","p","xs","sm","color","mt","spacing","m","pl","map","listed","direction","alignItems","justifyContent","minWidth","size","label","href","flexShrink","alignSelf"],"mappings":"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"}
@@ -2,11 +2,13 @@ import type { ConsoleWidgetUpgrade } from '@aglyn/aglyn/plugin-manager/feature-p
2
2
  import { type ReactNode } from 'react';
3
3
  import { AI_UPSELL_COPY, AI_UPSELL_CREATE_LABEL, aiUpsellLabel, aiUpsellOffer, type AiUpsellKind } from '../model/ai-upsell-copy';
4
4
  /**
5
- * "Create with AI" on a plan that could buy the AI add-on and has not
6
- * (AGL-3601). The shell mounts the entry with `entitled={false}` only where
7
- * the add-on is sold to this workspace, and the jobs route has said the plan
8
- * is the one thing missing; the entry then keeps its place on the page and
9
- * opens this instead of the brief, so the reader sees where the add-on is used.
5
+ * "Create with AI" where generation is switched off for a workspace that
6
+ * could buy an Aglyn AI tier (AGL-3601, AGL-3965). Since AGL-3965 every paid
7
+ * plan's own credits pay for generation, so this is reached only where a
8
+ * per-org setting closed it. The shell mounts the entry with
9
+ * `entitled={false}` only where a tier is sold to this workspace, and the
10
+ * jobs route has said that is the one thing missing; the entry then keeps its
11
+ * place on the page and opens this instead of the brief.
10
12
  */
11
13
  export { AI_UPSELL_COPY, AI_UPSELL_CREATE_LABEL, aiUpsellLabel, aiUpsellOffer };
12
14
  export type { AiUpsellCopy, AiUpsellKind } from '../model/ai-upsell-copy';
@@ -25,17 +25,19 @@ import { Button, Dialog, DialogActions, DialogContent, DialogTitle, Stack, Typog
25
25
  import { useEffect, useState } from "react";
26
26
  import { AI_UPSELL_COPY, AI_UPSELL_CREATE_LABEL, aiUpsellLabel, aiUpsellOffer } from "../model/ai-upsell-copy.js";
27
27
  /**
28
- * "Create with AI" on a plan that could buy the AI add-on and has not
29
- * (AGL-3601). The shell mounts the entry with `entitled={false}` only where
30
- * the add-on is sold to this workspace, and the jobs route has said the plan
31
- * is the one thing missing; the entry then keeps its place on the page and
32
- * opens this instead of the brief, so the reader sees where the add-on is used.
28
+ * "Create with AI" where generation is switched off for a workspace that
29
+ * could buy an Aglyn AI tier (AGL-3601, AGL-3965). Since AGL-3965 every paid
30
+ * plan's own credits pay for generation, so this is reached only where a
31
+ * per-org setting closed it. The shell mounts the entry with
32
+ * `entitled={false}` only where a tier is sold to this workspace, and the
33
+ * jobs route has said that is the one thing missing; the entry then keeps its
34
+ * place on the page and opens this instead of the brief.
33
35
  */ // The entries' words are the model's, which the native apps' door reads too
34
36
  // (AGL-3854); re-exported for this dialog's existing readers.
35
37
  export { AI_UPSELL_COPY, AI_UPSELL_CREATE_LABEL, aiUpsellLabel, aiUpsellOffer };
36
38
  /** The add-on's own section of the Create with AI guide (AGL-3660). */ const aiUpsellHelp = ()=>pluginDocsHelp('aiCreate', {
37
39
  anchor: '#without-the-add-on',
38
- excerpt: `Create with AI needs the ${aiAddonName()} add-on on a paid plan. An owner or admin adds it from Billing; on Free, the monthly AI credits cover it.`
40
+ excerpt: `On every paid plan, Create with AI runs on the AI credits the plan includes. Where it is switched off for a workspace, an ${aiAddonName()} tier switches it on; an owner or admin chooses one in Billing.`
39
41
  });
40
42
  export function AiUpsellDialog({ kind, open, onClose, upgrade }) {
41
43
  const copy = AI_UPSELL_COPY[kind];
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../../../../libs/plugins/ai/src/lib/components/ai-upsell-dialog.component.tsx"],"sourcesContent":["'use client'\n\n/**\n * @license\n * Copyright 2026 Aglyn LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { aiAddonName } from '@aglyn/aglyn'\nimport { trackEvent } from '@aglyn/aglyn/app-utils/analytics-events'\nimport type { ConsoleWidgetUpgrade } from '@aglyn/aglyn/plugin-manager/feature-plugins'\nimport { mdiCreation } from '@aglyn/shared-data-mdi'\nimport { pluginDocsHelp } from '@aglyn/aglyn/app-utils/docs-help'\nimport { HelpTip, MdiIcon } from '@aglyn/shared-ui-jsx'\nimport {\n Button,\n Dialog,\n DialogActions,\n DialogContent,\n DialogTitle,\n Stack,\n Typography,\n} from '@mui/material'\nimport { useEffect, useState, type ReactNode } from 'react'\nimport {\n AI_UPSELL_COPY,\n AI_UPSELL_CREATE_LABEL,\n aiUpsellLabel,\n aiUpsellOffer,\n type AiUpsellKind,\n} from '../model/ai-upsell-copy'\n\n/**\n * \"Create with AI\" on a plan that could buy the AI add-on and has not\n * (AGL-3601). The shell mounts the entry with `entitled={false}` only where\n * the add-on is sold to this workspace, and the jobs route has said the plan\n * is the one thing missing; the entry then keeps its place on the page and\n * opens this instead of the brief, so the reader sees where the add-on is used.\n */\n\n// The entries' words are the model's, which the native apps' door reads too\n// (AGL-3854); re-exported for this dialog's existing readers.\nexport { AI_UPSELL_COPY, AI_UPSELL_CREATE_LABEL, aiUpsellLabel, aiUpsellOffer }\nexport type { AiUpsellCopy, AiUpsellKind } from '../model/ai-upsell-copy'\n\nexport interface AiUpsellDialogProps {\n kind: AiUpsellKind\n open: boolean\n onClose: () => void\n upgrade: ConsoleWidgetUpgrade\n}\n\n/** The add-on's own section of the Create with AI guide (AGL-3660). */\nconst aiUpsellHelp = () =>\n pluginDocsHelp('aiCreate', {\n anchor: '#without-the-add-on',\n excerpt: `Create with AI needs the ${aiAddonName()} add-on on a paid plan. An owner or admin adds it from Billing; on Free, the monthly AI credits cover it.`,\n })\n\nexport function AiUpsellDialog({ kind, open, onClose, upgrade }: AiUpsellDialogProps) {\n const copy = AI_UPSELL_COPY[kind]\n const { canManageBilling, billingHref } = upgrade\n\n // Counted once per opening: the denominator the click is a rate against.\n useEffect(() => {\n if (open) trackEvent('ai_upsell_shown', { kind, can_manage: canManageBilling })\n }, [open, kind, canManageBilling])\n\n return (\n <Dialog open={open} onClose={onClose} fullWidth maxWidth=\"xs\">\n <DialogTitle sx={{ display: 'flex', alignItems: 'center', gap: 0.5 }}>\n {copy.title}\n <HelpTip {...aiUpsellHelp()} />\n </DialogTitle>\n <DialogContent>\n <Stack spacing={2}>\n <Typography variant=\"body2\">{copy.does}</Typography>\n <Typography variant=\"body2\" color=\"text.secondary\">\n {aiUpsellOffer(canManageBilling, kind === 'insight' ? copy.title : AI_UPSELL_CREATE_LABEL)}\n </Typography>\n </Stack>\n </DialogContent>\n <DialogActions>\n <Button onClick={onClose}>{canManageBilling ? 'Not now' : 'Close'}</Button>\n {canManageBilling ? (\n <Button\n variant=\"contained\"\n href={billingHref}\n onClick={() => trackEvent('ai_upsell_clicked', { kind })}\n >\n {`Add ${aiAddonName()}`}\n </Button>\n ) : null}\n </DialogActions>\n </Dialog>\n )\n}\n\n/**\n * The entry itself on a plan without the add-on: the same button, label and\n * icon as the entitled entry, opening {@link AiUpsellDialog}. Every entry that\n * draws it renders from the shell's client-side gates alone and asks the\n * server nothing until it is used (AGL-3601).\n */\nexport function AiUpsellButton({\n kind,\n upgrade,\n label,\n}: {\n kind: AiUpsellKind\n upgrade: ConsoleWidgetUpgrade\n /** The entitled entry's own label, when it is not the kind's. */\n label?: string\n}): ReactNode {\n const [open, setOpen] = useState(false)\n return (\n <>\n <Button\n size=\"small\"\n variant=\"outlined\"\n startIcon={<MdiIcon path={mdiCreation.path} />}\n onClick={() => setOpen(true)}\n >\n {label ?? aiUpsellLabel(kind)}\n </Button>\n <AiUpsellDialog kind={kind} open={open} onClose={() => setOpen(false)} upgrade={upgrade} />\n </>\n )\n}\n"],"names":["aiAddonName","trackEvent","mdiCreation","pluginDocsHelp","HelpTip","MdiIcon","Button","Dialog","DialogActions","DialogContent","DialogTitle","Stack","Typography","useEffect","useState","AI_UPSELL_COPY","AI_UPSELL_CREATE_LABEL","aiUpsellLabel","aiUpsellOffer","aiUpsellHelp","anchor","excerpt","AiUpsellDialog","kind","open","onClose","upgrade","copy","canManageBilling","billingHref","can_manage","fullWidth","maxWidth","sx","display","alignItems","gap","title","spacing","variant","does","color","onClick","href","AiUpsellButton","label","setOpen","size","startIcon","path"],"mappings":"AAAA;;;AAEA;;;;;;;;;;;;;;;CAeC,GAED,SAASA,WAAW,QAAQ,eAAc;AAC1C,SAASC,UAAU,QAAQ,0CAAyC;AAEpE,SAASC,WAAW,QAAQ,yBAAwB;AACpD,SAASC,cAAc,QAAQ,mCAAkC;AACjE,SAASC,OAAO,EAAEC,OAAO,QAAQ,uBAAsB;AACvD,SACEC,MAAM,EACNC,MAAM,EACNC,aAAa,EACbC,aAAa,EACbC,WAAW,EACXC,KAAK,EACLC,UAAU,QACL,gBAAe;AACtB,SAASC,SAAS,EAAEC,QAAQ,QAAwB,QAAO;AAC3D,SACEC,cAAc,EACdC,sBAAsB,EACtBC,aAAa,EACbC,aAAa,QAER,6BAAyB;AAEhC;;;;;;CAMC,GAED,4EAA4E;AAC5E,8DAA8D;AAC9D,SAASH,cAAc,EAAEC,sBAAsB,EAAEC,aAAa,EAAEC,aAAa,GAAE;AAU/E,qEAAqE,GACrE,MAAMC,eAAe,IACnBhB,eAAe,YAAY;QACzBiB,QAAQ;QACRC,SAAS,CAAC,yBAAyB,EAAErB,cAAc,yGAAyG,CAAC;IAC/J;AAEF,OAAO,SAASsB,eAAe,EAAEC,IAAI,EAAEC,IAAI,EAAEC,OAAO,EAAEC,OAAO,EAAuB;IAClF,MAAMC,OAAOZ,cAAc,CAACQ,KAAK;IACjC,MAAM,EAAEK,gBAAgB,EAAEC,WAAW,EAAE,GAAGH;IAE1C,yEAAyE;IACzEb,UAAU;QACR,IAAIW,MAAMvB,WAAW,mBAAmB;YAAEsB;YAAMO,YAAYF;QAAiB;IAC/E,GAAG;QAACJ;QAAMD;QAAMK;KAAiB;IAEjC,qBACE,MAACrB;QAAOiB,MAAMA;QAAMC,SAASA;QAASM,SAAS;QAACC,UAAS;;0BACvD,MAACtB;gBAAYuB,IAAI;oBAAEC,SAAS;oBAAQC,YAAY;oBAAUC,KAAK;gBAAI;;oBAChET,KAAKU,KAAK;kCACX,KAACjC,sBAAYe;;;0BAEf,KAACV;0BACC,cAAA,MAACE;oBAAM2B,SAAS;;sCACd,KAAC1B;4BAAW2B,SAAQ;sCAASZ,KAAKa,IAAI;;sCACtC,KAAC5B;4BAAW2B,SAAQ;4BAAQE,OAAM;sCAC/BvB,cAAcU,kBAAkBL,SAAS,YAAYI,KAAKU,KAAK,GAAGrB;;;;;0BAIzE,MAACR;;kCACC,KAACF;wBAAOoC,SAASjB;kCAAUG,mBAAmB,YAAY;;oBACzDA,iCACC,KAACtB;wBACCiC,SAAQ;wBACRI,MAAMd;wBACNa,SAAS,IAAMzC,WAAW,qBAAqB;gCAAEsB;4BAAK;kCAErD,CAAC,IAAI,EAAEvB,eAAe;yBAEvB;;;;;AAIZ;AAEA;;;;;CAKC,GACD,OAAO,SAAS4C,eAAe,EAC7BrB,IAAI,EACJG,OAAO,EACPmB,KAAK,EAMN;IACC,MAAM,CAACrB,MAAMsB,QAAQ,GAAGhC,SAAS;IACjC,qBACE;;0BACE,KAACR;gBACCyC,MAAK;gBACLR,SAAQ;gBACRS,yBAAW,KAAC3C;oBAAQ4C,MAAM/C,YAAY+C,IAAI;;gBAC1CP,SAAS,IAAMI,QAAQ;0BAEtBD,gBAAAA,QAAS5B,cAAcM;;0BAE1B,KAACD;gBAAeC,MAAMA;gBAAMC,MAAMA;gBAAMC,SAAS,IAAMqB,QAAQ;gBAAQpB,SAASA;;;;AAGtF"}
1
+ {"version":3,"sources":["../../../../../../../libs/plugins/ai/src/lib/components/ai-upsell-dialog.component.tsx"],"sourcesContent":["'use client'\n\n/**\n * @license\n * Copyright 2026 Aglyn LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { aiAddonName } from '@aglyn/aglyn'\nimport { trackEvent } from '@aglyn/aglyn/app-utils/analytics-events'\nimport type { ConsoleWidgetUpgrade } from '@aglyn/aglyn/plugin-manager/feature-plugins'\nimport { mdiCreation } from '@aglyn/shared-data-mdi'\nimport { pluginDocsHelp } from '@aglyn/aglyn/app-utils/docs-help'\nimport { HelpTip, MdiIcon } from '@aglyn/shared-ui-jsx'\nimport {\n Button,\n Dialog,\n DialogActions,\n DialogContent,\n DialogTitle,\n Stack,\n Typography,\n} from '@mui/material'\nimport { useEffect, useState, type ReactNode } from 'react'\nimport {\n AI_UPSELL_COPY,\n AI_UPSELL_CREATE_LABEL,\n aiUpsellLabel,\n aiUpsellOffer,\n type AiUpsellKind,\n} from '../model/ai-upsell-copy'\n\n/**\n * \"Create with AI\" where generation is switched off for a workspace that\n * could buy an Aglyn AI tier (AGL-3601, AGL-3965). Since AGL-3965 every paid\n * plan's own credits pay for generation, so this is reached only where a\n * per-org setting closed it. The shell mounts the entry with\n * `entitled={false}` only where a tier is sold to this workspace, and the\n * jobs route has said that is the one thing missing; the entry then keeps its\n * place on the page and opens this instead of the brief.\n */\n\n// The entries' words are the model's, which the native apps' door reads too\n// (AGL-3854); re-exported for this dialog's existing readers.\nexport { AI_UPSELL_COPY, AI_UPSELL_CREATE_LABEL, aiUpsellLabel, aiUpsellOffer }\nexport type { AiUpsellCopy, AiUpsellKind } from '../model/ai-upsell-copy'\n\nexport interface AiUpsellDialogProps {\n kind: AiUpsellKind\n open: boolean\n onClose: () => void\n upgrade: ConsoleWidgetUpgrade\n}\n\n/** The add-on's own section of the Create with AI guide (AGL-3660). */\nconst aiUpsellHelp = () =>\n pluginDocsHelp('aiCreate', {\n anchor: '#without-the-add-on',\n excerpt: `On every paid plan, Create with AI runs on the AI credits the plan includes. Where it is switched off for a workspace, an ${aiAddonName()} tier switches it on; an owner or admin chooses one in Billing.`,\n })\n\nexport function AiUpsellDialog({ kind, open, onClose, upgrade }: AiUpsellDialogProps) {\n const copy = AI_UPSELL_COPY[kind]\n const { canManageBilling, billingHref } = upgrade\n\n // Counted once per opening: the denominator the click is a rate against.\n useEffect(() => {\n if (open) trackEvent('ai_upsell_shown', { kind, can_manage: canManageBilling })\n }, [open, kind, canManageBilling])\n\n return (\n <Dialog open={open} onClose={onClose} fullWidth maxWidth=\"xs\">\n <DialogTitle sx={{ display: 'flex', alignItems: 'center', gap: 0.5 }}>\n {copy.title}\n <HelpTip {...aiUpsellHelp()} />\n </DialogTitle>\n <DialogContent>\n <Stack spacing={2}>\n <Typography variant=\"body2\">{copy.does}</Typography>\n <Typography variant=\"body2\" color=\"text.secondary\">\n {aiUpsellOffer(canManageBilling, kind === 'insight' ? copy.title : AI_UPSELL_CREATE_LABEL)}\n </Typography>\n </Stack>\n </DialogContent>\n <DialogActions>\n <Button onClick={onClose}>{canManageBilling ? 'Not now' : 'Close'}</Button>\n {canManageBilling ? (\n <Button\n variant=\"contained\"\n href={billingHref}\n onClick={() => trackEvent('ai_upsell_clicked', { kind })}\n >\n {`Add ${aiAddonName()}`}\n </Button>\n ) : null}\n </DialogActions>\n </Dialog>\n )\n}\n\n/**\n * The entry itself on a plan without the add-on: the same button, label and\n * icon as the entitled entry, opening {@link AiUpsellDialog}. Every entry that\n * draws it renders from the shell's client-side gates alone and asks the\n * server nothing until it is used (AGL-3601).\n */\nexport function AiUpsellButton({\n kind,\n upgrade,\n label,\n}: {\n kind: AiUpsellKind\n upgrade: ConsoleWidgetUpgrade\n /** The entitled entry's own label, when it is not the kind's. */\n label?: string\n}): ReactNode {\n const [open, setOpen] = useState(false)\n return (\n <>\n <Button\n size=\"small\"\n variant=\"outlined\"\n startIcon={<MdiIcon path={mdiCreation.path} />}\n onClick={() => setOpen(true)}\n >\n {label ?? aiUpsellLabel(kind)}\n </Button>\n <AiUpsellDialog kind={kind} open={open} onClose={() => setOpen(false)} upgrade={upgrade} />\n </>\n )\n}\n"],"names":["aiAddonName","trackEvent","mdiCreation","pluginDocsHelp","HelpTip","MdiIcon","Button","Dialog","DialogActions","DialogContent","DialogTitle","Stack","Typography","useEffect","useState","AI_UPSELL_COPY","AI_UPSELL_CREATE_LABEL","aiUpsellLabel","aiUpsellOffer","aiUpsellHelp","anchor","excerpt","AiUpsellDialog","kind","open","onClose","upgrade","copy","canManageBilling","billingHref","can_manage","fullWidth","maxWidth","sx","display","alignItems","gap","title","spacing","variant","does","color","onClick","href","AiUpsellButton","label","setOpen","size","startIcon","path"],"mappings":"AAAA;;;AAEA;;;;;;;;;;;;;;;CAeC,GAED,SAASA,WAAW,QAAQ,eAAc;AAC1C,SAASC,UAAU,QAAQ,0CAAyC;AAEpE,SAASC,WAAW,QAAQ,yBAAwB;AACpD,SAASC,cAAc,QAAQ,mCAAkC;AACjE,SAASC,OAAO,EAAEC,OAAO,QAAQ,uBAAsB;AACvD,SACEC,MAAM,EACNC,MAAM,EACNC,aAAa,EACbC,aAAa,EACbC,WAAW,EACXC,KAAK,EACLC,UAAU,QACL,gBAAe;AACtB,SAASC,SAAS,EAAEC,QAAQ,QAAwB,QAAO;AAC3D,SACEC,cAAc,EACdC,sBAAsB,EACtBC,aAAa,EACbC,aAAa,QAER,6BAAyB;AAEhC;;;;;;;;CAQC,GAED,4EAA4E;AAC5E,8DAA8D;AAC9D,SAASH,cAAc,EAAEC,sBAAsB,EAAEC,aAAa,EAAEC,aAAa,GAAE;AAU/E,qEAAqE,GACrE,MAAMC,eAAe,IACnBhB,eAAe,YAAY;QACzBiB,QAAQ;QACRC,SAAS,CAAC,0HAA0H,EAAErB,cAAc,+DAA+D,CAAC;IACtN;AAEF,OAAO,SAASsB,eAAe,EAAEC,IAAI,EAAEC,IAAI,EAAEC,OAAO,EAAEC,OAAO,EAAuB;IAClF,MAAMC,OAAOZ,cAAc,CAACQ,KAAK;IACjC,MAAM,EAAEK,gBAAgB,EAAEC,WAAW,EAAE,GAAGH;IAE1C,yEAAyE;IACzEb,UAAU;QACR,IAAIW,MAAMvB,WAAW,mBAAmB;YAAEsB;YAAMO,YAAYF;QAAiB;IAC/E,GAAG;QAACJ;QAAMD;QAAMK;KAAiB;IAEjC,qBACE,MAACrB;QAAOiB,MAAMA;QAAMC,SAASA;QAASM,SAAS;QAACC,UAAS;;0BACvD,MAACtB;gBAAYuB,IAAI;oBAAEC,SAAS;oBAAQC,YAAY;oBAAUC,KAAK;gBAAI;;oBAChET,KAAKU,KAAK;kCACX,KAACjC,sBAAYe;;;0BAEf,KAACV;0BACC,cAAA,MAACE;oBAAM2B,SAAS;;sCACd,KAAC1B;4BAAW2B,SAAQ;sCAASZ,KAAKa,IAAI;;sCACtC,KAAC5B;4BAAW2B,SAAQ;4BAAQE,OAAM;sCAC/BvB,cAAcU,kBAAkBL,SAAS,YAAYI,KAAKU,KAAK,GAAGrB;;;;;0BAIzE,MAACR;;kCACC,KAACF;wBAAOoC,SAASjB;kCAAUG,mBAAmB,YAAY;;oBACzDA,iCACC,KAACtB;wBACCiC,SAAQ;wBACRI,MAAMd;wBACNa,SAAS,IAAMzC,WAAW,qBAAqB;gCAAEsB;4BAAK;kCAErD,CAAC,IAAI,EAAEvB,eAAe;yBAEvB;;;;;AAIZ;AAEA;;;;;CAKC,GACD,OAAO,SAAS4C,eAAe,EAC7BrB,IAAI,EACJG,OAAO,EACPmB,KAAK,EAMN;IACC,MAAM,CAACrB,MAAMsB,QAAQ,GAAGhC,SAAS;IACjC,qBACE;;0BACE,KAACR;gBACCyC,MAAK;gBACLR,SAAQ;gBACRS,yBAAW,KAAC3C;oBAAQ4C,MAAM/C,YAAY+C,IAAI;;gBAC1CP,SAAS,IAAMI,QAAQ;0BAEtBD,gBAAAA,QAAS5B,cAAcM;;0BAE1B,KAACD;gBAAeC,MAAMA;gBAAMC,MAAMA;gBAAMC,SAAS,IAAMqB,QAAQ;gBAAQpB,SAASA;;;;AAGtF"}
@@ -23,10 +23,11 @@ import { useEffect, useRef, useState } from "react";
23
23
  import { aiBuildCanRetry, aiBuildItemRows, aiBuildOutcomeLine, aiBuildRetryCreditRange } from "../model/ai-build-progress.js";
24
24
  import { aiCreditRangeText } from "../model/ai-credit-estimate.js";
25
25
  import { AiCreditsPromptNotice } from "./ai-credits-prompt.component.js";
26
- import { aiCreditsBillingHref, aiStoreFinishLinks } from "./ai-job-links.js";
26
+ import { aiCreditsBillingHref, aiStoreFinishHostId, aiStoreFinishLinks } from "./ai-job-links.js";
27
27
  import { AiStoreFinishCard } from "./ai-store-finish-card.component.js";
28
28
  import { AI_JOB_TERMINAL_STATUSES } from "../model/ai-jobs.types.js";
29
29
  import { followAiJobEvents } from "./ai-job-events.js";
30
+ import { AiJobInputForm } from "./ai-job-input-form.component.js";
30
31
  import { AiJobPlan } from "./ai-job-plan.component.js";
31
32
  import { resumeAiJobRequest } from "./ai-job-requests.js";
32
33
  import { openAiJobs } from "./ai-jobs-store.js";
@@ -177,7 +178,16 @@ export function AssistBuildCard({ proposal, job, notice, orgId, user, staff = fa
177
178
  ]
178
179
  }, row.slot))
179
180
  }),
180
- job && paused && // Out of credits mid-build (AGL-3722): paused, never failed. What is
181
+ job && paused && job.input ? // A plan that needs an ID only the person has (AGL-3978): asked here,
182
+ // and answered back onto the plan card.
183
+ /*#__PURE__*/ _jsx(AiJobInputForm, {
184
+ job: _extends({}, job, {
185
+ input: job.input
186
+ }),
187
+ orgId: orgId,
188
+ user: user,
189
+ onJob: onJob
190
+ }) : job && paused && // Out of credits mid-build (AGL-3722): paused, never failed. What is
181
191
  // built is kept, and Resume carries on from the next item.
182
192
  /*#__PURE__*/ _jsx(Alert, {
183
193
  severity: "warning",
@@ -227,7 +237,8 @@ export function AssistBuildCard({ proposal, job, notice, orgId, user, staff = fa
227
237
  mt: 1
228
238
  },
229
239
  children: /*#__PURE__*/ _jsx(AiStoreFinishCard, {
230
- steps: storeFinish
240
+ steps: storeFinish,
241
+ hostId: job ? aiStoreFinishHostId(job) : null
231
242
  })
232
243
  }),
233
244
  job && /*#__PURE__*/ _jsxs(Stack, {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../../../../libs/plugins/ai/src/lib/components/assist-build-card.component.tsx"],"sourcesContent":["/**\n * @license\n * Copyright 2026 Aglyn LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n'use client'\n\nimport type { MaybeTokenSource } from '@aglyn/shared-util-http/authorized-token'\nimport { pluginDocsHelp } from '@aglyn/aglyn/app-utils/docs-help'\nimport { HelpTip } from '@aglyn/shared-ui-jsx'\nimport { Alert, Box, Button, CircularProgress, Paper, Stack, Typography } from '@mui/material'\nimport { useEffect, useRef, useState } from 'react'\nimport { aiBuildCanRetry, aiBuildItemRows, aiBuildOutcomeLine, aiBuildRetryCreditRange } from '../model/ai-build-progress'\nimport { aiCreditRangeText, type AiCreditsPrompt } from '../model/ai-credit-estimate'\nimport { AiCreditsPromptNotice } from './ai-credits-prompt.component'\nimport { aiCreditsBillingHref, aiStoreFinishLinks } from './ai-job-links'\nimport { AiStoreFinishCard } from './ai-store-finish-card.component'\nimport { AI_JOB_TERMINAL_STATUSES, type AiJobSummary } from '../model/ai-jobs.types'\nimport type { AssistBuildProposal } from '../model/assist-build'\nimport { followAiJobEvents } from './ai-job-events'\nimport { AiJobPlan } from './ai-job-plan.component'\nimport { resumeAiJobRequest, type AiJobResumeOptions } from './ai-job-requests'\nimport { openAiJobs } from './ai-jobs-store'\n\n/**\n * The one card a build proposed in the chat becomes (AGL-3616): while its\n * job plans, a line saying so; then the job's own plan card, with its one\n * price and Confirm — the same `AiJobPlan` the AI jobs drawer shows, so\n * confirming here and there is one door; then where the build stands, item\n * by item, with AI jobs a click away. The job itself is started by the\n * panel, once, when the turn that proposed it ends; this card only follows\n * it, so re-rendering a stored thread never starts a second build.\n */\nexport interface AssistBuildCardProps {\n proposal: AssistBuildProposal\n /** The job the proposal started, as last seen; `null` while it is being created. */\n job: AiJobSummary | null\n /** Why the job could not be created or confirmed, when it could not. */\n notice: string | null\n orgId: string\n user: MaybeTokenSource\n staff?: boolean\n /** The job as it moved, for the thread to keep. */\n onJob: (job: AiJobSummary) => void\n onNotice: (notice: string | null) => void\n /** The workspace's path slug, for Upgrade on a Free build past what is left or paused (AGL-3722). */\n orgSlug?: string | null\n}\n\n/** The card's own section of the Assist builds guide (AGL-3660). */\nconst ASSIST_BUILD_HELP = pluginDocsHelp('aiAssistBuilds', {\n anchor: '#the-plan-card',\n excerpt:\n 'What one request will build, item by item, with its estimate. Nothing is built until you choose Confirm plan, and what it makes is a draft.',\n})\n\nconst ITEM_STATES = { done: 'built', active: 'building', waiting: 'waiting', failed: 'failed', skipped: 'not built' } as const\n\nexport function AssistBuildCard({\n proposal,\n job,\n notice,\n orgId,\n user,\n staff = false,\n onJob,\n onNotice,\n orgSlug,\n}: AssistBuildCardProps): JSX.Element {\n const [busy, setBusy] = useState(false)\n // A Free Try again past what is left (AGL-3722): its prompt, until chosen.\n const [retryPrompt, setRetryPrompt] = useState<AiCreditsPrompt | null>(null)\n const userRef = useRef(user)\n userRef.current = user\n const onJobRef = useRef(onJob)\n onJobRef.current = onJob\n\n // Follow a job that is still planning or building; a plan waiting for its\n // confirmation and a settled job need nothing more from the stream.\n // A build the meter paused (AGL-3722) waits for Resume, not the stream.\n const paused = job?.status === 'needs_input'\n const following = Boolean(\n job && !AI_JOB_TERMINAL_STATUSES.includes(job.status) && job.status !== 'needs_review' && !paused,\n )\n const jobId = job?.id ?? null\n useEffect(() => {\n if (!following || !jobId) return\n const controller = new AbortController()\n void followAiJobEvents(() => userRef.current, orgId, jobId, controller.signal, (next) => onJobRef.current(next))\n return () => controller.abort()\n }, [following, jobId, orgId])\n\n const resume = async (target: AiJobSummary, options?: AiJobResumeOptions) => {\n setBusy(true)\n onNotice(null)\n setRetryPrompt(null)\n const decision = await resumeAiJobRequest(user, orgId, target, options)\n if (decision.job) onJob(decision.job)\n // A Free Try again past what is left asks with its choices; a plan's\n // card draws its own from the job the door answered with.\n if (decision.credits && options?.retry) setRetryPrompt(decision.credits)\n else if (decision.error && !(decision.credits && target.status === 'needs_review')) onNotice(decision.error)\n setBusy(false)\n }\n const retryRange = job && aiBuildCanRetry(job) ? aiBuildRetryCreditRange(job) : null\n\n const settled = job ? AI_JOB_TERMINAL_STATUSES.includes(job.status) : false\n const outcome = job ? aiBuildOutcomeLine(job) : null\n // A build that made the site a store (AGL-3676) ends with what is left before it sells.\n const storeFinish = job && orgSlug ? aiStoreFinishLinks(job, orgSlug) : null\n return (\n <Paper variant=\"outlined\" sx={{ mt: 1, p: 1.5 }} aria-label=\"Build plan\">\n <Stack direction=\"row\" spacing={0.5} sx={{ alignItems: 'center' }}>\n <Typography variant=\"subtitle2\">{proposal.summary}</Typography>\n <HelpTip {...ASSIST_BUILD_HELP} />\n </Stack>\n {!job && !notice && (\n <Stack direction=\"row\" spacing={1} sx={{ mt: 0.5, alignItems: 'center' }}>\n <CircularProgress size={14} />\n <Typography variant=\"body2\" color=\"text.secondary\">\n {'Planning what to build on this site…'}\n </Typography>\n </Stack>\n )}\n {notice && (\n <Typography variant=\"body2\" color=\"error\" sx={{ mt: 0.5 }} role=\"alert\">\n {notice}\n </Typography>\n )}\n {job && job.status === 'needs_review' && (\n <AiJobPlan\n job={job}\n busy={busy}\n staff={staff}\n user={user}\n orgSlug={orgSlug}\n onResume={(target, options) => void resume(target, options)}\n />\n )}\n {job && following && (\n <Stack direction=\"row\" spacing={1} sx={{ mt: 0.5, alignItems: 'center' }}>\n <CircularProgress size={14} />\n <Typography variant=\"body2\" color=\"text.secondary\">\n {job.plan?.status === 'confirmed'\n ? 'Building each part in turn. What it makes is an unpublished draft unless you chose to publish.'\n : 'Planning what to build on this site…'}\n </Typography>\n </Stack>\n )}\n {job && (job.items?.length ?? 0) > 0 && job.status !== 'needs_review' && (\n <Box component=\"ul\" aria-label=\"Items\" sx={{ m: 0, mt: 0.5, pl: 2 }}>\n {aiBuildItemRows(job).map((row) => (\n <Typography key={row.slot} component=\"li\" variant=\"caption\" data-item-state={row.state}>\n {`${row.label} — ${ITEM_STATES[row.state]}`}\n {row.detail ? `. ${row.detail}` : ''}\n </Typography>\n ))}\n </Box>\n )}\n {job && paused && (\n // Out of credits mid-build (AGL-3722): paused, never failed. What is\n // built is kept, and Resume carries on from the next item.\n <Alert\n severity=\"warning\"\n sx={{ mt: 0.5 }}\n action={\n <Stack direction=\"row\" spacing={1}>\n {orgSlug ? (\n <Button color=\"inherit\" size=\"small\" href={aiCreditsBillingHref(orgSlug)}>\n {'Upgrade'}\n </Button>\n ) : null}\n <Button color=\"inherit\" size=\"small\" disabled={busy} onClick={() => void resume(job)}>\n {'Resume'}\n </Button>\n </Stack>\n }\n >\n {`Paused. ${job.error ?? 'Your AI credits ran out.'} What is built so far is kept, and Resume carries on from the next item once you upgrade or your credits renew.`}\n </Alert>\n )}\n {job && retryPrompt && (\n <AiCreditsPromptNotice\n prompt={retryPrompt}\n noun=\"build\"\n orgSlug={orgSlug}\n busy={busy}\n onBuildWhatFits={() => void resume(job, { retry: 'failed-items', creditsConfirmed: true })}\n />\n )}\n {settled && (\n <Typography variant=\"body2\" sx={{ mt: 0.5 }}>\n {outcome ?? job?.error ?? ''}\n </Typography>\n )}\n {storeFinish && (\n <Box sx={{ mt: 1 }}>\n <AiStoreFinishCard steps={storeFinish} />\n </Box>\n )}\n {job && (\n <Stack direction=\"row\" spacing={1} sx={{ mt: 1 }}>\n {job && aiBuildCanRetry(job) && (\n <Button size=\"small\" variant=\"contained\" disabled={busy} onClick={() => void resume(job, { retry: 'failed-items' })}>\n {retryRange ? `Try again what failed · ${aiCreditRangeText(retryRange)}` : 'Try again what failed'}\n </Button>\n )}\n <Button size=\"small\" onClick={() => openAiJobs({ jobId: job.id })}>\n {'Open in AI jobs'}\n </Button>\n </Stack>\n )}\n </Paper>\n )\n}\n"],"names":["pluginDocsHelp","HelpTip","Alert","Box","Button","CircularProgress","Paper","Stack","Typography","useEffect","useRef","useState","aiBuildCanRetry","aiBuildItemRows","aiBuildOutcomeLine","aiBuildRetryCreditRange","aiCreditRangeText","AiCreditsPromptNotice","aiCreditsBillingHref","aiStoreFinishLinks","AiStoreFinishCard","AI_JOB_TERMINAL_STATUSES","followAiJobEvents","AiJobPlan","resumeAiJobRequest","openAiJobs","ASSIST_BUILD_HELP","anchor","excerpt","ITEM_STATES","done","active","waiting","failed","skipped","AssistBuildCard","proposal","job","notice","orgId","user","staff","onJob","onNotice","orgSlug","outcome","busy","setBusy","retryPrompt","setRetryPrompt","userRef","current","onJobRef","paused","status","following","Boolean","includes","jobId","id","controller","AbortController","signal","next","abort","resume","target","options","decision","credits","retry","error","retryRange","settled","storeFinish","variant","sx","mt","p","aria-label","direction","spacing","alignItems","summary","size","color","role","onResume","plan","items","length","component","m","pl","map","row","data-item-state","state","label","detail","slot","severity","action","href","disabled","onClick","prompt","noun","onBuildWhatFits","creditsConfirmed","steps"],"mappings":"AAAA;;;;;;;;;;;;;;;CAeC,GAED;;;AAGA,SAASA,cAAc,QAAQ,mCAAkC;AACjE,SAASC,OAAO,QAAQ,uBAAsB;AAC9C,SAASC,KAAK,EAAEC,GAAG,EAAEC,MAAM,EAAEC,gBAAgB,EAAEC,KAAK,EAAEC,KAAK,EAAEC,UAAU,QAAQ,gBAAe;AAC9F,SAASC,SAAS,EAAEC,MAAM,EAAEC,QAAQ,QAAQ,QAAO;AACnD,SAASC,eAAe,EAAEC,eAAe,EAAEC,kBAAkB,EAAEC,uBAAuB,QAAQ,gCAA4B;AAC1H,SAASC,iBAAiB,QAA8B,iCAA6B;AACrF,SAASC,qBAAqB,QAAQ,mCAA+B;AACrE,SAASC,oBAAoB,EAAEC,kBAAkB,QAAQ,oBAAgB;AACzE,SAASC,iBAAiB,QAAQ,sCAAkC;AACpE,SAASC,wBAAwB,QAA2B,4BAAwB;AAEpF,SAASC,iBAAiB,QAAQ,qBAAiB;AACnD,SAASC,SAAS,QAAQ,6BAAyB;AACnD,SAASC,kBAAkB,QAAiC,uBAAmB;AAC/E,SAASC,UAAU,QAAQ,qBAAiB;AA2B5C,kEAAkE,GAClE,MAAMC,oBAAoB1B,eAAe,kBAAkB;IACzD2B,QAAQ;IACRC,SACE;AACJ;AAEA,MAAMC,cAAc;IAAEC,MAAM;IAASC,QAAQ;IAAYC,SAAS;IAAWC,QAAQ;IAAUC,SAAS;AAAY;AAEpH,OAAO,SAASC,gBAAgB,EAC9BC,QAAQ,EACRC,GAAG,EACHC,MAAM,EACNC,KAAK,EACLC,IAAI,EACJC,QAAQ,KAAK,EACbC,KAAK,EACLC,QAAQ,EACRC,OAAO,EACc;qBA8GDP,YAcXQ;QAjDER,WAMEA;IAhFb,MAAM,CAACS,MAAMC,QAAQ,GAAGpC,SAAS;IACjC,2EAA2E;IAC3E,MAAM,CAACqC,aAAaC,eAAe,GAAGtC,SAAiC;IACvE,MAAMuC,UAAUxC,OAAO8B;IACvBU,QAAQC,OAAO,GAAGX;IAClB,MAAMY,WAAW1C,OAAOgC;IACxBU,SAASD,OAAO,GAAGT;IAEnB,0EAA0E;IAC1E,oEAAoE;IACpE,wEAAwE;IACxE,MAAMW,SAAShB,CAAAA,uBAAAA,IAAKiB,MAAM,MAAK;IAC/B,MAAMC,YAAYC,QAChBnB,OAAO,CAAChB,yBAAyBoC,QAAQ,CAACpB,IAAIiB,MAAM,KAAKjB,IAAIiB,MAAM,KAAK,kBAAkB,CAACD;IAE7F,MAAMK,gBAAQrB,uBAAAA,IAAKsB,EAAE,mBAAI;IACzBlD,UAAU;QACR,IAAI,CAAC8C,aAAa,CAACG,OAAO;QAC1B,MAAME,aAAa,IAAIC;QACvB,KAAKvC,kBAAkB,IAAM4B,QAAQC,OAAO,EAAEZ,OAAOmB,OAAOE,WAAWE,MAAM,EAAE,CAACC,OAASX,SAASD,OAAO,CAACY;QAC1G,OAAO,IAAMH,WAAWI,KAAK;IAC/B,GAAG;QAACT;QAAWG;QAAOnB;KAAM;IAE5B,MAAM0B,SAAS,OAAOC,QAAsBC;QAC1CpB,QAAQ;QACRJ,SAAS;QACTM,eAAe;QACf,MAAMmB,WAAW,MAAM5C,mBAAmBgB,MAAMD,OAAO2B,QAAQC;QAC/D,IAAIC,SAAS/B,GAAG,EAAEK,MAAM0B,SAAS/B,GAAG;QACpC,qEAAqE;QACrE,0DAA0D;QAC1D,IAAI+B,SAASC,OAAO,KAAIF,2BAAAA,QAASG,KAAK,GAAErB,eAAemB,SAASC,OAAO;aAClE,IAAID,SAASG,KAAK,IAAI,CAAEH,CAAAA,SAASC,OAAO,IAAIH,OAAOZ,MAAM,KAAK,cAAa,GAAIX,SAASyB,SAASG,KAAK;QAC3GxB,QAAQ;IACV;IACA,MAAMyB,aAAanC,OAAOzB,gBAAgByB,OAAOtB,wBAAwBsB,OAAO;IAEhF,MAAMoC,UAAUpC,MAAMhB,yBAAyBoC,QAAQ,CAACpB,IAAIiB,MAAM,IAAI;IACtE,MAAMT,UAAUR,MAAMvB,mBAAmBuB,OAAO;IAChD,wFAAwF;IACxF,MAAMqC,cAAcrC,OAAOO,UAAUzB,mBAAmBkB,KAAKO,WAAW;IACxE,qBACE,MAACtC;QAAMqE,SAAQ;QAAWC,IAAI;YAAEC,IAAI;YAAGC,GAAG;QAAI;QAAGC,cAAW;;0BAC1D,MAACxE;gBAAMyE,WAAU;gBAAMC,SAAS;gBAAKL,IAAI;oBAAEM,YAAY;gBAAS;;kCAC9D,KAAC1E;wBAAWmE,SAAQ;kCAAavC,SAAS+C,OAAO;;kCACjD,KAAClF,sBAAYyB;;;YAEd,CAACW,OAAO,CAACC,wBACR,MAAC/B;gBAAMyE,WAAU;gBAAMC,SAAS;gBAAGL,IAAI;oBAAEC,IAAI;oBAAKK,YAAY;gBAAS;;kCACrE,KAAC7E;wBAAiB+E,MAAM;;kCACxB,KAAC5E;wBAAWmE,SAAQ;wBAAQU,OAAM;kCAC/B;;;;YAIN/C,wBACC,KAAC9B;gBAAWmE,SAAQ;gBAAQU,OAAM;gBAAQT,IAAI;oBAAEC,IAAI;gBAAI;gBAAGS,MAAK;0BAC7DhD;;YAGJD,OAAOA,IAAIiB,MAAM,KAAK,gCACrB,KAAC/B;gBACCc,KAAKA;gBACLS,MAAMA;gBACNL,OAAOA;gBACPD,MAAMA;gBACNI,SAASA;gBACT2C,UAAU,CAACrB,QAAQC,UAAY,KAAKF,OAAOC,QAAQC;;YAGtD9B,OAAOkB,2BACN,MAAChD;gBAAMyE,WAAU;gBAAMC,SAAS;gBAAGL,IAAI;oBAAEC,IAAI;oBAAKK,YAAY;gBAAS;;kCACrE,KAAC7E;wBAAiB+E,MAAM;;kCACxB,KAAC5E;wBAAWmE,SAAQ;wBAAQU,OAAM;kCAC/BhD,EAAAA,YAAAA,IAAImD,IAAI,qBAARnD,UAAUiB,MAAM,MAAK,cAClB,mGACA;;;;YAITjB,OAAO,WAACA,aAAAA,IAAIoD,KAAK,qBAATpD,WAAWqD,MAAM,oBAAI,KAAK,KAAKrD,IAAIiB,MAAM,KAAK,gCACrD,KAACnD;gBAAIwF,WAAU;gBAAKZ,cAAW;gBAAQH,IAAI;oBAAEgB,GAAG;oBAAGf,IAAI;oBAAKgB,IAAI;gBAAE;0BAC/DhF,gBAAgBwB,KAAKyD,GAAG,CAAC,CAACC,oBACzB,MAACvF;wBAA0BmF,WAAU;wBAAKhB,SAAQ;wBAAUqB,mBAAiBD,IAAIE,KAAK;;4BACnF,GAAGF,IAAIG,KAAK,CAAC,GAAG,EAAErE,WAAW,CAACkE,IAAIE,KAAK,CAAC,EAAE;4BAC1CF,IAAII,MAAM,GAAG,CAAC,EAAE,EAAEJ,IAAII,MAAM,EAAE,GAAG;;uBAFnBJ,IAAIK,IAAI;;YAO9B/D,OAAOgB,UACN,qEAAqE;YACrE,2DAA2D;0BAC3D,KAACnD;gBACCmG,UAAS;gBACTzB,IAAI;oBAAEC,IAAI;gBAAI;gBACdyB,sBACE,MAAC/F;oBAAMyE,WAAU;oBAAMC,SAAS;;wBAC7BrC,wBACC,KAACxC;4BAAOiF,OAAM;4BAAUD,MAAK;4BAAQmB,MAAMrF,qBAAqB0B;sCAC7D;6BAED;sCACJ,KAACxC;4BAAOiF,OAAM;4BAAUD,MAAK;4BAAQoB,UAAU1D;4BAAM2D,SAAS,IAAM,KAAKxC,OAAO5B;sCAC7E;;;;0BAKN,CAAC,QAAQ,GAAEA,aAAAA,IAAIkC,KAAK,YAATlC,aAAa,2BAA2B,+GAA+G,CAAC;;YAGvKA,OAAOW,6BACN,KAAC/B;gBACCyF,QAAQ1D;gBACR2D,MAAK;gBACL/D,SAASA;gBACTE,MAAMA;gBACN8D,iBAAiB,IAAM,KAAK3C,OAAO5B,KAAK;wBAAEiC,OAAO;wBAAgBuC,kBAAkB;oBAAK;;YAG3FpC,yBACC,KAACjE;gBAAWmE,SAAQ;gBAAQC,IAAI;oBAAEC,IAAI;gBAAI;2BACvChC,QAAAA,kBAAAA,UAAWR,uBAAAA,IAAKkC,KAAK,YAArB1B,QAAyB;;YAG7B6B,6BACC,KAACvE;gBAAIyE,IAAI;oBAAEC,IAAI;gBAAE;0BACf,cAAA,KAACzD;oBAAkB0F,OAAOpC;;;YAG7BrC,qBACC,MAAC9B;gBAAMyE,WAAU;gBAAMC,SAAS;gBAAGL,IAAI;oBAAEC,IAAI;gBAAE;;oBAC5CxC,OAAOzB,gBAAgByB,sBACtB,KAACjC;wBAAOgF,MAAK;wBAAQT,SAAQ;wBAAY6B,UAAU1D;wBAAM2D,SAAS,IAAM,KAAKxC,OAAO5B,KAAK;gCAAEiC,OAAO;4BAAe;kCAC9GE,aAAa,CAAC,wBAAwB,EAAExD,kBAAkBwD,aAAa,GAAG;;kCAG/E,KAACpE;wBAAOgF,MAAK;wBAAQqB,SAAS,IAAMhF,WAAW;gCAAEiC,OAAOrB,IAAIsB,EAAE;4BAAC;kCAC5D;;;;;;AAMb"}
1
+ {"version":3,"sources":["../../../../../../../libs/plugins/ai/src/lib/components/assist-build-card.component.tsx"],"sourcesContent":["/**\n * @license\n * Copyright 2026 Aglyn LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n'use client'\n\nimport type { MaybeTokenSource } from '@aglyn/shared-util-http/authorized-token'\nimport { pluginDocsHelp } from '@aglyn/aglyn/app-utils/docs-help'\nimport { HelpTip } from '@aglyn/shared-ui-jsx'\nimport { Alert, Box, Button, CircularProgress, Paper, Stack, Typography } from '@mui/material'\nimport { useEffect, useRef, useState } from 'react'\nimport { aiBuildCanRetry, aiBuildItemRows, aiBuildOutcomeLine, aiBuildRetryCreditRange } from '../model/ai-build-progress'\nimport { aiCreditRangeText, type AiCreditsPrompt } from '../model/ai-credit-estimate'\nimport { AiCreditsPromptNotice } from './ai-credits-prompt.component'\nimport { aiCreditsBillingHref, aiStoreFinishHostId, aiStoreFinishLinks } from './ai-job-links'\nimport { AiStoreFinishCard } from './ai-store-finish-card.component'\nimport { AI_JOB_TERMINAL_STATUSES, type AiJobSummary } from '../model/ai-jobs.types'\nimport type { AssistBuildProposal } from '../model/assist-build'\nimport { followAiJobEvents } from './ai-job-events'\nimport { AiJobInputForm } from './ai-job-input-form.component'\nimport { AiJobPlan } from './ai-job-plan.component'\nimport { resumeAiJobRequest, type AiJobResumeOptions } from './ai-job-requests'\nimport { openAiJobs } from './ai-jobs-store'\n\n/**\n * The one card a build proposed in the chat becomes (AGL-3616): while its\n * job plans, a line saying so; then the job's own plan card, with its one\n * price and Confirm — the same `AiJobPlan` the AI jobs drawer shows, so\n * confirming here and there is one door; then where the build stands, item\n * by item, with AI jobs a click away. The job itself is started by the\n * panel, once, when the turn that proposed it ends; this card only follows\n * it, so re-rendering a stored thread never starts a second build.\n */\nexport interface AssistBuildCardProps {\n proposal: AssistBuildProposal\n /** The job the proposal started, as last seen; `null` while it is being created. */\n job: AiJobSummary | null\n /** Why the job could not be created or confirmed, when it could not. */\n notice: string | null\n orgId: string\n user: MaybeTokenSource\n staff?: boolean\n /** The job as it moved, for the thread to keep. */\n onJob: (job: AiJobSummary) => void\n onNotice: (notice: string | null) => void\n /** The workspace's path slug, for Upgrade on a Free build past what is left or paused (AGL-3722). */\n orgSlug?: string | null\n}\n\n/** The card's own section of the Assist builds guide (AGL-3660). */\nconst ASSIST_BUILD_HELP = pluginDocsHelp('aiAssistBuilds', {\n anchor: '#the-plan-card',\n excerpt:\n 'What one request will build, item by item, with its estimate. Nothing is built until you choose Confirm plan, and what it makes is a draft.',\n})\n\nconst ITEM_STATES = { done: 'built', active: 'building', waiting: 'waiting', failed: 'failed', skipped: 'not built' } as const\n\nexport function AssistBuildCard({\n proposal,\n job,\n notice,\n orgId,\n user,\n staff = false,\n onJob,\n onNotice,\n orgSlug,\n}: AssistBuildCardProps): JSX.Element {\n const [busy, setBusy] = useState(false)\n // A Free Try again past what is left (AGL-3722): its prompt, until chosen.\n const [retryPrompt, setRetryPrompt] = useState<AiCreditsPrompt | null>(null)\n const userRef = useRef(user)\n userRef.current = user\n const onJobRef = useRef(onJob)\n onJobRef.current = onJob\n\n // Follow a job that is still planning or building; a plan waiting for its\n // confirmation and a settled job need nothing more from the stream.\n // A build the meter paused (AGL-3722) waits for Resume, not the stream.\n const paused = job?.status === 'needs_input'\n const following = Boolean(\n job && !AI_JOB_TERMINAL_STATUSES.includes(job.status) && job.status !== 'needs_review' && !paused,\n )\n const jobId = job?.id ?? null\n useEffect(() => {\n if (!following || !jobId) return\n const controller = new AbortController()\n void followAiJobEvents(() => userRef.current, orgId, jobId, controller.signal, (next) => onJobRef.current(next))\n return () => controller.abort()\n }, [following, jobId, orgId])\n\n const resume = async (target: AiJobSummary, options?: AiJobResumeOptions) => {\n setBusy(true)\n onNotice(null)\n setRetryPrompt(null)\n const decision = await resumeAiJobRequest(user, orgId, target, options)\n if (decision.job) onJob(decision.job)\n // A Free Try again past what is left asks with its choices; a plan's\n // card draws its own from the job the door answered with.\n if (decision.credits && options?.retry) setRetryPrompt(decision.credits)\n else if (decision.error && !(decision.credits && target.status === 'needs_review')) onNotice(decision.error)\n setBusy(false)\n }\n const retryRange = job && aiBuildCanRetry(job) ? aiBuildRetryCreditRange(job) : null\n\n const settled = job ? AI_JOB_TERMINAL_STATUSES.includes(job.status) : false\n const outcome = job ? aiBuildOutcomeLine(job) : null\n // A build that made the site a store (AGL-3676) ends with what is left before it sells.\n const storeFinish = job && orgSlug ? aiStoreFinishLinks(job, orgSlug) : null\n return (\n <Paper variant=\"outlined\" sx={{ mt: 1, p: 1.5 }} aria-label=\"Build plan\">\n <Stack direction=\"row\" spacing={0.5} sx={{ alignItems: 'center' }}>\n <Typography variant=\"subtitle2\">{proposal.summary}</Typography>\n <HelpTip {...ASSIST_BUILD_HELP} />\n </Stack>\n {!job && !notice && (\n <Stack direction=\"row\" spacing={1} sx={{ mt: 0.5, alignItems: 'center' }}>\n <CircularProgress size={14} />\n <Typography variant=\"body2\" color=\"text.secondary\">\n {'Planning what to build on this site…'}\n </Typography>\n </Stack>\n )}\n {notice && (\n <Typography variant=\"body2\" color=\"error\" sx={{ mt: 0.5 }} role=\"alert\">\n {notice}\n </Typography>\n )}\n {job && job.status === 'needs_review' && (\n <AiJobPlan\n job={job}\n busy={busy}\n staff={staff}\n user={user}\n orgSlug={orgSlug}\n onResume={(target, options) => void resume(target, options)}\n />\n )}\n {job && following && (\n <Stack direction=\"row\" spacing={1} sx={{ mt: 0.5, alignItems: 'center' }}>\n <CircularProgress size={14} />\n <Typography variant=\"body2\" color=\"text.secondary\">\n {job.plan?.status === 'confirmed'\n ? 'Building each part in turn. What it makes is an unpublished draft unless you chose to publish.'\n : 'Planning what to build on this site…'}\n </Typography>\n </Stack>\n )}\n {job && (job.items?.length ?? 0) > 0 && job.status !== 'needs_review' && (\n <Box component=\"ul\" aria-label=\"Items\" sx={{ m: 0, mt: 0.5, pl: 2 }}>\n {aiBuildItemRows(job).map((row) => (\n <Typography key={row.slot} component=\"li\" variant=\"caption\" data-item-state={row.state}>\n {`${row.label} — ${ITEM_STATES[row.state]}`}\n {row.detail ? `. ${row.detail}` : ''}\n </Typography>\n ))}\n </Box>\n )}\n {job && paused && job.input ? (\n // A plan that needs an ID only the person has (AGL-3978): asked here,\n // and answered back onto the plan card.\n <AiJobInputForm job={{ ...job, input: job.input }} orgId={orgId} user={user} onJob={onJob} />\n ) : job && paused && (\n // Out of credits mid-build (AGL-3722): paused, never failed. What is\n // built is kept, and Resume carries on from the next item.\n <Alert\n severity=\"warning\"\n sx={{ mt: 0.5 }}\n action={\n <Stack direction=\"row\" spacing={1}>\n {orgSlug ? (\n <Button color=\"inherit\" size=\"small\" href={aiCreditsBillingHref(orgSlug)}>\n {'Upgrade'}\n </Button>\n ) : null}\n <Button color=\"inherit\" size=\"small\" disabled={busy} onClick={() => void resume(job)}>\n {'Resume'}\n </Button>\n </Stack>\n }\n >\n {`Paused. ${job.error ?? 'Your AI credits ran out.'} What is built so far is kept, and Resume carries on from the next item once you upgrade or your credits renew.`}\n </Alert>\n )}\n {job && retryPrompt && (\n <AiCreditsPromptNotice\n prompt={retryPrompt}\n noun=\"build\"\n orgSlug={orgSlug}\n busy={busy}\n onBuildWhatFits={() => void resume(job, { retry: 'failed-items', creditsConfirmed: true })}\n />\n )}\n {settled && (\n <Typography variant=\"body2\" sx={{ mt: 0.5 }}>\n {outcome ?? job?.error ?? ''}\n </Typography>\n )}\n {storeFinish && (\n <Box sx={{ mt: 1 }}>\n <AiStoreFinishCard steps={storeFinish} hostId={job ? aiStoreFinishHostId(job) : null} />\n </Box>\n )}\n {job && (\n <Stack direction=\"row\" spacing={1} sx={{ mt: 1 }}>\n {job && aiBuildCanRetry(job) && (\n <Button size=\"small\" variant=\"contained\" disabled={busy} onClick={() => void resume(job, { retry: 'failed-items' })}>\n {retryRange ? `Try again what failed · ${aiCreditRangeText(retryRange)}` : 'Try again what failed'}\n </Button>\n )}\n <Button size=\"small\" onClick={() => openAiJobs({ jobId: job.id })}>\n {'Open in AI jobs'}\n </Button>\n </Stack>\n )}\n </Paper>\n )\n}\n"],"names":["pluginDocsHelp","HelpTip","Alert","Box","Button","CircularProgress","Paper","Stack","Typography","useEffect","useRef","useState","aiBuildCanRetry","aiBuildItemRows","aiBuildOutcomeLine","aiBuildRetryCreditRange","aiCreditRangeText","AiCreditsPromptNotice","aiCreditsBillingHref","aiStoreFinishHostId","aiStoreFinishLinks","AiStoreFinishCard","AI_JOB_TERMINAL_STATUSES","followAiJobEvents","AiJobInputForm","AiJobPlan","resumeAiJobRequest","openAiJobs","ASSIST_BUILD_HELP","anchor","excerpt","ITEM_STATES","done","active","waiting","failed","skipped","AssistBuildCard","proposal","job","notice","orgId","user","staff","onJob","onNotice","orgSlug","outcome","busy","setBusy","retryPrompt","setRetryPrompt","userRef","current","onJobRef","paused","status","following","Boolean","includes","jobId","id","controller","AbortController","signal","next","abort","resume","target","options","decision","credits","retry","error","retryRange","settled","storeFinish","variant","sx","mt","p","aria-label","direction","spacing","alignItems","summary","size","color","role","onResume","plan","items","length","component","m","pl","map","row","data-item-state","state","label","detail","slot","input","severity","action","href","disabled","onClick","prompt","noun","onBuildWhatFits","creditsConfirmed","steps","hostId"],"mappings":"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"}
@@ -26,6 +26,7 @@ import { authorizedFetch } from "@aglyn/shared-util-http/authorized-token";
26
26
  import { Box, Button, Chip, CircularProgress, Collapse, IconButton, Stack, Typography } from "@mui/material";
27
27
  import { useCallback, useEffect, useRef, useState } from "react";
28
28
  import { AI_JOB_PHASE_LABELS, aiJobActivityCounts, aiJobPhase, aiJobsHeaderChips } from "../model/ai-job-activity.js";
29
+ import { AiJobInputForm } from "./ai-job-input-form.component.js";
29
30
  import { resumeAiJobRequest } from "./ai-job-requests.js";
30
31
  import { useAiJobCancel } from "./ai-job-cancel.component.js";
31
32
  import { aiBuildCanRetry, aiBuildItemRows, aiBuildRetryCreditRange, aiSitePartialCopy } from "../model/ai-build-progress.js";
@@ -591,7 +592,14 @@ export function AssistJobsDrawer({ orgId, org, orgReady, orgSlug, user, visible,
591
592
  creditsConfirmed: true
592
593
  })
593
594
  }) : null,
594
- job.status === 'needs_input' ? /*#__PURE__*/ _jsxs(Stack, {
595
+ job.status === 'needs_input' && job.input ? /*#__PURE__*/ _jsx(AiJobInputForm, {
596
+ job: _extends({}, job, {
597
+ input: job.input
598
+ }),
599
+ orgId: orgId,
600
+ user: user,
601
+ onJob: patchJob
602
+ }) : /* Paused by the meter (AGL-3722): Resume carries on from where it stopped. */ job.status === 'needs_input' ? /*#__PURE__*/ _jsxs(Stack, {
595
603
  direction: "row",
596
604
  spacing: 1,
597
605
  sx: {