@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,249 @@
1
+ import { createRemoteJWKSet, jwtVerify } from "jose";
2
+ import { env } from "./env.js";
3
+ /**
4
+ * The Manage-App as this runtime sees it (docs/manage-contract.md): it issues the tokens,
5
+ * knows the tenants and their credits. Nothing here runs when `MANAGE_URL` is empty.
6
+ */
7
+ export const managed = Boolean(env.manage.url);
8
+ const discoveries = new Map();
9
+ /** OIDC discovery of a Manage-App, cached for an hour. */
10
+ export async function discovery(base = env.manage.url) {
11
+ const hit = discoveries.get(base);
12
+ if (hit && Date.now() - hit.at < 3600_000) {
13
+ return hit.value;
14
+ }
15
+ const res = await fetch(`${base}/.well-known/openid-configuration`, {
16
+ signal: AbortSignal.timeout(10_000),
17
+ });
18
+ if (!res.ok) {
19
+ throw new Error(`Manage-App discovery failed: ${res.status}`);
20
+ }
21
+ const value = (await res.json());
22
+ discoveries.set(base, { at: Date.now(), value });
23
+ return value;
24
+ }
25
+ const keySets = new Map();
26
+ function toClaims(payload) {
27
+ const p = payload;
28
+ if (typeof p.sub !== "string" || typeof p.tenant !== "string") {
29
+ return null;
30
+ }
31
+ const role = p.role === "owner" || p.role === "admin" ? p.role : "member";
32
+ return {
33
+ userId: p.sub,
34
+ tenantId: p.tenant,
35
+ role,
36
+ name: typeof p.name === "string" ? p.name : "",
37
+ email: typeof p.email === "string" ? p.email : "",
38
+ clientId: typeof p.azp === "string" ? p.azp : String(p.client_id ?? ""),
39
+ scopes: String(p.scope ?? "")
40
+ .split(" ")
41
+ .filter(Boolean),
42
+ expiresAt: (p.exp ?? 0) * 1000,
43
+ };
44
+ }
45
+ /**
46
+ * Verifies an access token of the Manage-App against its JWKS — no round trip per request.
47
+ * `audiences` are the resources this caller accepts; null skips the audience check.
48
+ */
49
+ export async function verifyToken(token, audiences, base = env.manage.url) {
50
+ const payload = await verifySigned(token, audiences, base);
51
+ return payload ? toClaims(payload) : null;
52
+ }
53
+ /** Any token the Manage-App at `base` signed (its JWKS, its issuer); null when it is not one. */
54
+ export async function verifySigned(token, audiences, base = env.manage.url) {
55
+ try {
56
+ const d = await discovery(base);
57
+ let keys = keySets.get(d.jwks_uri);
58
+ if (!keys) {
59
+ keys = createRemoteJWKSet(new URL(d.jwks_uri));
60
+ keySets.set(d.jwks_uri, keys);
61
+ }
62
+ const { payload } = await jwtVerify(token, keys, {
63
+ issuer: d.issuer,
64
+ ...(audiences ? { audience: audiences } : {}),
65
+ });
66
+ return payload;
67
+ }
68
+ catch {
69
+ return null;
70
+ }
71
+ }
72
+ /** Reads a token's claims without verifying it — only for tokens the token endpoint just handed us. */
73
+ export function unverifiedClaims(token) {
74
+ try {
75
+ const payload = JSON.parse(Buffer.from(token.split(".")[1], "base64url").toString("utf8"));
76
+ return toClaims(payload);
77
+ }
78
+ catch {
79
+ return null;
80
+ }
81
+ }
82
+ // --- service calls -----------------------------------------------------------
83
+ export class ManageError extends Error {
84
+ status;
85
+ code;
86
+ constructor(status, code, message) {
87
+ super(message);
88
+ this.status = status;
89
+ this.code = code;
90
+ }
91
+ }
92
+ async function call(method, path, body) {
93
+ const res = await fetch(`${env.manage.url}${path}`, {
94
+ method,
95
+ headers: {
96
+ authorization: `Bearer ${env.manage.serviceKey}`,
97
+ ...(body === undefined ? {} : { "content-type": "application/json" }),
98
+ },
99
+ body: body === undefined ? undefined : JSON.stringify(body),
100
+ signal: AbortSignal.timeout(15_000),
101
+ });
102
+ const data = (await res.json().catch(() => ({})));
103
+ if (!res.ok) {
104
+ throw new ManageError(res.status, data.code ?? "error", data.error ?? `Manage-App ${res.status}`);
105
+ }
106
+ return data;
107
+ }
108
+ /** The people of a tenant, as the Manage-App keeps them; they are managed there. */
109
+ export function tenantMembers(id) {
110
+ return call("GET", `/v1/tenants/${encodeURIComponent(id)}/members`);
111
+ }
112
+ const users = new Map();
113
+ /** What the Manage-App says of a person beyond their token; cached a minute. */
114
+ export async function userInfo(userId) {
115
+ const hit = users.get(userId);
116
+ if (hit && Date.now() - hit.at < 60_000) {
117
+ return hit.value;
118
+ }
119
+ const value = await call("GET", `/v1/users/${encodeURIComponent(userId)}`)
120
+ .then((u) => ({ features: u.features ?? {}, admin: u.admin === true }))
121
+ .catch(() => hit?.value ?? { features: {}, admin: false });
122
+ users.set(userId, { at: Date.now(), value });
123
+ return value;
124
+ }
125
+ const tenants = new Map();
126
+ /** Plan, limits and balance of a tenant, cached for a minute. */
127
+ export async function tenantInfo(id, fresh = false) {
128
+ const hit = tenants.get(id);
129
+ if (!fresh && hit && Date.now() - hit.at < 60_000) {
130
+ return hit.value;
131
+ }
132
+ try {
133
+ const value = await call("GET", `/v1/tenants/${encodeURIComponent(id)}`);
134
+ tenants.set(id, { at: Date.now(), value });
135
+ return value;
136
+ }
137
+ catch (err) {
138
+ // The Manage-App is out of reach for a moment: what it said within the hour still counts.
139
+ if (hit && !(err instanceof ManageError) && Date.now() - hit.at < 3600_000) {
140
+ return hit.value;
141
+ }
142
+ throw err;
143
+ }
144
+ }
145
+ export function forgetTenant(id) {
146
+ tenants.delete(id);
147
+ }
148
+ /** Renames the team at the Manage-App; what it answers is the tenant as it stands now. */
149
+ export async function renameTenant(id, name) {
150
+ const value = await call("PATCH", `/v1/tenants/${encodeURIComponent(id)}`, {
151
+ name,
152
+ });
153
+ tenants.set(id, { at: Date.now(), value });
154
+ return value;
155
+ }
156
+ export function saveTeamProfile(tenantId, userId, lang, profile) {
157
+ return call("PUT", `/v1/tenants/${encodeURIComponent(tenantId)}/profile`, {
158
+ ...profile,
159
+ userId,
160
+ lang,
161
+ });
162
+ }
163
+ /** The Manage-App mails the install command and the first steps to one of the team's people. */
164
+ export function installMail(email, lang) {
165
+ return call("POST", "/v1/install-mail", { email, lang });
166
+ }
167
+ export function verifyKey(key) {
168
+ return call("POST", "/v1/keys/verify", { key });
169
+ }
170
+ /** Whether the grant behind an access token still stands: not disconnected, still a member. */
171
+ export function grantActive(userId, clientId, tenantId) {
172
+ return call("POST", "/v1/grants/check", { userId, clientId, tenantId });
173
+ }
174
+ export function reserve(tenantId, runId, credits) {
175
+ return call("POST", "/v1/reservations", { tenantId, runId, credits });
176
+ }
177
+ export function release(runId) {
178
+ return call("POST", "/v1/reservations/release", { runId });
179
+ }
180
+ export function runUsage(tenantId, runId) {
181
+ return call("GET", `/v1/runs/${encodeURIComponent(runId)}/usage?tenantId=${encodeURIComponent(tenantId)}`);
182
+ }
183
+ export function tenantUsage(tenantId, months = 3) {
184
+ return call("GET", `/v1/tenants/${encodeURIComponent(tenantId)}/usage?months=${months}`);
185
+ }
186
+ /** The plans of a Manage-App: public, no key needed. */
187
+ export async function publicPlans(base) {
188
+ const res = await fetch(`${base}/v1/plans`, { signal: AbortSignal.timeout(10_000) });
189
+ if (!res.ok) {
190
+ throw new ManageError(res.status, "error", `Manage-App ${res.status}`);
191
+ }
192
+ return (await res.json());
193
+ }
194
+ const channels = new Map();
195
+ /** The tenant's numbers, cached for a minute. */
196
+ export async function tenantChannels(id) {
197
+ const hit = channels.get(id);
198
+ if (hit && Date.now() - hit.at < 60_000) {
199
+ return hit.value;
200
+ }
201
+ const value = await call("GET", `/v1/tenants/${encodeURIComponent(id)}/channels`);
202
+ channels.set(id, { at: Date.now(), value });
203
+ return value;
204
+ }
205
+ /**
206
+ * Forgets what the Manage-App said of the tenant's numbers: the next `tenantChannels` asks.
207
+ * The runtime tests of the Manage-App's channel plugins (sms, calls, whatsapp) call it.
208
+ */
209
+ export function forgetChannels(id) {
210
+ channels.delete(id);
211
+ }
212
+ /** A person of the tenant asks for its number; what the Manage-App answers with is the request. */
213
+ export async function requestChannelNumber(id, input) {
214
+ channels.delete(id);
215
+ return call("POST", `/v1/tenants/${encodeURIComponent(id)}/channels/requests`, input);
216
+ }
217
+ /** The tenant takes its open request back. */
218
+ export async function withdrawChannelRequest(id) {
219
+ channels.delete(id);
220
+ return call("DELETE", `/v1/tenants/${encodeURIComponent(id)}/channels/requests`);
221
+ }
222
+ /** What a tenant's channel used, priced by the Manage-App: texts by segment, calls by minute. */
223
+ export function bookChannelUsage(id, input) {
224
+ return call("POST", `/v1/tenants/${encodeURIComponent(id)}/channels/usage`, input);
225
+ }
226
+ /** A push to the mobile app on one device; the Manage-App holds the APNs and FCM keys. */
227
+ export function pushToDevice(input) {
228
+ return call("POST", "/v1/push", input);
229
+ }
230
+ /** Code or refresh token → tokens. A confidential client sends its secret, a public one only its id. */
231
+ export async function tokenRequest(params, client, base = env.manage.url) {
232
+ const d = await discovery(base);
233
+ const body = new URLSearchParams({ ...params, client_id: client.id });
234
+ const headers = { "content-type": "application/x-www-form-urlencoded" };
235
+ if (client.secret) {
236
+ headers.authorization = `Basic ${Buffer.from(`${encodeURIComponent(client.id)}:${encodeURIComponent(client.secret)}`).toString("base64")}`;
237
+ }
238
+ const res = await fetch(d.token_endpoint, {
239
+ method: "POST",
240
+ headers,
241
+ body,
242
+ signal: AbortSignal.timeout(15_000),
243
+ });
244
+ const data = (await res.json().catch(() => ({})));
245
+ if (!res.ok || !data.access_token) {
246
+ throw new ManageError(res.status, data.error ?? "token_error", "Token request failed");
247
+ }
248
+ return data;
249
+ }
@@ -0,0 +1,161 @@
1
+ import { API_KEY_PREFIX, verifyLocalKey } from "../auth/keys.js";
2
+ import { LOCAL_CLIENT_HEADER, LOCAL_MCP_HEADER, localTicketExpiry } from "../auth/local-ticket.js";
3
+ import { env } from "../env.js";
4
+ import { grantActive, managed, verifyKey, verifyToken } from "../manage.js";
5
+ import { LOCAL_TENANT } from "../tenants/tenant.js";
6
+ import { MCP_RESOURCE, SCOPES } from "./scopes.js";
7
+ export function principalOf(info) {
8
+ return info.extra;
9
+ }
10
+ function authInfoFor(who, token, clientId) {
11
+ return { token, clientId, scopes: who.scopes, extra: { ...who } };
12
+ }
13
+ function bearer(request) {
14
+ return (request.headers
15
+ .get("authorization")
16
+ ?.match(/^Bearer\s+(.+)$/i)?.[1]
17
+ ?.trim() || null);
18
+ }
19
+ const resourceMetadataUrl = (() => {
20
+ const url = new URL(MCP_RESOURCE);
21
+ return `${url.origin}/.well-known/oauth-protected-resource${url.pathname}`;
22
+ })();
23
+ /** RFC 6750 / RFC 9728 challenge: tells an MCP client where to start OAuth. */
24
+ function challenge(status, error, description) {
25
+ return new Response(JSON.stringify({ error, error_description: description }), {
26
+ status,
27
+ headers: {
28
+ "content-type": "application/json",
29
+ ...(status === 401
30
+ ? {
31
+ "www-authenticate": managed
32
+ ? `Bearer error="${error}", error_description="${description}", resource_metadata="${resourceMetadataUrl}", scope="${SCOPES.join(" ")}"`
33
+ : `Bearer error="${error}", error_description="${description}"`,
34
+ }
35
+ : {}),
36
+ },
37
+ });
38
+ }
39
+ const keyCache = new Map();
40
+ /** An API key acts as its owner, in the key's tenant, with every scope. */
41
+ async function apiKeyAuth(key) {
42
+ if (!managed) {
43
+ const found = await verifyLocalKey(key);
44
+ if (!found) {
45
+ return challenge(401, "invalid_token", "This API key is unknown or revoked.");
46
+ }
47
+ const who = {
48
+ userId: "local",
49
+ tenantId: LOCAL_TENANT,
50
+ role: "owner",
51
+ client: found.name || "MCP",
52
+ scopes: [...SCOPES],
53
+ };
54
+ return authInfoFor(who, key, found.id);
55
+ }
56
+ const hit = keyCache.get(key);
57
+ if (hit && Date.now() - hit.at < 60_000) {
58
+ return authInfoFor(hit.who, key, hit.keyId);
59
+ }
60
+ const result = await verifyKey(key).catch(() => null);
61
+ if (!result?.valid || !result.userId || !result.tenantId) {
62
+ keyCache.delete(key);
63
+ return challenge(401, "invalid_token", "This API key is unknown or revoked.");
64
+ }
65
+ const who = {
66
+ userId: result.userId,
67
+ tenantId: result.tenantId,
68
+ role: result.role ?? "member",
69
+ client: result.name || "MCP",
70
+ scopes: [...SCOPES],
71
+ name: result.userName ?? "",
72
+ };
73
+ keyCache.set(key, { at: Date.now(), who, keyId: result.keyId ?? "" });
74
+ return authInfoFor(who, key, result.keyId ?? "");
75
+ }
76
+ const grantCache = new Map();
77
+ /** How long an answer of the Manage-App holds: "Trennen" takes effect within this time. */
78
+ const GRANT_TTL = 30_000;
79
+ /**
80
+ * A signed token lives its hour whatever happens; whether the person still allows the app —
81
+ * and is still in the team — the Manage-App knows. Asked at most every 30 seconds per grant;
82
+ * when it cannot be asked, the token is refused.
83
+ */
84
+ async function grantStands(userId, clientId, tenantId) {
85
+ const key = `${userId}\n${clientId}\n${tenantId}`;
86
+ const hit = grantCache.get(key);
87
+ if (hit && Date.now() - hit.at < GRANT_TTL) {
88
+ return hit.active;
89
+ }
90
+ const active = await grantActive(userId, clientId, tenantId)
91
+ .then((r) => r.active)
92
+ .catch(() => null);
93
+ if (active === null) {
94
+ return false;
95
+ }
96
+ grantCache.set(key, { at: Date.now(), active });
97
+ return active;
98
+ }
99
+ /** An access token of the Manage-App, issued for this MCP endpoint, acts within its scopes. */
100
+ async function tokenAuth(token) {
101
+ if (!managed) {
102
+ return challenge(401, "invalid_token", "Sign in with an API key from the settings.");
103
+ }
104
+ const claims = await verifyToken(token, [MCP_RESOURCE, env.appUrl]);
105
+ if (!claims) {
106
+ return challenge(401, "invalid_token", "The access token is invalid or expired.");
107
+ }
108
+ if (!(await grantStands(claims.userId, claims.clientId, claims.tenantId))) {
109
+ return challenge(401, "invalid_token", "This connection was ended. Connect again.");
110
+ }
111
+ const granted = new Set(claims.scopes);
112
+ const who = {
113
+ userId: claims.userId,
114
+ tenantId: claims.tenantId,
115
+ role: claims.role,
116
+ client: claims.clientId || "MCP",
117
+ scopes: SCOPES.filter((s) => granted.has(s)),
118
+ name: claims.name,
119
+ email: claims.email,
120
+ };
121
+ return authInfoFor(who, token, claims.clientId);
122
+ }
123
+ /**
124
+ * A request from `wizards mcp` on this machine: signed with the data folder's secret,
125
+ * which only a runtime alone has. It acts as the admin, like a key from the settings.
126
+ */
127
+ function localAuth(request, ticket) {
128
+ if (managed || !localTicketExpiry(env.authSecret, ticket, Date.now(), "local-mcp")) {
129
+ return challenge(401, "invalid_token", "This local signature is invalid or expired.");
130
+ }
131
+ const client = request.headers
132
+ .get(LOCAL_CLIENT_HEADER)
133
+ ?.replace(/[^\p{L}\p{N} ._-]/gu, "")
134
+ .trim()
135
+ .slice(0, 60) || "MCP";
136
+ const who = {
137
+ userId: "local",
138
+ tenantId: LOCAL_TENANT,
139
+ role: "owner",
140
+ client,
141
+ scopes: [...SCOPES],
142
+ };
143
+ return authInfoFor(who, ticket, "local");
144
+ }
145
+ /** Who an MCP or API request acts for: an API key (`x-api-key` or a `wz_…` bearer) or an OAuth access token. */
146
+ export async function authenticate(request) {
147
+ const local = request.headers.get(LOCAL_MCP_HEADER)?.trim();
148
+ if (local) {
149
+ return localAuth(request, local);
150
+ }
151
+ const header = request.headers.get("x-api-key")?.trim();
152
+ const token = bearer(request);
153
+ const key = header || (token?.startsWith(API_KEY_PREFIX) ? token : null);
154
+ if (key) {
155
+ return apiKeyAuth(key);
156
+ }
157
+ if (!token) {
158
+ return challenge(401, "invalid_token", "Sign in to use this endpoint.");
159
+ }
160
+ return tokenAuth(token);
161
+ }
@@ -0,0 +1,59 @@
1
+ import { AsyncLocalStorage } from "node:async_hooks";
2
+ import { randomBytes } from "node:crypto";
3
+ import { createMcpHandler, fromJsonSchema, McpServer, } from "@modelcontextprotocol/server";
4
+ import { env } from "../env.js";
5
+ const bridges = new Map();
6
+ const textOf = (value) => typeof value === "string" ? value : JSON.stringify(value ?? null);
7
+ /** A tool's result as MCP content: text, or the blocks its `toModelOutput` shapes (text and images). */
8
+ function contentOf(tool, output) {
9
+ const shaped = tool.toModelOutput?.(output);
10
+ if (shaped?.type === "content") {
11
+ return {
12
+ content: shaped.value.map((part) => part.type === "image-data"
13
+ ? { type: "image", data: part.data ?? "", mimeType: part.mediaType ?? "image/png" }
14
+ : { type: "text", text: part.text ?? textOf(part) }),
15
+ };
16
+ }
17
+ return { content: [{ type: "text", text: textOf(shaped ? shaped.value : output) }] };
18
+ }
19
+ export function openBridge(tools) {
20
+ const token = randomBytes(24).toString("base64url");
21
+ // The client's requests arrive on their own; the tools run as the call that opened the bridge —
22
+ // in its tenant, as its person.
23
+ const inCall = AsyncLocalStorage.snapshot();
24
+ const handler = createMcpHandler(() => {
25
+ const server = new McpServer({ name: "step", version: "0.1.0" }, { capabilities: { tools: {} } });
26
+ for (const tool of tools) {
27
+ server.registerTool(tool.name, {
28
+ description: tool.description,
29
+ inputSchema: fromJsonSchema(tool.inputSchema),
30
+ }, (async (args) => {
31
+ try {
32
+ return contentOf(tool, await inCall(() => tool.execute(args)));
33
+ }
34
+ catch (err) {
35
+ return {
36
+ isError: true,
37
+ content: [{ type: "text", text: err?.message ?? String(err) }],
38
+ };
39
+ }
40
+ }));
41
+ }
42
+ return server;
43
+ }, { legacy: "stateless" });
44
+ bridges.set(token, handler);
45
+ return {
46
+ url: `http://127.0.0.1:${env.port}/api/mcp/bridge/${token}`,
47
+ close: () => {
48
+ bridges.delete(token);
49
+ },
50
+ };
51
+ }
52
+ /** Answers an MCP request of an open bridge; a closed or unknown one is not found. */
53
+ export function bridgeRequest(token, request) {
54
+ const handler = bridges.get(token);
55
+ if (!handler) {
56
+ return Promise.resolve(new Response("not found", { status: 404 }));
57
+ }
58
+ return handler.fetch(request);
59
+ }
@@ -0,0 +1,97 @@
1
+ import { createHash } from "node:crypto";
2
+ import { readFileSync } from "node:fs";
3
+ import { dirname, resolve } from "node:path";
4
+ import { fileURLToPath } from "node:url";
5
+ import { RESOURCE_MIME_TYPE, registerAppResource } from "@modelcontextprotocol/ext-apps/server";
6
+ import { env } from "../env.js";
7
+ import { runTicket } from "../secrets/signing.js";
8
+ import { draftIssues, ownedWizard, publishedVersion } from "../services/wizards.js";
9
+ /**
10
+ * The flow widget (MCP Apps): a wizard as its diagram, and a run on it — where it stands, what
11
+ * it made, the page it waits for. Hosts that render MCP Apps (Claude Desktop, Cursor, VS Code,
12
+ * Goose, ChatGPT) show it in the chat; the others get the same tools as text.
13
+ */
14
+ /** Built by the web app (`vite.mcp-app.config.ts`) into one HTML file with everything inline. */
15
+ const FLOW_APP_FILE = resolve(dirname(fileURLToPath(import.meta.url)), "../../../web/dist/mcp/flow.html");
16
+ const MISSING = `<!doctype html><meta charset="utf-8"><body style="font:14px system-ui;padding:16px">
17
+ The flow widget is not built: run <code>pnpm --filter @engenty-wizards/web build</code>.</body>`;
18
+ function readWidget() {
19
+ try {
20
+ return readFileSync(FLOW_APP_FILE, "utf8");
21
+ }
22
+ catch {
23
+ return MISSING;
24
+ }
25
+ }
26
+ const FLOW_APP_HTML = readWidget();
27
+ /**
28
+ * Hosts keep a widget by its URI, so the URI names the build: a new widget gets a new address
29
+ * instead of the cached old one.
30
+ */
31
+ export const FLOW_APP_URI = `ui://engenty-wizards/flow-${createHash("sha256").update(FLOW_APP_HTML).digest("hex").slice(0, 10)}.html`;
32
+ export function registerFlowApp(server) {
33
+ // The widget reaches the run on the doors: their origin.
34
+ const origin = new URL(env.publicUrl).origin;
35
+ registerAppResource(server, "Wizard flow", FLOW_APP_URI, {
36
+ description: "A wizard as a diagram, and a run on it.",
37
+ mimeType: RESOURCE_MIME_TYPE,
38
+ }, async () => ({
39
+ contents: [
40
+ {
41
+ uri: FLOW_APP_URI,
42
+ mimeType: RESOURCE_MIME_TYPE,
43
+ text: FLOW_APP_HTML,
44
+ _meta: {
45
+ ui: {
46
+ // The run and its files are served by this runtime; the fonts by Google.
47
+ csp: {
48
+ connectDomains: [origin],
49
+ resourceDomains: [
50
+ origin,
51
+ "https://fonts.googleapis.com",
52
+ "https://fonts.gstatic.com",
53
+ ],
54
+ },
55
+ prefersBorder: true,
56
+ },
57
+ },
58
+ },
59
+ ],
60
+ }));
61
+ }
62
+ /**
63
+ * The widget's data for a wizard: the published version when there is one (that is what runs),
64
+ * else the draft. A run brings the definition it started on.
65
+ */
66
+ export async function flowView(userId, wizardId, options = {}) {
67
+ const w = await ownedWizard(userId, wizardId);
68
+ const published = options.shows === "draft" ? null : await publishedVersion(w);
69
+ const shows = published ? "published" : "draft";
70
+ const definition = options.definition ?? published?.definition ?? w.draft;
71
+ return {
72
+ wizard: {
73
+ id: w.id,
74
+ title: definition.title,
75
+ description: definition.description,
76
+ avatar: definition.avatar,
77
+ shows,
78
+ published: w.publishedVersion !== null,
79
+ issues: shows === "draft" ? (await draftIssues(w)).length : undefined,
80
+ },
81
+ definition,
82
+ run: options.run,
83
+ runtime: options.run
84
+ ? { base: env.publicUrl, ticket: runTicket(options.run.runId) }
85
+ : undefined,
86
+ };
87
+ }
88
+ /** A tool's `_meta` that opens the widget with the tool's result. */
89
+ export const flowAppMeta = {
90
+ ui: { resourceUri: FLOW_APP_URI },
91
+ "openai/outputTemplate": FLOW_APP_URI,
92
+ };
93
+ /**
94
+ * Where a result carries the widget's data. The definition stays out of `structuredContent`,
95
+ * which hosts hand to the model as well; `_meta` only reaches the widget.
96
+ */
97
+ export const FLOW_VIEW_KEY = "engenty/flow";
@@ -0,0 +1,54 @@
1
+ import { createMcpHandler, McpServer, originValidationResponse, } from "@modelcontextprotocol/server";
2
+ import { withTenant } from "../db/client.js";
3
+ import { env } from "../env.js";
4
+ import { asRole } from "../services/access.js";
5
+ import { tenantStatus } from "../tenants/control.js";
6
+ import { authenticate, principalOf } from "./auth.js";
7
+ import { registerFlowApp } from "./flow-app.js";
8
+ import { noteRequest } from "./seen.js";
9
+ import { registerPrompts, registerTools } from "./tools.js";
10
+ const INSTRUCTIONS = `engenty wizards: page-by-page AI wizards — the person answers pages, AI steps write, research and make images or videos, the person reviews, the result is files.
11
+ Use one: list_wizards, then run_wizard straight away — its widget shows the wizard itself (show_wizard only when the person wants to see a wizard before running it), then follow waitingFor (answer_page, review_step, answer_ask, get_run with waitSeconds). Runs spend credits.
12
+ Build one: get_authoring_guide (schema + design rules), a close starter with get_starter, create_wizard, edit_wizard until "issues" is empty, check with start_test_run + get_test_run. Publish only when the person asks.
13
+ When a run needs the browser, hand over its browserUrl, the wizard's own run page. The studioUrl is for building only: never send someone who uses a wizard to the studio.
14
+ Projects are called spaces in the studio. Ids are for the tools only: name wizards and spaces by their titles and names, and where two spaces share a name, by where each comes from.`;
15
+ /** A wizard definition is a few KB; this leaves room and refuses anything far beyond it. */
16
+ const MAX_BODY_BYTES = 300_000;
17
+ /**
18
+ * Streamable HTTP MCP endpoint, stateless: every request authenticates — with an access token of
19
+ * the Manage-App or an API key — and gets a fresh server whose tools act as that admin, in the
20
+ * tenant the token or key names.
21
+ */
22
+ export function mcpHandler() {
23
+ const allowedHosts = [new URL(env.appUrl).hostname, "localhost", "127.0.0.1"];
24
+ const handler = createMcpHandler((ctx) => {
25
+ const server = new McpServer({ name: "engenty-wizards", version: "0.1.0" }, { instructions: INSTRUCTIONS, capabilities: { tools: {}, prompts: {}, resources: {} } });
26
+ const who = principalOf(ctx.authInfo);
27
+ registerTools(server, who);
28
+ registerPrompts(server);
29
+ registerFlowApp(server);
30
+ return server;
31
+ }, { legacy: "stateless", maxRequestBodySize: MAX_BODY_BYTES });
32
+ return async (request) => {
33
+ const rejected = originValidationResponse(request, allowedHosts);
34
+ if (rejected) {
35
+ return rejected;
36
+ }
37
+ const authInfo = await authenticate(request);
38
+ if (authInfo instanceof Response) {
39
+ return authInfo;
40
+ }
41
+ const who = principalOf(authInfo);
42
+ if ((await tenantStatus(who.tenantId)) === "suspended") {
43
+ return new Response(JSON.stringify({ error: "This account is suspended.", code: "tenant_suspended" }), { status: 403 });
44
+ }
45
+ if (request.method === "POST") {
46
+ const body = await request
47
+ .clone()
48
+ .json()
49
+ .catch(() => null);
50
+ noteRequest(who.tenantId, authInfo.clientId, who.client, body);
51
+ }
52
+ return withTenant(who.tenantId, () => asRole(who.role, () => handler.fetch(request, { authInfo })));
53
+ };
54
+ }
@@ -0,0 +1,14 @@
1
+ import { env } from "../env.js";
2
+ /**
3
+ * What an MCP or API client may do; the Manage-App's consent page lists them, tools register only
4
+ * when granted. `runs:read`: the results of the live runs, as the WordPress plugin lists them.
5
+ */
6
+ export const SCOPES = [
7
+ "wizards:read",
8
+ "wizards:write",
9
+ "wizards:publish",
10
+ "runs:test",
11
+ "runs:read",
12
+ ];
13
+ /** The protected resource OAuth tokens are bound to (RFC 8707 / RFC 9728). */
14
+ export const MCP_RESOURCE = `${env.appUrl}/api/mcp`;