@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,170 @@
1
+ import { lookup } from "node:dns/promises";
2
+ import { BlockList, isIP } from "node:net";
3
+ import { Agent } from "undici";
4
+ const ALLOW_PRIVATE = process.env.ALLOW_PRIVATE_FETCH === "1";
5
+ /** Ranges that are not the public internet: this server, its networks, and special purposes. */
6
+ const blocked = new BlockList();
7
+ for (const [net, prefix] of [
8
+ ["0.0.0.0", 8], // "this" network
9
+ ["10.0.0.0", 8],
10
+ ["100.64.0.0", 10], // carrier-grade NAT
11
+ ["127.0.0.0", 8], // loopback
12
+ ["169.254.0.0", 16], // link-local, the cloud metadata service
13
+ ["172.16.0.0", 12], // also the Docker networks, the browser's DevTools among them
14
+ ["192.0.0.0", 24], // protocol assignments
15
+ ["192.0.2.0", 24], // documentation
16
+ ["192.88.99.0", 24], // 6to4 relays
17
+ ["192.168.0.0", 16],
18
+ ["198.18.0.0", 15], // benchmarking
19
+ ["198.51.100.0", 24], // documentation
20
+ ["203.0.113.0", 24], // documentation
21
+ ["224.0.0.0", 4], // multicast
22
+ ["240.0.0.0", 4], // reserved, and the broadcast address
23
+ ]) {
24
+ blocked.addSubnet(net, prefix, "ipv4");
25
+ }
26
+ for (const [net, prefix] of [
27
+ ["::", 128], // unspecified
28
+ ["::1", 128], // loopback
29
+ ["64:ff9b:1::", 48], // NAT64 for local use
30
+ ["100::", 64], // discard
31
+ ["2001::", 32], // Teredo: a tunnel to an IPv4 address
32
+ ["2001:db8::", 32], // documentation
33
+ ["fc00::", 7], // unique local
34
+ ["fe80::", 10], // link-local
35
+ ["fec0::", 10], // site-local
36
+ ["ff00::", 8], // multicast
37
+ ]) {
38
+ blocked.addSubnet(net, prefix, "ipv6");
39
+ }
40
+ /** The eight 16-bit words of an IPv6 address (the caller has checked it is one). */
41
+ function words(ip) {
42
+ let s = ip.split("%")[0].toLowerCase();
43
+ const v4 = /(\d+)\.(\d+)\.(\d+)\.(\d+)$/.exec(s);
44
+ if (v4) {
45
+ const [a, b, c, d] = v4.slice(1).map(Number);
46
+ s = `${s.slice(0, v4.index)}${(a * 256 + b).toString(16)}:${(c * 256 + d).toString(16)}`;
47
+ }
48
+ const [head, tail] = s.split("::");
49
+ const part = (x) => x ? x.split(":").map((w) => Number.parseInt(w, 16)) : [];
50
+ const h = part(head);
51
+ const t = part(tail);
52
+ return tail === undefined ? h : [...h, ...new Array(8 - h.length - t.length).fill(0), ...t];
53
+ }
54
+ const dotted = (hi, lo) => [Math.floor(hi / 256), hi % 256, Math.floor(lo / 256), lo % 256].join(".");
55
+ /**
56
+ * The IPv4 address an IPv6 address stands for: mapped (::ffff:a.b.c.d, also written
57
+ * ::ffff:a9fe:a9fe), translated, compatible (::a.b.c.d), NAT64 (64:ff9b::/96) and 6to4 (2002::/16).
58
+ * Connecting to any of them can reach that IPv4 address.
59
+ */
60
+ function embeddedV4(w) {
61
+ const zero = (from, to) => w.slice(from, to).every((x) => x === 0);
62
+ if (zero(0, 5) && w[5] === 0xffff) {
63
+ return dotted(w[6], w[7]);
64
+ }
65
+ if (zero(0, 4) && w[4] === 0xffff && w[5] === 0) {
66
+ return dotted(w[6], w[7]);
67
+ }
68
+ if (zero(0, 6)) {
69
+ return dotted(w[6], w[7]);
70
+ }
71
+ if (w[0] === 0x64 && w[1] === 0xff9b && zero(2, 6)) {
72
+ return dotted(w[6], w[7]);
73
+ }
74
+ if (w[0] === 0x2002) {
75
+ return dotted(w[1], w[2]);
76
+ }
77
+ return null;
78
+ }
79
+ /** Whether an IP address is on the public internet. Anything that is not an IP address is not. */
80
+ export function isPublicAddress(ip) {
81
+ const bare = ip.replace(/^\[|\]$/g, "");
82
+ const family = isIP(bare);
83
+ if (family === 4) {
84
+ return !blocked.check(bare, "ipv4");
85
+ }
86
+ if (family !== 6) {
87
+ return false;
88
+ }
89
+ const w = words(bare);
90
+ const v4 = embeddedV4(w);
91
+ if (v4) {
92
+ return isPublicAddress(v4);
93
+ }
94
+ return !blocked.check(w.map((x) => x.toString(16)).join(":"), "ipv6");
95
+ }
96
+ const PRIVATE = "Private addresses are not reachable from a wizard.";
97
+ /** The host's addresses, each of them public; throws if any one is not. */
98
+ async function publicAddresses(host) {
99
+ const family = isIP(host);
100
+ const addresses = family ? [{ address: host, family }] : await lookup(host, { all: true });
101
+ if (!ALLOW_PRIVATE && (!addresses.length || addresses.some((a) => !isPublicAddress(a.address)))) {
102
+ throw new Error(PRIVATE);
103
+ }
104
+ return addresses;
105
+ }
106
+ /** Agents may reach the public internet, never this server's own network. */
107
+ export async function assertPublicUrl(raw) {
108
+ let url;
109
+ try {
110
+ url = new URL(raw);
111
+ }
112
+ catch {
113
+ throw new Error(`Not a valid URL: ${raw}`);
114
+ }
115
+ if (url.protocol !== "http:" && url.protocol !== "https:") {
116
+ throw new Error("Only http and https URLs are allowed.");
117
+ }
118
+ if (ALLOW_PRIVATE) {
119
+ return url;
120
+ }
121
+ const host = url.hostname.replace(/^\[|\]$/g, "");
122
+ if (host === "localhost" || host.endsWith(".localhost") || host.endsWith(".local")) {
123
+ throw new Error(PRIVATE);
124
+ }
125
+ await publicAddresses(host);
126
+ return url;
127
+ }
128
+ /**
129
+ * Connects only to addresses that passed the check: the name is resolved and checked again at
130
+ * connect time, and the socket gets exactly those addresses, so a DNS answer that changes between
131
+ * the check and the connect (rebinding) cannot point it into the private network. TLS still
132
+ * verifies, and the Host header still names, the host of the URL.
133
+ */
134
+ const pinned = new Agent({
135
+ connect: {
136
+ lookup(host, options, callback) {
137
+ publicAddresses(host).then((addresses) => {
138
+ const usable = options.family
139
+ ? addresses.filter((a) => a.family === options.family)
140
+ : addresses;
141
+ if (!usable.length) {
142
+ callback(Object.assign(new Error(`No address for ${host}`), { code: "ENOTFOUND" }));
143
+ }
144
+ else if (options.all) {
145
+ callback(null, usable);
146
+ }
147
+ else {
148
+ callback(null, usable[0].address, usable[0].family);
149
+ }
150
+ }, callback);
151
+ },
152
+ },
153
+ });
154
+ /** fetch that re-checks every redirect hop, so a public URL cannot bounce into the private network. */
155
+ export async function safeFetch(raw, init = {}) {
156
+ let url = await assertPublicUrl(raw);
157
+ for (let hop = 0; hop < 6; hop++) {
158
+ const res = await fetch(url, {
159
+ ...init,
160
+ redirect: "manual",
161
+ dispatcher: pinned,
162
+ });
163
+ const location = res.headers.get("location");
164
+ if (res.status < 300 || res.status >= 400 || !location) {
165
+ return res;
166
+ }
167
+ url = await assertPublicUrl(new URL(location, url).toString());
168
+ }
169
+ throw new Error("Too many redirects.");
170
+ }
@@ -0,0 +1,81 @@
1
+ import { createTool } from "@mastra/core/tools";
2
+ import { z } from "zod";
3
+ import { runPages, writeRunPage } from "../services/space-data.js";
4
+ import { pageReadInput, readKnowledgePage } from "./project.js";
5
+ import { attempt, clip } from "./shared.js";
6
+ /**
7
+ * Pages for a step that lists "pages": Markdown its wizard keeps for every run — notes, a log, a
8
+ * summary that grows — its memory, shown in the studio's Memory tab and under Space → Data. Its
9
+ * page_read also reads the pages of Knowledge, by path. A test run reads the wizard's pages but
10
+ * writes into a copy of its own in the run's state, which goes with the run.
11
+ */
12
+ export function pageTools(ctx) {
13
+ const projectId = ctx.project.id;
14
+ const wizardId = ctx.store.wizardId;
15
+ /** The wizard's pages as this run sees them: a test run's own writes over the real ones. */
16
+ const pages = async () => {
17
+ const real = await runPages(projectId, wizardId);
18
+ const copy = ctx.test ? (ctx.state.memory ?? {}) : {};
19
+ const lower = (t) => t.toLowerCase();
20
+ const written = Object.entries(copy).map(([title, markdown]) => ({ title, markdown }));
21
+ return [
22
+ ...real.filter((p) => !written.some((w) => lower(w.title) === lower(p.title))),
23
+ ...written,
24
+ ].sort((a, b) => a.title.localeCompare(b.title));
25
+ };
26
+ return {
27
+ page_read: createTool({
28
+ id: "page_read",
29
+ description: "Read a page: one this wizard wrote, by its title, or a page of Knowledge, by its path (pages/…). Without either it lists the wizard's pages.",
30
+ inputSchema: z.object({
31
+ title: z.string().optional().describe("A page this wizard wrote"),
32
+ path: pageReadInput.path.optional(),
33
+ section: pageReadInput.section,
34
+ from: pageReadInput.from,
35
+ }),
36
+ execute: ({ title, path, section, from }) => {
37
+ if (path?.trim()) {
38
+ return readKnowledgePage(ctx, { path, section, from });
39
+ }
40
+ return attempt(async () => {
41
+ const all = await pages();
42
+ if (!title?.trim()) {
43
+ return { pages: all.map((p) => ({ title: p.title, chars: p.markdown.length })) };
44
+ }
45
+ const page = all.find((p) => p.title.toLowerCase() === title.trim().toLowerCase());
46
+ if (!page) {
47
+ return { error: `No page "${title}".`, pages: all.map((p) => p.title) };
48
+ }
49
+ return { title: page.title, markdown: clip(page.markdown, 40_000) };
50
+ });
51
+ },
52
+ }),
53
+ page_write: createTool({
54
+ id: "page_write",
55
+ description: "Write a page of this wizard in Markdown, kept for every later run and shown to the admin in the studio. A page with the same title is replaced — or added to with append: true (a log, a list that grows). Pages of Knowledge are read-only.",
56
+ inputSchema: z.object({
57
+ title: z.string().min(1).max(200),
58
+ markdown: z.string().max(200_000),
59
+ append: z.boolean().optional(),
60
+ }),
61
+ execute: (input) => attempt(async () => {
62
+ if (ctx.test) {
63
+ const title = input.title.trim();
64
+ const before = (await pages()).find((p) => p.title.toLowerCase() === title.toLowerCase());
65
+ const markdown = before && input.append
66
+ ? `${before.markdown.trimEnd()}\n\n${input.markdown.trim()}`
67
+ : input.markdown;
68
+ ctx.state.memory = { ...ctx.state.memory, [before?.title ?? title]: markdown };
69
+ await ctx.emit("tool", {
70
+ code: "writesPage",
71
+ params: { title: before?.title ?? title },
72
+ });
73
+ return { title: before?.title ?? title, chars: markdown.length, test: true };
74
+ }
75
+ const page = await writeRunPage(projectId, wizardId, input);
76
+ await ctx.emit("tool", { code: "writesPage", params: { title: page.title } });
77
+ return page;
78
+ }),
79
+ }),
80
+ };
81
+ }
@@ -0,0 +1,180 @@
1
+ import { pluginToolOf } from "@engenty-wizards/shared/definition";
2
+ import { note } from "@engenty-wizards/shared/run";
3
+ import { createTool } from "@mastra/core/tools";
4
+ import { StepError } from "../engine/types.js";
5
+ import { loadedPlugin, pluginIdsOf, pluginsOf } from "../plugins/registry.js";
6
+ import { attempt, clip } from "./shared.js";
7
+ /** The model's name of a plugin's tool: `<plugin>_<tool>`, since a tool name takes no dot. */
8
+ export function pluginToolName(plugin, tool) {
9
+ return `${plugin.replaceAll("-", "_")}_${tool}`;
10
+ }
11
+ /** What a plugin's tool learns of the step that calls it. */
12
+ function toolContext(ctx) {
13
+ const space = { id: ctx.project.id, name: ctx.project.name };
14
+ return {
15
+ runId: ctx.runId,
16
+ stepId: ctx.stepId,
17
+ tenantId: ctx.tenantId,
18
+ space,
19
+ project: space,
20
+ wizard: { id: ctx.store.wizardId, title: ctx.def.title },
21
+ mode: ctx.test ? "test" : "live",
22
+ signal: ctx.signal,
23
+ emit: (message) => ctx.emit("tool", message),
24
+ };
25
+ }
26
+ /** A plugin's tool as an agent step calls it. */
27
+ function stepTool(plugin, tool, ctx) {
28
+ return createTool({
29
+ id: pluginToolName(plugin, tool.name),
30
+ description: tool.description,
31
+ inputSchema: tool.inputSchema,
32
+ execute: (input) => attempt(async () => tool.execute(input, toolContext(ctx))),
33
+ });
34
+ }
35
+ /** A plugin's tool by its `<plugin>.<tool>` id, as this tenant has it; a StepError where it does not. */
36
+ async function toolOf(id, ctx) {
37
+ const named = pluginToolOf(id);
38
+ const has = named ? await pluginIdsOf(ctx.tenantId) : new Set();
39
+ const found = named && has.has(named.plugin) ? loadedPlugin(named.plugin)?.tools.get(named.tool) : undefined;
40
+ if (!(named && found)) {
41
+ const plugin = named?.plugin ?? id;
42
+ throw new StepError(note("stepNeedsToolPlugin", { id, plugin }));
43
+ }
44
+ return { plugin: named.plugin, tool: found };
45
+ }
46
+ /**
47
+ * Calls one plugin tool with its input as it is, no model between: a step's `call`. The input
48
+ * is checked against the tool's schema; what the tool throws is the step's error.
49
+ */
50
+ export async function callPluginTool(id, input, ctx) {
51
+ const { tool } = await toolOf(id, ctx);
52
+ const parsed = tool.inputSchema.safeParse(input);
53
+ if (!parsed.success) {
54
+ const issue = parsed.error.issues[0];
55
+ throw new StepError(note("pluginInvalidInput", {
56
+ id,
57
+ path: issue?.path.join(".") || "input",
58
+ problem: issue?.message ?? "",
59
+ }));
60
+ }
61
+ try {
62
+ return await tool.execute(parsed.data, toolContext(ctx));
63
+ }
64
+ catch (err) {
65
+ throw new StepError(String(err?.message ?? err).slice(0, 400));
66
+ }
67
+ }
68
+ /**
69
+ * The tools of plugins a step allowlists as `<plugin>.<tool>`. A step that names a tool this
70
+ * tenant does not have fails: the wizard was written for a runtime with that plugin.
71
+ */
72
+ export async function pluginTools(step, ctx) {
73
+ const tools = {};
74
+ for (const id of step.tools.filter((t) => pluginToolOf(t) !== null)) {
75
+ const { plugin, tool } = await toolOf(id, ctx);
76
+ tools[pluginToolName(plugin, tool.name)] = stepTool(plugin, tool, ctx);
77
+ }
78
+ return tools;
79
+ }
80
+ /** A block of a plugin is cut here: the step's instructions stay the step's. */
81
+ const MAX_BLOCK = 8000;
82
+ const contexts = new WeakMap();
83
+ /**
84
+ * What the tenant's plugins add to an AI step of a space's wizard (`registerSpaceContext`):
85
+ * asked once per step, for its instructions and for its tools — an agent step's, or an HTML
86
+ * step's blocks. A context that fails adds nothing.
87
+ */
88
+ export function spaceContextOf(ctx) {
89
+ let found = contexts.get(ctx);
90
+ if (!found) {
91
+ found = gather(ctx);
92
+ contexts.set(ctx, found);
93
+ }
94
+ return found;
95
+ }
96
+ async function gather(ctx) {
97
+ const space = { id: ctx.project.id, name: ctx.project.name };
98
+ const result = { blocks: [], html: [], tools: {} };
99
+ for (const plugin of await pluginsOf(ctx.tenantId)) {
100
+ for (const context of plugin.contexts) {
101
+ const steps = context.steps ?? ["agent"];
102
+ const block = await Promise.resolve()
103
+ .then(() => context.block(space))
104
+ .catch((err) => {
105
+ console.error(`[plugin ${plugin.source.id}] space context:`, err);
106
+ return null;
107
+ });
108
+ if (!block?.trim()) {
109
+ continue;
110
+ }
111
+ if (steps.includes("html")) {
112
+ result.html.push(clip(block.trim(), MAX_BLOCK));
113
+ }
114
+ if (!steps.includes("agent")) {
115
+ continue;
116
+ }
117
+ result.blocks.push(clip(block.trim(), MAX_BLOCK));
118
+ for (const tool of context.tools ?? []) {
119
+ result.tools[pluginToolName(plugin.source.id, tool.name)] = stepTool(plugin.source.id, tool, ctx);
120
+ }
121
+ }
122
+ }
123
+ return result;
124
+ }
125
+ /** The tenant's plugins' tools of the space assistant (`registerAssistantTool`). */
126
+ export async function assistantToolsOf(turn) {
127
+ const tools = {};
128
+ for (const plugin of await pluginsOf(turn.tenantId)) {
129
+ for (const tool of plugin.assistantTools.values()) {
130
+ const id = pluginToolName(plugin.source.id, tool.name);
131
+ tools[id] = createTool({
132
+ id,
133
+ description: tool.description,
134
+ inputSchema: tool.inputSchema,
135
+ execute: (input) => attempt(async () => {
136
+ const result = await tool.execute(input, {
137
+ tenantId: turn.tenantId,
138
+ space: turn.space,
139
+ userId: turn.userId,
140
+ signal: turn.signal,
141
+ emit: turn.emit,
142
+ changed: turn.changed,
143
+ });
144
+ if (tool.card) {
145
+ turn.card({ plugin: plugin.source.id, tool: tool.name, data: result ?? null });
146
+ }
147
+ return result;
148
+ }),
149
+ });
150
+ }
151
+ }
152
+ return tools;
153
+ }
154
+ /**
155
+ * The admin talks to the space assistant from a plugin's own page: what the plugin says that page
156
+ * holds now, and its name. `null` when the tenant has no such plugin.
157
+ */
158
+ export async function assistantPageOf(tenantId, pluginId, space) {
159
+ const plugin = (await pluginsOf(tenantId)).find((p) => p.source.id === pluginId);
160
+ if (!plugin) {
161
+ return null;
162
+ }
163
+ const blocks = [];
164
+ for (const page of plugin.assistantPages) {
165
+ try {
166
+ const text = await page.block(space);
167
+ if (text?.trim()) {
168
+ blocks.push(text.trim().slice(0, MAX_BLOCK));
169
+ }
170
+ }
171
+ catch (err) {
172
+ console.error(`[plugins] ${pluginId}: the assistant's page block failed:`, err);
173
+ }
174
+ }
175
+ return {
176
+ name: plugin.source.manifest.name,
177
+ description: plugin.source.manifest.description ?? null,
178
+ blocks,
179
+ };
180
+ }
@@ -0,0 +1,154 @@
1
+ import { whereSchema } from "@engenty-wizards/shared/knowledge";
2
+ import { createTool } from "@mastra/core/tools";
3
+ import { and, eq } from "drizzle-orm";
4
+ import { z } from "zod";
5
+ import { db, schema } from "../db/client.js";
6
+ import { filePaths, knowledgeCounts, listForStep, readPage, readTable, resolvePath, } from "../services/knowledge.js";
7
+ import { documentText, hasIndexEntries, searchKnowledge } from "../services/project-index.js";
8
+ import { attempt, clip } from "./shared.js";
9
+ /**
10
+ * Knowledge, for every agent step of the space's wizards: search it (a question, filtered by
11
+ * categories first, checked by a classifier after), list it by categories, read a page, a table
12
+ * or a file whole by its path. Hits and reads look like files — a path, front matter, Markdown or
13
+ * CSV — so a model reads them as it reads files. The search also finds what the space's plugins
14
+ * put into the index.
15
+ */
16
+ const where = whereSchema
17
+ .optional()
18
+ .describe('Filter by categories before searching, by their names: a value ("Baustelle": "Graz Süd"), a list of values, a range of numbers ({ "gte": 20000 }) or of days ({ "after": "2026-03-01", "before": "2026-03-31" }), { "contains": "…" } for a text, true/false. project_list without arguments names the categories and their values.');
19
+ export const pageReadInput = {
20
+ path: z.string().describe("The page's path, as project_search or project_list give it: pages/…"),
21
+ section: z
22
+ .string()
23
+ .optional()
24
+ .describe("Only this section: a heading of the page, or the start of one"),
25
+ from: z.number().int().min(0).optional().describe("Character to continue a long page at"),
26
+ };
27
+ /** A page of Knowledge by its path, for a step: its front matter and Markdown, in parts. */
28
+ export function readKnowledgePage(ctx, input) {
29
+ return attempt(async () => {
30
+ const read = await readPage(ctx.project.id, input.path, input);
31
+ await ctx.emit("tool", { code: "reads", params: { name: read.path } });
32
+ return read;
33
+ });
34
+ }
35
+ export async function projectTools(ctx) {
36
+ const projectId = ctx.project.id;
37
+ const counts = await knowledgeCounts(projectId);
38
+ const entries = await hasIndexEntries(projectId);
39
+ if (!(counts.pages || counts.tables || counts.files || entries)) {
40
+ return {};
41
+ }
42
+ const tools = {
43
+ project_search: createTool({
44
+ id: "project_search",
45
+ description: "Search the space's Knowledge: its pages, tables and files, and what its plugins keep (wiki pages, questions and answers). Gives items with their path, categories and best section, each checked for relevance. Ask in their language, with the words they would use; filter with `where` when the task names a category's value. Then read the items you need whole with page_read or table_read.",
46
+ inputSchema: z.object({
47
+ query: z.string().describe("What to look for: a question or keywords"),
48
+ where,
49
+ limit: z.number().int().min(1).max(12).optional().describe("Items to get, 6 by default"),
50
+ }),
51
+ execute: (input) => attempt(async () => {
52
+ const found = await searchKnowledge(projectId, input.query, {
53
+ where: input.where,
54
+ limit: input.limit,
55
+ signal: ctx.signal,
56
+ });
57
+ await ctx.emit("tool", {
58
+ code: "searchesKnowledge",
59
+ params: {
60
+ query: input.query.slice(0, 60),
61
+ relevant: found.hits.length,
62
+ candidates: found.candidates,
63
+ },
64
+ });
65
+ return {
66
+ hits: found.hits.map((h) => ({
67
+ ...(h.path ? { path: h.path } : {}),
68
+ title: h.title,
69
+ ...(h.categories.length ? { categories: h.categories } : {}),
70
+ ...(h.heading ? { section: h.heading } : {}),
71
+ ...(h.sheet ? { page: h.sheet } : {}),
72
+ ...(h.relevance !== null ? { relevance: h.relevance } : {}),
73
+ text: clip(h.text, 1500),
74
+ })),
75
+ checked: found.checked,
76
+ candidates: found.candidates,
77
+ ...(found.filtered !== null ? { filtered: found.filtered } : {}),
78
+ };
79
+ }),
80
+ }),
81
+ project_list: createTool({
82
+ id: "project_list",
83
+ description: "List Knowledge by its categories. Without `where`: the categories with their values and how many items each has. With `where`: the items it leaves, with their paths — all of them, where project_search gives the best few.",
84
+ inputSchema: z.object({ where }),
85
+ execute: (input) => attempt(async () => {
86
+ const listed = await listForStep(projectId, input.where);
87
+ await ctx.emit("tool", { code: "listsKnowledge" });
88
+ return listed;
89
+ }),
90
+ }),
91
+ };
92
+ if (counts.pages) {
93
+ tools.page_read = createTool({
94
+ id: "page_read",
95
+ description: "Read a page of Knowledge whole by its path: front matter (title, categories, its source and original, its parent and sub-pages) and its Markdown. Long pages come in parts: pass `from` to continue. `section` reads one section.",
96
+ inputSchema: z.object(pageReadInput),
97
+ execute: (input) => readKnowledgePage(ctx, input),
98
+ });
99
+ }
100
+ if (counts.tables) {
101
+ tools.table_read = createTool({
102
+ id: "table_read",
103
+ description: "Read a table of Knowledge by its path: its rows as CSV, filtered by its columns (by their names, like `where` of project_search). A few hundred rows at a time: pass `offset` to continue.",
104
+ inputSchema: z.object({
105
+ path: z.string().describe("The table's path: tables/…"),
106
+ where: whereSchema.optional().describe("Filter by columns, by their names"),
107
+ columns: z.array(z.string()).max(40).optional().describe("Only these columns"),
108
+ limit: z.number().int().min(1).max(1000).optional(),
109
+ offset: z.number().int().min(0).optional(),
110
+ }),
111
+ execute: (input) => attempt(async () => {
112
+ const read = await readTable(projectId, input.path, input);
113
+ await ctx.emit("tool", { code: "reads", params: { name: read.path } });
114
+ return read;
115
+ }),
116
+ });
117
+ }
118
+ if (counts.files) {
119
+ tools.project_document = createTool({
120
+ id: "project_document",
121
+ description: "Read a file of Knowledge as text by its path (files/…): a file that is not a page, or the original a page was read from. Long files come in parts: pass `from` to continue.",
122
+ inputSchema: z.object({
123
+ path: z
124
+ .string()
125
+ .describe("The file's path: files/…, as the page's front matter or a hit names it"),
126
+ from: z.number().int().min(0).optional().describe("Character to start at"),
127
+ }),
128
+ execute: ({ path, from }) => attempt(async () => {
129
+ const found = await resolvePath(projectId, path.startsWith("files/") ? path : `files/${path}`);
130
+ if (found?.kind !== "file") {
131
+ const there = [...(await filePaths(projectId)).values()].slice(0, 40);
132
+ throw new Error(`No file "${path}". There are: ${there.join(", ")}`);
133
+ }
134
+ const file = await db.query.projectFile.findFirst({
135
+ where: and(eq(schema.projectFile.id, found.id), eq(schema.projectFile.projectId, projectId)),
136
+ });
137
+ if (!file) {
138
+ throw new Error(`No file "${path}".`);
139
+ }
140
+ await ctx.emit("tool", { code: "reads", params: { name: file.name } });
141
+ const text = (await documentText(file)) || file.description;
142
+ const start = Math.min(from ?? 0, text.length);
143
+ const part = text.slice(start, start + 12_000);
144
+ return {
145
+ path: found.path,
146
+ text: clip(part, 12_000),
147
+ next: start + part.length < text.length ? start + part.length : null,
148
+ length: text.length,
149
+ };
150
+ }),
151
+ });
152
+ }
153
+ return tools;
154
+ }
@@ -0,0 +1,69 @@
1
+ import { ServiceError } from "../services/errors.js";
2
+ import { writeStoreFile } from "../store/index.js";
3
+ export const TEXT_LIMIT = 8000;
4
+ export function clip(s, limit = TEXT_LIMIT) {
5
+ return s.length > limit ? `${s.slice(0, limit)}\n…[truncated ${s.length - limit} chars]` : s;
6
+ }
7
+ /**
8
+ * A tool failure is something the model reads and reacts to, never a crashed step or turn. A
9
+ * service's refusal brings its data along (`issues`, `fields`, `column`), so the model can fix
10
+ * what it sent. The message is clipped to `limit` characters (400): a site or an API can answer
11
+ * with a whole page; the studio's agents, whose failures are the runtime's own, pass `Infinity`.
12
+ */
13
+ export async function attempt(run, { limit = 400 } = {}) {
14
+ try {
15
+ return await run();
16
+ }
17
+ catch (err) {
18
+ const error = String(err?.message ?? err).slice(0, limit);
19
+ return err instanceof ServiceError ? { error, ...err.data } : { error };
20
+ }
21
+ }
22
+ /**
23
+ * A tool's `toModelOutput` for a result that carries a picture: the base64 under `key` goes to the
24
+ * model as an image (of `mime`, else PNG), the rest as text beside it – as JSON, or as `text`
25
+ * makes it. A result without the picture, a failure among them, goes as JSON.
26
+ */
27
+ export function imageOutput(key, text = (rest) => JSON.stringify(rest)) {
28
+ return (out) => {
29
+ if (!out || out.error || typeof out[key] !== "string" || !out[key]) {
30
+ return { type: "json", value: out };
31
+ }
32
+ const { [key]: data, mime, ...rest } = out;
33
+ return {
34
+ type: "content",
35
+ value: [
36
+ { type: "text", text: text(rest) },
37
+ { type: "image-data", data, mediaType: mime ?? "image/png" },
38
+ ],
39
+ };
40
+ };
41
+ }
42
+ /**
43
+ * Files a step collects go two places: the wizard's store (kept for next time) and the step's
44
+ * result (this run's download). One keeper per step, so a file saved twice is one result.
45
+ */
46
+ export class FileKeeper {
47
+ ctx;
48
+ assets;
49
+ kept = new Map();
50
+ constructor(ctx, assets) {
51
+ this.ctx = ctx;
52
+ this.assets = assets;
53
+ }
54
+ async keep(rawPath, data, meta) {
55
+ const scope = this.ctx.store;
56
+ const file = await writeStoreFile(scope, rawPath, data, meta);
57
+ if (!this.kept.has(file.path)) {
58
+ const ref = await this.ctx.saveAsset({
59
+ kind: "file",
60
+ mime: file.mime,
61
+ name: file.path.split("/").pop() ?? "file",
62
+ data,
63
+ });
64
+ this.kept.set(file.path, ref);
65
+ this.assets.push(ref);
66
+ }
67
+ return { path: file.path, mime: file.mime, size: file.size };
68
+ }
69
+ }