waygraph 0.15.54 → 0.16.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (552) hide show
  1. package/README.md +8 -3
  2. package/bin/waygraph +2 -2
  3. package/dist/analysis/check.d.ts +38 -0
  4. package/dist/analysis/check.js +87 -0
  5. package/dist/analysis/coverage-gap.d.ts +1 -1
  6. package/dist/analysis/coverage-gap.js +14 -37
  7. package/dist/analysis/flow-source.d.ts +9 -0
  8. package/dist/analysis/flow-source.js +25 -0
  9. package/dist/analysis/graph.d.ts +10 -14
  10. package/dist/analysis/graph.js +48 -371
  11. package/dist/analysis/map-check.js +4 -39
  12. package/dist/analysis/practices-check.d.ts +1 -1
  13. package/dist/analysis/practices-check.js +24 -45
  14. package/dist/cli/args.d.ts +23 -0
  15. package/dist/cli/args.js +20 -0
  16. package/dist/{cli.d.ts → cli/cli.d.ts} +0 -1
  17. package/dist/{cli.js → cli/cli.js} +10 -9
  18. package/dist/{commands → cli/commands}/agent-dive-scaffold.js +35 -64
  19. package/dist/cli/commands/agent-dive.js +42 -0
  20. package/dist/cli/commands/browser.d.ts +2 -0
  21. package/dist/cli/commands/browser.js +109 -0
  22. package/dist/{commands → cli/commands}/check.d.ts +0 -1
  23. package/dist/cli/commands/check.js +104 -0
  24. package/dist/cli/commands/codemod-checkpoints.d.ts +18 -0
  25. package/dist/cli/commands/codemod-checkpoints.js +186 -0
  26. package/dist/cli/commands/codemod-flows.d.ts +18 -0
  27. package/dist/cli/commands/codemod-flows.js +284 -0
  28. package/dist/cli/commands/codemod-stubs.d.ts +10 -0
  29. package/dist/cli/commands/codemod-stubs.js +187 -0
  30. package/dist/{commands → cli/commands}/extensions.js +5 -4
  31. package/dist/{commands → cli/commands}/init.js +1 -2
  32. package/dist/{commands → cli/commands}/list.js +9 -7
  33. package/dist/cli/commands/manifest.d.ts +2 -0
  34. package/dist/cli/commands/manifest.js +20 -0
  35. package/dist/cli/commands/map.js +57 -0
  36. package/dist/cli/commands/pilot.d.ts +2 -0
  37. package/dist/cli/commands/pilot.js +102 -0
  38. package/dist/{commands → cli/commands}/run.d.ts +0 -1
  39. package/dist/cli/commands/run.js +64 -0
  40. package/dist/cli/commands/session-ops.d.ts +3 -0
  41. package/dist/cli/commands/session-ops.js +257 -0
  42. package/dist/cli/commands/session.js +132 -0
  43. package/dist/{commands → cli/commands}/test.js +11 -14
  44. package/dist/cli/commands/traverse.js +105 -0
  45. package/dist/{commands → cli/commands}/try.js +29 -25
  46. package/dist/{commands → cli/commands}/upgrade.js +40 -4
  47. package/dist/cli/flags.d.ts +193 -16
  48. package/dist/cli/flags.js +179 -234
  49. package/dist/cli/run-chain.d.ts +1 -0
  50. package/dist/cli/run-chain.js +42 -7
  51. package/dist/cli/usage.d.ts +1 -1
  52. package/dist/cli/usage.js +21 -53
  53. package/dist/cli/util.d.ts +2 -2
  54. package/dist/cli/util.js +2 -3
  55. package/dist/{highlights → demo/narration}/css.d.ts +1 -1
  56. package/dist/{highlights → demo/narration}/css.js +2 -3
  57. package/dist/{highlights → demo/narration}/demo-pace.d.ts +4 -12
  58. package/dist/{highlights → demo/narration}/demo-pace.js +5 -11
  59. package/dist/{highlights → demo/narration}/device.d.ts +4 -4
  60. package/dist/{highlights → demo/narration}/device.js +1 -1
  61. package/dist/demo/narration/merge.d.ts +10 -0
  62. package/dist/demo/narration/merge.js +67 -0
  63. package/dist/demo/narration/narration.d.ts +39 -0
  64. package/dist/{highlights/run-phase.js → demo/narration/narration.js} +25 -94
  65. package/dist/{highlights → demo/narration}/shorthand.d.ts +1 -1
  66. package/dist/demo/narration/stub-ctx.d.ts +8 -0
  67. package/dist/demo/narration/stub-ctx.js +164 -0
  68. package/dist/{highlights → demo/narration}/style.d.ts +1 -7
  69. package/dist/{highlights → demo/narration}/style.js +1 -41
  70. package/dist/{highlights → demo/narration}/todo-dock.d.ts +8 -8
  71. package/dist/{highlights → demo/narration}/todo-dock.js +13 -30
  72. package/dist/demo/overlay/auto-chrome.d.ts +7 -0
  73. package/dist/demo/overlay/auto-chrome.js +97 -0
  74. package/dist/demo/overlay/cursor.d.ts +19 -0
  75. package/dist/demo/overlay/cursor.js +142 -0
  76. package/dist/demo/overlay/device-stage.d.ts +26 -0
  77. package/dist/demo/overlay/device-stage.js +396 -0
  78. package/dist/demo/overlay/inpage/banner.d.ts +2 -0
  79. package/dist/demo/overlay/inpage/banner.js +160 -0
  80. package/dist/demo/overlay/inpage/caption.d.ts +2 -0
  81. package/dist/demo/overlay/inpage/caption.js +24 -0
  82. package/dist/demo/overlay/inpage/core.d.ts +2 -0
  83. package/dist/demo/overlay/inpage/core.js +345 -0
  84. package/dist/demo/overlay/inpage/device-chip.d.ts +1 -0
  85. package/dist/demo/overlay/inpage/device-chip.js +191 -0
  86. package/dist/demo/overlay/inpage/network.d.ts +10 -0
  87. package/dist/demo/overlay/inpage/network.js +189 -0
  88. package/dist/demo/overlay/inpage/panel-chrome.d.ts +1 -0
  89. package/dist/demo/overlay/inpage/panel-chrome.js +203 -0
  90. package/dist/demo/overlay/inpage/stamp.d.ts +1 -0
  91. package/dist/demo/overlay/inpage/stamp.js +46 -0
  92. package/dist/demo/overlay/inpage/swipe-zoom.d.ts +1 -0
  93. package/dist/demo/overlay/inpage/swipe-zoom.js +220 -0
  94. package/dist/demo/overlay/inpage/todos.d.ts +2 -0
  95. package/dist/demo/overlay/inpage/todos.js +293 -0
  96. package/dist/demo/overlay/locator-theater.d.ts +25 -0
  97. package/dist/demo/overlay/locator-theater.js +76 -0
  98. package/dist/demo/overlay/network-capture.d.ts +22 -0
  99. package/dist/demo/overlay/network-capture.js +127 -0
  100. package/dist/demo/overlay/overlay-css.d.ts +3 -0
  101. package/dist/demo/overlay/overlay-css.js +369 -0
  102. package/dist/demo/overlay/overlay-stage.d.ts +31 -0
  103. package/dist/demo/overlay/overlay-stage.js +106 -0
  104. package/dist/demo/overlay/overlay.d.ts +10 -0
  105. package/dist/demo/overlay/overlay.js +89 -0
  106. package/dist/{pilot-overlay/overlay-fixtures.d.ts → demo/overlay/phase-fixtures.d.ts} +2 -2
  107. package/dist/{pilot-overlay/overlay-fixtures.js → demo/overlay/phase-fixtures.js} +2 -2
  108. package/dist/{pilot-overlay/action-ring.js → demo/overlay/pilot/actions.js} +2 -1
  109. package/dist/{pilot-overlay → demo/overlay/pilot}/fixtures.d.ts +6 -5
  110. package/dist/{pilot-overlay → demo/overlay/pilot}/fixtures.js +19 -18
  111. package/dist/{pilot-overlay → demo/overlay/pilot}/shell.d.ts +2 -2
  112. package/dist/{pilot-overlay → demo/overlay/pilot}/shell.js +13 -22
  113. package/dist/demo/overlay/reattach.d.ts +7 -0
  114. package/dist/demo/overlay/reattach.js +23 -0
  115. package/dist/demo/overlay/rings.d.ts +61 -0
  116. package/dist/demo/overlay/rings.js +422 -0
  117. package/dist/{ui → demo/overlay/ui}/components/ring.js +2 -2
  118. package/dist/{ui → demo/overlay/ui}/overlay.css +4 -4
  119. package/dist/{ui → demo/overlay/ui}/shadow.d.ts +1 -1
  120. package/dist/{ui → demo/overlay/ui}/shadow.js +39 -2
  121. package/dist/demo/stepper/after.d.ts +3 -0
  122. package/dist/demo/stepper/after.js +103 -0
  123. package/dist/demo/stepper/banner-log.d.ts +35 -0
  124. package/dist/demo/stepper/banner-log.js +65 -0
  125. package/dist/demo/stepper/before.d.ts +4 -0
  126. package/dist/demo/stepper/before.js +110 -0
  127. package/dist/demo/stepper/demo-log.d.ts +48 -0
  128. package/dist/demo/stepper/demo-log.js +292 -0
  129. package/dist/demo/stepper/gate.d.ts +11 -0
  130. package/dist/demo/stepper/gate.js +78 -0
  131. package/dist/demo/stepper/interaction-patch.d.ts +4 -0
  132. package/dist/demo/stepper/interaction-patch.js +323 -0
  133. package/dist/demo/stepper/pacing.d.ts +21 -0
  134. package/dist/demo/stepper/pacing.js +23 -0
  135. package/dist/demo/stepper/panel-after.d.ts +17 -0
  136. package/dist/demo/stepper/panel-after.js +166 -0
  137. package/dist/demo/stepper/panel-before.d.ts +12 -0
  138. package/dist/demo/stepper/panel-before.js +241 -0
  139. package/dist/demo/stepper/slides.d.ts +23 -0
  140. package/dist/demo/stepper/slides.js +233 -0
  141. package/dist/demo/stepper/step-panels.d.ts +69 -0
  142. package/dist/demo/stepper/step-panels.js +172 -0
  143. package/dist/demo/stepper/stepper.d.ts +24 -0
  144. package/dist/demo/stepper/stepper.js +122 -0
  145. package/dist/demo/stepper/teardown.d.ts +47 -0
  146. package/dist/demo/stepper/teardown.js +178 -0
  147. package/dist/demo/stepper/todo-advance.d.ts +15 -0
  148. package/dist/demo/stepper/todo-advance.js +110 -0
  149. package/dist/demo/stepper/view.d.ts +58 -0
  150. package/dist/demo/stepper/view.js +31 -0
  151. package/dist/demo/types.d.ts +85 -0
  152. package/dist/demo/verbose-log.js +15 -0
  153. package/dist/engine/block/action-page.d.ts +53 -0
  154. package/dist/engine/block/action-page.js +1 -0
  155. package/dist/{types.d.ts → engine/block/block.d.ts} +102 -142
  156. package/dist/{core → engine/block}/block.js +12 -130
  157. package/dist/engine/block/branch.d.ts +17 -0
  158. package/dist/engine/block/branch.js +40 -0
  159. package/dist/{core → engine/block}/compose.d.ts +9 -7
  160. package/dist/{core → engine/block}/compose.js +1 -1
  161. package/dist/engine/block/dialog.d.ts +13 -0
  162. package/dist/engine/block/dialog.js +37 -0
  163. package/dist/{core/blocks → engine/block/kinds}/api.d.ts +16 -12
  164. package/dist/{core/blocks → engine/block/kinds}/api.js +26 -18
  165. package/dist/{core/blocks → engine/block/kinds}/effect.d.ts +13 -18
  166. package/dist/engine/block/kinds/effect.js +17 -0
  167. package/dist/{core/blocks → engine/block/kinds}/method.d.ts +17 -29
  168. package/dist/{core/blocks → engine/block/kinds}/method.js +6 -21
  169. package/dist/{core/blocks → engine/block/kinds}/nav.d.ts +21 -31
  170. package/dist/{core/blocks → engine/block/kinds}/nav.js +6 -12
  171. package/dist/{core/blocks → engine/block/kinds}/page.d.ts +14 -20
  172. package/dist/{core/blocks → engine/block/kinds}/page.js +5 -7
  173. package/dist/engine/checkpoint/checkpoint.d.ts +22 -0
  174. package/dist/engine/checkpoint/checkpoint.js +8 -0
  175. package/dist/engine/checkpoint/route.d.ts +28 -0
  176. package/dist/engine/checkpoint/route.js +28 -0
  177. package/dist/{core → engine}/config.d.ts +7 -2
  178. package/dist/engine/config.js +6 -0
  179. package/dist/engine/engine.d.ts +45 -0
  180. package/dist/{core → engine}/engine.js +6 -10
  181. package/dist/engine/env.d.ts +59 -0
  182. package/dist/engine/env.js +83 -0
  183. package/dist/{errors.d.ts → engine/errors.d.ts} +22 -22
  184. package/dist/{errors.js → engine/errors.js} +22 -22
  185. package/dist/{core → engine/flow}/branch-regression.d.ts +7 -7
  186. package/dist/{core → engine/flow}/branch-regression.js +4 -3
  187. package/dist/engine/flow/flow.d.ts +162 -0
  188. package/dist/engine/flow/flow.js +244 -0
  189. package/dist/engine/flow/map-branch.d.ts +9 -0
  190. package/dist/engine/flow/map-branch.js +57 -0
  191. package/dist/{core → engine/flow}/map-builder.d.ts +34 -54
  192. package/dist/engine/flow/map-builder.js +242 -0
  193. package/dist/engine/flow/map-steps.d.ts +30 -0
  194. package/dist/engine/flow/map-steps.js +87 -0
  195. package/dist/{core → engine}/locate.d.ts +1 -1
  196. package/dist/{core → engine}/locate.js +1 -2
  197. package/dist/{mem-stub.d.ts → engine/mem/mem-stub.d.ts} +9 -8
  198. package/dist/{mem-stub.js → engine/mem/mem-stub.js} +2 -2
  199. package/dist/{mem-page.d.ts → engine/mem/mem.d.ts} +1 -1
  200. package/dist/{mem-page.js → engine/mem/mem.js} +2 -1
  201. package/dist/engine/page-gone.d.ts +5 -0
  202. package/dist/engine/page-gone.js +20 -0
  203. package/dist/engine/run/connect.d.ts +28 -0
  204. package/dist/{types.js → engine/run/connect.js} +11 -10
  205. package/dist/engine/run/events.d.ts +67 -0
  206. package/dist/engine/run/events.js +90 -0
  207. package/dist/engine/run/hooks.d.ts +16 -0
  208. package/dist/engine/run/hooks.js +8 -0
  209. package/dist/engine/run/launch.d.ts +13 -0
  210. package/dist/engine/run/launch.js +27 -0
  211. package/dist/{core/run-graph.d.ts → engine/run/run.d.ts} +8 -12
  212. package/dist/{core/run-graph.js → engine/run/run.js} +22 -12
  213. package/dist/engine/stub/pace.d.ts +12 -0
  214. package/dist/engine/stub/pace.js +2 -0
  215. package/dist/engine/stub/ring.d.ts +130 -0
  216. package/dist/engine/stub/ring.js +41 -0
  217. package/dist/engine/stub/stub.d.ts +268 -0
  218. package/dist/engine/stub/stub.js +1 -0
  219. package/dist/engine/stub/todos.d.ts +104 -0
  220. package/dist/engine/stub/todos.js +2 -0
  221. package/dist/engine/stub/viewport.d.ts +26 -0
  222. package/dist/engine/stub/viewport.js +2 -0
  223. package/dist/{trait.d.ts → engine/trait/trait.d.ts} +1 -1
  224. package/dist/{trait.js → engine/trait/trait.js} +1 -1
  225. package/dist/index.d.ts +88 -36
  226. package/dist/index.js +46 -19
  227. package/dist/live/auto/auto.d.ts +22 -0
  228. package/dist/live/auto/auto.js +207 -0
  229. package/dist/{session/auto-explore.d.ts → live/auto/explore.d.ts} +4 -14
  230. package/dist/{session/auto-explore.js → live/auto/explore.js} +21 -127
  231. package/dist/live/auto/mem.d.ts +11 -0
  232. package/dist/live/auto/mem.js +85 -0
  233. package/dist/live/auto/menu.d.ts +30 -0
  234. package/dist/live/auto/menu.js +335 -0
  235. package/dist/live/auto-session/auto-session.d.ts +113 -0
  236. package/dist/live/auto-session/auto-session.js +452 -0
  237. package/dist/live/auto-session/console.d.ts +4 -0
  238. package/dist/live/auto-session/console.js +41 -0
  239. package/dist/live/auto-session/files.d.ts +44 -0
  240. package/dist/live/auto-session/files.js +145 -0
  241. package/dist/{auto-session → live/auto-session}/helpers.d.ts +9 -5
  242. package/dist/{auto-session → live/auto-session}/helpers.js +18 -1
  243. package/dist/live/auto-session/inspect.d.ts +4 -0
  244. package/dist/live/auto-session/inspect.js +75 -0
  245. package/dist/{session/auto-session-ipc.d.ts → live/auto-session/ipc.d.ts} +8 -25
  246. package/dist/{session/auto-session-ipc.js → live/auto-session/ipc.js} +36 -161
  247. package/dist/live/auto-session/open-browser.d.ts +6 -0
  248. package/dist/live/auto-session/open-browser.js +47 -0
  249. package/dist/{session/browser.d.ts → live/auto-session/start.d.ts} +1 -2
  250. package/dist/{session/browser.js → live/auto-session/start.js} +2 -3
  251. package/dist/{pilot-overlay → live/pilot}/panel.d.ts +1 -1
  252. package/dist/{pilot-overlay → live/pilot}/panel.js +23 -31
  253. package/dist/{session → live/pilot}/pilot.d.ts +3 -3
  254. package/dist/{session → live/pilot}/pilot.js +5 -4
  255. package/dist/{traverse/run.d.ts → live/traverse/traverse.d.ts} +1 -1
  256. package/dist/live/traverse/traverse.js +212 -0
  257. package/dist/live/traverse/worker.d.ts +37 -0
  258. package/dist/live/traverse/worker.js +200 -0
  259. package/dist/manifest/manifest.d.ts +52 -0
  260. package/dist/manifest/manifest.js +93 -0
  261. package/dist/manifest/map-imports.d.ts +7 -0
  262. package/dist/manifest/map-imports.js +22 -0
  263. package/dist/manifest/maps.d.ts +33 -0
  264. package/dist/manifest/maps.js +62 -0
  265. package/dist/manifest/pack.d.ts +21 -0
  266. package/dist/manifest/pack.js +109 -0
  267. package/dist/manifest/project.d.ts +60 -0
  268. package/dist/manifest/project.js +101 -0
  269. package/dist/{session/block-inject.js → manifest/roots.js} +1 -18
  270. package/dist/manifest/scan.d.ts +19 -0
  271. package/dist/manifest/scan.js +57 -0
  272. package/dist/manifest/source.d.ts +23 -0
  273. package/dist/manifest/source.js +86 -0
  274. package/dist/runner/mode.d.ts +71 -0
  275. package/dist/runner/mode.js +1 -0
  276. package/dist/runner/modes/branches.d.ts +5 -0
  277. package/dist/runner/modes/branches.js +37 -0
  278. package/dist/runner/modes/demo.d.ts +3 -0
  279. package/dist/runner/modes/demo.js +13 -0
  280. package/dist/runner/modes/report.d.ts +2 -0
  281. package/dist/runner/modes/report.js +54 -0
  282. package/dist/runner/modes/run.d.ts +2 -0
  283. package/dist/runner/modes/run.js +3 -0
  284. package/dist/runner/options.d.ts +31 -0
  285. package/dist/runner/options.js +42 -0
  286. package/dist/runner/plan/find.d.ts +18 -0
  287. package/dist/runner/plan/find.js +65 -0
  288. package/dist/runner/plan/plan.d.ts +11 -0
  289. package/dist/runner/plan/plan.js +97 -0
  290. package/dist/runner/plan/seed-mem.d.ts +12 -0
  291. package/dist/runner/plan/seed-mem.js +98 -0
  292. package/dist/runner/plan/spec.d.ts +5 -0
  293. package/dist/runner/plan/spec.js +17 -0
  294. package/dist/runner/play-steps.d.ts +2 -0
  295. package/dist/runner/play-steps.js +59 -0
  296. package/dist/runner/runner.d.ts +4 -0
  297. package/dist/runner/runner.js +64 -0
  298. package/dist/runner/session.d.ts +9 -0
  299. package/dist/runner/session.js +87 -0
  300. package/dist/{browser.js → runtime/browser.js} +4 -2
  301. package/dist/{env-file.js → runtime/env-file.js} +7 -12
  302. package/dist/{extensions.d.ts → runtime/extensions.d.ts} +1 -5
  303. package/dist/{extensions.js → runtime/extensions.js} +2 -1
  304. package/dist/runtime/full-launch.d.ts +1 -0
  305. package/dist/runtime/full-launch.js +34 -0
  306. package/dist/runtime/global-flag.d.ts +5 -0
  307. package/dist/runtime/global-flag.js +18 -0
  308. package/dist/{playwright-config.d.ts → runtime/playwright-config.d.ts} +1 -1
  309. package/dist/{playwright.config.js → runtime/playwright.config.js} +3 -2
  310. package/dist/runtime/run-log.d.ts +2 -0
  311. package/dist/runtime/run-log.js +17 -0
  312. package/dist/{video-dir.js → runtime/video-dir.js} +3 -2
  313. package/dist/{config.d.ts → runtime/waygraph-config.d.ts} +6 -9
  314. package/dist/{config.js → runtime/waygraph-config.js} +21 -51
  315. package/dist/{webserver.js → runtime/webserver.js} +5 -30
  316. package/examples/routed-demo/config/waygraph.config.ts +20 -0
  317. package/examples/routed-demo/package.json +1 -4
  318. package/examples/routed-demo/scripts/fixture-server.mjs +1 -1
  319. package/examples/routed-demo/src/flows/routed-demo-map.flow.ts +2 -4
  320. package/examples/routed-demo/src/flows/routed-demo.flow.ts +1 -2
  321. package/examples/routed-demo/src/map/(app_base)/dashboard/_methods/click-widget.block.ts +5 -4
  322. package/examples/routed-demo/src/map/(app_base)/dashboard/_nav.block.ts +3 -3
  323. package/examples/routed-demo/src/map/(app_base)/dashboard/_page.block.ts +3 -3
  324. package/examples/routed-demo/src/map/(external)/docs/_nav.block.ts +3 -3
  325. package/examples/routed-demo/src/map/(external)/docs/_page.block.ts +3 -3
  326. package/examples/routed-demo/src/states/routed-demo.states.ts +5 -3
  327. package/examples/routed-demo/tests/routed-demo.spec.ts +4 -4
  328. package/examples/routed-demo/tsconfig.json +1 -1
  329. package/examples/saucedemo/docs/CONVENTION.md +4 -5
  330. package/examples/saucedemo/docs/HELPERS.md +11 -11
  331. package/examples/saucedemo/src/blocks/SITE-MAP.md +0 -1
  332. package/examples/saucedemo/src/blocks/saucedemo-web/NAV.md +1 -5
  333. package/examples/saucedemo/src/blocks/saucedemo-web/cart/nav-cart.block.ts +3 -3
  334. package/examples/saucedemo/src/blocks/saucedemo-web/cart/nav-checkout-info.block.ts +3 -3
  335. package/examples/saucedemo/src/blocks/saucedemo-web/checkout-step-one/methods/fill-first-name.method.block.ts +5 -4
  336. package/examples/saucedemo/src/blocks/saucedemo-web/checkout-step-one/methods/fill-last-name.method.block.ts +5 -4
  337. package/examples/saucedemo/src/blocks/saucedemo-web/checkout-step-one/methods/fill-postal-code.method.block.ts +5 -4
  338. package/examples/saucedemo/src/blocks/saucedemo-web/checkout-step-one/methods/submit-checkout-info.method.block.ts +5 -4
  339. package/examples/saucedemo/src/blocks/saucedemo-web/checkout-step-two/methods/finish-order.method.block.ts +5 -8
  340. package/examples/saucedemo/src/blocks/saucedemo-web/inventory/inventory.page.block.ts +3 -3
  341. package/examples/saucedemo/src/blocks/saucedemo-web/inventory/methods/add-all-to-cart.method.block.ts +4 -6
  342. package/examples/saucedemo/src/blocks/saucedemo-web/inventory/methods/add-to-cart.effect.block.ts +35 -43
  343. package/examples/saucedemo/src/blocks/saucedemo-web/inventory/methods/remove-all-from-cart.method.block.ts +4 -6
  344. package/examples/saucedemo/src/blocks/saucedemo-web/inventory/methods/remove-from-cart.effect.block.ts +4 -3
  345. package/examples/saucedemo/src/blocks/saucedemo-web/inventory/nav-item-detail.block.ts +3 -3
  346. package/examples/saucedemo/src/blocks/saucedemo-web/inventory-item/nav-back-to-inventory.block.ts +3 -3
  347. package/examples/saucedemo/src/blocks/saucedemo-web/inventory-item/nav-back-to-products.block.ts +3 -3
  348. package/examples/saucedemo/src/blocks/saucedemo-web/inventory-item/nav-continue-shopping.block.ts +3 -3
  349. package/examples/saucedemo/src/blocks/saucedemo-web/methods/fill-password.method.block.ts +5 -4
  350. package/examples/saucedemo/src/blocks/saucedemo-web/methods/fill-username.method.block.ts +5 -4
  351. package/examples/saucedemo/src/blocks/saucedemo-web/methods/submit-login.method.block.ts +4 -5
  352. package/examples/saucedemo/src/blocks/saucedemo-web/methods/submit-logout.method.block.ts +5 -4
  353. package/examples/saucedemo/src/blocks/saucedemo-web/nav-login.block.ts +3 -3
  354. package/examples/saucedemo/src/flows/api-demo.flow.ts +12 -10
  355. package/examples/saucedemo/src/states/checkout.states.ts +21 -11
  356. package/examples/saucedemo/src/stubs/device-showcase.ts +8 -10
  357. package/examples/saucedemo/tests/auto-graph.spec.ts +4 -12
  358. package/package.json +14 -6
  359. package/templates/agents/waygraph-planner.agent.md +2 -2
  360. package/templates/quickstart/docs/CONVENTION.md +4 -4
  361. package/templates/quickstart/docs/HELPERS.md +10 -8
  362. package/templates/quickstart/package.json +0 -3
  363. package/templates/quickstart/src/blocks/SITE-MAP.md +0 -1
  364. package/templates/quickstart/src/blocks/saucedemo-web/NAV.md +1 -5
  365. package/templates/quickstart/src/blocks/saucedemo-web/cart/nav-cart.block.ts +3 -3
  366. package/templates/quickstart/src/blocks/saucedemo-web/cart/nav-checkout-info.block.ts +3 -3
  367. package/templates/quickstart/src/blocks/saucedemo-web/checkout-step-one/methods/fill-first-name.method.block.ts +5 -4
  368. package/templates/quickstart/src/blocks/saucedemo-web/checkout-step-one/methods/fill-last-name.method.block.ts +5 -4
  369. package/templates/quickstart/src/blocks/saucedemo-web/checkout-step-one/methods/fill-postal-code.method.block.ts +5 -4
  370. package/templates/quickstart/src/blocks/saucedemo-web/checkout-step-one/methods/submit-checkout-info.method.block.ts +5 -4
  371. package/templates/quickstart/src/blocks/saucedemo-web/checkout-step-two/methods/finish-order.method.block.ts +5 -8
  372. package/templates/quickstart/src/blocks/saucedemo-web/inventory/inventory.page.block.ts +3 -3
  373. package/templates/quickstart/src/blocks/saucedemo-web/inventory/methods/add-all-to-cart.method.block.ts +4 -6
  374. package/templates/quickstart/src/blocks/saucedemo-web/inventory/methods/add-to-cart.effect.block.ts +35 -43
  375. package/templates/quickstart/src/blocks/saucedemo-web/inventory/methods/remove-all-from-cart.method.block.ts +4 -6
  376. package/templates/quickstart/src/blocks/saucedemo-web/inventory/methods/remove-from-cart.effect.block.ts +4 -3
  377. package/templates/quickstart/src/blocks/saucedemo-web/inventory/nav-item-detail.block.ts +3 -3
  378. package/templates/quickstart/src/blocks/saucedemo-web/inventory-item/nav-back-to-inventory.block.ts +3 -3
  379. package/templates/quickstart/src/blocks/saucedemo-web/inventory-item/nav-back-to-products.block.ts +3 -3
  380. package/templates/quickstart/src/blocks/saucedemo-web/inventory-item/nav-continue-shopping.block.ts +3 -3
  381. package/templates/quickstart/src/blocks/saucedemo-web/methods/fill-password.method.block.ts +5 -4
  382. package/templates/quickstart/src/blocks/saucedemo-web/methods/fill-username.method.block.ts +5 -4
  383. package/templates/quickstart/src/blocks/saucedemo-web/methods/submit-login.method.block.ts +4 -5
  384. package/templates/quickstart/src/blocks/saucedemo-web/methods/submit-logout.method.block.ts +5 -4
  385. package/templates/quickstart/src/blocks/saucedemo-web/nav-login.block.ts +3 -3
  386. package/templates/quickstart/src/flows/api-demo.flow.ts +12 -10
  387. package/templates/quickstart/src/states/checkout.states.ts +21 -11
  388. package/templates/quickstart/src/stubs/device-showcase.ts +8 -10
  389. package/templates/scaffold/README.md +2 -1
  390. package/templates/scaffold/STRUCTURE.md +5 -4
  391. package/templates/scaffold/config/waygraph.config.ts +1 -0
  392. package/templates/scaffold/gitignore +1 -0
  393. package/templates/scaffold/src/flows/README.md +2 -2
  394. package/templates/scaffold/src/map/(app_base)/docs/_nav.block.ts +3 -3
  395. package/templates/scaffold/src/map/(app_base)/docs/_page.block.ts +3 -3
  396. package/templates/scaffold/src/map/(app_base)/home/_methods/add-item.effect.block.ts +4 -4
  397. package/templates/scaffold/src/map/(app_base)/home/_methods/assert-hello.method.block.ts +3 -3
  398. package/templates/scaffold/src/map/(app_base)/home/_methods/assert-item-added.method.block.ts +3 -3
  399. package/templates/scaffold/src/map/(app_base)/home/_methods/clear-cart.method.block.ts +5 -4
  400. package/templates/scaffold/src/map/(app_base)/home/_methods/remove-item.effect.block.ts +4 -4
  401. package/templates/scaffold/src/map/(app_base)/home/_nav.block.ts +3 -3
  402. package/templates/scaffold/src/map/(app_base)/home/_page.block.ts +3 -3
  403. package/templates/scaffold/src/map/(app_base)/home/nav-verification-link.block.ts +4 -4
  404. package/templates/scaffold/src/map/(external)/hoppscotch/_keys.ts +21 -0
  405. package/templates/scaffold/src/map/(external)/hoppscotch/_methods/assert-response-body.method.block.ts +4 -4
  406. package/templates/scaffold/src/map/(external)/hoppscotch/_methods/assert-response-header.method.block.ts +4 -4
  407. package/templates/scaffold/src/map/(external)/hoppscotch/_methods/assert-status.method.block.ts +4 -4
  408. package/templates/scaffold/src/map/(external)/hoppscotch/_methods/pick-extension-interceptor.method.block.ts +5 -4
  409. package/templates/scaffold/src/map/(external)/hoppscotch/_methods/read-response-body.method.block.ts +6 -5
  410. package/templates/scaffold/src/map/(external)/hoppscotch/_methods/read-response-headers.method.block.ts +6 -5
  411. package/templates/scaffold/src/map/(external)/hoppscotch/_methods/send-request.method.block.ts +5 -4
  412. package/templates/scaffold/src/map/(external)/hoppscotch/_methods/set-bearer-token.method.block.ts +6 -5
  413. package/templates/scaffold/src/map/(external)/hoppscotch/_methods/set-headers.method.block.ts +6 -5
  414. package/templates/scaffold/src/map/(external)/hoppscotch/_methods/set-json-body.method.block.ts +6 -5
  415. package/templates/scaffold/src/map/(external)/hoppscotch/_methods/set-method.method.block.ts +6 -5
  416. package/templates/scaffold/src/map/(external)/hoppscotch/_methods/set-query-params.method.block.ts +6 -5
  417. package/templates/scaffold/src/map/(external)/hoppscotch/_methods/set-url.method.block.ts +6 -5
  418. package/templates/scaffold/src/map/(external)/hoppscotch/_nav.block.ts +3 -3
  419. package/templates/scaffold/src/map/(external)/hoppscotch/_page.block.ts +3 -3
  420. package/templates/scaffold/src/map/(external)/hoppscotch/_states.ts +6 -0
  421. package/templates/scaffold/src/map/(external)/hoppscotch/settings/_nav.block.ts +3 -3
  422. package/templates/scaffold/src/map/(external)/mailpit/_keys.ts +13 -0
  423. package/templates/scaffold/src/map/(external)/mailpit/_methods/assert-email-content.method.block.ts +4 -4
  424. package/templates/scaffold/src/map/(external)/mailpit/_methods/assert-email-received.method.block.ts +4 -4
  425. package/templates/scaffold/src/map/(external)/mailpit/_methods/extract-email-link.method.block.ts +6 -5
  426. package/templates/scaffold/src/map/(external)/mailpit/_methods/open-message.method.block.ts +6 -5
  427. package/templates/scaffold/src/map/(external)/mailpit/_nav.block.ts +3 -3
  428. package/templates/scaffold/src/map/(external)/mailpit/_page.block.ts +3 -3
  429. package/templates/scaffold/src/map/(external)/mailpit/_states.ts +9 -0
  430. package/templates/scaffold/src/map/README.md +7 -0
  431. package/templates/scaffold/src/states/README.md +4 -1
  432. package/templates/scaffold/src/states/demo.mem-keys.ts +1 -29
  433. package/templates/scaffold/src/states/demo.states.ts +14 -20
  434. package/templates/scaffold/tests/hoppscotch.spec.ts +1 -11
  435. package/templates/scaffold/tests/mail-verify.spec.ts +2 -2
  436. package/templates/skills/waygraph-blind-pilot.skill.md +2 -6
  437. package/templates/skills/waygraph-convention.skill.md +23 -14
  438. package/templates/skills/waygraph-pilot.skill.md +7 -4
  439. package/dist/auto-session/session.d.ts +0 -193
  440. package/dist/auto-session/session.js +0 -719
  441. package/dist/auto-session/verbose-log.js +0 -16
  442. package/dist/auto-session.d.ts +0 -2
  443. package/dist/auto-session.js +0 -3
  444. package/dist/cli/discover.d.ts +0 -40
  445. package/dist/cli/discover.js +0 -148
  446. package/dist/commands/agent-dive.js +0 -52
  447. package/dist/commands/check.js +0 -192
  448. package/dist/commands/map.js +0 -29
  449. package/dist/commands/run.js +0 -104
  450. package/dist/commands/session.js +0 -600
  451. package/dist/commands/traverse.js +0 -177
  452. package/dist/core/block.d.ts +0 -109
  453. package/dist/core/blocks/effect.js +0 -23
  454. package/dist/core/config.js +0 -17
  455. package/dist/core/engine.d.ts +0 -198
  456. package/dist/core/flow.d.ts +0 -294
  457. package/dist/core/flow.js +0 -432
  458. package/dist/core/map-builder.js +0 -383
  459. package/dist/core.d.ts +0 -14
  460. package/dist/core.js +0 -15
  461. package/dist/highlights/merge.d.ts +0 -8
  462. package/dist/highlights/merge.js +0 -173
  463. package/dist/highlights/run-phase.d.ts +0 -43
  464. package/dist/highlights/stub-ctx.d.ts +0 -10
  465. package/dist/highlights/stub-ctx.js +0 -331
  466. package/dist/highlights/types.d.ts +0 -613
  467. package/dist/highlights.d.ts +0 -9
  468. package/dist/highlights.js +0 -10
  469. package/dist/pilot-overlay.d.ts +0 -5
  470. package/dist/pilot-overlay.js +0 -6
  471. package/dist/runner/banner-log.js +0 -63
  472. package/dist/runner/chain-run.js +0 -102
  473. package/dist/runner/cursor.js +0 -140
  474. package/dist/runner/demo-log.js +0 -316
  475. package/dist/runner/device-stage.d.ts +0 -9
  476. package/dist/runner/device-stage.js +0 -420
  477. package/dist/runner/discovery.js +0 -105
  478. package/dist/runner/index.js +0 -2
  479. package/dist/runner/inpage/banner.d.ts +0 -21
  480. package/dist/runner/inpage/banner.js +0 -156
  481. package/dist/runner/inpage/caption.d.ts +0 -3
  482. package/dist/runner/inpage/caption.js +0 -23
  483. package/dist/runner/inpage/core.d.ts +0 -4
  484. package/dist/runner/inpage/core.js +0 -316
  485. package/dist/runner/inpage/device.d.ts +0 -3
  486. package/dist/runner/inpage/device.js +0 -211
  487. package/dist/runner/inpage/network.d.ts +0 -15
  488. package/dist/runner/inpage/network.js +0 -217
  489. package/dist/runner/inpage/panel-chrome.js +0 -192
  490. package/dist/runner/inpage/stamp.js +0 -46
  491. package/dist/runner/inpage/swipe-zoom.js +0 -220
  492. package/dist/runner/inpage/todos.js +0 -337
  493. package/dist/runner/interaction-patch.js +0 -384
  494. package/dist/runner/main.js +0 -469
  495. package/dist/runner/network-capture.d.ts +0 -9
  496. package/dist/runner/network-capture.js +0 -126
  497. package/dist/runner/overlay-css.d.ts +0 -3
  498. package/dist/runner/overlay-css.js +0 -377
  499. package/dist/runner/overlay-install.js +0 -90
  500. package/dist/runner/overlay-stage.js +0 -110
  501. package/dist/runner/rings.js +0 -514
  502. package/dist/runner/seed-mem.js +0 -110
  503. package/dist/runner/slides.js +0 -278
  504. package/dist/runner/step-mode.js +0 -703
  505. package/dist/runner/step-panels.js +0 -729
  506. package/dist/runner/teardown.js +0 -202
  507. package/dist/runner/todo-dock.js +0 -142
  508. package/dist/session/auto-explore-run.d.ts +0 -40
  509. package/dist/session/auto-explore-run.js +0 -707
  510. package/dist/session/step-overlay.d.ts +0 -37
  511. package/dist/session/step-overlay.js +0 -244
  512. package/dist/traverse/run.js +0 -423
  513. package/examples/routed-demo/playwright.config.ts +0 -21
  514. package/examples/saucedemo/src/blocks/saucedemo-web/ff-owner-auth.block.ts +0 -22
  515. package/templates/quickstart/src/blocks/saucedemo-web/ff-owner-auth.block.ts +0 -22
  516. /package/dist/{commands → cli/commands}/agent-dive-scaffold.d.ts +0 -0
  517. /package/dist/{commands → cli/commands}/agent-dive.d.ts +0 -0
  518. /package/dist/{commands → cli/commands}/extensions.d.ts +0 -0
  519. /package/dist/{commands → cli/commands}/init.d.ts +0 -0
  520. /package/dist/{commands → cli/commands}/list.d.ts +0 -0
  521. /package/dist/{commands → cli/commands}/map.d.ts +0 -0
  522. /package/dist/{commands → cli/commands}/session.d.ts +0 -0
  523. /package/dist/{commands → cli/commands}/test.d.ts +0 -0
  524. /package/dist/{commands → cli/commands}/traverse.d.ts +0 -0
  525. /package/dist/{commands → cli/commands}/try.d.ts +0 -0
  526. /package/dist/{commands → cli/commands}/upgrade.d.ts +0 -0
  527. /package/dist/{highlights → demo/narration}/shorthand.js +0 -0
  528. /package/dist/{session/overlay-beacon.d.ts → demo/overlay/beacon.d.ts} +0 -0
  529. /package/dist/{session/overlay-beacon.js → demo/overlay/beacon.js} +0 -0
  530. /package/dist/{pilot-overlay/action-ring.d.ts → demo/overlay/pilot/actions.d.ts} +0 -0
  531. /package/dist/{ui → demo/overlay/ui}/components/ring.d.ts +0 -0
  532. /package/dist/{ui → demo/overlay/ui}/stylesheet.d.ts +0 -0
  533. /package/dist/{ui → demo/overlay/ui}/stylesheet.js +0 -0
  534. /package/dist/{ui → demo/overlay/ui}/tokens.d.ts +0 -0
  535. /package/dist/{ui → demo/overlay/ui}/tokens.js +0 -0
  536. /package/dist/{highlights → demo}/types.js +0 -0
  537. /package/dist/{auto-session → demo}/verbose-log.d.ts +0 -0
  538. /package/dist/{selector.d.ts → engine/trait/selector.d.ts} +0 -0
  539. /package/dist/{selector.js → engine/trait/selector.js} +0 -0
  540. /package/dist/{traverse → live/traverse}/coverage.d.ts +0 -0
  541. /package/dist/{traverse → live/traverse}/coverage.js +0 -0
  542. /package/dist/{traverse → live/traverse}/lease.d.ts +0 -0
  543. /package/dist/{traverse → live/traverse}/lease.js +0 -0
  544. /package/dist/{session/block-inject.d.ts → manifest/roots.d.ts} +0 -0
  545. /package/dist/{blocks-select.d.ts → manifest/select.d.ts} +0 -0
  546. /package/dist/{blocks-select.js → manifest/select.js} +0 -0
  547. /package/dist/{browser.d.ts → runtime/browser.d.ts} +0 -0
  548. /package/dist/{env-file.d.ts → runtime/env-file.d.ts} +0 -0
  549. /package/dist/{playwright-config.js → runtime/playwright-config.js} +0 -0
  550. /package/dist/{playwright.config.d.ts → runtime/playwright.config.d.ts} +0 -0
  551. /package/dist/{video-dir.d.ts → runtime/video-dir.d.ts} +0 -0
  552. /package/dist/{webserver.d.ts → runtime/webserver.d.ts} +0 -0
@@ -1,719 +0,0 @@
1
- // Split out of the former 1,078-line auto-session.ts (see src/ARCHITECTURE.md). Behavior unchanged.
2
- import { CONSOLE_LOG_MAX_ENTRIES, FULL_MODE_DEFAULT_DEPTH, FULL_MODE_MAX_NODES, FULL_MODE_MAX_TEXT_LENGTH, TRACE_MAX_STEPS, buildSessionSnapshot, parsePick, stubFilePath, stubPhaseHasContent, walkFullDom } from "./helpers.js";
3
- import { instrumentPilotActions, installPersistentPilotOverlay, showPilotActivity, showPilotFixtures, showPilotVision, phaseToOverlayFixtures, describeOverlayFixtures, updatePilotOverlay } from "../pilot-overlay.js";
4
- import { buildExploreContext, buildExploreMenu } from "../session/auto-explore.js";
5
- import { MemPage } from "../mem-page.js";
6
- import { Engine } from "../core.js";
7
- import { detectHere, ensureLivePage, ensureMem, resolveBaseUrl, runOneBlock, seedDefaultMem } from "../session/auto-explore-run.js";
8
- import { collectKnownInteractionSelectors, unmappedInteractionsPageScript } from "../analysis/coverage-gap.js";
9
- import { runStubPhase } from "../highlights.js";
10
- import { verboseLog } from "./verbose-log.js";
11
- import { findBlockPathDetailed } from "../analysis/graph.js";
12
- import { configuredExtensions } from "../config.js";
13
- import { chromiumExecutablePath, launchContext } from "../browser.js";
14
- /**
15
- * Non-interactive explore session: same graph/library/mem/browser setup
16
- * `runAutoExplore` runs in `--cli` mode, driven by `applyPick` instead of a
17
- * blocking `readline` loop. Headless by default (matching
18
- * `runAutoExplore`'s own `cli` branch), optionally visible via
19
- * `AutoSessionInit.headless: false` - this type only ever backs the `--cli`
20
- * picker, never the headful page-embedded panel, headless or not.
21
- */
22
- export class AutoSession {
23
- projectDir;
24
- inject;
25
- blocksSelect;
26
- graph;
27
- library;
28
- mem;
29
- engine;
30
- closeBrowser;
31
- context;
32
- page;
33
- startUrl;
34
- sessionId;
35
- here = null;
36
- lastRunNote = null;
37
- trace = [];
38
- consoleLog = [];
39
- knownInteractionSelectors;
40
- headless;
41
- lastOverlayInfo = null;
42
- constructor(projectDir, inject, blocksSelect, graph, library, mem, engine, closeBrowser, context, page, startUrl, sessionId, knownInteractionSelectors, headless) {
43
- this.projectDir = projectDir;
44
- this.inject = inject;
45
- this.blocksSelect = blocksSelect;
46
- this.graph = graph;
47
- this.library = library;
48
- this.mem = mem;
49
- this.engine = engine;
50
- this.closeBrowser = closeBrowser;
51
- this.context = context;
52
- this.page = page;
53
- this.startUrl = startUrl;
54
- this.sessionId = sessionId;
55
- this.knownInteractionSelectors = knownInteractionSelectors;
56
- this.headless = headless;
57
- }
58
- static async start(init) {
59
- const baseURL = init.baseURL ?? (await resolveBaseUrl(init.projectDir));
60
- const skipNav = init.skipInitialNavigation === true;
61
- const startUrl = skipNav ? undefined : (init.startUrl ?? baseURL);
62
- const exploreOpts = {
63
- ...(init.blocksSelect ? { blocksSelect: init.blocksSelect } : {}),
64
- ...(init.inject?.length ? { inject: init.inject } : {}),
65
- };
66
- const { graph, library } = await buildExploreContext(init.projectDir, Object.keys(exploreOpts).length ? exploreOpts : undefined);
67
- const mem = new MemPage();
68
- seedDefaultMem(library.byName, mem);
69
- const headless = init.headless ?? true;
70
- const engine = new Engine({ headless });
71
- const { chromium } = await import("@playwright/test");
72
- const executablePath = chromiumExecutablePath();
73
- // Real gap found live: a headed (--non-headless) session kept a fixed
74
- // 1280x720 content area even when the user maximized/fullscreened the
75
- // actual window - `viewport: null` alone only makes the PAGE track the
76
- // window; the window itself still launches at Chromium's own small
77
- // default size unless told to start maximized. Same fix cli.ts's own
78
- // --step/headed launch already uses (see its own comment there) -
79
- // headless keeps the fixed viewport since there's no real window to size.
80
- const launchOpts = {
81
- headless,
82
- // Keep Playwright's default --no-startup-window for headful: without it
83
- // Chromium opens its own "New Tab" window AND our context.newPage() opens
84
- // a second about:blank window. bringToFront() below surfaces the real page.
85
- args: headless ? [] : ["--start-maximized"],
86
- };
87
- if (executablePath)
88
- launchOpts.executablePath = executablePath;
89
- const contextOpts = {
90
- viewport: headless ? { width: 1280, height: 720 } : null,
91
- };
92
- if (baseURL)
93
- contextOpts.baseURL = baseURL;
94
- const { close: closeBrowser, context } = await launchContext({
95
- launcher: chromium,
96
- launch: launchOpts,
97
- context: contextOpts,
98
- extensions: await configuredExtensions(init.projectDir),
99
- });
100
- await installPersistentPilotOverlay(context);
101
- const page = await context.newPage();
102
- instrumentPilotActions(page, headless ? 0 : 450);
103
- if (startUrl) {
104
- await page.goto(startUrl, { waitUntil: "domcontentloaded" }).catch(() => { });
105
- await page.waitForLoadState("load").catch(() => { });
106
- }
107
- else {
108
- await page.goto("about:blank").catch(() => { });
109
- }
110
- const knownInteractionSelectors = collectKnownInteractionSelectors(init.projectDir, library, init.inject);
111
- const session = new AutoSession(init.projectDir, init.inject, init.blocksSelect, graph, library, mem, engine, closeBrowser, context, page, startUrl, init.sessionId, knownInteractionSelectors, headless);
112
- page.on("load", () => {
113
- void session.repaintOverlayAfterNavigation();
114
- });
115
- if (!headless) {
116
- await session.bootstrapOverlay().catch(() => { });
117
- await page.bringToFront().catch(() => { });
118
- }
119
- // Attached once, on the page created here - `ensureLivePage` only swaps
120
- // to a fresh Page if the current one closed (a rare case, e.g. the human
121
- // closing the tab), not on ordinary same-page SPA navigation, which is
122
- // all this target (and most real sites) actually do.
123
- page.on("console", (msg) => {
124
- session.pushConsoleLog({
125
- type: "console",
126
- level: msg.type(),
127
- text: msg.text(),
128
- timestamp: new Date().toISOString(),
129
- });
130
- });
131
- page.on("pageerror", (err) => {
132
- session.pushConsoleLog({
133
- type: "pageerror",
134
- text: err instanceof Error ? err.message : String(err),
135
- timestamp: new Date().toISOString(),
136
- });
137
- });
138
- page.on("response", (res) => {
139
- // Every failed response (the original case), PLUS every mutation
140
- // (non-GET) response regardless of status - a real gap found live:
141
- // "auto console" only logging failures made a SUCCESSFUL POST that
142
- // simply didn't navigate anywhere look identical to "nothing
143
- // happened at all," undiagnosable the same way a real failure was.
144
- // A mutation's outcome (2xx or not) is always diagnostically
145
- // relevant; a GET's usually isn't (assets, trackers) unless it failed.
146
- const method = res.request().method();
147
- if (res.status() < 400 && method === "GET")
148
- return;
149
- session.pushConsoleLog({
150
- type: "response",
151
- text: `${method} ${res.statusText()}`,
152
- url: res.url(),
153
- status: res.status(),
154
- timestamp: new Date().toISOString(),
155
- });
156
- });
157
- return session;
158
- }
159
- /** Pure getter - returns a copy, not the live array. */
160
- getTrace() {
161
- return [...this.trace];
162
- }
163
- pushTrace(step) {
164
- this.trace.push(step);
165
- if (this.trace.length > TRACE_MAX_STEPS)
166
- this.trace.shift();
167
- }
168
- /** Pure getter - returns a copy, not the live array. */
169
- getConsoleLog() {
170
- return [...this.consoleLog];
171
- }
172
- pushConsoleLog(entry) {
173
- this.consoleLog.push(entry);
174
- if (this.consoleLog.length > CONSOLE_LOG_MAX_ENTRIES)
175
- this.consoleLog.shift();
176
- }
177
- async currentMenu() {
178
- this.page = await ensureLivePage(this.context, this.page, this.startUrl);
179
- if (this.here === null) {
180
- this.here = await detectHere(this.page, this.library.navBlocks);
181
- }
182
- const menu = await buildExploreMenu(this.page, this.graph, this.library, this.here);
183
- // Every caller of currentMenu() (status reads, applyPick/applyPath,
184
- // the raw click/type/goto primitives, resync) already routes through
185
- // here, so hooking the overlay refresh at this one point covers every
186
- // real state-changing (and reading) path without needing a separate
187
- // call at each site. Awaited deliberately, not fire-and-forget - the
188
- // whole point is a human watching the screen sees the SAME state a
189
- // concurrent API caller just got back, not a stale frame that catches
190
- // up moments later.
191
- this.lastOverlayInfo = {
192
- sessionId: this.sessionId,
193
- snapshot: buildSessionSnapshot(menu, this.library.byName, this.here, this.lastRunNote),
194
- graph: this.graph,
195
- };
196
- await updatePilotOverlay(this.page, this.lastOverlayInfo);
197
- await this.warnUnmappedInteractions();
198
- return menu;
199
- }
200
- /** Paint the overlay on about:blank / immediately after session start (headful browser). */
201
- async bootstrapOverlay() {
202
- await this.currentMenu();
203
- }
204
- /** Re-apply cached overlay state after navigation (init script restores shell only). */
205
- async repaintOverlayAfterNavigation() {
206
- if (this.lastOverlayInfo) {
207
- await updatePilotOverlay(this.page, this.lastOverlayInfo).catch(() => { });
208
- return;
209
- }
210
- if (!this.headless) {
211
- await this.bootstrapOverlay().catch(() => { });
212
- }
213
- }
214
- /**
215
- * Flags same-origin `<a href>` paths and visible buttons with no NavBlock
216
- * URL / Block selector in the loaded library — read via `auto console`.
217
- * Deduped per page load so repeated status/send calls stay quiet.
218
- */
219
- async warnUnmappedInteractions() {
220
- const knownPathnames = [];
221
- for (const entry of this.library.navBlocks) {
222
- const url = entry.block.__waygraphNavUrl;
223
- if (!url)
224
- continue;
225
- try {
226
- knownPathnames.push(new URL(url, this.page.url()).pathname);
227
- }
228
- catch {
229
- /* not a resolvable URL (relative to an unset base, etc.) - skip */
230
- }
231
- }
232
- const payload = {
233
- knownPathnames,
234
- knownSelectors: this.knownInteractionSelectors,
235
- };
236
- await this.page.evaluate(unmappedInteractionsPageScript, payload).catch(() => { });
237
- }
238
- /** Pure getter - no Block runs, no mem/page mutation. */
239
- async currentSnapshot() {
240
- const menu = await this.currentMenu();
241
- return buildSessionSnapshot(menu, this.library.byName, this.here, this.lastRunNote);
242
- }
243
- /**
244
- * Pure getter - reads the live page's structure at the requested fidelity.
245
- * No Block runs, no mem/page mutation. `selector` scopes either mode to one
246
- * element's subtree; it is a modifier, not a third mode.
247
- */
248
- async inspectDom(opts) {
249
- this.page = await ensureLivePage(this.context, this.page, this.startUrl);
250
- const mode = opts.mode ?? "aria";
251
- const ariaOptions = opts.depth !== undefined ? { mode: "ai", depth: opts.depth } : { mode: "ai" };
252
- if (opts.selector) {
253
- const locator = this.page.locator(opts.selector).first();
254
- if ((await locator.count()) === 0) {
255
- return { ok: false, error: `no element matches selector "${opts.selector}"` };
256
- }
257
- await showPilotVision(this.page, opts.selector, `dom (${mode}): ${opts.selector}`, "orange");
258
- if (mode === "full") {
259
- const caps = {
260
- depth: opts.depth ?? FULL_MODE_DEFAULT_DEPTH,
261
- maxNodes: FULL_MODE_MAX_NODES,
262
- maxTextLength: FULL_MODE_MAX_TEXT_LENGTH,
263
- };
264
- const { tree, truncated } = await locator.evaluate(walkFullDom, caps);
265
- return { ok: true, snapshot: { mode: "full", selector: opts.selector, truncated, tree } };
266
- }
267
- const tree = await locator.ariaSnapshotJSON(ariaOptions);
268
- return { ok: true, snapshot: { mode: "aria", selector: opts.selector, truncated: false, tree } };
269
- }
270
- await showPilotActivity(this.page, `Running (Dom): ${mode}, whole page`);
271
- if (mode === "full") {
272
- // page.evaluate only ships the one function passed to it - it can't
273
- // reach another named function by closure. Routing the whole-page case
274
- // through the same `html` Locator lets both cases share one
275
- // self-contained walkFullDom instead of two near-duplicate callbacks.
276
- const caps = {
277
- depth: opts.depth ?? FULL_MODE_DEFAULT_DEPTH,
278
- maxNodes: FULL_MODE_MAX_NODES,
279
- maxTextLength: FULL_MODE_MAX_TEXT_LENGTH,
280
- };
281
- const { tree, truncated } = await this.page.locator("html").first().evaluate(walkFullDom, caps);
282
- return { ok: true, snapshot: { mode: "full", truncated, tree } };
283
- }
284
- const tree = await this.page.ariaSnapshotJSON(ariaOptions);
285
- return { ok: true, snapshot: { mode: "aria", truncated: false, tree } };
286
- }
287
- /**
288
- * Pure getter - reads the live page's client-side state: localStorage,
289
- * sessionStorage, and registered service workers (scope/active URL/state).
290
- * Real, direct follow-up to `auto console`'s own gap: a site doing web
291
- * push (this target has a real `NOTIFICATION_VAPID` config, confirmed via
292
- * `auto dom` earlier) keeps push-subscription/auth state in these places,
293
- * not in the rendered DOM `inspectDom` reads.
294
- */
295
- async inspectStorage() {
296
- this.page = await ensureLivePage(this.context, this.page, this.startUrl);
297
- const [localStorageEntries, sessionStorageEntries] = await this.page.evaluate(() => [
298
- Object.entries(window.localStorage),
299
- Object.entries(window.sessionStorage),
300
- ]);
301
- const cookies = await this.context.cookies();
302
- const workers = this.context.serviceWorkers();
303
- const registrations = await this.page
304
- .evaluate(async () => {
305
- if (!("serviceWorker" in navigator))
306
- return [];
307
- const regs = await navigator.serviceWorker.getRegistrations();
308
- return regs.map((r) => ({
309
- scope: r.scope,
310
- ...(r.active?.scriptURL ? { activeUrl: r.active.scriptURL } : {}),
311
- ...(r.active?.state ? { state: r.active.state } : {}),
312
- }));
313
- })
314
- .catch(() => []);
315
- return {
316
- localStorage: Object.fromEntries(localStorageEntries),
317
- sessionStorage: Object.fromEntries(sessionStorageEntries),
318
- cookies: cookies.map((c) => ({
319
- name: c.name,
320
- value: c.value,
321
- domain: c.domain,
322
- path: c.path,
323
- httpOnly: c.httpOnly,
324
- secure: c.secure,
325
- })),
326
- serviceWorkers: workers.map((w) => w.url()),
327
- serviceWorkerRegistrations: registrations,
328
- };
329
- }
330
- /**
331
- * Runs one already-resolved Block entry for real - the shared core both
332
- * `applyPick` (resolved via a live-menu index) and `applyPath` (resolved
333
- * directly by name, bypassing live-menu-visibility entirely - see
334
- * `applyPath`'s own comment for why) call. `expectedTo` is only used as a
335
- * fallback when a Block's own `resolve()` doesn't set `__state` - same
336
- * behavior `applyPick` always had, just factored out, not changed.
337
- */
338
- /** Paint + log a Block's authored waygraph overlay fixtures (same as demo does), best-effort. */
339
- async paintStubPhase(tag, phase, holdMs) {
340
- if (!this.page || !stubPhaseHasContent(phase))
341
- return;
342
- const fixtures = phaseToOverlayFixtures(phase, holdMs);
343
- for (const line of describeOverlayFixtures(tag, fixtures))
344
- verboseLog("pilot", line);
345
- await showPilotFixtures(this.page, fixtures).catch(() => { });
346
- }
347
- async runNamedBlock(entry, expectedTo, instanceOption) {
348
- const from = this.here;
349
- const stubBeforeResult = await runStubPhase(entry.block, "stubBefore");
350
- await this.paintStubPhase("stub.before", stubBeforeResult, 6000);
351
- const stepBase = {
352
- block: entry.block.name,
353
- from,
354
- timestamp: new Date().toISOString(),
355
- ...(stubPhaseHasContent(stubBeforeResult) ? { stubBefore: stubBeforeResult } : {}),
356
- };
357
- try {
358
- if (instanceOption) {
359
- this.mem.set(instanceOption.key, instanceOption.value);
360
- }
361
- // Always the non-interactive path (cli: false) - a detached session has
362
- // no TTY to prompt on; a missing mem key fails loud instead of hanging.
363
- await ensureMem(entry, this.mem, false);
364
- const result = await runOneBlock(this.engine, entry, this.context, this.page, this.mem, false);
365
- this.here = result.__state ?? expectedTo;
366
- this.lastRunNote = `${entry.block.name} -> ${this.here}`;
367
- const stubAfterResult = await runStubPhase(entry.block, "stubAfter", { out: result });
368
- await this.paintStubPhase("stub.after", stubAfterResult, 6000);
369
- this.pushTrace({
370
- ...stepBase,
371
- to: this.here,
372
- ...(stubPhaseHasContent(stubAfterResult) ? { stubAfter: stubAfterResult } : {}),
373
- });
374
- }
375
- catch (err) {
376
- this.lastRunNote = `${entry.block.name} failed`;
377
- const message = err instanceof Error ? err.message : String(err);
378
- const stubOnErrorResult = await runStubPhase(entry.block, "stubOnError", { error: err });
379
- await this.paintStubPhase("stub.error", stubOnErrorResult, 8000);
380
- this.pushTrace({
381
- ...stepBase,
382
- error: message,
383
- ...(stubPhaseHasContent(stubOnErrorResult) ? { stubOnError: stubOnErrorResult } : {}),
384
- });
385
- return { ok: false, error: `${entry.block.name} failed - ${message}` };
386
- }
387
- const nextMenu = await this.currentMenu();
388
- return {
389
- ok: true,
390
- snapshot: buildSessionSnapshot(nextMenu, this.library.byName, this.here, this.lastRunNote),
391
- quit: false,
392
- };
393
- }
394
- /** Applies exactly one pick: runs at most one Block, returns the resulting state. */
395
- async applyPick(raw) {
396
- const menu = await this.currentMenu();
397
- const pick = parsePick(raw, menu);
398
- if (pick.type === "invalid")
399
- return { ok: false, error: pick.reason };
400
- if (pick.type === "quit") {
401
- return {
402
- ok: true,
403
- snapshot: buildSessionSnapshot(menu, this.library.byName, this.here, this.lastRunNote),
404
- quit: true,
405
- };
406
- }
407
- const edge = menu.flat[pick.index];
408
- const entry = this.library.byName.get(edge.block);
409
- if (!entry) {
410
- return { ok: false, error: `Block "${edge.block}" not loaded - skipped` };
411
- }
412
- await showPilotActivity(this.page, `Running (Block): ${edge.block}`);
413
- return this.runNamedBlock(entry, edge.to, edge.instanceOption);
414
- }
415
- /**
416
- * Re-discovers the project's Block library and graph from disk, using the
417
- * exact same call `start()` itself makes - not a duplicated read - and
418
- * replaces `this.library`/`this.graph` in place. Leaves the live page,
419
- * mem, browser/context, and current Checkpoint (`here`) untouched, so a
420
- * Block written to disk mid-session becomes pickable via a later
421
- * `applyPick` without restarting the session. See
422
- * openspec/changes/waygraph-blind-pilot/design.md.
423
- */
424
- async reloadLibrary() {
425
- if (this.page)
426
- await showPilotActivity(this.page, "Running: reload");
427
- const exploreOpts = {
428
- ...(this.blocksSelect ? { blocksSelect: this.blocksSelect } : {}),
429
- ...(this.inject?.length ? { inject: this.inject } : {}),
430
- };
431
- const { graph, library } = await buildExploreContext(this.projectDir, Object.keys(exploreOpts).length ? exploreOpts : undefined);
432
- this.graph = graph;
433
- this.library = library;
434
- if (this.page)
435
- await showPilotActivity(this.page, "Map updated");
436
- }
437
- /**
438
- * Forces `here` to be re-detected from the real live page, discarding
439
- * whatever was cached - the fix for a real, confirmed gap: `here` is only
440
- * ever updated by an action this class itself ran (`applyPick`/`applyPath`
441
- * set it to a Block's own resolved Checkpoint; `rawClick`/`rawType`/
442
- * `rawGoto` reset it to `null` because *they* just changed the page). If a
443
- * human co-driving the same visible session clicks/types/navigates
444
- * directly - a real scenario for a headful Pilot session someone is
445
- * watching, not hypothetical - none of that goes through this class at
446
- * all, so `here` silently goes stale: `currentMenu()`'s own lazy check
447
- * (`if (this.here === null)`, just above) only re-detects when `here` is
448
- * already unknown, never to confirm a *known* value is still correct.
449
- * This does not crash the session (the process/socket/page all stay
450
- * alive) but subsequent `send`/`reach` calls would act on a menu built
451
- * from the wrong Checkpoint until something forces re-detection - this
452
- * method is that: unconditionally re-run the same `detectHere` logic the
453
- * lazy path already uses, regardless of what `here` currently holds.
454
- */
455
- async resync() {
456
- this.page = await ensureLivePage(this.context, this.page, this.startUrl);
457
- await showPilotActivity(this.page, "Running: resync");
458
- this.here = await detectHere(this.page, this.library.navBlocks);
459
- const menu = await this.currentMenu();
460
- this.lastRunNote = `resync -> ${this.here ?? "Unknown"}`;
461
- return {
462
- ok: true,
463
- snapshot: buildSessionSnapshot(menu, this.library.byName, this.here, this.lastRunNote),
464
- quit: false,
465
- };
466
- }
467
- /**
468
- * Raw interaction primitives for a page no Block covers yet (Blind Pilot -
469
- * see openspec/changes/waygraph-blind-pilot). Unlike `applyPick`, the
470
- * resulting Checkpoint isn't known ahead of time from a Block's own
471
- * `resolve()`, so each of these invalidates the cached `here` (forcing
472
- * `currentMenu()`'s existing lazy `detectHere` call to run again) rather
473
- * than assuming the page didn't move anywhere a Block now recognizes.
474
- * A selector matching nothing is a reported failure, not a silent no-op.
475
- */
476
- async rawClick(selector) {
477
- this.page = await ensureLivePage(this.context, this.page, this.startUrl);
478
- await showPilotActivity(this.page, `Running (no Block): click "${selector}"`);
479
- const locator = this.page.locator(selector).first();
480
- if ((await locator.count()) === 0) {
481
- return { ok: false, error: `no element matches selector "${selector}"` };
482
- }
483
- await showPilotVision(this.page, selector, `click: ${selector}`);
484
- await locator.click();
485
- this.here = null;
486
- const menu = await this.currentMenu();
487
- this.lastRunNote = `click "${selector}" -> ${this.here ?? "Unknown"}`;
488
- return {
489
- ok: true,
490
- snapshot: buildSessionSnapshot(menu, this.library.byName, this.here, this.lastRunNote),
491
- quit: false,
492
- };
493
- }
494
- async rawType(selector, text) {
495
- this.page = await ensureLivePage(this.context, this.page, this.startUrl);
496
- await showPilotActivity(this.page, `Running (no Block): type into "${selector}"`);
497
- const locator = this.page.locator(selector).first();
498
- if ((await locator.count()) === 0) {
499
- return { ok: false, error: `no element matches selector "${selector}"` };
500
- }
501
- await showPilotVision(this.page, selector, `type: ${selector}`);
502
- await locator.fill(text);
503
- this.here = null;
504
- const menu = await this.currentMenu();
505
- this.lastRunNote = `type into "${selector}" -> ${this.here ?? "Unknown"}`;
506
- return {
507
- ok: true,
508
- snapshot: buildSessionSnapshot(menu, this.library.byName, this.here, this.lastRunNote),
509
- quit: false,
510
- };
511
- }
512
- /**
513
- * Presses a real key on a real focused element - a real gap found live:
514
- * many real inline-edit inputs (no visible Save button at all) commit on
515
- * Enter, not on blur/click-elsewhere. `key` is a Playwright key name
516
- * (e.g. "Enter", "Escape", "Tab") - same vocabulary as
517
- * `page.keyboard.press`, which this wraps.
518
- */
519
- async rawPress(selector, key) {
520
- this.page = await ensureLivePage(this.context, this.page, this.startUrl);
521
- await showPilotActivity(this.page, `Running (no Block): press "${key}" on "${selector}"`);
522
- const locator = this.page.locator(selector).first();
523
- if ((await locator.count()) === 0) {
524
- return { ok: false, error: `no element matches selector "${selector}"` };
525
- }
526
- await showPilotVision(this.page, selector, `press ${key}: ${selector}`);
527
- await locator.press(key);
528
- this.here = null;
529
- const menu = await this.currentMenu();
530
- this.lastRunNote = `press "${key}" on "${selector}" -> ${this.here ?? "Unknown"}`;
531
- return {
532
- ok: true,
533
- snapshot: buildSessionSnapshot(menu, this.library.byName, this.here, this.lastRunNote),
534
- quit: false,
535
- };
536
- }
537
- async rawGoto(url) {
538
- this.page = await ensureLivePage(this.context, this.page, this.startUrl);
539
- await showPilotActivity(this.page, `Running (no Block): goto "${url}"`);
540
- try {
541
- await this.page.goto(url, { waitUntil: "domcontentloaded" });
542
- }
543
- catch (err) {
544
- return { ok: false, error: `goto "${url}" failed - ${err instanceof Error ? err.message : String(err)}` };
545
- }
546
- this.here = null;
547
- const menu = await this.currentMenu();
548
- this.lastRunNote = `goto "${url}" -> ${this.here ?? "Unknown"}`;
549
- return {
550
- ok: true,
551
- snapshot: buildSessionSnapshot(menu, this.library.byName, this.here, this.lastRunNote),
552
- quit: false,
553
- };
554
- }
555
- /**
556
- * Fills a real `<input type="file">` - a built-in stub kind
557
- * ("image"/"pdf"/"video", see `stubFilePath`) or a caller-supplied
558
- * `filePath` for anything else ("whatever", per the real request this
559
- * responds to). Same raw-primitive shape as click/type/goto: works with
560
- * zero Blocks, invalidates `here` since the app may react to the upload.
561
- */
562
- async rawUpload(selector, stub) {
563
- this.page = await ensureLivePage(this.context, this.page, this.startUrl);
564
- const filePath = typeof stub === "string" ? stubFilePath(stub) : stub.filePath;
565
- const label = typeof stub === "string" ? stub : filePath;
566
- await showPilotActivity(this.page, `Running (no Block): upload ${label} into "${selector}"`);
567
- const locator = this.page.locator(selector).first();
568
- if ((await locator.count()) === 0) {
569
- return { ok: false, error: `no element matches selector "${selector}"` };
570
- }
571
- await showPilotVision(this.page, selector, `upload ${label}: ${selector}`);
572
- try {
573
- await locator.setInputFiles(filePath);
574
- }
575
- catch (err) {
576
- return { ok: false, error: `upload into "${selector}" failed - ${err instanceof Error ? err.message : String(err)}` };
577
- }
578
- this.here = null;
579
- const menu = await this.currentMenu();
580
- this.lastRunNote = `upload ${label} into "${selector}" -> ${this.here ?? "Unknown"}`;
581
- return {
582
- ok: true,
583
- snapshot: buildSessionSnapshot(menu, this.library.byName, this.here, this.lastRunNote),
584
- quit: false,
585
- };
586
- }
587
- /**
588
- * Agent-sent highlight fixtures (rings + optional todos) on the live page -
589
- * the Pilot equivalent of Block `stubBefore` narration in `waygraph demo`.
590
- * Does not run a Block; paint-only. Missing selectors are reported, not fatal.
591
- */
592
- async applyHighlight(fixtures) {
593
- this.page = await ensureLivePage(this.context, this.page, this.startUrl);
594
- const detail = fixtures.clear === true
595
- ? "clear"
596
- : [
597
- fixtures.rings?.length ? `${fixtures.rings.length} ring(s)` : null,
598
- fixtures.todos?.length ? `${fixtures.todos.length} todo(s)` : null,
599
- fixtures.zoom && fixtures.zoom > 1.001 ? `zoom ${fixtures.zoom}` : null,
600
- fixtures.device
601
- ? `device ${typeof fixtures.device === "string" ? fixtures.device : fixtures.device.preset || "custom"}`
602
- : null,
603
- fixtures.rings?.some((r) => r.focus) ? "focus" : null,
604
- ]
605
- .filter(Boolean)
606
- .join(", ") || "fixtures";
607
- // Same bottom-left activity toast as Running (Dom)/(Block) - agent narration.
608
- await showPilotActivity(this.page, `Highlighting: ${detail}`);
609
- try {
610
- for (const line of describeOverlayFixtures("highlight", fixtures))
611
- verboseLog("pilot", line);
612
- const { painted, missing } = await showPilotFixtures(this.page, fixtures);
613
- const menu = await this.currentMenu();
614
- this.lastRunNote = fixtures.clear
615
- ? "highlight cleared"
616
- : `highlight painted ${painted}` +
617
- (missing.length ? ` (missing: ${missing.join(", ")})` : "");
618
- return {
619
- ok: true,
620
- painted,
621
- missing,
622
- snapshot: buildSessionSnapshot(menu, this.library.byName, this.here, this.lastRunNote),
623
- };
624
- }
625
- catch (err) {
626
- return {
627
- ok: false,
628
- error: `highlight failed - ${err instanceof Error ? err.message : String(err)}`,
629
- };
630
- }
631
- }
632
- /**
633
- * Runs a whole multi-step route to `targetCheckpoint` in one call, instead
634
- * of an agent hand-picking one index at a time across many separate
635
- * `applyPick` round trips - real, reported pain for any non-trivial task
636
- * on a rich graph ("the entire prompts of the day" driving one step per
637
- * call).
638
- *
639
- * Two other designs were tried and rejected by direct reproduction against
640
- * live saucedemo.com before this one, both undone by the same root cause:
641
- * a `from: "*"` edge (e.g. "Checkout", only clickable once you're actually
642
- * on the cart page with items) looks globally reachable to
643
- * `findBlockPath`'s static-graph BFS, which has no live-page access and
644
- * can't know the edge's real precondition isn't showing yet. Computing the
645
- * whole route once upfront names a premature wildcard step immediately;
646
- * scoring each live menu option by its static-graph distance to the
647
- * target (greedy best-first) doesn't fix it either - a harmless self-loop
648
- * Method can score just as well as real progress once wildcard "shortcuts"
649
- * are baked into every distance calculation, and the session gets stuck
650
- * repeating it.
651
- *
652
- * The fix that actually works: stop trying to be clever about live-menu
653
- * visibility per step, and reuse `auto --blocks <From> <To>`'s own already
654
- * -proven approach instead - compute the path ONCE (via
655
- * `findBlockPathDetailed`, the same BFS `findBlockPath`/`runChainAuto`
656
- * already use, extended to also return each hop's specific edge - see its
657
- * own doc comment for why that extra detail is load-bearing, not cosmetic),
658
- * then run each Block in it directly via `runNamedBlock`, trusting the
659
- * graph the same way `runChain`'s own flow execution already does, not
660
- * gated on live-menu visibility at all. The one real difference from
661
- * `runChainAuto`: this runs against the session's own already-live
662
- * page/context/mem, not a freshly spawned browser - the whole point of
663
- * staying in one session. A step whose real precondition genuinely isn't
664
- * met still fails loud, naming that step, exactly the way a mis-ordered
665
- * `runChain` spec would - and a step that runs without throwing but lands
666
- * somewhere other than what its own edge promised (a real, observed case,
667
- * not hypothetical - see this method's own test suite) fails loud too,
668
- * rather than reporting false success.
669
- */
670
- async applyPath(targetCheckpoint) {
671
- await this.currentMenu();
672
- const from = this.here;
673
- if (from === null) {
674
- return { ok: false, error: "cannot path-find: the session's current Checkpoint is unknown (here is null)" };
675
- }
676
- const path = findBlockPathDetailed(this.graph, from, targetCheckpoint);
677
- if (!path) {
678
- return { ok: false, error: `no Block path from "${from}" to "${targetCheckpoint}" in the discovered graph` };
679
- }
680
- for (const step of path) {
681
- const entry = this.library.byName.get(step.block);
682
- if (!entry) {
683
- return { ok: false, error: `path step "${step.block}" is in the discovered graph but not loaded in this session's library` };
684
- }
685
- if (entry.block.instanceOptions) {
686
- return {
687
- ok: false,
688
- error: `path step "${step.block}" needs a specific live option chosen (an instanceOptions Block, e.g. one per product) - ambiguous for automatic routing, use applyPick directly with the specific index`,
689
- };
690
- }
691
- if (this.page)
692
- await showPilotActivity(this.page, `Running (Block): ${step.block} (reach -> ${targetCheckpoint})`);
693
- const result = await this.runNamedBlock(entry, step.to);
694
- if (!result.ok) {
695
- return { ok: false, error: `step "${step.block}" failed - ${result.error}` };
696
- }
697
- // A Block can resolve to a DIFFERENT real Checkpoint than this exact
698
- // hop's own edge expected, without throwing at all - e.g.
699
- // submit-login's own resolve() legitimately "stays on LoginPage" on
700
- // bad auth instead of erroring. Trusting `result.ok` alone would
701
- // silently report success while sitting on the wrong page - a real
702
- // bug caught by this method's own test suite, not theoretical.
703
- // `step.to` (not a name-based re-lookup - a union-Out Block can have
704
- // several edges sharing one name with different `to` tags) is exactly
705
- // the Checkpoint THIS hop's own edge in the computed route promised.
706
- if (this.here !== step.to) {
707
- return {
708
- ok: false,
709
- error: `step "${step.block}" ran but landed on "${this.here}", not the expected "${step.to}" - it did not throw, but did not make the expected progress either`,
710
- };
711
- }
712
- }
713
- return { ok: true, path: path.map((s) => s.block), snapshot: await this.currentSnapshot() };
714
- }
715
- async close() {
716
- await this.context.close();
717
- await this.closeBrowser();
718
- }
719
- }