@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,112 @@
1
+ import { env } from "../env.js";
2
+ import { discovery, ManageError, tokenRequest } from "../manage.js";
3
+ import { CLIENT, keep, SCOPE } from "./account.js";
4
+ /**
5
+ * Signing in from a terminal (RFC 8628): the Manage-App hands out a code, the person types it
6
+ * on any browser at the account's /device page and allows it, and this process asks the token
7
+ * endpoint until they did. For `wizards setup` and `wizards account sign-in`; the studio keeps
8
+ * the browser flow of account.ts. Both end in the same keep(): the refresh token in the vault,
9
+ * the account in the settings, so the runtime picks it up wherever it runs.
10
+ *
11
+ * POST <account>/api/auth/device/code client_id, scope, resource → the codes
12
+ * POST <token endpoint of the discovery> grant_type device_code, every `interval` seconds,
13
+ * until tokens come, or the code expired or was refused
14
+ */
15
+ const GRANT = "urn:ietf:params:oauth:grant-type:device_code";
16
+ /** Why a sign-in ended without an account; the message is for the person. */
17
+ export class DeviceSignInError extends Error {
18
+ reason;
19
+ constructor(reason, message) {
20
+ super(message);
21
+ this.reason = reason;
22
+ }
23
+ }
24
+ /** Asks the Manage-App for a code to sign this install in with. */
25
+ export async function requestDeviceCode() {
26
+ const base = env.local.accountUrl;
27
+ // The discovery names the endpoint when the Manage-App advertises it.
28
+ const d = (await discovery(base).catch(() => null));
29
+ const res = await fetch(d?.device_authorization_endpoint ?? `${base}/api/auth/device/code`, {
30
+ method: "POST",
31
+ headers: { "content-type": "application/x-www-form-urlencoded" },
32
+ body: new URLSearchParams({
33
+ client_id: CLIENT.id,
34
+ scope: SCOPE,
35
+ resource: env.local.cloudUrl,
36
+ }),
37
+ signal: AbortSignal.timeout(15_000),
38
+ }).catch(() => null);
39
+ if (!res) {
40
+ throw new DeviceSignInError("unreachable", `${base} is not reachable right now.`);
41
+ }
42
+ const data = (await res.json().catch(() => ({})));
43
+ if (!(res.ok && data.device_code && data.user_code && data.verification_uri)) {
44
+ throw new DeviceSignInError("refused", data.error_description ||
45
+ (data.error
46
+ ? `The account refused the sign-in (${data.error}).`
47
+ : `The account did not hand out a code (${res.status}).`));
48
+ }
49
+ return {
50
+ deviceCode: data.device_code,
51
+ userCode: data.user_code,
52
+ verificationUri: data.verification_uri,
53
+ verificationUriComplete: data.verification_uri_complete ?? null,
54
+ expiresAt: Date.now() + (data.expires_in ?? 1800) * 1000,
55
+ interval: Math.max(1, data.interval ?? 5),
56
+ };
57
+ }
58
+ /** A pause that ends early when the signal aborts. */
59
+ const pause = (ms, signal) => new Promise((done) => {
60
+ const timer = setTimeout(done, ms);
61
+ signal?.addEventListener("abort", () => {
62
+ clearTimeout(timer);
63
+ done();
64
+ }, { once: true });
65
+ });
66
+ /**
67
+ * Asks the token endpoint until the person allowed the code in the browser, and keeps the
68
+ * tokens as the browser flow does. `authorization_pending` asks again after `interval`;
69
+ * `slow_down` asks five seconds later each time (RFC 8628 §3.5); a network error is tried
70
+ * again a few times. `expired_token` and `access_denied` end it.
71
+ */
72
+ export async function waitForDeviceSignIn(code, options = {}) {
73
+ const wait = options.wait ?? pause;
74
+ const { signal } = options;
75
+ let interval = code.interval;
76
+ let failures = 0;
77
+ for (;;) {
78
+ await wait(interval * 1000, signal);
79
+ if (signal?.aborted) {
80
+ throw new DeviceSignInError("skipped", "Skipped the sign-in.");
81
+ }
82
+ if (Date.now() >= code.expiresAt) {
83
+ throw new DeviceSignInError("expired", "The code has expired. Start the sign-in again.");
84
+ }
85
+ try {
86
+ const tokens = await tokenRequest({ grant_type: GRANT, device_code: code.deviceCode, resource: env.local.cloudUrl }, CLIENT, env.local.accountUrl);
87
+ return await keep(tokens);
88
+ }
89
+ catch (err) {
90
+ if (!(err instanceof ManageError)) {
91
+ if (++failures >= 5) {
92
+ throw new DeviceSignInError("unreachable", `${env.local.accountUrl} stopped answering. Start the sign-in again.`);
93
+ }
94
+ continue;
95
+ }
96
+ failures = 0;
97
+ switch (err.code) {
98
+ case "authorization_pending":
99
+ continue;
100
+ case "slow_down":
101
+ interval += 5;
102
+ continue;
103
+ case "expired_token":
104
+ throw new DeviceSignInError("expired", "The code has expired. Start the sign-in again.");
105
+ case "access_denied":
106
+ throw new DeviceSignInError("denied", "The sign-in was refused in the browser.");
107
+ default:
108
+ throw new DeviceSignInError("refused", `The account refused the sign-in (${err.code}).`);
109
+ }
110
+ }
111
+ }
112
+ }
@@ -0,0 +1,358 @@
1
+ import { createHash, createHmac, randomBytes, timingSafeEqual } from "node:crypto";
2
+ import { userInfo } from "node:os";
3
+ import { eq, lt } from "drizzle-orm";
4
+ import { Hono } from "hono";
5
+ import { deleteCookie, getCookie, setCookie } from "hono/cookie";
6
+ import { nanoid } from "nanoid";
7
+ import { control, controlDb, withTenant } from "../db/client.js";
8
+ import { basePath, env } from "../env.js";
9
+ import { discovery, managed, tokenRequest, verifyToken, } from "../manage.js";
10
+ import { refreshPro } from "../plugins/pro.js";
11
+ import { seal, unseal } from "../secrets/crypto.js";
12
+ import { LOCAL_TENANT } from "../tenants/tenant.js";
13
+ import { finishLink } from "./account.js";
14
+ import { localTicketExpiry } from "./local-ticket.js";
15
+ const secure = env.appUrl.startsWith("https");
16
+ // --- a runtime that runs alone ------------------------------------------------
17
+ // One person, one tenant. The studio answers only with a cookie that is set by opening the
18
+ // one-time link once: a web page in the same browser cannot reach it.
19
+ const LOCAL_COOKIE = "wz_local";
20
+ const localCookieValue = createHmac("sha256", env.authSecret).update("local-studio").digest("hex");
21
+ let accessKey = managed
22
+ ? null
23
+ : env.local.accessKey || randomBytes(24).toString("hex");
24
+ /** The link that lets the person in; printed at start, opened by the desktop app. */
25
+ export function localEntryUrl() {
26
+ return accessKey ? `${env.appUrl}/api/local/enter?k=${accessKey}` : null;
27
+ }
28
+ /** Sends everything published here to the cloud of the account that was just linked. */
29
+ async function firstSync() {
30
+ try {
31
+ // Loaded here: the services read the session this module makes.
32
+ const { syncAllToCloud } = await import("../services/cloud.js");
33
+ await withTenant(LOCAL_TENANT, () => syncAllToCloud(localUser().id));
34
+ }
35
+ catch (err) {
36
+ console.error("[cloud] first sync failed:", err);
37
+ }
38
+ }
39
+ const localUser = () => ({
40
+ id: "local",
41
+ tenantId: LOCAL_TENANT,
42
+ role: "owner",
43
+ name: userInfo().username || "Admin",
44
+ email: "",
45
+ });
46
+ function sameValue(a, b) {
47
+ const x = Buffer.from(a);
48
+ const y = Buffer.from(b);
49
+ return x.length === y.length && timingSafeEqual(x, y);
50
+ }
51
+ function setLocalCookie(c) {
52
+ setCookie(c, LOCAL_COOKIE, localCookieValue, {
53
+ httpOnly: true,
54
+ sameSite: "Strict",
55
+ secure,
56
+ path: cookiePath,
57
+ maxAge: 60 * 60 * 24 * 365,
58
+ });
59
+ }
60
+ // --- signed in at the Manage-App ------------------------------------------------
61
+ const SESSION_COOKIE = "wz_session";
62
+ /** How much of a wish goes along to the account's sign-in page. */
63
+ const WISH_MAX = 600;
64
+ const STATE_COOKIE = "wz_oauth";
65
+ const SESSION_DAYS = 30;
66
+ const SCOPE = "openid profile email offline_access wizards:read wizards:write wizards:publish runs:test";
67
+ // The desktop app shows a server in its window but signs in through the system browser
68
+ // (Google refuses embedded views). The finished session travels back as a one-time code in an
69
+ // `engenty-wizards://` link; it only counts in the window that asked for it, which holds the
70
+ // matching cookie — so a link sent by some web page signs nobody in.
71
+ const DESKTOP_COOKIE = "wz_desktop";
72
+ const usedHandoffs = new Set();
73
+ /** Tickets of the local one-time link that were opened, until they run out. */
74
+ const usedTickets = new Map();
75
+ const sessions = new Map();
76
+ const client = () => ({ id: env.manage.clientId, secret: env.manage.clientSecret || undefined });
77
+ /** Cookies and redirects stay under the path the app is served at. */
78
+ const cookiePath = basePath || "/";
79
+ /** Where a sign-in and the local link lead: the studio. */
80
+ const home = `${basePath}/studio/`;
81
+ const callbackUrl = () => `${env.appUrl}/api/auth/callback`;
82
+ function safeReturn(path) {
83
+ return path?.startsWith("/") && !path.startsWith("//") ? path : home;
84
+ }
85
+ function setSessionCookie(c, id) {
86
+ setCookie(c, SESSION_COOKIE, id, {
87
+ httpOnly: true,
88
+ sameSite: "Lax",
89
+ secure,
90
+ path: cookiePath,
91
+ maxAge: SESSION_DAYS * 24 * 3600,
92
+ });
93
+ }
94
+ async function claimsOf(tokens) {
95
+ const claims = await verifyToken(tokens.access_token, [env.appUrl]);
96
+ if (!claims) {
97
+ throw new Error("The Manage-App's token did not verify.");
98
+ }
99
+ return claims;
100
+ }
101
+ /** Renews tenant and role from the Manage-App once the access token they came from has run out. */
102
+ async function renew(row) {
103
+ const refresh = row.refreshToken ? unseal(row.refreshToken) : null;
104
+ if (!refresh) {
105
+ return null;
106
+ }
107
+ try {
108
+ const tokens = await tokenRequest({ grant_type: "refresh_token", refresh_token: refresh, resource: env.appUrl }, client());
109
+ const claims = await claimsOf(tokens);
110
+ const next = {
111
+ ...row,
112
+ tenantId: claims.tenantId,
113
+ role: claims.role,
114
+ name: claims.name || row.name,
115
+ email: claims.email || row.email,
116
+ refreshToken: tokens.refresh_token ? seal(tokens.refresh_token) : row.refreshToken,
117
+ claimsExpireAt: new Date(claims.expiresAt),
118
+ };
119
+ await controlDb.update(control.session).set(next).where(eq(control.session.id, row.id));
120
+ return next;
121
+ }
122
+ catch {
123
+ return null;
124
+ }
125
+ }
126
+ async function sessionPrincipal(id) {
127
+ const hit = sessions.get(id);
128
+ let row = hit && Date.now() - hit.at < 60_000
129
+ ? hit.row
130
+ : await controlDb.query.session.findFirst({ where: eq(control.session.id, id) });
131
+ if (!row || row.expiresAt.getTime() < Date.now()) {
132
+ sessions.delete(id);
133
+ return null;
134
+ }
135
+ if (row.claimsExpireAt.getTime() < Date.now()) {
136
+ const renewed = await renew(row);
137
+ if (!renewed) {
138
+ await controlDb.delete(control.session).where(eq(control.session.id, id));
139
+ sessions.delete(id);
140
+ return null;
141
+ }
142
+ row = renewed;
143
+ }
144
+ sessions.set(id, { at: Date.now(), row });
145
+ return {
146
+ id: row.userId,
147
+ tenantId: row.tenantId,
148
+ role: row.role,
149
+ name: row.name,
150
+ email: row.email,
151
+ image: row.image,
152
+ };
153
+ }
154
+ /** Sessions that ran out go once an hour, with the retention job. */
155
+ export async function purgeSessions() {
156
+ await controlDb.delete(control.session).where(lt(control.session.expiresAt, new Date()));
157
+ }
158
+ // --- both ------------------------------------------------------------------------
159
+ export async function principalOf(c) {
160
+ if (!managed) {
161
+ const cookie = getCookie(c, LOCAL_COOKIE);
162
+ return cookie && sameValue(cookie, localCookieValue) ? localUser() : null;
163
+ }
164
+ const id = getCookie(c, SESSION_COOKIE);
165
+ return id ? sessionPrincipal(id) : null;
166
+ }
167
+ const closePage = (message) => `<!doctype html><meta charset="utf-8"><title>engenty wizards</title>
168
+ <body style="font:16px system-ui;display:grid;place-items:center;height:100vh;margin:0;color:#333">
169
+ <p>${message}</p>`;
170
+ export const authRoutes = new Hono()
171
+ // Local: the one-time link. The key works once per start; a ticket (`wizards open`,
172
+ // the desktop app entering a runtime that already runs) once within its minute.
173
+ .get("/local/enter", (c) => {
174
+ const given = c.req.query("k") ?? "";
175
+ const ticket = c.req.query("t") ?? "";
176
+ const now = Date.now();
177
+ for (const [used, expires] of usedTickets) {
178
+ if (expires <= now) {
179
+ usedTickets.delete(used);
180
+ }
181
+ }
182
+ const expires = !managed && ticket && !usedTickets.has(ticket)
183
+ ? localTicketExpiry(env.authSecret, ticket, now)
184
+ : null;
185
+ if (expires) {
186
+ usedTickets.set(ticket, expires);
187
+ }
188
+ else if (managed || !accessKey || !sameValue(given, accessKey)) {
189
+ return c.text("This link is no longer valid. Run wizards open to get a new one.", 403);
190
+ }
191
+ else {
192
+ accessKey = null;
193
+ }
194
+ setLocalCookie(c);
195
+ return c.redirect(home);
196
+ })
197
+ // Local development only: the "Dev-Login" button.
198
+ .post("/dev/login", (c) => {
199
+ if (managed || !env.devLogin) {
200
+ return c.notFound();
201
+ }
202
+ setLocalCookie(c);
203
+ return c.json({ ok: true });
204
+ })
205
+ // The desktop app's window asks for a sign-in that will run in the system browser.
206
+ .post("/auth/desktop/start", (c) => {
207
+ if (!managed) {
208
+ return c.notFound();
209
+ }
210
+ const desktop = randomBytes(24).toString("base64url");
211
+ setCookie(c, DESKTOP_COOKIE, desktop, {
212
+ httpOnly: true,
213
+ sameSite: "Lax",
214
+ secure,
215
+ path: `${basePath}/api/auth`,
216
+ maxAge: 900,
217
+ });
218
+ const ticket = seal({ desktop, exp: Date.now() + 15 * 60_000 });
219
+ return c.json({ url: `${env.appUrl}/api/auth/login?desktop=${encodeURIComponent(ticket)}` });
220
+ })
221
+ .get("/auth/handoff", async (c) => {
222
+ const code = c.req.query("code") ?? "";
223
+ const handoff = unseal(code);
224
+ const desktop = getCookie(c, DESKTOP_COOKIE);
225
+ deleteCookie(c, DESKTOP_COOKIE, { path: `${basePath}/api/auth` });
226
+ if (!managed ||
227
+ !handoff ||
228
+ handoff.exp < Date.now() ||
229
+ !desktop ||
230
+ !sameValue(desktop, handoff.desktop) ||
231
+ usedHandoffs.has(handoff.sid)) {
232
+ return c.redirect(`${home}?signin=failed`);
233
+ }
234
+ usedHandoffs.add(handoff.sid);
235
+ setSessionCookie(c, handoff.sid);
236
+ return c.redirect(home);
237
+ })
238
+ .get("/auth/login", async (c) => {
239
+ if (!managed) {
240
+ return c.notFound();
241
+ }
242
+ const d = await discovery();
243
+ const verifier = randomBytes(32).toString("base64url");
244
+ const ticket = unseal(c.req.query("desktop") ?? "");
245
+ const state = {
246
+ verifier,
247
+ nonce: nanoid(16),
248
+ returnTo: safeReturn(c.req.query("return")),
249
+ exp: Date.now() + 15 * 60_000,
250
+ ...(ticket && ticket.exp > Date.now() ? { desktop: ticket.desktop } : {}),
251
+ };
252
+ setCookie(c, STATE_COOKIE, seal(state), {
253
+ httpOnly: true,
254
+ sameSite: "Lax",
255
+ secure,
256
+ path: `${basePath}/api/auth`,
257
+ maxAge: 900,
258
+ });
259
+ const url = new URL(d.authorization_endpoint);
260
+ url.search = new URLSearchParams({
261
+ response_type: "code",
262
+ client_id: env.manage.clientId,
263
+ redirect_uri: callbackUrl(),
264
+ scope: SCOPE,
265
+ resource: env.appUrl,
266
+ code_challenge: createHash("sha256").update(verifier).digest("base64url"),
267
+ code_challenge_method: "S256",
268
+ state: state.nonce,
269
+ }).toString();
270
+ // What the person wants built (the studio's start page): the account's sign-in page shows it.
271
+ const wish = (c.req.query("wish") ?? "").trim().slice(0, WISH_MAX);
272
+ if (wish) {
273
+ url.searchParams.set("wish", wish);
274
+ }
275
+ return c.redirect(url.toString());
276
+ })
277
+ .get("/auth/callback", async (c) => {
278
+ const code = c.req.query("code");
279
+ const rawState = c.req.query("state") ?? "";
280
+ if (!managed) {
281
+ // The linked account of a runtime that runs alone: the system browser lands here.
282
+ if (!code) {
283
+ return c.html(closePage("Sign-in cancelled. You can close this window."), 400);
284
+ }
285
+ try {
286
+ await finishLink(code, rawState);
287
+ // What is published here goes to the account's cloud, from now on and once for all there is.
288
+ void firstSync();
289
+ // The Pro modules the account's plan includes.
290
+ void refreshPro();
291
+ return c.html(closePage("Signed in. You can close this window."));
292
+ }
293
+ catch (err) {
294
+ console.error("[account]", err);
295
+ return c.html(closePage("The sign-in didn’t work. Try again."), 400);
296
+ }
297
+ }
298
+ const state = unseal(getCookie(c, STATE_COOKIE) ?? "");
299
+ deleteCookie(c, STATE_COOKIE, { path: `${basePath}/api/auth` });
300
+ if (!code || !state || state.exp < Date.now() || state.nonce !== rawState) {
301
+ return c.redirect(`${home}?signin=failed`);
302
+ }
303
+ try {
304
+ const tokens = await tokenRequest({
305
+ grant_type: "authorization_code",
306
+ code,
307
+ redirect_uri: callbackUrl(),
308
+ code_verifier: state.verifier,
309
+ resource: env.appUrl,
310
+ }, client());
311
+ const claims = await claimsOf(tokens);
312
+ const id = randomBytes(32).toString("base64url");
313
+ await controlDb.insert(control.session).values({
314
+ id,
315
+ userId: claims.userId,
316
+ tenantId: claims.tenantId,
317
+ role: claims.role,
318
+ name: claims.name || claims.email,
319
+ email: claims.email,
320
+ refreshToken: tokens.refresh_token ? seal(tokens.refresh_token) : null,
321
+ claimsExpireAt: new Date(claims.expiresAt),
322
+ expiresAt: new Date(Date.now() + SESSION_DAYS * 24 * 3600_000),
323
+ });
324
+ if (state.desktop) {
325
+ // The session belongs to the app's window, not to this browser.
326
+ const code = seal({
327
+ sid: id,
328
+ desktop: state.desktop,
329
+ exp: Date.now() + 2 * 60_000,
330
+ });
331
+ const link = `engenty-wizards://signin?code=${encodeURIComponent(code)}`;
332
+ return c.html(`${closePage("Signed in. Go back to engenty wizards now.")}
333
+ <script>location.href = ${JSON.stringify(link)};</script>`);
334
+ }
335
+ setSessionCookie(c, id);
336
+ return c.redirect(state.returnTo);
337
+ }
338
+ catch (err) {
339
+ console.error("[sign-in]", err);
340
+ return c.redirect(`${home}?signin=failed`);
341
+ }
342
+ })
343
+ .post("/auth/sign-out", async (c) => {
344
+ const id = getCookie(c, SESSION_COOKIE);
345
+ if (id) {
346
+ await controlDb.delete(control.session).where(eq(control.session.id, id));
347
+ sessions.delete(id);
348
+ }
349
+ deleteCookie(c, SESSION_COOKIE, { path: cookiePath });
350
+ deleteCookie(c, LOCAL_COOKIE, { path: cookiePath });
351
+ if (!managed) {
352
+ return c.json({ ok: true });
353
+ }
354
+ // The person signs out of the account too (the Manage-App's `/api/sign-out`, a form the page
355
+ // sends there): still signed in there, the sign-in page would sign them in again at once.
356
+ const d = await discovery().catch(() => null);
357
+ return c.json({ ok: true, account: d ? new URL("/api/sign-out", d.issuer).toString() : null });
358
+ });
@@ -0,0 +1,55 @@
1
+ import { createHash, randomBytes } from "node:crypto";
2
+ import { nanoid } from "nanoid";
3
+ import { readSetting, writeSetting } from "../settings.js";
4
+ /**
5
+ * API keys of a runtime that runs alone: the person's own MCP client (Claude Code, Cursor,
6
+ * Codex) and scripts sign in with them. Only the hash is kept. A runtime of a Manage-App has
7
+ * none of its own — keys are issued and checked there.
8
+ */
9
+ export const API_KEY_PREFIX = "wz_";
10
+ const hashOf = (key) => createHash("sha256").update(key).digest("hex");
11
+ /** A key that lives only as long as this process: the studio chat's own client signs in with it. */
12
+ let internal = null;
13
+ export function internalKey() {
14
+ internal ??= `${API_KEY_PREFIX}${randomBytes(24).toString("base64url")}`;
15
+ return internal;
16
+ }
17
+ const INTERNAL_CLIENT = "Claude (Abo)";
18
+ async function all() {
19
+ return (await readSetting("apiKeys")) ?? [];
20
+ }
21
+ export async function listLocalKeys() {
22
+ return (await all()).map(({ hash: _hash, ...rest }) => rest);
23
+ }
24
+ export async function createLocalKey(name) {
25
+ const key = `${API_KEY_PREFIX}${randomBytes(24).toString("base64url")}`;
26
+ const row = {
27
+ id: nanoid(12),
28
+ name,
29
+ start: key.slice(0, 8),
30
+ hash: hashOf(key),
31
+ createdAt: new Date().toISOString(),
32
+ lastRequest: null,
33
+ };
34
+ await writeSetting("apiKeys", [...(await all()), row]);
35
+ return { id: row.id, name, key };
36
+ }
37
+ export async function deleteLocalKey(id) {
38
+ await writeSetting("apiKeys", (await all()).filter((k) => k.id !== id));
39
+ }
40
+ export async function verifyLocalKey(key) {
41
+ if (internal && key === internal) {
42
+ return { id: "internal", name: INTERNAL_CLIENT };
43
+ }
44
+ const keys = await all();
45
+ const found = keys.find((k) => k.hash === hashOf(key));
46
+ if (!found) {
47
+ return null;
48
+ }
49
+ // One write a minute is enough to show the key is in use.
50
+ if (!found.lastRequest || Date.now() - Date.parse(found.lastRequest) > 60_000) {
51
+ found.lastRequest = new Date().toISOString();
52
+ await writeSetting("apiKeys", keys);
53
+ }
54
+ return { id: found.id, name: found.name };
55
+ }
@@ -0,0 +1,26 @@
1
+ import { createHmac, timingSafeEqual } from "node:crypto";
2
+ /**
3
+ * A second way through the one-time link: a ticket signed with the data folder's secret, good
4
+ * for a minute. Who can read that secret can already make the studio's cookie, so a ticket opens
5
+ * nothing new — it lets the command line and the desktop app enter a runtime that already runs.
6
+ */
7
+ const TTL_MS = 60_000;
8
+ /** The header `wizards mcp` signs its requests with, and the one naming its client. */
9
+ export const LOCAL_MCP_HEADER = "x-engenty-local";
10
+ export const LOCAL_CLIENT_HEADER = "x-engenty-client";
11
+ const sign = (secret, expires, purpose) => createHmac("sha256", secret).update(`${purpose}.${expires}`).digest("hex");
12
+ export function mintLocalTicket(secret, now = Date.now(), purpose = "local-enter") {
13
+ const expires = now + TTL_MS;
14
+ return `${expires}.${sign(secret, expires, purpose)}`;
15
+ }
16
+ /** When a ticket runs out, or null when it is not one of ours or already ran out. */
17
+ export function localTicketExpiry(secret, ticket, now = Date.now(), purpose = "local-enter") {
18
+ const [head, signature] = ticket.split(".");
19
+ const expires = Number(head);
20
+ if (!signature || !Number.isSafeInteger(expires) || expires <= now || expires > now + TTL_MS) {
21
+ return null;
22
+ }
23
+ const given = Buffer.from(signature);
24
+ const expected = Buffer.from(sign(secret, expires, purpose));
25
+ return given.length === expected.length && timingSafeEqual(given, expected) ? expires : null;
26
+ }
@@ -0,0 +1,74 @@
1
+ /**
2
+ * The wizard the authoring guide shows as an example of the schema: a post with an image. It is
3
+ * the guide's own, not a marketplace entry, so the guide never depends on the marketplace.
4
+ */
5
+ export const EXAMPLE_WIZARD = {
6
+ version: 1,
7
+ title: "X post with an image",
8
+ description: "Turns a topic into a finished post with an image.",
9
+ avatar: "flame",
10
+ lang: "en",
11
+ intro: "Tell me briefly what it is about – I write the post and draw the image for it.",
12
+ steps: [
13
+ {
14
+ id: "about",
15
+ type: "page",
16
+ title: "What is it about?",
17
+ fields: [
18
+ {
19
+ id: "topic",
20
+ label: "Topic or occasion",
21
+ kind: "textarea",
22
+ required: true,
23
+ placeholder: "e.g. We open our new studio in Vienna on Friday",
24
+ },
25
+ {
26
+ id: "tone",
27
+ label: "Tone",
28
+ kind: "select",
29
+ options: ["Casual", "Professional", "Funny", "Inspiring"],
30
+ default: "Casual",
31
+ },
32
+ { id: "link", label: "Link (optional)", kind: "url" },
33
+ ],
34
+ },
35
+ {
36
+ id: "post",
37
+ type: "agent",
38
+ title: "Write the post",
39
+ working: "Writing the post …",
40
+ instructions: "Write a post for X (Twitter) on the topic: {{topic}}. Tone: {{tone}}. At most 270 characters including the link, and at most two hashtags. If a link is given ({{link}}), put it at the end. A strong first sentence. Output only the post.",
41
+ tools: [],
42
+ output: { format: "text" },
43
+ model: "standard",
44
+ },
45
+ {
46
+ id: "visual",
47
+ type: "generate",
48
+ title: "Draw the image",
49
+ working: "Drawing the image …",
50
+ asset: "image",
51
+ prompt: "A striking image to go with this post: {{steps.post}}. Topic: {{topic}}. No text in the image.",
52
+ options: { aspectRatio: "16:9", style: "modern editorial, clean, high contrast" },
53
+ },
54
+ {
55
+ id: "check",
56
+ type: "review",
57
+ title: "Does this work?",
58
+ description: "You can change the text directly or ask for a new variant.",
59
+ show: ["post", "visual"],
60
+ edit: true,
61
+ regenerate: true,
62
+ },
63
+ {
64
+ id: "done",
65
+ type: "result",
66
+ title: "Ready to post",
67
+ message: "Copy the text and download the image.",
68
+ deliverables: [
69
+ { from: "post", label: "Post", formats: ["txt", "md"] },
70
+ { from: "visual", label: "Image", formats: ["png"] },
71
+ ],
72
+ },
73
+ ],
74
+ };