waygraph 0.13.7 → 0.14.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 +820 -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 +417 -51
- package/dist/engine.d.ts +40 -1
- package/dist/engine.js +82 -0
- 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/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/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.flow.ts +12 -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/routes/(base_app)/dashboard/dashboard.sel.ts +10 -0
- package/examples/routed-demo/src/routes/(base_app)/dashboard/methods/click-widget.block.ts +23 -0
- package/examples/routed-demo/src/routes/(base_app)/dashboard/nav.block.ts +18 -0
- package/examples/routed-demo/src/routes/(base_app)/dashboard/page.block.ts +22 -0
- package/examples/routed-demo/src/routes/(external)/docs/docs.sel.ts +7 -0
- package/examples/routed-demo/src/routes/(external)/docs/nav.block.ts +21 -0
- package/examples/routed-demo/src/routes/(external)/docs/page.block.ts +15 -0
- package/examples/routed-demo/src/states/routed-demo.states.ts +10 -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/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/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/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/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/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/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/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/5c47910f.log +0 -0
- package/examples/saucedemo/.waygraph-auto/5eda8273.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/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/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/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/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/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/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/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/b83e6259.log +0 -0
- package/examples/saucedemo/.waygraph-auto/b9cb2796.log +0 -0
- package/examples/saucedemo/.waygraph-auto/bb0a0018.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/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/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/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/e101d19a.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/ebad3410.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/f3c29b21.log +0 -0
- package/examples/saucedemo/.waygraph-auto/f53f7cfc.log +0 -0
- package/examples/saucedemo/.waygraph-auto/f5ad5830.log +0 -0
- package/examples/saucedemo/.waygraph-auto/faed36dd.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/src/blocks/demo-external/mailpit/mailpit-inbox.page.block.ts +30 -0
- package/templates/scaffold/src/blocks/demo-external/mailpit/mailpit-sel.ts +5 -0
- package/templates/scaffold/src/blocks/demo-external/mailpit/methods/assert-email-content.method.block.ts +48 -0
- package/templates/scaffold/src/blocks/demo-external/mailpit/methods/assert-email-received.method.block.ts +49 -0
- package/templates/scaffold/src/blocks/demo-external/mailpit/methods/extract-email-link.method.block.ts +41 -0
- package/templates/scaffold/src/blocks/demo-external/mailpit/methods/open-message.method.block.ts +39 -0
- package/templates/scaffold/src/blocks/demo-external/mailpit/nav-mailpit-inbox.block.ts +20 -0
- package/templates/scaffold/src/blocks/demo-web/demo-sel.ts +1 -0
- package/templates/scaffold/src/blocks/demo-web/docs.html +8 -0
- package/templates/scaffold/src/blocks/demo-web/home.html +4 -0
- package/templates/scaffold/src/blocks/demo-web/methods/assert-hello.method.block.ts +34 -38
- package/templates/scaffold/src/blocks/demo-web/methods/assert-item-added.method.block.ts +38 -0
- package/templates/scaffold/src/blocks/demo-web/nav-verification-link.block.ts +34 -0
- package/templates/scaffold/src/flows/mail-verify.flow.ts +85 -0
- package/templates/scaffold/src/flows/routes-demo.flow.ts +14 -0
- package/templates/scaffold/src/flows/shop.flow.ts +19 -2
- package/templates/scaffold/src/routes/(external)/docs/docs.sel.ts +7 -0
- package/templates/scaffold/src/routes/(external)/docs/nav.block.ts +21 -0
- package/templates/scaffold/src/routes/(external)/docs/page.block.ts +15 -0
- package/templates/scaffold/src/states/demo.mem-keys.ts +25 -1
- package/templates/scaffold/src/states/demo.states.ts +13 -0
- package/templates/scaffold/test-results/.last-run.json +4 -0
- 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/dist/cli.js
CHANGED
|
@@ -19,6 +19,8 @@ import { fileURLToPath } from "node:url";
|
|
|
19
19
|
import { spawn } from "node:child_process";
|
|
20
20
|
import { discoverGraph, toMermaid, findOrphanBlocks, findBlockPath } from "./graph.js";
|
|
21
21
|
import { runAutoExplore } from "./auto-explore-run.js";
|
|
22
|
+
import { pilotStart } from "./pilot.js";
|
|
23
|
+
import { spawnDetachedSession, requestSession, runAttachLoop, runAutoServeCommand, } from "./auto-session-ipc.js";
|
|
22
24
|
import { runAgentDive } from "./agent-dive.js";
|
|
23
25
|
import { runTraverse } from "./traverse-run.js";
|
|
24
26
|
import { parseMinEdgeCoverage } from "./traverse-coverage.js";
|
|
@@ -232,6 +234,7 @@ import {
|
|
|
232
234
|
completeSequentialTodoDock,
|
|
233
235
|
applyDevicePhase,
|
|
234
236
|
resolveDeviceState,
|
|
237
|
+
WAYGRAPH_RING_CSS,
|
|
235
238
|
} from "waygraph";
|
|
236
239
|
|
|
237
240
|
function walkDir(dir, pattern) {
|
|
@@ -416,45 +419,10 @@ function seedMemForFlow(mem, flowBlocks, json, label) {
|
|
|
416
419
|
// Purely CLI-level orchestration - no engine changes, no change to the
|
|
417
420
|
// non-STEP path above.
|
|
418
421
|
const RING_CSS =
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
//
|
|
422
|
-
|
|
423
|
-
// color transitions read as a muddy gray/purple/yellow morph on ring 2+.
|
|
424
|
-
"box-shadow:0 0 0 4px rgba(124,58,237,.16);transition:opacity .3s ease;}" +
|
|
425
|
-
// Planned (stubs / fixtures / YAP / instruction.highlights) = purple.
|
|
426
|
-
// Automation (verify fallback, unmatched fill/click) = gray - operators
|
|
427
|
-
// can ignore engine checks and watch purple + semantic tones.
|
|
428
|
-
"#wg-ring[data-tone=planned]{border-color:#7C3AED;box-shadow:0 0 0 4px rgba(124,58,237,.16);}" +
|
|
429
|
-
"#wg-ring[data-tone=auto]{border-color:#9CA3AF;box-shadow:0 0 0 4px rgba(156,163,175,.28);}" +
|
|
430
|
-
"#wg-ring[data-tone=info]{border-color:#3B82F6;box-shadow:0 0 0 4px rgba(59,130,246,.22);}" +
|
|
431
|
-
"#wg-ring[data-tone=warning]{border-color:#EAB308;box-shadow:0 0 0 4px rgba(234,179,8,.22);}" +
|
|
432
|
-
"#wg-ring[data-tone=danger]{border-color:#EF4444;box-shadow:0 0 0 4px rgba(239,68,68,.22);}" +
|
|
433
|
-
"#wg-ring[data-tone=success]{border-color:#22C55E;box-shadow:0 0 0 4px rgba(34,197,94,.22);}" +
|
|
434
|
-
// A real element, not a ::after pseudo-element - a pseudo-element's
|
|
435
|
-
// position is CSS-relative to the ring's own box (left:0 always meant
|
|
436
|
-
// "the ring's own left edge"), so it had no way to be clamped back onto
|
|
437
|
-
// screen when that box sat near a viewport edge - the label's text just
|
|
438
|
-
// ran off, invisibly, with no overflow guard at all. A real sibling can
|
|
439
|
-
// be measured (its actual rendered width) and repositioned in JS -
|
|
440
|
-
// pushed back onto screen, same width, never shrunk. See
|
|
441
|
-
// window.__wgPositionRing in installOverlay.
|
|
442
|
-
"#wg-ring-label{position:fixed;z-index:2147483646;pointer-events:none;opacity:0;" +
|
|
443
|
-
"max-width:min(360px,70vw);white-space:normal;padding:6px 10px;border-radius:7px;background:#7C3AED;color:#fff;" +
|
|
444
|
-
"font:600 12px/1.35 system-ui,sans-serif;transition:opacity .3s ease;}" +
|
|
445
|
-
"#wg-ring-label[data-tone=planned]{background:#7C3AED;color:#fff;}" +
|
|
446
|
-
"#wg-ring-label[data-tone=auto]{background:#6B7280;color:#fff;}" +
|
|
447
|
-
"#wg-ring-label[data-tone=info]{background:#2563EB;color:#fff;}" +
|
|
448
|
-
"#wg-ring-label[data-tone=warning]{background:#EAB308;color:#1c1917;}" +
|
|
449
|
-
"#wg-ring-label[data-tone=danger]{background:#DC2626;color:#fff;}" +
|
|
450
|
-
"#wg-ring-label[data-tone=success]{background:#16A34A;color:#fff;}" +
|
|
451
|
-
// size: ring pad + label font; weight: label boldness
|
|
452
|
-
"#wg-ring[data-size=sm]{border-width:1.5px;border-radius:8px;}" +
|
|
453
|
-
"#wg-ring[data-size=lg]{border-width:4px;border-radius:12px;}" +
|
|
454
|
-
"#wg-ring-label[data-size=sm]{font-size:10px;line-height:1.25;padding:4px 7px;border-radius:5px;}" +
|
|
455
|
-
"#wg-ring-label[data-size=lg]{font-size:16px;line-height:1.35;padding:8px 14px;border-radius:9px;max-width:min(480px,85vw);}" +
|
|
456
|
-
"#wg-ring-label[data-weight=bold]{font-weight:800;}" +
|
|
457
|
-
"#wg-ring-label[data-weight=normal]{font-weight:600;}" +
|
|
422
|
+
// Shared with pilot-overlay.ts's showPilotVision - same ring/label CSS,
|
|
423
|
+
// one source of truth (highlights.ts), so a Blind Pilot vision ring and a
|
|
424
|
+
// demo stepper ring never visually drift apart.
|
|
425
|
+
WAYGRAPH_RING_CSS +
|
|
458
426
|
// Mouse cursor icon that travels to a target before it's acted on, plus a
|
|
459
427
|
// quick expanding ripple at the moment of a click - same idea as
|
|
460
428
|
// help-center-clip-engine's #clip-cursor/#clip-ring (video-pipeline). The
|
|
@@ -6343,7 +6311,7 @@ async function validateFlows(projectDir) {
|
|
|
6343
6311
|
// instant a regular Block's act() calls a navigation method; this command
|
|
6344
6312
|
// sweeps a whole project in one shot for contexts with no editor watching
|
|
6345
6313
|
// (CI, an autonomous agent writing Block files without a language server).
|
|
6346
|
-
// See openspec/
|
|
6314
|
+
// See openspec/specs/nav-block-and-check/spec.md for the full rationale.
|
|
6347
6315
|
// ---------------------------------------------------------------------------
|
|
6348
6316
|
function discoverBlocks(projectDir) {
|
|
6349
6317
|
return walkDir(projectDir, /\.block\.ts$/);
|
|
@@ -6362,6 +6330,19 @@ function isNavBlockMarked(val) {
|
|
|
6362
6330
|
return val.__waygraphKind === "nav";
|
|
6363
6331
|
}
|
|
6364
6332
|
const NAV_METHOD_CALLS = ["page.goto(", "page.reload(", "page.goBack(", "page.goForward("];
|
|
6333
|
+
/**
|
|
6334
|
+
* Matches a selector-taking Trait factory call whose first argument is a
|
|
6335
|
+
* literal string/template, not an identifier or property access - the exact
|
|
6336
|
+
* shape found repeatedly in hand-written assertion Blocks
|
|
6337
|
+
* (`Trait.visible("#some-id")` instead of `Trait.visible(SomeSel.thing)`).
|
|
6338
|
+
* `Trait.url(...)` is deliberately excluded - it takes a URLPatternInit, never
|
|
6339
|
+
* a DOM selector. Same file-scoped-regex bluntness the nav-escape sweep above
|
|
6340
|
+
* already accepts (see openspec/specs/nav-block-and-check/spec.md) - a known
|
|
6341
|
+
* blind spot on string concatenation/template-built selectors, not solved
|
|
6342
|
+
* here for the same "recipe before promotion" reason that check accepts its
|
|
6343
|
+
* own shared-helper blind spot.
|
|
6344
|
+
*/
|
|
6345
|
+
const INLINE_SELECTOR_CALL = /\b(?:Trait\.visible|Trait\.text|textEquals|visible)\(\s*["'`]/;
|
|
6365
6346
|
/**
|
|
6366
6347
|
* Walks every `*.block.ts` file under `projectDir`, imports each to find its
|
|
6367
6348
|
* exported Blocks, and for any Block NOT built via `defineNavBlock`, scans
|
|
@@ -6457,7 +6438,8 @@ function initCommand(projectName) {
|
|
|
6457
6438
|
}
|
|
6458
6439
|
async function checkCommand(projectDir) {
|
|
6459
6440
|
const files = discoverBlocks(projectDir);
|
|
6460
|
-
const
|
|
6441
|
+
const navWarnings = [];
|
|
6442
|
+
const selWarnings = [];
|
|
6461
6443
|
for (const file of files) {
|
|
6462
6444
|
let mod;
|
|
6463
6445
|
try {
|
|
@@ -6470,15 +6452,21 @@ async function checkCommand(projectDir) {
|
|
|
6470
6452
|
for (const [exportName, exported] of Object.entries(mod)) {
|
|
6471
6453
|
if (!isBlockLike(exported))
|
|
6472
6454
|
continue;
|
|
6473
|
-
if (isNavBlockMarked(exported))
|
|
6474
|
-
continue;
|
|
6475
6455
|
src ??= readFileSync(file, "utf-8");
|
|
6476
|
-
|
|
6477
|
-
|
|
6456
|
+
// Nav-escape: NavBlocks are exempt (their generated act() is the one
|
|
6457
|
+
// legitimate goto/click call site).
|
|
6458
|
+
if (!isNavBlockMarked(exported) &&
|
|
6459
|
+
NAV_METHOD_CALLS.some((needle) => src.includes(needle))) {
|
|
6460
|
+
navWarnings.push({ file, blockName: exported.name, exportName });
|
|
6461
|
+
}
|
|
6462
|
+
// Inline selector: applies to every Block kind, including NavBlocks -
|
|
6463
|
+
// a Nav's own `verify` array is just as likely to inline a selector.
|
|
6464
|
+
if (INLINE_SELECTOR_CALL.test(src)) {
|
|
6465
|
+
selWarnings.push({ file, blockName: exported.name, exportName });
|
|
6478
6466
|
}
|
|
6479
6467
|
}
|
|
6480
6468
|
}
|
|
6481
|
-
return
|
|
6469
|
+
return { navWarnings, selWarnings };
|
|
6482
6470
|
}
|
|
6483
6471
|
function takeFlagValue(argv, i, a, flag) {
|
|
6484
6472
|
if (a.startsWith(flag + "=")) {
|
|
@@ -6560,6 +6548,9 @@ function parseRunFlags(argv) {
|
|
|
6560
6548
|
else if (a === "--cli") {
|
|
6561
6549
|
out.cli = true;
|
|
6562
6550
|
}
|
|
6551
|
+
else if (a === "--detach") {
|
|
6552
|
+
out.detach = true;
|
|
6553
|
+
}
|
|
6563
6554
|
else if (a === "--headed") {
|
|
6564
6555
|
out.headed = true;
|
|
6565
6556
|
}
|
|
@@ -6881,9 +6872,81 @@ function usage() {
|
|
|
6881
6872
|
Primary (less is more):
|
|
6882
6873
|
waygraph auto [project|.flow.ts] Interactive explore (picker)
|
|
6883
6874
|
--cli Terminal menu instead of browser panel
|
|
6875
|
+
--cli --detach Run the --cli session as a background socket
|
|
6876
|
+
server; prints {sessionId, socketPath} and exits
|
|
6884
6877
|
--blocks <From> <To> Graph path-find From->To, then run
|
|
6885
6878
|
--data '{...}' Mem seed (same as demo/run)
|
|
6886
6879
|
(pass a .flow.ts to run that flow - same as run)
|
|
6880
|
+
--cli --detach --non-headless Detached session with a real visible browser
|
|
6881
|
+
(same --non-headless flag run/demo already use)
|
|
6882
|
+
waygraph auto send <sessionId> "<pick>" Send one pick to a --detach session, print
|
|
6883
|
+
the resulting state as JSON (no TTY needed)
|
|
6884
|
+
--timeout <ms> Override the 15s default wait for this one call -
|
|
6885
|
+
a single Block can legitimately run a slow real
|
|
6886
|
+
interaction (e.g. a multi-step mouse drag)
|
|
6887
|
+
waygraph auto status <sessionId> Read a --detach session's state (no side effects)
|
|
6888
|
+
waygraph auto attach <sessionId> Reopen an interactive terminal against a
|
|
6889
|
+
running --detach session
|
|
6890
|
+
waygraph auto dom <sessionId> Read the live page's structure (no side effects)
|
|
6891
|
+
--mode aria|full Default aria (Playwright ariaSnapshotJSON, AI mode);
|
|
6892
|
+
full = bounded raw DOM walk (tag/attrs/text/children)
|
|
6893
|
+
--selector <sel> Scope either mode to one element's subtree
|
|
6894
|
+
--depth N Limit snapshot depth (aria: native; full: caller cap)
|
|
6895
|
+
waygraph auto trace <sessionId> Read the session's Checkpoint/Block-level history
|
|
6896
|
+
(no side effects; not raw click/fill recording)
|
|
6897
|
+
waygraph auto console <sessionId> Read the real browser console/pageerror messages and
|
|
6898
|
+
failed (4xx/5xx) network responses seen so far - for
|
|
6899
|
+
diagnosing a silent failure (e.g. a form submit that
|
|
6900
|
+
does nothing observable in the DOM) that inspectDom
|
|
6901
|
+
alone can't explain, since it only reads what actually
|
|
6902
|
+
rendered, not what the page/network actually said
|
|
6903
|
+
waygraph auto storage <sessionId> Read localStorage/sessionStorage plus registered
|
|
6904
|
+
service workers (scope/active URL/state) - client-
|
|
6905
|
+
side state (push-subscription/auth tokens etc.) that
|
|
6906
|
+
never appears in the rendered DOM inspectDom reads
|
|
6907
|
+
waygraph auto click <sessionId> <sel> Click a real element - works even with zero Blocks
|
|
6908
|
+
(Blind Pilot: act before any Block covers this)
|
|
6909
|
+
waygraph auto type <sessionId> <sel> <text> Fill a real input the same way
|
|
6910
|
+
waygraph auto goto <sessionId> <url> Navigate the real live page
|
|
6911
|
+
waygraph auto press <sessionId> <sel> <key>
|
|
6912
|
+
Presses a real key (Playwright name, e.g. Enter,
|
|
6913
|
+
Escape, Tab) on a real focused element - many real
|
|
6914
|
+
inline-edit inputs (no visible Save button until you
|
|
6915
|
+
type) commit on Enter, not blur/click-elsewhere
|
|
6916
|
+
waygraph auto upload <sessionId> <sel> <image|pdf|video|path>
|
|
6917
|
+
Fill a real <input type="file"> - a built-in stub
|
|
6918
|
+
(small, real, valid: assets/stubs/stub.png|pdf|mp4)
|
|
6919
|
+
or a caller-supplied file path
|
|
6920
|
+
(click/type/goto/upload each re-detect the session's Checkpoint afterward,
|
|
6921
|
+
same detection send/status already use)
|
|
6922
|
+
waygraph auto reload <sessionId> Re-discover the project's Block library/graph
|
|
6923
|
+
from disk without restarting the session - picks
|
|
6924
|
+
up a Block written to disk mid-session
|
|
6925
|
+
waygraph auto reach <sessionId> <Checkpoint> Path-find from here to Checkpoint and run
|
|
6926
|
+
the whole route in one call - not one auto send
|
|
6927
|
+
per step. Same findBlockPath BFS auto --blocks
|
|
6928
|
+
<From> <To> already uses, against this session's
|
|
6929
|
+
own live graph/position. Fails loud (not a guess)
|
|
6930
|
+
if a step has several live options on the page
|
|
6931
|
+
(an instanceOptions Block) - use send for that step
|
|
6932
|
+
waygraph auto resync <sessionId> Force here to be re-detected from the real live
|
|
6933
|
+
page right now, discarding whatever was cached -
|
|
6934
|
+
fixes a session's tracked position going stale
|
|
6935
|
+
after anything OUTSIDE this session changed the
|
|
6936
|
+
page (e.g. a human clicking around in a visible
|
|
6937
|
+
--non-headless session someone is co-driving);
|
|
6938
|
+
send/reach never do this on their own, since they
|
|
6939
|
+
only re-detect when the position is already unknown
|
|
6940
|
+
waygraph pilot start Bootstrap for an agent: starts a --detach session
|
|
6941
|
+
(same as auto --cli --detach) AND reads back the
|
|
6942
|
+
whole project's Block graph (same as waygraph
|
|
6943
|
+
graph) in one call - {sessionId, socketPath,
|
|
6944
|
+
headless, graph, snapshot}. Drive it afterward with
|
|
6945
|
+
auto send/status/dom/trace <sessionId> - pilot start
|
|
6946
|
+
does not resolve, narrate, or act on anything itself;
|
|
6947
|
+
planning a multi-step request is the agent's job.
|
|
6948
|
+
--non-headless Real visible browser (same flag as auto/demo/run)
|
|
6949
|
+
--base-url / --data Same as auto/demo/run
|
|
6887
6950
|
waygraph demo [--blocks <flow|file|spec>] Watch with step overlay (QA path)
|
|
6888
6951
|
--data '{...}' Mem seed JSON (or inline flow({...}))
|
|
6889
6952
|
--auto-next Auto-advance steps (alias: --autoplay)
|
|
@@ -7311,6 +7374,233 @@ Agents shipped: waygraph-planner, waygraph-author, waygraph-healer.
|
|
|
7311
7374
|
}
|
|
7312
7375
|
case "graph":
|
|
7313
7376
|
case "auto": {
|
|
7377
|
+
// auto send|status|attach <sessionId> - session control against a
|
|
7378
|
+
// --detach'd background session. Intercepted before the normal
|
|
7379
|
+
// project-directory resolution below, same pattern `try demo|auto|
|
|
7380
|
+
// auto:cli` already uses for a sub-verb positional.
|
|
7381
|
+
if (command === "auto" &&
|
|
7382
|
+
(args[1] === "send" ||
|
|
7383
|
+
args[1] === "status" ||
|
|
7384
|
+
args[1] === "attach" ||
|
|
7385
|
+
args[1] === "dom" ||
|
|
7386
|
+
args[1] === "trace" ||
|
|
7387
|
+
args[1] === "console" ||
|
|
7388
|
+
args[1] === "storage" ||
|
|
7389
|
+
args[1] === "upload" ||
|
|
7390
|
+
args[1] === "click" ||
|
|
7391
|
+
args[1] === "type" ||
|
|
7392
|
+
args[1] === "press" ||
|
|
7393
|
+
args[1] === "goto" ||
|
|
7394
|
+
args[1] === "reload" ||
|
|
7395
|
+
args[1] === "reach" ||
|
|
7396
|
+
args[1] === "resync")) {
|
|
7397
|
+
const sub = args[1];
|
|
7398
|
+
const sessionId = args[2];
|
|
7399
|
+
if (!sessionId) {
|
|
7400
|
+
console.error(`waygraph auto ${sub}: missing <sessionId>`);
|
|
7401
|
+
process.exit(1);
|
|
7402
|
+
}
|
|
7403
|
+
const proj = resolve(process.cwd());
|
|
7404
|
+
if (sub === "attach") {
|
|
7405
|
+
await runAttachLoop(proj, sessionId);
|
|
7406
|
+
break;
|
|
7407
|
+
}
|
|
7408
|
+
if (sub === "send") {
|
|
7409
|
+
const pick = args[3];
|
|
7410
|
+
if (pick === undefined) {
|
|
7411
|
+
console.error('waygraph auto send: usage: waygraph auto send <sessionId> "<pick>" [--timeout <ms>]');
|
|
7412
|
+
process.exit(1);
|
|
7413
|
+
}
|
|
7414
|
+
// Real, direct need found live: a single Block can legitimately
|
|
7415
|
+
// run a genuinely slow real interaction (e.g. a multi-step mouse
|
|
7416
|
+
// drag) that exceeds the 15s default - same reasoning `auto
|
|
7417
|
+
// reach` already gets a 90s default for (multiple Blocks in one
|
|
7418
|
+
// call). Unlike reach, send has no way to know ahead of time
|
|
7419
|
+
// whether the ONE Block it's running is fast or slow, so this is
|
|
7420
|
+
// opt-in via a flag rather than a raised default.
|
|
7421
|
+
let timeoutMs;
|
|
7422
|
+
for (let i = 4; i < args.length; i++) {
|
|
7423
|
+
if (args[i] === "--timeout") {
|
|
7424
|
+
const raw = args[++i];
|
|
7425
|
+
const n = Number(raw);
|
|
7426
|
+
if (!Number.isFinite(n) || n <= 0) {
|
|
7427
|
+
console.error(`waygraph auto send: --timeout must be a positive number of ms, got "${raw}"`);
|
|
7428
|
+
process.exit(1);
|
|
7429
|
+
}
|
|
7430
|
+
timeoutMs = n;
|
|
7431
|
+
}
|
|
7432
|
+
}
|
|
7433
|
+
const res = await requestSession(proj, sessionId, { op: "send", pick }, timeoutMs);
|
|
7434
|
+
console.log(JSON.stringify(res));
|
|
7435
|
+
if (!res.ok)
|
|
7436
|
+
process.exitCode = 1;
|
|
7437
|
+
break;
|
|
7438
|
+
}
|
|
7439
|
+
if (sub === "dom") {
|
|
7440
|
+
const domArgs = args.slice(3);
|
|
7441
|
+
let mode;
|
|
7442
|
+
let selector;
|
|
7443
|
+
let depth;
|
|
7444
|
+
for (let i = 0; i < domArgs.length; i++) {
|
|
7445
|
+
const a = domArgs[i];
|
|
7446
|
+
if (a === "--mode" || a.startsWith("--mode=")) {
|
|
7447
|
+
const v = a.startsWith("--mode=") ? a.slice("--mode=".length) : domArgs[++i];
|
|
7448
|
+
if (v !== "aria" && v !== "full") {
|
|
7449
|
+
console.error(`waygraph auto dom: --mode must be "aria" or "full", got "${v}"`);
|
|
7450
|
+
process.exit(1);
|
|
7451
|
+
}
|
|
7452
|
+
mode = v;
|
|
7453
|
+
}
|
|
7454
|
+
else if (a === "--selector" || a.startsWith("--selector=")) {
|
|
7455
|
+
selector = a.startsWith("--selector=") ? a.slice("--selector=".length) : domArgs[++i];
|
|
7456
|
+
}
|
|
7457
|
+
else if (a === "--depth" || a.startsWith("--depth=")) {
|
|
7458
|
+
const raw = a.startsWith("--depth=") ? a.slice("--depth=".length) : domArgs[++i];
|
|
7459
|
+
const n = Number(raw);
|
|
7460
|
+
if (!Number.isInteger(n) || n < 1) {
|
|
7461
|
+
console.error(`waygraph auto dom: --depth must be a positive integer, got "${raw}"`);
|
|
7462
|
+
process.exit(1);
|
|
7463
|
+
}
|
|
7464
|
+
depth = n;
|
|
7465
|
+
}
|
|
7466
|
+
else {
|
|
7467
|
+
console.error(`waygraph auto dom: unrecognized argument "${a}"`);
|
|
7468
|
+
process.exit(1);
|
|
7469
|
+
}
|
|
7470
|
+
}
|
|
7471
|
+
const res = await requestSession(proj, sessionId, {
|
|
7472
|
+
op: "dom",
|
|
7473
|
+
...(mode ? { mode } : {}),
|
|
7474
|
+
...(selector ? { selector } : {}),
|
|
7475
|
+
...(depth !== undefined ? { depth } : {}),
|
|
7476
|
+
});
|
|
7477
|
+
console.log(JSON.stringify(res));
|
|
7478
|
+
if (!res.ok)
|
|
7479
|
+
process.exitCode = 1;
|
|
7480
|
+
break;
|
|
7481
|
+
}
|
|
7482
|
+
if (sub === "trace") {
|
|
7483
|
+
const res = await requestSession(proj, sessionId, { op: "trace" });
|
|
7484
|
+
console.log(JSON.stringify(res));
|
|
7485
|
+
if (!res.ok)
|
|
7486
|
+
process.exitCode = 1;
|
|
7487
|
+
break;
|
|
7488
|
+
}
|
|
7489
|
+
if (sub === "console") {
|
|
7490
|
+
const res = await requestSession(proj, sessionId, { op: "console" });
|
|
7491
|
+
console.log(JSON.stringify(res));
|
|
7492
|
+
if (!res.ok)
|
|
7493
|
+
process.exitCode = 1;
|
|
7494
|
+
break;
|
|
7495
|
+
}
|
|
7496
|
+
if (sub === "storage") {
|
|
7497
|
+
const res = await requestSession(proj, sessionId, { op: "storage" });
|
|
7498
|
+
console.log(JSON.stringify(res));
|
|
7499
|
+
if (!res.ok)
|
|
7500
|
+
process.exitCode = 1;
|
|
7501
|
+
break;
|
|
7502
|
+
}
|
|
7503
|
+
if (sub === "click") {
|
|
7504
|
+
const selector = args[3];
|
|
7505
|
+
if (selector === undefined) {
|
|
7506
|
+
console.error('waygraph auto click: usage: waygraph auto click <sessionId> "<selector>"');
|
|
7507
|
+
process.exit(1);
|
|
7508
|
+
}
|
|
7509
|
+
const res = await requestSession(proj, sessionId, { op: "click", selector });
|
|
7510
|
+
console.log(JSON.stringify(res));
|
|
7511
|
+
if (!res.ok)
|
|
7512
|
+
process.exitCode = 1;
|
|
7513
|
+
break;
|
|
7514
|
+
}
|
|
7515
|
+
if (sub === "type") {
|
|
7516
|
+
const selector = args[3];
|
|
7517
|
+
const text = args[4];
|
|
7518
|
+
if (selector === undefined || text === undefined) {
|
|
7519
|
+
console.error('waygraph auto type: usage: waygraph auto type <sessionId> "<selector>" "<text>"');
|
|
7520
|
+
process.exit(1);
|
|
7521
|
+
}
|
|
7522
|
+
const res = await requestSession(proj, sessionId, { op: "type", selector, text });
|
|
7523
|
+
console.log(JSON.stringify(res));
|
|
7524
|
+
if (!res.ok)
|
|
7525
|
+
process.exitCode = 1;
|
|
7526
|
+
break;
|
|
7527
|
+
}
|
|
7528
|
+
if (sub === "press") {
|
|
7529
|
+
const selector = args[3];
|
|
7530
|
+
const key = args[4];
|
|
7531
|
+
if (selector === undefined || key === undefined) {
|
|
7532
|
+
console.error('waygraph auto press: usage: waygraph auto press <sessionId> "<selector>" <key>');
|
|
7533
|
+
process.exit(1);
|
|
7534
|
+
}
|
|
7535
|
+
const res = await requestSession(proj, sessionId, { op: "press", selector, key });
|
|
7536
|
+
console.log(JSON.stringify(res));
|
|
7537
|
+
if (!res.ok)
|
|
7538
|
+
process.exitCode = 1;
|
|
7539
|
+
break;
|
|
7540
|
+
}
|
|
7541
|
+
if (sub === "goto") {
|
|
7542
|
+
const url = args[3];
|
|
7543
|
+
if (url === undefined) {
|
|
7544
|
+
console.error("waygraph auto goto: usage: waygraph auto goto <sessionId> <url>");
|
|
7545
|
+
process.exit(1);
|
|
7546
|
+
}
|
|
7547
|
+
const res = await requestSession(proj, sessionId, { op: "goto", url });
|
|
7548
|
+
console.log(JSON.stringify(res));
|
|
7549
|
+
if (!res.ok)
|
|
7550
|
+
process.exitCode = 1;
|
|
7551
|
+
break;
|
|
7552
|
+
}
|
|
7553
|
+
if (sub === "upload") {
|
|
7554
|
+
const selector = args[3];
|
|
7555
|
+
const kindOrPath = args[4];
|
|
7556
|
+
if (selector === undefined || kindOrPath === undefined) {
|
|
7557
|
+
console.error('waygraph auto upload: usage: waygraph auto upload <sessionId> "<selector>" <image|pdf|video|path-to-file>');
|
|
7558
|
+
process.exit(1);
|
|
7559
|
+
}
|
|
7560
|
+
const stub = kindOrPath === "image" || kindOrPath === "pdf" || kindOrPath === "video"
|
|
7561
|
+
? { selector, stub: kindOrPath }
|
|
7562
|
+
: { selector, stub: { filePath: resolve(process.cwd(), kindOrPath) } };
|
|
7563
|
+
const res = await requestSession(proj, sessionId, { op: "upload", ...stub });
|
|
7564
|
+
console.log(JSON.stringify(res));
|
|
7565
|
+
if (!res.ok)
|
|
7566
|
+
process.exitCode = 1;
|
|
7567
|
+
break;
|
|
7568
|
+
}
|
|
7569
|
+
if (sub === "reload") {
|
|
7570
|
+
const res = await requestSession(proj, sessionId, { op: "reload" });
|
|
7571
|
+
console.log(JSON.stringify(res));
|
|
7572
|
+
if (!res.ok)
|
|
7573
|
+
process.exitCode = 1;
|
|
7574
|
+
break;
|
|
7575
|
+
}
|
|
7576
|
+
if (sub === "reach") {
|
|
7577
|
+
const checkpoint = args[3];
|
|
7578
|
+
if (checkpoint === undefined) {
|
|
7579
|
+
console.error("waygraph auto reach: usage: waygraph auto reach <sessionId> <Checkpoint>");
|
|
7580
|
+
process.exit(1);
|
|
7581
|
+
}
|
|
7582
|
+
// Longer than every other op's default (15s): a real multi-step
|
|
7583
|
+
// route runs several real Blocks in sequence server-side before
|
|
7584
|
+
// responding - a legitimately slow single request, not a hang.
|
|
7585
|
+
const res = await requestSession(proj, sessionId, { op: "reach", checkpoint }, 90_000);
|
|
7586
|
+
console.log(JSON.stringify(res));
|
|
7587
|
+
if (!res.ok)
|
|
7588
|
+
process.exitCode = 1;
|
|
7589
|
+
break;
|
|
7590
|
+
}
|
|
7591
|
+
if (sub === "resync") {
|
|
7592
|
+
const res = await requestSession(proj, sessionId, { op: "resync" });
|
|
7593
|
+
console.log(JSON.stringify(res));
|
|
7594
|
+
if (!res.ok)
|
|
7595
|
+
process.exitCode = 1;
|
|
7596
|
+
break;
|
|
7597
|
+
}
|
|
7598
|
+
const res = await requestSession(proj, sessionId, { op: "status" });
|
|
7599
|
+
console.log(JSON.stringify(res));
|
|
7600
|
+
if (!res.ok)
|
|
7601
|
+
process.exitCode = 1;
|
|
7602
|
+
break;
|
|
7603
|
+
}
|
|
7314
7604
|
const flags = parseRunFlags(args.slice(1));
|
|
7315
7605
|
applyRunFlags(flags);
|
|
7316
7606
|
const mermaid = flags.mermaid === true;
|
|
@@ -7345,6 +7635,29 @@ Agents shipped: waygraph-planner, waygraph-author, waygraph-healer.
|
|
|
7345
7635
|
" or path-find: waygraph auto --blocks LoginPage OrderComplete");
|
|
7346
7636
|
process.exit(1);
|
|
7347
7637
|
}
|
|
7638
|
+
// auto --cli --detach: start the explore session as a background socket
|
|
7639
|
+
// server instead of blocking in the interactive loop. Session control
|
|
7640
|
+
// only applies to --cli (spec: "Headful mode is unaffected").
|
|
7641
|
+
if (command === "auto" && flags.detach) {
|
|
7642
|
+
if (!cliPicker) {
|
|
7643
|
+
console.error("waygraph auto --detach requires --cli (headful has no session control)");
|
|
7644
|
+
process.exit(1);
|
|
7645
|
+
}
|
|
7646
|
+
const baseURL = flags.baseUrl ?? process.env.WAYGRAPH_BASE_URL ?? resolveBaseUrl(proj);
|
|
7647
|
+
try {
|
|
7648
|
+
const meta = await spawnDetachedSession({
|
|
7649
|
+
projectDir: proj,
|
|
7650
|
+
...(baseURL ? { baseURL } : {}),
|
|
7651
|
+
...(flags.nonHeadless ? { headless: false } : {}),
|
|
7652
|
+
});
|
|
7653
|
+
console.log(JSON.stringify({ sessionId: meta.sessionId, socketPath: meta.socketPath, headless: meta.headless }));
|
|
7654
|
+
}
|
|
7655
|
+
catch (err) {
|
|
7656
|
+
console.error(`waygraph auto --detach: ${err instanceof Error ? err.message : String(err)}`);
|
|
7657
|
+
process.exit(1);
|
|
7658
|
+
}
|
|
7659
|
+
break;
|
|
7660
|
+
}
|
|
7348
7661
|
// auto --blocks From To (graph path-find + run)
|
|
7349
7662
|
// auto --blocks '/regex/' or '**/*.block.ts' (Phase C file select → explore)
|
|
7350
7663
|
if (command === "auto" && (flags.blocksFromTo || flags.blocks)) {
|
|
@@ -7389,6 +7702,49 @@ Agents shipped: waygraph-planner, waygraph-author, waygraph-healer.
|
|
|
7389
7702
|
await runAutoExplore(proj, baseURL ? { cli: cliPicker, baseURL } : { cli: cliPicker });
|
|
7390
7703
|
break;
|
|
7391
7704
|
}
|
|
7705
|
+
case "pilot": {
|
|
7706
|
+
if (args[1] !== "start") {
|
|
7707
|
+
console.error('waygraph pilot: usage: waygraph pilot start [--non-headless] [--base-url <url>] [--data <json>]');
|
|
7708
|
+
process.exit(1);
|
|
7709
|
+
}
|
|
7710
|
+
const flags = parseRunFlags(args.slice(2));
|
|
7711
|
+
applyRunFlags(flags);
|
|
7712
|
+
const proj = resolve(process.cwd());
|
|
7713
|
+
const baseURL = flags.baseUrl ?? process.env.WAYGRAPH_BASE_URL ?? resolveBaseUrl(proj);
|
|
7714
|
+
try {
|
|
7715
|
+
const result = await pilotStart({
|
|
7716
|
+
projectDir: proj,
|
|
7717
|
+
...(baseURL ? { baseURL } : {}),
|
|
7718
|
+
...(flags.nonHeadless ? { headless: false } : {}),
|
|
7719
|
+
});
|
|
7720
|
+
console.log(JSON.stringify(result));
|
|
7721
|
+
}
|
|
7722
|
+
catch (err) {
|
|
7723
|
+
console.error(`waygraph pilot start: ${err instanceof Error ? err.message : String(err)}`);
|
|
7724
|
+
process.exit(1);
|
|
7725
|
+
}
|
|
7726
|
+
break;
|
|
7727
|
+
}
|
|
7728
|
+
// Hidden: the detached server's own entry point, spawned by
|
|
7729
|
+
// `spawnDetachedSession` (auto --cli --detach). Not documented in
|
|
7730
|
+
// usage() - not meant to be invoked directly by a person.
|
|
7731
|
+
case "__auto-serve": {
|
|
7732
|
+
const proj = resolve(args[1] ?? process.cwd());
|
|
7733
|
+
const flags = parseRunFlags(args.slice(2));
|
|
7734
|
+
const sessionIdIdx = args.indexOf("--session-id");
|
|
7735
|
+
const sessionId = sessionIdIdx >= 0 ? args[sessionIdIdx + 1] : undefined;
|
|
7736
|
+
if (!sessionId) {
|
|
7737
|
+
console.error("waygraph __auto-serve: missing --session-id");
|
|
7738
|
+
process.exit(1);
|
|
7739
|
+
}
|
|
7740
|
+
const baseURL = flags.baseUrl ?? process.env.WAYGRAPH_BASE_URL ?? resolveBaseUrl(proj);
|
|
7741
|
+
await runAutoServeCommand({
|
|
7742
|
+
projectDir: proj,
|
|
7743
|
+
...(baseURL ? { baseURL } : {}),
|
|
7744
|
+
...(flags.nonHeadless ? { headless: false } : {}),
|
|
7745
|
+
}, sessionId);
|
|
7746
|
+
break;
|
|
7747
|
+
}
|
|
7392
7748
|
case "try": {
|
|
7393
7749
|
const flags = parseRunFlags(args.slice(1));
|
|
7394
7750
|
applyRunFlags(flags);
|
|
@@ -7418,20 +7774,30 @@ Agents shipped: waygraph-planner, waygraph-author, waygraph-healer.
|
|
|
7418
7774
|
}
|
|
7419
7775
|
case "check": {
|
|
7420
7776
|
const proj = resolve(args[1] ?? process.cwd());
|
|
7421
|
-
const
|
|
7422
|
-
if (
|
|
7777
|
+
const { navWarnings, selWarnings } = await checkCommand(proj);
|
|
7778
|
+
if (navWarnings.length === 0) {
|
|
7423
7779
|
console.log(`waygraph check: no navigation found outside NavBlocks under ${proj}`);
|
|
7424
7780
|
}
|
|
7425
7781
|
else {
|
|
7426
|
-
for (const w of
|
|
7782
|
+
for (const w of navWarnings) {
|
|
7427
7783
|
const rel = relative(proj, w.file);
|
|
7428
7784
|
console.warn(`waygraph check: ${rel} (${w.blockName}) calls page.goto/reload/goBack/goForward outside a NavBlock - consider defineNavBlock instead`);
|
|
7429
7785
|
}
|
|
7430
|
-
console.log(`waygraph check: ${
|
|
7786
|
+
console.log(`waygraph check: ${navWarnings.length} nav warning${navWarnings.length === 1 ? "" : "s"}`);
|
|
7787
|
+
}
|
|
7788
|
+
if (selWarnings.length === 0) {
|
|
7789
|
+
console.log(`waygraph check: no inline selectors found in verify arrays under ${proj}`);
|
|
7790
|
+
}
|
|
7791
|
+
else {
|
|
7792
|
+
for (const w of selWarnings) {
|
|
7793
|
+
const rel = relative(proj, w.file);
|
|
7794
|
+
console.warn(`waygraph check: ${rel} (${w.blockName}) has an inline selector literal in verify - move it into a *Sel object`);
|
|
7795
|
+
}
|
|
7796
|
+
console.log(`waygraph check: ${selWarnings.length} inline-selector warning${selWarnings.length === 1 ? "" : "s"}`);
|
|
7431
7797
|
}
|
|
7432
7798
|
const orphans = await findOrphanBlocks(proj);
|
|
7433
7799
|
printOrphanReport(proj, orphans);
|
|
7434
|
-
//
|
|
7800
|
+
// Warnings only - never fail exit code. Orphans are reported for
|
|
7435
7801
|
// human/agent cleanup; chain auto refuses while any remain.
|
|
7436
7802
|
break;
|
|
7437
7803
|
}
|
package/dist/engine.d.ts
CHANGED
|
@@ -637,7 +637,7 @@ export declare function defineBlock<In extends Checkpoint<string>, Out extends C
|
|
|
637
637
|
* (same shape `DefinedBlock`/`ComposedBlock` already use), so it drops into
|
|
638
638
|
* `defineFlow([...])`, `connect()`, `composeBlock()` exactly like any other
|
|
639
639
|
* Block - no special-casing needed anywhere that only expects a `Block`.
|
|
640
|
-
* See `openspec/
|
|
640
|
+
* See `openspec/specs/nav-block-and-check/spec.md` for why this exists.
|
|
641
641
|
*/
|
|
642
642
|
export type NavBlock<Out extends Checkpoint<string>> = DefinedBlock<Checkpoint<string>, Out>;
|
|
643
643
|
/**
|
|
@@ -742,6 +742,45 @@ export type ActionBlock<In extends Checkpoint<string>, Out extends Checkpoint<st
|
|
|
742
742
|
export declare function defineMethodBlock<In extends Checkpoint<string>, Out extends Checkpoint<string>>(base: Parameters<typeof defineBlock<In, Out>>[0]): MethodBlock<In, Out>;
|
|
743
743
|
/** @deprecated Prefer {@link defineMethodBlock} - identical helper (0.7 name). */
|
|
744
744
|
export declare const defineActionBlock: typeof defineMethodBlock;
|
|
745
|
+
export interface AssertBlockOptions<Out extends Checkpoint<string> = Checkpoint<string>> {
|
|
746
|
+
name: string;
|
|
747
|
+
description?: string;
|
|
748
|
+
/** Self-loop target - the Checkpoint this assertion runs on and returns to. */
|
|
749
|
+
checkpoint: Out["__state"];
|
|
750
|
+
/**
|
|
751
|
+
* Shorthand for the wait-then-assert shape found repeatedly in hand-written
|
|
752
|
+
* assertion Blocks: waits for a heading with this accessible name before
|
|
753
|
+
* `verify` runs. Omit for a pure "assert whatever is already on the page"
|
|
754
|
+
* check with no wait. Not a general `act()` override - a Block that needs
|
|
755
|
+
* more than this stays a plain `defineMethodBlock`.
|
|
756
|
+
*/
|
|
757
|
+
waitForHeading?: string;
|
|
758
|
+
verify: Trait[] | ((out: Out) => Trait[]);
|
|
759
|
+
/** Mem keys this assertion's `verify` reads (e.g. a mem-aware Trait) - checked by preflight before the flow runs. */
|
|
760
|
+
requires?: readonly MemKey<any>[];
|
|
761
|
+
stubBefore?: import("./highlights.js").HighlightStubPhaseOrFn<Out>;
|
|
762
|
+
stubAfter?: import("./highlights.js").HighlightStubPhaseOrFn<Out>;
|
|
763
|
+
stubOnError?: import("./highlights.js").HighlightStubPhaseOrFn<Out>;
|
|
764
|
+
/** Multi-step yap slides (demo only) - same field `Instruction.slides` exposes elsewhere. */
|
|
765
|
+
slides?: import("./highlights.js").WaygraphSlidesOrFn<Out>;
|
|
766
|
+
}
|
|
767
|
+
/**
|
|
768
|
+
* Sugar for a self-loop-only "pure assertion" Block: no hand-written
|
|
769
|
+
* `act`/`resolve`, just a name, a `checkpoint` tag, and a `verify` array.
|
|
770
|
+
* `resolve` is generated from the one `checkpoint` field given, closing the
|
|
771
|
+
* copy/rename footgun where a hand-restated checkpoint string can silently
|
|
772
|
+
* drift wrong across a copy/pasted file. Mirrors `definePageBlock`'s own
|
|
773
|
+
* construction pattern (flat options in, `defineBlock` built internally).
|
|
774
|
+
* See openspec/changes/waygraph-agent-skill-hardening/spec.md.
|
|
775
|
+
* @example
|
|
776
|
+
* defineAssertBlock({
|
|
777
|
+
* name: "assert-raw-materials-table",
|
|
778
|
+
* checkpoint: "RawMaterials",
|
|
779
|
+
* waitForHeading: "Raw Materials & Lead Times",
|
|
780
|
+
* verify: [Trait.visible(RawMaterialsSel.reorderBadge)],
|
|
781
|
+
* });
|
|
782
|
+
*/
|
|
783
|
+
export declare function defineAssertBlock<Out extends Checkpoint<string> = Checkpoint<string>>(options: AssertBlockOptions<Out>): MethodBlock<Out, Out>;
|
|
745
784
|
/** One Block (or lazy factory) registered on a {@link PageBlock}. */
|
|
746
785
|
export type PageMethodEntry = DefinedBlock<any, any> | (() => DefinedBlock<any, any>);
|
|
747
786
|
export type PageBlockOptions<Out extends Checkpoint<string>> = {
|