@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,508 @@
1
+ import { existsSync, mkdirSync, watch } from "node:fs";
2
+ import { join, resolve, sep } from "node:path";
3
+ import { fileURLToPath } from "node:url";
4
+ import { FIELD_KINDS, PLUGIN_ID, PLUGIN_TOOL_NAME, wizardSchema, } from "@engenty-wizards/shared/definition";
5
+ import { BUILT_IN_RUNNERS, OUTPUT_KINDS, RESERVED_PATHS, RUNNER_ID, } from "@engenty-wizards/shared/runners";
6
+ import { generateText, Output } from "ai";
7
+ import { eq } from "drizzle-orm";
8
+ import { createJiti } from "jiti";
9
+ import { z } from "zod";
10
+ import { readPage } from "../agents/website.js";
11
+ import { packageRoot } from "../cli/home.js";
12
+ import { pluginConnections } from "../connectors/plugin-connections.js";
13
+ import { db, onTenantOpen, schema } from "../db/client.js";
14
+ import { parseDocument } from "../documents/parse.js";
15
+ import { env } from "../env.js";
16
+ import { currentFeatures } from "../features.js";
17
+ import { managed } from "../manage.js";
18
+ import { conversationAccess, ModelUnavailableError, textModel } from "../models.js";
19
+ import { seal, unseal } from "../secrets/crypto.js";
20
+ import { putIndexEntry, removeIndexEntries } from "../services/project-index.js";
21
+ import { originData } from "../services/space-origin.js";
22
+ import { safeFetch } from "../tools/net-guard.js";
23
+ import { channelsApi } from "./channels.js";
24
+ import { claimsApiFor } from "./claims.js";
25
+ import { discoverPlugins } from "./discovery.js";
26
+ import { migrateOpenTenants, migratePlugins } from "./migrations.js";
27
+ import { proModulesDir, proSources } from "./pro-state.js";
28
+ import { publicRefOf, publicUrlOf, sharedUrlOf } from "./public.js";
29
+ import { announceChange, compileRoute, dropPlugin, emptyRecord, loadedPlugin, loadedPlugins, setPlugin, } from "./registry.js";
30
+ import { runsApiFor } from "./runs.js";
31
+ /**
32
+ * Loading plugins (docs/content/dev/plugins). A plugin's server half is TypeScript or JavaScript read
33
+ * from its file as it is: no build step, and a reload reads the files again. What a plugin
34
+ * imports of the runtime's own packages comes from the runtime's copies, wherever the plugin's
35
+ * file lies.
36
+ */
37
+ /** What ships with this runtime, then the folders of `PLUGINS_DIR`. */
38
+ export function pluginDirs() {
39
+ return [join(packageRoot, "modules"), ...env.plugins.dirs];
40
+ }
41
+ const own = (specifier) => fileURLToPath(import.meta.resolve(specifier));
42
+ /**
43
+ * The longer name first: an alias also matches what begins with it. `@engenty-wizards/plugin-sdk`
44
+ * is the name plugins written before `@engenty/wizards/plugin` import.
45
+ */
46
+ function aliases() {
47
+ const thread = own("@engenty/wizards/plugin/thread");
48
+ const plugin = own("@engenty/wizards/plugin");
49
+ return {
50
+ "@engenty/wizards/plugin/thread": thread,
51
+ "@engenty/wizards/plugin": plugin,
52
+ "@engenty-wizards/plugin-sdk/thread": thread,
53
+ "@engenty-wizards/plugin-sdk": plugin,
54
+ "drizzle-orm/sqlite-core": own("drizzle-orm/sqlite-core"),
55
+ "drizzle-orm": own("drizzle-orm"),
56
+ zod: own("zod"),
57
+ };
58
+ }
59
+ async function importFactory(entry) {
60
+ // No module cache: every load evaluates the plugin's files anew.
61
+ const jiti = createJiti(import.meta.url, { moduleCache: false, alias: aliases() });
62
+ const factory = await jiti.import(entry, { default: true });
63
+ if (typeof factory !== "function") {
64
+ throw new Error("The default export is not a function.");
65
+ }
66
+ return factory;
67
+ }
68
+ /** A job runs at most this often. */
69
+ const MIN_EVERY_MS = 60_000;
70
+ /** The built-in runners and the sub-paths of a wizard's address that are something else. */
71
+ const RESERVED_RUNNER_IDS = new Set([...BUILT_IN_RUNNERS.map((r) => r.id), ...RESERVED_PATHS]);
72
+ /** What a plugin says about a runner, checked: the lists hold known kinds only. */
73
+ const runnerInfoSchema = z.object({
74
+ id: z.string().regex(RUNNER_ID, 'lower case, digits and "-", at most 24 characters'),
75
+ label: z.object({ de: z.string().min(1), en: z.string().min(1) }),
76
+ kind: z.enum(["page", "channel"]),
77
+ capabilities: z.object({
78
+ input: z.array(z.enum(FIELD_KINDS)),
79
+ output: z.object({
80
+ shows: z.array(z.enum(OUTPUT_KINDS)),
81
+ pictures: z.array(z.enum(OUTPUT_KINDS)),
82
+ }),
83
+ asks: z.array(z.enum(["confirm", "login"])),
84
+ review: z.array(z.enum(["accept", "regenerate", "edit"])),
85
+ waits: z.boolean(),
86
+ handoff: z.array(z.enum(["screen", "thread", "sms", "push"])),
87
+ }),
88
+ plugin: z.string(),
89
+ });
90
+ function apiFor(record) {
91
+ const { source } = record;
92
+ const tag = `[plugin ${source.id}]`;
93
+ /** The names a step's model sees: the plugin's step tools and its context tools share them. */
94
+ const stepToolNames = () => [
95
+ ...record.tools.keys(),
96
+ ...record.contexts.flatMap((c) => (c.tools ?? []).map((t) => t.name)),
97
+ ];
98
+ const named = (kind, name) => {
99
+ if (!PLUGIN_TOOL_NAME.test(name)) {
100
+ throw new Error(`${kind} "${name}": a name is lower case, digits and "_".`);
101
+ }
102
+ };
103
+ return {
104
+ plugin: source.manifest,
105
+ resolvePath: (relative) => resolve(source.root, relative),
106
+ config: { get: (key) => process.env[key]?.trim() || undefined },
107
+ features: {
108
+ // A short name is the plugin's own switch; a dotted or core name is taken as it is.
109
+ has: async (name) => {
110
+ const all = await currentFeatures();
111
+ const own = `${source.id}.${name}`;
112
+ return (own in all ? all[own] : all[name]) === true;
113
+ },
114
+ all: currentFeatures,
115
+ },
116
+ log: {
117
+ info: (...args) => console.log(tag, ...args),
118
+ warn: (...args) => console.warn(tag, ...args),
119
+ error: (...args) => console.error(tag, ...args),
120
+ },
121
+ server: {
122
+ registerHttpRoute(route) {
123
+ record.routes.push(compileRoute(route));
124
+ },
125
+ registerTool(tool) {
126
+ named("Tool", tool.name);
127
+ if (stepToolNames().includes(tool.name)) {
128
+ throw new Error(`Tool "${tool.name}" is registered twice.`);
129
+ }
130
+ record.tools.set(tool.name, tool);
131
+ },
132
+ registerSpaceContext(context) {
133
+ const names = (context.tools ?? []).map((t) => t.name);
134
+ for (const name of names) {
135
+ named("Tool", name);
136
+ if (stepToolNames().includes(name) || names.indexOf(name) !== names.lastIndexOf(name)) {
137
+ throw new Error(`Tool "${name}" is registered twice.`);
138
+ }
139
+ }
140
+ record.contexts.push(context);
141
+ },
142
+ registerAssistantTool(tool) {
143
+ named("Assistant tool", tool.name);
144
+ if (record.assistantTools.has(tool.name)) {
145
+ throw new Error(`Assistant tool "${tool.name}" is registered twice.`);
146
+ }
147
+ record.assistantTools.set(tool.name, tool);
148
+ },
149
+ registerAssistantContext(context) {
150
+ record.assistantPages.push(context);
151
+ },
152
+ registerPublicRoute(route) {
153
+ record.publicRoutes.push(compileRoute(route));
154
+ },
155
+ registerRunner(runner) {
156
+ const info = runnerInfoSchema.parse({ ...runner, plugin: source.id });
157
+ if (record.runners.has(info.id) || RESERVED_RUNNER_IDS.has(info.id)) {
158
+ throw new Error(`Runner "${info.id}" is taken.`);
159
+ }
160
+ if (info.kind === "page" && typeof runner.page !== "function") {
161
+ throw new Error(`Runner "${info.id}": a page runner needs a page.`);
162
+ }
163
+ record.runners.set(info.id, {
164
+ info,
165
+ page: runner.page,
166
+ problem: runner.problem,
167
+ address: runner.address,
168
+ });
169
+ },
170
+ publicUrl: (path) => publicUrlOf(source.id, path),
171
+ publicRef: () => publicRefOf(source.id),
172
+ registerSharedRoute(route) {
173
+ record.sharedRoutes.push(compileRoute(route));
174
+ },
175
+ sharedUrl: (path) => sharedUrlOf(source.id, path),
176
+ channels: channelsApi,
177
+ claims: claimsApiFor(source.id),
178
+ runs: runsApiFor(source.id),
179
+ speech: {
180
+ async conversation() {
181
+ const access = await conversationAccess().catch((err) => {
182
+ throw err instanceof ModelUnavailableError
183
+ ? Object.assign(err, { name: "ModelUnavailableError", status: 503, code: "no_model" })
184
+ : err;
185
+ });
186
+ return { provider: "openai", ...access };
187
+ },
188
+ },
189
+ every(name, everyMs, handler) {
190
+ named("Job", name);
191
+ if (record.jobs.has(name)) {
192
+ throw new Error(`Job "${name}" is registered twice.`);
193
+ }
194
+ record.jobs.set(name, { everyMs: Math.max(MIN_EVERY_MS, everyMs), handler });
195
+ },
196
+ index: {
197
+ put: (entry) => putIndexEntry(source.id, entry),
198
+ remove: (space, key) => removeIndexEntries(source.id, space, key),
199
+ },
200
+ spaceData: originData(source.id),
201
+ spaces: {
202
+ async brand(space) {
203
+ const p = await db.query.project.findFirst({ where: eq(schema.project.id, space) });
204
+ return p
205
+ ? {
206
+ name: p.brand.name ?? "",
207
+ colors: (p.brand.colors ?? []).map(({ name, value }) => ({ name, value })),
208
+ fonts: (p.brand.fonts ?? []).map(({ family, role, weights }) => ({
209
+ family,
210
+ role,
211
+ weights,
212
+ })),
213
+ }
214
+ : null;
215
+ },
216
+ },
217
+ web: {
218
+ fetch: (url, init) => safeFetch(url, init),
219
+ read: (url, options) => readPage(url, options?.signal),
220
+ },
221
+ documents: {
222
+ async parse(file, options) {
223
+ const parsed = await parseDocument(file, { signal: options?.signal });
224
+ return { markdown: parsed.markdown, pages: parsed.pages };
225
+ },
226
+ },
227
+ registerMigrations(folder) {
228
+ record.migrations.push(resolve(source.root, folder));
229
+ },
230
+ on(event, listener) {
231
+ const listeners = (record.listeners[event] ?? []);
232
+ listeners.push(listener);
233
+ record.listeners[event] = listeners;
234
+ },
235
+ getTenantDb: () => db,
236
+ async generate(request) {
237
+ const resolved = await textModel(request.model ?? "standard").catch((err) => {
238
+ // Said so a route can pass it on as it is: 503 with the code `no_model`.
239
+ throw err instanceof ModelUnavailableError
240
+ ? Object.assign(err, { name: "ModelUnavailableError", status: 503, code: "no_model" })
241
+ : err;
242
+ });
243
+ const files = request.files ?? [];
244
+ const result = await generateText({
245
+ model: resolved.model,
246
+ system: request.system,
247
+ // Pictures and PDFs go with the prompt as parts of one message.
248
+ ...(files.length
249
+ ? {
250
+ messages: [
251
+ {
252
+ role: "user",
253
+ content: [
254
+ ...files.map((f) => ({
255
+ type: "file",
256
+ data: f.data,
257
+ mediaType: f.mediaType,
258
+ ...(f.name ? { filename: f.name } : {}),
259
+ })),
260
+ { type: "text", text: request.prompt },
261
+ ],
262
+ },
263
+ ],
264
+ }
265
+ : { prompt: request.prompt }),
266
+ maxOutputTokens: request.maxOutputTokens,
267
+ abortSignal: request.signal ?? AbortSignal.timeout(120_000),
268
+ ...(request.schema ? { output: Output.object({ schema: request.schema }) } : {}),
269
+ });
270
+ return {
271
+ text: result.text,
272
+ object: (request.schema ? result.output : undefined),
273
+ };
274
+ },
275
+ connections: pluginConnections(source.id),
276
+ secrets: { seal, unseal },
277
+ registerStarter(starter) {
278
+ if (!PLUGIN_ID.test(starter.id)) {
279
+ throw new Error(`Starter "${starter.id}": an id is lower case, digits and "-".`);
280
+ }
281
+ if (record.starters.has(starter.id)) {
282
+ throw new Error(`Starter "${starter.id}" is registered twice.`);
283
+ }
284
+ const parsed = wizardSchema.safeParse(starter.definition);
285
+ if (!parsed.success) {
286
+ const issue = parsed.error.issues[0];
287
+ throw new Error(`Starter "${starter.id}": ${issue?.path.join(".") || "definition"}: ${issue?.message}`);
288
+ }
289
+ record.starters.set(starter.id, { ...starter, definition: parsed.data });
290
+ },
291
+ onUnload(dispose) {
292
+ record.disposers.push(dispose);
293
+ },
294
+ },
295
+ };
296
+ }
297
+ /** Runs what the plugin asked to have undone, the last first. */
298
+ async function dispose(record) {
299
+ // Its jobs are told to stop; the runtime stops starting them with the record gone.
300
+ record.stopped.abort();
301
+ for (const undo of record.disposers.splice(0).reverse()) {
302
+ try {
303
+ await undo();
304
+ }
305
+ catch (err) {
306
+ console.error(`[plugins] ${record.source.id}: undoing failed:`, err);
307
+ }
308
+ }
309
+ }
310
+ async function load(source) {
311
+ const record = emptyRecord(source);
312
+ if (source.entry) {
313
+ try {
314
+ const factory = await importFactory(source.entry);
315
+ await factory(apiFor(record));
316
+ }
317
+ catch (err) {
318
+ // Half a plugin is worse than none: what it registered before it failed goes as well.
319
+ await dispose(record);
320
+ record.routes = [];
321
+ record.tools.clear();
322
+ record.contexts = [];
323
+ record.assistantTools.clear();
324
+ record.assistantPages = [];
325
+ record.publicRoutes = [];
326
+ record.sharedRoutes = [];
327
+ record.runners.clear();
328
+ record.jobs.clear();
329
+ record.starters.clear();
330
+ record.listeners = {};
331
+ record.migrations = [];
332
+ record.error = err?.message || String(err);
333
+ console.error(`[plugins] ${source.id} did not load:`, err);
334
+ }
335
+ }
336
+ setPlugin(record);
337
+ return record;
338
+ }
339
+ async function unload(id) {
340
+ const record = dropPlugin(id);
341
+ if (record) {
342
+ await dispose(record);
343
+ }
344
+ }
345
+ let problems = [];
346
+ /** Files and folders that look like a plugin and are none, as of the last look. */
347
+ export function pluginProblems() {
348
+ return problems;
349
+ }
350
+ function discover() {
351
+ const result = discoverPlugins(pluginDirs());
352
+ // Pro modules come last and only while the plan has them (pro-state.ts).
353
+ const pro = managed ? null : discoverPlugins([proModulesDir()]);
354
+ const allowed = pro
355
+ ? proSources(pro.found, new Set(result.found.map((s) => s.id)))
356
+ : { load: [], problems: [] };
357
+ problems = [...result.problems, ...(pro?.problems ?? []), ...allowed.problems];
358
+ for (const problem of problems) {
359
+ console.error(`[plugins] ${problem.path}: ${problem.message}`);
360
+ }
361
+ return [...result.found, ...allowed.load];
362
+ }
363
+ /** One load at a time: the watcher and a person may ask for a reload at the same moment. */
364
+ let queue = Promise.resolve();
365
+ function inTurn(work) {
366
+ const next = queue.catch(() => undefined).then(work);
367
+ queue = next;
368
+ return next;
369
+ }
370
+ let hooked = false;
371
+ /** At start: finds the plugins and loads each. Must run before a tenant database opens. */
372
+ export function loadPlugins() {
373
+ return inTurn(async () => {
374
+ if (!hooked) {
375
+ hooked = true;
376
+ // A plugin whose tables cannot be made must not keep the tenant's database from opening.
377
+ onTenantOpen((tenantId, client) => migratePlugins(tenantId, client).catch((err) => console.error(`[plugins] tables for tenant ${tenantId}:`, err.message)));
378
+ }
379
+ const found = discover();
380
+ for (const source of found) {
381
+ await load(source);
382
+ }
383
+ if (found.length) {
384
+ console.log(`plugins: ${found.map((s) => s.id).join(", ")}`);
385
+ }
386
+ await migrateOpenTenants();
387
+ if (env.plugins.watch) {
388
+ watchPlugins();
389
+ }
390
+ });
391
+ }
392
+ /** Loads one plugin again from its files; a plugin whose files are gone unloads. */
393
+ export function reloadPlugin(id) {
394
+ return inTurn(async () => {
395
+ const found = discover();
396
+ const source = found.find((s) => s.id === id);
397
+ await unload(id);
398
+ const record = source ? await load(source) : null;
399
+ // Its manifest may name another id now: under the old one it is gone, under the new one new.
400
+ await loadMissing(found);
401
+ await migrateOpenTenants();
402
+ announceChange({ id });
403
+ return record;
404
+ });
405
+ }
406
+ /** Loads what was found and is not loaded yet. */
407
+ async function loadMissing(found) {
408
+ const missing = found.filter((source) => !loadedPlugin(source.id));
409
+ for (const source of missing) {
410
+ await load(source);
411
+ }
412
+ return missing.length > 0;
413
+ }
414
+ /**
415
+ * Looks again and leaves what is loaded alone: plugins that are new load, plugins whose files
416
+ * went unload.
417
+ */
418
+ export function findNewPlugins() {
419
+ return inTurn(async () => {
420
+ const found = discover();
421
+ const gone = loadedPlugins().filter((p) => !found.some((s) => s.id === p.source.id));
422
+ for (const plugin of gone) {
423
+ await unload(plugin.source.id);
424
+ }
425
+ if ((await loadMissing(found)) || gone.length) {
426
+ await migrateOpenTenants();
427
+ announceChange({ id: null });
428
+ }
429
+ });
430
+ }
431
+ /** Loads every plugin anew, new ones included, and unloads what is gone. */
432
+ export function rescanPlugins() {
433
+ return inTurn(async () => {
434
+ const found = discover();
435
+ for (const loaded of loadedPlugins()) {
436
+ await unload(loaded.source.id);
437
+ }
438
+ for (const source of found) {
439
+ await load(source);
440
+ }
441
+ await migrateOpenTenants();
442
+ announceChange({ id: null });
443
+ });
444
+ }
445
+ /** The studio half was built again: the server half stays as it is, the studio fetches the files. */
446
+ function refreshStudioHalf(id) {
447
+ return inTurn(async () => {
448
+ const record = loadedPlugin(id);
449
+ const source = discover().find((s) => s.id === id);
450
+ if (record && source) {
451
+ record.source = { ...record.source, studio: source.studio, styles: source.styles };
452
+ announceChange({ id });
453
+ }
454
+ });
455
+ }
456
+ const watchers = [];
457
+ /**
458
+ * Reloads a plugin when one of its files changes. `ui/` is left alone: it only counts once it
459
+ * is built, and a change below `dist/` is that build.
460
+ */
461
+ function watchPlugins() {
462
+ for (const watcher of watchers.splice(0)) {
463
+ watcher.close();
464
+ }
465
+ const timers = new Map();
466
+ const soon = (key, run) => {
467
+ clearTimeout(timers.get(key));
468
+ timers.set(key, setTimeout(() => {
469
+ timers.delete(key);
470
+ run().catch((err) => console.error("[plugins]", err));
471
+ }, 150));
472
+ };
473
+ for (const dir of pluginDirs()) {
474
+ // A folder of this install's own plugins is made, so the first plugin put there is seen.
475
+ if (env.plugins.dirs.includes(dir)) {
476
+ try {
477
+ mkdirSync(dir, { recursive: true });
478
+ }
479
+ catch {
480
+ // a place that cannot be written to
481
+ }
482
+ }
483
+ if (!existsSync(dir)) {
484
+ continue;
485
+ }
486
+ const watcher = watch(dir, { recursive: true }, (_event, file) => {
487
+ const parts = file?.toString().split(sep) ?? [];
488
+ if (!parts.length || parts.includes("node_modules") || parts.some((p) => p.startsWith("."))) {
489
+ return;
490
+ }
491
+ const top = join(dir, parts[0]);
492
+ const plugin = loadedPlugins().find((p) => p.source.single ? p.source.entry === top : p.source.root === top);
493
+ const { id, entry } = plugin?.source ?? {};
494
+ if (!id) {
495
+ // A plugin that is new here, or what is left of one that went. The others stay loaded.
496
+ soon("*", findNewPlugins);
497
+ }
498
+ else if (parts[1] === "dist" && !entry?.startsWith(join(top, "dist") + sep)) {
499
+ soon(`${id}/studio`, () => refreshStudioHalf(id));
500
+ }
501
+ else if (parts[1] !== "ui") {
502
+ soon(id, () => reloadPlugin(id));
503
+ }
504
+ });
505
+ watcher.unref();
506
+ watchers.push(watcher);
507
+ }
508
+ }
@@ -0,0 +1,69 @@
1
+ import { readdirSync, readFileSync } from "node:fs";
2
+ import { join } from "node:path";
3
+ import { openTenantClients } from "../db/client.js";
4
+ import { loadedPlugins } from "./registry.js";
5
+ /**
6
+ * A plugin's own tables. Each `.sql` file of the folders a plugin registered runs once per
7
+ * tenant database, in the order of the file names; `plugin_migration` records which ran. A
8
+ * database gets them when it opens, and the open ones get them when a plugin loads. Unloading a
9
+ * plugin leaves its tables and their rows where they are.
10
+ */
11
+ const RECORD = `CREATE TABLE IF NOT EXISTS plugin_migration (
12
+ plugin TEXT NOT NULL,
13
+ name TEXT NOT NULL,
14
+ applied_at INTEGER NOT NULL,
15
+ PRIMARY KEY (plugin, name)
16
+ )`;
17
+ /** One at a time per database: a plugin that loads while a database opens must not run a file twice. */
18
+ const queues = new Map();
19
+ async function apply(client) {
20
+ const pending = loadedPlugins().filter((p) => p.migrations.length);
21
+ if (!pending.length) {
22
+ return;
23
+ }
24
+ await client.execute(RECORD);
25
+ const done = await client.execute("SELECT plugin, name FROM plugin_migration");
26
+ const ran = new Set(done.rows.map((row) => `${row.plugin}/${row.name}`));
27
+ for (const plugin of pending) {
28
+ for (const folder of plugin.migrations) {
29
+ const files = readdirSync(folder)
30
+ .filter((name) => name.endsWith(".sql"))
31
+ .sort();
32
+ for (const name of files) {
33
+ if (ran.has(`${plugin.source.id}/${name}`)) {
34
+ continue;
35
+ }
36
+ // The file and its record go in together or not at all.
37
+ const tx = await client.transaction("write");
38
+ try {
39
+ await tx.executeMultiple(readFileSync(join(folder, name), "utf8"));
40
+ await tx.execute({
41
+ sql: "INSERT INTO plugin_migration (plugin, name, applied_at) VALUES (?, ?, ?)",
42
+ args: [plugin.source.id, name, Date.now()],
43
+ });
44
+ await tx.commit();
45
+ }
46
+ catch (err) {
47
+ await tx.rollback().catch(() => undefined);
48
+ throw new Error(`Plugin "${plugin.source.id}", ${name}: ${err.message}`);
49
+ }
50
+ finally {
51
+ tx.close();
52
+ }
53
+ }
54
+ }
55
+ }
56
+ }
57
+ export function migratePlugins(tenantId, client) {
58
+ const next = (queues.get(tenantId) ?? Promise.resolve())
59
+ .catch(() => undefined)
60
+ .then(() => apply(client));
61
+ queues.set(tenantId, next);
62
+ return next;
63
+ }
64
+ /** After a plugin loaded: its tables for every database that is open already. */
65
+ export async function migrateOpenTenants() {
66
+ for (const [tenantId, client] of await openTenantClients()) {
67
+ await migratePlugins(tenantId, client).catch((err) => console.error(`[plugins] tables for tenant ${tenantId}:`, err.message));
68
+ }
69
+ }
@@ -0,0 +1,34 @@
1
+ import { createPublicKey, verify } from "node:crypto";
2
+ import { env } from "../env.js";
3
+ /**
4
+ * The keys a Pro module's package must be signed with (docs/pro-modules.md).
5
+ * Only the public halves are here; the private one signs in the build of the closed plugins and
6
+ * is kept nowhere else. A new key is added beside the old one, which goes a release later.
7
+ */
8
+ const SHIPPED = ["MCowBQYDK2VwAyEAqVQAptgVhkBtobNObBDHAZzKFdted0nH0I+LWAHGER8="];
9
+ let keys = null;
10
+ function trusted() {
11
+ keys ??= [...SHIPPED, ...env.plugins.proKeys].map((der) => createPublicKey({ key: Buffer.from(der, "base64"), format: "der", type: "spki" }));
12
+ return keys;
13
+ }
14
+ /** What the signature covers; the packer of the closed plugins writes the same text. */
15
+ const message = (p) => `engenty-module:v1\n${p.id}\n${p.version}\n${p.runtime}\n${p.sha256}`;
16
+ /** Whether one of the trusted keys signed this package for this release. */
17
+ export function signedByUs(p) {
18
+ let signature;
19
+ try {
20
+ signature = Buffer.from(p.signature, "base64");
21
+ }
22
+ catch {
23
+ return false;
24
+ }
25
+ const data = Buffer.from(message(p));
26
+ return trusted().some((key) => {
27
+ try {
28
+ return verify(null, data, key, signature);
29
+ }
30
+ catch {
31
+ return false;
32
+ }
33
+ });
34
+ }