waygraph 0.15.54 → 0.16.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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/cli/commands/browser.d.ts +2 -0
- package/dist/cli/commands/browser.js +109 -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/cli/commands/pilot.d.ts +2 -0
- package/dist/cli/commands/pilot.js +102 -0
- package/dist/{commands → cli/commands}/run.d.ts +0 -1
- package/dist/cli/commands/run.js +64 -0
- package/dist/cli/commands/session-ops.d.ts +3 -0
- package/dist/cli/commands/session-ops.js +257 -0
- package/dist/cli/commands/session.js +132 -0
- 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 +4 -12
- package/dist/{highlights → demo/narration}/demo-pace.js +5 -11
- package/dist/{highlights → demo/narration}/device.d.ts +4 -4
- package/dist/{highlights → demo/narration}/device.js +1 -1
- package/dist/demo/narration/merge.d.ts +10 -0
- package/dist/demo/narration/merge.js +67 -0
- package/dist/demo/narration/narration.d.ts +39 -0
- 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 +8 -8
- 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 +19 -0
- package/dist/demo/overlay/cursor.js +142 -0
- package/dist/demo/overlay/device-stage.d.ts +26 -0
- package/dist/demo/overlay/device-stage.js +396 -0
- package/dist/demo/overlay/inpage/banner.d.ts +2 -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 +2 -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 +10 -0
- package/dist/demo/overlay/inpage/network.js +189 -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 +2 -0
- package/dist/demo/overlay/inpage/todos.js +293 -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 +31 -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 +61 -0
- package/dist/demo/overlay/rings.js +422 -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 +103 -0
- package/dist/demo/stepper/banner-log.d.ts +35 -0
- package/dist/demo/stepper/banner-log.js +65 -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 +48 -0
- package/dist/demo/stepper/demo-log.js +292 -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 +4 -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/panel-after.d.ts +17 -0
- package/dist/demo/stepper/panel-after.js +166 -0
- package/dist/demo/stepper/panel-before.d.ts +12 -0
- package/dist/demo/stepper/panel-before.js +241 -0
- package/dist/demo/stepper/slides.d.ts +23 -0
- package/dist/demo/stepper/slides.js +233 -0
- package/dist/demo/stepper/step-panels.d.ts +69 -0
- package/dist/demo/stepper/step-panels.js +172 -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 +47 -0
- package/dist/demo/stepper/teardown.js +178 -0
- package/dist/demo/stepper/todo-advance.d.ts +15 -0
- package/dist/demo/stepper/todo-advance.js +110 -0
- package/dist/demo/stepper/view.d.ts +58 -0
- package/dist/demo/stepper/view.js +31 -0
- package/dist/demo/types.d.ts +85 -0
- package/dist/demo/verbose-log.js +15 -0
- package/dist/engine/block/action-page.d.ts +53 -0
- package/dist/engine/block/action-page.js +1 -0
- package/dist/{types.d.ts → engine/block/block.d.ts} +102 -142
- package/dist/{core → engine/block}/block.js +12 -130
- package/dist/engine/block/branch.d.ts +17 -0
- package/dist/engine/block/branch.js +40 -0
- package/dist/{core → engine/block}/compose.d.ts +9 -7
- package/dist/{core → engine/block}/compose.js +1 -1
- package/dist/engine/block/dialog.d.ts +13 -0
- package/dist/engine/block/dialog.js +37 -0
- 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/engine/flow/map-branch.d.ts +9 -0
- package/dist/engine/flow/map-branch.js +57 -0
- package/dist/{core → engine/flow}/map-builder.d.ts +34 -54
- package/dist/engine/flow/map-builder.js +242 -0
- package/dist/engine/flow/map-steps.d.ts +30 -0
- package/dist/engine/flow/map-steps.js +87 -0
- 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/{trait.js → engine/trait/trait.js} +1 -1
- package/dist/index.d.ts +88 -36
- package/dist/index.js +46 -19
- package/dist/live/auto/auto.d.ts +22 -0
- package/dist/live/auto/auto.js +207 -0
- 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/live/auto/mem.d.ts +11 -0
- package/dist/live/auto/mem.js +85 -0
- package/dist/live/auto/menu.d.ts +30 -0
- package/dist/live/auto/menu.js +335 -0
- package/dist/live/auto-session/auto-session.d.ts +113 -0
- package/dist/live/auto-session/auto-session.js +452 -0
- package/dist/live/auto-session/console.d.ts +4 -0
- package/dist/live/auto-session/console.js +41 -0
- package/dist/live/auto-session/files.d.ts +44 -0
- package/dist/live/auto-session/files.js +145 -0
- package/dist/{auto-session → live/auto-session}/helpers.d.ts +9 -5
- package/dist/{auto-session → live/auto-session}/helpers.js +18 -1
- package/dist/live/auto-session/inspect.d.ts +4 -0
- package/dist/live/auto-session/inspect.js +75 -0
- package/dist/{session/auto-session-ipc.d.ts → live/auto-session/ipc.d.ts} +8 -25
- package/dist/{session/auto-session-ipc.js → live/auto-session/ipc.js} +36 -161
- package/dist/live/auto-session/open-browser.d.ts +6 -0
- package/dist/live/auto-session/open-browser.js +47 -0
- 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 +5 -4
- package/dist/{traverse/run.d.ts → live/traverse/traverse.d.ts} +1 -1
- package/dist/live/traverse/traverse.js +212 -0
- package/dist/live/traverse/worker.d.ts +37 -0
- package/dist/live/traverse/worker.js +200 -0
- 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 +14 -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/session.d.ts +0 -193
- package/dist/auto-session/session.js +0 -719
- 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/session.js +0 -600
- 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/map-builder.js +0 -383
- 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/run-phase.d.ts +0 -43
- 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/auto-explore-run.d.ts +0 -40
- package/dist/session/auto-explore-run.js +0 -707
- package/dist/session/step-overlay.d.ts +0 -37
- package/dist/session/step-overlay.js +0 -244
- package/dist/traverse/run.js +0 -423
- 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/{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
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { AutoSessionInit } from "
|
|
1
|
+
import type { AutoSessionInit } from "./helpers.js";
|
|
2
2
|
export interface BrowserStartInit extends AutoSessionInit {
|
|
3
3
|
/** Preset names or paths; resolved before spawn. */
|
|
4
4
|
injectTokens?: string[];
|
|
@@ -12,4 +12,3 @@ export interface BrowserStartResult {
|
|
|
12
12
|
}
|
|
13
13
|
/** Always spawns a new detached session — does not stop or reuse existing ones. */
|
|
14
14
|
export declare function browserStart(init: BrowserStartInit): Promise<BrowserStartResult>;
|
|
15
|
-
export { listBrowserSessions, stopBrowserSession, stopAllBrowserSessions, type SessionMeta, } from "./auto-session-ipc.js";
|
|
@@ -6,8 +6,8 @@
|
|
|
6
6
|
* Session lifecycle is explicit: `browser sessions` lists what's live;
|
|
7
7
|
* `browser start` always opens another; `browser attach` / `browser stop` pick one up or shut it down.
|
|
8
8
|
*/
|
|
9
|
-
import { spawnDetachedSession } from "./
|
|
10
|
-
import { resolveInjectRoots } from "
|
|
9
|
+
import { spawnDetachedSession } from "./ipc.js";
|
|
10
|
+
import { resolveInjectRoots } from "../../manifest/roots.js";
|
|
11
11
|
/** Always spawns a new detached session — does not stop or reuse existing ones. */
|
|
12
12
|
export async function browserStart(init) {
|
|
13
13
|
const inject = init.inject ??
|
|
@@ -26,4 +26,3 @@ export async function browserStart(init) {
|
|
|
26
26
|
inject,
|
|
27
27
|
};
|
|
28
28
|
}
|
|
29
|
-
export { listBrowserSessions, stopBrowserSession, stopAllBrowserSessions, } from "./auto-session-ipc.js";
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { SessionSnapshot } from "../auto-session.js";
|
|
1
|
+
import type { SessionSnapshot } from "../auto-session/helpers.js";
|
|
2
2
|
import type { Page } from "@playwright/test";
|
|
3
3
|
/** Minimal shape needed to render the graph tree - matches WaygraphGraph. */
|
|
4
4
|
interface PilotOverlayGraph {
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { ensureInstalled } from "
|
|
1
|
+
import { ensureInstalled } from "../../demo/overlay/pilot/shell.js";
|
|
2
|
+
import { ignorePageGone } from "../../engine/page-gone.js";
|
|
2
3
|
/**
|
|
3
4
|
* Refreshes the badge text and the (possibly-collapsed) panel's two tabs
|
|
4
5
|
* ("Here" - current live menu; "All nodes" - whole project graph as a
|
|
@@ -10,6 +11,8 @@ export async function updatePilotOverlay(page, info) {
|
|
|
10
11
|
await ensureInstalled(page);
|
|
11
12
|
await page
|
|
12
13
|
.evaluate(async ({ sessionId, snapshot, graph }) => {
|
|
14
|
+
// Block names, labels and descriptions can carry the page's own text (an Effect's instance label is read off
|
|
15
|
+
// the live DOM), so they go in as text nodes (__wgEl), never as markup.
|
|
13
16
|
const badge = __wgById("wg-pilot-badge");
|
|
14
17
|
const current = __wgById("wg-pilot-panel-current");
|
|
15
18
|
const graphPanel = __wgById("wg-pilot-panel-graph");
|
|
@@ -21,26 +24,16 @@ export async function updatePilotOverlay(page, info) {
|
|
|
21
24
|
badge.textContent = `Waygraph Pilot - ${idPart} - ${hereLabel}`;
|
|
22
25
|
const totalEdges = snapshot.sections.reduce((n, s) => n + s.edges.length, 0);
|
|
23
26
|
if (totalEdges === 0) {
|
|
24
|
-
current.
|
|
25
|
-
? '<div class="wg-pilot-empty">Blank page — no Block moves yet. Use auto goto or a nav Block when ready.</div>'
|
|
26
|
-
: '<div class="wg-pilot-empty">No Block moves from here right now.</div>';
|
|
27
|
+
__wgSet(current, __wgEl("div", { class: "wg-pilot-empty" }, onBlank ? "Blank page — no Block moves yet. Use auto goto or a nav Block when ready." : "No Block moves from here right now."));
|
|
27
28
|
}
|
|
28
29
|
else {
|
|
29
|
-
current
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
const desc = edge.description ? ` - ${edge.description}` : "";
|
|
34
|
-
const label = edge.label ? ` (${edge.label})` : "";
|
|
35
|
-
return `<div class="wg-pilot-edge">[${edge.index}] <span class="wg-pilot-kind">${edge.kind}</span> ${edge.block}${label} -> ${edge.to}${desc}</div>`;
|
|
36
|
-
})
|
|
37
|
-
.join("");
|
|
38
|
-
return `<div class="wg-pilot-section">${section.title}</div>${rows}`;
|
|
39
|
-
})
|
|
40
|
-
.join("");
|
|
30
|
+
__wgSet(current, snapshot.sections.map((section) => [
|
|
31
|
+
__wgEl("div", { class: "wg-pilot-section" }, section.title),
|
|
32
|
+
section.edges.map((edge) => __wgEl("div", { class: "wg-pilot-edge" }, `[${edge.index}] `, __wgEl("span", { class: "wg-pilot-kind" }, edge.kind), ` ${edge.block}${edge.label ? ` (${edge.label})` : ""} -> ${edge.to}${edge.description ? ` - ${edge.description}` : ""}`)),
|
|
33
|
+
]));
|
|
41
34
|
}
|
|
42
35
|
if (!graph || graph.nodes.length === 0) {
|
|
43
|
-
graphPanel
|
|
36
|
+
__wgSet(graphPanel, __wgEl("div", { class: "wg-pilot-empty" }, "No graph data yet."));
|
|
44
37
|
return;
|
|
45
38
|
}
|
|
46
39
|
// Flat indented-text tree - the ORIGINAL "All nodes" rendering.
|
|
@@ -49,18 +42,14 @@ export async function updatePilotOverlay(page, info) {
|
|
|
49
42
|
// when Mermaid genuinely can't load (e.g. offline), not the primary
|
|
50
43
|
// rendering anymore.
|
|
51
44
|
const renderTextTree = () => {
|
|
52
|
-
graphPanel
|
|
53
|
-
.map((node) => {
|
|
45
|
+
__wgSet(graphPanel, graph.nodes.map((node) => {
|
|
54
46
|
const outgoing = graph.edges.filter((e) => e.from === node.checkpoint || e.from === "*");
|
|
55
47
|
const rows = outgoing.length
|
|
56
|
-
? outgoing
|
|
57
|
-
|
|
58
|
-
.join("")
|
|
59
|
-
: '<div class="wg-pilot-graph-edge wg-pilot-empty">(no outgoing edges)</div>';
|
|
48
|
+
? outgoing.map((e) => __wgEl("div", { class: "wg-pilot-graph-edge" }, __wgEl("span", { class: "wg-pilot-kind" }, e.kind), ` ${e.block} -> ${e.to}`))
|
|
49
|
+
: [__wgEl("div", { class: "wg-pilot-graph-edge wg-pilot-empty" }, "(no outgoing edges)")];
|
|
60
50
|
const here = node.checkpoint === snapshot.here ? " (here)" : "";
|
|
61
|
-
return
|
|
62
|
-
})
|
|
63
|
-
.join("");
|
|
51
|
+
return __wgEl("div", { class: "wg-pilot-graph-node" }, __wgEl("div", { class: "wg-pilot-graph-checkpoint" }, node.checkpoint + here), rows);
|
|
52
|
+
}));
|
|
64
53
|
};
|
|
65
54
|
try {
|
|
66
55
|
const w = window;
|
|
@@ -80,10 +69,11 @@ export async function updatePilotOverlay(page, info) {
|
|
|
80
69
|
throw new Error("mermaid did not attach to window after load");
|
|
81
70
|
// Real, direct user request: "left to right stuff. maybe mermaid?
|
|
82
71
|
// with square ish arrows???" - LR layout, linear (non-curvy) edges.
|
|
83
|
-
|
|
72
|
+
// strict: Mermaid escapes label text itself; plain SVG labels (no HTML) so the result parses as SVG.
|
|
73
|
+
w.mermaid.initialize({ startOnLoad: false, theme: "dark", securityLevel: "strict", flowchart: { curve: "linear", htmlLabels: false } });
|
|
84
74
|
const sanitize = (s) => s.replace(/[^A-Za-z0-9_]/g, "_");
|
|
85
75
|
// Every Nav Block gets a `from:"*"` wildcard edge for pathfinding
|
|
86
|
-
// (see auto
|
|
76
|
+
// (see live/auto/explore.ts's own isUrlNav comment). Real, screenshot-
|
|
87
77
|
// confirmed finding, TWICE over:
|
|
88
78
|
// 1. Collapsing all of these into one shared "Anywhere" hub node
|
|
89
79
|
// still broke the layout - ~9 of 10 Checkpoints have their own
|
|
@@ -137,8 +127,10 @@ export async function updatePilotOverlay(page, info) {
|
|
|
137
127
|
lines.push(` ${sanitize(e.from)} -->|${e.block}| ${sanitize(e.to)}`);
|
|
138
128
|
}
|
|
139
129
|
const { svg } = await w.mermaid.render(`wg-mermaid-${Date.now()}`, lines.join("\n"));
|
|
140
|
-
|
|
141
|
-
|
|
130
|
+
const diagram = __wgSvg(svg);
|
|
131
|
+
if (diagram.nodeName !== "svg")
|
|
132
|
+
throw new Error("mermaid output did not parse as SVG");
|
|
133
|
+
__wgSet(graphPanel, diagram, __wgEl("div", { class: "wg-pilot-graph-note" }, '[nav] = also directly reachable via sidebar/URL from anywhere (not drawn as an edge - see the "Here" tab for what\'s live on this page).'));
|
|
142
134
|
// Real, direct user request: "i hope it is zoomed to the current
|
|
143
135
|
// node" - the diagram is usually bigger than the panel, so scroll
|
|
144
136
|
// (not zoom - the SVG itself stays real size, legible) the "here"
|
|
@@ -151,5 +143,5 @@ export async function updatePilotOverlay(page, info) {
|
|
|
151
143
|
renderTextTree();
|
|
152
144
|
}
|
|
153
145
|
}, { sessionId: info.sessionId, snapshot: info.snapshot, graph: info.graph ?? null })
|
|
154
|
-
.catch(
|
|
146
|
+
.catch(ignorePageGone);
|
|
155
147
|
}
|
|
@@ -28,9 +28,9 @@
|
|
|
28
28
|
* hand-picking indices from each status response) that proved this needs no
|
|
29
29
|
* new execution primitive.
|
|
30
30
|
*/
|
|
31
|
-
import { type WaygraphGraph } from "
|
|
32
|
-
import {
|
|
33
|
-
import type
|
|
31
|
+
import { type WaygraphGraph } from "../../analysis/graph.js";
|
|
32
|
+
import type { SessionSnapshot } from "../auto-session/helpers.js";
|
|
33
|
+
import { type BrowserStartInit } from "../auto-session/start.js";
|
|
34
34
|
/** What `pilotStart` returns: the session id, socket path and first snapshot. */
|
|
35
35
|
export interface PilotStartResult {
|
|
36
36
|
sessionId: string;
|
|
@@ -28,9 +28,10 @@
|
|
|
28
28
|
* hand-picking indices from each status response) that proved this needs no
|
|
29
29
|
* new execution primitive.
|
|
30
30
|
*/
|
|
31
|
-
import { discoverGraph } from "
|
|
32
|
-
import {
|
|
33
|
-
import {
|
|
31
|
+
import { discoverGraph } from "../../analysis/graph.js";
|
|
32
|
+
import { resolveSessionMeta } from "../auto-session/files.js";
|
|
33
|
+
import { requestSession, } from "../auto-session/ipc.js";
|
|
34
|
+
import { browserStart } from "../auto-session/start.js";
|
|
34
35
|
/**
|
|
35
36
|
* Starts a detached session and reads back its own graph + starting
|
|
36
37
|
* snapshot in one call, so an agent bootstraps with everything it needs
|
|
@@ -39,7 +40,7 @@ import { browserStart } from "./browser.js";
|
|
|
39
40
|
* --detach` and `waygraph graph` itself.
|
|
40
41
|
*/
|
|
41
42
|
export async function pilotStart(init) {
|
|
42
|
-
const { resolveInjectRoots } = await import("
|
|
43
|
+
const { resolveInjectRoots } = await import("../../manifest/roots.js");
|
|
43
44
|
const exploreInject = init.inject ??
|
|
44
45
|
(init.injectTokens?.length ? resolveInjectRoots(init.injectTokens, init.projectDir) : undefined);
|
|
45
46
|
const started = await browserStart({
|
|
@@ -28,7 +28,7 @@ export interface TraverseOptions {
|
|
|
28
28
|
/** Traverse id for greppable lines (default traverse-1). */
|
|
29
29
|
traverseId?: string;
|
|
30
30
|
/** Phase C: glob / regex / bare `--blocks` file select. */
|
|
31
|
-
blocksSelect?: import("
|
|
31
|
+
blocksSelect?: import("../../manifest/select.js").BlocksSelect;
|
|
32
32
|
/** Phase D: parallel workers (default 1). Cap 4. */
|
|
33
33
|
parallel?: number;
|
|
34
34
|
/** Phase D: clone (default) or inherit. Inherit refused when parallel > 1. */
|
|
@@ -0,0 +1,212 @@
|
|
|
1
|
+
import { Engine } from "../../engine/engine.js";
|
|
2
|
+
import { envFlag, envString } from "../../engine/env.js";
|
|
3
|
+
import { MemPage } from "../../engine/mem/mem.js";
|
|
4
|
+
import { ignorePageGone, ignoreTimeout } from "../../engine/page-gone.js";
|
|
5
|
+
import { chromiumExecutablePath } from "../../runtime/browser.js";
|
|
6
|
+
import { resolveBaseUrl } from "../../runtime/waygraph-config.js";
|
|
7
|
+
import { buildExploreContext, } from "../auto/explore.js";
|
|
8
|
+
import { buildCoverageReport, collectGraphEdgeKeys, defaultCoverageOutPath, formatCoverageLine, writeCoverageReport, } from "./coverage.js";
|
|
9
|
+
import { EdgeLeaseCoordinator } from "./lease.js";
|
|
10
|
+
import { restoreMem, runTraverseWorker, seedMem, snapshotMem } from "./worker.js";
|
|
11
|
+
/**
|
|
12
|
+
* Serial or parallel graph crawl. Prints greppable PASS/FAIL + Coverage lines.
|
|
13
|
+
* Exit: 0 leaf ok (+ coverage ok), 1 break/timeout, 2 coverage gate fail (Phase E).
|
|
14
|
+
*/
|
|
15
|
+
export async function runTraverse(projectDir, options = {}) {
|
|
16
|
+
let parallel = Math.max(1, Math.floor(options.parallel ?? 1));
|
|
17
|
+
if (parallel > 4) {
|
|
18
|
+
console.error(`waygraph traverse: --parallel ${parallel} capped to 4`);
|
|
19
|
+
parallel = 4;
|
|
20
|
+
}
|
|
21
|
+
const session = options.session ?? (parallel > 1 ? "clone" : "clone");
|
|
22
|
+
if (parallel > 1 && session === "inherit") {
|
|
23
|
+
console.error("waygraph traverse: --session inherit is refused with --parallel > 1 (races); use --session clone");
|
|
24
|
+
return 1;
|
|
25
|
+
}
|
|
26
|
+
const maxSteps = options.maxSteps ?? 50;
|
|
27
|
+
const maxVisitsPerNode = options.maxVisitsPerNode ?? 2;
|
|
28
|
+
const maxVisitsPerEdge = options.maxVisitsPerEdge ?? 1;
|
|
29
|
+
const timeoutMs = options.timeoutMs ?? 15 * 60_000;
|
|
30
|
+
const headed = options.headed === true || envFlag("WAYGRAPH_HEADED");
|
|
31
|
+
const baseURL = options.baseURL ?? (await resolveBaseUrl(projectDir)) ?? envString("WAYGRAPH_BASE_URL");
|
|
32
|
+
const startUrl = options.startUrl ?? baseURL;
|
|
33
|
+
const minEdgeCoverage = options.minEdgeCoverage != null && Number.isFinite(options.minEdgeCoverage)
|
|
34
|
+
? options.minEdgeCoverage
|
|
35
|
+
: undefined;
|
|
36
|
+
const coverageOut = options.coverageOut ?? defaultCoverageOutPath(projectDir);
|
|
37
|
+
const { graph, library } = await buildExploreContext(projectDir, options.blocksSelect ? { blocksSelect: options.blocksSelect } : undefined);
|
|
38
|
+
if (options.blocksSelect) {
|
|
39
|
+
console.error(`waygraph traverse: --blocks ${options.blocksSelect.raw} -> ` +
|
|
40
|
+
`${library.byName.size} block(s), ${graph.edges.length} edge(s)`);
|
|
41
|
+
}
|
|
42
|
+
const allEdgeKeys = collectGraphEdgeKeys(graph.edges);
|
|
43
|
+
const leases = new EdgeLeaseCoordinator({ projectDir, persist: parallel > 1 });
|
|
44
|
+
const engine = new Engine({ headless: !headed, slowMo: headed ? 100 : 0 });
|
|
45
|
+
if (envString("WAYGRAPH_EXTENSIONS"))
|
|
46
|
+
console.error("waygraph traverse: extensions are not loaded (workers use plain contexts)");
|
|
47
|
+
const { chromium } = await import("@playwright/test");
|
|
48
|
+
const executablePath = chromiumExecutablePath();
|
|
49
|
+
const launchOpts = {
|
|
50
|
+
headless: !headed,
|
|
51
|
+
};
|
|
52
|
+
if (executablePath)
|
|
53
|
+
launchOpts.executablePath = executablePath;
|
|
54
|
+
const browser = await chromium.launch(launchOpts);
|
|
55
|
+
console.error(`waygraph traverse: ${graph.nodes.length} node(s), ${graph.edges.length} edge(s)` +
|
|
56
|
+
(baseURL ? ` base=${baseURL}` : "") +
|
|
57
|
+
` parallel=${parallel} session=${session}` +
|
|
58
|
+
` maxSteps=${maxSteps} maxVisits/node=${maxVisitsPerNode} maxVisits/edge=${maxVisitsPerEdge}` +
|
|
59
|
+
(minEdgeCoverage !== undefined
|
|
60
|
+
? ` minEdgeCoverage=${(minEdgeCoverage * 100).toFixed(1)}%`
|
|
61
|
+
: ""));
|
|
62
|
+
const emitCoverage = (workers) => {
|
|
63
|
+
const hitUnion = new Set();
|
|
64
|
+
for (const w of workers) {
|
|
65
|
+
for (const k of w.result.edgesHit)
|
|
66
|
+
hitUnion.add(k);
|
|
67
|
+
}
|
|
68
|
+
const report = buildCoverageReport({
|
|
69
|
+
projectDir,
|
|
70
|
+
parallel,
|
|
71
|
+
allEdgeKeys,
|
|
72
|
+
hitKeys: hitUnion,
|
|
73
|
+
...(minEdgeCoverage !== undefined ? { minEdgeCoverage } : {}),
|
|
74
|
+
workers: workers.map(({ traverseId, result }) => ({
|
|
75
|
+
traverseId,
|
|
76
|
+
exitCode: result.exitCode,
|
|
77
|
+
steps: result.steps,
|
|
78
|
+
edgesHit: result.edgesHit.length,
|
|
79
|
+
...(result.leaf ? { leaf: result.leaf } : {}),
|
|
80
|
+
})),
|
|
81
|
+
});
|
|
82
|
+
console.log(formatCoverageLine(report));
|
|
83
|
+
console.error(`waygraph traverse: coverage hit=${report.edgesHit}/${report.edgesTotal}` +
|
|
84
|
+
(report.missed.length
|
|
85
|
+
? ` missed=${report.missed.slice(0, 8).join(",")}${report.missed.length > 8 ? "..." : ""}`
|
|
86
|
+
: "") +
|
|
87
|
+
(options.noCoverageReport ? "" : ` report=${coverageOut}`));
|
|
88
|
+
if (!options.noCoverageReport) {
|
|
89
|
+
writeCoverageReport(coverageOut, report);
|
|
90
|
+
}
|
|
91
|
+
if (report.coveragePass === false) {
|
|
92
|
+
console.error(`waygraph traverse: FAIL coverage gate ratio=${(report.ratio * 100).toFixed(1)}%` +
|
|
93
|
+
` < min=${((report.minEdgeCoverage ?? 0) * 100).toFixed(1)}%`);
|
|
94
|
+
return 2;
|
|
95
|
+
}
|
|
96
|
+
return 0;
|
|
97
|
+
};
|
|
98
|
+
try {
|
|
99
|
+
if (parallel <= 1) {
|
|
100
|
+
const contextOpts = {
|
|
101
|
+
viewport: { width: 1280, height: 720 },
|
|
102
|
+
};
|
|
103
|
+
if (baseURL)
|
|
104
|
+
contextOpts.baseURL = baseURL;
|
|
105
|
+
const context = await browser.newContext(contextOpts);
|
|
106
|
+
const page = await context.newPage();
|
|
107
|
+
const mem = new MemPage();
|
|
108
|
+
seedMem(library.byName, mem, options.data);
|
|
109
|
+
if (startUrl) {
|
|
110
|
+
await page.goto(startUrl, { waitUntil: "domcontentloaded" }).catch(ignorePageGone);
|
|
111
|
+
await page.waitForLoadState("load").catch(ignoreTimeout);
|
|
112
|
+
}
|
|
113
|
+
const traverseId = options.traverseId ?? "traverse-1";
|
|
114
|
+
const result = await runTraverseWorker({
|
|
115
|
+
traverseId,
|
|
116
|
+
workerIndex: 0,
|
|
117
|
+
parallel: 1,
|
|
118
|
+
maxSteps,
|
|
119
|
+
maxVisitsPerNode,
|
|
120
|
+
maxVisitsPerEdge,
|
|
121
|
+
timeoutMs,
|
|
122
|
+
...(options.from ? { from: options.from } : {}),
|
|
123
|
+
...(startUrl ? { startUrl } : {}),
|
|
124
|
+
...(baseURL ? { baseURL } : {}),
|
|
125
|
+
...(options.data ? { data: options.data } : {}),
|
|
126
|
+
graph,
|
|
127
|
+
library,
|
|
128
|
+
engine,
|
|
129
|
+
context,
|
|
130
|
+
page,
|
|
131
|
+
mem,
|
|
132
|
+
leases,
|
|
133
|
+
});
|
|
134
|
+
await context.close().catch(ignorePageGone);
|
|
135
|
+
const coverageCode = emitCoverage([{ traverseId, result }]);
|
|
136
|
+
if (result.exitCode !== 0)
|
|
137
|
+
return result.exitCode;
|
|
138
|
+
return coverageCode;
|
|
139
|
+
}
|
|
140
|
+
// Phase D: bootstrap one context for storageState, then N clones.
|
|
141
|
+
const bootOpts = {
|
|
142
|
+
viewport: { width: 1280, height: 720 },
|
|
143
|
+
};
|
|
144
|
+
if (baseURL)
|
|
145
|
+
bootOpts.baseURL = baseURL;
|
|
146
|
+
const bootContext = await browser.newContext(bootOpts);
|
|
147
|
+
const bootPage = await bootContext.newPage();
|
|
148
|
+
const bootMem = new MemPage();
|
|
149
|
+
seedMem(library.byName, bootMem, options.data);
|
|
150
|
+
if (startUrl) {
|
|
151
|
+
await bootPage.goto(startUrl, { waitUntil: "domcontentloaded" }).catch(ignorePageGone);
|
|
152
|
+
await bootPage.waitForLoadState("load").catch(ignoreTimeout);
|
|
153
|
+
}
|
|
154
|
+
const storageState = await bootContext.storageState();
|
|
155
|
+
const memSnap = snapshotMem(library.byName, bootMem);
|
|
156
|
+
await bootContext.close().catch(ignorePageGone);
|
|
157
|
+
console.error(`waygraph traverse: forked ${parallel} clone workers (storageState + mem snapshot)`);
|
|
158
|
+
const workerMeta = await Promise.all(Array.from({ length: parallel }, async (_, i) => {
|
|
159
|
+
const traverseId = `traverse-${i + 1}`;
|
|
160
|
+
const ctxOpts = {
|
|
161
|
+
viewport: { width: 1280, height: 720 },
|
|
162
|
+
storageState,
|
|
163
|
+
};
|
|
164
|
+
if (baseURL)
|
|
165
|
+
ctxOpts.baseURL = baseURL;
|
|
166
|
+
const context = await browser.newContext(ctxOpts);
|
|
167
|
+
const page = await context.newPage();
|
|
168
|
+
const mem = new MemPage();
|
|
169
|
+
restoreMem(library.byName, mem, memSnap, options.data);
|
|
170
|
+
if (startUrl) {
|
|
171
|
+
await page.goto(startUrl, { waitUntil: "domcontentloaded" }).catch(ignorePageGone);
|
|
172
|
+
}
|
|
173
|
+
try {
|
|
174
|
+
const result = await runTraverseWorker({
|
|
175
|
+
traverseId,
|
|
176
|
+
workerIndex: i,
|
|
177
|
+
parallel,
|
|
178
|
+
maxSteps,
|
|
179
|
+
maxVisitsPerNode,
|
|
180
|
+
maxVisitsPerEdge,
|
|
181
|
+
timeoutMs,
|
|
182
|
+
...(options.from ? { from: options.from } : {}),
|
|
183
|
+
...(startUrl ? { startUrl } : {}),
|
|
184
|
+
...(baseURL ? { baseURL } : {}),
|
|
185
|
+
...(options.data ? { data: options.data } : {}),
|
|
186
|
+
graph,
|
|
187
|
+
library,
|
|
188
|
+
engine,
|
|
189
|
+
context,
|
|
190
|
+
page,
|
|
191
|
+
mem,
|
|
192
|
+
leases,
|
|
193
|
+
});
|
|
194
|
+
return { traverseId, result };
|
|
195
|
+
}
|
|
196
|
+
finally {
|
|
197
|
+
await context.close().catch(ignorePageGone);
|
|
198
|
+
}
|
|
199
|
+
}));
|
|
200
|
+
const results = workerMeta.map((w) => w.result);
|
|
201
|
+
const worst = results.reduce((a, b) => Math.max(a, b.exitCode), 0);
|
|
202
|
+
const pass = results.filter((c) => c.exitCode === 0).length;
|
|
203
|
+
console.error(`waygraph traverse: suite parallel=${parallel} pass=${pass}/${parallel} exit=${worst}`);
|
|
204
|
+
const coverageCode = emitCoverage(workerMeta);
|
|
205
|
+
if (worst !== 0)
|
|
206
|
+
return worst;
|
|
207
|
+
return coverageCode;
|
|
208
|
+
}
|
|
209
|
+
finally {
|
|
210
|
+
await browser.close().catch(ignorePageGone);
|
|
211
|
+
}
|
|
212
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import type { BrowserContext, Page } from "@playwright/test";
|
|
2
|
+
import type { WaygraphGraph } from "../../analysis/graph.js";
|
|
3
|
+
import type { Checkpoint } from "../../engine/checkpoint/checkpoint.js";
|
|
4
|
+
import { Engine } from "../../engine/engine.js";
|
|
5
|
+
import { MemPage, type MemKey } from "../../engine/mem/mem.js";
|
|
6
|
+
import type { BlockEntry } from "../../manifest/project.js";
|
|
7
|
+
import { buildExploreContext, type ExploreEdge } from "../auto/explore.js";
|
|
8
|
+
import { EdgeLeaseCoordinator } from "./lease.js";
|
|
9
|
+
import type { TraverseWorkerResult } from "./traverse.js";
|
|
10
|
+
export declare function seedMem(library: Map<string, BlockEntry>, mem: MemPage, dataJson?: string): void;
|
|
11
|
+
export declare function snapshotMem(library: Map<string, BlockEntry>, mem: MemPage): Record<string, unknown>;
|
|
12
|
+
export declare function restoreMem(library: Map<string, BlockEntry>, mem: MemPage, snap: Record<string, unknown>, dataJson?: string): void;
|
|
13
|
+
export declare function missingMemKeys(entry: BlockEntry, mem: MemPage): MemKey<unknown>[];
|
|
14
|
+
export declare function ensureMem(entry: BlockEntry, mem: MemPage): void;
|
|
15
|
+
export declare function edgeKey(edge: ExploreEdge): string;
|
|
16
|
+
export declare function runOneBlock(engine: Engine, entry: BlockEntry, context: BrowserContext, page: Page, mem: MemPage): Promise<Checkpoint<string>>;
|
|
17
|
+
export interface WorkerOpts {
|
|
18
|
+
traverseId: string;
|
|
19
|
+
workerIndex: number;
|
|
20
|
+
parallel: number;
|
|
21
|
+
maxSteps: number;
|
|
22
|
+
maxVisitsPerNode: number;
|
|
23
|
+
maxVisitsPerEdge: number;
|
|
24
|
+
timeoutMs: number;
|
|
25
|
+
from?: string;
|
|
26
|
+
startUrl?: string;
|
|
27
|
+
baseURL?: string;
|
|
28
|
+
data?: string;
|
|
29
|
+
graph: WaygraphGraph;
|
|
30
|
+
library: Awaited<ReturnType<typeof buildExploreContext>>["library"];
|
|
31
|
+
engine: Engine;
|
|
32
|
+
context: BrowserContext;
|
|
33
|
+
page: Page;
|
|
34
|
+
mem: MemPage;
|
|
35
|
+
leases: EdgeLeaseCoordinator;
|
|
36
|
+
}
|
|
37
|
+
export declare function runTraverseWorker(opts: WorkerOpts): Promise<TraverseWorkerResult>;
|
|
@@ -0,0 +1,200 @@
|
|
|
1
|
+
import { envString } from "../../engine/env.js";
|
|
2
|
+
import { buildFlow } from "../../engine/flow/flow.js";
|
|
3
|
+
import { ignorePageGone } from "../../engine/page-gone.js";
|
|
4
|
+
import { detectHere } from "../auto/auto.js";
|
|
5
|
+
import { buildExploreMenu } from "../auto/explore.js";
|
|
6
|
+
import { memStubValue } from "../auto/mem.js";
|
|
7
|
+
import { EdgeLeaseCoordinator } from "./lease.js";
|
|
8
|
+
export function seedMem(library, mem, dataJson) {
|
|
9
|
+
const raw = dataJson ?? envString("WAYGRAPH_DATA") ?? envString("WAYGRAPH_AUTO_MEM");
|
|
10
|
+
let envParsed = {};
|
|
11
|
+
if (raw) {
|
|
12
|
+
try {
|
|
13
|
+
envParsed = JSON.parse(raw);
|
|
14
|
+
}
|
|
15
|
+
catch {
|
|
16
|
+
throw new Error(`waygraph traverse: --data / WAYGRAPH_DATA is not valid JSON`);
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
for (const entry of library.values()) {
|
|
20
|
+
for (const k of entry.block.requires ?? []) {
|
|
21
|
+
if (mem.has(k))
|
|
22
|
+
continue;
|
|
23
|
+
if (k.name in envParsed) {
|
|
24
|
+
mem.set(k, envParsed[k.name]);
|
|
25
|
+
continue;
|
|
26
|
+
}
|
|
27
|
+
const def = memStubValue(k);
|
|
28
|
+
if (def !== undefined)
|
|
29
|
+
mem.set(k, def);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
export function snapshotMem(library, mem) {
|
|
34
|
+
const out = {};
|
|
35
|
+
for (const entry of library.values()) {
|
|
36
|
+
for (const k of entry.block.requires ?? []) {
|
|
37
|
+
if (mem.has(k) && !(k.name in out)) {
|
|
38
|
+
out[k.name] = mem.get(k);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
return out;
|
|
43
|
+
}
|
|
44
|
+
export function restoreMem(library, mem, snap, dataJson) {
|
|
45
|
+
seedMem(library, mem, dataJson);
|
|
46
|
+
for (const entry of library.values()) {
|
|
47
|
+
for (const k of entry.block.requires ?? []) {
|
|
48
|
+
if (k.name in snap) {
|
|
49
|
+
mem.set(k, snap[k.name]);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
export function missingMemKeys(entry, mem) {
|
|
55
|
+
return (entry.block.requires ?? []).filter((k) => !mem.has(k));
|
|
56
|
+
}
|
|
57
|
+
export function ensureMem(entry, mem) {
|
|
58
|
+
const missing = missingMemKeys(entry, mem);
|
|
59
|
+
if (missing.length === 0)
|
|
60
|
+
return;
|
|
61
|
+
throw new Error(`Block "${entry.block.name}" needs Mem keys: ${missing.map((k) => k.name).join(", ")} ` +
|
|
62
|
+
`(pass --data '{...}' or WAYGRAPH_DATA)`);
|
|
63
|
+
}
|
|
64
|
+
export function edgeKey(edge) {
|
|
65
|
+
const id = edge.instanceOption?.id;
|
|
66
|
+
return id ? `${edge.block}::${id}` : edge.block;
|
|
67
|
+
}
|
|
68
|
+
export async function runOneBlock(engine, entry, context, page, mem) {
|
|
69
|
+
const flow = buildFlow([entry.block], engine.config);
|
|
70
|
+
const BLOCK_TIMEOUT_MS = 45000;
|
|
71
|
+
let timer;
|
|
72
|
+
try {
|
|
73
|
+
const ran = await Promise.race([
|
|
74
|
+
flow.run(context, mem, { page, closeOnFinish: false }),
|
|
75
|
+
new Promise((_, reject) => {
|
|
76
|
+
timer = setTimeout(() => reject(new Error(`Block "${entry.block.name}" timed out after ${BLOCK_TIMEOUT_MS / 1000}s`)), BLOCK_TIMEOUT_MS);
|
|
77
|
+
}),
|
|
78
|
+
]);
|
|
79
|
+
return ran.result;
|
|
80
|
+
}
|
|
81
|
+
finally {
|
|
82
|
+
if (timer)
|
|
83
|
+
clearTimeout(timer);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
export async function runTraverseWorker(opts) {
|
|
87
|
+
const { traverseId, workerIndex, parallel, maxSteps, maxVisitsPerNode, maxVisitsPerEdge, timeoutMs, graph, library, engine, context, mem, leases, } = opts;
|
|
88
|
+
let page = opts.page;
|
|
89
|
+
const startUrl = opts.startUrl;
|
|
90
|
+
const nodeVisits = new Map();
|
|
91
|
+
const edgeVisits = new Map();
|
|
92
|
+
const edgesHit = new Set();
|
|
93
|
+
let steps = 0;
|
|
94
|
+
const startedAt = Date.now();
|
|
95
|
+
let lastHere = opts.from ?? null;
|
|
96
|
+
let exitCode = 0;
|
|
97
|
+
let leaf;
|
|
98
|
+
try {
|
|
99
|
+
for (;;) {
|
|
100
|
+
if (Date.now() - startedAt > timeoutMs) {
|
|
101
|
+
console.log(`[Killed timeout[${traverseId}] node=${lastHere ?? "?"} wallMs=${timeoutMs}]`);
|
|
102
|
+
exitCode = 1;
|
|
103
|
+
break;
|
|
104
|
+
}
|
|
105
|
+
if (steps >= maxSteps) {
|
|
106
|
+
console.log(`[Killed max-steps[${traverseId}] node=${lastHere ?? "?"} steps=${steps} max=${maxSteps}]`);
|
|
107
|
+
exitCode = 1;
|
|
108
|
+
break;
|
|
109
|
+
}
|
|
110
|
+
if (page.isClosed()) {
|
|
111
|
+
page = await context.newPage();
|
|
112
|
+
if (startUrl) {
|
|
113
|
+
await page.goto(startUrl, { waitUntil: "domcontentloaded" }).catch(ignorePageGone);
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
const detected = await detectHere(page, library.navBlocks);
|
|
117
|
+
const here = lastHere ?? detected ?? opts.from ?? null;
|
|
118
|
+
if (here && (nodeVisits.get(here) ?? 0) >= maxVisitsPerNode) {
|
|
119
|
+
console.log(`[Killed loop[${traverseId}] node=${here} visits=${nodeVisits.get(here)} max=${maxVisitsPerNode}]`);
|
|
120
|
+
exitCode = 1;
|
|
121
|
+
break;
|
|
122
|
+
}
|
|
123
|
+
const menu = await buildExploreMenu(page, graph, library, here);
|
|
124
|
+
const candidates = menu.flat.filter((edge) => {
|
|
125
|
+
const key = edgeKey(edge);
|
|
126
|
+
if ((edgeVisits.get(key) ?? 0) >= maxVisitsPerEdge)
|
|
127
|
+
return false;
|
|
128
|
+
if (parallel > 1) {
|
|
129
|
+
if (EdgeLeaseCoordinator.partitionIndex(key, parallel) !== workerIndex) {
|
|
130
|
+
return false;
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
return true;
|
|
134
|
+
});
|
|
135
|
+
if (candidates.length === 0) {
|
|
136
|
+
const label = here ?? detected ?? "unknown";
|
|
137
|
+
leaf = label;
|
|
138
|
+
console.log(`[Reached Leaf Node[${traverseId}] at=${label} steps=${steps}]`);
|
|
139
|
+
console.error(`waygraph traverse[${traverseId}]: PASS leaf edgesHit=${edgesHit.size} steps=${steps}`);
|
|
140
|
+
break;
|
|
141
|
+
}
|
|
142
|
+
const pick = [...candidates].sort((a, b) => {
|
|
143
|
+
const aWild = a.from === "*" ? 1 : 0;
|
|
144
|
+
const bWild = b.from === "*" ? 1 : 0;
|
|
145
|
+
if (aWild !== bWild)
|
|
146
|
+
return aWild - bWild;
|
|
147
|
+
return edgeKey(a).localeCompare(edgeKey(b));
|
|
148
|
+
})[0];
|
|
149
|
+
const key = edgeKey(pick);
|
|
150
|
+
if (!leases.tryClaim(key, traverseId)) {
|
|
151
|
+
// Another worker won a race (instance fan-out); treat as unavailable.
|
|
152
|
+
edgeVisits.set(key, maxVisitsPerEdge);
|
|
153
|
+
continue;
|
|
154
|
+
}
|
|
155
|
+
const entry = library.byName.get(pick.block);
|
|
156
|
+
if (!entry) {
|
|
157
|
+
console.log(`[Broke at edge[${traverseId}] block=${pick.block} from=${here ?? "?"} to=${pick.to} reason=not-loaded]`);
|
|
158
|
+
exitCode = 1;
|
|
159
|
+
break;
|
|
160
|
+
}
|
|
161
|
+
const fromLabel = here ?? pick.from;
|
|
162
|
+
try {
|
|
163
|
+
if (pick.instanceOption) {
|
|
164
|
+
mem.set(pick.instanceOption.key, pick.instanceOption.value);
|
|
165
|
+
}
|
|
166
|
+
ensureMem(entry, mem);
|
|
167
|
+
console.error(`waygraph traverse[${traverseId}]: step ${steps + 1} ${fromLabel} -[${pick.block}]-> ${pick.to}` +
|
|
168
|
+
(pick.label ? ` (${pick.label})` : ""));
|
|
169
|
+
const out = await runOneBlock(engine, entry, context, page, mem);
|
|
170
|
+
const observed = typeof out === "object" && out && "__state" in out
|
|
171
|
+
? String(out.__state)
|
|
172
|
+
: pick.to;
|
|
173
|
+
edgeVisits.set(key, (edgeVisits.get(key) ?? 0) + 1);
|
|
174
|
+
edgesHit.add(key);
|
|
175
|
+
if (here)
|
|
176
|
+
nodeVisits.set(here, (nodeVisits.get(here) ?? 0) + 1);
|
|
177
|
+
lastHere = observed;
|
|
178
|
+
steps += 1;
|
|
179
|
+
if (observed !== pick.to && pick.to !== "*") {
|
|
180
|
+
console.error(`waygraph traverse[${traverseId}]: WARN static to=${pick.to} observed=${observed}`);
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
catch (err) {
|
|
184
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
185
|
+
console.log(`[Broke at edge[${traverseId}] block=${pick.block} from=${fromLabel} to=${pick.to}] ${msg}`);
|
|
186
|
+
exitCode = 1;
|
|
187
|
+
break;
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
finally {
|
|
192
|
+
console.error(`waygraph traverse[${traverseId}]: done exit=${exitCode} steps=${steps} edgesHit=${edgesHit.size}`);
|
|
193
|
+
}
|
|
194
|
+
return {
|
|
195
|
+
exitCode,
|
|
196
|
+
steps,
|
|
197
|
+
edgesHit: [...edgesHit],
|
|
198
|
+
...(leaf ? { leaf } : {}),
|
|
199
|
+
};
|
|
200
|
+
}
|