@engenty/wizards-runtime 0.7.11 → 0.9.0

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 (257) hide show
  1. package/README.md +5 -1
  2. package/apps/runtime/dist/agents/architect.js +2 -2
  3. package/apps/runtime/dist/agents/studio-assistant.js +1 -1
  4. package/apps/runtime/dist/agents/website.js +1 -1
  5. package/apps/runtime/dist/app.js +1 -1
  6. package/apps/runtime/dist/assistant/browser.js +1 -1
  7. package/apps/runtime/dist/authoring/guide.js +16 -4
  8. package/apps/runtime/dist/authoring/ops.js +1 -1
  9. package/apps/runtime/dist/cli/exec.js +4 -1
  10. package/apps/runtime/dist/cli/features.js +1 -1
  11. package/apps/runtime/dist/cli/validate.js +2 -2
  12. package/apps/runtime/dist/connectors/builtin.js +4 -2
  13. package/apps/runtime/dist/connectors/external.js +1 -1
  14. package/apps/runtime/dist/connectors/index.js +37 -6
  15. package/apps/runtime/dist/connectors/smtp.js +221 -0
  16. package/apps/runtime/dist/connectors/via-account.js +1 -1
  17. package/apps/runtime/dist/credits/estimate.js +1 -1
  18. package/apps/runtime/dist/db/migrations/tenant/0018_share_job.sql +18 -0
  19. package/apps/runtime/dist/db/migrations/tenant/meta/0018_snapshot.json +3460 -0
  20. package/apps/runtime/dist/db/migrations/tenant/meta/_journal.json +7 -0
  21. package/apps/runtime/dist/db/schema.js +19 -0
  22. package/apps/runtime/dist/docs/dev/index.md +25 -13
  23. package/apps/runtime/dist/docs/dev/integration/index.md +1 -1
  24. package/apps/runtime/dist/docs/dev/integration/openui.md +1 -1
  25. package/apps/runtime/dist/docs/dev/integration/own-ui.md +2 -2
  26. package/apps/runtime/dist/docs/dev/meta.json +8 -2
  27. package/apps/runtime/dist/docs/dev/plugins/examples.md +2 -3
  28. package/apps/runtime/dist/docs/dev/plugins/studio.md +5 -6
  29. package/apps/runtime/dist/docs/dev/plugins/styling.md +10 -7
  30. package/apps/runtime/dist/docs/dev/wizard-format/agent-steps.md +112 -0
  31. package/apps/runtime/dist/docs/dev/wizard-format/branches.md +63 -0
  32. package/apps/runtime/dist/docs/dev/wizard-format/film-steps.md +47 -0
  33. package/apps/runtime/dist/docs/dev/wizard-format/generate-steps.md +57 -0
  34. package/apps/runtime/dist/docs/dev/wizard-format/index.md +188 -0
  35. package/apps/runtime/dist/docs/dev/wizard-format/lists-and-connections.md +65 -0
  36. package/apps/runtime/dist/docs/dev/wizard-format/meta.json +19 -0
  37. package/apps/runtime/dist/docs/dev/wizard-format/pages-and-fields.md +102 -0
  38. package/apps/runtime/dist/docs/dev/wizard-format/review-and-result.md +64 -0
  39. package/apps/runtime/dist/docs/dev/wizard-format/templates.md +57 -0
  40. package/apps/runtime/dist/docs/dev/wizard-format/validate.md +63 -0
  41. package/apps/runtime/dist/docs/dev/wizard-format/views-and-widgets.md +103 -0
  42. package/apps/runtime/dist/docs/dev/wizard-format/wizard-file.md +147 -0
  43. package/apps/runtime/dist/docs/user/build-a-wizard.md +2 -2
  44. package/apps/runtime/dist/docs/user/run.md +21 -4
  45. package/apps/runtime/dist/docs/user/space.md +14 -10
  46. package/apps/runtime/dist/docs/user/steps.md +26 -1
  47. package/apps/runtime/dist/docs/user/test-and-share.md +3 -2
  48. package/apps/runtime/dist/documents/parse.js +1 -1
  49. package/apps/runtime/dist/engine/decide.js +1 -1
  50. package/apps/runtime/dist/engine/events.js +1 -1
  51. package/apps/runtime/dist/engine/input.js +3 -3
  52. package/apps/runtime/dist/engine/prepare.js +1 -1
  53. package/apps/runtime/dist/engine/requirements.js +25 -10
  54. package/apps/runtime/dist/engine/runner.js +23 -14
  55. package/apps/runtime/dist/engine/steps.js +6 -6
  56. package/apps/runtime/dist/engine/surface.js +3 -3
  57. package/apps/runtime/dist/engine/template.js +4 -4
  58. package/apps/runtime/dist/env.js +5 -0
  59. package/apps/runtime/dist/features.js +1 -1
  60. package/apps/runtime/dist/film/project.js +2 -2
  61. package/apps/runtime/dist/film/step.js +2 -2
  62. package/apps/runtime/dist/harness/antigravity.js +2 -10
  63. package/apps/runtime/dist/harness/apple.js +1 -1
  64. package/apps/runtime/dist/harness/claude.js +3 -11
  65. package/apps/runtime/dist/harness/codex.js +6 -12
  66. package/apps/runtime/dist/harness/cursor.js +2 -10
  67. package/apps/runtime/dist/harness/env.js +23 -0
  68. package/apps/runtime/dist/harness/index.js +6 -3
  69. package/apps/runtime/dist/harness/model.js +1 -1
  70. package/apps/runtime/dist/harness/terminal.js +1 -1
  71. package/apps/runtime/dist/mcp/flow-app.js +1 -1
  72. package/apps/runtime/dist/media/conversation.js +1 -1
  73. package/apps/runtime/dist/media/transcribe.js +1 -1
  74. package/apps/runtime/dist/model-errors.js +1 -1
  75. package/apps/runtime/dist/models.js +3 -3
  76. package/apps/runtime/dist/plugin.js +1 -1
  77. package/apps/runtime/dist/plugins/discovery.js +1 -1
  78. package/apps/runtime/dist/plugins/loader.js +2 -2
  79. package/apps/runtime/dist/plugins/runs.js +2 -2
  80. package/apps/runtime/dist/render/downloads.js +2 -2
  81. package/apps/runtime/dist/render/shaped.js +1 -1
  82. package/apps/runtime/dist/routes/api.js +2 -2
  83. package/apps/runtime/dist/routes/lang.js +1 -1
  84. package/apps/runtime/dist/routes/marketplace.js +1 -1
  85. package/apps/runtime/dist/routes/runs.js +110 -10
  86. package/apps/runtime/dist/routes/studio.js +20 -8
  87. package/apps/runtime/dist/services/access.js +1 -1
  88. package/apps/runtime/dist/services/api.js +4 -4
  89. package/apps/runtime/dist/services/assistant-chats.js +2 -2
  90. package/apps/runtime/dist/services/brand.js +2 -2
  91. package/apps/runtime/dist/services/cloud.js +1 -1
  92. package/apps/runtime/dist/services/errors.js +1 -1
  93. package/apps/runtime/dist/services/files.js +1 -1
  94. package/apps/runtime/dist/services/knowledge-model.js +3 -3
  95. package/apps/runtime/dist/services/knowledge.js +2 -2
  96. package/apps/runtime/dist/services/marketplace.js +5 -5
  97. package/apps/runtime/dist/services/package-file.js +3 -3
  98. package/apps/runtime/dist/services/package.js +2 -2
  99. package/apps/runtime/dist/services/profile.js +1 -1
  100. package/apps/runtime/dist/services/project-files.js +2 -2
  101. package/apps/runtime/dist/services/project-index.js +1 -1
  102. package/apps/runtime/dist/services/projects.js +2 -2
  103. package/apps/runtime/dist/services/runners.js +3 -3
  104. package/apps/runtime/dist/services/runs.js +2 -2
  105. package/apps/runtime/dist/services/shares.js +1 -1
  106. package/apps/runtime/dist/services/site.js +2 -2
  107. package/apps/runtime/dist/services/space-categories.js +3 -3
  108. package/apps/runtime/dist/services/space-data.js +4 -4
  109. package/apps/runtime/dist/services/spaces.js +6 -6
  110. package/apps/runtime/dist/services/translations.js +5 -5
  111. package/apps/runtime/dist/services/widgets.js +1 -1
  112. package/apps/runtime/dist/services/wizards.js +3 -3
  113. package/apps/runtime/dist/sharing/agent.js +65 -0
  114. package/apps/runtime/dist/sharing/files.js +121 -0
  115. package/apps/runtime/dist/sharing/index.js +298 -0
  116. package/apps/runtime/dist/sharing/jobs.js +186 -0
  117. package/apps/runtime/dist/sharing/state.js +116 -0
  118. package/apps/runtime/dist/sharing/targets/browser.js +131 -0
  119. package/apps/runtime/dist/sharing/targets/connector.js +63 -0
  120. package/apps/runtime/dist/sharing/targets/email.js +98 -0
  121. package/apps/runtime/dist/sharing/targets/slack.js +54 -0
  122. package/apps/runtime/dist/sharing/targets/storage.js +164 -0
  123. package/apps/runtime/dist/sharing/types.js +13 -0
  124. package/apps/runtime/dist/store/index.js +3 -3
  125. package/apps/runtime/dist/store/shared-lists.js +1 -1
  126. package/apps/runtime/dist/texts.js +109 -1
  127. package/apps/runtime/dist/tools/browser.js +48 -0
  128. package/apps/runtime/dist/tools/connector.js +3 -2
  129. package/apps/runtime/dist/tools/index.js +1 -1
  130. package/apps/runtime/dist/tools/plugin.js +2 -2
  131. package/apps/runtime/dist/tools/project.js +1 -1
  132. package/apps/runtime/dist/tools/store.js +20 -3
  133. package/apps/runtime/dist/widgets/bundle.js +1 -1
  134. package/apps/runtime/dist/widgets/step.js +3 -3
  135. package/apps/web/dist/assets/AboutDialog-CB0EwGxP.js +1 -0
  136. package/apps/web/dist/assets/{ChangelogDialog-CZrd-MgC.js → ChangelogDialog-BQRBkiVD.js} +1 -1
  137. package/apps/web/dist/assets/ChatView-BLZkLlHi.js +10 -0
  138. package/apps/web/dist/assets/EditorPage-YawfYRAL.js +4 -0
  139. package/apps/web/dist/assets/{FlowPreview-oX_Emm7u.js → FlowPreview-B0xF8e3r.js} +1 -1
  140. package/apps/web/dist/assets/{Harness-DiB8CBdY.js → Harness-snRbALGd.js} +2 -2
  141. package/apps/web/dist/assets/NewWizardChannels-BGzp9z0m.js +1 -0
  142. package/apps/web/dist/assets/{NewWizardPage-C2Oh2sMM.js → NewWizardPage-cOHfwcnA.js} +2 -2
  143. package/apps/web/dist/assets/OnboardingPage-jB3ChKi3.js +1 -0
  144. package/apps/web/dist/assets/ProjectPage-hRCBquNb.js +1 -0
  145. package/apps/web/dist/assets/PublicRunner-D_ZkOyRV.js +1 -0
  146. package/apps/web/dist/assets/{ReadOnly-CD5YWvrW.js → ReadOnly-Db_odT6Y.js} +1 -1
  147. package/apps/web/dist/assets/RunDrawer-B6AQw90D.js +4 -0
  148. package/apps/web/dist/assets/RunnerView-DHUkvi_G.js +1 -0
  149. package/apps/web/dist/assets/SettingsPage-DleMaLz8.js +2 -0
  150. package/apps/web/dist/assets/SetupPage-DTvVJR1U.js +1 -0
  151. package/apps/web/dist/assets/{SharePage-B6u9kS12.js → SharePage-Bl-rfCji.js} +1 -1
  152. package/apps/web/dist/assets/changelog-BcW79fHm.js +1 -0
  153. package/apps/web/dist/assets/esm-Bji0ThaK.js +7 -0
  154. package/apps/web/dist/assets/index-CQKA-z2z.js +14 -0
  155. package/apps/web/dist/assets/index-Cnziz-H-.css +1 -0
  156. package/apps/web/dist/assets/oss-credits-BjwxLtU4.js +1 -0
  157. package/apps/web/dist/assets/{phone-BjmhIKuT.js → phone-DwAf8S3l.js} +1 -1
  158. package/apps/web/dist/assets/settings-menu-B1ND1GF3.js +1 -0
  159. package/apps/web/dist/assets/ui-Cdv3QUOd.js +137 -0
  160. package/apps/web/dist/assets/{upload-JX9BcMTq.js → upload-DCMZI6pp.js} +1 -1
  161. package/apps/web/dist/assets/{wrench-BSxnPs2_.js → wrench-BRYtnxti.js} +1 -1
  162. package/apps/web/dist/index.html +3 -3
  163. package/apps/web/dist/mcp/flow.html +53 -53
  164. package/node_modules/{@engenty-wizards/shared → @engenty/wizards-shared}/dist/definition.d.ts +22 -0
  165. package/node_modules/{@engenty-wizards/shared → @engenty/wizards-shared}/dist/definition.js +26 -0
  166. package/node_modules/{@engenty-wizards/shared → @engenty/wizards-shared}/dist/run.d.ts +6 -0
  167. package/node_modules/{@engenty-wizards/shared → @engenty/wizards-shared}/dist/run.js +2 -0
  168. package/node_modules/@engenty/wizards-shared/dist/sharing.d.ts +135 -0
  169. package/node_modules/@engenty/wizards-shared/dist/sharing.js +11 -0
  170. package/node_modules/{@engenty-wizards/shared → @engenty/wizards-shared}/dist/store.d.ts +8 -0
  171. package/node_modules/{@engenty-wizards/shared → @engenty/wizards-shared}/package.json +1 -1
  172. package/package.json +4 -3
  173. package/plugin/.claude-plugin/plugin.json +1 -1
  174. package/apps/runtime/dist/docs/dev/wizard-format.md +0 -125
  175. package/apps/web/dist/assets/AboutDialog-CPRAlD2H.js +0 -1
  176. package/apps/web/dist/assets/ChatView-DVeERQdi.js +0 -10
  177. package/apps/web/dist/assets/EditorPage-DhUoKcss.js +0 -4
  178. package/apps/web/dist/assets/NewWizardChannels-Ba3XGpro.js +0 -1
  179. package/apps/web/dist/assets/OnboardingPage-D_4ShWrL.js +0 -1
  180. package/apps/web/dist/assets/ProjectPage-C58rq50b.js +0 -1
  181. package/apps/web/dist/assets/PublicRunner-CE0ohzyd.js +0 -1
  182. package/apps/web/dist/assets/RunDrawer-Cd8-qHV7.js +0 -4
  183. package/apps/web/dist/assets/RunnerView-BW1h4x63.js +0 -1
  184. package/apps/web/dist/assets/SettingsPage-ChYLv-MG.js +0 -1
  185. package/apps/web/dist/assets/SetupPage-hX7deF0g.js +0 -1
  186. package/apps/web/dist/assets/changelog-Dn9LT4MS.js +0 -1
  187. package/apps/web/dist/assets/esm-C-ZWeuhU.js +0 -7
  188. package/apps/web/dist/assets/index-4jH2mkp7.js +0 -14
  189. package/apps/web/dist/assets/index-BwW652E-.css +0 -1
  190. package/apps/web/dist/assets/oss-credits-Bc05Qv5H.js +0 -1
  191. package/apps/web/dist/assets/settings-menu-Dpkp3f56.js +0 -1
  192. package/apps/web/dist/assets/ui-DMmT-cSO.js +0 -137
  193. /package/node_modules/{@engenty-wizards/shared → @engenty/wizards-shared}/dist/assistant.d.ts +0 -0
  194. /package/node_modules/{@engenty-wizards/shared → @engenty/wizards-shared}/dist/assistant.js +0 -0
  195. /package/node_modules/{@engenty-wizards/shared → @engenty/wizards-shared}/dist/changes.d.ts +0 -0
  196. /package/node_modules/{@engenty-wizards/shared → @engenty/wizards-shared}/dist/changes.js +0 -0
  197. /package/node_modules/{@engenty-wizards/shared → @engenty/wizards-shared}/dist/claude-plugin.d.ts +0 -0
  198. /package/node_modules/{@engenty-wizards/shared → @engenty/wizards-shared}/dist/claude-plugin.js +0 -0
  199. /package/node_modules/{@engenty-wizards/shared → @engenty/wizards-shared}/dist/connectors.d.ts +0 -0
  200. /package/node_modules/{@engenty-wizards/shared → @engenty/wizards-shared}/dist/connectors.js +0 -0
  201. /package/node_modules/{@engenty-wizards/shared → @engenty/wizards-shared}/dist/decision.d.ts +0 -0
  202. /package/node_modules/{@engenty-wizards/shared → @engenty/wizards-shared}/dist/decision.js +0 -0
  203. /package/node_modules/{@engenty-wizards/shared → @engenty/wizards-shared}/dist/engenty/data-tables/columns-format.d.ts +0 -0
  204. /package/node_modules/{@engenty-wizards/shared → @engenty/wizards-shared}/dist/engenty/data-tables/columns-format.js +0 -0
  205. /package/node_modules/{@engenty-wizards/shared → @engenty/wizards-shared}/dist/engenty/data-tables/columns-value.d.ts +0 -0
  206. /package/node_modules/{@engenty-wizards/shared → @engenty/wizards-shared}/dist/engenty/data-tables/columns-value.js +0 -0
  207. /package/node_modules/{@engenty-wizards/shared → @engenty/wizards-shared}/dist/engenty/data-tables/columns.d.ts +0 -0
  208. /package/node_modules/{@engenty-wizards/shared → @engenty/wizards-shared}/dist/engenty/data-tables/columns.js +0 -0
  209. /package/node_modules/{@engenty-wizards/shared → @engenty/wizards-shared}/dist/engenty/data-tables/index.d.ts +0 -0
  210. /package/node_modules/{@engenty-wizards/shared → @engenty/wizards-shared}/dist/engenty/data-tables/index.js +0 -0
  211. /package/node_modules/{@engenty-wizards/shared → @engenty/wizards-shared}/dist/engenty/search-index/catalog-lexical.d.ts +0 -0
  212. /package/node_modules/{@engenty-wizards/shared → @engenty/wizards-shared}/dist/engenty/search-index/catalog-lexical.js +0 -0
  213. /package/node_modules/{@engenty-wizards/shared → @engenty/wizards-shared}/dist/engenty/search-index/catalog-rank.d.ts +0 -0
  214. /package/node_modules/{@engenty-wizards/shared → @engenty/wizards-shared}/dist/engenty/search-index/catalog-rank.js +0 -0
  215. /package/node_modules/{@engenty-wizards/shared → @engenty/wizards-shared}/dist/feature-flags.d.ts +0 -0
  216. /package/node_modules/{@engenty-wizards/shared → @engenty/wizards-shared}/dist/feature-flags.js +0 -0
  217. /package/node_modules/{@engenty-wizards/shared → @engenty/wizards-shared}/dist/features.d.ts +0 -0
  218. /package/node_modules/{@engenty-wizards/shared → @engenty/wizards-shared}/dist/features.js +0 -0
  219. /package/node_modules/{@engenty-wizards/shared → @engenty/wizards-shared}/dist/fit.d.ts +0 -0
  220. /package/node_modules/{@engenty-wizards/shared → @engenty/wizards-shared}/dist/fit.js +0 -0
  221. /package/node_modules/{@engenty-wizards/shared → @engenty/wizards-shared}/dist/json-schema.d.ts +0 -0
  222. /package/node_modules/{@engenty-wizards/shared → @engenty/wizards-shared}/dist/json-schema.js +0 -0
  223. /package/node_modules/{@engenty-wizards/shared → @engenty/wizards-shared}/dist/knowledge.d.ts +0 -0
  224. /package/node_modules/{@engenty-wizards/shared → @engenty/wizards-shared}/dist/knowledge.js +0 -0
  225. /package/node_modules/{@engenty-wizards/shared → @engenty/wizards-shared}/dist/marketplace-entry.d.ts +0 -0
  226. /package/node_modules/{@engenty-wizards/shared → @engenty/wizards-shared}/dist/marketplace-entry.js +0 -0
  227. /package/node_modules/{@engenty-wizards/shared → @engenty/wizards-shared}/dist/marketplace-search.d.ts +0 -0
  228. /package/node_modules/{@engenty-wizards/shared → @engenty/wizards-shared}/dist/marketplace-search.js +0 -0
  229. /package/node_modules/{@engenty-wizards/shared → @engenty/wizards-shared}/dist/marketplace.d.ts +0 -0
  230. /package/node_modules/{@engenty-wizards/shared → @engenty/wizards-shared}/dist/marketplace.js +0 -0
  231. /package/node_modules/{@engenty-wizards/shared → @engenty/wizards-shared}/dist/merge.d.ts +0 -0
  232. /package/node_modules/{@engenty-wizards/shared → @engenty/wizards-shared}/dist/merge.js +0 -0
  233. /package/node_modules/{@engenty-wizards/shared → @engenty/wizards-shared}/dist/numbers.d.ts +0 -0
  234. /package/node_modules/{@engenty-wizards/shared → @engenty/wizards-shared}/dist/numbers.js +0 -0
  235. /package/node_modules/{@engenty-wizards/shared → @engenty/wizards-shared}/dist/projects.d.ts +0 -0
  236. /package/node_modules/{@engenty-wizards/shared → @engenty/wizards-shared}/dist/projects.js +0 -0
  237. /package/node_modules/{@engenty-wizards/shared → @engenty/wizards-shared}/dist/providers.d.ts +0 -0
  238. /package/node_modules/{@engenty-wizards/shared → @engenty/wizards-shared}/dist/providers.js +0 -0
  239. /package/node_modules/{@engenty-wizards/shared → @engenty/wizards-shared}/dist/runner-texts.d.ts +0 -0
  240. /package/node_modules/{@engenty-wizards/shared → @engenty/wizards-shared}/dist/runner-texts.js +0 -0
  241. /package/node_modules/{@engenty-wizards/shared → @engenty/wizards-shared}/dist/runners.d.ts +0 -0
  242. /package/node_modules/{@engenty-wizards/shared → @engenty/wizards-shared}/dist/runners.js +0 -0
  243. /package/node_modules/{@engenty-wizards/shared → @engenty/wizards-shared}/dist/shape.d.ts +0 -0
  244. /package/node_modules/{@engenty-wizards/shared → @engenty/wizards-shared}/dist/shape.js +0 -0
  245. /package/node_modules/{@engenty-wizards/shared → @engenty/wizards-shared}/dist/space-data.d.ts +0 -0
  246. /package/node_modules/{@engenty-wizards/shared → @engenty/wizards-shared}/dist/space-data.js +0 -0
  247. /package/node_modules/{@engenty-wizards/shared → @engenty/wizards-shared}/dist/store.js +0 -0
  248. /package/node_modules/{@engenty-wizards/shared → @engenty/wizards-shared}/dist/surface.d.ts +0 -0
  249. /package/node_modules/{@engenty-wizards/shared → @engenty/wizards-shared}/dist/surface.js +0 -0
  250. /package/node_modules/{@engenty-wizards/shared → @engenty/wizards-shared}/dist/texts.d.ts +0 -0
  251. /package/node_modules/{@engenty-wizards/shared → @engenty/wizards-shared}/dist/texts.js +0 -0
  252. /package/node_modules/{@engenty-wizards/shared → @engenty/wizards-shared}/dist/translation.d.ts +0 -0
  253. /package/node_modules/{@engenty-wizards/shared → @engenty/wizards-shared}/dist/translation.js +0 -0
  254. /package/node_modules/{@engenty-wizards/shared → @engenty/wizards-shared}/dist/wizard-package.d.ts +0 -0
  255. /package/node_modules/{@engenty-wizards/shared → @engenty/wizards-shared}/dist/wizard-package.js +0 -0
  256. /package/node_modules/{@engenty-wizards/shared → @engenty/wizards-shared}/dist/workspace.d.ts +0 -0
  257. /package/node_modules/{@engenty-wizards/shared → @engenty/wizards-shared}/dist/workspace.js +0 -0
@@ -1,5 +1,5 @@
1
- import { note } from "@engenty-wizards/shared/run";
2
- import { resolveEnv, run } from "./env.js";
1
+ import { note } from "@engenty/wizards-shared/run";
2
+ import { probeVersion, resolveEnv, run } from "./env.js";
3
3
  import { failureOf, HarnessModel, lastJson, runClient, } from "./model.js";
4
4
  /**
5
5
  * Claude Code: `claude -p` answers on the person's sign-in — the client's keychain, or the key
@@ -132,15 +132,7 @@ export const claude = {
132
132
  name: "Claude Code",
133
133
  bin: CLAUDE_BIN,
134
134
  classes: CLASSES,
135
- async version(env) {
136
- try {
137
- const { stdout } = await run(CLAUDE_BIN, ["--version"], { timeout: 5000, env });
138
- return stdout.trim().split(/\s+/)[0] || stdout.trim();
139
- }
140
- catch {
141
- return null;
142
- }
143
- },
135
+ version: (env) => probeVersion(CLAUDE_BIN, env, (stdout) => stdout.trim().split(/\s+/)[0] || stdout.trim()),
144
136
  login: { args: ["auth", "login"], interactive: false },
145
137
  model: (alias, effort) => new ClaudeCodeModel(claude, alias || "sonnet", effort),
146
138
  exhausted: note("anthropicAccountClaudeCode"),
@@ -1,8 +1,8 @@
1
1
  import { existsSync, readdirSync, readFileSync, rmSync, statSync, writeFileSync } from "node:fs";
2
2
  import { homedir } from "node:os";
3
3
  import { join } from "node:path";
4
- import { note } from "@engenty-wizards/shared/run";
5
- import { resolveEnv, run } from "./env.js";
4
+ import { note } from "@engenty/wizards-shared/run";
5
+ import { probeVersion, resolveEnv, run } from "./env.js";
6
6
  import { failureOf, HarnessImageModel, HarnessModel, runClient, } from "./model.js";
7
7
  /**
8
8
  * Codex: `codex exec` answers on the ChatGPT sign-in kept in CODEX_HOME. The person's own
@@ -212,16 +212,10 @@ export const codex = {
212
212
  name: "Codex",
213
213
  bin: CODEX_BIN,
214
214
  classes: CLASSES,
215
- async version(env) {
216
- try {
217
- const { stdout } = await run(CODEX_BIN, ["--version"], { timeout: 5000, env });
218
- const words = stdout.trim().split(/\s+/);
219
- return words[words.length - 1] || null;
220
- }
221
- catch {
222
- return null;
223
- }
224
- },
215
+ version: (env) => probeVersion(CODEX_BIN, env, (stdout) => {
216
+ const words = stdout.trim().split(/\s+/);
217
+ return words[words.length - 1] || null;
218
+ }),
225
219
  login: { args: ["login"], interactive: false },
226
220
  model: (alias, effort) => new CodexModel(codex, alias || "default", effort),
227
221
  image: { alias: "image", model: (alias) => new CodexImageModel(codex, alias || "image") },
@@ -1,6 +1,6 @@
1
1
  import { mkdirSync, writeFileSync } from "node:fs";
2
2
  import { join } from "node:path";
3
- import { resolveEnv, run } from "./env.js";
3
+ import { probeVersion, resolveEnv, run } from "./env.js";
4
4
  import { failureOf, HarnessModel, lastJson, runClient, } from "./model.js";
5
5
  /**
6
6
  * Cursor Agent: `cursor-agent -p` answers on the Cursor sign-in. The call's folder is its
@@ -79,15 +79,7 @@ export const cursor = {
79
79
  name: "Cursor Agent",
80
80
  bin: CURSOR_BIN,
81
81
  classes: CLASSES,
82
- async version(env) {
83
- try {
84
- const { stdout } = await run(CURSOR_BIN, ["--version"], { timeout: 10_000, env });
85
- return stdout.trim().split("\n").pop()?.trim() || null;
86
- }
87
- catch {
88
- return null;
89
- }
90
- },
82
+ version: (env) => probeVersion(CURSOR_BIN, env, (stdout) => stdout.trim().split("\n").pop()?.trim() || null),
91
83
  login: { args: ["login"], interactive: false },
92
84
  model: (alias, effort) => new CursorModel(cursor, alias || "auto", effort),
93
85
  };
@@ -3,6 +3,29 @@ import { join } from "node:path";
3
3
  import { runFile } from "../cli/exec.js";
4
4
  import { layout } from "../cli/home.js";
5
5
  export const run = runFile;
6
+ /** A version probe that could not finish: the machine is busy, the client may well be there. */
7
+ export class ProbeUndecided extends Error {
8
+ }
9
+ /** Spawn failures that say the machine is short of something, not that the client is missing. */
10
+ const BUSY_CODES = new Set(["EAGAIN", "EMFILE", "ENFILE", "ENOMEM"]);
11
+ /**
12
+ * `<bin> --version`, read by `pick`. Null: the client is not there or does not answer. A probe
13
+ * that ran out of time or could not start for want of resources throws ProbeUndecided: a client
14
+ * that starts slowly while another one is busy is still installed.
15
+ */
16
+ export async function probeVersion(bin, env, pick) {
17
+ try {
18
+ const { stdout } = await run(bin, ["--version"], { timeout: 15_000, env });
19
+ return pick(stdout);
20
+ }
21
+ catch (err) {
22
+ const { killed, code } = err;
23
+ if (killed || (typeof code === "string" && BUSY_CODES.has(code))) {
24
+ throw new ProbeUndecided(`${bin} --version did not finish`, { cause: err });
25
+ }
26
+ return null;
27
+ }
28
+ }
6
29
  let shellEnv = null;
7
30
  /** The person's login shell, asked once: a desktop app and a bare dev server start without its variables. */
8
31
  export function loginShellEnv() {
@@ -7,7 +7,7 @@ import { antigravity } from "./antigravity.js";
7
7
  import { claude } from "./claude.js";
8
8
  import { codex } from "./codex.js";
9
9
  import { cursor } from "./cursor.js";
10
- import { forgetEnv, loginShellEnv, resolveEnv } from "./env.js";
10
+ import { forgetEnv, loginShellEnv, ProbeUndecided, resolveEnv } from "./env.js";
11
11
  export { HarnessModel, notInstalled, signedOut } from "./model.js";
12
12
  export { HARNESS_IDS } from "./types.js";
13
13
  /**
@@ -55,8 +55,11 @@ export async function detectHarness(id, force = false) {
55
55
  value = { ...value, version, auth };
56
56
  }
57
57
  }
58
- catch {
59
- // not installed
58
+ catch (err) {
59
+ if (err instanceof ProbeUndecided && hit?.value.version) {
60
+ // The machine is busy (another client is working): the client was there, it still is.
61
+ value = hit.value;
62
+ }
60
63
  }
61
64
  detected.set(id, { at: Date.now(), value });
62
65
  return value;
@@ -1,6 +1,6 @@
1
1
  import { mkdirSync, rmSync, writeFileSync } from "node:fs";
2
2
  import { join } from "node:path";
3
- import { note } from "@engenty-wizards/shared/run";
3
+ import { note } from "@engenty/wizards-shared/run";
4
4
  import spawn from "cross-spawn";
5
5
  import { nanoid } from "nanoid";
6
6
  import { env } from "../env.js";
@@ -1,7 +1,7 @@
1
1
  import { accessSync, chmodSync, constants } from "node:fs";
2
2
  import { createRequire } from "node:module";
3
3
  import { dirname, join } from "node:path";
4
- import { note } from "@engenty-wizards/shared/run";
4
+ import { note } from "@engenty/wizards-shared/run";
5
5
  import { nanoid } from "nanoid";
6
6
  import { ServiceError } from "../services/errors.js";
7
7
  const BUFFER = 200_000;
@@ -14,7 +14,7 @@ import { draftIssues, ownedWizard, publishedVersion } from "../services/wizards.
14
14
  /** Built by the web app (`vite.mcp-app.config.ts`) into one HTML file with everything inline. */
15
15
  const FLOW_APP_FILE = resolve(dirname(fileURLToPath(import.meta.url)), "../../../web/dist/mcp/flow.html");
16
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>`;
17
+ The flow widget is not built: run <code>pnpm --filter @engenty/wizards-studio build</code>.</body>`;
18
18
  function readWidget() {
19
19
  try {
20
20
  return readFileSync(FLOW_APP_FILE, "utf8");
@@ -1,4 +1,4 @@
1
- import { langNameEn } from "@engenty-wizards/shared/definition";
1
+ import { langNameEn } from "@engenty/wizards-shared/definition";
2
2
  import { NotedError } from "../model-errors.js";
3
3
  import { conversationAccess } from "../models.js";
4
4
  /**
@@ -1,6 +1,6 @@
1
1
  import { readFile, writeFile } from "node:fs/promises";
2
2
  import { join } from "node:path";
3
- import { SPEECH_LOCALES } from "@engenty-wizards/shared/definition";
3
+ import { SPEECH_LOCALES } from "@engenty/wizards-shared/definition";
4
4
  import { generateText, experimental_transcribe as transcribe } from "ai";
5
5
  import { costOf, listenerModel, transcriptionCostUsd } from "../models.js";
6
6
  import { ffmpeg, hasFfmpeg, probeMedia, withTempDir } from "./ffmpeg.js";
@@ -1,4 +1,4 @@
1
- import { noteText } from "@engenty-wizards/shared/run";
1
+ import { noteText } from "@engenty/wizards-shared/run";
2
2
  import { serverText } from "./texts.js";
3
3
  /**
4
4
  * A failure the person reads, given as a note of `RUN_NOTES` or a line of the server's table
@@ -6,9 +6,9 @@ import { createGateway } from "@ai-sdk/gateway";
6
6
  import { createGoogle } from "@ai-sdk/google";
7
7
  import { createOpenAI } from "@ai-sdk/openai";
8
8
  import { createReplicate } from "@ai-sdk/replicate";
9
- import { MODEL_CLASSES, TEXT_CLASSES, } from "@engenty-wizards/shared/definition";
10
- import { CAPABILITY_CLASSES, creditsModelOf, isCreditsRef, PROVIDER_IDS, providerInfo, providerOfRef, } from "@engenty-wizards/shared/providers";
11
- import { note, saidText } from "@engenty-wizards/shared/run";
9
+ import { MODEL_CLASSES, TEXT_CLASSES, } from "@engenty/wizards-shared/definition";
10
+ import { CAPABILITY_CLASSES, creditsModelOf, isCreditsRef, PROVIDER_IDS, providerInfo, providerOfRef, } from "@engenty/wizards-shared/providers";
11
+ import { note, saidText } from "@engenty/wizards-shared/run";
12
12
  import { generateSpeech, generateText, } from "ai";
13
13
  import { accountToken, linkedAccount } from "./auth/account.js";
14
14
  import { ollamaDecisionModel, ollamaRoot } from "./decision-model.js";
@@ -3,7 +3,7 @@ import { existsSync } from "node:fs";
3
3
  import { readdir, readFile } from "node:fs/promises";
4
4
  import { dirname, join, relative, resolve } from "node:path";
5
5
  import { fileURLToPath } from "node:url";
6
- import { marketplaceNameOf } from "@engenty-wizards/shared/claude-plugin";
6
+ import { marketplaceNameOf } from "@engenty/wizards-shared/claude-plugin";
7
7
  import { zipSync } from "fflate";
8
8
  import { env } from "./env.js";
9
9
  /**
@@ -1,6 +1,6 @@
1
1
  import { existsSync, readdirSync, readFileSync, statSync } from "node:fs";
2
2
  import { basename, extname, join, resolve, sep } from "node:path";
3
- import { PLUGIN_ID } from "@engenty-wizards/shared/definition";
3
+ import { PLUGIN_ID } from "@engenty/wizards-shared/definition";
4
4
  import { z } from "zod";
5
5
  /**
6
6
  * Finding plugins. A folder of plugins holds, in any mix:
@@ -1,8 +1,8 @@
1
1
  import { existsSync, mkdirSync, watch } from "node:fs";
2
2
  import { join, resolve, sep } from "node:path";
3
3
  import { fileURLToPath } from "node:url";
4
- import { FIELD_KINDS, PLUGIN_ID, PLUGIN_TOOL_NAME, wizardSchema, } from "@engenty-wizards/shared/definition";
5
- import { BUILT_IN_RUNNERS, OUTPUT_KINDS, RESERVED_PATHS, RUNNER_ID, } from "@engenty-wizards/shared/runners";
4
+ import { FIELD_KINDS, PLUGIN_ID, PLUGIN_TOOL_NAME, wizardSchema, } from "@engenty/wizards-shared/definition";
5
+ import { BUILT_IN_RUNNERS, OUTPUT_KINDS, RESERVED_PATHS, RUNNER_ID, } from "@engenty/wizards-shared/runners";
6
6
  import { generateText, Output } from "ai";
7
7
  import { eq } from "drizzle-orm";
8
8
  import { createJiti } from "jiti";
@@ -1,6 +1,6 @@
1
1
  import { createHash } from "node:crypto";
2
- import { LANGS, textLang, wizardLang } from "@engenty-wizards/shared/definition";
3
- import { noteText } from "@engenty-wizards/shared/run";
2
+ import { LANGS, textLang, wizardLang } from "@engenty/wizards-shared/definition";
3
+ import { noteText } from "@engenty/wizards-shared/run";
4
4
  import { and, asc, eq, inArray, isNotNull } from "drizzle-orm";
5
5
  import { db, schema, withTenant } from "../db/client.js";
6
6
  import { answerAsk } from "../engine/asks.js";
@@ -1,5 +1,5 @@
1
- import { formatsFor, widgetSize } from "@engenty-wizards/shared/definition";
2
- import { listAsMarkdown } from "@engenty-wizards/shared/store";
1
+ import { formatsFor, widgetSize } from "@engenty/wizards-shared/definition";
2
+ import { listAsMarkdown } from "@engenty/wizards-shared/store";
3
3
  import { and, eq } from "drizzle-orm";
4
4
  import { zipSync } from "fflate";
5
5
  import { db, schema } from "../db/client.js";
@@ -1,4 +1,4 @@
1
- import { labelOf, titleKey, } from "@engenty-wizards/shared/shape";
1
+ import { labelOf, titleKey, } from "@engenty/wizards-shared/shape";
2
2
  const isEntry = (v) => Boolean(v) && typeof v === "object" && !Array.isArray(v);
3
3
  /** A value that fits in a cell or a line: no lists of entries, no objects. */
4
4
  const flat = (s) => s.kind !== "object" && s.kind !== "table" && !(s.kind === "list" && s.of.kind === "object");
@@ -1,5 +1,5 @@
1
- import { note } from "@engenty-wizards/shared/run";
2
- import { PACKAGE_MIME } from "@engenty-wizards/shared/wizard-package";
1
+ import { note } from "@engenty/wizards-shared/run";
2
+ import { PACKAGE_MIME } from "@engenty/wizards-shared/wizard-package";
3
3
  import { Hono } from "hono";
4
4
  import { bodyLimit } from "hono/body-limit";
5
5
  import { z } from "zod";
@@ -1,4 +1,4 @@
1
- import { localLang } from "@engenty-wizards/shared/definition";
1
+ import { localLang } from "@engenty/wizards-shared/definition";
2
2
  import { serverText } from "../texts.js";
3
3
  /**
4
4
  * The language a visitor's request asks for, as the studio starts in it (`localLang`): the
@@ -1,4 +1,4 @@
1
- import { CAPABILITY_IDS, INDUSTRY_IDS, ITEM_FORMAT_IDS, MARKETPLACE_PLAN_IDS, USE_CASE_IDS, } from "@engenty-wizards/shared/marketplace";
1
+ import { CAPABILITY_IDS, INDUSTRY_IDS, ITEM_FORMAT_IDS, MARKETPLACE_PLAN_IDS, USE_CASE_IDS, } from "@engenty/wizards-shared/marketplace";
2
2
  import { Hono } from "hono";
3
3
  import { z } from "zod";
4
4
  import { asLang, marketplaceDetail, searchMarketplace, searchMarketplaceAsGuest, starEntry, } from "../services/marketplace.js";
@@ -1,7 +1,7 @@
1
- import { FORMATS, isLang, LANG_CODE, LANGS, LIST_FORMATS, TEXT_CLASSES, wizardLang, } from "@engenty-wizards/shared/definition";
2
- import { TableColumnValueError } from "@engenty-wizards/shared/engenty/data-tables";
3
- import { noteText, } from "@engenty-wizards/shared/run";
4
- import { machineTranslated, translateDefinition, } from "@engenty-wizards/shared/translation";
1
+ import { FORMATS, isLang, LANG_CODE, LANGS, LIST_FORMATS, TEXT_CLASSES, wizardLang, } from "@engenty/wizards-shared/definition";
2
+ import { TableColumnValueError } from "@engenty/wizards-shared/engenty/data-tables";
3
+ import { noteText, } from "@engenty/wizards-shared/run";
4
+ import { machineTranslated, translateDefinition, } from "@engenty/wizards-shared/translation";
5
5
  import { getConnInfo } from "@hono/node-server/conninfo";
6
6
  import { and, eq } from "drizzle-orm";
7
7
  import { Hono } from "hono";
@@ -12,7 +12,7 @@ import { z } from "zod";
12
12
  import { principalOf } from "../auth/index.js";
13
13
  import { MARK_FOCUSED_PERSONAL } from "../browser/snapshot.js";
14
14
  import { clientOf, clientRefused } from "../clients.js";
15
- import { ConnectError, connectionViews, connectWithCredentials, disconnect, finishOAuth, oauthStateLang, oauthStateRun, startOAuth, } from "../connectors/index.js";
15
+ import { ConnectError, connectionViews, connectWithCredentials, disconnect, findConnection, finishOAuth, oauthStateLang, oauthStateRun, startOAuth, } from "../connectors/index.js";
16
16
  import { finishPluginOAuth, pluginStateTenant } from "../connectors/plugin-connections.js";
17
17
  import { db, schema, withTenant } from "../db/client.js";
18
18
  import { answerAsk, pendingAsk } from "../engine/asks.js";
@@ -39,6 +39,8 @@ import { publicRunners, servePageRunner } from "../services/runners.js";
39
39
  import { sharedRun, shareImage, shareRun, shareView, unshareRun } from "../services/shares.js";
40
40
  import { isLangCode, storedTranslation, translateResult, translationFor, uiTexts, } from "../services/translations.js";
41
41
  import { isIconFile, wizardAvatarSvg, wizardIcon } from "../services/wizard-icon.js";
42
+ import { shareOverview } from "../sharing/index.js";
43
+ import { cancelShare, ShareInputError, shareChoices, startShare } from "../sharing/jobs.js";
42
44
  import { clearStore, deleteRows, listRows, listSecrets, readStoreFile, StoreError, saveRows, scopeOf, storeFiles, updateRow, } from "../store/index.js";
43
45
  import { tenantOfLink, tenantOfRun, tenantStatus, tokenOfCode, visitorOverLimit, } from "../tenants/control.js";
44
46
  import { bareMime, byteRange, inlineSafe, uploadLimit, uploadMime, wizardManifest, } from "./delivery.js";
@@ -671,6 +673,8 @@ export const runRoutes = new Hono()
671
673
  return c.json(notFoundAnswer(c), 404);
672
674
  }
673
675
  try {
676
+ // A result that is on its way somewhere stops going there when the person steps back.
677
+ await cancelShare(run.id);
674
678
  await goBack(run.id);
675
679
  return c.json({ ok: true });
676
680
  }
@@ -904,7 +908,10 @@ export const runRoutes = new Hono()
904
908
  // Who drives the wizard's browser: the wizard, or the person who took it over.
905
909
  .get("/:id/browser/seat", async (c) => {
906
910
  const run = await accessibleRun(c, c.req.param("id"));
907
- const resources = run?.status === "running" ? liveResources(run.id) : null;
911
+ // A step of the run has it open, or a share job that is asking the person.
912
+ const resources = run && (run.status === "running" || (await pendingAsk(run.id)))
913
+ ? liveResources(run.id)
914
+ : null;
908
915
  if (!resources?.openPage()) {
909
916
  // The run may work in another process: its runner answers.
910
917
  return (run && (await fromOwner(c, run.id))) || c.json(notFoundAnswer(c), 404);
@@ -1063,7 +1070,10 @@ export const runRoutes = new Hono()
1063
1070
  // --- the person's accounts ----------------------------------------------------
1064
1071
  .post("/:id/connections/:connectionId/oauth/:connectorId", async (c) => {
1065
1072
  const run = await accessibleRun(c, c.req.param("id"));
1066
- const connection = run?.definition.connections?.find((x) => x.id === c.req.param("connectionId"));
1073
+ const projectId = run ? await projectIdOf(run) : "";
1074
+ const connection = run
1075
+ ? await findConnection(run, c.req.param("connectionId"), projectId)
1076
+ : null;
1067
1077
  if (!run || !connection) {
1068
1078
  return c.json(notFoundAnswer(c), 404);
1069
1079
  }
@@ -1080,7 +1090,10 @@ export const runRoutes = new Hono()
1080
1090
  })
1081
1091
  .post("/:id/connections/:connectionId/credentials/:connectorId", async (c) => {
1082
1092
  const run = await accessibleRun(c, c.req.param("id"));
1083
- const connection = run?.definition.connections?.find((x) => x.id === c.req.param("connectionId"));
1093
+ const projectId = run ? await projectIdOf(run) : "";
1094
+ const connection = run
1095
+ ? await findConnection(run, c.req.param("connectionId"), projectId)
1096
+ : null;
1084
1097
  if (!run || !connection) {
1085
1098
  return c.json(notFoundAnswer(c), 404);
1086
1099
  }
@@ -1088,7 +1101,7 @@ export const runRoutes = new Hono()
1088
1101
  .object({ values: z.record(z.string(), z.string().max(500)) })
1089
1102
  .parse(await c.req.json());
1090
1103
  try {
1091
- const label = await connectWithCredentials(scopeOf(run), await projectIdOf(run), connection, c.req.param("connectorId"), values);
1104
+ const label = await connectWithCredentials(scopeOf(run), projectId, connection, c.req.param("connectorId"), values);
1092
1105
  signalChanged(run.id);
1093
1106
  return c.json({ ok: true, label });
1094
1107
  }
@@ -1189,10 +1202,25 @@ export const runRoutes = new Hono()
1189
1202
  rows: (await listRows(scope, def)).length,
1190
1203
  })));
1191
1204
  const secrets = await listSecrets(scope);
1205
+ // Accounts connected for sharing are kept like the wizard's own connections.
1206
+ const forSharing = secrets
1207
+ .filter((x) => x.slot.startsWith("connection:share:"))
1208
+ .map((x) => ({
1209
+ id: x.slot.slice("connection:".length),
1210
+ kind: null,
1211
+ connector: null,
1212
+ title: null,
1213
+ description: null,
1214
+ account: { connector: x.provider, label: x.label, connectedAt: x.createdAt },
1215
+ connectors: [],
1216
+ }));
1192
1217
  return c.json({
1193
1218
  lists,
1194
1219
  files: await storeFiles(scope),
1195
- connections: (await connectionViews(run.definition.connections ?? [], scope, await projectIdOf(run), requestLang(c))).filter((x) => x.account),
1220
+ connections: [
1221
+ ...(await connectionViews(run.definition.connections ?? [], scope, await projectIdOf(run), requestLang(c))).filter((x) => x.account),
1222
+ ...forSharing,
1223
+ ],
1196
1224
  keepsSignIns: secrets.some((s) => s.slot === "browser"),
1197
1225
  });
1198
1226
  })
@@ -1275,7 +1303,79 @@ export const runRoutes = new Hono()
1275
1303
  }
1276
1304
  await unshareRun(run);
1277
1305
  return c.json({ ok: true });
1306
+ })
1307
+ // --- sending the result on: by e-mail, into a folder, to a channel, onto a website ---------
1308
+ .get("/:id/share/targets", async (c) => {
1309
+ const run = await accessibleRun(c, c.req.param("id"));
1310
+ if (!run) {
1311
+ return c.json({ error: "not found" }, 404);
1312
+ }
1313
+ return c.json(await shareOverview(run, await projectIdOf(run), await isMember(c, run), langOf(c)));
1314
+ })
1315
+ .get("/:id/share/targets/:key/choices/:field", async (c) => {
1316
+ const run = await accessibleRun(c, c.req.param("id"));
1317
+ if (!run) {
1318
+ return c.json({ error: "not found" }, 404);
1319
+ }
1320
+ try {
1321
+ return c.json({
1322
+ choices: await shareChoices(run, c.req.param("key"), c.req.param("field"), {
1323
+ member: await isMember(c, run),
1324
+ lang: langOf(c),
1325
+ }),
1326
+ });
1327
+ }
1328
+ catch (err) {
1329
+ if (err instanceof ServiceError) {
1330
+ return c.json(err.toJSON(requestLang(c)), err.status);
1331
+ }
1332
+ // The account answered with an error: the form shows it and lets the person type instead.
1333
+ return c.json({ error: String(err.message).slice(0, 200) }, 502);
1334
+ }
1335
+ })
1336
+ .post("/:id/share/jobs", async (c) => {
1337
+ const run = await accessibleRun(c, c.req.param("id"));
1338
+ if (!run) {
1339
+ return c.json({ error: "not found" }, 404);
1340
+ }
1341
+ const request = z
1342
+ .object({
1343
+ target: z.string().min(1).max(200),
1344
+ items: z
1345
+ .array(z.object({ from: z.string().max(80), format: z.enum(FORMATS) }))
1346
+ .max(20)
1347
+ .default([]),
1348
+ values: z.record(z.string().max(60), z.string().max(20_000)).default({}),
1349
+ lang: z.enum(["de", "en"]).optional(),
1350
+ })
1351
+ .parse(await c.req.json());
1352
+ try {
1353
+ return c.json(await startShare(run, request, { member: await isMember(c, run) }));
1354
+ }
1355
+ catch (err) {
1356
+ if (err instanceof ShareInputError) {
1357
+ return c.json({ error: err.message, fields: err.fields }, 422);
1358
+ }
1359
+ if (err instanceof ServiceError) {
1360
+ return c.json(err.toJSON(requestLang(c)), err.status);
1361
+ }
1362
+ throw err;
1363
+ }
1364
+ })
1365
+ .post("/:id/share/jobs/:jobId/cancel", async (c) => {
1366
+ const run = await accessibleRun(c, c.req.param("id"));
1367
+ if (!run) {
1368
+ return c.json({ error: "not found" }, 404);
1369
+ }
1370
+ await cancelShare(run.id, c.req.param("jobId"));
1371
+ return c.json({ ok: true });
1278
1372
  });
1373
+ /** Signed in to the studio of the run's tenant: the wizard is their own. */
1374
+ async function isMember(c, run) {
1375
+ const user = await principalOf(c);
1376
+ return Boolean(user && user.tenantId === run.tenantId);
1377
+ }
1378
+ const langOf = (c) => (c.req.query("lang") === "en" ? "en" : "de");
1279
1379
  function listError(c, err) {
1280
1380
  if (err instanceof TableColumnValueError || err instanceof StoreError) {
1281
1381
  return c.json({ error: errorText(err, requestLang(c)) }, 422);
@@ -1,13 +1,13 @@
1
1
  import { mkdirSync } from "node:fs";
2
2
  import { join } from "node:path";
3
- import { ASSISTANT_LAYOUTS, ASSISTANT_PAGE_BYTES, assistantSignalSchema, assistantTurnSchema, } from "@engenty-wizards/shared/assistant";
4
- import { LANGS, MODEL_CLASSES, TEXT_CLASSES, wizardLang, } from "@engenty-wizards/shared/definition";
5
- import { CATEGORY_TYPES, whereSchema } from "@engenty-wizards/shared/knowledge";
6
- import { PROJECT_FILE_KINDS } from "@engenty-wizards/shared/projects";
7
- import { isCreditsRef } from "@engenty-wizards/shared/providers";
8
- import { note } from "@engenty-wizards/shared/run";
9
- import { wizardTexts } from "@engenty-wizards/shared/translation";
10
- import { PACKAGE_EXTENSION, PACKAGE_MAX_BYTES, PACKAGE_MIME, } from "@engenty-wizards/shared/wizard-package";
3
+ import { ASSISTANT_LAYOUTS, ASSISTANT_PAGE_BYTES, assistantSignalSchema, assistantTurnSchema, } from "@engenty/wizards-shared/assistant";
4
+ import { LANGS, MODEL_CLASSES, TEXT_CLASSES, wizardLang, } from "@engenty/wizards-shared/definition";
5
+ import { CATEGORY_TYPES, whereSchema } from "@engenty/wizards-shared/knowledge";
6
+ import { PROJECT_FILE_KINDS } from "@engenty/wizards-shared/projects";
7
+ import { isCreditsRef } from "@engenty/wizards-shared/providers";
8
+ import { note } from "@engenty/wizards-shared/run";
9
+ import { wizardTexts } from "@engenty/wizards-shared/translation";
10
+ import { PACKAGE_EXTENSION, PACKAGE_MAX_BYTES, PACKAGE_MIME, } from "@engenty/wizards-shared/wizard-package";
11
11
  import { generateText } from "ai";
12
12
  import { Hono } from "hono";
13
13
  import { streamSSE } from "hono/streaming";
@@ -63,6 +63,7 @@ import { deleteTranslation, editTranslation, isLangCode, publishedDefinition, tr
63
63
  import { draftWidgetPreview } from "../services/widgets.js";
64
64
  import { createWizard, deleteWizard, draftChanges, duplicateWizard, listWizards, ownedWizard, rotateShareLink, updateWizardSettings, wizardMessages, wizardState, writableWizard, writeDraft, } from "../services/wizards.js";
65
65
  import { readSetting, writeSetting } from "../settings.js";
66
+ import { projectShareTargets, sharePreview } from "../sharing/index.js";
66
67
  import { codeOf } from "../tenants/control.js";
67
68
  import { currentTenant } from "../tenants/tenant.js";
68
69
  import { serverText } from "../texts.js";
@@ -980,6 +981,17 @@ export const studio = new Hono()
980
981
  "content-disposition": `attachment; filename="${name}"`,
981
982
  "cache-control": "private, no-store",
982
983
  });
984
+ })
985
+ // The share targets a result of this wizard can name, for the editor.
986
+ .get("/wizards/:id/share-targets", async (c) => {
987
+ const w = await ownedWizard(c.get("user").id, c.req.param("id"));
988
+ return c.json(await projectShareTargets(w.projectId, requestLang(c)));
989
+ })
990
+ // The draft's result page with its share sheet, for a visitor (`as=visitor`) or the owner.
991
+ .get("/wizards/:id/share-preview", async (c) => {
992
+ const user = c.get("user");
993
+ const w = await ownedWizard(user.id, c.req.param("id"));
994
+ return c.json(await sharePreview(w, user.id, c.req.query("step") || null, c.req.query("as") === "owner", requestLang(c)));
983
995
  })
984
996
  .get("/wizards/:id", async (c) => {
985
997
  const user = c.get("user");
@@ -1,5 +1,5 @@
1
1
  import { AsyncLocalStorage } from "node:async_hooks";
2
- import { note } from "@engenty-wizards/shared/run";
2
+ import { note } from "@engenty/wizards-shared/run";
3
3
  import { and, eq } from "drizzle-orm";
4
4
  import { db, schema } from "../db/client.js";
5
5
  import { managed, tenantInfo } from "../manage.js";
@@ -1,7 +1,7 @@
1
- import { textLang, wizardLang, } from "@engenty-wizards/shared/definition";
2
- import { standaloneEntry } from "@engenty-wizards/shared/fit";
3
- import { pluginsOf } from "@engenty-wizards/shared/marketplace";
4
- import { noteText } from "@engenty-wizards/shared/run";
1
+ import { textLang, wizardLang, } from "@engenty/wizards-shared/definition";
2
+ import { standaloneEntry } from "@engenty/wizards-shared/fit";
3
+ import { pluginsOf } from "@engenty/wizards-shared/marketplace";
4
+ import { noteText } from "@engenty/wizards-shared/run";
5
5
  import { and, count, desc, eq, gte, inArray, isNotNull, or, sql } from "drizzle-orm";
6
6
  import { MICROS_PER_CREDIT } from "../credits/credits.js";
7
7
  import { db, schema } from "../db/client.js";
@@ -1,5 +1,5 @@
1
- import { ASSISTANT_LAYOUTS } from "@engenty-wizards/shared/assistant";
2
- import { note } from "@engenty-wizards/shared/run";
1
+ import { ASSISTANT_LAYOUTS } from "@engenty/wizards-shared/assistant";
2
+ import { note } from "@engenty/wizards-shared/run";
3
3
  import { generateText } from "ai";
4
4
  import { and, asc, desc, eq, isNotNull, isNull, sql } from "drizzle-orm";
5
5
  import { nanoid } from "nanoid";
@@ -1,5 +1,5 @@
1
- import { GRADIENT_TYPES, gradientCss, mainLogo, runTheme, } from "@engenty-wizards/shared/projects";
2
- import { note } from "@engenty-wizards/shared/run";
1
+ import { GRADIENT_TYPES, gradientCss, mainLogo, runTheme, } from "@engenty/wizards-shared/projects";
2
+ import { note } from "@engenty/wizards-shared/run";
3
3
  import { generateText, Output } from "ai";
4
4
  import { and, asc, eq } from "drizzle-orm";
5
5
  import { z } from "zod";
@@ -1,5 +1,5 @@
1
1
  import { createHash } from "node:crypto";
2
- import { note } from "@engenty-wizards/shared/run";
2
+ import { note } from "@engenty/wizards-shared/run";
3
3
  import { and, asc, eq, inArray, isNotNull, isNull, like } from "drizzle-orm";
4
4
  import { accountToken, linkedAccount } from "../auth/account.js";
5
5
  import { control, controlDb, db, schema } from "../db/client.js";
@@ -1,4 +1,4 @@
1
- import { note } from "@engenty-wizards/shared/run";
1
+ import { note } from "@engenty/wizards-shared/run";
2
2
  import { errorText, NotedError } from "../model-errors.js";
3
3
  const STATUS = {
4
4
  not_found: 404,
@@ -1,4 +1,4 @@
1
- import { cleanPath, isTextMime, mimeForPath, WORKSPACE_LIMITS, } from "@engenty-wizards/shared/workspace";
1
+ import { cleanPath, isTextMime, mimeForPath, WORKSPACE_LIMITS, } from "@engenty/wizards-shared/workspace";
2
2
  import { and, asc, eq, inArray } from "drizzle-orm";
3
3
  import { db, schema } from "../db/client.js";
4
4
  import { getBlob, putBlob } from "../files/blobs.js";
@@ -1,6 +1,6 @@
1
- import { dayOf, slugOf } from "@engenty-wizards/shared/knowledge";
2
- import { note } from "@engenty-wizards/shared/run";
3
- import { columnIdOf } from "@engenty-wizards/shared/space-data";
1
+ import { dayOf, slugOf } from "@engenty/wizards-shared/knowledge";
2
+ import { note } from "@engenty/wizards-shared/run";
3
+ import { columnIdOf } from "@engenty/wizards-shared/space-data";
4
4
  import { generateText, Output } from "ai";
5
5
  import { and, eq, inArray, isNull } from "drizzle-orm";
6
6
  import { nanoid } from "nanoid";
@@ -1,5 +1,5 @@
1
- import { formatTableCell } from "@engenty-wizards/shared/engenty/data-tables";
2
- import { slugOf, } from "@engenty-wizards/shared/knowledge";
1
+ import { formatTableCell } from "@engenty/wizards-shared/engenty/data-tables";
2
+ import { slugOf, } from "@engenty/wizards-shared/knowledge";
3
3
  import { and, asc, count, eq, inArray, isNotNull, isNull } from "drizzle-orm";
4
4
  import { db, schema } from "../db/client.js";
5
5
  import { embeddingModel, systemOneAccess } from "../models.js";
@@ -1,10 +1,10 @@
1
1
  import { createHash } from "node:crypto";
2
2
  import { statSync } from "node:fs";
3
- import { DEFINITION_VERSION, readable, wizardSchema, } from "@engenty-wizards/shared/definition";
4
- import { capabilitiesOf, costTierOf, effortOf, formatsOf, MARKETPLACE_LANGS, pluginsOf, } from "@engenty-wizards/shared/marketplace";
5
- import { wizardOutline } from "@engenty-wizards/shared/marketplace-entry";
6
- import { searchEntries } from "@engenty-wizards/shared/marketplace-search";
7
- import { note } from "@engenty-wizards/shared/run";
3
+ import { DEFINITION_VERSION, readable, wizardSchema, } from "@engenty/wizards-shared/definition";
4
+ import { capabilitiesOf, costTierOf, effortOf, formatsOf, MARKETPLACE_LANGS, pluginsOf, } from "@engenty/wizards-shared/marketplace";
5
+ import { wizardOutline } from "@engenty/wizards-shared/marketplace-entry";
6
+ import { searchEntries } from "@engenty/wizards-shared/marketplace-search";
7
+ import { note } from "@engenty/wizards-shared/run";
8
8
  import { and, eq, inArray, notInArray } from "drizzle-orm";
9
9
  import { formulaEstimate } from "../credits/estimate.js";
10
10
  import { control, controlDb, db, schema, withTenant } from "../db/client.js";