@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,792 @@
1
+ import { TableColumnValueError, tableColumnsSchema, } from "@engenty-wizards/shared/engenty/data-tables";
2
+ import { note } from "@engenty-wizards/shared/run";
3
+ import { editCells, SPACE_DATA_LIMITS, } from "@engenty-wizards/shared/space-data";
4
+ import { rowKey } from "@engenty-wizards/shared/store";
5
+ import { and, asc, count, desc, eq, inArray, isNotNull, isNull, max } from "drizzle-orm";
6
+ import { nanoid } from "nanoid";
7
+ import { db, schema } from "../db/client.js";
8
+ import { saidOf } from "../model-errors.js";
9
+ import { currentTenant } from "../tenants/tenant.js";
10
+ import { serverText } from "../texts.js";
11
+ import { projectWritable, requireWritableProject } from "./access.js";
12
+ import { notFound, ServiceError } from "./errors.js";
13
+ import { filePaths, freeSlug, knowledgePage, pageTree, tablePaths } from "./knowledge.js";
14
+ import { queueIndex } from "./project-index.js";
15
+ import { ownedProject } from "./projects.js";
16
+ import { itemCategoriesOf, setItemCategories, syncTableRowCategories } from "./space-categories.js";
17
+ /** A wizard of the space, or null for the space's own. */
18
+ async function ownerOf(projectId, wizardId) {
19
+ if (!wizardId) {
20
+ return null;
21
+ }
22
+ const w = await db.query.wizard.findFirst({
23
+ where: and(eq(schema.wizard.id, wizardId), eq(schema.wizard.projectId, projectId)),
24
+ columns: { id: true },
25
+ });
26
+ if (!w) {
27
+ throw new ServiceError("invalid", note("wizardNotSpace"));
28
+ }
29
+ return w.id;
30
+ }
31
+ function cellError(err) {
32
+ if (err instanceof TableColumnValueError) {
33
+ throw new ServiceError("invalid", saidOf(err), { column: err.columnId });
34
+ }
35
+ throw err;
36
+ }
37
+ export function checkColumns(columns) {
38
+ const parsed = tableColumnsSchema.safeParse(columns);
39
+ if (!parsed.success) {
40
+ throw new ServiceError("invalid", parsed.error.issues[0]?.message ?? note("invalidColumns"));
41
+ }
42
+ return parsed.data;
43
+ }
44
+ /** Data: the tables and pages the space's wizards keep, and the wizards to name whose they are. */
45
+ export async function listSpaceData(userId, projectId) {
46
+ const project = await ownedProject(userId, projectId);
47
+ const [tables, rows, pages, wizards] = await Promise.all([
48
+ db.query.spaceTable.findMany({
49
+ where: and(eq(schema.spaceTable.projectId, project.id), isNotNull(schema.spaceTable.wizardId)),
50
+ orderBy: [asc(schema.spaceTable.title)],
51
+ columns: { id: true, wizardId: true, list: true, title: true, updatedAt: true },
52
+ }),
53
+ db
54
+ .select({ tableId: schema.spaceTableRow.tableId, n: count() })
55
+ .from(schema.spaceTableRow)
56
+ .innerJoin(schema.spaceTable, eq(schema.spaceTable.id, schema.spaceTableRow.tableId))
57
+ .where(eq(schema.spaceTable.projectId, project.id))
58
+ .groupBy(schema.spaceTableRow.tableId),
59
+ db.query.spacePage.findMany({
60
+ where: and(eq(schema.spacePage.projectId, project.id), isNotNull(schema.spacePage.wizardId)),
61
+ orderBy: [asc(schema.spacePage.title)],
62
+ columns: { id: true, wizardId: true, title: true, updatedAt: true },
63
+ }),
64
+ db.query.wizard.findMany({
65
+ where: eq(schema.wizard.projectId, project.id),
66
+ orderBy: [desc(schema.wizard.updatedAt)],
67
+ columns: { id: true, title: true },
68
+ }),
69
+ ]);
70
+ return {
71
+ tables: tables.map((t) => ({
72
+ ...t,
73
+ rows: rows.find((r) => r.tableId === t.id)?.n ?? 0,
74
+ updatedAt: t.updatedAt.toISOString(),
75
+ })),
76
+ pages: pages.map((p) => ({ ...p, updatedAt: p.updatedAt.toISOString() })),
77
+ wizards,
78
+ };
79
+ }
80
+ // --- tables --------------------------------------------------------------------
81
+ async function tableRow(tableId) {
82
+ const table = await db.query.spaceTable.findFirst({
83
+ where: and(eq(schema.spaceTable.id, tableId), eq(schema.spaceTable.tenantId, currentTenant())),
84
+ });
85
+ if (!table) {
86
+ throw notFound();
87
+ }
88
+ return table;
89
+ }
90
+ async function writableTable(tableId) {
91
+ const table = await tableRow(tableId);
92
+ await requireWritableProject(table.projectId);
93
+ return table;
94
+ }
95
+ /** A person changed a table: when a plugin wrote it, the plugin no longer does. */
96
+ async function touchTable(table) {
97
+ await db
98
+ .update(schema.spaceTable)
99
+ .set({ updatedAt: new Date(), ...(table.origin && !table.kept ? { kept: true } : {}) })
100
+ .where(eq(schema.spaceTable.id, table.id));
101
+ }
102
+ async function tableCount(projectId) {
103
+ const [{ n }] = await db
104
+ .select({ n: count() })
105
+ .from(schema.spaceTable)
106
+ .where(eq(schema.spaceTable.projectId, projectId));
107
+ if (n >= SPACE_DATA_LIMITS.tables) {
108
+ throw new ServiceError("refused", note("spaceMostTables", { count: SPACE_DATA_LIMITS.tables }));
109
+ }
110
+ }
111
+ export async function createTable(userId, projectId, input, lang = "en") {
112
+ const project = await ownedProject(userId, projectId);
113
+ await requireWritableProject(project.id);
114
+ await tableCount(project.id);
115
+ const columns = input.columns
116
+ ? checkColumns(input.columns)
117
+ : input.format === "faq"
118
+ ? [
119
+ { id: "question", name: serverText(lang, "faqQuestion"), type: "text" },
120
+ {
121
+ id: "answer",
122
+ name: serverText(lang, "faqAnswer"),
123
+ type: "text",
124
+ format: { style: "multiline" },
125
+ },
126
+ ]
127
+ : [{ id: "name", name: "Name", type: "text" }];
128
+ const id = nanoid(12);
129
+ const wizardId = await ownerOf(project.id, input.wizardId);
130
+ const title = input.title.trim() || serverText(lang, "tableTitle");
131
+ await db.insert(schema.spaceTable).values({
132
+ id,
133
+ tenantId: currentTenant(),
134
+ projectId: project.id,
135
+ wizardId,
136
+ title,
137
+ slug: wizardId ? null : await freeSlug(project.id, title, "table"),
138
+ format: input.format ?? null,
139
+ columns,
140
+ });
141
+ return { id };
142
+ }
143
+ async function tableKnowledge(table) {
144
+ if (table.wizardId) {
145
+ return null;
146
+ }
147
+ const file = table.fileId
148
+ ? await db.query.projectFile.findFirst({
149
+ where: eq(schema.projectFile.id, table.fileId),
150
+ columns: { id: true, name: true, mime: true },
151
+ })
152
+ : undefined;
153
+ return {
154
+ path: (await tablePaths(table.projectId)).get(table.id) ?? "",
155
+ categories: (await itemCategoriesOf([{ tableId: table.id }])).get(`t:${table.id}`) ?? [],
156
+ origin: table.origin,
157
+ originLabel: table.originLabel,
158
+ kept: table.kept,
159
+ review: table.review,
160
+ file: file ?? null,
161
+ };
162
+ }
163
+ export async function getTable(userId, tableId) {
164
+ const table = await tableRow(tableId);
165
+ const project = await ownedProject(userId, table.projectId);
166
+ const rows = await db.query.spaceTableRow.findMany({
167
+ where: eq(schema.spaceTableRow.tableId, table.id),
168
+ orderBy: [asc(schema.spaceTableRow.createdAt), asc(schema.spaceTableRow.id)],
169
+ });
170
+ return {
171
+ id: table.id,
172
+ projectId: table.projectId,
173
+ wizardId: table.wizardId,
174
+ list: table.list,
175
+ title: table.title,
176
+ format: table.format,
177
+ columns: table.columns,
178
+ rows: rows.map((r) => ({ id: r.id, cells: r.cells, updatedAt: r.updatedAt.toISOString() })),
179
+ readOnly: !(await projectWritable(project)),
180
+ knowledge: await tableKnowledge(table),
181
+ };
182
+ }
183
+ /**
184
+ * A new title, owner or columns. Rows keep their cells: a removed column's cells are dropped
185
+ * the next time the row changes, and are not shown before. `review: null`: a person looked.
186
+ */
187
+ export async function updateTable(_userId, tableId, patch) {
188
+ const table = await writableTable(tableId);
189
+ if (table.list && (patch.columns !== undefined || patch.wizardId !== undefined)) {
190
+ throw new ServiceError("refused", note("tableBelongsOneWizard"));
191
+ }
192
+ const title = patch.title !== undefined ? patch.title.trim() || table.title : table.title;
193
+ const wizardId = patch.wizardId !== undefined ? await ownerOf(table.projectId, patch.wizardId) : table.wizardId;
194
+ const changed = title !== table.title || patch.columns !== undefined || patch.format !== undefined;
195
+ await db
196
+ .update(schema.spaceTable)
197
+ .set({
198
+ title,
199
+ wizardId,
200
+ ...(title !== table.title || wizardId !== table.wizardId
201
+ ? { slug: wizardId ? null : await freeSlug(table.projectId, title, "table", table.id) }
202
+ : {}),
203
+ ...(patch.columns !== undefined ? { columns: checkColumns(patch.columns) } : {}),
204
+ ...(patch.format !== undefined ? { format: patch.format } : {}),
205
+ ...(patch.review === null ? { review: null } : {}),
206
+ ...(changed && table.origin ? { kept: true } : {}),
207
+ updatedAt: new Date(),
208
+ })
209
+ .where(eq(schema.spaceTable.id, table.id));
210
+ if (changed || wizardId !== table.wizardId) {
211
+ queueIndex(`t:${table.id}`);
212
+ }
213
+ }
214
+ /** The file an item was read from goes with it, when it was uploaded and nothing else uses it. */
215
+ async function dropOriginal(item) {
216
+ if (!item.fileId || item.originKey) {
217
+ return;
218
+ }
219
+ const used = (await db.query.spacePage.findFirst({
220
+ where: eq(schema.spacePage.fileId, item.fileId),
221
+ columns: { id: true },
222
+ })) ??
223
+ (await db.query.spaceTable.findFirst({
224
+ where: eq(schema.spaceTable.fileId, item.fileId),
225
+ columns: { id: true },
226
+ }));
227
+ if (!used) {
228
+ const { removeProjectFile } = await import("./project-files.js");
229
+ await removeProjectFile(item.projectId, item.fileId).catch(() => undefined);
230
+ }
231
+ }
232
+ export async function deleteTable(_userId, tableId) {
233
+ const table = await writableTable(tableId);
234
+ await db.delete(schema.spaceTable).where(eq(schema.spaceTable.id, table.id));
235
+ await dropOriginal(table);
236
+ }
237
+ /** The key a row of a shared list is matched on; tables made in the studio have none. */
238
+ function keyOf(table, cells) {
239
+ return table.keyColumn
240
+ ? rowKey({ id: table.list ?? "", title: table.title, columns: table.columns, key: table.keyColumn }, cells)
241
+ : null;
242
+ }
243
+ /** A row of a shared list whose key another row has already is refused: runs match on it. */
244
+ async function refuseClash(tableId, key, rowId) {
245
+ if (!key) {
246
+ return;
247
+ }
248
+ const other = await db.query.spaceTableRow.findFirst({
249
+ where: and(eq(schema.spaceTableRow.tableId, tableId), eq(schema.spaceTableRow.key, key)),
250
+ columns: { id: true },
251
+ });
252
+ if (other && other.id !== rowId) {
253
+ throw new ServiceError("invalid", note("entryAlreadyExists"));
254
+ }
255
+ }
256
+ /** After a row of a table of Knowledge changed: its categories from its columns, its unit. */
257
+ async function rowChanged(table, rowId) {
258
+ if (table.wizardId) {
259
+ return;
260
+ }
261
+ await syncTableRowCategories(table.id, [rowId]);
262
+ queueIndex(`r:${rowId}`);
263
+ }
264
+ /** Adds a row; `cells` may leave columns empty, even required ones, to be filled later. */
265
+ export async function addTableRow(_userId, tableId, cells = {}) {
266
+ const table = await writableTable(tableId);
267
+ const [{ n }] = await db
268
+ .select({ n: count() })
269
+ .from(schema.spaceTableRow)
270
+ .where(eq(schema.spaceTableRow.tableId, table.id));
271
+ if (n >= SPACE_DATA_LIMITS.rowsPerTable) {
272
+ throw new ServiceError("refused", note("tableMostRows", { count: SPACE_DATA_LIMITS.rowsPerTable }));
273
+ }
274
+ let value;
275
+ try {
276
+ value = editCells(table.columns, {}, cells);
277
+ }
278
+ catch (err) {
279
+ cellError(err);
280
+ }
281
+ const key = keyOf(table, value);
282
+ await refuseClash(table.id, key, null);
283
+ const row = { id: nanoid(14), tableId: table.id, key, cells: value, createdAt: new Date() };
284
+ await db.insert(schema.spaceTableRow).values(row);
285
+ await touchTable(table);
286
+ await rowChanged(table, row.id);
287
+ return { id: row.id, cells: value };
288
+ }
289
+ /** Changes the cells named in `cells`; the others stay. */
290
+ export async function updateTableRow(_userId, tableId, rowId, cells) {
291
+ const table = await writableTable(tableId);
292
+ const row = await db.query.spaceTableRow.findFirst({
293
+ where: and(eq(schema.spaceTableRow.id, rowId), eq(schema.spaceTableRow.tableId, table.id)),
294
+ });
295
+ if (!row) {
296
+ throw notFound();
297
+ }
298
+ let value;
299
+ try {
300
+ value = editCells(table.columns, row.cells, cells);
301
+ }
302
+ catch (err) {
303
+ cellError(err);
304
+ }
305
+ const key = keyOf(table, value);
306
+ await refuseClash(table.id, key, row.id);
307
+ await db
308
+ .update(schema.spaceTableRow)
309
+ .set({ cells: value, key, updatedAt: new Date() })
310
+ .where(eq(schema.spaceTableRow.id, row.id));
311
+ await touchTable(table);
312
+ await rowChanged(table, row.id);
313
+ return { id: row.id, cells: value };
314
+ }
315
+ export async function deleteTableRows(_userId, tableId, rowIds) {
316
+ const table = await writableTable(tableId);
317
+ if (!rowIds.length) {
318
+ return;
319
+ }
320
+ await db
321
+ .delete(schema.spaceTableRow)
322
+ .where(and(eq(schema.spaceTableRow.tableId, table.id), inArray(schema.spaceTableRow.id, rowIds)));
323
+ await touchTable(table);
324
+ }
325
+ // --- pages ---------------------------------------------------------------------
326
+ async function pageRow(pageId) {
327
+ const page = await db.query.spacePage.findFirst({
328
+ where: and(eq(schema.spacePage.id, pageId), eq(schema.spacePage.tenantId, currentTenant())),
329
+ });
330
+ if (!page) {
331
+ throw notFound();
332
+ }
333
+ return page;
334
+ }
335
+ function checkMarkdown(markdown) {
336
+ if (markdown.length > SPACE_DATA_LIMITS.pageChars) {
337
+ throw new ServiceError("refused", note("pageMostChars", { count: SPACE_DATA_LIMITS.pageChars }));
338
+ }
339
+ return markdown;
340
+ }
341
+ async function pageCount(projectId, more = 1) {
342
+ const [{ n }] = await db
343
+ .select({ n: count() })
344
+ .from(schema.spacePage)
345
+ .where(eq(schema.spacePage.projectId, projectId));
346
+ if (n + more > SPACE_DATA_LIMITS.pages) {
347
+ throw new ServiceError("refused", note("spaceMostPages", { count: SPACE_DATA_LIMITS.pages }));
348
+ }
349
+ }
350
+ /** A page of the space's own that a sub-page may stand under: never one of its own sub-pages. */
351
+ async function parentOf(projectId, parentId, pageId) {
352
+ if (!parentId) {
353
+ return null;
354
+ }
355
+ const parent = await db.query.spacePage.findFirst({
356
+ where: and(eq(schema.spacePage.id, parentId), eq(schema.spacePage.projectId, projectId)),
357
+ columns: { id: true, wizardId: true, parentId: true },
358
+ });
359
+ if (!parent || parent.wizardId) {
360
+ throw new ServiceError("invalid", note("pageNotSubpages"));
361
+ }
362
+ for (let at = parent.id; at && pageId;) {
363
+ if (at === pageId) {
364
+ throw new ServiceError("invalid", note("pageNotOwnSubpage"));
365
+ }
366
+ const up = await db.query.spacePage.findFirst({
367
+ where: eq(schema.spacePage.id, at),
368
+ columns: { parentId: true },
369
+ });
370
+ at = up?.parentId ?? null;
371
+ }
372
+ return parent.id;
373
+ }
374
+ async function nextPosition(projectId, parentId) {
375
+ const [{ last }] = await db
376
+ .select({ last: max(schema.spacePage.position) })
377
+ .from(schema.spacePage)
378
+ .where(and(eq(schema.spacePage.projectId, projectId), isNull(schema.spacePage.wizardId), parentId ? eq(schema.spacePage.parentId, parentId) : isNull(schema.spacePage.parentId)));
379
+ return (last ?? -1) + 1;
380
+ }
381
+ export async function createPage(userId, projectId, input) {
382
+ const project = await ownedProject(userId, projectId);
383
+ await requireWritableProject(project.id);
384
+ await pageCount(project.id);
385
+ const id = nanoid(12);
386
+ const wizardId = await ownerOf(project.id, input.wizardId);
387
+ const parentId = wizardId ? null : await parentOf(project.id, input.parentId);
388
+ const title = input.title.trim() || "Seite";
389
+ await db.insert(schema.spacePage).values({
390
+ id,
391
+ tenantId: currentTenant(),
392
+ projectId: project.id,
393
+ wizardId,
394
+ parentId,
395
+ position: wizardId ? 0 : await nextPosition(project.id, parentId),
396
+ title,
397
+ slug: wizardId ? null : await freeSlug(project.id, title, { parentId }),
398
+ markdown: checkMarkdown(input.markdown ?? ""),
399
+ });
400
+ if (!wizardId) {
401
+ queueIndex(`p:${id}`);
402
+ }
403
+ return { id };
404
+ }
405
+ export async function getPage(userId, pageId) {
406
+ const page = await pageRow(pageId);
407
+ const project = await ownedProject(userId, page.projectId);
408
+ return {
409
+ id: page.id,
410
+ projectId: page.projectId,
411
+ wizardId: page.wizardId,
412
+ title: page.title,
413
+ markdown: page.markdown,
414
+ updatedAt: page.updatedAt.toISOString(),
415
+ readOnly: !(await projectWritable(project)),
416
+ knowledge: page.wizardId ? null : await knowledgePage(page),
417
+ };
418
+ }
419
+ /**
420
+ * A new title, text, owner or place. A person who changes what a plugin wrote keeps the page:
421
+ * the plugin no longer writes it. `review: null`: a person looked at it.
422
+ */
423
+ export async function updatePage(_userId, pageId, patch) {
424
+ const page = await pageRow(pageId);
425
+ await requireWritableProject(page.projectId);
426
+ const title = patch.title !== undefined ? patch.title.trim() || page.title : page.title;
427
+ const wizardId = patch.wizardId !== undefined ? await ownerOf(page.projectId, patch.wizardId) : page.wizardId;
428
+ const parentId = wizardId !== null
429
+ ? null
430
+ : patch.parentId !== undefined
431
+ ? await parentOf(page.projectId, patch.parentId, page.id)
432
+ : page.parentId;
433
+ const moved = title !== page.title || wizardId !== page.wizardId || parentId !== page.parentId;
434
+ const edited = moved || (patch.markdown !== undefined && patch.markdown !== page.markdown);
435
+ await db
436
+ .update(schema.spacePage)
437
+ .set({
438
+ title,
439
+ wizardId,
440
+ parentId,
441
+ ...(moved
442
+ ? {
443
+ slug: wizardId ? null : await freeSlug(page.projectId, title, { parentId }, page.id),
444
+ ...(parentId !== page.parentId
445
+ ? { position: await nextPosition(page.projectId, parentId) }
446
+ : {}),
447
+ }
448
+ : {}),
449
+ ...(patch.markdown !== undefined ? { markdown: checkMarkdown(patch.markdown) } : {}),
450
+ ...(patch.review === null ? { review: null } : {}),
451
+ ...(edited && page.origin ? { kept: true } : {}),
452
+ updatedAt: new Date(),
453
+ })
454
+ .where(eq(schema.spacePage.id, page.id));
455
+ if (moved) {
456
+ queueIndex(`P:${page.id}`);
457
+ }
458
+ else if (edited) {
459
+ queueIndex(`p:${page.id}`);
460
+ }
461
+ }
462
+ export async function deletePage(_userId, pageId) {
463
+ const page = await pageRow(pageId);
464
+ await requireWritableProject(page.projectId);
465
+ await db.delete(schema.spacePage).where(eq(schema.spacePage.id, page.id));
466
+ await dropOriginal(page);
467
+ }
468
+ /** Puts a page's sub-pages into the order of `ids`. */
469
+ export async function orderSubPages(_userId, pageId, ids) {
470
+ const page = await pageRow(pageId);
471
+ await requireWritableProject(page.projectId);
472
+ for (const [position, id] of ids.entries()) {
473
+ await db
474
+ .update(schema.spacePage)
475
+ .set({ position })
476
+ .where(and(eq(schema.spacePage.id, id), eq(schema.spacePage.parentId, page.id)));
477
+ }
478
+ }
479
+ // --- what runs read and write --------------------------------------------------
480
+ // A run writes the pages of its own wizard, on the runtime it runs on: a run on the server writes
481
+ // the server's, also in a space a local install synced, which the studio there only shows. It
482
+ // reads its wizard's pages; the space's own are Knowledge, read by path.
483
+ /** The pages of a run's wizard. */
484
+ export async function runPages(projectId, wizardId) {
485
+ return db.query.spacePage.findMany({
486
+ where: and(eq(schema.spacePage.projectId, projectId), eq(schema.spacePage.wizardId, wizardId)),
487
+ columns: { id: true, wizardId: true, title: true, markdown: true, updatedAt: true },
488
+ orderBy: [asc(schema.spacePage.title)],
489
+ });
490
+ }
491
+ /** Writes a page of the run's wizard: a new one, or the one with this title, replaced or added to. */
492
+ export async function writeRunPage(projectId, wizardId, input) {
493
+ const title = input.title.trim();
494
+ if (!title) {
495
+ throw new ServiceError("invalid", note("pageNeedsTitle"));
496
+ }
497
+ const existing = (await db.query.spacePage.findMany({
498
+ where: and(eq(schema.spacePage.projectId, projectId), eq(schema.spacePage.wizardId, wizardId)),
499
+ })).find((p) => p.title.toLowerCase() === title.toLowerCase());
500
+ const markdown = existing && input.append
501
+ ? `${existing.markdown.trimEnd()}\n\n${input.markdown.trim()}`
502
+ : input.markdown;
503
+ checkMarkdown(markdown);
504
+ if (existing) {
505
+ await db
506
+ .update(schema.spacePage)
507
+ .set({ markdown, updatedAt: new Date() })
508
+ .where(eq(schema.spacePage.id, existing.id));
509
+ return { id: existing.id, title: existing.title, chars: markdown.length, made: false };
510
+ }
511
+ const [{ n }] = await db
512
+ .select({ n: count() })
513
+ .from(schema.spacePage)
514
+ .where(eq(schema.spacePage.projectId, projectId));
515
+ if (n >= SPACE_DATA_LIMITS.pages) {
516
+ throw new ServiceError("refused", note("spaceMostPages", { count: SPACE_DATA_LIMITS.pages }));
517
+ }
518
+ const id = nanoid(12);
519
+ await db.insert(schema.spacePage).values({
520
+ id,
521
+ tenantId: currentTenant(),
522
+ projectId,
523
+ wizardId,
524
+ title: title.slice(0, 200),
525
+ markdown,
526
+ });
527
+ return { id, title, chars: markdown.length, made: true };
528
+ }
529
+ async function originSpace(space) {
530
+ const project = await db.query.project.findFirst({
531
+ where: and(eq(schema.project.id, space), eq(schema.project.tenantId, currentTenant())),
532
+ columns: { id: true },
533
+ });
534
+ if (!project) {
535
+ throw new ServiceError("not_found", note("unknownSpace", { space }));
536
+ }
537
+ await requireWritableProject(project.id);
538
+ return project.id;
539
+ }
540
+ /** Keeps the original of what a plugin wrote: a document of the space under the same key. */
541
+ async function originalFile(origin, projectId, key, label, original, text) {
542
+ const { putOriginFile } = await import("./project-files.js");
543
+ return putOriginFile(origin, {
544
+ space: projectId,
545
+ key,
546
+ label,
547
+ name: original.name,
548
+ mime: original.mime,
549
+ data: original.data,
550
+ text,
551
+ });
552
+ }
553
+ export async function putOriginPage(origin, input) {
554
+ const projectId = await originSpace(input.space);
555
+ const key = input.key.trim().slice(0, 300);
556
+ const existing = await db.query.spacePage.findFirst({
557
+ where: and(eq(schema.spacePage.projectId, projectId), eq(schema.spacePage.origin, origin), eq(schema.spacePage.originKey, key)),
558
+ });
559
+ if (existing?.kept) {
560
+ return { id: existing.id, state: "kept" };
561
+ }
562
+ const parent = input.parent
563
+ ? await db.query.spacePage.findFirst({
564
+ where: and(eq(schema.spacePage.projectId, projectId), eq(schema.spacePage.origin, origin), eq(schema.spacePage.originKey, input.parent)),
565
+ columns: { id: true },
566
+ })
567
+ : null;
568
+ if (input.parent && !parent) {
569
+ throw new ServiceError("invalid", note("noParentPage", { parent: input.parent }));
570
+ }
571
+ const title = input.title.replace(/\s+/g, " ").trim().slice(0, 200) || "Seite";
572
+ const markdown = checkMarkdown(input.markdown);
573
+ const label = input.label?.trim().slice(0, 120) || null;
574
+ const parentId = parent?.id ?? null;
575
+ const fileId = input.original
576
+ ? await originalFile(origin, projectId, key, label, input.original, markdown)
577
+ : (existing?.fileId ?? null);
578
+ const position = input.position ?? existing?.position ?? (await nextPosition(projectId, parentId));
579
+ let id = existing?.id;
580
+ const moved = !existing || existing.title !== title || existing.parentId !== parentId;
581
+ if (existing) {
582
+ await db
583
+ .update(schema.spacePage)
584
+ .set({
585
+ title,
586
+ markdown,
587
+ parentId,
588
+ position,
589
+ originLabel: label,
590
+ fileId,
591
+ review: input.review ?? null,
592
+ ...(moved ? { slug: await freeSlug(projectId, title, { parentId }, existing.id) } : {}),
593
+ updatedAt: new Date(),
594
+ })
595
+ .where(eq(schema.spacePage.id, existing.id));
596
+ }
597
+ else {
598
+ await pageCount(projectId);
599
+ id = nanoid(12);
600
+ await db.insert(schema.spacePage).values({
601
+ id,
602
+ tenantId: currentTenant(),
603
+ projectId,
604
+ parentId,
605
+ position,
606
+ title,
607
+ slug: await freeSlug(projectId, title, { parentId }),
608
+ markdown,
609
+ origin,
610
+ originKey: key,
611
+ originLabel: label,
612
+ fileId,
613
+ review: input.review ?? null,
614
+ });
615
+ }
616
+ const set = input.categories
617
+ ? await setItemCategories(projectId, { pageId: id }, input.categories, "origin")
618
+ : { changed: false };
619
+ queueIndex(`${moved || set.changed ? "P" : "p"}:${id}`);
620
+ return { id: id, state: "written" };
621
+ }
622
+ export async function putOriginTable(origin, input) {
623
+ const projectId = await originSpace(input.space);
624
+ const key = input.key.trim().slice(0, 300);
625
+ const existing = await db.query.spaceTable.findFirst({
626
+ where: and(eq(schema.spaceTable.projectId, projectId), eq(schema.spaceTable.origin, origin), eq(schema.spaceTable.originKey, key)),
627
+ });
628
+ if (existing?.kept) {
629
+ return { id: existing.id, state: "kept" };
630
+ }
631
+ const columns = checkColumns(input.columns);
632
+ if (input.rows.length > SPACE_DATA_LIMITS.rowsPerTable) {
633
+ throw new ServiceError("refused", note("tableMostRows", { count: SPACE_DATA_LIMITS.rowsPerTable }));
634
+ }
635
+ let cells;
636
+ try {
637
+ cells = input.rows.map((row) => editCells(columns, {}, row));
638
+ }
639
+ catch (err) {
640
+ cellError(err);
641
+ }
642
+ const title = input.title.replace(/\s+/g, " ").trim().slice(0, 120) || "Tabelle";
643
+ const label = input.label?.trim().slice(0, 120) || null;
644
+ const csv = [
645
+ columns.map((c) => c.name).join(","),
646
+ ...cells.map((r) => columns.map((c) => String(r[c.id] ?? "")).join(",")),
647
+ ].join("\n");
648
+ const fileId = input.original
649
+ ? await originalFile(origin, projectId, key, label, input.original, csv)
650
+ : (existing?.fileId ?? null);
651
+ let id = existing?.id;
652
+ if (existing) {
653
+ await db
654
+ .update(schema.spaceTable)
655
+ .set({
656
+ title,
657
+ columns,
658
+ format: input.format ?? null,
659
+ originLabel: label,
660
+ fileId,
661
+ review: input.review ?? null,
662
+ ...(existing.title !== title
663
+ ? { slug: await freeSlug(projectId, title, "table", existing.id) }
664
+ : {}),
665
+ updatedAt: new Date(),
666
+ })
667
+ .where(eq(schema.spaceTable.id, existing.id));
668
+ await db.delete(schema.spaceTableRow).where(eq(schema.spaceTableRow.tableId, existing.id));
669
+ }
670
+ else {
671
+ await tableCount(projectId);
672
+ id = nanoid(12);
673
+ await db.insert(schema.spaceTable).values({
674
+ id,
675
+ tenantId: currentTenant(),
676
+ projectId,
677
+ title,
678
+ slug: await freeSlug(projectId, title, "table"),
679
+ format: input.format ?? null,
680
+ columns,
681
+ origin,
682
+ originKey: key,
683
+ originLabel: label,
684
+ fileId,
685
+ review: input.review ?? null,
686
+ });
687
+ }
688
+ const now = Date.now();
689
+ for (let i = 0; i < cells.length; i += 200) {
690
+ await db.insert(schema.spaceTableRow).values(cells.slice(i, i + 200).map((c, j) => ({
691
+ id: nanoid(14),
692
+ tableId: id,
693
+ cells: c,
694
+ // The order they came in: one millisecond apart.
695
+ createdAt: new Date(now - cells.length + i + j),
696
+ })));
697
+ }
698
+ if (input.categories) {
699
+ await setItemCategories(projectId, { tableId: id }, input.categories, "origin");
700
+ }
701
+ await syncTableRowCategories(id);
702
+ queueIndex(`t:${id}`);
703
+ return { id: id, state: "written" };
704
+ }
705
+ /** What a plugin wrote into a space, by its keys. */
706
+ export async function listOrigin(origin, space) {
707
+ const projectId = await originSpace(space);
708
+ const [pages, tables, files] = await Promise.all([
709
+ // What a document of the plugin was read into stands behind the document, not on its own.
710
+ db.query.spacePage.findMany({
711
+ where: and(eq(schema.spacePage.projectId, projectId), eq(schema.spacePage.origin, origin), isNotNull(schema.spacePage.originKey)),
712
+ columns: {
713
+ id: true,
714
+ originKey: true,
715
+ title: true,
716
+ kept: true,
717
+ review: true,
718
+ updatedAt: true,
719
+ },
720
+ }),
721
+ db.query.spaceTable.findMany({
722
+ where: and(eq(schema.spaceTable.projectId, projectId), eq(schema.spaceTable.origin, origin), isNotNull(schema.spaceTable.originKey)),
723
+ columns: {
724
+ id: true,
725
+ originKey: true,
726
+ title: true,
727
+ kept: true,
728
+ review: true,
729
+ updatedAt: true,
730
+ },
731
+ }),
732
+ db.query.projectFile.findMany({
733
+ where: and(eq(schema.projectFile.projectId, projectId), eq(schema.projectFile.origin, origin)),
734
+ columns: { id: true, originKey: true, name: true, updatedAt: true },
735
+ }),
736
+ ]);
737
+ const [tree, tPaths, fPaths] = await Promise.all([
738
+ pageTree(projectId),
739
+ tablePaths(projectId),
740
+ filePaths(projectId),
741
+ ]);
742
+ return [
743
+ ...pages.map((p) => ({
744
+ key: p.originKey,
745
+ kind: "page",
746
+ id: p.id,
747
+ title: p.title,
748
+ path: tree.get(p.id)?.path ?? "",
749
+ state: (p.kept ? "kept" : "written"),
750
+ review: p.review,
751
+ updatedAt: p.updatedAt.toISOString(),
752
+ })),
753
+ ...tables.map((t) => ({
754
+ key: t.originKey,
755
+ kind: "table",
756
+ id: t.id,
757
+ title: t.title,
758
+ path: tPaths.get(t.id) ?? "",
759
+ state: (t.kept ? "kept" : "written"),
760
+ review: t.review,
761
+ updatedAt: t.updatedAt.toISOString(),
762
+ })),
763
+ ...files.map((f) => ({
764
+ key: f.originKey,
765
+ kind: "file",
766
+ id: f.id,
767
+ title: f.name,
768
+ path: fPaths.get(f.id) ?? "",
769
+ state: "written",
770
+ review: null,
771
+ updatedAt: f.updatedAt.toISOString(),
772
+ })),
773
+ ];
774
+ }
775
+ /**
776
+ * Takes out what a plugin wrote under a key, or without a key everything it wrote into the
777
+ * space. What a person changed since stays. Returns how many items went.
778
+ */
779
+ export async function removeOrigin(origin, space, key) {
780
+ const projectId = await originSpace(space);
781
+ const pages = await db
782
+ .delete(schema.spacePage)
783
+ .where(and(eq(schema.spacePage.projectId, projectId), eq(schema.spacePage.origin, origin), eq(schema.spacePage.kept, false), key === undefined ? undefined : eq(schema.spacePage.originKey, key)))
784
+ .returning({ id: schema.spacePage.id });
785
+ const tables = await db
786
+ .delete(schema.spaceTable)
787
+ .where(and(eq(schema.spaceTable.projectId, projectId), eq(schema.spaceTable.origin, origin), eq(schema.spaceTable.kept, false), key === undefined ? undefined : eq(schema.spaceTable.originKey, key)))
788
+ .returning({ id: schema.spaceTable.id });
789
+ const { removeOriginFiles } = await import("./project-files.js");
790
+ const files = await removeOriginFiles(origin, projectId, key);
791
+ return pages.length + tables.length + files;
792
+ }