@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,456 @@
1
+ import { createHash } from "node:crypto";
2
+ import { note } from "@engenty-wizards/shared/run";
3
+ import { and, asc, eq, inArray, isNotNull, isNull, like } from "drizzle-orm";
4
+ import { accountToken, linkedAccount } from "../auth/account.js";
5
+ import { control, controlDb, db, schema } from "../db/client.js";
6
+ import { env } from "../env.js";
7
+ import { getBlob } from "../files/blobs.js";
8
+ import { managed } from "../manage.js";
9
+ import { deleteSetting, readSetting, writeSetting } from "../settings.js";
10
+ import { currentTenant } from "../tenants/tenant.js";
11
+ import { mainLogoId } from "./brand.js";
12
+ import { ServiceError } from "./errors.js";
13
+ import { projectFileContent, projectFiles } from "./project-files.js";
14
+ import { ownedProject } from "./projects.js";
15
+ import { ownedWizard, publishedVersion, publishWizard } from "./wizards.js";
16
+ const key = (wizardId) => `cloud:${wizardId}`;
17
+ const EMPTY = { copy: null, error: null };
18
+ /** Whether this runtime sends what it publishes: it runs alone and an account is linked. */
19
+ export async function cloudLinked() {
20
+ return !managed && Boolean(await linkedAccount());
21
+ }
22
+ /** Where a local wizard stands in the cloud. */
23
+ export async function cloudState(wizardId) {
24
+ return (await readSetting(key(wizardId))) ?? EMPTY;
25
+ }
26
+ async function call(method, path, body, timeoutMs = 30_000) {
27
+ const token = await accountToken();
28
+ if (!token) {
29
+ throw new ServiceError("refused", note("accountSignedOut"), {
30
+ reason: "signed_out",
31
+ });
32
+ }
33
+ const res = await fetch(`${env.local.cloudUrl}/api/v1${path}`, {
34
+ method,
35
+ headers: {
36
+ authorization: `Bearer ${token}`,
37
+ ...(body === undefined ? {} : { "content-type": "application/json" }),
38
+ },
39
+ body: body === undefined ? undefined : JSON.stringify(body),
40
+ signal: AbortSignal.timeout(timeoutMs),
41
+ }).catch(() => null);
42
+ if (!res) {
43
+ throw new ServiceError("refused", note("cloudNotReachedRight"), {
44
+ reason: "unreachable",
45
+ });
46
+ }
47
+ const parsed = (await res.json().catch(() => ({})));
48
+ return { ok: res.ok, status: res.status, body: parsed };
49
+ }
50
+ function refusal(answer, fallback) {
51
+ const { error, reason, ...rest } = answer.body;
52
+ const message = answer.status === 401
53
+ ? note("accountSignedOut")
54
+ : typeof error === "string" && error
55
+ ? error
56
+ : fallback;
57
+ return new ServiceError("refused", message, {
58
+ reason: answer.status === 401 ? "signed_out" : typeof reason === "string" ? reason : "refused",
59
+ status: answer.status,
60
+ ...(Array.isArray(rest.spaces) ? { spaces: rest.spaces } : {}),
61
+ });
62
+ }
63
+ /** A try is made again by itself when the cloud, not what was sent, was the trouble. */
64
+ function worthAnotherTry(err) {
65
+ if (!(err instanceof ServiceError)) {
66
+ return true;
67
+ }
68
+ const status = typeof err.data.status === "number" ? err.data.status : 0;
69
+ return err.data.reason === "unreachable" || status >= 500 || status === 429;
70
+ }
71
+ /** A minute, then twice as long each time, up to an hour. */
72
+ function nextTry(tries, from) {
73
+ const minutes = Math.min(60, 2 ** (tries - 1));
74
+ return new Date(from.getTime() + minutes * 60_000).toISOString();
75
+ }
76
+ /** The project as the cloud keeps it: its name, what it says about itself, its logo. */
77
+ async function spaceOf(userId, projectId) {
78
+ const project = await ownedProject(userId, projectId);
79
+ const logoId = await mainLogoId(project.id);
80
+ const logo = logoId ? await projectFileContent(project.id, logoId).catch(() => null) : null;
81
+ return {
82
+ name: project.name,
83
+ brand: {
84
+ name: project.brand.name,
85
+ about: project.brand.about,
86
+ colors: project.brand.colors,
87
+ },
88
+ facts: project.facts,
89
+ logo: logo
90
+ ? {
91
+ name: logo.row.name,
92
+ mime: logo.row.mime,
93
+ description: logo.row.description,
94
+ data: Buffer.from(logo.data).toString("base64"),
95
+ }
96
+ : null,
97
+ };
98
+ }
99
+ /** The space's own tables and pages, as they are sent: not what a wizard's runs keep. */
100
+ async function spaceDataOf(projectId) {
101
+ const own = (table) => and(eq(table.projectId, projectId), isNull(table.wizardId));
102
+ const tables = await db.query.spaceTable.findMany({
103
+ where: own(schema.spaceTable),
104
+ orderBy: [asc(schema.spaceTable.id)],
105
+ });
106
+ const rows = tables.length
107
+ ? await db.query.spaceTableRow.findMany({
108
+ where: inArray(schema.spaceTableRow.tableId, tables.map((t) => t.id)),
109
+ orderBy: [asc(schema.spaceTableRow.createdAt), asc(schema.spaceTableRow.id)],
110
+ })
111
+ : [];
112
+ const pages = await db.query.spacePage.findMany({
113
+ where: own(schema.spacePage),
114
+ orderBy: [asc(schema.spacePage.id)],
115
+ });
116
+ const categories = await db.query.spaceCategory.findMany({
117
+ where: and(eq(schema.spaceCategory.projectId, projectId), eq(schema.spaceCategory.proposed, false)),
118
+ orderBy: [asc(schema.spaceCategory.position), asc(schema.spaceCategory.id)],
119
+ });
120
+ const values = categories.length
121
+ ? await db.query.spaceCategoryValue.findMany({
122
+ where: inArray(schema.spaceCategoryValue.categoryId, categories.map((c) => c.id)),
123
+ orderBy: [asc(schema.spaceCategoryValue.position), asc(schema.spaceCategoryValue.id)],
124
+ })
125
+ : [];
126
+ const assignments = categories.length
127
+ ? await db.query.spaceItemCategory.findMany({
128
+ where: and(eq(schema.spaceItemCategory.projectId, projectId), isNull(schema.spaceItemCategory.fileId)),
129
+ orderBy: [asc(schema.spaceItemCategory.id)],
130
+ })
131
+ : [];
132
+ const tableIds = new Set(tables.map((t) => t.id));
133
+ const rowIds = new Set(rows.map((r) => r.id));
134
+ const pageIds = new Set(pages.map((p) => p.id));
135
+ return {
136
+ tables: tables.map((t) => ({
137
+ id: t.id,
138
+ title: t.title,
139
+ format: t.format,
140
+ originLabel: t.originLabel,
141
+ columns: t.columns,
142
+ rows: rows.filter((r) => r.tableId === t.id).map((r) => ({ id: r.id, cells: r.cells })),
143
+ })),
144
+ pages: pages.map((p) => ({
145
+ id: p.id,
146
+ title: p.title,
147
+ markdown: p.markdown,
148
+ parentId: p.parentId,
149
+ position: p.position,
150
+ originLabel: p.originLabel,
151
+ })),
152
+ categories: categories.map((c) => ({
153
+ id: c.id,
154
+ name: c.name,
155
+ type: c.type,
156
+ unit: c.unit,
157
+ multiple: c.multiple,
158
+ ordered: c.ordered,
159
+ hint: c.hint,
160
+ tableId: c.tableId && tableIds.has(c.tableId) ? c.tableId : null,
161
+ columnId: c.tableId && tableIds.has(c.tableId) ? c.columnId : null,
162
+ position: c.position,
163
+ values: values
164
+ .filter((v) => v.categoryId === c.id)
165
+ .map((v) => ({ id: v.id, value: v.value, position: v.position, summary: v.summary })),
166
+ })),
167
+ // Only what goes along: a page, a table or a row of it.
168
+ assignments: assignments
169
+ .filter((a) => (a.pageId && pageIds.has(a.pageId)) ||
170
+ (a.tableId && tableIds.has(a.tableId)) ||
171
+ (a.rowId && rowIds.has(a.rowId)))
172
+ .map((a) => ({
173
+ categoryId: a.categoryId,
174
+ item: a.pageId ? `p:${a.pageId}` : a.tableId ? `t:${a.tableId}` : `r:${a.rowId}`,
175
+ valueId: a.valueId,
176
+ text: a.text,
177
+ num: a.num,
178
+ at: a.at,
179
+ bool: a.bool,
180
+ by: a.by,
181
+ })),
182
+ };
183
+ }
184
+ /**
185
+ * Sends the space's own tables and pages along with a wizard, when they changed since they last
186
+ * arrived. A sending that fails is tried with the next wizard; the wizard is there either way.
187
+ */
188
+ async function syncSpaceDataToCloud(projectId) {
189
+ const data = await spaceDataOf(projectId);
190
+ const hash = createHash("sha256").update(JSON.stringify(data)).digest("hex");
191
+ const sent = `cloud-data:${projectId}`;
192
+ if ((await readSetting(sent)) === hash) {
193
+ return;
194
+ }
195
+ try {
196
+ const answer = await call("PUT", `/spaces/${projectId}/data`, data, 120_000);
197
+ if (answer.ok) {
198
+ await writeSetting(sent, hash);
199
+ }
200
+ else {
201
+ console.error("[cloud] the space's data was not taken:", answer.status, answer.body);
202
+ }
203
+ }
204
+ catch (err) {
205
+ console.error("[cloud] sending the space's data failed:", err);
206
+ }
207
+ }
208
+ /**
209
+ * Sends a wizard's published version to the cloud: the same wizard again updates its copy
210
+ * there, whose link stays. What came back is kept; a try that failed is kept as such beside
211
+ * the copy from before. The space's own tables and pages follow it.
212
+ */
213
+ export async function syncToCloud(userId, wizardId) {
214
+ const w = await ownedWizard(userId, wizardId);
215
+ const version = await publishedVersion(w);
216
+ if (!version) {
217
+ throw new ServiceError("refused", note("publishWizardFirst"));
218
+ }
219
+ const before = await cloudState(w.id);
220
+ try {
221
+ const files = await Promise.all(version.files.map(async (f) => ({
222
+ path: f.path,
223
+ mime: f.mime,
224
+ data: (await getBlob(f.hash)).toString("base64"),
225
+ })));
226
+ const answer = await call("PUT", `/spaces/${w.projectId}/wizards/${w.id}`, {
227
+ space: await spaceOf(userId, w.projectId),
228
+ version: version.version,
229
+ definition: version.definition,
230
+ files,
231
+ shareEnabled: w.shareEnabled,
232
+ dailyRunLimit: w.dailyRunLimit,
233
+ }, 120_000);
234
+ if (!answer.ok || !answer.body.shareUrl) {
235
+ throw refusal(answer, "The cloud did not take the wizard.");
236
+ }
237
+ const state = {
238
+ copy: {
239
+ shareUrl: answer.body.shareUrl,
240
+ code: answer.body.code,
241
+ version: version.version,
242
+ publishedVersion: answer.body.publishedVersion,
243
+ runnable: answer.body.runnable,
244
+ problems: answer.body.problems ?? [],
245
+ syncedAt: new Date().toISOString(),
246
+ },
247
+ error: null,
248
+ };
249
+ await writeSetting(key(w.id), state);
250
+ await syncSpaceDataToCloud(w.projectId);
251
+ return state;
252
+ }
253
+ catch (err) {
254
+ const now = new Date();
255
+ const tries = (before.error?.tries ?? 0) + 1;
256
+ const failed = {
257
+ copy: before.copy,
258
+ error: {
259
+ message: err instanceof ServiceError ? err.message : "Sending did not work.",
260
+ reason: err instanceof ServiceError ? err.data.reason : undefined,
261
+ at: now.toISOString(),
262
+ tries,
263
+ again: worthAnotherTry(err) ? nextTry(tries, now) : null,
264
+ },
265
+ };
266
+ await writeSetting(key(w.id), failed);
267
+ if (!(err instanceof ServiceError)) {
268
+ console.error("[cloud] sync failed:", err);
269
+ }
270
+ return failed;
271
+ }
272
+ }
273
+ /**
274
+ * Publishes here and, with an account linked, sends the version on. The cloud never holds the
275
+ * publishing up or back: what it answered comes along as `cloud`.
276
+ */
277
+ export async function publishAndSync(userId, wizardId) {
278
+ const published = await publishWizard(userId, wizardId);
279
+ const cloud = (await cloudLinked()) ? await syncToCloud(userId, wizardId) : null;
280
+ return { ...published, cloud };
281
+ }
282
+ /** How a wizard is shared changed here: the copy in the cloud follows. */
283
+ export async function pushSharing(userId, wizardId) {
284
+ if (!(await cloudLinked())) {
285
+ return;
286
+ }
287
+ const state = await cloudState(wizardId);
288
+ if (!state.copy) {
289
+ return;
290
+ }
291
+ const w = await ownedWizard(userId, wizardId);
292
+ await call("PATCH", `/spaces/${w.projectId}/wizards/${w.id}`, {
293
+ shareEnabled: w.shareEnabled,
294
+ dailyRunLimit: w.dailyRunLimit,
295
+ translate: w.translate,
296
+ ...(w.runners ? { runners: w.runners } : {}),
297
+ }).catch((err) => console.error("[cloud] sharing not sent:", err.message));
298
+ }
299
+ /**
300
+ * A new link was made here: the copy in the cloud gets a new one too, and its old one stops
301
+ * answering. Null where no account is linked; the state as it was where the cloud has no copy.
302
+ */
303
+ export async function rotateInCloud(userId, wizardId) {
304
+ if (!(await cloudLinked())) {
305
+ return null;
306
+ }
307
+ const state = await cloudState(wizardId);
308
+ if (!state.copy) {
309
+ return state;
310
+ }
311
+ const w = await ownedWizard(userId, wizardId);
312
+ const answer = await call("POST", `/spaces/${w.projectId}/wizards/${w.id}/rotate-link`);
313
+ if (!answer.ok || !answer.body.shareUrl) {
314
+ throw refusal(answer, "The link in the cloud could not be renewed.");
315
+ }
316
+ const next = {
317
+ ...state,
318
+ copy: { ...state.copy, shareUrl: answer.body.shareUrl, code: answer.body.code },
319
+ };
320
+ await writeSetting(key(w.id), next);
321
+ return next;
322
+ }
323
+ /** A wizard is about to be deleted here: its copy in the cloud goes too. */
324
+ export async function removeFromCloud(userId, wizardId) {
325
+ const state = await cloudState(wizardId);
326
+ if (!state.copy && !state.error) {
327
+ return;
328
+ }
329
+ const w = await ownedWizard(userId, wizardId).catch(() => null);
330
+ await deleteSetting(key(wizardId));
331
+ if (!w || !state.copy || !(await cloudLinked())) {
332
+ return;
333
+ }
334
+ await call("DELETE", `/spaces/${w.projectId}/wizards/${w.id}`).catch((err) => console.error("[cloud] copy not removed:", err.message));
335
+ }
336
+ /**
337
+ * Sends again what did not arrive and is due for another try. Called every minute by the
338
+ * runtime that runs alone; a wizard that is gone meanwhile is forgotten.
339
+ */
340
+ export async function retryFailedSends(userId) {
341
+ if (!(await cloudLinked())) {
342
+ return;
343
+ }
344
+ const now = new Date().toISOString();
345
+ const rows = await controlDb
346
+ .select({ key: control.setting.key, value: control.setting.value })
347
+ .from(control.setting)
348
+ .where(like(control.setting.key, "cloud:%"));
349
+ for (const row of rows) {
350
+ const state = row.value;
351
+ if (!state.error?.again || state.error.again > now) {
352
+ continue;
353
+ }
354
+ const wizardId = row.key.slice("cloud:".length);
355
+ const w = await ownedWizard(userId, wizardId).catch(() => null);
356
+ if (!w?.publishedVersion) {
357
+ await deleteSetting(row.key);
358
+ continue;
359
+ }
360
+ const sent = await syncToCloud(userId, wizardId);
361
+ // Something the person has to see to (signed out, no room) holds for every wizard.
362
+ if (sent.error && !sent.error.again) {
363
+ break;
364
+ }
365
+ }
366
+ }
367
+ /** The account was unlinked: what this runtime kept of its cloud belongs to no account now. */
368
+ export async function forgetCloud() {
369
+ await controlDb.delete(control.setting).where(like(control.setting.key, "cloud:%"));
370
+ await forgetSentData();
371
+ }
372
+ /** The space's data counts as not sent: the next wizard takes it along again. */
373
+ async function forgetSentData() {
374
+ await controlDb.delete(control.setting).where(like(control.setting.key, "cloud-data:%"));
375
+ }
376
+ /** Sends every published wizard: once after an account was linked. */
377
+ export async function syncAllToCloud(userId) {
378
+ // A cloud that was linked anew, or whose spaces were replaced, has none of it.
379
+ await forgetSentData();
380
+ const wizards = await db
381
+ .select({ id: schema.wizard.id })
382
+ .from(schema.wizard)
383
+ .where(and(eq(schema.wizard.tenantId, currentTenant()), isNotNull(schema.wizard.publishedVersion)));
384
+ let sent = 0;
385
+ let failed = 0;
386
+ for (const [i, { id }] of wizards.entries()) {
387
+ const state = await syncToCloud(userId, id);
388
+ if (state.error) {
389
+ failed++;
390
+ // A refusal that holds for every wizard (no room, signed out) is not asked again; a cloud
391
+ // out of reach neither, but the rest is then tried again later, with this one.
392
+ if (state.error.reason && state.error.reason !== "refused") {
393
+ for (const rest of wizards.slice(i + 1)) {
394
+ failed++;
395
+ await writeSetting(key(rest.id), {
396
+ copy: (await cloudState(rest.id)).copy,
397
+ error: state.error,
398
+ });
399
+ }
400
+ break;
401
+ }
402
+ }
403
+ else {
404
+ sent++;
405
+ }
406
+ }
407
+ return { sent, failed };
408
+ }
409
+ /** What the cloud would lack for the draft, asked before it is published. */
410
+ export async function checkForCloud(userId, wizardId) {
411
+ const w = await ownedWizard(userId, wizardId);
412
+ const files = await db
413
+ .select({ path: schema.wizardFile.path })
414
+ .from(schema.wizardFile)
415
+ .where(eq(schema.wizardFile.wizardId, w.id));
416
+ const answer = await call("POST", "/spaces/check", {
417
+ definition: w.draft,
418
+ files: files.map((f) => f.path),
419
+ });
420
+ if (!answer.ok) {
421
+ throw refusal(answer, "The cloud did not answer.");
422
+ }
423
+ const documents = await projectFiles(w.projectId, "document");
424
+ return {
425
+ problems: answer.body.problems ?? [],
426
+ documents: documents.length > 0 && w.draft.steps.some((s) => s.type === "agent"),
427
+ };
428
+ }
429
+ /** The projects the account's cloud holds of local installs: this one's, or another machine's. */
430
+ export async function cloudSpaces() {
431
+ const answer = await call("GET", "/spaces");
432
+ if (!answer.ok) {
433
+ throw refusal(answer, "The cloud did not answer.");
434
+ }
435
+ return answer.body.spaces ?? [];
436
+ }
437
+ /**
438
+ * Makes room for this install's project: the projects of other installs go from the cloud, with
439
+ * their links, then everything published here is sent. For the person who moved to a new
440
+ * machine or installed anew.
441
+ */
442
+ export async function replaceCloudSpaces(userId) {
443
+ const mine = new Set((await db
444
+ .select({ id: schema.project.id })
445
+ .from(schema.project)
446
+ .where(eq(schema.project.tenantId, currentTenant()))).map((p) => p.id));
447
+ for (const space of await cloudSpaces()) {
448
+ if (!mine.has(space.id)) {
449
+ const answer = await call("DELETE", `/spaces/${space.id}`);
450
+ if (!answer.ok) {
451
+ throw refusal(answer, "The space in the cloud could not be removed.");
452
+ }
453
+ }
454
+ }
455
+ return syncAllToCloud(userId);
456
+ }
@@ -0,0 +1,27 @@
1
+ import { EventEmitter } from "node:events";
2
+ const bus = new EventEmitter();
3
+ bus.setMaxListeners(0);
4
+ export function emitDraftChanged(change) {
5
+ bus.emit(change.wizardId, change);
6
+ }
7
+ export function subscribeDraft(wizardId, listener) {
8
+ bus.on(wizardId, listener);
9
+ return () => bus.off(wizardId, listener);
10
+ }
11
+ /** Steps that are new or differ in `after`. */
12
+ export function changedSteps(before, after) {
13
+ const old = new Map(before.steps.map((s) => [s.id, JSON.stringify(s)]));
14
+ return after.steps.filter((s) => old.get(s.id) !== JSON.stringify(s)).map((s) => s.id);
15
+ }
16
+ /** A workspace file was written or removed. Files carry no revision; the draft's is passed along. */
17
+ export function filesChanged(w, path) {
18
+ return {
19
+ wizardId: w.id,
20
+ kind: "files",
21
+ revision: w.revision,
22
+ source: "studio",
23
+ client: null,
24
+ note: null,
25
+ touched: [path],
26
+ };
27
+ }
@@ -0,0 +1,71 @@
1
+ // Written by apps/web/scripts/engenty-shapes.tsx from apps/web/src/engenty — do not edit by hand.
2
+ export const ENGENTY_KINDS = ["round", "drop", "dome", "flame", "oval", "bean", "pebble", "sprout", "tower", "wedge"];
3
+ /** Each kind's fill in oklch, as the web writes it: the stage of a wizard takes its hue. */
4
+ export const ENGENTY_FILL_OKLCH = {
5
+ "round": "oklch(60% 0.23 262)",
6
+ "drop": "oklch(82% 0.17 78)",
7
+ "dome": "oklch(72% 0.22 145)",
8
+ "flame": "oklch(64% 0.25 18)",
9
+ "oval": "oklch(70% 0.21 42)",
10
+ "bean": "oklch(74% 0.16 192)",
11
+ "pebble": "oklch(66% 0.13 235)",
12
+ "sprout": "oklch(89% 0.2 118)",
13
+ "tower": "oklch(60% 0.25 300)",
14
+ "wedge": "oklch(65% 0.28 345)"
15
+ };
16
+ /** Still SVG, 120 × 120. */
17
+ export const ENGENTY_SVG = {
18
+ "round": "<svg viewBox=\"0 0 120 120\"><g><path fill=\"#2873ff\" d=\"M60 22 Q96 26 96 62 Q96 96 60 100 Q24 96 24 62 Q24 26 60 22 Z\"></path><circle cx=\"97\" cy=\"34\" fill=\"#2873ff\" opacity=\"0.5\" r=\"6\"></circle><circle cx=\"106\" cy=\"24\" fill=\"#2873ff\" opacity=\"0.35\" r=\"3.5\"></circle><g><ellipse cx=\"68\" cy=\"58\" fill=\"#fff\" rx=\"8\" ry=\"9.2\"></ellipse><circle cx=\"68\" cy=\"59\" fill=\"#000e34\" r=\"3.84\"></circle><circle cx=\"66\" cy=\"55.6\" fill=\"#fff\" r=\"1.44\"></circle></g></g></svg>",
19
+ "drop": "<svg viewBox=\"0 0 120 120\"><g><path fill=\"#ffb407\" d=\"M60 16 Q90 34 90 66 Q90 96 60 98 Q30 96 30 66 Q30 34 60 16 Z\"></path><g><ellipse cx=\"60\" cy=\"56\" fill=\"#fff\" rx=\"8\" ry=\"9.2\"></ellipse><circle cx=\"60\" cy=\"57\" fill=\"#501c00\" r=\"3.84\"></circle><circle cx=\"58\" cy=\"53.6\" fill=\"#fff\" r=\"1.44\"></circle></g><path d=\"M48 76 Q54 72 60 76 Q66 80 72 76\" fill=\"none\" stroke=\"#511a00\" stroke-linecap=\"round\" stroke-width=\"2.6\"></path></g></svg>",
20
+ "dome": "<svg viewBox=\"0 0 120 120\"><g><path fill=\"#19c63c\" d=\"M60 20 Q92 30 92 70 Q92 96 60 96 Q28 96 28 70 Q28 30 60 20 Z\"></path><path d=\"M46 90 L46 80 M60 92 L60 82 M74 90 L74 80\" opacity=\"0.5\" stroke=\"#003610\" stroke-linecap=\"round\" stroke-width=\"2.4\"></path><circle cx=\"60\" cy=\"6\" fill=\"#19c63c\" r=\"3\"></circle><g><ellipse cx=\"60\" cy=\"54\" fill=\"#fff\" rx=\"8.5\" ry=\"9.774999999999999\"></ellipse><circle cx=\"60\" cy=\"55\" fill=\"#001602\" r=\"4.08\"></circle><circle cx=\"57.875\" cy=\"51.45\" fill=\"#fff\" r=\"1.53\"></circle></g></g></svg>",
21
+ "flame": "<svg viewBox=\"0 0 120 120\"><g><path fill=\"#ff154f\" d=\"M60 14 Q84 44 80 76 Q78 98 60 98 Q42 98 40 76 Q36 44 60 14 Z\"></path><path d=\"M40 20 Q60 6 80 20\" fill=\"none\" opacity=\"0.55\" stroke=\"#ff154f\" stroke-linecap=\"round\" stroke-width=\"3\"></path><g><ellipse cx=\"60\" cy=\"62\" fill=\"#fff\" rx=\"8\" ry=\"9.2\"></ellipse><circle cx=\"60\" cy=\"63\" fill=\"#3d0007\" r=\"3.84\"></circle><circle cx=\"58\" cy=\"59.6\" fill=\"#fff\" r=\"1.44\"></circle></g><circle cx=\"60\" cy=\"82\" fill=\"#3d0007\" r=\"2.6\"></circle></g></svg>",
22
+ "oval": "<svg viewBox=\"0 0 120 120\"><g><path fill=\"#ff6404\" d=\"M60 34 Q100 38 100 64 Q100 92 60 94 Q20 92 20 64 Q20 38 60 34 Z\"></path><g fill=\"none\" opacity=\"0.45\" stroke=\"#8a0700\" stroke-width=\"2.2\"><path d=\"M28 54 Q60 48 92 54\"></path><path d=\"M26 70 Q60 64 94 70\"></path></g><g><ellipse cx=\"66\" cy=\"58\" fill=\"#fff\" rx=\"8\" ry=\"9.2\"></ellipse><circle cx=\"66\" cy=\"59\" fill=\"#430000\" r=\"3.84\"></circle><circle cx=\"64\" cy=\"55.6\" fill=\"#fff\" r=\"1.44\"></circle></g></g></svg>",
23
+ "bean": "<svg viewBox=\"0 0 120 120\"><g><path fill=\"#00c9c5\" d=\"M48 96 Q24 92 26 68 Q28 44 52 38 Q78 32 88 50 Q98 66 84 84 Q70 100 48 96 Z\"></path><circle cx=\"32\" cy=\"94\" fill=\"#00c9c5\" opacity=\"0.4\" r=\"4\"></circle><g><ellipse cx=\"70\" cy=\"58\" fill=\"#fff\" rx=\"8\" ry=\"9.2\"></ellipse><circle cx=\"70\" cy=\"59\" fill=\"#001a1f\" r=\"3.84\"></circle><circle cx=\"68\" cy=\"55.6\" fill=\"#fff\" r=\"1.44\"></circle></g></g></svg>",
24
+ "pebble": "<svg viewBox=\"0 0 120 120\"><g><path fill=\"#259ed6\" d=\"M60 96 Q20 96 18 78 Q16 60 46 56 Q78 52 98 62 Q110 72 104 86 Q98 96 60 96 Z\"></path><g fill=\"#163045\" opacity=\"0.32\"><circle cx=\"42\" cy=\"76\" r=\"3\"></circle><circle cx=\"56\" cy=\"86\" r=\"2.2\"></circle><circle cx=\"86\" cy=\"80\" r=\"2.6\"></circle></g><g><ellipse cx=\"68\" cy=\"72\" fill=\"#fff\" rx=\"7.5\" ry=\"8.625\"></ellipse><circle cx=\"68\" cy=\"73\" fill=\"#00182f\" r=\"3.5999999999999996\"></circle><circle cx=\"66.125\" cy=\"69.75\" fill=\"#fff\" r=\"1.3499999999999999\"></circle></g></g></svg>",
25
+ "sprout": "<svg viewBox=\"0 0 120 120\"><g><g fill=\"#d0eb24\"><ellipse cx=\"48\" cy=\"34\" rx=\"6\" ry=\"10\"></ellipse><ellipse cx=\"72\" cy=\"32\" rx=\"5.5\" ry=\"9\"></ellipse></g><path fill=\"#d0eb24\" d=\"M60 100 Q28 98 28 72 Q28 46 60 44 Q92 46 92 72 Q92 98 60 100 Z\"></path><g><ellipse cx=\"60\" cy=\"68\" fill=\"#fff\" rx=\"8.5\" ry=\"9.774999999999999\"></ellipse><circle cx=\"60\" cy=\"69\" fill=\"#242100\" r=\"4.08\"></circle><circle cx=\"57.875\" cy=\"65.45\" fill=\"#fff\" r=\"1.53\"></circle></g></g></svg>",
26
+ "tower": "<svg viewBox=\"0 0 120 120\"><g><path fill=\"#9b48fb\" d=\"M60 102 Q36 100 38 78 Q40 58 42 44 Q44 26 60 24 Q76 26 78 44 Q80 58 82 78 Q84 100 60 102 Z\"></path><g fill=\"none\" opacity=\"0.4\" stroke=\"#37164e\" stroke-linecap=\"round\" stroke-width=\"2.2\"><path d=\"M42 74 Q60 70 78 74\"></path><path d=\"M40 88 Q60 84 80 88\"></path></g><g><ellipse cx=\"60\" cy=\"52\" fill=\"#fff\" rx=\"8\" ry=\"9.2\"></ellipse><circle cx=\"60\" cy=\"53\" fill=\"#210434\" r=\"3.84\"></circle><circle cx=\"58\" cy=\"49.6\" fill=\"#fff\" r=\"1.44\"></circle></g></g></svg>",
27
+ "wedge": "<svg viewBox=\"0 0 120 120\"><g><path fill=\"#f800b5\" d=\"M60 30 Q74 40 86 70 Q96 92 78 98 Q60 102 42 98 Q24 92 34 70 Q46 40 60 30 Z\"></path><path d=\"M52 22 Q60 14 68 22\" fill=\"none\" opacity=\"0.5\" stroke=\"#f800b5\" stroke-linecap=\"round\" stroke-width=\"3\"></path><g><ellipse cx=\"60\" cy=\"70\" fill=\"#fff\" rx=\"8\" ry=\"9.2\"></ellipse><circle cx=\"60\" cy=\"71\" fill=\"#370025\" r=\"3.84\"></circle><circle cx=\"58\" cy=\"67.6\" fill=\"#fff\" r=\"1.44\"></circle></g></g></svg>"
28
+ };
29
+ /** The line each kind stands on (`cy`) and its shadow's half width, in the same 120 × 120. */
30
+ export const ENGENTY_SHADOW = {
31
+ "round": {
32
+ "cy": 108,
33
+ "rx": 26
34
+ },
35
+ "drop": {
36
+ "cy": 106,
37
+ "rx": 24
38
+ },
39
+ "dome": {
40
+ "cy": 104,
41
+ "rx": 27
42
+ },
43
+ "flame": {
44
+ "cy": 106,
45
+ "rx": 22
46
+ },
47
+ "oval": {
48
+ "cy": 102,
49
+ "rx": 32
50
+ },
51
+ "bean": {
52
+ "cy": 102,
53
+ "rx": 26
54
+ },
55
+ "pebble": {
56
+ "cy": 102,
57
+ "rx": 34
58
+ },
59
+ "sprout": {
60
+ "cy": 106,
61
+ "rx": 26
62
+ },
63
+ "tower": {
64
+ "cy": 108,
65
+ "rx": 20
66
+ },
67
+ "wedge": {
68
+ "cy": 106,
69
+ "rx": 28
70
+ }
71
+ };
@@ -0,0 +1,29 @@
1
+ import { note } from "@engenty-wizards/shared/run";
2
+ import { errorText, NotedError } from "../model-errors.js";
3
+ const STATUS = {
4
+ not_found: 404,
5
+ invalid: 400,
6
+ has_issues: 400,
7
+ revision_conflict: 409,
8
+ no_credits: 402,
9
+ refused: 400,
10
+ read_only: 403,
11
+ forbidden: 403,
12
+ };
13
+ export class ServiceError extends NotedError {
14
+ code;
15
+ data;
16
+ constructor(code, said, data = {}) {
17
+ super(said);
18
+ this.code = code;
19
+ this.data = data;
20
+ }
21
+ get status() {
22
+ return STATUS[this.code];
23
+ }
24
+ /** The answer, its words in the asker's language; English where none is known. */
25
+ toJSON(lang = "en") {
26
+ return { error: errorText(this, lang), code: this.code, ...this.data };
27
+ }
28
+ }
29
+ export const notFound = () => new ServiceError("not_found", note("notFound"));