waygraph 0.15.54 → 0.16.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +8 -3
- package/bin/waygraph +2 -2
- package/dist/analysis/check.d.ts +38 -0
- package/dist/analysis/check.js +87 -0
- package/dist/analysis/coverage-gap.d.ts +1 -1
- package/dist/analysis/coverage-gap.js +14 -37
- package/dist/analysis/flow-source.d.ts +9 -0
- package/dist/analysis/flow-source.js +25 -0
- package/dist/analysis/graph.d.ts +10 -14
- package/dist/analysis/graph.js +48 -371
- package/dist/analysis/map-check.js +4 -39
- package/dist/analysis/practices-check.d.ts +1 -1
- package/dist/analysis/practices-check.js +24 -45
- package/dist/cli/args.d.ts +23 -0
- package/dist/cli/args.js +20 -0
- package/dist/{cli.d.ts → cli/cli.d.ts} +0 -1
- package/dist/{cli.js → cli/cli.js} +10 -9
- package/dist/{commands → cli/commands}/agent-dive-scaffold.js +35 -64
- package/dist/cli/commands/agent-dive.js +42 -0
- package/dist/{commands → cli/commands}/check.d.ts +0 -1
- package/dist/cli/commands/check.js +104 -0
- package/dist/cli/commands/codemod-checkpoints.d.ts +18 -0
- package/dist/cli/commands/codemod-checkpoints.js +186 -0
- package/dist/cli/commands/codemod-flows.d.ts +18 -0
- package/dist/cli/commands/codemod-flows.js +284 -0
- package/dist/cli/commands/codemod-stubs.d.ts +10 -0
- package/dist/cli/commands/codemod-stubs.js +187 -0
- package/dist/{commands → cli/commands}/extensions.js +5 -4
- package/dist/{commands → cli/commands}/init.js +1 -2
- package/dist/{commands → cli/commands}/list.js +9 -7
- package/dist/cli/commands/manifest.d.ts +2 -0
- package/dist/cli/commands/manifest.js +20 -0
- package/dist/cli/commands/map.js +57 -0
- package/dist/{commands → cli/commands}/run.d.ts +0 -1
- package/dist/cli/commands/run.js +64 -0
- package/dist/{commands → cli/commands}/session.js +61 -88
- package/dist/{commands → cli/commands}/test.js +11 -14
- package/dist/cli/commands/traverse.js +105 -0
- package/dist/{commands → cli/commands}/try.js +29 -25
- package/dist/{commands → cli/commands}/upgrade.js +40 -4
- package/dist/cli/flags.d.ts +193 -16
- package/dist/cli/flags.js +179 -234
- package/dist/cli/run-chain.d.ts +1 -0
- package/dist/cli/run-chain.js +42 -7
- package/dist/cli/usage.d.ts +1 -1
- package/dist/cli/usage.js +21 -53
- package/dist/cli/util.d.ts +2 -2
- package/dist/cli/util.js +2 -3
- package/dist/{highlights → demo/narration}/css.d.ts +1 -1
- package/dist/{highlights → demo/narration}/css.js +2 -3
- package/dist/{highlights → demo/narration}/demo-pace.d.ts +3 -11
- package/dist/{highlights → demo/narration}/demo-pace.js +5 -11
- package/dist/{highlights → demo/narration}/device.d.ts +2 -2
- package/dist/{highlights → demo/narration}/device.js +1 -1
- package/dist/demo/narration/merge.d.ts +8 -0
- package/dist/demo/narration/merge.js +71 -0
- package/dist/{highlights/run-phase.d.ts → demo/narration/narration.d.ts} +10 -14
- package/dist/{highlights/run-phase.js → demo/narration/narration.js} +25 -94
- package/dist/{highlights → demo/narration}/shorthand.d.ts +1 -1
- package/dist/demo/narration/stub-ctx.d.ts +8 -0
- package/dist/demo/narration/stub-ctx.js +164 -0
- package/dist/{highlights → demo/narration}/style.d.ts +1 -7
- package/dist/{highlights → demo/narration}/style.js +1 -41
- package/dist/{highlights → demo/narration}/todo-dock.d.ts +3 -3
- package/dist/{highlights → demo/narration}/todo-dock.js +13 -30
- package/dist/demo/overlay/auto-chrome.d.ts +7 -0
- package/dist/demo/overlay/auto-chrome.js +97 -0
- package/dist/demo/overlay/cursor.d.ts +12 -0
- package/dist/demo/overlay/cursor.js +142 -0
- package/dist/demo/overlay/device-stage.d.ts +13 -0
- package/dist/demo/overlay/device-stage.js +396 -0
- package/dist/demo/overlay/inpage/banner.d.ts +1 -0
- package/dist/demo/overlay/inpage/banner.js +160 -0
- package/dist/demo/overlay/inpage/caption.d.ts +2 -0
- package/dist/demo/overlay/inpage/caption.js +24 -0
- package/dist/demo/overlay/inpage/core.d.ts +1 -0
- package/dist/demo/overlay/inpage/core.js +345 -0
- package/dist/demo/overlay/inpage/device-chip.d.ts +1 -0
- package/dist/demo/overlay/inpage/device-chip.js +191 -0
- package/dist/demo/overlay/inpage/network.d.ts +9 -0
- package/dist/demo/overlay/inpage/network.js +200 -0
- package/dist/demo/overlay/inpage/panel-chrome.d.ts +1 -0
- package/dist/demo/overlay/inpage/panel-chrome.js +203 -0
- package/dist/demo/overlay/inpage/stamp.d.ts +1 -0
- package/dist/demo/overlay/inpage/stamp.js +46 -0
- package/dist/demo/overlay/inpage/swipe-zoom.d.ts +1 -0
- package/dist/demo/overlay/inpage/swipe-zoom.js +220 -0
- package/dist/demo/overlay/inpage/todos.d.ts +1 -0
- package/dist/demo/overlay/inpage/todos.js +294 -0
- package/dist/demo/overlay/locator-theater.d.ts +25 -0
- package/dist/demo/overlay/locator-theater.js +76 -0
- package/dist/demo/overlay/network-capture.d.ts +22 -0
- package/dist/demo/overlay/network-capture.js +127 -0
- package/dist/demo/overlay/overlay-css.d.ts +3 -0
- package/dist/demo/overlay/overlay-css.js +369 -0
- package/dist/demo/overlay/overlay-stage.d.ts +23 -0
- package/dist/demo/overlay/overlay-stage.js +106 -0
- package/dist/demo/overlay/overlay.d.ts +10 -0
- package/dist/demo/overlay/overlay.js +89 -0
- package/dist/{pilot-overlay/overlay-fixtures.d.ts → demo/overlay/phase-fixtures.d.ts} +2 -2
- package/dist/{pilot-overlay/overlay-fixtures.js → demo/overlay/phase-fixtures.js} +2 -2
- package/dist/{pilot-overlay/action-ring.js → demo/overlay/pilot/actions.js} +2 -1
- package/dist/{pilot-overlay → demo/overlay/pilot}/fixtures.d.ts +6 -5
- package/dist/{pilot-overlay → demo/overlay/pilot}/fixtures.js +19 -18
- package/dist/{pilot-overlay → demo/overlay/pilot}/shell.d.ts +2 -2
- package/dist/{pilot-overlay → demo/overlay/pilot}/shell.js +13 -22
- package/dist/demo/overlay/reattach.d.ts +7 -0
- package/dist/demo/overlay/reattach.js +23 -0
- package/dist/demo/overlay/rings.d.ts +33 -0
- package/dist/demo/overlay/rings.js +448 -0
- package/dist/{ui → demo/overlay/ui}/components/ring.js +2 -2
- package/dist/{ui → demo/overlay/ui}/overlay.css +4 -4
- package/dist/{ui → demo/overlay/ui}/shadow.d.ts +1 -1
- package/dist/{ui → demo/overlay/ui}/shadow.js +39 -2
- package/dist/demo/stepper/after.d.ts +3 -0
- package/dist/demo/stepper/after.js +113 -0
- package/dist/demo/stepper/banner-log.d.ts +37 -0
- package/dist/demo/stepper/banner-log.js +63 -0
- package/dist/demo/stepper/before.d.ts +4 -0
- package/dist/demo/stepper/before.js +110 -0
- package/dist/demo/stepper/demo-log.d.ts +31 -0
- package/dist/demo/stepper/demo-log.js +309 -0
- package/dist/demo/stepper/gate.d.ts +11 -0
- package/dist/demo/stepper/gate.js +78 -0
- package/dist/demo/stepper/interaction-patch.d.ts +3 -0
- package/dist/demo/stepper/interaction-patch.js +323 -0
- package/dist/demo/stepper/pacing.d.ts +21 -0
- package/dist/demo/stepper/pacing.js +23 -0
- package/dist/demo/stepper/slides.d.ts +11 -0
- package/dist/demo/stepper/slides.js +233 -0
- package/dist/demo/stepper/step-panels.d.ts +21 -0
- package/dist/demo/stepper/step-panels.js +589 -0
- package/dist/demo/stepper/stepper.d.ts +24 -0
- package/dist/demo/stepper/stepper.js +122 -0
- package/dist/demo/stepper/teardown.d.ts +48 -0
- package/dist/demo/stepper/teardown.js +179 -0
- package/dist/demo/stepper/todo-advance.d.ts +14 -0
- package/dist/demo/stepper/todo-advance.js +110 -0
- package/dist/demo/stepper/view.d.ts +68 -0
- package/dist/demo/stepper/view.js +31 -0
- package/dist/demo/types.d.ts +17 -0
- package/dist/demo/verbose-log.js +15 -0
- package/dist/{types.d.ts → engine/block/block.d.ts} +106 -91
- package/dist/{core → engine/block}/block.js +10 -53
- package/dist/{core → engine/block}/compose.d.ts +9 -7
- package/dist/{core → engine/block}/compose.js +1 -1
- package/dist/{core/blocks → engine/block/kinds}/api.d.ts +16 -12
- package/dist/{core/blocks → engine/block/kinds}/api.js +26 -18
- package/dist/{core/blocks → engine/block/kinds}/effect.d.ts +13 -18
- package/dist/engine/block/kinds/effect.js +17 -0
- package/dist/{core/blocks → engine/block/kinds}/method.d.ts +17 -29
- package/dist/{core/blocks → engine/block/kinds}/method.js +6 -21
- package/dist/{core/blocks → engine/block/kinds}/nav.d.ts +21 -31
- package/dist/{core/blocks → engine/block/kinds}/nav.js +6 -12
- package/dist/{core/blocks → engine/block/kinds}/page.d.ts +14 -20
- package/dist/{core/blocks → engine/block/kinds}/page.js +5 -7
- package/dist/engine/checkpoint/checkpoint.d.ts +22 -0
- package/dist/engine/checkpoint/checkpoint.js +8 -0
- package/dist/engine/checkpoint/route.d.ts +28 -0
- package/dist/engine/checkpoint/route.js +28 -0
- package/dist/{core → engine}/config.d.ts +7 -2
- package/dist/engine/config.js +6 -0
- package/dist/engine/engine.d.ts +45 -0
- package/dist/{core → engine}/engine.js +6 -10
- package/dist/engine/env.d.ts +59 -0
- package/dist/engine/env.js +83 -0
- package/dist/{errors.d.ts → engine/errors.d.ts} +22 -22
- package/dist/{errors.js → engine/errors.js} +22 -22
- package/dist/{core → engine/flow}/branch-regression.d.ts +7 -7
- package/dist/{core → engine/flow}/branch-regression.js +4 -3
- package/dist/engine/flow/flow.d.ts +162 -0
- package/dist/engine/flow/flow.js +244 -0
- package/dist/{core → engine/flow}/map-builder.d.ts +34 -39
- package/dist/{core → engine/flow}/map-builder.js +45 -47
- package/dist/{core → engine}/locate.d.ts +1 -1
- package/dist/{core → engine}/locate.js +1 -2
- package/dist/{mem-stub.d.ts → engine/mem/mem-stub.d.ts} +9 -8
- package/dist/{mem-stub.js → engine/mem/mem-stub.js} +2 -2
- package/dist/{mem-page.d.ts → engine/mem/mem.d.ts} +1 -1
- package/dist/{mem-page.js → engine/mem/mem.js} +2 -1
- package/dist/engine/page-gone.d.ts +5 -0
- package/dist/engine/page-gone.js +20 -0
- package/dist/engine/run/connect.d.ts +28 -0
- package/dist/{types.js → engine/run/connect.js} +11 -10
- package/dist/engine/run/events.d.ts +67 -0
- package/dist/engine/run/events.js +90 -0
- package/dist/engine/run/hooks.d.ts +16 -0
- package/dist/engine/run/hooks.js +8 -0
- package/dist/engine/run/launch.d.ts +13 -0
- package/dist/engine/run/launch.js +27 -0
- package/dist/{core/run-graph.d.ts → engine/run/run.d.ts} +8 -12
- package/dist/{core/run-graph.js → engine/run/run.js} +22 -12
- package/dist/engine/stub/pace.d.ts +12 -0
- package/dist/engine/stub/pace.js +2 -0
- package/dist/engine/stub/ring.d.ts +130 -0
- package/dist/engine/stub/ring.js +41 -0
- package/dist/engine/stub/stub.d.ts +268 -0
- package/dist/engine/stub/stub.js +1 -0
- package/dist/engine/stub/todos.d.ts +104 -0
- package/dist/engine/stub/todos.js +2 -0
- package/dist/engine/stub/viewport.d.ts +26 -0
- package/dist/engine/stub/viewport.js +2 -0
- package/dist/{trait.d.ts → engine/trait/trait.d.ts} +1 -1
- package/dist/index.d.ts +84 -36
- package/dist/index.js +44 -19
- package/dist/{session/auto-explore-run.d.ts → live/auto/auto.d.ts} +10 -16
- package/dist/{session/auto-explore-run.js → live/auto/auto.js} +164 -254
- package/dist/{session/auto-explore.d.ts → live/auto/explore.d.ts} +4 -14
- package/dist/{session/auto-explore.js → live/auto/explore.js} +21 -127
- package/dist/{auto-session/session.d.ts → live/auto-session/auto-session.d.ts} +1 -1
- package/dist/{auto-session/session.js → live/auto-session/auto-session.js} +27 -24
- package/dist/{auto-session → live/auto-session}/helpers.d.ts +6 -5
- package/dist/{auto-session → live/auto-session}/helpers.js +1 -1
- package/dist/{session/auto-session-ipc.d.ts → live/auto-session/ipc.d.ts} +7 -5
- package/dist/{session/auto-session-ipc.js → live/auto-session/ipc.js} +31 -16
- package/dist/{session/browser.d.ts → live/auto-session/start.d.ts} +1 -2
- package/dist/{session/browser.js → live/auto-session/start.js} +2 -3
- package/dist/{pilot-overlay → live/pilot}/panel.d.ts +1 -1
- package/dist/{pilot-overlay → live/pilot}/panel.js +23 -31
- package/dist/{session → live/pilot}/pilot.d.ts +3 -3
- package/dist/{session → live/pilot}/pilot.js +4 -4
- package/dist/{traverse/run.d.ts → live/traverse/traverse.d.ts} +1 -1
- package/dist/{traverse/run.js → live/traverse/traverse.js} +26 -43
- package/dist/manifest/manifest.d.ts +52 -0
- package/dist/manifest/manifest.js +93 -0
- package/dist/manifest/map-imports.d.ts +7 -0
- package/dist/manifest/map-imports.js +22 -0
- package/dist/manifest/maps.d.ts +33 -0
- package/dist/manifest/maps.js +62 -0
- package/dist/manifest/pack.d.ts +21 -0
- package/dist/manifest/pack.js +109 -0
- package/dist/manifest/project.d.ts +60 -0
- package/dist/manifest/project.js +101 -0
- package/dist/{session/block-inject.js → manifest/roots.js} +1 -18
- package/dist/manifest/scan.d.ts +19 -0
- package/dist/manifest/scan.js +57 -0
- package/dist/manifest/source.d.ts +23 -0
- package/dist/manifest/source.js +86 -0
- package/dist/runner/mode.d.ts +71 -0
- package/dist/runner/mode.js +1 -0
- package/dist/runner/modes/branches.d.ts +5 -0
- package/dist/runner/modes/branches.js +37 -0
- package/dist/runner/modes/demo.d.ts +3 -0
- package/dist/runner/modes/demo.js +13 -0
- package/dist/runner/modes/report.d.ts +2 -0
- package/dist/runner/modes/report.js +54 -0
- package/dist/runner/modes/run.d.ts +2 -0
- package/dist/runner/modes/run.js +3 -0
- package/dist/runner/options.d.ts +31 -0
- package/dist/runner/options.js +42 -0
- package/dist/runner/plan/find.d.ts +18 -0
- package/dist/runner/plan/find.js +65 -0
- package/dist/runner/plan/plan.d.ts +11 -0
- package/dist/runner/plan/plan.js +97 -0
- package/dist/runner/plan/seed-mem.d.ts +12 -0
- package/dist/runner/plan/seed-mem.js +98 -0
- package/dist/runner/plan/spec.d.ts +5 -0
- package/dist/runner/plan/spec.js +17 -0
- package/dist/runner/play-steps.d.ts +2 -0
- package/dist/runner/play-steps.js +59 -0
- package/dist/runner/runner.d.ts +4 -0
- package/dist/runner/runner.js +64 -0
- package/dist/runner/session.d.ts +9 -0
- package/dist/runner/session.js +87 -0
- package/dist/{browser.js → runtime/browser.js} +4 -2
- package/dist/{env-file.js → runtime/env-file.js} +7 -12
- package/dist/{extensions.d.ts → runtime/extensions.d.ts} +1 -5
- package/dist/{extensions.js → runtime/extensions.js} +2 -1
- package/dist/runtime/full-launch.d.ts +1 -0
- package/dist/runtime/full-launch.js +34 -0
- package/dist/runtime/global-flag.d.ts +5 -0
- package/dist/runtime/global-flag.js +18 -0
- package/dist/{playwright-config.d.ts → runtime/playwright-config.d.ts} +1 -1
- package/dist/{playwright.config.js → runtime/playwright.config.js} +3 -2
- package/dist/runtime/run-log.d.ts +2 -0
- package/dist/runtime/run-log.js +17 -0
- package/dist/{video-dir.js → runtime/video-dir.js} +3 -2
- package/dist/{config.d.ts → runtime/waygraph-config.d.ts} +6 -9
- package/dist/{config.js → runtime/waygraph-config.js} +21 -51
- package/dist/{webserver.js → runtime/webserver.js} +5 -30
- package/examples/routed-demo/config/waygraph.config.ts +20 -0
- package/examples/routed-demo/package.json +1 -4
- package/examples/routed-demo/scripts/fixture-server.mjs +1 -1
- package/examples/routed-demo/src/flows/routed-demo-map.flow.ts +2 -4
- package/examples/routed-demo/src/flows/routed-demo.flow.ts +1 -2
- package/examples/routed-demo/src/map/(app_base)/dashboard/_methods/click-widget.block.ts +5 -4
- package/examples/routed-demo/src/map/(app_base)/dashboard/_nav.block.ts +3 -3
- package/examples/routed-demo/src/map/(app_base)/dashboard/_page.block.ts +3 -3
- package/examples/routed-demo/src/map/(external)/docs/_nav.block.ts +3 -3
- package/examples/routed-demo/src/map/(external)/docs/_page.block.ts +3 -3
- package/examples/routed-demo/src/states/routed-demo.states.ts +5 -3
- package/examples/routed-demo/tests/routed-demo.spec.ts +4 -4
- package/examples/routed-demo/tsconfig.json +1 -1
- package/examples/saucedemo/docs/CONVENTION.md +4 -5
- package/examples/saucedemo/docs/HELPERS.md +11 -11
- package/examples/saucedemo/src/blocks/SITE-MAP.md +0 -1
- package/examples/saucedemo/src/blocks/saucedemo-web/NAV.md +1 -5
- package/examples/saucedemo/src/blocks/saucedemo-web/cart/nav-cart.block.ts +3 -3
- package/examples/saucedemo/src/blocks/saucedemo-web/cart/nav-checkout-info.block.ts +3 -3
- package/examples/saucedemo/src/blocks/saucedemo-web/checkout-step-one/methods/fill-first-name.method.block.ts +5 -4
- package/examples/saucedemo/src/blocks/saucedemo-web/checkout-step-one/methods/fill-last-name.method.block.ts +5 -4
- package/examples/saucedemo/src/blocks/saucedemo-web/checkout-step-one/methods/fill-postal-code.method.block.ts +5 -4
- package/examples/saucedemo/src/blocks/saucedemo-web/checkout-step-one/methods/submit-checkout-info.method.block.ts +5 -4
- package/examples/saucedemo/src/blocks/saucedemo-web/checkout-step-two/methods/finish-order.method.block.ts +5 -8
- package/examples/saucedemo/src/blocks/saucedemo-web/inventory/inventory.page.block.ts +3 -3
- package/examples/saucedemo/src/blocks/saucedemo-web/inventory/methods/add-all-to-cart.method.block.ts +4 -6
- package/examples/saucedemo/src/blocks/saucedemo-web/inventory/methods/add-to-cart.effect.block.ts +35 -43
- package/examples/saucedemo/src/blocks/saucedemo-web/inventory/methods/remove-all-from-cart.method.block.ts +4 -6
- package/examples/saucedemo/src/blocks/saucedemo-web/inventory/methods/remove-from-cart.effect.block.ts +4 -3
- package/examples/saucedemo/src/blocks/saucedemo-web/inventory/nav-item-detail.block.ts +3 -3
- package/examples/saucedemo/src/blocks/saucedemo-web/inventory-item/nav-back-to-inventory.block.ts +3 -3
- package/examples/saucedemo/src/blocks/saucedemo-web/inventory-item/nav-back-to-products.block.ts +3 -3
- package/examples/saucedemo/src/blocks/saucedemo-web/inventory-item/nav-continue-shopping.block.ts +3 -3
- package/examples/saucedemo/src/blocks/saucedemo-web/methods/fill-password.method.block.ts +5 -4
- package/examples/saucedemo/src/blocks/saucedemo-web/methods/fill-username.method.block.ts +5 -4
- package/examples/saucedemo/src/blocks/saucedemo-web/methods/submit-login.method.block.ts +4 -5
- package/examples/saucedemo/src/blocks/saucedemo-web/methods/submit-logout.method.block.ts +5 -4
- package/examples/saucedemo/src/blocks/saucedemo-web/nav-login.block.ts +3 -3
- package/examples/saucedemo/src/flows/api-demo.flow.ts +12 -10
- package/examples/saucedemo/src/states/checkout.states.ts +21 -11
- package/examples/saucedemo/src/stubs/device-showcase.ts +8 -10
- package/examples/saucedemo/tests/auto-graph.spec.ts +4 -12
- package/package.json +10 -6
- package/templates/agents/waygraph-planner.agent.md +2 -2
- package/templates/quickstart/docs/CONVENTION.md +4 -4
- package/templates/quickstart/docs/HELPERS.md +10 -8
- package/templates/quickstart/package.json +0 -3
- package/templates/quickstart/src/blocks/SITE-MAP.md +0 -1
- package/templates/quickstart/src/blocks/saucedemo-web/NAV.md +1 -5
- package/templates/quickstart/src/blocks/saucedemo-web/cart/nav-cart.block.ts +3 -3
- package/templates/quickstart/src/blocks/saucedemo-web/cart/nav-checkout-info.block.ts +3 -3
- package/templates/quickstart/src/blocks/saucedemo-web/checkout-step-one/methods/fill-first-name.method.block.ts +5 -4
- package/templates/quickstart/src/blocks/saucedemo-web/checkout-step-one/methods/fill-last-name.method.block.ts +5 -4
- package/templates/quickstart/src/blocks/saucedemo-web/checkout-step-one/methods/fill-postal-code.method.block.ts +5 -4
- package/templates/quickstart/src/blocks/saucedemo-web/checkout-step-one/methods/submit-checkout-info.method.block.ts +5 -4
- package/templates/quickstart/src/blocks/saucedemo-web/checkout-step-two/methods/finish-order.method.block.ts +5 -8
- package/templates/quickstart/src/blocks/saucedemo-web/inventory/inventory.page.block.ts +3 -3
- package/templates/quickstart/src/blocks/saucedemo-web/inventory/methods/add-all-to-cart.method.block.ts +4 -6
- package/templates/quickstart/src/blocks/saucedemo-web/inventory/methods/add-to-cart.effect.block.ts +35 -43
- package/templates/quickstart/src/blocks/saucedemo-web/inventory/methods/remove-all-from-cart.method.block.ts +4 -6
- package/templates/quickstart/src/blocks/saucedemo-web/inventory/methods/remove-from-cart.effect.block.ts +4 -3
- 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-back-to-inventory.block.ts +3 -3
- package/templates/quickstart/src/blocks/saucedemo-web/inventory-item/nav-back-to-products.block.ts +3 -3
- package/templates/quickstart/src/blocks/saucedemo-web/inventory-item/nav-continue-shopping.block.ts +3 -3
- package/templates/quickstart/src/blocks/saucedemo-web/methods/fill-password.method.block.ts +5 -4
- package/templates/quickstart/src/blocks/saucedemo-web/methods/fill-username.method.block.ts +5 -4
- package/templates/quickstart/src/blocks/saucedemo-web/methods/submit-login.method.block.ts +4 -5
- package/templates/quickstart/src/blocks/saucedemo-web/methods/submit-logout.method.block.ts +5 -4
- package/templates/quickstart/src/blocks/saucedemo-web/nav-login.block.ts +3 -3
- package/templates/quickstart/src/flows/api-demo.flow.ts +12 -10
- package/templates/quickstart/src/states/checkout.states.ts +21 -11
- package/templates/quickstart/src/stubs/device-showcase.ts +8 -10
- package/templates/scaffold/README.md +2 -1
- package/templates/scaffold/STRUCTURE.md +5 -4
- package/templates/scaffold/config/waygraph.config.ts +1 -0
- package/templates/scaffold/gitignore +1 -0
- package/templates/scaffold/src/flows/README.md +2 -2
- package/templates/scaffold/src/map/(app_base)/docs/_nav.block.ts +3 -3
- package/templates/scaffold/src/map/(app_base)/docs/_page.block.ts +3 -3
- package/templates/scaffold/src/map/(app_base)/home/_methods/add-item.effect.block.ts +4 -4
- package/templates/scaffold/src/map/(app_base)/home/_methods/assert-hello.method.block.ts +3 -3
- package/templates/scaffold/src/map/(app_base)/home/_methods/assert-item-added.method.block.ts +3 -3
- package/templates/scaffold/src/map/(app_base)/home/_methods/clear-cart.method.block.ts +5 -4
- package/templates/scaffold/src/map/(app_base)/home/_methods/remove-item.effect.block.ts +4 -4
- package/templates/scaffold/src/map/(app_base)/home/_nav.block.ts +3 -3
- package/templates/scaffold/src/map/(app_base)/home/_page.block.ts +3 -3
- package/templates/scaffold/src/map/(app_base)/home/nav-verification-link.block.ts +4 -4
- package/templates/scaffold/src/map/(external)/hoppscotch/_keys.ts +21 -0
- package/templates/scaffold/src/map/(external)/hoppscotch/_methods/assert-response-body.method.block.ts +4 -4
- package/templates/scaffold/src/map/(external)/hoppscotch/_methods/assert-response-header.method.block.ts +4 -4
- package/templates/scaffold/src/map/(external)/hoppscotch/_methods/assert-status.method.block.ts +4 -4
- package/templates/scaffold/src/map/(external)/hoppscotch/_methods/pick-extension-interceptor.method.block.ts +5 -4
- package/templates/scaffold/src/map/(external)/hoppscotch/_methods/read-response-body.method.block.ts +6 -5
- package/templates/scaffold/src/map/(external)/hoppscotch/_methods/read-response-headers.method.block.ts +6 -5
- package/templates/scaffold/src/map/(external)/hoppscotch/_methods/send-request.method.block.ts +5 -4
- package/templates/scaffold/src/map/(external)/hoppscotch/_methods/set-bearer-token.method.block.ts +6 -5
- package/templates/scaffold/src/map/(external)/hoppscotch/_methods/set-headers.method.block.ts +6 -5
- package/templates/scaffold/src/map/(external)/hoppscotch/_methods/set-json-body.method.block.ts +6 -5
- package/templates/scaffold/src/map/(external)/hoppscotch/_methods/set-method.method.block.ts +6 -5
- package/templates/scaffold/src/map/(external)/hoppscotch/_methods/set-query-params.method.block.ts +6 -5
- package/templates/scaffold/src/map/(external)/hoppscotch/_methods/set-url.method.block.ts +6 -5
- package/templates/scaffold/src/map/(external)/hoppscotch/_nav.block.ts +3 -3
- package/templates/scaffold/src/map/(external)/hoppscotch/_page.block.ts +3 -3
- package/templates/scaffold/src/map/(external)/hoppscotch/_states.ts +6 -0
- package/templates/scaffold/src/map/(external)/hoppscotch/settings/_nav.block.ts +3 -3
- package/templates/scaffold/src/map/(external)/mailpit/_keys.ts +13 -0
- package/templates/scaffold/src/map/(external)/mailpit/_methods/assert-email-content.method.block.ts +4 -4
- package/templates/scaffold/src/map/(external)/mailpit/_methods/assert-email-received.method.block.ts +4 -4
- package/templates/scaffold/src/map/(external)/mailpit/_methods/extract-email-link.method.block.ts +6 -5
- package/templates/scaffold/src/map/(external)/mailpit/_methods/open-message.method.block.ts +6 -5
- package/templates/scaffold/src/map/(external)/mailpit/_nav.block.ts +3 -3
- package/templates/scaffold/src/map/(external)/mailpit/_page.block.ts +3 -3
- package/templates/scaffold/src/map/(external)/mailpit/_states.ts +9 -0
- package/templates/scaffold/src/map/README.md +7 -0
- package/templates/scaffold/src/states/README.md +4 -1
- package/templates/scaffold/src/states/demo.mem-keys.ts +1 -29
- package/templates/scaffold/src/states/demo.states.ts +14 -20
- package/templates/scaffold/tests/hoppscotch.spec.ts +1 -11
- package/templates/scaffold/tests/mail-verify.spec.ts +2 -2
- package/templates/skills/waygraph-blind-pilot.skill.md +2 -6
- package/templates/skills/waygraph-convention.skill.md +23 -14
- package/templates/skills/waygraph-pilot.skill.md +7 -4
- package/dist/auto-session/verbose-log.js +0 -16
- package/dist/auto-session.d.ts +0 -2
- package/dist/auto-session.js +0 -3
- package/dist/cli/discover.d.ts +0 -40
- package/dist/cli/discover.js +0 -148
- package/dist/commands/agent-dive.js +0 -52
- package/dist/commands/check.js +0 -192
- package/dist/commands/map.js +0 -29
- package/dist/commands/run.js +0 -104
- package/dist/commands/traverse.js +0 -177
- package/dist/core/block.d.ts +0 -109
- package/dist/core/blocks/effect.js +0 -23
- package/dist/core/config.js +0 -17
- package/dist/core/engine.d.ts +0 -198
- package/dist/core/flow.d.ts +0 -294
- package/dist/core/flow.js +0 -432
- package/dist/core.d.ts +0 -14
- package/dist/core.js +0 -15
- package/dist/highlights/merge.d.ts +0 -8
- package/dist/highlights/merge.js +0 -173
- package/dist/highlights/stub-ctx.d.ts +0 -10
- package/dist/highlights/stub-ctx.js +0 -331
- package/dist/highlights/types.d.ts +0 -613
- package/dist/highlights.d.ts +0 -9
- package/dist/highlights.js +0 -10
- package/dist/pilot-overlay.d.ts +0 -5
- package/dist/pilot-overlay.js +0 -6
- package/dist/runner/banner-log.js +0 -63
- package/dist/runner/chain-run.js +0 -102
- package/dist/runner/cursor.js +0 -140
- package/dist/runner/demo-log.js +0 -316
- package/dist/runner/device-stage.d.ts +0 -9
- package/dist/runner/device-stage.js +0 -420
- package/dist/runner/discovery.js +0 -105
- package/dist/runner/index.js +0 -2
- package/dist/runner/inpage/banner.d.ts +0 -21
- package/dist/runner/inpage/banner.js +0 -156
- package/dist/runner/inpage/caption.d.ts +0 -3
- package/dist/runner/inpage/caption.js +0 -23
- package/dist/runner/inpage/core.d.ts +0 -4
- package/dist/runner/inpage/core.js +0 -316
- package/dist/runner/inpage/device.d.ts +0 -3
- package/dist/runner/inpage/device.js +0 -211
- package/dist/runner/inpage/network.d.ts +0 -15
- package/dist/runner/inpage/network.js +0 -217
- package/dist/runner/inpage/panel-chrome.js +0 -192
- package/dist/runner/inpage/stamp.js +0 -46
- package/dist/runner/inpage/swipe-zoom.js +0 -220
- package/dist/runner/inpage/todos.js +0 -337
- package/dist/runner/interaction-patch.js +0 -384
- package/dist/runner/main.js +0 -469
- package/dist/runner/network-capture.d.ts +0 -9
- package/dist/runner/network-capture.js +0 -126
- package/dist/runner/overlay-css.d.ts +0 -3
- package/dist/runner/overlay-css.js +0 -377
- package/dist/runner/overlay-install.js +0 -90
- package/dist/runner/overlay-stage.js +0 -110
- package/dist/runner/rings.js +0 -514
- package/dist/runner/seed-mem.js +0 -110
- package/dist/runner/slides.js +0 -278
- package/dist/runner/step-mode.js +0 -703
- package/dist/runner/step-panels.js +0 -729
- package/dist/runner/teardown.js +0 -202
- package/dist/runner/todo-dock.js +0 -142
- package/dist/session/step-overlay.d.ts +0 -37
- package/dist/session/step-overlay.js +0 -244
- package/examples/routed-demo/playwright.config.ts +0 -21
- package/examples/saucedemo/src/blocks/saucedemo-web/ff-owner-auth.block.ts +0 -22
- package/templates/quickstart/src/blocks/saucedemo-web/ff-owner-auth.block.ts +0 -22
- /package/dist/{commands → cli/commands}/agent-dive-scaffold.d.ts +0 -0
- /package/dist/{commands → cli/commands}/agent-dive.d.ts +0 -0
- /package/dist/{commands → cli/commands}/extensions.d.ts +0 -0
- /package/dist/{commands → cli/commands}/init.d.ts +0 -0
- /package/dist/{commands → cli/commands}/list.d.ts +0 -0
- /package/dist/{commands → cli/commands}/map.d.ts +0 -0
- /package/dist/{commands → cli/commands}/session.d.ts +0 -0
- /package/dist/{commands → cli/commands}/test.d.ts +0 -0
- /package/dist/{commands → cli/commands}/traverse.d.ts +0 -0
- /package/dist/{commands → cli/commands}/try.d.ts +0 -0
- /package/dist/{commands → cli/commands}/upgrade.d.ts +0 -0
- /package/dist/{highlights → demo/narration}/shorthand.js +0 -0
- /package/dist/{session/overlay-beacon.d.ts → demo/overlay/beacon.d.ts} +0 -0
- /package/dist/{session/overlay-beacon.js → demo/overlay/beacon.js} +0 -0
- /package/dist/{pilot-overlay/action-ring.d.ts → demo/overlay/pilot/actions.d.ts} +0 -0
- /package/dist/{ui → demo/overlay/ui}/components/ring.d.ts +0 -0
- /package/dist/{ui → demo/overlay/ui}/stylesheet.d.ts +0 -0
- /package/dist/{ui → demo/overlay/ui}/stylesheet.js +0 -0
- /package/dist/{ui → demo/overlay/ui}/tokens.d.ts +0 -0
- /package/dist/{ui → demo/overlay/ui}/tokens.js +0 -0
- /package/dist/{highlights → demo}/types.js +0 -0
- /package/dist/{auto-session → demo}/verbose-log.d.ts +0 -0
- /package/dist/{selector.d.ts → engine/trait/selector.d.ts} +0 -0
- /package/dist/{selector.js → engine/trait/selector.js} +0 -0
- /package/dist/{trait.js → engine/trait/trait.js} +0 -0
- /package/dist/{traverse → live/traverse}/coverage.d.ts +0 -0
- /package/dist/{traverse → live/traverse}/coverage.js +0 -0
- /package/dist/{traverse → live/traverse}/lease.d.ts +0 -0
- /package/dist/{traverse → live/traverse}/lease.js +0 -0
- /package/dist/{session/block-inject.d.ts → manifest/roots.d.ts} +0 -0
- /package/dist/{blocks-select.d.ts → manifest/select.d.ts} +0 -0
- /package/dist/{blocks-select.js → manifest/select.js} +0 -0
- /package/dist/{browser.d.ts → runtime/browser.d.ts} +0 -0
- /package/dist/{env-file.d.ts → runtime/env-file.d.ts} +0 -0
- /package/dist/{playwright-config.js → runtime/playwright-config.js} +0 -0
- /package/dist/{playwright.config.d.ts → runtime/playwright.config.d.ts} +0 -0
- /package/dist/{video-dir.d.ts → runtime/video-dir.d.ts} +0 -0
- /package/dist/{webserver.d.ts → runtime/webserver.d.ts} +0 -0
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
// Scans a project (and any injected Block libraries) into its Blocks and Flows, with each Block's route.
|
|
2
|
+
import { relative } from "node:path";
|
|
3
|
+
import { matchBlocksSelect } from "./select.js";
|
|
4
|
+
import { exploreRoots, injectTaggedFile } from "./roots.js";
|
|
5
|
+
import { blockKind, importFresh, isBlockLike, isFlowLike, walkDir } from "./scan.js";
|
|
6
|
+
import { installedMapPackages, mapPackageBlockFiles } from "./maps.js";
|
|
7
|
+
function kindOf(block) {
|
|
8
|
+
const kind = blockKind(block);
|
|
9
|
+
if (kind === "nav" || kind === "page" || kind === "assert" || kind === "api")
|
|
10
|
+
return kind;
|
|
11
|
+
const salt = block.__waygraphSalt;
|
|
12
|
+
if (salt === "effect" || salt === "method" || salt === "api")
|
|
13
|
+
return salt;
|
|
14
|
+
return "block";
|
|
15
|
+
}
|
|
16
|
+
/** A file that fails to import is left out of the scan, and said so: a silent skip reads as "nothing there". */
|
|
17
|
+
export function reportImportError(relFile, err) {
|
|
18
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
19
|
+
console.error(`waygraph: skip ${relFile}: ${msg.split("\n")[0]}`);
|
|
20
|
+
}
|
|
21
|
+
/** Imports every `*.block.ts` (and `*.flow.ts`) under the project and its injected roots. */
|
|
22
|
+
export async function scanProject(projectDir, opts = {}) {
|
|
23
|
+
const select = opts.blocksSelect;
|
|
24
|
+
const onError = opts.onImportError ?? reportImportError;
|
|
25
|
+
const blocks = [];
|
|
26
|
+
const flows = [];
|
|
27
|
+
const skipped = [];
|
|
28
|
+
const scanBlockFile = async (absFile, rel, file, map) => {
|
|
29
|
+
let mod;
|
|
30
|
+
try {
|
|
31
|
+
mod = await importFresh(absFile);
|
|
32
|
+
}
|
|
33
|
+
catch (err) {
|
|
34
|
+
onError(rel, err);
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
for (const [exportName, exported] of Object.entries(mod)) {
|
|
38
|
+
if (!isBlockLike(exported))
|
|
39
|
+
continue;
|
|
40
|
+
if (select && !matchBlocksSelect(select, { relFile: file, blockName: exported.name }))
|
|
41
|
+
continue;
|
|
42
|
+
const marked = exported;
|
|
43
|
+
const from = marked.__waygraphFrom ?? [];
|
|
44
|
+
const to = marked.__waygraphTo ?? [];
|
|
45
|
+
// Every factory records a route; only a bare defineBlock has none.
|
|
46
|
+
if (to.length === 0)
|
|
47
|
+
skipped.push({ block: exported.name, file, reason: "no route: build it with a define*Block factory and Checkpoint values" });
|
|
48
|
+
blocks.push({
|
|
49
|
+
block: exported,
|
|
50
|
+
name: exported.name,
|
|
51
|
+
exportName,
|
|
52
|
+
kind: kindOf(exported),
|
|
53
|
+
description: typeof exported.description === "string" ? exported.description : "",
|
|
54
|
+
from: [...from],
|
|
55
|
+
to: [...to],
|
|
56
|
+
requires: (exported.requires ?? []).map((k) => k.name),
|
|
57
|
+
file,
|
|
58
|
+
absFile,
|
|
59
|
+
...(map ? { map } : {}),
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
};
|
|
63
|
+
for (const root of exploreRoots(projectDir, opts.inject)) {
|
|
64
|
+
let files = walkDir(root, /\.block\.ts$/);
|
|
65
|
+
if (select && select.kind !== "regex") {
|
|
66
|
+
files = files.filter((f) => matchBlocksSelect(select, { relFile: relative(root, f).replace(/\\/g, "/") }));
|
|
67
|
+
}
|
|
68
|
+
for (const absFile of files) {
|
|
69
|
+
const rel = relative(root, absFile).replace(/\\/g, "/");
|
|
70
|
+
await scanBlockFile(absFile, rel, injectTaggedFile(projectDir, root, rel));
|
|
71
|
+
}
|
|
72
|
+
if (opts.flows === false)
|
|
73
|
+
continue;
|
|
74
|
+
for (const absFile of walkDir(root, /\.flow\.ts$/)) {
|
|
75
|
+
const rel = relative(root, absFile).replace(/\\/g, "/");
|
|
76
|
+
let mod;
|
|
77
|
+
try {
|
|
78
|
+
mod = await importFresh(absFile);
|
|
79
|
+
}
|
|
80
|
+
catch (err) {
|
|
81
|
+
onError(rel, err);
|
|
82
|
+
continue;
|
|
83
|
+
}
|
|
84
|
+
for (const [exportName, exported] of Object.entries(mod)) {
|
|
85
|
+
if (isFlowLike(exported))
|
|
86
|
+
flows.push({ flow: exported, exportName, file: injectTaggedFile(projectDir, root, rel), absFile });
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
if (opts.maps !== false) {
|
|
91
|
+
for (const pkg of installedMapPackages(projectDir)) {
|
|
92
|
+
for (const absFile of mapPackageBlockFiles(pkg)) {
|
|
93
|
+
const rel = relative(pkg.dir, absFile).replace(/\\/g, "/");
|
|
94
|
+
if (select && select.kind !== "regex" && !matchBlocksSelect(select, { relFile: `${pkg.name}/${rel}` }))
|
|
95
|
+
continue;
|
|
96
|
+
await scanBlockFile(absFile, rel, `${pkg.name}/${rel}`, pkg.name);
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
return { projectDir, blocks, flows, skipped };
|
|
101
|
+
}
|
|
@@ -5,12 +5,9 @@
|
|
|
5
5
|
import { existsSync } from "node:fs";
|
|
6
6
|
import { basename, dirname, join, resolve } from "node:path";
|
|
7
7
|
import { fileURLToPath } from "node:url";
|
|
8
|
-
import { homedir } from "node:os";
|
|
9
8
|
/**
|
|
10
9
|
* This package's own installed root (contains `templates/`/`examples/`, sibling to `dist/`) -
|
|
11
|
-
* this file compiles to `dist/
|
|
12
|
-
* bug as `cli/util.ts`'s own `packageRoot()` (see its comment) - self-inflicted here by moving
|
|
13
|
-
* this file into `src/session/` without updating the path math to match the new depth.
|
|
10
|
+
* this file compiles to `dist/manifest/roots.js`, two levels down.
|
|
14
11
|
*/
|
|
15
12
|
function packageRoot() {
|
|
16
13
|
return resolve(dirname(fileURLToPath(import.meta.url)), "..", "..");
|
|
@@ -32,20 +29,6 @@ export function injectTaggedFile(hostDir, root, relFile) {
|
|
|
32
29
|
}
|
|
33
30
|
const PRESETS = {
|
|
34
31
|
saucedemo: () => join(packageRoot(), "examples", "saucedemo"),
|
|
35
|
-
demosauce: () => join(packageRoot(), "examples", "saucedemo"),
|
|
36
|
-
veciro: () => {
|
|
37
|
-
if (process.env.WAYGRAPH_INJECT_VECIRO) {
|
|
38
|
-
return resolve(process.env.WAYGRAPH_INJECT_VECIRO);
|
|
39
|
-
}
|
|
40
|
-
for (const c of [
|
|
41
|
-
join(homedir(), "Desktop", "Work", "veciro-waygraph"),
|
|
42
|
-
join(homedir(), "Desktop", "Projects", "veciro-waygraph"),
|
|
43
|
-
]) {
|
|
44
|
-
if (existsSync(c))
|
|
45
|
-
return c;
|
|
46
|
-
}
|
|
47
|
-
return null;
|
|
48
|
-
},
|
|
49
32
|
};
|
|
50
33
|
/**
|
|
51
34
|
* Resolve one `--inject` token to an absolute directory (preset name or path).
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { Block } from "../engine/block/block.js";
|
|
2
|
+
import type { Checkpoint } from "../engine/checkpoint/checkpoint.js";
|
|
3
|
+
/** Every file under `dir` whose name matches, skipping `node_modules`, `dist` and `.git`. */
|
|
4
|
+
export declare function walkDir(dir: string, pattern: RegExp): string[];
|
|
5
|
+
/**
|
|
6
|
+
* Imports a project file. The file's mtime is part of the URL: Node caches an ESM import per specifier for the life of the
|
|
7
|
+
* process, so a long-running session reloading an edited Block would otherwise keep the first version.
|
|
8
|
+
*/
|
|
9
|
+
export declare function importFresh(filePath: string): Promise<Record<string, unknown>>;
|
|
10
|
+
export type AnyBlock = Block<Checkpoint<string>, Checkpoint<string>> & {
|
|
11
|
+
description?: string;
|
|
12
|
+
};
|
|
13
|
+
export declare function isBlockLike(val: unknown): val is AnyBlock;
|
|
14
|
+
export declare function isFlowLike(val: unknown): val is {
|
|
15
|
+
run: (...args: unknown[]) => Promise<unknown>;
|
|
16
|
+
blocks: () => unknown[];
|
|
17
|
+
};
|
|
18
|
+
/** The factory kind a Block was built with (`nav`, `page`, `assert`), or undefined for Methods and Effects. */
|
|
19
|
+
export declare function blockKind(block: object): string | undefined;
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
// The one place a project's files are walked and imported. Everything that needs the project's Blocks or Flows
|
|
2
|
+
// (graph, check, map, auto, traverse, the runner) goes through here.
|
|
3
|
+
import { readdirSync, statSync } from "node:fs";
|
|
4
|
+
import { join, resolve } from "node:path";
|
|
5
|
+
import { pathToFileURL } from "node:url";
|
|
6
|
+
/** Every file under `dir` whose name matches, skipping `node_modules`, `dist` and `.git`. */
|
|
7
|
+
export function walkDir(dir, pattern) {
|
|
8
|
+
const results = [];
|
|
9
|
+
let entries;
|
|
10
|
+
try {
|
|
11
|
+
entries = readdirSync(dir, { withFileTypes: true });
|
|
12
|
+
}
|
|
13
|
+
catch {
|
|
14
|
+
return results;
|
|
15
|
+
}
|
|
16
|
+
for (const entry of entries) {
|
|
17
|
+
const full = join(dir, entry.name);
|
|
18
|
+
if (entry.isDirectory()) {
|
|
19
|
+
if (entry.name === "node_modules" || entry.name === "dist" || entry.name === ".git")
|
|
20
|
+
continue;
|
|
21
|
+
results.push(...walkDir(full, pattern));
|
|
22
|
+
}
|
|
23
|
+
else if (pattern.test(entry.name)) {
|
|
24
|
+
results.push(full);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
return results;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Imports a project file. The file's mtime is part of the URL: Node caches an ESM import per specifier for the life of the
|
|
31
|
+
* process, so a long-running session reloading an edited Block would otherwise keep the first version.
|
|
32
|
+
*/
|
|
33
|
+
export async function importFresh(filePath) {
|
|
34
|
+
const resolved = resolve(filePath);
|
|
35
|
+
const url = pathToFileURL(resolved);
|
|
36
|
+
url.searchParams.set("t", String(statSync(resolved).mtimeMs));
|
|
37
|
+
return (await import(url.href));
|
|
38
|
+
}
|
|
39
|
+
export function isBlockLike(val) {
|
|
40
|
+
if (val === null || typeof val !== "object")
|
|
41
|
+
return false;
|
|
42
|
+
const obj = val;
|
|
43
|
+
if (typeof obj.name !== "string")
|
|
44
|
+
return false;
|
|
45
|
+
const instruction = obj.instruction;
|
|
46
|
+
return instruction !== null && typeof instruction === "object" && typeof instruction?.act === "function";
|
|
47
|
+
}
|
|
48
|
+
export function isFlowLike(val) {
|
|
49
|
+
return (val !== null &&
|
|
50
|
+
typeof val === "object" &&
|
|
51
|
+
typeof val.run === "function" &&
|
|
52
|
+
typeof val.blocks === "function");
|
|
53
|
+
}
|
|
54
|
+
/** The factory kind a Block was built with (`nav`, `page`, `assert`), or undefined for Methods and Effects. */
|
|
55
|
+
export function blockKind(block) {
|
|
56
|
+
return block.__waygraphKind;
|
|
57
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { SourceFile } from "ts-morph";
|
|
2
|
+
/** The file as it is on disk now. */
|
|
3
|
+
export declare function parseSource(file: string): SourceFile;
|
|
4
|
+
/** Names the file exports: `export const|let|var|function|class X`, and `export { X }`. */
|
|
5
|
+
export declare function exportedNames(sf: SourceFile): string[];
|
|
6
|
+
/** Every module the file imports or re-exports from, including dynamic `import("x")`. */
|
|
7
|
+
export declare function importSpecifiers(sf: SourceFile): string[];
|
|
8
|
+
/** Names imported from modules whose specifier passes `from`, in source order (the imported name, not an alias). */
|
|
9
|
+
export declare function namedImportsFrom(sf: SourceFile, from: (specifier: string) => boolean): string[];
|
|
10
|
+
/** The string literal at `argIndex` of every call whose callee text passes `callee`, in source order. */
|
|
11
|
+
export declare function stringArgs(sf: SourceFile, callee: (text: string) => boolean, argIndex?: number): string[];
|
|
12
|
+
/** A string property of the object literal passed to every matching call: `Trait.url({ pathname: "/x" })` -> "/x". */
|
|
13
|
+
export declare function objectArgProperty(sf: SourceFile, callee: (text: string) => boolean, property: string): string[];
|
|
14
|
+
/** Every string literal in the file (comments are not strings), with the property name it initializes, if any. */
|
|
15
|
+
export declare function stringLiterals(sf: SourceFile): {
|
|
16
|
+
value: string;
|
|
17
|
+
property: string | undefined;
|
|
18
|
+
}[];
|
|
19
|
+
/** Every call in the file (comments and strings are not calls): its callee as written and whether its first argument is a string. */
|
|
20
|
+
export declare function calls(sf: SourceFile): {
|
|
21
|
+
callee: string;
|
|
22
|
+
literalFirstArg: boolean;
|
|
23
|
+
}[];
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
// Reads a TypeScript file's shape (its exports, imports, string arguments) from the AST (ts-morph), for the places that
|
|
2
|
+
// need it without importing the file: `list`, `nav`, a flow file's export name, a map group's imports.
|
|
3
|
+
import { readFileSync } from "node:fs";
|
|
4
|
+
import { Node, Project, SyntaxKind } from "ts-morph";
|
|
5
|
+
const project = new Project({ useInMemoryFileSystem: true, skipFileDependencyResolution: true });
|
|
6
|
+
/** The file as it is on disk now. */
|
|
7
|
+
export function parseSource(file) {
|
|
8
|
+
return project.createSourceFile(file.replace(/\\/g, "/").replace(/^[A-Za-z]:/, ""), readFileSync(file, "utf8"), { overwrite: true });
|
|
9
|
+
}
|
|
10
|
+
/** Names the file exports: `export const|let|var|function|class X`, and `export { X }`. */
|
|
11
|
+
export function exportedNames(sf) {
|
|
12
|
+
const names = [];
|
|
13
|
+
for (const statement of sf.getStatements()) {
|
|
14
|
+
if (Node.isVariableStatement(statement) && statement.isExported())
|
|
15
|
+
names.push(...statement.getDeclarations().map((d) => d.getName()));
|
|
16
|
+
else if ((Node.isFunctionDeclaration(statement) || Node.isClassDeclaration(statement)) && statement.isExported() && statement.getName())
|
|
17
|
+
names.push(statement.getName());
|
|
18
|
+
else if (Node.isExportDeclaration(statement) && !statement.getModuleSpecifier())
|
|
19
|
+
names.push(...statement.getNamedExports().map((e) => e.getAliasNode()?.getText() ?? e.getName()));
|
|
20
|
+
}
|
|
21
|
+
return names;
|
|
22
|
+
}
|
|
23
|
+
/** Every module the file imports or re-exports from, including dynamic `import("x")`. */
|
|
24
|
+
export function importSpecifiers(sf) {
|
|
25
|
+
const specs = [
|
|
26
|
+
...sf.getImportDeclarations().map((d) => d.getModuleSpecifierValue()),
|
|
27
|
+
...sf.getExportDeclarations().flatMap((d) => d.getModuleSpecifierValue() ?? []),
|
|
28
|
+
];
|
|
29
|
+
for (const call of sf.getDescendantsOfKind(SyntaxKind.CallExpression)) {
|
|
30
|
+
const arg = call.getArguments()[0];
|
|
31
|
+
if (call.getExpression().getKind() === SyntaxKind.ImportKeyword && Node.isStringLiteral(arg))
|
|
32
|
+
specs.push(arg.getLiteralValue());
|
|
33
|
+
}
|
|
34
|
+
return specs;
|
|
35
|
+
}
|
|
36
|
+
/** Names imported from modules whose specifier passes `from`, in source order (the imported name, not an alias). */
|
|
37
|
+
export function namedImportsFrom(sf, from) {
|
|
38
|
+
return sf
|
|
39
|
+
.getImportDeclarations()
|
|
40
|
+
.filter((d) => from(d.getModuleSpecifierValue()))
|
|
41
|
+
.flatMap((d) => d.getNamedImports().map((n) => n.getName()));
|
|
42
|
+
}
|
|
43
|
+
/** The string literal at `argIndex` of every call whose callee text passes `callee`, in source order. */
|
|
44
|
+
export function stringArgs(sf, callee, argIndex = 0) {
|
|
45
|
+
const out = [];
|
|
46
|
+
for (const call of sf.getDescendantsOfKind(SyntaxKind.CallExpression)) {
|
|
47
|
+
if (!callee(call.getExpression().getText()))
|
|
48
|
+
continue;
|
|
49
|
+
const arg = call.getArguments()[argIndex];
|
|
50
|
+
if (Node.isStringLiteral(arg) || Node.isNoSubstitutionTemplateLiteral(arg))
|
|
51
|
+
out.push(arg.getLiteralValue());
|
|
52
|
+
}
|
|
53
|
+
return out;
|
|
54
|
+
}
|
|
55
|
+
/** A string property of the object literal passed to every matching call: `Trait.url({ pathname: "/x" })` -> "/x". */
|
|
56
|
+
export function objectArgProperty(sf, callee, property) {
|
|
57
|
+
const out = [];
|
|
58
|
+
for (const call of sf.getDescendantsOfKind(SyntaxKind.CallExpression)) {
|
|
59
|
+
if (!callee(call.getExpression().getText()))
|
|
60
|
+
continue;
|
|
61
|
+
const arg = call.getArguments()[0];
|
|
62
|
+
const prop = Node.isObjectLiteralExpression(arg) ? arg.getProperty(property) : undefined;
|
|
63
|
+
const value = Node.isPropertyAssignment(prop) ? prop.getInitializer() : undefined;
|
|
64
|
+
if (Node.isStringLiteral(value) || Node.isNoSubstitutionTemplateLiteral(value))
|
|
65
|
+
out.push(value.getLiteralValue());
|
|
66
|
+
}
|
|
67
|
+
return out;
|
|
68
|
+
}
|
|
69
|
+
/** Every string literal in the file (comments are not strings), with the property name it initializes, if any. */
|
|
70
|
+
export function stringLiterals(sf) {
|
|
71
|
+
const out = [];
|
|
72
|
+
for (const node of [...sf.getDescendantsOfKind(SyntaxKind.StringLiteral), ...sf.getDescendantsOfKind(SyntaxKind.NoSubstitutionTemplateLiteral)]) {
|
|
73
|
+
const parent = node.getParent();
|
|
74
|
+
if (Node.isImportDeclaration(parent) || Node.isExportDeclaration(parent))
|
|
75
|
+
continue;
|
|
76
|
+
out.push({ value: node.getLiteralValue(), property: Node.isPropertyAssignment(parent) && parent.getInitializer() === node ? parent.getName() : undefined });
|
|
77
|
+
}
|
|
78
|
+
return out;
|
|
79
|
+
}
|
|
80
|
+
/** Every call in the file (comments and strings are not calls): its callee as written and whether its first argument is a string. */
|
|
81
|
+
export function calls(sf) {
|
|
82
|
+
return sf.getDescendantsOfKind(SyntaxKind.CallExpression).map((call) => {
|
|
83
|
+
const arg = call.getArguments()[0];
|
|
84
|
+
return { callee: call.getExpression().getText(), literalFirstArg: Node.isStringLiteral(arg) || Node.isTemplateExpression(arg) || Node.isNoSubstitutionTemplateLiteral(arg) };
|
|
85
|
+
});
|
|
86
|
+
}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import type { BrowserContext } from "@playwright/test";
|
|
2
|
+
import type { Checkpoint } from "../engine/checkpoint/checkpoint.js";
|
|
3
|
+
import type { EngineConfig } from "../engine/config.js";
|
|
4
|
+
import type { MemPage } from "../engine/mem/mem.js";
|
|
5
|
+
import type { DemoPace } from "../engine/stub/pace.js";
|
|
6
|
+
import type { HighlightStyleDefaults } from "../engine/stub/ring.js";
|
|
7
|
+
import type { WgPage } from "../demo/types.js";
|
|
8
|
+
import type { SomeBlock } from "../engine/block/block.js";
|
|
9
|
+
/** One Block to play, with what its flow says about it. */
|
|
10
|
+
export interface PlayStep {
|
|
11
|
+
block: SomeBlock;
|
|
12
|
+
exportName: string;
|
|
13
|
+
/** The engine config of the flow it came from (its layouts apply when it runs). */
|
|
14
|
+
config: EngineConfig;
|
|
15
|
+
/** Set on a named flow's steps; ad hoc Block chains have no episodes. */
|
|
16
|
+
episodeNumber?: number | undefined;
|
|
17
|
+
episodeTitle?: string | undefined;
|
|
18
|
+
/** Clear cookies and storage before this step (a flow with `sessionReset`, chained after another). */
|
|
19
|
+
resetSession: boolean;
|
|
20
|
+
/** Seeds this segment's `--data` into mem; set on a segment's first step. */
|
|
21
|
+
seedMem?: (() => void) | undefined;
|
|
22
|
+
/** Set on a flow's last step when the flow is meant to fail (`map({ expectedFailure })`). */
|
|
23
|
+
expectedFailureReason?: string | undefined;
|
|
24
|
+
demoPace?: DemoPace | undefined;
|
|
25
|
+
highlightStyle?: HighlightStyleDefaults | undefined;
|
|
26
|
+
/** An inner step of an expanded fast-forward unit (`--ff-expand`). */
|
|
27
|
+
wasFastForward?: boolean | undefined;
|
|
28
|
+
ffSource?: string | undefined;
|
|
29
|
+
}
|
|
30
|
+
/** The browser everything plays in. */
|
|
31
|
+
export interface PlaySession {
|
|
32
|
+
context: BrowserContext;
|
|
33
|
+
page: WgPage;
|
|
34
|
+
mem: MemPage;
|
|
35
|
+
baseURL: string | undefined;
|
|
36
|
+
}
|
|
37
|
+
/** How a step ended, for a mode's `failed` hook: it threw, or it landed on the branch its flow expects to fail on. */
|
|
38
|
+
export type StepFailure = {
|
|
39
|
+
error: unknown;
|
|
40
|
+
result?: undefined;
|
|
41
|
+
} | {
|
|
42
|
+
error?: undefined;
|
|
43
|
+
result: Checkpoint<string>;
|
|
44
|
+
};
|
|
45
|
+
export interface PlayOutcome {
|
|
46
|
+
ok: boolean;
|
|
47
|
+
result?: Checkpoint<string> | undefined;
|
|
48
|
+
/** The step that failed, when one did. */
|
|
49
|
+
failedAt?: {
|
|
50
|
+
index: number;
|
|
51
|
+
step: PlayStep;
|
|
52
|
+
error: unknown;
|
|
53
|
+
} | undefined;
|
|
54
|
+
/** Set when the run stopped where its flow expects to fail. */
|
|
55
|
+
expectedFailure?: {
|
|
56
|
+
step: PlayStep;
|
|
57
|
+
reason: string;
|
|
58
|
+
} | undefined;
|
|
59
|
+
}
|
|
60
|
+
/** A way of playing steps. Every hook is optional; with none, it is a plain Playwright run. */
|
|
61
|
+
export interface Mode {
|
|
62
|
+
name: string;
|
|
63
|
+
begin?(steps: readonly PlayStep[]): Promise<void>;
|
|
64
|
+
/** After the page was reset between episodes. */
|
|
65
|
+
afterReset?(): Promise<void>;
|
|
66
|
+
before?(index: number): Promise<void>;
|
|
67
|
+
after?(index: number, result: Checkpoint<string>, ms: number): Promise<void>;
|
|
68
|
+
/** A step failed (or reached its expected failure): retry its episode, or stop. Without the hook: stop. */
|
|
69
|
+
failed?(index: number, failure: StepFailure, ms: number): Promise<"retry" | "stop">;
|
|
70
|
+
end?(outcome: PlayOutcome): Promise<void>;
|
|
71
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { MemPage } from "../../engine/mem/mem.js";
|
|
2
|
+
import type { Flow } from "../../engine/flow/flow.js";
|
|
3
|
+
import type { PlayOptions } from "../options.js";
|
|
4
|
+
import type { Checkpoint } from "../../engine/checkpoint/checkpoint.js";
|
|
5
|
+
export declare function playBranches(flows: readonly Flow<Checkpoint<string>>[], mem: MemPage, options: PlayOptions): Promise<void>;
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { branchRoutes, runBranchRegression } from "../../engine/flow/branch-regression.js";
|
|
2
|
+
import { extensionPathsFromEnv } from "../../runtime/browser.js";
|
|
3
|
+
export async function playBranches(flows, mem, options) {
|
|
4
|
+
const flow = flows.length === 1 ? flows[0] : undefined;
|
|
5
|
+
if (!flow) {
|
|
6
|
+
console.error("waygraph run --all-branches: needs a single Flow reference (e.g. --blocks loginFlow), not a multi-segment chain spec - nothing else has one branch tree to explore.");
|
|
7
|
+
process.exitCode = 1;
|
|
8
|
+
return;
|
|
9
|
+
}
|
|
10
|
+
if (!branchRoutes(flow)) {
|
|
11
|
+
console.error("waygraph run --all-branches: this Flow was not built with MapBuilder.branch() - there is no branch tree to explore. Run it normally instead.");
|
|
12
|
+
process.exitCode = 1;
|
|
13
|
+
return;
|
|
14
|
+
}
|
|
15
|
+
if (extensionPathsFromEnv().length > 0) {
|
|
16
|
+
console.warn("waygraph run --all-branches: extensions are not loaded (branches run in cloned contexts)");
|
|
17
|
+
}
|
|
18
|
+
const { chromium } = await import("@playwright/test");
|
|
19
|
+
const browser = await chromium.launch({ headless: !options.headed });
|
|
20
|
+
try {
|
|
21
|
+
const context = await browser.newContext(options.baseURL ? { baseURL: options.baseURL } : undefined);
|
|
22
|
+
const results = await runBranchRegression(flow, context, mem, { cloneSession: !options.sharedSession });
|
|
23
|
+
for (const r of results) {
|
|
24
|
+
console.log(`waygraph run --all-branches: ${r.path || "(root)"} -> ${r.status}` +
|
|
25
|
+
(r.result ? ` (${JSON.stringify(r.result)})` : "") +
|
|
26
|
+
(r.error ? ` - ${r.error}` : ""));
|
|
27
|
+
}
|
|
28
|
+
const failed = results.filter((r) => r.status === "failed");
|
|
29
|
+
if (failed.length) {
|
|
30
|
+
console.error(`waygraph run --all-branches: ${failed.length}/${results.length} path(s) failed`);
|
|
31
|
+
process.exitCode = 1;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
finally {
|
|
35
|
+
await browser.close();
|
|
36
|
+
}
|
|
37
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
// `waygraph demo`: the same steps, with the waygraph UI around each one (src/demo/stepper/).
|
|
2
|
+
import { createStepper } from "../../demo/stepper/stepper.js";
|
|
3
|
+
export async function demoMode(session, steps, options, beat) {
|
|
4
|
+
const stepper = await createStepper(session.page, session.mem, steps, { title: options.title, fastBlocks: options.fastBlocks, beat });
|
|
5
|
+
return {
|
|
6
|
+
name: "demo",
|
|
7
|
+
afterReset: stepper.afterReset,
|
|
8
|
+
before: stepper.before,
|
|
9
|
+
after: (index, result) => stepper.after(index, result),
|
|
10
|
+
failed: (index, failure) => stepper.failed(index, failure),
|
|
11
|
+
end: () => stepper.end(),
|
|
12
|
+
};
|
|
13
|
+
}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
// `waygraph run` with WAYGRAPH_JSON=1: plays like `run` and prints one JSON report (each step's Checkpoint and time,
|
|
2
|
+
// a screenshot on failure). `runId` names the matching `.waygraph/runs/<runId>.jsonl`.
|
|
3
|
+
import { join } from "node:path";
|
|
4
|
+
import { tmpdir } from "node:os";
|
|
5
|
+
import { currentRunId, recordArtifact } from "../../engine/run/events.js";
|
|
6
|
+
export function reportMode(session) {
|
|
7
|
+
let steps = [];
|
|
8
|
+
const done = [];
|
|
9
|
+
let screenshot = null;
|
|
10
|
+
const message = (error) => (error instanceof Error ? error.message : String(error));
|
|
11
|
+
return {
|
|
12
|
+
name: "report",
|
|
13
|
+
async begin(all) {
|
|
14
|
+
steps = all;
|
|
15
|
+
},
|
|
16
|
+
async after(index, result, ms) {
|
|
17
|
+
done.push({ name: steps[index].block.name, checkpoint: result, ms });
|
|
18
|
+
},
|
|
19
|
+
async failed(index, failure, ms) {
|
|
20
|
+
const step = steps[index];
|
|
21
|
+
if (failure.result) {
|
|
22
|
+
done.push({ name: step.block.name, checkpoint: failure.result, ms });
|
|
23
|
+
}
|
|
24
|
+
else if (step.expectedFailureReason) {
|
|
25
|
+
done.push({ name: step.block.name, expectedFailure: true, error: message(failure.error), ms });
|
|
26
|
+
}
|
|
27
|
+
else {
|
|
28
|
+
screenshot = join(tmpdir(), "waygraph-chain-failure-" + Date.now() + ".png");
|
|
29
|
+
await session.page.screenshot({ path: screenshot, fullPage: true }).then(() => recordArtifact("screenshot", screenshot), () => (screenshot = null));
|
|
30
|
+
}
|
|
31
|
+
return "stop";
|
|
32
|
+
},
|
|
33
|
+
async end(outcome) {
|
|
34
|
+
const runId = currentRunId();
|
|
35
|
+
const report = outcome.failedAt
|
|
36
|
+
? {
|
|
37
|
+
runId,
|
|
38
|
+
ok: false,
|
|
39
|
+
failedAt: outcome.failedAt.step.block.name,
|
|
40
|
+
stepIndex: outcome.failedAt.index,
|
|
41
|
+
totalSteps: steps.length,
|
|
42
|
+
error: message(outcome.failedAt.error),
|
|
43
|
+
steps: done,
|
|
44
|
+
screenshot,
|
|
45
|
+
}
|
|
46
|
+
: outcome.expectedFailure && outcome.result === undefined
|
|
47
|
+
? { runId, ok: true, expectedFailure: true, failedAt: outcome.expectedFailure.step.block.name, reason: outcome.expectedFailure.reason, steps: done }
|
|
48
|
+
: { runId, ok: true, result: done.length > 0 ? done[done.length - 1].checkpoint : null, steps: done };
|
|
49
|
+
console.log(JSON.stringify(report, null, 2));
|
|
50
|
+
if (!report.ok)
|
|
51
|
+
process.exitCode = 1;
|
|
52
|
+
},
|
|
53
|
+
};
|
|
54
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import type { PlayStep } from "./mode.js";
|
|
2
|
+
export type ModeName = "run" | "demo" | "report" | "branches";
|
|
3
|
+
export interface PlayOptions {
|
|
4
|
+
mode: ModeName;
|
|
5
|
+
headed: boolean;
|
|
6
|
+
baseURL: string | undefined;
|
|
7
|
+
title: string | undefined;
|
|
8
|
+
/** Block names that skip the demo's added dwell (WAYGRAPH_FAST_BLOCKS). */
|
|
9
|
+
fastBlocks: Set<string>;
|
|
10
|
+
/** Clear the session before every step after the first (WAYGRAPH_CLEAR_SESSION). */
|
|
11
|
+
clearSession: boolean;
|
|
12
|
+
/** Record a video: the folder, or "1" for the default one. */
|
|
13
|
+
video: string | undefined;
|
|
14
|
+
videoViewport: string | undefined;
|
|
15
|
+
/** Expand fast-forward units into their inner steps (--ff-expand / --ff-disabled). */
|
|
16
|
+
ffExpand: boolean;
|
|
17
|
+
ffDisabled: boolean;
|
|
18
|
+
/** Fill missing `requires` from registerMemStub for every flow (--mem-stub). */
|
|
19
|
+
memStub: boolean;
|
|
20
|
+
/** --all-branches without cloning the session per branch. */
|
|
21
|
+
sharedSession: boolean;
|
|
22
|
+
}
|
|
23
|
+
export declare function readOptions(): PlayOptions;
|
|
24
|
+
/**
|
|
25
|
+
* The slowMo for the browser launch and the demo's own beat after each action. The demo launches at 0 and paces
|
|
26
|
+
* itself, so a step's pace can remove the beat; a fast-forward unit in the steps drops the beat to 0.
|
|
27
|
+
*/
|
|
28
|
+
export declare function slowMoFor(options: PlayOptions, steps: readonly PlayStep[]): {
|
|
29
|
+
launch: number | undefined;
|
|
30
|
+
demoBeat: number;
|
|
31
|
+
};
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
// How to play, read once from the environment the CLI set (flags beat the config file, which beats these defaults).
|
|
2
|
+
import { envFlag, envNumber, envString, envSwitch } from "../engine/env.js";
|
|
3
|
+
function readMode() {
|
|
4
|
+
if (envFlag("WAYGRAPH_ALL_BRANCHES"))
|
|
5
|
+
return "branches";
|
|
6
|
+
if (envFlag("WAYGRAPH_JSON"))
|
|
7
|
+
return "report";
|
|
8
|
+
return envFlag("WAYGRAPH_STEP") ? "demo" : "run";
|
|
9
|
+
}
|
|
10
|
+
export function readOptions() {
|
|
11
|
+
const mode = readMode();
|
|
12
|
+
return {
|
|
13
|
+
mode,
|
|
14
|
+
// A manual demo is watched, so it is headed by default; WAYGRAPH_HEADED=0 (e.g. --auto-play-video) still wins.
|
|
15
|
+
headed: envSwitch("WAYGRAPH_HEADED", mode === "demo"),
|
|
16
|
+
baseURL: envString("WAYGRAPH_BASE_URL"),
|
|
17
|
+
title: envString("WAYGRAPH_TITLE"),
|
|
18
|
+
fastBlocks: new Set((envString("WAYGRAPH_FAST_BLOCKS") || "").split(",").map((s) => s.trim()).filter(Boolean)),
|
|
19
|
+
clearSession: envFlag("WAYGRAPH_CLEAR_SESSION"),
|
|
20
|
+
video: envString("WAYGRAPH_VIDEO"),
|
|
21
|
+
videoViewport: envString("WAYGRAPH_VIDEO_VIEWPORT"),
|
|
22
|
+
ffExpand: envFlag("WAYGRAPH_FF_EXPAND") || envFlag("WAYGRAPH_FF_DISABLED"),
|
|
23
|
+
ffDisabled: envFlag("WAYGRAPH_FF_DISABLED"),
|
|
24
|
+
memStub: envFlag("WAYGRAPH_MEM_STUB"),
|
|
25
|
+
sharedSession: envFlag("WAYGRAPH_SHARED_SESSION"),
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* The slowMo for the browser launch and the demo's own beat after each action. The demo launches at 0 and paces
|
|
30
|
+
* itself, so a step's pace can remove the beat; a fast-forward unit in the steps drops the beat to 0.
|
|
31
|
+
*/
|
|
32
|
+
export function slowMoFor(options, steps) {
|
|
33
|
+
const demo = options.mode === "demo";
|
|
34
|
+
const hasFastForward = steps.some((s) => s.block.fastForward === true || s.wasFastForward === true);
|
|
35
|
+
const slowMo = envNumber("WAYGRAPH_SLOWMO") ?? (demo ? (hasFastForward ? 0 : 350) : undefined);
|
|
36
|
+
if (demo && hasFastForward && envNumber("WAYGRAPH_SLOWMO") === undefined) {
|
|
37
|
+
console.error(options.ffDisabled
|
|
38
|
+
? "waygraph demo: --ff-disabled (expanded) -> Playwright slowMo=0 on former FF steps (blitz; same acts as opaque FF)"
|
|
39
|
+
: "waygraph demo: opaque FFCompose in flow -> Playwright slowMo=0 (blitz); set WAYGRAPH_SLOWMO to override");
|
|
40
|
+
}
|
|
41
|
+
return { launch: demo ? 0 : slowMo, demoBeat: slowMo ?? 0 };
|
|
42
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { AnyBlock } from "../../manifest/scan.js";
|
|
2
|
+
import type { Flow } from "../../engine/flow/flow.js";
|
|
3
|
+
import type { Checkpoint } from "../../engine/checkpoint/checkpoint.js";
|
|
4
|
+
export interface FoundBlock {
|
|
5
|
+
block: AnyBlock;
|
|
6
|
+
exportName: string;
|
|
7
|
+
file: string;
|
|
8
|
+
}
|
|
9
|
+
export declare function findBlock(projectDir: string, ref: string): Promise<FoundBlock>;
|
|
10
|
+
/**
|
|
11
|
+
* Finds an already-defined Flow by its export name (e.g. loginFlow) among
|
|
12
|
+
* the project's *.flow.ts files - "I already have this wired up, just point
|
|
13
|
+
* the stepper at it, no chain spec to hand-write." Flows have no runtime
|
|
14
|
+
* .name of their own (unlike Blocks), so this only matches by export
|
|
15
|
+
* identifier. Returns null (not a throw) when nothing matches - the caller
|
|
16
|
+
* falls back to ordinary block-chain spec parsing.
|
|
17
|
+
*/
|
|
18
|
+
export declare function findFlow(projectDir: string, flowName: string): Promise<Flow<Checkpoint<string>> | null>;
|