@engenty/wizards-runtime 0.0.0-stage → 0.7.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (523) hide show
  1. package/LICENSE +110 -0
  2. package/README.md +214 -2
  3. package/apps/runtime/dist/agents/architect.js +444 -0
  4. package/apps/runtime/dist/agents/studio-assistant.js +883 -0
  5. package/apps/runtime/dist/agents/subscription.js +207 -0
  6. package/apps/runtime/dist/agents/thought.js +21 -0
  7. package/apps/runtime/dist/agents/website.js +480 -0
  8. package/apps/runtime/dist/app.js +359 -0
  9. package/apps/runtime/dist/apple/wizards-apple +0 -0
  10. package/apps/runtime/dist/assistant/browser.js +26 -0
  11. package/apps/runtime/dist/assistant/docs.js +158 -0
  12. package/apps/runtime/dist/assistant/knows.js +353 -0
  13. package/apps/runtime/dist/assistant/primer.js +26 -0
  14. package/apps/runtime/dist/assistant/runs.js +24 -0
  15. package/apps/runtime/dist/auth/account.js +175 -0
  16. package/apps/runtime/dist/auth/device.js +112 -0
  17. package/apps/runtime/dist/auth/index.js +358 -0
  18. package/apps/runtime/dist/auth/keys.js +55 -0
  19. package/apps/runtime/dist/auth/local-ticket.js +26 -0
  20. package/apps/runtime/dist/authoring/example.js +74 -0
  21. package/apps/runtime/dist/authoring/guide.js +433 -0
  22. package/apps/runtime/dist/authoring/ops.js +117 -0
  23. package/apps/runtime/dist/browser/fast/action-space.js +160 -0
  24. package/apps/runtime/dist/browser/fast/classifier.js +91 -0
  25. package/apps/runtime/dist/browser/fast/decide.js +171 -0
  26. package/apps/runtime/dist/browser/fast/driver.js +141 -0
  27. package/apps/runtime/dist/browser/fast/instructions.js +33 -0
  28. package/apps/runtime/dist/browser/fast/run.js +249 -0
  29. package/apps/runtime/dist/browser/fast/span-picker.js +153 -0
  30. package/apps/runtime/dist/browser/fast/text-helper.js +178 -0
  31. package/apps/runtime/dist/browser/snapshot.js +335 -0
  32. package/apps/runtime/dist/cli/account.js +385 -0
  33. package/apps/runtime/dist/cli/autostart.js +182 -0
  34. package/apps/runtime/dist/cli/autoupdate.js +221 -0
  35. package/apps/runtime/dist/cli/clients.js +44 -0
  36. package/apps/runtime/dist/cli/connect.js +540 -0
  37. package/apps/runtime/dist/cli/environment.js +95 -0
  38. package/apps/runtime/dist/cli/exec.js +45 -0
  39. package/apps/runtime/dist/cli/features.js +50 -0
  40. package/apps/runtime/dist/cli/home.js +88 -0
  41. package/apps/runtime/dist/cli/install-env.js +33 -0
  42. package/apps/runtime/dist/cli/machine.js +107 -0
  43. package/apps/runtime/dist/cli/main.js +231 -0
  44. package/apps/runtime/dist/cli/mcp.js +136 -0
  45. package/apps/runtime/dist/cli/menu.js +202 -0
  46. package/apps/runtime/dist/cli/processes.js +72 -0
  47. package/apps/runtime/dist/cli/report.js +66 -0
  48. package/apps/runtime/dist/cli/sandbox.js +77 -0
  49. package/apps/runtime/dist/cli/setup.js +335 -0
  50. package/apps/runtime/dist/cli/start.js +276 -0
  51. package/apps/runtime/dist/cli/status.js +212 -0
  52. package/apps/runtime/dist/cli/ui.js +59 -0
  53. package/apps/runtime/dist/cli/uninstall-main.js +20 -0
  54. package/apps/runtime/dist/cli/uninstall.js +231 -0
  55. package/apps/runtime/dist/cli/update.js +86 -0
  56. package/apps/runtime/dist/cli/validate.js +75 -0
  57. package/apps/runtime/dist/cli/versions.js +123 -0
  58. package/apps/runtime/dist/connectors/builtin.js +86 -0
  59. package/apps/runtime/dist/connectors/external.js +409 -0
  60. package/apps/runtime/dist/connectors/gmail.js +107 -0
  61. package/apps/runtime/dist/connectors/imap.js +261 -0
  62. package/apps/runtime/dist/connectors/index.js +325 -0
  63. package/apps/runtime/dist/connectors/mail.js +72 -0
  64. package/apps/runtime/dist/connectors/outlook.js +90 -0
  65. package/apps/runtime/dist/connectors/plugin-connections.js +343 -0
  66. package/apps/runtime/dist/connectors/via-account.js +65 -0
  67. package/apps/runtime/dist/credits/credits.js +100 -0
  68. package/apps/runtime/dist/credits/estimate.js +152 -0
  69. package/apps/runtime/dist/db/adopt.js +149 -0
  70. package/apps/runtime/dist/db/client.js +173 -0
  71. package/apps/runtime/dist/db/control-schema.js +133 -0
  72. package/apps/runtime/dist/db/migrations/control/0000_last_absorbing_man.sql +47 -0
  73. package/apps/runtime/dist/db/migrations/control/0001_gorgeous_nicolaos.sql +41 -0
  74. package/apps/runtime/dist/db/migrations/control/0002_secret_penance.sql +1 -0
  75. package/apps/runtime/dist/db/migrations/control/0003_nasty_mordo.sql +3 -0
  76. package/apps/runtime/dist/db/migrations/control/0004_breezy_eddie_brock.sql +6 -0
  77. package/apps/runtime/dist/db/migrations/control/0005_chilly_oracle.sql +1 -0
  78. package/apps/runtime/dist/db/migrations/control/0006_sleepy_mojo.sql +1 -0
  79. package/apps/runtime/dist/db/migrations/control/0007_common_the_hand.sql +15 -0
  80. package/apps/runtime/dist/db/migrations/control/0008_runner.sql +8 -0
  81. package/apps/runtime/dist/db/migrations/control/0009_plugin_claim.sql +9 -0
  82. package/apps/runtime/dist/db/migrations/control/0010_tan_snowbird.sql +6 -0
  83. package/apps/runtime/dist/db/migrations/control/meta/0000_snapshot.json +311 -0
  84. package/apps/runtime/dist/db/migrations/control/meta/0001_snapshot.json +599 -0
  85. package/apps/runtime/dist/db/migrations/control/meta/0002_snapshot.json +607 -0
  86. package/apps/runtime/dist/db/migrations/control/meta/0003_snapshot.json +311 -0
  87. package/apps/runtime/dist/db/migrations/control/meta/0004_snapshot.json +350 -0
  88. package/apps/runtime/dist/db/migrations/control/meta/0005_snapshot.json +358 -0
  89. package/apps/runtime/dist/db/migrations/control/meta/0006_snapshot.json +365 -0
  90. package/apps/runtime/dist/db/migrations/control/meta/0007_snapshot.json +460 -0
  91. package/apps/runtime/dist/db/migrations/control/meta/0008_snapshot.json +505 -0
  92. package/apps/runtime/dist/db/migrations/control/meta/0009_snapshot.json +561 -0
  93. package/apps/runtime/dist/db/migrations/control/meta/0010_snapshot.json +600 -0
  94. package/apps/runtime/dist/db/migrations/control/meta/_journal.json +83 -0
  95. package/apps/runtime/dist/db/migrations/tenant/0000_eminent_freak.sql +188 -0
  96. package/apps/runtime/dist/db/migrations/tenant/0001_salty_master_chief.sql +1 -0
  97. package/apps/runtime/dist/db/migrations/tenant/0002_cloudy_firebird.sql +1 -0
  98. package/apps/runtime/dist/db/migrations/tenant/0003_brown_warbound.sql +52 -0
  99. package/apps/runtime/dist/db/migrations/tenant/0004_romantic_nocturne.sql +6 -0
  100. package/apps/runtime/dist/db/migrations/tenant/0005_reflective_forgotten_one.sql +2 -0
  101. package/apps/runtime/dist/db/migrations/tenant/0006_hard_war_machine.sql +30 -0
  102. package/apps/runtime/dist/db/migrations/tenant/0007_space_data.sql +43 -0
  103. package/apps/runtime/dist/db/migrations/tenant/0008_run_event_note.sql +1 -0
  104. package/apps/runtime/dist/db/migrations/tenant/0009_knowledge.sql +104 -0
  105. package/apps/runtime/dist/db/migrations/tenant/0010_plugin_connection.sql +15 -0
  106. package/apps/runtime/dist/db/migrations/tenant/0011_runners.sql +2 -0
  107. package/apps/runtime/dist/db/migrations/tenant/0012_assistant_chat.sql +40 -0
  108. package/apps/runtime/dist/db/migrations/tenant/0013_run_origin.sql +1 -0
  109. package/apps/runtime/dist/db/migrations/tenant/0014_run_answer.sql +2 -0
  110. package/apps/runtime/dist/db/migrations/tenant/0015_device_calls.sql +13 -0
  111. package/apps/runtime/dist/db/migrations/tenant/0016_even_trish_tilby.sql +12 -0
  112. package/apps/runtime/dist/db/migrations/tenant/meta/0000_snapshot.json +1323 -0
  113. package/apps/runtime/dist/db/migrations/tenant/meta/0001_snapshot.json +1330 -0
  114. package/apps/runtime/dist/db/migrations/tenant/meta/0002_snapshot.json +1337 -0
  115. package/apps/runtime/dist/db/migrations/tenant/meta/0003_snapshot.json +1605 -0
  116. package/apps/runtime/dist/db/migrations/tenant/meta/0004_snapshot.json +1645 -0
  117. package/apps/runtime/dist/db/migrations/tenant/meta/0005_snapshot.json +1659 -0
  118. package/apps/runtime/dist/db/migrations/tenant/meta/0006_snapshot.json +1696 -0
  119. package/apps/runtime/dist/db/migrations/tenant/meta/0007_snapshot.json +2012 -0
  120. package/apps/runtime/dist/db/migrations/tenant/meta/0008_snapshot.json +2019 -0
  121. package/apps/runtime/dist/db/migrations/tenant/meta/0009_snapshot.json +2837 -0
  122. package/apps/runtime/dist/db/migrations/tenant/meta/0010_snapshot.json +2942 -0
  123. package/apps/runtime/dist/db/migrations/tenant/meta/0011_snapshot.json +2956 -0
  124. package/apps/runtime/dist/db/migrations/tenant/meta/0012_snapshot.json +3132 -0
  125. package/apps/runtime/dist/db/migrations/tenant/meta/0013_snapshot.json +3139 -0
  126. package/apps/runtime/dist/db/migrations/tenant/meta/0014_snapshot.json +3154 -0
  127. package/apps/runtime/dist/db/migrations/tenant/meta/0015_snapshot.json +3243 -0
  128. package/apps/runtime/dist/db/migrations/tenant/meta/0016_snapshot.json +3326 -0
  129. package/apps/runtime/dist/db/migrations/tenant/meta/_journal.json +125 -0
  130. package/apps/runtime/dist/db/schema.js +602 -0
  131. package/apps/runtime/dist/debug.js +197 -0
  132. package/apps/runtime/dist/docs/dev/index.md +41 -0
  133. package/apps/runtime/dist/docs/dev/meta.json +7 -0
  134. package/apps/runtime/dist/docs/dev/plugins/connections.md +74 -0
  135. package/apps/runtime/dist/docs/dev/plugins/events.md +89 -0
  136. package/apps/runtime/dist/docs/dev/plugins/examples.md +101 -0
  137. package/apps/runtime/dist/docs/dev/plugins/index.md +78 -0
  138. package/apps/runtime/dist/docs/dev/plugins/layout.md +90 -0
  139. package/apps/runtime/dist/docs/dev/plugins/meta.json +28 -0
  140. package/apps/runtime/dist/docs/dev/plugins/quick-start.md +94 -0
  141. package/apps/runtime/dist/docs/dev/plugins/reference.md +348 -0
  142. package/apps/runtime/dist/docs/dev/plugins/reloading.md +76 -0
  143. package/apps/runtime/dist/docs/dev/plugins/routes.md +185 -0
  144. package/apps/runtime/dist/docs/dev/plugins/runners.md +230 -0
  145. package/apps/runtime/dist/docs/dev/plugins/server.md +281 -0
  146. package/apps/runtime/dist/docs/dev/plugins/shipping.md +79 -0
  147. package/apps/runtime/dist/docs/dev/plugins/space.md +297 -0
  148. package/apps/runtime/dist/docs/dev/plugins/starters.md +70 -0
  149. package/apps/runtime/dist/docs/dev/plugins/studio.md +363 -0
  150. package/apps/runtime/dist/docs/dev/plugins/styling.md +129 -0
  151. package/apps/runtime/dist/docs/dev/plugins/tables.md +104 -0
  152. package/apps/runtime/dist/docs/dev/plugins/tools.md +139 -0
  153. package/apps/runtime/dist/docs/dev/wizard-format.md +125 -0
  154. package/apps/runtime/dist/docs/meta.json +3 -0
  155. package/apps/runtime/dist/docs/user/ai-apps.md +112 -0
  156. package/apps/runtime/dist/docs/user/assistant.md +77 -0
  157. package/apps/runtime/dist/docs/user/build-a-wizard.md +116 -0
  158. package/apps/runtime/dist/docs/user/command-line.md +86 -0
  159. package/apps/runtime/dist/docs/user/connectors.md +90 -0
  160. package/apps/runtime/dist/docs/user/create-account.md +52 -0
  161. package/apps/runtime/dist/docs/user/data.md +66 -0
  162. package/apps/runtime/dist/docs/user/first-start.md +60 -0
  163. package/apps/runtime/dist/docs/user/index.md +49 -0
  164. package/apps/runtime/dist/docs/user/install.md +123 -0
  165. package/apps/runtime/dist/docs/user/local-only.md +42 -0
  166. package/apps/runtime/dist/docs/user/meta.json +32 -0
  167. package/apps/runtime/dist/docs/user/models.md +156 -0
  168. package/apps/runtime/dist/docs/user/plugins.md +71 -0
  169. package/apps/runtime/dist/docs/user/run.md +98 -0
  170. package/apps/runtime/dist/docs/user/server.md +52 -0
  171. package/apps/runtime/dist/docs/user/space.md +126 -0
  172. package/apps/runtime/dist/docs/user/steps.md +220 -0
  173. package/apps/runtime/dist/docs/user/test-and-share.md +224 -0
  174. package/apps/runtime/dist/docs/user/troubleshooting.md +67 -0
  175. package/apps/runtime/dist/docs/user/wordpress.md +121 -0
  176. package/apps/runtime/dist/documents/parse.js +246 -0
  177. package/apps/runtime/dist/engenty/connections-external/build-connector.js +193 -0
  178. package/apps/runtime/dist/engenty/connections-external/errors.js +11 -0
  179. package/apps/runtime/dist/engenty/connections-external/import-service.js +270 -0
  180. package/apps/runtime/dist/engenty/connections-external/importer/classify.js +34 -0
  181. package/apps/runtime/dist/engenty/connections-external/importer/map-auth.js +185 -0
  182. package/apps/runtime/dist/engenty/connections-external/importer/normalize-mcp.js +63 -0
  183. package/apps/runtime/dist/engenty/connections-external/importer/normalize-openapi.js +130 -0
  184. package/apps/runtime/dist/engenty/connections-external/invoke/http-invoker.js +143 -0
  185. package/apps/runtime/dist/engenty/connections-external/invoke/mcp-client.js +143 -0
  186. package/apps/runtime/dist/engenty/connections-external/net/guarded-fetch.js +119 -0
  187. package/apps/runtime/dist/engenty/connections-external/oauth-dcr.js +88 -0
  188. package/apps/runtime/dist/engenty/connections-external/registry-client.js +336 -0
  189. package/apps/runtime/dist/engenty/connections-external/registry-source.js +82 -0
  190. package/apps/runtime/dist/engenty/connections-external/types.js +7 -0
  191. package/apps/runtime/dist/engenty/connections-github/connector.js +209 -0
  192. package/apps/runtime/dist/engenty/connections-google/connectors/calendar.js +381 -0
  193. package/apps/runtime/dist/engenty/connections-google/connectors/contacts.js +94 -0
  194. package/apps/runtime/dist/engenty/connections-google/connectors/drive.js +290 -0
  195. package/apps/runtime/dist/engenty/connections-google/connectors/gmail.js +567 -0
  196. package/apps/runtime/dist/engenty/connections-google/definitions.js +11 -0
  197. package/apps/runtime/dist/engenty/connections-google/shared.js +73 -0
  198. package/apps/runtime/dist/engenty/connections-hubspot/connector.js +140 -0
  199. package/apps/runtime/dist/engenty/connections-microsoft/action.js +17 -0
  200. package/apps/runtime/dist/engenty/connections-microsoft/graph.js +114 -0
  201. package/apps/runtime/dist/engenty/connections-microsoft/onedrive.js +286 -0
  202. package/apps/runtime/dist/engenty/connections-microsoft/outlook.js +492 -0
  203. package/apps/runtime/dist/engenty/connections-s3/s3.js +328 -0
  204. package/apps/runtime/dist/engenty/connections-sdk/files-capability.js +86 -0
  205. package/apps/runtime/dist/engenty/connections-sdk/oauth2.js +150 -0
  206. package/apps/runtime/dist/engenty/connections-sdk/registry.js +89 -0
  207. package/apps/runtime/dist/engenty/connections-sdk/storage-capability.js +84 -0
  208. package/apps/runtime/dist/engenty/connections-sdk/types.js +30 -0
  209. package/apps/runtime/dist/engenty/connections-slack/connector.js +360 -0
  210. package/apps/runtime/dist/engenty/csv-import/csv-matrix.js +178 -0
  211. package/apps/runtime/dist/engenty/csv-import/import-sources.js +87 -0
  212. package/apps/runtime/dist/engenty/csv-import/parse-csv.js +129 -0
  213. package/apps/runtime/dist/engenty/csv-import/serialize-csv.js +20 -0
  214. package/apps/runtime/dist/engenty/csv-import/types.js +1 -0
  215. package/apps/runtime/dist/engenty/csv-import/xlsx-workbook.js +159 -0
  216. package/apps/runtime/dist/engenty/doc-converter/interface.js +9 -0
  217. package/apps/runtime/dist/engenty/doc-converter/page-break.js +92 -0
  218. package/apps/runtime/dist/engenty/doc-converter/providers/local/index.js +72 -0
  219. package/apps/runtime/dist/engenty/document-scanner/schemas/classifier.js +30 -0
  220. package/apps/runtime/dist/engenty/document-scanner/schemas/index.js +4 -0
  221. package/apps/runtime/dist/engenty/document-scanner/schemas/invoice.js +73 -0
  222. package/apps/runtime/dist/engenty/document-scanner/schemas/receipt.js +63 -0
  223. package/apps/runtime/dist/engenty/document-scanner/schemas/shared.js +40 -0
  224. package/apps/runtime/dist/engenty/search-index/chunks.js +164 -0
  225. package/apps/runtime/dist/engenty/search-index/contracts.js +9 -0
  226. package/apps/runtime/dist/engenty/shims/connections-sdk.js +39 -0
  227. package/apps/runtime/dist/engenty/shims/plugin-sdk.js +1 -0
  228. package/apps/runtime/dist/engenty/shims/web-ingest.js +19 -0
  229. package/apps/runtime/dist/engenty/web-ingest/ssrf.js +277 -0
  230. package/apps/runtime/dist/engine/asks.js +82 -0
  231. package/apps/runtime/dist/engine/decide.js +82 -0
  232. package/apps/runtime/dist/engine/device.js +194 -0
  233. package/apps/runtime/dist/engine/events.js +128 -0
  234. package/apps/runtime/dist/engine/input.js +208 -0
  235. package/apps/runtime/dist/engine/owner.js +32 -0
  236. package/apps/runtime/dist/engine/prepare.js +90 -0
  237. package/apps/runtime/dist/engine/push.js +58 -0
  238. package/apps/runtime/dist/engine/requirements.js +355 -0
  239. package/apps/runtime/dist/engine/resources.js +198 -0
  240. package/apps/runtime/dist/engine/runner.js +970 -0
  241. package/apps/runtime/dist/engine/steps.js +1000 -0
  242. package/apps/runtime/dist/engine/surface.js +91 -0
  243. package/apps/runtime/dist/engine/template.js +240 -0
  244. package/apps/runtime/dist/engine/types.js +4 -0
  245. package/apps/runtime/dist/env.js +279 -0
  246. package/apps/runtime/dist/features.js +123 -0
  247. package/apps/runtime/dist/files/blobs.js +22 -0
  248. package/apps/runtime/dist/files/objects.js +86 -0
  249. package/apps/runtime/dist/files/storage.js +120 -0
  250. package/apps/runtime/dist/files/web-images.js +101 -0
  251. package/apps/runtime/dist/film/project.js +257 -0
  252. package/apps/runtime/dist/film/skills.js +91 -0
  253. package/apps/runtime/dist/film/sounds.js +122 -0
  254. package/apps/runtime/dist/film/step.js +289 -0
  255. package/apps/runtime/dist/film/tools.js +99 -0
  256. package/apps/runtime/dist/geocode.js +58 -0
  257. package/apps/runtime/dist/harness/antigravity.js +129 -0
  258. package/apps/runtime/dist/harness/apple.js +270 -0
  259. package/apps/runtime/dist/harness/claude.js +147 -0
  260. package/apps/runtime/dist/harness/codex.js +229 -0
  261. package/apps/runtime/dist/harness/cursor.js +93 -0
  262. package/apps/runtime/dist/harness/env.js +124 -0
  263. package/apps/runtime/dist/harness/index.js +95 -0
  264. package/apps/runtime/dist/harness/model.js +279 -0
  265. package/apps/runtime/dist/harness/prompt.js +121 -0
  266. package/apps/runtime/dist/harness/terminal.js +194 -0
  267. package/apps/runtime/dist/harness/types.js +7 -0
  268. package/apps/runtime/dist/index.js +113 -0
  269. package/apps/runtime/dist/limits.js +81 -0
  270. package/apps/runtime/dist/link-preview.js +60 -0
  271. package/apps/runtime/dist/log.js +106 -0
  272. package/apps/runtime/dist/manage.js +249 -0
  273. package/apps/runtime/dist/mcp/auth.js +161 -0
  274. package/apps/runtime/dist/mcp/bridge.js +59 -0
  275. package/apps/runtime/dist/mcp/flow-app.js +97 -0
  276. package/apps/runtime/dist/mcp/handler.js +54 -0
  277. package/apps/runtime/dist/mcp/scopes.js +14 -0
  278. package/apps/runtime/dist/mcp/seen.js +65 -0
  279. package/apps/runtime/dist/mcp/tools.js +572 -0
  280. package/apps/runtime/dist/media/conversation.js +167 -0
  281. package/apps/runtime/dist/media/ffmpeg.js +121 -0
  282. package/apps/runtime/dist/media/generate.js +120 -0
  283. package/apps/runtime/dist/media/marking.js +121 -0
  284. package/apps/runtime/dist/media/transcribe.js +198 -0
  285. package/apps/runtime/dist/model-errors.js +42 -0
  286. package/apps/runtime/dist/models.js +1164 -0
  287. package/apps/runtime/dist/plugin.js +61 -0
  288. package/apps/runtime/dist/plugins/channels.js +78 -0
  289. package/apps/runtime/dist/plugins/claims.js +56 -0
  290. package/apps/runtime/dist/plugins/discovery.js +155 -0
  291. package/apps/runtime/dist/plugins/events.js +63 -0
  292. package/apps/runtime/dist/plugins/jobs.js +64 -0
  293. package/apps/runtime/dist/plugins/loader.js +508 -0
  294. package/apps/runtime/dist/plugins/migrations.js +69 -0
  295. package/apps/runtime/dist/plugins/pro-keys.js +34 -0
  296. package/apps/runtime/dist/plugins/pro-state.js +83 -0
  297. package/apps/runtime/dist/plugins/pro.js +310 -0
  298. package/apps/runtime/dist/plugins/public.js +44 -0
  299. package/apps/runtime/dist/plugins/registry.js +122 -0
  300. package/apps/runtime/dist/plugins/runs.js +210 -0
  301. package/apps/runtime/dist/render/browser-path.js +54 -0
  302. package/apps/runtime/dist/render/chromium.js +98 -0
  303. package/apps/runtime/dist/render/convert.js +158 -0
  304. package/apps/runtime/dist/render/downloads.js +299 -0
  305. package/apps/runtime/dist/render/guard.js +25 -0
  306. package/apps/runtime/dist/render/shaped.js +137 -0
  307. package/apps/runtime/dist/routes/api.js +440 -0
  308. package/apps/runtime/dist/routes/debug.js +42 -0
  309. package/apps/runtime/dist/routes/delivery.js +90 -0
  310. package/apps/runtime/dist/routes/internal.js +81 -0
  311. package/apps/runtime/dist/routes/lang.js +25 -0
  312. package/apps/runtime/dist/routes/marketplace.js +43 -0
  313. package/apps/runtime/dist/routes/plugin-public.js +113 -0
  314. package/apps/runtime/dist/routes/plugins.js +212 -0
  315. package/apps/runtime/dist/routes/runs.js +1422 -0
  316. package/apps/runtime/dist/routes/studio.js +1629 -0
  317. package/apps/runtime/dist/routes/wizard-stream.js +30 -0
  318. package/apps/runtime/dist/running.js +39 -0
  319. package/apps/runtime/dist/sandbox/agentos-package.js +73 -0
  320. package/apps/runtime/dist/sandbox/agentos.js +162 -0
  321. package/apps/runtime/dist/sandbox/docker.js +45 -0
  322. package/apps/runtime/dist/sandbox/index.js +52 -0
  323. package/apps/runtime/dist/sandbox/install.js +122 -0
  324. package/apps/runtime/dist/sandbox/mastra.js +71 -0
  325. package/apps/runtime/dist/sandbox/types.js +1 -0
  326. package/apps/runtime/dist/secrets/crypto.js +28 -0
  327. package/apps/runtime/dist/secrets/signing.js +52 -0
  328. package/apps/runtime/dist/secrets/vault.js +59 -0
  329. package/apps/runtime/dist/services/access.js +88 -0
  330. package/apps/runtime/dist/services/api.js +248 -0
  331. package/apps/runtime/dist/services/architect.js +95 -0
  332. package/apps/runtime/dist/services/assistant-chats.js +311 -0
  333. package/apps/runtime/dist/services/brand.js +85 -0
  334. package/apps/runtime/dist/services/cloud.js +456 -0
  335. package/apps/runtime/dist/services/draft-events.js +27 -0
  336. package/apps/runtime/dist/services/engenty-shapes.js +71 -0
  337. package/apps/runtime/dist/services/errors.js +29 -0
  338. package/apps/runtime/dist/services/files.js +178 -0
  339. package/apps/runtime/dist/services/knowledge-model.js +559 -0
  340. package/apps/runtime/dist/services/knowledge.js +721 -0
  341. package/apps/runtime/dist/services/links.js +16 -0
  342. package/apps/runtime/dist/services/marketplace.js +492 -0
  343. package/apps/runtime/dist/services/onboarding.js +152 -0
  344. package/apps/runtime/dist/services/package-file.js +82 -0
  345. package/apps/runtime/dist/services/package.js +170 -0
  346. package/apps/runtime/dist/services/profile.js +51 -0
  347. package/apps/runtime/dist/services/project-files.js +439 -0
  348. package/apps/runtime/dist/services/project-index.js +707 -0
  349. package/apps/runtime/dist/services/projects.js +387 -0
  350. package/apps/runtime/dist/services/relevance.js +58 -0
  351. package/apps/runtime/dist/services/runners.js +178 -0
  352. package/apps/runtime/dist/services/runs.js +524 -0
  353. package/apps/runtime/dist/services/shares.js +130 -0
  354. package/apps/runtime/dist/services/site.js +270 -0
  355. package/apps/runtime/dist/services/space-categories.js +861 -0
  356. package/apps/runtime/dist/services/space-data.js +792 -0
  357. package/apps/runtime/dist/services/space-origin.js +207 -0
  358. package/apps/runtime/dist/services/spaces.js +657 -0
  359. package/apps/runtime/dist/services/translations.js +306 -0
  360. package/apps/runtime/dist/services/widgets.js +34 -0
  361. package/apps/runtime/dist/services/wizard-icon.js +157 -0
  362. package/apps/runtime/dist/services/wizards.js +420 -0
  363. package/apps/runtime/dist/settings.js +16 -0
  364. package/apps/runtime/dist/store/errors.js +4 -0
  365. package/apps/runtime/dist/store/index.js +299 -0
  366. package/apps/runtime/dist/store/shared-lists.js +123 -0
  367. package/apps/runtime/dist/tenants/control.js +238 -0
  368. package/apps/runtime/dist/tenants/tenant.js +26 -0
  369. package/apps/runtime/dist/texts.js +207 -0
  370. package/apps/runtime/dist/tools/browser.js +703 -0
  371. package/apps/runtime/dist/tools/connector.js +204 -0
  372. package/apps/runtime/dist/tools/index.js +291 -0
  373. package/apps/runtime/dist/tools/mail.js +104 -0
  374. package/apps/runtime/dist/tools/net-guard.js +170 -0
  375. package/apps/runtime/dist/tools/pages.js +81 -0
  376. package/apps/runtime/dist/tools/plugin.js +180 -0
  377. package/apps/runtime/dist/tools/project.js +154 -0
  378. package/apps/runtime/dist/tools/shared.js +69 -0
  379. package/apps/runtime/dist/tools/store.js +238 -0
  380. package/apps/runtime/dist/update.js +113 -0
  381. package/apps/runtime/dist/widgets/bundle.js +99 -0
  382. package/apps/runtime/dist/widgets/render.js +329 -0
  383. package/apps/runtime/dist/widgets/runtime.js +108 -0
  384. package/apps/runtime/dist/widgets/script.js +30 -0
  385. package/apps/runtime/dist/widgets/step.js +223 -0
  386. package/apps/web/dist/ai-labels/ai-black.svg +20 -0
  387. package/apps/web/dist/ai-labels/ai-generated-black.svg +31 -0
  388. package/apps/web/dist/ai-labels/ai-generated-white.svg +32 -0
  389. package/apps/web/dist/ai-labels/ai-modified-black.svg +30 -0
  390. package/apps/web/dist/ai-labels/ai-modified-white.svg +31 -0
  391. package/apps/web/dist/ai-labels/ai-white.svg +21 -0
  392. package/apps/web/dist/assets/AboutDialog-DYgXPagX.js +1 -0
  393. package/apps/web/dist/assets/ChangelogDialog-BXqBW8j3.js +1 -0
  394. package/apps/web/dist/assets/ChatView-CK2--tsE.js +10 -0
  395. package/apps/web/dist/assets/EditorPage-jvcwyXbU.js +3 -0
  396. package/apps/web/dist/assets/FlowPreview-CusP7ci9.js +1 -0
  397. package/apps/web/dist/assets/Harness-BrP-ENHg.css +1 -0
  398. package/apps/web/dist/assets/Harness-CV9uYzbv.js +16 -0
  399. package/apps/web/dist/assets/NewWizardChannels-BakW5q6s.js +1 -0
  400. package/apps/web/dist/assets/NewWizardPage-BoA-LJuW.js +7 -0
  401. package/apps/web/dist/assets/OnboardingPage-DaD1XnOe.js +1 -0
  402. package/apps/web/dist/assets/ProjectPage-BFgk1DEv.js +1 -0
  403. package/apps/web/dist/assets/PublicRunner-C9MwEvxy.js +1 -0
  404. package/apps/web/dist/assets/ReadOnly-DC2Kp7l8.js +1 -0
  405. package/apps/web/dist/assets/RunDrawer-CY6NZSrI.js +4 -0
  406. package/apps/web/dist/assets/RunnerView-BT26XgcY.js +1 -0
  407. package/apps/web/dist/assets/SettingsPage-AFt9IDLt.js +1 -0
  408. package/apps/web/dist/assets/SetupPage-DtFYAbwJ.js +1 -0
  409. package/apps/web/dist/assets/SharePage-t2xwNS61.js +1 -0
  410. package/apps/web/dist/assets/changelog-CATQFxCQ.js +1 -0
  411. package/apps/web/dist/assets/engenty-eXZ-EAwd.js +1 -0
  412. package/apps/web/dist/assets/esm-DXeMu8Lb.js +7 -0
  413. package/apps/web/dist/assets/fluffy-engenty-ClRou7yu.js +456 -0
  414. package/apps/web/dist/assets/index-AfUa8xKD.css +1 -0
  415. package/apps/web/dist/assets/index-Drw7FMTQ.js +14 -0
  416. package/apps/web/dist/assets/jsx-runtime-BNakU3Ej.js +1 -0
  417. package/apps/web/dist/assets/lock-R_CfU0Xo.js +1 -0
  418. package/apps/web/dist/assets/oss-credits-cZ9NUaLZ.js +1 -0
  419. package/apps/web/dist/assets/pdfmake-Cx9scTbD.js +228 -0
  420. package/apps/web/dist/assets/phone-CgrIS4_-.js +1 -0
  421. package/apps/web/dist/assets/preload-helper-CNEI7N0N.js +1 -0
  422. package/apps/web/dist/assets/qr-scanner-worker.min-CJaXo3yu.js +98 -0
  423. package/apps/web/dist/assets/qr-scanner.min-C_UI0gH-.js +1 -0
  424. package/apps/web/dist/assets/rolldown-runtime-hePW80VL.js +1 -0
  425. package/apps/web/dist/assets/settings-menu-2IMOOlLl.js +1 -0
  426. package/apps/web/dist/assets/ui-dzGvc3xk.js +137 -0
  427. package/apps/web/dist/assets/upload-BSuTilFF.js +1 -0
  428. package/apps/web/dist/assets/vfs_fonts-DllDSYt1.js +1 -0
  429. package/apps/web/dist/embed.js +266 -0
  430. package/apps/web/dist/favicon.svg +1 -0
  431. package/apps/web/dist/icons/apple-touch-icon.png +0 -0
  432. package/apps/web/dist/icons/icon-192.png +0 -0
  433. package/apps/web/dist/icons/icon-512.png +0 -0
  434. package/apps/web/dist/icons/icon-maskable-512.png +0 -0
  435. package/apps/web/dist/index.html +48 -0
  436. package/apps/web/dist/install.sh +577 -0
  437. package/apps/web/dist/manifest.webmanifest +21 -0
  438. package/apps/web/dist/mcp/flow.html +980 -0
  439. package/apps/web/dist/sw.js +15 -0
  440. package/bin/wizards.mjs +288 -0
  441. package/modules/README.md +15 -0
  442. package/node_modules/@engenty/wizards/dist/plugin/index.d.ts +1150 -0
  443. package/node_modules/@engenty/wizards/dist/plugin/index.js +4 -0
  444. package/node_modules/@engenty/wizards/dist/plugin/studio.d.ts +322 -0
  445. package/node_modules/@engenty/wizards/dist/plugin/studio.js +4 -0
  446. package/node_modules/@engenty/wizards/dist/plugin/thread.d.ts +174 -0
  447. package/node_modules/@engenty/wizards/dist/plugin/thread.js +821 -0
  448. package/node_modules/@engenty/wizards/package.json +11 -0
  449. package/node_modules/@engenty-wizards/shared/dist/assistant.d.ts +174 -0
  450. package/node_modules/@engenty-wizards/shared/dist/assistant.js +65 -0
  451. package/node_modules/@engenty-wizards/shared/dist/changes.d.ts +22 -0
  452. package/node_modules/@engenty-wizards/shared/dist/changes.js +61 -0
  453. package/node_modules/@engenty-wizards/shared/dist/connectors.d.ts +77 -0
  454. package/node_modules/@engenty-wizards/shared/dist/connectors.js +2 -0
  455. package/node_modules/@engenty-wizards/shared/dist/decision.d.ts +76 -0
  456. package/node_modules/@engenty-wizards/shared/dist/decision.js +147 -0
  457. package/node_modules/@engenty-wizards/shared/dist/definition.d.ts +2922 -0
  458. package/node_modules/@engenty-wizards/shared/dist/definition.js +1920 -0
  459. package/node_modules/@engenty-wizards/shared/dist/engenty/data-tables/columns-format.d.ts +5 -0
  460. package/node_modules/@engenty-wizards/shared/dist/engenty/data-tables/columns-format.js +132 -0
  461. package/node_modules/@engenty-wizards/shared/dist/engenty/data-tables/columns-value.d.ts +11 -0
  462. package/node_modules/@engenty-wizards/shared/dist/engenty/data-tables/columns-value.js +209 -0
  463. package/node_modules/@engenty-wizards/shared/dist/engenty/data-tables/columns.d.ts +532 -0
  464. package/node_modules/@engenty-wizards/shared/dist/engenty/data-tables/columns.js +217 -0
  465. package/node_modules/@engenty-wizards/shared/dist/engenty/data-tables/index.d.ts +3 -0
  466. package/node_modules/@engenty-wizards/shared/dist/engenty/data-tables/index.js +3 -0
  467. package/node_modules/@engenty-wizards/shared/dist/engenty/search-index/catalog-lexical.d.ts +14 -0
  468. package/node_modules/@engenty-wizards/shared/dist/engenty/search-index/catalog-lexical.js +166 -0
  469. package/node_modules/@engenty-wizards/shared/dist/engenty/search-index/catalog-rank.d.ts +33 -0
  470. package/node_modules/@engenty-wizards/shared/dist/engenty/search-index/catalog-rank.js +99 -0
  471. package/node_modules/@engenty-wizards/shared/dist/feature-flags.d.ts +78 -0
  472. package/node_modules/@engenty-wizards/shared/dist/feature-flags.js +70 -0
  473. package/node_modules/@engenty-wizards/shared/dist/features.d.ts +41 -0
  474. package/node_modules/@engenty-wizards/shared/dist/features.js +89 -0
  475. package/node_modules/@engenty-wizards/shared/dist/fit.d.ts +71 -0
  476. package/node_modules/@engenty-wizards/shared/dist/fit.js +382 -0
  477. package/node_modules/@engenty-wizards/shared/dist/json-schema.d.ts +14 -0
  478. package/node_modules/@engenty-wizards/shared/dist/json-schema.js +66 -0
  479. package/node_modules/@engenty-wizards/shared/dist/knowledge.d.ts +199 -0
  480. package/node_modules/@engenty-wizards/shared/dist/knowledge.js +68 -0
  481. package/node_modules/@engenty-wizards/shared/dist/marketplace-entry.d.ts +35 -0
  482. package/node_modules/@engenty-wizards/shared/dist/marketplace-entry.js +107 -0
  483. package/node_modules/@engenty-wizards/shared/dist/marketplace-search.d.ts +20 -0
  484. package/node_modules/@engenty-wizards/shared/dist/marketplace-search.js +136 -0
  485. package/node_modules/@engenty-wizards/shared/dist/marketplace.d.ts +227 -0
  486. package/node_modules/@engenty-wizards/shared/dist/marketplace.js +354 -0
  487. package/node_modules/@engenty-wizards/shared/dist/merge.d.ts +7 -0
  488. package/node_modules/@engenty-wizards/shared/dist/merge.js +40 -0
  489. package/node_modules/@engenty-wizards/shared/dist/numbers.d.ts +24 -0
  490. package/node_modules/@engenty-wizards/shared/dist/numbers.js +54 -0
  491. package/node_modules/@engenty-wizards/shared/dist/projects.d.ts +224 -0
  492. package/node_modules/@engenty-wizards/shared/dist/projects.js +319 -0
  493. package/node_modules/@engenty-wizards/shared/dist/providers.d.ts +101 -0
  494. package/node_modules/@engenty-wizards/shared/dist/providers.js +390 -0
  495. package/node_modules/@engenty-wizards/shared/dist/run.d.ts +680 -0
  496. package/node_modules/@engenty-wizards/shared/dist/run.js +620 -0
  497. package/node_modules/@engenty-wizards/shared/dist/runner-texts.d.ts +546 -0
  498. package/node_modules/@engenty-wizards/shared/dist/runner-texts.js +523 -0
  499. package/node_modules/@engenty-wizards/shared/dist/runners.d.ts +93 -0
  500. package/node_modules/@engenty-wizards/shared/dist/runners.js +146 -0
  501. package/node_modules/@engenty-wizards/shared/dist/shape.d.ts +102 -0
  502. package/node_modules/@engenty-wizards/shared/dist/shape.js +318 -0
  503. package/node_modules/@engenty-wizards/shared/dist/space-data.d.ts +89 -0
  504. package/node_modules/@engenty-wizards/shared/dist/space-data.js +47 -0
  505. package/node_modules/@engenty-wizards/shared/dist/store.d.ts +117 -0
  506. package/node_modules/@engenty-wizards/shared/dist/store.js +81 -0
  507. package/node_modules/@engenty-wizards/shared/dist/surface.d.ts +115 -0
  508. package/node_modules/@engenty-wizards/shared/dist/surface.js +442 -0
  509. package/node_modules/@engenty-wizards/shared/dist/texts.d.ts +45 -0
  510. package/node_modules/@engenty-wizards/shared/dist/texts.js +54 -0
  511. package/node_modules/@engenty-wizards/shared/dist/translation.d.ts +23 -0
  512. package/node_modules/@engenty-wizards/shared/dist/translation.js +154 -0
  513. package/node_modules/@engenty-wizards/shared/dist/wizard-package.d.ts +48 -0
  514. package/node_modules/@engenty-wizards/shared/dist/wizard-package.js +49 -0
  515. package/node_modules/@engenty-wizards/shared/dist/workspace.d.ts +16 -0
  516. package/node_modules/@engenty-wizards/shared/dist/workspace.js +51 -0
  517. package/node_modules/@engenty-wizards/shared/package.json +10 -0
  518. package/package.json +77 -4
  519. package/plugin/.claude-plugin/plugin.json +9 -0
  520. package/plugin/.mcp.json +8 -0
  521. package/plugin/commands/wizard.md +8 -0
  522. package/plugin/skills/build-wizard/SKILL.md +27 -0
  523. package/plugin/skills/use-wizard/SKILL.md +18 -0
@@ -0,0 +1,707 @@
1
+ import { formatTableCell } from "@engenty-wizards/shared/engenty/data-tables";
2
+ import { embedMany } from "ai";
3
+ import { and, eq, inArray, isNotNull, isNull, sql } from "drizzle-orm";
4
+ import { db, schema, withTenant } from "../db/client.js";
5
+ import { createSearchChunks } from "../engenty/search-index/chunks.js";
6
+ import { getBlob, putBlob } from "../files/blobs.js";
7
+ import { embeddingModel } from "../models.js";
8
+ import { pluginIdsOf } from "../plugins/registry.js";
9
+ import { currentTenant } from "../tenants/tenant.js";
10
+ import { ServiceError } from "./errors.js";
11
+ import { filePaths, pageTree, tablePaths } from "./knowledge.js";
12
+ import { judgeRelevance, MIN_RELEVANCE } from "./relevance.js";
13
+ import { categoryLines, categoryRows, filterItems, itemCategoriesOf, } from "./space-categories.js";
14
+ const CHUNK = { mode: "paragraph", max_chunk_length: 1200, overlap: 120 };
15
+ /** Units of one item; a longer one keeps its start. */
16
+ const MAX_UNITS = 2000;
17
+ /** A section longer than this is cut at paragraphs into parts about PART_CHARS long. */
18
+ const SECTION_CHARS = 2400;
19
+ const PART_CHARS = 1800;
20
+ /** What the keywords and the vectors hand on to the classifier. */
21
+ const CANDIDATES = 24;
22
+ const vectorBytes = (v) => Buffer.from(new Float32Array(v).buffer);
23
+ async function embed(texts) {
24
+ const resolved = await embeddingModel();
25
+ if (!resolved || !texts.length) {
26
+ return null;
27
+ }
28
+ const result = await embedMany({ model: resolved.model, values: texts, maxParallelCalls: 4 });
29
+ return { vectors: result.embeddings.map((e) => Array.from(e)), model: resolved.ref };
30
+ }
31
+ export async function dropIndex(fileId) {
32
+ await db.delete(schema.projectChunk).where(eq(schema.projectChunk.fileId, fileId));
33
+ }
34
+ export async function documentText(file) {
35
+ return file.textHash ? (await getBlob(file.textHash)).toString("utf8") : "";
36
+ }
37
+ /** Keeps a document's text, for a step that reads the file itself. */
38
+ export async function keepText(text) {
39
+ return putBlob(Buffer.from(text, "utf8"));
40
+ }
41
+ /**
42
+ * Replaces the units `scope` held with `units`. A unit whose text has not changed keeps its
43
+ * vector: editing one row of a long table embeds one row.
44
+ */
45
+ async function writeUnits(scope, units) {
46
+ const before = await db
47
+ .select({
48
+ text: schema.projectChunk.text,
49
+ embedding: schema.projectChunk.embedding,
50
+ model: schema.projectChunk.model,
51
+ })
52
+ .from(schema.projectChunk)
53
+ .where(scope);
54
+ const resolved = await embeddingModel().catch(() => null);
55
+ const kept = new Map(before
56
+ .filter((b) => b.embedding && b.model && b.model === resolved?.ref)
57
+ .map((b) => [b.text, b.embedding]));
58
+ const missing = [...new Set(units.map((u) => u.text).filter((t) => !kept.has(t)))];
59
+ // Without an embedding model, or when it fails, the keywords still find the unit.
60
+ const embedded = await embed(missing).catch((err) => {
61
+ console.error("[project-index] embedding failed", err);
62
+ return null;
63
+ });
64
+ if (embedded) {
65
+ for (const [i, text] of missing.entries()) {
66
+ kept.set(text, vectorBytes(embedded.vectors[i]));
67
+ }
68
+ }
69
+ const model = embedded?.model ?? (kept.size ? (resolved?.ref ?? null) : null);
70
+ await db.delete(schema.projectChunk).where(scope);
71
+ for (let i = 0; i < units.length; i += 100) {
72
+ await db.insert(schema.projectChunk).values(units.slice(i, i + 100).map((u) => {
73
+ const vector = kept.get(u.text) ?? null;
74
+ return { ...u, embedding: vector, model: vector ? model : null };
75
+ }));
76
+ }
77
+ }
78
+ const SHEET = /^\s*<!--\s*S\.\s*(\d+)\s*-->\s*$/;
79
+ /** A page's Markdown cut at its headings; the page marks of its original say where each starts. */
80
+ export function sectionsOf(markdown) {
81
+ const out = [];
82
+ const stack = [];
83
+ let sheet = null;
84
+ let current = { heading: [], sheet: null, body: "", lines: [] };
85
+ let fence = false;
86
+ const close = () => {
87
+ const body = current.lines.join("\n").trim();
88
+ if (body) {
89
+ out.push({ heading: current.heading, sheet: current.sheet, body });
90
+ }
91
+ };
92
+ for (const line of markdown.split("\n")) {
93
+ if (/^\s*(```|~~~)/.test(line)) {
94
+ fence = !fence;
95
+ }
96
+ const mark = fence ? null : SHEET.exec(line);
97
+ if (mark) {
98
+ sheet = Number(mark[1]);
99
+ if (current.lines.join("").trim()) {
100
+ current.lines.push(`[S. ${sheet}]`);
101
+ }
102
+ else {
103
+ current.sheet = sheet;
104
+ }
105
+ continue;
106
+ }
107
+ const h = fence ? null : /^(#{1,4})\s+(.+?)\s*#*\s*$/.exec(line);
108
+ if (h) {
109
+ close();
110
+ const level = h[1].length;
111
+ while (stack.length && stack.at(-1).level >= level) {
112
+ stack.pop();
113
+ }
114
+ stack.push({ level, text: h[2].trim() });
115
+ current = { heading: stack.map((s) => s.text), sheet, body: "", lines: [] };
116
+ continue;
117
+ }
118
+ current.lines.push(line);
119
+ }
120
+ close();
121
+ return out;
122
+ }
123
+ /** A long section in parts at its paragraphs; a paragraph longer than a part at its sentences. */
124
+ function partsOf(body) {
125
+ if (body.length <= SECTION_CHARS) {
126
+ return [body];
127
+ }
128
+ const pieces = body
129
+ .split(/\n\s*\n/)
130
+ .flatMap((p) => p.length <= PART_CHARS ? [p] : (p.match(/[^.!?]+[.!?]+["»“)]?\s*|[^.!?]+$/g) ?? [p]));
131
+ const parts = [];
132
+ let now = "";
133
+ for (const piece of pieces) {
134
+ if (now && now.length + piece.length > PART_CHARS) {
135
+ parts.push(now.trim());
136
+ now = "";
137
+ }
138
+ now += (now ? "\n\n" : "") + piece;
139
+ }
140
+ if (now.trim()) {
141
+ parts.push(now.trim());
142
+ }
143
+ return parts;
144
+ }
145
+ const head = (titles, lines) => [titles.join(" › "), lines.length ? lines.join(" · ") : ""].filter(Boolean).join("\n");
146
+ async function indexPage(pageId) {
147
+ const scope = eq(schema.projectChunk.pageId, pageId);
148
+ const page = await db.query.spacePage.findFirst({ where: eq(schema.spacePage.id, pageId) });
149
+ if (!page || page.wizardId) {
150
+ await db.delete(schema.projectChunk).where(scope);
151
+ return;
152
+ }
153
+ const [tree, categories] = await Promise.all([
154
+ pageTree(page.projectId),
155
+ categoryRows(page.projectId),
156
+ ]);
157
+ const node = tree.get(page.id);
158
+ const lines = categoryLines(categories, (await itemCategoriesOf([{ pageId: page.id }])).get(`p:${page.id}`));
159
+ const prefix = head(node?.titles ?? [page.title], lines);
160
+ const sections = sectionsOf(page.markdown);
161
+ const units = [];
162
+ // A page without text is still found by its title and categories.
163
+ for (const section of sections.length ? sections : [{ heading: [], sheet: null, body: "" }]) {
164
+ // A page's own first heading is its title: the path says it already.
165
+ const path = section.heading[0]?.toLowerCase() === page.title.toLowerCase()
166
+ ? section.heading.slice(1)
167
+ : section.heading;
168
+ const heading = path.join(" › ") || null;
169
+ for (const part of partsOf(section.body)) {
170
+ units.push({
171
+ projectId: page.projectId,
172
+ pageId: page.id,
173
+ heading,
174
+ sheet: section.sheet,
175
+ idx: units.length,
176
+ text: [prefix, heading ? `## ${heading}` : "", part].filter(Boolean).join("\n\n"),
177
+ });
178
+ }
179
+ }
180
+ await writeUnits(scope, units.slice(0, MAX_UNITS));
181
+ }
182
+ async function indexRows(tableId, rowIds) {
183
+ const table = await db.query.spaceTable.findFirst({ where: eq(schema.spaceTable.id, tableId) });
184
+ const scope = rowIds
185
+ ? inArray(schema.projectChunk.rowId, rowIds)
186
+ : eq(schema.projectChunk.tableId, tableId);
187
+ if (!table || table.wizardId) {
188
+ await db.delete(schema.projectChunk).where(scope);
189
+ return;
190
+ }
191
+ const rows = await db.query.spaceTableRow.findMany({
192
+ where: rowIds
193
+ ? and(eq(schema.spaceTableRow.tableId, table.id), inArray(schema.spaceTableRow.id, rowIds))
194
+ : eq(schema.spaceTableRow.tableId, table.id),
195
+ });
196
+ const categories = await categoryRows(table.projectId);
197
+ const cats = await itemCategoriesOf([
198
+ { tableId: table.id },
199
+ ...rows.map((r) => ({ rowId: r.id })),
200
+ ]);
201
+ const tableLines = categoryLines(categories, cats.get(`t:${table.id}`));
202
+ const units = rows.map((row, i) => {
203
+ const own = categoryLines(categories, cats.get(`r:${row.id}`)).filter((l) => !tableLines.includes(l));
204
+ const cells = table.columns
205
+ .map((c) => [c.name, formatTableCell(c, row.cells[c.id], "de")])
206
+ .filter(([, v]) => v);
207
+ const body = table.format === "faq" && cells.length >= 2
208
+ ? `${cells[0][1]}\n\n${cells
209
+ .slice(1)
210
+ .map(([, v]) => v)
211
+ .join("\n\n")}`
212
+ : cells.map(([name, v]) => `${name}: ${v}`).join("\n");
213
+ return {
214
+ projectId: table.projectId,
215
+ tableId: table.id,
216
+ rowId: row.id,
217
+ heading: table.format === "faq" ? (cells[0]?.[1] ?? null) : null,
218
+ idx: i,
219
+ text: `${head([table.title], [...tableLines, ...own])}\n\n${body}`,
220
+ };
221
+ });
222
+ await writeUnits(scope, units);
223
+ }
224
+ async function indexFile(fileId) {
225
+ const file = await db.query.projectFile.findFirst({ where: eq(schema.projectFile.id, fileId) });
226
+ if (file?.kind !== "document" || file.status !== "ready") {
227
+ return;
228
+ }
229
+ const converted = (await db.query.spacePage.findFirst({
230
+ where: eq(schema.spacePage.fileId, file.id),
231
+ columns: { id: true },
232
+ })) ??
233
+ (await db.query.spaceTable.findFirst({
234
+ where: eq(schema.spaceTable.fileId, file.id),
235
+ columns: { id: true },
236
+ }));
237
+ const scope = eq(schema.projectChunk.fileId, file.id);
238
+ if (converted) {
239
+ // Its text is the page's now; the file stands behind it as the original.
240
+ await db.delete(schema.projectChunk).where(scope);
241
+ return;
242
+ }
243
+ const passages = await db
244
+ .select({ heading: schema.projectChunk.heading, idx: schema.projectChunk.idx })
245
+ .from(schema.projectChunk)
246
+ .where(scope);
247
+ // Passages of a document read before Knowledge had pages stay until it is read again.
248
+ if (passages.some((p) => p.heading === null)) {
249
+ return;
250
+ }
251
+ const categories = await categoryRows(file.projectId);
252
+ const lines = categoryLines(categories, (await itemCategoriesOf([{ fileId: file.id }])).get(`f:${file.id}`));
253
+ await writeUnits(scope, [
254
+ {
255
+ projectId: file.projectId,
256
+ fileId: file.id,
257
+ heading: file.name,
258
+ idx: 0,
259
+ text: [head([file.name], lines), file.description].filter(Boolean).join("\n\n"),
260
+ },
261
+ ]);
262
+ }
263
+ async function indexValue(valueId) {
264
+ const scope = eq(schema.projectChunk.valueId, valueId);
265
+ const value = await db.query.spaceCategoryValue.findFirst({
266
+ where: eq(schema.spaceCategoryValue.id, valueId),
267
+ });
268
+ const category = value
269
+ ? await db.query.spaceCategory.findFirst({
270
+ where: eq(schema.spaceCategory.id, value.categoryId),
271
+ })
272
+ : undefined;
273
+ if (!(value?.summary && category)) {
274
+ await db.delete(schema.projectChunk).where(scope);
275
+ return;
276
+ }
277
+ const units = partsOf(value.summary).map((part, i) => ({
278
+ projectId: category.projectId,
279
+ valueId: value.id,
280
+ heading: `${category.name}: ${value.value}`,
281
+ idx: i,
282
+ text: `${category.name}: ${value.value} — Summary\n\n${part}`,
283
+ }));
284
+ await writeUnits(scope, units);
285
+ }
286
+ /** Every page under a page. */
287
+ async function subPages(pageId) {
288
+ const rows = await db.all(sql `
289
+ WITH RECURSIVE tree(id) AS (
290
+ SELECT id FROM space_page WHERE parent_id = ${pageId}
291
+ UNION SELECT p.id FROM space_page p JOIN tree ON p.parent_id = tree.id
292
+ ) SELECT id FROM tree`);
293
+ return rows.map((r) => r.id);
294
+ }
295
+ /**
296
+ * Brings one item's units up to date. `p:` a page, `P:` a page and its sub-pages (its title or
297
+ * categories changed: they stand in theirs), `t:` a table's rows, `r:` one row, `f:` a file, `v:`
298
+ * a value's summary.
299
+ */
300
+ export async function indexItem(key) {
301
+ const id = key.slice(2);
302
+ switch (key[0]) {
303
+ case "p":
304
+ return indexPage(id);
305
+ case "P":
306
+ await indexPage(id);
307
+ for (const sub of await subPages(id)) {
308
+ await indexPage(sub);
309
+ }
310
+ return;
311
+ case "t":
312
+ return indexRows(id);
313
+ case "r": {
314
+ const row = await db.query.spaceTableRow.findFirst({
315
+ where: eq(schema.spaceTableRow.id, id),
316
+ columns: { tableId: true },
317
+ });
318
+ return row ? indexRows(row.tableId, [id]) : undefined;
319
+ }
320
+ case "f":
321
+ return indexFile(id);
322
+ case "v":
323
+ return indexValue(id);
324
+ default:
325
+ return;
326
+ }
327
+ }
328
+ // --- the queue ------------------------------------------------------------------------
329
+ // A page saves a moment after the person stops typing; the index follows a moment later, once
330
+ // per item however often it changed, one item after the other.
331
+ const INDEX_DELAY_MS = 1500;
332
+ const waiting = new Map();
333
+ let working = Promise.resolve();
334
+ function run(tenant, key) {
335
+ working = working
336
+ .then(() => withTenant(tenant, () => indexItem(key)))
337
+ .catch((err) => console.error(`[project-index] ${key}`, err));
338
+ }
339
+ /** Indexes an item a moment from now; a change before then waits again. */
340
+ export function queueIndex(key) {
341
+ const tenant = currentTenant();
342
+ const id = `${tenant}|${key}`;
343
+ const known = waiting.get(id);
344
+ if (known) {
345
+ clearTimeout(known.timer);
346
+ }
347
+ const timer = setTimeout(() => {
348
+ waiting.delete(id);
349
+ run(tenant, key);
350
+ }, INDEX_DELAY_MS);
351
+ timer.unref?.();
352
+ waiting.set(id, { tenant, key, timer });
353
+ }
354
+ /** Indexes what waits now, and resolves when the index has caught up. */
355
+ export async function flushIndex() {
356
+ while (waiting.size) {
357
+ for (const [id, entry] of [...waiting]) {
358
+ clearTimeout(entry.timer);
359
+ waiting.delete(id);
360
+ run(entry.tenant, entry.key);
361
+ }
362
+ await working;
363
+ }
364
+ await working;
365
+ }
366
+ // --- plugins' texts ---------------------------------------------------------------------
367
+ /** Puts a plugin's text into the space's index, in the place of what its key held. */
368
+ export async function putIndexEntry(plugin, entry) {
369
+ const space = await db.query.project.findFirst({ where: eq(schema.project.id, entry.space) });
370
+ if (!space) {
371
+ throw new ServiceError("not_found", `There is no space "${entry.space}".`);
372
+ }
373
+ const text = `${entry.title.trim()}\n\n${entry.text.trim()}`;
374
+ const chunks = createSearchChunks({ doc_id: `${plugin}:${entry.key}`, text, ...CHUNK }).slice(0, MAX_UNITS);
375
+ await writeUnits(and(eq(schema.projectChunk.projectId, entry.space), eq(schema.projectChunk.plugin, plugin), eq(schema.projectChunk.ref, entry.key)), chunks.map((c) => ({
376
+ projectId: entry.space,
377
+ plugin,
378
+ ref: entry.key,
379
+ title: entry.title.trim().slice(0, 300),
380
+ link: entry.link ?? null,
381
+ idx: c.chunk_index,
382
+ text: c.text,
383
+ })));
384
+ }
385
+ /** Takes a plugin's text out of the space's index; without a key, all of the plugin's texts. */
386
+ export async function removeIndexEntries(plugin, space, key) {
387
+ await db
388
+ .delete(schema.projectChunk)
389
+ .where(and(eq(schema.projectChunk.projectId, space), eq(schema.projectChunk.plugin, plugin), key === undefined ? undefined : eq(schema.projectChunk.ref, key)));
390
+ }
391
+ /** Whether a plugin the tenant has put a text into the space's index. */
392
+ export async function hasIndexEntries(projectId) {
393
+ const plugins = [...(await pluginIdsOf(currentTenant()))];
394
+ if (!plugins.length) {
395
+ return false;
396
+ }
397
+ const found = await db.query.projectChunk.findFirst({
398
+ columns: { id: true },
399
+ where: and(eq(schema.projectChunk.projectId, projectId), inArray(schema.projectChunk.plugin, plugins)),
400
+ });
401
+ return Boolean(found);
402
+ }
403
+ // --- search -------------------------------------------------------------------------------
404
+ const STOP = new Set("der die das den dem des ein eine einen einem einer und oder aber ist sind war wie was wer wo für von mit auf aus bei zu zum zur im in an am es ich du wir ihr sie nicht auch gibt gibt's welche welcher welches the a an of to and or is are was for with on at by it this that what which".split(" "));
405
+ const wordsOf = (query) => [...new Set(query.toLowerCase().match(/[\p{L}\p{N}]{2,}/gu) ?? [])]
406
+ .filter((w) => !STOP.has(w))
407
+ .slice(0, 16);
408
+ /** The question's words as an FTS5 query: any of them, also as the start of a longer word. */
409
+ function keywordQuery(query) {
410
+ const words = wordsOf(query);
411
+ return words.length ? words.map((w) => `"${w}"*`).join(" OR ") : null;
412
+ }
413
+ /**
414
+ * The question as a trigram query: each word of three letters or more anywhere in a unit, so
415
+ * "Förderhöhe" finds "Höchstförderhöhe"; a code with digits also as it was written ("WIN 6").
416
+ */
417
+ export function trigramQuery(query) {
418
+ const words = wordsOf(query).filter((w) => w.length >= 3);
419
+ const codes = (query.match(/[\p{L}\p{N}][\p{L}\p{N}\-./ ]*\d[\p{L}\p{N}\-./]*/gu) ?? [])
420
+ .map((c) => c.trim())
421
+ .filter((c) => c.length >= 3 && c.includes(" "));
422
+ const terms = [...new Set([...codes, ...words])].map((t) => `"${t.replace(/"/g, "")}"`);
423
+ return terms.length ? terms.join(" OR ") : null;
424
+ }
425
+ const COLUMNS = sql.raw("c.id, c.file_id, c.page_id, c.row_id, c.table_id, c.value_id, c.heading, c.sheet, c.plugin, c.ref, c.title, c.link, c.idx, c.text");
426
+ /** A unit of the space's own Knowledge, or of a plugin's text while the tenant has that plugin. */
427
+ function searchable(plugins) {
428
+ return plugins.length
429
+ ? sql `(c.plugin IS NULL OR c.plugin IN (${sql.join(plugins.map((p) => sql `${p}`), sql `, `)}))`
430
+ : sql `c.plugin IS NULL`;
431
+ }
432
+ const IN_LIMIT = 2000;
433
+ /** The units a filter leaves, as SQL while the lists are short; else null and checked after. */
434
+ function filtered(f) {
435
+ const lists = [
436
+ ["c.page_id", f.pages],
437
+ ["c.row_id", f.rows],
438
+ ["c.file_id", f.files],
439
+ ];
440
+ if (lists.reduce((n, [, s]) => n + s.size, 0) > IN_LIMIT) {
441
+ return null;
442
+ }
443
+ const parts = lists
444
+ .filter(([, s]) => s.size)
445
+ .map(([column, s]) => sql `${sql.raw(column)} IN (${sql.join([...s].map((id) => sql `${id}`), sql `, `)})`);
446
+ return parts.length ? sql `(${sql.join(parts, sql ` OR `)})` : sql `0`;
447
+ }
448
+ const leaves = (f, u) => (u.page_id !== null && f.pages.has(u.page_id)) ||
449
+ (u.row_id !== null && f.rows.has(u.row_id)) ||
450
+ (u.file_id !== null && f.files.has(u.file_id));
451
+ /** The key of the item a unit belongs to: hits are grouped by it. */
452
+ function itemOf(u) {
453
+ if (u.page_id) {
454
+ return `p:${u.page_id}`;
455
+ }
456
+ if (u.row_id) {
457
+ return `r:${u.row_id}`;
458
+ }
459
+ if (u.value_id) {
460
+ return `v:${u.value_id}`;
461
+ }
462
+ if (u.file_id) {
463
+ return `f:${u.file_id}`;
464
+ }
465
+ return `x:${u.plugin}:${u.ref}`;
466
+ }
467
+ /**
468
+ * Searches Knowledge: items whose categories pass `where`, then the units the keywords, the
469
+ * trigrams and the vectors rank best, merged by rank (RRF), then the classifier's judgement of
470
+ * each of the CANDIDATES best. Gives up to `limit` items with their best section. `check: false`
471
+ * leaves the classifier out.
472
+ */
473
+ export async function searchKnowledge(projectId, query, opts = {}) {
474
+ const limit = Math.min(Math.max(1, opts.limit ?? 6), 12);
475
+ const filter = await filterItems(projectId, opts.where);
476
+ if (filter && !filter.size) {
477
+ return { hits: [], candidates: 0, checked: false, filtered: 0 };
478
+ }
479
+ const plugins = [...(await pluginIdsOf(currentTenant()))];
480
+ const inFilter = filter ? filtered(filter) : null;
481
+ // A filter keeps plugins' texts and summaries out: they have no categories.
482
+ const where = and(sql `c.project_id = ${projectId}`, searchable(plugins), filter
483
+ ? (inFilter ?? sql `(c.page_id IS NOT NULL OR c.row_id IS NOT NULL OR c.file_id IS NOT NULL)`)
484
+ : undefined);
485
+ const take = filter && !inFilter ? 300 : CANDIDATES;
486
+ const lists = [];
487
+ const words = keywordQuery(query);
488
+ if (words) {
489
+ lists.push(await db.all(sql `
490
+ SELECT ${COLUMNS} FROM project_chunk_fts f JOIN project_chunk c ON c.id = f.rowid
491
+ WHERE project_chunk_fts MATCH ${words} AND ${where}
492
+ ORDER BY bm25(project_chunk_fts) LIMIT ${take}`));
493
+ }
494
+ const grams = trigramQuery(query);
495
+ if (grams) {
496
+ lists.push(await db
497
+ .all(sql `
498
+ SELECT ${COLUMNS} FROM project_chunk_tri f JOIN project_chunk c ON c.id = f.rowid
499
+ WHERE project_chunk_tri MATCH ${grams} AND ${where}
500
+ ORDER BY bm25(project_chunk_tri) LIMIT ${take}`)
501
+ .catch(() => []));
502
+ }
503
+ const embedded = await embed([query]).catch(() => null);
504
+ if (embedded) {
505
+ lists.push(await db.all(sql `
506
+ SELECT ${COLUMNS} FROM project_chunk c
507
+ WHERE ${where} AND c.model = ${embedded.model}
508
+ ORDER BY vector_distance_cos(c.embedding, ${vectorBytes(embedded.vectors[0])}) LIMIT ${take}`));
509
+ }
510
+ // Reciprocal rank fusion: a unit the lists rank high comes first.
511
+ const scored = new Map();
512
+ for (const list of lists) {
513
+ list
514
+ .filter((u) => !filter || inFilter || leaves(filter, u))
515
+ .slice(0, CANDIDATES)
516
+ .forEach((unit, rank) => {
517
+ const entry = scored.get(unit.id) ?? { unit, score: 0 };
518
+ entry.score += 1 / (60 + rank);
519
+ scored.set(unit.id, entry);
520
+ });
521
+ }
522
+ const candidates = [...scored.values()].sort((a, b) => b.score - a.score).slice(0, CANDIDATES);
523
+ if (!candidates.length) {
524
+ return { hits: [], candidates: 0, checked: false, filtered: filter?.size ?? null };
525
+ }
526
+ const described = await describe(projectId, candidates.map((c) => c.unit));
527
+ const judged = opts.check === false
528
+ ? null
529
+ : await judgeRelevance(query, described.map((d) => ({
530
+ title: d.title,
531
+ path: d.path,
532
+ categories: d.categories,
533
+ heading: d.heading,
534
+ text: d.text,
535
+ })), opts.signal);
536
+ const ranked = described
537
+ .map((hit, i) => ({ hit: { ...hit, relevance: judged?.[i] ?? null }, rank: i }))
538
+ .filter(({ hit }) => hit.relevance === null || hit.relevance >= MIN_RELEVANCE)
539
+ .sort((a, b) => judged
540
+ ? (b.hit.relevance ?? MIN_RELEVANCE) - (a.hit.relevance ?? MIN_RELEVANCE) || a.rank - b.rank
541
+ : a.rank - b.rank);
542
+ // One hit per item: its best section.
543
+ const seen = new Set();
544
+ const hits = [];
545
+ for (const { hit } of ranked) {
546
+ if (seen.has(hit.key)) {
547
+ continue;
548
+ }
549
+ seen.add(hit.key);
550
+ hits.push(hit);
551
+ if (hits.length >= limit) {
552
+ break;
553
+ }
554
+ }
555
+ return {
556
+ hits,
557
+ candidates: candidates.length,
558
+ checked: judged !== null,
559
+ filtered: filter?.size ?? null,
560
+ };
561
+ }
562
+ /** What a step and the studio see of each unit: the item's path, title and categories. */
563
+ async function describe(projectId, units) {
564
+ const pageIds = [...new Set(units.flatMap((u) => (u.page_id ? [u.page_id] : [])))];
565
+ const rowIds = [...new Set(units.flatMap((u) => (u.row_id ? [u.row_id] : [])))];
566
+ const fileIds = [...new Set(units.flatMap((u) => (u.file_id ? [u.file_id] : [])))];
567
+ const valueIds = [...new Set(units.flatMap((u) => (u.value_id ? [u.value_id] : [])))];
568
+ const [tree, tPaths, fPaths, categories, rows, files, values] = await Promise.all([
569
+ pageIds.length ? pageTree(projectId) : new Map(),
570
+ rowIds.length ? tablePaths(projectId) : new Map(),
571
+ fileIds.length ? filePaths(projectId) : new Map(),
572
+ categoryRows(projectId),
573
+ rowIds.length
574
+ ? db.query.spaceTableRow.findMany({
575
+ where: inArray(schema.spaceTableRow.id, rowIds),
576
+ columns: { id: true, tableId: true },
577
+ })
578
+ : [],
579
+ fileIds.length
580
+ ? db.query.projectFile.findMany({
581
+ where: inArray(schema.projectFile.id, fileIds),
582
+ columns: { id: true, name: true },
583
+ })
584
+ : [],
585
+ valueIds.length
586
+ ? db.query.spaceCategoryValue.findMany({
587
+ where: inArray(schema.spaceCategoryValue.id, valueIds),
588
+ })
589
+ : [],
590
+ ]);
591
+ const tableIds = [...new Set(rows.map((r) => r.tableId))];
592
+ const tables = tableIds.length
593
+ ? await db.query.spaceTable.findMany({
594
+ where: inArray(schema.spaceTable.id, tableIds),
595
+ columns: { id: true, title: true },
596
+ })
597
+ : [];
598
+ const cats = await itemCategoriesOf([
599
+ ...pageIds.map((pageId) => ({ pageId })),
600
+ ...rowIds.map((rowId) => ({ rowId })),
601
+ ...tableIds.map((tableId) => ({ tableId })),
602
+ ...fileIds.map((fileId) => ({ fileId })),
603
+ ]);
604
+ // The unit's text without the head it was indexed with: the step gets that as fields.
605
+ const bodyOf = (u) => {
606
+ const parts = u.text.split("\n\n");
607
+ if (!(u.page_id || u.row_id || u.value_id) || parts.length < 2) {
608
+ return u.text;
609
+ }
610
+ const rest = parts.slice(1);
611
+ return (rest[0].startsWith("## ") ? rest.slice(1) : rest).join("\n\n");
612
+ };
613
+ return units.map((u) => {
614
+ const base = {
615
+ key: itemOf(u),
616
+ heading: u.heading,
617
+ sheet: u.sheet,
618
+ rowId: u.row_id,
619
+ text: bodyOf(u),
620
+ relevance: null,
621
+ link: u.link,
622
+ plugin: u.plugin,
623
+ };
624
+ if (u.page_id) {
625
+ const node = tree.get(u.page_id);
626
+ return {
627
+ ...base,
628
+ kind: "page",
629
+ open: `p:${u.page_id}`,
630
+ path: node?.path ?? "",
631
+ title: node?.titles.join(" › ") ?? "",
632
+ categories: categoryLines(categories, cats.get(`p:${u.page_id}`)),
633
+ };
634
+ }
635
+ if (u.row_id) {
636
+ const tableId = rows.find((r) => r.id === u.row_id)?.tableId ?? "";
637
+ return {
638
+ ...base,
639
+ kind: "table",
640
+ open: `t:${tableId}`,
641
+ path: tPaths.get(tableId) ?? "",
642
+ title: tables.find((t) => t.id === tableId)?.title ?? "",
643
+ categories: [
644
+ ...categoryLines(categories, cats.get(`t:${tableId}`)),
645
+ ...categoryLines(categories, cats.get(`r:${u.row_id}`)),
646
+ ].filter((l, i, all) => all.indexOf(l) === i),
647
+ };
648
+ }
649
+ if (u.value_id) {
650
+ const value = values.find((v) => v.id === u.value_id);
651
+ const category = categories.find((c) => c.id === value?.categoryId);
652
+ return {
653
+ ...base,
654
+ kind: "summary",
655
+ open: `v:${u.value_id}`,
656
+ path: "",
657
+ title: `${category?.name}: ${value?.value} — Summary`,
658
+ categories: [],
659
+ };
660
+ }
661
+ if (u.file_id) {
662
+ return {
663
+ ...base,
664
+ kind: "file",
665
+ open: `f:${u.file_id}`,
666
+ path: fPaths.get(u.file_id) ?? "",
667
+ title: files.find((f) => f.id === u.file_id)?.name ?? "",
668
+ categories: categoryLines(categories, cats.get(`f:${u.file_id}`)),
669
+ };
670
+ }
671
+ return { ...base, kind: "plugin", open: null, path: "", title: u.title ?? "", categories: [] };
672
+ });
673
+ }
674
+ /** Puts every item of a space into the index again: after a sync, or a change of embedding model. */
675
+ export async function reindexSpace(projectId) {
676
+ const [pages, tables, files, values] = await Promise.all([
677
+ db.query.spacePage.findMany({
678
+ where: and(eq(schema.spacePage.projectId, projectId), isNull(schema.spacePage.wizardId)),
679
+ columns: { id: true },
680
+ }),
681
+ db.query.spaceTable.findMany({
682
+ where: and(eq(schema.spaceTable.projectId, projectId), isNull(schema.spaceTable.wizardId)),
683
+ columns: { id: true },
684
+ }),
685
+ db.query.projectFile.findMany({
686
+ where: and(eq(schema.projectFile.projectId, projectId), eq(schema.projectFile.kind, "document")),
687
+ columns: { id: true },
688
+ }),
689
+ db
690
+ .select({ id: schema.spaceCategoryValue.id })
691
+ .from(schema.spaceCategoryValue)
692
+ .innerJoin(schema.spaceCategory, eq(schema.spaceCategory.id, schema.spaceCategoryValue.categoryId))
693
+ .where(and(eq(schema.spaceCategory.projectId, projectId), isNotNull(schema.spaceCategoryValue.summary))),
694
+ ]);
695
+ for (const p of pages) {
696
+ queueIndex(`p:${p.id}`);
697
+ }
698
+ for (const t of tables) {
699
+ queueIndex(`t:${t.id}`);
700
+ }
701
+ for (const f of files) {
702
+ queueIndex(`f:${f.id}`);
703
+ }
704
+ for (const v of values) {
705
+ queueIndex(`v:${v.id}`);
706
+ }
707
+ }