waygraph 0.13.7 → 0.15.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.
- package/README.md +970 -232
- package/assets/stubs/stub.mp4 +0 -0
- package/assets/stubs/stub.pdf +32 -0
- package/assets/stubs/stub.png +0 -0
- package/dist/agent-dive.d.ts +9 -0
- package/dist/agent-dive.js +32 -0
- package/dist/auto-explore-run.d.ts +20 -2
- package/dist/auto-explore-run.js +9 -8
- package/dist/auto-explore.js +22 -2
- package/dist/auto-session-ipc.d.ts +123 -0
- package/dist/auto-session-ipc.js +381 -0
- package/dist/auto-session.d.ts +342 -0
- package/dist/auto-session.js +760 -0
- package/dist/cli.js +450 -51
- package/dist/engine.d.ts +201 -1
- package/dist/engine.js +312 -2
- package/dist/graph.d.ts +18 -0
- package/dist/graph.js +65 -2
- package/dist/highlights.d.ts +20 -1
- package/dist/highlights.js +60 -0
- package/dist/index.d.ts +8 -4
- package/dist/index.js +5 -3
- package/dist/map-check.d.ts +18 -0
- package/dist/map-check.js +140 -0
- package/dist/pilot-overlay.d.ts +88 -0
- package/dist/pilot-overlay.js +363 -0
- package/dist/pilot.d.ts +49 -0
- package/dist/pilot.js +53 -0
- package/dist/trait.d.ts +22 -0
- package/dist/trait.js +60 -3
- package/dist/types.d.ts +21 -1
- package/dist/types.js +17 -1
- package/examples/routed-demo/.waygraph-auto/4d4902b7.log +0 -0
- package/examples/routed-demo/.waygraph-auto/51ef462e.log +0 -0
- package/examples/routed-demo/.waygraph-auto/71527ad9.log +0 -0
- package/examples/routed-demo/.waygraph-auto/ca16778e.log +0 -0
- package/examples/routed-demo/package.json +26 -0
- package/examples/routed-demo/playwright.config.ts +20 -0
- package/examples/routed-demo/scripts/fixture-server.mjs +37 -0
- package/examples/routed-demo/scripts/with-fixture.mjs +70 -0
- package/examples/routed-demo/src/flows/routed-demo-map.flow.ts +39 -0
- package/examples/routed-demo/src/flows/routed-demo.flow.ts +12 -0
- package/examples/routed-demo/src/map/(app_base)/dashboard/_methods/click-widget.block.ts +23 -0
- package/examples/routed-demo/src/map/(app_base)/dashboard/_nav.block.ts +18 -0
- package/examples/routed-demo/src/map/(app_base)/dashboard/_page.block.ts +22 -0
- package/examples/routed-demo/src/map/(app_base)/dashboard/_sel.ts +10 -0
- package/examples/routed-demo/src/map/(external)/docs/_nav.block.ts +21 -0
- package/examples/routed-demo/src/map/(external)/docs/_page.block.ts +15 -0
- package/examples/routed-demo/src/map/(external)/docs/_sel.ts +7 -0
- package/examples/routed-demo/src/pages/dashboard.html +10 -0
- package/examples/routed-demo/src/pages/docs.html +8 -0
- package/examples/routed-demo/src/states/routed-demo.states.ts +10 -0
- package/examples/routed-demo/test-results/.last-run.json +4 -0
- package/examples/routed-demo/tests/routed-demo-map.spec.ts +17 -0
- package/examples/routed-demo/tests/routed-demo.spec.ts +75 -0
- package/examples/routed-demo/tsconfig.json +18 -0
- package/examples/routed-demo-consumer/package.json +18 -0
- package/examples/saucedemo/.waygraph-auto/00d5336e.log +0 -0
- package/examples/saucedemo/.waygraph-auto/010dd92b.log +0 -0
- package/examples/saucedemo/.waygraph-auto/011ad671.log +0 -0
- package/examples/saucedemo/.waygraph-auto/01b45645.log +0 -0
- package/examples/saucedemo/.waygraph-auto/03764153.log +0 -0
- package/examples/saucedemo/.waygraph-auto/0593587e.log +0 -0
- package/examples/saucedemo/.waygraph-auto/06d12823.log +0 -0
- package/examples/saucedemo/.waygraph-auto/083cc5b9.log +0 -0
- package/examples/saucedemo/.waygraph-auto/0b1f5b26.json +8 -0
- package/examples/saucedemo/.waygraph-auto/0c00f25f.log +0 -0
- package/examples/saucedemo/.waygraph-auto/0e480591.log +0 -0
- package/examples/saucedemo/.waygraph-auto/104751ef.log +0 -0
- package/examples/saucedemo/.waygraph-auto/110958b8.log +0 -0
- package/examples/saucedemo/.waygraph-auto/138107c1.log +0 -0
- package/examples/saucedemo/.waygraph-auto/159d541b.log +0 -0
- package/examples/saucedemo/.waygraph-auto/16aa2c01.log +0 -0
- package/examples/saucedemo/.waygraph-auto/16c35dd5.log +0 -0
- package/examples/saucedemo/.waygraph-auto/1706547d.log +0 -0
- package/examples/saucedemo/.waygraph-auto/17537e42.log +0 -0
- package/examples/saucedemo/.waygraph-auto/175655f7.log +0 -0
- package/examples/saucedemo/.waygraph-auto/17ede493.log +0 -0
- package/examples/saucedemo/.waygraph-auto/1fe2414f.log +0 -0
- package/examples/saucedemo/.waygraph-auto/1fe2e3b8.log +0 -0
- package/examples/saucedemo/.waygraph-auto/2219f00b.log +0 -0
- package/examples/saucedemo/.waygraph-auto/23e62571.log +0 -0
- package/examples/saucedemo/.waygraph-auto/25f68ada.log +0 -0
- package/examples/saucedemo/.waygraph-auto/26ca9cd8.log +0 -0
- package/examples/saucedemo/.waygraph-auto/2bb6c4e8.log +0 -0
- package/examples/saucedemo/.waygraph-auto/2d425004.log +0 -0
- package/examples/saucedemo/.waygraph-auto/2f5b3ea6.log +0 -0
- package/examples/saucedemo/.waygraph-auto/31bb303d.log +0 -0
- package/examples/saucedemo/.waygraph-auto/31f2042f.log +0 -0
- package/examples/saucedemo/.waygraph-auto/36551ec1.log +0 -0
- package/examples/saucedemo/.waygraph-auto/36a1c274.log +0 -0
- package/examples/saucedemo/.waygraph-auto/381aa338.log +0 -0
- package/examples/saucedemo/.waygraph-auto/3882bce1.log +0 -0
- package/examples/saucedemo/.waygraph-auto/38acd1dc.log +0 -0
- package/examples/saucedemo/.waygraph-auto/3b8b77b9.log +0 -0
- package/examples/saucedemo/.waygraph-auto/4028d2a2.log +0 -0
- package/examples/saucedemo/.waygraph-auto/4168b208.log +0 -0
- package/examples/saucedemo/.waygraph-auto/42cc9113.log +0 -0
- package/examples/saucedemo/.waygraph-auto/439d30aa.log +0 -0
- package/examples/saucedemo/.waygraph-auto/43ab66ce.log +0 -0
- package/examples/saucedemo/.waygraph-auto/43f66838.log +0 -0
- package/examples/saucedemo/.waygraph-auto/442171d4.log +0 -0
- package/examples/saucedemo/.waygraph-auto/453b1ce1.log +0 -0
- package/examples/saucedemo/.waygraph-auto/457322bd.log +0 -0
- package/examples/saucedemo/.waygraph-auto/46197027.log +0 -0
- package/examples/saucedemo/.waygraph-auto/46889468.log +0 -0
- package/examples/saucedemo/.waygraph-auto/4890da1c.log +0 -0
- package/examples/saucedemo/.waygraph-auto/4893a63b.log +0 -0
- package/examples/saucedemo/.waygraph-auto/4a85f496.log +0 -0
- package/examples/saucedemo/.waygraph-auto/4af71440.log +0 -0
- package/examples/saucedemo/.waygraph-auto/4f7496d1.log +0 -0
- package/examples/saucedemo/.waygraph-auto/50e8baaa.log +0 -0
- package/examples/saucedemo/.waygraph-auto/52b3a455.log +0 -0
- package/examples/saucedemo/.waygraph-auto/532dd9b8.log +0 -0
- package/examples/saucedemo/.waygraph-auto/5391ce40.log +0 -0
- package/examples/saucedemo/.waygraph-auto/57dbddb3.log +0 -0
- package/examples/saucedemo/.waygraph-auto/5897f501.log +0 -0
- package/examples/saucedemo/.waygraph-auto/59c0b57d.log +0 -0
- package/examples/saucedemo/.waygraph-auto/5b511794.log +0 -0
- package/examples/saucedemo/.waygraph-auto/5c0eef7f.log +0 -0
- package/examples/saucedemo/.waygraph-auto/5c47910f.log +0 -0
- package/examples/saucedemo/.waygraph-auto/5d60da77.log +0 -0
- package/examples/saucedemo/.waygraph-auto/5eda8273.log +0 -0
- package/examples/saucedemo/.waygraph-auto/5fc3a33b.log +0 -0
- package/examples/saucedemo/.waygraph-auto/61b6546d.log +0 -0
- package/examples/saucedemo/.waygraph-auto/621518ad.log +0 -0
- package/examples/saucedemo/.waygraph-auto/632b7118.log +0 -0
- package/examples/saucedemo/.waygraph-auto/64314c2b.log +0 -0
- package/examples/saucedemo/.waygraph-auto/650ed066.log +0 -0
- package/examples/saucedemo/.waygraph-auto/66516213.log +0 -0
- package/examples/saucedemo/.waygraph-auto/66c17079.log +0 -0
- package/examples/saucedemo/.waygraph-auto/69bf0b80.log +0 -0
- package/examples/saucedemo/.waygraph-auto/69c2347a.log +0 -0
- package/examples/saucedemo/.waygraph-auto/6d22bdb0.log +0 -0
- package/examples/saucedemo/.waygraph-auto/6d9aaad3.log +0 -0
- package/examples/saucedemo/.waygraph-auto/7103bebb.log +0 -0
- package/examples/saucedemo/.waygraph-auto/740c9faa.log +0 -0
- package/examples/saucedemo/.waygraph-auto/74872fc5.log +0 -0
- package/examples/saucedemo/.waygraph-auto/75846ca9.log +0 -0
- package/examples/saucedemo/.waygraph-auto/7626c85b.log +0 -0
- package/examples/saucedemo/.waygraph-auto/76308eec.log +0 -0
- package/examples/saucedemo/.waygraph-auto/76c1650e.log +0 -0
- package/examples/saucedemo/.waygraph-auto/7861f38f.log +0 -0
- package/examples/saucedemo/.waygraph-auto/78b21219.log +0 -0
- package/examples/saucedemo/.waygraph-auto/7af224ed.log +0 -0
- package/examples/saucedemo/.waygraph-auto/7c3be585.log +0 -0
- package/examples/saucedemo/.waygraph-auto/7ed55a2c.log +0 -0
- package/examples/saucedemo/.waygraph-auto/80086ba2.log +0 -0
- package/examples/saucedemo/.waygraph-auto/80206369.log +0 -0
- package/examples/saucedemo/.waygraph-auto/847f1092.log +0 -0
- package/examples/saucedemo/.waygraph-auto/84d6d293.log +0 -0
- package/examples/saucedemo/.waygraph-auto/8581abfa.log +0 -0
- package/examples/saucedemo/.waygraph-auto/87b7e0fd.log +0 -0
- package/examples/saucedemo/.waygraph-auto/87c79256.log +0 -0
- package/examples/saucedemo/.waygraph-auto/88af2495.log +0 -0
- package/examples/saucedemo/.waygraph-auto/8a3eb088.log +0 -0
- package/examples/saucedemo/.waygraph-auto/8c04a403.log +0 -0
- package/examples/saucedemo/.waygraph-auto/8c9ab09e.log +0 -0
- package/examples/saucedemo/.waygraph-auto/8cc5db51.log +0 -0
- package/examples/saucedemo/.waygraph-auto/8ea3a69c.log +0 -0
- package/examples/saucedemo/.waygraph-auto/9150f913.log +0 -0
- package/examples/saucedemo/.waygraph-auto/929a4313.log +0 -0
- package/examples/saucedemo/.waygraph-auto/95a599e4.log +0 -0
- package/examples/saucedemo/.waygraph-auto/96c45350.log +0 -0
- package/examples/saucedemo/.waygraph-auto/986030e6.log +0 -0
- package/examples/saucedemo/.waygraph-auto/99787abb.log +0 -0
- package/examples/saucedemo/.waygraph-auto/99ddb62c.log +0 -0
- package/examples/saucedemo/.waygraph-auto/a2dd30dd.log +0 -0
- package/examples/saucedemo/.waygraph-auto/a63a2d20.log +0 -0
- package/examples/saucedemo/.waygraph-auto/a78befb7.log +0 -0
- package/examples/saucedemo/.waygraph-auto/a84d9b79.log +0 -0
- package/examples/saucedemo/.waygraph-auto/a87bb3ee.log +0 -0
- package/examples/saucedemo/.waygraph-auto/a9270890.log +0 -0
- package/examples/saucedemo/.waygraph-auto/aa440153.log +0 -0
- package/examples/saucedemo/.waygraph-auto/ab7561e0.log +0 -0
- package/examples/saucedemo/.waygraph-auto/ac19ae60.log +0 -0
- package/examples/saucedemo/.waygraph-auto/ae21ad8e.log +0 -0
- package/examples/saucedemo/.waygraph-auto/af09042f.log +0 -0
- package/examples/saucedemo/.waygraph-auto/b1684126.log +0 -0
- package/examples/saucedemo/.waygraph-auto/b21e9d12.log +0 -0
- package/examples/saucedemo/.waygraph-auto/b5a838be.log +0 -0
- package/examples/saucedemo/.waygraph-auto/b603549d.log +0 -0
- package/examples/saucedemo/.waygraph-auto/b81e074f.log +0 -0
- package/examples/saucedemo/.waygraph-auto/b83e6259.log +0 -0
- package/examples/saucedemo/.waygraph-auto/b9cb2796.log +0 -0
- package/examples/saucedemo/.waygraph-auto/ba58abb7.log +0 -0
- package/examples/saucedemo/.waygraph-auto/bb0a0018.log +0 -0
- package/examples/saucedemo/.waygraph-auto/bb9fd384.log +0 -0
- package/examples/saucedemo/.waygraph-auto/bc0bdd0e.log +0 -0
- package/examples/saucedemo/.waygraph-auto/bc7d4a83.log +0 -0
- package/examples/saucedemo/.waygraph-auto/bd8e082a.log +0 -0
- package/examples/saucedemo/.waygraph-auto/bea0c93e.log +0 -0
- package/examples/saucedemo/.waygraph-auto/bf35201a.log +0 -0
- package/examples/saucedemo/.waygraph-auto/bffa3a7a.log +0 -0
- package/examples/saucedemo/.waygraph-auto/c02ea583.log +0 -0
- package/examples/saucedemo/.waygraph-auto/c2caf0a8.log +0 -0
- package/examples/saucedemo/.waygraph-auto/c3bdc714.log +0 -0
- package/examples/saucedemo/.waygraph-auto/c4afb8bc.log +0 -0
- package/examples/saucedemo/.waygraph-auto/c916a654.log +0 -0
- package/examples/saucedemo/.waygraph-auto/c9b8d69e.log +0 -0
- package/examples/saucedemo/.waygraph-auto/cd68bbc4.log +0 -0
- package/examples/saucedemo/.waygraph-auto/cdc6db50.log +0 -0
- package/examples/saucedemo/.waygraph-auto/d01906a7.log +0 -0
- package/examples/saucedemo/.waygraph-auto/d02e5e7e.log +0 -0
- package/examples/saucedemo/.waygraph-auto/d09aff71.log +0 -0
- package/examples/saucedemo/.waygraph-auto/d0e41396.log +0 -0
- package/examples/saucedemo/.waygraph-auto/d1370d76.log +0 -0
- package/examples/saucedemo/.waygraph-auto/d3714ae4.log +0 -0
- package/examples/saucedemo/.waygraph-auto/d9e5f8a4.log +0 -0
- package/examples/saucedemo/.waygraph-auto/da0685dc.log +0 -0
- package/examples/saucedemo/.waygraph-auto/da894ad8.log +0 -0
- package/examples/saucedemo/.waygraph-auto/daa2f922.log +0 -0
- package/examples/saucedemo/.waygraph-auto/daefb614.log +0 -0
- package/examples/saucedemo/.waygraph-auto/db97e833.log +0 -0
- package/examples/saucedemo/.waygraph-auto/dec3076e.log +0 -0
- package/examples/saucedemo/.waygraph-auto/e101d19a.log +0 -0
- package/examples/saucedemo/.waygraph-auto/e1973991.log +0 -0
- package/examples/saucedemo/.waygraph-auto/e207c989.log +0 -0
- package/examples/saucedemo/.waygraph-auto/e633e545.log +0 -0
- package/examples/saucedemo/.waygraph-auto/e69aec68.log +0 -0
- package/examples/saucedemo/.waygraph-auto/e70e2d06.log +0 -0
- package/examples/saucedemo/.waygraph-auto/e8306a4b.log +0 -0
- package/examples/saucedemo/.waygraph-auto/ebad3410.log +0 -0
- package/examples/saucedemo/.waygraph-auto/ec88b3ef.log +0 -0
- package/examples/saucedemo/.waygraph-auto/ecbb0966.log +0 -0
- package/examples/saucedemo/.waygraph-auto/ecdee753.log +0 -0
- package/examples/saucedemo/.waygraph-auto/ed888783.log +0 -0
- package/examples/saucedemo/.waygraph-auto/ed931dac.log +0 -0
- package/examples/saucedemo/.waygraph-auto/ef655a3f.log +0 -0
- package/examples/saucedemo/.waygraph-auto/f34c9a26.log +0 -0
- package/examples/saucedemo/.waygraph-auto/f3c29b21.log +0 -0
- package/examples/saucedemo/.waygraph-auto/f53f7cfc.log +0 -0
- package/examples/saucedemo/.waygraph-auto/f5525d53.log +0 -0
- package/examples/saucedemo/.waygraph-auto/f5ad5830.log +0 -0
- package/examples/saucedemo/.waygraph-auto/f90035b3.log +0 -0
- package/examples/saucedemo/.waygraph-auto/fa687bc2.log +0 -0
- package/examples/saucedemo/.waygraph-auto/faed36dd.log +0 -0
- package/examples/saucedemo/.waygraph-auto/fb66fba0.log +0 -0
- package/examples/saucedemo/.waygraph-auto/fc48fd76.log +0 -0
- package/examples/saucedemo/docs/CONVENTION.md +25 -5
- package/examples/saucedemo/docs/HELPERS.md +15 -4
- package/examples/saucedemo/scripts/capture-wrong-login.mjs +8 -2
- package/examples/saucedemo/scripts/prove-wrong-login-runtime.mjs +8 -2
- package/examples/saucedemo/src/blocks/SITE-MAP.md +14 -3
- package/examples/saucedemo/src/blocks/saucedemo-web/NAV.md +15 -1
- package/examples/saucedemo/src/blocks/saucedemo-web/cart/NAV.md +1 -0
- package/examples/saucedemo/src/blocks/saucedemo-web/cart/cart.sel.ts +9 -0
- package/examples/saucedemo/src/blocks/saucedemo-web/cart/nav-cart.block.ts +3 -2
- package/examples/saucedemo/src/blocks/saucedemo-web/cart/nav-checkout-info.block.ts +2 -1
- package/examples/saucedemo/src/blocks/saucedemo-web/checkout-step-one/NAV.md +6 -1
- package/examples/saucedemo/src/blocks/saucedemo-web/checkout-step-one/methods/checkout-info.sel.ts +11 -0
- package/examples/saucedemo/src/blocks/saucedemo-web/checkout-step-one/methods/fill-first-name.method.block.ts +22 -0
- package/examples/saucedemo/src/blocks/saucedemo-web/checkout-step-one/methods/fill-last-name.method.block.ts +21 -0
- package/examples/saucedemo/src/blocks/saucedemo-web/checkout-step-one/methods/fill-postal-code.method.block.ts +21 -0
- package/examples/saucedemo/src/blocks/saucedemo-web/checkout-step-one/methods/submit-checkout-info.method.block.ts +6 -7
- package/examples/saucedemo/src/blocks/saucedemo-web/checkout-step-two/NAV.md +2 -0
- package/examples/saucedemo/src/blocks/saucedemo-web/checkout-step-two/methods/checkout-overview.sel.ts +9 -0
- package/examples/saucedemo/src/blocks/saucedemo-web/checkout-step-two/methods/finish-order.method.block.ts +7 -6
- package/examples/saucedemo/src/blocks/saucedemo-web/ff-owner-auth.block.ts +7 -2
- package/examples/saucedemo/src/blocks/saucedemo-web/inventory-item/NAV.md +1 -0
- package/examples/saucedemo/src/blocks/saucedemo-web/inventory-item/item-detail.sel.ts +9 -0
- package/examples/saucedemo/src/blocks/saucedemo-web/inventory-item/nav-back-to-inventory.block.ts +2 -1
- package/examples/saucedemo/src/blocks/saucedemo-web/inventory-item/nav-back-to-products.block.ts +2 -1
- package/examples/saucedemo/src/blocks/saucedemo-web/inventory-item/nav-continue-shopping.block.ts +2 -1
- package/examples/saucedemo/src/blocks/saucedemo-web/methods/fill-password.method.block.ts +51 -0
- package/examples/saucedemo/src/blocks/saucedemo-web/methods/fill-username.method.block.ts +69 -0
- package/examples/saucedemo/src/blocks/saucedemo-web/methods/login.sel.ts +13 -0
- package/examples/saucedemo/src/blocks/saucedemo-web/methods/submit-login-for-flow.ts +4 -4
- package/examples/saucedemo/src/blocks/saucedemo-web/methods/submit-login.method.block.ts +13 -51
- package/examples/saucedemo/src/blocks/saucedemo-web/methods/submit-logout.method.block.ts +4 -3
- package/examples/saucedemo/src/blocks/saucedemo-web/nav-login.block.ts +14 -6
- package/examples/saucedemo/src/flows/checkout-then-browse-again.flow.ts +15 -0
- package/examples/saucedemo/src/flows/checkout.flow.ts +20 -2
- package/examples/saucedemo/src/flows/device-showcase.flow.ts +4 -0
- package/examples/saucedemo/src/flows/login.flow.ts +3 -1
- package/examples/saucedemo/src/flows/shop.flow.ts +6 -0
- package/examples/saucedemo/src/flows/smoke.flow.ts +13 -7
- package/examples/saucedemo/src/flows/stub-on-error.flow.ts +4 -2
- package/examples/saucedemo/src/flows/viewer-blocked.flow.ts +6 -2
- package/examples/saucedemo/tests/flow-block-verify.spec.ts +3 -3
- package/examples/saucedemo/tests/submit-login-branch.spec.ts +5 -3
- package/package.json +2 -1
- package/templates/agents/waygraph-author.agent.md +43 -5
- package/templates/agents/waygraph-planner.agent.md +33 -2
- package/templates/quickstart/src/blocks/saucedemo-web/NAV.md +15 -1
- package/templates/quickstart/src/blocks/saucedemo-web/cart/NAV.md +1 -0
- package/templates/quickstart/src/blocks/saucedemo-web/cart/cart.sel.ts +9 -0
- package/templates/quickstart/src/blocks/saucedemo-web/cart/nav-cart.block.ts +19 -15
- package/templates/quickstart/src/blocks/saucedemo-web/cart/nav-checkout-info.block.ts +2 -1
- package/templates/quickstart/src/blocks/saucedemo-web/checkout-step-one/NAV.md +6 -1
- package/templates/quickstart/src/blocks/saucedemo-web/checkout-step-one/methods/checkout-info.sel.ts +11 -0
- package/templates/quickstart/src/blocks/saucedemo-web/checkout-step-one/methods/fill-first-name.method.block.ts +22 -0
- package/templates/quickstart/src/blocks/saucedemo-web/checkout-step-one/methods/fill-last-name.method.block.ts +21 -0
- package/templates/quickstart/src/blocks/saucedemo-web/checkout-step-one/methods/fill-postal-code.method.block.ts +21 -0
- package/templates/quickstart/src/blocks/saucedemo-web/checkout-step-one/methods/submit-checkout-info.method.block.ts +6 -7
- package/templates/quickstart/src/blocks/saucedemo-web/checkout-step-two/NAV.md +2 -0
- package/templates/quickstart/src/blocks/saucedemo-web/checkout-step-two/methods/checkout-overview.sel.ts +9 -0
- package/templates/quickstart/src/blocks/saucedemo-web/checkout-step-two/methods/finish-order.method.block.ts +7 -6
- package/templates/quickstart/src/blocks/saucedemo-web/ff-owner-auth.block.ts +7 -2
- package/templates/quickstart/src/blocks/saucedemo-web/inventory/methods/add-to-cart.effect.block.ts +24 -16
- package/templates/quickstart/src/blocks/saucedemo-web/inventory/nav-item-detail.block.ts +3 -3
- package/templates/quickstart/src/blocks/saucedemo-web/inventory-item/NAV.md +1 -0
- package/templates/quickstart/src/blocks/saucedemo-web/inventory-item/item-detail.sel.ts +9 -0
- package/templates/quickstart/src/blocks/saucedemo-web/inventory-item/nav-back-to-inventory.block.ts +2 -1
- package/templates/quickstart/src/blocks/saucedemo-web/inventory-item/nav-back-to-products.block.ts +2 -1
- package/templates/quickstart/src/blocks/saucedemo-web/inventory-item/nav-continue-shopping.block.ts +2 -1
- package/templates/quickstart/src/blocks/saucedemo-web/methods/fill-password.method.block.ts +51 -0
- package/templates/quickstart/src/blocks/saucedemo-web/methods/fill-username.method.block.ts +69 -0
- package/templates/quickstart/src/blocks/saucedemo-web/methods/login.sel.ts +13 -0
- package/templates/quickstart/src/blocks/saucedemo-web/methods/submit-login-for-flow.ts +4 -4
- package/templates/quickstart/src/blocks/saucedemo-web/methods/submit-login.method.block.ts +35 -63
- package/templates/quickstart/src/blocks/saucedemo-web/methods/submit-logout.method.block.ts +4 -3
- package/templates/quickstart/src/blocks/saucedemo-web/nav-login.block.ts +14 -6
- package/templates/quickstart/src/flows/checkout-then-browse-again.flow.ts +15 -0
- package/templates/quickstart/src/flows/checkout.flow.ts +29 -2
- package/templates/quickstart/src/flows/device-showcase.flow.ts +4 -0
- package/templates/quickstart/src/flows/login.flow.ts +3 -1
- package/templates/quickstart/src/flows/shop.flow.ts +6 -0
- package/templates/quickstart/src/flows/smoke.flow.ts +13 -7
- package/templates/quickstart/src/flows/viewer-blocked.flow.ts +6 -2
- package/templates/quickstart/tests/chain-flow.spec.ts +8 -1
- package/templates/scaffold/STRUCTURE.md +23 -3
- package/templates/scaffold/scripts/fixture-server.mjs +11 -2
- package/templates/scaffold/src/flows/example.flow.ts +8 -6
- package/templates/scaffold/src/flows/mail-verify.flow.ts +85 -0
- package/templates/scaffold/src/flows/shop.flow.ts +23 -6
- package/templates/scaffold/src/map/(app_base)/docs/_nav.block.ts +20 -0
- package/templates/scaffold/src/map/(app_base)/docs/_page.block.ts +15 -0
- package/templates/scaffold/src/map/(app_base)/docs/_sel.ts +7 -0
- package/templates/scaffold/src/map/(app_base)/docs/docs.html +8 -0
- package/templates/scaffold/src/{blocks/demo-web/methods → map/(app_base)/home/_methods}/add-item.effect.block.ts +3 -3
- package/templates/scaffold/src/map/(app_base)/home/_methods/assert-hello.method.block.ts +46 -0
- package/templates/scaffold/src/map/(app_base)/home/_methods/assert-item-added.method.block.ts +38 -0
- package/templates/scaffold/src/{blocks/demo-web/methods → map/(app_base)/home/_methods}/clear-cart.method.block.ts +9 -3
- package/templates/scaffold/src/{blocks/demo-web/methods → map/(app_base)/home/_methods}/remove-item.effect.block.ts +3 -3
- package/templates/scaffold/src/{blocks/demo-web/nav-home.block.ts → map/(app_base)/home/_nav.block.ts} +2 -2
- package/templates/scaffold/src/{blocks/demo-web/home.page.block.ts → map/(app_base)/home/_page.block.ts} +7 -7
- package/templates/scaffold/src/{blocks/demo-web/demo-sel.ts → map/(app_base)/home/_sel.ts} +1 -0
- package/templates/scaffold/src/{blocks/demo-web → map/(app_base)/home}/home.html +4 -0
- package/templates/scaffold/src/map/(app_base)/home/nav-verification-link.block.ts +34 -0
- package/templates/scaffold/src/map/(external)/mailpit/_methods/assert-email-content.method.block.ts +48 -0
- package/templates/scaffold/src/map/(external)/mailpit/_methods/assert-email-received.method.block.ts +49 -0
- package/templates/scaffold/src/map/(external)/mailpit/_methods/extract-email-link.method.block.ts +41 -0
- package/templates/scaffold/src/map/(external)/mailpit/_methods/open-message.method.block.ts +39 -0
- package/templates/scaffold/src/map/(external)/mailpit/_nav.block.ts +20 -0
- package/templates/scaffold/src/map/(external)/mailpit/_page.block.ts +30 -0
- package/templates/scaffold/src/map/(external)/mailpit/_sel.ts +5 -0
- package/templates/scaffold/src/states/demo.mem-keys.ts +25 -1
- package/templates/scaffold/src/states/demo.states.ts +11 -0
- package/templates/scaffold/test-results/.last-run.json +4 -0
- package/templates/scaffold/tests/example.spec.ts +2 -2
- package/templates/scaffold/tests/mail-verify.spec.ts +191 -0
- package/templates/skills/waygraph-blind-pilot.skill.md +61 -0
- package/templates/skills/waygraph-pilot.skill.md +108 -0
- package/templates/quickstart/README-saucedemo-commands.md +0 -72
- package/templates/scaffold/src/blocks/SITE-MAP.md +0 -12
- package/templates/scaffold/src/blocks/demo-web/NAV.md +0 -29
- package/templates/scaffold/src/blocks/demo-web/methods/assert-hello.method.block.ts +0 -50
package/dist/engine.d.ts
CHANGED
|
@@ -13,6 +13,52 @@ import { type HighlightStyleDefaults, type DemoPace } from "./highlights.js";
|
|
|
13
13
|
* since those depend on a runtime decision that hasn't happened yet.
|
|
14
14
|
*/
|
|
15
15
|
export declare function preflight(mem: MemPage, block: Block<any, any>): void;
|
|
16
|
+
/**
|
|
17
|
+
* A cross-cutting, automatically-enforced verify - the real engine
|
|
18
|
+
* primitive behind "persistent UI" (a sidebar, a header, anything that's
|
|
19
|
+
* supposed to be present on many/most Checkpoints, not just one page's own
|
|
20
|
+
* Block). Deliberately NOT tied to any folder convention - `appliesTo`
|
|
21
|
+
* matches by Checkpoint tag, explicitly, so this works the same whether a
|
|
22
|
+
* project uses the Waygraph Map folder convention or the older freeform
|
|
23
|
+
* "manual mode" layout real production consumers (pia-waygraph,
|
|
24
|
+
* zsign-atomic-waygraph) already use - registering a Layout with an Engine
|
|
25
|
+
* is the only requirement, folder structure is irrelevant to it.
|
|
26
|
+
*
|
|
27
|
+
* Not a Block: no `act`/`resolve`/Checkpoint of its own, never a graph
|
|
28
|
+
* node - it only ever adds extra `verify` Traits to Checkpoints something
|
|
29
|
+
* else already resolved to, the same way `runVerify` already runs after
|
|
30
|
+
* any Block's own `resolve()` (see `runGraph`'s own verify step, just
|
|
31
|
+
* below) - a Layout is that mechanism made reusable across many
|
|
32
|
+
* Checkpoints instead of hand-repeated per Block.
|
|
33
|
+
*/
|
|
34
|
+
export interface Layout {
|
|
35
|
+
name: string;
|
|
36
|
+
description?: string;
|
|
37
|
+
appliesTo: (tag: string) => boolean;
|
|
38
|
+
/** Function form gets the full resolved Checkpoint, same shape `runVerify`/a Block's own `verify` already use - not just the tag. */
|
|
39
|
+
verify: Trait[] | ((out: Checkpoint<string>) => Trait[]);
|
|
40
|
+
}
|
|
41
|
+
export interface LayoutOptions {
|
|
42
|
+
name: string;
|
|
43
|
+
description?: string;
|
|
44
|
+
/** A fixed tag list, or a predicate for open-ended matching (e.g. a naming pattern). */
|
|
45
|
+
appliesTo: readonly string[] | ((tag: string) => boolean);
|
|
46
|
+
verify: Trait[] | ((out: Checkpoint<string>) => Trait[]);
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* @example
|
|
50
|
+
* const AppShellLayout = defineLayout({
|
|
51
|
+
* name: "app-shell",
|
|
52
|
+
* appliesTo: ["AppHome", "Chats", "Notifications", "Settings"],
|
|
53
|
+
* verify: [Trait.visible(SidebarSel.root)],
|
|
54
|
+
* });
|
|
55
|
+
* const engine = new Engine({ layouts: [AppShellLayout] });
|
|
56
|
+
* // Now every Block resolving to one of those four Checkpoints, in any
|
|
57
|
+
* // Flow this engine defines, also gets AppShellLayout's own verify run
|
|
58
|
+
* // automatically - a page that silently drops the sidebar fails loud,
|
|
59
|
+
* // even though no individual Block's own `verify` mentions it.
|
|
60
|
+
*/
|
|
61
|
+
export declare function defineLayout(options: LayoutOptions): Layout;
|
|
16
62
|
/**
|
|
17
63
|
* Runs `entry` against a fresh tab and returns the resulting terminal Checkpoint.
|
|
18
64
|
* The engine owns the tab's lifecycle, not any individual Block: the tab is
|
|
@@ -52,6 +98,14 @@ export interface RunGraphOptions {
|
|
|
52
98
|
* `page` and `closeOnFinish` together) - it just does what you ask.
|
|
53
99
|
*/
|
|
54
100
|
closeOnFinish?: boolean;
|
|
101
|
+
/**
|
|
102
|
+
* Layouts (see {@link defineLayout}) whose `verify` runs automatically
|
|
103
|
+
* after any Block in this run resolves to a Checkpoint they apply to -
|
|
104
|
+
* `Flow.run` threads this in from `EngineConfig.layouts` by default; pass
|
|
105
|
+
* it directly here to call `runGraph` standalone (outside a `Flow`) with
|
|
106
|
+
* layouts still enforced.
|
|
107
|
+
*/
|
|
108
|
+
layouts?: readonly Layout[];
|
|
55
109
|
}
|
|
56
110
|
/**
|
|
57
111
|
* Drives a genuinely separate second tab through its own Block/Flow, in the
|
|
@@ -435,6 +489,14 @@ export interface EngineConfig {
|
|
|
435
489
|
height: number;
|
|
436
490
|
};
|
|
437
491
|
};
|
|
492
|
+
/**
|
|
493
|
+
* Cross-cutting, automatically-enforced verify (see {@link defineLayout})
|
|
494
|
+
* - applies to every Flow this Engine defines. Works the same regardless
|
|
495
|
+
* of folder convention (Waygraph Map or freeform "manual mode") since
|
|
496
|
+
* matching is by Checkpoint tag, never by file path.
|
|
497
|
+
* @example new Engine({ layouts: [AppShellLayout] })
|
|
498
|
+
*/
|
|
499
|
+
layouts?: readonly Layout[];
|
|
438
500
|
}
|
|
439
501
|
type S = Checkpoint<"__start__">;
|
|
440
502
|
/**
|
|
@@ -595,7 +657,106 @@ export declare class Engine {
|
|
|
595
657
|
Block<N, O>,
|
|
596
658
|
EndMarker
|
|
597
659
|
]): Flow<O>;
|
|
660
|
+
/**
|
|
661
|
+
* Fluent, kind-checked alternative to `defineFlow([start, ...blocks, end])` -
|
|
662
|
+
* see {@link MapBuilder}. Real, direct request this responds to: pia/zsign's
|
|
663
|
+
* own agents kept hand-editing/hand-composing Blocks into ad hoc shapes
|
|
664
|
+
* ("locks" convention tried, still got broken) - `map()` forces every step
|
|
665
|
+
* through this Engine's own `define*Block` factories (checked by the same
|
|
666
|
+
* `__waygraphKind`/`__waygraphSalt` runtime markers `graph.ts`/`map-check.ts`
|
|
667
|
+
* already trust), so a hand-rolled plain-object Block can never silently
|
|
668
|
+
* pass as a real navigation/assertion/method step. `homeOrigin`, if given,
|
|
669
|
+
* also gates `.gotoPage()`/`.gotoExternal()` against each Nav/Page Block's
|
|
670
|
+
* own static `url` (skipped, honestly, for click-based/dynamic nav - not
|
|
671
|
+
* statically checkable, same limitation `map-check.ts` already documents).
|
|
672
|
+
* @example
|
|
673
|
+
* const flow = engine.map({ homeOrigin: "https://app.example.com" })
|
|
674
|
+
* .start()
|
|
675
|
+
* .gotoPage(NavHomeBlock)
|
|
676
|
+
* .assert(AssertHelloBlock)
|
|
677
|
+
* .gotoExternal(NavMailpitBlock)
|
|
678
|
+
* .end();
|
|
679
|
+
*/
|
|
680
|
+
map(options?: MapBuilderOptions): MapBuilder<S>;
|
|
681
|
+
}
|
|
682
|
+
export interface MapBuilderOptions {
|
|
683
|
+
/**
|
|
684
|
+
* This project's own origin (e.g. `"https://app.example.com"`) - enables
|
|
685
|
+
* `.gotoPage()`/`.gotoExternal()`'s origin check against a Block's static
|
|
686
|
+
* `url`. Omit to skip that check entirely (still fully kind-checked either
|
|
687
|
+
* way; only the internal/external origin distinction is opt-in).
|
|
688
|
+
*/
|
|
689
|
+
homeOrigin?: string;
|
|
598
690
|
}
|
|
691
|
+
/**
|
|
692
|
+
* Fluent builder over {@link Engine.defineFlow} - see `map()`'s own doc
|
|
693
|
+
* comment for why this exists. Each step method is scoped to exactly the
|
|
694
|
+
* Block kind its name promises, checked at RUNTIME against the
|
|
695
|
+
* `__waygraphKind`/`__waygraphSalt` markers `defineNavBlock`/`definePageBlock`/
|
|
696
|
+
* `defineAssertBlock`/`defineMethodBlock`/`defineEffectBlock` already set
|
|
697
|
+
* (the same markers `graph.ts` and `map-check.ts` trust) - not just a type
|
|
698
|
+
* hint, since a hand-rolled object can satisfy the TypeScript `Block<In,Out>`
|
|
699
|
+
* shape without ever going through a real factory. Each call also
|
|
700
|
+
* typechecks the accumulated Checkpoint chain exactly like `defineFlow`'s
|
|
701
|
+
* own tuple overloads do (a step's `In` must equal the previous step's
|
|
702
|
+
* `Out`) - this is what "no teleporting" means: there is no method on this
|
|
703
|
+
* builder that can skip from one Checkpoint to an unrelated one without a
|
|
704
|
+
* real, kind-correct Block in between.
|
|
705
|
+
*/
|
|
706
|
+
export declare class MapBuilder<Out extends Checkpoint<string>> {
|
|
707
|
+
private readonly engine;
|
|
708
|
+
private readonly steps;
|
|
709
|
+
private readonly homeOrigin;
|
|
710
|
+
private constructor();
|
|
711
|
+
/** @internal - use `engine.map()` or the standalone `map()` export. */
|
|
712
|
+
static begin(engine: Engine, homeOrigin: string | undefined): MapBuilder<S>;
|
|
713
|
+
/** Readable chain-opener - mirrors `defineFlow`'s leading `start` sentinel. Returns `this` unchanged; entirely optional. */
|
|
714
|
+
start(): MapBuilder<Out>;
|
|
715
|
+
/**
|
|
716
|
+
* Appends an internal navigation/page-arrival step - requires a Block from
|
|
717
|
+
* `defineNavBlock`/`defineMemNavBlock`/`definePageBlock`. Throws if given
|
|
718
|
+
* anything else, including a `homeOrigin`-mismatched static `url`.
|
|
719
|
+
*/
|
|
720
|
+
gotoPage<NextOut extends Checkpoint<string>>(block: Block<Out, NextOut> & {
|
|
721
|
+
name: string;
|
|
722
|
+
}): MapBuilder<NextOut>;
|
|
723
|
+
/**
|
|
724
|
+
* Appends a genuinely cross-origin navigation step (e.g. `(external)/`
|
|
725
|
+
* Blocks in the Waygraph Map convention: mailpit, maildrop.cc) - same
|
|
726
|
+
* kind requirement as {@link gotoPage}, plus the inverse `homeOrigin` check.
|
|
727
|
+
*/
|
|
728
|
+
gotoExternal<NextOut extends Checkpoint<string>>(block: Block<Out, NextOut> & {
|
|
729
|
+
name: string;
|
|
730
|
+
}): MapBuilder<NextOut>;
|
|
731
|
+
/** Appends a self-loop verification step - requires a Block from `defineAssertBlock`. */
|
|
732
|
+
assert<NextOut extends Checkpoint<string>>(block: Block<Out, NextOut> & {
|
|
733
|
+
name: string;
|
|
734
|
+
}): MapBuilder<NextOut>;
|
|
735
|
+
/**
|
|
736
|
+
* Appends a non-navigating page action (submit, upload, add/remove an
|
|
737
|
+
* instance) - requires a Block from `defineMethodBlock`/`defineActionBlock`/
|
|
738
|
+
* `defineEffectBlock`/`defineMemEffectBlock`.
|
|
739
|
+
*/
|
|
740
|
+
method<NextOut extends Checkpoint<string>>(block: Block<Out, NextOut> & {
|
|
741
|
+
name: string;
|
|
742
|
+
}): MapBuilder<NextOut>;
|
|
743
|
+
/**
|
|
744
|
+
* Finalizes this chain into a real, runnable {@link Flow} - same object
|
|
745
|
+
* `defineFlow` returns, so `withBlockVerify`/`modBlockVerify` and every
|
|
746
|
+
* `withTitle`/`withHighlightFixtures`/etc. decorator still apply exactly
|
|
747
|
+
* as they do today; this builder only changes how the chain is assembled,
|
|
748
|
+
* never what it produces. Throws if no step was ever added - an empty map
|
|
749
|
+
* isn't a flow.
|
|
750
|
+
*/
|
|
751
|
+
end(): Flow<Out>;
|
|
752
|
+
}
|
|
753
|
+
/**
|
|
754
|
+
* Standalone convenience for `new Engine(config).map(options)` - use this
|
|
755
|
+
* when a call site doesn't otherwise need its own `Engine` instance (no
|
|
756
|
+
* shared `headless`/`slowMo`/`layouts` across several flows).
|
|
757
|
+
* @example const flow = map({ homeOrigin: "https://app.example.com" }).gotoPage(NavHomeBlock).end();
|
|
758
|
+
*/
|
|
759
|
+
export declare function map(options?: MapBuilderOptions & EngineConfig): MapBuilder<S>;
|
|
599
760
|
/**
|
|
600
761
|
* Attaches routing to `block` without touching its act/observe/resolve/verify -
|
|
601
762
|
* `routes` must cover every tag of `block`'s output (a missing route is a compile
|
|
@@ -637,7 +798,7 @@ export declare function defineBlock<In extends Checkpoint<string>, Out extends C
|
|
|
637
798
|
* (same shape `DefinedBlock`/`ComposedBlock` already use), so it drops into
|
|
638
799
|
* `defineFlow([...])`, `connect()`, `composeBlock()` exactly like any other
|
|
639
800
|
* Block - no special-casing needed anywhere that only expects a `Block`.
|
|
640
|
-
* See `openspec/
|
|
801
|
+
* See `openspec/specs/nav-block-and-check/spec.md` for why this exists.
|
|
641
802
|
*/
|
|
642
803
|
export type NavBlock<Out extends Checkpoint<string>> = DefinedBlock<Checkpoint<string>, Out>;
|
|
643
804
|
/**
|
|
@@ -742,6 +903,45 @@ export type ActionBlock<In extends Checkpoint<string>, Out extends Checkpoint<st
|
|
|
742
903
|
export declare function defineMethodBlock<In extends Checkpoint<string>, Out extends Checkpoint<string>>(base: Parameters<typeof defineBlock<In, Out>>[0]): MethodBlock<In, Out>;
|
|
743
904
|
/** @deprecated Prefer {@link defineMethodBlock} - identical helper (0.7 name). */
|
|
744
905
|
export declare const defineActionBlock: typeof defineMethodBlock;
|
|
906
|
+
export interface AssertBlockOptions<Out extends Checkpoint<string> = Checkpoint<string>> {
|
|
907
|
+
name: string;
|
|
908
|
+
description?: string;
|
|
909
|
+
/** Self-loop target - the Checkpoint this assertion runs on and returns to. */
|
|
910
|
+
checkpoint: Out["__state"];
|
|
911
|
+
/**
|
|
912
|
+
* Shorthand for the wait-then-assert shape found repeatedly in hand-written
|
|
913
|
+
* assertion Blocks: waits for a heading with this accessible name before
|
|
914
|
+
* `verify` runs. Omit for a pure "assert whatever is already on the page"
|
|
915
|
+
* check with no wait. Not a general `act()` override - a Block that needs
|
|
916
|
+
* more than this stays a plain `defineMethodBlock`.
|
|
917
|
+
*/
|
|
918
|
+
waitForHeading?: string;
|
|
919
|
+
verify: Trait[] | ((out: Out) => Trait[]);
|
|
920
|
+
/** Mem keys this assertion's `verify` reads (e.g. a mem-aware Trait) - checked by preflight before the flow runs. */
|
|
921
|
+
requires?: readonly MemKey<any>[];
|
|
922
|
+
stubBefore?: import("./highlights.js").HighlightStubPhaseOrFn<Out>;
|
|
923
|
+
stubAfter?: import("./highlights.js").HighlightStubPhaseOrFn<Out>;
|
|
924
|
+
stubOnError?: import("./highlights.js").HighlightStubPhaseOrFn<Out>;
|
|
925
|
+
/** Multi-step yap slides (demo only) - same field `Instruction.slides` exposes elsewhere. */
|
|
926
|
+
slides?: import("./highlights.js").WaygraphSlidesOrFn<Out>;
|
|
927
|
+
}
|
|
928
|
+
/**
|
|
929
|
+
* Sugar for a self-loop-only "pure assertion" Block: no hand-written
|
|
930
|
+
* `act`/`resolve`, just a name, a `checkpoint` tag, and a `verify` array.
|
|
931
|
+
* `resolve` is generated from the one `checkpoint` field given, closing the
|
|
932
|
+
* copy/rename footgun where a hand-restated checkpoint string can silently
|
|
933
|
+
* drift wrong across a copy/pasted file. Mirrors `definePageBlock`'s own
|
|
934
|
+
* construction pattern (flat options in, `defineBlock` built internally).
|
|
935
|
+
* See openspec/changes/waygraph-agent-skill-hardening/spec.md.
|
|
936
|
+
* @example
|
|
937
|
+
* defineAssertBlock({
|
|
938
|
+
* name: "assert-raw-materials-table",
|
|
939
|
+
* checkpoint: "RawMaterials",
|
|
940
|
+
* waitForHeading: "Raw Materials & Lead Times",
|
|
941
|
+
* verify: [Trait.visible(RawMaterialsSel.reorderBadge)],
|
|
942
|
+
* });
|
|
943
|
+
*/
|
|
944
|
+
export declare function defineAssertBlock<Out extends Checkpoint<string> = Checkpoint<string>>(options: AssertBlockOptions<Out>): MethodBlock<Out, Out>;
|
|
745
945
|
/** One Block (or lazy factory) registered on a {@link PageBlock}. */
|
|
746
946
|
export type PageMethodEntry = DefinedBlock<any, any> | (() => DefinedBlock<any, any>);
|
|
747
947
|
export type PageBlockOptions<Out extends Checkpoint<string>> = {
|
package/dist/engine.js
CHANGED
|
@@ -34,6 +34,46 @@ export function preflight(mem, block) {
|
|
|
34
34
|
.join(", ")}`);
|
|
35
35
|
}
|
|
36
36
|
}
|
|
37
|
+
/**
|
|
38
|
+
* @example
|
|
39
|
+
* const AppShellLayout = defineLayout({
|
|
40
|
+
* name: "app-shell",
|
|
41
|
+
* appliesTo: ["AppHome", "Chats", "Notifications", "Settings"],
|
|
42
|
+
* verify: [Trait.visible(SidebarSel.root)],
|
|
43
|
+
* });
|
|
44
|
+
* const engine = new Engine({ layouts: [AppShellLayout] });
|
|
45
|
+
* // Now every Block resolving to one of those four Checkpoints, in any
|
|
46
|
+
* // Flow this engine defines, also gets AppShellLayout's own verify run
|
|
47
|
+
* // automatically - a page that silently drops the sidebar fails loud,
|
|
48
|
+
* // even though no individual Block's own `verify` mentions it.
|
|
49
|
+
*/
|
|
50
|
+
export function defineLayout(options) {
|
|
51
|
+
const appliesTo = typeof options.appliesTo === "function"
|
|
52
|
+
? options.appliesTo
|
|
53
|
+
: (tag) => options.appliesTo.includes(tag);
|
|
54
|
+
return {
|
|
55
|
+
name: options.name,
|
|
56
|
+
...(options.description ? { description: options.description } : {}),
|
|
57
|
+
appliesTo,
|
|
58
|
+
verify: options.verify,
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Runs every registered layout whose `appliesTo(tag)` matches the just-
|
|
63
|
+
* resolved Checkpoint, in registration order, right after the Block's own
|
|
64
|
+
* `verify` already ran. A layout's own Trait failing throws the same way
|
|
65
|
+
* any other `runVerify` failure does, naming the layout so it's clearly
|
|
66
|
+
* distinguishable from the Block's own verify in the error message.
|
|
67
|
+
*/
|
|
68
|
+
async function runLayouts(layouts, tag, out, page, mem, blockName) {
|
|
69
|
+
if (!layouts)
|
|
70
|
+
return;
|
|
71
|
+
for (const layout of layouts) {
|
|
72
|
+
if (!layout.appliesTo(tag))
|
|
73
|
+
continue;
|
|
74
|
+
await runVerify(layout.verify, out, page, mem, `${blockName} (layout: "${layout.name}")`);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
37
77
|
/**
|
|
38
78
|
* Runs `entry` against a fresh tab and returns the resulting terminal Checkpoint.
|
|
39
79
|
* The engine owns the tab's lifecycle, not any individual Block: the tab is
|
|
@@ -72,6 +112,7 @@ export async function runGraph(entry, terminals, context, mem, maxSteps = 5000,
|
|
|
72
112
|
: undefined;
|
|
73
113
|
const checkpoint = await current.instruction.resolve(observed);
|
|
74
114
|
await runVerify(current.instruction.verify, checkpoint, page, mem, current.name);
|
|
115
|
+
await runLayouts(options?.layouts, checkpoint.__state, checkpoint, page, mem, current.name);
|
|
75
116
|
const next = current.next?.(checkpoint);
|
|
76
117
|
if (!next) {
|
|
77
118
|
if (terminals && !terminals.has(checkpoint.__state)) {
|
|
@@ -218,7 +259,11 @@ function buildFlow(middle, engineConfig) {
|
|
|
218
259
|
// withSessionReset()/withTitle() instead (non-destructive decorators,
|
|
219
260
|
// same pattern as withVerify), which also re-apply themselves after any
|
|
220
261
|
// further withBlockVerify/modBlockVerify patch so the flag survives.
|
|
221
|
-
|
|
262
|
+
// Layouts have to be threaded into every pairwise connect(), not just the
|
|
263
|
+
// trailing runGraph call - see connect()'s own doc comment in types.ts:
|
|
264
|
+
// buildFlow's reduce IS the only place a defineFlow-built Flow's
|
|
265
|
+
// intermediate (non-final) Checkpoints are ever verified at all.
|
|
266
|
+
const chain = middle.reduce((a, b) => connect(a, b, engineConfig.layouts));
|
|
222
267
|
// Declared separately (not as the object-literal method below) so the
|
|
223
268
|
// three-overload `Flow.run` signature can be checked against the actual
|
|
224
269
|
// per-call-shape behavior, then attached with a cast - object-literal
|
|
@@ -248,7 +293,9 @@ function buildFlow(middle, engineConfig) {
|
|
|
248
293
|
try {
|
|
249
294
|
const context = await browser.newContext(config.recordVideo ? { recordVideo: config.recordVideo } : {});
|
|
250
295
|
try {
|
|
251
|
-
return await runGraph(chain, undefined, context, mem
|
|
296
|
+
return await runGraph(chain, undefined, context, mem, 5000, {
|
|
297
|
+
...(config.layouts !== undefined ? { layouts: config.layouts } : {}),
|
|
298
|
+
});
|
|
252
299
|
}
|
|
253
300
|
finally {
|
|
254
301
|
// Playwright finalizes recordVideo on context.close(); skip when
|
|
@@ -277,9 +324,11 @@ function buildFlow(middle, engineConfig) {
|
|
|
277
324
|
// call from before this option existed. An explicit `closeOnFinish`
|
|
278
325
|
// always wins either way.
|
|
279
326
|
const closeOnFinish = options?.closeOnFinish ?? gotOwnPage;
|
|
327
|
+
const resolvedLayouts = options?.layouts ?? engineConfig.layouts;
|
|
280
328
|
const result = await runGraph(chain, undefined, context, mem, 5000, {
|
|
281
329
|
page,
|
|
282
330
|
closeOnFinish: false,
|
|
331
|
+
...(resolvedLayouts !== undefined ? { layouts: resolvedLayouts } : {}),
|
|
283
332
|
});
|
|
284
333
|
if (closeOnFinish) {
|
|
285
334
|
await page.close();
|
|
@@ -655,6 +704,185 @@ export class Engine {
|
|
|
655
704
|
defineFlow(blocks) {
|
|
656
705
|
return buildFlow(blocks.slice(1, -1), this.config);
|
|
657
706
|
}
|
|
707
|
+
/**
|
|
708
|
+
* Fluent, kind-checked alternative to `defineFlow([start, ...blocks, end])` -
|
|
709
|
+
* see {@link MapBuilder}. Real, direct request this responds to: pia/zsign's
|
|
710
|
+
* own agents kept hand-editing/hand-composing Blocks into ad hoc shapes
|
|
711
|
+
* ("locks" convention tried, still got broken) - `map()` forces every step
|
|
712
|
+
* through this Engine's own `define*Block` factories (checked by the same
|
|
713
|
+
* `__waygraphKind`/`__waygraphSalt` runtime markers `graph.ts`/`map-check.ts`
|
|
714
|
+
* already trust), so a hand-rolled plain-object Block can never silently
|
|
715
|
+
* pass as a real navigation/assertion/method step. `homeOrigin`, if given,
|
|
716
|
+
* also gates `.gotoPage()`/`.gotoExternal()` against each Nav/Page Block's
|
|
717
|
+
* own static `url` (skipped, honestly, for click-based/dynamic nav - not
|
|
718
|
+
* statically checkable, same limitation `map-check.ts` already documents).
|
|
719
|
+
* @example
|
|
720
|
+
* const flow = engine.map({ homeOrigin: "https://app.example.com" })
|
|
721
|
+
* .start()
|
|
722
|
+
* .gotoPage(NavHomeBlock)
|
|
723
|
+
* .assert(AssertHelloBlock)
|
|
724
|
+
* .gotoExternal(NavMailpitBlock)
|
|
725
|
+
* .end();
|
|
726
|
+
*/
|
|
727
|
+
map(options) {
|
|
728
|
+
return MapBuilder.begin(this, options?.homeOrigin);
|
|
729
|
+
}
|
|
730
|
+
}
|
|
731
|
+
function mapKindOf(block) {
|
|
732
|
+
return block?.__waygraphKind;
|
|
733
|
+
}
|
|
734
|
+
function mapSaltOf(block) {
|
|
735
|
+
return block?.__waygraphSalt;
|
|
736
|
+
}
|
|
737
|
+
function mapNavUrlOf(block) {
|
|
738
|
+
const url = block?.__waygraphNavUrl;
|
|
739
|
+
return typeof url === "string" ? url : undefined;
|
|
740
|
+
}
|
|
741
|
+
const MAP_KIND_FACTORY_HINT = {
|
|
742
|
+
nav: "defineNavBlock/defineMemNavBlock",
|
|
743
|
+
page: "definePageBlock",
|
|
744
|
+
assert: "defineAssertBlock",
|
|
745
|
+
};
|
|
746
|
+
const MAP_SALT_FACTORY_HINT = {
|
|
747
|
+
method: "defineMethodBlock",
|
|
748
|
+
effect: "defineEffectBlock",
|
|
749
|
+
};
|
|
750
|
+
function assertMapKind(block, allowed, method) {
|
|
751
|
+
const kind = mapKindOf(block);
|
|
752
|
+
if (kind !== undefined && allowed.includes(kind))
|
|
753
|
+
return;
|
|
754
|
+
const wanted = allowed.map((k) => MAP_KIND_FACTORY_HINT[k] ?? k).join(" or ");
|
|
755
|
+
const found = kind ? `a Block of kind "${kind}"` : "an object with no waygraph kind marker at all";
|
|
756
|
+
throw new Error(`Waygraph map: .${method}("${block?.name ?? "?"}") requires a Block built with ${wanted} ` +
|
|
757
|
+
`(found ${found} - a hand-built plain object doesn't count). This check is the whole point ` +
|
|
758
|
+
"of the map() builder: only real Blocks from waygraph's own factories can enter a chain.");
|
|
759
|
+
}
|
|
760
|
+
function assertMapSalt(block, allowed, method) {
|
|
761
|
+
const salt = mapSaltOf(block);
|
|
762
|
+
if (salt !== undefined && allowed.includes(salt))
|
|
763
|
+
return;
|
|
764
|
+
const wanted = allowed.map((s) => MAP_SALT_FACTORY_HINT[s] ?? s).join(" or ");
|
|
765
|
+
const found = salt ? `a Block salted "${salt}"` : "an object with no waygraph salt marker at all";
|
|
766
|
+
throw new Error(`Waygraph map: .${method}("${block?.name ?? "?"}") requires a Block built with ${wanted} ` +
|
|
767
|
+
`(found ${found} - a hand-built plain object doesn't count). This check is the whole point ` +
|
|
768
|
+
"of the map() builder: only real Blocks from waygraph's own factories can enter a chain.");
|
|
769
|
+
}
|
|
770
|
+
function assertMapOrigin(block, homeOrigin, expect, method) {
|
|
771
|
+
if (!homeOrigin)
|
|
772
|
+
return; // not configured - can't validate, honest no-op
|
|
773
|
+
const navUrl = mapNavUrlOf(block);
|
|
774
|
+
if (navUrl === undefined)
|
|
775
|
+
return; // click-based/dynamic nav - not statically checkable
|
|
776
|
+
let targetOrigin;
|
|
777
|
+
let wantOrigin;
|
|
778
|
+
try {
|
|
779
|
+
targetOrigin = new URL(navUrl, homeOrigin).origin;
|
|
780
|
+
wantOrigin = new URL(homeOrigin).origin;
|
|
781
|
+
}
|
|
782
|
+
catch {
|
|
783
|
+
return; // malformed URL - not this check's job to validate that
|
|
784
|
+
}
|
|
785
|
+
const isExternal = targetOrigin !== wantOrigin;
|
|
786
|
+
if (expect === "internal" && isExternal) {
|
|
787
|
+
throw new Error(`Waygraph map: .gotoPage("${block.name}") targets ${targetOrigin}, which is NOT this map's ` +
|
|
788
|
+
`home origin (${wantOrigin}) - use .gotoExternal() for a genuinely cross-origin destination.`);
|
|
789
|
+
}
|
|
790
|
+
if (expect === "external" && !isExternal) {
|
|
791
|
+
throw new Error(`Waygraph map: .gotoExternal("${block.name}") targets ${targetOrigin}, which IS this map's ` +
|
|
792
|
+
`home origin (${wantOrigin}) - use .gotoPage() for an internal destination.`);
|
|
793
|
+
}
|
|
794
|
+
}
|
|
795
|
+
/**
|
|
796
|
+
* Fluent builder over {@link Engine.defineFlow} - see `map()`'s own doc
|
|
797
|
+
* comment for why this exists. Each step method is scoped to exactly the
|
|
798
|
+
* Block kind its name promises, checked at RUNTIME against the
|
|
799
|
+
* `__waygraphKind`/`__waygraphSalt` markers `defineNavBlock`/`definePageBlock`/
|
|
800
|
+
* `defineAssertBlock`/`defineMethodBlock`/`defineEffectBlock` already set
|
|
801
|
+
* (the same markers `graph.ts` and `map-check.ts` trust) - not just a type
|
|
802
|
+
* hint, since a hand-rolled object can satisfy the TypeScript `Block<In,Out>`
|
|
803
|
+
* shape without ever going through a real factory. Each call also
|
|
804
|
+
* typechecks the accumulated Checkpoint chain exactly like `defineFlow`'s
|
|
805
|
+
* own tuple overloads do (a step's `In` must equal the previous step's
|
|
806
|
+
* `Out`) - this is what "no teleporting" means: there is no method on this
|
|
807
|
+
* builder that can skip from one Checkpoint to an unrelated one without a
|
|
808
|
+
* real, kind-correct Block in between.
|
|
809
|
+
*/
|
|
810
|
+
export class MapBuilder {
|
|
811
|
+
engine;
|
|
812
|
+
steps;
|
|
813
|
+
homeOrigin;
|
|
814
|
+
constructor(engine, steps, homeOrigin) {
|
|
815
|
+
this.engine = engine;
|
|
816
|
+
this.steps = steps;
|
|
817
|
+
this.homeOrigin = homeOrigin;
|
|
818
|
+
}
|
|
819
|
+
/** @internal - use `engine.map()` or the standalone `map()` export. */
|
|
820
|
+
static begin(engine, homeOrigin) {
|
|
821
|
+
return new MapBuilder(engine, [], homeOrigin);
|
|
822
|
+
}
|
|
823
|
+
/** Readable chain-opener - mirrors `defineFlow`'s leading `start` sentinel. Returns `this` unchanged; entirely optional. */
|
|
824
|
+
start() {
|
|
825
|
+
return this;
|
|
826
|
+
}
|
|
827
|
+
/**
|
|
828
|
+
* Appends an internal navigation/page-arrival step - requires a Block from
|
|
829
|
+
* `defineNavBlock`/`defineMemNavBlock`/`definePageBlock`. Throws if given
|
|
830
|
+
* anything else, including a `homeOrigin`-mismatched static `url`.
|
|
831
|
+
*/
|
|
832
|
+
gotoPage(block) {
|
|
833
|
+
assertMapKind(block, ["nav", "page"], "gotoPage");
|
|
834
|
+
assertMapOrigin(block, this.homeOrigin, "internal", "gotoPage");
|
|
835
|
+
return new MapBuilder(this.engine, [...this.steps, block], this.homeOrigin);
|
|
836
|
+
}
|
|
837
|
+
/**
|
|
838
|
+
* Appends a genuinely cross-origin navigation step (e.g. `(external)/`
|
|
839
|
+
* Blocks in the Waygraph Map convention: mailpit, maildrop.cc) - same
|
|
840
|
+
* kind requirement as {@link gotoPage}, plus the inverse `homeOrigin` check.
|
|
841
|
+
*/
|
|
842
|
+
gotoExternal(block) {
|
|
843
|
+
assertMapKind(block, ["nav", "page"], "gotoExternal");
|
|
844
|
+
assertMapOrigin(block, this.homeOrigin, "external", "gotoExternal");
|
|
845
|
+
return new MapBuilder(this.engine, [...this.steps, block], this.homeOrigin);
|
|
846
|
+
}
|
|
847
|
+
/** Appends a self-loop verification step - requires a Block from `defineAssertBlock`. */
|
|
848
|
+
assert(block) {
|
|
849
|
+
assertMapKind(block, ["assert"], "assert");
|
|
850
|
+
return new MapBuilder(this.engine, [...this.steps, block], this.homeOrigin);
|
|
851
|
+
}
|
|
852
|
+
/**
|
|
853
|
+
* Appends a non-navigating page action (submit, upload, add/remove an
|
|
854
|
+
* instance) - requires a Block from `defineMethodBlock`/`defineActionBlock`/
|
|
855
|
+
* `defineEffectBlock`/`defineMemEffectBlock`.
|
|
856
|
+
*/
|
|
857
|
+
method(block) {
|
|
858
|
+
assertMapSalt(block, ["method", "effect"], "method");
|
|
859
|
+
return new MapBuilder(this.engine, [...this.steps, block], this.homeOrigin);
|
|
860
|
+
}
|
|
861
|
+
/**
|
|
862
|
+
* Finalizes this chain into a real, runnable {@link Flow} - same object
|
|
863
|
+
* `defineFlow` returns, so `withBlockVerify`/`modBlockVerify` and every
|
|
864
|
+
* `withTitle`/`withHighlightFixtures`/etc. decorator still apply exactly
|
|
865
|
+
* as they do today; this builder only changes how the chain is assembled,
|
|
866
|
+
* never what it produces. Throws if no step was ever added - an empty map
|
|
867
|
+
* isn't a flow.
|
|
868
|
+
*/
|
|
869
|
+
end() {
|
|
870
|
+
if (this.steps.length === 0) {
|
|
871
|
+
throw new Error("Waygraph map: .end() called with zero steps - add at least one .gotoPage()/.gotoExternal()/" +
|
|
872
|
+
".assert()/.method() before .end()");
|
|
873
|
+
}
|
|
874
|
+
const chain = [start, ...this.steps, end];
|
|
875
|
+
return this.engine.defineFlow(chain);
|
|
876
|
+
}
|
|
877
|
+
}
|
|
878
|
+
/**
|
|
879
|
+
* Standalone convenience for `new Engine(config).map(options)` - use this
|
|
880
|
+
* when a call site doesn't otherwise need its own `Engine` instance (no
|
|
881
|
+
* shared `headless`/`slowMo`/`layouts` across several flows).
|
|
882
|
+
* @example const flow = map({ homeOrigin: "https://app.example.com" }).gotoPage(NavHomeBlock).end();
|
|
883
|
+
*/
|
|
884
|
+
export function map(options) {
|
|
885
|
+
return new Engine(options).map(options);
|
|
658
886
|
}
|
|
659
887
|
/**
|
|
660
888
|
* Attaches routing to `block` without touching its act/observe/resolve/verify -
|
|
@@ -797,6 +1025,20 @@ export function defineNavBlock(options) {
|
|
|
797
1025
|
configurable: false,
|
|
798
1026
|
});
|
|
799
1027
|
}
|
|
1028
|
+
// Same idea, for the url case - only when it's a plain string (a
|
|
1029
|
+
// function URL is mem-dependent/dynamic, can't be compared statically
|
|
1030
|
+
// without running it). Real, direct request this responds to: an agent
|
|
1031
|
+
// driving Blind Pilot had no structured way to ask "which of the links
|
|
1032
|
+
// on THIS page are already covered by a NavBlock" without re-parsing
|
|
1033
|
+
// every nav.block.ts's own source - this is what `AutoSession` now reads
|
|
1034
|
+
// to warn about real, unmapped nav links found live on the page.
|
|
1035
|
+
if (typeof options.url === "string") {
|
|
1036
|
+
Object.defineProperty(built, "__waygraphNavUrl", {
|
|
1037
|
+
value: options.url,
|
|
1038
|
+
enumerable: false,
|
|
1039
|
+
configurable: false,
|
|
1040
|
+
});
|
|
1041
|
+
}
|
|
800
1042
|
return built;
|
|
801
1043
|
}
|
|
802
1044
|
/** @see {@link NavClickBlockOptions} */
|
|
@@ -826,6 +1068,60 @@ export function defineMethodBlock(base) {
|
|
|
826
1068
|
}
|
|
827
1069
|
/** @deprecated Prefer {@link defineMethodBlock} - identical helper (0.7 name). */
|
|
828
1070
|
export const defineActionBlock = defineMethodBlock;
|
|
1071
|
+
/**
|
|
1072
|
+
* Sugar for a self-loop-only "pure assertion" Block: no hand-written
|
|
1073
|
+
* `act`/`resolve`, just a name, a `checkpoint` tag, and a `verify` array.
|
|
1074
|
+
* `resolve` is generated from the one `checkpoint` field given, closing the
|
|
1075
|
+
* copy/rename footgun where a hand-restated checkpoint string can silently
|
|
1076
|
+
* drift wrong across a copy/pasted file. Mirrors `definePageBlock`'s own
|
|
1077
|
+
* construction pattern (flat options in, `defineBlock` built internally).
|
|
1078
|
+
* See openspec/changes/waygraph-agent-skill-hardening/spec.md.
|
|
1079
|
+
* @example
|
|
1080
|
+
* defineAssertBlock({
|
|
1081
|
+
* name: "assert-raw-materials-table",
|
|
1082
|
+
* checkpoint: "RawMaterials",
|
|
1083
|
+
* waitForHeading: "Raw Materials & Lead Times",
|
|
1084
|
+
* verify: [Trait.visible(RawMaterialsSel.reorderBadge)],
|
|
1085
|
+
* });
|
|
1086
|
+
*/
|
|
1087
|
+
export function defineAssertBlock(options) {
|
|
1088
|
+
const built = defineMethodBlock({
|
|
1089
|
+
name: options.name,
|
|
1090
|
+
...(options.description ? { description: options.description } : {}),
|
|
1091
|
+
...(options.requires ? { requires: options.requires } : {}),
|
|
1092
|
+
instruction: {
|
|
1093
|
+
async act(page) {
|
|
1094
|
+
if (options.waitForHeading !== undefined) {
|
|
1095
|
+
await page.getByRole("heading", { name: options.waitForHeading }).waitFor();
|
|
1096
|
+
}
|
|
1097
|
+
},
|
|
1098
|
+
resolve: () => checkpoint(options.checkpoint),
|
|
1099
|
+
verify: options.verify,
|
|
1100
|
+
...(options.stubBefore ? { stubBefore: options.stubBefore } : {}),
|
|
1101
|
+
...(options.stubAfter ? { stubAfter: options.stubAfter } : {}),
|
|
1102
|
+
...(options.stubOnError ? { stubOnError: options.stubOnError } : {}),
|
|
1103
|
+
...(options.slides ? { slides: options.slides } : {}),
|
|
1104
|
+
},
|
|
1105
|
+
});
|
|
1106
|
+
// Real bug this closes: `waygraph graph`'s static discovery only knows
|
|
1107
|
+
// how to read a Block's Checkpoint tags from an EXPLICIT `<In, Out>`
|
|
1108
|
+
// generic written in the source text (or, for Nav/Page Blocks, by calling
|
|
1109
|
+
// their own input-independent `resolve()` directly). `defineAssertBlock`'s
|
|
1110
|
+
// whole point is skipping that generic - called exactly as documented
|
|
1111
|
+
// (`defineAssertBlock({ name, checkpoint, verify })`, no generics), it was
|
|
1112
|
+
// silently invisible to both `waygraph graph` and the live Pilot menu
|
|
1113
|
+
// ("2 Block(s) skipped (Out not resolvable)", confirmed live against a
|
|
1114
|
+
// real veciro-waygraph session). `resolve()` here is ALSO input-
|
|
1115
|
+
// independent (always `checkpoint(options.checkpoint)`), so the same
|
|
1116
|
+
// resolve()-calling path Nav/Page Blocks already use is reused via this
|
|
1117
|
+
// marker instead of requiring authors to write generics just to be found.
|
|
1118
|
+
Object.defineProperty(built, "__waygraphKind", {
|
|
1119
|
+
value: "assert",
|
|
1120
|
+
enumerable: false,
|
|
1121
|
+
configurable: false,
|
|
1122
|
+
});
|
|
1123
|
+
return built;
|
|
1124
|
+
}
|
|
829
1125
|
function resolvePageMethods(methods) {
|
|
830
1126
|
if (!methods)
|
|
831
1127
|
return [];
|
|
@@ -884,6 +1180,20 @@ export function definePageBlock(options) {
|
|
|
884
1180
|
enumerable: false,
|
|
885
1181
|
configurable: false,
|
|
886
1182
|
});
|
|
1183
|
+
// Same marker `defineNavBlock` sets, same reason - a page hub with a
|
|
1184
|
+
// `url` (deep-link) is exactly as "known, coverable" as a plain
|
|
1185
|
+
// `defineNavBlock`, and in practice most real projects' own nav Blocks
|
|
1186
|
+
// ARE page hubs (methods hanging off them), not bare NavBlocks - the real
|
|
1187
|
+
// saucedemo fixture this whole package tests against uses definePageBlock
|
|
1188
|
+
// for every one of its own nav-* Blocks. Missing this here meant the
|
|
1189
|
+
// marker existed but was never actually set on any real project's Blocks.
|
|
1190
|
+
if (typeof options.url === "string") {
|
|
1191
|
+
Object.defineProperty(built, "__waygraphNavUrl", {
|
|
1192
|
+
value: options.url,
|
|
1193
|
+
enumerable: false,
|
|
1194
|
+
configurable: false,
|
|
1195
|
+
});
|
|
1196
|
+
}
|
|
887
1197
|
if (options.url !== undefined || options.click !== undefined) {
|
|
888
1198
|
Object.defineProperty(built, "__waygraphPageDeepLink", {
|
|
889
1199
|
value: true,
|
package/dist/graph.d.ts
CHANGED
|
@@ -58,6 +58,24 @@ export declare function findOrphanBlocks(projectDir: string): Promise<OrphanBloc
|
|
|
58
58
|
* edges. NavBlocks (`from: "*"`) count from any state.
|
|
59
59
|
*/
|
|
60
60
|
export declare function findBlockPath(graph: WaygraphGraph, fromTag: string, toTag: string): string[] | null;
|
|
61
|
+
export interface BlockPathStep {
|
|
62
|
+
block: string;
|
|
63
|
+
/** The specific Checkpoint this hop's edge targets - NOT re-derivable by
|
|
64
|
+
* looking up `block` by name afterward, since a union-Out Block (e.g.
|
|
65
|
+
* "Union Out tags create duplicate edges for the same Block", see
|
|
66
|
+
* `discoverGraph`'s own comment above) can have several edges with the
|
|
67
|
+
* same `block` name but different `to` tags; only the specific edge BFS
|
|
68
|
+
* actually routed through here is correct. */
|
|
69
|
+
to: string;
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Same BFS as `findBlockPath`, but returns each hop's specific edge (block
|
|
73
|
+
* name + the Checkpoint it targets), not just the block name - needed by any
|
|
74
|
+
* caller that must verify a step actually landed where the route intended,
|
|
75
|
+
* not just re-guess it afterward. `findBlockPath` itself is unchanged and
|
|
76
|
+
* still used wherever only the block-name sequence matters.
|
|
77
|
+
*/
|
|
78
|
+
export declare function findBlockPathDetailed(graph: WaygraphGraph, fromTag: string, toTag: string): BlockPathStep[] | null;
|
|
61
79
|
/**
|
|
62
80
|
* Walks every `*.block.ts` file under `projectDir` and builds the app's own
|
|
63
81
|
* state graph. Shares the same in-process-import limitation `waygraph
|