waygraph 0.15.47 → 0.15.50
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/dist/analysis/graph.js +2 -2
- package/dist/auto-session/session.js +3 -3
- package/dist/cli/discover.d.ts +1 -1
- package/dist/cli/discover.js +1 -1
- package/dist/cli/flags.d.ts +7 -5
- package/dist/cli/flags.js +9 -32
- package/dist/cli/run-chain.js +1 -1
- package/dist/cli.js +1 -1
- package/dist/{agent-dive.js → commands/agent-dive-scaffold.js} +2 -2
- package/dist/commands/agent-dive.js +1 -1
- package/dist/commands/check.js +1 -1
- package/dist/commands/run.js +4 -4
- package/dist/commands/session.js +7 -7
- package/dist/config.d.ts +34 -0
- package/dist/config.js +94 -0
- package/dist/{engine/core.js → core/block.js} +6 -6
- package/dist/core/blocks/api.d.ts +54 -0
- package/dist/core/blocks/api.js +75 -0
- package/dist/{engine → core}/blocks/effect.d.ts +1 -1
- package/dist/{engine → core}/blocks/effect.js +1 -1
- package/dist/{engine → core}/blocks/method.d.ts +1 -1
- package/dist/{engine → core}/blocks/method.js +1 -1
- package/dist/{engine → core}/blocks/nav.js +1 -1
- package/dist/{engine → core}/blocks/page.js +1 -1
- package/dist/{engine → core}/branch-regression.js +2 -3
- package/dist/{engine → core}/compose.js +4 -4
- package/dist/{engine/engine-class.d.ts → core/engine.d.ts} +2 -133
- package/dist/core/engine.js +50 -0
- package/dist/{engine → core}/flow.js +5 -5
- package/dist/core/map-builder.d.ts +171 -0
- package/dist/{engine/engine-class.js → core/map-builder.js} +82 -98
- package/dist/{engine → core}/run-graph.js +4 -6
- package/dist/core.d.ts +14 -0
- package/dist/core.js +15 -0
- package/dist/env-file.d.ts +10 -0
- package/dist/env-file.js +58 -0
- package/dist/errors.d.ts +54 -20
- package/dist/errors.js +67 -20
- package/dist/highlights/run-phase.js +15 -2
- package/dist/highlights/stub-ctx.js +16 -0
- package/dist/highlights/types.d.ts +38 -0
- package/dist/index.d.ts +7 -3
- package/dist/index.js +2 -1
- package/dist/mem-page.js +2 -2
- package/dist/mem-stub.d.ts +1 -1
- package/dist/pilot-overlay/fixtures.js +42 -10
- package/dist/pilot-overlay/shell.js +23 -10
- package/dist/runner/banner-log.js +1 -0
- package/dist/runner/device-stage.js +35 -15
- package/dist/runner/inpage/banner.d.ts +9 -1
- package/dist/runner/inpage/banner.js +27 -2
- package/dist/runner/inpage/caption.d.ts +3 -0
- package/dist/runner/inpage/caption.js +23 -0
- package/dist/runner/inpage/core.js +32 -9
- package/dist/runner/inpage/network.d.ts +15 -0
- package/dist/runner/inpage/network.js +217 -0
- package/dist/runner/inpage/panel-chrome.js +41 -1
- package/dist/runner/inpage/swipe-zoom.js +1 -1
- package/dist/runner/inpage/todos.js +6 -1
- package/dist/runner/main.js +9 -2
- package/dist/runner/network-capture.d.ts +9 -0
- package/dist/runner/network-capture.js +126 -0
- package/dist/runner/overlay-css.js +71 -7
- package/dist/runner/overlay-install.js +39 -2
- package/dist/runner/overlay-stage.js +5 -0
- package/dist/runner/rings.js +69 -45
- package/dist/runner/slides.js +14 -8
- package/dist/runner/step-mode.js +12 -0
- package/dist/runner/step-panels.js +9 -3
- package/dist/runner/teardown.js +16 -9
- package/dist/session/auto-explore-run.d.ts +5 -2
- package/dist/session/auto-explore-run.js +52 -36
- package/dist/{step-overlay.d.ts → session/step-overlay.d.ts} +1 -1
- package/dist/{step-overlay.js → session/step-overlay.js} +1 -1
- package/dist/trait.d.ts +1 -0
- package/dist/trait.js +15 -0
- package/dist/traverse/run.js +3 -22
- package/dist/ui/components/ring.js +4 -2
- package/dist/ui/overlay.css +36 -3
- package/examples/saucedemo/.waygraph-auto/00d147d1.log +21 -0
- package/examples/saucedemo/.waygraph-auto/0402cfcf.log +6 -0
- package/examples/saucedemo/.waygraph-auto/062b581f.log +20 -0
- package/examples/saucedemo/.waygraph-auto/0681582b.log +6 -0
- package/examples/saucedemo/.waygraph-auto/07f3e964.log +6 -0
- package/examples/saucedemo/.waygraph-auto/0868ae4d.log +0 -0
- package/examples/saucedemo/.waygraph-auto/0924ddaa.log +22 -0
- package/examples/saucedemo/.waygraph-auto/092d6173.log +5 -0
- package/examples/saucedemo/.waygraph-auto/09924510.log +0 -0
- package/examples/saucedemo/.waygraph-auto/0998c941.log +21 -0
- package/examples/saucedemo/.waygraph-auto/0bf74300.log +21 -0
- package/examples/saucedemo/.waygraph-auto/0c01fd29.log +4 -0
- package/examples/saucedemo/.waygraph-auto/0c302590.log +0 -0
- package/examples/saucedemo/.waygraph-auto/0dee62d6.log +5 -0
- package/examples/saucedemo/.waygraph-auto/0eb4c081.log +5 -0
- package/examples/saucedemo/.waygraph-auto/10fd431c.log +0 -0
- package/examples/saucedemo/.waygraph-auto/13c6fe3c.log +0 -0
- package/examples/saucedemo/.waygraph-auto/1581b677.log +0 -0
- package/examples/saucedemo/.waygraph-auto/161cc8dd.log +22 -0
- package/examples/saucedemo/.waygraph-auto/164761a5.log +6 -0
- package/examples/saucedemo/.waygraph-auto/1905ceb2.log +0 -0
- package/examples/saucedemo/.waygraph-auto/1b1d55c6.log +0 -0
- package/examples/saucedemo/.waygraph-auto/1b80fd24.log +6 -0
- package/examples/saucedemo/.waygraph-auto/1c30a3c2.log +0 -0
- package/examples/saucedemo/.waygraph-auto/1d90aa9a.log +0 -0
- package/examples/saucedemo/.waygraph-auto/1de7d889.log +0 -0
- package/examples/saucedemo/.waygraph-auto/1f233a4c.log +6 -0
- package/examples/saucedemo/.waygraph-auto/20e66801.log +0 -0
- package/examples/saucedemo/.waygraph-auto/20ffdb77.log +0 -0
- package/examples/saucedemo/.waygraph-auto/22048fff.log +4 -0
- package/examples/saucedemo/.waygraph-auto/22f1a704.log +5 -0
- package/examples/saucedemo/.waygraph-auto/239cced3.log +20 -0
- package/examples/saucedemo/.waygraph-auto/25204b46.log +4 -0
- package/examples/saucedemo/.waygraph-auto/25e2e90f.log +0 -0
- package/examples/saucedemo/.waygraph-auto/2708455e.log +22 -0
- package/examples/saucedemo/.waygraph-auto/272a96fd.log +20 -0
- package/examples/saucedemo/.waygraph-auto/28d7be5d.log +0 -0
- package/examples/saucedemo/.waygraph-auto/2a6a8266.log +6 -0
- package/examples/saucedemo/.waygraph-auto/2b3401cf.log +20 -0
- package/examples/saucedemo/.waygraph-auto/2ceccd6d.log +0 -0
- package/examples/saucedemo/.waygraph-auto/2f1b0c13.log +6 -0
- package/examples/saucedemo/.waygraph-auto/2f8d4073.log +6 -0
- package/examples/saucedemo/.waygraph-auto/30739278.log +6 -0
- package/examples/saucedemo/.waygraph-auto/31cb2e80.log +0 -0
- package/examples/saucedemo/.waygraph-auto/322d63cd.log +0 -0
- package/examples/saucedemo/.waygraph-auto/3239aa8a.log +6 -0
- package/examples/saucedemo/.waygraph-auto/326d87b7.log +6 -0
- package/examples/saucedemo/.waygraph-auto/3351c0b6.log +0 -0
- package/examples/saucedemo/.waygraph-auto/33df0770.log +0 -0
- package/examples/saucedemo/.waygraph-auto/340d624d.log +0 -0
- package/examples/saucedemo/.waygraph-auto/36367ccf.log +0 -0
- package/examples/saucedemo/.waygraph-auto/372536a5.log +6 -0
- package/examples/saucedemo/.waygraph-auto/3a412f3c.log +0 -0
- package/examples/saucedemo/.waygraph-auto/3a859bd7.log +0 -0
- package/examples/saucedemo/.waygraph-auto/3cb0add7.log +0 -0
- package/examples/saucedemo/.waygraph-auto/3e42f0d8.log +0 -0
- package/examples/saucedemo/.waygraph-auto/4144071d.log +0 -0
- package/examples/saucedemo/.waygraph-auto/4176a3c6.log +0 -0
- package/examples/saucedemo/.waygraph-auto/41d0793d.log +4 -0
- package/examples/saucedemo/.waygraph-auto/424b4d5d.log +0 -0
- package/examples/saucedemo/.waygraph-auto/43253aba.log +0 -0
- package/examples/saucedemo/.waygraph-auto/438c6c53.log +22 -0
- package/examples/saucedemo/.waygraph-auto/4477db12.log +0 -0
- package/examples/saucedemo/.waygraph-auto/4a1258b7.log +0 -0
- package/examples/saucedemo/.waygraph-auto/4adcd179.log +20 -0
- package/examples/saucedemo/.waygraph-auto/4c9d9b16.log +21 -0
- package/examples/saucedemo/.waygraph-auto/4da39c36.log +6 -0
- package/examples/saucedemo/.waygraph-auto/4dbefa7e.log +5 -0
- package/examples/saucedemo/.waygraph-auto/4efa7035.log +6 -0
- package/examples/saucedemo/.waygraph-auto/505affdc.log +4 -0
- package/examples/saucedemo/.waygraph-auto/51bcb60a.log +0 -0
- package/examples/saucedemo/.waygraph-auto/5291bc78.log +22 -0
- package/examples/saucedemo/.waygraph-auto/54274c39.log +5 -0
- package/examples/saucedemo/.waygraph-auto/5440ce7e.log +0 -0
- package/examples/saucedemo/.waygraph-auto/5738175f.log +22 -0
- package/examples/saucedemo/.waygraph-auto/57ce5643.log +22 -0
- package/examples/saucedemo/.waygraph-auto/5984426b.log +6 -0
- package/examples/saucedemo/.waygraph-auto/5a682e7c.log +22 -0
- package/examples/saucedemo/.waygraph-auto/5b79320c.log +21 -0
- package/examples/saucedemo/.waygraph-auto/5c55aaac.log +21 -0
- package/examples/saucedemo/.waygraph-auto/5d285cd3.log +0 -0
- package/examples/saucedemo/.waygraph-auto/5ed00b16.log +4 -0
- package/examples/saucedemo/.waygraph-auto/60b9c066.log +6 -0
- package/examples/saucedemo/.waygraph-auto/610dd127.log +0 -0
- package/examples/saucedemo/.waygraph-auto/61105500.log +5 -0
- package/examples/saucedemo/.waygraph-auto/6134afe8.log +20 -0
- package/examples/saucedemo/.waygraph-auto/62a0bdc9.log +22 -0
- package/examples/saucedemo/.waygraph-auto/6376fc15.log +0 -0
- package/examples/saucedemo/.waygraph-auto/6599cbca.log +22 -0
- package/examples/saucedemo/.waygraph-auto/67aaca30.log +0 -0
- package/examples/saucedemo/.waygraph-auto/68b10298.log +0 -0
- package/examples/saucedemo/.waygraph-auto/68be5e12.log +0 -0
- package/examples/saucedemo/.waygraph-auto/68df05a6.log +22 -0
- package/examples/saucedemo/.waygraph-auto/693f67c4.log +20 -0
- package/examples/saucedemo/.waygraph-auto/69ae030a.log +6 -0
- package/examples/saucedemo/.waygraph-auto/69e73f35.log +6 -0
- package/examples/saucedemo/.waygraph-auto/6b2333b0.log +5 -0
- package/examples/saucedemo/.waygraph-auto/6c4c3817.log +0 -0
- package/examples/saucedemo/.waygraph-auto/6c954911.log +0 -0
- package/examples/saucedemo/.waygraph-auto/6d65a439.log +5 -0
- package/examples/saucedemo/.waygraph-auto/6d700055.log +0 -0
- package/examples/saucedemo/.waygraph-auto/6ead848f.log +0 -0
- package/examples/saucedemo/.waygraph-auto/72675b2d.log +6 -0
- package/examples/saucedemo/.waygraph-auto/733dd260.log +5 -0
- package/examples/saucedemo/.waygraph-auto/75016486.log +0 -0
- package/examples/saucedemo/.waygraph-auto/752b01c6.log +22 -0
- package/examples/saucedemo/.waygraph-auto/75675227.log +6 -0
- package/examples/saucedemo/.waygraph-auto/75e2e658.log +0 -0
- package/examples/saucedemo/.waygraph-auto/76ac1a86.log +0 -0
- package/examples/saucedemo/.waygraph-auto/77605295.log +0 -0
- package/examples/saucedemo/.waygraph-auto/792671f4.log +22 -0
- package/examples/saucedemo/.waygraph-auto/79915adb.log +20 -0
- package/examples/saucedemo/.waygraph-auto/7a398774.log +6 -0
- package/examples/saucedemo/.waygraph-auto/7a72f66e.log +6 -0
- package/examples/saucedemo/.waygraph-auto/7a984334.log +4 -0
- package/examples/saucedemo/.waygraph-auto/7c6ee793.log +20 -0
- package/examples/saucedemo/.waygraph-auto/7c726dc4.log +22 -0
- package/examples/saucedemo/.waygraph-auto/7c72e8a5.log +4 -0
- package/examples/saucedemo/.waygraph-auto/7dbee625.log +22 -0
- package/examples/saucedemo/.waygraph-auto/7df66956.log +0 -0
- package/examples/saucedemo/.waygraph-auto/7e053160.log +0 -0
- package/examples/saucedemo/.waygraph-auto/7fcb512f.log +22 -0
- package/examples/saucedemo/.waygraph-auto/802a0b5b.log +0 -0
- package/examples/saucedemo/.waygraph-auto/80322e0b.log +0 -0
- package/examples/saucedemo/.waygraph-auto/80a4978e.log +6 -0
- package/examples/saucedemo/.waygraph-auto/81cfe480.log +22 -0
- package/examples/saucedemo/.waygraph-auto/832f5add.log +0 -0
- package/examples/saucedemo/.waygraph-auto/8337b6ad.log +0 -0
- package/examples/saucedemo/.waygraph-auto/8493928e.log +0 -0
- package/examples/saucedemo/.waygraph-auto/84dc6480.log +6 -0
- package/examples/saucedemo/.waygraph-auto/853bde43.log +0 -0
- package/examples/saucedemo/.waygraph-auto/86350ea6.log +22 -0
- package/examples/saucedemo/.waygraph-auto/86bb598a.log +0 -0
- package/examples/saucedemo/.waygraph-auto/86d09876.log +22 -0
- package/examples/saucedemo/.waygraph-auto/878ad01b.log +4 -0
- package/examples/saucedemo/.waygraph-auto/87c88ba5.log +0 -0
- package/examples/saucedemo/.waygraph-auto/87cb80ff.log +0 -0
- package/examples/saucedemo/.waygraph-auto/880b2e78.log +6 -0
- package/examples/saucedemo/.waygraph-auto/88527936.log +5 -0
- package/examples/saucedemo/.waygraph-auto/88eda676.log +0 -0
- package/examples/saucedemo/.waygraph-auto/893023ea.log +5 -0
- package/examples/saucedemo/.waygraph-auto/89416718.log +0 -0
- package/examples/saucedemo/.waygraph-auto/8996a857.log +6 -0
- package/examples/saucedemo/.waygraph-auto/8a08b68d.log +6 -0
- package/examples/saucedemo/.waygraph-auto/8a64ba0f.log +6 -0
- package/examples/saucedemo/.waygraph-auto/8b1cc2aa.log +6 -0
- package/examples/saucedemo/.waygraph-auto/8b73d13e.log +6 -0
- package/examples/saucedemo/.waygraph-auto/8d9e5cd2.log +21 -0
- package/examples/saucedemo/.waygraph-auto/8ec7d260.log +0 -0
- package/examples/saucedemo/.waygraph-auto/8ed43279.log +0 -0
- package/examples/saucedemo/.waygraph-auto/93acae32.log +5 -0
- package/examples/saucedemo/.waygraph-auto/96321a08.log +0 -0
- package/examples/saucedemo/.waygraph-auto/9742b6c2.log +6 -0
- package/examples/saucedemo/.waygraph-auto/99cc93eb.log +6 -0
- package/examples/saucedemo/.waygraph-auto/9cbfbedc.log +0 -0
- package/examples/saucedemo/.waygraph-auto/9dc147d2.log +22 -0
- package/examples/saucedemo/.waygraph-auto/a215a395.log +22 -0
- package/examples/saucedemo/.waygraph-auto/a23b7086.log +4 -0
- package/examples/saucedemo/.waygraph-auto/a35bd5ec.log +0 -0
- package/examples/saucedemo/.waygraph-auto/a68995e9.log +22 -0
- package/examples/saucedemo/.waygraph-auto/a6e4f936.log +22 -0
- package/examples/saucedemo/.waygraph-auto/a7da862b.log +0 -0
- package/examples/saucedemo/.waygraph-auto/a82e2a48.log +0 -0
- package/examples/saucedemo/.waygraph-auto/a952eb91.log +0 -0
- package/examples/saucedemo/.waygraph-auto/a9559653.log +5 -0
- package/examples/saucedemo/.waygraph-auto/aa478de2.log +0 -0
- package/examples/saucedemo/.waygraph-auto/ac350fc7.log +20 -0
- package/examples/saucedemo/.waygraph-auto/acc1b63a.log +0 -0
- package/examples/saucedemo/.waygraph-auto/ad12d191.log +0 -0
- package/examples/saucedemo/.waygraph-auto/b04638f4.log +6 -0
- package/examples/saucedemo/.waygraph-auto/b48863e5.log +22 -0
- package/examples/saucedemo/.waygraph-auto/b56968e1.log +6 -0
- package/examples/saucedemo/.waygraph-auto/b64e0620.log +20 -0
- package/examples/saucedemo/.waygraph-auto/b86a6218.log +6 -0
- package/examples/saucedemo/.waygraph-auto/b8e9e956.log +22 -0
- package/examples/saucedemo/.waygraph-auto/b9b310ff.log +21 -0
- package/examples/saucedemo/.waygraph-auto/bc111745.log +22 -0
- package/examples/saucedemo/.waygraph-auto/bf7a77a2.log +0 -0
- package/examples/saucedemo/.waygraph-auto/c0d6f353.log +21 -0
- package/examples/saucedemo/.waygraph-auto/c0febcf2.log +20 -0
- package/examples/saucedemo/.waygraph-auto/c4c52998.log +6 -0
- package/examples/saucedemo/.waygraph-auto/c809ceb4.log +22 -0
- package/examples/saucedemo/.waygraph-auto/ca6de7e7.log +0 -0
- package/examples/saucedemo/.waygraph-auto/ca8561bc.log +0 -0
- package/examples/saucedemo/.waygraph-auto/cb86d45b.log +0 -0
- package/examples/saucedemo/.waygraph-auto/cb9a1978.log +6 -0
- package/examples/saucedemo/.waygraph-auto/cbbc689c.log +6 -0
- package/examples/saucedemo/.waygraph-auto/cd88364b.log +0 -0
- package/examples/saucedemo/.waygraph-auto/cd919e1d.log +0 -0
- package/examples/saucedemo/.waygraph-auto/cfff9eef.log +20 -0
- package/examples/saucedemo/.waygraph-auto/d0f59b21.log +4 -0
- package/examples/saucedemo/.waygraph-auto/d1195079.log +20 -0
- package/examples/saucedemo/.waygraph-auto/d2ef067a.log +5 -0
- package/examples/saucedemo/.waygraph-auto/d425471f.log +6 -0
- package/examples/saucedemo/.waygraph-auto/d5293921.log +0 -0
- package/examples/saucedemo/.waygraph-auto/d62a22c2.log +21 -0
- package/examples/saucedemo/.waygraph-auto/d6d1761f.log +22 -0
- package/examples/saucedemo/.waygraph-auto/d6d5f411.log +22 -0
- package/examples/saucedemo/.waygraph-auto/d6df2771.log +6 -0
- package/examples/saucedemo/.waygraph-auto/d7075012.log +21 -0
- package/examples/saucedemo/.waygraph-auto/d9ddc297.log +0 -0
- package/examples/saucedemo/.waygraph-auto/db4ac845.log +0 -0
- package/examples/saucedemo/.waygraph-auto/db6d7774.log +0 -0
- package/examples/saucedemo/.waygraph-auto/db839827.log +5 -0
- package/examples/saucedemo/.waygraph-auto/dde5e859.log +22 -0
- package/examples/saucedemo/.waygraph-auto/de8cac58.log +0 -0
- package/examples/saucedemo/.waygraph-auto/dedfcb18.log +0 -0
- package/examples/saucedemo/.waygraph-auto/def4d9b1.log +0 -0
- package/examples/saucedemo/.waygraph-auto/e1549e40.log +0 -0
- package/examples/saucedemo/.waygraph-auto/e1b0676d.log +21 -0
- package/examples/saucedemo/.waygraph-auto/e5111463.log +0 -0
- package/examples/saucedemo/.waygraph-auto/e5fc1d7c.log +5 -0
- package/examples/saucedemo/.waygraph-auto/e6fd2202.log +0 -0
- package/examples/saucedemo/.waygraph-auto/edaa806d.log +0 -0
- package/examples/saucedemo/.waygraph-auto/edaf33de.log +0 -0
- package/examples/saucedemo/.waygraph-auto/edd40cbb.log +20 -0
- package/examples/saucedemo/.waygraph-auto/eddfbffc.log +6 -0
- package/examples/saucedemo/.waygraph-auto/ee9fa1ad.log +5 -0
- package/examples/saucedemo/.waygraph-auto/ef319474.log +22 -0
- package/examples/saucedemo/.waygraph-auto/f28eee8d.log +0 -0
- package/examples/saucedemo/.waygraph-auto/f33bde90.log +0 -0
- package/examples/saucedemo/.waygraph-auto/f6ba7cb4.log +6 -0
- package/examples/saucedemo/.waygraph-auto/f7ac4d62.log +20 -0
- package/examples/saucedemo/.waygraph-auto/f929bb79.log +0 -0
- package/examples/saucedemo/.waygraph-auto/f92d4c6c.log +22 -0
- package/examples/saucedemo/.waygraph-auto/f92faf40.log +5 -0
- package/examples/saucedemo/.waygraph-auto/fa784369.log +21 -0
- package/examples/saucedemo/.waygraph-auto/fb55f723.log +20 -0
- package/examples/saucedemo/.waygraph-auto/fba3b738.log +0 -0
- package/examples/saucedemo/.waygraph-auto/fdf66b74.log +0 -0
- package/examples/saucedemo/.waygraph-auto/ffdf2854.log +6 -0
- package/examples/saucedemo/README.md +13 -2
- package/examples/saucedemo/package.json +4 -0
- package/examples/saucedemo/src/flows/api-demo.flow.ts +37 -0
- package/examples/saucedemo/src/flows/checkout.flow.ts +34 -11
- package/package.json +5 -3
- package/templates/scaffold/src/flows/shop.flow.ts +42 -27
- package/dist/auto-explore-run.d.ts +0 -37
- package/dist/auto-explore-run.js +0 -670
- package/dist/auto-explore.d.ts +0 -57
- package/dist/auto-explore.js +0 -376
- package/dist/auto-session-ipc.d.ts +0 -150
- package/dist/auto-session-ipc.js +0 -497
- package/dist/block-inject.d.ts +0 -15
- package/dist/block-inject.js +0 -91
- package/dist/browser.d.ts +0 -15
- package/dist/browser.js +0 -29
- package/dist/coverage-gap.d.ts +0 -11
- package/dist/coverage-gap.js +0 -119
- package/dist/engine.d.ts +0 -12
- package/dist/engine.js +0 -13
- package/dist/graph.d.ts +0 -92
- package/dist/graph.js +0 -467
- package/dist/highlight-shorthand.d.ts +0 -24
- package/dist/highlight-shorthand.js +0 -30
- package/dist/map-check.d.ts +0 -18
- package/dist/map-check.js +0 -140
- package/dist/overlay-beacon.d.ts +0 -44
- package/dist/overlay-beacon.js +0 -85
- package/dist/pilot.d.ts +0 -54
- package/dist/pilot.js +0 -80
- package/dist/practices-check.d.ts +0 -14
- package/dist/practices-check.js +0 -195
- package/dist/traverse-coverage.d.ts +0 -59
- package/dist/traverse-coverage.js +0 -127
- package/dist/traverse-lease.d.ts +0 -18
- package/dist/traverse-lease.js +0 -62
- package/dist/traverse-run.d.ts +0 -47
- package/dist/traverse-run.js +0 -439
- package/dist/ui/compose.d.ts +0 -4
- package/dist/ui/compose.js +0 -7
- /package/dist/{verbose-log.d.ts → auto-session/verbose-log.d.ts} +0 -0
- /package/dist/{verbose-log.js → auto-session/verbose-log.js} +0 -0
- /package/dist/{agent-dive.d.ts → commands/agent-dive-scaffold.d.ts} +0 -0
- /package/dist/{engine/core.d.ts → core/block.d.ts} +0 -0
- /package/dist/{engine → core}/blocks/nav.d.ts +0 -0
- /package/dist/{engine → core}/blocks/page.d.ts +0 -0
- /package/dist/{engine → core}/branch-regression.d.ts +0 -0
- /package/dist/{engine → core}/compose.d.ts +0 -0
- /package/dist/{engine → core}/config.d.ts +0 -0
- /package/dist/{engine → core}/config.js +0 -0
- /package/dist/{engine → core}/flow.d.ts +0 -0
- /package/dist/{engine → core}/locate.d.ts +0 -0
- /package/dist/{engine → core}/locate.js +0 -0
- /package/dist/{engine → core}/run-graph.d.ts +0 -0
|
@@ -242,6 +242,21 @@ export async function applyDeviceToPage(page, device, sync) {
|
|
|
242
242
|
} catch {
|
|
243
243
|
from = null;
|
|
244
244
|
}
|
|
245
|
+
// Non-headless (no --video) used to literally resize the real OS browser window/viewport to
|
|
246
|
+
// each device's pixel size - a real, confirmed complaint: it didn't look like the same animated
|
|
247
|
+
// device-shell bezel the --video path already has, just a plain resize. Both now use the exact
|
|
248
|
+
// same applyVideoDeviceStage bezel technique - the "stage" (the fixed outer viewport the shell is
|
|
249
|
+
// centered within) is the recordVideo canvas size when recording, or the window's own size at
|
|
250
|
+
// the FIRST device switch when not (captured once, persisted on the page - the window itself is
|
|
251
|
+
// only really resized that one time, to establish a stable stage; every device switch after that
|
|
252
|
+
// paints the animated shell inside it instead of resizing the window again).
|
|
253
|
+
let establishingHeadedStage = false;
|
|
254
|
+
if (!videoStage && !page.__wgHeadedStage) {
|
|
255
|
+
page.__wgHeadedStage =
|
|
256
|
+
from && from.width > 0 && from.height > 0 ? { width: from.width, height: from.height } : { width: 1280, height: 720 };
|
|
257
|
+
establishingHeadedStage = true;
|
|
258
|
+
}
|
|
259
|
+
const stage = videoStage || page.__wgHeadedStage;
|
|
245
260
|
const announce = mode === "set" || mode === "clear";
|
|
246
261
|
const toDesktop =
|
|
247
262
|
mode === "clear" || (d.preset === "desktop" && !d.touchMode);
|
|
@@ -275,13 +290,18 @@ export async function applyDeviceToPage(page, device, sync) {
|
|
|
275
290
|
page.__wgDeviceOrient = nextOrient;
|
|
276
291
|
page.__wgDevicePreset = toDesktop ? "desktop" : d.preset || "";
|
|
277
292
|
|
|
278
|
-
if (
|
|
279
|
-
// Lock Playwright viewport to the
|
|
280
|
-
//
|
|
281
|
-
//
|
|
282
|
-
//
|
|
293
|
+
if (stage) {
|
|
294
|
+
// Lock the Playwright viewport to the stage size so frames/window fill it; center the device
|
|
295
|
+
// shell inside (OS window centering alone does not). Do NOT fitWindow to the device size -
|
|
296
|
+
// that shrinks the viewport below the stage and (when recording) pads the .webm with grey
|
|
297
|
+
// (top-left bias). Headed-without-video reuses this exact technique (see `stage`'s own
|
|
298
|
+
// comment above) - the real OS window is only ever resized once, right here, to establish the
|
|
299
|
+
// stage itself; every device switch after that paints the animated shell inside it instead.
|
|
300
|
+
if (!videoStage && establishingHeadedStage) {
|
|
301
|
+
await fitWindowToDeviceViewport(page, stage, { maximize: false }).catch(() => {});
|
|
302
|
+
}
|
|
283
303
|
try {
|
|
284
|
-
await realSet(
|
|
304
|
+
await realSet(stage);
|
|
285
305
|
} catch {
|
|
286
306
|
/* ignore */
|
|
287
307
|
}
|
|
@@ -290,22 +310,22 @@ export async function applyDeviceToPage(page, device, sync) {
|
|
|
290
310
|
// Zoom already cleared above. Full-bleed desktop shell (no matte frame).
|
|
291
311
|
// Shutter-out: soft rounded -> radius 0, then flat edge-to-edge.
|
|
292
312
|
const desk = {
|
|
293
|
-
width:
|
|
294
|
-
height:
|
|
313
|
+
width: stage.width,
|
|
314
|
+
height: stage.height,
|
|
295
315
|
};
|
|
296
316
|
page.__wgDeviceShell = { ...desk };
|
|
297
|
-
await applyVideoDeviceStage(page, desk,
|
|
317
|
+
await applyVideoDeviceStage(page, desk, stage, {
|
|
298
318
|
clear: false,
|
|
299
319
|
shutterOut: true,
|
|
300
320
|
desktopFlat: true,
|
|
301
321
|
});
|
|
302
322
|
try {
|
|
303
|
-
await realSet(
|
|
323
|
+
await realSet(stage);
|
|
304
324
|
} catch {
|
|
305
325
|
/* ignore */
|
|
306
326
|
}
|
|
307
327
|
} else {
|
|
308
|
-
// Lerp shell size when switching mobile <-> tablet mid-
|
|
328
|
+
// Lerp shell size when switching mobile <-> tablet mid-run.
|
|
309
329
|
const firstDevice = !page.__wgDeviceShell;
|
|
310
330
|
if (
|
|
311
331
|
announce &&
|
|
@@ -322,22 +342,22 @@ export async function applyDeviceToPage(page, device, sync) {
|
|
|
322
342
|
width: Math.round(shellFrom.width + (target.width - shellFrom.width) * e),
|
|
323
343
|
height: Math.round(shellFrom.height + (target.height - shellFrom.height) * e),
|
|
324
344
|
};
|
|
325
|
-
await applyVideoDeviceStage(page, mid,
|
|
345
|
+
await applyVideoDeviceStage(page, mid, stage, {
|
|
326
346
|
clear: false,
|
|
327
347
|
enterIn: i === 1 && firstDevice,
|
|
328
348
|
});
|
|
329
349
|
if (i < steps) await new Promise((r) => setTimeout(r, stepMs));
|
|
330
350
|
}
|
|
331
351
|
} else {
|
|
332
|
-
await applyVideoDeviceStage(page, target,
|
|
352
|
+
await applyVideoDeviceStage(page, target, stage, {
|
|
333
353
|
clear: false,
|
|
334
354
|
enterIn: firstDevice || announce,
|
|
335
355
|
});
|
|
336
356
|
}
|
|
337
357
|
page.__wgDeviceShell = { ...target };
|
|
338
|
-
// Re-assert stage size after any prior
|
|
358
|
+
// Re-assert stage size after any prior fitWindow.
|
|
339
359
|
try {
|
|
340
|
-
await realSet(
|
|
360
|
+
await realSet(stage);
|
|
341
361
|
} catch {
|
|
342
362
|
/* ignore */
|
|
343
363
|
}
|
|
@@ -8,6 +8,14 @@ export function installBanner(args: {
|
|
|
8
8
|
todoPos?: string | undefined;
|
|
9
9
|
envAutoplay?: boolean | undefined;
|
|
10
10
|
todoDockUi?: unknown;
|
|
11
|
-
bannerUi?:
|
|
11
|
+
bannerUi?:
|
|
12
|
+
| {
|
|
13
|
+
hidden?: boolean | undefined;
|
|
14
|
+
collision?: boolean | undefined;
|
|
15
|
+
pos?: string | undefined;
|
|
16
|
+
/** Title-change fade duration in ms (default 220); 0 = instant swap, no fade. */
|
|
17
|
+
captionFadeMs?: number | undefined;
|
|
18
|
+
}
|
|
19
|
+
| undefined;
|
|
12
20
|
tag?: string | undefined;
|
|
13
21
|
}): void;
|
|
@@ -43,14 +43,31 @@ export function installBanner({ title, favicon, bannerPos, todoPos, envAutoplay,
|
|
|
43
43
|
__wgAdd(banner);
|
|
44
44
|
} else {
|
|
45
45
|
// Fixture / episode title changes every step - update in place
|
|
46
|
-
// (banner is created once; do not leave the first step's text stuck).
|
|
46
|
+
// (banner is created once; do not leave the first step's text stuck). Fades out/in
|
|
47
|
+
// instead of an instant swap, so a title change reads as a deliberate beat, not a
|
|
48
|
+
// flicker - opt-out (or re-tune) via bannerUi.captionFadeMs, 0 = instant.
|
|
47
49
|
let text = banner.querySelector(".wg-banner-text");
|
|
48
50
|
if (!text) {
|
|
49
51
|
text = document.createElement("span");
|
|
50
52
|
text.className = "wg-banner-text";
|
|
51
53
|
banner.appendChild(text);
|
|
52
54
|
}
|
|
53
|
-
text.textContent
|
|
55
|
+
if (text.textContent !== title) {
|
|
56
|
+
const fadeMs =
|
|
57
|
+
bannerUi && Number.isFinite(Number(bannerUi.captionFadeMs))
|
|
58
|
+
? Math.max(0, Number(bannerUi.captionFadeMs))
|
|
59
|
+
: 220;
|
|
60
|
+
if (fadeMs <= 0 || !text.textContent) {
|
|
61
|
+
text.textContent = title;
|
|
62
|
+
} else {
|
|
63
|
+
text.style.transition = "opacity " + fadeMs + "ms ease";
|
|
64
|
+
text.style.opacity = "0";
|
|
65
|
+
setTimeout(() => {
|
|
66
|
+
text.textContent = title;
|
|
67
|
+
text.style.opacity = "1";
|
|
68
|
+
}, fadeMs);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
54
71
|
}
|
|
55
72
|
}
|
|
56
73
|
// Authored banner UX (StubCtx.titlePos / bannerUi): applied every step, wins over click/env.
|
|
@@ -107,6 +124,14 @@ export function installBanner({ title, favicon, bannerPos, todoPos, envAutoplay,
|
|
|
107
124
|
if (b.dataset.home) b.dataset.pos = b.dataset.home;
|
|
108
125
|
delete b.dataset.moved;
|
|
109
126
|
};
|
|
127
|
+
// Dim the banner while a ring caption is the focus - same "auto opacity" effect the todo
|
|
128
|
+
// dock already has via __wgTodosSetBehind, extended to the banner so both floating chrome
|
|
129
|
+
// pieces step back the same way instead of only one of them fading.
|
|
130
|
+
window.__wgBannerSetBehind = (on) => {
|
|
131
|
+
const b = __wgById("wg-banner");
|
|
132
|
+
if (!b) return;
|
|
133
|
+
b.classList.toggle("wg-banner-behind", !!on);
|
|
134
|
+
};
|
|
110
135
|
// Tab title/favicon: a real navigation resets document.title and any
|
|
111
136
|
// <link rel="icon"> the new document brings, so re-check (not
|
|
112
137
|
// re-append) on every call instead of a one-time flag.
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
// In-page installer (page.evaluate target) - must stay self-contained, no module-scope closure.
|
|
2
|
+
// Bottom narration caption - a white rounded card, not the dark zsign-ported scrim this started as
|
|
3
|
+
// (see ui/css/caption.css's own header); narration-timeline/TTS sync not ported yet.
|
|
4
|
+
export function showCaption(text) {
|
|
5
|
+
let bar = __wgById("wg-caption-bar");
|
|
6
|
+
if (!bar) {
|
|
7
|
+
bar = document.createElement("div");
|
|
8
|
+
bar.id = "wg-caption-bar";
|
|
9
|
+
bar.setAttribute("data-wg-ui", "1");
|
|
10
|
+
const span = document.createElement("span");
|
|
11
|
+
span.className = "wg-caption-text";
|
|
12
|
+
bar.appendChild(span);
|
|
13
|
+
__wgAdd(bar);
|
|
14
|
+
}
|
|
15
|
+
const span = bar.querySelector(".wg-caption-text");
|
|
16
|
+
span.textContent = text;
|
|
17
|
+
bar.classList.add("wg-in");
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export function hideCaption() {
|
|
21
|
+
const bar = __wgById("wg-caption-bar");
|
|
22
|
+
if (bar) bar.classList.remove("wg-in");
|
|
23
|
+
}
|
|
@@ -78,7 +78,25 @@ export function installCore({ title, favicon, bannerPos, todoPos, envAutoplay, t
|
|
|
78
78
|
const lh = ringLabel.offsetHeight;
|
|
79
79
|
let labelLeft = left;
|
|
80
80
|
let labelTop = top + height + 8;
|
|
81
|
-
|
|
81
|
+
const aboveTop = top - lh - 8;
|
|
82
|
+
if (labelTop + lh > vh - margin) {
|
|
83
|
+
labelTop = aboveTop;
|
|
84
|
+
} else {
|
|
85
|
+
// Below the ringed box is often the NEXT form field in a tightly stacked list (e.g.
|
|
86
|
+
// saucedemo's checkout "First Name" / "Last Name" / "Zip" inputs) - a fixed +8px gap
|
|
87
|
+
// has no idea that's there and the label just sits on top of it. Sample a few points
|
|
88
|
+
// under the would-be label and flip above if any land on real page content (not our
|
|
89
|
+
// own ring/label elements, which are the only things expected there otherwise).
|
|
90
|
+
const probe = (x, y) => {
|
|
91
|
+
const el = document.elementFromPoint(x, y);
|
|
92
|
+
return el && el.id !== ringId && el.id !== labelId && !(el.closest && el.closest("#wg-root"));
|
|
93
|
+
};
|
|
94
|
+
const hitsPageContent =
|
|
95
|
+
probe(labelLeft + 2, labelTop + 2) ||
|
|
96
|
+
probe(labelLeft + lw - 2, labelTop + 2) ||
|
|
97
|
+
probe(labelLeft + 2, labelTop + lh - 2);
|
|
98
|
+
if (hitsPageContent && aboveTop >= margin) labelTop = aboveTop;
|
|
99
|
+
}
|
|
82
100
|
if (labelTop < margin) labelTop = margin;
|
|
83
101
|
if (labelLeft + lw > vw - margin) labelLeft = Math.max(margin, vw - margin - lw);
|
|
84
102
|
if (labelLeft < margin) labelLeft = margin;
|
|
@@ -136,6 +154,7 @@ export function installCore({ title, favicon, bannerPos, todoPos, envAutoplay, t
|
|
|
136
154
|
if (!box) return;
|
|
137
155
|
window.__wgPaintRingAt("wg-ring", "wg-ring-label", box, label, tone, style);
|
|
138
156
|
if (window.__wgTodosSetBehind) window.__wgTodosSetBehind(true);
|
|
157
|
+
if (window.__wgBannerSetBehind) window.__wgBannerSetBehind(true);
|
|
139
158
|
if (window.__wgTodosAvoidRingCollision) window.__wgTodosAvoidRingCollision(box);
|
|
140
159
|
if (window.__wgBannerAvoidRing) window.__wgBannerAvoidRing(box);
|
|
141
160
|
};
|
|
@@ -188,22 +207,25 @@ export function installCore({ title, favicon, bannerPos, todoPos, envAutoplay, t
|
|
|
188
207
|
break;
|
|
189
208
|
}
|
|
190
209
|
};
|
|
191
|
-
/** Live-follow a
|
|
210
|
+
/** Live-follow a resolved element with rAF (accurate under device shell scale). */
|
|
192
211
|
window.__wgStopRingFollow = () => {
|
|
193
212
|
if (window.__wgRingFollowRaf) {
|
|
194
213
|
cancelAnimationFrame(window.__wgRingFollowRaf);
|
|
195
214
|
window.__wgRingFollowRaf = 0;
|
|
196
215
|
}
|
|
197
|
-
window.
|
|
216
|
+
window.__wgRingFollowEl = null;
|
|
198
217
|
};
|
|
199
|
-
|
|
218
|
+
// `el` is a real DOM element (a Playwright ElementHandle unwrapped by evaluate() - see
|
|
219
|
+
// rings.js's showRing), not a selector string - >> piercing / :has-text() are Playwright's
|
|
220
|
+
// own selector-engine syntax, which document.querySelector has no way to understand, so
|
|
221
|
+
// resolution happens once on the Node side via page.locator(), before this ever runs.
|
|
222
|
+
window.__wgFollowRing = (el, label, tone, style, focus) => {
|
|
200
223
|
window.__wgStopRingFollow();
|
|
201
|
-
if (!
|
|
202
|
-
window.
|
|
224
|
+
if (!el) return;
|
|
225
|
+
window.__wgRingFollowEl = el;
|
|
203
226
|
const tick = () => {
|
|
204
|
-
if (window.
|
|
205
|
-
|
|
206
|
-
if (!el) {
|
|
227
|
+
if (window.__wgRingFollowEl !== el) return;
|
|
228
|
+
if (!el.isConnected) {
|
|
207
229
|
window.__wgRingFollowRaf = requestAnimationFrame(tick);
|
|
208
230
|
return;
|
|
209
231
|
}
|
|
@@ -244,6 +266,7 @@ export function installCore({ title, favicon, bannerPos, todoPos, envAutoplay, t
|
|
|
244
266
|
if (ringLabel) ringLabel.style.opacity = "0";
|
|
245
267
|
if (window.__wgClearFocus) window.__wgClearFocus();
|
|
246
268
|
if (window.__wgTodosSetBehind) window.__wgTodosSetBehind(false);
|
|
269
|
+
if (window.__wgBannerSetBehind) window.__wgBannerSetBehind(false);
|
|
247
270
|
if (window.__wgBannerRestore) window.__wgBannerRestore();
|
|
248
271
|
window.__wgTodoCollisionLocked = false;
|
|
249
272
|
__wgQA(".wg-todo-dock[data-tucked], #wg-todo-dock[data-tucked]").forEach((el) => {
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/** In-page installer (page.evaluate target) - see network.js's own header. */
|
|
2
|
+
export interface NetworkEntry {
|
|
3
|
+
method: string;
|
|
4
|
+
url: string;
|
|
5
|
+
status: number;
|
|
6
|
+
ok: boolean;
|
|
7
|
+
ms?: number | undefined;
|
|
8
|
+
reqHeaders?: Record<string, string> | undefined;
|
|
9
|
+
resHeaders?: Record<string, string> | undefined;
|
|
10
|
+
reqBody?: string | undefined;
|
|
11
|
+
resBody?: string | undefined;
|
|
12
|
+
}
|
|
13
|
+
export function addNetworkEntry(entry: NetworkEntry): void;
|
|
14
|
+
export function setNetworkTabVisible(visible: boolean): void;
|
|
15
|
+
export function clearNetworkLog(): void;
|
|
@@ -0,0 +1,217 @@
|
|
|
1
|
+
// In-page installer (page.evaluate target) - must stay self-contained, no module-scope closure
|
|
2
|
+
// (page.evaluate serializes ONLY the passed function's own source, not sibling top-level
|
|
3
|
+
// functions in this file - every helper below is nested inside addNetworkEntry itself for exactly
|
|
4
|
+
// that reason; a row's click handler still works after addNetworkEntry returns because it's a
|
|
5
|
+
// closure over ITS OWN invocation's nested helpers, not a reference to module scope).
|
|
6
|
+
//
|
|
7
|
+
// A real network-tab overlay (`#wg-network-log`): the DevTools Network panel itself can't be
|
|
8
|
+
// embedded (it lives in browser chrome, not reachable from automation), but every entry's real
|
|
9
|
+
// data is - this renders that, on-page: method, url, status, and (click a row) request/response
|
|
10
|
+
// headers + bodies + a "copy as cURL" command, a Postman-style inspector for both real page
|
|
11
|
+
// traffic (installNetworkCapture, network-capture.js) and defineApiBlock's own page.request calls.
|
|
12
|
+
export function addNetworkEntry(entry) {
|
|
13
|
+
// No-op outside a demo/pilot/auto run - ensureShadowRoot() (and its __wgById/__wgAdd globals)
|
|
14
|
+
// is never installed for a plain `waygraph run`/Playwright test, and this must not throw there.
|
|
15
|
+
if (typeof __wgById !== "function" || typeof __wgAdd !== "function") return;
|
|
16
|
+
|
|
17
|
+
function esc(s) {
|
|
18
|
+
const d = document.createElement("div");
|
|
19
|
+
d.textContent = String(s == null ? "" : s);
|
|
20
|
+
return d.innerHTML;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
function methodClass(method) {
|
|
24
|
+
const m = (method || "GET").toUpperCase();
|
|
25
|
+
if (m === "GET") return "get";
|
|
26
|
+
if (m === "POST") return "post";
|
|
27
|
+
if (m === "PUT" || m === "PATCH") return "put";
|
|
28
|
+
if (m === "DELETE") return "delete";
|
|
29
|
+
return "other";
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
function toCurl(e) {
|
|
33
|
+
let cmd = "curl -X " + (e.method || "GET") + " '" + String(e.url || "").replace(/'/g, "'\\''") + "'";
|
|
34
|
+
const headers = e.reqHeaders || {};
|
|
35
|
+
for (const k of Object.keys(headers)) {
|
|
36
|
+
if (/^:/.test(k)) continue; // HTTP/2 pseudo-headers - not valid curl -H input
|
|
37
|
+
cmd += " \\\n -H '" + k + ": " + String(headers[k]).replace(/'/g, "'\\''") + "'";
|
|
38
|
+
}
|
|
39
|
+
if (e.reqBody) cmd += " \\\n --data '" + String(e.reqBody).replace(/'/g, "'\\''") + "'";
|
|
40
|
+
return cmd;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
function renderHeaders(headers) {
|
|
44
|
+
const h = headers || {};
|
|
45
|
+
const keys = Object.keys(h);
|
|
46
|
+
if (keys.length === 0) return '<div class="wg-net-empty">(none)</div>';
|
|
47
|
+
return (
|
|
48
|
+
'<table class="wg-net-headers">' +
|
|
49
|
+
keys.map((k) => "<tr><td>" + esc(k) + "</td><td>" + esc(h[k]) + "</td></tr>").join("") +
|
|
50
|
+
"</table>"
|
|
51
|
+
);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
function renderBody(body) {
|
|
55
|
+
if (body === undefined || body === null || body === "") return '<div class="wg-net-empty">(empty)</div>';
|
|
56
|
+
let text = body;
|
|
57
|
+
try {
|
|
58
|
+
text = JSON.stringify(JSON.parse(body), null, 2);
|
|
59
|
+
} catch {
|
|
60
|
+
/* not JSON - show raw */
|
|
61
|
+
}
|
|
62
|
+
return "<pre class=\"wg-net-body\">" + esc(String(text).slice(0, 4000)) + "</pre>";
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
function renderDetail(e) {
|
|
66
|
+
return (
|
|
67
|
+
'<div class="wg-net-detail-section"><h4>Request headers</h4>' +
|
|
68
|
+
renderHeaders(e.reqHeaders) +
|
|
69
|
+
"</div>" +
|
|
70
|
+
(e.reqBody
|
|
71
|
+
? '<div class="wg-net-detail-section"><h4>Request body</h4>' + renderBody(e.reqBody) + "</div>"
|
|
72
|
+
: "") +
|
|
73
|
+
'<div class="wg-net-detail-section"><h4>Response headers</h4>' +
|
|
74
|
+
renderHeaders(e.resHeaders) +
|
|
75
|
+
"</div>" +
|
|
76
|
+
'<div class="wg-net-detail-section"><h4>Response body</h4>' +
|
|
77
|
+
renderBody(e.resBody) +
|
|
78
|
+
"</div>" +
|
|
79
|
+
'<div class="wg-net-detail-section"><h4>cURL</h4>' +
|
|
80
|
+
'<pre class="wg-net-body wg-net-curl">' +
|
|
81
|
+
esc(toCurl(e)) +
|
|
82
|
+
"</pre>" +
|
|
83
|
+
'<button type="button" class="wg-net-copy" data-copy="1">Copy as cURL</button></div>'
|
|
84
|
+
);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
let panel = __wgById("wg-network-log");
|
|
88
|
+
if (!panel) {
|
|
89
|
+
panel = document.createElement("div");
|
|
90
|
+
panel.id = "wg-network-log";
|
|
91
|
+
panel.setAttribute("data-wg-ui", "1");
|
|
92
|
+
const header = document.createElement("div");
|
|
93
|
+
header.className = "wg-net-header";
|
|
94
|
+
const title = document.createElement("span");
|
|
95
|
+
title.className = "wg-net-title";
|
|
96
|
+
title.textContent = "Network";
|
|
97
|
+
const count = document.createElement("span");
|
|
98
|
+
count.className = "wg-net-count";
|
|
99
|
+
count.textContent = "0";
|
|
100
|
+
const toggle = document.createElement("button");
|
|
101
|
+
toggle.type = "button";
|
|
102
|
+
toggle.className = "wg-net-collapse";
|
|
103
|
+
toggle.textContent = "−"; // minus
|
|
104
|
+
toggle.addEventListener("click", (ev) => {
|
|
105
|
+
ev.stopPropagation();
|
|
106
|
+
panel.classList.toggle("wg-net-collapsed");
|
|
107
|
+
toggle.textContent = panel.classList.contains("wg-net-collapsed") ? "+" : "−";
|
|
108
|
+
});
|
|
109
|
+
header.appendChild(title);
|
|
110
|
+
header.appendChild(count);
|
|
111
|
+
header.appendChild(toggle);
|
|
112
|
+
const list = document.createElement("ol");
|
|
113
|
+
list.className = "wg-net-list";
|
|
114
|
+
panel.appendChild(header);
|
|
115
|
+
panel.appendChild(list);
|
|
116
|
+
__wgAdd(panel);
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
const w = window;
|
|
120
|
+
w.__wgNetworkEntries = w.__wgNetworkEntries || [];
|
|
121
|
+
w.__wgNetworkEntries.push(entry);
|
|
122
|
+
while (w.__wgNetworkEntries.length > 30) w.__wgNetworkEntries.shift();
|
|
123
|
+
|
|
124
|
+
const list = panel.querySelector(".wg-net-list");
|
|
125
|
+
const row = document.createElement("li");
|
|
126
|
+
row.className = "wg-net-row";
|
|
127
|
+
row.dataset.ok = entry.ok ? "1" : "0";
|
|
128
|
+
let path = entry.url;
|
|
129
|
+
try {
|
|
130
|
+
const u = new URL(entry.url);
|
|
131
|
+
path = u.pathname + u.search;
|
|
132
|
+
} catch {
|
|
133
|
+
/* not an absolute URL - show as given */
|
|
134
|
+
}
|
|
135
|
+
row.innerHTML =
|
|
136
|
+
'<span class="wg-net-method wg-net-method-' +
|
|
137
|
+
methodClass(entry.method) +
|
|
138
|
+
'">' +
|
|
139
|
+
esc((entry.method || "GET").toUpperCase()) +
|
|
140
|
+
'</span><span class="wg-net-path" title="' +
|
|
141
|
+
esc(entry.url) +
|
|
142
|
+
'">' +
|
|
143
|
+
esc(path) +
|
|
144
|
+
'</span><span class="wg-net-status">' +
|
|
145
|
+
esc(entry.status) +
|
|
146
|
+
(entry.ms !== undefined ? '</span><span class="wg-net-ms">' + esc(entry.ms) + "ms</span>" : "</span>");
|
|
147
|
+
row.addEventListener("click", () => {
|
|
148
|
+
const open = row.classList.contains("wg-net-open");
|
|
149
|
+
__wgQA(".wg-net-row.wg-net-open").forEach((r) => {
|
|
150
|
+
r.classList.remove("wg-net-open");
|
|
151
|
+
const d = r.nextElementSibling;
|
|
152
|
+
if (d && d.classList && d.classList.contains("wg-net-detail")) d.remove();
|
|
153
|
+
});
|
|
154
|
+
if (open) return;
|
|
155
|
+
row.classList.add("wg-net-open");
|
|
156
|
+
const detail = document.createElement("li");
|
|
157
|
+
detail.className = "wg-net-detail";
|
|
158
|
+
detail.innerHTML = renderDetail(entry);
|
|
159
|
+
const copyBtn = detail.querySelector("[data-copy]");
|
|
160
|
+
if (copyBtn) {
|
|
161
|
+
copyBtn.addEventListener("click", (ev) => {
|
|
162
|
+
ev.stopPropagation();
|
|
163
|
+
const text = toCurl(entry);
|
|
164
|
+
if (navigator.clipboard && navigator.clipboard.writeText) {
|
|
165
|
+
navigator.clipboard.writeText(text).catch(() => {});
|
|
166
|
+
}
|
|
167
|
+
copyBtn.textContent = "Copied!";
|
|
168
|
+
setTimeout(() => {
|
|
169
|
+
copyBtn.textContent = "Copy as cURL";
|
|
170
|
+
}, 1200);
|
|
171
|
+
});
|
|
172
|
+
}
|
|
173
|
+
row.after(detail);
|
|
174
|
+
});
|
|
175
|
+
list.appendChild(row);
|
|
176
|
+
while (list.children.length > 30) list.removeChild(list.firstChild);
|
|
177
|
+
const countEl = panel.querySelector(".wg-net-count");
|
|
178
|
+
if (countEl) countEl.textContent = String(w.__wgNetworkEntries.length);
|
|
179
|
+
// Always captured, only shown when explicitly turned on (ctx.showNetworkTab(); default hidden -
|
|
180
|
+
// see StubCtx's own doc comment) - the DOM/row still gets built either way, so toggling visible
|
|
181
|
+
// later shows the full history immediately, not just entries captured after that point.
|
|
182
|
+
if (w.__wgNetworkTabVisible) {
|
|
183
|
+
panel.classList.remove("wg-out");
|
|
184
|
+
void panel.offsetWidth;
|
|
185
|
+
panel.classList.add("wg-in");
|
|
186
|
+
void row.offsetWidth;
|
|
187
|
+
row.classList.add("wg-in");
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
/**
|
|
192
|
+
* Shows or hides the network-tab panel - capture keeps happening either way (addNetworkEntry
|
|
193
|
+
* always builds the DOM row; this only toggles whether the panel itself is visible). Safe to call
|
|
194
|
+
* before any entry exists yet - it just remembers the flag for addNetworkEntry to check later.
|
|
195
|
+
*/
|
|
196
|
+
export function setNetworkTabVisible(visible) {
|
|
197
|
+
if (typeof __wgById !== "function") return;
|
|
198
|
+
window.__wgNetworkTabVisible = !!visible;
|
|
199
|
+
const panel = __wgById("wg-network-log");
|
|
200
|
+
if (!panel) return;
|
|
201
|
+
if (visible) {
|
|
202
|
+
panel.classList.remove("wg-out");
|
|
203
|
+
panel.classList.add("wg-in");
|
|
204
|
+
__wgQA(".wg-net-row").forEach((r) => r.classList.add("wg-in"));
|
|
205
|
+
} else {
|
|
206
|
+
panel.classList.remove("wg-in");
|
|
207
|
+
panel.classList.add("wg-out");
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
/** Clears every captured entry and removes the panel - a fresh navigation/session starting over. */
|
|
212
|
+
export function clearNetworkLog() {
|
|
213
|
+
if (typeof __wgById !== "function") return;
|
|
214
|
+
window.__wgNetworkEntries = [];
|
|
215
|
+
const panel = __wgById("wg-network-log");
|
|
216
|
+
if (panel) panel.remove();
|
|
217
|
+
}
|
|
@@ -60,6 +60,40 @@ export function installPanelChrome({ title, favicon, bannerPos, todoPos, envAuto
|
|
|
60
60
|
ensureChrome();
|
|
61
61
|
const stepLabel = opts.stepLabel || panel.dataset.wgStepLabel || "";
|
|
62
62
|
if (stepLabel) panel.dataset.wgStepLabel = stepLabel;
|
|
63
|
+
if (opts.fastForward !== undefined) {
|
|
64
|
+
panel.dataset.wgFastForward = opts.fastForward ? "1" : "0";
|
|
65
|
+
}
|
|
66
|
+
if (opts.isApi !== undefined) {
|
|
67
|
+
panel.dataset.wgIsApi = opts.isApi ? "1" : "0";
|
|
68
|
+
}
|
|
69
|
+
const buildFfIcon = () => {
|
|
70
|
+
const span = document.createElement("span");
|
|
71
|
+
span.className = "wg-ff-icon";
|
|
72
|
+
span.setAttribute("aria-hidden", "true");
|
|
73
|
+
span.innerHTML =
|
|
74
|
+
'<svg viewBox="0 0 16 16" fill="none">' +
|
|
75
|
+
'<path class="wg-ff-chev" d="M2 3l5 5-5 5" stroke="#c9a6ff" stroke-width="1.8" ' +
|
|
76
|
+
'stroke-linecap="round" stroke-linejoin="round"/>' +
|
|
77
|
+
'<path class="wg-ff-chev" d="M8 3l5 5-5 5" stroke="#c9a6ff" stroke-width="1.8" ' +
|
|
78
|
+
'stroke-linecap="round" stroke-linejoin="round"/></svg>';
|
|
79
|
+
return span;
|
|
80
|
+
};
|
|
81
|
+
// Terminal icon: the current step is an API check (defineApiBlock) - no DOM change, no
|
|
82
|
+
// ring of its own, so without this it's an unexplained instant step with nothing visibly
|
|
83
|
+
// happening on the page at all (worse than a fast-forward block, which at least has the
|
|
84
|
+
// FF icon marking it as different).
|
|
85
|
+
const buildApiIcon = () => {
|
|
86
|
+
const span = document.createElement("span");
|
|
87
|
+
span.className = "wg-api-icon";
|
|
88
|
+
span.setAttribute("aria-hidden", "true");
|
|
89
|
+
span.innerHTML =
|
|
90
|
+
'<svg viewBox="0 0 16 16" fill="none">' +
|
|
91
|
+
'<rect x="1" y="2" width="14" height="12" rx="1.5" stroke="#7dd3fc" stroke-width="1.3"/>' +
|
|
92
|
+
'<path d="M3.5 5.5l2.5 2.5-2.5 2.5" stroke="#7dd3fc" stroke-width="1.3" ' +
|
|
93
|
+
'stroke-linecap="round" stroke-linejoin="round"/>' +
|
|
94
|
+
'<path d="M7.5 10.5h4" stroke="#7dd3fc" stroke-width="1.3" stroke-linecap="round"/></svg>';
|
|
95
|
+
return span;
|
|
96
|
+
};
|
|
63
97
|
const syncMiniNext = (hidden) => {
|
|
64
98
|
const miniNext = panel.querySelector("[data-wg-mini-next]");
|
|
65
99
|
if (!miniNext) return;
|
|
@@ -85,10 +119,16 @@ export function installPanelChrome({ title, favicon, bannerPos, todoPos, envAuto
|
|
|
85
119
|
const t = panel.querySelector("[data-wg-toggle]");
|
|
86
120
|
const titleEl = panel.querySelector(".wg-chrome-title");
|
|
87
121
|
const label = panel.dataset.wgStepLabel || stepLabel;
|
|
122
|
+
const isFf = panel.dataset.wgFastForward === "1";
|
|
123
|
+
const isApi = panel.dataset.wgIsApi === "1";
|
|
88
124
|
if (titleEl) {
|
|
89
|
-
|
|
125
|
+
const text = hidden
|
|
90
126
|
? (label || chromeTitle || "waygraph demo")
|
|
91
127
|
: (chromeTitle || "waygraph demo");
|
|
128
|
+
titleEl.textContent = "";
|
|
129
|
+
if (hidden && isFf) titleEl.appendChild(buildFfIcon());
|
|
130
|
+
if (hidden && isApi) titleEl.appendChild(buildApiIcon());
|
|
131
|
+
titleEl.appendChild(document.createTextNode(text));
|
|
92
132
|
}
|
|
93
133
|
if (t) t.textContent = hidden ? "Show" : "Hide";
|
|
94
134
|
syncMiniNext(hidden);
|
|
@@ -125,7 +125,7 @@ export function installSwipeZoom({ title, favicon, bannerPos, todoPos, envAutopl
|
|
|
125
125
|
if (window.__wgSetZoomBadge) window.__wgSetZoomBadge(1, "");
|
|
126
126
|
};
|
|
127
127
|
const ZOOM_ICO =
|
|
128
|
-
'<svg viewBox="0 0 24 24" fill="none" stroke="#
|
|
128
|
+
'<svg viewBox="0 0 24 24" fill="none" stroke="#c9a6ff" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">' +
|
|
129
129
|
'<circle cx="11" cy="11" r="7"/><path d="M20 20l-3.5-3.5"/></svg>';
|
|
130
130
|
window.__wgSetZoomBadge = (scale, sel) => {
|
|
131
131
|
const n = Number(scale);
|
|
@@ -51,7 +51,12 @@ export function installTodos({ title, favicon, bannerPos, todoPos, envAutoplay,
|
|
|
51
51
|
);
|
|
52
52
|
const relayoutTodoDocks = () => {
|
|
53
53
|
const docks = allDocks();
|
|
54
|
-
|
|
54
|
+
// Must match .wg-todo-dock/#wg-todo-dock's own CSS `top` (runner/overlay-css.js,
|
|
55
|
+
// ui/css/dock.css) - this inline style OVERRIDES that CSS the instant more than one
|
|
56
|
+
// dock exists (multi-todo stacking), so a CSS-only change here is silently underwater;
|
|
57
|
+
// real bug this was: the CSS top was bumped 72 -> 104 for banner clearance, but this
|
|
58
|
+
// hardcoded 72 kept winning at runtime and nothing actually moved.
|
|
59
|
+
let top = 104;
|
|
55
60
|
for (const el of docks) {
|
|
56
61
|
el.style.top = top + "px";
|
|
57
62
|
top += Math.max(48, el.getBoundingClientRect().height) + 10;
|
package/dist/runner/main.js
CHANGED
|
@@ -8,7 +8,7 @@ import { isExpectedChainFailure, parseVideoViewport, runChainedFlows, runJsonRep
|
|
|
8
8
|
import { runStepMode } from "./step-mode.js";
|
|
9
9
|
import { connect } from "../types.js";
|
|
10
10
|
import { MemPage } from "../mem-page.js";
|
|
11
|
-
import { Engine, start, end, chainFlow, isFastForwardBlock, branchRoutes, runBranchRegression } from "../
|
|
11
|
+
import { Engine, start, end, chainFlow, isFastForwardBlock, branchRoutes, runBranchRegression } from "../core.js";
|
|
12
12
|
|
|
13
13
|
async function main() {
|
|
14
14
|
const projectDir = process.argv[2];
|
|
@@ -356,6 +356,13 @@ async function main() {
|
|
|
356
356
|
}
|
|
357
357
|
}
|
|
358
358
|
} finally {
|
|
359
|
+
// A recorded run's last visible state (a fixture ring, the network panel, a todo dock update)
|
|
360
|
+
// gets cut off mid-fade otherwise - context.close() used to fire the instant the flow's own
|
|
361
|
+
// promise resolved, with zero trailing room. Real, confirmed case: defineApiBlock's network
|
|
362
|
+
// panel only became visible in the recording's final ~1-2s because of this.
|
|
363
|
+
if (process.env.WAYGRAPH_VIDEO && pageForVideo && !pageForVideo.isClosed()) {
|
|
364
|
+
await new Promise((r) => setTimeout(r, 1800));
|
|
365
|
+
}
|
|
359
366
|
await context.close();
|
|
360
367
|
const savedVideo =
|
|
361
368
|
pageForVideo?.video() !== null && pageForVideo?.video() !== undefined
|
|
@@ -394,7 +401,7 @@ async function main() {
|
|
|
394
401
|
|
|
395
402
|
/**
|
|
396
403
|
* `waygraph run --blocks <flowName> --all-branches`: explore every path through that flow's own
|
|
397
|
-
* `.branch()` tree (see src/
|
|
404
|
+
* `.branch()` tree (see src/core/branch-regression.ts), not just whichever one the live state
|
|
398
405
|
* would dispatch to. Needs a single, bare Flow reference - a multi-segment chain spec has no one
|
|
399
406
|
* Flow to walk. `--shared-session` opts out of session cloning (WAYGRAPH_SHARED_SESSION=1).
|
|
400
407
|
*/
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { Page } from "@playwright/test";
|
|
2
|
+
import type { NetworkEntry } from "./inpage/network.js";
|
|
3
|
+
|
|
4
|
+
/** Records one network-tab entry (and paints it live) - see network-capture.js's own header. */
|
|
5
|
+
export function recordNetworkEntry(page: Page, entry: NetworkEntry): Promise<void>;
|
|
6
|
+
/** Replays page.__wgNetworkHistory into a freshly (re)installed panel after a navigation. */
|
|
7
|
+
export function restoreNetworkHistory(page: Page): Promise<void>;
|
|
8
|
+
/** Hooks page.on('request'/'requestfinished') to capture real page traffic into the same panel. */
|
|
9
|
+
export function installNetworkCapture(page: Page): void;
|