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,50 +1,31 @@
1
- import {
2
- Engine,
3
- start,
4
- end,
5
- withTitle,
6
- withSessionReset,
7
- withExpectedFailure,
8
- withHighlightFixtures,
9
- Trait,
10
- } from "waygraph";
1
+ import { engine } from "../../config/waygraph.config.js";
2
+ import "../states/checkout.mem-stubs.js";
3
+ import { Trait } from "waygraph";
11
4
  import { NavLoginBlock } from "../blocks/saucedemo-web/nav-login.block.js";
12
5
  import { FillUsernameBlock } from "../blocks/saucedemo-web/methods/fill-username.method.block.js";
13
6
  import { FillPasswordBlock } from "../blocks/saucedemo-web/methods/fill-password.method.block.js";
14
7
  import { SubmitLoginBlock } from "../blocks/saucedemo-web/methods/submit-login.method.block.js";
15
-
16
- const engine = new Engine();
8
+ import { loginFailed } from "../stubs/login.js";
17
9
 
18
10
  /**
19
- * Prove stubOnError (waygraph 0.12.4+): force verify to demand /inventory.html
20
- * while mem is locked_out_user — step throws, demo rings the error banner
21
- * before the error panel, then expected-failure styling.
22
- *
23
- * waygraph demo --blocks stubOnErrorFlow --auto-next --fast \\
24
- * --data '{"saucedemo.credentials":{"username":"locked_out_user","password":"secret_sauce"}}'
11
+ * Forces a verify failure (locked_out_user is refused, but the verify demands the inventory page) to show `stubOnError` ringing
12
+ * the error banner before the failure panel. Needs locked_out_user credentials: `--data` or mem.
25
13
  */
26
- const forcedInventoryVerify = withSessionReset(
27
- engine
28
- .defineFlow([start, NavLoginBlock, FillUsernameBlock, FillPasswordBlock, SubmitLoginBlock, end])
29
- .withBlockVerify("submit-login", [Trait.url({ pathname: "/inventory.html" })]),
30
- );
31
-
32
- export const stubOnErrorFlow = withHighlightFixtures(
33
- withExpectedFailure(
34
- withTitle(forcedInventoryVerify, "stubOnError: locked_out fail rings"),
35
- "Intentional verify fail - stubOnError rings the error banner before the panel",
36
- ),
37
- {
38
- "submit-login": {
39
- stubOnError: {
40
- error: {
41
- label: "BUG · locked out still on login",
42
- detail: "Verify demanded inventory; banner is the proof point.",
43
- tag: "FAIL",
44
- duration: true,
45
- fastMode: 500,
46
- },
47
- },
48
- },
49
- },
50
- );
14
+ export const stubOnErrorFlow = engine
15
+ .map({
16
+ expectedFailure:
17
+ "Intentional verify fail - stubOnError rings the error banner before the panel",
18
+ })
19
+ .start()
20
+ .gotoPage(
21
+ NavLoginBlock.stubBefore((ctx) =>
22
+ ctx.title("stubOnError: locked_out fail rings"),
23
+ ),
24
+ )
25
+ .method(FillUsernameBlock)
26
+ .method(FillPasswordBlock)
27
+ .method(SubmitLoginBlock.stubOnError(loginFailed))
28
+ .end()
29
+ .withBlockVerify("submit-login", [
30
+ Trait.url({ pathname: "/inventory.html" }),
31
+ ]);
@@ -1,40 +1,32 @@
1
- import { Engine, withTitle, withSessionReset, withExpectedFailure } from "waygraph";
1
+ import { engine } from "../../config/waygraph.config.js";
2
+ import "../states/checkout.mem-stubs.js";
2
3
  import { NavLoginBlock } from "../blocks/saucedemo-web/nav-login.block.js";
3
4
  import { FillUsernameBlock } from "../blocks/saucedemo-web/methods/fill-username.method.block.js";
4
5
  import { FillPasswordBlock } from "../blocks/saucedemo-web/methods/fill-password.method.block.js";
5
6
  import { SubmitLoginBlock } from "../blocks/saucedemo-web/methods/submit-login.method.block.js";
7
+ import { loginRefused } from "../stubs/login.js";
6
8
 
7
- const engine = new Engine();
8
-
9
- // A genuinely DIFFERENT scenario from checkoutFlow - not the same steps
10
- // split in half. Same login blocks, different user, different outcome:
11
- // locked_out_user attempts the exact same login an Owner (standard_user,
12
- // checkoutFlow) just completed successfully, and is blocked -
13
- // saucedemo.com's real response, verified live: stays on "/", shows
14
- // "Epic sadface: Sorry, this user has been locked out."
15
- //
16
- // withSessionReset matters here for real, not cosmetically - entered right
17
- // after checkoutFlow's already-authenticated session, this needs its own
18
- // genuinely fresh cookies/storage, or the previous user's session would
19
- // still be live and this login attempt wouldn't mean anything.
20
- //
21
- // submit-login branches: observe sees no /inventory.html navigation,
22
- // resolve -> LoginPage, verify confirms the error banner. Demo still wraps
23
- // withExpectedFailure so step 9/9 shows stubOnError rings + amber
24
- // "expected outcome" panel (branching no longer throws).
25
- export const viewerBlockedFlow = withExpectedFailure(
26
- withTitle(
27
- withSessionReset(
28
- engine
29
- .map()
30
- .start()
31
- .gotoPage(NavLoginBlock)
32
- .method(FillUsernameBlock)
33
- .method(FillPasswordBlock)
34
- .method(SubmitLoginBlock)
35
- .end(),
9
+ /**
10
+ * locked_out_user attempts the login a standard user just completed and is refused: the app stays on the login page and
11
+ * shows the error banner. Run it after another flow to see it needs a reset: `.flow(viewerBlockedFlow, { reset: true })`.
12
+ */
13
+ export const viewerBlockedFlow = engine
14
+ .map({
15
+ sessionReset: true,
16
+ expectedFailure:
17
+ "locked_out_user stays on LoginPage with the error banner - this is the product working as intended.",
18
+ })
19
+ .start()
20
+ .gotoPage(
21
+ NavLoginBlock.stubBefore((ctx) =>
22
+ ctx.title("Viewer: Blocked Login Attempt"),
36
23
  ),
37
- "Viewer: Blocked Login Attempt",
38
- ),
39
- "locked_out_user stays on LoginPage with the error banner - this is the product working as intended.",
40
- );
24
+ )
25
+ .method(FillUsernameBlock)
26
+ .method(FillPasswordBlock)
27
+ .method(
28
+ SubmitLoginBlock.stubAfter((ctx) => {
29
+ if (ctx.out?.__state === "LoginPage") loginRefused(ctx);
30
+ }),
31
+ )
32
+ .end();
@@ -0,0 +1,11 @@
1
+ import { registerMemStub } from "waygraph";
2
+ import { LoginCreds, SelectedItem } from "./checkout.mem-keys.js";
3
+
4
+ registerMemStub(LoginCreds.key, () => ({
5
+ username: "standard_user",
6
+ password: "secret_sauce",
7
+ }));
8
+ registerMemStub(SelectedItem.key, () => ({
9
+ id: "sauce-labs-backpack",
10
+ name: "Sauce Labs Backpack",
11
+ }));
@@ -1,19 +1,29 @@
1
- import type { Checkpoint } from "waygraph";
1
+ import { checkpoint } from "waygraph";
2
2
 
3
3
  // One Checkpoint per real state the target app can be in - kept together so the
4
4
  // whole checkout flow's state space reads in one place, the same reason a
5
5
  // backend keeps its models together instead of scattered across handlers.
6
6
  // `Start` is waygraph's own exported type, not redeclared here.
7
7
 
8
- export type LoginPage = Checkpoint<"LoginPage">;
9
- export type LoggedIn = Checkpoint<"LoggedIn">;
8
+ export const LoginPage = checkpoint("LoginPage");
9
+ export type LoginPage = typeof LoginPage;
10
+ export const LoggedIn = checkpoint("LoggedIn");
11
+ export type LoggedIn = typeof LoggedIn;
10
12
  /** submit-login: inventory on success, login form + error banner on auth failure. */
11
- export type LoginSubmitOutcome = LoggedIn | LoginPage;
12
- export type ItemInCart = Checkpoint<"ItemInCart">;
13
+ export const LoginSubmitOutcome = [LoggedIn, LoginPage] as const;
14
+ export type LoginSubmitOutcome = (typeof LoginSubmitOutcome)[number];
15
+ export const ItemInCart = checkpoint("ItemInCart");
16
+ export type ItemInCart = typeof ItemInCart;
13
17
  /** remove-from-cart: still has items → ItemInCart; empty cart → LoggedIn. */
14
- export type RemoveFromCartOutcome = ItemInCart | LoggedIn;
15
- export type CartPage = Checkpoint<"CartPage">;
16
- export type CheckoutInfoPage = Checkpoint<"CheckoutInfoPage">;
17
- export type CheckoutOverviewPage = Checkpoint<"CheckoutOverviewPage">;
18
- export type ItemDetailPage = Checkpoint<"ItemDetailPage">;
19
- export type OrderComplete = Checkpoint<"OrderComplete">;
18
+ export const RemoveFromCartOutcome = [ItemInCart, LoggedIn] as const;
19
+ export type RemoveFromCartOutcome = (typeof RemoveFromCartOutcome)[number];
20
+ export const CartPage = checkpoint("CartPage");
21
+ export type CartPage = typeof CartPage;
22
+ export const CheckoutInfoPage = checkpoint("CheckoutInfoPage");
23
+ export type CheckoutInfoPage = typeof CheckoutInfoPage;
24
+ export const CheckoutOverviewPage = checkpoint("CheckoutOverviewPage");
25
+ export type CheckoutOverviewPage = typeof CheckoutOverviewPage;
26
+ export const ItemDetailPage = checkpoint("ItemDetailPage");
27
+ export type ItemDetailPage = typeof ItemDetailPage;
28
+ export const OrderComplete = checkpoint("OrderComplete");
29
+ export type OrderComplete = typeof OrderComplete;
@@ -0,0 +1,191 @@
1
+ import type { StubCtx } from "waygraph";
2
+ import { LoginCreds } from "../states/checkout.mem-keys.js";
3
+ import { LoginSel } from "../blocks/saucedemo-web/methods/login.sel.js";
4
+ import { CartSel } from "../blocks/saucedemo-web/cart/cart.sel.js";
5
+ import { InventorySel } from "../blocks/saucedemo-web/inventory/methods/inventory-items.js";
6
+
7
+ const PRODUCT_ID = "sauce-labs-backpack";
8
+
9
+ /** The six-step checklist of the device showcase; `done` is how many are ticked, `index` the highlighted one. */
10
+ function checklist(done: number, index: number) {
11
+ const steps = [
12
+ "Enter username",
13
+ "Enter password",
14
+ "Tap Login",
15
+ "Find the product",
16
+ "Add to cart",
17
+ "Open cart",
18
+ ];
19
+ const ids = [
20
+ "login-user",
21
+ "login-pass",
22
+ "login-submit",
23
+ "cart-find",
24
+ "cart-add",
25
+ "cart-open",
26
+ ];
27
+ return [
28
+ ids.map((id, i) => ({
29
+ id,
30
+ text: steps[i]!,
31
+ ...(i < done ? { done: true } : {}),
32
+ })),
33
+ { title: "Device showcase", index },
34
+ ] as const;
35
+ }
36
+
37
+ /** Narration for the device showcase flow: phone login, tablet shelf, landscape cart. Each is a stub to chain on its Block. */
38
+ export const deviceShowcase = {
39
+ username: {
40
+ before: (ctx: StubCtx) => {
41
+ ctx.title("Signing in · mobile");
42
+ ctx.device("mobile");
43
+ ctx.orientation("portrait");
44
+ ctx.todos("saucedemo", ...checklist(0, 0));
45
+ ctx.zoom(1.35);
46
+ const fromMem = ctx.mem?.get(LoginCreds.key)?.username;
47
+ ctx.ring("username", {
48
+ selector: LoginSel.username,
49
+ label: "Username",
50
+ detail: fromMem
51
+ ? `tone: info (blue) - mem ${fromMem}`
52
+ : "tone: info (blue)",
53
+ tone: "info",
54
+ todo: "login-user",
55
+ focus: true,
56
+ zoom: 1.4,
57
+ });
58
+ },
59
+ after: (ctx: StubCtx) => {
60
+ ctx.todos("saucedemo", ...checklist(1, 1));
61
+ },
62
+ },
63
+ password: {
64
+ before: (ctx: StubCtx) => {
65
+ ctx.ring("password", {
66
+ selector: LoginSel.password,
67
+ label: "Password",
68
+ detail: "tone: planned (purple)",
69
+ todo: "login-pass",
70
+ tone: "planned",
71
+ focus: true,
72
+ zoom: 1.4,
73
+ });
74
+ },
75
+ after: (ctx: StubCtx) => {
76
+ ctx.todos("saucedemo", ...checklist(2, 2));
77
+ },
78
+ },
79
+ submit: {
80
+ before: (ctx: StubCtx) => {
81
+ ctx.highlights({
82
+ submit: {
83
+ selector: LoginSel.loginButton,
84
+ label: "Login",
85
+ detail: "tone: warning (yellow)",
86
+ todo: "login-submit",
87
+ tone: "warning",
88
+ focus: true,
89
+ zoom: 1.55,
90
+ weight: "bold",
91
+ gesture: "tap",
92
+ },
93
+ });
94
+ },
95
+ after: (ctx: StubCtx) => {
96
+ ctx.title("Inventory · landscape");
97
+ ctx.orientation("landscape");
98
+ ctx.todos("saucedemo", ...checklist(3, 3));
99
+ ctx.ring("shelf", {
100
+ selector: ".inventory_list",
101
+ label: "Product shelf",
102
+ detail: "tone: success (green) - ready to shop",
103
+ tone: "success",
104
+ focus: true,
105
+ zoom: 1.25,
106
+ duration: true,
107
+ });
108
+ },
109
+ },
110
+ addToCart: {
111
+ before: (ctx: StubCtx) => {
112
+ ctx.title("Pick a product · tablet");
113
+ ctx.device("tablet");
114
+ ctx.orientation("portrait");
115
+ ctx.todos("saucedemo", ...checklist(3, 3));
116
+ ctx.zoom(1.35);
117
+ ctx.zoomOut(false);
118
+ ctx.highlights({
119
+ product: {
120
+ selector: InventorySel.title(PRODUCT_ID),
121
+ label: "Sauce Labs Backpack",
122
+ detail: "tone: info (blue)",
123
+ tone: "info",
124
+ focus: true,
125
+ zoom: 1.45,
126
+ zoomOut: false,
127
+ },
128
+ add: {
129
+ selector: InventorySel.addBtn(PRODUCT_ID),
130
+ label: "Add to cart",
131
+ detail: "tone: success (green)",
132
+ tone: "success",
133
+ focus: true,
134
+ zoom: 1.5,
135
+ zoomOut: false,
136
+ weight: "bold",
137
+ },
138
+ });
139
+ },
140
+ after: (ctx: StubCtx) => {
141
+ ctx.title("In the cart");
142
+ ctx.todos("saucedemo", ...checklist(4, 4));
143
+ ctx.zoomOut(false);
144
+ ctx.ring("badge", {
145
+ selector: InventorySel.cartBadge,
146
+ label: "Cart badge",
147
+ detail: "tone: success (green) - count updated",
148
+ tone: "success",
149
+ focus: true,
150
+ zoomOut: false,
151
+ duration: true,
152
+ });
153
+ },
154
+ },
155
+ openCart: {
156
+ before: (ctx: StubCtx) => {
157
+ ctx.title("Open cart · landscape");
158
+ ctx.orientation("landscape");
159
+ ctx.todos("saucedemo", ...checklist(5, 5));
160
+ ctx.zoom(1.4);
161
+ ctx.zoomOut(false);
162
+ ctx.highlights({
163
+ cart: {
164
+ selector: CartSel.cartLink,
165
+ label: "Cart",
166
+ detail: "tone: planned (purple) - open cart",
167
+ tone: "planned",
168
+ focus: true,
169
+ zoomOut: false,
170
+ weight: "bold",
171
+ gesture: "tap",
172
+ },
173
+ });
174
+ },
175
+ after: (ctx: StubCtx) => {
176
+ ctx.title("Your cart · desktop");
177
+ ctx.hideDevice();
178
+ ctx.hideTodos();
179
+ ctx.zoomOut(true);
180
+ ctx.ring("items", {
181
+ selector: InventorySel.cartItem,
182
+ label: "Cart items",
183
+ detail: "tone: success (green) - product in cart",
184
+ tone: "success",
185
+ focus: true,
186
+ zoomOut: true,
187
+ duration: true,
188
+ });
189
+ },
190
+ },
191
+ };
@@ -0,0 +1,37 @@
1
+ import type { StubCtx } from "waygraph";
2
+ import { LoginSel } from "../blocks/saucedemo-web/methods/login.sel.js";
3
+
4
+ /** What a refused login looks like on screen: the title, a finished checklist and the error banner. */
5
+ export function loginRefused(ctx: StubCtx): void {
6
+ ctx.title("Login blocked");
7
+ ctx.todos(
8
+ "saucedemo",
9
+ [
10
+ { id: "login-user", text: "Enter username", done: true },
11
+ { id: "login-pass", text: "Enter password", done: true },
12
+ { id: "login-submit", text: "Click Login", done: true },
13
+ ],
14
+ { title: "Sign in", style: "checklist" },
15
+ );
16
+ ctx.ring("error", {
17
+ selector: LoginSel.errorBanner,
18
+ label: "Login error banner",
19
+ detail: "tone: danger (red)",
20
+ tone: "danger",
21
+ focus: true,
22
+ duration: true,
23
+ });
24
+ }
25
+
26
+ /** Rings the error banner when the login step itself throws. */
27
+ export function loginFailed(ctx: StubCtx): void {
28
+ ctx.title("Login failed");
29
+ ctx.ring("error", {
30
+ selector: LoginSel.errorBanner,
31
+ label: "Login error banner",
32
+ detail: "tone: danger (red)",
33
+ tone: "danger",
34
+ focus: true,
35
+ duration: true,
36
+ });
37
+ }
@@ -5,7 +5,7 @@ import { dirname, join } from "node:path";
5
5
 
6
6
  const projectDir = join(dirname(fileURLToPath(import.meta.url)), "..");
7
7
 
8
- test("waygraph auto discovers the decomposed saucedemo graph, skipping only the FFCompose auth step", async () => {
8
+ test("waygraph auto discovers the decomposed saucedemo graph, with no Block skipped", async () => {
9
9
  const graph = await discoverGraph(projectDir);
10
10
 
11
11
  expect(graph.nodes.map((n) => n.checkpoint).sort()).toEqual(
@@ -22,9 +22,7 @@ test("waygraph auto discovers the decomposed saucedemo graph, skipping only the
22
22
  );
23
23
  // 24 vs the earlier 15: checkout-info split into fill-first-name/
24
24
  // fill-last-name/fill-postal-code (+2 net) plus the atomic login Blocks
25
- // (fill-username/fill-password/submit-login's 2 branches) that static
26
- // discovery still sees even though checkoutFlow itself now drives them
27
- // through the ff-owner-auth composition below.
25
+ // (fill-username/fill-password/submit-login's 2 branches).
28
26
  expect(graph.edges.length).toBe(24);
29
27
  const removeEdges = graph.edges.filter((e) => e.block === "remove-from-cart");
30
28
  expect(removeEdges).toEqual(
@@ -37,14 +35,8 @@ test("waygraph auto discovers the decomposed saucedemo graph, skipping only the
37
35
  const loginFail = graph.edges.find((e) => e.block === "submit-login" && e.to === "LoginPage");
38
36
  expect(loginFail).toMatchObject({ from: "LoginPage", to: "LoginPage", kind: "action" });
39
37
 
40
- // ff-owner-auth (fastForwardComposeBlock) collapses nav-login + fill-username
41
- // + fill-password + submit-login into one opaque demo/run step - discoverGraph
42
- // only understands plain defineMethodBlock/defineEffectBlock<In, Out> generic
43
- // calls, so this one Block is expected to be skipped by static discovery even
44
- // though it's a real, used step (see src/blocks/saucedemo-web/ff-owner-auth.block.ts).
45
- expect(graph.skipped).toEqual([
46
- expect.objectContaining({ block: "ff-owner-auth" }),
47
- ]);
38
+ // Every Block has a route, so nothing is skipped.
39
+ expect(graph.skipped).toEqual([]);
48
40
 
49
41
  const logout = graph.edges.find((e) => e.block === "submit-logout");
50
42
  expect(logout).toMatchObject({ from: "LoggedIn", to: "LoginPage", kind: "action" });
@@ -1,30 +1,28 @@
1
1
  import { test, expect } from "@playwright/test";
2
- import { MemPage, checkpoint, chainFlow } from "waygraph";
2
+ import { MemPage, checkpoint } from "waygraph";
3
+ import { engine } from "../config/waygraph.config.js";
3
4
  import { loginFlow } from "../src/flows/login.flow.js";
4
5
  import { shopFlow } from "../src/flows/shop.flow.js";
5
6
  import { LoginCreds, SelectedItem } from "../src/states/checkout.mem-keys.js";
6
7
 
7
- // Proves the 2-episode chainFlow scenario the step-mode CLI demo shows
8
+ // Proves the 2-episode nested-flow scenario the step-mode CLI demo shows
8
9
  // interactively ("Episode 1: Sign In" -> "Episode 2: Shop & Checkout") also
9
10
  // works as a real, automated, headless test - not just something you have
10
11
  // to click through by hand. loginFlow/shopFlow are the exact same Flow
11
12
  // objects `waygraph chain "loginFlow(...) then shopFlow"` drives.
12
- test("chainFlow sequences 2 titled episodes (loginFlow then shopFlow) against the real live site", async () => {
13
+ test("nested flows run 2 episodes (loginFlow then shopFlow) against the real live site", async () => {
13
14
  const mem = new MemPage();
14
15
  mem.set(LoginCreds({ username: "standard_user", password: "secret_sauce" }));
15
16
  mem.set(SelectedItem({ id: "sauce-labs-backpack", name: "Sauce Labs Backpack" }));
16
17
 
17
- const combined = chainFlow(loginFlow, shopFlow);
18
+ const combined = engine.map().start().flow(loginFlow).flow(shopFlow).end();
18
19
  const result = await combined.run(mem);
19
20
 
20
21
  expect(result).toEqual(checkpoint("OrderComplete"));
21
22
  });
22
23
 
23
- test("each episode's title survives chaining, and blocks() reports the flattened chain in order", () => {
24
- expect(loginFlow.title).toBe("Sign In");
25
- expect(shopFlow.title).toBe("Shop & Checkout");
26
-
27
- const combined = chainFlow(loginFlow, shopFlow);
24
+ test("blocks() reports the flattened chain in order", () => {
25
+ const combined = engine.map().start().flow(loginFlow).flow(shopFlow).end();
28
26
  const blocks = combined.blocks();
29
27
 
30
28
  expect(blocks.map((b) => b.name)).toEqual([
@@ -1,5 +1,6 @@
1
1
  import { test, expect } from "@playwright/test";
2
- import { MemPage, Engine, start, end } from "waygraph";
2
+ import { MemPage } from "waygraph";
3
+ import { engine } from "../config/waygraph.config.js";
3
4
  import { NavLoginBlock } from "../src/blocks/saucedemo-web/nav-login.block.js";
4
5
  import { FillUsernameBlock } from "../src/blocks/saucedemo-web/methods/fill-username.method.block.js";
5
6
  import { FillPasswordBlock } from "../src/blocks/saucedemo-web/methods/fill-password.method.block.js";
@@ -10,8 +11,14 @@ test("submit-login: wrong password branches to LoginPage with error banner", asy
10
11
  const mem = new MemPage();
11
12
  mem.set(LoginCreds({ username: "standard_user", password: "wrong-password" }));
12
13
 
13
- const engine = new Engine();
14
- const flow = engine.defineFlow([start, NavLoginBlock, FillUsernameBlock, FillPasswordBlock, SubmitLoginBlock, end]);
14
+ const flow = engine
15
+ .map()
16
+ .start()
17
+ .gotoPage(NavLoginBlock)
18
+ .method(FillUsernameBlock)
19
+ .method(FillPasswordBlock)
20
+ .method(SubmitLoginBlock)
21
+ .end();
15
22
  const result = await flow.run(mem);
16
23
 
17
24
  expect(result.__state).toBe("LoginPage");
@@ -21,8 +28,14 @@ test("submit-login: good password branches to LoggedIn", async () => {
21
28
  const mem = new MemPage();
22
29
  mem.set(LoginCreds({ username: "standard_user", password: "secret_sauce" }));
23
30
 
24
- const engine = new Engine();
25
- const flow = engine.defineFlow([start, NavLoginBlock, FillUsernameBlock, FillPasswordBlock, SubmitLoginBlock, end]);
31
+ const flow = engine
32
+ .map()
33
+ .start()
34
+ .gotoPage(NavLoginBlock)
35
+ .method(FillUsernameBlock)
36
+ .method(FillPasswordBlock)
37
+ .method(SubmitLoginBlock)
38
+ .end();
26
39
  const result = await flow.run(mem);
27
40
 
28
41
  expect(result.__state).toBe("LoggedIn");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "waygraph",
3
- "version": "0.15.53",
3
+ "version": "0.16.0",
4
4
  "type": "module",
5
5
  "description": "A typed graph of reusable Blocks for driving a browser through E2E flows.",
6
6
  "license": "MIT",
@@ -12,7 +12,7 @@
12
12
  "default": "./dist/index.js"
13
13
  },
14
14
  "./runner": {
15
- "default": "./dist/runner/index.js"
15
+ "default": "./dist/runner/runner.js"
16
16
  }
17
17
  },
18
18
  "bin": {
@@ -38,7 +38,9 @@
38
38
  "!**/playwright-report",
39
39
  "!**/playwright-report/**",
40
40
  "!**/.waygraph-chain-*.mjs",
41
- "!**/*.log"
41
+ "!**/*.log",
42
+ "!examples/**/.waygraph",
43
+ "!examples/**/.waygraph/**"
42
44
  ],
43
45
  "repository": {
44
46
  "type": "git",
@@ -46,7 +48,7 @@
46
48
  },
47
49
  "scripts": {
48
50
  "clean": "node -e \"require('node:fs').rmSync('dist', { recursive: true, force: true })\"",
49
- "build": "npm run clean && tsc -p tsconfig.build.json && node scripts/copy-runner.mjs && node scripts/copy-ui-css.mjs",
51
+ "build": "npm run clean && tsc -p tsconfig.build.json && node scripts/copy-ui-css.mjs",
50
52
  "typecheck": "node bin/waygraph typecheck .",
51
53
  "test": "npm run check:structure && npm run knip && npm run test:unit && playwright test",
52
54
  "test:ui": "playwright test --ui",
@@ -58,16 +60,19 @@
58
60
  "docs:dev": "npm run docs:api && vitepress dev docs",
59
61
  "docs:build": "npm run docs:api && vitepress build docs",
60
62
  "docs:preview": "vitepress preview docs",
61
- "docs:api": "typedoc && node scripts/gen-deprecated.mjs",
62
- "knip": "knip"
63
+ "docs:api": "typedoc && node scripts/gen-deprecated.mjs && node --import tsx scripts/gen-env.mjs",
64
+ "knip": "knip",
65
+ "sync:quickstart": "node scripts/sync-quickstart.mjs"
63
66
  },
64
67
  "peerDependencies": {
65
68
  "@playwright/test": "^1.40.0"
66
69
  },
67
70
  "dependencies": {
68
71
  "open-props": "^1.7.23",
72
+ "ts-morph": "^28.0.0",
69
73
  "tsx": "^4.0.0",
70
- "urlpattern-polyfill": "^10.1.0"
74
+ "urlpattern-polyfill": "^10.1.0",
75
+ "yaml": "^2.9.1"
71
76
  },
72
77
  "devDependencies": {
73
78
  "@playwright/test": "^1.63.0",
@@ -50,9 +50,9 @@ When there is no app codebase to read - a production target, or a deliberately
50
50
  codebase-blind engagement - discover the route/interaction structure live instead, using the
51
51
  `waygraph auto` session tools rather than skipping planning:
52
52
 
53
- 1. `waygraph auto --cli --detach [--base-url <url>]` against a throwaway project dir (or the
53
+ 1. `waygraph browser start --headless [--base-url <url>] --goto /` against a throwaway project dir (or the
54
54
  target project once a `src/map/` or `src/blocks/` tree exists) - starts a driveable session, prints
55
- `{sessionId, socketPath}`.
55
+ `{sessionId, socketPath, headless}`.
56
56
  2. `waygraph auto status <sessionId>` to read the current menu (what Blocks/edges are already
57
57
  discoverable) and `waygraph auto dom <sessionId>` (default `aria` mode) to see the live
58
58
  page's actual interactive elements by role/name - this is how you find real routes and
@@ -1,10 +1,7 @@
1
1
  # waygraph quickstart (Sauce Demo)
2
2
 
3
- Temp-dir template for `npx waygraph try demo`. Same Blocks as
4
- `examples/saucedemo` (route-folder convention under `src/blocks/saucedemo-web/`).
3
+ Temp-dir template for `npx waygraph try demo`. A copy of `examples/saucedemo` (freeform route-folder layout under
4
+ `src/blocks/saucedemo-web/`, flows in `src/flows/`, narration in `src/stubs/`, settings in `config/waygraph.config.ts`).
5
5
 
6
- Convention walkthrough on Pages:
7
- https://deviate-dv8.github.io/waygraph/saucedemo/
8
-
9
- Do not edit this tree as the long-lived showcase - edit `examples/saucedemo`,
10
- then re-copy Blocks here when shipping a release that bumps `try demo`.
6
+ Do not edit this tree as the long-lived showcase: edit `examples/saucedemo`, then run `npm run sync:quickstart` in the
7
+ waygraph repo before a release.
@@ -0,0 +1,17 @@
1
+ import { Engine, defineConfig } from "waygraph";
2
+
3
+ const config = defineConfig({
4
+ baseUrl: "https://www.saucedemo.com",
5
+ playwright: {
6
+ workers: 1,
7
+ fullyParallel: false,
8
+ timeout: 30_000,
9
+ use: {
10
+ headless: true,
11
+ launchOptions: { args: ["--no-sandbox", "--disable-dev-shm-usage"] },
12
+ },
13
+ },
14
+ });
15
+
16
+ export default config;
17
+ export const engine = new Engine(config);