waygraph 0.15.53 → 0.16.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (556) 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 +13 -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/{commands → cli/commands}/check.d.ts +0 -1
  21. package/dist/cli/commands/check.js +104 -0
  22. package/dist/cli/commands/codemod-checkpoints.d.ts +18 -0
  23. package/dist/cli/commands/codemod-checkpoints.js +186 -0
  24. package/dist/cli/commands/codemod-flows.d.ts +18 -0
  25. package/dist/cli/commands/codemod-flows.js +284 -0
  26. package/dist/cli/commands/codemod-stubs.d.ts +10 -0
  27. package/dist/cli/commands/codemod-stubs.js +187 -0
  28. package/dist/{commands → cli/commands}/extensions.js +5 -4
  29. package/dist/{commands → cli/commands}/init.js +1 -2
  30. package/dist/{commands → cli/commands}/list.js +9 -7
  31. package/dist/cli/commands/manifest.d.ts +2 -0
  32. package/dist/cli/commands/manifest.js +20 -0
  33. package/dist/cli/commands/map.js +57 -0
  34. package/dist/{commands → cli/commands}/run.d.ts +0 -1
  35. package/dist/cli/commands/run.js +64 -0
  36. package/dist/{commands → cli/commands}/session.js +61 -88
  37. package/dist/{commands → cli/commands}/test.js +11 -14
  38. package/dist/cli/commands/traverse.js +105 -0
  39. package/dist/{commands → cli/commands}/try.js +29 -25
  40. package/dist/{commands → cli/commands}/upgrade.js +40 -4
  41. package/dist/cli/flags.d.ts +193 -16
  42. package/dist/cli/flags.js +179 -234
  43. package/dist/cli/run-chain.d.ts +1 -0
  44. package/dist/cli/run-chain.js +42 -7
  45. package/dist/cli/usage.d.ts +1 -1
  46. package/dist/cli/usage.js +21 -53
  47. package/dist/cli/util.d.ts +2 -2
  48. package/dist/cli/util.js +2 -3
  49. package/dist/{highlights → demo/narration}/css.d.ts +1 -1
  50. package/dist/{highlights → demo/narration}/css.js +2 -3
  51. package/dist/{highlights → demo/narration}/demo-pace.d.ts +7 -11
  52. package/dist/{highlights → demo/narration}/demo-pace.js +9 -11
  53. package/dist/{highlights → demo/narration}/device.d.ts +4 -2
  54. package/dist/{highlights → demo/narration}/device.js +3 -1
  55. package/dist/demo/narration/merge.d.ts +8 -0
  56. package/dist/demo/narration/merge.js +71 -0
  57. package/dist/{highlights/run-phase.d.ts → demo/narration/narration.d.ts} +10 -14
  58. package/dist/{highlights/run-phase.js → demo/narration/narration.js} +25 -94
  59. package/dist/{highlights → demo/narration}/shorthand.d.ts +1 -1
  60. package/dist/demo/narration/stub-ctx.d.ts +8 -0
  61. package/dist/demo/narration/stub-ctx.js +164 -0
  62. package/dist/{highlights → demo/narration}/style.d.ts +1 -7
  63. package/dist/{highlights → demo/narration}/style.js +1 -41
  64. package/dist/{highlights → demo/narration}/todo-dock.d.ts +3 -3
  65. package/dist/{highlights → demo/narration}/todo-dock.js +13 -30
  66. package/dist/demo/overlay/auto-chrome.d.ts +7 -0
  67. package/dist/demo/overlay/auto-chrome.js +97 -0
  68. package/dist/{session/overlay-beacon.d.ts → demo/overlay/beacon.d.ts} +7 -0
  69. package/dist/{session/overlay-beacon.js → demo/overlay/beacon.js} +5 -0
  70. package/dist/demo/overlay/cursor.d.ts +12 -0
  71. package/dist/demo/overlay/cursor.js +142 -0
  72. package/dist/demo/overlay/device-stage.d.ts +13 -0
  73. package/dist/demo/overlay/device-stage.js +396 -0
  74. package/dist/demo/overlay/inpage/banner.d.ts +1 -0
  75. package/dist/demo/overlay/inpage/banner.js +160 -0
  76. package/dist/demo/overlay/inpage/caption.d.ts +2 -0
  77. package/dist/demo/overlay/inpage/caption.js +24 -0
  78. package/dist/demo/overlay/inpage/core.d.ts +1 -0
  79. package/dist/demo/overlay/inpage/core.js +345 -0
  80. package/dist/demo/overlay/inpage/device-chip.d.ts +1 -0
  81. package/dist/demo/overlay/inpage/device-chip.js +191 -0
  82. package/dist/demo/overlay/inpage/network.d.ts +9 -0
  83. package/dist/demo/overlay/inpage/network.js +200 -0
  84. package/dist/demo/overlay/inpage/panel-chrome.d.ts +1 -0
  85. package/dist/demo/overlay/inpage/panel-chrome.js +203 -0
  86. package/dist/demo/overlay/inpage/stamp.d.ts +1 -0
  87. package/dist/demo/overlay/inpage/stamp.js +46 -0
  88. package/dist/demo/overlay/inpage/swipe-zoom.d.ts +1 -0
  89. package/dist/demo/overlay/inpage/swipe-zoom.js +220 -0
  90. package/dist/demo/overlay/inpage/todos.d.ts +1 -0
  91. package/dist/demo/overlay/inpage/todos.js +294 -0
  92. package/dist/demo/overlay/locator-theater.d.ts +25 -0
  93. package/dist/demo/overlay/locator-theater.js +76 -0
  94. package/dist/demo/overlay/network-capture.d.ts +22 -0
  95. package/dist/demo/overlay/network-capture.js +127 -0
  96. package/dist/demo/overlay/overlay-css.d.ts +3 -0
  97. package/dist/demo/overlay/overlay-css.js +369 -0
  98. package/dist/demo/overlay/overlay-stage.d.ts +23 -0
  99. package/dist/demo/overlay/overlay-stage.js +106 -0
  100. package/dist/demo/overlay/overlay.d.ts +10 -0
  101. package/dist/demo/overlay/overlay.js +89 -0
  102. package/dist/{pilot-overlay/overlay-fixtures.d.ts → demo/overlay/phase-fixtures.d.ts} +2 -2
  103. package/dist/{pilot-overlay/overlay-fixtures.js → demo/overlay/phase-fixtures.js} +2 -2
  104. package/dist/{pilot-overlay/action-ring.js → demo/overlay/pilot/actions.js} +2 -1
  105. package/dist/{pilot-overlay → demo/overlay/pilot}/fixtures.d.ts +6 -5
  106. package/dist/{pilot-overlay → demo/overlay/pilot}/fixtures.js +19 -18
  107. package/dist/{pilot-overlay → demo/overlay/pilot}/shell.d.ts +2 -2
  108. package/dist/{pilot-overlay → demo/overlay/pilot}/shell.js +13 -22
  109. package/dist/demo/overlay/reattach.d.ts +7 -0
  110. package/dist/demo/overlay/reattach.js +23 -0
  111. package/dist/demo/overlay/rings.d.ts +33 -0
  112. package/dist/demo/overlay/rings.js +448 -0
  113. package/dist/{ui → demo/overlay/ui}/components/ring.js +2 -2
  114. package/dist/{ui → demo/overlay/ui}/overlay.css +4 -4
  115. package/dist/{ui → demo/overlay/ui}/shadow.d.ts +1 -1
  116. package/dist/{ui → demo/overlay/ui}/shadow.js +39 -2
  117. package/dist/demo/stepper/after.d.ts +3 -0
  118. package/dist/demo/stepper/after.js +113 -0
  119. package/dist/demo/stepper/banner-log.d.ts +37 -0
  120. package/dist/demo/stepper/banner-log.js +63 -0
  121. package/dist/demo/stepper/before.d.ts +4 -0
  122. package/dist/demo/stepper/before.js +110 -0
  123. package/dist/demo/stepper/demo-log.d.ts +31 -0
  124. package/dist/demo/stepper/demo-log.js +309 -0
  125. package/dist/demo/stepper/gate.d.ts +11 -0
  126. package/dist/demo/stepper/gate.js +78 -0
  127. package/dist/demo/stepper/interaction-patch.d.ts +3 -0
  128. package/dist/demo/stepper/interaction-patch.js +323 -0
  129. package/dist/demo/stepper/pacing.d.ts +21 -0
  130. package/dist/demo/stepper/pacing.js +23 -0
  131. package/dist/demo/stepper/slides.d.ts +11 -0
  132. package/dist/demo/stepper/slides.js +233 -0
  133. package/dist/demo/stepper/step-panels.d.ts +21 -0
  134. package/dist/demo/stepper/step-panels.js +589 -0
  135. package/dist/demo/stepper/stepper.d.ts +24 -0
  136. package/dist/demo/stepper/stepper.js +122 -0
  137. package/dist/demo/stepper/teardown.d.ts +48 -0
  138. package/dist/demo/stepper/teardown.js +179 -0
  139. package/dist/demo/stepper/todo-advance.d.ts +14 -0
  140. package/dist/demo/stepper/todo-advance.js +110 -0
  141. package/dist/demo/stepper/view.d.ts +68 -0
  142. package/dist/demo/stepper/view.js +31 -0
  143. package/dist/demo/types.d.ts +17 -0
  144. package/dist/demo/verbose-log.js +15 -0
  145. package/dist/{types.d.ts → engine/block/block.d.ts} +106 -91
  146. package/dist/{core → engine/block}/block.js +10 -53
  147. package/dist/{core → engine/block}/compose.d.ts +10 -7
  148. package/dist/{core → engine/block}/compose.js +1 -1
  149. package/dist/{core/blocks → engine/block/kinds}/api.d.ts +17 -12
  150. package/dist/{core/blocks → engine/block/kinds}/api.js +26 -18
  151. package/dist/{core/blocks → engine/block/kinds}/effect.d.ts +13 -18
  152. package/dist/engine/block/kinds/effect.js +17 -0
  153. package/dist/{core/blocks → engine/block/kinds}/method.d.ts +19 -29
  154. package/dist/{core/blocks → engine/block/kinds}/method.js +7 -21
  155. package/dist/{core/blocks → engine/block/kinds}/nav.d.ts +22 -31
  156. package/dist/{core/blocks → engine/block/kinds}/nav.js +6 -12
  157. package/dist/{core/blocks → engine/block/kinds}/page.d.ts +15 -20
  158. package/dist/{core/blocks → engine/block/kinds}/page.js +5 -7
  159. package/dist/engine/checkpoint/checkpoint.d.ts +22 -0
  160. package/dist/engine/checkpoint/checkpoint.js +8 -0
  161. package/dist/engine/checkpoint/route.d.ts +28 -0
  162. package/dist/engine/checkpoint/route.js +28 -0
  163. package/dist/{core → engine}/config.d.ts +7 -2
  164. package/dist/engine/config.js +6 -0
  165. package/dist/engine/engine.d.ts +45 -0
  166. package/dist/{core → engine}/engine.js +6 -10
  167. package/dist/engine/env.d.ts +59 -0
  168. package/dist/engine/env.js +83 -0
  169. package/dist/{errors.d.ts → engine/errors.d.ts} +23 -22
  170. package/dist/{errors.js → engine/errors.js} +22 -22
  171. package/dist/{core → engine/flow}/branch-regression.d.ts +8 -7
  172. package/dist/{core → engine/flow}/branch-regression.js +4 -3
  173. package/dist/engine/flow/flow.d.ts +162 -0
  174. package/dist/engine/flow/flow.js +244 -0
  175. package/dist/{core → engine/flow}/map-builder.d.ts +42 -40
  176. package/dist/{core → engine/flow}/map-builder.js +46 -48
  177. package/dist/{core → engine}/locate.d.ts +1 -1
  178. package/dist/{core → engine}/locate.js +1 -2
  179. package/dist/{mem-stub.d.ts → engine/mem/mem-stub.d.ts} +9 -8
  180. package/dist/{mem-stub.js → engine/mem/mem-stub.js} +2 -2
  181. package/dist/{mem-page.d.ts → engine/mem/mem.d.ts} +1 -1
  182. package/dist/{mem-page.js → engine/mem/mem.js} +2 -1
  183. package/dist/engine/page-gone.d.ts +5 -0
  184. package/dist/engine/page-gone.js +20 -0
  185. package/dist/engine/run/connect.d.ts +28 -0
  186. package/dist/{types.js → engine/run/connect.js} +11 -10
  187. package/dist/engine/run/events.d.ts +67 -0
  188. package/dist/engine/run/events.js +90 -0
  189. package/dist/engine/run/hooks.d.ts +16 -0
  190. package/dist/engine/run/hooks.js +8 -0
  191. package/dist/engine/run/launch.d.ts +13 -0
  192. package/dist/engine/run/launch.js +27 -0
  193. package/dist/{core/run-graph.d.ts → engine/run/run.d.ts} +9 -11
  194. package/dist/{core/run-graph.js → engine/run/run.js} +22 -11
  195. package/dist/engine/stub/pace.d.ts +12 -0
  196. package/dist/engine/stub/pace.js +2 -0
  197. package/dist/engine/stub/ring.d.ts +130 -0
  198. package/dist/engine/stub/ring.js +41 -0
  199. package/dist/engine/stub/stub.d.ts +268 -0
  200. package/dist/engine/stub/stub.js +1 -0
  201. package/dist/engine/stub/todos.d.ts +104 -0
  202. package/dist/engine/stub/todos.js +2 -0
  203. package/dist/engine/stub/viewport.d.ts +26 -0
  204. package/dist/engine/stub/viewport.js +2 -0
  205. package/dist/{trait.d.ts → engine/trait/trait.d.ts} +1 -1
  206. package/dist/index.d.ts +84 -36
  207. package/dist/index.js +44 -19
  208. package/dist/{session/auto-explore-run.d.ts → live/auto/auto.d.ts} +10 -16
  209. package/dist/{session/auto-explore-run.js → live/auto/auto.js} +164 -248
  210. package/dist/{session/auto-explore.d.ts → live/auto/explore.d.ts} +4 -14
  211. package/dist/{session/auto-explore.js → live/auto/explore.js} +21 -127
  212. package/dist/{auto-session/session.d.ts → live/auto-session/auto-session.d.ts} +1 -1
  213. package/dist/{auto-session/session.js → live/auto-session/auto-session.js} +27 -24
  214. package/dist/{auto-session → live/auto-session}/helpers.d.ts +16 -5
  215. package/dist/{auto-session → live/auto-session}/helpers.js +1 -1
  216. package/dist/{session/auto-session-ipc.d.ts → live/auto-session/ipc.d.ts} +7 -5
  217. package/dist/{session/auto-session-ipc.js → live/auto-session/ipc.js} +31 -16
  218. package/dist/{session/browser.d.ts → live/auto-session/start.d.ts} +1 -2
  219. package/dist/{session/browser.js → live/auto-session/start.js} +2 -3
  220. package/dist/{pilot-overlay → live/pilot}/panel.d.ts +1 -1
  221. package/dist/{pilot-overlay → live/pilot}/panel.js +23 -31
  222. package/dist/{session → live/pilot}/pilot.d.ts +4 -3
  223. package/dist/{session → live/pilot}/pilot.js +4 -4
  224. package/dist/{traverse → live/traverse}/coverage.d.ts +4 -0
  225. package/dist/{traverse → live/traverse}/coverage.js +3 -0
  226. package/dist/{traverse → live/traverse}/lease.d.ts +1 -0
  227. package/dist/{traverse → live/traverse}/lease.js +1 -0
  228. package/dist/{traverse/run.d.ts → live/traverse/traverse.d.ts} +4 -1
  229. package/dist/{traverse/run.js → live/traverse/traverse.js} +26 -43
  230. package/dist/manifest/manifest.d.ts +52 -0
  231. package/dist/manifest/manifest.js +93 -0
  232. package/dist/manifest/map-imports.d.ts +7 -0
  233. package/dist/manifest/map-imports.js +22 -0
  234. package/dist/manifest/maps.d.ts +33 -0
  235. package/dist/manifest/maps.js +62 -0
  236. package/dist/manifest/pack.d.ts +21 -0
  237. package/dist/manifest/pack.js +109 -0
  238. package/dist/manifest/project.d.ts +60 -0
  239. package/dist/manifest/project.js +101 -0
  240. package/dist/{session/block-inject.js → manifest/roots.js} +1 -18
  241. package/dist/manifest/scan.d.ts +19 -0
  242. package/dist/manifest/scan.js +57 -0
  243. package/dist/{blocks-select.d.ts → manifest/select.d.ts} +3 -0
  244. package/dist/{blocks-select.js → manifest/select.js} +2 -0
  245. package/dist/manifest/source.d.ts +23 -0
  246. package/dist/manifest/source.js +86 -0
  247. package/dist/runner/mode.d.ts +71 -0
  248. package/dist/runner/mode.js +1 -0
  249. package/dist/runner/modes/branches.d.ts +5 -0
  250. package/dist/runner/modes/branches.js +37 -0
  251. package/dist/runner/modes/demo.d.ts +3 -0
  252. package/dist/runner/modes/demo.js +13 -0
  253. package/dist/runner/modes/report.d.ts +2 -0
  254. package/dist/runner/modes/report.js +54 -0
  255. package/dist/runner/modes/run.d.ts +2 -0
  256. package/dist/runner/modes/run.js +3 -0
  257. package/dist/runner/options.d.ts +31 -0
  258. package/dist/runner/options.js +42 -0
  259. package/dist/runner/plan/find.d.ts +18 -0
  260. package/dist/runner/plan/find.js +65 -0
  261. package/dist/runner/plan/plan.d.ts +11 -0
  262. package/dist/runner/plan/plan.js +97 -0
  263. package/dist/runner/plan/seed-mem.d.ts +12 -0
  264. package/dist/runner/plan/seed-mem.js +98 -0
  265. package/dist/runner/plan/spec.d.ts +5 -0
  266. package/dist/runner/plan/spec.js +17 -0
  267. package/dist/runner/play-steps.d.ts +2 -0
  268. package/dist/runner/play-steps.js +59 -0
  269. package/dist/runner/runner.d.ts +4 -0
  270. package/dist/runner/runner.js +64 -0
  271. package/dist/runner/session.d.ts +9 -0
  272. package/dist/runner/session.js +87 -0
  273. package/dist/{browser.js → runtime/browser.js} +4 -2
  274. package/dist/{env-file.js → runtime/env-file.js} +7 -12
  275. package/dist/{extensions.d.ts → runtime/extensions.d.ts} +2 -5
  276. package/dist/{extensions.js → runtime/extensions.js} +3 -1
  277. package/dist/runtime/full-launch.d.ts +1 -0
  278. package/dist/runtime/full-launch.js +34 -0
  279. package/dist/runtime/global-flag.d.ts +5 -0
  280. package/dist/runtime/global-flag.js +18 -0
  281. package/dist/{playwright-config.d.ts → runtime/playwright-config.d.ts} +1 -1
  282. package/dist/{playwright.config.js → runtime/playwright.config.js} +3 -2
  283. package/dist/runtime/run-log.d.ts +2 -0
  284. package/dist/runtime/run-log.js +17 -0
  285. package/dist/{video-dir.js → runtime/video-dir.js} +3 -2
  286. package/dist/{config.d.ts → runtime/waygraph-config.d.ts} +8 -9
  287. package/dist/{config.js → runtime/waygraph-config.js} +21 -51
  288. package/dist/{webserver.js → runtime/webserver.js} +5 -30
  289. package/examples/routed-demo/config/waygraph.config.ts +20 -0
  290. package/examples/routed-demo/package.json +1 -4
  291. package/examples/routed-demo/scripts/fixture-server.mjs +1 -1
  292. package/examples/routed-demo/src/flows/routed-demo-map.flow.ts +2 -4
  293. package/examples/routed-demo/src/flows/routed-demo.flow.ts +2 -3
  294. package/examples/routed-demo/src/map/(app_base)/dashboard/_methods/click-widget.block.ts +5 -4
  295. package/examples/routed-demo/src/map/(app_base)/dashboard/_nav.block.ts +3 -3
  296. package/examples/routed-demo/src/map/(app_base)/dashboard/_page.block.ts +3 -3
  297. package/examples/routed-demo/src/map/(external)/docs/_nav.block.ts +3 -3
  298. package/examples/routed-demo/src/map/(external)/docs/_page.block.ts +3 -3
  299. package/examples/routed-demo/src/states/routed-demo.states.ts +5 -3
  300. package/examples/routed-demo/tests/routed-demo.spec.ts +4 -4
  301. package/examples/routed-demo/tsconfig.json +1 -1
  302. package/examples/saucedemo/README.md +11 -12
  303. package/examples/saucedemo/config/waygraph.config.ts +17 -0
  304. package/examples/saucedemo/docs/CONVENTION.md +5 -7
  305. package/examples/saucedemo/docs/HELPERS.md +12 -12
  306. package/examples/saucedemo/package-lock.json +10 -3
  307. package/examples/saucedemo/package.json +12 -29
  308. package/examples/saucedemo/src/blocks/SITE-MAP.md +0 -1
  309. package/examples/saucedemo/src/blocks/saucedemo-web/NAV.md +1 -5
  310. package/examples/saucedemo/src/blocks/saucedemo-web/cart/nav-cart.block.ts +3 -52
  311. package/examples/saucedemo/src/blocks/saucedemo-web/cart/nav-checkout-info.block.ts +3 -3
  312. package/examples/saucedemo/src/blocks/saucedemo-web/checkout-step-one/methods/fill-first-name.method.block.ts +5 -4
  313. package/examples/saucedemo/src/blocks/saucedemo-web/checkout-step-one/methods/fill-last-name.method.block.ts +5 -4
  314. package/examples/saucedemo/src/blocks/saucedemo-web/checkout-step-one/methods/fill-postal-code.method.block.ts +5 -4
  315. package/examples/saucedemo/src/blocks/saucedemo-web/checkout-step-one/methods/submit-checkout-info.method.block.ts +5 -4
  316. package/examples/saucedemo/src/blocks/saucedemo-web/checkout-step-two/methods/finish-order.method.block.ts +21 -27
  317. package/examples/saucedemo/src/blocks/saucedemo-web/inventory/inventory.page.block.ts +3 -9
  318. package/examples/saucedemo/src/blocks/saucedemo-web/inventory/methods/add-all-to-cart.method.block.ts +4 -6
  319. package/examples/saucedemo/src/blocks/saucedemo-web/inventory/methods/add-to-cart.effect.block.ts +10 -76
  320. package/examples/saucedemo/src/blocks/saucedemo-web/inventory/methods/remove-all-from-cart.method.block.ts +4 -6
  321. package/examples/saucedemo/src/blocks/saucedemo-web/inventory/methods/remove-from-cart.effect.block.ts +4 -3
  322. package/examples/saucedemo/src/blocks/saucedemo-web/inventory/nav-item-detail.block.ts +3 -3
  323. package/examples/saucedemo/src/blocks/saucedemo-web/inventory-item/nav-back-to-inventory.block.ts +3 -3
  324. package/examples/saucedemo/src/blocks/saucedemo-web/inventory-item/nav-back-to-products.block.ts +3 -3
  325. package/examples/saucedemo/src/blocks/saucedemo-web/inventory-item/nav-continue-shopping.block.ts +3 -3
  326. package/examples/saucedemo/src/blocks/saucedemo-web/methods/fill-password.method.block.ts +5 -29
  327. package/examples/saucedemo/src/blocks/saucedemo-web/methods/fill-username.method.block.ts +5 -48
  328. package/examples/saucedemo/src/blocks/saucedemo-web/methods/submit-login.method.block.ts +13 -77
  329. package/examples/saucedemo/src/blocks/saucedemo-web/methods/submit-logout.method.block.ts +5 -4
  330. package/examples/saucedemo/src/blocks/saucedemo-web/nav-login.block.ts +3 -3
  331. package/examples/saucedemo/src/flows/api-demo.flow.ts +26 -18
  332. package/examples/saucedemo/src/flows/cart-bulk.flow.ts +19 -14
  333. package/examples/saucedemo/src/flows/cart-continue.flow.ts +10 -8
  334. package/examples/saucedemo/src/flows/cart-mem.flow.ts +7 -7
  335. package/examples/saucedemo/src/flows/catalog-logout.flow.ts +13 -8
  336. package/examples/saucedemo/src/flows/checkout-then-browse-again.flow.ts +26 -48
  337. package/examples/saucedemo/src/flows/checkout.flow.ts +70 -86
  338. package/examples/saucedemo/src/flows/device-showcase.flow.ts +24 -25
  339. package/examples/saucedemo/src/flows/login.flow.ts +11 -18
  340. package/examples/saucedemo/src/flows/mem-stub-demo.flow.ts +9 -20
  341. package/examples/saucedemo/src/flows/shop.flow.ts +15 -20
  342. package/examples/saucedemo/src/flows/smoke.flow.ts +12 -27
  343. package/examples/saucedemo/src/flows/stub-on-error.flow.ts +24 -43
  344. package/examples/saucedemo/src/flows/viewer-blocked.flow.ts +26 -34
  345. package/examples/saucedemo/src/states/checkout.mem-stubs.ts +11 -0
  346. package/examples/saucedemo/src/states/checkout.states.ts +21 -11
  347. package/examples/saucedemo/src/stubs/device-showcase.ts +191 -0
  348. package/examples/saucedemo/src/stubs/login.ts +37 -0
  349. package/examples/saucedemo/tests/auto-graph.spec.ts +4 -12
  350. package/examples/saucedemo/tests/chain-flow-episodes.spec.ts +7 -9
  351. package/examples/saucedemo/tests/submit-login-branch.spec.ts +18 -5
  352. package/package.json +12 -7
  353. package/templates/agents/waygraph-planner.agent.md +2 -2
  354. package/templates/quickstart/README.md +4 -7
  355. package/templates/quickstart/config/waygraph.config.ts +17 -0
  356. package/templates/quickstart/docs/CONVENTION.md +5 -6
  357. package/templates/quickstart/docs/HELPERS.md +11 -9
  358. package/templates/quickstart/package.json +14 -17
  359. package/templates/quickstart/src/blocks/SITE-MAP.md +13 -3
  360. package/templates/quickstart/src/blocks/saucedemo-web/NAV.md +1 -5
  361. package/templates/quickstart/src/blocks/saucedemo-web/cart/nav-cart.block.ts +3 -52
  362. package/templates/quickstart/src/blocks/saucedemo-web/cart/nav-checkout-info.block.ts +3 -3
  363. package/templates/quickstart/src/blocks/saucedemo-web/checkout-step-one/methods/fill-first-name.method.block.ts +5 -4
  364. package/templates/quickstart/src/blocks/saucedemo-web/checkout-step-one/methods/fill-last-name.method.block.ts +5 -4
  365. package/templates/quickstart/src/blocks/saucedemo-web/checkout-step-one/methods/fill-postal-code.method.block.ts +5 -4
  366. package/templates/quickstart/src/blocks/saucedemo-web/checkout-step-one/methods/submit-checkout-info.method.block.ts +5 -4
  367. package/templates/quickstart/src/blocks/saucedemo-web/checkout-step-two/methods/finish-order.method.block.ts +21 -27
  368. package/templates/quickstart/src/blocks/saucedemo-web/inventory/inventory.page.block.ts +3 -9
  369. package/templates/quickstart/src/blocks/saucedemo-web/inventory/methods/add-all-to-cart.method.block.ts +4 -6
  370. package/templates/quickstart/src/blocks/saucedemo-web/inventory/methods/add-to-cart.effect.block.ts +10 -76
  371. package/templates/quickstart/src/blocks/saucedemo-web/inventory/methods/remove-all-from-cart.method.block.ts +4 -6
  372. package/templates/quickstart/src/blocks/saucedemo-web/inventory/methods/remove-from-cart.effect.block.ts +4 -3
  373. package/templates/quickstart/src/blocks/saucedemo-web/inventory/nav-item-detail.block.ts +3 -3
  374. package/templates/quickstart/src/blocks/saucedemo-web/inventory-item/nav-back-to-inventory.block.ts +3 -3
  375. package/templates/quickstart/src/blocks/saucedemo-web/inventory-item/nav-back-to-products.block.ts +3 -3
  376. package/templates/quickstart/src/blocks/saucedemo-web/inventory-item/nav-continue-shopping.block.ts +3 -3
  377. package/templates/quickstart/src/blocks/saucedemo-web/methods/fill-password.method.block.ts +5 -29
  378. package/templates/quickstart/src/blocks/saucedemo-web/methods/fill-username.method.block.ts +5 -48
  379. package/templates/quickstart/src/blocks/saucedemo-web/methods/submit-login.method.block.ts +13 -77
  380. package/templates/quickstart/src/blocks/saucedemo-web/methods/submit-logout.method.block.ts +5 -4
  381. package/templates/quickstart/src/blocks/saucedemo-web/nav-login.block.ts +3 -3
  382. package/templates/quickstart/src/flows/api-demo.flow.ts +45 -0
  383. package/templates/quickstart/src/flows/cart-bulk.flow.ts +19 -14
  384. package/templates/quickstart/src/flows/cart-continue.flow.ts +10 -8
  385. package/templates/quickstart/src/flows/cart-mem.flow.ts +7 -7
  386. package/templates/quickstart/src/flows/catalog-logout.flow.ts +13 -8
  387. package/templates/quickstart/src/flows/checkout-then-browse-again.flow.ts +26 -48
  388. package/templates/quickstart/src/flows/checkout.flow.ts +70 -63
  389. package/templates/quickstart/src/flows/device-showcase.flow.ts +24 -25
  390. package/templates/quickstart/src/flows/login.flow.ts +11 -18
  391. package/templates/quickstart/src/flows/mem-stub-demo.flow.ts +12 -0
  392. package/templates/quickstart/src/flows/shop.flow.ts +15 -20
  393. package/templates/quickstart/src/flows/smoke.flow.ts +12 -27
  394. package/templates/quickstart/src/flows/stub-on-error.flow.ts +31 -0
  395. package/templates/quickstart/src/flows/viewer-blocked.flow.ts +26 -34
  396. package/templates/quickstart/src/states/checkout.mem-stubs.ts +11 -0
  397. package/templates/quickstart/src/states/checkout.states.ts +21 -11
  398. package/templates/quickstart/src/stubs/device-showcase.ts +191 -0
  399. package/templates/quickstart/src/stubs/login.ts +37 -0
  400. package/templates/quickstart/tests/chain-flow.spec.ts +7 -10
  401. package/templates/scaffold/README.md +2 -1
  402. package/templates/scaffold/STRUCTURE.md +5 -4
  403. package/templates/scaffold/config/waygraph.config.ts +1 -0
  404. package/templates/scaffold/gitignore +1 -0
  405. package/templates/scaffold/src/flows/README.md +2 -2
  406. package/templates/scaffold/src/map/(app_base)/docs/_nav.block.ts +3 -3
  407. package/templates/scaffold/src/map/(app_base)/docs/_page.block.ts +3 -3
  408. package/templates/scaffold/src/map/(app_base)/home/_methods/add-item.effect.block.ts +4 -4
  409. package/templates/scaffold/src/map/(app_base)/home/_methods/assert-hello.method.block.ts +3 -3
  410. package/templates/scaffold/src/map/(app_base)/home/_methods/assert-item-added.method.block.ts +3 -3
  411. package/templates/scaffold/src/map/(app_base)/home/_methods/clear-cart.method.block.ts +5 -4
  412. package/templates/scaffold/src/map/(app_base)/home/_methods/remove-item.effect.block.ts +4 -4
  413. package/templates/scaffold/src/map/(app_base)/home/_nav.block.ts +3 -3
  414. package/templates/scaffold/src/map/(app_base)/home/_page.block.ts +3 -3
  415. package/templates/scaffold/src/map/(app_base)/home/nav-verification-link.block.ts +4 -4
  416. package/templates/scaffold/src/map/(external)/hoppscotch/_keys.ts +21 -0
  417. package/templates/scaffold/src/map/(external)/hoppscotch/_methods/assert-response-body.method.block.ts +4 -4
  418. package/templates/scaffold/src/map/(external)/hoppscotch/_methods/assert-response-header.method.block.ts +4 -4
  419. package/templates/scaffold/src/map/(external)/hoppscotch/_methods/assert-status.method.block.ts +4 -4
  420. package/templates/scaffold/src/map/(external)/hoppscotch/_methods/pick-extension-interceptor.method.block.ts +5 -4
  421. package/templates/scaffold/src/map/(external)/hoppscotch/_methods/read-response-body.method.block.ts +6 -5
  422. package/templates/scaffold/src/map/(external)/hoppscotch/_methods/read-response-headers.method.block.ts +6 -5
  423. package/templates/scaffold/src/map/(external)/hoppscotch/_methods/send-request.method.block.ts +5 -4
  424. package/templates/scaffold/src/map/(external)/hoppscotch/_methods/set-bearer-token.method.block.ts +6 -5
  425. package/templates/scaffold/src/map/(external)/hoppscotch/_methods/set-headers.method.block.ts +6 -5
  426. package/templates/scaffold/src/map/(external)/hoppscotch/_methods/set-json-body.method.block.ts +6 -5
  427. package/templates/scaffold/src/map/(external)/hoppscotch/_methods/set-method.method.block.ts +6 -5
  428. package/templates/scaffold/src/map/(external)/hoppscotch/_methods/set-query-params.method.block.ts +6 -5
  429. package/templates/scaffold/src/map/(external)/hoppscotch/_methods/set-url.method.block.ts +6 -5
  430. package/templates/scaffold/src/map/(external)/hoppscotch/_nav.block.ts +3 -3
  431. package/templates/scaffold/src/map/(external)/hoppscotch/_page.block.ts +3 -3
  432. package/templates/scaffold/src/map/(external)/hoppscotch/_states.ts +6 -0
  433. package/templates/scaffold/src/map/(external)/hoppscotch/settings/_nav.block.ts +3 -3
  434. package/templates/scaffold/src/map/(external)/mailpit/_keys.ts +13 -0
  435. package/templates/scaffold/src/map/(external)/mailpit/_methods/assert-email-content.method.block.ts +4 -4
  436. package/templates/scaffold/src/map/(external)/mailpit/_methods/assert-email-received.method.block.ts +4 -4
  437. package/templates/scaffold/src/map/(external)/mailpit/_methods/extract-email-link.method.block.ts +6 -5
  438. package/templates/scaffold/src/map/(external)/mailpit/_methods/open-message.method.block.ts +6 -5
  439. package/templates/scaffold/src/map/(external)/mailpit/_nav.block.ts +3 -3
  440. package/templates/scaffold/src/map/(external)/mailpit/_page.block.ts +3 -3
  441. package/templates/scaffold/src/map/(external)/mailpit/_states.ts +9 -0
  442. package/templates/scaffold/src/map/README.md +7 -0
  443. package/templates/scaffold/src/states/README.md +4 -1
  444. package/templates/scaffold/src/states/demo.mem-keys.ts +1 -29
  445. package/templates/scaffold/src/states/demo.states.ts +14 -20
  446. package/templates/scaffold/tests/hoppscotch.spec.ts +1 -11
  447. package/templates/scaffold/tests/mail-verify.spec.ts +2 -2
  448. package/templates/skills/waygraph-blind-pilot.skill.md +2 -6
  449. package/templates/skills/waygraph-convention.skill.md +23 -14
  450. package/templates/skills/waygraph-pilot.skill.md +7 -4
  451. package/dist/auto-session/verbose-log.js +0 -16
  452. package/dist/auto-session.d.ts +0 -2
  453. package/dist/auto-session.js +0 -3
  454. package/dist/cli/discover.d.ts +0 -40
  455. package/dist/cli/discover.js +0 -148
  456. package/dist/commands/agent-dive.js +0 -52
  457. package/dist/commands/check.js +0 -192
  458. package/dist/commands/map.js +0 -29
  459. package/dist/commands/run.js +0 -104
  460. package/dist/commands/traverse.js +0 -177
  461. package/dist/core/block.d.ts +0 -109
  462. package/dist/core/blocks/effect.js +0 -23
  463. package/dist/core/config.js +0 -17
  464. package/dist/core/engine.d.ts +0 -198
  465. package/dist/core/flow.d.ts +0 -293
  466. package/dist/core/flow.js +0 -432
  467. package/dist/core.d.ts +0 -14
  468. package/dist/core.js +0 -15
  469. package/dist/highlights/merge.d.ts +0 -8
  470. package/dist/highlights/merge.js +0 -173
  471. package/dist/highlights/stub-ctx.d.ts +0 -10
  472. package/dist/highlights/stub-ctx.js +0 -331
  473. package/dist/highlights/types.d.ts +0 -607
  474. package/dist/highlights.d.ts +0 -9
  475. package/dist/highlights.js +0 -10
  476. package/dist/pilot-overlay.d.ts +0 -5
  477. package/dist/pilot-overlay.js +0 -6
  478. package/dist/runner/banner-log.js +0 -63
  479. package/dist/runner/chain-run.js +0 -102
  480. package/dist/runner/cursor.js +0 -140
  481. package/dist/runner/demo-log.js +0 -316
  482. package/dist/runner/device-stage.d.ts +0 -9
  483. package/dist/runner/device-stage.js +0 -420
  484. package/dist/runner/discovery.js +0 -105
  485. package/dist/runner/index.js +0 -2
  486. package/dist/runner/inpage/banner.d.ts +0 -21
  487. package/dist/runner/inpage/banner.js +0 -156
  488. package/dist/runner/inpage/caption.d.ts +0 -3
  489. package/dist/runner/inpage/caption.js +0 -23
  490. package/dist/runner/inpage/core.d.ts +0 -4
  491. package/dist/runner/inpage/core.js +0 -316
  492. package/dist/runner/inpage/device.d.ts +0 -3
  493. package/dist/runner/inpage/device.js +0 -211
  494. package/dist/runner/inpage/network.d.ts +0 -15
  495. package/dist/runner/inpage/network.js +0 -217
  496. package/dist/runner/inpage/panel-chrome.js +0 -192
  497. package/dist/runner/inpage/stamp.js +0 -46
  498. package/dist/runner/inpage/swipe-zoom.js +0 -220
  499. package/dist/runner/inpage/todos.js +0 -337
  500. package/dist/runner/interaction-patch.js +0 -384
  501. package/dist/runner/main.js +0 -469
  502. package/dist/runner/network-capture.d.ts +0 -9
  503. package/dist/runner/network-capture.js +0 -126
  504. package/dist/runner/overlay-css.d.ts +0 -3
  505. package/dist/runner/overlay-css.js +0 -377
  506. package/dist/runner/overlay-install.js +0 -90
  507. package/dist/runner/overlay-stage.js +0 -110
  508. package/dist/runner/rings.js +0 -514
  509. package/dist/runner/seed-mem.js +0 -110
  510. package/dist/runner/slides.js +0 -278
  511. package/dist/runner/step-mode.js +0 -703
  512. package/dist/runner/step-panels.js +0 -729
  513. package/dist/runner/teardown.js +0 -202
  514. package/dist/runner/todo-dock.js +0 -142
  515. package/dist/session/step-overlay.d.ts +0 -37
  516. package/dist/session/step-overlay.js +0 -244
  517. package/examples/routed-demo/playwright.config.ts +0 -21
  518. package/examples/saucedemo/playwright.config.ts +0 -19
  519. package/examples/saucedemo/scripts/drive-auto-cli.mjs +0 -93
  520. package/examples/saucedemo/scripts/prove-add-to-cart-menu.mjs +0 -126
  521. package/examples/saucedemo/scripts/prove-auto-graph.mjs +0 -92
  522. package/examples/saucedemo/scripts/prove-wrong-login-runtime.mjs +0 -63
  523. package/examples/saucedemo/src/blocks/saucedemo-web/ff-owner-auth.block.ts +0 -22
  524. package/templates/quickstart/playwright.config.ts +0 -14
  525. package/templates/quickstart/scripts/drive-auto-cli.mjs +0 -93
  526. package/templates/quickstart/src/blocks/saucedemo-web/ff-owner-auth.block.ts +0 -22
  527. /package/dist/{commands → cli/commands}/agent-dive-scaffold.d.ts +0 -0
  528. /package/dist/{commands → cli/commands}/agent-dive.d.ts +0 -0
  529. /package/dist/{commands → cli/commands}/extensions.d.ts +0 -0
  530. /package/dist/{commands → cli/commands}/init.d.ts +0 -0
  531. /package/dist/{commands → cli/commands}/list.d.ts +0 -0
  532. /package/dist/{commands → cli/commands}/map.d.ts +0 -0
  533. /package/dist/{commands → cli/commands}/session.d.ts +0 -0
  534. /package/dist/{commands → cli/commands}/test.d.ts +0 -0
  535. /package/dist/{commands → cli/commands}/traverse.d.ts +0 -0
  536. /package/dist/{commands → cli/commands}/try.d.ts +0 -0
  537. /package/dist/{commands → cli/commands}/upgrade.d.ts +0 -0
  538. /package/dist/{highlights → demo/narration}/shorthand.js +0 -0
  539. /package/dist/{pilot-overlay/action-ring.d.ts → demo/overlay/pilot/actions.d.ts} +0 -0
  540. /package/dist/{ui → demo/overlay/ui}/components/ring.d.ts +0 -0
  541. /package/dist/{ui → demo/overlay/ui}/stylesheet.d.ts +0 -0
  542. /package/dist/{ui → demo/overlay/ui}/stylesheet.js +0 -0
  543. /package/dist/{ui → demo/overlay/ui}/tokens.d.ts +0 -0
  544. /package/dist/{ui → demo/overlay/ui}/tokens.js +0 -0
  545. /package/dist/{highlights → demo}/types.js +0 -0
  546. /package/dist/{auto-session → demo}/verbose-log.d.ts +0 -0
  547. /package/dist/{selector.d.ts → engine/trait/selector.d.ts} +0 -0
  548. /package/dist/{selector.js → engine/trait/selector.js} +0 -0
  549. /package/dist/{trait.js → engine/trait/trait.js} +0 -0
  550. /package/dist/{session/block-inject.d.ts → manifest/roots.d.ts} +0 -0
  551. /package/dist/{browser.d.ts → runtime/browser.d.ts} +0 -0
  552. /package/dist/{env-file.d.ts → runtime/env-file.d.ts} +0 -0
  553. /package/dist/{playwright-config.js → runtime/playwright-config.js} +0 -0
  554. /package/dist/{playwright.config.d.ts → runtime/playwright.config.d.ts} +0 -0
  555. /package/dist/{video-dir.d.ts → runtime/video-dir.d.ts} +0 -0
  556. /package/dist/{webserver.d.ts → runtime/webserver.d.ts} +0 -0
@@ -0,0 +1,323 @@
1
+ import { installOverlay } from "../overlay/overlay.js";
2
+ import { applyHighlightZoom, captionForLocator, dwellMatchedStub, ensureLocatorInView, hideRing, matchStubIndexForLocator, showRing, wasJustNarrated } from "../overlay/rings.js";
3
+ import { syncTodoDockAdvance } from "./todo-advance.js";
4
+ import { clickPulseAt, moveCursorTo } from "../overlay/cursor.js";
5
+ import { demoHighlight } from "./demo-log.js";
6
+ import { repaintOverlay } from "../overlay/reattach.js";
7
+ import { setLocatorTheater } from "../overlay/locator-theater.js";
8
+ import { envNumber } from "../../engine/env.js";
9
+ import { ignorePageGone, ignoreTimeout } from "../../engine/page-gone.js";
10
+ export function instrumentInteractionHighlighting(page, mem, slowMo, pacing, stubBeforeRef, todoDockRef, deviceRef) {
11
+ // Playwright's own slowMo ALREADY pauses after every single low-level
12
+ // action it dispatches - and pressSequentially() fires one such action
13
+ // PER CHARACTER. Also giving pressSequentially its own fixed delay
14
+ // double-paces every keystroke (45ms + slowMo's own ~350ms, per
15
+ // character) - an ordinary 22-character email alone stretched past 8
16
+ // seconds. When slowMo is already doing the pacing, add none of our own;
17
+ // only fall back to a small typing delay when slowMo is off entirely.
18
+ //
19
+ // pacing.skipTheater (WAYGRAPH_FAST_BLOCKS **or** FFCompose): near-zero
20
+ // cursor / pop / typing - blitz this step. --fast alone sets gatesFast only
21
+ // (shorter Next/autoplay gates) and must NOT skip theater, or the whole demo
22
+ // looks like plain waygraph run.
23
+ const skipTheater = () => !!pacing.skipTheater;
24
+ // `slowMo` here is the demo's own beat: ms to rest after each action (once per call, never per keystroke). The browser
25
+ // itself is launched with slowMo 0 in step mode, so a step whose pace is blitz really does run at full speed.
26
+ const beat = () => (skipTheater() ? 0 : slowMo || 0);
27
+ const pause = (ms) => (ms > 0 ? new Promise((res) => setTimeout(res, ms)) : undefined);
28
+ // Per-character typing delay (WAYGRAPH_TYPING_MS, default 30). 0 for blitz steps.
29
+ const typingMs = () => {
30
+ if (skipTheater())
31
+ return 0;
32
+ const n = envNumber("WAYGRAPH_TYPING_MS");
33
+ return n !== undefined && n >= 0 ? n : 30;
34
+ };
35
+ const typeDelay = typingMs;
36
+ const keyboard = page.keyboard;
37
+ if (!keyboard.__wgBeatPatched) {
38
+ keyboard.__wgBeatPatched = true;
39
+ const originalType = keyboard.type.bind(keyboard);
40
+ keyboard.type = async (text, options) => {
41
+ await originalType(text, { delay: typingMs(), ...(options || {}) });
42
+ await pause(beat());
43
+ };
44
+ const originalPress = keyboard.press.bind(keyboard);
45
+ keyboard.press = async (key, options) => {
46
+ await originalPress(key, options);
47
+ await pause(beat());
48
+ };
49
+ const originalInsertText = keyboard.insertText.bind(keyboard);
50
+ keyboard.insertText = async (text) => {
51
+ await originalInsertText(text);
52
+ await pause(beat());
53
+ };
54
+ }
55
+ // Click is a single action, not per-character, so it doesn't compound
56
+ // the same way - but slowMo still adds its own pause around the actual
57
+ // click, so trim our own explicit "pop" pauses when it's already active
58
+ // rather than stacking a full 1.2s on top of that.
59
+ const clickPrePop = () => (skipTheater() ? 0 : slowMo ? 300 : 700);
60
+ const clickPostPop = () => (skipTheater() ? 0 : slowMo ? 200 : 500);
61
+ // FF / FAST_BLOCKS: no cursor travel animation (0). Plain theater keeps full.
62
+ const cursorMs = (full) => (skipTheater() ? 0 : full);
63
+ // Locator.fill()/click() only ever see a raw call, no context of where
64
+ // the value came from. Patching mem.get() to remember the most recently
65
+ // read key's name (Blocks read-then-immediately-fill, e.g. const { email
66
+ // } = mem.get(LoginInput.key); ...fill(email)) lets the fill patch below
67
+ // label the ring with the real key, not a generic "writing from mem".
68
+ // Patches this ONE mem instance only, not MemPage's shared prototype -
69
+ // there's exactly one mem per chain run.
70
+ const memTrack = { lastKeyName: null, at: 0 };
71
+ const originalGet = mem.get.bind(mem);
72
+ mem.get = (key) => {
73
+ memTrack.lastKeyName = key && key.name;
74
+ memTrack.at = Date.now();
75
+ return originalGet(key);
76
+ };
77
+ const WAIT_CAP_FLOOR_MS = 700;
78
+ const WAIT_CAP_FRACTION = 0.3;
79
+ const scaledWaitCap = (declared) => Math.min(declared, Math.max(WAIT_CAP_FLOOR_MS, declared * WAIT_CAP_FRACTION));
80
+ setLocatorTheater(page, {
81
+ async beforeFill(locator, options) {
82
+ await installOverlay(page);
83
+ await locator.waitFor({
84
+ state: "visible",
85
+ timeout: (options && options.timeout) || 30000,
86
+ }).catch(ignoreTimeout);
87
+ // Smooth scroll before measuring - otherwise off-screen fields
88
+ // teleport when Playwright's fill actionability scrolls.
89
+ await ensureLocatorInView(locator, { instant: skipTheater() });
90
+ const box = await locator.boundingBox();
91
+ let typeLabel = "input";
92
+ try {
93
+ const meta = await locator.evaluate((el) => {
94
+ const id = (el.id || "").toLowerCase();
95
+ const name = (el.getAttribute("name") || "").toLowerCase();
96
+ const ph = (el.getAttribute("placeholder") || "").toLowerCase();
97
+ const ty = (el.getAttribute("type") || "text").toLowerCase();
98
+ if (ty === "password" || /pass/.test(id + name + ph))
99
+ return "password";
100
+ if (/user|email|login/.test(id + name + ph))
101
+ return "username";
102
+ if (ty && ty !== "text")
103
+ return ty;
104
+ return id || name || ph || "input";
105
+ });
106
+ if (meta)
107
+ typeLabel = String(meta);
108
+ }
109
+ catch {
110
+ /* ignore */
111
+ }
112
+ if (box && !(await wasJustNarrated(page))) {
113
+ // Only trust the "last mem.get()" as THIS fill's source if it
114
+ // happened recently - a stale read from several actions ago is
115
+ // more likely unrelated than actually describing this field.
116
+ const fallback = memTrack.lastKeyName && Date.now() - memTrack.at < 3000
117
+ ? "from mem: " + memTrack.lastKeyName
118
+ : "writing from mem";
119
+ const stubs = (stubBeforeRef && stubBeforeRef.current) || [];
120
+ const cap = await captionForLocator(page, locator, stubs, fallback);
121
+ const stubIdx = await matchStubIndexForLocator(page, locator, stubs);
122
+ const stub = stubIdx >= 0 ? stubs[stubIdx] : null;
123
+ await syncTodoDockAdvance(page, todoDockRef, stubIdx, stub);
124
+ await moveCursorTo(page, box, cursorMs(500));
125
+ if (stub) {
126
+ await applyHighlightZoom(page, stub.selector, stub.zoom, stub.zoomOut);
127
+ }
128
+ demoHighlight({
129
+ selector: stub && stub.selector,
130
+ label: cap.label,
131
+ tone: cap.tone || (stub && stub.tone) || "planned",
132
+ color: stub && stub.color,
133
+ focus: !!(stub && stub.focus),
134
+ zoom: stub && stub.zoom,
135
+ zoomOut: stub && stub.zoomOut,
136
+ gesture: stub && stub.gesture,
137
+ weight: cap.weight,
138
+ size: cap.size,
139
+ }, "fill");
140
+ await showRing(page, box, cap.label, cap.tone, {
141
+ size: cap.size,
142
+ weight: cap.weight,
143
+ selector: stub && stub.selector ? stub.selector : undefined,
144
+ focus: !!(stub && stub.focus),
145
+ });
146
+ await dwellMatchedStub(page, locator, stubs, pacing);
147
+ await new Promise((res) => setTimeout(res, skipTheater() ? 0 : 200));
148
+ if (cap && cap.label)
149
+ typeLabel = String(cap.label).slice(0, 40);
150
+ }
151
+ else if (box) {
152
+ // Ring/caption already handled by narrate() - still move the
153
+ // cursor there, just skip re-showing the ring with a generic label.
154
+ await moveCursorTo(page, box, cursorMs(200));
155
+ }
156
+ await page
157
+ .evaluate((label) => {
158
+ if (window.__wgSetTypingBadge)
159
+ window.__wgSetTypingBadge(true, label);
160
+ }, typeLabel)
161
+ .catch(ignorePageGone);
162
+ },
163
+ typingDelay: typeDelay,
164
+ async afterFill() {
165
+ await page
166
+ .evaluate(() => {
167
+ if (window.__wgSetTypingBadge)
168
+ window.__wgSetTypingBadge(false);
169
+ })
170
+ .catch(ignorePageGone);
171
+ // Fade the ring back out once this field is actually done, instead
172
+ // of leaving it lit until the next Block's own before-panel clears
173
+ // it - it was sticking around through the whole rest of the step.
174
+ await hideRing(page);
175
+ await repaintOverlay(page);
176
+ await pause(beat());
177
+ },
178
+ async beforeClick(locator, options) {
179
+ let clickPoint = null;
180
+ let clickTone = "auto";
181
+ await installOverlay(page);
182
+ // Wait until the target is visible BEFORE measuring - otherwise
183
+ // defineNavBlock({ click }) (and any slow-to-appear control) skips
184
+ // the cursor entirely: boundingBox was null, then originalClick
185
+ // waited and clicked with no demo animation.
186
+ await locator.waitFor({
187
+ state: "visible",
188
+ timeout: (options && options.timeout) || 30000,
189
+ }).catch(ignoreTimeout);
190
+ // Smooth-scroll off-screen targets before cursor/ring. Playwright's
191
+ // own click scroll is instant and reads as a teleport under --fast.
192
+ await ensureLocatorInView(locator, { instant: skipTheater() });
193
+ const box = await locator.boundingBox();
194
+ const narrated = box ? await wasJustNarrated(page) : false;
195
+ if (box && !narrated) {
196
+ let fallback = "click";
197
+ try {
198
+ const text = (await locator.textContent())?.trim();
199
+ if (text && text.length > 0 && text.length <= 30)
200
+ fallback = text;
201
+ }
202
+ catch {
203
+ // element has no simple text (an icon button, say) - generic label is fine
204
+ }
205
+ // Prefer "nav: …" when this locator is a NavBlock click target
206
+ // (set on page by runStepMode just before act).
207
+ const navLabel = await page.evaluate(() => window.__wgPendingNavClickLabel || null).catch(ignorePageGone);
208
+ if (navLabel)
209
+ fallback = String(navLabel);
210
+ const stubs = (stubBeforeRef && stubBeforeRef.current) || [];
211
+ const cap = await captionForLocator(page, locator, stubs, fallback);
212
+ const stubIdx = await matchStubIndexForLocator(page, locator, stubs);
213
+ const stub = stubIdx >= 0 ? stubs[stubIdx] : null;
214
+ await syncTodoDockAdvance(page, todoDockRef, stubIdx, stub);
215
+ clickTone = cap.tone;
216
+ clickPoint = await moveCursorTo(page, box, cursorMs(600));
217
+ if (stub) {
218
+ await applyHighlightZoom(page, stub.selector, stub.zoom, stub.zoomOut);
219
+ }
220
+ demoHighlight({
221
+ selector: stub && stub.selector,
222
+ label: cap.label,
223
+ tone: cap.tone || (stub && stub.tone) || "planned",
224
+ color: stub && stub.color,
225
+ focus: !!(stub && stub.focus),
226
+ zoom: stub && stub.zoom,
227
+ zoomOut: stub && stub.zoomOut,
228
+ gesture: stub && stub.gesture,
229
+ weight: cap.weight,
230
+ size: cap.size,
231
+ }, "click");
232
+ await showRing(page, box, cap.label, cap.tone, {
233
+ size: cap.size,
234
+ weight: cap.weight,
235
+ selector: stub && stub.selector ? stub.selector : undefined,
236
+ focus: !!(stub && stub.focus),
237
+ });
238
+ await dwellMatchedStub(page, locator, stubs, pacing);
239
+ // "pop for a few seconds" - the user's own phrase, matching the
240
+ // zsign demo-engine's ring-before-click pattern in
241
+ // services/help-center-clip-engine's video-pipeline.
242
+ await new Promise((res) => setTimeout(res, clickPrePop()));
243
+ }
244
+ else if (box) {
245
+ // Ring/caption already handled by narrate() - still move the
246
+ // cursor + pulse the click point, just skip re-showing the ring.
247
+ clickPoint = await moveCursorTo(page, box, cursorMs(200));
248
+ clickTone = "planned";
249
+ }
250
+ if (clickPoint) {
251
+ await clickPulseAt(page, clickPoint.x, clickPoint.y, clickTone);
252
+ // clickPulseAt only triggers the CSS animation class - it doesn't
253
+ // wait for it. Without a pause here, the real click (and any
254
+ // resulting navigation/DOM change) fires while the ripple is still
255
+ // mid-animation, sometimes cutting it off before it's even visible.
256
+ // Wait out the same .5s the "@keyframes wg-pulse" rule uses, so the
257
+ // mock click visually completes before the real one fires.
258
+ await new Promise((res) => setTimeout(res, skipTheater() ? 0 : 500));
259
+ }
260
+ // Touch theater (0.13+): prefer Locator.tap / long-press when device
261
+ // touchMode is on (context launched with hasTouch). gesture on stub
262
+ // wins: tap | hold | click.
263
+ const stubs = (stubBeforeRef && stubBeforeRef.current) || [];
264
+ const touch = !!(deviceRef && deviceRef.current && deviceRef.current.touchMode);
265
+ const idx = await matchStubIndexForLocator(page, locator, stubs).catch(() => -1);
266
+ const stub = idx >= 0 ? stubs[idx] : null;
267
+ if (stub && (stub.gesture === "tap" || stub.gesture === "hold" || stub.gesture === "click"))
268
+ return stub.gesture;
269
+ return touch ? "tap" : "click";
270
+ },
271
+ holdMs: () => (skipTheater() ? 0 : 600),
272
+ async afterClick() {
273
+ await new Promise((res) => setTimeout(res, clickPostPop()));
274
+ await hideRing(page);
275
+ // Full document navigation drops #wg-todo-dock + rings; restore carry.
276
+ await repaintOverlay(page);
277
+ await pause(beat());
278
+ },
279
+ // Caps any Locator.waitFor()/page.waitForTimeout() timeout during step
280
+ // mode - a Block polling for something that will NEVER happen (e.g. "is
281
+ // there an unverified-account banner" on an account that IS verified)
282
+ // has no choice but to wait out its own hardcoded timeout in full before
283
+ // concluding "no". Only the WAIT gets capped, never the real outcome -
284
+ // if the thing genuinely appears at 800ms into a 5000ms wait, waitFor
285
+ // still resolves at 800ms same as always; this only shortens the "it's
286
+ // just never going to happen" case. Plain setTimeout()-based sleep()
287
+ // helpers some Blocks use for their own pacing are NOT Playwright calls
288
+ // at all and can't be touched this way - a real, disclosed limit, not
289
+ // silently ignored.
290
+ // Pushed down to 700ms earlier this session based on login.block.ts
291
+ // alone - every waitFor() there is a "give up gracefully" pattern
292
+ // (wrapped in .catch()/Promise.race, a timeout IS the expected negative
293
+ // result). That's a different kind of wait than a REQUIRED
294
+ // synchronization point with no catch - e.g. overview-metrics.block.ts
295
+ // waits (uncaught) for a "Loading pending actions..." placeholder to
296
+ // actually appear before it's safe to check for an error, a real
297
+ // hydration signal the block's own comment calls "deterministic,"
298
+ // not a probe. A flat 700ms cap broke that block outright on this
299
+ // shared, loaded box (a real 3-block chain run threw instead of
300
+ // catching). Bumping the SAME flat cap to 4000ms to cover it just
301
+ // reintroduced most of the original torture on login.block.ts's own
302
+ // 5000ms unverified-email check - 4000ms is barely better than the real
303
+ // 5000ms it's capping.
304
+ //
305
+ // A single flat number can't serve both: it has no way to tell "safe to
306
+ // cut short" from "must actually happen" apart from the outside. But
307
+ // each call site's OWN declared timeout is already a real signal of
308
+ // which kind it is - a Block author who wrote timeout: 5000 for a quick
309
+ // conditional check and one who wrote timeout: 15000 for a real
310
+ // hydration wait weren't picking the same number by accident. Scale the
311
+ // cap off that instead of a single constant: 30% of whatever was
312
+ // declared, never below a 700ms floor (the value already proven safe
313
+ // for the fast/common case), and never above what was declared in the
314
+ // first place. login's 5000ms check -> 1500ms (still 3.5s faster than
315
+ // uncapped). overview-metrics' 15000ms wait -> 4500ms (more headroom
316
+ // than the flat 4000ms fix, not less).
317
+ capWait: scaledWaitCap,
318
+ // A plain sleep (not a "wait for condition X") never has a hidden
319
+ // "must actually happen" requirement attached - always safe to cut
320
+ // to the floor, no scaling needed.
321
+ capSleep: (ms) => Math.min(ms, WAIT_CAP_FLOOR_MS),
322
+ });
323
+ }
@@ -0,0 +1,21 @@
1
+ import type { DemoPace } from "../../engine/stub/pace.js";
2
+ export interface Pacing {
3
+ /** Shorter Next gates (keeps the smooth cursor). */
4
+ gatesFast: boolean;
5
+ gatesSlow: boolean;
6
+ /** Skip the overlay's added dwell entirely (blitz, fast-forward, WAYGRAPH_FAST_BLOCKS). */
7
+ skipTheater: boolean;
8
+ demoPace: DemoPace;
9
+ }
10
+ export declare function newPacing(demoFast: boolean): Pacing;
11
+ interface PacedStep {
12
+ block: {
13
+ name: string;
14
+ demoPace?: DemoPace | string | number | null;
15
+ fastForward?: boolean;
16
+ };
17
+ demoPace?: DemoPace | undefined;
18
+ wasFastForward?: boolean | undefined;
19
+ }
20
+ export declare function paceStep(pacing: Pacing, step: PacedStep, demoFast: boolean, fastBlocks: Set<string>): void;
21
+ export {};
@@ -0,0 +1,23 @@
1
+ import { demoPaceIsBlitz, demoPaceIsFast, demoPaceIsSlow, normalizeDemoPace, resolveStepDemoPace } from "../narration/demo-pace.js";
2
+ import { envString } from "../../engine/env.js";
3
+ export function newPacing(demoFast) {
4
+ return { gatesFast: demoFast, gatesSlow: false, skipTheater: false, demoPace: "normal" };
5
+ }
6
+ const isSet = (pace) => pace != null && pace !== "";
7
+ export function paceStep(pacing, step, demoFast, fastBlocks) {
8
+ const defaultPace = envString("WAYGRAPH_DEMO_PACE") ? normalizeDemoPace(envString("WAYGRAPH_DEMO_PACE")) : undefined;
9
+ const fastForward = !!step.block.fastForward || !!step.wasFastForward;
10
+ const flowPace = step.demoPace ?? defaultPace;
11
+ const stepPace = resolveStepDemoPace({
12
+ ...(step.block.demoPace !== undefined ? { blockPace: step.block.demoPace } : {}),
13
+ ...(flowPace !== undefined ? { flowPace } : {}),
14
+ fastForward: !!step.block.fastForward,
15
+ wasFastForward: !!step.wasFastForward,
16
+ });
17
+ const authoredPace = isSet(step.block.demoPace) || isSet(step.demoPace) || defaultPace != null;
18
+ const listedFast = fastBlocks.has(step.block.name);
19
+ pacing.demoPace = stepPace === "normal" && (demoFast || listedFast) && !authoredPace ? (listedFast ? "blitz" : "fast") : stepPace;
20
+ pacing.gatesFast = demoPaceIsFast(pacing.demoPace) || fastForward || (!authoredPace && demoFast);
21
+ pacing.gatesSlow = demoPaceIsSlow(pacing.demoPace);
22
+ pacing.skipTheater = demoPaceIsBlitz(pacing.demoPace) || listedFast || fastForward;
23
+ }
@@ -0,0 +1,11 @@
1
+ import type { WgPage } from "../types.js";
2
+ /**
3
+ * Multi-step yap captions - not block lifecycle. Each slide waits for Next
4
+ * (or auto-next), optional ring via slide.selector.
5
+ *
6
+ * Advance wait does NOT use exposeFunction/gate(): after a real navigation
7
+ * (e.g. finish-order -> checkout-complete) the panel can render while
8
+ * __wgNext is momentarily wedged, which left "Next slide" looking live but
9
+ * doing nothing. In-page data-wg-acked + autoplay poll is the source of truth.
10
+ */
11
+ export declare function presentSlides(page: WgPage, slides: any, _gate: any, opts: any): Promise<void>;
@@ -0,0 +1,233 @@
1
+ import { demoPaceGateMs, formatDemoPaceBadge, formatDemoPaceLabel, normalizeDemoPace, resolveFixtureDwellMs } from "../narration/demo-pace.js";
2
+ import { formatHighlightCaption } from "../narration/style.js";
3
+ import { normalizeHighlightSize, normalizeHighlightTone, normalizeHighlightWeight } from "../../engine/stub/ring.js";
4
+ import { installOverlay } from "../overlay/overlay.js";
5
+ import { applyHighlightZoom, ensureSelectorInView, hideRing, showRing } from "../overlay/rings.js";
6
+ import { demoPaceKind } from "./demo-log.js";
7
+ import { envFlag, envNumber, envString } from "../../engine/env.js";
8
+ /**
9
+ * Multi-step yap captions - not block lifecycle. Each slide waits for Next
10
+ * (or auto-next), optional ring via slide.selector.
11
+ *
12
+ * Advance wait does NOT use exposeFunction/gate(): after a real navigation
13
+ * (e.g. finish-order -> checkout-complete) the panel can render while
14
+ * __wgNext is momentarily wedged, which left "Next slide" looking live but
15
+ * doing nothing. In-page data-wg-acked + autoplay poll is the source of truth.
16
+ */
17
+ export async function presentSlides(page, slides, _gate, opts) {
18
+ const title = (opts && opts.title) || "waygraph demo";
19
+ const blockName = (opts && opts.blockName) || "";
20
+ const episodeNumber = opts && opts.episodeNumber;
21
+ const episodeTitle = (opts && opts.episodeTitle) || "";
22
+ const gatesFast = !!(opts && opts.fast);
23
+ const demoPace = normalizeDemoPace((opts && opts.pace) || (gatesFast ? "fast" : "normal"));
24
+ const baseAutoplay = opts && opts.autoplayMs
25
+ ? Number(opts.autoplayMs)
26
+ : (envNumber("WAYGRAPH_AUTOPLAY_MS") ?? 1800);
27
+ const autoplayMs = demoPaceGateMs(demoPace, baseAutoplay);
28
+ for (let i = 0; i < slides.length; i++) {
29
+ const s = slides[i];
30
+ const caption = formatHighlightCaption(s);
31
+ const slideTone = normalizeHighlightTone(s.tone);
32
+ const slideStyle = {
33
+ size: normalizeHighlightSize(s.size),
34
+ weight: normalizeHighlightWeight(s.weight),
35
+ };
36
+ const isLast = i === slides.length - 1;
37
+ const dwellMs = resolveFixtureDwellMs(s, { gatesFast, pace: demoPace });
38
+ await installOverlay(page, title);
39
+ if (s.selector) {
40
+ try {
41
+ await ensureSelectorInView(page, s.selector);
42
+ await applyHighlightZoom(page, s.selector, s.zoom, s.zoomOut);
43
+ // Playwright's own locator (>> piercing / :has-text() / :visible support), not a raw
44
+ // querySelector string - see rings.js's showRing for the same fix, same reason. count()
45
+ // gate: Locator.evaluate() has no timeout option and auto-waits ~30s for a match to
46
+ // appear - count() never waits, keeping this an immediate "does it exist now" check.
47
+ const sLoc = page.locator(s.selector).first();
48
+ const box = (await sLoc.count().catch(() => 0)) > 0
49
+ ? await sLoc
50
+ .evaluate((el) => {
51
+ const r = el.getBoundingClientRect();
52
+ return { x: r.x, y: r.y, width: r.width, height: r.height };
53
+ })
54
+ .catch(() => null)
55
+ : null;
56
+ if (box && box.width > 0 && box.height > 0) {
57
+ await showRing(page, box, caption, slideTone, {
58
+ ...slideStyle,
59
+ selector: s.selector,
60
+ focus: !!s.focus,
61
+ });
62
+ }
63
+ }
64
+ catch {
65
+ await hideRing(page);
66
+ }
67
+ }
68
+ else {
69
+ await hideRing(page);
70
+ }
71
+ await page.evaluate((info) => {
72
+ let panel = __wgById("wg-panel");
73
+ const isNew = !panel;
74
+ if (!panel) {
75
+ panel = document.createElement("div");
76
+ panel.id = "wg-panel";
77
+ }
78
+ panel.classList.remove("wg-error", "wg-expected");
79
+ // Do not clear wg-collapsed - WirePanelChrome honors Hide (localStorage)
80
+ // unless forceCollapsed:true (--mini / --video).
81
+ const episodeLine = info.episodeNumber !== undefined && info.episodeNumber !== null
82
+ ? __wgEl("div", { class: "wg-episode" }, "Episode " + info.episodeNumber + (info.episodeTitle ? ": " + info.episodeTitle : "") + " · yap slides")
83
+ : null;
84
+ const pace = info.paceBadge || info.paceLabel
85
+ ? __wgEl("div", { class: "wg-pace", data: { paceKind: info.paceKind || "normal" } }, __wgEl("span", { class: "wg-pace-badge" }, info.paceBadge || "1x"), __wgEl("span", null, info.paceLabel || ""))
86
+ : null;
87
+ const autoplay = __wgEl("input", { id: "wg-autoplay-cb", attrs: { type: "checkbox" } });
88
+ autoplay.checked = !!info.autoNow;
89
+ const run = __wgEl("button", { id: "wg-run", attrs: { type: "button" } }, info.isLast ? "Continue \u25B6" : "Next slide \u25B6");
90
+ run.disabled = info.dwellMs != null;
91
+ __wgSet(panel, __wgEl("div", { class: "wg-chrome" }, __wgEl("span", { class: "wg-chrome-title" }, "waygraph demo"), __wgEl("button", { class: "wg-hide-btn", data: { wgToggle: "1" }, attrs: { type: "button" } }, "Hide")), __wgEl("div", { class: "wg-body" }, episodeLine, pace, __wgEl("h3", null, "Slide " + (info.index + 1) + " / " + info.total + (info.blockName ? " · " + info.blockName : "")), info.tag ? __wgEl("div", { style: "border:none;padding:0;margin:0 0 6px;font-size:11px;color:#c9a6ff" }, info.tag) : null, __wgEl("div", { class: "wg-narration" }, String(info.caption)), info.detail ? __wgEl("div", { class: "wg-result-pretty", style: "margin:0 0 12px;color:#f0e8ff" }, info.detail) : null, info.dwellMs != null
92
+ ? __wgEl("div", { class: "wg-auto", id: "wg-dwell-hint", style: "margin:0 0 8px" }, "Hold " + (info.dwellMs / 1000).toFixed(1) + "s before next...")
93
+ : null, __wgEl("div", { class: "wg-autoplay-row" }, __wgEl("label", null, autoplay, " Auto-advance")), __wgEl("div", { id: "wg-gate-manual", style: info.autoNow ? "display:none" : "" }, run), __wgEl("div", { id: "wg-gate-auto", class: "wg-auto", style: info.autoNow ? "" : "display:none" }, "Auto-advancing...")));
94
+ if (isNew) {
95
+ __wgAdd(panel);
96
+ requestAnimationFrame(() => panel.classList.add("wg-in"));
97
+ }
98
+ if (window.__wgWirePanelChrome) {
99
+ window.__wgWirePanelChrome(panel, "wg-panel-hidden", "waygraph demo", {
100
+ stepLabel: (info.episodeNumber !== undefined && info.episodeNumber !== null
101
+ ? "Ep " + info.episodeNumber + " \u00b7 "
102
+ : "") +
103
+ "Slide " +
104
+ (info.index + 1) +
105
+ " / " +
106
+ info.total +
107
+ (info.blockName ? " \u00b7 " + info.blockName : ""),
108
+ // Video / --mini: compact pill. Else omit so Hide sticks.
109
+ forceCollapsed: info.forceCollapsed === true ? true : undefined,
110
+ });
111
+ }
112
+ if (window.__wgStampModal) {
113
+ window.__wgStampModal(panel, "panel", {
114
+ phase: "slide",
115
+ step: info.index + 1,
116
+ total: info.total,
117
+ block: info.blockName || "",
118
+ ready: true,
119
+ });
120
+ }
121
+ let autoNow = false;
122
+ try {
123
+ autoNow = localStorage.getItem("wg-autoplay") === "1";
124
+ }
125
+ catch {
126
+ /* ignore */
127
+ }
128
+ const cb = __wgById("wg-autoplay-cb");
129
+ if (cb) {
130
+ cb.checked = autoNow;
131
+ cb.addEventListener("change", () => {
132
+ try {
133
+ localStorage.setItem("wg-autoplay", cb.checked ? "1" : "0");
134
+ }
135
+ catch {
136
+ /* ignore */
137
+ }
138
+ const manual = __wgById("wg-gate-manual");
139
+ const auto = __wgById("wg-gate-auto");
140
+ if (manual)
141
+ manual.style.display = cb.checked ? "none" : "";
142
+ if (auto)
143
+ auto.style.display = cb.checked ? "" : "none";
144
+ });
145
+ }
146
+ const manual = __wgById("wg-gate-manual");
147
+ const auto = __wgById("wg-gate-auto");
148
+ if (manual)
149
+ manual.style.display = autoNow ? "none" : "";
150
+ if (auto)
151
+ auto.style.display = autoNow ? "" : "none";
152
+ const runBtn = __wgById("wg-run");
153
+ if (runBtn) {
154
+ runBtn.removeAttribute("data-wg-acked");
155
+ runBtn.addEventListener("click", (e) => {
156
+ e.preventDefault();
157
+ e.stopPropagation();
158
+ if (runBtn.disabled)
159
+ return;
160
+ runBtn.setAttribute("data-wg-acked", "1");
161
+ });
162
+ }
163
+ if (info.dwellMs != null && info.dwellMs > 0) {
164
+ const unlockAt = Date.now() + info.dwellMs;
165
+ const tick = () => {
166
+ const left = Math.max(0, unlockAt - Date.now());
167
+ const hint = __wgById("wg-dwell-hint");
168
+ const btn = __wgById("wg-run");
169
+ if (left <= 0) {
170
+ if (hint)
171
+ hint.remove();
172
+ if (btn)
173
+ btn.disabled = false;
174
+ return;
175
+ }
176
+ if (hint)
177
+ hint.textContent = "Hold " + (left / 1000).toFixed(1) + "s before next...";
178
+ setTimeout(tick, 100);
179
+ };
180
+ setTimeout(tick, 100);
181
+ }
182
+ }, {
183
+ index: i,
184
+ total: slides.length,
185
+ caption: s.caption,
186
+ detail: s.detail || "",
187
+ tag: s.tag || "",
188
+ blockName,
189
+ isLast,
190
+ autoNow: false,
191
+ dwellMs,
192
+ episodeNumber: episodeNumber !== undefined ? episodeNumber : null,
193
+ episodeTitle,
194
+ paceBadge: formatDemoPaceBadge(demoPace, baseAutoplay),
195
+ paceLabel: formatDemoPaceLabel(demoPace, baseAutoplay),
196
+ paceKind: demoPaceKind(demoPace),
197
+ forceCollapsed: !!envString("WAYGRAPH_VIDEO") ||
198
+ envFlag("WAYGRAPH_MINI")
199
+ ? true
200
+ : undefined,
201
+ });
202
+ const started = Date.now();
203
+ // When duration is set: floor both manual Next and auto-next to dwellMs.
204
+ // When unset: auto uses autoplayMs, manual Next is immediate.
205
+ const autoWaitMs = dwellMs != null ? dwellMs : autoplayMs;
206
+ for (;;) {
207
+ const acked = await page
208
+ .evaluate(() => {
209
+ const btn = __wgById("wg-run");
210
+ return !!(btn && btn.getAttribute("data-wg-acked") === "1");
211
+ })
212
+ .catch(() => false);
213
+ if (acked) {
214
+ if (dwellMs == null || Date.now() - started >= dwellMs)
215
+ break;
216
+ }
217
+ const auto = await page
218
+ .evaluate(() => {
219
+ try {
220
+ return localStorage.getItem("wg-autoplay") === "1";
221
+ }
222
+ catch {
223
+ return false;
224
+ }
225
+ })
226
+ .catch(() => false);
227
+ if (auto && Date.now() - started >= autoWaitMs)
228
+ break;
229
+ await new Promise((res) => setTimeout(res, 100));
230
+ }
231
+ }
232
+ await hideRing(page);
233
+ }
@@ -0,0 +1,21 @@
1
+ import type { WgPage } from "../types.js";
2
+ export declare function renderBeforeStep(page: WgPage, info: any): Promise<void>;
3
+ /**
4
+ * stubOnError rings + amber "expected outcome" / red error panel, then wait
5
+ * for Stop/Retry. Used when a step throws OR when a `map({ expectedFailure })` flow's last
6
+ * block succeeds on the intentional fail branch (e.g. LoginPage + error banner).
7
+ */
8
+ export declare function presentFailPanel(page: WgPage, opts: any): Promise<any>;
9
+ export declare function renderAfterStep(page: WgPage, info: any): Promise<void>;
10
+ /**
11
+ * Recovers a DOM selector from a built-in Trait's own .name string -
12
+ * visible(sel) / text-equals(sel, "...") - since Trait.check itself is
13
+ * an opaque closure with no selector field of its own. Best-effort only: a
14
+ * hand-written bespoke Trait, or url-matches(...) (no DOM target), yields
15
+ * nothing to highlight, which is fine - the panel still shows the result.
16
+ */
17
+ export declare function extractVerifyHighlights(block: any, resultTag: any): {
18
+ selector: string | undefined;
19
+ label: string;
20
+ tone: string;
21
+ }[];