waygraph 0.15.54 → 0.16.1

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 (552) hide show
  1. package/README.md +8 -3
  2. package/bin/waygraph +2 -2
  3. package/dist/analysis/check.d.ts +38 -0
  4. package/dist/analysis/check.js +87 -0
  5. package/dist/analysis/coverage-gap.d.ts +1 -1
  6. package/dist/analysis/coverage-gap.js +14 -37
  7. package/dist/analysis/flow-source.d.ts +9 -0
  8. package/dist/analysis/flow-source.js +25 -0
  9. package/dist/analysis/graph.d.ts +10 -14
  10. package/dist/analysis/graph.js +48 -371
  11. package/dist/analysis/map-check.js +4 -39
  12. package/dist/analysis/practices-check.d.ts +1 -1
  13. package/dist/analysis/practices-check.js +24 -45
  14. package/dist/cli/args.d.ts +23 -0
  15. package/dist/cli/args.js +20 -0
  16. package/dist/{cli.d.ts → cli/cli.d.ts} +0 -1
  17. package/dist/{cli.js → cli/cli.js} +10 -9
  18. package/dist/{commands → cli/commands}/agent-dive-scaffold.js +35 -64
  19. package/dist/cli/commands/agent-dive.js +42 -0
  20. package/dist/cli/commands/browser.d.ts +2 -0
  21. package/dist/cli/commands/browser.js +109 -0
  22. package/dist/{commands → cli/commands}/check.d.ts +0 -1
  23. package/dist/cli/commands/check.js +104 -0
  24. package/dist/cli/commands/codemod-checkpoints.d.ts +18 -0
  25. package/dist/cli/commands/codemod-checkpoints.js +186 -0
  26. package/dist/cli/commands/codemod-flows.d.ts +18 -0
  27. package/dist/cli/commands/codemod-flows.js +284 -0
  28. package/dist/cli/commands/codemod-stubs.d.ts +10 -0
  29. package/dist/cli/commands/codemod-stubs.js +187 -0
  30. package/dist/{commands → cli/commands}/extensions.js +5 -4
  31. package/dist/{commands → cli/commands}/init.js +1 -2
  32. package/dist/{commands → cli/commands}/list.js +9 -7
  33. package/dist/cli/commands/manifest.d.ts +2 -0
  34. package/dist/cli/commands/manifest.js +20 -0
  35. package/dist/cli/commands/map.js +57 -0
  36. package/dist/cli/commands/pilot.d.ts +2 -0
  37. package/dist/cli/commands/pilot.js +102 -0
  38. package/dist/{commands → cli/commands}/run.d.ts +0 -1
  39. package/dist/cli/commands/run.js +64 -0
  40. package/dist/cli/commands/session-ops.d.ts +3 -0
  41. package/dist/cli/commands/session-ops.js +257 -0
  42. package/dist/cli/commands/session.js +132 -0
  43. package/dist/{commands → cli/commands}/test.js +11 -14
  44. package/dist/cli/commands/traverse.js +105 -0
  45. package/dist/{commands → cli/commands}/try.js +29 -25
  46. package/dist/{commands → cli/commands}/upgrade.js +40 -4
  47. package/dist/cli/flags.d.ts +193 -16
  48. package/dist/cli/flags.js +179 -234
  49. package/dist/cli/run-chain.d.ts +1 -0
  50. package/dist/cli/run-chain.js +42 -7
  51. package/dist/cli/usage.d.ts +1 -1
  52. package/dist/cli/usage.js +21 -53
  53. package/dist/cli/util.d.ts +2 -2
  54. package/dist/cli/util.js +2 -3
  55. package/dist/{highlights → demo/narration}/css.d.ts +1 -1
  56. package/dist/{highlights → demo/narration}/css.js +2 -3
  57. package/dist/{highlights → demo/narration}/demo-pace.d.ts +4 -12
  58. package/dist/{highlights → demo/narration}/demo-pace.js +5 -11
  59. package/dist/{highlights → demo/narration}/device.d.ts +4 -4
  60. package/dist/{highlights → demo/narration}/device.js +1 -1
  61. package/dist/demo/narration/merge.d.ts +10 -0
  62. package/dist/demo/narration/merge.js +67 -0
  63. package/dist/demo/narration/narration.d.ts +39 -0
  64. package/dist/{highlights/run-phase.js → demo/narration/narration.js} +25 -94
  65. package/dist/{highlights → demo/narration}/shorthand.d.ts +1 -1
  66. package/dist/demo/narration/stub-ctx.d.ts +8 -0
  67. package/dist/demo/narration/stub-ctx.js +164 -0
  68. package/dist/{highlights → demo/narration}/style.d.ts +1 -7
  69. package/dist/{highlights → demo/narration}/style.js +1 -41
  70. package/dist/{highlights → demo/narration}/todo-dock.d.ts +8 -8
  71. package/dist/{highlights → demo/narration}/todo-dock.js +13 -30
  72. package/dist/demo/overlay/auto-chrome.d.ts +7 -0
  73. package/dist/demo/overlay/auto-chrome.js +97 -0
  74. package/dist/demo/overlay/cursor.d.ts +19 -0
  75. package/dist/demo/overlay/cursor.js +142 -0
  76. package/dist/demo/overlay/device-stage.d.ts +26 -0
  77. package/dist/demo/overlay/device-stage.js +396 -0
  78. package/dist/demo/overlay/inpage/banner.d.ts +2 -0
  79. package/dist/demo/overlay/inpage/banner.js +160 -0
  80. package/dist/demo/overlay/inpage/caption.d.ts +2 -0
  81. package/dist/demo/overlay/inpage/caption.js +24 -0
  82. package/dist/demo/overlay/inpage/core.d.ts +2 -0
  83. package/dist/demo/overlay/inpage/core.js +345 -0
  84. package/dist/demo/overlay/inpage/device-chip.d.ts +1 -0
  85. package/dist/demo/overlay/inpage/device-chip.js +191 -0
  86. package/dist/demo/overlay/inpage/network.d.ts +10 -0
  87. package/dist/demo/overlay/inpage/network.js +189 -0
  88. package/dist/demo/overlay/inpage/panel-chrome.d.ts +1 -0
  89. package/dist/demo/overlay/inpage/panel-chrome.js +203 -0
  90. package/dist/demo/overlay/inpage/stamp.d.ts +1 -0
  91. package/dist/demo/overlay/inpage/stamp.js +46 -0
  92. package/dist/demo/overlay/inpage/swipe-zoom.d.ts +1 -0
  93. package/dist/demo/overlay/inpage/swipe-zoom.js +220 -0
  94. package/dist/demo/overlay/inpage/todos.d.ts +2 -0
  95. package/dist/demo/overlay/inpage/todos.js +293 -0
  96. package/dist/demo/overlay/locator-theater.d.ts +25 -0
  97. package/dist/demo/overlay/locator-theater.js +76 -0
  98. package/dist/demo/overlay/network-capture.d.ts +22 -0
  99. package/dist/demo/overlay/network-capture.js +127 -0
  100. package/dist/demo/overlay/overlay-css.d.ts +3 -0
  101. package/dist/demo/overlay/overlay-css.js +369 -0
  102. package/dist/demo/overlay/overlay-stage.d.ts +31 -0
  103. package/dist/demo/overlay/overlay-stage.js +106 -0
  104. package/dist/demo/overlay/overlay.d.ts +10 -0
  105. package/dist/demo/overlay/overlay.js +89 -0
  106. package/dist/{pilot-overlay/overlay-fixtures.d.ts → demo/overlay/phase-fixtures.d.ts} +2 -2
  107. package/dist/{pilot-overlay/overlay-fixtures.js → demo/overlay/phase-fixtures.js} +2 -2
  108. package/dist/{pilot-overlay/action-ring.js → demo/overlay/pilot/actions.js} +2 -1
  109. package/dist/{pilot-overlay → demo/overlay/pilot}/fixtures.d.ts +6 -5
  110. package/dist/{pilot-overlay → demo/overlay/pilot}/fixtures.js +19 -18
  111. package/dist/{pilot-overlay → demo/overlay/pilot}/shell.d.ts +2 -2
  112. package/dist/{pilot-overlay → demo/overlay/pilot}/shell.js +13 -22
  113. package/dist/demo/overlay/reattach.d.ts +7 -0
  114. package/dist/demo/overlay/reattach.js +23 -0
  115. package/dist/demo/overlay/rings.d.ts +61 -0
  116. package/dist/demo/overlay/rings.js +422 -0
  117. package/dist/{ui → demo/overlay/ui}/components/ring.js +2 -2
  118. package/dist/{ui → demo/overlay/ui}/overlay.css +4 -4
  119. package/dist/{ui → demo/overlay/ui}/shadow.d.ts +1 -1
  120. package/dist/{ui → demo/overlay/ui}/shadow.js +39 -2
  121. package/dist/demo/stepper/after.d.ts +3 -0
  122. package/dist/demo/stepper/after.js +103 -0
  123. package/dist/demo/stepper/banner-log.d.ts +35 -0
  124. package/dist/demo/stepper/banner-log.js +65 -0
  125. package/dist/demo/stepper/before.d.ts +4 -0
  126. package/dist/demo/stepper/before.js +110 -0
  127. package/dist/demo/stepper/demo-log.d.ts +48 -0
  128. package/dist/demo/stepper/demo-log.js +292 -0
  129. package/dist/demo/stepper/gate.d.ts +11 -0
  130. package/dist/demo/stepper/gate.js +78 -0
  131. package/dist/demo/stepper/interaction-patch.d.ts +4 -0
  132. package/dist/demo/stepper/interaction-patch.js +323 -0
  133. package/dist/demo/stepper/pacing.d.ts +21 -0
  134. package/dist/demo/stepper/pacing.js +23 -0
  135. package/dist/demo/stepper/panel-after.d.ts +17 -0
  136. package/dist/demo/stepper/panel-after.js +166 -0
  137. package/dist/demo/stepper/panel-before.d.ts +12 -0
  138. package/dist/demo/stepper/panel-before.js +241 -0
  139. package/dist/demo/stepper/slides.d.ts +23 -0
  140. package/dist/demo/stepper/slides.js +233 -0
  141. package/dist/demo/stepper/step-panels.d.ts +69 -0
  142. package/dist/demo/stepper/step-panels.js +172 -0
  143. package/dist/demo/stepper/stepper.d.ts +24 -0
  144. package/dist/demo/stepper/stepper.js +122 -0
  145. package/dist/demo/stepper/teardown.d.ts +47 -0
  146. package/dist/demo/stepper/teardown.js +178 -0
  147. package/dist/demo/stepper/todo-advance.d.ts +15 -0
  148. package/dist/demo/stepper/todo-advance.js +110 -0
  149. package/dist/demo/stepper/view.d.ts +58 -0
  150. package/dist/demo/stepper/view.js +31 -0
  151. package/dist/demo/types.d.ts +85 -0
  152. package/dist/demo/verbose-log.js +15 -0
  153. package/dist/engine/block/action-page.d.ts +53 -0
  154. package/dist/engine/block/action-page.js +1 -0
  155. package/dist/{types.d.ts → engine/block/block.d.ts} +102 -142
  156. package/dist/{core → engine/block}/block.js +12 -130
  157. package/dist/engine/block/branch.d.ts +17 -0
  158. package/dist/engine/block/branch.js +40 -0
  159. package/dist/{core → engine/block}/compose.d.ts +9 -7
  160. package/dist/{core → engine/block}/compose.js +1 -1
  161. package/dist/engine/block/dialog.d.ts +13 -0
  162. package/dist/engine/block/dialog.js +37 -0
  163. package/dist/{core/blocks → engine/block/kinds}/api.d.ts +16 -12
  164. package/dist/{core/blocks → engine/block/kinds}/api.js +26 -18
  165. package/dist/{core/blocks → engine/block/kinds}/effect.d.ts +13 -18
  166. package/dist/engine/block/kinds/effect.js +17 -0
  167. package/dist/{core/blocks → engine/block/kinds}/method.d.ts +17 -29
  168. package/dist/{core/blocks → engine/block/kinds}/method.js +6 -21
  169. package/dist/{core/blocks → engine/block/kinds}/nav.d.ts +21 -31
  170. package/dist/{core/blocks → engine/block/kinds}/nav.js +6 -12
  171. package/dist/{core/blocks → engine/block/kinds}/page.d.ts +14 -20
  172. package/dist/{core/blocks → engine/block/kinds}/page.js +5 -7
  173. package/dist/engine/checkpoint/checkpoint.d.ts +22 -0
  174. package/dist/engine/checkpoint/checkpoint.js +8 -0
  175. package/dist/engine/checkpoint/route.d.ts +28 -0
  176. package/dist/engine/checkpoint/route.js +28 -0
  177. package/dist/{core → engine}/config.d.ts +7 -2
  178. package/dist/engine/config.js +6 -0
  179. package/dist/engine/engine.d.ts +45 -0
  180. package/dist/{core → engine}/engine.js +6 -10
  181. package/dist/engine/env.d.ts +59 -0
  182. package/dist/engine/env.js +83 -0
  183. package/dist/{errors.d.ts → engine/errors.d.ts} +22 -22
  184. package/dist/{errors.js → engine/errors.js} +22 -22
  185. package/dist/{core → engine/flow}/branch-regression.d.ts +7 -7
  186. package/dist/{core → engine/flow}/branch-regression.js +4 -3
  187. package/dist/engine/flow/flow.d.ts +162 -0
  188. package/dist/engine/flow/flow.js +244 -0
  189. package/dist/engine/flow/map-branch.d.ts +9 -0
  190. package/dist/engine/flow/map-branch.js +57 -0
  191. package/dist/{core → engine/flow}/map-builder.d.ts +34 -54
  192. package/dist/engine/flow/map-builder.js +242 -0
  193. package/dist/engine/flow/map-steps.d.ts +30 -0
  194. package/dist/engine/flow/map-steps.js +87 -0
  195. package/dist/{core → engine}/locate.d.ts +1 -1
  196. package/dist/{core → engine}/locate.js +1 -2
  197. package/dist/{mem-stub.d.ts → engine/mem/mem-stub.d.ts} +9 -8
  198. package/dist/{mem-stub.js → engine/mem/mem-stub.js} +2 -2
  199. package/dist/{mem-page.d.ts → engine/mem/mem.d.ts} +1 -1
  200. package/dist/{mem-page.js → engine/mem/mem.js} +2 -1
  201. package/dist/engine/page-gone.d.ts +5 -0
  202. package/dist/engine/page-gone.js +20 -0
  203. package/dist/engine/run/connect.d.ts +28 -0
  204. package/dist/{types.js → engine/run/connect.js} +11 -10
  205. package/dist/engine/run/events.d.ts +67 -0
  206. package/dist/engine/run/events.js +90 -0
  207. package/dist/engine/run/hooks.d.ts +16 -0
  208. package/dist/engine/run/hooks.js +8 -0
  209. package/dist/engine/run/launch.d.ts +13 -0
  210. package/dist/engine/run/launch.js +27 -0
  211. package/dist/{core/run-graph.d.ts → engine/run/run.d.ts} +8 -12
  212. package/dist/{core/run-graph.js → engine/run/run.js} +22 -12
  213. package/dist/engine/stub/pace.d.ts +12 -0
  214. package/dist/engine/stub/pace.js +2 -0
  215. package/dist/engine/stub/ring.d.ts +130 -0
  216. package/dist/engine/stub/ring.js +41 -0
  217. package/dist/engine/stub/stub.d.ts +268 -0
  218. package/dist/engine/stub/stub.js +1 -0
  219. package/dist/engine/stub/todos.d.ts +104 -0
  220. package/dist/engine/stub/todos.js +2 -0
  221. package/dist/engine/stub/viewport.d.ts +26 -0
  222. package/dist/engine/stub/viewport.js +2 -0
  223. package/dist/{trait.d.ts → engine/trait/trait.d.ts} +1 -1
  224. package/dist/{trait.js → engine/trait/trait.js} +1 -1
  225. package/dist/index.d.ts +88 -36
  226. package/dist/index.js +46 -19
  227. package/dist/live/auto/auto.d.ts +22 -0
  228. package/dist/live/auto/auto.js +207 -0
  229. package/dist/{session/auto-explore.d.ts → live/auto/explore.d.ts} +4 -14
  230. package/dist/{session/auto-explore.js → live/auto/explore.js} +21 -127
  231. package/dist/live/auto/mem.d.ts +11 -0
  232. package/dist/live/auto/mem.js +85 -0
  233. package/dist/live/auto/menu.d.ts +30 -0
  234. package/dist/live/auto/menu.js +335 -0
  235. package/dist/live/auto-session/auto-session.d.ts +113 -0
  236. package/dist/live/auto-session/auto-session.js +452 -0
  237. package/dist/live/auto-session/console.d.ts +4 -0
  238. package/dist/live/auto-session/console.js +41 -0
  239. package/dist/live/auto-session/files.d.ts +44 -0
  240. package/dist/live/auto-session/files.js +145 -0
  241. package/dist/{auto-session → live/auto-session}/helpers.d.ts +9 -5
  242. package/dist/{auto-session → live/auto-session}/helpers.js +18 -1
  243. package/dist/live/auto-session/inspect.d.ts +4 -0
  244. package/dist/live/auto-session/inspect.js +75 -0
  245. package/dist/{session/auto-session-ipc.d.ts → live/auto-session/ipc.d.ts} +8 -25
  246. package/dist/{session/auto-session-ipc.js → live/auto-session/ipc.js} +36 -161
  247. package/dist/live/auto-session/open-browser.d.ts +6 -0
  248. package/dist/live/auto-session/open-browser.js +47 -0
  249. package/dist/{session/browser.d.ts → live/auto-session/start.d.ts} +1 -2
  250. package/dist/{session/browser.js → live/auto-session/start.js} +2 -3
  251. package/dist/{pilot-overlay → live/pilot}/panel.d.ts +1 -1
  252. package/dist/{pilot-overlay → live/pilot}/panel.js +23 -31
  253. package/dist/{session → live/pilot}/pilot.d.ts +3 -3
  254. package/dist/{session → live/pilot}/pilot.js +5 -4
  255. package/dist/{traverse/run.d.ts → live/traverse/traverse.d.ts} +1 -1
  256. package/dist/live/traverse/traverse.js +212 -0
  257. package/dist/live/traverse/worker.d.ts +37 -0
  258. package/dist/live/traverse/worker.js +200 -0
  259. package/dist/manifest/manifest.d.ts +52 -0
  260. package/dist/manifest/manifest.js +93 -0
  261. package/dist/manifest/map-imports.d.ts +7 -0
  262. package/dist/manifest/map-imports.js +22 -0
  263. package/dist/manifest/maps.d.ts +33 -0
  264. package/dist/manifest/maps.js +62 -0
  265. package/dist/manifest/pack.d.ts +21 -0
  266. package/dist/manifest/pack.js +109 -0
  267. package/dist/manifest/project.d.ts +60 -0
  268. package/dist/manifest/project.js +101 -0
  269. package/dist/{session/block-inject.js → manifest/roots.js} +1 -18
  270. package/dist/manifest/scan.d.ts +19 -0
  271. package/dist/manifest/scan.js +57 -0
  272. package/dist/manifest/source.d.ts +23 -0
  273. package/dist/manifest/source.js +86 -0
  274. package/dist/runner/mode.d.ts +71 -0
  275. package/dist/runner/mode.js +1 -0
  276. package/dist/runner/modes/branches.d.ts +5 -0
  277. package/dist/runner/modes/branches.js +37 -0
  278. package/dist/runner/modes/demo.d.ts +3 -0
  279. package/dist/runner/modes/demo.js +13 -0
  280. package/dist/runner/modes/report.d.ts +2 -0
  281. package/dist/runner/modes/report.js +54 -0
  282. package/dist/runner/modes/run.d.ts +2 -0
  283. package/dist/runner/modes/run.js +3 -0
  284. package/dist/runner/options.d.ts +31 -0
  285. package/dist/runner/options.js +42 -0
  286. package/dist/runner/plan/find.d.ts +18 -0
  287. package/dist/runner/plan/find.js +65 -0
  288. package/dist/runner/plan/plan.d.ts +11 -0
  289. package/dist/runner/plan/plan.js +97 -0
  290. package/dist/runner/plan/seed-mem.d.ts +12 -0
  291. package/dist/runner/plan/seed-mem.js +98 -0
  292. package/dist/runner/plan/spec.d.ts +5 -0
  293. package/dist/runner/plan/spec.js +17 -0
  294. package/dist/runner/play-steps.d.ts +2 -0
  295. package/dist/runner/play-steps.js +59 -0
  296. package/dist/runner/runner.d.ts +4 -0
  297. package/dist/runner/runner.js +64 -0
  298. package/dist/runner/session.d.ts +9 -0
  299. package/dist/runner/session.js +87 -0
  300. package/dist/{browser.js → runtime/browser.js} +4 -2
  301. package/dist/{env-file.js → runtime/env-file.js} +7 -12
  302. package/dist/{extensions.d.ts → runtime/extensions.d.ts} +1 -5
  303. package/dist/{extensions.js → runtime/extensions.js} +2 -1
  304. package/dist/runtime/full-launch.d.ts +1 -0
  305. package/dist/runtime/full-launch.js +34 -0
  306. package/dist/runtime/global-flag.d.ts +5 -0
  307. package/dist/runtime/global-flag.js +18 -0
  308. package/dist/{playwright-config.d.ts → runtime/playwright-config.d.ts} +1 -1
  309. package/dist/{playwright.config.js → runtime/playwright.config.js} +3 -2
  310. package/dist/runtime/run-log.d.ts +2 -0
  311. package/dist/runtime/run-log.js +17 -0
  312. package/dist/{video-dir.js → runtime/video-dir.js} +3 -2
  313. package/dist/{config.d.ts → runtime/waygraph-config.d.ts} +6 -9
  314. package/dist/{config.js → runtime/waygraph-config.js} +21 -51
  315. package/dist/{webserver.js → runtime/webserver.js} +5 -30
  316. package/examples/routed-demo/config/waygraph.config.ts +20 -0
  317. package/examples/routed-demo/package.json +1 -4
  318. package/examples/routed-demo/scripts/fixture-server.mjs +1 -1
  319. package/examples/routed-demo/src/flows/routed-demo-map.flow.ts +2 -4
  320. package/examples/routed-demo/src/flows/routed-demo.flow.ts +1 -2
  321. package/examples/routed-demo/src/map/(app_base)/dashboard/_methods/click-widget.block.ts +5 -4
  322. package/examples/routed-demo/src/map/(app_base)/dashboard/_nav.block.ts +3 -3
  323. package/examples/routed-demo/src/map/(app_base)/dashboard/_page.block.ts +3 -3
  324. package/examples/routed-demo/src/map/(external)/docs/_nav.block.ts +3 -3
  325. package/examples/routed-demo/src/map/(external)/docs/_page.block.ts +3 -3
  326. package/examples/routed-demo/src/states/routed-demo.states.ts +5 -3
  327. package/examples/routed-demo/tests/routed-demo.spec.ts +4 -4
  328. package/examples/routed-demo/tsconfig.json +1 -1
  329. package/examples/saucedemo/docs/CONVENTION.md +4 -5
  330. package/examples/saucedemo/docs/HELPERS.md +11 -11
  331. package/examples/saucedemo/src/blocks/SITE-MAP.md +0 -1
  332. package/examples/saucedemo/src/blocks/saucedemo-web/NAV.md +1 -5
  333. package/examples/saucedemo/src/blocks/saucedemo-web/cart/nav-cart.block.ts +3 -3
  334. package/examples/saucedemo/src/blocks/saucedemo-web/cart/nav-checkout-info.block.ts +3 -3
  335. package/examples/saucedemo/src/blocks/saucedemo-web/checkout-step-one/methods/fill-first-name.method.block.ts +5 -4
  336. package/examples/saucedemo/src/blocks/saucedemo-web/checkout-step-one/methods/fill-last-name.method.block.ts +5 -4
  337. package/examples/saucedemo/src/blocks/saucedemo-web/checkout-step-one/methods/fill-postal-code.method.block.ts +5 -4
  338. package/examples/saucedemo/src/blocks/saucedemo-web/checkout-step-one/methods/submit-checkout-info.method.block.ts +5 -4
  339. package/examples/saucedemo/src/blocks/saucedemo-web/checkout-step-two/methods/finish-order.method.block.ts +5 -8
  340. package/examples/saucedemo/src/blocks/saucedemo-web/inventory/inventory.page.block.ts +3 -3
  341. package/examples/saucedemo/src/blocks/saucedemo-web/inventory/methods/add-all-to-cart.method.block.ts +4 -6
  342. package/examples/saucedemo/src/blocks/saucedemo-web/inventory/methods/add-to-cart.effect.block.ts +35 -43
  343. package/examples/saucedemo/src/blocks/saucedemo-web/inventory/methods/remove-all-from-cart.method.block.ts +4 -6
  344. package/examples/saucedemo/src/blocks/saucedemo-web/inventory/methods/remove-from-cart.effect.block.ts +4 -3
  345. package/examples/saucedemo/src/blocks/saucedemo-web/inventory/nav-item-detail.block.ts +3 -3
  346. package/examples/saucedemo/src/blocks/saucedemo-web/inventory-item/nav-back-to-inventory.block.ts +3 -3
  347. package/examples/saucedemo/src/blocks/saucedemo-web/inventory-item/nav-back-to-products.block.ts +3 -3
  348. package/examples/saucedemo/src/blocks/saucedemo-web/inventory-item/nav-continue-shopping.block.ts +3 -3
  349. package/examples/saucedemo/src/blocks/saucedemo-web/methods/fill-password.method.block.ts +5 -4
  350. package/examples/saucedemo/src/blocks/saucedemo-web/methods/fill-username.method.block.ts +5 -4
  351. package/examples/saucedemo/src/blocks/saucedemo-web/methods/submit-login.method.block.ts +4 -5
  352. package/examples/saucedemo/src/blocks/saucedemo-web/methods/submit-logout.method.block.ts +5 -4
  353. package/examples/saucedemo/src/blocks/saucedemo-web/nav-login.block.ts +3 -3
  354. package/examples/saucedemo/src/flows/api-demo.flow.ts +12 -10
  355. package/examples/saucedemo/src/states/checkout.states.ts +21 -11
  356. package/examples/saucedemo/src/stubs/device-showcase.ts +8 -10
  357. package/examples/saucedemo/tests/auto-graph.spec.ts +4 -12
  358. package/package.json +14 -6
  359. package/templates/agents/waygraph-planner.agent.md +2 -2
  360. package/templates/quickstart/docs/CONVENTION.md +4 -4
  361. package/templates/quickstart/docs/HELPERS.md +10 -8
  362. package/templates/quickstart/package.json +0 -3
  363. package/templates/quickstart/src/blocks/SITE-MAP.md +0 -1
  364. package/templates/quickstart/src/blocks/saucedemo-web/NAV.md +1 -5
  365. package/templates/quickstart/src/blocks/saucedemo-web/cart/nav-cart.block.ts +3 -3
  366. package/templates/quickstart/src/blocks/saucedemo-web/cart/nav-checkout-info.block.ts +3 -3
  367. package/templates/quickstart/src/blocks/saucedemo-web/checkout-step-one/methods/fill-first-name.method.block.ts +5 -4
  368. package/templates/quickstart/src/blocks/saucedemo-web/checkout-step-one/methods/fill-last-name.method.block.ts +5 -4
  369. package/templates/quickstart/src/blocks/saucedemo-web/checkout-step-one/methods/fill-postal-code.method.block.ts +5 -4
  370. package/templates/quickstart/src/blocks/saucedemo-web/checkout-step-one/methods/submit-checkout-info.method.block.ts +5 -4
  371. package/templates/quickstart/src/blocks/saucedemo-web/checkout-step-two/methods/finish-order.method.block.ts +5 -8
  372. package/templates/quickstart/src/blocks/saucedemo-web/inventory/inventory.page.block.ts +3 -3
  373. package/templates/quickstart/src/blocks/saucedemo-web/inventory/methods/add-all-to-cart.method.block.ts +4 -6
  374. package/templates/quickstart/src/blocks/saucedemo-web/inventory/methods/add-to-cart.effect.block.ts +35 -43
  375. package/templates/quickstart/src/blocks/saucedemo-web/inventory/methods/remove-all-from-cart.method.block.ts +4 -6
  376. package/templates/quickstart/src/blocks/saucedemo-web/inventory/methods/remove-from-cart.effect.block.ts +4 -3
  377. package/templates/quickstart/src/blocks/saucedemo-web/inventory/nav-item-detail.block.ts +3 -3
  378. package/templates/quickstart/src/blocks/saucedemo-web/inventory-item/nav-back-to-inventory.block.ts +3 -3
  379. package/templates/quickstart/src/blocks/saucedemo-web/inventory-item/nav-back-to-products.block.ts +3 -3
  380. package/templates/quickstart/src/blocks/saucedemo-web/inventory-item/nav-continue-shopping.block.ts +3 -3
  381. package/templates/quickstart/src/blocks/saucedemo-web/methods/fill-password.method.block.ts +5 -4
  382. package/templates/quickstart/src/blocks/saucedemo-web/methods/fill-username.method.block.ts +5 -4
  383. package/templates/quickstart/src/blocks/saucedemo-web/methods/submit-login.method.block.ts +4 -5
  384. package/templates/quickstart/src/blocks/saucedemo-web/methods/submit-logout.method.block.ts +5 -4
  385. package/templates/quickstart/src/blocks/saucedemo-web/nav-login.block.ts +3 -3
  386. package/templates/quickstart/src/flows/api-demo.flow.ts +12 -10
  387. package/templates/quickstart/src/states/checkout.states.ts +21 -11
  388. package/templates/quickstart/src/stubs/device-showcase.ts +8 -10
  389. package/templates/scaffold/README.md +2 -1
  390. package/templates/scaffold/STRUCTURE.md +5 -4
  391. package/templates/scaffold/config/waygraph.config.ts +1 -0
  392. package/templates/scaffold/gitignore +1 -0
  393. package/templates/scaffold/src/flows/README.md +2 -2
  394. package/templates/scaffold/src/map/(app_base)/docs/_nav.block.ts +3 -3
  395. package/templates/scaffold/src/map/(app_base)/docs/_page.block.ts +3 -3
  396. package/templates/scaffold/src/map/(app_base)/home/_methods/add-item.effect.block.ts +4 -4
  397. package/templates/scaffold/src/map/(app_base)/home/_methods/assert-hello.method.block.ts +3 -3
  398. package/templates/scaffold/src/map/(app_base)/home/_methods/assert-item-added.method.block.ts +3 -3
  399. package/templates/scaffold/src/map/(app_base)/home/_methods/clear-cart.method.block.ts +5 -4
  400. package/templates/scaffold/src/map/(app_base)/home/_methods/remove-item.effect.block.ts +4 -4
  401. package/templates/scaffold/src/map/(app_base)/home/_nav.block.ts +3 -3
  402. package/templates/scaffold/src/map/(app_base)/home/_page.block.ts +3 -3
  403. package/templates/scaffold/src/map/(app_base)/home/nav-verification-link.block.ts +4 -4
  404. package/templates/scaffold/src/map/(external)/hoppscotch/_keys.ts +21 -0
  405. package/templates/scaffold/src/map/(external)/hoppscotch/_methods/assert-response-body.method.block.ts +4 -4
  406. package/templates/scaffold/src/map/(external)/hoppscotch/_methods/assert-response-header.method.block.ts +4 -4
  407. package/templates/scaffold/src/map/(external)/hoppscotch/_methods/assert-status.method.block.ts +4 -4
  408. package/templates/scaffold/src/map/(external)/hoppscotch/_methods/pick-extension-interceptor.method.block.ts +5 -4
  409. package/templates/scaffold/src/map/(external)/hoppscotch/_methods/read-response-body.method.block.ts +6 -5
  410. package/templates/scaffold/src/map/(external)/hoppscotch/_methods/read-response-headers.method.block.ts +6 -5
  411. package/templates/scaffold/src/map/(external)/hoppscotch/_methods/send-request.method.block.ts +5 -4
  412. package/templates/scaffold/src/map/(external)/hoppscotch/_methods/set-bearer-token.method.block.ts +6 -5
  413. package/templates/scaffold/src/map/(external)/hoppscotch/_methods/set-headers.method.block.ts +6 -5
  414. package/templates/scaffold/src/map/(external)/hoppscotch/_methods/set-json-body.method.block.ts +6 -5
  415. package/templates/scaffold/src/map/(external)/hoppscotch/_methods/set-method.method.block.ts +6 -5
  416. package/templates/scaffold/src/map/(external)/hoppscotch/_methods/set-query-params.method.block.ts +6 -5
  417. package/templates/scaffold/src/map/(external)/hoppscotch/_methods/set-url.method.block.ts +6 -5
  418. package/templates/scaffold/src/map/(external)/hoppscotch/_nav.block.ts +3 -3
  419. package/templates/scaffold/src/map/(external)/hoppscotch/_page.block.ts +3 -3
  420. package/templates/scaffold/src/map/(external)/hoppscotch/_states.ts +6 -0
  421. package/templates/scaffold/src/map/(external)/hoppscotch/settings/_nav.block.ts +3 -3
  422. package/templates/scaffold/src/map/(external)/mailpit/_keys.ts +13 -0
  423. package/templates/scaffold/src/map/(external)/mailpit/_methods/assert-email-content.method.block.ts +4 -4
  424. package/templates/scaffold/src/map/(external)/mailpit/_methods/assert-email-received.method.block.ts +4 -4
  425. package/templates/scaffold/src/map/(external)/mailpit/_methods/extract-email-link.method.block.ts +6 -5
  426. package/templates/scaffold/src/map/(external)/mailpit/_methods/open-message.method.block.ts +6 -5
  427. package/templates/scaffold/src/map/(external)/mailpit/_nav.block.ts +3 -3
  428. package/templates/scaffold/src/map/(external)/mailpit/_page.block.ts +3 -3
  429. package/templates/scaffold/src/map/(external)/mailpit/_states.ts +9 -0
  430. package/templates/scaffold/src/map/README.md +7 -0
  431. package/templates/scaffold/src/states/README.md +4 -1
  432. package/templates/scaffold/src/states/demo.mem-keys.ts +1 -29
  433. package/templates/scaffold/src/states/demo.states.ts +14 -20
  434. package/templates/scaffold/tests/hoppscotch.spec.ts +1 -11
  435. package/templates/scaffold/tests/mail-verify.spec.ts +2 -2
  436. package/templates/skills/waygraph-blind-pilot.skill.md +2 -6
  437. package/templates/skills/waygraph-convention.skill.md +23 -14
  438. package/templates/skills/waygraph-pilot.skill.md +7 -4
  439. package/dist/auto-session/session.d.ts +0 -193
  440. package/dist/auto-session/session.js +0 -719
  441. package/dist/auto-session/verbose-log.js +0 -16
  442. package/dist/auto-session.d.ts +0 -2
  443. package/dist/auto-session.js +0 -3
  444. package/dist/cli/discover.d.ts +0 -40
  445. package/dist/cli/discover.js +0 -148
  446. package/dist/commands/agent-dive.js +0 -52
  447. package/dist/commands/check.js +0 -192
  448. package/dist/commands/map.js +0 -29
  449. package/dist/commands/run.js +0 -104
  450. package/dist/commands/session.js +0 -600
  451. package/dist/commands/traverse.js +0 -177
  452. package/dist/core/block.d.ts +0 -109
  453. package/dist/core/blocks/effect.js +0 -23
  454. package/dist/core/config.js +0 -17
  455. package/dist/core/engine.d.ts +0 -198
  456. package/dist/core/flow.d.ts +0 -294
  457. package/dist/core/flow.js +0 -432
  458. package/dist/core/map-builder.js +0 -383
  459. package/dist/core.d.ts +0 -14
  460. package/dist/core.js +0 -15
  461. package/dist/highlights/merge.d.ts +0 -8
  462. package/dist/highlights/merge.js +0 -173
  463. package/dist/highlights/run-phase.d.ts +0 -43
  464. package/dist/highlights/stub-ctx.d.ts +0 -10
  465. package/dist/highlights/stub-ctx.js +0 -331
  466. package/dist/highlights/types.d.ts +0 -613
  467. package/dist/highlights.d.ts +0 -9
  468. package/dist/highlights.js +0 -10
  469. package/dist/pilot-overlay.d.ts +0 -5
  470. package/dist/pilot-overlay.js +0 -6
  471. package/dist/runner/banner-log.js +0 -63
  472. package/dist/runner/chain-run.js +0 -102
  473. package/dist/runner/cursor.js +0 -140
  474. package/dist/runner/demo-log.js +0 -316
  475. package/dist/runner/device-stage.d.ts +0 -9
  476. package/dist/runner/device-stage.js +0 -420
  477. package/dist/runner/discovery.js +0 -105
  478. package/dist/runner/index.js +0 -2
  479. package/dist/runner/inpage/banner.d.ts +0 -21
  480. package/dist/runner/inpage/banner.js +0 -156
  481. package/dist/runner/inpage/caption.d.ts +0 -3
  482. package/dist/runner/inpage/caption.js +0 -23
  483. package/dist/runner/inpage/core.d.ts +0 -4
  484. package/dist/runner/inpage/core.js +0 -316
  485. package/dist/runner/inpage/device.d.ts +0 -3
  486. package/dist/runner/inpage/device.js +0 -211
  487. package/dist/runner/inpage/network.d.ts +0 -15
  488. package/dist/runner/inpage/network.js +0 -217
  489. package/dist/runner/inpage/panel-chrome.js +0 -192
  490. package/dist/runner/inpage/stamp.js +0 -46
  491. package/dist/runner/inpage/swipe-zoom.js +0 -220
  492. package/dist/runner/inpage/todos.js +0 -337
  493. package/dist/runner/interaction-patch.js +0 -384
  494. package/dist/runner/main.js +0 -469
  495. package/dist/runner/network-capture.d.ts +0 -9
  496. package/dist/runner/network-capture.js +0 -126
  497. package/dist/runner/overlay-css.d.ts +0 -3
  498. package/dist/runner/overlay-css.js +0 -377
  499. package/dist/runner/overlay-install.js +0 -90
  500. package/dist/runner/overlay-stage.js +0 -110
  501. package/dist/runner/rings.js +0 -514
  502. package/dist/runner/seed-mem.js +0 -110
  503. package/dist/runner/slides.js +0 -278
  504. package/dist/runner/step-mode.js +0 -703
  505. package/dist/runner/step-panels.js +0 -729
  506. package/dist/runner/teardown.js +0 -202
  507. package/dist/runner/todo-dock.js +0 -142
  508. package/dist/session/auto-explore-run.d.ts +0 -40
  509. package/dist/session/auto-explore-run.js +0 -707
  510. package/dist/session/step-overlay.d.ts +0 -37
  511. package/dist/session/step-overlay.js +0 -244
  512. package/dist/traverse/run.js +0 -423
  513. package/examples/routed-demo/playwright.config.ts +0 -21
  514. package/examples/saucedemo/src/blocks/saucedemo-web/ff-owner-auth.block.ts +0 -22
  515. package/templates/quickstart/src/blocks/saucedemo-web/ff-owner-auth.block.ts +0 -22
  516. /package/dist/{commands → cli/commands}/agent-dive-scaffold.d.ts +0 -0
  517. /package/dist/{commands → cli/commands}/agent-dive.d.ts +0 -0
  518. /package/dist/{commands → cli/commands}/extensions.d.ts +0 -0
  519. /package/dist/{commands → cli/commands}/init.d.ts +0 -0
  520. /package/dist/{commands → cli/commands}/list.d.ts +0 -0
  521. /package/dist/{commands → cli/commands}/map.d.ts +0 -0
  522. /package/dist/{commands → cli/commands}/session.d.ts +0 -0
  523. /package/dist/{commands → cli/commands}/test.d.ts +0 -0
  524. /package/dist/{commands → cli/commands}/traverse.d.ts +0 -0
  525. /package/dist/{commands → cli/commands}/try.d.ts +0 -0
  526. /package/dist/{commands → cli/commands}/upgrade.d.ts +0 -0
  527. /package/dist/{highlights → demo/narration}/shorthand.js +0 -0
  528. /package/dist/{session/overlay-beacon.d.ts → demo/overlay/beacon.d.ts} +0 -0
  529. /package/dist/{session/overlay-beacon.js → demo/overlay/beacon.js} +0 -0
  530. /package/dist/{pilot-overlay/action-ring.d.ts → demo/overlay/pilot/actions.d.ts} +0 -0
  531. /package/dist/{ui → demo/overlay/ui}/components/ring.d.ts +0 -0
  532. /package/dist/{ui → demo/overlay/ui}/stylesheet.d.ts +0 -0
  533. /package/dist/{ui → demo/overlay/ui}/stylesheet.js +0 -0
  534. /package/dist/{ui → demo/overlay/ui}/tokens.d.ts +0 -0
  535. /package/dist/{ui → demo/overlay/ui}/tokens.js +0 -0
  536. /package/dist/{highlights → demo}/types.js +0 -0
  537. /package/dist/{auto-session → demo}/verbose-log.d.ts +0 -0
  538. /package/dist/{selector.d.ts → engine/trait/selector.d.ts} +0 -0
  539. /package/dist/{selector.js → engine/trait/selector.js} +0 -0
  540. /package/dist/{traverse → live/traverse}/coverage.d.ts +0 -0
  541. /package/dist/{traverse → live/traverse}/coverage.js +0 -0
  542. /package/dist/{traverse → live/traverse}/lease.d.ts +0 -0
  543. /package/dist/{traverse → live/traverse}/lease.js +0 -0
  544. /package/dist/{session/block-inject.d.ts → manifest/roots.d.ts} +0 -0
  545. /package/dist/{blocks-select.d.ts → manifest/select.d.ts} +0 -0
  546. /package/dist/{blocks-select.js → manifest/select.js} +0 -0
  547. /package/dist/{browser.d.ts → runtime/browser.d.ts} +0 -0
  548. /package/dist/{env-file.d.ts → runtime/env-file.d.ts} +0 -0
  549. /package/dist/{playwright-config.js → runtime/playwright-config.js} +0 -0
  550. /package/dist/{playwright.config.d.ts → runtime/playwright.config.d.ts} +0 -0
  551. /package/dist/{video-dir.d.ts → runtime/video-dir.d.ts} +0 -0
  552. /package/dist/{webserver.d.ts → runtime/webserver.d.ts} +0 -0
@@ -0,0 +1,12 @@
1
+ import type { MemPage } from "../../engine/mem/mem.js";
2
+ import type { BlockInfo } from "../../engine/flow/flow.js";
3
+ import type { FoundBlock } from "./find.js";
4
+ export declare function seedMemForBlock(mem: MemPage, resolved: FoundBlock, json: string | undefined, stubActive: boolean): void;
5
+ /**
6
+ * Same idea as seedMemForBlock, but for a whole Flow segment
7
+ * ("loginFlow({...}) then ...") - a Flow has no single .requires of its
8
+ * own, so this unions every constituent Block's requires (deduped by key
9
+ * name) and seeds them all from one JSON payload, same keyed-by-name shape
10
+ * as a multi-key Block payload already uses.
11
+ */
12
+ export declare function seedMemForFlow(mem: MemPage, flowBlocks: readonly BlockInfo[], json: string | undefined, label: string, stubActive: boolean): void;
@@ -0,0 +1,98 @@
1
+ import { getMemStub } from "../../engine/mem/mem-stub.js";
2
+ import { envString } from "../../engine/env.js";
3
+ const isRecord = (v) => v !== null && typeof v === "object" && !Array.isArray(v);
4
+ function seedMemFromRequires(mem, requires, json, label, stubActive) {
5
+ if (requires.length === 0) {
6
+ if (json !== undefined) {
7
+ throw new Error("waygraph chain: \"" + label + "\" takes no input (empty requires) but got a payload: " + json);
8
+ }
9
+ return;
10
+ }
11
+ if (json === undefined) {
12
+ // --data / WAYGRAPH_DATA supplies the same payload shape as blockName({...}).
13
+ const fromEnv = envString("WAYGRAPH_DATA");
14
+ if (fromEnv && fromEnv.trim())
15
+ json = fromEnv;
16
+ }
17
+ let parsed;
18
+ let haveParsed = false;
19
+ if (json !== undefined) {
20
+ try {
21
+ parsed = JSON.parse(json);
22
+ haveParsed = true;
23
+ }
24
+ catch (err) {
25
+ throw new Error("waygraph chain: \"" + label + "\" payload is not valid JSON - " + String(err));
26
+ }
27
+ }
28
+ if (!haveParsed) {
29
+ // No payload at all - only a hard failure when memStub isn't active for
30
+ // this flow; when it is, fall through with an empty object so the
31
+ // per-key loop below gets a chance to fill each one from the registry.
32
+ if (!stubActive) {
33
+ throw new Error("waygraph chain: \"" + label + "\" requires " + requires.map((k) => k.name).join(", ") +
34
+ " - give a JSON payload (inline blockName({...}) or --data '{...}'), or enable --mem-stub" +
35
+ " with registerMemStub for these keys");
36
+ }
37
+ parsed = {};
38
+ }
39
+ // Keyed-by-name when every require name is a top-level key (preferred for
40
+ // --data and for {"saucedemo.credentials":{...}} even with one require).
41
+ if (isRecord(parsed)) {
42
+ const payload = parsed;
43
+ if (requires.every((k) => k.name in payload)) {
44
+ for (const k of requires)
45
+ mem.set(k, payload[k.name]);
46
+ return;
47
+ }
48
+ }
49
+ // Single-key shorthand: the whole payload IS that one key's value - only
50
+ // when a real payload was actually given (the stub-only "{}" fallback
51
+ // above must fall through to per-key stub resolution instead).
52
+ if (haveParsed && requires.length === 1) {
53
+ mem.set(requires[0], parsed);
54
+ return;
55
+ }
56
+ if (!isRecord(parsed)) {
57
+ throw new Error("waygraph chain: \"" + label + "\" requires " + requires.length + " keys (" +
58
+ requires.map((k) => k.name).join(", ") + ") - payload must be an object keyed by each key's name");
59
+ }
60
+ const payload = parsed;
61
+ const stillMissing = [];
62
+ for (const k of requires) {
63
+ if (k.name in payload) {
64
+ mem.set(k, payload[k.name]);
65
+ continue;
66
+ }
67
+ const fake = stubActive ? getMemStub(k) : undefined;
68
+ if (fake) {
69
+ mem.set(k, fake());
70
+ continue;
71
+ }
72
+ stillMissing.push(k);
73
+ }
74
+ if (stillMissing.length > 0) {
75
+ throw new Error("waygraph chain: \"" + label + "\" payload is missing required key(s): " +
76
+ stillMissing.map((k) => "\"" + k.name + "\"").join(", "));
77
+ }
78
+ }
79
+ export function seedMemForBlock(mem, resolved, json, stubActive) {
80
+ seedMemFromRequires(mem, resolved.block.requires ?? [], json, resolved.exportName, stubActive);
81
+ }
82
+ /**
83
+ * Same idea as seedMemForBlock, but for a whole Flow segment
84
+ * ("loginFlow({...}) then ...") - a Flow has no single .requires of its
85
+ * own, so this unions every constituent Block's requires (deduped by key
86
+ * name) and seeds them all from one JSON payload, same keyed-by-name shape
87
+ * as a multi-key Block payload already uses.
88
+ */
89
+ export function seedMemForFlow(mem, flowBlocks, json, label, stubActive) {
90
+ const seen = new Map();
91
+ for (const bi of flowBlocks) {
92
+ for (const k of bi.block.requires ?? []) {
93
+ if (!seen.has(k.name))
94
+ seen.set(k.name, k);
95
+ }
96
+ }
97
+ seedMemFromRequires(mem, Array.from(seen.values()), json, label, stubActive);
98
+ }
@@ -0,0 +1,5 @@
1
+ /** Splits a spec into segments, each a Block or Flow name with optional inline JSON for its mem. */
2
+ export declare function parseChainSpec(spec: string): {
3
+ ref: string;
4
+ json?: string;
5
+ }[];
@@ -0,0 +1,17 @@
1
+ // The CLI chain spec: "login then addToCart({...json...}) then checkoutFlow".
2
+ /** Splits a spec into segments, each a Block or Flow name with optional inline JSON for its mem. */
3
+ export function parseChainSpec(spec) {
4
+ return spec
5
+ .split(/\bthen\b/)
6
+ .map((s) => s.trim())
7
+ .filter((s) => s.length > 0)
8
+ .map((s) => {
9
+ const m = /^([A-Za-z_$][\w-]*)\s*(?:\(([\s\S]*)\))?$/.exec(s);
10
+ if (!m) {
11
+ throw new Error("waygraph chain: could not parse segment \"" + s + "\" - expected \"blockName\" or \"blockName({...json...})\"");
12
+ }
13
+ const ref = m[1];
14
+ const json = m[2] ? m[2].trim() : undefined;
15
+ return json ? { ref, json } : { ref };
16
+ });
17
+ }
@@ -0,0 +1,2 @@
1
+ import type { Mode, PlayOutcome, PlaySession, PlayStep } from "./mode.js";
2
+ export declare function playSteps(steps: readonly PlayStep[], session: PlaySession, mode: Mode, clearSession: boolean): Promise<PlayOutcome>;
@@ -0,0 +1,59 @@
1
+ import { buildFlow } from "../engine/flow/flow.js";
2
+ import { resetPage } from "./session.js";
3
+ /** Where a "retry" goes back to: the first step of this step's episode, or the start of an ad hoc chain. */
4
+ function episodeStart(steps, index) {
5
+ const episode = steps[index].episodeNumber;
6
+ return episode === undefined ? 0 : steps.findIndex((s) => s.episodeNumber === episode);
7
+ }
8
+ /** Runs one Block through the engine, on the session's page, with its own flow's config. */
9
+ async function runStep(step, session) {
10
+ const flow = buildFlow([step.block], step.config);
11
+ const { result } = await flow.run(session.context, session.mem, { page: session.page, closeOnFinish: false });
12
+ return result;
13
+ }
14
+ export async function playSteps(steps, session, mode, clearSession) {
15
+ await mode.begin?.(steps);
16
+ let outcome = { ok: true };
17
+ for (let i = 0; i < steps.length; i++) {
18
+ const step = steps[i];
19
+ // A segment's --data is seeded when it starts, so two segments can give the same key different values.
20
+ step.seedMem?.();
21
+ if ((clearSession || step.resetSession) && i > 0) {
22
+ await resetPage(session);
23
+ await mode.afterReset?.();
24
+ }
25
+ await mode.before?.(i);
26
+ const startedAt = Date.now();
27
+ let result;
28
+ try {
29
+ result = await runStep(step, session);
30
+ }
31
+ catch (error) {
32
+ if ((await mode.failed?.(i, { error }, Date.now() - startedAt)) === "retry") {
33
+ await resetPage(session);
34
+ await mode.afterReset?.();
35
+ i = episodeStart(steps, i) - 1;
36
+ continue;
37
+ }
38
+ outcome = step.expectedFailureReason
39
+ ? { ok: true, expectedFailure: { step, reason: step.expectedFailureReason } }
40
+ : { ok: false, failedAt: { index: i, step, error } };
41
+ break;
42
+ }
43
+ outcome = { ok: true, result };
44
+ // A flow meant to fail can also end on its failure branch without throwing (a login that stays on the login page).
45
+ if (step.expectedFailureReason) {
46
+ if ((await mode.failed?.(i, { result }, Date.now() - startedAt)) === "retry") {
47
+ await resetPage(session);
48
+ await mode.afterReset?.();
49
+ i = episodeStart(steps, i) - 1;
50
+ continue;
51
+ }
52
+ outcome = { ok: true, result, expectedFailure: { step, reason: step.expectedFailureReason } };
53
+ break;
54
+ }
55
+ await mode.after?.(i, result, Date.now() - startedAt);
56
+ }
57
+ await mode.end?.(outcome);
58
+ return outcome;
59
+ }
@@ -0,0 +1,4 @@
1
+ import "../runtime/run-log.js";
2
+ export declare function play(projectDir: string, spec: string): Promise<void>;
3
+ /** The process entry the CLI's bootstrap calls: one run (and one run log) per invocation. */
4
+ export declare function startRunner(): void;
@@ -0,0 +1,64 @@
1
+ // How `waygraph run` and `waygraph demo` play a flow. The CLI spawns this inside the project (so the project's own
2
+ // Playwright is used) with the project dir and the spec ("cartFlow", "loginFlow then add-item"). Every mode plays the
3
+ // same steps through the same engine; the mode decides what happens around each step.
4
+ import { MemPage } from "../engine/mem/mem.js";
5
+ import { beginRun, endRun } from "../engine/run/events.js";
6
+ import { withWebServer } from "../runtime/webserver.js";
7
+ import "../runtime/run-log.js";
8
+ import { planSteps } from "./plan/plan.js";
9
+ import { readOptions, slowMoFor } from "./options.js";
10
+ import { openSession } from "./session.js";
11
+ import { playSteps } from "./play-steps.js";
12
+ import { playBranches } from "./modes/branches.js";
13
+ import { runMode } from "./modes/run.js";
14
+ import { demoMode } from "./modes/demo.js";
15
+ import { reportMode } from "./modes/report.js";
16
+ export async function play(projectDir, spec) {
17
+ const options = readOptions();
18
+ const mem = new MemPage();
19
+ const { steps, flows } = await planSteps(projectDir, spec, mem, options);
20
+ if (options.mode === "branches")
21
+ return playBranches(flows, mem, options);
22
+ const slowMo = slowMoFor(options, steps);
23
+ const { session, close } = await openSession(projectDir, options, mem, slowMo.launch);
24
+ let outcome;
25
+ try {
26
+ const mode = await pickMode(options, session, steps, slowMo.demoBeat);
27
+ outcome = await playSteps(steps, session, mode, options.clearSession);
28
+ }
29
+ finally {
30
+ await close();
31
+ }
32
+ if (options.mode !== "report")
33
+ finish(outcome);
34
+ }
35
+ function pickMode(options, session, steps, demoBeat) {
36
+ if (options.mode === "demo")
37
+ return demoMode(session, steps, options, demoBeat);
38
+ if (options.mode === "report")
39
+ return reportMode(session);
40
+ return runMode();
41
+ }
42
+ function finish(outcome) {
43
+ if (outcome.failedAt)
44
+ throw outcome.failedAt.error;
45
+ if (outcome.expectedFailure) {
46
+ const { step, reason } = outcome.expectedFailure;
47
+ console.log(`waygraph: chain finished (expected failure on ${step.block.name}) -- ${reason}`);
48
+ }
49
+ else {
50
+ console.log("waygraph: chain finished -- " + JSON.stringify(outcome.result));
51
+ }
52
+ }
53
+ /** The process entry the CLI's bootstrap calls: one run (and one run log) per invocation. */
54
+ export function startRunner() {
55
+ const projectDir = process.argv[2] ?? process.cwd();
56
+ const spec = process.argv[3] ?? "";
57
+ const opened = beginRun(spec);
58
+ withWebServer(projectDir, () => play(projectDir, spec))
59
+ .then(() => endRun(opened, {}), (err) => {
60
+ endRun(opened, { error: err });
61
+ console.error(err && err.stack ? err.stack : String(err));
62
+ process.exitCode = 1;
63
+ });
64
+ }
@@ -0,0 +1,9 @@
1
+ import type { MemPage } from "../engine/mem/mem.js";
2
+ import type { PlaySession } from "./mode.js";
3
+ import type { PlayOptions } from "./options.js";
4
+ export declare function openSession(projectDir: string, options: PlayOptions, mem: MemPage, launchSlowMo: number | undefined): Promise<{
5
+ session: PlaySession;
6
+ close: () => Promise<void>;
7
+ }>;
8
+ /** A fresh session between episodes: no cookies, no storage, back on the base URL (so the page itself looks fresh too). */
9
+ export declare function resetPage(session: PlaySession): Promise<void>;
@@ -0,0 +1,87 @@
1
+ // The browser a run plays in: launched with the project's extensions, sized for the mode and an optional video.
2
+ import { mkdirSync } from "node:fs";
3
+ import { recordArtifact } from "../engine/run/events.js";
4
+ import { chromiumExecutablePath, extensionPathsFromEnv, launchContext } from "../runtime/browser.js";
5
+ import { resolveVideoDir } from "../runtime/video-dir.js";
6
+ import { ignorePageGone } from "../engine/page-gone.js";
7
+ /** WAYGRAPH_VIDEO_VIEWPORT / --video-viewport: "1920x1080" or "1920,1080". */
8
+ function parseVideoViewport(raw) {
9
+ const m = raw?.trim().match(/^(\d{3,5})[xX,](\d{3,5})$/);
10
+ if (!m)
11
+ return null;
12
+ const width = Number(m[1]);
13
+ const height = Number(m[2]);
14
+ if (width < 320 || height < 240 || width > 7680 || height > 4320)
15
+ return null;
16
+ return { width, height };
17
+ }
18
+ /**
19
+ * A demo window fills the screen (viewport null, maximized). A video is a fixed 16:9 capture (1920x1080 for a demo,
20
+ * 1280x720 for a run) with the device scale locked, so the recording keeps that size on HiDPI hosts.
21
+ */
22
+ function viewportFor(options, videoSize) {
23
+ if (videoSize)
24
+ return { viewport: videoSize, deviceScaleFactor: 1 };
25
+ return options.mode === "demo" ? { viewport: null } : { viewport: { width: 1280, height: 720 } };
26
+ }
27
+ export async function openSession(projectDir, options, mem, launchSlowMo) {
28
+ const videoDir = options.video ? (options.video === "1" ? await resolveVideoDir(projectDir) : options.video) : null;
29
+ if (videoDir)
30
+ mkdirSync(videoDir, { recursive: true });
31
+ const videoSize = videoDir
32
+ ? (parseVideoViewport(options.videoViewport) ?? (options.mode === "demo" ? { width: 1920, height: 1080 } : { width: 1280, height: 720 }))
33
+ : null;
34
+ const { chromium } = await import("@playwright/test");
35
+ const executablePath = chromiumExecutablePath();
36
+ const { context, close: closeBrowser } = await launchContext({
37
+ launcher: chromium,
38
+ launch: {
39
+ headless: !options.headed,
40
+ ...(launchSlowMo !== undefined ? { slowMo: launchSlowMo } : {}),
41
+ args: options.mode === "demo" || videoSize ? ["--start-maximized"] : [],
42
+ ...(executablePath ? { executablePath } : {}),
43
+ },
44
+ context: {
45
+ ...(options.baseURL ? { baseURL: options.baseURL } : {}),
46
+ hasTouch: true,
47
+ ...viewportFor(options, videoSize),
48
+ ...(videoDir ? { recordVideo: videoSize ? { dir: videoDir, size: videoSize } : { dir: videoDir } } : {}),
49
+ },
50
+ extensions: extensionPathsFromEnv(),
51
+ });
52
+ const page = (await context.newPage());
53
+ if (videoSize)
54
+ page.__wgVideoViewport = videoSize;
55
+ // The first step's panel shows over the real app, not a blank page.
56
+ if (options.baseURL)
57
+ await page.goto(options.baseURL).catch(ignorePageGone);
58
+ const close = async () => {
59
+ // A recording's last moment (a ring, the network panel) would be cut off mid-fade without a little room.
60
+ if (videoDir && !page.isClosed())
61
+ await new Promise((r) => setTimeout(r, 1800));
62
+ await context.close();
63
+ const video = await page.video()?.path().catch(() => null);
64
+ if (video) {
65
+ console.log("waygraph: video saved to " + video);
66
+ recordArtifact("video", video);
67
+ }
68
+ await closeBrowser();
69
+ };
70
+ return { session: { context, page, mem, baseURL: options.baseURL }, close };
71
+ }
72
+ /** A fresh session between episodes: no cookies, no storage, back on the base URL (so the page itself looks fresh too). */
73
+ export async function resetPage(session) {
74
+ await session.context.clearCookies().catch(ignorePageGone);
75
+ await session.page
76
+ .evaluate(() => {
77
+ try {
78
+ localStorage.clear();
79
+ sessionStorage.clear();
80
+ }
81
+ catch {
82
+ /* storage blocked (e.g. about:blank) - nothing to clear anyway */
83
+ }
84
+ })
85
+ .catch(ignorePageGone);
86
+ await session.page.goto(session.baseURL || "about:blank").catch(ignorePageGone);
87
+ }
@@ -1,6 +1,8 @@
1
1
  import { existsSync, mkdtempSync, readFileSync, rmSync } from "node:fs";
2
2
  import { tmpdir } from "node:os";
3
3
  import { join } from "node:path";
4
+ import { envString } from "../engine/env.js";
5
+ import { ignoreTimeout } from "../engine/page-gone.js";
4
6
  let warned = false;
5
7
  /**
6
8
  * CHROME_PATH / CHROMIUM_PATH, if set and the file exists. A stale path (browser uninstalled)
@@ -20,7 +22,7 @@ export function chromiumExecutablePath() {
20
22
  }
21
23
  /** Unpacked extension directories, as resolved by `resolveExtensions` - also what `WAYGRAPH_EXTENSIONS` carries to child processes. */
22
24
  export function extensionPathsFromEnv() {
23
- return (process.env.WAYGRAPH_EXTENSIONS ?? "").split(",").filter(Boolean);
25
+ return (envString("WAYGRAPH_EXTENSIONS") ?? "").split(",").filter(Boolean);
24
26
  }
25
27
  /**
26
28
  * Launches a browser and its first context. With `extensions` it uses a persistent context, the only
@@ -49,7 +51,7 @@ export async function launchContext(opts) {
49
51
  // An extension's background worker registers its page hooks, so wait for it before the first navigation.
50
52
  const hasWorker = extensions.some((dir) => JSON.parse(readFileSync(join(dir, "manifest.json"), "utf-8")).background?.service_worker !== undefined);
51
53
  if (hasWorker && context.serviceWorkers().length === 0) {
52
- await context.waitForEvent("serviceworker", { timeout: 10_000 }).catch(() => undefined);
54
+ await context.waitForEvent("serviceworker", { timeout: 10_000 }).catch(ignoreTimeout);
53
55
  }
54
56
  return {
55
57
  browser: context.browser(),
@@ -5,6 +5,8 @@
5
5
  // field) to get waygraph to see the same config their actual app already uses.
6
6
  import { existsSync, readFileSync } from "node:fs";
7
7
  import { join } from "node:path";
8
+ import { envString, setEnv } from "../engine/env.js";
9
+ import { takeGlobalFlag } from "./global-flag.js";
8
10
  /** `KEY=value` lines only - no `${VAR}` expansion, no multiline values. Matches the common
9
11
  * Vite/Next `.env` shape, not full dotenv-expand parity. */
10
12
  function parseEnvFile(content) {
@@ -30,21 +32,14 @@ function parseEnvFile(content) {
30
32
  }
31
33
  /** The env mode: `--env <mode>` / `WAYGRAPH_ENV`, else `NODE_ENV`, else "development". */
32
34
  export function envMode() {
33
- return process.env.WAYGRAPH_ENV || process.env.NODE_ENV || "development";
35
+ return envString("WAYGRAPH_ENV") || process.env.NODE_ENV || "development";
34
36
  }
35
37
  /** Removes `--env <mode>` / `--env=<mode>` from argv and records it as `WAYGRAPH_ENV`, so it never reaches a forwarded command. */
36
38
  export function takeEnvFlag(argv) {
37
- const out = [];
38
- for (let i = 0; i < argv.length; i++) {
39
- const a = argv[i];
40
- if (a === "--env" && argv[i + 1] !== undefined)
41
- process.env.WAYGRAPH_ENV = argv[++i];
42
- else if (a.startsWith("--env="))
43
- process.env.WAYGRAPH_ENV = a.slice("--env=".length);
44
- else
45
- out.push(a);
46
- }
47
- return out;
39
+ const { value, rest } = takeGlobalFlag(argv, "env");
40
+ if (value !== undefined)
41
+ setEnv("WAYGRAPH_ENV", value);
42
+ return rest;
48
43
  }
49
44
  /**
50
45
  * Loads `.env` / `.env.local` / `.env.<mode>` / `.env.<mode>.local` from a project's root, the layering
@@ -1,9 +1,5 @@
1
1
  /** A known name (`"hoppscotch"`), a Chrome Web Store id, a path to an unpacked extension, or `{ id, sha256 }`. */
2
- export type ExtensionSpec = string | {
3
- id?: string;
4
- path?: string;
5
- sha256?: string;
6
- };
2
+ import type { ExtensionSpec } from "../engine/config.js";
7
3
  /** Names accepted in `extensions: [...]` mapped to their Chrome Web Store ids. */
8
4
  export declare const KNOWN_EXTENSIONS: Readonly<Record<string, string>>;
9
5
  /** Unpacks a .crx and pins the manifest `key`, so the extension keeps its store id (its origin is then stable, e.g. for an API allowlist). */
@@ -4,13 +4,14 @@ import { existsSync, mkdirSync, readFileSync, renameSync, rmSync, writeFileSync
4
4
  import { homedir } from "node:os";
5
5
  import { dirname, join, resolve, sep } from "node:path";
6
6
  import { inflateRawSync } from "node:zlib";
7
+ import { envString } from "../engine/env.js";
7
8
  /** Names accepted in `extensions: [...]` mapped to their Chrome Web Store ids. */
8
9
  export const KNOWN_EXTENSIONS = {
9
10
  hoppscotch: "amknoiejhlmhancpahfcfcfhllgkpbld",
10
11
  };
11
12
  const STORE_ID = /^[a-p]{32}$/;
12
13
  function cacheDir() {
13
- const base = process.env.WAYGRAPH_CACHE_DIR ?? join(process.env.XDG_CACHE_HOME ?? join(homedir(), ".cache"), "waygraph");
14
+ const base = envString("WAYGRAPH_CACHE_DIR") ?? join(process.env.XDG_CACHE_HOME ?? join(homedir(), ".cache"), "waygraph");
14
15
  return join(base, "extensions");
15
16
  }
16
17
  /** Reads the end-of-central-directory record and extracts every entry; rejects paths that escape `dest`. */
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,34 @@
1
+ import { setOwnContextLauncher } from "../engine/run/launch.js";
2
+ import { resolveLauncher } from "../engine/config.js";
3
+ import { chromiumExecutablePath, extensionPathsFromEnv, launchContext } from "./browser.js";
4
+ import { resolveExtensions } from "./extensions.js";
5
+ import { loadWaygraphConfig } from "./waygraph-config.js";
6
+ import { envString } from "../engine/env.js";
7
+ // An Engine's own browser follows the selected config (--config), the Chromium override and the configured extensions.
8
+ setOwnContextLauncher(async (engineConfig) => {
9
+ // A config chosen with `--config` / WAYGRAPH_CONFIG wins over the one the Engine was built with.
10
+ const chosen = envString("WAYGRAPH_CONFIG") ? await loadWaygraphConfig(process.cwd()) : undefined;
11
+ const config = chosen
12
+ ? {
13
+ ...engineConfig,
14
+ ...(chosen.baseUrl !== undefined ? { baseUrl: chosen.baseUrl } : {}),
15
+ ...(chosen.extensions !== undefined ? { extensions: chosen.extensions } : {}),
16
+ }
17
+ : engineConfig;
18
+ const browserName = config?.browserName ?? "chromium";
19
+ const executablePath = browserName === "chromium" ? chromiumExecutablePath() : undefined;
20
+ const baseURL = config?.baseUrl ?? envString("WAYGRAPH_BASE_URL");
21
+ return launchContext({
22
+ launcher: resolveLauncher(browserName, config),
23
+ launch: {
24
+ headless: config?.headless ?? true,
25
+ ...(config?.slowMo !== undefined ? { slowMo: config.slowMo } : {}),
26
+ ...(executablePath ? { executablePath } : {}),
27
+ },
28
+ context: {
29
+ ...(baseURL ? { baseURL } : {}),
30
+ ...(config?.recordVideo ? { recordVideo: config.recordVideo } : {}),
31
+ },
32
+ extensions: await resolveExtensions(config?.extensions ?? extensionPathsFromEnv(), process.cwd()),
33
+ });
34
+ });
@@ -0,0 +1,5 @@
1
+ /** The value of `--<name> <v>` / `--<name>=<v>` (the last one wins) and argv without it. */
2
+ export declare function takeGlobalFlag(argv: string[], name: string): {
3
+ value: string | undefined;
4
+ rest: string[];
5
+ };
@@ -0,0 +1,18 @@
1
+ // Options any command takes (`--config`, `--env`): read with node:util's parseArgs and taken out of argv, so they never
2
+ // reach a command that forwards its arguments (waygraph test -> playwright test).
3
+ import { parseArgs } from "node:util";
4
+ /** The value of `--<name> <v>` / `--<name>=<v>` (the last one wins) and argv without it. */
5
+ export function takeGlobalFlag(argv, name) {
6
+ const { tokens } = parseArgs({ args: argv, options: { [name]: { type: "string" } }, strict: false, allowPositionals: true, tokens: true });
7
+ let value;
8
+ const drop = new Set();
9
+ for (const t of tokens) {
10
+ if (t.kind !== "option" || t.name !== name || typeof t.value !== "string")
11
+ continue;
12
+ value = t.value;
13
+ drop.add(t.index);
14
+ if (!t.inlineValue)
15
+ drop.add(t.index + 1);
16
+ }
17
+ return { value, rest: argv.filter((_, i) => !drop.has(i)) };
18
+ }
@@ -1,4 +1,4 @@
1
1
  import type { PlaywrightTestConfig } from "@playwright/test";
2
- import type { WaygraphConfig } from "./config.js";
2
+ import type { WaygraphConfig } from "./waygraph-config.js";
3
3
  /** The test runner's config for a project, built from its waygraph config. `waygraph test` uses this when there is no playwright.config. */
4
4
  export declare function playwrightConfigFrom(config: WaygraphConfig, projectDir: string, baseURL: string | undefined): PlaywrightTestConfig;
@@ -1,6 +1,7 @@
1
1
  // Loaded by `waygraph test` (playwright test -c) for projects that keep their settings in config/waygraph.config.ts.
2
2
  import { defineConfig } from "@playwright/test";
3
- import { loadWaygraphConfig, resolveBaseUrl } from "./config.js";
3
+ import { loadWaygraphConfig, resolveBaseUrl } from "./waygraph-config.js";
4
4
  import { playwrightConfigFrom } from "./playwright-config.js";
5
- const projectDir = process.env.WAYGRAPH_PROJECT_DIR ?? process.cwd();
5
+ import { envString } from "../engine/env.js";
6
+ const projectDir = envString("WAYGRAPH_PROJECT_DIR") ?? process.cwd();
6
7
  export default defineConfig(playwrightConfigFrom((await loadWaygraphConfig(projectDir)) ?? {}, projectDir, await resolveBaseUrl(projectDir)));
@@ -0,0 +1,2 @@
1
+ /** The folder run logs go to for a project unless the config or the environment says otherwise. */
2
+ export declare function defaultRunLogDir(projectDir: string): string;
@@ -0,0 +1,17 @@
1
+ // Writes every run event to `<dir>/<runId>.jsonl` when WAYGRAPH_RUN_LOG names a folder (the CLI sets it to the project's
2
+ // `.waygraph/runs`; `runLog: false` in the config turns it off). This is the run history Waygraph UI reads.
3
+ import { appendFileSync, mkdirSync } from "node:fs";
4
+ import { join } from "node:path";
5
+ import { onRunEvent } from "../engine/run/events.js";
6
+ import { envString } from "../engine/env.js";
7
+ onRunEvent((event) => {
8
+ const dir = envString("WAYGRAPH_RUN_LOG");
9
+ if (!dir || dir === "0")
10
+ return;
11
+ mkdirSync(dir, { recursive: true });
12
+ appendFileSync(join(dir, `${event.runId}.jsonl`), JSON.stringify(event) + "\n");
13
+ });
14
+ /** The folder run logs go to for a project unless the config or the environment says otherwise. */
15
+ export function defaultRunLogDir(projectDir) {
16
+ return join(projectDir, ".waygraph", "runs");
17
+ }
@@ -1,7 +1,8 @@
1
1
  import { existsSync, mkdirSync, readFileSync, rmSync, writeFileSync } from "node:fs";
2
2
  import { homedir } from "node:os";
3
3
  import { basename, isAbsolute, join, resolve } from "node:path";
4
- import { loadWaygraphConfig } from "./config.js";
4
+ import { loadWaygraphConfig } from "./waygraph-config.js";
5
+ import { envString } from "../engine/env.js";
5
6
  /** The user's Downloads folder, or undefined when there is none (a server, a container). */
6
7
  export function downloadsDir() {
7
8
  const home = homedir();
@@ -41,7 +42,7 @@ function writable(dir) {
41
42
  */
42
43
  export async function resolveVideoDir(projectDir) {
43
44
  const fallback = join(projectDir, ".waygraph-videos");
44
- const configured = process.env.WAYGRAPH_VIDEO_DIR || (await loadWaygraphConfig(projectDir))?.video?.dir;
45
+ const configured = envString("WAYGRAPH_VIDEO_DIR") || (await loadWaygraphConfig(projectDir))?.video?.dir;
45
46
  if (configured) {
46
47
  const dir = isAbsolute(expandHome(configured)) ? expandHome(configured) : resolve(projectDir, configured);
47
48
  if (writable(dir))
@@ -1,7 +1,7 @@
1
1
  import type { PlaywrightTestConfig } from "@playwright/test";
2
- import type { ExtensionSpec } from "./extensions.js";
2
+ import type { ExtensionSpec } from "../engine/config.js";
3
3
  import type { WebServerConfig } from "./webserver.js";
4
- import type { DemoPace } from "./highlights.js";
4
+ import type { DemoPace } from "../engine/stub/pace.js";
5
5
  /** Where `--video` recordings are saved and at what size. */
6
6
  export interface VideoSettings {
7
7
  /** Where recordings are saved: absolute, `~/…`, or relative to the project. Default `~/Downloads/waygraph-videos/<project>` (the project's `.waygraph-videos/` where there is no Downloads folder, and on CI). */
@@ -57,6 +57,8 @@ export interface WaygraphConfig {
57
57
  run?: RunSettings;
58
58
  /** Settings for `waygraph demo` only. They override the shared ones above. */
59
59
  demo?: DemoSettings;
60
+ /** Write each run's events to `.waygraph/runs/<runId>.jsonl` (the history Waygraph UI shows), or to this folder. Default true. */
61
+ runLog?: boolean | string;
60
62
  /** Folder of test files, relative to the project. Default `"tests"`. */
61
63
  testDir?: string;
62
64
  /** App to start around `waygraph test`, `run`, `demo` and `auto` (same fields as Playwright's `webServer`). */
@@ -79,7 +81,7 @@ export declare function defineConfig(config: WaygraphConfig | ((context: ConfigC
79
81
  export declare function takeConfigFlag(argv: string[]): string[];
80
82
  /**
81
83
  * Looks for the first `waygraph.config.*` in `projectDir` and imports it - `.ts` works
82
- * unmodified because `bin/waygraph` already registers `tsx/esm` before `dist/cli.js` ever runs
84
+ * unmodified because `bin/waygraph` already registers `tsx/esm` before `dist/cli/cli.js` ever runs
83
85
  * (the same mechanism that already lets a consumer's `.block.ts`/`.flow.ts` import directly), so
84
86
  * no separate loader/transpile step is needed here. A broken config file throws loud, naming the
85
87
  * file - silently swallowing it would make a missing `baseUrl` look like "nobody configured
@@ -88,7 +90,7 @@ export declare function takeConfigFlag(argv: string[]): string[];
88
90
  export declare function loadWaygraphConfig(projectDir: string): Promise<WaygraphConfig | undefined>;
89
91
  /**
90
92
  * Single source of truth for a project's base URL. Was three independently drifted copies
91
- * (`src/cli/flags.ts`, `src/traverse/run.ts`, `src/session/auto-explore-run.ts`), each checking
93
+ * (`src/cli/flags.ts`, `src/live/traverse/traverse.ts`, `src/live/auto/auto.ts`), each checking
92
94
  * a slightly different subset of sources in a different order - real duplication, not just
93
95
  * stylistic, since one copy skipped `config.waygraph.*` nesting and another checked
94
96
  * `WAYGRAPH_BASE_URL` first instead of last. Checked in this order:
@@ -97,11 +99,6 @@ export declare function loadWaygraphConfig(projectDir: string): Promise<Waygraph
97
99
  * `loadEnvFiles`, called here so every caller gets native `.env` support for free, not just
98
100
  * whichever command remembered to call it).
99
101
  * 2. A `waygraph.config.*` file's `baseUrl`.
100
- * 3. `package.json`'s `waygraph.baseUrl`/`baseURL` (`config.waygraph.*` also checked - a common
101
- * nested-config convention some tooling uses).
102
- * 4. `playwright.config.*`'s own `baseURL` (regex-read as text, never imported - importing a
103
- * consumer's real playwright.config risks pulling in `@playwright/test`'s own global setup
104
- * as a side effect, which resolving a URL string has no business doing).
105
102
  */
106
103
  export declare function resolveBaseUrl(projectDir: string): Promise<string | undefined>;
107
104
  /** Unpacked extension directories for a run: `WAYGRAPH_EXTENSIONS` if set, else the config file's `extensions` (fetched on first use). */