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

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 (274) hide show
  1. package/README.md +3 -3
  2. package/package.json +17 -17
  3. package/src/lib/activity/ai-activity-actions.js +7 -1
  4. package/src/lib/activity/ai-activity-actions.js.map +1 -1
  5. package/src/lib/components/ai-automation-zones.d.ts +38 -0
  6. package/src/lib/components/ai-automation-zones.js +5 -1
  7. package/src/lib/components/ai-automation-zones.js.map +1 -1
  8. package/src/lib/components/ai-brief-dialog.component.d.ts +20 -2
  9. package/src/lib/components/ai-brief-dialog.component.js +87 -8
  10. package/src/lib/components/ai-brief-dialog.component.js.map +1 -1
  11. package/src/lib/components/ai-campaign-create.component.d.ts +54 -0
  12. package/src/lib/components/ai-campaign-create.component.js +270 -0
  13. package/src/lib/components/ai-campaign-create.component.js.map +1 -0
  14. package/src/lib/components/ai-describe-automation.component.d.ts +8 -3
  15. package/src/lib/components/ai-describe-automation.component.js +15 -6
  16. package/src/lib/components/ai-describe-automation.component.js.map +1 -1
  17. package/src/lib/components/ai-describe-button.component.d.ts +20 -8
  18. package/src/lib/components/ai-describe-button.component.js +19 -36
  19. package/src/lib/components/ai-describe-button.component.js.map +1 -1
  20. package/src/lib/components/ai-describe-email.component.d.ts +31 -0
  21. package/src/lib/components/ai-describe-email.component.js +22 -0
  22. package/src/lib/components/ai-describe-email.component.js.map +1 -0
  23. package/src/lib/components/ai-describe-org-automation.component.d.ts +36 -0
  24. package/src/lib/components/ai-describe-org-automation.component.js +238 -0
  25. package/src/lib/components/ai-describe-org-automation.component.js.map +1 -0
  26. package/src/lib/components/ai-experiment-cards.component.d.ts +9 -1
  27. package/src/lib/components/ai-experiment-cards.component.js +104 -18
  28. package/src/lib/components/ai-experiment-cards.component.js.map +1 -1
  29. package/src/lib/components/ai-explain-automation.component.js +1 -5
  30. package/src/lib/components/ai-explain-automation.component.js.map +1 -1
  31. package/src/lib/components/ai-funnel-zones.component.d.ts +61 -0
  32. package/src/lib/components/ai-funnel-zones.component.js +178 -0
  33. package/src/lib/components/ai-funnel-zones.component.js.map +1 -0
  34. package/src/lib/components/ai-insight-card.component.d.ts +42 -0
  35. package/src/lib/components/ai-insight-card.component.js +137 -0
  36. package/src/lib/components/ai-insight-card.component.js.map +1 -0
  37. package/src/lib/components/ai-insight-dialog.component.d.ts +6 -0
  38. package/src/lib/components/ai-insight-dialog.component.js +9 -3
  39. package/src/lib/components/ai-insight-dialog.component.js.map +1 -1
  40. package/src/lib/components/ai-job-plan.component.d.ts +7 -2
  41. package/src/lib/components/ai-job-plan.component.js +35 -5
  42. package/src/lib/components/ai-job-plan.component.js.map +1 -1
  43. package/src/lib/components/ai-job-requests.d.ts +17 -1
  44. package/src/lib/components/ai-job-requests.js +39 -3
  45. package/src/lib/components/ai-job-requests.js.map +1 -1
  46. package/src/lib/components/ai-jobs-list-page.component.js +12 -1
  47. package/src/lib/components/ai-jobs-list-page.component.js.map +1 -1
  48. package/src/lib/components/ai-logic-zones.d.ts +64 -0
  49. package/src/lib/components/ai-logic-zones.js +18 -0
  50. package/src/lib/components/ai-logic-zones.js.map +1 -0
  51. package/src/lib/components/ai-logic.component.d.ts +77 -0
  52. package/src/lib/components/ai-logic.component.js +553 -0
  53. package/src/lib/components/ai-logic.component.js.map +1 -0
  54. package/src/lib/components/ai-marketing-insight.component.d.ts +30 -0
  55. package/src/lib/components/ai-marketing-insight.component.js +80 -0
  56. package/src/lib/components/ai-marketing-insight.component.js.map +1 -0
  57. package/src/lib/components/ai-media-create.component.d.ts +55 -0
  58. package/src/lib/components/ai-media-create.component.js +433 -0
  59. package/src/lib/components/ai-media-create.component.js.map +1 -0
  60. package/src/lib/components/ai-overlay-cards.component.d.ts +83 -0
  61. package/src/lib/components/ai-overlay-cards.component.js +505 -0
  62. package/src/lib/components/ai-overlay-cards.component.js.map +1 -0
  63. package/src/lib/components/ai-product-zones.d.ts +5 -0
  64. package/src/lib/components/ai-product-zones.js +1 -1
  65. package/src/lib/components/ai-product-zones.js.map +1 -1
  66. package/src/lib/components/ai-products-create-button.component.d.ts +42 -0
  67. package/src/lib/components/ai-products-create-button.component.js +67 -0
  68. package/src/lib/components/ai-products-create-button.component.js.map +1 -0
  69. package/src/lib/components/ai-products-hub-card.component.js +100 -81
  70. package/src/lib/components/ai-products-hub-card.component.js.map +1 -1
  71. package/src/lib/components/ai-revise-automation.component.d.ts +16 -0
  72. package/src/lib/components/ai-revise-automation.component.js +207 -0
  73. package/src/lib/components/ai-revise-automation.component.js.map +1 -0
  74. package/src/lib/components/ai-site-build-page.component.d.ts +1 -1
  75. package/src/lib/components/ai-site-build-page.component.js +177 -20
  76. package/src/lib/components/ai-site-build-page.component.js.map +1 -1
  77. package/src/lib/components/ai-site-start-card.component.d.ts +10 -1
  78. package/src/lib/components/ai-site-start-card.component.js +7 -4
  79. package/src/lib/components/ai-site-start-card.component.js.map +1 -1
  80. package/src/lib/components/ai-upsell-dialog.component.d.ts +53 -0
  81. package/src/lib/components/ai-upsell-dialog.component.js +177 -0
  82. package/src/lib/components/ai-upsell-dialog.component.js.map +1 -0
  83. package/src/lib/components/assist-build-card.component.d.ts +42 -0
  84. package/src/lib/components/assist-build-card.component.js +183 -0
  85. package/src/lib/components/assist-build-card.component.js.map +1 -0
  86. package/src/lib/components/assist-edit-canvas.d.ts +2 -0
  87. package/src/lib/components/assist-edit-canvas.js +56 -1
  88. package/src/lib/components/assist-edit-canvas.js.map +1 -1
  89. package/src/lib/components/assist-jobs-drawer.component.d.ts +11 -0
  90. package/src/lib/components/assist-jobs-drawer.component.js +85 -4
  91. package/src/lib/components/assist-jobs-drawer.component.js.map +1 -1
  92. package/src/lib/components/assist-panel.component.js +51 -2
  93. package/src/lib/components/assist-panel.component.js.map +1 -1
  94. package/src/lib/components/use-ai-job-run.d.ts +3 -14
  95. package/src/lib/components/use-ai-job-run.js +0 -50
  96. package/src/lib/components/use-ai-job-run.js.map +1 -1
  97. package/src/lib/jobs/ai-build-capabilities.d.ts +58 -0
  98. package/src/lib/jobs/ai-build-capabilities.js +256 -0
  99. package/src/lib/jobs/ai-build-capabilities.js.map +1 -0
  100. package/src/lib/jobs/ai-build-unit-outcome.d.ts +52 -0
  101. package/src/lib/jobs/ai-build-unit-outcome.js +138 -0
  102. package/src/lib/jobs/ai-build-unit-outcome.js.map +1 -0
  103. package/src/lib/jobs/ai-job-build-step.d.ts +144 -0
  104. package/src/lib/jobs/ai-job-build-step.js +657 -0
  105. package/src/lib/jobs/ai-job-build-step.js.map +1 -0
  106. package/src/lib/jobs/ai-job-draft-ids.js +9 -1
  107. package/src/lib/jobs/ai-job-draft-ids.js.map +1 -1
  108. package/src/lib/jobs/ai-job-drafts.d.ts +14 -4
  109. package/src/lib/jobs/ai-job-drafts.js +25 -4
  110. package/src/lib/jobs/ai-job-drafts.js.map +1 -1
  111. package/src/lib/jobs/ai-job-layout-site-pages.d.ts +70 -0
  112. package/src/lib/jobs/ai-job-layout-site-pages.js +216 -0
  113. package/src/lib/jobs/ai-job-layout-site-pages.js.map +1 -0
  114. package/src/lib/jobs/ai-job-layout-step.d.ts +2 -2
  115. package/src/lib/jobs/ai-job-layout-step.js +19 -1
  116. package/src/lib/jobs/ai-job-layout-step.js.map +1 -1
  117. package/src/lib/jobs/ai-job-logic-step.d.ts +107 -0
  118. package/src/lib/jobs/ai-job-logic-step.js +395 -0
  119. package/src/lib/jobs/ai-job-logic-step.js.map +1 -0
  120. package/src/lib/jobs/ai-job-overlay-copy.d.ts +70 -0
  121. package/src/lib/jobs/ai-job-overlay-copy.js +178 -0
  122. package/src/lib/jobs/ai-job-overlay-copy.js.map +1 -0
  123. package/src/lib/jobs/ai-job-page-step.js +6 -6
  124. package/src/lib/jobs/ai-job-page-step.js.map +1 -1
  125. package/src/lib/jobs/ai-job-plan-step.d.ts +26 -1
  126. package/src/lib/jobs/ai-job-plan-step.js +79 -11
  127. package/src/lib/jobs/ai-job-plan-step.js.map +1 -1
  128. package/src/lib/jobs/ai-job-site-step.d.ts +15 -1
  129. package/src/lib/jobs/ai-job-site-step.js +207 -58
  130. package/src/lib/jobs/ai-job-site-step.js.map +1 -1
  131. package/src/lib/jobs/ai-job-text-step.d.ts +22 -1
  132. package/src/lib/jobs/ai-job-text-step.js +12 -0
  133. package/src/lib/jobs/ai-job-text-step.js.map +1 -1
  134. package/src/lib/jobs/ai-job-workflow-step.d.ts +54 -4
  135. package/src/lib/jobs/ai-job-workflow-step.js +318 -13
  136. package/src/lib/jobs/ai-job-workflow-step.js.map +1 -1
  137. package/src/lib/jobs/ai-jobs.d.ts +90 -2
  138. package/src/lib/jobs/ai-jobs.js +495 -61
  139. package/src/lib/jobs/ai-jobs.js.map +1 -1
  140. package/src/lib/jobs/ai-logic-records.d.ts +40 -0
  141. package/src/lib/jobs/ai-logic-records.js +55 -0
  142. package/src/lib/jobs/ai-logic-records.js.map +1 -0
  143. package/src/lib/jobs/ai-site-publish.d.ts +7 -0
  144. package/src/lib/jobs/ai-site-publish.js +9 -0
  145. package/src/lib/jobs/ai-site-publish.js.map +1 -1
  146. package/src/lib/jobs/ai-workflow-records.d.ts +4 -0
  147. package/src/lib/jobs/ai-workflow-records.js +40 -1
  148. package/src/lib/jobs/ai-workflow-records.js.map +1 -1
  149. package/src/lib/model/ai-automation-draft.d.ts +18 -0
  150. package/src/lib/model/ai-automation-draft.js +86 -0
  151. package/src/lib/model/ai-automation-draft.js.map +1 -1
  152. package/src/lib/model/ai-build-job.d.ts +201 -0
  153. package/src/lib/model/ai-build-job.js +471 -0
  154. package/src/lib/model/ai-build-job.js.map +1 -0
  155. package/src/lib/model/ai-build-plan.d.ts +61 -0
  156. package/src/lib/model/ai-build-plan.js +154 -9
  157. package/src/lib/model/ai-build-plan.js.map +1 -1
  158. package/src/lib/model/ai-build-progress.d.ts +56 -0
  159. package/src/lib/model/ai-build-progress.js +128 -0
  160. package/src/lib/model/ai-build-progress.js.map +1 -0
  161. package/src/lib/model/ai-insight.d.ts +20 -10
  162. package/src/lib/model/ai-insight.js +72 -9
  163. package/src/lib/model/ai-insight.js.map +1 -1
  164. package/src/lib/model/ai-job-activity.js +3 -1
  165. package/src/lib/model/ai-job-activity.js.map +1 -1
  166. package/src/lib/model/ai-job-failure-copy.d.ts +20 -1
  167. package/src/lib/model/ai-job-failure-copy.js +28 -1
  168. package/src/lib/model/ai-job-failure-copy.js.map +1 -1
  169. package/src/lib/model/ai-job-notice.d.ts +3 -0
  170. package/src/lib/model/ai-job-notice.js +11 -2
  171. package/src/lib/model/ai-job-notice.js.map +1 -1
  172. package/src/lib/model/ai-jobs.types.d.ts +87 -2
  173. package/src/lib/model/ai-jobs.types.js +3 -1
  174. package/src/lib/model/ai-jobs.types.js.map +1 -1
  175. package/src/lib/model/ai-logic-job.d.ts +108 -0
  176. package/src/lib/model/ai-logic-job.js +327 -0
  177. package/src/lib/model/ai-logic-job.js.map +1 -0
  178. package/src/lib/model/ai-media-credits.d.ts +52 -0
  179. package/src/lib/model/ai-media-credits.js +61 -0
  180. package/src/lib/model/ai-media-credits.js.map +1 -0
  181. package/src/lib/model/ai-overlay-copy.d.ts +114 -0
  182. package/src/lib/model/ai-overlay-copy.js +175 -0
  183. package/src/lib/model/ai-overlay-copy.js.map +1 -0
  184. package/src/lib/model/ai-site-build-progress.d.ts +28 -3
  185. package/src/lib/model/ai-site-build-progress.js +231 -17
  186. package/src/lib/model/ai-site-build-progress.js.map +1 -1
  187. package/src/lib/model/ai-site-start-seo.d.ts +16 -0
  188. package/src/lib/model/ai-site-start-seo.js +54 -4
  189. package/src/lib/model/ai-site-start-seo.js.map +1 -1
  190. package/src/lib/model/ai-site-start.d.ts +14 -0
  191. package/src/lib/model/ai-site-start.js +43 -0
  192. package/src/lib/model/ai-site-start.js.map +1 -1
  193. package/src/lib/model/ai-svg.d.ts +69 -0
  194. package/src/lib/model/ai-svg.js +265 -0
  195. package/src/lib/model/ai-svg.js.map +1 -0
  196. package/src/lib/model/ai-usage-by-user.d.ts +3 -2
  197. package/src/lib/model/ai-usage-by-user.js.map +1 -1
  198. package/src/lib/model/ai-workflow-job.d.ts +92 -4
  199. package/src/lib/model/ai-workflow-job.js +124 -7
  200. package/src/lib/model/ai-workflow-job.js.map +1 -1
  201. package/src/lib/model/assist-build.d.ts +58 -0
  202. package/src/lib/model/assist-build.js +52 -0
  203. package/src/lib/model/assist-build.js.map +1 -0
  204. package/src/lib/model/assist-edit.d.ts +48 -3
  205. package/src/lib/model/assist-edit.js +48 -4
  206. package/src/lib/model/assist-edit.js.map +1 -1
  207. package/src/lib/plugin-config.js +2 -0
  208. package/src/lib/plugin-config.js.map +1 -1
  209. package/src/lib/plugin.js +240 -11
  210. package/src/lib/plugin.js.map +1 -1
  211. package/src/lib/providers/catalog.d.ts +81 -4
  212. package/src/lib/providers/catalog.js +80 -9
  213. package/src/lib/providers/catalog.js.map +1 -1
  214. package/src/lib/providers/image-contract.d.ts +116 -0
  215. package/src/lib/providers/image-contract.js +74 -0
  216. package/src/lib/providers/image-contract.js.map +1 -0
  217. package/src/lib/providers/model-choice.js +11 -0
  218. package/src/lib/providers/model-choice.js.map +1 -1
  219. package/src/lib/providers/routing.js +18 -0
  220. package/src/lib/providers/routing.js.map +1 -1
  221. package/src/lib/providers/vertex-image.d.ts +121 -0
  222. package/src/lib/providers/vertex-image.js +312 -0
  223. package/src/lib/providers/vertex-image.js.map +1 -0
  224. package/src/lib/runtime/ai-doctrine-validators.d.ts +19 -0
  225. package/src/lib/runtime/ai-doctrine-validators.js +89 -0
  226. package/src/lib/runtime/ai-doctrine-validators.js.map +1 -1
  227. package/src/lib/runtime/ai-doctrine.d.ts +6 -0
  228. package/src/lib/runtime/ai-doctrine.js +16 -6
  229. package/src/lib/runtime/ai-doctrine.js.map +1 -1
  230. package/src/lib/runtime/ai-eval-live.js +4 -0
  231. package/src/lib/runtime/ai-eval-live.js.map +1 -1
  232. package/src/lib/runtime/ai-eval.d.ts +15 -1
  233. package/src/lib/runtime/ai-eval.js +52 -1
  234. package/src/lib/runtime/ai-eval.js.map +1 -1
  235. package/src/lib/runtime/experiment-variant-copy.d.ts +34 -0
  236. package/src/lib/runtime/experiment-variant-copy.js +102 -0
  237. package/src/lib/runtime/experiment-variant-copy.js.map +1 -0
  238. package/src/lib/server/ai-experiment-versions.d.ts +51 -0
  239. package/src/lib/server/ai-experiment-versions.js +270 -0
  240. package/src/lib/server/ai-experiment-versions.js.map +1 -0
  241. package/src/lib/server/ai-jobs-resume.js +74 -4
  242. package/src/lib/server/ai-jobs-resume.js.map +1 -1
  243. package/src/lib/server/ai-media-image.d.ts +66 -0
  244. package/src/lib/server/ai-media-image.js +521 -0
  245. package/src/lib/server/ai-media-image.js.map +1 -0
  246. package/src/lib/server/ai-media-svg.d.ts +91 -0
  247. package/src/lib/server/ai-media-svg.js +186 -0
  248. package/src/lib/server/ai-media-svg.js.map +1 -0
  249. package/src/lib/server/assist-build.d.ts +54 -0
  250. package/src/lib/server/assist-build.js +121 -0
  251. package/src/lib/server/assist-build.js.map +1 -0
  252. package/src/lib/server/assist-chat.js +108 -12
  253. package/src/lib/server/assist-chat.js.map +1 -1
  254. package/src/lib/server/assist-edit.js +213 -3
  255. package/src/lib/server/assist-edit.js.map +1 -1
  256. package/src/lib/server/assist-view-context.js +242 -4
  257. package/src/lib/server/assist-view-context.js.map +1 -1
  258. package/src/lib/server.js +26 -0
  259. package/src/lib/server.js.map +1 -1
  260. package/src/lib/tools/ai-logic-tool.d.ts +27 -0
  261. package/src/lib/tools/ai-logic-tool.js +207 -0
  262. package/src/lib/tools/ai-logic-tool.js.map +1 -0
  263. package/src/lib/tools/ai-overlay-tool.d.ts +35 -0
  264. package/src/lib/tools/ai-overlay-tool.js +107 -0
  265. package/src/lib/tools/ai-overlay-tool.js.map +1 -0
  266. package/src/lib/tools/ai-workflow-tool.d.ts +11 -0
  267. package/src/lib/tools/ai-workflow-tool.js +31 -0
  268. package/src/lib/tools/ai-workflow-tool.js.map +1 -1
  269. package/src/lib/usage/assist-job-refund.d.ts +31 -3
  270. package/src/lib/usage/assist-job-refund.js +46 -10
  271. package/src/lib/usage/assist-job-refund.js.map +1 -1
  272. package/src/lib/usage/assist-usage.d.ts +5 -0
  273. package/src/lib/usage/assist-usage.js +2 -0
  274. package/src/lib/usage/assist-usage.js.map +1 -1
@@ -17,7 +17,9 @@ import { _ as _extends } from "@swc/helpers/_/_extends";
17
17
  */ import { linealRelationshipPermits } from "@aglyn/aglyn/app-utils/lineal-order";
18
18
  import { SCREEN_SEO_TEXT_FIELDS, SCREEN_SEO_TEXT_GUIDANCE } from "@aglyn/aglyn/app-utils/screen-seo-fields";
19
19
  import { CANVAS_ROOT_ELEMENT_ID } from "@aglyn/aglyn/foundation/constants/canvas";
20
- import { ASSIST_EDIT_ACTION_ID, ASSIST_EDIT_CONTEXT_MAX_NODES, ASSIST_EDIT_CONTEXT_MAX_PROPS, ASSIST_EDIT_MAX_DROPPED_REASONS, ASSIST_EDIT_OP_KINDS, ASSIST_EDIT_OUTLINE_TEXT_CHARS, ASSIST_EDIT_SELECTED_TEXT_CHARS, ASSIST_EDIT_TOOL_NAME, summarizeAssistEditOps } from "../model/assist-edit.js";
20
+ import { NODE_MAX_INTERACTIONS, nodeInteractionSelector } from "@aglyn/aglyn/app-utils/node-interactions";
21
+ import { ACTION_MAX_STEPS, CLIENT_INTERACTION_STEP_LABELS, validateInteraction } from "@aglyn/aglyn/app-utils/site-interactions";
22
+ import { ASSIST_EDIT_ACTION_ID, ASSIST_EDIT_CONTEXT_MAX_NODES, ASSIST_EDIT_CONTEXT_MAX_PROPS, ASSIST_EDIT_INTERACTION_EVENTS, ASSIST_EDIT_INTERACTION_STEPS, ASSIST_EDIT_MAX_DROPPED_REASONS, ASSIST_EDIT_OP_KINDS, ASSIST_EDIT_OUTLINE_TEXT_CHARS, ASSIST_EDIT_SELECTED_TEXT_CHARS, ASSIST_EDIT_TOOL_NAME, summarizeAssistEditOps } from "../model/assist-edit.js";
21
23
  import { aiDoctrineCatalog, validateStreamedGeneration } from "../runtime/ai-doctrine.js";
22
24
  import { AI_SX_ALLOWED_KEYS, validateAiNodePatch, validateAiNodeTree } from "../runtime/ai-node-tree.js";
23
25
  import { AI_NODE_CAPABILITIES, AI_PALETTE, AI_SX_TOKENS } from "../runtime/ai-palette.generated.js";
@@ -137,6 +139,37 @@ const strictObject = (properties)=>({
137
139
  },
138
140
  value: STRING
139
141
  });
142
+ const step = strictObject({
143
+ type: {
144
+ type: 'string',
145
+ enum: [
146
+ ...ASSIST_EDIT_INTERACTION_STEPS
147
+ ]
148
+ },
149
+ targetId: STRING,
150
+ className: STRING,
151
+ url: STRING,
152
+ message: STRING,
153
+ delayMs: {
154
+ type: 'integer'
155
+ }
156
+ });
157
+ const interaction = strictObject({
158
+ event: {
159
+ type: 'string',
160
+ enum: [
161
+ '',
162
+ ...ASSIST_EDIT_INTERACTION_EVENTS
163
+ ]
164
+ },
165
+ everyTime: {
166
+ type: 'boolean'
167
+ },
168
+ steps: {
169
+ type: 'array',
170
+ items: step
171
+ }
172
+ });
140
173
  const op = strictObject({
141
174
  op: {
142
175
  type: 'string',
@@ -163,7 +196,8 @@ const strictObject = (properties)=>({
163
196
  seo: {
164
197
  type: 'array',
165
198
  items: seo
166
- }
199
+ },
200
+ interaction
167
201
  });
168
202
  return {
169
203
  name: ASSIST_EDIT_TOOL_NAME,
@@ -212,7 +246,8 @@ const strictObject = (properties)=>({
212
246
  '- insertSubtree: parentId, index (-1 appends) and nodes — the new elements, nodes[0] their root, each listing its children by the ids you gave them in this operation. Build only from the elements below, and keep it small.',
213
247
  '- move: nodeId, parentId and index — the position the element takes among the parent’s children once moved (-1 appends).',
214
248
  '- remove: nodeId — the element and everything inside it.',
215
- '- rename: nodeId and name, the layer name shown in the hierarchy.'
249
+ '- rename: nodeId and name, the layer name shown in the hierarchy.',
250
+ `- addInteraction: nodeId, name and interaction — what the element does when a visitor acts on it, added beside any it already has. event: ${ASSIST_EDIT_INTERACTION_EVENTS.join(', ')}. everyTime: true for anything a visitor repeats, such as opening a menu; false to run once a page view. steps, in order, each a type with only its own fields filled: ${ASSIST_EDIT_INTERACTION_STEPS.join(', ')}. targetId is the element a step acts on (an id listed below; "" for the page's first drawer or menu, and for redirect and siteAlert); className for the class steps; url for redirect (a path such as /contact, or an https address); message for siteAlert; delayMs for show and hide (-1 for none). An element's "interactions" lists what it already does, for explaining it.`
216
251
  ];
217
252
  if (kind === 'screen') {
218
253
  lines.push(`- setSeo: seo as field/value — ${SCREEN_SEO_TEXT_FIELDS.map((field)=>`${field} (reads best at ${SCREEN_SEO_TEXT_GUIDANCE[field]} characters or fewer)`).join(', ')}.`);
@@ -264,6 +299,28 @@ function describeSx(raw) {
264
299
  }
265
300
  return Object.keys(sx).length ? sx : undefined;
266
301
  }
302
+ const STEP_NAME = /^[A-Za-z][A-Za-z0-9_.:-]{0,63}$/;
303
+ /**
304
+ * The selected element's interactions as an outline may carry them: a name,
305
+ * an event and the kinds of its steps, each to its own alphabet — never a
306
+ * selector, a script or HTML.
307
+ */ function describeInteractions(raw) {
308
+ if (!Array.isArray(raw)) return undefined;
309
+ const out = [];
310
+ for (const entry of raw.slice(0, NODE_MAX_INTERACTIONS)){
311
+ var _entry_event;
312
+ if (!isRecord(entry)) continue;
313
+ const event = String((_entry_event = entry['event']) != null ? _entry_event : '');
314
+ if (!STEP_NAME.test(event)) continue;
315
+ out.push({
316
+ name: cleanText(entry['name'], LAYER_NAME_CHARS).replace(/[<>]/g, ''),
317
+ event,
318
+ steps: (Array.isArray(entry['steps']) ? entry['steps'] : []).map(String).filter((type)=>STEP_NAME.test(type)).slice(0, ACTION_MAX_STEPS),
319
+ enabled: entry['enabled'] !== false
320
+ });
321
+ }
322
+ return out.length ? out : undefined;
323
+ }
267
324
  /**
268
325
  * The canvas outline a request carried, held to what may enter a prompt.
269
326
  *
@@ -297,6 +354,7 @@ function describeSx(raw) {
297
354
  const brief = entry['brief'] === true && !selected;
298
355
  const props = brief ? undefined : describeProps(entry['props'], selected ? ASSIST_EDIT_SELECTED_TEXT_CHARS : ASSIST_EDIT_OUTLINE_TEXT_CHARS);
299
356
  const sx = selected ? describeSx(entry['sx']) : undefined;
357
+ const interactions = selected ? describeInteractions(entry['interactions']) : undefined;
300
358
  // Alike only an element described before this one.
301
359
  const like = entry['like'];
302
360
  const alike = isNodeId(like) && seen.has(like);
@@ -317,6 +375,8 @@ function describeSx(raw) {
317
375
  brief: true
318
376
  } : {}, alike ? {
319
377
  like
378
+ } : {}, interactions ? {
379
+ interactions
320
380
  } : {}));
321
381
  }
322
382
  if (!nodes.some((node)=>node.id === CANVAS_ROOT_ELEMENT_ID)) return null;
@@ -429,6 +489,7 @@ function describeSx(raw) {
429
489
  'Elements, one JSON object per line:'
430
490
  ];
431
491
  for (const node of context.nodes){
492
+ var _node_interactions;
432
493
  if (node.brief) continue;
433
494
  const more = unlisted(node);
434
495
  lines.push(JSON.stringify(_extends({
@@ -447,6 +508,8 @@ function describeSx(raw) {
447
508
  props: node.props
448
509
  } : {}, node.sx ? {
449
510
  sx: node.sx
511
+ } : {}, ((_node_interactions = node.interactions) == null ? void 0 : _node_interactions.length) ? {
512
+ interactions: node.interactions
450
513
  } : {})));
451
514
  }
452
515
  const around = context.nodes.filter((node)=>node.brief);
@@ -559,6 +622,137 @@ const triplesToSx = (value)=>{
559
622
  // An ancestor the outline does not describe: the chain cannot be checked.
560
623
  return null;
561
624
  }
625
+ /** A class name a class step may toggle: one plain CSS identifier. */ const CLASS_NAME = /^-?[A-Za-z_][A-Za-z0-9_-]{0,40}$/;
626
+ /** Where a redirect may go: a path on the site, or an https address. */ const REDIRECT_URL = /^(\/[^\s<>"']{0,200}|https:\/\/[^\s<>"']{1,200})$/;
627
+ const ELEMENT_STEPS = new Set([
628
+ 'showElement',
629
+ 'hideElement',
630
+ 'toggleElement',
631
+ 'addClass',
632
+ 'removeClass',
633
+ 'toggleClass',
634
+ 'scrollTo',
635
+ 'playVideo'
636
+ ]);
637
+ const DELAYED_STEPS = new Set([
638
+ 'showElement',
639
+ 'hideElement',
640
+ 'toggleElement'
641
+ ]);
642
+ /** A short id for an interaction Assist adds; the element keeps it. */ function interactionId() {
643
+ return `ai${Math.random().toString(36).slice(2, 10)}`;
644
+ }
645
+ /**
646
+ * An `addInteraction` op's interaction, in the shape the element stores it,
647
+ * or why it was left out. Every element a step acts on is one the request
648
+ * described; a step's selector is DERIVED from that element's id, as the
649
+ * Besigner's target picker writes it, never taken from the model.
650
+ */ function interactionOf(raw, label, target) {
651
+ const spec = isRecord(raw['interaction']) ? raw['interaction'] : {};
652
+ const event = spec['event'];
653
+ if (!ASSIST_EDIT_INTERACTION_EVENTS.includes(event)) {
654
+ return `${label}: the interaction listens for nothing an element does`;
655
+ }
656
+ const rawSteps = (Array.isArray(spec['steps']) ? spec['steps'] : []).filter(isRecord);
657
+ if (!rawSteps.length) return `${label}: the interaction does nothing`;
658
+ if (rawSteps.length > ACTION_MAX_STEPS) return `${label}: more than ${ACTION_MAX_STEPS} steps`;
659
+ const targets = [];
660
+ const steps = [];
661
+ for (const [index, rawStep] of rawSteps.entries()){
662
+ var _rawStep_targetId;
663
+ const where = `${label}, step ${index + 1}`;
664
+ const type = rawStep['type'];
665
+ if (!ASSIST_EDIT_INTERACTION_STEPS.includes(type)) {
666
+ return `${where}: not a step an interaction may take here`;
667
+ }
668
+ const targetId = String((_rawStep_targetId = rawStep['targetId']) != null ? _rawStep_targetId : '');
669
+ let step;
670
+ if (ELEMENT_STEPS.has(type)) {
671
+ const node = target(targetId);
672
+ if (!node) return `${where}: acts on an element that is not on the canvas described`;
673
+ targets.push({
674
+ nodeId: node.id,
675
+ componentId: node.componentId
676
+ });
677
+ step = {
678
+ type,
679
+ selector: nodeInteractionSelector(node.id)
680
+ };
681
+ if (type === 'addClass' || type === 'removeClass' || type === 'toggleClass') {
682
+ var _rawStep_className;
683
+ const className = String((_rawStep_className = rawStep['className']) != null ? _rawStep_className : '').trim();
684
+ if (!CLASS_NAME.test(className)) return `${where}: names no class`;
685
+ step = _extends({}, step, {
686
+ className
687
+ });
688
+ }
689
+ const delay = Number(rawStep['delayMs']);
690
+ if (DELAYED_STEPS.has(type) && Number.isInteger(delay) && delay > 0) step = _extends({}, step, {
691
+ delayMs: delay
692
+ });
693
+ } else if (type === 'redirect') {
694
+ var _rawStep_url;
695
+ const url = String((_rawStep_url = rawStep['url']) != null ? _rawStep_url : '').trim();
696
+ if (!REDIRECT_URL.test(url)) return `${where}: redirects nowhere a visitor can go`;
697
+ step = {
698
+ type,
699
+ url
700
+ };
701
+ } else if (type === 'siteAlert') {
702
+ const message = cleanText(rawStep['message'], 200);
703
+ if (!message || MARKUP.test(message)) return `${where}: the message is empty or carries markup`;
704
+ step = {
705
+ type,
706
+ message
707
+ };
708
+ } else {
709
+ // A drawer or a menu: the element named, or the page's first one.
710
+ const field = type.endsWith('Drawer') ? 'drawerNodeId' : 'menuNodeId';
711
+ if (targetId) {
712
+ const node = target(targetId);
713
+ if (!node) return `${where}: acts on an element that is not on the canvas described`;
714
+ targets.push({
715
+ nodeId: node.id,
716
+ componentId: node.componentId
717
+ });
718
+ step = {
719
+ type,
720
+ [field]: node.id
721
+ };
722
+ } else {
723
+ step = {
724
+ type
725
+ };
726
+ }
727
+ }
728
+ steps.push(step);
729
+ }
730
+ const name = cleanText(raw['name'], LAYER_NAME_CHARS).replace(/[<>]/g, '') || CLIENT_INTERACTION_STEP_LABELS[steps[0].type] || 'Interaction';
731
+ const trigger = _extends({
732
+ event: event
733
+ }, spec['everyTime'] === true ? {
734
+ everyTime: true
735
+ } : {});
736
+ const interaction = {
737
+ id: interactionId(),
738
+ name,
739
+ trigger,
740
+ steps: steps,
741
+ enabled: true
742
+ };
743
+ // The platform's own check, as the Interactions builder saves one: the
744
+ // element's derived selector stands in for the trigger's.
745
+ const problem = validateInteraction(_extends({}, interaction, {
746
+ trigger: _extends({}, trigger, {
747
+ selector: nodeInteractionSelector('selected')
748
+ })
749
+ }));
750
+ if (problem) return `${label}: ${problem}`;
751
+ return {
752
+ interaction,
753
+ targets
754
+ };
755
+ }
562
756
  /**
563
757
  * The tool's input, held to the closed world: every element an op names is
564
758
  * one the request described, and an op the structure alone refuses is
@@ -765,6 +959,22 @@ const triplesToSx = (value)=>{
765
959
  });
766
960
  return;
767
961
  }
962
+ case 'addInteraction':
963
+ {
964
+ const node = described(raw['nodeId'], label);
965
+ if (!node) return;
966
+ const built = interactionOf(raw, label, (id)=>typeof id === 'string' && byId.has(id) && id !== CANVAS_ROOT_ELEMENT_ID && !insideRemoved(id) ? byId.get(id) : null);
967
+ if (typeof built === 'string') {
968
+ dropped.push(built);
969
+ return;
970
+ }
971
+ pending.push(_extends({
972
+ op,
973
+ nodeId: node.id,
974
+ componentId: node.componentId
975
+ }, built));
976
+ return;
977
+ }
768
978
  default:
769
979
  dropped.push(`${label}: not an operation the canvas takes`);
770
980
  }