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
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
// Where a detached session lives on disk: its metadata (per project, plus a global copy keyed by id), its short
|
|
2
|
+
// socket path under the OS temp folder, its log; and listing, resolving and stopping sessions by id.
|
|
3
|
+
import { randomBytes } from "node:crypto";
|
|
4
|
+
import { existsSync, mkdirSync, readdirSync, readFileSync, rmSync, writeFileSync } from "node:fs";
|
|
5
|
+
import { tmpdir } from "node:os";
|
|
6
|
+
import { join } from "node:path";
|
|
7
|
+
export function sessionDir(projectDir) {
|
|
8
|
+
return join(projectDir, ".waygraph-auto");
|
|
9
|
+
}
|
|
10
|
+
export function metaPath(projectDir, sessionId) {
|
|
11
|
+
return join(sessionDir(projectDir), `${sessionId}.json`);
|
|
12
|
+
}
|
|
13
|
+
/** Global index so session control works even when cwd ≠ the project that spawned the session. */
|
|
14
|
+
export function globalMetaPath(sessionId) {
|
|
15
|
+
return join(socketDir(), `${sessionId}.meta.json`);
|
|
16
|
+
}
|
|
17
|
+
export function isPidAlive(pid) {
|
|
18
|
+
try {
|
|
19
|
+
process.kill(pid, 0);
|
|
20
|
+
return true;
|
|
21
|
+
}
|
|
22
|
+
catch {
|
|
23
|
+
return false;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Deliberately NOT under the project directory (unlike meta/log files) -
|
|
28
|
+
* a real bug found while proving out openspec/changes/waygraph-map's own
|
|
29
|
+
* "waypack" loading claim: a project loaded through a consumer's own deeply
|
|
30
|
+
* nested `node_modules/<pkg>` path can push the socket's absolute path past
|
|
31
|
+
* the OS's AF_UNIX `sun_path` limit (~108 bytes on Linux), failing with
|
|
32
|
+
* `listen EINVAL`. A short, fixed-location directory sidesteps this
|
|
33
|
+
* regardless of how deep `projectDir` itself is nested. `sessionId` alone
|
|
34
|
+
* (8 hex chars, `generateSessionId()`) is enough to keep this collision-safe
|
|
35
|
+
* across every project on the machine sharing this one flat directory - the
|
|
36
|
+
* same randomness space this package already relied on per-project.
|
|
37
|
+
*/
|
|
38
|
+
export function socketDir() {
|
|
39
|
+
return join(tmpdir(), "waygraph-auto");
|
|
40
|
+
}
|
|
41
|
+
export function socketPathFor(sessionId) {
|
|
42
|
+
return join(socketDir(), `${sessionId}.sock`);
|
|
43
|
+
}
|
|
44
|
+
export function logPathFor(projectDir, sessionId) {
|
|
45
|
+
return join(sessionDir(projectDir), `${sessionId}.log`);
|
|
46
|
+
}
|
|
47
|
+
export function generateSessionId() {
|
|
48
|
+
return randomBytes(4).toString("hex");
|
|
49
|
+
}
|
|
50
|
+
export function readSessionMeta(projectDir, sessionId) {
|
|
51
|
+
const p = metaPath(projectDir, sessionId);
|
|
52
|
+
if (!existsSync(p))
|
|
53
|
+
return null;
|
|
54
|
+
try {
|
|
55
|
+
return JSON.parse(readFileSync(p, "utf-8"));
|
|
56
|
+
}
|
|
57
|
+
catch {
|
|
58
|
+
return null;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Resolve session metadata from a project hint (cwd) or the global registry.
|
|
63
|
+
* Fixes "session unreachable" when the agent calls status/send from a different
|
|
64
|
+
* directory or pane than the one that ran `pilot start`.
|
|
65
|
+
*/
|
|
66
|
+
export function resolveSessionMeta(sessionId, projectDirHint) {
|
|
67
|
+
if (projectDirHint) {
|
|
68
|
+
const local = readSessionMeta(projectDirHint, sessionId);
|
|
69
|
+
if (local)
|
|
70
|
+
return local;
|
|
71
|
+
}
|
|
72
|
+
const globalPath = globalMetaPath(sessionId);
|
|
73
|
+
if (existsSync(globalPath)) {
|
|
74
|
+
try {
|
|
75
|
+
return JSON.parse(readFileSync(globalPath, "utf-8"));
|
|
76
|
+
}
|
|
77
|
+
catch {
|
|
78
|
+
return null;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
return null;
|
|
82
|
+
}
|
|
83
|
+
export function writeGlobalSessionMeta(meta) {
|
|
84
|
+
mkdirSync(socketDir(), { recursive: true });
|
|
85
|
+
writeFileSync(globalMetaPath(meta.sessionId), JSON.stringify(meta, null, 2));
|
|
86
|
+
}
|
|
87
|
+
export function removeSessionFiles(projectDir, sessionId) {
|
|
88
|
+
for (const p of [
|
|
89
|
+
metaPath(projectDir, sessionId),
|
|
90
|
+
globalMetaPath(sessionId),
|
|
91
|
+
socketPathFor(sessionId),
|
|
92
|
+
]) {
|
|
93
|
+
try {
|
|
94
|
+
rmSync(p, { force: true });
|
|
95
|
+
}
|
|
96
|
+
catch {
|
|
97
|
+
/* ignore */
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
/** Stop one detached session (SIGTERM + cleanup metadata/socket). */
|
|
102
|
+
export function stopBrowserSession(projectDir, sessionId) {
|
|
103
|
+
const meta = resolveSessionMeta(sessionId, projectDir);
|
|
104
|
+
if (!meta)
|
|
105
|
+
return false;
|
|
106
|
+
try {
|
|
107
|
+
process.kill(meta.pid, "SIGTERM");
|
|
108
|
+
}
|
|
109
|
+
catch {
|
|
110
|
+
/* already gone */
|
|
111
|
+
}
|
|
112
|
+
removeSessionFiles(meta.projectDir, sessionId);
|
|
113
|
+
return true;
|
|
114
|
+
}
|
|
115
|
+
/** Stop every live session registered for a project. */
|
|
116
|
+
export function stopAllBrowserSessions(projectDir) {
|
|
117
|
+
const sessions = listBrowserSessions(projectDir);
|
|
118
|
+
for (const meta of sessions) {
|
|
119
|
+
stopBrowserSession(meta.projectDir, meta.sessionId);
|
|
120
|
+
}
|
|
121
|
+
return sessions.length;
|
|
122
|
+
}
|
|
123
|
+
/** Live browser sessions for a project (metadata + socket + pid still present). */
|
|
124
|
+
export function listBrowserSessions(projectDir) {
|
|
125
|
+
const dir = sessionDir(projectDir);
|
|
126
|
+
if (!existsSync(dir))
|
|
127
|
+
return [];
|
|
128
|
+
const out = [];
|
|
129
|
+
for (const f of readdirSync(dir)) {
|
|
130
|
+
if (!f.endsWith(".json"))
|
|
131
|
+
continue;
|
|
132
|
+
const id = f.slice(0, -".json".length);
|
|
133
|
+
const meta = readSessionMeta(projectDir, id);
|
|
134
|
+
if (!meta)
|
|
135
|
+
continue;
|
|
136
|
+
if (!existsSync(socketPathFor(id)))
|
|
137
|
+
continue;
|
|
138
|
+
if (!isPidAlive(meta.pid)) {
|
|
139
|
+
removeSessionFiles(projectDir, id);
|
|
140
|
+
continue;
|
|
141
|
+
}
|
|
142
|
+
out.push(meta);
|
|
143
|
+
}
|
|
144
|
+
return out.sort((a, b) => a.startedAt.localeCompare(b.startedAt));
|
|
145
|
+
}
|
|
@@ -1,6 +1,8 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
import type {
|
|
3
|
-
import type {
|
|
1
|
+
import type { PilotHighlightFixtures } from "../../demo/overlay/pilot/fixtures.js";
|
|
2
|
+
import type { StubPhaseResult } from "../../engine/stub/stub.js";
|
|
3
|
+
import type { BlockEntry } from "../../manifest/project.js";
|
|
4
|
+
import type { ExploreMenu } from "../auto/explore.js";
|
|
5
|
+
import type { PickResult } from "../auto/menu.js";
|
|
4
6
|
/** True when a stub-phase result actually carries authored content worth keeping. */
|
|
5
7
|
export declare function stubPhaseHasContent(r: StubPhaseResult): boolean;
|
|
6
8
|
/** One available move in a session snapshot: a Block and the Checkpoint it leads to. */
|
|
@@ -90,7 +92,7 @@ export interface AutoSessionInit {
|
|
|
90
92
|
projectDir: string;
|
|
91
93
|
baseURL?: string;
|
|
92
94
|
startUrl?: string;
|
|
93
|
-
blocksSelect?: import("
|
|
95
|
+
blocksSelect?: import("../../manifest/select.js").BlocksSelect;
|
|
94
96
|
/** Absolute paths — merged Block libraries (see `waygraph browser --inject`). */
|
|
95
97
|
inject?: string[];
|
|
96
98
|
/** When true, open about:blank instead of baseURL/startUrl (browser default). */
|
|
@@ -139,7 +141,7 @@ export interface TraceStep {
|
|
|
139
141
|
* Resolved demo-narration fixtures (highlights/todos/device), when the
|
|
140
142
|
* Block actually authors `stubBefore`/`stubAfter`/`stubOnError` - the same
|
|
141
143
|
* data `waygraph demo`'s lifecycle logging already computes (`runStubPhase`
|
|
142
|
-
* in
|
|
144
|
+
* in demo/narration/index.ts), reused here for extra context on what a step meant to
|
|
143
145
|
* convey. Omitted when the Block has none, or the result carries nothing.
|
|
144
146
|
*/
|
|
145
147
|
stubBefore?: StubPhaseResult;
|
|
@@ -210,4 +212,6 @@ export interface StorageSnapshot {
|
|
|
210
212
|
serviceWorkers: string[];
|
|
211
213
|
serviceWorkerRegistrations: ServiceWorkerRegistrationInfo[];
|
|
212
214
|
}
|
|
215
|
+
/** What a highlight call paints, in a few words, for the session's activity line. */
|
|
216
|
+
export declare function describeHighlight(fixtures: PilotHighlightFixtures): string;
|
|
213
217
|
export {};
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
// The session's shared shapes and pure helpers: snapshots, picks, trace / console entries, DOM walking, stub files.
|
|
1
2
|
import { dirname, join, resolve } from "node:path";
|
|
2
3
|
import { fileURLToPath } from "node:url";
|
|
3
4
|
/** True when a stub-phase result actually carries authored content worth keeping. */
|
|
@@ -137,7 +138,7 @@ export const TRACE_MAX_STEPS = 500;
|
|
|
137
138
|
* exist for more than a moment.
|
|
138
139
|
*/
|
|
139
140
|
export function stubFilePath(kind) {
|
|
140
|
-
const packageRoot = resolve(dirname(fileURLToPath(import.meta.url)), "..", "..");
|
|
141
|
+
const packageRoot = resolve(dirname(fileURLToPath(import.meta.url)), "..", "..", "..");
|
|
141
142
|
const names = {
|
|
142
143
|
image: "stub.png",
|
|
143
144
|
pdf: "stub.pdf",
|
|
@@ -146,3 +147,19 @@ export function stubFilePath(kind) {
|
|
|
146
147
|
return join(packageRoot, "assets", "stubs", names[kind]);
|
|
147
148
|
}
|
|
148
149
|
export const CONSOLE_LOG_MAX_ENTRIES = 200;
|
|
150
|
+
/** What a highlight call paints, in a few words, for the session's activity line. */
|
|
151
|
+
export function describeHighlight(fixtures) {
|
|
152
|
+
if (fixtures.clear === true)
|
|
153
|
+
return "clear";
|
|
154
|
+
return ([
|
|
155
|
+
fixtures.rings?.length ? `${fixtures.rings.length} ring(s)` : null,
|
|
156
|
+
fixtures.todos?.length ? `${fixtures.todos.length} todo(s)` : null,
|
|
157
|
+
fixtures.zoom && fixtures.zoom > 1.001 ? `zoom ${fixtures.zoom}` : null,
|
|
158
|
+
fixtures.device
|
|
159
|
+
? `device ${typeof fixtures.device === "string" ? fixtures.device : fixtures.device.preset || "custom"}`
|
|
160
|
+
: null,
|
|
161
|
+
fixtures.rings?.some((r) => r.focus) ? "focus" : null,
|
|
162
|
+
]
|
|
163
|
+
.filter(Boolean)
|
|
164
|
+
.join(", ") || "fixtures");
|
|
165
|
+
}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { BrowserContext, Page } from "@playwright/test";
|
|
2
|
+
import type { InspectDomOptions, InspectDomResult, StorageSnapshot } from "./helpers.js";
|
|
3
|
+
export declare function inspectDom(page: Page, opts: InspectDomOptions): Promise<InspectDomResult>;
|
|
4
|
+
export declare function inspectStorage(page: Page, context: BrowserContext): Promise<StorageSnapshot>;
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import { showPilotActivity, showPilotVision } from "../../demo/overlay/pilot/shell.js";
|
|
2
|
+
import { ignorePageGone } from "../../engine/page-gone.js";
|
|
3
|
+
import { FULL_MODE_DEFAULT_DEPTH, FULL_MODE_MAX_NODES, FULL_MODE_MAX_TEXT_LENGTH, walkFullDom } from "./helpers.js";
|
|
4
|
+
export async function inspectDom(page, opts) {
|
|
5
|
+
const mode = opts.mode ?? "aria";
|
|
6
|
+
const ariaOptions = opts.depth !== undefined ? { mode: "ai", depth: opts.depth } : { mode: "ai" };
|
|
7
|
+
if (opts.selector) {
|
|
8
|
+
const locator = page.locator(opts.selector).first();
|
|
9
|
+
if ((await locator.count()) === 0) {
|
|
10
|
+
return { ok: false, error: `no element matches selector "${opts.selector}"` };
|
|
11
|
+
}
|
|
12
|
+
await showPilotVision(page, opts.selector, `dom (${mode}): ${opts.selector}`, "orange");
|
|
13
|
+
if (mode === "full") {
|
|
14
|
+
const caps = {
|
|
15
|
+
depth: opts.depth ?? FULL_MODE_DEFAULT_DEPTH,
|
|
16
|
+
maxNodes: FULL_MODE_MAX_NODES,
|
|
17
|
+
maxTextLength: FULL_MODE_MAX_TEXT_LENGTH,
|
|
18
|
+
};
|
|
19
|
+
const { tree, truncated } = await locator.evaluate(walkFullDom, caps);
|
|
20
|
+
return { ok: true, snapshot: { mode: "full", selector: opts.selector, truncated, tree } };
|
|
21
|
+
}
|
|
22
|
+
const tree = await locator.ariaSnapshotJSON(ariaOptions);
|
|
23
|
+
return { ok: true, snapshot: { mode: "aria", selector: opts.selector, truncated: false, tree } };
|
|
24
|
+
}
|
|
25
|
+
await showPilotActivity(page, `Running (Dom): ${mode}, whole page`);
|
|
26
|
+
if (mode === "full") {
|
|
27
|
+
// page.evaluate only ships the one function passed to it - it can't
|
|
28
|
+
// reach another named function by closure. Routing the whole-page case
|
|
29
|
+
// through the same `html` Locator lets both cases share one
|
|
30
|
+
// self-contained walkFullDom instead of two near-duplicate callbacks.
|
|
31
|
+
const caps = {
|
|
32
|
+
depth: opts.depth ?? FULL_MODE_DEFAULT_DEPTH,
|
|
33
|
+
maxNodes: FULL_MODE_MAX_NODES,
|
|
34
|
+
maxTextLength: FULL_MODE_MAX_TEXT_LENGTH,
|
|
35
|
+
};
|
|
36
|
+
const { tree, truncated } = await page.locator("html").first().evaluate(walkFullDom, caps);
|
|
37
|
+
return { ok: true, snapshot: { mode: "full", truncated, tree } };
|
|
38
|
+
}
|
|
39
|
+
const tree = await page.ariaSnapshotJSON(ariaOptions);
|
|
40
|
+
return { ok: true, snapshot: { mode: "aria", truncated: false, tree } };
|
|
41
|
+
}
|
|
42
|
+
export async function inspectStorage(page, context) {
|
|
43
|
+
const [localStorageEntries, sessionStorageEntries] = await page.evaluate(() => [
|
|
44
|
+
Object.entries(window.localStorage),
|
|
45
|
+
Object.entries(window.sessionStorage),
|
|
46
|
+
]);
|
|
47
|
+
const cookies = await context.cookies();
|
|
48
|
+
const workers = context.serviceWorkers();
|
|
49
|
+
const registrations = await page
|
|
50
|
+
.evaluate(async () => {
|
|
51
|
+
if (!("serviceWorker" in navigator))
|
|
52
|
+
return [];
|
|
53
|
+
const regs = await navigator.serviceWorker.getRegistrations();
|
|
54
|
+
return regs.map((r) => ({
|
|
55
|
+
scope: r.scope,
|
|
56
|
+
...(r.active?.scriptURL ? { activeUrl: r.active.scriptURL } : {}),
|
|
57
|
+
...(r.active?.state ? { state: r.active.state } : {}),
|
|
58
|
+
}));
|
|
59
|
+
})
|
|
60
|
+
.catch(ignorePageGone);
|
|
61
|
+
return {
|
|
62
|
+
localStorage: Object.fromEntries(localStorageEntries),
|
|
63
|
+
sessionStorage: Object.fromEntries(sessionStorageEntries),
|
|
64
|
+
cookies: cookies.map((c) => ({
|
|
65
|
+
name: c.name,
|
|
66
|
+
value: c.value,
|
|
67
|
+
domain: c.domain,
|
|
68
|
+
path: c.path,
|
|
69
|
+
httpOnly: c.httpOnly,
|
|
70
|
+
secure: c.secure,
|
|
71
|
+
})),
|
|
72
|
+
serviceWorkers: workers.map((w) => w.url()),
|
|
73
|
+
serviceWorkerRegistrations: registrations ?? [],
|
|
74
|
+
};
|
|
75
|
+
}
|
|
@@ -1,14 +1,7 @@
|
|
|
1
|
-
import
|
|
2
|
-
import
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
sessionId: string;
|
|
6
|
-
socketPath: string;
|
|
7
|
-
pid: number;
|
|
8
|
-
projectDir: string;
|
|
9
|
-
startedAt: string;
|
|
10
|
-
headless: boolean;
|
|
11
|
-
}
|
|
1
|
+
import type { PilotHighlightFixtures } from "../../demo/overlay/pilot/fixtures.js";
|
|
2
|
+
import { AutoSession } from "./auto-session.js";
|
|
3
|
+
import { SessionMeta } from "./files.js";
|
|
4
|
+
import { type ApplyPathResult, type AutoSessionInit, type ConsoleLogEntry, type DomSnapshot, type InspectDomOptions, type SessionSnapshot, type StorageSnapshot, type StubFileKind, type TraceStep } from "./helpers.js";
|
|
12
5
|
export type StatusOrSendResponse = {
|
|
13
6
|
ok: true;
|
|
14
7
|
snapshot: SessionSnapshot;
|
|
@@ -54,12 +47,6 @@ export type HighlightResponse = {
|
|
|
54
47
|
ok: false;
|
|
55
48
|
error: string;
|
|
56
49
|
};
|
|
57
|
-
/**
|
|
58
|
-
* Resolve session metadata from a project hint (cwd) or the global registry.
|
|
59
|
-
* Fixes "session unreachable" when the agent calls status/send from a different
|
|
60
|
-
* directory or pane than the one that ran `pilot start`.
|
|
61
|
-
*/
|
|
62
|
-
export declare function resolveSessionMeta(sessionId: string, projectDirHint?: string): SessionMeta | null;
|
|
63
50
|
/**
|
|
64
51
|
* Client-side: sends one request to a running session and returns its
|
|
65
52
|
* response. Reports a stale/unreachable session as an error within
|
|
@@ -128,19 +115,15 @@ export declare function serveSession(session: AutoSession, projectDir: string, s
|
|
|
128
115
|
export declare function runAutoServeCommand(init: AutoSessionInit, sessionId: string): Promise<void>;
|
|
129
116
|
/**
|
|
130
117
|
* Parent-side: spawns a detached background process running the same
|
|
131
|
-
* explore session as a socket server, waits for it to
|
|
132
|
-
*
|
|
118
|
+
* explore session as a socket server, waits for it to say it is serving (one
|
|
119
|
+
* message over an IPC channel, then disconnect), and returns its identity. A
|
|
120
|
+
* child that exits or stays silent past the timeout fails the start, and a silent
|
|
121
|
+
* one is stopped. Recurses through the
|
|
133
122
|
* existing `bin/waygraph` launcher (same tsx/esm registration every other
|
|
134
123
|
* invocation already gets) with the hidden `__auto-serve` command, rather
|
|
135
124
|
* than re-implementing that resolution here.
|
|
136
125
|
*/
|
|
137
126
|
export declare function spawnDetachedSession(init: AutoSessionInit, readyTimeoutMs?: number): Promise<SessionMeta>;
|
|
138
|
-
/** Stop one detached session (SIGTERM + cleanup metadata/socket). */
|
|
139
|
-
export declare function stopBrowserSession(projectDir: string, sessionId: string): boolean;
|
|
140
|
-
/** Stop every live session registered for a project. */
|
|
141
|
-
export declare function stopAllBrowserSessions(projectDir: string): number;
|
|
142
|
-
/** Live browser sessions for a project (metadata + socket + pid still present). */
|
|
143
|
-
export declare function listBrowserSessions(projectDir: string): SessionMeta[];
|
|
144
127
|
/**
|
|
145
128
|
* Client-only interactive loop against a running detached session - reopens
|
|
146
129
|
* the same rendering/parsing the foreground `--cli` loop uses, driven purely
|
|
@@ -4,111 +4,17 @@
|
|
|
4
4
|
* directory, mirroring the existing `.waygraph-traverse/` dotdir convention.
|
|
5
5
|
* See openspec/changes/waygraph-auto-cli-session-control.
|
|
6
6
|
*/
|
|
7
|
-
import { createServer, connect } from "node:net";
|
|
8
7
|
import { spawn } from "node:child_process";
|
|
8
|
+
import { mkdirSync, openSync, rmSync, writeFileSync, } from "node:fs";
|
|
9
9
|
import { createRequire } from "node:module";
|
|
10
|
-
import {
|
|
11
|
-
import {
|
|
12
|
-
import { tmpdir } from "node:os";
|
|
13
|
-
import { fileURLToPath } from "node:url";
|
|
14
|
-
import { randomBytes } from "node:crypto";
|
|
15
|
-
import { createInterface } from "node:readline/promises";
|
|
10
|
+
import { connect, createServer } from "node:net";
|
|
11
|
+
import { dirname, join } from "node:path";
|
|
16
12
|
import { stdin as input, stdout as output } from "node:process";
|
|
17
|
-
import {
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
return join(sessionDir(projectDir), `${sessionId}.json`);
|
|
23
|
-
}
|
|
24
|
-
/** Global index so session control works even when cwd ≠ the project that spawned the session. */
|
|
25
|
-
function globalMetaPath(sessionId) {
|
|
26
|
-
return join(socketDir(), `${sessionId}.meta.json`);
|
|
27
|
-
}
|
|
28
|
-
function isPidAlive(pid) {
|
|
29
|
-
try {
|
|
30
|
-
process.kill(pid, 0);
|
|
31
|
-
return true;
|
|
32
|
-
}
|
|
33
|
-
catch {
|
|
34
|
-
return false;
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
/**
|
|
38
|
-
* Deliberately NOT under the project directory (unlike meta/log files) -
|
|
39
|
-
* a real bug found while proving out openspec/changes/waygraph-map's own
|
|
40
|
-
* "waypack" loading claim: a project loaded through a consumer's own deeply
|
|
41
|
-
* nested `node_modules/<pkg>` path can push the socket's absolute path past
|
|
42
|
-
* the OS's AF_UNIX `sun_path` limit (~108 bytes on Linux), failing with
|
|
43
|
-
* `listen EINVAL`. A short, fixed-location directory sidesteps this
|
|
44
|
-
* regardless of how deep `projectDir` itself is nested. `sessionId` alone
|
|
45
|
-
* (8 hex chars, `generateSessionId()`) is enough to keep this collision-safe
|
|
46
|
-
* across every project on the machine sharing this one flat directory - the
|
|
47
|
-
* same randomness space this package already relied on per-project.
|
|
48
|
-
*/
|
|
49
|
-
function socketDir() {
|
|
50
|
-
return join(tmpdir(), "waygraph-auto");
|
|
51
|
-
}
|
|
52
|
-
function socketPathFor(sessionId) {
|
|
53
|
-
return join(socketDir(), `${sessionId}.sock`);
|
|
54
|
-
}
|
|
55
|
-
function logPathFor(projectDir, sessionId) {
|
|
56
|
-
return join(sessionDir(projectDir), `${sessionId}.log`);
|
|
57
|
-
}
|
|
58
|
-
function generateSessionId() {
|
|
59
|
-
return randomBytes(4).toString("hex");
|
|
60
|
-
}
|
|
61
|
-
function readSessionMeta(projectDir, sessionId) {
|
|
62
|
-
const p = metaPath(projectDir, sessionId);
|
|
63
|
-
if (!existsSync(p))
|
|
64
|
-
return null;
|
|
65
|
-
try {
|
|
66
|
-
return JSON.parse(readFileSync(p, "utf-8"));
|
|
67
|
-
}
|
|
68
|
-
catch {
|
|
69
|
-
return null;
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
/**
|
|
73
|
-
* Resolve session metadata from a project hint (cwd) or the global registry.
|
|
74
|
-
* Fixes "session unreachable" when the agent calls status/send from a different
|
|
75
|
-
* directory or pane than the one that ran `pilot start`.
|
|
76
|
-
*/
|
|
77
|
-
export function resolveSessionMeta(sessionId, projectDirHint) {
|
|
78
|
-
if (projectDirHint) {
|
|
79
|
-
const local = readSessionMeta(projectDirHint, sessionId);
|
|
80
|
-
if (local)
|
|
81
|
-
return local;
|
|
82
|
-
}
|
|
83
|
-
const globalPath = globalMetaPath(sessionId);
|
|
84
|
-
if (existsSync(globalPath)) {
|
|
85
|
-
try {
|
|
86
|
-
return JSON.parse(readFileSync(globalPath, "utf-8"));
|
|
87
|
-
}
|
|
88
|
-
catch {
|
|
89
|
-
return null;
|
|
90
|
-
}
|
|
91
|
-
}
|
|
92
|
-
return null;
|
|
93
|
-
}
|
|
94
|
-
function writeGlobalSessionMeta(meta) {
|
|
95
|
-
mkdirSync(socketDir(), { recursive: true });
|
|
96
|
-
writeFileSync(globalMetaPath(meta.sessionId), JSON.stringify(meta, null, 2));
|
|
97
|
-
}
|
|
98
|
-
function removeSessionFiles(projectDir, sessionId) {
|
|
99
|
-
for (const p of [
|
|
100
|
-
metaPath(projectDir, sessionId),
|
|
101
|
-
globalMetaPath(sessionId),
|
|
102
|
-
socketPathFor(sessionId),
|
|
103
|
-
]) {
|
|
104
|
-
try {
|
|
105
|
-
rmSync(p, { force: true });
|
|
106
|
-
}
|
|
107
|
-
catch {
|
|
108
|
-
/* ignore */
|
|
109
|
-
}
|
|
110
|
-
}
|
|
111
|
-
}
|
|
13
|
+
import { createInterface } from "node:readline/promises";
|
|
14
|
+
import { fileURLToPath } from "node:url";
|
|
15
|
+
import { ignorePageGone } from "../../engine/page-gone.js";
|
|
16
|
+
import { AutoSession } from "./auto-session.js";
|
|
17
|
+
import { generateSessionId, isPidAlive, logPathFor, metaPath, readSessionMeta, removeSessionFiles, resolveSessionMeta, sessionDir, socketDir, socketPathFor, writeGlobalSessionMeta } from "./files.js";
|
|
112
18
|
/** Reads newline-delimited JSON off a socket, one message at a time. */
|
|
113
19
|
function readOneMessage(sock, timeoutMs) {
|
|
114
20
|
return new Promise((resolvePromise, reject) => {
|
|
@@ -318,7 +224,7 @@ export async function serveSession(session, projectDir, sessionId, headless = tr
|
|
|
318
224
|
return;
|
|
319
225
|
shuttingDown = true;
|
|
320
226
|
server.close();
|
|
321
|
-
await session.close().catch(
|
|
227
|
+
await session.close().catch(ignorePageGone);
|
|
322
228
|
removeSessionFiles(projectDir, sessionId);
|
|
323
229
|
process.exit(0);
|
|
324
230
|
}
|
|
@@ -343,14 +249,19 @@ export async function serveSession(session, projectDir, sessionId, headless = tr
|
|
|
343
249
|
export async function runAutoServeCommand(init, sessionId) {
|
|
344
250
|
const session = await AutoSession.start({ ...init, sessionId });
|
|
345
251
|
await serveSession(session, init.projectDir, sessionId, init.headless ?? true);
|
|
252
|
+
// Tell the parent that spawned us (spawnDetachedSession) we are serving, then let it go.
|
|
253
|
+
process.send?.({ ready: true });
|
|
254
|
+
process.disconnect?.();
|
|
346
255
|
// Keep the event loop alive - the listening server already does this,
|
|
347
256
|
// but await forever here documents the intent for a reader.
|
|
348
257
|
await new Promise(() => { });
|
|
349
258
|
}
|
|
350
259
|
/**
|
|
351
260
|
* Parent-side: spawns a detached background process running the same
|
|
352
|
-
* explore session as a socket server, waits for it to
|
|
353
|
-
*
|
|
261
|
+
* explore session as a socket server, waits for it to say it is serving (one
|
|
262
|
+
* message over an IPC channel, then disconnect), and returns its identity. A
|
|
263
|
+
* child that exits or stays silent past the timeout fails the start, and a silent
|
|
264
|
+
* one is stopped. Recurses through the
|
|
354
265
|
* existing `bin/waygraph` launcher (same tsx/esm registration every other
|
|
355
266
|
* invocation already gets) with the hidden `__auto-serve` command, rather
|
|
356
267
|
* than re-implementing that resolution here.
|
|
@@ -358,12 +269,12 @@ export async function runAutoServeCommand(init, sessionId) {
|
|
|
358
269
|
export async function spawnDetachedSession(init, readyTimeoutMs = 20_000) {
|
|
359
270
|
const sessionId = generateSessionId();
|
|
360
271
|
mkdirSync(sessionDir(init.projectDir), { recursive: true });
|
|
361
|
-
// This file compiles to dist/
|
|
272
|
+
// This file compiles to dist/live/auto-session/ipc.js - three levels down from the package
|
|
362
273
|
// root, not one. Same bug class as cli/util.ts's own packageRoot(); see its comment.
|
|
363
|
-
const pkgRoot = join(dirname(fileURLToPath(import.meta.url)), "..", "..");
|
|
274
|
+
const pkgRoot = join(dirname(fileURLToPath(import.meta.url)), "..", "..", "..");
|
|
364
275
|
const require = createRequire(join(pkgRoot, "package.json"));
|
|
365
276
|
const tsxEsm = require.resolve("tsx/esm");
|
|
366
|
-
const cli = join(pkgRoot, "dist", "cli.js");
|
|
277
|
+
const cli = join(pkgRoot, "dist", "cli", "cli.js");
|
|
367
278
|
const logFd = openSync(logPathFor(init.projectDir, sessionId), "a");
|
|
368
279
|
const args = ["--import", tsxEsm, cli, "__auto-serve", init.projectDir, "--session-id", sessionId];
|
|
369
280
|
if (init.baseURL)
|
|
@@ -382,65 +293,29 @@ export async function spawnDetachedSession(init, readyTimeoutMs = 20_000) {
|
|
|
382
293
|
// Spawn cli.js directly — not bin/waygraph (which would fork a second Node).
|
|
383
294
|
const child = spawn(process.execPath, args, {
|
|
384
295
|
detached: true,
|
|
385
|
-
stdio: ["ignore", logFd, logFd],
|
|
296
|
+
stdio: ["ignore", logFd, logFd, "ipc"],
|
|
386
297
|
windowsHide: true,
|
|
387
298
|
env: process.env,
|
|
388
299
|
});
|
|
300
|
+
const log = logPathFor(init.projectDir, sessionId);
|
|
301
|
+
const outcome = await new Promise((done) => {
|
|
302
|
+
const timer = setTimeout(() => done("timeout"), readyTimeoutMs);
|
|
303
|
+
child.once("message", () => (clearTimeout(timer), done("ready")));
|
|
304
|
+
child.once("exit", (code) => (clearTimeout(timer), done({ exit: code })));
|
|
305
|
+
});
|
|
306
|
+
if (child.connected)
|
|
307
|
+
child.disconnect();
|
|
389
308
|
child.unref();
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
if (meta)
|
|
394
|
-
return meta;
|
|
395
|
-
await new Promise((r) => setTimeout(r, 150));
|
|
309
|
+
if (outcome === "timeout") {
|
|
310
|
+
child.kill("SIGTERM");
|
|
311
|
+
throw new Error(`session "${sessionId}" did not become ready within ${readyTimeoutMs}ms (stopped it) - check ${log} for errors`);
|
|
396
312
|
}
|
|
397
|
-
|
|
398
|
-
`
|
|
399
|
-
|
|
400
|
-
/** Stop one detached session (SIGTERM + cleanup metadata/socket). */
|
|
401
|
-
export function stopBrowserSession(projectDir, sessionId) {
|
|
402
|
-
const meta = resolveSessionMeta(sessionId, projectDir);
|
|
313
|
+
if (outcome !== "ready")
|
|
314
|
+
throw new Error(`session "${sessionId}" exited (code ${outcome.exit}) before it was ready - check ${log}`);
|
|
315
|
+
const meta = readSessionMeta(init.projectDir, sessionId);
|
|
403
316
|
if (!meta)
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
process.kill(meta.pid, "SIGTERM");
|
|
407
|
-
}
|
|
408
|
-
catch {
|
|
409
|
-
/* already gone */
|
|
410
|
-
}
|
|
411
|
-
removeSessionFiles(meta.projectDir, sessionId);
|
|
412
|
-
return true;
|
|
413
|
-
}
|
|
414
|
-
/** Stop every live session registered for a project. */
|
|
415
|
-
export function stopAllBrowserSessions(projectDir) {
|
|
416
|
-
const sessions = listBrowserSessions(projectDir);
|
|
417
|
-
for (const meta of sessions) {
|
|
418
|
-
stopBrowserSession(meta.projectDir, meta.sessionId);
|
|
419
|
-
}
|
|
420
|
-
return sessions.length;
|
|
421
|
-
}
|
|
422
|
-
/** Live browser sessions for a project (metadata + socket + pid still present). */
|
|
423
|
-
export function listBrowserSessions(projectDir) {
|
|
424
|
-
const dir = sessionDir(projectDir);
|
|
425
|
-
if (!existsSync(dir))
|
|
426
|
-
return [];
|
|
427
|
-
const out = [];
|
|
428
|
-
for (const f of readdirSync(dir)) {
|
|
429
|
-
if (!f.endsWith(".json"))
|
|
430
|
-
continue;
|
|
431
|
-
const id = f.slice(0, -".json".length);
|
|
432
|
-
const meta = readSessionMeta(projectDir, id);
|
|
433
|
-
if (!meta)
|
|
434
|
-
continue;
|
|
435
|
-
if (!existsSync(socketPathFor(id)))
|
|
436
|
-
continue;
|
|
437
|
-
if (!isPidAlive(meta.pid)) {
|
|
438
|
-
removeSessionFiles(projectDir, id);
|
|
439
|
-
continue;
|
|
440
|
-
}
|
|
441
|
-
out.push(meta);
|
|
442
|
-
}
|
|
443
|
-
return out.sort((a, b) => a.startedAt.localeCompare(b.startedAt));
|
|
317
|
+
throw new Error(`session "${sessionId}" said it was ready but wrote no metadata - check ${log}`);
|
|
318
|
+
return meta;
|
|
444
319
|
}
|
|
445
320
|
function printSnapshotMenu(snapshot) {
|
|
446
321
|
console.log("");
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { BrowserContext, Page } from "@playwright/test";
|
|
2
|
+
export declare function openSessionBrowser(projectDir: string, headless: boolean, baseURL: string | undefined, startUrl: string | undefined): Promise<{
|
|
3
|
+
closeBrowser: () => Promise<void>;
|
|
4
|
+
context: BrowserContext;
|
|
5
|
+
page: Page;
|
|
6
|
+
}>;
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { instrumentPilotActions } from "../../demo/overlay/pilot/actions.js";
|
|
2
|
+
import { installPersistentPilotOverlay } from "../../demo/overlay/pilot/shell.js";
|
|
3
|
+
import { ignorePageGone, ignoreTimeout } from "../../engine/page-gone.js";
|
|
4
|
+
import { chromiumExecutablePath, launchContext } from "../../runtime/browser.js";
|
|
5
|
+
import { configuredExtensions } from "../../runtime/waygraph-config.js";
|
|
6
|
+
export async function openSessionBrowser(projectDir, headless, baseURL, startUrl) {
|
|
7
|
+
const { chromium } = await import("@playwright/test");
|
|
8
|
+
const executablePath = chromiumExecutablePath();
|
|
9
|
+
// Real gap found live: a headed (--non-headless) session kept a fixed
|
|
10
|
+
// 1280x720 content area even when the user maximized/fullscreened the
|
|
11
|
+
// actual window - `viewport: null` alone only makes the PAGE track the
|
|
12
|
+
// window; the window itself still launches at Chromium's own small
|
|
13
|
+
// default size unless told to start maximized. Same fix cli.ts's own
|
|
14
|
+
// --step/headed launch already uses (see its own comment there) -
|
|
15
|
+
// headless keeps the fixed viewport since there's no real window to size.
|
|
16
|
+
const launchOpts = {
|
|
17
|
+
headless,
|
|
18
|
+
// Keep Playwright's default --no-startup-window for headful: without it
|
|
19
|
+
// Chromium opens its own "New Tab" window AND our context.newPage() opens
|
|
20
|
+
// a second about:blank window. bringToFront() below surfaces the real page.
|
|
21
|
+
args: headless ? [] : ["--start-maximized"],
|
|
22
|
+
};
|
|
23
|
+
if (executablePath)
|
|
24
|
+
launchOpts.executablePath = executablePath;
|
|
25
|
+
const contextOpts = {
|
|
26
|
+
viewport: headless ? { width: 1280, height: 720 } : null,
|
|
27
|
+
};
|
|
28
|
+
if (baseURL)
|
|
29
|
+
contextOpts.baseURL = baseURL;
|
|
30
|
+
const { close: closeBrowser, context } = await launchContext({
|
|
31
|
+
launcher: chromium,
|
|
32
|
+
launch: launchOpts,
|
|
33
|
+
context: contextOpts,
|
|
34
|
+
extensions: await configuredExtensions(projectDir),
|
|
35
|
+
});
|
|
36
|
+
await installPersistentPilotOverlay(context);
|
|
37
|
+
const page = await context.newPage();
|
|
38
|
+
instrumentPilotActions(page, headless ? 0 : 450);
|
|
39
|
+
if (startUrl) {
|
|
40
|
+
await page.goto(startUrl, { waitUntil: "domcontentloaded" }).catch(ignorePageGone);
|
|
41
|
+
await page.waitForLoadState("load").catch(ignoreTimeout);
|
|
42
|
+
}
|
|
43
|
+
else {
|
|
44
|
+
await page.goto("about:blank").catch(ignorePageGone);
|
|
45
|
+
}
|
|
46
|
+
return { closeBrowser, context, page };
|
|
47
|
+
}
|