@engenty/wizards-runtime 0.0.0-stage → 0.7.6

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 (523) hide show
  1. package/LICENSE +110 -0
  2. package/README.md +214 -2
  3. package/apps/runtime/dist/agents/architect.js +444 -0
  4. package/apps/runtime/dist/agents/studio-assistant.js +883 -0
  5. package/apps/runtime/dist/agents/subscription.js +207 -0
  6. package/apps/runtime/dist/agents/thought.js +21 -0
  7. package/apps/runtime/dist/agents/website.js +480 -0
  8. package/apps/runtime/dist/app.js +359 -0
  9. package/apps/runtime/dist/apple/wizards-apple +0 -0
  10. package/apps/runtime/dist/assistant/browser.js +26 -0
  11. package/apps/runtime/dist/assistant/docs.js +158 -0
  12. package/apps/runtime/dist/assistant/knows.js +353 -0
  13. package/apps/runtime/dist/assistant/primer.js +26 -0
  14. package/apps/runtime/dist/assistant/runs.js +24 -0
  15. package/apps/runtime/dist/auth/account.js +175 -0
  16. package/apps/runtime/dist/auth/device.js +112 -0
  17. package/apps/runtime/dist/auth/index.js +358 -0
  18. package/apps/runtime/dist/auth/keys.js +55 -0
  19. package/apps/runtime/dist/auth/local-ticket.js +26 -0
  20. package/apps/runtime/dist/authoring/example.js +74 -0
  21. package/apps/runtime/dist/authoring/guide.js +433 -0
  22. package/apps/runtime/dist/authoring/ops.js +117 -0
  23. package/apps/runtime/dist/browser/fast/action-space.js +160 -0
  24. package/apps/runtime/dist/browser/fast/classifier.js +91 -0
  25. package/apps/runtime/dist/browser/fast/decide.js +171 -0
  26. package/apps/runtime/dist/browser/fast/driver.js +141 -0
  27. package/apps/runtime/dist/browser/fast/instructions.js +33 -0
  28. package/apps/runtime/dist/browser/fast/run.js +249 -0
  29. package/apps/runtime/dist/browser/fast/span-picker.js +153 -0
  30. package/apps/runtime/dist/browser/fast/text-helper.js +178 -0
  31. package/apps/runtime/dist/browser/snapshot.js +335 -0
  32. package/apps/runtime/dist/cli/account.js +385 -0
  33. package/apps/runtime/dist/cli/autostart.js +182 -0
  34. package/apps/runtime/dist/cli/autoupdate.js +221 -0
  35. package/apps/runtime/dist/cli/clients.js +44 -0
  36. package/apps/runtime/dist/cli/connect.js +540 -0
  37. package/apps/runtime/dist/cli/environment.js +95 -0
  38. package/apps/runtime/dist/cli/exec.js +45 -0
  39. package/apps/runtime/dist/cli/features.js +50 -0
  40. package/apps/runtime/dist/cli/home.js +88 -0
  41. package/apps/runtime/dist/cli/install-env.js +33 -0
  42. package/apps/runtime/dist/cli/machine.js +107 -0
  43. package/apps/runtime/dist/cli/main.js +231 -0
  44. package/apps/runtime/dist/cli/mcp.js +136 -0
  45. package/apps/runtime/dist/cli/menu.js +202 -0
  46. package/apps/runtime/dist/cli/processes.js +72 -0
  47. package/apps/runtime/dist/cli/report.js +66 -0
  48. package/apps/runtime/dist/cli/sandbox.js +77 -0
  49. package/apps/runtime/dist/cli/setup.js +335 -0
  50. package/apps/runtime/dist/cli/start.js +276 -0
  51. package/apps/runtime/dist/cli/status.js +212 -0
  52. package/apps/runtime/dist/cli/ui.js +59 -0
  53. package/apps/runtime/dist/cli/uninstall-main.js +20 -0
  54. package/apps/runtime/dist/cli/uninstall.js +231 -0
  55. package/apps/runtime/dist/cli/update.js +86 -0
  56. package/apps/runtime/dist/cli/validate.js +75 -0
  57. package/apps/runtime/dist/cli/versions.js +123 -0
  58. package/apps/runtime/dist/connectors/builtin.js +86 -0
  59. package/apps/runtime/dist/connectors/external.js +409 -0
  60. package/apps/runtime/dist/connectors/gmail.js +107 -0
  61. package/apps/runtime/dist/connectors/imap.js +261 -0
  62. package/apps/runtime/dist/connectors/index.js +325 -0
  63. package/apps/runtime/dist/connectors/mail.js +72 -0
  64. package/apps/runtime/dist/connectors/outlook.js +90 -0
  65. package/apps/runtime/dist/connectors/plugin-connections.js +343 -0
  66. package/apps/runtime/dist/connectors/via-account.js +65 -0
  67. package/apps/runtime/dist/credits/credits.js +100 -0
  68. package/apps/runtime/dist/credits/estimate.js +152 -0
  69. package/apps/runtime/dist/db/adopt.js +149 -0
  70. package/apps/runtime/dist/db/client.js +173 -0
  71. package/apps/runtime/dist/db/control-schema.js +133 -0
  72. package/apps/runtime/dist/db/migrations/control/0000_last_absorbing_man.sql +47 -0
  73. package/apps/runtime/dist/db/migrations/control/0001_gorgeous_nicolaos.sql +41 -0
  74. package/apps/runtime/dist/db/migrations/control/0002_secret_penance.sql +1 -0
  75. package/apps/runtime/dist/db/migrations/control/0003_nasty_mordo.sql +3 -0
  76. package/apps/runtime/dist/db/migrations/control/0004_breezy_eddie_brock.sql +6 -0
  77. package/apps/runtime/dist/db/migrations/control/0005_chilly_oracle.sql +1 -0
  78. package/apps/runtime/dist/db/migrations/control/0006_sleepy_mojo.sql +1 -0
  79. package/apps/runtime/dist/db/migrations/control/0007_common_the_hand.sql +15 -0
  80. package/apps/runtime/dist/db/migrations/control/0008_runner.sql +8 -0
  81. package/apps/runtime/dist/db/migrations/control/0009_plugin_claim.sql +9 -0
  82. package/apps/runtime/dist/db/migrations/control/0010_tan_snowbird.sql +6 -0
  83. package/apps/runtime/dist/db/migrations/control/meta/0000_snapshot.json +311 -0
  84. package/apps/runtime/dist/db/migrations/control/meta/0001_snapshot.json +599 -0
  85. package/apps/runtime/dist/db/migrations/control/meta/0002_snapshot.json +607 -0
  86. package/apps/runtime/dist/db/migrations/control/meta/0003_snapshot.json +311 -0
  87. package/apps/runtime/dist/db/migrations/control/meta/0004_snapshot.json +350 -0
  88. package/apps/runtime/dist/db/migrations/control/meta/0005_snapshot.json +358 -0
  89. package/apps/runtime/dist/db/migrations/control/meta/0006_snapshot.json +365 -0
  90. package/apps/runtime/dist/db/migrations/control/meta/0007_snapshot.json +460 -0
  91. package/apps/runtime/dist/db/migrations/control/meta/0008_snapshot.json +505 -0
  92. package/apps/runtime/dist/db/migrations/control/meta/0009_snapshot.json +561 -0
  93. package/apps/runtime/dist/db/migrations/control/meta/0010_snapshot.json +600 -0
  94. package/apps/runtime/dist/db/migrations/control/meta/_journal.json +83 -0
  95. package/apps/runtime/dist/db/migrations/tenant/0000_eminent_freak.sql +188 -0
  96. package/apps/runtime/dist/db/migrations/tenant/0001_salty_master_chief.sql +1 -0
  97. package/apps/runtime/dist/db/migrations/tenant/0002_cloudy_firebird.sql +1 -0
  98. package/apps/runtime/dist/db/migrations/tenant/0003_brown_warbound.sql +52 -0
  99. package/apps/runtime/dist/db/migrations/tenant/0004_romantic_nocturne.sql +6 -0
  100. package/apps/runtime/dist/db/migrations/tenant/0005_reflective_forgotten_one.sql +2 -0
  101. package/apps/runtime/dist/db/migrations/tenant/0006_hard_war_machine.sql +30 -0
  102. package/apps/runtime/dist/db/migrations/tenant/0007_space_data.sql +43 -0
  103. package/apps/runtime/dist/db/migrations/tenant/0008_run_event_note.sql +1 -0
  104. package/apps/runtime/dist/db/migrations/tenant/0009_knowledge.sql +104 -0
  105. package/apps/runtime/dist/db/migrations/tenant/0010_plugin_connection.sql +15 -0
  106. package/apps/runtime/dist/db/migrations/tenant/0011_runners.sql +2 -0
  107. package/apps/runtime/dist/db/migrations/tenant/0012_assistant_chat.sql +40 -0
  108. package/apps/runtime/dist/db/migrations/tenant/0013_run_origin.sql +1 -0
  109. package/apps/runtime/dist/db/migrations/tenant/0014_run_answer.sql +2 -0
  110. package/apps/runtime/dist/db/migrations/tenant/0015_device_calls.sql +13 -0
  111. package/apps/runtime/dist/db/migrations/tenant/0016_even_trish_tilby.sql +12 -0
  112. package/apps/runtime/dist/db/migrations/tenant/meta/0000_snapshot.json +1323 -0
  113. package/apps/runtime/dist/db/migrations/tenant/meta/0001_snapshot.json +1330 -0
  114. package/apps/runtime/dist/db/migrations/tenant/meta/0002_snapshot.json +1337 -0
  115. package/apps/runtime/dist/db/migrations/tenant/meta/0003_snapshot.json +1605 -0
  116. package/apps/runtime/dist/db/migrations/tenant/meta/0004_snapshot.json +1645 -0
  117. package/apps/runtime/dist/db/migrations/tenant/meta/0005_snapshot.json +1659 -0
  118. package/apps/runtime/dist/db/migrations/tenant/meta/0006_snapshot.json +1696 -0
  119. package/apps/runtime/dist/db/migrations/tenant/meta/0007_snapshot.json +2012 -0
  120. package/apps/runtime/dist/db/migrations/tenant/meta/0008_snapshot.json +2019 -0
  121. package/apps/runtime/dist/db/migrations/tenant/meta/0009_snapshot.json +2837 -0
  122. package/apps/runtime/dist/db/migrations/tenant/meta/0010_snapshot.json +2942 -0
  123. package/apps/runtime/dist/db/migrations/tenant/meta/0011_snapshot.json +2956 -0
  124. package/apps/runtime/dist/db/migrations/tenant/meta/0012_snapshot.json +3132 -0
  125. package/apps/runtime/dist/db/migrations/tenant/meta/0013_snapshot.json +3139 -0
  126. package/apps/runtime/dist/db/migrations/tenant/meta/0014_snapshot.json +3154 -0
  127. package/apps/runtime/dist/db/migrations/tenant/meta/0015_snapshot.json +3243 -0
  128. package/apps/runtime/dist/db/migrations/tenant/meta/0016_snapshot.json +3326 -0
  129. package/apps/runtime/dist/db/migrations/tenant/meta/_journal.json +125 -0
  130. package/apps/runtime/dist/db/schema.js +602 -0
  131. package/apps/runtime/dist/debug.js +197 -0
  132. package/apps/runtime/dist/docs/dev/index.md +41 -0
  133. package/apps/runtime/dist/docs/dev/meta.json +7 -0
  134. package/apps/runtime/dist/docs/dev/plugins/connections.md +74 -0
  135. package/apps/runtime/dist/docs/dev/plugins/events.md +89 -0
  136. package/apps/runtime/dist/docs/dev/plugins/examples.md +101 -0
  137. package/apps/runtime/dist/docs/dev/plugins/index.md +78 -0
  138. package/apps/runtime/dist/docs/dev/plugins/layout.md +90 -0
  139. package/apps/runtime/dist/docs/dev/plugins/meta.json +28 -0
  140. package/apps/runtime/dist/docs/dev/plugins/quick-start.md +94 -0
  141. package/apps/runtime/dist/docs/dev/plugins/reference.md +348 -0
  142. package/apps/runtime/dist/docs/dev/plugins/reloading.md +76 -0
  143. package/apps/runtime/dist/docs/dev/plugins/routes.md +185 -0
  144. package/apps/runtime/dist/docs/dev/plugins/runners.md +230 -0
  145. package/apps/runtime/dist/docs/dev/plugins/server.md +281 -0
  146. package/apps/runtime/dist/docs/dev/plugins/shipping.md +79 -0
  147. package/apps/runtime/dist/docs/dev/plugins/space.md +297 -0
  148. package/apps/runtime/dist/docs/dev/plugins/starters.md +70 -0
  149. package/apps/runtime/dist/docs/dev/plugins/studio.md +363 -0
  150. package/apps/runtime/dist/docs/dev/plugins/styling.md +129 -0
  151. package/apps/runtime/dist/docs/dev/plugins/tables.md +104 -0
  152. package/apps/runtime/dist/docs/dev/plugins/tools.md +139 -0
  153. package/apps/runtime/dist/docs/dev/wizard-format.md +125 -0
  154. package/apps/runtime/dist/docs/meta.json +3 -0
  155. package/apps/runtime/dist/docs/user/ai-apps.md +112 -0
  156. package/apps/runtime/dist/docs/user/assistant.md +77 -0
  157. package/apps/runtime/dist/docs/user/build-a-wizard.md +116 -0
  158. package/apps/runtime/dist/docs/user/command-line.md +86 -0
  159. package/apps/runtime/dist/docs/user/connectors.md +90 -0
  160. package/apps/runtime/dist/docs/user/create-account.md +52 -0
  161. package/apps/runtime/dist/docs/user/data.md +66 -0
  162. package/apps/runtime/dist/docs/user/first-start.md +60 -0
  163. package/apps/runtime/dist/docs/user/index.md +49 -0
  164. package/apps/runtime/dist/docs/user/install.md +123 -0
  165. package/apps/runtime/dist/docs/user/local-only.md +42 -0
  166. package/apps/runtime/dist/docs/user/meta.json +32 -0
  167. package/apps/runtime/dist/docs/user/models.md +156 -0
  168. package/apps/runtime/dist/docs/user/plugins.md +71 -0
  169. package/apps/runtime/dist/docs/user/run.md +98 -0
  170. package/apps/runtime/dist/docs/user/server.md +52 -0
  171. package/apps/runtime/dist/docs/user/space.md +126 -0
  172. package/apps/runtime/dist/docs/user/steps.md +220 -0
  173. package/apps/runtime/dist/docs/user/test-and-share.md +224 -0
  174. package/apps/runtime/dist/docs/user/troubleshooting.md +67 -0
  175. package/apps/runtime/dist/docs/user/wordpress.md +121 -0
  176. package/apps/runtime/dist/documents/parse.js +246 -0
  177. package/apps/runtime/dist/engenty/connections-external/build-connector.js +193 -0
  178. package/apps/runtime/dist/engenty/connections-external/errors.js +11 -0
  179. package/apps/runtime/dist/engenty/connections-external/import-service.js +270 -0
  180. package/apps/runtime/dist/engenty/connections-external/importer/classify.js +34 -0
  181. package/apps/runtime/dist/engenty/connections-external/importer/map-auth.js +185 -0
  182. package/apps/runtime/dist/engenty/connections-external/importer/normalize-mcp.js +63 -0
  183. package/apps/runtime/dist/engenty/connections-external/importer/normalize-openapi.js +130 -0
  184. package/apps/runtime/dist/engenty/connections-external/invoke/http-invoker.js +143 -0
  185. package/apps/runtime/dist/engenty/connections-external/invoke/mcp-client.js +143 -0
  186. package/apps/runtime/dist/engenty/connections-external/net/guarded-fetch.js +119 -0
  187. package/apps/runtime/dist/engenty/connections-external/oauth-dcr.js +88 -0
  188. package/apps/runtime/dist/engenty/connections-external/registry-client.js +336 -0
  189. package/apps/runtime/dist/engenty/connections-external/registry-source.js +82 -0
  190. package/apps/runtime/dist/engenty/connections-external/types.js +7 -0
  191. package/apps/runtime/dist/engenty/connections-github/connector.js +209 -0
  192. package/apps/runtime/dist/engenty/connections-google/connectors/calendar.js +381 -0
  193. package/apps/runtime/dist/engenty/connections-google/connectors/contacts.js +94 -0
  194. package/apps/runtime/dist/engenty/connections-google/connectors/drive.js +290 -0
  195. package/apps/runtime/dist/engenty/connections-google/connectors/gmail.js +567 -0
  196. package/apps/runtime/dist/engenty/connections-google/definitions.js +11 -0
  197. package/apps/runtime/dist/engenty/connections-google/shared.js +73 -0
  198. package/apps/runtime/dist/engenty/connections-hubspot/connector.js +140 -0
  199. package/apps/runtime/dist/engenty/connections-microsoft/action.js +17 -0
  200. package/apps/runtime/dist/engenty/connections-microsoft/graph.js +114 -0
  201. package/apps/runtime/dist/engenty/connections-microsoft/onedrive.js +286 -0
  202. package/apps/runtime/dist/engenty/connections-microsoft/outlook.js +492 -0
  203. package/apps/runtime/dist/engenty/connections-s3/s3.js +328 -0
  204. package/apps/runtime/dist/engenty/connections-sdk/files-capability.js +86 -0
  205. package/apps/runtime/dist/engenty/connections-sdk/oauth2.js +150 -0
  206. package/apps/runtime/dist/engenty/connections-sdk/registry.js +89 -0
  207. package/apps/runtime/dist/engenty/connections-sdk/storage-capability.js +84 -0
  208. package/apps/runtime/dist/engenty/connections-sdk/types.js +30 -0
  209. package/apps/runtime/dist/engenty/connections-slack/connector.js +360 -0
  210. package/apps/runtime/dist/engenty/csv-import/csv-matrix.js +178 -0
  211. package/apps/runtime/dist/engenty/csv-import/import-sources.js +87 -0
  212. package/apps/runtime/dist/engenty/csv-import/parse-csv.js +129 -0
  213. package/apps/runtime/dist/engenty/csv-import/serialize-csv.js +20 -0
  214. package/apps/runtime/dist/engenty/csv-import/types.js +1 -0
  215. package/apps/runtime/dist/engenty/csv-import/xlsx-workbook.js +159 -0
  216. package/apps/runtime/dist/engenty/doc-converter/interface.js +9 -0
  217. package/apps/runtime/dist/engenty/doc-converter/page-break.js +92 -0
  218. package/apps/runtime/dist/engenty/doc-converter/providers/local/index.js +72 -0
  219. package/apps/runtime/dist/engenty/document-scanner/schemas/classifier.js +30 -0
  220. package/apps/runtime/dist/engenty/document-scanner/schemas/index.js +4 -0
  221. package/apps/runtime/dist/engenty/document-scanner/schemas/invoice.js +73 -0
  222. package/apps/runtime/dist/engenty/document-scanner/schemas/receipt.js +63 -0
  223. package/apps/runtime/dist/engenty/document-scanner/schemas/shared.js +40 -0
  224. package/apps/runtime/dist/engenty/search-index/chunks.js +164 -0
  225. package/apps/runtime/dist/engenty/search-index/contracts.js +9 -0
  226. package/apps/runtime/dist/engenty/shims/connections-sdk.js +39 -0
  227. package/apps/runtime/dist/engenty/shims/plugin-sdk.js +1 -0
  228. package/apps/runtime/dist/engenty/shims/web-ingest.js +19 -0
  229. package/apps/runtime/dist/engenty/web-ingest/ssrf.js +277 -0
  230. package/apps/runtime/dist/engine/asks.js +82 -0
  231. package/apps/runtime/dist/engine/decide.js +82 -0
  232. package/apps/runtime/dist/engine/device.js +194 -0
  233. package/apps/runtime/dist/engine/events.js +128 -0
  234. package/apps/runtime/dist/engine/input.js +208 -0
  235. package/apps/runtime/dist/engine/owner.js +32 -0
  236. package/apps/runtime/dist/engine/prepare.js +90 -0
  237. package/apps/runtime/dist/engine/push.js +58 -0
  238. package/apps/runtime/dist/engine/requirements.js +355 -0
  239. package/apps/runtime/dist/engine/resources.js +198 -0
  240. package/apps/runtime/dist/engine/runner.js +970 -0
  241. package/apps/runtime/dist/engine/steps.js +1000 -0
  242. package/apps/runtime/dist/engine/surface.js +91 -0
  243. package/apps/runtime/dist/engine/template.js +240 -0
  244. package/apps/runtime/dist/engine/types.js +4 -0
  245. package/apps/runtime/dist/env.js +279 -0
  246. package/apps/runtime/dist/features.js +123 -0
  247. package/apps/runtime/dist/files/blobs.js +22 -0
  248. package/apps/runtime/dist/files/objects.js +86 -0
  249. package/apps/runtime/dist/files/storage.js +120 -0
  250. package/apps/runtime/dist/files/web-images.js +101 -0
  251. package/apps/runtime/dist/film/project.js +257 -0
  252. package/apps/runtime/dist/film/skills.js +91 -0
  253. package/apps/runtime/dist/film/sounds.js +122 -0
  254. package/apps/runtime/dist/film/step.js +289 -0
  255. package/apps/runtime/dist/film/tools.js +99 -0
  256. package/apps/runtime/dist/geocode.js +58 -0
  257. package/apps/runtime/dist/harness/antigravity.js +129 -0
  258. package/apps/runtime/dist/harness/apple.js +270 -0
  259. package/apps/runtime/dist/harness/claude.js +147 -0
  260. package/apps/runtime/dist/harness/codex.js +229 -0
  261. package/apps/runtime/dist/harness/cursor.js +93 -0
  262. package/apps/runtime/dist/harness/env.js +124 -0
  263. package/apps/runtime/dist/harness/index.js +95 -0
  264. package/apps/runtime/dist/harness/model.js +279 -0
  265. package/apps/runtime/dist/harness/prompt.js +121 -0
  266. package/apps/runtime/dist/harness/terminal.js +194 -0
  267. package/apps/runtime/dist/harness/types.js +7 -0
  268. package/apps/runtime/dist/index.js +113 -0
  269. package/apps/runtime/dist/limits.js +81 -0
  270. package/apps/runtime/dist/link-preview.js +60 -0
  271. package/apps/runtime/dist/log.js +106 -0
  272. package/apps/runtime/dist/manage.js +249 -0
  273. package/apps/runtime/dist/mcp/auth.js +161 -0
  274. package/apps/runtime/dist/mcp/bridge.js +59 -0
  275. package/apps/runtime/dist/mcp/flow-app.js +97 -0
  276. package/apps/runtime/dist/mcp/handler.js +54 -0
  277. package/apps/runtime/dist/mcp/scopes.js +14 -0
  278. package/apps/runtime/dist/mcp/seen.js +65 -0
  279. package/apps/runtime/dist/mcp/tools.js +572 -0
  280. package/apps/runtime/dist/media/conversation.js +167 -0
  281. package/apps/runtime/dist/media/ffmpeg.js +121 -0
  282. package/apps/runtime/dist/media/generate.js +120 -0
  283. package/apps/runtime/dist/media/marking.js +121 -0
  284. package/apps/runtime/dist/media/transcribe.js +198 -0
  285. package/apps/runtime/dist/model-errors.js +42 -0
  286. package/apps/runtime/dist/models.js +1164 -0
  287. package/apps/runtime/dist/plugin.js +61 -0
  288. package/apps/runtime/dist/plugins/channels.js +78 -0
  289. package/apps/runtime/dist/plugins/claims.js +56 -0
  290. package/apps/runtime/dist/plugins/discovery.js +155 -0
  291. package/apps/runtime/dist/plugins/events.js +63 -0
  292. package/apps/runtime/dist/plugins/jobs.js +64 -0
  293. package/apps/runtime/dist/plugins/loader.js +508 -0
  294. package/apps/runtime/dist/plugins/migrations.js +69 -0
  295. package/apps/runtime/dist/plugins/pro-keys.js +34 -0
  296. package/apps/runtime/dist/plugins/pro-state.js +83 -0
  297. package/apps/runtime/dist/plugins/pro.js +310 -0
  298. package/apps/runtime/dist/plugins/public.js +44 -0
  299. package/apps/runtime/dist/plugins/registry.js +122 -0
  300. package/apps/runtime/dist/plugins/runs.js +210 -0
  301. package/apps/runtime/dist/render/browser-path.js +54 -0
  302. package/apps/runtime/dist/render/chromium.js +98 -0
  303. package/apps/runtime/dist/render/convert.js +158 -0
  304. package/apps/runtime/dist/render/downloads.js +299 -0
  305. package/apps/runtime/dist/render/guard.js +25 -0
  306. package/apps/runtime/dist/render/shaped.js +137 -0
  307. package/apps/runtime/dist/routes/api.js +440 -0
  308. package/apps/runtime/dist/routes/debug.js +42 -0
  309. package/apps/runtime/dist/routes/delivery.js +90 -0
  310. package/apps/runtime/dist/routes/internal.js +81 -0
  311. package/apps/runtime/dist/routes/lang.js +25 -0
  312. package/apps/runtime/dist/routes/marketplace.js +43 -0
  313. package/apps/runtime/dist/routes/plugin-public.js +113 -0
  314. package/apps/runtime/dist/routes/plugins.js +212 -0
  315. package/apps/runtime/dist/routes/runs.js +1422 -0
  316. package/apps/runtime/dist/routes/studio.js +1629 -0
  317. package/apps/runtime/dist/routes/wizard-stream.js +30 -0
  318. package/apps/runtime/dist/running.js +39 -0
  319. package/apps/runtime/dist/sandbox/agentos-package.js +73 -0
  320. package/apps/runtime/dist/sandbox/agentos.js +162 -0
  321. package/apps/runtime/dist/sandbox/docker.js +45 -0
  322. package/apps/runtime/dist/sandbox/index.js +52 -0
  323. package/apps/runtime/dist/sandbox/install.js +122 -0
  324. package/apps/runtime/dist/sandbox/mastra.js +71 -0
  325. package/apps/runtime/dist/sandbox/types.js +1 -0
  326. package/apps/runtime/dist/secrets/crypto.js +28 -0
  327. package/apps/runtime/dist/secrets/signing.js +52 -0
  328. package/apps/runtime/dist/secrets/vault.js +59 -0
  329. package/apps/runtime/dist/services/access.js +88 -0
  330. package/apps/runtime/dist/services/api.js +248 -0
  331. package/apps/runtime/dist/services/architect.js +95 -0
  332. package/apps/runtime/dist/services/assistant-chats.js +311 -0
  333. package/apps/runtime/dist/services/brand.js +85 -0
  334. package/apps/runtime/dist/services/cloud.js +456 -0
  335. package/apps/runtime/dist/services/draft-events.js +27 -0
  336. package/apps/runtime/dist/services/engenty-shapes.js +71 -0
  337. package/apps/runtime/dist/services/errors.js +29 -0
  338. package/apps/runtime/dist/services/files.js +178 -0
  339. package/apps/runtime/dist/services/knowledge-model.js +559 -0
  340. package/apps/runtime/dist/services/knowledge.js +721 -0
  341. package/apps/runtime/dist/services/links.js +16 -0
  342. package/apps/runtime/dist/services/marketplace.js +492 -0
  343. package/apps/runtime/dist/services/onboarding.js +152 -0
  344. package/apps/runtime/dist/services/package-file.js +82 -0
  345. package/apps/runtime/dist/services/package.js +170 -0
  346. package/apps/runtime/dist/services/profile.js +51 -0
  347. package/apps/runtime/dist/services/project-files.js +439 -0
  348. package/apps/runtime/dist/services/project-index.js +707 -0
  349. package/apps/runtime/dist/services/projects.js +387 -0
  350. package/apps/runtime/dist/services/relevance.js +58 -0
  351. package/apps/runtime/dist/services/runners.js +178 -0
  352. package/apps/runtime/dist/services/runs.js +524 -0
  353. package/apps/runtime/dist/services/shares.js +130 -0
  354. package/apps/runtime/dist/services/site.js +270 -0
  355. package/apps/runtime/dist/services/space-categories.js +861 -0
  356. package/apps/runtime/dist/services/space-data.js +792 -0
  357. package/apps/runtime/dist/services/space-origin.js +207 -0
  358. package/apps/runtime/dist/services/spaces.js +657 -0
  359. package/apps/runtime/dist/services/translations.js +306 -0
  360. package/apps/runtime/dist/services/widgets.js +34 -0
  361. package/apps/runtime/dist/services/wizard-icon.js +157 -0
  362. package/apps/runtime/dist/services/wizards.js +420 -0
  363. package/apps/runtime/dist/settings.js +16 -0
  364. package/apps/runtime/dist/store/errors.js +4 -0
  365. package/apps/runtime/dist/store/index.js +299 -0
  366. package/apps/runtime/dist/store/shared-lists.js +123 -0
  367. package/apps/runtime/dist/tenants/control.js +238 -0
  368. package/apps/runtime/dist/tenants/tenant.js +26 -0
  369. package/apps/runtime/dist/texts.js +207 -0
  370. package/apps/runtime/dist/tools/browser.js +703 -0
  371. package/apps/runtime/dist/tools/connector.js +204 -0
  372. package/apps/runtime/dist/tools/index.js +291 -0
  373. package/apps/runtime/dist/tools/mail.js +104 -0
  374. package/apps/runtime/dist/tools/net-guard.js +170 -0
  375. package/apps/runtime/dist/tools/pages.js +81 -0
  376. package/apps/runtime/dist/tools/plugin.js +180 -0
  377. package/apps/runtime/dist/tools/project.js +154 -0
  378. package/apps/runtime/dist/tools/shared.js +69 -0
  379. package/apps/runtime/dist/tools/store.js +238 -0
  380. package/apps/runtime/dist/update.js +113 -0
  381. package/apps/runtime/dist/widgets/bundle.js +99 -0
  382. package/apps/runtime/dist/widgets/render.js +329 -0
  383. package/apps/runtime/dist/widgets/runtime.js +108 -0
  384. package/apps/runtime/dist/widgets/script.js +30 -0
  385. package/apps/runtime/dist/widgets/step.js +223 -0
  386. package/apps/web/dist/ai-labels/ai-black.svg +20 -0
  387. package/apps/web/dist/ai-labels/ai-generated-black.svg +31 -0
  388. package/apps/web/dist/ai-labels/ai-generated-white.svg +32 -0
  389. package/apps/web/dist/ai-labels/ai-modified-black.svg +30 -0
  390. package/apps/web/dist/ai-labels/ai-modified-white.svg +31 -0
  391. package/apps/web/dist/ai-labels/ai-white.svg +21 -0
  392. package/apps/web/dist/assets/AboutDialog-DYgXPagX.js +1 -0
  393. package/apps/web/dist/assets/ChangelogDialog-BXqBW8j3.js +1 -0
  394. package/apps/web/dist/assets/ChatView-CK2--tsE.js +10 -0
  395. package/apps/web/dist/assets/EditorPage-jvcwyXbU.js +3 -0
  396. package/apps/web/dist/assets/FlowPreview-CusP7ci9.js +1 -0
  397. package/apps/web/dist/assets/Harness-BrP-ENHg.css +1 -0
  398. package/apps/web/dist/assets/Harness-CV9uYzbv.js +16 -0
  399. package/apps/web/dist/assets/NewWizardChannels-BakW5q6s.js +1 -0
  400. package/apps/web/dist/assets/NewWizardPage-BoA-LJuW.js +7 -0
  401. package/apps/web/dist/assets/OnboardingPage-DaD1XnOe.js +1 -0
  402. package/apps/web/dist/assets/ProjectPage-BFgk1DEv.js +1 -0
  403. package/apps/web/dist/assets/PublicRunner-C9MwEvxy.js +1 -0
  404. package/apps/web/dist/assets/ReadOnly-DC2Kp7l8.js +1 -0
  405. package/apps/web/dist/assets/RunDrawer-CY6NZSrI.js +4 -0
  406. package/apps/web/dist/assets/RunnerView-BT26XgcY.js +1 -0
  407. package/apps/web/dist/assets/SettingsPage-AFt9IDLt.js +1 -0
  408. package/apps/web/dist/assets/SetupPage-DtFYAbwJ.js +1 -0
  409. package/apps/web/dist/assets/SharePage-t2xwNS61.js +1 -0
  410. package/apps/web/dist/assets/changelog-CATQFxCQ.js +1 -0
  411. package/apps/web/dist/assets/engenty-eXZ-EAwd.js +1 -0
  412. package/apps/web/dist/assets/esm-DXeMu8Lb.js +7 -0
  413. package/apps/web/dist/assets/fluffy-engenty-ClRou7yu.js +456 -0
  414. package/apps/web/dist/assets/index-AfUa8xKD.css +1 -0
  415. package/apps/web/dist/assets/index-Drw7FMTQ.js +14 -0
  416. package/apps/web/dist/assets/jsx-runtime-BNakU3Ej.js +1 -0
  417. package/apps/web/dist/assets/lock-R_CfU0Xo.js +1 -0
  418. package/apps/web/dist/assets/oss-credits-cZ9NUaLZ.js +1 -0
  419. package/apps/web/dist/assets/pdfmake-Cx9scTbD.js +228 -0
  420. package/apps/web/dist/assets/phone-CgrIS4_-.js +1 -0
  421. package/apps/web/dist/assets/preload-helper-CNEI7N0N.js +1 -0
  422. package/apps/web/dist/assets/qr-scanner-worker.min-CJaXo3yu.js +98 -0
  423. package/apps/web/dist/assets/qr-scanner.min-C_UI0gH-.js +1 -0
  424. package/apps/web/dist/assets/rolldown-runtime-hePW80VL.js +1 -0
  425. package/apps/web/dist/assets/settings-menu-2IMOOlLl.js +1 -0
  426. package/apps/web/dist/assets/ui-dzGvc3xk.js +137 -0
  427. package/apps/web/dist/assets/upload-BSuTilFF.js +1 -0
  428. package/apps/web/dist/assets/vfs_fonts-DllDSYt1.js +1 -0
  429. package/apps/web/dist/embed.js +266 -0
  430. package/apps/web/dist/favicon.svg +1 -0
  431. package/apps/web/dist/icons/apple-touch-icon.png +0 -0
  432. package/apps/web/dist/icons/icon-192.png +0 -0
  433. package/apps/web/dist/icons/icon-512.png +0 -0
  434. package/apps/web/dist/icons/icon-maskable-512.png +0 -0
  435. package/apps/web/dist/index.html +48 -0
  436. package/apps/web/dist/install.sh +577 -0
  437. package/apps/web/dist/manifest.webmanifest +21 -0
  438. package/apps/web/dist/mcp/flow.html +980 -0
  439. package/apps/web/dist/sw.js +15 -0
  440. package/bin/wizards.mjs +288 -0
  441. package/modules/README.md +15 -0
  442. package/node_modules/@engenty/wizards/dist/plugin/index.d.ts +1150 -0
  443. package/node_modules/@engenty/wizards/dist/plugin/index.js +4 -0
  444. package/node_modules/@engenty/wizards/dist/plugin/studio.d.ts +322 -0
  445. package/node_modules/@engenty/wizards/dist/plugin/studio.js +4 -0
  446. package/node_modules/@engenty/wizards/dist/plugin/thread.d.ts +174 -0
  447. package/node_modules/@engenty/wizards/dist/plugin/thread.js +821 -0
  448. package/node_modules/@engenty/wizards/package.json +11 -0
  449. package/node_modules/@engenty-wizards/shared/dist/assistant.d.ts +174 -0
  450. package/node_modules/@engenty-wizards/shared/dist/assistant.js +65 -0
  451. package/node_modules/@engenty-wizards/shared/dist/changes.d.ts +22 -0
  452. package/node_modules/@engenty-wizards/shared/dist/changes.js +61 -0
  453. package/node_modules/@engenty-wizards/shared/dist/connectors.d.ts +77 -0
  454. package/node_modules/@engenty-wizards/shared/dist/connectors.js +2 -0
  455. package/node_modules/@engenty-wizards/shared/dist/decision.d.ts +76 -0
  456. package/node_modules/@engenty-wizards/shared/dist/decision.js +147 -0
  457. package/node_modules/@engenty-wizards/shared/dist/definition.d.ts +2922 -0
  458. package/node_modules/@engenty-wizards/shared/dist/definition.js +1920 -0
  459. package/node_modules/@engenty-wizards/shared/dist/engenty/data-tables/columns-format.d.ts +5 -0
  460. package/node_modules/@engenty-wizards/shared/dist/engenty/data-tables/columns-format.js +132 -0
  461. package/node_modules/@engenty-wizards/shared/dist/engenty/data-tables/columns-value.d.ts +11 -0
  462. package/node_modules/@engenty-wizards/shared/dist/engenty/data-tables/columns-value.js +209 -0
  463. package/node_modules/@engenty-wizards/shared/dist/engenty/data-tables/columns.d.ts +532 -0
  464. package/node_modules/@engenty-wizards/shared/dist/engenty/data-tables/columns.js +217 -0
  465. package/node_modules/@engenty-wizards/shared/dist/engenty/data-tables/index.d.ts +3 -0
  466. package/node_modules/@engenty-wizards/shared/dist/engenty/data-tables/index.js +3 -0
  467. package/node_modules/@engenty-wizards/shared/dist/engenty/search-index/catalog-lexical.d.ts +14 -0
  468. package/node_modules/@engenty-wizards/shared/dist/engenty/search-index/catalog-lexical.js +166 -0
  469. package/node_modules/@engenty-wizards/shared/dist/engenty/search-index/catalog-rank.d.ts +33 -0
  470. package/node_modules/@engenty-wizards/shared/dist/engenty/search-index/catalog-rank.js +99 -0
  471. package/node_modules/@engenty-wizards/shared/dist/feature-flags.d.ts +78 -0
  472. package/node_modules/@engenty-wizards/shared/dist/feature-flags.js +70 -0
  473. package/node_modules/@engenty-wizards/shared/dist/features.d.ts +41 -0
  474. package/node_modules/@engenty-wizards/shared/dist/features.js +89 -0
  475. package/node_modules/@engenty-wizards/shared/dist/fit.d.ts +71 -0
  476. package/node_modules/@engenty-wizards/shared/dist/fit.js +382 -0
  477. package/node_modules/@engenty-wizards/shared/dist/json-schema.d.ts +14 -0
  478. package/node_modules/@engenty-wizards/shared/dist/json-schema.js +66 -0
  479. package/node_modules/@engenty-wizards/shared/dist/knowledge.d.ts +199 -0
  480. package/node_modules/@engenty-wizards/shared/dist/knowledge.js +68 -0
  481. package/node_modules/@engenty-wizards/shared/dist/marketplace-entry.d.ts +35 -0
  482. package/node_modules/@engenty-wizards/shared/dist/marketplace-entry.js +107 -0
  483. package/node_modules/@engenty-wizards/shared/dist/marketplace-search.d.ts +20 -0
  484. package/node_modules/@engenty-wizards/shared/dist/marketplace-search.js +136 -0
  485. package/node_modules/@engenty-wizards/shared/dist/marketplace.d.ts +227 -0
  486. package/node_modules/@engenty-wizards/shared/dist/marketplace.js +354 -0
  487. package/node_modules/@engenty-wizards/shared/dist/merge.d.ts +7 -0
  488. package/node_modules/@engenty-wizards/shared/dist/merge.js +40 -0
  489. package/node_modules/@engenty-wizards/shared/dist/numbers.d.ts +24 -0
  490. package/node_modules/@engenty-wizards/shared/dist/numbers.js +54 -0
  491. package/node_modules/@engenty-wizards/shared/dist/projects.d.ts +224 -0
  492. package/node_modules/@engenty-wizards/shared/dist/projects.js +319 -0
  493. package/node_modules/@engenty-wizards/shared/dist/providers.d.ts +101 -0
  494. package/node_modules/@engenty-wizards/shared/dist/providers.js +390 -0
  495. package/node_modules/@engenty-wizards/shared/dist/run.d.ts +680 -0
  496. package/node_modules/@engenty-wizards/shared/dist/run.js +620 -0
  497. package/node_modules/@engenty-wizards/shared/dist/runner-texts.d.ts +546 -0
  498. package/node_modules/@engenty-wizards/shared/dist/runner-texts.js +523 -0
  499. package/node_modules/@engenty-wizards/shared/dist/runners.d.ts +93 -0
  500. package/node_modules/@engenty-wizards/shared/dist/runners.js +146 -0
  501. package/node_modules/@engenty-wizards/shared/dist/shape.d.ts +102 -0
  502. package/node_modules/@engenty-wizards/shared/dist/shape.js +318 -0
  503. package/node_modules/@engenty-wizards/shared/dist/space-data.d.ts +89 -0
  504. package/node_modules/@engenty-wizards/shared/dist/space-data.js +47 -0
  505. package/node_modules/@engenty-wizards/shared/dist/store.d.ts +117 -0
  506. package/node_modules/@engenty-wizards/shared/dist/store.js +81 -0
  507. package/node_modules/@engenty-wizards/shared/dist/surface.d.ts +115 -0
  508. package/node_modules/@engenty-wizards/shared/dist/surface.js +442 -0
  509. package/node_modules/@engenty-wizards/shared/dist/texts.d.ts +45 -0
  510. package/node_modules/@engenty-wizards/shared/dist/texts.js +54 -0
  511. package/node_modules/@engenty-wizards/shared/dist/translation.d.ts +23 -0
  512. package/node_modules/@engenty-wizards/shared/dist/translation.js +154 -0
  513. package/node_modules/@engenty-wizards/shared/dist/wizard-package.d.ts +48 -0
  514. package/node_modules/@engenty-wizards/shared/dist/wizard-package.js +49 -0
  515. package/node_modules/@engenty-wizards/shared/dist/workspace.d.ts +16 -0
  516. package/node_modules/@engenty-wizards/shared/dist/workspace.js +51 -0
  517. package/node_modules/@engenty-wizards/shared/package.json +10 -0
  518. package/package.json +77 -4
  519. package/plugin/.claude-plugin/plugin.json +9 -0
  520. package/plugin/.mcp.json +8 -0
  521. package/plugin/commands/wizard.md +8 -0
  522. package/plugin/skills/build-wizard/SKILL.md +27 -0
  523. package/plugin/skills/use-wizard/SKILL.md +18 -0
@@ -0,0 +1,524 @@
1
+ import { FIELD_WAYS, formatsFor, isDecidedField, shownFields, slotText, wizardLang, } from "@engenty-wizards/shared/definition";
2
+ import { note } from "@engenty-wizards/shared/run";
3
+ import { and, count, desc, eq, gte, inArray, max, or, sql } from "drizzle-orm";
4
+ import { canSpend, MICROS_PER_CREDIT } from "../credits/credits.js";
5
+ import { db, schema } from "../db/client.js";
6
+ import { answerAsk } from "../engine/asks.js";
7
+ import { emitEvent, recentEvents, watchRun } from "../engine/events.js";
8
+ import { fieldErrorsIn } from "../engine/input.js";
9
+ import { cancel, createRun, goBack, NoCreditsError, pageContext, RunConflict, RunInputError, retry, reviewStep, submitPage, } from "../engine/runner.js";
10
+ import { ModelUnavailableError, saidOf } from "../model-errors.js";
11
+ import { signedUrl } from "../secrets/signing.js";
12
+ import { currentTenant } from "../tenants/tenant.js";
13
+ import { notFound, ServiceError } from "./errors.js";
14
+ import { ownedWizard, requireClean, shareUrl, studioUrl } from "./wizards.js";
15
+ /** Test runs an MCP client started with answers: pages are filled and reviews accepted for it. */
16
+ const autopilots = new Set();
17
+ export async function startTestRun(userId, wizardId, autopilot) {
18
+ const w = await ownedWizard(userId, wizardId);
19
+ const { definition, files } = await requireClean(w);
20
+ if (!(await canSpend())) {
21
+ throw new ServiceError("no_credits", note("creditsUsedUp"));
22
+ }
23
+ const runId = await createRun({
24
+ wizardId: w.id,
25
+ definition,
26
+ files,
27
+ version: null,
28
+ mode: "test",
29
+ userId,
30
+ unattended: Boolean(autopilot),
31
+ }).catch((err) => {
32
+ throw err instanceof ModelUnavailableError ? new ServiceError("refused", saidOf(err)) : err;
33
+ });
34
+ if (autopilot) {
35
+ fly(runId, autopilot.answers, autopilot.acceptReviews);
36
+ }
37
+ return { runId };
38
+ }
39
+ function fly(runId, answers, acceptReviews) {
40
+ autopilots.add(runId);
41
+ let busy = false;
42
+ let again = false;
43
+ const land = () => {
44
+ autopilots.delete(runId);
45
+ unsubscribe();
46
+ clearTimeout(timeout);
47
+ };
48
+ const step = async () => {
49
+ if (busy) {
50
+ again = true;
51
+ return;
52
+ }
53
+ busy = true;
54
+ try {
55
+ do {
56
+ again = false;
57
+ const run = await db.query.run.findFirst({ where: eq(schema.run.id, runId) });
58
+ if (!run ||
59
+ run.status === "done" ||
60
+ run.status === "failed" ||
61
+ run.status === "cancelled") {
62
+ land();
63
+ return;
64
+ }
65
+ if (run.status !== "waiting_input") {
66
+ continue;
67
+ }
68
+ const current = run.definition.steps.find((s) => s.id === run.cursor);
69
+ if (current?.type === "page") {
70
+ const values = Object.fromEntries(current.fields.filter((f) => f.id in answers).map((f) => [f.id, answers[f.id]]));
71
+ await submitPage(runId, current.id, values);
72
+ }
73
+ else if (current?.type === "review" && acceptReviews) {
74
+ await reviewStep(runId, current.id, { type: "accept" });
75
+ }
76
+ else {
77
+ land();
78
+ return;
79
+ }
80
+ } while (again);
81
+ }
82
+ catch (err) {
83
+ const message = err instanceof RunInputError
84
+ ? note("answersMissing", {
85
+ answers: err.errors.map((e) => note("fieldError", { field: e.field, message: e.message })),
86
+ })
87
+ : saidOf(err);
88
+ await emitEvent(runId, null, "error", message).catch(() => undefined);
89
+ land();
90
+ }
91
+ finally {
92
+ busy = false;
93
+ }
94
+ };
95
+ const unsubscribe = watchRun(runId, () => {
96
+ void step();
97
+ });
98
+ const timeout = setTimeout(land, 30 * 60_000);
99
+ void step();
100
+ }
101
+ /**
102
+ * A run the caller may see: any test run of their tenant, or a run they started themselves
103
+ * from an MCP client (run_wizard). `test` narrows it to test runs; `live` takes every live run of
104
+ * the tenant, what visitors started (the results `/api/v1/runs` lists with `runs:read`).
105
+ */
106
+ async function ownedRun(userId, runId, only) {
107
+ const run = await db.query.run.findFirst({
108
+ where: and(eq(schema.run.id, runId), eq(schema.run.tenantId, currentTenant()), only
109
+ ? eq(schema.run.mode, only)
110
+ : or(eq(schema.run.mode, "test"), eq(schema.run.userId, userId))),
111
+ });
112
+ if (!run) {
113
+ throw notFound();
114
+ }
115
+ return run;
116
+ }
117
+ /** Still moving: running, or waiting on a page the autopilot is about to fill. */
118
+ function moving(run) {
119
+ return run.status === "running" || (run.status === "waiting_input" && autopilots.has(run.id));
120
+ }
121
+ /** A run a plugin's door may drive: any run of the current tenant, by id. */
122
+ export async function pluginRun(runId) {
123
+ const run = await db.query.run.findFirst({
124
+ where: and(eq(schema.run.id, runId), eq(schema.run.tenantId, currentTenant())),
125
+ });
126
+ if (!run) {
127
+ throw notFound();
128
+ }
129
+ return run;
130
+ }
131
+ /** Loads the run again while it works, up to `seconds` (at most 45), and gives it as it stands. */
132
+ export async function waitRun(load, seconds) {
133
+ const deadline = Date.now() + Math.min(45, Math.max(0, seconds)) * 1000;
134
+ let run = await load();
135
+ while (moving(run) && Date.now() < deadline) {
136
+ await new Promise((resolve) => {
137
+ const unsubscribe = watchRun(run.id, () => {
138
+ unsubscribe();
139
+ clearTimeout(timer);
140
+ resolve();
141
+ });
142
+ const timer = setTimeout(() => {
143
+ unsubscribe();
144
+ resolve();
145
+ }, deadline - Date.now());
146
+ });
147
+ run = await load();
148
+ }
149
+ return run;
150
+ }
151
+ async function waitWhileMoving(userId, runId, seconds, only) {
152
+ const deadline = Date.now() + seconds * 1000;
153
+ let run = await ownedRun(userId, runId, only);
154
+ while (moving(run) && Date.now() < deadline) {
155
+ await new Promise((resolve) => {
156
+ const unsubscribe = watchRun(runId, () => {
157
+ unsubscribe();
158
+ clearTimeout(timer);
159
+ resolve();
160
+ });
161
+ const timer = setTimeout(() => {
162
+ unsubscribe();
163
+ resolve();
164
+ }, deadline - Date.now());
165
+ });
166
+ run = await ownedRun(userId, runId, only);
167
+ }
168
+ return run;
169
+ }
170
+ function clip(text, max) {
171
+ return text.length > max
172
+ ? `${text.slice(0, max)} … [${text.length - max} more characters]`
173
+ : text;
174
+ }
175
+ function deliverableFormats(run, step) {
176
+ const possible = formatsFor(step);
177
+ const listed = run.definition.steps
178
+ .flatMap((s) => (s.type === "result" ? s.deliverables : []))
179
+ .find((d) => d.from === step.id);
180
+ return listed ? listed.formats.filter((f) => possible.includes(f)) : [];
181
+ }
182
+ /**
183
+ * What a client needs besides the plain field: a slot's times as the person reads them, and the
184
+ * one value of them to send back.
185
+ */
186
+ function slotHints(run, field, options) {
187
+ if (field.kind !== "slot") {
188
+ return {};
189
+ }
190
+ const lang = wizardLang(run.definition);
191
+ const value = run.state.values[field.id];
192
+ return {
193
+ times: (options ?? []).map((o) => ({ value: o, label: slotText(o, lang) })),
194
+ ...(typeof value === "string" ? { valueText: slotText(value, lang) } : {}),
195
+ hint: options?.length
196
+ ? "One appointment time: show the person the labels, answer with the value of the one they pick, exactly as given."
197
+ : "No times are free right now: tell the person.",
198
+ };
199
+ }
200
+ /** Where the person can go on in a browser: the run page of a live run, the studio for a test. */
201
+ /** The live run's page — the wizard itself, never the studio. A test run has none. */
202
+ async function browserUrl(run) {
203
+ if (run.mode === "test") {
204
+ return null;
205
+ }
206
+ const w = await db.query.wizard.findFirst({ where: eq(schema.wizard.id, run.wizardId) });
207
+ return w ? `${shareUrl(w.shareToken)}/${run.id}` : null;
208
+ }
209
+ /**
210
+ * What a run waits for. `draft`: what a door that asks one field at a time has so far, so a
211
+ * field's `shown` follows those answers as it follows the form on the screen.
212
+ */
213
+ async function waitingFor(run, current, draft) {
214
+ if (run.status === "running" && run.ask) {
215
+ const ask = run.ask;
216
+ return ask.kind === "confirm"
217
+ ? {
218
+ ask: ask.id,
219
+ kind: ask.kind,
220
+ reason: ask.reason,
221
+ service: ask.service,
222
+ action: ask.action.summary,
223
+ input: clip(ask.input, 1500),
224
+ hint: "Ask the person, then answer_ask with allow or skip.",
225
+ }
226
+ : {
227
+ ask: ask.id,
228
+ kind: ask.kind,
229
+ reason: ask.reason,
230
+ site: ask.site.host,
231
+ hint: "A sign-in: the person types it on the run page (browserUrl).",
232
+ };
233
+ }
234
+ if (run.status !== "waiting_input" || !current) {
235
+ return undefined;
236
+ }
237
+ if (current.type === "page") {
238
+ // What the page knows from before it, the choices its fields take from data, the fields a
239
+ // decision kept: a field left out here is not asked, as the run page leaves it out.
240
+ const ctx = await pageContext(run, current);
241
+ const fields = current.fields
242
+ .filter((f) => !isDecidedField(f) || ctx.decided.includes(f.id))
243
+ .map((f) => (ctx.options[f.id]?.length ? { ...f, options: ctx.options[f.id] } : f));
244
+ const page = {
245
+ ...Object.fromEntries(fields.filter((f) => f.id in run.state.values).map((f) => [f.id, run.state.values[f.id]])),
246
+ ...draft,
247
+ };
248
+ const shown = new Set(shownFields(fields, ctx.known, page).map((f) => f.id));
249
+ return {
250
+ page: current.id,
251
+ title: current.title,
252
+ /** What the fields' conditions read from before the page, by reference. */
253
+ known: ctx.known,
254
+ fields: fields.map((f) => ({
255
+ id: f.id,
256
+ label: f.label,
257
+ kind: f.kind,
258
+ required: Boolean(f.required),
259
+ options: f.options,
260
+ placeholder: f.placeholder,
261
+ help: f.help,
262
+ default: f.default,
263
+ value: run.state.values[f.id],
264
+ columns: f.columns,
265
+ ...slotHints(run, f, f.options),
266
+ ...(f.multiple ? { multiple: true } : {}),
267
+ // A file, a recording or a signature comes from the person's device: the run page.
268
+ inChat: FIELD_WAYS[f.kind] !== "device",
269
+ // A field with a condition is asked only while it holds; one on another field of this
270
+ // page holds or not as the person answers. `shown` says so for what is known now.
271
+ ...(f.when ? { when: f.when, shown: shown.has(f.id) } : {}),
272
+ })),
273
+ hint: "Ask the fields in order; skip a field whose `when` does not hold on the answers so far (a hidden one is not required and not kept).",
274
+ };
275
+ }
276
+ if (current.type === "review") {
277
+ return {
278
+ review: current.id,
279
+ title: current.title,
280
+ show: current.show,
281
+ editable: Boolean(current.edit),
282
+ hint: "Show the person the outputs, then review_step: accept, or regenerate one with a note.",
283
+ };
284
+ }
285
+ return undefined;
286
+ }
287
+ /** What a run did so far, for a client without the run page: outputs, links, cost, errors. */
288
+ export async function runReport(userId, runId, waitSeconds = 0, only) {
289
+ return runReportOf(await waitWhileMoving(userId, runId, waitSeconds, only));
290
+ }
291
+ /** The report of a run as it stands; `draft` as for `waitingFor`. */
292
+ export async function runReportOf(run, draft) {
293
+ const current = run.definition.steps.find((s) => s.id === run.cursor) ?? null;
294
+ const base = `/api/runs/${run.id}`;
295
+ const outputs = run.definition.steps.flatMap((step) => {
296
+ const output = run.state.outputs[step.id];
297
+ if (!output) {
298
+ return [];
299
+ }
300
+ // A document, a dashboard or a widget drawn as one picture: for a door that shows pictures
301
+ // with a link. A generated image is a picture already.
302
+ const picture = formatsFor(step).includes("png") && !(step.type === "generate" && step.asset === "image")
303
+ ? signedUrl(`${base}/steps/${step.id}/download?format=png`)
304
+ : null;
305
+ return [
306
+ {
307
+ stepId: step.id,
308
+ title: step.title,
309
+ text: output.text ? clip(output.text, 1500) : undefined,
310
+ json: output.json === undefined ? undefined : clip(JSON.stringify(output.json), 1500),
311
+ assets: (output.assets ?? []).map((a) => ({
312
+ name: a.name,
313
+ mime: a.mime,
314
+ url: signedUrl(`${base}/assets/${a.id}`),
315
+ })),
316
+ downloads: Object.fromEntries(deliverableFormats(run, step).map((f) => [
317
+ f,
318
+ signedUrl(`${base}/steps/${step.id}/download?format=${f}`),
319
+ ])),
320
+ picture,
321
+ },
322
+ ];
323
+ });
324
+ return {
325
+ runId: run.id,
326
+ wizardId: run.wizardId,
327
+ mode: run.mode,
328
+ lang: wizardLang(run.definition),
329
+ status: moving(run) ? "running" : run.status,
330
+ step: current ? { id: current.id, type: current.type, title: current.title } : null,
331
+ /** Steps behind the run: answered pages and reviews, every step with a result, the end. */
332
+ passed: run.definition.steps
333
+ .filter((s) => run.state.history.includes(s.id) ||
334
+ run.state.outputs[s.id] ||
335
+ (run.status === "done" && s.id === run.cursor))
336
+ .map((s) => s.id),
337
+ waitingFor: await waitingFor(run, current, draft),
338
+ error: run.error,
339
+ credits: Math.ceil(run.costMicros / MICROS_PER_CREDIT),
340
+ events: (await recentEvents(run.id, 0, 15)).map((e) => ({
341
+ step: e.stepId,
342
+ type: e.type,
343
+ message: e.message,
344
+ })),
345
+ outputs,
346
+ browserUrl: await browserUrl(run),
347
+ ...(run.mode === "test" ? { studioUrl: studioUrl(run.wizardId) } : {}),
348
+ };
349
+ }
350
+ export const testRunReport = (userId, runId, waitSeconds = 0) => runReport(userId, runId, waitSeconds, "test");
351
+ /** A command the run refused, as a tool error the client can act on. */
352
+ export function refusedInput(err) {
353
+ if (err instanceof RunInputError) {
354
+ throw new ServiceError("invalid", saidOf(err), { fields: fieldErrorsIn(err.errors, "en") });
355
+ }
356
+ if (err instanceof RunConflict) {
357
+ throw new ServiceError("refused", saidOf(err));
358
+ }
359
+ throw err;
360
+ }
361
+ /**
362
+ * Runs the published version of a wizard for the admin, from their own AI client: a live run
363
+ * that is theirs — no visitor, no share link needed. With answers the first page is filled.
364
+ */
365
+ export async function startRun(userId, wizardId, answers = {}) {
366
+ const w = await ownedWizard(userId, wizardId);
367
+ if (w.publishedVersion === null) {
368
+ throw new ServiceError("refused", "This wizard isn’t published yet. Publish it, or try the draft with start_test_run.");
369
+ }
370
+ const version = await db.query.wizardVersion.findFirst({
371
+ where: and(eq(schema.wizardVersion.wizardId, w.id), eq(schema.wizardVersion.version, w.publishedVersion)),
372
+ });
373
+ if (!version) {
374
+ throw notFound();
375
+ }
376
+ if (!(await canSpend())) {
377
+ throw new ServiceError("no_credits", note("creditsUsedUp"));
378
+ }
379
+ const runId = await createRun({
380
+ wizardId: w.id,
381
+ definition: version.definition,
382
+ files: version.files,
383
+ version: w.publishedVersion,
384
+ mode: "live",
385
+ userId,
386
+ }).catch((err) => {
387
+ if (err instanceof ModelUnavailableError) {
388
+ throw new ServiceError("refused", saidOf(err));
389
+ }
390
+ if (err instanceof NoCreditsError) {
391
+ throw new ServiceError("no_credits", note("creditsUsedUp"));
392
+ }
393
+ throw err;
394
+ });
395
+ const first = version.definition.steps[0];
396
+ if (first?.type !== "page" || !Object.keys(answers).length) {
397
+ return { runId, refused: null };
398
+ }
399
+ const values = Object.fromEntries(first.fields.filter((f) => f.id in answers).map((f) => [f.id, answers[f.id]]));
400
+ // The run is there either way; what did not fit is answered again with answer_page.
401
+ try {
402
+ await submitPage(runId, first.id, values);
403
+ return { runId, refused: null };
404
+ }
405
+ catch (err) {
406
+ if (err instanceof RunInputError) {
407
+ return { runId, refused: fieldErrorsIn(err.errors, "en") };
408
+ }
409
+ throw err;
410
+ }
411
+ }
412
+ export async function answerRunPage(userId, runId, stepId, values) {
413
+ await ownedRun(userId, runId);
414
+ await submitPage(runId, stepId, values).catch(refusedInput);
415
+ }
416
+ export async function reviewRun(userId, runId, stepId, action) {
417
+ await ownedRun(userId, runId);
418
+ await reviewStep(runId, stepId, action).catch(refusedInput);
419
+ }
420
+ export async function controlRun(userId, runId, action) {
421
+ await ownedRun(userId, runId);
422
+ const command = { back: goBack, retry, cancel }[action];
423
+ await command(runId).catch(refusedInput);
424
+ }
425
+ /** Answers what a running step asks: allow a change in a connected account, or skip it. */
426
+ export async function answerRunAsk(userId, runId, askId, answer) {
427
+ await ownedRun(userId, runId);
428
+ if (!(await answerAsk(runId, askId, answer === "allow" ? { type: "done" } : { type: "skip" }))) {
429
+ throw new ServiceError("refused", { code: "askClosed" });
430
+ }
431
+ }
432
+ export async function listRuns(userId, wizardId) {
433
+ const w = await ownedWizard(userId, wizardId);
434
+ const rows = await db.query.run.findMany({
435
+ where: eq(schema.run.wizardId, w.id),
436
+ orderBy: [desc(schema.run.createdAt)],
437
+ limit: 100,
438
+ });
439
+ const assetCounts = rows.length
440
+ ? await db
441
+ .select({ runId: schema.asset.runId, n: count() })
442
+ .from(schema.asset)
443
+ .where(inArray(schema.asset.runId, rows.map((r) => r.id)))
444
+ .groupBy(schema.asset.runId)
445
+ : [];
446
+ return rows.map((r) => ({
447
+ id: r.id,
448
+ mode: r.mode,
449
+ status: r.status,
450
+ version: r.version,
451
+ createdAt: r.createdAt.toISOString(),
452
+ credits: Math.ceil(r.costMicros / MICROS_PER_CREDIT),
453
+ assets: assetCounts.find((a) => a.runId === r.id)?.n ?? 0,
454
+ stepTitle: r.definition.steps.find((s) => s.id === r.cursor)?.title ?? null,
455
+ }));
456
+ }
457
+ /**
458
+ * The results of a space: its wizards' runs that reached their result, newest first, narrowed by
459
+ * `filter`; and each wizard with how many it has and when its last one came, the latest first.
460
+ */
461
+ export async function listResults(projectId, filter = {}) {
462
+ const wizards = await db
463
+ .select({
464
+ id: schema.wizard.id,
465
+ title: schema.wizard.title,
466
+ results: count(schema.run.id),
467
+ lastAt: max(schema.run.updatedAt),
468
+ })
469
+ .from(schema.wizard)
470
+ .leftJoin(schema.run, and(eq(schema.run.wizardId, schema.wizard.id), eq(schema.run.status, "done")))
471
+ .where(and(eq(schema.wizard.projectId, projectId), eq(schema.wizard.tenantId, currentTenant())))
472
+ .groupBy(schema.wizard.id)
473
+ // Wizards without a result last: SQLite sorts null below every time.
474
+ .orderBy(desc(max(schema.run.updatedAt)), desc(schema.wizard.updatedAt));
475
+ const q = filter.q?.trim().toLowerCase();
476
+ const like = q ? `%${q.replace(/[\\%_]/g, (c) => `\\${c}`)}%` : null;
477
+ const titled = like
478
+ ? new Set(wizards.filter((w) => w.title.toLowerCase().includes(q)).map((w) => w.id))
479
+ : null;
480
+ const ids = wizards.map((w) => w.id).filter((id) => !filter.wizardId || id === filter.wizardId);
481
+ const rows = ids.length
482
+ ? await db
483
+ .select({
484
+ id: schema.run.id,
485
+ wizardId: schema.run.wizardId,
486
+ mode: schema.run.mode,
487
+ version: schema.run.version,
488
+ costMicros: schema.run.costMicros,
489
+ updatedAt: schema.run.updatedAt,
490
+ })
491
+ .from(schema.run)
492
+ .where(and(inArray(schema.run.wizardId, ids), eq(schema.run.status, "done"), filter.mode ? eq(schema.run.mode, filter.mode) : undefined, filter.days
493
+ ? gte(schema.run.updatedAt, new Date(Date.now() - filter.days * 86_400_000))
494
+ : undefined, like
495
+ ? or(titled?.size ? inArray(schema.run.wizardId, [...titled]) : undefined, sql `lower(${schema.run.state}) like ${like} escape '\\'`)
496
+ : undefined))
497
+ .orderBy(desc(schema.run.updatedAt))
498
+ .limit(100)
499
+ : [];
500
+ const assetCounts = rows.length
501
+ ? await db
502
+ .select({ runId: schema.asset.runId, n: count() })
503
+ .from(schema.asset)
504
+ .where(inArray(schema.asset.runId, rows.map((r) => r.id)))
505
+ .groupBy(schema.asset.runId)
506
+ : [];
507
+ return {
508
+ wizards: wizards.map((w) => ({
509
+ id: w.id,
510
+ title: w.title,
511
+ results: w.results,
512
+ lastAt: w.lastAt ? new Date(w.lastAt).toISOString() : null,
513
+ })),
514
+ runs: rows.map((r) => ({
515
+ id: r.id,
516
+ wizardId: r.wizardId,
517
+ mode: r.mode,
518
+ version: r.version,
519
+ doneAt: r.updatedAt.toISOString(),
520
+ credits: Math.ceil(r.costMicros / MICROS_PER_CREDIT),
521
+ assets: assetCounts.find((a) => a.runId === r.id)?.n ?? 0,
522
+ })),
523
+ };
524
+ }
@@ -0,0 +1,130 @@
1
+ import { note } from "@engenty-wizards/shared/run";
2
+ import { and, eq, isNotNull, lt } from "drizzle-orm";
3
+ import { nanoid } from "nanoid";
4
+ import { db, schema } from "../db/client.js";
5
+ import { availableFormats } from "../engine/runner.js";
6
+ import { env } from "../env.js";
7
+ import { inlineAssetRefs, loadAsset, loadAssetText, removeAssetFiles, saveAsset, } from "../files/storage.js";
8
+ import { htmlToPng } from "../render/convert.js";
9
+ import { dropLinks, dropRuns, putLink } from "../tenants/control.js";
10
+ import { brandView } from "./brand.js";
11
+ import { ServiceError } from "./errors.js";
12
+ export const shareUrlFor = (token) => `${env.publicUrl}/s/${token}`;
13
+ /** Shares a finished run. Idempotent: the same run keeps the same link. */
14
+ export async function shareRun(run) {
15
+ if (run.status !== "done") {
16
+ throw new ServiceError("refused", note("onlyFinishedResultsShared"));
17
+ }
18
+ let token = run.shareToken;
19
+ if (!token) {
20
+ token = nanoid(16);
21
+ await db
22
+ .update(schema.run)
23
+ .set({ shareToken: token, sharedAt: new Date() })
24
+ .where(eq(schema.run.id, run.id));
25
+ await putLink(token, "result", run.id);
26
+ }
27
+ return { url: shareUrlFor(token), expiresAt: run.expiresAt?.toISOString() ?? null };
28
+ }
29
+ export async function unshareRun(run) {
30
+ if (run.shareToken) {
31
+ await dropLinks([run.shareToken]);
32
+ }
33
+ await db
34
+ .update(schema.run)
35
+ .set({ shareToken: null, sharedAt: null })
36
+ .where(eq(schema.run.id, run.id));
37
+ }
38
+ /** The shared run behind a token, unless the link was withdrawn or the run expired. */
39
+ export async function sharedRun(token) {
40
+ const run = await db.query.run.findFirst({ where: eq(schema.run.shareToken, token) });
41
+ if (run?.status !== "done" || (run.expiresAt && run.expiresAt < new Date())) {
42
+ return null;
43
+ }
44
+ return run;
45
+ }
46
+ export async function shareView(run) {
47
+ const def = run.definition;
48
+ const result = def.steps.find((s) => s.id === run.cursor && s.type === "result") ??
49
+ def.steps.findLast((s) => s.type === "result");
50
+ const deliverables = result?.type === "result" ? result.deliverables : [];
51
+ const shown = await Promise.all(deliverables.flatMap((d) => {
52
+ const step = def.steps.find((s) => s.id === d.from);
53
+ const output = run.state.outputs[d.from];
54
+ return step && output
55
+ ? [
56
+ (async () => ({
57
+ step,
58
+ output,
59
+ formats: await availableFormats(step, run, d.formats),
60
+ label: d.label ?? null,
61
+ }))(),
62
+ ]
63
+ : [];
64
+ }));
65
+ const w = await db.query.wizard.findFirst({ where: eq(schema.wizard.id, run.wizardId) });
66
+ return {
67
+ token: run.shareToken ?? "",
68
+ title: result?.title ?? def.title,
69
+ message: result?.type === "result" ? (result.message ?? null) : null,
70
+ wizard: { title: def.title, description: def.description, avatar: def.avatar },
71
+ brand: await brandView(w?.projectId ?? ""),
72
+ shown,
73
+ createdAt: run.createdAt.toISOString(),
74
+ expiresAt: run.expiresAt?.toISOString() ?? null,
75
+ wizardUrl: w?.shareEnabled && w.publishedVersion !== null ? `${env.publicUrl}/w/${w.shareToken}` : null,
76
+ };
77
+ }
78
+ /**
79
+ * The picture link previews (X, LinkedIn, WhatsApp, Slack) show: the first image of the result,
80
+ * a widget's poster, or a document's first screen. Rendered once and kept.
81
+ */
82
+ export async function shareImage(run) {
83
+ const view = await shareView(run);
84
+ for (const { output } of view.shown) {
85
+ const assets = output?.assets ?? [];
86
+ const image = assets.find((a) => a.mime.startsWith("image/"));
87
+ if (image) {
88
+ const found = await loadAsset(image.id);
89
+ if (found) {
90
+ return { data: new Uint8Array(found.data), mime: found.row.mime };
91
+ }
92
+ }
93
+ const html = assets.find((a) => a.mime === "text/html");
94
+ if (html) {
95
+ const name = `${html.id}.og.png`;
96
+ const hit = await db.query.asset.findFirst({
97
+ where: and(eq(schema.asset.kind, "render"), eq(schema.asset.name, name)),
98
+ });
99
+ const cached = hit ? await loadAsset(hit.id) : null;
100
+ if (cached) {
101
+ return { data: new Uint8Array(cached.data), mime: "image/png" };
102
+ }
103
+ const page = await inlineAssetRefs(await loadAssetText(html.id));
104
+ const png = await htmlToPng(page, 1200, { height: 630, fullPage: false, scale: 1 });
105
+ await saveAsset({
106
+ runId: run.id,
107
+ kind: "render",
108
+ mime: "image/png",
109
+ name,
110
+ data: png,
111
+ });
112
+ return { data: png, mime: "image/png" };
113
+ }
114
+ }
115
+ return null;
116
+ }
117
+ /** Deletes runs past their expiry with everything they made. Runs hourly. */
118
+ export async function purgeExpiredRuns() {
119
+ const expired = await db
120
+ .select({ id: schema.run.id, shareToken: schema.run.shareToken })
121
+ .from(schema.run)
122
+ .where(and(isNotNull(schema.run.expiresAt), lt(schema.run.expiresAt, new Date())));
123
+ for (const { id } of expired) {
124
+ await removeAssetFiles(id);
125
+ await db.delete(schema.run).where(eq(schema.run.id, id));
126
+ }
127
+ await dropLinks(expired.map((r) => r.shareToken).filter((t) => Boolean(t)));
128
+ await dropRuns(expired.map((r) => r.id));
129
+ return expired.length;
130
+ }