@engenty/wizards-runtime 0.0.0-stage → 0.7.5

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 (518) 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 +93 -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 +222 -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/setup.js +335 -0
  49. package/apps/runtime/dist/cli/start.js +276 -0
  50. package/apps/runtime/dist/cli/status.js +203 -0
  51. package/apps/runtime/dist/cli/ui.js +59 -0
  52. package/apps/runtime/dist/cli/uninstall-main.js +20 -0
  53. package/apps/runtime/dist/cli/uninstall.js +231 -0
  54. package/apps/runtime/dist/cli/update.js +86 -0
  55. package/apps/runtime/dist/cli/validate.js +75 -0
  56. package/apps/runtime/dist/cli/versions.js +123 -0
  57. package/apps/runtime/dist/connectors/builtin.js +86 -0
  58. package/apps/runtime/dist/connectors/external.js +409 -0
  59. package/apps/runtime/dist/connectors/gmail.js +107 -0
  60. package/apps/runtime/dist/connectors/imap.js +261 -0
  61. package/apps/runtime/dist/connectors/index.js +325 -0
  62. package/apps/runtime/dist/connectors/mail.js +72 -0
  63. package/apps/runtime/dist/connectors/outlook.js +90 -0
  64. package/apps/runtime/dist/connectors/plugin-connections.js +343 -0
  65. package/apps/runtime/dist/connectors/via-account.js +65 -0
  66. package/apps/runtime/dist/credits/credits.js +100 -0
  67. package/apps/runtime/dist/credits/estimate.js +152 -0
  68. package/apps/runtime/dist/db/adopt.js +149 -0
  69. package/apps/runtime/dist/db/client.js +173 -0
  70. package/apps/runtime/dist/db/control-schema.js +133 -0
  71. package/apps/runtime/dist/db/migrations/control/0000_last_absorbing_man.sql +47 -0
  72. package/apps/runtime/dist/db/migrations/control/0001_gorgeous_nicolaos.sql +41 -0
  73. package/apps/runtime/dist/db/migrations/control/0002_secret_penance.sql +1 -0
  74. package/apps/runtime/dist/db/migrations/control/0003_nasty_mordo.sql +3 -0
  75. package/apps/runtime/dist/db/migrations/control/0004_breezy_eddie_brock.sql +6 -0
  76. package/apps/runtime/dist/db/migrations/control/0005_chilly_oracle.sql +1 -0
  77. package/apps/runtime/dist/db/migrations/control/0006_sleepy_mojo.sql +1 -0
  78. package/apps/runtime/dist/db/migrations/control/0007_common_the_hand.sql +15 -0
  79. package/apps/runtime/dist/db/migrations/control/0008_runner.sql +8 -0
  80. package/apps/runtime/dist/db/migrations/control/0009_plugin_claim.sql +9 -0
  81. package/apps/runtime/dist/db/migrations/control/0010_tan_snowbird.sql +6 -0
  82. package/apps/runtime/dist/db/migrations/control/meta/0000_snapshot.json +311 -0
  83. package/apps/runtime/dist/db/migrations/control/meta/0001_snapshot.json +599 -0
  84. package/apps/runtime/dist/db/migrations/control/meta/0002_snapshot.json +607 -0
  85. package/apps/runtime/dist/db/migrations/control/meta/0003_snapshot.json +311 -0
  86. package/apps/runtime/dist/db/migrations/control/meta/0004_snapshot.json +350 -0
  87. package/apps/runtime/dist/db/migrations/control/meta/0005_snapshot.json +358 -0
  88. package/apps/runtime/dist/db/migrations/control/meta/0006_snapshot.json +365 -0
  89. package/apps/runtime/dist/db/migrations/control/meta/0007_snapshot.json +460 -0
  90. package/apps/runtime/dist/db/migrations/control/meta/0008_snapshot.json +505 -0
  91. package/apps/runtime/dist/db/migrations/control/meta/0009_snapshot.json +561 -0
  92. package/apps/runtime/dist/db/migrations/control/meta/0010_snapshot.json +600 -0
  93. package/apps/runtime/dist/db/migrations/control/meta/_journal.json +83 -0
  94. package/apps/runtime/dist/db/migrations/tenant/0000_eminent_freak.sql +188 -0
  95. package/apps/runtime/dist/db/migrations/tenant/0001_salty_master_chief.sql +1 -0
  96. package/apps/runtime/dist/db/migrations/tenant/0002_cloudy_firebird.sql +1 -0
  97. package/apps/runtime/dist/db/migrations/tenant/0003_brown_warbound.sql +52 -0
  98. package/apps/runtime/dist/db/migrations/tenant/0004_romantic_nocturne.sql +6 -0
  99. package/apps/runtime/dist/db/migrations/tenant/0005_reflective_forgotten_one.sql +2 -0
  100. package/apps/runtime/dist/db/migrations/tenant/0006_hard_war_machine.sql +30 -0
  101. package/apps/runtime/dist/db/migrations/tenant/0007_space_data.sql +43 -0
  102. package/apps/runtime/dist/db/migrations/tenant/0008_run_event_note.sql +1 -0
  103. package/apps/runtime/dist/db/migrations/tenant/0009_knowledge.sql +104 -0
  104. package/apps/runtime/dist/db/migrations/tenant/0010_plugin_connection.sql +15 -0
  105. package/apps/runtime/dist/db/migrations/tenant/0011_runners.sql +2 -0
  106. package/apps/runtime/dist/db/migrations/tenant/0012_assistant_chat.sql +40 -0
  107. package/apps/runtime/dist/db/migrations/tenant/0013_run_origin.sql +1 -0
  108. package/apps/runtime/dist/db/migrations/tenant/0014_run_answer.sql +2 -0
  109. package/apps/runtime/dist/db/migrations/tenant/0015_device_calls.sql +13 -0
  110. package/apps/runtime/dist/db/migrations/tenant/0016_even_trish_tilby.sql +12 -0
  111. package/apps/runtime/dist/db/migrations/tenant/meta/0000_snapshot.json +1323 -0
  112. package/apps/runtime/dist/db/migrations/tenant/meta/0001_snapshot.json +1330 -0
  113. package/apps/runtime/dist/db/migrations/tenant/meta/0002_snapshot.json +1337 -0
  114. package/apps/runtime/dist/db/migrations/tenant/meta/0003_snapshot.json +1605 -0
  115. package/apps/runtime/dist/db/migrations/tenant/meta/0004_snapshot.json +1645 -0
  116. package/apps/runtime/dist/db/migrations/tenant/meta/0005_snapshot.json +1659 -0
  117. package/apps/runtime/dist/db/migrations/tenant/meta/0006_snapshot.json +1696 -0
  118. package/apps/runtime/dist/db/migrations/tenant/meta/0007_snapshot.json +2012 -0
  119. package/apps/runtime/dist/db/migrations/tenant/meta/0008_snapshot.json +2019 -0
  120. package/apps/runtime/dist/db/migrations/tenant/meta/0009_snapshot.json +2837 -0
  121. package/apps/runtime/dist/db/migrations/tenant/meta/0010_snapshot.json +2942 -0
  122. package/apps/runtime/dist/db/migrations/tenant/meta/0011_snapshot.json +2956 -0
  123. package/apps/runtime/dist/db/migrations/tenant/meta/0012_snapshot.json +3132 -0
  124. package/apps/runtime/dist/db/migrations/tenant/meta/0013_snapshot.json +3139 -0
  125. package/apps/runtime/dist/db/migrations/tenant/meta/0014_snapshot.json +3154 -0
  126. package/apps/runtime/dist/db/migrations/tenant/meta/0015_snapshot.json +3243 -0
  127. package/apps/runtime/dist/db/migrations/tenant/meta/0016_snapshot.json +3326 -0
  128. package/apps/runtime/dist/db/migrations/tenant/meta/_journal.json +125 -0
  129. package/apps/runtime/dist/db/schema.js +602 -0
  130. package/apps/runtime/dist/debug.js +196 -0
  131. package/apps/runtime/dist/docs/dev/index.md +41 -0
  132. package/apps/runtime/dist/docs/dev/meta.json +7 -0
  133. package/apps/runtime/dist/docs/dev/plugins/connections.md +74 -0
  134. package/apps/runtime/dist/docs/dev/plugins/events.md +89 -0
  135. package/apps/runtime/dist/docs/dev/plugins/examples.md +101 -0
  136. package/apps/runtime/dist/docs/dev/plugins/index.md +78 -0
  137. package/apps/runtime/dist/docs/dev/plugins/layout.md +90 -0
  138. package/apps/runtime/dist/docs/dev/plugins/meta.json +28 -0
  139. package/apps/runtime/dist/docs/dev/plugins/quick-start.md +94 -0
  140. package/apps/runtime/dist/docs/dev/plugins/reference.md +348 -0
  141. package/apps/runtime/dist/docs/dev/plugins/reloading.md +76 -0
  142. package/apps/runtime/dist/docs/dev/plugins/routes.md +185 -0
  143. package/apps/runtime/dist/docs/dev/plugins/runners.md +230 -0
  144. package/apps/runtime/dist/docs/dev/plugins/server.md +281 -0
  145. package/apps/runtime/dist/docs/dev/plugins/shipping.md +79 -0
  146. package/apps/runtime/dist/docs/dev/plugins/space.md +297 -0
  147. package/apps/runtime/dist/docs/dev/plugins/starters.md +70 -0
  148. package/apps/runtime/dist/docs/dev/plugins/studio.md +363 -0
  149. package/apps/runtime/dist/docs/dev/plugins/styling.md +129 -0
  150. package/apps/runtime/dist/docs/dev/plugins/tables.md +104 -0
  151. package/apps/runtime/dist/docs/dev/plugins/tools.md +139 -0
  152. package/apps/runtime/dist/docs/dev/wizard-format.md +125 -0
  153. package/apps/runtime/dist/docs/meta.json +3 -0
  154. package/apps/runtime/dist/docs/user/ai-apps.md +112 -0
  155. package/apps/runtime/dist/docs/user/assistant.md +77 -0
  156. package/apps/runtime/dist/docs/user/build-a-wizard.md +116 -0
  157. package/apps/runtime/dist/docs/user/command-line.md +83 -0
  158. package/apps/runtime/dist/docs/user/connectors.md +90 -0
  159. package/apps/runtime/dist/docs/user/create-account.md +52 -0
  160. package/apps/runtime/dist/docs/user/data.md +66 -0
  161. package/apps/runtime/dist/docs/user/first-start.md +60 -0
  162. package/apps/runtime/dist/docs/user/index.md +49 -0
  163. package/apps/runtime/dist/docs/user/install.md +123 -0
  164. package/apps/runtime/dist/docs/user/local-only.md +42 -0
  165. package/apps/runtime/dist/docs/user/meta.json +32 -0
  166. package/apps/runtime/dist/docs/user/models.md +156 -0
  167. package/apps/runtime/dist/docs/user/plugins.md +71 -0
  168. package/apps/runtime/dist/docs/user/run.md +98 -0
  169. package/apps/runtime/dist/docs/user/server.md +52 -0
  170. package/apps/runtime/dist/docs/user/space.md +126 -0
  171. package/apps/runtime/dist/docs/user/steps.md +220 -0
  172. package/apps/runtime/dist/docs/user/test-and-share.md +224 -0
  173. package/apps/runtime/dist/docs/user/troubleshooting.md +67 -0
  174. package/apps/runtime/dist/docs/user/wordpress.md +121 -0
  175. package/apps/runtime/dist/documents/parse.js +246 -0
  176. package/apps/runtime/dist/engenty/connections-external/build-connector.js +193 -0
  177. package/apps/runtime/dist/engenty/connections-external/errors.js +11 -0
  178. package/apps/runtime/dist/engenty/connections-external/import-service.js +270 -0
  179. package/apps/runtime/dist/engenty/connections-external/importer/classify.js +34 -0
  180. package/apps/runtime/dist/engenty/connections-external/importer/map-auth.js +185 -0
  181. package/apps/runtime/dist/engenty/connections-external/importer/normalize-mcp.js +63 -0
  182. package/apps/runtime/dist/engenty/connections-external/importer/normalize-openapi.js +130 -0
  183. package/apps/runtime/dist/engenty/connections-external/invoke/http-invoker.js +143 -0
  184. package/apps/runtime/dist/engenty/connections-external/invoke/mcp-client.js +143 -0
  185. package/apps/runtime/dist/engenty/connections-external/net/guarded-fetch.js +119 -0
  186. package/apps/runtime/dist/engenty/connections-external/oauth-dcr.js +88 -0
  187. package/apps/runtime/dist/engenty/connections-external/registry-client.js +336 -0
  188. package/apps/runtime/dist/engenty/connections-external/registry-source.js +82 -0
  189. package/apps/runtime/dist/engenty/connections-external/types.js +7 -0
  190. package/apps/runtime/dist/engenty/connections-github/connector.js +209 -0
  191. package/apps/runtime/dist/engenty/connections-google/connectors/calendar.js +381 -0
  192. package/apps/runtime/dist/engenty/connections-google/connectors/contacts.js +94 -0
  193. package/apps/runtime/dist/engenty/connections-google/connectors/drive.js +290 -0
  194. package/apps/runtime/dist/engenty/connections-google/connectors/gmail.js +567 -0
  195. package/apps/runtime/dist/engenty/connections-google/definitions.js +11 -0
  196. package/apps/runtime/dist/engenty/connections-google/shared.js +73 -0
  197. package/apps/runtime/dist/engenty/connections-hubspot/connector.js +140 -0
  198. package/apps/runtime/dist/engenty/connections-microsoft/action.js +17 -0
  199. package/apps/runtime/dist/engenty/connections-microsoft/graph.js +114 -0
  200. package/apps/runtime/dist/engenty/connections-microsoft/onedrive.js +286 -0
  201. package/apps/runtime/dist/engenty/connections-microsoft/outlook.js +492 -0
  202. package/apps/runtime/dist/engenty/connections-s3/s3.js +328 -0
  203. package/apps/runtime/dist/engenty/connections-sdk/files-capability.js +86 -0
  204. package/apps/runtime/dist/engenty/connections-sdk/oauth2.js +150 -0
  205. package/apps/runtime/dist/engenty/connections-sdk/registry.js +89 -0
  206. package/apps/runtime/dist/engenty/connections-sdk/storage-capability.js +84 -0
  207. package/apps/runtime/dist/engenty/connections-sdk/types.js +30 -0
  208. package/apps/runtime/dist/engenty/connections-slack/connector.js +360 -0
  209. package/apps/runtime/dist/engenty/csv-import/csv-matrix.js +178 -0
  210. package/apps/runtime/dist/engenty/csv-import/import-sources.js +87 -0
  211. package/apps/runtime/dist/engenty/csv-import/parse-csv.js +129 -0
  212. package/apps/runtime/dist/engenty/csv-import/serialize-csv.js +20 -0
  213. package/apps/runtime/dist/engenty/csv-import/types.js +1 -0
  214. package/apps/runtime/dist/engenty/csv-import/xlsx-workbook.js +159 -0
  215. package/apps/runtime/dist/engenty/doc-converter/interface.js +9 -0
  216. package/apps/runtime/dist/engenty/doc-converter/page-break.js +92 -0
  217. package/apps/runtime/dist/engenty/doc-converter/providers/local/index.js +72 -0
  218. package/apps/runtime/dist/engenty/document-scanner/schemas/classifier.js +30 -0
  219. package/apps/runtime/dist/engenty/document-scanner/schemas/index.js +4 -0
  220. package/apps/runtime/dist/engenty/document-scanner/schemas/invoice.js +73 -0
  221. package/apps/runtime/dist/engenty/document-scanner/schemas/receipt.js +63 -0
  222. package/apps/runtime/dist/engenty/document-scanner/schemas/shared.js +40 -0
  223. package/apps/runtime/dist/engenty/search-index/chunks.js +164 -0
  224. package/apps/runtime/dist/engenty/search-index/contracts.js +9 -0
  225. package/apps/runtime/dist/engenty/shims/connections-sdk.js +39 -0
  226. package/apps/runtime/dist/engenty/shims/plugin-sdk.js +1 -0
  227. package/apps/runtime/dist/engenty/shims/web-ingest.js +19 -0
  228. package/apps/runtime/dist/engenty/web-ingest/ssrf.js +277 -0
  229. package/apps/runtime/dist/engine/asks.js +82 -0
  230. package/apps/runtime/dist/engine/decide.js +82 -0
  231. package/apps/runtime/dist/engine/device.js +194 -0
  232. package/apps/runtime/dist/engine/events.js +128 -0
  233. package/apps/runtime/dist/engine/input.js +208 -0
  234. package/apps/runtime/dist/engine/owner.js +32 -0
  235. package/apps/runtime/dist/engine/prepare.js +90 -0
  236. package/apps/runtime/dist/engine/push.js +58 -0
  237. package/apps/runtime/dist/engine/requirements.js +355 -0
  238. package/apps/runtime/dist/engine/resources.js +198 -0
  239. package/apps/runtime/dist/engine/runner.js +970 -0
  240. package/apps/runtime/dist/engine/steps.js +1000 -0
  241. package/apps/runtime/dist/engine/surface.js +91 -0
  242. package/apps/runtime/dist/engine/template.js +240 -0
  243. package/apps/runtime/dist/engine/types.js +4 -0
  244. package/apps/runtime/dist/env.js +295 -0
  245. package/apps/runtime/dist/features.js +123 -0
  246. package/apps/runtime/dist/files/blobs.js +22 -0
  247. package/apps/runtime/dist/files/objects.js +86 -0
  248. package/apps/runtime/dist/files/storage.js +120 -0
  249. package/apps/runtime/dist/files/web-images.js +101 -0
  250. package/apps/runtime/dist/film/project.js +257 -0
  251. package/apps/runtime/dist/film/skills.js +91 -0
  252. package/apps/runtime/dist/film/sounds.js +122 -0
  253. package/apps/runtime/dist/film/step.js +289 -0
  254. package/apps/runtime/dist/film/tools.js +99 -0
  255. package/apps/runtime/dist/geocode.js +58 -0
  256. package/apps/runtime/dist/harness/antigravity.js +129 -0
  257. package/apps/runtime/dist/harness/apple.js +270 -0
  258. package/apps/runtime/dist/harness/claude.js +147 -0
  259. package/apps/runtime/dist/harness/codex.js +229 -0
  260. package/apps/runtime/dist/harness/cursor.js +93 -0
  261. package/apps/runtime/dist/harness/env.js +124 -0
  262. package/apps/runtime/dist/harness/index.js +95 -0
  263. package/apps/runtime/dist/harness/model.js +279 -0
  264. package/apps/runtime/dist/harness/prompt.js +121 -0
  265. package/apps/runtime/dist/harness/terminal.js +194 -0
  266. package/apps/runtime/dist/harness/types.js +7 -0
  267. package/apps/runtime/dist/index.js +113 -0
  268. package/apps/runtime/dist/limits.js +81 -0
  269. package/apps/runtime/dist/link-preview.js +60 -0
  270. package/apps/runtime/dist/log.js +106 -0
  271. package/apps/runtime/dist/manage.js +249 -0
  272. package/apps/runtime/dist/mcp/auth.js +161 -0
  273. package/apps/runtime/dist/mcp/bridge.js +59 -0
  274. package/apps/runtime/dist/mcp/flow-app.js +97 -0
  275. package/apps/runtime/dist/mcp/handler.js +54 -0
  276. package/apps/runtime/dist/mcp/scopes.js +14 -0
  277. package/apps/runtime/dist/mcp/seen.js +65 -0
  278. package/apps/runtime/dist/mcp/tools.js +572 -0
  279. package/apps/runtime/dist/media/conversation.js +167 -0
  280. package/apps/runtime/dist/media/ffmpeg.js +121 -0
  281. package/apps/runtime/dist/media/generate.js +120 -0
  282. package/apps/runtime/dist/media/marking.js +121 -0
  283. package/apps/runtime/dist/media/transcribe.js +198 -0
  284. package/apps/runtime/dist/model-errors.js +42 -0
  285. package/apps/runtime/dist/models.js +1164 -0
  286. package/apps/runtime/dist/plugin.js +61 -0
  287. package/apps/runtime/dist/plugins/channels.js +78 -0
  288. package/apps/runtime/dist/plugins/claims.js +56 -0
  289. package/apps/runtime/dist/plugins/discovery.js +155 -0
  290. package/apps/runtime/dist/plugins/events.js +63 -0
  291. package/apps/runtime/dist/plugins/jobs.js +64 -0
  292. package/apps/runtime/dist/plugins/loader.js +508 -0
  293. package/apps/runtime/dist/plugins/migrations.js +69 -0
  294. package/apps/runtime/dist/plugins/pro-keys.js +34 -0
  295. package/apps/runtime/dist/plugins/pro-state.js +83 -0
  296. package/apps/runtime/dist/plugins/pro.js +310 -0
  297. package/apps/runtime/dist/plugins/public.js +44 -0
  298. package/apps/runtime/dist/plugins/registry.js +122 -0
  299. package/apps/runtime/dist/plugins/runs.js +210 -0
  300. package/apps/runtime/dist/render/browser-path.js +54 -0
  301. package/apps/runtime/dist/render/chromium.js +98 -0
  302. package/apps/runtime/dist/render/convert.js +158 -0
  303. package/apps/runtime/dist/render/downloads.js +299 -0
  304. package/apps/runtime/dist/render/guard.js +25 -0
  305. package/apps/runtime/dist/render/shaped.js +137 -0
  306. package/apps/runtime/dist/routes/api.js +440 -0
  307. package/apps/runtime/dist/routes/debug.js +42 -0
  308. package/apps/runtime/dist/routes/delivery.js +90 -0
  309. package/apps/runtime/dist/routes/internal.js +81 -0
  310. package/apps/runtime/dist/routes/lang.js +25 -0
  311. package/apps/runtime/dist/routes/marketplace.js +43 -0
  312. package/apps/runtime/dist/routes/plugin-public.js +113 -0
  313. package/apps/runtime/dist/routes/plugins.js +212 -0
  314. package/apps/runtime/dist/routes/runs.js +1422 -0
  315. package/apps/runtime/dist/routes/studio.js +1629 -0
  316. package/apps/runtime/dist/routes/wizard-stream.js +30 -0
  317. package/apps/runtime/dist/running.js +39 -0
  318. package/apps/runtime/dist/sandbox/docker.js +75 -0
  319. package/apps/runtime/dist/sandbox/index.js +23 -0
  320. package/apps/runtime/dist/sandbox/types.js +1 -0
  321. package/apps/runtime/dist/secrets/crypto.js +28 -0
  322. package/apps/runtime/dist/secrets/signing.js +52 -0
  323. package/apps/runtime/dist/secrets/vault.js +59 -0
  324. package/apps/runtime/dist/services/access.js +88 -0
  325. package/apps/runtime/dist/services/api.js +248 -0
  326. package/apps/runtime/dist/services/architect.js +95 -0
  327. package/apps/runtime/dist/services/assistant-chats.js +311 -0
  328. package/apps/runtime/dist/services/brand.js +85 -0
  329. package/apps/runtime/dist/services/cloud.js +456 -0
  330. package/apps/runtime/dist/services/draft-events.js +27 -0
  331. package/apps/runtime/dist/services/engenty-shapes.js +71 -0
  332. package/apps/runtime/dist/services/errors.js +29 -0
  333. package/apps/runtime/dist/services/files.js +178 -0
  334. package/apps/runtime/dist/services/knowledge-model.js +559 -0
  335. package/apps/runtime/dist/services/knowledge.js +721 -0
  336. package/apps/runtime/dist/services/links.js +16 -0
  337. package/apps/runtime/dist/services/marketplace.js +492 -0
  338. package/apps/runtime/dist/services/onboarding.js +152 -0
  339. package/apps/runtime/dist/services/package-file.js +82 -0
  340. package/apps/runtime/dist/services/package.js +170 -0
  341. package/apps/runtime/dist/services/profile.js +51 -0
  342. package/apps/runtime/dist/services/project-files.js +439 -0
  343. package/apps/runtime/dist/services/project-index.js +707 -0
  344. package/apps/runtime/dist/services/projects.js +387 -0
  345. package/apps/runtime/dist/services/relevance.js +58 -0
  346. package/apps/runtime/dist/services/runners.js +178 -0
  347. package/apps/runtime/dist/services/runs.js +524 -0
  348. package/apps/runtime/dist/services/shares.js +130 -0
  349. package/apps/runtime/dist/services/site.js +270 -0
  350. package/apps/runtime/dist/services/space-categories.js +861 -0
  351. package/apps/runtime/dist/services/space-data.js +792 -0
  352. package/apps/runtime/dist/services/space-origin.js +207 -0
  353. package/apps/runtime/dist/services/spaces.js +656 -0
  354. package/apps/runtime/dist/services/translations.js +306 -0
  355. package/apps/runtime/dist/services/widgets.js +34 -0
  356. package/apps/runtime/dist/services/wizard-icon.js +157 -0
  357. package/apps/runtime/dist/services/wizards.js +420 -0
  358. package/apps/runtime/dist/settings.js +16 -0
  359. package/apps/runtime/dist/store/errors.js +4 -0
  360. package/apps/runtime/dist/store/index.js +299 -0
  361. package/apps/runtime/dist/store/shared-lists.js +123 -0
  362. package/apps/runtime/dist/tenants/control.js +238 -0
  363. package/apps/runtime/dist/tenants/tenant.js +26 -0
  364. package/apps/runtime/dist/texts.js +207 -0
  365. package/apps/runtime/dist/tools/browser.js +703 -0
  366. package/apps/runtime/dist/tools/connector.js +204 -0
  367. package/apps/runtime/dist/tools/index.js +291 -0
  368. package/apps/runtime/dist/tools/mail.js +104 -0
  369. package/apps/runtime/dist/tools/net-guard.js +170 -0
  370. package/apps/runtime/dist/tools/pages.js +81 -0
  371. package/apps/runtime/dist/tools/plugin.js +180 -0
  372. package/apps/runtime/dist/tools/project.js +154 -0
  373. package/apps/runtime/dist/tools/shared.js +69 -0
  374. package/apps/runtime/dist/tools/store.js +238 -0
  375. package/apps/runtime/dist/update.js +113 -0
  376. package/apps/runtime/dist/widgets/bundle.js +99 -0
  377. package/apps/runtime/dist/widgets/render.js +329 -0
  378. package/apps/runtime/dist/widgets/runtime.js +108 -0
  379. package/apps/runtime/dist/widgets/script.js +30 -0
  380. package/apps/runtime/dist/widgets/step.js +223 -0
  381. package/apps/web/dist/ai-labels/ai-black.svg +20 -0
  382. package/apps/web/dist/ai-labels/ai-generated-black.svg +31 -0
  383. package/apps/web/dist/ai-labels/ai-generated-white.svg +32 -0
  384. package/apps/web/dist/ai-labels/ai-modified-black.svg +30 -0
  385. package/apps/web/dist/ai-labels/ai-modified-white.svg +31 -0
  386. package/apps/web/dist/ai-labels/ai-white.svg +21 -0
  387. package/apps/web/dist/assets/AboutDialog-D4mvc-zu.js +1 -0
  388. package/apps/web/dist/assets/ChangelogDialog-DLqpJsF6.js +1 -0
  389. package/apps/web/dist/assets/ChatView-3laypRcE.js +10 -0
  390. package/apps/web/dist/assets/EditorPage-BalA5U2Y.js +3 -0
  391. package/apps/web/dist/assets/FlowPreview-CusP7ci9.js +1 -0
  392. package/apps/web/dist/assets/Harness-BrP-ENHg.css +1 -0
  393. package/apps/web/dist/assets/Harness-iYLtOLaK.js +16 -0
  394. package/apps/web/dist/assets/NewWizardChannels-CbwJ9A56.js +1 -0
  395. package/apps/web/dist/assets/NewWizardPage-BOBYiB9i.js +7 -0
  396. package/apps/web/dist/assets/OnboardingPage-CUwCiVIr.js +1 -0
  397. package/apps/web/dist/assets/ProjectPage-Bb16MdYG.js +1 -0
  398. package/apps/web/dist/assets/PublicRunner-BCt7Q6C-.js +1 -0
  399. package/apps/web/dist/assets/ReadOnly-kIHX2TEy.js +1 -0
  400. package/apps/web/dist/assets/RunDrawer-hZ9oeSXu.js +4 -0
  401. package/apps/web/dist/assets/RunnerView-DUS9fPmx.js +1 -0
  402. package/apps/web/dist/assets/SettingsPage-BzwR50fi.js +1 -0
  403. package/apps/web/dist/assets/SetupPage-gAp7rPxp.js +1 -0
  404. package/apps/web/dist/assets/SharePage-DqZWHva_.js +1 -0
  405. package/apps/web/dist/assets/changelog-DugmCNSf.js +1 -0
  406. package/apps/web/dist/assets/engenty-eXZ-EAwd.js +1 -0
  407. package/apps/web/dist/assets/esm-DXeMu8Lb.js +7 -0
  408. package/apps/web/dist/assets/fluffy-engenty-ClRou7yu.js +456 -0
  409. package/apps/web/dist/assets/index-AfUa8xKD.css +1 -0
  410. package/apps/web/dist/assets/index-C5Sm7tTR.js +14 -0
  411. package/apps/web/dist/assets/jsx-runtime-BNakU3Ej.js +1 -0
  412. package/apps/web/dist/assets/lock-R_CfU0Xo.js +1 -0
  413. package/apps/web/dist/assets/oss-credits-cZ9NUaLZ.js +1 -0
  414. package/apps/web/dist/assets/pdfmake-Cx9scTbD.js +228 -0
  415. package/apps/web/dist/assets/phone-CgrIS4_-.js +1 -0
  416. package/apps/web/dist/assets/preload-helper-CNEI7N0N.js +1 -0
  417. package/apps/web/dist/assets/qr-scanner-worker.min-CJaXo3yu.js +98 -0
  418. package/apps/web/dist/assets/qr-scanner.min-C_UI0gH-.js +1 -0
  419. package/apps/web/dist/assets/rolldown-runtime-hePW80VL.js +1 -0
  420. package/apps/web/dist/assets/settings-menu-2IMOOlLl.js +1 -0
  421. package/apps/web/dist/assets/ui-dzGvc3xk.js +137 -0
  422. package/apps/web/dist/assets/upload-BSuTilFF.js +1 -0
  423. package/apps/web/dist/assets/vfs_fonts-DllDSYt1.js +1 -0
  424. package/apps/web/dist/embed.js +266 -0
  425. package/apps/web/dist/favicon.svg +1 -0
  426. package/apps/web/dist/icons/apple-touch-icon.png +0 -0
  427. package/apps/web/dist/icons/icon-192.png +0 -0
  428. package/apps/web/dist/icons/icon-512.png +0 -0
  429. package/apps/web/dist/icons/icon-maskable-512.png +0 -0
  430. package/apps/web/dist/index.html +48 -0
  431. package/apps/web/dist/install.sh +577 -0
  432. package/apps/web/dist/manifest.webmanifest +21 -0
  433. package/apps/web/dist/mcp/flow.html +980 -0
  434. package/apps/web/dist/sw.js +15 -0
  435. package/bin/wizards.mjs +288 -0
  436. package/modules/README.md +15 -0
  437. package/node_modules/@engenty/wizards/dist/plugin/index.d.ts +1150 -0
  438. package/node_modules/@engenty/wizards/dist/plugin/index.js +4 -0
  439. package/node_modules/@engenty/wizards/dist/plugin/studio.d.ts +322 -0
  440. package/node_modules/@engenty/wizards/dist/plugin/studio.js +4 -0
  441. package/node_modules/@engenty/wizards/dist/plugin/thread.d.ts +174 -0
  442. package/node_modules/@engenty/wizards/dist/plugin/thread.js +821 -0
  443. package/node_modules/@engenty/wizards/package.json +11 -0
  444. package/node_modules/@engenty-wizards/shared/dist/assistant.d.ts +174 -0
  445. package/node_modules/@engenty-wizards/shared/dist/assistant.js +65 -0
  446. package/node_modules/@engenty-wizards/shared/dist/changes.d.ts +22 -0
  447. package/node_modules/@engenty-wizards/shared/dist/changes.js +61 -0
  448. package/node_modules/@engenty-wizards/shared/dist/connectors.d.ts +77 -0
  449. package/node_modules/@engenty-wizards/shared/dist/connectors.js +2 -0
  450. package/node_modules/@engenty-wizards/shared/dist/decision.d.ts +76 -0
  451. package/node_modules/@engenty-wizards/shared/dist/decision.js +147 -0
  452. package/node_modules/@engenty-wizards/shared/dist/definition.d.ts +2922 -0
  453. package/node_modules/@engenty-wizards/shared/dist/definition.js +1920 -0
  454. package/node_modules/@engenty-wizards/shared/dist/engenty/data-tables/columns-format.d.ts +5 -0
  455. package/node_modules/@engenty-wizards/shared/dist/engenty/data-tables/columns-format.js +132 -0
  456. package/node_modules/@engenty-wizards/shared/dist/engenty/data-tables/columns-value.d.ts +11 -0
  457. package/node_modules/@engenty-wizards/shared/dist/engenty/data-tables/columns-value.js +209 -0
  458. package/node_modules/@engenty-wizards/shared/dist/engenty/data-tables/columns.d.ts +532 -0
  459. package/node_modules/@engenty-wizards/shared/dist/engenty/data-tables/columns.js +217 -0
  460. package/node_modules/@engenty-wizards/shared/dist/engenty/data-tables/index.d.ts +3 -0
  461. package/node_modules/@engenty-wizards/shared/dist/engenty/data-tables/index.js +3 -0
  462. package/node_modules/@engenty-wizards/shared/dist/engenty/search-index/catalog-lexical.d.ts +14 -0
  463. package/node_modules/@engenty-wizards/shared/dist/engenty/search-index/catalog-lexical.js +166 -0
  464. package/node_modules/@engenty-wizards/shared/dist/engenty/search-index/catalog-rank.d.ts +33 -0
  465. package/node_modules/@engenty-wizards/shared/dist/engenty/search-index/catalog-rank.js +99 -0
  466. package/node_modules/@engenty-wizards/shared/dist/feature-flags.d.ts +78 -0
  467. package/node_modules/@engenty-wizards/shared/dist/feature-flags.js +70 -0
  468. package/node_modules/@engenty-wizards/shared/dist/features.d.ts +41 -0
  469. package/node_modules/@engenty-wizards/shared/dist/features.js +89 -0
  470. package/node_modules/@engenty-wizards/shared/dist/fit.d.ts +71 -0
  471. package/node_modules/@engenty-wizards/shared/dist/fit.js +382 -0
  472. package/node_modules/@engenty-wizards/shared/dist/json-schema.d.ts +14 -0
  473. package/node_modules/@engenty-wizards/shared/dist/json-schema.js +66 -0
  474. package/node_modules/@engenty-wizards/shared/dist/knowledge.d.ts +199 -0
  475. package/node_modules/@engenty-wizards/shared/dist/knowledge.js +68 -0
  476. package/node_modules/@engenty-wizards/shared/dist/marketplace-entry.d.ts +35 -0
  477. package/node_modules/@engenty-wizards/shared/dist/marketplace-entry.js +107 -0
  478. package/node_modules/@engenty-wizards/shared/dist/marketplace-search.d.ts +20 -0
  479. package/node_modules/@engenty-wizards/shared/dist/marketplace-search.js +136 -0
  480. package/node_modules/@engenty-wizards/shared/dist/marketplace.d.ts +227 -0
  481. package/node_modules/@engenty-wizards/shared/dist/marketplace.js +354 -0
  482. package/node_modules/@engenty-wizards/shared/dist/merge.d.ts +7 -0
  483. package/node_modules/@engenty-wizards/shared/dist/merge.js +40 -0
  484. package/node_modules/@engenty-wizards/shared/dist/numbers.d.ts +24 -0
  485. package/node_modules/@engenty-wizards/shared/dist/numbers.js +54 -0
  486. package/node_modules/@engenty-wizards/shared/dist/projects.d.ts +224 -0
  487. package/node_modules/@engenty-wizards/shared/dist/projects.js +319 -0
  488. package/node_modules/@engenty-wizards/shared/dist/providers.d.ts +101 -0
  489. package/node_modules/@engenty-wizards/shared/dist/providers.js +390 -0
  490. package/node_modules/@engenty-wizards/shared/dist/run.d.ts +680 -0
  491. package/node_modules/@engenty-wizards/shared/dist/run.js +620 -0
  492. package/node_modules/@engenty-wizards/shared/dist/runner-texts.d.ts +546 -0
  493. package/node_modules/@engenty-wizards/shared/dist/runner-texts.js +523 -0
  494. package/node_modules/@engenty-wizards/shared/dist/runners.d.ts +93 -0
  495. package/node_modules/@engenty-wizards/shared/dist/runners.js +146 -0
  496. package/node_modules/@engenty-wizards/shared/dist/shape.d.ts +102 -0
  497. package/node_modules/@engenty-wizards/shared/dist/shape.js +318 -0
  498. package/node_modules/@engenty-wizards/shared/dist/space-data.d.ts +89 -0
  499. package/node_modules/@engenty-wizards/shared/dist/space-data.js +47 -0
  500. package/node_modules/@engenty-wizards/shared/dist/store.d.ts +117 -0
  501. package/node_modules/@engenty-wizards/shared/dist/store.js +81 -0
  502. package/node_modules/@engenty-wizards/shared/dist/surface.d.ts +115 -0
  503. package/node_modules/@engenty-wizards/shared/dist/surface.js +442 -0
  504. package/node_modules/@engenty-wizards/shared/dist/texts.d.ts +45 -0
  505. package/node_modules/@engenty-wizards/shared/dist/texts.js +54 -0
  506. package/node_modules/@engenty-wizards/shared/dist/translation.d.ts +23 -0
  507. package/node_modules/@engenty-wizards/shared/dist/translation.js +154 -0
  508. package/node_modules/@engenty-wizards/shared/dist/wizard-package.d.ts +48 -0
  509. package/node_modules/@engenty-wizards/shared/dist/wizard-package.js +49 -0
  510. package/node_modules/@engenty-wizards/shared/dist/workspace.d.ts +16 -0
  511. package/node_modules/@engenty-wizards/shared/dist/workspace.js +51 -0
  512. package/node_modules/@engenty-wizards/shared/package.json +10 -0
  513. package/package.json +77 -4
  514. package/plugin/.claude-plugin/plugin.json +9 -0
  515. package/plugin/.mcp.json +8 -0
  516. package/plugin/commands/wizard.md +8 -0
  517. package/plugin/skills/build-wizard/SKILL.md +27 -0
  518. package/plugin/skills/use-wizard/SKILL.md +18 -0
@@ -0,0 +1,656 @@
1
+ import { createHash } from "node:crypto";
2
+ import { tableColumnsSchema } from "@engenty-wizards/shared/engenty/data-tables";
3
+ import { CATEGORY_TYPES } from "@engenty-wizards/shared/knowledge";
4
+ import { PROJECT_LIMITS } from "@engenty-wizards/shared/projects";
5
+ import { note } from "@engenty-wizards/shared/run";
6
+ import { SPACE_DATA_LIMITS } from "@engenty-wizards/shared/space-data";
7
+ import { WORKSPACE_LIMITS } from "@engenty-wizards/shared/workspace";
8
+ import { and, count, eq, inArray, isNull, notInArray, sql } from "drizzle-orm";
9
+ import { nanoid } from "nanoid";
10
+ import { z } from "zod";
11
+ import { db, inTransaction, schema } from "../db/client.js";
12
+ import { missingModels, unavoidableSteps } from "../engine/requirements.js";
13
+ import { env } from "../env.js";
14
+ import { spaceChanged } from "../plugins/events.js";
15
+ import { codeOf, putLink } from "../tenants/control.js";
16
+ import { currentTenant } from "../tenants/tenant.js";
17
+ import { asSync, mayBuild } from "./access.js";
18
+ import { emitDraftChanged } from "./draft-events.js";
19
+ import { notFound, ServiceError } from "./errors.js";
20
+ import { keepFiles, replaceFiles } from "./files.js";
21
+ import { addProjectFile, projectFiles, removeProjectFile } from "./project-files.js";
22
+ import { reindexSpace } from "./project-index.js";
23
+ import { brandColorSchema, projectFactSchema, projectLimit, removeProject, } from "./projects.js";
24
+ import { deleteWizard, draftIssues, parseDraft, rotateShareLink, shareUrl } from "./wizards.js";
25
+ /**
26
+ * A local install's project on this runtime (docs/manage-contract.md, "Spaces of a local
27
+ * install"). The install sends a wizard when it publishes it: the published version and its
28
+ * workspace, under the ids they have there. Here the project is shown and its wizards run; it
29
+ * is changed only by the next sync. The share link is this runtime's own.
30
+ */
31
+ /** Ids as the local install makes them (nanoid); nothing else is taken as a key. */
32
+ const syncedId = z.string().regex(/^[A-Za-z0-9_-]{8,40}$/);
33
+ const spaceSchema = z.object({
34
+ name: z.string().min(1).max(80),
35
+ brand: z
36
+ .object({
37
+ name: z.string().max(120).optional(),
38
+ about: z.string().max(8000).optional(),
39
+ colors: z.array(brandColorSchema).max(PROJECT_LIMITS.colors).optional(),
40
+ })
41
+ .default({}),
42
+ facts: z.array(projectFactSchema).max(PROJECT_LIMITS.facts).default([]),
43
+ /** The logo end users see; null for none. */
44
+ logo: z
45
+ .object({
46
+ name: z.string().min(1).max(120),
47
+ mime: z.string().max(100),
48
+ description: z.string().max(600).default(""),
49
+ data: z.string(),
50
+ })
51
+ .nullable()
52
+ .default(null),
53
+ });
54
+ export const syncWizardSchema = z.object({
55
+ space: spaceSchema,
56
+ /** The version the install published, as it counts them. */
57
+ version: z.number().int().min(1).max(1_000_000),
58
+ definition: z.unknown(),
59
+ files: z
60
+ .array(z.object({
61
+ path: z.string().max(300),
62
+ mime: z.string().max(100).optional(),
63
+ data: z.string(),
64
+ }))
65
+ .max(WORKSPACE_LIMITS.files)
66
+ .default([]),
67
+ shareEnabled: z.boolean().default(true),
68
+ dailyRunLimit: z.number().int().min(1).max(10_000).optional(),
69
+ });
70
+ export const syncSettingsSchema = z.object({
71
+ shareEnabled: z.boolean().optional(),
72
+ translate: z.boolean().optional(),
73
+ dailyRunLimit: z.number().int().min(1).max(10_000).optional(),
74
+ });
75
+ export const checkSchema = z.object({
76
+ definition: z.unknown(),
77
+ /** Paths of the wizard's workspace files. */
78
+ files: z.array(z.string().max(300)).max(WORKSPACE_LIMITS.files).default([]),
79
+ });
80
+ const stepsWith = (def, has) => def.steps.filter(has).map((s) => ({ id: s.id, title: s.title }));
81
+ /**
82
+ * What of a wizard does not work on this runtime: what its validator says here (a connector
83
+ * the project lacks, a plugin's tool), model classes nothing is bound to, the sandbox where
84
+ * there is none, MCP servers the project does not know.
85
+ */
86
+ export async function serverProblems(def, issues, mcpServers) {
87
+ const problems = issues.map((issue) => ({
88
+ code: /connector/i.test(issue.message) ? "connector" : "invalid",
89
+ blocking: true,
90
+ steps: stepsWith(def, (s) => s.id === issue.stepId),
91
+ detail: issue.message,
92
+ }));
93
+ for (const missing of await missingModels(def)) {
94
+ problems.push({
95
+ code: "model",
96
+ blocking: missing.blocking,
97
+ steps: missing.steps,
98
+ detail: `${missing.cls}: ${missing.problem}`,
99
+ });
100
+ }
101
+ if (env.sandbox === "off") {
102
+ const steps = stepsWith(def, (s) => s.type === "agent" && s.tools.includes("sandbox"));
103
+ if (steps.length) {
104
+ problems.push({ code: "sandbox", blocking: false, steps, detail: "" });
105
+ }
106
+ }
107
+ const unknown = new Set();
108
+ const steps = stepsWith(def, (s) => {
109
+ const lacking = s.type === "agent" ? (s.mcp ?? []).filter((id) => !mcpServers.includes(id)) : [];
110
+ for (const id of lacking) {
111
+ unknown.add(id);
112
+ }
113
+ return lacking.length > 0;
114
+ });
115
+ if (steps.length) {
116
+ const unavoidable = unavoidableSteps(def);
117
+ problems.push({
118
+ code: "mcp",
119
+ blocking: steps.some((s) => unavoidable.has(s.id)),
120
+ steps,
121
+ detail: [...unknown].join(", "),
122
+ });
123
+ }
124
+ return problems;
125
+ }
126
+ /** What a wizard would lack here, asked before it is sent: no project is touched. */
127
+ export async function checkOnServer(input) {
128
+ const { draft, issues } = parseDraft(input.definition, input.files);
129
+ // Connectors are a project's; a project that is not here yet has none.
130
+ const connectors = (draft.connections ?? [])
131
+ .filter((c) => c.connector)
132
+ .map((c) => ({
133
+ message: `Connection "${c.id}" uses connector "${c.connector}", which this project has not imported.`,
134
+ }));
135
+ return serverProblems(draft, [...issues, ...connectors], []);
136
+ }
137
+ async function syncedProject(spaceId) {
138
+ const p = await db.query.project.findFirst({
139
+ where: and(eq(schema.project.id, spaceId), eq(schema.project.tenantId, currentTenant())),
140
+ });
141
+ return p ?? null;
142
+ }
143
+ /** Refuses a project beyond the tenant's number; a synced one counts like one made here. */
144
+ async function requireRoom(spaceId) {
145
+ const mine = eq(schema.project.tenantId, currentTenant());
146
+ // What a tenant that builds nothing here once made here is not shown, so it takes no place.
147
+ const counted = (await mayBuild()) ? mine : and(mine, eq(schema.project.origin, "local"));
148
+ const others = await db
149
+ .select({ id: schema.project.id, name: schema.project.name, origin: schema.project.origin })
150
+ .from(schema.project)
151
+ .where(and(counted, sql `${schema.project.id} <> ${spaceId}`));
152
+ const limit = await projectLimit();
153
+ if (others.length >= limit) {
154
+ throw new ServiceError("refused", limit === 1 ? note("accountAlreadySpace") : note("accountAlreadySpaces", { count: limit }), {
155
+ reason: "space_limit",
156
+ limit,
157
+ spaces: others.filter((p) => p.origin === "local").map((p) => ({ id: p.id, name: p.name })),
158
+ });
159
+ }
160
+ }
161
+ /** A synced project holds so many wizards: each brings up to 25 MB of files to keep. */
162
+ async function requireWizardRoom(spaceId) {
163
+ const [row] = await db
164
+ .select({ n: count() })
165
+ .from(schema.wizard)
166
+ .where(eq(schema.wizard.projectId, spaceId));
167
+ if ((row?.n ?? 0) >= env.limits.syncedWizards) {
168
+ throw new ServiceError("refused", note("roomMostPublishedWizards", { count: env.limits.syncedWizards }), { reason: "wizard_limit", limit: env.limits.syncedWizards });
169
+ }
170
+ }
171
+ const hashOf = (data) => createHash("sha256").update(data).digest("hex");
172
+ /**
173
+ * The project's logo follows the install's: kept when it is the same picture, else replaced —
174
+ * the new one is stored before the old one goes, so a store that fails leaves the old one.
175
+ */
176
+ async function syncLogo(projectId, logo) {
177
+ const here = await projectFiles(projectId, "logo");
178
+ const data = logo ? Buffer.from(logo.data, "base64") : null;
179
+ const mark = data ? `sync:${hashOf(data)}` : null;
180
+ if (mark && here.length === 1 && here[0].source === mark) {
181
+ return;
182
+ }
183
+ if (logo && data && mark) {
184
+ await addProjectFile(projectId, {
185
+ kind: "logo",
186
+ name: logo.name,
187
+ mime: logo.mime,
188
+ data,
189
+ // With words of its own no model is asked to describe it.
190
+ description: logo.description || logo.name,
191
+ source: mark,
192
+ });
193
+ }
194
+ for (const old of here) {
195
+ await removeProjectFile(projectId, old.id);
196
+ }
197
+ }
198
+ /** Makes or updates the synced project: its name and what it says about itself (the logo: syncLogo). */
199
+ async function syncSpace(spaceId, space) {
200
+ const existing = await syncedProject(spaceId);
201
+ if (existing && existing.origin !== "local") {
202
+ throw new ServiceError("refused", note("spaceIdAlreadyExists"), {
203
+ reason: "id_taken",
204
+ });
205
+ }
206
+ if (!existing) {
207
+ await requireRoom(spaceId);
208
+ }
209
+ const now = new Date();
210
+ const values = { name: space.name, brand: space.brand, facts: space.facts, syncedAt: now };
211
+ if (existing) {
212
+ await db
213
+ .update(schema.project)
214
+ .set({ ...values, updatedAt: now })
215
+ .where(eq(schema.project.id, spaceId));
216
+ }
217
+ else {
218
+ await db.insert(schema.project).values({
219
+ id: spaceId,
220
+ tenantId: currentTenant(),
221
+ origin: "local",
222
+ mcpServers: [],
223
+ ...values,
224
+ });
225
+ }
226
+ spaceChanged(existing ? "space.updated" : "space.created", spaceId);
227
+ const project = await syncedProject(spaceId);
228
+ if (!project) {
229
+ throw notFound();
230
+ }
231
+ return project;
232
+ }
233
+ /**
234
+ * Takes a wizard a local install published: the project it is in, the wizard under its id, its
235
+ * workspace, and the version — published here when a run of it can finish. Sending the same
236
+ * wizard again updates the copy; its link stays. The files' bytes are kept first; then the
237
+ * project, the wizard, its workspace and the version are written in one transaction, so an
238
+ * install whose sending broke off finds nothing half done and sends again.
239
+ */
240
+ export async function syncWizard(rawSpaceId, rawWizardId, input) {
241
+ const spaceId = syncedId.parse(rawSpaceId);
242
+ const wizardId = syncedId.parse(rawWizardId);
243
+ // The shape is checked before anything is written; a wrong one leaves nothing behind.
244
+ const { draft } = parseDraft(input.definition, input.files.map((f) => f.path));
245
+ return asSync(async () => {
246
+ const files = await keepFiles(input.files.map((f) => ({ path: f.path, mime: f.mime, data: Buffer.from(f.data, "base64") })));
247
+ const taken = await inTransaction(async () => {
248
+ const project = await syncSpace(spaceId, input.space);
249
+ const existing = await db.query.wizard.findFirst({
250
+ where: and(eq(schema.wizard.id, wizardId), eq(schema.wizard.tenantId, currentTenant())),
251
+ });
252
+ if (existing && existing.projectId !== spaceId) {
253
+ throw new ServiceError("refused", note("wizardIdAlreadyBelongs"), {
254
+ reason: "id_taken",
255
+ });
256
+ }
257
+ const settings = {
258
+ title: draft.title,
259
+ draft,
260
+ shareEnabled: input.shareEnabled,
261
+ ...(input.dailyRunLimit ? { dailyRunLimit: input.dailyRunLimit } : {}),
262
+ };
263
+ if (!existing) {
264
+ await requireWizardRoom(spaceId);
265
+ }
266
+ if (existing) {
267
+ await db
268
+ .update(schema.wizard)
269
+ .set({ ...settings, revision: sql `${schema.wizard.revision} + 1`, updatedAt: new Date() })
270
+ .where(eq(schema.wizard.id, wizardId));
271
+ }
272
+ else {
273
+ await db.insert(schema.wizard).values({
274
+ id: wizardId,
275
+ projectId: spaceId,
276
+ tenantId: currentTenant(),
277
+ // The link is made here: a token an install brought could be one another tenant holds.
278
+ shareToken: nanoid(14),
279
+ dailyRunLimit: env.limits.defaultDailyRuns,
280
+ ...settings,
281
+ });
282
+ }
283
+ // The workspace becomes what was sent: files that are gone there go here.
284
+ await replaceFiles(wizardId, files);
285
+ const row = await db.query.wizard.findFirst({ where: eq(schema.wizard.id, wizardId) });
286
+ if (!row) {
287
+ throw notFound();
288
+ }
289
+ const problems = await serverProblems(draft, await draftIssues(row), project.mcpServers.map((s) => s.id));
290
+ const runnable = !problems.some((p) => p.blocking);
291
+ let publishedVersion = row.publishedVersion;
292
+ if (runnable) {
293
+ await db
294
+ .insert(schema.wizardVersion)
295
+ .values({ id: nanoid(12), wizardId, version: input.version, definition: draft, files })
296
+ .onConflictDoUpdate({
297
+ target: [schema.wizardVersion.wizardId, schema.wizardVersion.version],
298
+ set: { definition: draft, files },
299
+ });
300
+ await db
301
+ .update(schema.wizard)
302
+ .set({ publishedVersion: input.version })
303
+ .where(eq(schema.wizard.id, wizardId));
304
+ publishedVersion = input.version;
305
+ }
306
+ // Last, since it reaches the object store: a store that fails takes everything back.
307
+ await syncLogo(spaceId, input.space.logo);
308
+ return { row, problems, runnable, publishedVersion };
309
+ });
310
+ const { row, problems, runnable, publishedVersion } = taken;
311
+ // The public link lives in the control database, outside the transaction: set on every
312
+ // sync, so one that failed to get there once is there after the next.
313
+ await putLink(row.shareToken, "wizard", wizardId);
314
+ emitDraftChanged({
315
+ wizardId,
316
+ kind: "draft",
317
+ revision: row.revision,
318
+ source: "mcp",
319
+ client: "sync",
320
+ note: null,
321
+ touched: [],
322
+ });
323
+ return {
324
+ wizardId,
325
+ shareUrl: shareUrl(row.shareToken),
326
+ code: await codeOf(row.shareToken),
327
+ shareEnabled: row.shareEnabled,
328
+ publishedVersion,
329
+ runnable,
330
+ problems,
331
+ };
332
+ });
333
+ }
334
+ async function syncedWizard(rawSpaceId, rawWizardId) {
335
+ const spaceId = syncedId.parse(rawSpaceId);
336
+ const wizardId = syncedId.parse(rawWizardId);
337
+ const project = await syncedProject(spaceId);
338
+ const w = project?.origin === "local"
339
+ ? await db.query.wizard.findFirst({
340
+ where: and(eq(schema.wizard.id, wizardId), eq(schema.wizard.projectId, spaceId)),
341
+ })
342
+ : null;
343
+ if (!w) {
344
+ throw notFound();
345
+ }
346
+ return w;
347
+ }
348
+ /** The install changed how a synced wizard is shared: its link on or off, its runs a day. */
349
+ export async function patchSyncedWizard(spaceId, wizardId, patch) {
350
+ const w = await syncedWizard(spaceId, wizardId);
351
+ await db
352
+ .update(schema.wizard)
353
+ .set({ ...patch, updatedAt: new Date() })
354
+ .where(eq(schema.wizard.id, w.id));
355
+ return { ok: true };
356
+ }
357
+ /** The install made a new link for a wizard: its copy here gets one too, the old one stops. */
358
+ export async function rotateSyncedLink(userId, spaceId, wizardId) {
359
+ const w = await syncedWizard(spaceId, wizardId);
360
+ const { shareToken } = await asSync(() => rotateShareLink(userId, w.id));
361
+ return { shareUrl: shareUrl(shareToken), code: await codeOf(shareToken) };
362
+ }
363
+ /** The install deleted a wizard: its copy here goes, with its link and its runs. */
364
+ export async function removeSyncedWizard(userId, spaceId, wizardId) {
365
+ const w = await syncedWizard(spaceId, wizardId);
366
+ await asSync(() => deleteWizard(userId, w.id));
367
+ return { ok: true };
368
+ }
369
+ /** The projects local installs synced, with their wizards: what an install compares itself to. */
370
+ export async function listSyncedSpaces() {
371
+ const projects = await db.query.project.findMany({
372
+ where: and(eq(schema.project.tenantId, currentTenant()), eq(schema.project.origin, "local")),
373
+ orderBy: [schema.project.createdAt],
374
+ });
375
+ const wizards = projects.length
376
+ ? await db
377
+ .select({
378
+ id: schema.wizard.id,
379
+ projectId: schema.wizard.projectId,
380
+ title: schema.wizard.title,
381
+ publishedVersion: schema.wizard.publishedVersion,
382
+ shareToken: schema.wizard.shareToken,
383
+ shareEnabled: schema.wizard.shareEnabled,
384
+ })
385
+ .from(schema.wizard)
386
+ .where(inArray(schema.wizard.projectId, projects.map((p) => p.id)))
387
+ : [];
388
+ return projects.map((p) => ({
389
+ id: p.id,
390
+ name: p.name,
391
+ syncedAt: p.syncedAt?.toISOString() ?? null,
392
+ wizards: wizards
393
+ .filter((w) => w.projectId === p.id)
394
+ .map((w) => ({
395
+ id: w.id,
396
+ title: w.title,
397
+ publishedVersion: w.publishedVersion,
398
+ shareUrl: shareUrl(w.shareToken),
399
+ shareEnabled: w.shareEnabled,
400
+ })),
401
+ }));
402
+ }
403
+ /** Takes a synced project away from this runtime: its wizards, their links and runs, its files. */
404
+ export async function removeSyncedSpace(rawSpaceId) {
405
+ const spaceId = syncedId.parse(rawSpaceId);
406
+ const project = await syncedProject(spaceId);
407
+ if (project?.origin !== "local") {
408
+ throw notFound();
409
+ }
410
+ await asSync(() => removeProject(spaceId));
411
+ return { ok: true };
412
+ }
413
+ // --- the space's own tables and pages --------------------------------------------
414
+ // What the admin made under Space → Data on the install, not what a wizard keeps: those stay
415
+ // where their runs write them. Sent as a whole, it replaces what came before.
416
+ // Since Knowledge: sub-pages, where an item came from, categories and what has them. An install of
417
+ // before sends none of it.
418
+ export const syncDataSchema = z.object({
419
+ tables: z
420
+ .array(z.object({
421
+ id: syncedId,
422
+ title: z.string().min(1).max(120),
423
+ format: z.enum(["faq"]).nullish(),
424
+ originLabel: z.string().max(120).nullish(),
425
+ columns: tableColumnsSchema,
426
+ rows: z
427
+ .array(z.object({ id: syncedId, cells: z.record(z.string(), z.unknown()) }))
428
+ .max(SPACE_DATA_LIMITS.rowsPerTable),
429
+ }))
430
+ .max(SPACE_DATA_LIMITS.tables),
431
+ pages: z
432
+ .array(z.object({
433
+ id: syncedId,
434
+ title: z.string().min(1).max(200),
435
+ markdown: z.string().max(SPACE_DATA_LIMITS.pageChars),
436
+ parentId: syncedId.nullish(),
437
+ position: z.number().int().min(0).optional(),
438
+ originLabel: z.string().max(120).nullish(),
439
+ }))
440
+ .max(SPACE_DATA_LIMITS.pages),
441
+ categories: z
442
+ .array(z.object({
443
+ id: syncedId,
444
+ name: z.string().min(1).max(80),
445
+ type: z.enum(CATEGORY_TYPES),
446
+ unit: z.string().max(20).nullish(),
447
+ multiple: z.boolean(),
448
+ ordered: z.boolean(),
449
+ hint: z.string().max(120).nullish(),
450
+ tableId: syncedId.nullish(),
451
+ columnId: z.string().max(64).nullish(),
452
+ position: z.number().int().min(0),
453
+ values: z
454
+ .array(z.object({
455
+ id: syncedId,
456
+ value: z.string().min(1).max(200),
457
+ position: z.number().int().min(0),
458
+ summary: z.string().max(20_000).nullish(),
459
+ }))
460
+ .max(2000),
461
+ }))
462
+ .max(60)
463
+ .optional(),
464
+ /** `p:<page>`, `t:<table>`, `r:<row>`: files stay with the install. */
465
+ assignments: z
466
+ .array(z.object({
467
+ categoryId: syncedId,
468
+ item: z.string().regex(/^[ptr]:[A-Za-z0-9_-]{8,40}$/),
469
+ valueId: syncedId.nullish(),
470
+ text: z.string().max(300).nullish(),
471
+ num: z.number().nullish(),
472
+ at: z.number().int().nullish(),
473
+ bool: z.boolean().nullish(),
474
+ by: z.enum(["person", "origin", "model"]),
475
+ }))
476
+ .max(200_000)
477
+ .optional(),
478
+ });
479
+ /**
480
+ * Takes the space's own tables and pages a local install sent: those it no longer has go, the
481
+ * others are written under the ids they have there. The space must be here already: it comes
482
+ * with the first wizard.
483
+ */
484
+ export async function syncSpaceData(rawSpaceId, input) {
485
+ const spaceId = syncedId.parse(rawSpaceId);
486
+ const project = await syncedProject(spaceId);
487
+ if (project?.origin !== "local") {
488
+ throw notFound();
489
+ }
490
+ const own = (table) => and(eq(table.projectId, spaceId), isNull(table.wizardId));
491
+ const tableIds = input.tables.map((t) => t.id);
492
+ const pageIds = input.pages.map((p) => p.id);
493
+ // An id this tenant uses for something else is not taken over.
494
+ const [tablesHere, pagesHere] = await Promise.all([
495
+ tableIds.length
496
+ ? db.query.spaceTable.findMany({
497
+ where: inArray(schema.spaceTable.id, tableIds),
498
+ columns: { id: true, projectId: true, wizardId: true },
499
+ })
500
+ : [],
501
+ pageIds.length
502
+ ? db.query.spacePage.findMany({
503
+ where: inArray(schema.spacePage.id, pageIds),
504
+ columns: { id: true, projectId: true, wizardId: true },
505
+ })
506
+ : [],
507
+ ]);
508
+ if ([...tablesHere, ...pagesHere].some((x) => x.projectId !== spaceId || x.wizardId !== null)) {
509
+ throw new ServiceError("refused", note("idAlreadyUse"), {
510
+ reason: "id_taken",
511
+ });
512
+ }
513
+ const now = new Date();
514
+ await inTransaction(async () => {
515
+ await db
516
+ .delete(schema.spaceTable)
517
+ .where(and(own(schema.spaceTable), tableIds.length ? notInArray(schema.spaceTable.id, tableIds) : undefined));
518
+ await db
519
+ .delete(schema.spacePage)
520
+ .where(and(own(schema.spacePage), pageIds.length ? notInArray(schema.spacePage.id, pageIds) : undefined));
521
+ for (const table of input.tables) {
522
+ const values = { title: table.title, columns: table.columns, updatedAt: now };
523
+ await db
524
+ .insert(schema.spaceTable)
525
+ .values({ id: table.id, tenantId: currentTenant(), projectId: spaceId, ...values })
526
+ .onConflictDoUpdate({ target: schema.spaceTable.id, set: values });
527
+ await db.delete(schema.spaceTableRow).where(eq(schema.spaceTableRow.tableId, table.id));
528
+ for (let i = 0; i < table.rows.length; i += 200) {
529
+ const batch = table.rows.slice(i, i + 200);
530
+ // The order they stand in there: one millisecond apart.
531
+ await db.insert(schema.spaceTableRow).values(batch.map((row, j) => ({
532
+ id: row.id,
533
+ tableId: table.id,
534
+ cells: row.cells,
535
+ createdAt: new Date(now.getTime() - table.rows.length + i + j),
536
+ })));
537
+ }
538
+ }
539
+ for (const page of input.pages) {
540
+ const values = {
541
+ title: page.title,
542
+ markdown: page.markdown,
543
+ position: page.position ?? 0,
544
+ originLabel: page.originLabel ?? null,
545
+ // Its place comes after every page is there.
546
+ parentId: null,
547
+ slug: null,
548
+ updatedAt: now,
549
+ };
550
+ await db
551
+ .insert(schema.spacePage)
552
+ .values({ id: page.id, tenantId: currentTenant(), projectId: spaceId, ...values })
553
+ .onConflictDoUpdate({ target: schema.spacePage.id, set: values });
554
+ }
555
+ const pagesThere = new Set(pageIds);
556
+ for (const page of input.pages) {
557
+ if (page.parentId && pagesThere.has(page.parentId) && page.parentId !== page.id) {
558
+ await db
559
+ .update(schema.spacePage)
560
+ .set({ parentId: page.parentId })
561
+ .where(eq(schema.spacePage.id, page.id));
562
+ }
563
+ }
564
+ for (const table of input.tables) {
565
+ await db
566
+ .update(schema.spaceTable)
567
+ .set({ format: table.format ?? null, originLabel: table.originLabel ?? null, slug: null })
568
+ .where(eq(schema.spaceTable.id, table.id));
569
+ }
570
+ if (input.categories) {
571
+ await syncCategories(spaceId, input.categories, input.assignments ?? []);
572
+ }
573
+ });
574
+ await reindexSpace(spaceId);
575
+ return { tables: input.tables.length, pages: input.pages.length };
576
+ }
577
+ /** The categories a local install sent, their values, and what has them: they replace these here. */
578
+ async function syncCategories(spaceId, categories, assignments) {
579
+ const ids = categories.map((c) => c.id);
580
+ const taken = ids.length
581
+ ? await db.query.spaceCategory.findMany({
582
+ where: inArray(schema.spaceCategory.id, ids),
583
+ columns: { id: true, projectId: true },
584
+ })
585
+ : [];
586
+ if (taken.some((c) => c.projectId !== spaceId)) {
587
+ throw new ServiceError("refused", note("idAlreadyUse"), {
588
+ reason: "id_taken",
589
+ });
590
+ }
591
+ await db
592
+ .delete(schema.spaceCategory)
593
+ .where(and(eq(schema.spaceCategory.projectId, spaceId), ids.length ? notInArray(schema.spaceCategory.id, ids) : undefined));
594
+ await db.delete(schema.spaceItemCategory).where(eq(schema.spaceItemCategory.projectId, spaceId));
595
+ const tables = new Set((await db.query.spaceTable.findMany({
596
+ where: eq(schema.spaceTable.projectId, spaceId),
597
+ columns: { id: true },
598
+ })).map((t) => t.id));
599
+ const values = new Set();
600
+ for (const c of categories) {
601
+ const row = {
602
+ name: c.name,
603
+ type: c.type,
604
+ unit: c.unit ?? null,
605
+ multiple: c.multiple,
606
+ ordered: c.ordered,
607
+ hint: c.hint ?? null,
608
+ proposed: false,
609
+ tableId: c.tableId && tables.has(c.tableId) ? c.tableId : null,
610
+ columnId: c.tableId && tables.has(c.tableId) ? (c.columnId ?? null) : null,
611
+ position: c.position,
612
+ updatedAt: new Date(),
613
+ };
614
+ await db
615
+ .insert(schema.spaceCategory)
616
+ .values({ id: c.id, tenantId: currentTenant(), projectId: spaceId, ...row })
617
+ .onConflictDoUpdate({ target: schema.spaceCategory.id, set: row });
618
+ const valueIds = c.values.map((v) => v.id);
619
+ await db
620
+ .delete(schema.spaceCategoryValue)
621
+ .where(and(eq(schema.spaceCategoryValue.categoryId, c.id), valueIds.length ? notInArray(schema.spaceCategoryValue.id, valueIds) : undefined));
622
+ for (const v of c.values) {
623
+ const set = {
624
+ value: v.value,
625
+ position: v.position,
626
+ summary: v.summary ?? null,
627
+ summaryAt: v.summary ? new Date() : null,
628
+ };
629
+ await db
630
+ .insert(schema.spaceCategoryValue)
631
+ .values({ id: v.id, categoryId: c.id, ...set })
632
+ .onConflictDoUpdate({ target: schema.spaceCategoryValue.id, set });
633
+ values.add(v.id);
634
+ }
635
+ }
636
+ const known = new Set(ids);
637
+ const rows = assignments.filter((a) => known.has(a.categoryId) && (!a.valueId || values.has(a.valueId)));
638
+ for (let i = 0; i < rows.length; i += 200) {
639
+ await db.insert(schema.spaceItemCategory).values(rows.slice(i, i + 200).map((a) => {
640
+ const id = a.item.slice(2);
641
+ return {
642
+ projectId: spaceId,
643
+ categoryId: a.categoryId,
644
+ pageId: a.item[0] === "p" ? id : null,
645
+ tableId: a.item[0] === "t" ? id : null,
646
+ rowId: a.item[0] === "r" ? id : null,
647
+ valueId: a.valueId ?? null,
648
+ text: a.text ?? null,
649
+ num: a.num ?? null,
650
+ at: a.at ?? null,
651
+ bool: a.bool ?? null,
652
+ by: a.by,
653
+ };
654
+ }));
655
+ }
656
+ }