@engenty/wizards-runtime 0.0.0-stage → 0.7.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (523) hide show
  1. package/LICENSE +110 -0
  2. package/README.md +214 -2
  3. package/apps/runtime/dist/agents/architect.js +444 -0
  4. package/apps/runtime/dist/agents/studio-assistant.js +883 -0
  5. package/apps/runtime/dist/agents/subscription.js +207 -0
  6. package/apps/runtime/dist/agents/thought.js +21 -0
  7. package/apps/runtime/dist/agents/website.js +480 -0
  8. package/apps/runtime/dist/app.js +359 -0
  9. package/apps/runtime/dist/apple/wizards-apple +0 -0
  10. package/apps/runtime/dist/assistant/browser.js +26 -0
  11. package/apps/runtime/dist/assistant/docs.js +158 -0
  12. package/apps/runtime/dist/assistant/knows.js +353 -0
  13. package/apps/runtime/dist/assistant/primer.js +26 -0
  14. package/apps/runtime/dist/assistant/runs.js +24 -0
  15. package/apps/runtime/dist/auth/account.js +175 -0
  16. package/apps/runtime/dist/auth/device.js +112 -0
  17. package/apps/runtime/dist/auth/index.js +358 -0
  18. package/apps/runtime/dist/auth/keys.js +55 -0
  19. package/apps/runtime/dist/auth/local-ticket.js +26 -0
  20. package/apps/runtime/dist/authoring/example.js +74 -0
  21. package/apps/runtime/dist/authoring/guide.js +433 -0
  22. package/apps/runtime/dist/authoring/ops.js +117 -0
  23. package/apps/runtime/dist/browser/fast/action-space.js +160 -0
  24. package/apps/runtime/dist/browser/fast/classifier.js +91 -0
  25. package/apps/runtime/dist/browser/fast/decide.js +171 -0
  26. package/apps/runtime/dist/browser/fast/driver.js +141 -0
  27. package/apps/runtime/dist/browser/fast/instructions.js +33 -0
  28. package/apps/runtime/dist/browser/fast/run.js +249 -0
  29. package/apps/runtime/dist/browser/fast/span-picker.js +153 -0
  30. package/apps/runtime/dist/browser/fast/text-helper.js +178 -0
  31. package/apps/runtime/dist/browser/snapshot.js +335 -0
  32. package/apps/runtime/dist/cli/account.js +385 -0
  33. package/apps/runtime/dist/cli/autostart.js +182 -0
  34. package/apps/runtime/dist/cli/autoupdate.js +221 -0
  35. package/apps/runtime/dist/cli/clients.js +44 -0
  36. package/apps/runtime/dist/cli/connect.js +540 -0
  37. package/apps/runtime/dist/cli/environment.js +95 -0
  38. package/apps/runtime/dist/cli/exec.js +45 -0
  39. package/apps/runtime/dist/cli/features.js +50 -0
  40. package/apps/runtime/dist/cli/home.js +88 -0
  41. package/apps/runtime/dist/cli/install-env.js +33 -0
  42. package/apps/runtime/dist/cli/machine.js +107 -0
  43. package/apps/runtime/dist/cli/main.js +231 -0
  44. package/apps/runtime/dist/cli/mcp.js +136 -0
  45. package/apps/runtime/dist/cli/menu.js +202 -0
  46. package/apps/runtime/dist/cli/processes.js +72 -0
  47. package/apps/runtime/dist/cli/report.js +66 -0
  48. package/apps/runtime/dist/cli/sandbox.js +77 -0
  49. package/apps/runtime/dist/cli/setup.js +335 -0
  50. package/apps/runtime/dist/cli/start.js +276 -0
  51. package/apps/runtime/dist/cli/status.js +212 -0
  52. package/apps/runtime/dist/cli/ui.js +59 -0
  53. package/apps/runtime/dist/cli/uninstall-main.js +20 -0
  54. package/apps/runtime/dist/cli/uninstall.js +231 -0
  55. package/apps/runtime/dist/cli/update.js +86 -0
  56. package/apps/runtime/dist/cli/validate.js +75 -0
  57. package/apps/runtime/dist/cli/versions.js +123 -0
  58. package/apps/runtime/dist/connectors/builtin.js +86 -0
  59. package/apps/runtime/dist/connectors/external.js +409 -0
  60. package/apps/runtime/dist/connectors/gmail.js +107 -0
  61. package/apps/runtime/dist/connectors/imap.js +261 -0
  62. package/apps/runtime/dist/connectors/index.js +325 -0
  63. package/apps/runtime/dist/connectors/mail.js +72 -0
  64. package/apps/runtime/dist/connectors/outlook.js +90 -0
  65. package/apps/runtime/dist/connectors/plugin-connections.js +343 -0
  66. package/apps/runtime/dist/connectors/via-account.js +65 -0
  67. package/apps/runtime/dist/credits/credits.js +100 -0
  68. package/apps/runtime/dist/credits/estimate.js +152 -0
  69. package/apps/runtime/dist/db/adopt.js +149 -0
  70. package/apps/runtime/dist/db/client.js +173 -0
  71. package/apps/runtime/dist/db/control-schema.js +133 -0
  72. package/apps/runtime/dist/db/migrations/control/0000_last_absorbing_man.sql +47 -0
  73. package/apps/runtime/dist/db/migrations/control/0001_gorgeous_nicolaos.sql +41 -0
  74. package/apps/runtime/dist/db/migrations/control/0002_secret_penance.sql +1 -0
  75. package/apps/runtime/dist/db/migrations/control/0003_nasty_mordo.sql +3 -0
  76. package/apps/runtime/dist/db/migrations/control/0004_breezy_eddie_brock.sql +6 -0
  77. package/apps/runtime/dist/db/migrations/control/0005_chilly_oracle.sql +1 -0
  78. package/apps/runtime/dist/db/migrations/control/0006_sleepy_mojo.sql +1 -0
  79. package/apps/runtime/dist/db/migrations/control/0007_common_the_hand.sql +15 -0
  80. package/apps/runtime/dist/db/migrations/control/0008_runner.sql +8 -0
  81. package/apps/runtime/dist/db/migrations/control/0009_plugin_claim.sql +9 -0
  82. package/apps/runtime/dist/db/migrations/control/0010_tan_snowbird.sql +6 -0
  83. package/apps/runtime/dist/db/migrations/control/meta/0000_snapshot.json +311 -0
  84. package/apps/runtime/dist/db/migrations/control/meta/0001_snapshot.json +599 -0
  85. package/apps/runtime/dist/db/migrations/control/meta/0002_snapshot.json +607 -0
  86. package/apps/runtime/dist/db/migrations/control/meta/0003_snapshot.json +311 -0
  87. package/apps/runtime/dist/db/migrations/control/meta/0004_snapshot.json +350 -0
  88. package/apps/runtime/dist/db/migrations/control/meta/0005_snapshot.json +358 -0
  89. package/apps/runtime/dist/db/migrations/control/meta/0006_snapshot.json +365 -0
  90. package/apps/runtime/dist/db/migrations/control/meta/0007_snapshot.json +460 -0
  91. package/apps/runtime/dist/db/migrations/control/meta/0008_snapshot.json +505 -0
  92. package/apps/runtime/dist/db/migrations/control/meta/0009_snapshot.json +561 -0
  93. package/apps/runtime/dist/db/migrations/control/meta/0010_snapshot.json +600 -0
  94. package/apps/runtime/dist/db/migrations/control/meta/_journal.json +83 -0
  95. package/apps/runtime/dist/db/migrations/tenant/0000_eminent_freak.sql +188 -0
  96. package/apps/runtime/dist/db/migrations/tenant/0001_salty_master_chief.sql +1 -0
  97. package/apps/runtime/dist/db/migrations/tenant/0002_cloudy_firebird.sql +1 -0
  98. package/apps/runtime/dist/db/migrations/tenant/0003_brown_warbound.sql +52 -0
  99. package/apps/runtime/dist/db/migrations/tenant/0004_romantic_nocturne.sql +6 -0
  100. package/apps/runtime/dist/db/migrations/tenant/0005_reflective_forgotten_one.sql +2 -0
  101. package/apps/runtime/dist/db/migrations/tenant/0006_hard_war_machine.sql +30 -0
  102. package/apps/runtime/dist/db/migrations/tenant/0007_space_data.sql +43 -0
  103. package/apps/runtime/dist/db/migrations/tenant/0008_run_event_note.sql +1 -0
  104. package/apps/runtime/dist/db/migrations/tenant/0009_knowledge.sql +104 -0
  105. package/apps/runtime/dist/db/migrations/tenant/0010_plugin_connection.sql +15 -0
  106. package/apps/runtime/dist/db/migrations/tenant/0011_runners.sql +2 -0
  107. package/apps/runtime/dist/db/migrations/tenant/0012_assistant_chat.sql +40 -0
  108. package/apps/runtime/dist/db/migrations/tenant/0013_run_origin.sql +1 -0
  109. package/apps/runtime/dist/db/migrations/tenant/0014_run_answer.sql +2 -0
  110. package/apps/runtime/dist/db/migrations/tenant/0015_device_calls.sql +13 -0
  111. package/apps/runtime/dist/db/migrations/tenant/0016_even_trish_tilby.sql +12 -0
  112. package/apps/runtime/dist/db/migrations/tenant/meta/0000_snapshot.json +1323 -0
  113. package/apps/runtime/dist/db/migrations/tenant/meta/0001_snapshot.json +1330 -0
  114. package/apps/runtime/dist/db/migrations/tenant/meta/0002_snapshot.json +1337 -0
  115. package/apps/runtime/dist/db/migrations/tenant/meta/0003_snapshot.json +1605 -0
  116. package/apps/runtime/dist/db/migrations/tenant/meta/0004_snapshot.json +1645 -0
  117. package/apps/runtime/dist/db/migrations/tenant/meta/0005_snapshot.json +1659 -0
  118. package/apps/runtime/dist/db/migrations/tenant/meta/0006_snapshot.json +1696 -0
  119. package/apps/runtime/dist/db/migrations/tenant/meta/0007_snapshot.json +2012 -0
  120. package/apps/runtime/dist/db/migrations/tenant/meta/0008_snapshot.json +2019 -0
  121. package/apps/runtime/dist/db/migrations/tenant/meta/0009_snapshot.json +2837 -0
  122. package/apps/runtime/dist/db/migrations/tenant/meta/0010_snapshot.json +2942 -0
  123. package/apps/runtime/dist/db/migrations/tenant/meta/0011_snapshot.json +2956 -0
  124. package/apps/runtime/dist/db/migrations/tenant/meta/0012_snapshot.json +3132 -0
  125. package/apps/runtime/dist/db/migrations/tenant/meta/0013_snapshot.json +3139 -0
  126. package/apps/runtime/dist/db/migrations/tenant/meta/0014_snapshot.json +3154 -0
  127. package/apps/runtime/dist/db/migrations/tenant/meta/0015_snapshot.json +3243 -0
  128. package/apps/runtime/dist/db/migrations/tenant/meta/0016_snapshot.json +3326 -0
  129. package/apps/runtime/dist/db/migrations/tenant/meta/_journal.json +125 -0
  130. package/apps/runtime/dist/db/schema.js +602 -0
  131. package/apps/runtime/dist/debug.js +197 -0
  132. package/apps/runtime/dist/docs/dev/index.md +41 -0
  133. package/apps/runtime/dist/docs/dev/meta.json +7 -0
  134. package/apps/runtime/dist/docs/dev/plugins/connections.md +74 -0
  135. package/apps/runtime/dist/docs/dev/plugins/events.md +89 -0
  136. package/apps/runtime/dist/docs/dev/plugins/examples.md +101 -0
  137. package/apps/runtime/dist/docs/dev/plugins/index.md +78 -0
  138. package/apps/runtime/dist/docs/dev/plugins/layout.md +90 -0
  139. package/apps/runtime/dist/docs/dev/plugins/meta.json +28 -0
  140. package/apps/runtime/dist/docs/dev/plugins/quick-start.md +94 -0
  141. package/apps/runtime/dist/docs/dev/plugins/reference.md +348 -0
  142. package/apps/runtime/dist/docs/dev/plugins/reloading.md +76 -0
  143. package/apps/runtime/dist/docs/dev/plugins/routes.md +185 -0
  144. package/apps/runtime/dist/docs/dev/plugins/runners.md +230 -0
  145. package/apps/runtime/dist/docs/dev/plugins/server.md +281 -0
  146. package/apps/runtime/dist/docs/dev/plugins/shipping.md +79 -0
  147. package/apps/runtime/dist/docs/dev/plugins/space.md +297 -0
  148. package/apps/runtime/dist/docs/dev/plugins/starters.md +70 -0
  149. package/apps/runtime/dist/docs/dev/plugins/studio.md +363 -0
  150. package/apps/runtime/dist/docs/dev/plugins/styling.md +129 -0
  151. package/apps/runtime/dist/docs/dev/plugins/tables.md +104 -0
  152. package/apps/runtime/dist/docs/dev/plugins/tools.md +139 -0
  153. package/apps/runtime/dist/docs/dev/wizard-format.md +125 -0
  154. package/apps/runtime/dist/docs/meta.json +3 -0
  155. package/apps/runtime/dist/docs/user/ai-apps.md +112 -0
  156. package/apps/runtime/dist/docs/user/assistant.md +77 -0
  157. package/apps/runtime/dist/docs/user/build-a-wizard.md +116 -0
  158. package/apps/runtime/dist/docs/user/command-line.md +86 -0
  159. package/apps/runtime/dist/docs/user/connectors.md +90 -0
  160. package/apps/runtime/dist/docs/user/create-account.md +52 -0
  161. package/apps/runtime/dist/docs/user/data.md +66 -0
  162. package/apps/runtime/dist/docs/user/first-start.md +60 -0
  163. package/apps/runtime/dist/docs/user/index.md +49 -0
  164. package/apps/runtime/dist/docs/user/install.md +123 -0
  165. package/apps/runtime/dist/docs/user/local-only.md +42 -0
  166. package/apps/runtime/dist/docs/user/meta.json +32 -0
  167. package/apps/runtime/dist/docs/user/models.md +156 -0
  168. package/apps/runtime/dist/docs/user/plugins.md +71 -0
  169. package/apps/runtime/dist/docs/user/run.md +98 -0
  170. package/apps/runtime/dist/docs/user/server.md +52 -0
  171. package/apps/runtime/dist/docs/user/space.md +126 -0
  172. package/apps/runtime/dist/docs/user/steps.md +220 -0
  173. package/apps/runtime/dist/docs/user/test-and-share.md +224 -0
  174. package/apps/runtime/dist/docs/user/troubleshooting.md +67 -0
  175. package/apps/runtime/dist/docs/user/wordpress.md +121 -0
  176. package/apps/runtime/dist/documents/parse.js +246 -0
  177. package/apps/runtime/dist/engenty/connections-external/build-connector.js +193 -0
  178. package/apps/runtime/dist/engenty/connections-external/errors.js +11 -0
  179. package/apps/runtime/dist/engenty/connections-external/import-service.js +270 -0
  180. package/apps/runtime/dist/engenty/connections-external/importer/classify.js +34 -0
  181. package/apps/runtime/dist/engenty/connections-external/importer/map-auth.js +185 -0
  182. package/apps/runtime/dist/engenty/connections-external/importer/normalize-mcp.js +63 -0
  183. package/apps/runtime/dist/engenty/connections-external/importer/normalize-openapi.js +130 -0
  184. package/apps/runtime/dist/engenty/connections-external/invoke/http-invoker.js +143 -0
  185. package/apps/runtime/dist/engenty/connections-external/invoke/mcp-client.js +143 -0
  186. package/apps/runtime/dist/engenty/connections-external/net/guarded-fetch.js +119 -0
  187. package/apps/runtime/dist/engenty/connections-external/oauth-dcr.js +88 -0
  188. package/apps/runtime/dist/engenty/connections-external/registry-client.js +336 -0
  189. package/apps/runtime/dist/engenty/connections-external/registry-source.js +82 -0
  190. package/apps/runtime/dist/engenty/connections-external/types.js +7 -0
  191. package/apps/runtime/dist/engenty/connections-github/connector.js +209 -0
  192. package/apps/runtime/dist/engenty/connections-google/connectors/calendar.js +381 -0
  193. package/apps/runtime/dist/engenty/connections-google/connectors/contacts.js +94 -0
  194. package/apps/runtime/dist/engenty/connections-google/connectors/drive.js +290 -0
  195. package/apps/runtime/dist/engenty/connections-google/connectors/gmail.js +567 -0
  196. package/apps/runtime/dist/engenty/connections-google/definitions.js +11 -0
  197. package/apps/runtime/dist/engenty/connections-google/shared.js +73 -0
  198. package/apps/runtime/dist/engenty/connections-hubspot/connector.js +140 -0
  199. package/apps/runtime/dist/engenty/connections-microsoft/action.js +17 -0
  200. package/apps/runtime/dist/engenty/connections-microsoft/graph.js +114 -0
  201. package/apps/runtime/dist/engenty/connections-microsoft/onedrive.js +286 -0
  202. package/apps/runtime/dist/engenty/connections-microsoft/outlook.js +492 -0
  203. package/apps/runtime/dist/engenty/connections-s3/s3.js +328 -0
  204. package/apps/runtime/dist/engenty/connections-sdk/files-capability.js +86 -0
  205. package/apps/runtime/dist/engenty/connections-sdk/oauth2.js +150 -0
  206. package/apps/runtime/dist/engenty/connections-sdk/registry.js +89 -0
  207. package/apps/runtime/dist/engenty/connections-sdk/storage-capability.js +84 -0
  208. package/apps/runtime/dist/engenty/connections-sdk/types.js +30 -0
  209. package/apps/runtime/dist/engenty/connections-slack/connector.js +360 -0
  210. package/apps/runtime/dist/engenty/csv-import/csv-matrix.js +178 -0
  211. package/apps/runtime/dist/engenty/csv-import/import-sources.js +87 -0
  212. package/apps/runtime/dist/engenty/csv-import/parse-csv.js +129 -0
  213. package/apps/runtime/dist/engenty/csv-import/serialize-csv.js +20 -0
  214. package/apps/runtime/dist/engenty/csv-import/types.js +1 -0
  215. package/apps/runtime/dist/engenty/csv-import/xlsx-workbook.js +159 -0
  216. package/apps/runtime/dist/engenty/doc-converter/interface.js +9 -0
  217. package/apps/runtime/dist/engenty/doc-converter/page-break.js +92 -0
  218. package/apps/runtime/dist/engenty/doc-converter/providers/local/index.js +72 -0
  219. package/apps/runtime/dist/engenty/document-scanner/schemas/classifier.js +30 -0
  220. package/apps/runtime/dist/engenty/document-scanner/schemas/index.js +4 -0
  221. package/apps/runtime/dist/engenty/document-scanner/schemas/invoice.js +73 -0
  222. package/apps/runtime/dist/engenty/document-scanner/schemas/receipt.js +63 -0
  223. package/apps/runtime/dist/engenty/document-scanner/schemas/shared.js +40 -0
  224. package/apps/runtime/dist/engenty/search-index/chunks.js +164 -0
  225. package/apps/runtime/dist/engenty/search-index/contracts.js +9 -0
  226. package/apps/runtime/dist/engenty/shims/connections-sdk.js +39 -0
  227. package/apps/runtime/dist/engenty/shims/plugin-sdk.js +1 -0
  228. package/apps/runtime/dist/engenty/shims/web-ingest.js +19 -0
  229. package/apps/runtime/dist/engenty/web-ingest/ssrf.js +277 -0
  230. package/apps/runtime/dist/engine/asks.js +82 -0
  231. package/apps/runtime/dist/engine/decide.js +82 -0
  232. package/apps/runtime/dist/engine/device.js +194 -0
  233. package/apps/runtime/dist/engine/events.js +128 -0
  234. package/apps/runtime/dist/engine/input.js +208 -0
  235. package/apps/runtime/dist/engine/owner.js +32 -0
  236. package/apps/runtime/dist/engine/prepare.js +90 -0
  237. package/apps/runtime/dist/engine/push.js +58 -0
  238. package/apps/runtime/dist/engine/requirements.js +355 -0
  239. package/apps/runtime/dist/engine/resources.js +198 -0
  240. package/apps/runtime/dist/engine/runner.js +970 -0
  241. package/apps/runtime/dist/engine/steps.js +1000 -0
  242. package/apps/runtime/dist/engine/surface.js +91 -0
  243. package/apps/runtime/dist/engine/template.js +240 -0
  244. package/apps/runtime/dist/engine/types.js +4 -0
  245. package/apps/runtime/dist/env.js +279 -0
  246. package/apps/runtime/dist/features.js +123 -0
  247. package/apps/runtime/dist/files/blobs.js +22 -0
  248. package/apps/runtime/dist/files/objects.js +86 -0
  249. package/apps/runtime/dist/files/storage.js +120 -0
  250. package/apps/runtime/dist/files/web-images.js +101 -0
  251. package/apps/runtime/dist/film/project.js +257 -0
  252. package/apps/runtime/dist/film/skills.js +91 -0
  253. package/apps/runtime/dist/film/sounds.js +122 -0
  254. package/apps/runtime/dist/film/step.js +289 -0
  255. package/apps/runtime/dist/film/tools.js +99 -0
  256. package/apps/runtime/dist/geocode.js +58 -0
  257. package/apps/runtime/dist/harness/antigravity.js +129 -0
  258. package/apps/runtime/dist/harness/apple.js +270 -0
  259. package/apps/runtime/dist/harness/claude.js +147 -0
  260. package/apps/runtime/dist/harness/codex.js +229 -0
  261. package/apps/runtime/dist/harness/cursor.js +93 -0
  262. package/apps/runtime/dist/harness/env.js +124 -0
  263. package/apps/runtime/dist/harness/index.js +95 -0
  264. package/apps/runtime/dist/harness/model.js +279 -0
  265. package/apps/runtime/dist/harness/prompt.js +121 -0
  266. package/apps/runtime/dist/harness/terminal.js +194 -0
  267. package/apps/runtime/dist/harness/types.js +7 -0
  268. package/apps/runtime/dist/index.js +113 -0
  269. package/apps/runtime/dist/limits.js +81 -0
  270. package/apps/runtime/dist/link-preview.js +60 -0
  271. package/apps/runtime/dist/log.js +106 -0
  272. package/apps/runtime/dist/manage.js +249 -0
  273. package/apps/runtime/dist/mcp/auth.js +161 -0
  274. package/apps/runtime/dist/mcp/bridge.js +59 -0
  275. package/apps/runtime/dist/mcp/flow-app.js +97 -0
  276. package/apps/runtime/dist/mcp/handler.js +54 -0
  277. package/apps/runtime/dist/mcp/scopes.js +14 -0
  278. package/apps/runtime/dist/mcp/seen.js +65 -0
  279. package/apps/runtime/dist/mcp/tools.js +572 -0
  280. package/apps/runtime/dist/media/conversation.js +167 -0
  281. package/apps/runtime/dist/media/ffmpeg.js +121 -0
  282. package/apps/runtime/dist/media/generate.js +120 -0
  283. package/apps/runtime/dist/media/marking.js +121 -0
  284. package/apps/runtime/dist/media/transcribe.js +198 -0
  285. package/apps/runtime/dist/model-errors.js +42 -0
  286. package/apps/runtime/dist/models.js +1164 -0
  287. package/apps/runtime/dist/plugin.js +61 -0
  288. package/apps/runtime/dist/plugins/channels.js +78 -0
  289. package/apps/runtime/dist/plugins/claims.js +56 -0
  290. package/apps/runtime/dist/plugins/discovery.js +155 -0
  291. package/apps/runtime/dist/plugins/events.js +63 -0
  292. package/apps/runtime/dist/plugins/jobs.js +64 -0
  293. package/apps/runtime/dist/plugins/loader.js +508 -0
  294. package/apps/runtime/dist/plugins/migrations.js +69 -0
  295. package/apps/runtime/dist/plugins/pro-keys.js +34 -0
  296. package/apps/runtime/dist/plugins/pro-state.js +83 -0
  297. package/apps/runtime/dist/plugins/pro.js +310 -0
  298. package/apps/runtime/dist/plugins/public.js +44 -0
  299. package/apps/runtime/dist/plugins/registry.js +122 -0
  300. package/apps/runtime/dist/plugins/runs.js +210 -0
  301. package/apps/runtime/dist/render/browser-path.js +54 -0
  302. package/apps/runtime/dist/render/chromium.js +98 -0
  303. package/apps/runtime/dist/render/convert.js +158 -0
  304. package/apps/runtime/dist/render/downloads.js +299 -0
  305. package/apps/runtime/dist/render/guard.js +25 -0
  306. package/apps/runtime/dist/render/shaped.js +137 -0
  307. package/apps/runtime/dist/routes/api.js +440 -0
  308. package/apps/runtime/dist/routes/debug.js +42 -0
  309. package/apps/runtime/dist/routes/delivery.js +90 -0
  310. package/apps/runtime/dist/routes/internal.js +81 -0
  311. package/apps/runtime/dist/routes/lang.js +25 -0
  312. package/apps/runtime/dist/routes/marketplace.js +43 -0
  313. package/apps/runtime/dist/routes/plugin-public.js +113 -0
  314. package/apps/runtime/dist/routes/plugins.js +212 -0
  315. package/apps/runtime/dist/routes/runs.js +1422 -0
  316. package/apps/runtime/dist/routes/studio.js +1629 -0
  317. package/apps/runtime/dist/routes/wizard-stream.js +30 -0
  318. package/apps/runtime/dist/running.js +39 -0
  319. package/apps/runtime/dist/sandbox/agentos-package.js +73 -0
  320. package/apps/runtime/dist/sandbox/agentos.js +162 -0
  321. package/apps/runtime/dist/sandbox/docker.js +45 -0
  322. package/apps/runtime/dist/sandbox/index.js +52 -0
  323. package/apps/runtime/dist/sandbox/install.js +122 -0
  324. package/apps/runtime/dist/sandbox/mastra.js +71 -0
  325. package/apps/runtime/dist/sandbox/types.js +1 -0
  326. package/apps/runtime/dist/secrets/crypto.js +28 -0
  327. package/apps/runtime/dist/secrets/signing.js +52 -0
  328. package/apps/runtime/dist/secrets/vault.js +59 -0
  329. package/apps/runtime/dist/services/access.js +88 -0
  330. package/apps/runtime/dist/services/api.js +248 -0
  331. package/apps/runtime/dist/services/architect.js +95 -0
  332. package/apps/runtime/dist/services/assistant-chats.js +311 -0
  333. package/apps/runtime/dist/services/brand.js +85 -0
  334. package/apps/runtime/dist/services/cloud.js +456 -0
  335. package/apps/runtime/dist/services/draft-events.js +27 -0
  336. package/apps/runtime/dist/services/engenty-shapes.js +71 -0
  337. package/apps/runtime/dist/services/errors.js +29 -0
  338. package/apps/runtime/dist/services/files.js +178 -0
  339. package/apps/runtime/dist/services/knowledge-model.js +559 -0
  340. package/apps/runtime/dist/services/knowledge.js +721 -0
  341. package/apps/runtime/dist/services/links.js +16 -0
  342. package/apps/runtime/dist/services/marketplace.js +492 -0
  343. package/apps/runtime/dist/services/onboarding.js +152 -0
  344. package/apps/runtime/dist/services/package-file.js +82 -0
  345. package/apps/runtime/dist/services/package.js +170 -0
  346. package/apps/runtime/dist/services/profile.js +51 -0
  347. package/apps/runtime/dist/services/project-files.js +439 -0
  348. package/apps/runtime/dist/services/project-index.js +707 -0
  349. package/apps/runtime/dist/services/projects.js +387 -0
  350. package/apps/runtime/dist/services/relevance.js +58 -0
  351. package/apps/runtime/dist/services/runners.js +178 -0
  352. package/apps/runtime/dist/services/runs.js +524 -0
  353. package/apps/runtime/dist/services/shares.js +130 -0
  354. package/apps/runtime/dist/services/site.js +270 -0
  355. package/apps/runtime/dist/services/space-categories.js +861 -0
  356. package/apps/runtime/dist/services/space-data.js +792 -0
  357. package/apps/runtime/dist/services/space-origin.js +207 -0
  358. package/apps/runtime/dist/services/spaces.js +657 -0
  359. package/apps/runtime/dist/services/translations.js +306 -0
  360. package/apps/runtime/dist/services/widgets.js +34 -0
  361. package/apps/runtime/dist/services/wizard-icon.js +157 -0
  362. package/apps/runtime/dist/services/wizards.js +420 -0
  363. package/apps/runtime/dist/settings.js +16 -0
  364. package/apps/runtime/dist/store/errors.js +4 -0
  365. package/apps/runtime/dist/store/index.js +299 -0
  366. package/apps/runtime/dist/store/shared-lists.js +123 -0
  367. package/apps/runtime/dist/tenants/control.js +238 -0
  368. package/apps/runtime/dist/tenants/tenant.js +26 -0
  369. package/apps/runtime/dist/texts.js +207 -0
  370. package/apps/runtime/dist/tools/browser.js +703 -0
  371. package/apps/runtime/dist/tools/connector.js +204 -0
  372. package/apps/runtime/dist/tools/index.js +291 -0
  373. package/apps/runtime/dist/tools/mail.js +104 -0
  374. package/apps/runtime/dist/tools/net-guard.js +170 -0
  375. package/apps/runtime/dist/tools/pages.js +81 -0
  376. package/apps/runtime/dist/tools/plugin.js +180 -0
  377. package/apps/runtime/dist/tools/project.js +154 -0
  378. package/apps/runtime/dist/tools/shared.js +69 -0
  379. package/apps/runtime/dist/tools/store.js +238 -0
  380. package/apps/runtime/dist/update.js +113 -0
  381. package/apps/runtime/dist/widgets/bundle.js +99 -0
  382. package/apps/runtime/dist/widgets/render.js +329 -0
  383. package/apps/runtime/dist/widgets/runtime.js +108 -0
  384. package/apps/runtime/dist/widgets/script.js +30 -0
  385. package/apps/runtime/dist/widgets/step.js +223 -0
  386. package/apps/web/dist/ai-labels/ai-black.svg +20 -0
  387. package/apps/web/dist/ai-labels/ai-generated-black.svg +31 -0
  388. package/apps/web/dist/ai-labels/ai-generated-white.svg +32 -0
  389. package/apps/web/dist/ai-labels/ai-modified-black.svg +30 -0
  390. package/apps/web/dist/ai-labels/ai-modified-white.svg +31 -0
  391. package/apps/web/dist/ai-labels/ai-white.svg +21 -0
  392. package/apps/web/dist/assets/AboutDialog-DYgXPagX.js +1 -0
  393. package/apps/web/dist/assets/ChangelogDialog-BXqBW8j3.js +1 -0
  394. package/apps/web/dist/assets/ChatView-CK2--tsE.js +10 -0
  395. package/apps/web/dist/assets/EditorPage-jvcwyXbU.js +3 -0
  396. package/apps/web/dist/assets/FlowPreview-CusP7ci9.js +1 -0
  397. package/apps/web/dist/assets/Harness-BrP-ENHg.css +1 -0
  398. package/apps/web/dist/assets/Harness-CV9uYzbv.js +16 -0
  399. package/apps/web/dist/assets/NewWizardChannels-BakW5q6s.js +1 -0
  400. package/apps/web/dist/assets/NewWizardPage-BoA-LJuW.js +7 -0
  401. package/apps/web/dist/assets/OnboardingPage-DaD1XnOe.js +1 -0
  402. package/apps/web/dist/assets/ProjectPage-BFgk1DEv.js +1 -0
  403. package/apps/web/dist/assets/PublicRunner-C9MwEvxy.js +1 -0
  404. package/apps/web/dist/assets/ReadOnly-DC2Kp7l8.js +1 -0
  405. package/apps/web/dist/assets/RunDrawer-CY6NZSrI.js +4 -0
  406. package/apps/web/dist/assets/RunnerView-BT26XgcY.js +1 -0
  407. package/apps/web/dist/assets/SettingsPage-AFt9IDLt.js +1 -0
  408. package/apps/web/dist/assets/SetupPage-DtFYAbwJ.js +1 -0
  409. package/apps/web/dist/assets/SharePage-t2xwNS61.js +1 -0
  410. package/apps/web/dist/assets/changelog-CATQFxCQ.js +1 -0
  411. package/apps/web/dist/assets/engenty-eXZ-EAwd.js +1 -0
  412. package/apps/web/dist/assets/esm-DXeMu8Lb.js +7 -0
  413. package/apps/web/dist/assets/fluffy-engenty-ClRou7yu.js +456 -0
  414. package/apps/web/dist/assets/index-AfUa8xKD.css +1 -0
  415. package/apps/web/dist/assets/index-Drw7FMTQ.js +14 -0
  416. package/apps/web/dist/assets/jsx-runtime-BNakU3Ej.js +1 -0
  417. package/apps/web/dist/assets/lock-R_CfU0Xo.js +1 -0
  418. package/apps/web/dist/assets/oss-credits-cZ9NUaLZ.js +1 -0
  419. package/apps/web/dist/assets/pdfmake-Cx9scTbD.js +228 -0
  420. package/apps/web/dist/assets/phone-CgrIS4_-.js +1 -0
  421. package/apps/web/dist/assets/preload-helper-CNEI7N0N.js +1 -0
  422. package/apps/web/dist/assets/qr-scanner-worker.min-CJaXo3yu.js +98 -0
  423. package/apps/web/dist/assets/qr-scanner.min-C_UI0gH-.js +1 -0
  424. package/apps/web/dist/assets/rolldown-runtime-hePW80VL.js +1 -0
  425. package/apps/web/dist/assets/settings-menu-2IMOOlLl.js +1 -0
  426. package/apps/web/dist/assets/ui-dzGvc3xk.js +137 -0
  427. package/apps/web/dist/assets/upload-BSuTilFF.js +1 -0
  428. package/apps/web/dist/assets/vfs_fonts-DllDSYt1.js +1 -0
  429. package/apps/web/dist/embed.js +266 -0
  430. package/apps/web/dist/favicon.svg +1 -0
  431. package/apps/web/dist/icons/apple-touch-icon.png +0 -0
  432. package/apps/web/dist/icons/icon-192.png +0 -0
  433. package/apps/web/dist/icons/icon-512.png +0 -0
  434. package/apps/web/dist/icons/icon-maskable-512.png +0 -0
  435. package/apps/web/dist/index.html +48 -0
  436. package/apps/web/dist/install.sh +577 -0
  437. package/apps/web/dist/manifest.webmanifest +21 -0
  438. package/apps/web/dist/mcp/flow.html +980 -0
  439. package/apps/web/dist/sw.js +15 -0
  440. package/bin/wizards.mjs +288 -0
  441. package/modules/README.md +15 -0
  442. package/node_modules/@engenty/wizards/dist/plugin/index.d.ts +1150 -0
  443. package/node_modules/@engenty/wizards/dist/plugin/index.js +4 -0
  444. package/node_modules/@engenty/wizards/dist/plugin/studio.d.ts +322 -0
  445. package/node_modules/@engenty/wizards/dist/plugin/studio.js +4 -0
  446. package/node_modules/@engenty/wizards/dist/plugin/thread.d.ts +174 -0
  447. package/node_modules/@engenty/wizards/dist/plugin/thread.js +821 -0
  448. package/node_modules/@engenty/wizards/package.json +11 -0
  449. package/node_modules/@engenty-wizards/shared/dist/assistant.d.ts +174 -0
  450. package/node_modules/@engenty-wizards/shared/dist/assistant.js +65 -0
  451. package/node_modules/@engenty-wizards/shared/dist/changes.d.ts +22 -0
  452. package/node_modules/@engenty-wizards/shared/dist/changes.js +61 -0
  453. package/node_modules/@engenty-wizards/shared/dist/connectors.d.ts +77 -0
  454. package/node_modules/@engenty-wizards/shared/dist/connectors.js +2 -0
  455. package/node_modules/@engenty-wizards/shared/dist/decision.d.ts +76 -0
  456. package/node_modules/@engenty-wizards/shared/dist/decision.js +147 -0
  457. package/node_modules/@engenty-wizards/shared/dist/definition.d.ts +2922 -0
  458. package/node_modules/@engenty-wizards/shared/dist/definition.js +1920 -0
  459. package/node_modules/@engenty-wizards/shared/dist/engenty/data-tables/columns-format.d.ts +5 -0
  460. package/node_modules/@engenty-wizards/shared/dist/engenty/data-tables/columns-format.js +132 -0
  461. package/node_modules/@engenty-wizards/shared/dist/engenty/data-tables/columns-value.d.ts +11 -0
  462. package/node_modules/@engenty-wizards/shared/dist/engenty/data-tables/columns-value.js +209 -0
  463. package/node_modules/@engenty-wizards/shared/dist/engenty/data-tables/columns.d.ts +532 -0
  464. package/node_modules/@engenty-wizards/shared/dist/engenty/data-tables/columns.js +217 -0
  465. package/node_modules/@engenty-wizards/shared/dist/engenty/data-tables/index.d.ts +3 -0
  466. package/node_modules/@engenty-wizards/shared/dist/engenty/data-tables/index.js +3 -0
  467. package/node_modules/@engenty-wizards/shared/dist/engenty/search-index/catalog-lexical.d.ts +14 -0
  468. package/node_modules/@engenty-wizards/shared/dist/engenty/search-index/catalog-lexical.js +166 -0
  469. package/node_modules/@engenty-wizards/shared/dist/engenty/search-index/catalog-rank.d.ts +33 -0
  470. package/node_modules/@engenty-wizards/shared/dist/engenty/search-index/catalog-rank.js +99 -0
  471. package/node_modules/@engenty-wizards/shared/dist/feature-flags.d.ts +78 -0
  472. package/node_modules/@engenty-wizards/shared/dist/feature-flags.js +70 -0
  473. package/node_modules/@engenty-wizards/shared/dist/features.d.ts +41 -0
  474. package/node_modules/@engenty-wizards/shared/dist/features.js +89 -0
  475. package/node_modules/@engenty-wizards/shared/dist/fit.d.ts +71 -0
  476. package/node_modules/@engenty-wizards/shared/dist/fit.js +382 -0
  477. package/node_modules/@engenty-wizards/shared/dist/json-schema.d.ts +14 -0
  478. package/node_modules/@engenty-wizards/shared/dist/json-schema.js +66 -0
  479. package/node_modules/@engenty-wizards/shared/dist/knowledge.d.ts +199 -0
  480. package/node_modules/@engenty-wizards/shared/dist/knowledge.js +68 -0
  481. package/node_modules/@engenty-wizards/shared/dist/marketplace-entry.d.ts +35 -0
  482. package/node_modules/@engenty-wizards/shared/dist/marketplace-entry.js +107 -0
  483. package/node_modules/@engenty-wizards/shared/dist/marketplace-search.d.ts +20 -0
  484. package/node_modules/@engenty-wizards/shared/dist/marketplace-search.js +136 -0
  485. package/node_modules/@engenty-wizards/shared/dist/marketplace.d.ts +227 -0
  486. package/node_modules/@engenty-wizards/shared/dist/marketplace.js +354 -0
  487. package/node_modules/@engenty-wizards/shared/dist/merge.d.ts +7 -0
  488. package/node_modules/@engenty-wizards/shared/dist/merge.js +40 -0
  489. package/node_modules/@engenty-wizards/shared/dist/numbers.d.ts +24 -0
  490. package/node_modules/@engenty-wizards/shared/dist/numbers.js +54 -0
  491. package/node_modules/@engenty-wizards/shared/dist/projects.d.ts +224 -0
  492. package/node_modules/@engenty-wizards/shared/dist/projects.js +319 -0
  493. package/node_modules/@engenty-wizards/shared/dist/providers.d.ts +101 -0
  494. package/node_modules/@engenty-wizards/shared/dist/providers.js +390 -0
  495. package/node_modules/@engenty-wizards/shared/dist/run.d.ts +680 -0
  496. package/node_modules/@engenty-wizards/shared/dist/run.js +620 -0
  497. package/node_modules/@engenty-wizards/shared/dist/runner-texts.d.ts +546 -0
  498. package/node_modules/@engenty-wizards/shared/dist/runner-texts.js +523 -0
  499. package/node_modules/@engenty-wizards/shared/dist/runners.d.ts +93 -0
  500. package/node_modules/@engenty-wizards/shared/dist/runners.js +146 -0
  501. package/node_modules/@engenty-wizards/shared/dist/shape.d.ts +102 -0
  502. package/node_modules/@engenty-wizards/shared/dist/shape.js +318 -0
  503. package/node_modules/@engenty-wizards/shared/dist/space-data.d.ts +89 -0
  504. package/node_modules/@engenty-wizards/shared/dist/space-data.js +47 -0
  505. package/node_modules/@engenty-wizards/shared/dist/store.d.ts +117 -0
  506. package/node_modules/@engenty-wizards/shared/dist/store.js +81 -0
  507. package/node_modules/@engenty-wizards/shared/dist/surface.d.ts +115 -0
  508. package/node_modules/@engenty-wizards/shared/dist/surface.js +442 -0
  509. package/node_modules/@engenty-wizards/shared/dist/texts.d.ts +45 -0
  510. package/node_modules/@engenty-wizards/shared/dist/texts.js +54 -0
  511. package/node_modules/@engenty-wizards/shared/dist/translation.d.ts +23 -0
  512. package/node_modules/@engenty-wizards/shared/dist/translation.js +154 -0
  513. package/node_modules/@engenty-wizards/shared/dist/wizard-package.d.ts +48 -0
  514. package/node_modules/@engenty-wizards/shared/dist/wizard-package.js +49 -0
  515. package/node_modules/@engenty-wizards/shared/dist/workspace.d.ts +16 -0
  516. package/node_modules/@engenty-wizards/shared/dist/workspace.js +51 -0
  517. package/node_modules/@engenty-wizards/shared/package.json +10 -0
  518. package/package.json +77 -4
  519. package/plugin/.claude-plugin/plugin.json +9 -0
  520. package/plugin/.mcp.json +8 -0
  521. package/plugin/commands/wizard.md +8 -0
  522. package/plugin/skills/build-wizard/SKILL.md +27 -0
  523. package/plugin/skills/use-wizard/SKILL.md +18 -0
@@ -0,0 +1,703 @@
1
+ import { readFile } from "node:fs/promises";
2
+ import { createTool } from "@mastra/core/tools";
3
+ import { generateText } from "ai";
4
+ import { z } from "zod";
5
+ import { classifierClient } from "../browser/fast/classifier.js";
6
+ import { runFastLoop } from "../browser/fast/run.js";
7
+ import { createFieldText } from "../browser/fast/text-helper.js";
8
+ import { nodeScript, PAGE_SCRIPT, settleScript, targetScript, } from "../browser/snapshot.js";
9
+ import { env } from "../env.js";
10
+ import { costOf, textModel } from "../models.js";
11
+ import { assertPublicUrl } from "./net-guard.js";
12
+ import { attempt, imageOutput } from "./shared.js";
13
+ /** The page as an agent step reads it; retried while the page is between two documents. */
14
+ export async function readPage(page) {
15
+ for (let attempt = 0; attempt < 5; attempt++) {
16
+ const view = await page.evaluate(PAGE_SCRIPT).catch(() => null);
17
+ if (view) {
18
+ return view;
19
+ }
20
+ await page.waitForLoadState("domcontentloaded", { timeout: 5000 }).catch(() => undefined);
21
+ await new Promise((r) => setTimeout(r, 200));
22
+ }
23
+ return {
24
+ url: page.url(),
25
+ title: "",
26
+ text: "",
27
+ items: [],
28
+ omitted: 0,
29
+ scroll: { y: 0, height: 0, viewport: 0 },
30
+ };
31
+ }
32
+ function line(item) {
33
+ const parts = [`[${item.ref}]`, item.role, JSON.stringify(item.label)];
34
+ if (item.kind === "fill") {
35
+ parts.push(item.value ? `= ${JSON.stringify(item.value)}` : "(empty)");
36
+ }
37
+ else if (item.kind === "password") {
38
+ parts.push(item.value ? "(filled)" : "(empty)");
39
+ }
40
+ else if (item.kind === "select") {
41
+ const more = item.more_options ? ` | … ${item.more_options} more` : "";
42
+ parts.push(`= ${JSON.stringify(item.value ?? "")}; options: ${(item.options ?? []).join(" | ")}${more}`);
43
+ }
44
+ for (const key of ["checked", "selected", "expanded"]) {
45
+ if (item[key] !== undefined) {
46
+ parts.push(`${key}=${item[key]}`);
47
+ }
48
+ }
49
+ if (item.dialog) {
50
+ parts.push("(dialog)");
51
+ }
52
+ return parts.join(" ");
53
+ }
54
+ /**
55
+ * The page as the model gets it: one line per control, named by its [number] — a dialog or
56
+ * banner first, marked (dialog) — then the page's visible text.
57
+ */
58
+ export function pageForModel(view) {
59
+ const more = view.omitted
60
+ ? `\n… ${view.omitted} more not listed: close what is open, scroll, or read the page again.`
61
+ : "";
62
+ return {
63
+ url: view.url,
64
+ title: view.title,
65
+ elements: view.items.map(line).join("\n") + more,
66
+ text: view.text,
67
+ scroll: `${view.scroll.y} of ${view.scroll.height} px, ${view.scroll.viewport} px in view`,
68
+ };
69
+ }
70
+ function originOf(url) {
71
+ try {
72
+ const parsed = new URL(url);
73
+ return parsed.protocol === "https:" || parsed.protocol === "http:" ? parsed.origin : null;
74
+ }
75
+ catch {
76
+ return null;
77
+ }
78
+ }
79
+ /** A wait that timed out is a rejection, so waits can be raced. */
80
+ function found(wait) {
81
+ const p = wait.then((v) => v ?? Promise.reject(new Error("none")));
82
+ p.catch(() => undefined);
83
+ return p;
84
+ }
85
+ /**
86
+ * Lets the page come to rest after an input: no DOM changes and no animation for a moment, or
87
+ * the next document loaded where the input navigated.
88
+ */
89
+ async function settle(page) {
90
+ await page.evaluate(settleScript(null)).catch(() => undefined);
91
+ await page.waitForLoadState("domcontentloaded", { timeout: 10_000 }).catch(() => undefined);
92
+ }
93
+ /**
94
+ * Fetches a URL with the browser's sign-in, outside any page. Page requests pass the context's
95
+ * host guard; this one does not, so every redirect hop is checked here.
96
+ */
97
+ async function signedInGet(page, url) {
98
+ let next = url;
99
+ for (let hop = 0; hop < 6; hop++) {
100
+ const safe = await assertPublicUrl(next);
101
+ const res = await page
102
+ .context()
103
+ .request.get(safe.toString(), { timeout: 60_000, maxRedirects: 0 });
104
+ const location = res.headers().location;
105
+ if (res.status() < 300 || res.status() >= 400 || !location) {
106
+ return res;
107
+ }
108
+ next = new URL(location, safe).toString();
109
+ }
110
+ throw new Error("Too many redirects.");
111
+ }
112
+ /** Why a [number] cannot be used, for the model. */
113
+ function targetError(n, target) {
114
+ switch (target.error) {
115
+ case "covered":
116
+ return `[${n}] is covered by "${target.by}". Deal with that first — a cookie or consent banner: click its least consent (only necessary / reject all).`;
117
+ case "disabled":
118
+ return `[${n}] is disabled right now.`;
119
+ case "gone":
120
+ return `[${n}] is not on the page any more. Use the numbers of the page below.`;
121
+ default:
122
+ return `[${n}] cannot be seen on the page.`;
123
+ }
124
+ }
125
+ /**
126
+ * Where to put the pointer for a [number]: scrolled into view and not covered by anything — so
127
+ * a click never lands on whatever lies over it.
128
+ */
129
+ function pointAt(page, n) {
130
+ return page.evaluate(targetScript(n)).catch(() => ({ error: "gone" }));
131
+ }
132
+ /** The element a [number] names, for what Playwright does best (fill, select). */
133
+ async function handleOf(page, n) {
134
+ const handle = await page.evaluateHandle(nodeScript(n)).catch(() => null);
135
+ return handle?.asElement() ?? null;
136
+ }
137
+ /** Clicks at a point; a tab the click opens is where the agent goes on. */
138
+ async function clickAt(ctx, page, point) {
139
+ const opened = [];
140
+ const onPage = (p) => {
141
+ opened.push(p);
142
+ };
143
+ page.context().on("page", onPage);
144
+ try {
145
+ await page.mouse.click(point.x, point.y);
146
+ await settle(page);
147
+ }
148
+ finally {
149
+ page.context().off("page", onPage);
150
+ }
151
+ const popup = opened.at(-1);
152
+ if (popup) {
153
+ ctx.resources.adopt(popup);
154
+ await popup.waitForLoadState("domcontentloaded", { timeout: 10_000 }).catch(() => undefined);
155
+ return popup;
156
+ }
157
+ return page;
158
+ }
159
+ const credentialField = z.object({
160
+ ref: z.number().describe("The field's [number] from your latest page."),
161
+ label: z.string().min(1).max(60).describe("What the person sees, e.g. E-Mail."),
162
+ kind: z
163
+ .enum(["username", "password", "otp", "text"])
164
+ .describe("password only fills a password input."),
165
+ });
166
+ /**
167
+ * Types the person's values into the page. A password goes only into a password input, and
168
+ * only while the page is still the site the person was shown. Each field is marked as the
169
+ * person's, so no reading of the page gives its value to a model. Failures are codes: a browser
170
+ * error message could quote the value it failed to type.
171
+ */
172
+ async function fillCredentials(page, origin, fields, values) {
173
+ if (originOf(page.url()) !== origin) {
174
+ return { error: "origin_changed" };
175
+ }
176
+ const filled = [];
177
+ for (const [index, field] of fields.entries()) {
178
+ const value = values[`field_${index + 1}`];
179
+ if (typeof value !== "string" || !value) {
180
+ continue;
181
+ }
182
+ const handle = await handleOf(page, field.ref);
183
+ const element = handle
184
+ ? await handle
185
+ .evaluate((el) => ({ tag: el.tagName, type: el.type ?? "" }))
186
+ .catch(() => null)
187
+ : null;
188
+ if (!(handle && element)) {
189
+ return { error: "field_missing" };
190
+ }
191
+ if (element.tag !== "INPUT" && element.tag !== "TEXTAREA") {
192
+ return { error: "not_an_input" };
193
+ }
194
+ if (field.kind === "password" && element.type !== "password") {
195
+ return { error: "not_a_password_field" };
196
+ }
197
+ try {
198
+ await handle.evaluate((el) => {
199
+ const w = window;
200
+ w.__wzPersonal ??= new WeakSet();
201
+ w.__wzPersonal.add(el);
202
+ });
203
+ await handle.fill(value, { timeout: 10_000 });
204
+ }
205
+ catch {
206
+ return { error: "fill_failed" };
207
+ }
208
+ filled.push(field.label);
209
+ }
210
+ return { filled };
211
+ }
212
+ const NOBODY = "Nobody is at the keyboard for this run, so a sign-in cannot be asked for. Go on without it and report what the person has to do.";
213
+ const DECLINED = "The person did not sign in. Do not ask again for this site; go on without it and say in your result what is missing and what the person can do.";
214
+ const TOOK_OVER = "The person took the browser over and has handed it back; nothing you asked for was done. The page may have changed — here it is as it stands now. Go on from here.";
215
+ const RUN_FAST_DESCRIPTION = "Hand a small, concrete browser sub-goal to the fast executor: on the CURRENT page it reads the visible controls, picks one element per step with a classifier (no language model), types field values taken from your goal, and repeats until the goal is visibly satisfied or it is unsure. Use it for mechanical sequences — click a cookie banner away, fill and submit a form, pick a date in a calendar, choose an autocomplete suggestion, set filters and dropdowns, open a matching result. Give one page's worth of work per call with every value spelled out (dates, names, filters); it never invents data. Returns status `done`, or `uncertain`/`blocked`/`budget`/`error` with the page and a note naming the step it could not decide. Then do THAT ONE step with the other browser_* tools and call browser_run_fast again with the same goal — do not finish the rest by hand. Open the page with browser_open first; it does not open URLs.";
216
+ /** One line of at most 60 characters, for the run's log. */
217
+ function short(text) {
218
+ const one = text.trim().replace(/\s+/g, " ");
219
+ return one.length > 60 ? `${one.slice(0, 59)}…` : one;
220
+ }
221
+ /** What a step of the fast loop did, for the run's log. */
222
+ function fastStepNote(step) {
223
+ const name = short(step.target_label ?? "");
224
+ switch (step.operation) {
225
+ case "CLICK":
226
+ return name ? { code: "clicksOn", params: { name } } : { code: "clicks" };
227
+ case "TYPE_TEXT":
228
+ return { code: "types" };
229
+ case "SELECT":
230
+ return name ? { code: "selects", params: { option: name } } : null;
231
+ case "SCROLL_UP":
232
+ case "SCROLL_DOWN":
233
+ return { code: "scrolls" };
234
+ case "WAIT":
235
+ return { code: "waitsForPage" };
236
+ default:
237
+ return null;
238
+ }
239
+ }
240
+ export async function browserTools(ctx, assets, files) {
241
+ const page = () => ctx.resources.browserPage();
242
+ const tools = {};
243
+ /** What each [number] was called on the latest reading, for the run's log. */
244
+ const names = new Map();
245
+ const read = async (p) => {
246
+ const view = await readPage(p);
247
+ for (const item of view.items) {
248
+ names.set(item.ref, item.label);
249
+ }
250
+ return pageForModel(view);
251
+ };
252
+ // There is one page. A model may ask for several browser actions at once; they run one after
253
+ // the other, in the order asked — else a navigation would cut a download short.
254
+ let queue = Promise.resolve();
255
+ const inTurn = (run) => {
256
+ const next = queue.then(() => attempt(run));
257
+ queue = next;
258
+ return next;
259
+ };
260
+ // While the person drives the browser, nothing the agent asks for happens; when they hand it
261
+ // back, the agent gets the page as they left it instead.
262
+ const acting = (run) => inTurn(async () => {
263
+ if (await ctx.resources.agentTurn(ctx.signal)) {
264
+ return { note: TOOK_OVER, page: await read(await page()) };
265
+ }
266
+ return run();
267
+ });
268
+ const atRef = async (p, n) => {
269
+ const target = await pointAt(p, n);
270
+ return "error" in target ? { error: targetError(n, target), page: await read(p) } : target;
271
+ };
272
+ tools.browser_open = createTool({
273
+ id: "browser_open",
274
+ description: "Open a URL in the browser and return the page: its controls, each with a [number], and its text. A cookie banner in the way: click its least consent (only necessary / reject all) first. Sites the person signed in to on an earlier run may still be signed in.",
275
+ inputSchema: z.object({ url: z.string() }),
276
+ execute: ({ url }) => acting(async () => {
277
+ const safe = await assertPublicUrl(url);
278
+ // The page first, so whoever watches the browser on this line finds one.
279
+ const p = await page();
280
+ await ctx.emit("tool", { code: "opens", params: { name: safe.hostname } });
281
+ await p.goto(safe.toString(), { waitUntil: "domcontentloaded", timeout: 30_000 });
282
+ await p.waitForLoadState("networkidle", { timeout: 5000 }).catch(() => undefined);
283
+ return read(p);
284
+ }),
285
+ });
286
+ tools.browser_read = createTool({
287
+ id: "browser_read",
288
+ description: "Read the current page again: its controls with their [numbers] and its text. A number stays with its element as long as the element is on the page.",
289
+ inputSchema: z.object({}),
290
+ execute: () => acting(async () => read(await page())),
291
+ });
292
+ tools.browser_click = createTool({
293
+ id: "browser_click",
294
+ description: "Click an element by its [number]. It is scrolled into view first; a click on something covered by a banner or dialog is refused and names what covers it.",
295
+ inputSchema: z.object({ ref: z.number() }),
296
+ execute: ({ ref: n }) => acting(async () => {
297
+ const p = await page();
298
+ const target = await atRef(p, n);
299
+ if ("error" in target) {
300
+ return target;
301
+ }
302
+ const name = short(names.get(n) ?? "");
303
+ await ctx.emit("tool", name ? { code: "clicksOn", params: { name } } : { code: "clicks" });
304
+ return read(await clickAt(ctx, p, target));
305
+ }),
306
+ });
307
+ tools.browser_type = createTool({
308
+ id: "browser_type",
309
+ description: "Type text into a field by its [number], replacing what is in it; set submit to press Enter afterwards. Never for passwords or codes — those the person enters through browser_request_credentials.",
310
+ inputSchema: z.object({ ref: z.number(), text: z.string(), submit: z.boolean().optional() }),
311
+ execute: ({ ref: n, text, submit }) => acting(async () => {
312
+ const p = await page();
313
+ const target = await atRef(p, n);
314
+ if ("error" in target) {
315
+ return target;
316
+ }
317
+ const el = await handleOf(p, n);
318
+ if (!el) {
319
+ return { error: targetError(n, { error: "gone" }), page: await read(p) };
320
+ }
321
+ if ((await el.evaluate((e) => e.type)) === "password") {
322
+ return {
323
+ error: `[${n}] is a password field: the person fills it through browser_request_credentials.`,
324
+ };
325
+ }
326
+ const said = short(text);
327
+ await ctx.emit("tool", said ? { code: "typesText", params: { text: said } } : { code: "types" });
328
+ await el.fill(text, { timeout: 10_000 });
329
+ if (submit) {
330
+ await el.press("Enter");
331
+ }
332
+ await settle(p);
333
+ return read(ctx.resources.openPage() ?? p);
334
+ }),
335
+ });
336
+ tools.browser_select = createTool({
337
+ id: "browser_select",
338
+ description: "Choose an option in a dropdown (a select element) by its [number] and the option's name as the page lists it. For a dropdown the page draws itself (no options listed), click it open and click the option instead.",
339
+ inputSchema: z.object({ ref: z.number(), option: z.string() }),
340
+ execute: ({ ref: n, option }) => acting(async () => {
341
+ const p = await page();
342
+ const target = await atRef(p, n);
343
+ if ("error" in target) {
344
+ return target;
345
+ }
346
+ const el = await handleOf(p, n);
347
+ if (!el) {
348
+ return { error: targetError(n, { error: "gone" }), page: await read(p) };
349
+ }
350
+ await ctx.emit("tool", { code: "selects", params: { option: short(option) } });
351
+ const chosen = (await el.selectOption({ label: option }, { timeout: 5000 }).catch(() => null)) ??
352
+ (await el.selectOption(option, { timeout: 5000 }).catch(() => null));
353
+ if (!chosen?.length) {
354
+ return { error: `[${n}] has no option "${option}".`, page: await read(p) };
355
+ }
356
+ await settle(p);
357
+ return read(ctx.resources.openPage() ?? p);
358
+ }),
359
+ });
360
+ tools.browser_scroll = createTool({
361
+ id: "browser_scroll",
362
+ description: "Scroll the page down or up by most of a screen, or bring the element with this [number] into view. For results further down, lists that load as you scroll, and footers.",
363
+ inputSchema: z.object({
364
+ direction: z.enum(["down", "up"]).optional(),
365
+ ref: z.number().optional(),
366
+ }),
367
+ execute: ({ direction, ref: n }) => acting(async () => {
368
+ const p = await page();
369
+ await ctx.emit("tool", { code: "scrolls" });
370
+ if (n !== undefined) {
371
+ const target = await atRef(p, n);
372
+ if ("error" in target) {
373
+ return target;
374
+ }
375
+ }
376
+ else {
377
+ const size = p.viewportSize() ?? { width: 1280, height: 900 };
378
+ await p.mouse.move(Math.floor(size.width / 2), Math.floor(size.height / 2));
379
+ await p.mouse.wheel(0, (direction === "up" ? -0.8 : 0.8) * size.height);
380
+ }
381
+ await settle(p);
382
+ return read(p);
383
+ }),
384
+ });
385
+ tools.browser_press = createTool({
386
+ id: "browser_press",
387
+ description: "Press a key on the page: Enter to send, Escape to close a popup, Tab to move on, the arrows to move through a list of suggestions.",
388
+ inputSchema: z.object({
389
+ key: z.enum([
390
+ "Enter",
391
+ "Escape",
392
+ "Tab",
393
+ "Backspace",
394
+ "ArrowDown",
395
+ "ArrowUp",
396
+ "ArrowLeft",
397
+ "ArrowRight",
398
+ "PageDown",
399
+ "PageUp",
400
+ "Space",
401
+ ]),
402
+ }),
403
+ execute: ({ key }) => acting(async () => {
404
+ const p = await page();
405
+ await ctx.emit("tool", { code: "presses", params: { key } });
406
+ await p.keyboard.press(key === "Space" ? " " : key);
407
+ await settle(p);
408
+ return read(ctx.resources.openPage() ?? p);
409
+ }),
410
+ });
411
+ tools.browser_back = createTool({
412
+ id: "browser_back",
413
+ description: "Go back to the previous page, like the browser's back button.",
414
+ inputSchema: z.object({}),
415
+ execute: () => acting(async () => {
416
+ const p = await page();
417
+ await ctx.emit("tool", { code: "goesBack" });
418
+ const went = await p
419
+ .goBack({ waitUntil: "domcontentloaded", timeout: 20_000 })
420
+ .catch(() => null);
421
+ if (!went) {
422
+ return { error: "There is no page to go back to.", page: await read(p) };
423
+ }
424
+ return read(p);
425
+ }),
426
+ });
427
+ tools.browser_wait = createTool({
428
+ id: "browser_wait",
429
+ description: "Wait for the page: until a text appears on it (results that load, a confirmation), or for a few seconds. Then returns the page.",
430
+ inputSchema: z.object({
431
+ text: z.string().optional().describe("Wait until this text is on the page."),
432
+ seconds: z.number().min(1).max(15).optional().describe("How long at most; default 5."),
433
+ }),
434
+ execute: ({ text, seconds }) => acting(async () => {
435
+ const p = await page();
436
+ await ctx.emit("tool", { code: "waitsForPage" });
437
+ const ms = (seconds ?? 5) * 1000;
438
+ let note;
439
+ if (text) {
440
+ const appeared = await p
441
+ .getByText(text)
442
+ .first()
443
+ .waitFor({ timeout: ms })
444
+ .then(() => true)
445
+ .catch(() => false);
446
+ note = appeared ? undefined : `"${text}" did not appear within ${ms / 1000} s.`;
447
+ }
448
+ else {
449
+ await p.waitForTimeout(ms);
450
+ }
451
+ await settle(p);
452
+ return { ...(note ? { note } : {}), page: await read(p) };
453
+ }),
454
+ });
455
+ tools.browser_screenshot = createTool({
456
+ id: "browser_screenshot",
457
+ description: "Look at the current page: returns a picture of it to you. Use it when the text is not enough (charts, a layout you cannot make sense of, a captcha or cookie wall). Set save to also hand the picture to the person as part of the result.",
458
+ inputSchema: z.object({ save: z.boolean().optional(), name: z.string().optional() }),
459
+ execute: ({ save, name }) => inTurn(async () => {
460
+ const p = await page();
461
+ await ctx.emit("tool", { code: "looksAtPage" });
462
+ const png = await p.screenshot({ type: "png" });
463
+ let saved;
464
+ if (save) {
465
+ const asset = await ctx.saveAsset({
466
+ kind: "image",
467
+ mime: "image/png",
468
+ name: name ?? "screenshot.png",
469
+ data: png,
470
+ });
471
+ assets.push(asset);
472
+ saved = asset.id;
473
+ }
474
+ return { url: p.url(), saved, screenshot: Buffer.from(png).toString("base64") };
475
+ }),
476
+ toModelOutput: imageOutput("screenshot"),
477
+ });
478
+ const handOver = async (input) => {
479
+ const p = await page();
480
+ const origin = originOf(p.url());
481
+ if (!origin) {
482
+ return { error: "no_site", note: "Open the site's sign-in page first." };
483
+ }
484
+ for (const field of input.fields) {
485
+ if (!(await handleOf(p, field.ref))) {
486
+ return {
487
+ error: "fields_not_found",
488
+ note: `[${field.ref}] is not on the page any more. Read the page again and ask with its numbers.`,
489
+ };
490
+ }
491
+ }
492
+ await ctx.emit("tool", {
493
+ code: "waitsForSignIn",
494
+ params: { name: new URL(origin).hostname },
495
+ });
496
+ const answer = await ctx.ask({
497
+ kind: "login",
498
+ reason: input.reason,
499
+ site: { host: new URL(origin).hostname, title: await p.title() },
500
+ fields: input.fields.map((f, i) => ({
501
+ id: `field_${i + 1}`,
502
+ label: f.label,
503
+ secret: f.kind === "password",
504
+ })),
505
+ });
506
+ if (!answer) {
507
+ return { status: "needs_person", note: NOBODY };
508
+ }
509
+ if (answer.type === "skip" || answer.type === "timeout") {
510
+ return { status: "declined", note: DECLINED };
511
+ }
512
+ // The person may have gone on in a tab the site opened.
513
+ const current = ctx.resources.openPage() ?? p;
514
+ let note = "The person signed in on the page themselves.";
515
+ if (answer.type === "fill") {
516
+ const result = await fillCredentials(current, origin, input.fields, answer.values);
517
+ if ("error" in result) {
518
+ return {
519
+ error: result.error,
520
+ note: "Nothing you can read was entered. Read the page again and ask with its current numbers.",
521
+ };
522
+ }
523
+ if (result.filled.length && input.submitRef !== undefined) {
524
+ const target = await pointAt(current, input.submitRef);
525
+ if (!("error" in target)) {
526
+ await clickAt(ctx, current, target).catch(() => undefined);
527
+ }
528
+ }
529
+ await settle(current);
530
+ await current.waitForLoadState("networkidle", { timeout: 5000 }).catch(() => undefined);
531
+ note = `The person entered ${result.filled.join(", ")} straight into the page${input.submitRef !== undefined ? " and it was submitted" : ""}. You do not see what they typed and must not try to read it back.`;
532
+ }
533
+ if (answer.remember) {
534
+ await ctx.resources.keepSession().catch(() => undefined);
535
+ }
536
+ return { status: "done", note, page: await read(ctx.resources.openPage() ?? current) };
537
+ };
538
+ tools.browser_request_credentials = createTool({
539
+ id: "browser_request_credentials",
540
+ description: "THE way to get a login into a page: ask the person to enter a username, e-mail, password or one-time code into fields on your current page, WITHOUT you seeing it. The person sees the page live, the site's address and a form; what they type goes straight into the page, never to you. Give each field's [number] from your latest page, and submit_ref to press the sign-in or next button afterwards. A login spread over several pages (e-mail, then password, then code) is one call per page. WAITS for the person. Never ask for a password any other way.",
541
+ inputSchema: z.object({
542
+ reason: z
543
+ .string()
544
+ .min(1)
545
+ .max(300)
546
+ .describe("One sentence for the person, in their language: which site and why."),
547
+ fields: z.array(credentialField).min(1).max(4),
548
+ submit_ref: z
549
+ .number()
550
+ .optional()
551
+ .describe("[number] of the button to press once the fields are filled."),
552
+ }),
553
+ execute: ({ reason, fields, submit_ref }) => acting(() => handOver({ reason, fields, submitRef: submit_ref })),
554
+ });
555
+ tools.browser_request_user = createTool({
556
+ id: "browser_request_user",
557
+ description: "Hand the page to the person for something no form can do: a captcha, 'continue with Google', a passkey, a cookie wall you cannot get past. They click and type in the live page and say when they are done. For a plain login form use browser_request_credentials instead. WAITS for the person.",
558
+ inputSchema: z.object({
559
+ reason: z
560
+ .string()
561
+ .min(1)
562
+ .max(300)
563
+ .describe("One sentence for the person, in their language: what to do on the page."),
564
+ }),
565
+ execute: ({ reason }) => acting(() => handOver({ reason, fields: [] })),
566
+ });
567
+ tools.browser_download = createTool({
568
+ id: "browser_download",
569
+ description: "Download a file (an invoice PDF, an export) with the browser's sign-in and keep it: click the element with this [number], or fetch this URL. The file is stored under `path` in the wizard's files and added to this step's result.",
570
+ inputSchema: z.object({
571
+ ref: z.number().optional().describe("[number] of the download link or button."),
572
+ url: z.string().optional().describe("Direct URL of the file, instead of ref."),
573
+ path: z
574
+ .string()
575
+ .describe("Where to keep it, e.g. invoices/2026-09/2026-09-03_Notion_INV-123.pdf"),
576
+ source: z.string().optional().describe("Where it came from, in words, for the person."),
577
+ }),
578
+ execute: ({ ref: n, url, path, source }) => acting(async () => {
579
+ const p = await page();
580
+ let data;
581
+ let mime;
582
+ if (url) {
583
+ await ctx.emit("tool", {
584
+ code: "downloads",
585
+ params: { name: path.split("/").pop() ?? "" },
586
+ });
587
+ const res = await signedInGet(p, new URL(url, p.url()).toString());
588
+ if (!res.ok()) {
589
+ return { error: `The server answered ${res.status()}.` };
590
+ }
591
+ data = await res.body();
592
+ mime = res.headers()["content-type"]?.split(";")[0];
593
+ }
594
+ else if (n !== undefined) {
595
+ const target = await atRef(p, n);
596
+ if ("error" in target) {
597
+ return target;
598
+ }
599
+ await ctx.emit("tool", {
600
+ code: "downloads",
601
+ params: { name: path.split("/").pop() ?? "" },
602
+ });
603
+ // A click may start a download, open the file in a new tab, or both.
604
+ const download = found(p.waitForEvent("download", { timeout: 12_000 }));
605
+ const popup = found(p.context().waitForEvent("page", { timeout: 5000 }));
606
+ await p.mouse.click(target.x, target.y);
607
+ const opened = await Promise.race([popup, download.then(() => null)]).catch(() => null);
608
+ const got = await Promise.any([
609
+ download,
610
+ ...(opened ? [found(opened.waitForEvent("download", { timeout: 8000 }))] : []),
611
+ ]).catch(() => null);
612
+ if (got) {
613
+ data = await readFile(await got.path());
614
+ await opened?.close().catch(() => undefined);
615
+ }
616
+ else {
617
+ // No download event: the click opened the file in a tab (a PDF viewer).
618
+ const shown = opened ?? p;
619
+ await settle(shown);
620
+ const res = await signedInGet(p, shown.url());
621
+ mime = res.headers()["content-type"]?.split(";")[0];
622
+ if (!res.ok() || mime === "text/html") {
623
+ await opened?.close().catch(() => undefined);
624
+ return { error: "The click did not give a file.", page: await read(p) };
625
+ }
626
+ data = await res.body();
627
+ await opened?.close().catch(() => undefined);
628
+ }
629
+ }
630
+ else {
631
+ return { error: "Give ref or url." };
632
+ }
633
+ if (mime === "text/html") {
634
+ return { error: "That is a web page, not a file — you may not be signed in." };
635
+ }
636
+ const kept = await files.keep(path, data, {
637
+ mime,
638
+ source: source ?? `Download von ${new URL(p.url()).hostname}`,
639
+ });
640
+ return { saved: kept.path, mime: kept.mime, size: kept.size };
641
+ }),
642
+ });
643
+ // The fast loop, where a decision model can be reached: a classifier picks each step.
644
+ const classifier = env.browserFastLoop
645
+ ? await classifierClient(ctx.signal)
646
+ : null;
647
+ if (classifier) {
648
+ const fieldText = createFieldText({
649
+ spans: { client: classifier },
650
+ ask: async (instructions, prompt) => {
651
+ const resolved = await textModel("classifier", ctx.call);
652
+ const result = await generateText({
653
+ model: resolved.model,
654
+ system: instructions,
655
+ prompt,
656
+ temperature: 0,
657
+ maxOutputTokens: 1024,
658
+ abortSignal: ctx.signal,
659
+ });
660
+ await ctx.chargeUsd(costOf(resolved, result.usage));
661
+ return result.text;
662
+ },
663
+ });
664
+ tools.browser_run_fast = createTool({
665
+ id: "browser_run_fast",
666
+ description: RUN_FAST_DESCRIPTION,
667
+ inputSchema: z.object({
668
+ goal: z
669
+ .string()
670
+ .min(1)
671
+ .max(2000)
672
+ .describe("The sub-goal for the current page, with every concrete value it needs (e.g. 'Close the cookie banner with only the necessary cookies, type lego millennium falcon into the search and search')."),
673
+ max_steps: z.number().int().min(1).max(100).optional().describe("Step budget; default 40."),
674
+ }),
675
+ execute: ({ goal, max_steps }) => acting(async () => {
676
+ const p = await page();
677
+ await ctx.emit("tool", { code: "fastLoop", params: { goal: short(goal) } });
678
+ const result = await runFastLoop({
679
+ client: classifier,
680
+ fieldText,
681
+ goal,
682
+ maxSteps: max_steps ?? 40,
683
+ minMargin: 0.1,
684
+ page: p,
685
+ shouldStop: () => ctx.signal.aborted || ctx.resources.seatHolder() === "person",
686
+ onStep: (step) => {
687
+ const note = fastStepNote(step);
688
+ if (note) {
689
+ ctx.emit("tool", note).catch(() => undefined);
690
+ }
691
+ },
692
+ });
693
+ return {
694
+ status: result.status,
695
+ note: result.note,
696
+ steps: result.history.map((h) => `${h.step}. ${h.operation} ${h.action}${h.text ? ` = "${h.text}"` : ""}${h.page_changed === false ? " (nothing changed)" : ""}`),
697
+ page: await read(ctx.resources.openPage() ?? p),
698
+ };
699
+ }),
700
+ });
701
+ }
702
+ return tools;
703
+ }