@engenty/wizards-runtime 0.0.0-stage → 0.7.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (523) hide show
  1. package/LICENSE +110 -0
  2. package/README.md +214 -2
  3. package/apps/runtime/dist/agents/architect.js +444 -0
  4. package/apps/runtime/dist/agents/studio-assistant.js +883 -0
  5. package/apps/runtime/dist/agents/subscription.js +207 -0
  6. package/apps/runtime/dist/agents/thought.js +21 -0
  7. package/apps/runtime/dist/agents/website.js +480 -0
  8. package/apps/runtime/dist/app.js +359 -0
  9. package/apps/runtime/dist/apple/wizards-apple +0 -0
  10. package/apps/runtime/dist/assistant/browser.js +26 -0
  11. package/apps/runtime/dist/assistant/docs.js +158 -0
  12. package/apps/runtime/dist/assistant/knows.js +353 -0
  13. package/apps/runtime/dist/assistant/primer.js +26 -0
  14. package/apps/runtime/dist/assistant/runs.js +24 -0
  15. package/apps/runtime/dist/auth/account.js +175 -0
  16. package/apps/runtime/dist/auth/device.js +112 -0
  17. package/apps/runtime/dist/auth/index.js +358 -0
  18. package/apps/runtime/dist/auth/keys.js +55 -0
  19. package/apps/runtime/dist/auth/local-ticket.js +26 -0
  20. package/apps/runtime/dist/authoring/example.js +74 -0
  21. package/apps/runtime/dist/authoring/guide.js +433 -0
  22. package/apps/runtime/dist/authoring/ops.js +117 -0
  23. package/apps/runtime/dist/browser/fast/action-space.js +160 -0
  24. package/apps/runtime/dist/browser/fast/classifier.js +91 -0
  25. package/apps/runtime/dist/browser/fast/decide.js +171 -0
  26. package/apps/runtime/dist/browser/fast/driver.js +141 -0
  27. package/apps/runtime/dist/browser/fast/instructions.js +33 -0
  28. package/apps/runtime/dist/browser/fast/run.js +249 -0
  29. package/apps/runtime/dist/browser/fast/span-picker.js +153 -0
  30. package/apps/runtime/dist/browser/fast/text-helper.js +178 -0
  31. package/apps/runtime/dist/browser/snapshot.js +335 -0
  32. package/apps/runtime/dist/cli/account.js +385 -0
  33. package/apps/runtime/dist/cli/autostart.js +182 -0
  34. package/apps/runtime/dist/cli/autoupdate.js +221 -0
  35. package/apps/runtime/dist/cli/clients.js +44 -0
  36. package/apps/runtime/dist/cli/connect.js +540 -0
  37. package/apps/runtime/dist/cli/environment.js +95 -0
  38. package/apps/runtime/dist/cli/exec.js +45 -0
  39. package/apps/runtime/dist/cli/features.js +50 -0
  40. package/apps/runtime/dist/cli/home.js +88 -0
  41. package/apps/runtime/dist/cli/install-env.js +33 -0
  42. package/apps/runtime/dist/cli/machine.js +107 -0
  43. package/apps/runtime/dist/cli/main.js +231 -0
  44. package/apps/runtime/dist/cli/mcp.js +136 -0
  45. package/apps/runtime/dist/cli/menu.js +202 -0
  46. package/apps/runtime/dist/cli/processes.js +72 -0
  47. package/apps/runtime/dist/cli/report.js +66 -0
  48. package/apps/runtime/dist/cli/sandbox.js +77 -0
  49. package/apps/runtime/dist/cli/setup.js +335 -0
  50. package/apps/runtime/dist/cli/start.js +276 -0
  51. package/apps/runtime/dist/cli/status.js +212 -0
  52. package/apps/runtime/dist/cli/ui.js +59 -0
  53. package/apps/runtime/dist/cli/uninstall-main.js +20 -0
  54. package/apps/runtime/dist/cli/uninstall.js +231 -0
  55. package/apps/runtime/dist/cli/update.js +86 -0
  56. package/apps/runtime/dist/cli/validate.js +75 -0
  57. package/apps/runtime/dist/cli/versions.js +123 -0
  58. package/apps/runtime/dist/connectors/builtin.js +86 -0
  59. package/apps/runtime/dist/connectors/external.js +409 -0
  60. package/apps/runtime/dist/connectors/gmail.js +107 -0
  61. package/apps/runtime/dist/connectors/imap.js +261 -0
  62. package/apps/runtime/dist/connectors/index.js +325 -0
  63. package/apps/runtime/dist/connectors/mail.js +72 -0
  64. package/apps/runtime/dist/connectors/outlook.js +90 -0
  65. package/apps/runtime/dist/connectors/plugin-connections.js +343 -0
  66. package/apps/runtime/dist/connectors/via-account.js +65 -0
  67. package/apps/runtime/dist/credits/credits.js +100 -0
  68. package/apps/runtime/dist/credits/estimate.js +152 -0
  69. package/apps/runtime/dist/db/adopt.js +149 -0
  70. package/apps/runtime/dist/db/client.js +173 -0
  71. package/apps/runtime/dist/db/control-schema.js +133 -0
  72. package/apps/runtime/dist/db/migrations/control/0000_last_absorbing_man.sql +47 -0
  73. package/apps/runtime/dist/db/migrations/control/0001_gorgeous_nicolaos.sql +41 -0
  74. package/apps/runtime/dist/db/migrations/control/0002_secret_penance.sql +1 -0
  75. package/apps/runtime/dist/db/migrations/control/0003_nasty_mordo.sql +3 -0
  76. package/apps/runtime/dist/db/migrations/control/0004_breezy_eddie_brock.sql +6 -0
  77. package/apps/runtime/dist/db/migrations/control/0005_chilly_oracle.sql +1 -0
  78. package/apps/runtime/dist/db/migrations/control/0006_sleepy_mojo.sql +1 -0
  79. package/apps/runtime/dist/db/migrations/control/0007_common_the_hand.sql +15 -0
  80. package/apps/runtime/dist/db/migrations/control/0008_runner.sql +8 -0
  81. package/apps/runtime/dist/db/migrations/control/0009_plugin_claim.sql +9 -0
  82. package/apps/runtime/dist/db/migrations/control/0010_tan_snowbird.sql +6 -0
  83. package/apps/runtime/dist/db/migrations/control/meta/0000_snapshot.json +311 -0
  84. package/apps/runtime/dist/db/migrations/control/meta/0001_snapshot.json +599 -0
  85. package/apps/runtime/dist/db/migrations/control/meta/0002_snapshot.json +607 -0
  86. package/apps/runtime/dist/db/migrations/control/meta/0003_snapshot.json +311 -0
  87. package/apps/runtime/dist/db/migrations/control/meta/0004_snapshot.json +350 -0
  88. package/apps/runtime/dist/db/migrations/control/meta/0005_snapshot.json +358 -0
  89. package/apps/runtime/dist/db/migrations/control/meta/0006_snapshot.json +365 -0
  90. package/apps/runtime/dist/db/migrations/control/meta/0007_snapshot.json +460 -0
  91. package/apps/runtime/dist/db/migrations/control/meta/0008_snapshot.json +505 -0
  92. package/apps/runtime/dist/db/migrations/control/meta/0009_snapshot.json +561 -0
  93. package/apps/runtime/dist/db/migrations/control/meta/0010_snapshot.json +600 -0
  94. package/apps/runtime/dist/db/migrations/control/meta/_journal.json +83 -0
  95. package/apps/runtime/dist/db/migrations/tenant/0000_eminent_freak.sql +188 -0
  96. package/apps/runtime/dist/db/migrations/tenant/0001_salty_master_chief.sql +1 -0
  97. package/apps/runtime/dist/db/migrations/tenant/0002_cloudy_firebird.sql +1 -0
  98. package/apps/runtime/dist/db/migrations/tenant/0003_brown_warbound.sql +52 -0
  99. package/apps/runtime/dist/db/migrations/tenant/0004_romantic_nocturne.sql +6 -0
  100. package/apps/runtime/dist/db/migrations/tenant/0005_reflective_forgotten_one.sql +2 -0
  101. package/apps/runtime/dist/db/migrations/tenant/0006_hard_war_machine.sql +30 -0
  102. package/apps/runtime/dist/db/migrations/tenant/0007_space_data.sql +43 -0
  103. package/apps/runtime/dist/db/migrations/tenant/0008_run_event_note.sql +1 -0
  104. package/apps/runtime/dist/db/migrations/tenant/0009_knowledge.sql +104 -0
  105. package/apps/runtime/dist/db/migrations/tenant/0010_plugin_connection.sql +15 -0
  106. package/apps/runtime/dist/db/migrations/tenant/0011_runners.sql +2 -0
  107. package/apps/runtime/dist/db/migrations/tenant/0012_assistant_chat.sql +40 -0
  108. package/apps/runtime/dist/db/migrations/tenant/0013_run_origin.sql +1 -0
  109. package/apps/runtime/dist/db/migrations/tenant/0014_run_answer.sql +2 -0
  110. package/apps/runtime/dist/db/migrations/tenant/0015_device_calls.sql +13 -0
  111. package/apps/runtime/dist/db/migrations/tenant/0016_even_trish_tilby.sql +12 -0
  112. package/apps/runtime/dist/db/migrations/tenant/meta/0000_snapshot.json +1323 -0
  113. package/apps/runtime/dist/db/migrations/tenant/meta/0001_snapshot.json +1330 -0
  114. package/apps/runtime/dist/db/migrations/tenant/meta/0002_snapshot.json +1337 -0
  115. package/apps/runtime/dist/db/migrations/tenant/meta/0003_snapshot.json +1605 -0
  116. package/apps/runtime/dist/db/migrations/tenant/meta/0004_snapshot.json +1645 -0
  117. package/apps/runtime/dist/db/migrations/tenant/meta/0005_snapshot.json +1659 -0
  118. package/apps/runtime/dist/db/migrations/tenant/meta/0006_snapshot.json +1696 -0
  119. package/apps/runtime/dist/db/migrations/tenant/meta/0007_snapshot.json +2012 -0
  120. package/apps/runtime/dist/db/migrations/tenant/meta/0008_snapshot.json +2019 -0
  121. package/apps/runtime/dist/db/migrations/tenant/meta/0009_snapshot.json +2837 -0
  122. package/apps/runtime/dist/db/migrations/tenant/meta/0010_snapshot.json +2942 -0
  123. package/apps/runtime/dist/db/migrations/tenant/meta/0011_snapshot.json +2956 -0
  124. package/apps/runtime/dist/db/migrations/tenant/meta/0012_snapshot.json +3132 -0
  125. package/apps/runtime/dist/db/migrations/tenant/meta/0013_snapshot.json +3139 -0
  126. package/apps/runtime/dist/db/migrations/tenant/meta/0014_snapshot.json +3154 -0
  127. package/apps/runtime/dist/db/migrations/tenant/meta/0015_snapshot.json +3243 -0
  128. package/apps/runtime/dist/db/migrations/tenant/meta/0016_snapshot.json +3326 -0
  129. package/apps/runtime/dist/db/migrations/tenant/meta/_journal.json +125 -0
  130. package/apps/runtime/dist/db/schema.js +602 -0
  131. package/apps/runtime/dist/debug.js +197 -0
  132. package/apps/runtime/dist/docs/dev/index.md +41 -0
  133. package/apps/runtime/dist/docs/dev/meta.json +7 -0
  134. package/apps/runtime/dist/docs/dev/plugins/connections.md +74 -0
  135. package/apps/runtime/dist/docs/dev/plugins/events.md +89 -0
  136. package/apps/runtime/dist/docs/dev/plugins/examples.md +101 -0
  137. package/apps/runtime/dist/docs/dev/plugins/index.md +78 -0
  138. package/apps/runtime/dist/docs/dev/plugins/layout.md +90 -0
  139. package/apps/runtime/dist/docs/dev/plugins/meta.json +28 -0
  140. package/apps/runtime/dist/docs/dev/plugins/quick-start.md +94 -0
  141. package/apps/runtime/dist/docs/dev/plugins/reference.md +348 -0
  142. package/apps/runtime/dist/docs/dev/plugins/reloading.md +76 -0
  143. package/apps/runtime/dist/docs/dev/plugins/routes.md +185 -0
  144. package/apps/runtime/dist/docs/dev/plugins/runners.md +230 -0
  145. package/apps/runtime/dist/docs/dev/plugins/server.md +281 -0
  146. package/apps/runtime/dist/docs/dev/plugins/shipping.md +79 -0
  147. package/apps/runtime/dist/docs/dev/plugins/space.md +297 -0
  148. package/apps/runtime/dist/docs/dev/plugins/starters.md +70 -0
  149. package/apps/runtime/dist/docs/dev/plugins/studio.md +363 -0
  150. package/apps/runtime/dist/docs/dev/plugins/styling.md +129 -0
  151. package/apps/runtime/dist/docs/dev/plugins/tables.md +104 -0
  152. package/apps/runtime/dist/docs/dev/plugins/tools.md +139 -0
  153. package/apps/runtime/dist/docs/dev/wizard-format.md +125 -0
  154. package/apps/runtime/dist/docs/meta.json +3 -0
  155. package/apps/runtime/dist/docs/user/ai-apps.md +112 -0
  156. package/apps/runtime/dist/docs/user/assistant.md +77 -0
  157. package/apps/runtime/dist/docs/user/build-a-wizard.md +116 -0
  158. package/apps/runtime/dist/docs/user/command-line.md +86 -0
  159. package/apps/runtime/dist/docs/user/connectors.md +90 -0
  160. package/apps/runtime/dist/docs/user/create-account.md +52 -0
  161. package/apps/runtime/dist/docs/user/data.md +66 -0
  162. package/apps/runtime/dist/docs/user/first-start.md +60 -0
  163. package/apps/runtime/dist/docs/user/index.md +49 -0
  164. package/apps/runtime/dist/docs/user/install.md +123 -0
  165. package/apps/runtime/dist/docs/user/local-only.md +42 -0
  166. package/apps/runtime/dist/docs/user/meta.json +32 -0
  167. package/apps/runtime/dist/docs/user/models.md +156 -0
  168. package/apps/runtime/dist/docs/user/plugins.md +71 -0
  169. package/apps/runtime/dist/docs/user/run.md +98 -0
  170. package/apps/runtime/dist/docs/user/server.md +52 -0
  171. package/apps/runtime/dist/docs/user/space.md +126 -0
  172. package/apps/runtime/dist/docs/user/steps.md +220 -0
  173. package/apps/runtime/dist/docs/user/test-and-share.md +224 -0
  174. package/apps/runtime/dist/docs/user/troubleshooting.md +67 -0
  175. package/apps/runtime/dist/docs/user/wordpress.md +121 -0
  176. package/apps/runtime/dist/documents/parse.js +246 -0
  177. package/apps/runtime/dist/engenty/connections-external/build-connector.js +193 -0
  178. package/apps/runtime/dist/engenty/connections-external/errors.js +11 -0
  179. package/apps/runtime/dist/engenty/connections-external/import-service.js +270 -0
  180. package/apps/runtime/dist/engenty/connections-external/importer/classify.js +34 -0
  181. package/apps/runtime/dist/engenty/connections-external/importer/map-auth.js +185 -0
  182. package/apps/runtime/dist/engenty/connections-external/importer/normalize-mcp.js +63 -0
  183. package/apps/runtime/dist/engenty/connections-external/importer/normalize-openapi.js +130 -0
  184. package/apps/runtime/dist/engenty/connections-external/invoke/http-invoker.js +143 -0
  185. package/apps/runtime/dist/engenty/connections-external/invoke/mcp-client.js +143 -0
  186. package/apps/runtime/dist/engenty/connections-external/net/guarded-fetch.js +119 -0
  187. package/apps/runtime/dist/engenty/connections-external/oauth-dcr.js +88 -0
  188. package/apps/runtime/dist/engenty/connections-external/registry-client.js +336 -0
  189. package/apps/runtime/dist/engenty/connections-external/registry-source.js +82 -0
  190. package/apps/runtime/dist/engenty/connections-external/types.js +7 -0
  191. package/apps/runtime/dist/engenty/connections-github/connector.js +209 -0
  192. package/apps/runtime/dist/engenty/connections-google/connectors/calendar.js +381 -0
  193. package/apps/runtime/dist/engenty/connections-google/connectors/contacts.js +94 -0
  194. package/apps/runtime/dist/engenty/connections-google/connectors/drive.js +290 -0
  195. package/apps/runtime/dist/engenty/connections-google/connectors/gmail.js +567 -0
  196. package/apps/runtime/dist/engenty/connections-google/definitions.js +11 -0
  197. package/apps/runtime/dist/engenty/connections-google/shared.js +73 -0
  198. package/apps/runtime/dist/engenty/connections-hubspot/connector.js +140 -0
  199. package/apps/runtime/dist/engenty/connections-microsoft/action.js +17 -0
  200. package/apps/runtime/dist/engenty/connections-microsoft/graph.js +114 -0
  201. package/apps/runtime/dist/engenty/connections-microsoft/onedrive.js +286 -0
  202. package/apps/runtime/dist/engenty/connections-microsoft/outlook.js +492 -0
  203. package/apps/runtime/dist/engenty/connections-s3/s3.js +328 -0
  204. package/apps/runtime/dist/engenty/connections-sdk/files-capability.js +86 -0
  205. package/apps/runtime/dist/engenty/connections-sdk/oauth2.js +150 -0
  206. package/apps/runtime/dist/engenty/connections-sdk/registry.js +89 -0
  207. package/apps/runtime/dist/engenty/connections-sdk/storage-capability.js +84 -0
  208. package/apps/runtime/dist/engenty/connections-sdk/types.js +30 -0
  209. package/apps/runtime/dist/engenty/connections-slack/connector.js +360 -0
  210. package/apps/runtime/dist/engenty/csv-import/csv-matrix.js +178 -0
  211. package/apps/runtime/dist/engenty/csv-import/import-sources.js +87 -0
  212. package/apps/runtime/dist/engenty/csv-import/parse-csv.js +129 -0
  213. package/apps/runtime/dist/engenty/csv-import/serialize-csv.js +20 -0
  214. package/apps/runtime/dist/engenty/csv-import/types.js +1 -0
  215. package/apps/runtime/dist/engenty/csv-import/xlsx-workbook.js +159 -0
  216. package/apps/runtime/dist/engenty/doc-converter/interface.js +9 -0
  217. package/apps/runtime/dist/engenty/doc-converter/page-break.js +92 -0
  218. package/apps/runtime/dist/engenty/doc-converter/providers/local/index.js +72 -0
  219. package/apps/runtime/dist/engenty/document-scanner/schemas/classifier.js +30 -0
  220. package/apps/runtime/dist/engenty/document-scanner/schemas/index.js +4 -0
  221. package/apps/runtime/dist/engenty/document-scanner/schemas/invoice.js +73 -0
  222. package/apps/runtime/dist/engenty/document-scanner/schemas/receipt.js +63 -0
  223. package/apps/runtime/dist/engenty/document-scanner/schemas/shared.js +40 -0
  224. package/apps/runtime/dist/engenty/search-index/chunks.js +164 -0
  225. package/apps/runtime/dist/engenty/search-index/contracts.js +9 -0
  226. package/apps/runtime/dist/engenty/shims/connections-sdk.js +39 -0
  227. package/apps/runtime/dist/engenty/shims/plugin-sdk.js +1 -0
  228. package/apps/runtime/dist/engenty/shims/web-ingest.js +19 -0
  229. package/apps/runtime/dist/engenty/web-ingest/ssrf.js +277 -0
  230. package/apps/runtime/dist/engine/asks.js +82 -0
  231. package/apps/runtime/dist/engine/decide.js +82 -0
  232. package/apps/runtime/dist/engine/device.js +194 -0
  233. package/apps/runtime/dist/engine/events.js +128 -0
  234. package/apps/runtime/dist/engine/input.js +208 -0
  235. package/apps/runtime/dist/engine/owner.js +32 -0
  236. package/apps/runtime/dist/engine/prepare.js +90 -0
  237. package/apps/runtime/dist/engine/push.js +58 -0
  238. package/apps/runtime/dist/engine/requirements.js +355 -0
  239. package/apps/runtime/dist/engine/resources.js +198 -0
  240. package/apps/runtime/dist/engine/runner.js +970 -0
  241. package/apps/runtime/dist/engine/steps.js +1000 -0
  242. package/apps/runtime/dist/engine/surface.js +91 -0
  243. package/apps/runtime/dist/engine/template.js +240 -0
  244. package/apps/runtime/dist/engine/types.js +4 -0
  245. package/apps/runtime/dist/env.js +279 -0
  246. package/apps/runtime/dist/features.js +123 -0
  247. package/apps/runtime/dist/files/blobs.js +22 -0
  248. package/apps/runtime/dist/files/objects.js +86 -0
  249. package/apps/runtime/dist/files/storage.js +120 -0
  250. package/apps/runtime/dist/files/web-images.js +101 -0
  251. package/apps/runtime/dist/film/project.js +257 -0
  252. package/apps/runtime/dist/film/skills.js +91 -0
  253. package/apps/runtime/dist/film/sounds.js +122 -0
  254. package/apps/runtime/dist/film/step.js +289 -0
  255. package/apps/runtime/dist/film/tools.js +99 -0
  256. package/apps/runtime/dist/geocode.js +58 -0
  257. package/apps/runtime/dist/harness/antigravity.js +129 -0
  258. package/apps/runtime/dist/harness/apple.js +270 -0
  259. package/apps/runtime/dist/harness/claude.js +147 -0
  260. package/apps/runtime/dist/harness/codex.js +229 -0
  261. package/apps/runtime/dist/harness/cursor.js +93 -0
  262. package/apps/runtime/dist/harness/env.js +124 -0
  263. package/apps/runtime/dist/harness/index.js +95 -0
  264. package/apps/runtime/dist/harness/model.js +279 -0
  265. package/apps/runtime/dist/harness/prompt.js +121 -0
  266. package/apps/runtime/dist/harness/terminal.js +194 -0
  267. package/apps/runtime/dist/harness/types.js +7 -0
  268. package/apps/runtime/dist/index.js +113 -0
  269. package/apps/runtime/dist/limits.js +81 -0
  270. package/apps/runtime/dist/link-preview.js +60 -0
  271. package/apps/runtime/dist/log.js +106 -0
  272. package/apps/runtime/dist/manage.js +249 -0
  273. package/apps/runtime/dist/mcp/auth.js +161 -0
  274. package/apps/runtime/dist/mcp/bridge.js +59 -0
  275. package/apps/runtime/dist/mcp/flow-app.js +97 -0
  276. package/apps/runtime/dist/mcp/handler.js +54 -0
  277. package/apps/runtime/dist/mcp/scopes.js +14 -0
  278. package/apps/runtime/dist/mcp/seen.js +65 -0
  279. package/apps/runtime/dist/mcp/tools.js +572 -0
  280. package/apps/runtime/dist/media/conversation.js +167 -0
  281. package/apps/runtime/dist/media/ffmpeg.js +121 -0
  282. package/apps/runtime/dist/media/generate.js +120 -0
  283. package/apps/runtime/dist/media/marking.js +121 -0
  284. package/apps/runtime/dist/media/transcribe.js +198 -0
  285. package/apps/runtime/dist/model-errors.js +42 -0
  286. package/apps/runtime/dist/models.js +1164 -0
  287. package/apps/runtime/dist/plugin.js +61 -0
  288. package/apps/runtime/dist/plugins/channels.js +78 -0
  289. package/apps/runtime/dist/plugins/claims.js +56 -0
  290. package/apps/runtime/dist/plugins/discovery.js +155 -0
  291. package/apps/runtime/dist/plugins/events.js +63 -0
  292. package/apps/runtime/dist/plugins/jobs.js +64 -0
  293. package/apps/runtime/dist/plugins/loader.js +508 -0
  294. package/apps/runtime/dist/plugins/migrations.js +69 -0
  295. package/apps/runtime/dist/plugins/pro-keys.js +34 -0
  296. package/apps/runtime/dist/plugins/pro-state.js +83 -0
  297. package/apps/runtime/dist/plugins/pro.js +310 -0
  298. package/apps/runtime/dist/plugins/public.js +44 -0
  299. package/apps/runtime/dist/plugins/registry.js +122 -0
  300. package/apps/runtime/dist/plugins/runs.js +210 -0
  301. package/apps/runtime/dist/render/browser-path.js +54 -0
  302. package/apps/runtime/dist/render/chromium.js +98 -0
  303. package/apps/runtime/dist/render/convert.js +158 -0
  304. package/apps/runtime/dist/render/downloads.js +299 -0
  305. package/apps/runtime/dist/render/guard.js +25 -0
  306. package/apps/runtime/dist/render/shaped.js +137 -0
  307. package/apps/runtime/dist/routes/api.js +440 -0
  308. package/apps/runtime/dist/routes/debug.js +42 -0
  309. package/apps/runtime/dist/routes/delivery.js +90 -0
  310. package/apps/runtime/dist/routes/internal.js +81 -0
  311. package/apps/runtime/dist/routes/lang.js +25 -0
  312. package/apps/runtime/dist/routes/marketplace.js +43 -0
  313. package/apps/runtime/dist/routes/plugin-public.js +113 -0
  314. package/apps/runtime/dist/routes/plugins.js +212 -0
  315. package/apps/runtime/dist/routes/runs.js +1422 -0
  316. package/apps/runtime/dist/routes/studio.js +1629 -0
  317. package/apps/runtime/dist/routes/wizard-stream.js +30 -0
  318. package/apps/runtime/dist/running.js +39 -0
  319. package/apps/runtime/dist/sandbox/agentos-package.js +73 -0
  320. package/apps/runtime/dist/sandbox/agentos.js +162 -0
  321. package/apps/runtime/dist/sandbox/docker.js +45 -0
  322. package/apps/runtime/dist/sandbox/index.js +52 -0
  323. package/apps/runtime/dist/sandbox/install.js +122 -0
  324. package/apps/runtime/dist/sandbox/mastra.js +71 -0
  325. package/apps/runtime/dist/sandbox/types.js +1 -0
  326. package/apps/runtime/dist/secrets/crypto.js +28 -0
  327. package/apps/runtime/dist/secrets/signing.js +52 -0
  328. package/apps/runtime/dist/secrets/vault.js +59 -0
  329. package/apps/runtime/dist/services/access.js +88 -0
  330. package/apps/runtime/dist/services/api.js +248 -0
  331. package/apps/runtime/dist/services/architect.js +95 -0
  332. package/apps/runtime/dist/services/assistant-chats.js +311 -0
  333. package/apps/runtime/dist/services/brand.js +85 -0
  334. package/apps/runtime/dist/services/cloud.js +456 -0
  335. package/apps/runtime/dist/services/draft-events.js +27 -0
  336. package/apps/runtime/dist/services/engenty-shapes.js +71 -0
  337. package/apps/runtime/dist/services/errors.js +29 -0
  338. package/apps/runtime/dist/services/files.js +178 -0
  339. package/apps/runtime/dist/services/knowledge-model.js +559 -0
  340. package/apps/runtime/dist/services/knowledge.js +721 -0
  341. package/apps/runtime/dist/services/links.js +16 -0
  342. package/apps/runtime/dist/services/marketplace.js +492 -0
  343. package/apps/runtime/dist/services/onboarding.js +152 -0
  344. package/apps/runtime/dist/services/package-file.js +82 -0
  345. package/apps/runtime/dist/services/package.js +170 -0
  346. package/apps/runtime/dist/services/profile.js +51 -0
  347. package/apps/runtime/dist/services/project-files.js +439 -0
  348. package/apps/runtime/dist/services/project-index.js +707 -0
  349. package/apps/runtime/dist/services/projects.js +387 -0
  350. package/apps/runtime/dist/services/relevance.js +58 -0
  351. package/apps/runtime/dist/services/runners.js +178 -0
  352. package/apps/runtime/dist/services/runs.js +524 -0
  353. package/apps/runtime/dist/services/shares.js +130 -0
  354. package/apps/runtime/dist/services/site.js +270 -0
  355. package/apps/runtime/dist/services/space-categories.js +861 -0
  356. package/apps/runtime/dist/services/space-data.js +792 -0
  357. package/apps/runtime/dist/services/space-origin.js +207 -0
  358. package/apps/runtime/dist/services/spaces.js +657 -0
  359. package/apps/runtime/dist/services/translations.js +306 -0
  360. package/apps/runtime/dist/services/widgets.js +34 -0
  361. package/apps/runtime/dist/services/wizard-icon.js +157 -0
  362. package/apps/runtime/dist/services/wizards.js +420 -0
  363. package/apps/runtime/dist/settings.js +16 -0
  364. package/apps/runtime/dist/store/errors.js +4 -0
  365. package/apps/runtime/dist/store/index.js +299 -0
  366. package/apps/runtime/dist/store/shared-lists.js +123 -0
  367. package/apps/runtime/dist/tenants/control.js +238 -0
  368. package/apps/runtime/dist/tenants/tenant.js +26 -0
  369. package/apps/runtime/dist/texts.js +207 -0
  370. package/apps/runtime/dist/tools/browser.js +703 -0
  371. package/apps/runtime/dist/tools/connector.js +204 -0
  372. package/apps/runtime/dist/tools/index.js +291 -0
  373. package/apps/runtime/dist/tools/mail.js +104 -0
  374. package/apps/runtime/dist/tools/net-guard.js +170 -0
  375. package/apps/runtime/dist/tools/pages.js +81 -0
  376. package/apps/runtime/dist/tools/plugin.js +180 -0
  377. package/apps/runtime/dist/tools/project.js +154 -0
  378. package/apps/runtime/dist/tools/shared.js +69 -0
  379. package/apps/runtime/dist/tools/store.js +238 -0
  380. package/apps/runtime/dist/update.js +113 -0
  381. package/apps/runtime/dist/widgets/bundle.js +99 -0
  382. package/apps/runtime/dist/widgets/render.js +329 -0
  383. package/apps/runtime/dist/widgets/runtime.js +108 -0
  384. package/apps/runtime/dist/widgets/script.js +30 -0
  385. package/apps/runtime/dist/widgets/step.js +223 -0
  386. package/apps/web/dist/ai-labels/ai-black.svg +20 -0
  387. package/apps/web/dist/ai-labels/ai-generated-black.svg +31 -0
  388. package/apps/web/dist/ai-labels/ai-generated-white.svg +32 -0
  389. package/apps/web/dist/ai-labels/ai-modified-black.svg +30 -0
  390. package/apps/web/dist/ai-labels/ai-modified-white.svg +31 -0
  391. package/apps/web/dist/ai-labels/ai-white.svg +21 -0
  392. package/apps/web/dist/assets/AboutDialog-DYgXPagX.js +1 -0
  393. package/apps/web/dist/assets/ChangelogDialog-BXqBW8j3.js +1 -0
  394. package/apps/web/dist/assets/ChatView-CK2--tsE.js +10 -0
  395. package/apps/web/dist/assets/EditorPage-jvcwyXbU.js +3 -0
  396. package/apps/web/dist/assets/FlowPreview-CusP7ci9.js +1 -0
  397. package/apps/web/dist/assets/Harness-BrP-ENHg.css +1 -0
  398. package/apps/web/dist/assets/Harness-CV9uYzbv.js +16 -0
  399. package/apps/web/dist/assets/NewWizardChannels-BakW5q6s.js +1 -0
  400. package/apps/web/dist/assets/NewWizardPage-BoA-LJuW.js +7 -0
  401. package/apps/web/dist/assets/OnboardingPage-DaD1XnOe.js +1 -0
  402. package/apps/web/dist/assets/ProjectPage-BFgk1DEv.js +1 -0
  403. package/apps/web/dist/assets/PublicRunner-C9MwEvxy.js +1 -0
  404. package/apps/web/dist/assets/ReadOnly-DC2Kp7l8.js +1 -0
  405. package/apps/web/dist/assets/RunDrawer-CY6NZSrI.js +4 -0
  406. package/apps/web/dist/assets/RunnerView-BT26XgcY.js +1 -0
  407. package/apps/web/dist/assets/SettingsPage-AFt9IDLt.js +1 -0
  408. package/apps/web/dist/assets/SetupPage-DtFYAbwJ.js +1 -0
  409. package/apps/web/dist/assets/SharePage-t2xwNS61.js +1 -0
  410. package/apps/web/dist/assets/changelog-CATQFxCQ.js +1 -0
  411. package/apps/web/dist/assets/engenty-eXZ-EAwd.js +1 -0
  412. package/apps/web/dist/assets/esm-DXeMu8Lb.js +7 -0
  413. package/apps/web/dist/assets/fluffy-engenty-ClRou7yu.js +456 -0
  414. package/apps/web/dist/assets/index-AfUa8xKD.css +1 -0
  415. package/apps/web/dist/assets/index-Drw7FMTQ.js +14 -0
  416. package/apps/web/dist/assets/jsx-runtime-BNakU3Ej.js +1 -0
  417. package/apps/web/dist/assets/lock-R_CfU0Xo.js +1 -0
  418. package/apps/web/dist/assets/oss-credits-cZ9NUaLZ.js +1 -0
  419. package/apps/web/dist/assets/pdfmake-Cx9scTbD.js +228 -0
  420. package/apps/web/dist/assets/phone-CgrIS4_-.js +1 -0
  421. package/apps/web/dist/assets/preload-helper-CNEI7N0N.js +1 -0
  422. package/apps/web/dist/assets/qr-scanner-worker.min-CJaXo3yu.js +98 -0
  423. package/apps/web/dist/assets/qr-scanner.min-C_UI0gH-.js +1 -0
  424. package/apps/web/dist/assets/rolldown-runtime-hePW80VL.js +1 -0
  425. package/apps/web/dist/assets/settings-menu-2IMOOlLl.js +1 -0
  426. package/apps/web/dist/assets/ui-dzGvc3xk.js +137 -0
  427. package/apps/web/dist/assets/upload-BSuTilFF.js +1 -0
  428. package/apps/web/dist/assets/vfs_fonts-DllDSYt1.js +1 -0
  429. package/apps/web/dist/embed.js +266 -0
  430. package/apps/web/dist/favicon.svg +1 -0
  431. package/apps/web/dist/icons/apple-touch-icon.png +0 -0
  432. package/apps/web/dist/icons/icon-192.png +0 -0
  433. package/apps/web/dist/icons/icon-512.png +0 -0
  434. package/apps/web/dist/icons/icon-maskable-512.png +0 -0
  435. package/apps/web/dist/index.html +48 -0
  436. package/apps/web/dist/install.sh +577 -0
  437. package/apps/web/dist/manifest.webmanifest +21 -0
  438. package/apps/web/dist/mcp/flow.html +980 -0
  439. package/apps/web/dist/sw.js +15 -0
  440. package/bin/wizards.mjs +288 -0
  441. package/modules/README.md +15 -0
  442. package/node_modules/@engenty/wizards/dist/plugin/index.d.ts +1150 -0
  443. package/node_modules/@engenty/wizards/dist/plugin/index.js +4 -0
  444. package/node_modules/@engenty/wizards/dist/plugin/studio.d.ts +322 -0
  445. package/node_modules/@engenty/wizards/dist/plugin/studio.js +4 -0
  446. package/node_modules/@engenty/wizards/dist/plugin/thread.d.ts +174 -0
  447. package/node_modules/@engenty/wizards/dist/plugin/thread.js +821 -0
  448. package/node_modules/@engenty/wizards/package.json +11 -0
  449. package/node_modules/@engenty-wizards/shared/dist/assistant.d.ts +174 -0
  450. package/node_modules/@engenty-wizards/shared/dist/assistant.js +65 -0
  451. package/node_modules/@engenty-wizards/shared/dist/changes.d.ts +22 -0
  452. package/node_modules/@engenty-wizards/shared/dist/changes.js +61 -0
  453. package/node_modules/@engenty-wizards/shared/dist/connectors.d.ts +77 -0
  454. package/node_modules/@engenty-wizards/shared/dist/connectors.js +2 -0
  455. package/node_modules/@engenty-wizards/shared/dist/decision.d.ts +76 -0
  456. package/node_modules/@engenty-wizards/shared/dist/decision.js +147 -0
  457. package/node_modules/@engenty-wizards/shared/dist/definition.d.ts +2922 -0
  458. package/node_modules/@engenty-wizards/shared/dist/definition.js +1920 -0
  459. package/node_modules/@engenty-wizards/shared/dist/engenty/data-tables/columns-format.d.ts +5 -0
  460. package/node_modules/@engenty-wizards/shared/dist/engenty/data-tables/columns-format.js +132 -0
  461. package/node_modules/@engenty-wizards/shared/dist/engenty/data-tables/columns-value.d.ts +11 -0
  462. package/node_modules/@engenty-wizards/shared/dist/engenty/data-tables/columns-value.js +209 -0
  463. package/node_modules/@engenty-wizards/shared/dist/engenty/data-tables/columns.d.ts +532 -0
  464. package/node_modules/@engenty-wizards/shared/dist/engenty/data-tables/columns.js +217 -0
  465. package/node_modules/@engenty-wizards/shared/dist/engenty/data-tables/index.d.ts +3 -0
  466. package/node_modules/@engenty-wizards/shared/dist/engenty/data-tables/index.js +3 -0
  467. package/node_modules/@engenty-wizards/shared/dist/engenty/search-index/catalog-lexical.d.ts +14 -0
  468. package/node_modules/@engenty-wizards/shared/dist/engenty/search-index/catalog-lexical.js +166 -0
  469. package/node_modules/@engenty-wizards/shared/dist/engenty/search-index/catalog-rank.d.ts +33 -0
  470. package/node_modules/@engenty-wizards/shared/dist/engenty/search-index/catalog-rank.js +99 -0
  471. package/node_modules/@engenty-wizards/shared/dist/feature-flags.d.ts +78 -0
  472. package/node_modules/@engenty-wizards/shared/dist/feature-flags.js +70 -0
  473. package/node_modules/@engenty-wizards/shared/dist/features.d.ts +41 -0
  474. package/node_modules/@engenty-wizards/shared/dist/features.js +89 -0
  475. package/node_modules/@engenty-wizards/shared/dist/fit.d.ts +71 -0
  476. package/node_modules/@engenty-wizards/shared/dist/fit.js +382 -0
  477. package/node_modules/@engenty-wizards/shared/dist/json-schema.d.ts +14 -0
  478. package/node_modules/@engenty-wizards/shared/dist/json-schema.js +66 -0
  479. package/node_modules/@engenty-wizards/shared/dist/knowledge.d.ts +199 -0
  480. package/node_modules/@engenty-wizards/shared/dist/knowledge.js +68 -0
  481. package/node_modules/@engenty-wizards/shared/dist/marketplace-entry.d.ts +35 -0
  482. package/node_modules/@engenty-wizards/shared/dist/marketplace-entry.js +107 -0
  483. package/node_modules/@engenty-wizards/shared/dist/marketplace-search.d.ts +20 -0
  484. package/node_modules/@engenty-wizards/shared/dist/marketplace-search.js +136 -0
  485. package/node_modules/@engenty-wizards/shared/dist/marketplace.d.ts +227 -0
  486. package/node_modules/@engenty-wizards/shared/dist/marketplace.js +354 -0
  487. package/node_modules/@engenty-wizards/shared/dist/merge.d.ts +7 -0
  488. package/node_modules/@engenty-wizards/shared/dist/merge.js +40 -0
  489. package/node_modules/@engenty-wizards/shared/dist/numbers.d.ts +24 -0
  490. package/node_modules/@engenty-wizards/shared/dist/numbers.js +54 -0
  491. package/node_modules/@engenty-wizards/shared/dist/projects.d.ts +224 -0
  492. package/node_modules/@engenty-wizards/shared/dist/projects.js +319 -0
  493. package/node_modules/@engenty-wizards/shared/dist/providers.d.ts +101 -0
  494. package/node_modules/@engenty-wizards/shared/dist/providers.js +390 -0
  495. package/node_modules/@engenty-wizards/shared/dist/run.d.ts +680 -0
  496. package/node_modules/@engenty-wizards/shared/dist/run.js +620 -0
  497. package/node_modules/@engenty-wizards/shared/dist/runner-texts.d.ts +546 -0
  498. package/node_modules/@engenty-wizards/shared/dist/runner-texts.js +523 -0
  499. package/node_modules/@engenty-wizards/shared/dist/runners.d.ts +93 -0
  500. package/node_modules/@engenty-wizards/shared/dist/runners.js +146 -0
  501. package/node_modules/@engenty-wizards/shared/dist/shape.d.ts +102 -0
  502. package/node_modules/@engenty-wizards/shared/dist/shape.js +318 -0
  503. package/node_modules/@engenty-wizards/shared/dist/space-data.d.ts +89 -0
  504. package/node_modules/@engenty-wizards/shared/dist/space-data.js +47 -0
  505. package/node_modules/@engenty-wizards/shared/dist/store.d.ts +117 -0
  506. package/node_modules/@engenty-wizards/shared/dist/store.js +81 -0
  507. package/node_modules/@engenty-wizards/shared/dist/surface.d.ts +115 -0
  508. package/node_modules/@engenty-wizards/shared/dist/surface.js +442 -0
  509. package/node_modules/@engenty-wizards/shared/dist/texts.d.ts +45 -0
  510. package/node_modules/@engenty-wizards/shared/dist/texts.js +54 -0
  511. package/node_modules/@engenty-wizards/shared/dist/translation.d.ts +23 -0
  512. package/node_modules/@engenty-wizards/shared/dist/translation.js +154 -0
  513. package/node_modules/@engenty-wizards/shared/dist/wizard-package.d.ts +48 -0
  514. package/node_modules/@engenty-wizards/shared/dist/wizard-package.js +49 -0
  515. package/node_modules/@engenty-wizards/shared/dist/workspace.d.ts +16 -0
  516. package/node_modules/@engenty-wizards/shared/dist/workspace.js +51 -0
  517. package/node_modules/@engenty-wizards/shared/package.json +10 -0
  518. package/package.json +77 -4
  519. package/plugin/.claude-plugin/plugin.json +9 -0
  520. package/plugin/.mcp.json +8 -0
  521. package/plugin/commands/wizard.md +8 -0
  522. package/plugin/skills/build-wizard/SKILL.md +27 -0
  523. package/plugin/skills/use-wizard/SKILL.md +18 -0
@@ -0,0 +1,204 @@
1
+ import { createTool } from "@mastra/core/tools";
2
+ import { z } from "zod";
3
+ import { refreshConnector, resolveConnector } from "../connectors/external.js";
4
+ import { connectionContext } from "../connectors/index.js";
5
+ import { attempt, clip } from "./shared.js";
6
+ import { resolveFile } from "./store.js";
7
+ const FILE_NOTE = " File content never passes through you: returned content is kept as a file and you get its path; to send a kept file, give `file:<path>` where an input asks for `*_base64`.";
8
+ /** Above this many actions a connector is offered as "find an action, then call it". */
9
+ const DIRECT_TOOLS = 24;
10
+ const TOOL_NAME = /^[a-zA-Z0-9_-]{1,64}$/;
11
+ /**
12
+ * The actions of imported connectors a step may use, as tools. Reading is free; anything that
13
+ * changes the person's account waits for their yes — engenty's default policy for connectors
14
+ * (read: allow, write and destructive: ask), asked of the person who is running the wizard.
15
+ */
16
+ export async function connectorTools(step, ctx, files) {
17
+ const tools = {};
18
+ const connections = (ctx.def.connections ?? []).filter((c) => c.connector && step.connections?.includes(c.id));
19
+ for (const connection of connections) {
20
+ Object.assign(tools, await toolsOf(connection, ctx, files));
21
+ }
22
+ return tools;
23
+ }
24
+ const MAGIC = [
25
+ ["%PDF", "application/pdf", "pdf"],
26
+ ["\x89PNG", "image/png", "png"],
27
+ ["\xff\xd8\xff", "image/jpeg", "jpg"],
28
+ ["GIF8", "image/gif", "gif"],
29
+ ["PK\x03\x04", "application/zip", "zip"],
30
+ ];
31
+ /** What a file is, by its first bytes — connectors often hand over content without a name. */
32
+ function sniff(data) {
33
+ const head = data.subarray(0, 8).toString("latin1");
34
+ const hit = MAGIC.find(([magic]) => head.startsWith(magic));
35
+ return hit ? { mime: hit[1], ext: hit[2] } : null;
36
+ }
37
+ /**
38
+ * A model cannot carry a file: content an action returns as base64 is kept in the wizard's
39
+ * files and the result names the path instead.
40
+ */
41
+ async function keepContent(result, action, service, files) {
42
+ if (!result || typeof result !== "object" || Array.isArray(result)) {
43
+ return result;
44
+ }
45
+ const out = { ...result };
46
+ for (const [key, value] of Object.entries(out)) {
47
+ if (!key.endsWith("_base64") || typeof value !== "string" || !value) {
48
+ continue;
49
+ }
50
+ const data = Buffer.from(value, "base64");
51
+ const kind = sniff(data);
52
+ const given = [out.name, out.filename, out.file_name].find((v) => typeof v === "string" && v.length > 0);
53
+ const name = given ?? `${action.id}-${Date.now().toString(36)}.${kind?.ext ?? "bin"}`;
54
+ const declared = [out.mime_type, out.mimeType, out.content_type].find((v) => typeof v === "string");
55
+ const kept = await files.keep(`${service}/${name}`, data, {
56
+ mime: declared ?? kind?.mime,
57
+ source: `${service}: ${action.summary || action.id}`,
58
+ });
59
+ delete out[key];
60
+ out.saved = kept.path;
61
+ out.note = "The content is kept as a file; read it with read_document.";
62
+ }
63
+ return out;
64
+ }
65
+ /** The other way round: `file:<path>` in a `*_base64` input sends a kept file or an upload. */
66
+ async function sendContent(input, ctx) {
67
+ if (!input || typeof input !== "object" || Array.isArray(input)) {
68
+ return input;
69
+ }
70
+ const out = { ...input };
71
+ for (const [key, value] of Object.entries(out)) {
72
+ if (key.endsWith("_base64") && typeof value === "string" && value.startsWith("file:")) {
73
+ const file = await resolveFile(ctx, value.slice("file:".length));
74
+ out[key] = Buffer.from(file.data).toString("base64");
75
+ }
76
+ }
77
+ return out;
78
+ }
79
+ /**
80
+ * Whether the person is asked before an action runs. The wizard's author can settle it per
81
+ * action (a server may call a plain lookup a change); deleting is never taken off the person.
82
+ */
83
+ function asks(connection, action) {
84
+ if (action.group === "destructive") {
85
+ return true;
86
+ }
87
+ return (connection.policy?.[action.id] ?? (action.group === "read" ? "allow" : "ask")) === "ask";
88
+ }
89
+ async function toolsOf(connection, ctx, files) {
90
+ const projectId = ctx.project.id;
91
+ const id = connection.connector ?? "";
92
+ let resolved = await resolveConnector(projectId, id);
93
+ if (!resolved) {
94
+ return {};
95
+ }
96
+ const account = () => connectionContext(ctx.store, connection, projectId);
97
+ // An MCP server that lists its tools only to a signed-in account: ask it now that there is one.
98
+ if (resolved.imported && !resolved.connector.actions.length) {
99
+ const found = await account();
100
+ if (found) {
101
+ await refreshConnector(projectId, id, found.ctx.accessToken).catch(() => undefined);
102
+ resolved = (await resolveConnector(projectId, id)) ?? resolved;
103
+ }
104
+ }
105
+ const { connector, inputSchema } = resolved;
106
+ const usable = connection.actions
107
+ ? connector.actions.filter((a) => connection.actions?.includes(a.id))
108
+ : connector.actions.filter((a) => a.group === "read");
109
+ const service = connection.title ?? connector.name;
110
+ const call = (action, input) => attempt(async () => {
111
+ const found = await account();
112
+ if (!found) {
113
+ return {
114
+ error: `The person has not connected ${service}. Go on without it and say so in your result.`,
115
+ };
116
+ }
117
+ const key = `${connection.id}:${action.id}`;
118
+ if (asks(connection, action) && !ctx.resources.allowed.has(key)) {
119
+ const answer = await ctx.ask({
120
+ kind: "confirm",
121
+ reason: action.summary || action.id,
122
+ service,
123
+ action: {
124
+ id: action.id,
125
+ summary: action.summary,
126
+ destructive: action.group === "destructive",
127
+ },
128
+ input: JSON.stringify(input ?? {}, null, 2).slice(0, 4000),
129
+ });
130
+ if (!answer) {
131
+ return {
132
+ error: "Nobody is there to allow this change, so it was not made. Report it as open in your result.",
133
+ };
134
+ }
135
+ if (answer.type !== "done") {
136
+ return {
137
+ error: "The person did not allow this change. Do not try it again; say in your result that it was not made.",
138
+ };
139
+ }
140
+ if (answer.remember) {
141
+ ctx.resources.allowed.add(key);
142
+ }
143
+ }
144
+ await ctx.emit("tool", `${service}: ${action.summary || action.id}`.slice(0, 120));
145
+ const result = await keepContent(await action.handler(await sendContent(input ?? {}, ctx), found.ctx), action, service, files);
146
+ const text = typeof result === "string" ? result : JSON.stringify(result);
147
+ return { result: clip(text ?? "", 8000) };
148
+ });
149
+ const prefix = connector.toolPrefix;
150
+ const direct = usable.length <= DIRECT_TOOLS && usable.every((a) => TOOL_NAME.test(`${prefix}_${a.id}`));
151
+ if (direct) {
152
+ return Object.fromEntries(usable.map((action) => [
153
+ `${prefix}_${action.id}`,
154
+ createTool({
155
+ id: `${prefix}_${action.id}`,
156
+ description: `${service}: ${action.description || action.summary}${asks(connection, action) ? " — the person is asked before this runs." : ""}${FILE_NOTE}`.slice(0, 1100),
157
+ inputSchema: action.inputSchema,
158
+ execute: (input) => call(action, input),
159
+ }),
160
+ ]));
161
+ }
162
+ return {
163
+ [`${prefix}_actions`]: createTool({
164
+ id: `${prefix}_actions`,
165
+ description: `${service} offers ${usable.length} actions. Find the ones you need by words from their name or purpose; you get each action's id, what it does and its input. Then call ${prefix}_call.`,
166
+ inputSchema: z.object({
167
+ query: z.string().describe("Words to look for, e.g. 'search pages' or 'invoice list'."),
168
+ }),
169
+ execute: ({ query }) => attempt(async () => {
170
+ const words = query.toLowerCase().split(/\s+/).filter(Boolean);
171
+ const scored = usable
172
+ .map((a) => {
173
+ const text = `${a.id} ${a.summary} ${a.description}`.toLowerCase();
174
+ return { a, score: words.filter((w) => text.includes(w)).length };
175
+ })
176
+ .filter((x) => x.score > 0)
177
+ .sort((x, y) => y.score - x.score)
178
+ .slice(0, 12);
179
+ return {
180
+ actions: scored.map(({ a }) => ({
181
+ id: a.id,
182
+ does: a.summary || a.description.slice(0, 200),
183
+ asks_person_first: asks(connection, a),
184
+ input: inputSchema(a.id),
185
+ })),
186
+ };
187
+ }),
188
+ }),
189
+ [`${prefix}_call`]: createTool({
190
+ id: `${prefix}_call`,
191
+ description: `Run one ${service} action found with ${prefix}_actions. Some wait for the person's yes first.${FILE_NOTE}`,
192
+ inputSchema: z.object({
193
+ action: z.string(),
194
+ input: z.record(z.string(), z.unknown()).optional(),
195
+ }),
196
+ execute: ({ action: id, input }) => {
197
+ const action = usable.find((a) => a.id === id);
198
+ return action
199
+ ? call(action, input)
200
+ : Promise.resolve({ error: `No action "${id}". Use ${prefix}_actions to find one.` });
201
+ },
202
+ }),
203
+ };
204
+ }
@@ -0,0 +1,291 @@
1
+ import { anthropic } from "@ai-sdk/anthropic";
2
+ import { isTextMime } from "@engenty-wizards/shared/workspace";
3
+ import { createTool } from "@mastra/core/tools";
4
+ import { MCPClient } from "@mastra/mcp";
5
+ import { z } from "zod";
6
+ import { documentMime, parseDocument } from "../documents/parse.js";
7
+ import { generateImageMedia } from "../media/generate.js";
8
+ import { markMedia } from "../media/marking.js";
9
+ import { gatewayTools, isHarnessVendor } from "../models.js";
10
+ import { htmlToMarkdown } from "../render/convert.js";
11
+ import { sandboxCapabilities, shellToolDescription } from "../sandbox/index.js";
12
+ import { snapshotFile } from "../services/files.js";
13
+ import { hasStoreFiles } from "../store/index.js";
14
+ import { browserTools } from "./browser.js";
15
+ import { connectorTools } from "./connector.js";
16
+ import { mailTools } from "./mail.js";
17
+ import { assertPublicUrl, safeFetch } from "./net-guard.js";
18
+ import { pageTools } from "./pages.js";
19
+ import { pluginTools, spaceContextOf } from "./plugin.js";
20
+ import { projectTools } from "./project.js";
21
+ import { clip, FileKeeper } from "./shared.js";
22
+ import { storeTools } from "./store.js";
23
+ /**
24
+ * Whether a fetched body is text a model can read: a text type, or no type and next to no
25
+ * bytes that only decode as replacement or control characters.
26
+ */
27
+ function isReadable(type, body) {
28
+ if (isTextMime(type) ||
29
+ type.includes("html") ||
30
+ type.includes("xml") ||
31
+ type.includes("json") ||
32
+ type.includes("javascript")) {
33
+ return true;
34
+ }
35
+ if (type && type !== "application/octet-stream") {
36
+ return false;
37
+ }
38
+ const sample = body.slice(0, 4000);
39
+ let odd = 0;
40
+ for (let i = 0; i < sample.length; i++) {
41
+ const code = sample.charCodeAt(i);
42
+ if (code === 0xfffd || code < 0x09 || (code > 0x0d && code < 0x20)) {
43
+ odd++;
44
+ }
45
+ }
46
+ return odd <= sample.length * 0.01;
47
+ }
48
+ /**
49
+ * Whether a step has no use for the wizard's store: it declares no tools and no connections,
50
+ * got no uploads, and the wizard keeps no lists. Its files may still be there (`buildStepTools`).
51
+ */
52
+ export function storeIdle(step, lists, uploads) {
53
+ return step.tools.length === 0 && !step.connections?.length && lists === 0 && uploads === 0;
54
+ }
55
+ /** The tools an agent step may use: exactly what its definition allowlists. */
56
+ export async function buildStepTools(step, ctx, resolved, uploads) {
57
+ const tools = {};
58
+ const assets = [];
59
+ const allowed = new Set(step.tools);
60
+ let mcp = null;
61
+ if (allowed.has("web_search")) {
62
+ // Anthropic models search natively; other models search through the AI Gateway's tool.
63
+ if (resolved.vendor === "anthropic") {
64
+ tools.web_search = anthropic.tools.webSearch_20250305({ maxUses: 8 });
65
+ }
66
+ else if (isHarnessVendor(resolved.vendor)) {
67
+ // An installed client searches with its own tool; naming it here switches it on.
68
+ tools.web_search = createTool({
69
+ id: "web_search",
70
+ description: "Search the web.",
71
+ inputSchema: z.object({ query: z.string() }),
72
+ execute: async () => ({ error: "The client searches itself." }),
73
+ });
74
+ }
75
+ else if (resolved.gateway) {
76
+ tools.web_search = gatewayTools.perplexitySearch({ maxResults: 8 });
77
+ }
78
+ }
79
+ if (allowed.has("web_fetch") || allowed.has("web_search")) {
80
+ tools.web_fetch = createTool({
81
+ id: "web_fetch",
82
+ description: "Fetch a public web page or file and return its readable text (Markdown).",
83
+ inputSchema: z.object({ url: z.string().describe("Absolute http(s) URL") }),
84
+ execute: async ({ url }) => {
85
+ const safe = await assertPublicUrl(url);
86
+ await ctx.emit("tool", { code: "reads", params: { name: safe.hostname } });
87
+ const res = await safeFetch(safe.toString(), {
88
+ signal: AbortSignal.any([ctx.signal, AbortSignal.timeout(20_000)]),
89
+ headers: { "user-agent": "Mozilla/5.0 (compatible; engenty-wizards/0.1)" },
90
+ });
91
+ const type = (res.headers.get("content-type") ?? "").split(";")[0].trim().toLowerCase();
92
+ const data = new Uint8Array(await res.arrayBuffer());
93
+ const name = new URL(res.url || safe.toString()).pathname.split("/").pop() || "download";
94
+ const mime = documentMime(name, type);
95
+ // A PDF or Word file is read by its own text; an image or other bytes are not text at all.
96
+ if (mime === "application/pdf" || mime.includes("word")) {
97
+ const doc = await parseDocument({ data, name, mime }, { charge: (usd) => ctx.chargeUsd(usd), signal: ctx.signal, call: ctx.call }).catch(() => null);
98
+ return doc
99
+ ? { status: res.status, url: res.url, content: clip(doc.markdown) }
100
+ : { status: res.status, url: res.url, error: `The ${mime} file could not be read.` };
101
+ }
102
+ const body = new TextDecoder().decode(data);
103
+ if (!isReadable(type, body)) {
104
+ return {
105
+ status: res.status,
106
+ url: res.url,
107
+ type: type || "unknown",
108
+ bytes: data.length,
109
+ note: type.startsWith("image/")
110
+ ? "An image, not a page: the address works. Its bytes are not text and are not shown."
111
+ : "Not a text page: its bytes are not shown.",
112
+ };
113
+ }
114
+ const text = type.includes("html") ? htmlToMarkdown(body) : body;
115
+ return { status: res.status, url: res.url, content: clip(text) };
116
+ },
117
+ });
118
+ }
119
+ if (allowed.has("http")) {
120
+ tools.http_request = createTool({
121
+ id: "http_request",
122
+ description: "Call a public HTTP API. Use for REST endpoints the instructions name.",
123
+ inputSchema: z.object({
124
+ method: z.enum(["GET", "POST", "PUT", "PATCH", "DELETE"]).default("GET"),
125
+ url: z.string(),
126
+ headers: z.record(z.string(), z.string()).optional(),
127
+ json: z.unknown().optional().describe("JSON body"),
128
+ }),
129
+ execute: async ({ method, url, headers, json }) => {
130
+ const safe = await assertPublicUrl(url);
131
+ await ctx.emit("tool", `${method} ${safe.hostname}${safe.pathname}`);
132
+ const res = await safeFetch(safe.toString(), {
133
+ method,
134
+ signal: AbortSignal.any([ctx.signal, AbortSignal.timeout(30_000)]),
135
+ headers: {
136
+ ...(json !== undefined ? { "content-type": "application/json" } : {}),
137
+ ...headers,
138
+ },
139
+ body: json !== undefined ? JSON.stringify(json) : undefined,
140
+ });
141
+ return { status: res.status, body: clip(await res.text(), 8000) };
142
+ },
143
+ });
144
+ }
145
+ const files = new FileKeeper(ctx, assets);
146
+ if (allowed.has("browser")) {
147
+ Object.assign(tools, await browserTools(ctx, assets, files));
148
+ }
149
+ // The wizard's lists and files, the documents the person gave and the project's documents are
150
+ // always at hand. An installed client gets tools over an MCP bridge its CLI starts for every
151
+ // call, seconds of its own: a step with no use for the store goes without its tools, and
152
+ // without others (Knowledge, a workspace file) the client answers without the bridge.
153
+ const idle = isHarnessVendor(resolved.vendor) &&
154
+ storeIdle(step, ctx.def.lists?.length ?? 0, uploads.length) &&
155
+ !(await hasStoreFiles(ctx.store));
156
+ if (!idle) {
157
+ Object.assign(tools, storeTools(ctx, uploads, files));
158
+ }
159
+ Object.assign(tools, await projectTools(ctx));
160
+ Object.assign(tools, mailTools(step, ctx, files));
161
+ Object.assign(tools, await connectorTools(step, ctx, files));
162
+ Object.assign(tools, await pluginTools(step, ctx));
163
+ Object.assign(tools, (await spaceContextOf(ctx)).tools);
164
+ if (allowed.has("pages")) {
165
+ Object.assign(tools, pageTools(ctx));
166
+ }
167
+ const sandbox = sandboxCapabilities();
168
+ if (allowed.has("sandbox") && sandbox) {
169
+ const timeoutMs = (seconds) => Math.min((seconds ?? 120) * 1000, 600_000);
170
+ const report = (result) => ({
171
+ exitCode: result.exitCode,
172
+ stdout: clip(result.stdout, 8000),
173
+ stderr: clip(result.stderr, 4000),
174
+ });
175
+ tools.run_command = createTool({
176
+ id: "run_command",
177
+ description: shellToolDescription(sandbox),
178
+ inputSchema: z.object({ command: z.string(), timeoutSeconds: z.number().optional() }),
179
+ execute: async ({ command, timeoutSeconds }) => {
180
+ await ctx.emit("tool", { code: "runs", params: { command: command.slice(0, 80) } });
181
+ return report(await ctx.resources
182
+ .sandboxHandle()
183
+ .exec(command, { timeoutMs: timeoutMs(timeoutSeconds) }));
184
+ },
185
+ });
186
+ tools.export_file = createTool({
187
+ id: "export_file",
188
+ description: "Hand a file from the sandbox to the person as a result (e.g. a chart PNG, a CSV).",
189
+ inputSchema: z.object({
190
+ path: z.string(),
191
+ mime: z.string().describe("e.g. image/png, text/csv"),
192
+ }),
193
+ execute: async ({ path, mime }) => {
194
+ let bytes;
195
+ try {
196
+ bytes = await ctx.resources.sandboxHandle().readFile(path);
197
+ }
198
+ catch (err) {
199
+ return { error: err.message || "file not found" };
200
+ }
201
+ const ref = await ctx.saveAsset({
202
+ kind: mime.startsWith("image/") ? "image" : "file",
203
+ mime,
204
+ name: path.split("/").pop() ?? "file",
205
+ data: Buffer.from(bytes),
206
+ });
207
+ assets.push(ref);
208
+ return { saved: true, assetId: ref.id };
209
+ },
210
+ });
211
+ }
212
+ if (allowed.has("image")) {
213
+ tools.generate_image = createTool({
214
+ id: "generate_image",
215
+ description: "Draw an image from a detailed visual prompt. The image is shown to the person.",
216
+ inputSchema: z.object({
217
+ prompt: z.string(),
218
+ aspectRatio: z.enum(["1:1", "16:9", "9:16", "4:5", "3:2", "2:3"]).optional(),
219
+ }),
220
+ execute: async ({ prompt, aspectRatio }) => {
221
+ await ctx.emit("tool", { code: "drawing" });
222
+ const media = await generateImageMedia({
223
+ call: ctx.call,
224
+ prompt,
225
+ aspectRatio,
226
+ abortSignal: ctx.signal,
227
+ });
228
+ await ctx.chargeUsd(media.costUsd);
229
+ const ref = await ctx.saveAsset({
230
+ kind: "image",
231
+ mime: media.mime,
232
+ name: "image.png",
233
+ data: markMedia(media.bytes, media.mime, { origin: "generated", system: media.system }),
234
+ ai: "generated",
235
+ });
236
+ assets.push(ref);
237
+ return { saved: true, assetId: ref.id };
238
+ },
239
+ });
240
+ }
241
+ // The wizard's workspace (reference data, price lists, templates) is always readable.
242
+ if (ctx.files.length) {
243
+ tools.read_workspace_file = createTool({
244
+ id: "read_workspace_file",
245
+ description: `Read a file from the wizard's workspace. Files: ${ctx.files
246
+ .slice(0, 60)
247
+ .map((f) => f.path)
248
+ .join(", ")}`,
249
+ inputSchema: z.object({ path: z.string() }),
250
+ execute: async ({ path }) => {
251
+ const found = await snapshotFile(ctx.files, path);
252
+ if (!found) {
253
+ return { error: `No file ${path}` };
254
+ }
255
+ return isTextMime(found.file.mime)
256
+ ? { path, text: clip(found.data.toString("utf8"), 40_000) }
257
+ : { path, mime: found.file.mime, size: found.file.size, note: "binary file" };
258
+ },
259
+ });
260
+ }
261
+ const servers = ctx.project.mcpServers.filter((s) => step.mcp?.includes(s.id));
262
+ if (servers.length) {
263
+ mcp = new MCPClient({
264
+ id: `run-${ctx.runId}-${step.id}`,
265
+ servers: Object.fromEntries(servers.map((s) => [
266
+ s.id,
267
+ { url: new URL(s.url), requestInit: { headers: s.headers ?? {} }, timeout: 60_000 },
268
+ ])),
269
+ });
270
+ try {
271
+ Object.assign(tools, await mcp.listTools());
272
+ await ctx.emit("tool", {
273
+ code: "mcpConnected",
274
+ params: { names: servers.map((s) => s.name).join(", ") },
275
+ });
276
+ }
277
+ catch (err) {
278
+ await ctx.emit("info", {
279
+ code: "mcpUnreachable",
280
+ params: { detail: err.message },
281
+ });
282
+ }
283
+ }
284
+ return {
285
+ tools,
286
+ assets,
287
+ close: async () => {
288
+ await mcp?.disconnect().catch(() => undefined);
289
+ },
290
+ };
291
+ }
@@ -0,0 +1,104 @@
1
+ import { createTool } from "@mastra/core/tools";
2
+ import { z } from "zod";
3
+ import { connectionContext } from "../connectors/index.js";
4
+ import { mailAction, mailSearchInput, } from "../connectors/mail.js";
5
+ import { escapeHtml, htmlToPdf } from "../render/convert.js";
6
+ import { guardHtml } from "../render/guard.js";
7
+ import { attempt, clip } from "./shared.js";
8
+ const NOT_CONNECTED = "The person has not connected a mailbox. Go on without mail and say in your result that the mailbox is not connected.";
9
+ /**
10
+ * Read-only mail for a step that names a mail connection. The tools are the same whichever
11
+ * provider the person connected; attachments never pass through the model — they are saved.
12
+ */
13
+ export function mailTools(step, ctx, files) {
14
+ const connection = (ctx.def.connections ?? []).find((c) => c.kind === "mail" && step.connections?.includes(c.id));
15
+ if (!connection) {
16
+ return {};
17
+ }
18
+ const open = async () => {
19
+ const found = await connectionContext(ctx.store, connection, ctx.project.id);
20
+ if (!found) {
21
+ throw new Error(NOT_CONNECTED);
22
+ }
23
+ return found;
24
+ };
25
+ const tools = {};
26
+ tools.mail_search = createTool({
27
+ id: "mail_search",
28
+ description: "Search the person's mailbox (read-only), newest first. Returns id, date, sender, subject, snippet and attachments (id, name, size) of each mail. Search broadly with several terms at once rather than one call per word.",
29
+ inputSchema: mailSearchInput,
30
+ execute: (input) => attempt(async () => {
31
+ const { connector, ctx: actionCtx, label } = await open();
32
+ await ctx.emit("tool", { code: "searchesMail", params: { label } });
33
+ const { mails } = await mailAction(connector, "search", input, actionCtx);
34
+ return {
35
+ mailbox: label,
36
+ total: mails.length,
37
+ mails: mails.map((m) => ({ ...m, snippet: m.snippet.slice(0, 200) })),
38
+ };
39
+ }),
40
+ });
41
+ tools.mail_read = createTool({
42
+ id: "mail_read",
43
+ description: "Read one mail in full: sender, recipients, text, attachments.",
44
+ inputSchema: z.object({ id: z.string() }),
45
+ execute: ({ id }) => attempt(async () => {
46
+ const { connector, ctx: actionCtx } = await open();
47
+ const mail = await mailAction(connector, "read", { id }, actionCtx);
48
+ const { html: _html, ...rest } = mail;
49
+ return { ...rest, text: clip(mail.text, 6000) };
50
+ }),
51
+ });
52
+ tools.mail_save = createTool({
53
+ id: "mail_save",
54
+ description: "Keep mail attachments (invoice PDFs) as files, several at once: each is stored under `path` in the wizard's files and added to this step's result. Leave attachment_id out to keep the mail itself as a PDF — for receipts that only exist as mail text. Then read them with scan_documents or read_document.",
55
+ inputSchema: z.object({
56
+ items: z
57
+ .array(z.object({
58
+ id: z.string().describe("Mail id from mail_search."),
59
+ attachment_id: z.string().optional(),
60
+ path: z.string().describe("e.g. invoices/2026-09/2026-09-03_Notion_INV-123.pdf"),
61
+ }))
62
+ .min(1)
63
+ .max(40),
64
+ }),
65
+ execute: ({ items }) => attempt(async () => {
66
+ const { connector, ctx: actionCtx, label } = await open();
67
+ await ctx.emit("tool", {
68
+ code: "savesReceipts",
69
+ params: { count: items.length, label },
70
+ });
71
+ const saved = [];
72
+ for (const item of items) {
73
+ try {
74
+ if (item.attachment_id) {
75
+ const a = await mailAction(connector, "get_attachment", { id: item.id, attachment_id: item.attachment_id }, actionCtx);
76
+ const kept = await files.keep(item.path, Buffer.from(a.data_base64, "base64"), {
77
+ mime: a.mime,
78
+ source: `E-Mail-Anhang „${a.name}“ aus ${label}`,
79
+ });
80
+ saved.push({ id: item.id, saved: kept.path, size: kept.size });
81
+ }
82
+ else {
83
+ const mail = await mailAction(connector, "read", { id: item.id }, actionCtx);
84
+ const page = mail.html ??
85
+ `<pre style="white-space:pre-wrap;font:14px system-ui">${escapeHtml(mail.text)}</pre>`;
86
+ const head = `<div style="font:13px system-ui;color:#444;border-bottom:1px solid #ddd;padding-bottom:8px;margin-bottom:12px">${escapeHtml(mail.from ?? "")}<br>${escapeHtml(mail.date ?? "")}<br><b>${escapeHtml(mail.subject ?? "")}</b></div>`;
87
+ // The mail's own HTML is rendered offline: its remote images and scripts never load.
88
+ const pdf = await htmlToPdf(guardHtml(`<!doctype html><html><body>${head}${page}</body></html>`));
89
+ const kept = await files.keep(item.path.replace(/(\.pdf)?$/i, ".pdf"), pdf, {
90
+ mime: "application/pdf",
91
+ source: `E-Mail „${mail.subject ?? ""}“ aus ${label}`,
92
+ });
93
+ saved.push({ id: item.id, saved: kept.path, size: kept.size });
94
+ }
95
+ }
96
+ catch (err) {
97
+ saved.push({ id: item.id, error: String(err.message).slice(0, 200) });
98
+ }
99
+ }
100
+ return { saved };
101
+ }),
102
+ });
103
+ return tools;
104
+ }