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
@@ -1,729 +0,0 @@
1
- // Moved verbatim from the former CHAIN_RUNNER_SCRIPT template string in cli.ts (see src/ARCHITECTURE.md).
2
- // Runs inside the target project's own waygraph copy - keep it dependency-light and self-contained.
3
- import { installOverlay } from "./overlay-install.js";
4
- import { join } from "node:path";
5
- import { applyHighlightStyleDefaults, formatHighlightCaption, hasAuthoredStubOnError, normalizeHighlightTone, runStubPhase } from "../highlights.js";
6
- import { cycleHighlightRings } from "./rings.js";
7
-
8
- export async function renderBeforeStep(page, info) {
9
- await installOverlay(page, info.title, info.bannerUi, info.caption, info.networkTabVisible);
10
- // A ring left highlighting the PREVIOUS step's element (and its live
11
- // resize/scroll tracker) shouldn't linger once a new step's own panel is
12
- // up - only relevant when a Block's act() doesn't navigate away, since a
13
- // real navigation already wipes document.documentElement's children.
14
- await page
15
- .evaluate(() => {
16
- if (window.__wgRingTrack) {
17
- window.removeEventListener("resize", window.__wgRingTrack);
18
- window.removeEventListener("scroll", window.__wgRingTrack, true);
19
- window.__wgRingTrack = null;
20
- }
21
- if (window.__wgHideRing) window.__wgHideRing();
22
- if (window.__wgHideCursor) window.__wgHideCursor();
23
- })
24
- .catch(() => {});
25
- // miniStepLabel / todosHtmlFromInfo are Node-only — browser evaluate has no closure.
26
- const payload = { ...info, stepLabel: miniStepLabel(info) };
27
- await page
28
- .evaluate((info) => {
29
- // Reused in place, not removed + recreated, every step - the old
30
- // remove()-then-fade-back-in cycle was a real flash on every single
31
- // transition (Dan: "the appear and disappear... hurts eyes and
32
- // dizzy"). Updating one persistent element's content has nothing to
33
- // flash - it only ever fades in ONCE, the first time this page
34
- // genuinely has no panel yet (a real navigation wiped the whole
35
- // document, or this is the very first step).
36
- let panel = __wgById("wg-panel");
37
- const isNewPanel = !panel;
38
- if (!panel) {
39
- panel = document.createElement("div");
40
- panel.id = "wg-panel";
41
- }
42
- const pct = Math.round((info.index / info.total) * 100);
43
- const esc = (s) => String(s).replace(/&/g, "&amp;").replace(/"/g, "&quot;").replace(/</g, "&lt;");
44
- // A real tab bar, not a single text line - every episode this chain
45
- // touches, the current one reading as active (Dan: "if episode 1 is
46
- // active, the episode 2 tab is inactive"). Absent entirely for an ad
47
- // hoc block chain with no named Flows.
48
- const episodesHtml = info.allEpisodes && info.allEpisodes.length > 0
49
- ? "<div id=\"wg-episodes\">" +
50
- info.allEpisodes
51
- .map((e) => {
52
- const cls = e.episodeNumber < info.episodeNumber ? "wg-ep-done"
53
- : e.episodeNumber === info.episodeNumber ? "wg-ep-current"
54
- : "wg-ep-upcoming";
55
- // The gentle one-time glow only plays on the tab actually
56
- // being entered right now, not on every render of it.
57
- const enteredCls = info.justEnteredEpisode && e.episodeNumber === info.episodeNumber
58
- ? " wg-ep-entered"
59
- : "";
60
- return "<span class=\"wg-ep-tab " + cls + enteredCls + "\">Episode " + e.episodeNumber + ": " +
61
- esc(e.episodeTitle || "") + "</span>";
62
- })
63
- .join("") +
64
- "</div>"
65
- : "";
66
- // Scoped to THIS episode's own blocks (info.allNames is already the
67
- // episode-local subset the caller computed) - moduleIndex is this
68
- // step's position WITHIN that subset, not the whole chain's index -
69
- // "in episode 2 it shows 2nd to the last... it should start from the
70
- // first block" (Dan).
71
- const modulesClass = info.stepperMode === "full" ? "wg-modules-full" : "wg-modules-carousel";
72
- const modulesHtml = info.allNames
73
- .map((name, idx) => {
74
- const cls = idx < info.moduleIndex ? "wg-mod-done" : idx === info.moduleIndex ? "wg-mod-current" : "wg-mod-upcoming";
75
- const desc = info.allDescriptions && info.allDescriptions[idx];
76
- const titleAttr = desc ? " title=\"" + esc(desc) + "\"" : "";
77
- return "<span class=\"wg-mod " + cls + "\"" + titleAttr + ">" + name + "</span>";
78
- })
79
- .join("");
80
- const narrationHtml = info.description
81
- ? "<div class=\"wg-narration\">" + esc(info.description) + "</div>"
82
- : "";
83
- const paceHtml =
84
- info.paceBadge || info.paceLabel
85
- ? "<div class=\"wg-pace\" data-pace-kind=\"" +
86
- esc(info.paceKind || "normal") +
87
- "\"><span class=\"wg-pace-badge\">" +
88
- esc(info.paceBadge || "1x") +
89
- "</span><span>" +
90
- esc(info.paceLabel || "") +
91
- "</span></div>"
92
- : "";
93
- // Todos render into floating #wg-todo-dock via __wgSyncTodos - never
94
- // inside .wg-body (would vanish under --mini / Hide collapse).
95
- let html =
96
- "<div id=\"wg-progress\"><div id=\"wg-progress-bar\" style=\"width:" + pct + "%\"></div></div>" +
97
- episodesHtml +
98
- paceHtml +
99
- "<div id=\"wg-modules\" class=\"" + modulesClass + "\">" + modulesHtml + "</div>" +
100
- "<h3>Step " + (info.index + 1) + " / " + info.total + " - " + info.blockName + "</h3>" +
101
- narrationHtml;
102
- if (info.keys.length === 0) {
103
- html += "<div class=\"wg-key\">(no MemKeys required)</div>";
104
- }
105
- for (const k of info.keys) {
106
- html +=
107
- "<div class=\"wg-key\"><label>" + k.name + "</label>" +
108
- "<textarea data-key=\"" + k.name + "\" rows=\"2\">" +
109
- k.value.replace(/</g, "&lt;") + "</textarea>" +
110
- "<div class=\"wg-key-pretty\" data-pretty-for=\"" + esc(k.name) + "\"></div>" +
111
- "</div>";
112
- }
113
- let autoNow = false;
114
- try {
115
- autoNow = localStorage.getItem("wg-autoplay") === "1";
116
- } catch {
117
- /* private mode / blocked storage - defaults to manual */
118
- }
119
- html +=
120
- "<div class=\"wg-autoplay-row\"><label><input type=\"checkbox\" id=\"wg-autoplay-cb\"" +
121
- (autoNow ? " checked" : "") +
122
- "> Auto-advance</label></div>" +
123
- "<div id=\"wg-gate-manual\"" + (autoNow ? " style=\"display:none\"" : "") +
124
- "><button id=\"wg-run\">Run this step \u25B6</button></div>" +
125
- "<div id=\"wg-gate-auto\" class=\"wg-auto\"" + (autoNow ? "" : " style=\"display:none\"") +
126
- ">Auto-advancing...</div>";
127
- panel.innerHTML = html;
128
- if (isNewPanel) {
129
- __wgAdd(panel);
130
- requestAnimationFrame(() => panel.classList.add("wg-in"));
131
- } else {
132
- panel.classList.add("wg-in");
133
- }
134
- if (window.__wgWirePanelChrome) {
135
- window.__wgWirePanelChrome(panel, "wg-panel-hidden", "waygraph demo", {
136
- stepLabel: info.stepLabel || "",
137
- forceCollapsed: info.forceCollapsed === true ? true : undefined,
138
- fastForward: !!info.fastForward,
139
- isApi: !!info.isApi,
140
- });
141
- }
142
- if (window.__wgSyncTodos) {
143
- const sync = info.todoSync || (info.todos && info.todos.length ? "set" : "keep");
144
- // Prefer dock-only payload. Passing list:[] with a dock used to clear
145
- // marks a frame later (empty-list clear path).
146
- if (sync === "keep" && !info.todoDock) {
147
- /* leave floating dock alone */
148
- } else {
149
- const payload = {
150
- sync: sync,
151
- dock: info.todoDock || null,
152
- pos: info.todoPos || null,
153
- todoId: info.todoId || (info.todoDock && info.todoDock.id) || null,
154
- };
155
- if (!info.todoDock && info.todos && info.todos.length) {
156
- payload.list = info.todos;
157
- }
158
- window.__wgSyncTodos(payload);
159
- }
160
- }
161
- if (window.__wgStampModal) {
162
- window.__wgStampModal(panel, "panel", {
163
- phase: "before",
164
- step: info.index + 1,
165
- total: info.total,
166
- block: info.blockName || "",
167
- ready: true,
168
- });
169
- }
170
- // Live, human-readable preview of what a MemKey's raw JSON will
171
- // actually write - object fields become "Field: value" lines
172
- // (camelCase split the same way state tags already are); a
173
- // non-object payload (a plain string/number/array) is shown as-is.
174
- // Hidden entirely in JSON mode - shares the SAME global toggle the
175
- // result display's own Pretty/JSON buttons already set, not a
176
- // second, separate preference.
177
- const prettyMemValue = (raw) => {
178
- let parsed;
179
- try {
180
- parsed = JSON.parse(raw);
181
- } catch {
182
- return "<em>(invalid JSON)</em>";
183
- }
184
- if (parsed === null || typeof parsed !== "object" || Array.isArray(parsed)) {
185
- return esc(JSON.stringify(parsed));
186
- }
187
- return Object.entries(parsed)
188
- .map(([field, value]) => {
189
- const label = field.replace(/([a-z0-9])([A-Z])/g, "$1 $2").replace(/^./, (c) => c.toUpperCase());
190
- return "<div class=\"wg-key-pretty-row\"><span class=\"wg-key-pretty-label\">" +
191
- esc(label) + ":</span> " + esc(String(value)) + "</div>";
192
- })
193
- .join("");
194
- };
195
- const applyKeyPretty = () => {
196
- const prettyOn = window.__wgPretty !== false;
197
- panel.querySelectorAll("textarea[data-key]").forEach((ta) => {
198
- const key = ta.getAttribute("data-key");
199
- const previewEl = panel.querySelector(".wg-key-pretty[data-pretty-for=\"" + key + "\"]");
200
- if (!previewEl) return;
201
- previewEl.style.display = prettyOn ? "" : "none";
202
- if (prettyOn) previewEl.innerHTML = prettyMemValue(ta.value);
203
- });
204
- };
205
- applyKeyPretty();
206
- panel.querySelectorAll("textarea[data-key]").forEach((ta) => {
207
- ta.addEventListener("input", applyKeyPretty);
208
- });
209
- const runBtn = __wgById("wg-run");
210
- if (runBtn) {
211
- runBtn.addEventListener("click", () => {
212
- const edits = {};
213
- panel.querySelectorAll("textarea[data-key]").forEach((el) => {
214
- edits[el.getAttribute("data-key")] = el.value;
215
- });
216
- window.__wgNext(edits);
217
- });
218
- }
219
- // Live toggle - flips localStorage immediately so an in-flight gate()
220
- // poll (on the Node side) picks it up within its next poll slice,
221
- // without needing this whole panel to re-render. A manual click
222
- // still always wins over an active autoplay wait, whichever the
223
- // checkbox says - this is the "hybrid" control: autoplay is a
224
- // default, not a lockout.
225
- const cb = __wgById("wg-autoplay-cb");
226
- if (cb) {
227
- cb.addEventListener("change", () => {
228
- try {
229
- localStorage.setItem("wg-autoplay", cb.checked ? "1" : "0");
230
- } catch {
231
- /* private mode / blocked storage - toggle still works this page */
232
- }
233
- const manual = __wgById("wg-gate-manual");
234
- const auto = __wgById("wg-gate-auto");
235
- if (manual) manual.style.display = cb.checked ? "none" : "";
236
- if (auto) auto.style.display = cb.checked ? "" : "none";
237
- });
238
- }
239
- }, payload)
240
- .catch(() => {});
241
- if (process.env.WAYGRAPH_PROVE_SHOT || process.env.WAYGRAPH_PROVE_EXIT === "1") {
242
- // Default: prove once on first painted panel. PROVE_EVERY=1 re-checks
243
- // every step (noisy; useful when hunting a mid-chain blank).
244
- const proveEvery = process.env.WAYGRAPH_PROVE_EVERY === "1";
245
- const already = globalThis.__wgProveDone;
246
- if (!already || proveEvery || process.env.WAYGRAPH_PROVE_EXIT === "1") {
247
- await page.waitForTimeout(500).catch(() => {});
248
- if (process.env.WAYGRAPH_PROVE_SHOT) {
249
- await page.screenshot({ path: process.env.WAYGRAPH_PROVE_SHOT }).catch(() => {});
250
- }
251
- const ok = await page
252
- .evaluate(() => {
253
- const beacons =
254
- typeof window.__wgOverlayBeacon === "function" ? window.__wgOverlayBeacon() : [];
255
- const panel = beacons.find((b) => b.modal === "panel" && b.ready && b.visible);
256
- const textOk = panel && panel.textLen >= 12;
257
- const opacityOk = panel && Number(panel.opacity) > 0.5;
258
- return {
259
- ok: !!(panel && textOk && opacityOk),
260
- beacons,
261
- hasRun: !!__wgById("wg-run"),
262
- readyAttr: __wgById("wg-panel")?.getAttribute("data-wg-ready") || null,
263
- };
264
- })
265
- .catch((e) => ({ ok: false, reason: String(e && e.message ? e.message : e) }));
266
- console.error("WAYGRAPH_PROVE " + JSON.stringify(ok));
267
- globalThis.__wgProveDone = true;
268
- if (process.env.WAYGRAPH_PROVE_EXIT === "1") {
269
- process.exit(ok && ok.ok ? 0 : 2);
270
- }
271
- }
272
- }
273
- }
274
-
275
-
276
- function miniStepLabel(info) {
277
- const ep =
278
- info.episodeNumber !== undefined && info.episodeNumber !== null
279
- ? "Ep " + info.episodeNumber + " \u00b7 "
280
- : "";
281
- return (
282
- ep +
283
- (info.index + 1) +
284
- " / " +
285
- info.total +
286
- (info.blockName ? " \u00b7 " + info.blockName : "") +
287
- (info.paceBadge ? " \u00b7 " + info.paceBadge : "")
288
- );
289
- }
290
-
291
-
292
- /**
293
- * stubOnError rings + amber "expected outcome" / red error panel, then wait
294
- * for Stop/Retry. Used when a step throws OR when withExpectedFailure's last
295
- * block succeeds on the intentional fail branch (e.g. LoginPage + error banner).
296
- */
297
- export async function presentFailPanel(page, opts) {
298
- const {
299
- block,
300
- fixtures,
301
- error,
302
- index,
303
- total,
304
- blockName,
305
- message,
306
- allNames,
307
- allDescriptions,
308
- moduleIndex,
309
- allEpisodes,
310
- title,
311
- episodeNumber,
312
- episodeTitle,
313
- expectedFailureReason,
314
- stepperMode,
315
- gatesFast,
316
- demoPace,
317
- gate,
318
- mem,
319
- } = opts;
320
- if (hasAuthoredStubOnError(block, fixtures)) {
321
- await page
322
- .evaluate(() => {
323
- if (window.__wgRingTrack) {
324
- window.removeEventListener("resize", window.__wgRingTrack);
325
- window.removeEventListener("scroll", window.__wgRingTrack, true);
326
- window.__wgRingTrack = null;
327
- }
328
- })
329
- .catch(() => {});
330
- const errPhase = await runStubPhase(block, "stubOnError", {
331
- fixtures,
332
- error,
333
- out: opts.out,
334
- mem,
335
- });
336
- const errHighlights = errPhase.highlights.map((h) => {
337
- const styled = applyHighlightStyleDefaults(h, opts.highlightStyle);
338
- return {
339
- selector: styled.selector,
340
- label: formatHighlightCaption(styled),
341
- duration: styled.duration,
342
- fastMode: styled.fastMode,
343
- tone: styled.tone,
344
- size: styled.size,
345
- weight: styled.weight,
346
- zoom: styled.zoom,
347
- zoomOut: styled.zoomOut,
348
- focus: !!styled.focus,
349
- tone: styled.tone,
350
- color: styled.color,
351
- detail: styled.detail,
352
- };
353
- });
354
- await cycleHighlightRings(page, errHighlights, !!gatesFast, {
355
- defaultHoldMs: 2000,
356
- pace: demoPace,
357
- todos: errPhase.todos,
358
- });
359
- }
360
- await renderStepError(page, {
361
- index,
362
- total,
363
- blockName,
364
- message,
365
- allNames,
366
- allDescriptions,
367
- moduleIndex,
368
- allEpisodes,
369
- title,
370
- episodeNumber,
371
- episodeTitle,
372
- expectedFailureReason,
373
- stepperMode,
374
- });
375
- return gate();
376
- }
377
-
378
-
379
- export async function renderAfterStep(page, info) {
380
- await installOverlay(page, info.title, info.bannerUi, info.caption, info.networkTabVisible);
381
- // Clear any tracker from a previous highlight before cycling through this
382
- // step's own.
383
- await page
384
- .evaluate(() => {
385
- if (window.__wgRingTrack) {
386
- window.removeEventListener("resize", window.__wgRingTrack);
387
- window.removeEventListener("scroll", window.__wgRingTrack, true);
388
- window.__wgRingTrack = null;
389
- }
390
- })
391
- .catch(() => {});
392
- const highlights = info.highlights || [];
393
- const gatesFast = !!info.gatesFast;
394
- // Cycle through EVERY declared/recovered highlight in order, each shown
395
- // long enough to actually register - "it highlights something [...] then
396
- // it highlights something [else] and next," not just the first one.
397
- // duration / fastMode on stubAfter (or flow fixtures) override the legacy
398
- // 900ms / 200ms holds when set.
399
- await cycleHighlightRings(page, highlights, gatesFast, {
400
- pace: info.pace,
401
- stepLabel: miniStepLabel(info),
402
- todoDock: info.todoDock,
403
- todos: info.todos,
404
- todoSync: info.todoSync,
405
- todoDockRef: info.todoDockRef,
406
- // stubAfter already authored progress - do not re-index by ring 0..n
407
- advanceTodos: false,
408
- });
409
- // After-ring advances may have moved the dock - surface latest for caller.
410
- if (info.todoDockRef && info.todoDockRef.current) {
411
- info.todoDock = info.todoDockRef.current;
412
- }
413
- const afterPayload = { ...info, stepLabel: miniStepLabel(info) };
414
- await page
415
- .evaluate((info) => {
416
- // Reused in place - see renderBeforeStep's own comment on this.
417
- let panel = __wgById("wg-panel");
418
- const isNewPanel = !panel;
419
- if (!panel) {
420
- panel = document.createElement("div");
421
- panel.id = "wg-panel";
422
- }
423
- const pct = Math.round(((info.index + 1) / info.total) * 100);
424
- const heading = info.isLast
425
- ? "End of chain - " + info.total + " / " + info.total + " blocks covered - " + info.blockName + " done"
426
- : "Step " + (info.index + 1) + " / " + info.total + " - " + info.blockName + " done";
427
- const buttonLabel = info.isLast ? "Finish" : "Next \u25B6";
428
- const escA = (s) => String(s).replace(/&/g, "&amp;").replace(/"/g, "&quot;").replace(/</g, "&lt;");
429
- const modulesClass = info.stepperMode === "full" ? "wg-modules-full" : "wg-modules-carousel";
430
- const modulesHtml = info.allNames
431
- .map((name, idx) => {
432
- const cls = idx <= info.moduleIndex ? "wg-mod-done" : "wg-mod-upcoming";
433
- const desc = info.allDescriptions && info.allDescriptions[idx];
434
- const titleAttr = desc ? " title=\"" + escA(desc) + "\"" : "";
435
- return "<span class=\"wg-mod " + cls + "\"" + titleAttr + ">" + name + "</span>";
436
- })
437
- .join("");
438
- // QA-friendly by default ("LoginSuccess" -> "Login Success") - raw
439
- // JSON is one click away for whoever actually wants __state.
440
- const stateTag = info.result && info.result.__state ? info.result.__state : "";
441
- const prettyText = stateTag
442
- .replace(/([a-z0-9])([A-Z])/g, "$1 $2")
443
- .replace(/([A-Z]+)([A-Z][a-z])/g, "$1 $2") || info.resultTag;
444
- const pretty = window.__wgPretty !== false;
445
- const resultHtml =
446
- "<div class=\"wg-toggle\">" +
447
- "<button class=\"wg-toggle-btn" + (pretty ? " wg-active" : "") + "\" data-mode=\"pretty\">Pretty</button>" +
448
- "<button class=\"wg-toggle-btn" + (pretty ? "" : " wg-active") + "\" data-mode=\"json\">JSON</button>" +
449
- "</div>" +
450
- "<div class=\"wg-result wg-result-pretty\" style=\"display:" + (pretty ? "block" : "none") + "\">" +
451
- prettyText + "</div>" +
452
- "<div class=\"wg-result wg-result-json\" style=\"display:" + (pretty ? "none" : "block") + "\">" +
453
- info.resultTag + "</div>";
454
- let autoNow = false;
455
- try {
456
- autoNow = localStorage.getItem("wg-autoplay") === "1";
457
- } catch {
458
- /* private mode / blocked storage - defaults to manual */
459
- }
460
- const gateHtml =
461
- "<div class=\"wg-autoplay-row\"><label><input type=\"checkbox\" id=\"wg-autoplay-cb\"" +
462
- (autoNow ? " checked" : "") +
463
- "> Auto-advance</label></div>" +
464
- "<div id=\"wg-gate-manual\"" + (autoNow ? " style=\"display:none\"" : "") +
465
- "><button id=\"wg-run\">" + buttonLabel + "</button></div>" +
466
- "<div id=\"wg-gate-auto\" class=\"wg-auto\"" + (autoNow ? "" : " style=\"display:none\"") +
467
- ">Auto-advancing...</div>";
468
- const episodesHtml = info.allEpisodes && info.allEpisodes.length > 0
469
- ? "<div id=\"wg-episodes\">" +
470
- info.allEpisodes
471
- .map((e) => {
472
- const cls = e.episodeNumber < info.episodeNumber ? "wg-ep-done"
473
- : e.episodeNumber === info.episodeNumber ? "wg-ep-current"
474
- : "wg-ep-upcoming";
475
- return "<span class=\"wg-ep-tab " + cls + "\">Episode " + e.episodeNumber + ": " +
476
- escA(e.episodeTitle || "") + "</span>";
477
- })
478
- .join("") +
479
- "</div>"
480
- : "";
481
- const paceHtml =
482
- info.paceBadge || info.paceLabel
483
- ? "<div class=\"wg-pace\" data-pace-kind=\"" +
484
- escA(info.paceKind || "normal") +
485
- "\"><span class=\"wg-pace-badge\">" +
486
- escA(info.paceBadge || "1x") +
487
- "</span><span>" +
488
- escA(info.paceLabel || "") +
489
- "</span></div>"
490
- : "";
491
- const todosHtml = ""; // todos float in #wg-todo-dock via __wgSyncTodos
492
- panel.innerHTML =
493
- "<div id=\"wg-progress\"><div id=\"wg-progress-bar\" style=\"width:" + pct + "%\"></div></div>" +
494
- episodesHtml +
495
- paceHtml +
496
- "<div id=\"wg-modules\" class=\"" + modulesClass + "\">" + modulesHtml + "</div>" +
497
- "<h3>" + heading + "</h3>" +
498
- todosHtml +
499
- resultHtml +
500
- gateHtml;
501
- if (isNewPanel) {
502
- __wgAdd(panel);
503
- requestAnimationFrame(() => panel.classList.add("wg-in"));
504
- } else {
505
- panel.classList.add("wg-in");
506
- }
507
- if (window.__wgWirePanelChrome) {
508
- window.__wgWirePanelChrome(panel, "wg-panel-hidden", "waygraph demo", {
509
- stepLabel: info.stepLabel || "",
510
- forceCollapsed: info.forceCollapsed === true ? true : undefined,
511
- fastForward: !!info.fastForward,
512
- isApi: !!info.isApi,
513
- });
514
- }
515
- if (window.__wgSyncTodos) {
516
- const sync = info.todoSync || (info.todos && info.todos.length ? "set" : "keep");
517
- // Prefer dock-only payload. Passing list:[] with a dock used to clear
518
- // marks a frame later (empty-list clear path).
519
- if (sync === "keep" && !info.todoDock) {
520
- /* leave floating dock alone */
521
- } else {
522
- const payload = {
523
- sync: sync,
524
- dock: info.todoDock || null,
525
- pos: info.todoPos || null,
526
- todoId: info.todoId || (info.todoDock && info.todoDock.id) || null,
527
- };
528
- if (!info.todoDock && info.todos && info.todos.length) {
529
- payload.list = info.todos;
530
- }
531
- window.__wgSyncTodos(payload);
532
- }
533
- }
534
- if (window.__wgStampModal) {
535
- window.__wgStampModal(panel, "panel", {
536
- phase: "after",
537
- step: info.index + 1,
538
- total: info.total,
539
- block: info.blockName || "",
540
- ready: true,
541
- });
542
- }
543
- panel.querySelectorAll(".wg-toggle-btn").forEach((btn) => {
544
- btn.addEventListener("click", () => {
545
- const wantPretty = btn.getAttribute("data-mode") === "pretty";
546
- window.__wgPretty = wantPretty;
547
- panel.querySelectorAll(".wg-toggle-btn").forEach((b) => b.classList.remove("wg-active"));
548
- btn.classList.add("wg-active");
549
- panel.querySelector(".wg-result-pretty").style.display = wantPretty ? "block" : "none";
550
- panel.querySelector(".wg-result-json").style.display = wantPretty ? "none" : "block";
551
- });
552
- });
553
- const runBtn = __wgById("wg-run");
554
- if (runBtn) runBtn.addEventListener("click", () => window.__wgNext({}));
555
- const cb = __wgById("wg-autoplay-cb");
556
- if (cb) {
557
- cb.addEventListener("change", () => {
558
- try {
559
- localStorage.setItem("wg-autoplay", cb.checked ? "1" : "0");
560
- } catch {
561
- /* private mode / blocked storage - toggle still works this page */
562
- }
563
- const manual = __wgById("wg-gate-manual");
564
- const auto = __wgById("wg-gate-auto");
565
- if (manual) manual.style.display = cb.checked ? "none" : "";
566
- if (auto) auto.style.display = cb.checked ? "" : "none";
567
- });
568
- }
569
- }, afterPayload)
570
- .catch(() => {});
571
- }
572
-
573
-
574
- /**
575
- * A Block threw - act()/observe() rejected, or Flow.run's own verify Trait
576
- * check failed. Shown instead of letting it crash the whole Node process
577
- * silently from a human's point of view (the browser closes right after
578
- * regardless - main()'s own try/finally - but not before this is visible).
579
- */
580
- async function renderStepError(page, info) {
581
- await installOverlay(page, info.title, info.bannerUi, info.caption, info.networkTabVisible);
582
- const errorPayload = { ...info, stepLabel: miniStepLabel(info) };
583
- await page
584
- .evaluate((info) => {
585
- // Reused in place - see renderBeforeStep's own comment on this.
586
- let panel = __wgById("wg-panel");
587
- const isNewPanel = !panel;
588
- if (!panel) {
589
- panel = document.createElement("div");
590
- panel.id = "wg-panel";
591
- }
592
- const isExpected = !!info.expectedFailureReason;
593
- const errClass = isExpected ? "wg-expected" : "wg-error";
594
- panel.classList.remove("wg-error", "wg-expected");
595
- panel.classList.add(errClass);
596
- if (!isNewPanel) panel.classList.add("wg-in");
597
- const esc = (s) => String(s).replace(/&/g, "&amp;").replace(/"/g, "&quot;").replace(/</g, "&lt;");
598
- const episodesHtml = info.allEpisodes && info.allEpisodes.length > 0
599
- ? "<div id=\"wg-episodes\">" +
600
- info.allEpisodes
601
- .map((e) => {
602
- const cls = e.episodeNumber < info.episodeNumber ? "wg-ep-done"
603
- : e.episodeNumber === info.episodeNumber ? "wg-ep-current"
604
- : "wg-ep-upcoming";
605
- return "<span class=\"wg-ep-tab " + cls + "\">Episode " + e.episodeNumber + ": " +
606
- esc(e.episodeTitle || "") + "</span>";
607
- })
608
- .join("") +
609
- "</div>"
610
- : "";
611
- const modulesClass = info.stepperMode === "full" ? "wg-modules-full" : "wg-modules-carousel";
612
- const modulesHtml = info.allNames
613
- .map((name, idx) => {
614
- const cls = idx === info.moduleIndex ? "wg-mod-current" : idx < info.moduleIndex ? "wg-mod-done" : "wg-mod-upcoming";
615
- const desc = info.allDescriptions && info.allDescriptions[idx];
616
- const titleAttr = desc ? " title=\"" + esc(desc) + "\"" : "";
617
- return "<span class=\"wg-mod " + cls + "\"" + titleAttr + ">" + name + "</span>";
618
- })
619
- .join("");
620
- const retryLabel = info.episodeNumber !== undefined ? "Retry Episode " + info.episodeNumber : "Retry";
621
- const headingText = isExpected
622
- ? "Expected outcome - Step " + (info.index + 1) + " / " + info.total + " - " + info.blockName + " failed as intended"
623
- : "Step " + (info.index + 1) + " / " + info.total + " - " + info.blockName + " threw";
624
- const reasonHtml = isExpected
625
- ? "<div class=\"wg-expected-reason\">" + esc(info.expectedFailureReason) + "</div>"
626
- : "";
627
- panel.innerHTML =
628
- episodesHtml +
629
- "<div id=\"wg-modules\" class=\"" + modulesClass + "\">" + modulesHtml + "</div>" +
630
- "<h3 class=\"" + (isExpected ? "wg-expected-heading" : "wg-error-heading") + "\">" + headingText + "</h3>" +
631
- reasonHtml +
632
- "<div class=\"wg-error-msg\">" + esc(info.message) + "</div>" +
633
- "<div class=\"wg-error-actions\">" +
634
- "<button id=\"wg-error-retry\" class=\"wg-error-retry\">" + esc(retryLabel) + "</button>" +
635
- "<button id=\"wg-run\" class=\"wg-error-stop\">Stop</button>" +
636
- "</div>";
637
- if (isNewPanel) {
638
- __wgAdd(panel);
639
- requestAnimationFrame(() => panel.classList.add("wg-in"));
640
- } else {
641
- panel.classList.add("wg-in");
642
- }
643
- if (window.__wgWirePanelChrome) {
644
- window.__wgWirePanelChrome(panel, "wg-panel-hidden", "waygraph demo", {
645
- stepLabel: info.stepLabel || "",
646
- forceCollapsed: info.forceCollapsed === true ? true : undefined,
647
- fastForward: !!info.fastForward,
648
- isApi: !!info.isApi,
649
- });
650
- }
651
- if (window.__wgStampModal) {
652
- window.__wgStampModal(panel, "panel", {
653
- phase: "error",
654
- step: info.index + 1,
655
- total: info.total,
656
- block: info.blockName || "",
657
- ready: true,
658
- });
659
- }
660
- const runBtn = __wgById("wg-run");
661
- if (runBtn) runBtn.addEventListener("click", () => window.__wgNext({}));
662
- const retryBtn = __wgById("wg-error-retry");
663
- if (retryBtn) retryBtn.addEventListener("click", () => window.__wgNext({ __wgRetry: "1" }));
664
- }, errorPayload)
665
- .catch(() => {});
666
- }
667
-
668
-
669
- /**
670
- * A Block's own explicit instruction.highlights, if it declared any -
671
- * arbitrary, author-controlled highlight points, independent of verify
672
- * ("remember this ID" isn't a pass/fail check). Takes priority over
673
- * anything recovered from verify traits below.
674
- */
675
- function resolveDeclaredHighlights(block, resultTag) {
676
- let highlights = block.instruction && block.instruction.highlights;
677
- if (typeof highlights === "function") {
678
- try {
679
- highlights = highlights({ __state: resultTag });
680
- } catch {
681
- highlights = [];
682
- }
683
- }
684
- if (!Array.isArray(highlights)) return [];
685
- return highlights.filter((h) => h && typeof h.selector === "string" && typeof h.label === "string").map((h) => ({
686
- ...h,
687
- tone: normalizeHighlightTone(h.tone),
688
- }));
689
- }
690
-
691
-
692
- /**
693
- * Recovers a DOM selector from a built-in Trait's own .name string -
694
- * visible(sel) / text-equals(sel, "...") - since Trait.check itself is
695
- * an opaque closure with no selector field of its own. Best-effort only: a
696
- * hand-written bespoke Trait, or url-matches(...) (no DOM target), yields
697
- * nothing to highlight, which is fine - the panel still shows the result.
698
- * Only used as a FALLBACK when the Block declared no explicit
699
- * instruction.highlights of its own - see resolveDeclaredHighlights.
700
- */
701
- export function extractVerifyHighlights(block, resultTag) {
702
- const declared = resolveDeclaredHighlights(block, resultTag);
703
- if (declared.length > 0) return declared;
704
- let verify = block.instruction && block.instruction.verify;
705
- if (typeof verify === "function") {
706
- try {
707
- verify = verify({ __state: resultTag });
708
- } catch {
709
- verify = [];
710
- }
711
- }
712
- if (!Array.isArray(verify)) return [];
713
- const highlights = [];
714
- for (const t of verify) {
715
- const name = t && t.name;
716
- if (typeof name !== "string") continue;
717
- let m = /^visible\((.+)\)$/.exec(name);
718
- if (m) {
719
- highlights.push({ selector: m[1], label: name, tone: "auto" });
720
- continue;
721
- }
722
- m = /^text-equals\((.+?),\s*"/.exec(name);
723
- if (m) {
724
- highlights.push({ selector: m[1], label: name, tone: "auto" });
725
- continue;
726
- }
727
- }
728
- return highlights;
729
- }