waygraph 0.15.47 → 0.15.49
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 +2 -2
- package/dist/cli/discover.d.ts +1 -1
- package/dist/cli/discover.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/{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/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 +5 -3
- package/dist/index.js +1 -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 +1 -1
- package/dist/session/auto-explore-run.js +47 -10
- 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 +1 -1
- 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/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/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/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/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/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/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/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/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/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
package/dist/analysis/graph.js
CHANGED
|
@@ -229,12 +229,12 @@ function isBlockLike(val) {
|
|
|
229
229
|
const instruction = obj.instruction;
|
|
230
230
|
return instruction !== null && typeof instruction === "object" && typeof instruction?.act === "function";
|
|
231
231
|
}
|
|
232
|
-
/** Set by `defineNavBlock` (non-enumerable) - see src/
|
|
232
|
+
/** Set by `defineNavBlock` (non-enumerable) - see src/core.ts. */
|
|
233
233
|
function isNavBlockMarked(val) {
|
|
234
234
|
const kind = val.__waygraphKind;
|
|
235
235
|
return kind === "nav" || kind === "page";
|
|
236
236
|
}
|
|
237
|
-
/** Set by `defineAssertBlock` (non-enumerable) - see src/
|
|
237
|
+
/** Set by `defineAssertBlock` (non-enumerable) - see src/core.ts. */
|
|
238
238
|
function isAssertBlockMarked(val) {
|
|
239
239
|
return val.__waygraphKind === "assert";
|
|
240
240
|
}
|
|
@@ -3,11 +3,11 @@ import { CONSOLE_LOG_MAX_ENTRIES, FULL_MODE_DEFAULT_DEPTH, FULL_MODE_MAX_NODES,
|
|
|
3
3
|
import { instrumentPilotActions, installPersistentPilotOverlay, showPilotActivity, showPilotFixtures, showPilotVision, phaseToOverlayFixtures, describeOverlayFixtures, updatePilotOverlay } from "../pilot-overlay.js";
|
|
4
4
|
import { buildExploreContext, buildExploreMenu } from "../session/auto-explore.js";
|
|
5
5
|
import { MemPage } from "../mem-page.js";
|
|
6
|
-
import { Engine } from "../
|
|
6
|
+
import { Engine } from "../core.js";
|
|
7
7
|
import { detectHere, ensureLivePage, ensureMem, resolveBaseUrl, runOneBlock, seedDefaultMem } from "../session/auto-explore-run.js";
|
|
8
8
|
import { collectKnownInteractionSelectors, unmappedInteractionsPageScript } from "../analysis/coverage-gap.js";
|
|
9
9
|
import { runStubPhase } from "../highlights.js";
|
|
10
|
-
import { verboseLog } from "
|
|
10
|
+
import { verboseLog } from "./verbose-log.js";
|
|
11
11
|
import { findBlockPathDetailed } from "../analysis/graph.js";
|
|
12
12
|
/**
|
|
13
13
|
* Non-interactive explore session: same graph/library/mem/browser setup
|
package/dist/cli/discover.d.ts
CHANGED
|
@@ -22,7 +22,7 @@ export declare function isBlockLike(val: unknown): val is {
|
|
|
22
22
|
act: unknown;
|
|
23
23
|
};
|
|
24
24
|
};
|
|
25
|
-
/** Set by `defineNavBlock` (non-enumerable) - see src/
|
|
25
|
+
/** Set by `defineNavBlock` (non-enumerable) - see src/core.ts. */
|
|
26
26
|
export declare function isNavBlockMarked(val: Record<string, unknown>): boolean;
|
|
27
27
|
export declare const NAV_METHOD_CALLS: readonly ["page.goto(", "page.reload(", "page.goBack(", "page.goForward("];
|
|
28
28
|
/**
|
package/dist/cli/discover.js
CHANGED
|
@@ -128,7 +128,7 @@ export function isBlockLike(val) {
|
|
|
128
128
|
const instruction = obj.instruction;
|
|
129
129
|
return instruction !== null && typeof instruction === "object" && typeof instruction?.act === "function";
|
|
130
130
|
}
|
|
131
|
-
/** Set by `defineNavBlock` (non-enumerable) - see src/
|
|
131
|
+
/** Set by `defineNavBlock` (non-enumerable) - see src/core.ts. */
|
|
132
132
|
export function isNavBlockMarked(val) {
|
|
133
133
|
return val.__waygraphKind === "nav";
|
|
134
134
|
}
|
package/dist/cli.js
CHANGED
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
*
|
|
15
15
|
* "project" defaults to cwd. Flags beat WAYGRAPH_* env.
|
|
16
16
|
*/
|
|
17
|
-
import { SKILL_FLAG_MAP, printSkillIndex, readSkillMarkdown } from "./agent-dive.js";
|
|
17
|
+
import { SKILL_FLAG_MAP, printSkillIndex, readSkillMarkdown } from "./commands/agent-dive-scaffold.js";
|
|
18
18
|
import { usage } from "./cli/usage.js";
|
|
19
19
|
import { listCase, navCase } from "./commands/list.js";
|
|
20
20
|
import { checkCase, typecheckCase, validateCase } from "./commands/check.js";
|
|
@@ -6,8 +6,8 @@ import { existsSync, mkdirSync, readdirSync, readFileSync, writeFileSync, } from
|
|
|
6
6
|
import { basename, dirname, join, resolve } from "node:path";
|
|
7
7
|
import { fileURLToPath } from "node:url";
|
|
8
8
|
function packageRoot() {
|
|
9
|
-
// dist/agent-dive.js ->
|
|
10
|
-
return resolve(dirname(fileURLToPath(import.meta.url)), "..");
|
|
9
|
+
// dist/commands/agent-dive-scaffold.js -> ../..
|
|
10
|
+
return resolve(dirname(fileURLToPath(import.meta.url)), "..", "..");
|
|
11
11
|
}
|
|
12
12
|
function agentsTemplateDir() {
|
|
13
13
|
return join(packageRoot(), "templates", "agents");
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// Split out of the former 8,700-line cli.ts (see src/ARCHITECTURE.md). Behavior unchanged.
|
|
2
|
-
import { runAgentDive } from "
|
|
2
|
+
import { runAgentDive } from "./agent-dive-scaffold.js";
|
|
3
3
|
import { resolve } from "node:path";
|
|
4
4
|
import { existsSync, statSync } from "node:fs";
|
|
5
5
|
export async function agentDiveCase(args) {
|
|
@@ -1,15 +1,15 @@
|
|
|
1
|
-
import { WaygraphError } from "../errors.js";
|
|
1
|
+
import { WaygraphError, MSG_FLOW_BLOCK_NOT_FOUND_BY_INDEX, MSG_FLOW_BLOCK_NOT_FOUND_BY_NAME, MSG_MODVERIFY_FUNCTION_FORM, MSG_MODVERIFY_NOT_FOUND_BY_INDEX, MSG_MODVERIFY_NOT_FOUND_BY_NAME, } from "../errors.js";
|
|
2
2
|
export function findBlockIndex(middle, block) {
|
|
3
3
|
if (typeof block === "number") {
|
|
4
4
|
if (block < 0 || block >= middle.length) {
|
|
5
|
-
throw new WaygraphError("WG_FLOW_BLOCK_NOT_FOUND",
|
|
5
|
+
throw new WaygraphError("WG_FLOW_BLOCK_NOT_FOUND", MSG_FLOW_BLOCK_NOT_FOUND_BY_INDEX(block, middle.length));
|
|
6
6
|
}
|
|
7
7
|
return block;
|
|
8
8
|
}
|
|
9
9
|
const blockName = typeof block === "string" ? block : block.name;
|
|
10
10
|
const index = middle.findIndex((b) => b.name === blockName);
|
|
11
11
|
if (index === -1) {
|
|
12
|
-
throw new WaygraphError("WG_FLOW_BLOCK_NOT_FOUND",
|
|
12
|
+
throw new WaygraphError("WG_FLOW_BLOCK_NOT_FOUND", MSG_FLOW_BLOCK_NOT_FOUND_BY_NAME(blockName, middle.map((b) => b.name).join(", ")));
|
|
13
13
|
}
|
|
14
14
|
return index;
|
|
15
15
|
}
|
|
@@ -229,15 +229,15 @@ export function withStubOnError(block, stub) {
|
|
|
229
229
|
export function modVerify(block, nameOrIndex, newCheck) {
|
|
230
230
|
const verify = block.instruction.verify;
|
|
231
231
|
if (typeof verify === "function") {
|
|
232
|
-
throw new WaygraphError("WG_MODVERIFY_FUNCTION_FORM",
|
|
232
|
+
throw new WaygraphError("WG_MODVERIFY_FUNCTION_FORM", MSG_MODVERIFY_FUNCTION_FORM(block.name));
|
|
233
233
|
}
|
|
234
234
|
const traits = verify ?? [];
|
|
235
235
|
const index = typeof nameOrIndex === "number" ? nameOrIndex : traits.findIndex((t) => t.name === nameOrIndex);
|
|
236
236
|
const existing = traits[index];
|
|
237
237
|
if (!existing) {
|
|
238
238
|
throw new WaygraphError("WG_MODVERIFY_NOT_FOUND", typeof nameOrIndex === "number"
|
|
239
|
-
?
|
|
240
|
-
:
|
|
239
|
+
? MSG_MODVERIFY_NOT_FOUND_BY_INDEX(block.name, nameOrIndex, traits.length)
|
|
240
|
+
: MSG_MODVERIFY_NOT_FOUND_BY_NAME(block.name, nameOrIndex, traits.map((t) => t.name).join(", ")));
|
|
241
241
|
}
|
|
242
242
|
const replacement = typeof newCheck === "function"
|
|
243
243
|
? { name: typeof nameOrIndex === "string" ? nameOrIndex : existing.name, check: newCheck }
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import type { Checkpoint, DefinedBlock } from "../../types.js";
|
|
2
|
+
import type { Trait } from "../../trait.js";
|
|
3
|
+
import { MemPage } from "../../mem-page.js";
|
|
4
|
+
import type { MemKey } from "../../mem-page.js";
|
|
5
|
+
import type { APIRequestContext, APIResponse } from "@playwright/test";
|
|
6
|
+
/** What `resolve`/`verify` see: the response's status and parsed body, nothing Playwright-specific. */
|
|
7
|
+
export interface ApiCallResult {
|
|
8
|
+
status: number;
|
|
9
|
+
ok: boolean;
|
|
10
|
+
/** `response.json()` if the body parses as JSON, else the raw text (or `undefined` if neither). */
|
|
11
|
+
body: unknown;
|
|
12
|
+
}
|
|
13
|
+
export interface ApiBlockOptions<In extends Checkpoint<string>, Out extends Checkpoint<string>> {
|
|
14
|
+
name: string;
|
|
15
|
+
description?: string;
|
|
16
|
+
/**
|
|
17
|
+
* Make the request - `request` is Playwright's own `page.request` (same cookies/origin as the
|
|
18
|
+
* browser context, so an authenticated UI session carries over to the API call for free).
|
|
19
|
+
* @example call: ({ request }) => request.get("/api/orders/1")
|
|
20
|
+
*/
|
|
21
|
+
call: (ctx: {
|
|
22
|
+
request: APIRequestContext;
|
|
23
|
+
mem: MemPage;
|
|
24
|
+
}) => Promise<APIResponse>;
|
|
25
|
+
/**
|
|
26
|
+
* HTTP method shown in the network-tab overlay (GET/POST/PATCH/...) - `APIResponse` (unlike a
|
|
27
|
+
* page's own `Response`) carries no back-reference to the request that produced it, so this
|
|
28
|
+
* can't be read back automatically; defaults to "GET" if omitted. Purely cosmetic - never
|
|
29
|
+
* affects the actual request `call` makes.
|
|
30
|
+
* @example method: "POST"
|
|
31
|
+
*/
|
|
32
|
+
method?: string;
|
|
33
|
+
/** Pure, like every other Block's resolve - classifies the response into a Checkpoint tag. */
|
|
34
|
+
resolve: (result: ApiCallResult) => Out;
|
|
35
|
+
verify?: Trait[] | ((out: Out) => Trait[]);
|
|
36
|
+
requires?: readonly MemKey<any>[];
|
|
37
|
+
stubBefore?: import("../../highlights.js").HighlightStubPhaseOrFn<Out>;
|
|
38
|
+
stubAfter?: import("../../highlights.js").HighlightStubPhaseOrFn<Out>;
|
|
39
|
+
stubOnError?: import("../../highlights.js").HighlightStubPhaseOrFn<Out>;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* A Block whose `act()` is a real HTTP request, not a page interaction - lets one Flow narrate a
|
|
43
|
+
* UI step (`.gotoPage()`) and a backend check (`.method(checkOrderCreated)`) as the same state
|
|
44
|
+
* machine, checked by the same Trait/verify system. Runs through `page.request`, so it shares the
|
|
45
|
+
* browser context's cookies/origin - no separate auth dance for an already-logged-in session.
|
|
46
|
+
* @example
|
|
47
|
+
* const CheckOrderCreated = defineApiBlock<LoggedIn, OrderConfirmed | OrderFailed>({
|
|
48
|
+
* name: "check-order-created",
|
|
49
|
+
* call: ({ request }) => request.get("/api/orders/latest"),
|
|
50
|
+
* resolve: (r) => (r.ok ? checkpoint("OrderConfirmed") : checkpoint("OrderFailed")),
|
|
51
|
+
* verify: [Trait.disabled],
|
|
52
|
+
* });
|
|
53
|
+
*/
|
|
54
|
+
export declare function defineApiBlock<In extends Checkpoint<string>, Out extends Checkpoint<string>>(options: ApiBlockOptions<In, Out>): DefinedBlock<In, Out>;
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import { defineBlock } from "../block.js";
|
|
2
|
+
import { key } from "../../mem-page.js";
|
|
3
|
+
// Internal scratch key threading act()'s result to observe()/resolve() - Instruction has no other
|
|
4
|
+
// channel for this (resolve is pure, given only what observe returns). Identity-keyed, so this can
|
|
5
|
+
// never collide with a real author's own MemKey even if names happened to match; safe to share one
|
|
6
|
+
// instance across every ApiBlock since runGraph runs act->observe->resolve fully serially per Block.
|
|
7
|
+
const API_RESULT_SCRATCH = key("__wgApiBlockResult");
|
|
8
|
+
/**
|
|
9
|
+
* A Block whose `act()` is a real HTTP request, not a page interaction - lets one Flow narrate a
|
|
10
|
+
* UI step (`.gotoPage()`) and a backend check (`.method(checkOrderCreated)`) as the same state
|
|
11
|
+
* machine, checked by the same Trait/verify system. Runs through `page.request`, so it shares the
|
|
12
|
+
* browser context's cookies/origin - no separate auth dance for an already-logged-in session.
|
|
13
|
+
* @example
|
|
14
|
+
* const CheckOrderCreated = defineApiBlock<LoggedIn, OrderConfirmed | OrderFailed>({
|
|
15
|
+
* name: "check-order-created",
|
|
16
|
+
* call: ({ request }) => request.get("/api/orders/latest"),
|
|
17
|
+
* resolve: (r) => (r.ok ? checkpoint("OrderConfirmed") : checkpoint("OrderFailed")),
|
|
18
|
+
* verify: [Trait.disabled],
|
|
19
|
+
* });
|
|
20
|
+
*/
|
|
21
|
+
export function defineApiBlock(options) {
|
|
22
|
+
const built = defineBlock({
|
|
23
|
+
name: options.name,
|
|
24
|
+
...(options.description ? { description: options.description } : {}),
|
|
25
|
+
...(options.requires ? { requires: options.requires } : {}),
|
|
26
|
+
instruction: {
|
|
27
|
+
async act(page, _input, mem) {
|
|
28
|
+
const startedAt = Date.now();
|
|
29
|
+
const response = await options.call({ request: page.request, mem });
|
|
30
|
+
const ms = Date.now() - startedAt;
|
|
31
|
+
let body;
|
|
32
|
+
try {
|
|
33
|
+
body = await response.json();
|
|
34
|
+
}
|
|
35
|
+
catch {
|
|
36
|
+
body = await response.text().catch(() => undefined);
|
|
37
|
+
}
|
|
38
|
+
mem.set(API_RESULT_SCRATCH, { status: response.status(), ok: response.ok(), body });
|
|
39
|
+
// Best-effort, demo-only visibility - an API step has no DOM change and no ring of its own,
|
|
40
|
+
// so without this it's a silent title flash. No-ops outside a demo/pilot/auto run (see
|
|
41
|
+
// addNetworkEntry's own guard) and never fails the Block if painting the panel throws.
|
|
42
|
+
// Same network-tab panel real page traffic feeds too (network-capture.js) - this is the
|
|
43
|
+
// page.request side of it (a separate APIRequestContext, never seen by page.on('request')).
|
|
44
|
+
try {
|
|
45
|
+
// recordNetworkEntry, not a bare addNetworkEntry evaluate - it also persists this entry
|
|
46
|
+
// to page.__wgNetworkHistory (Node-side, survives navigation), so it isn't lost the
|
|
47
|
+
// moment a later step in the same Flow navigates and wipes the panel's DOM.
|
|
48
|
+
const { recordNetworkEntry } = await import("../../runner/network-capture.js");
|
|
49
|
+
await recordNetworkEntry(page, {
|
|
50
|
+
method: options.method || "GET",
|
|
51
|
+
url: response.url(),
|
|
52
|
+
status: response.status(),
|
|
53
|
+
ok: response.ok(),
|
|
54
|
+
ms,
|
|
55
|
+
resHeaders: response.headers(),
|
|
56
|
+
resBody: typeof body === "string" ? body : body !== undefined ? JSON.stringify(body) : undefined,
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
catch {
|
|
60
|
+
/* overlay not installed / page already closed - not this Block's job to report that */
|
|
61
|
+
}
|
|
62
|
+
},
|
|
63
|
+
async observe(_page, mem) {
|
|
64
|
+
return mem.get(API_RESULT_SCRATCH);
|
|
65
|
+
},
|
|
66
|
+
resolve: (observed) => options.resolve(observed),
|
|
67
|
+
...(options.verify !== undefined ? { verify: options.verify } : {}),
|
|
68
|
+
...(options.stubBefore !== undefined ? { stubBefore: options.stubBefore } : {}),
|
|
69
|
+
...(options.stubAfter !== undefined ? { stubAfter: options.stubAfter } : {}),
|
|
70
|
+
...(options.stubOnError !== undefined ? { stubOnError: options.stubOnError } : {}),
|
|
71
|
+
},
|
|
72
|
+
});
|
|
73
|
+
Object.defineProperty(built, "__waygraphKind", { value: "api", enumerable: false, configurable: false });
|
|
74
|
+
return built;
|
|
75
|
+
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { Block, Checkpoint, DefinedBlock } from "../../types.js";
|
|
2
2
|
import type { MemKey } from "../../mem-page.js";
|
|
3
3
|
import type { Trait } from "../../trait.js";
|
|
4
|
-
import { defineBlock } from "../
|
|
4
|
+
import { defineBlock } from "../block.js";
|
|
5
5
|
/**
|
|
6
6
|
* TypeScript salt over {@link defineBlock}: same runtime Block, but the type
|
|
7
7
|
* forces `requires` + `instanceOptions` so `waygraph auto` can list one menu
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { Checkpoint, DefinedBlock } from "../../types.js";
|
|
2
2
|
import type { Trait } from "../../trait.js";
|
|
3
|
-
import { defineBlock } from "../
|
|
3
|
+
import { defineBlock } from "../block.js";
|
|
4
4
|
import type { MemKey } from "../../mem-page.js";
|
|
5
5
|
/**
|
|
6
6
|
* TypeScript salt over {@link defineBlock} for one-shot non-nav app steps
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// Split out of the former 2,900-line engine.ts (see src/ARCHITECTURE.md). Behavior unchanged.
|
|
2
2
|
import { checkpoint } from "../../types.js";
|
|
3
|
-
import { defineBlock } from "../
|
|
3
|
+
import { defineBlock } from "../block.js";
|
|
4
4
|
export function defineMethodBlock(base) {
|
|
5
5
|
const built = defineBlock(base);
|
|
6
6
|
Object.defineProperty(built, "__waygraphSalt", {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// Split out of the former 2,900-line engine.ts (see src/ARCHITECTURE.md). Behavior unchanged.
|
|
2
2
|
import { checkpoint } from "../../types.js";
|
|
3
|
-
import { defineBlock } from "../
|
|
3
|
+
import { defineBlock } from "../block.js";
|
|
4
4
|
/**
|
|
5
5
|
* Builds a {@link NavBlock}. The generated `act()` is always exactly
|
|
6
6
|
* `page.goto(url)` or `page.locator(click).click()` - never anything else,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// Split out of the former 2,900-line engine.ts (see src/ARCHITECTURE.md). Behavior unchanged.
|
|
2
2
|
import { checkpoint } from "../../types.js";
|
|
3
|
-
import { defineBlock } from "../
|
|
3
|
+
import { defineBlock } from "../block.js";
|
|
4
4
|
function resolvePageMethods(methods) {
|
|
5
5
|
if (!methods)
|
|
6
6
|
return [];
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { WaygraphError } from "../errors.js";
|
|
1
|
+
import { WaygraphError, MSG_BRANCH_REGRESSION_NO_BROWSER } from "../errors.js";
|
|
2
2
|
import { MemPage } from "../mem-page.js";
|
|
3
3
|
import { seedMemStub } from "../mem-stub.js";
|
|
4
4
|
function branchInfo(flow) {
|
|
@@ -48,8 +48,7 @@ export async function runBranchRegression(flow, context, mem = new MemPage(), op
|
|
|
48
48
|
const results = [];
|
|
49
49
|
const browser = cloneSession ? context.browser() : null;
|
|
50
50
|
if (cloneSession && !browser) {
|
|
51
|
-
throw new WaygraphError("WG_BRANCH_REGRESSION_NO_BROWSER",
|
|
52
|
-
"has none) - pass { cloneSession: false } to run the single live path in this context instead.");
|
|
51
|
+
throw new WaygraphError("WG_BRANCH_REGRESSION_NO_BROWSER", MSG_BRANCH_REGRESSION_NO_BROWSER);
|
|
53
52
|
}
|
|
54
53
|
/** `entryPage`, when given, is already positioned (cloned session + navigated) - reused as-is,
|
|
55
54
|
* never replaced by a fresh `ctx.newPage()` (that would throw away the whole point of cloning). */
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { connect } from "../types.js";
|
|
2
|
-
import { WaygraphError } from "../errors.js";
|
|
3
|
-
import { findBlockIndex, modVerify, withVerify } from "./
|
|
2
|
+
import { WaygraphError, MSG_COMPOSE_EMPTY, MSG_FASTFORWARD_EMPTY } from "../errors.js";
|
|
3
|
+
import { findBlockIndex, modVerify, withVerify } from "./block.js";
|
|
4
4
|
export function composeBlock(name, steps) {
|
|
5
5
|
if (steps.length === 0) {
|
|
6
|
-
throw new WaygraphError("WG_COMPOSE_EMPTY",
|
|
6
|
+
throw new WaygraphError("WG_COMPOSE_EMPTY", MSG_COMPOSE_EMPTY(name));
|
|
7
7
|
}
|
|
8
8
|
const chain = steps.reduce((a, b) => connect(a, b));
|
|
9
9
|
return {
|
|
@@ -42,7 +42,7 @@ function wrapFfError(ffName, err) {
|
|
|
42
42
|
}
|
|
43
43
|
export function fastForwardComposeBlock(name, steps) {
|
|
44
44
|
if (steps.length === 0) {
|
|
45
|
-
throw new WaygraphError("WG_FASTFORWARD_EMPTY",
|
|
45
|
+
throw new WaygraphError("WG_FASTFORWARD_EMPTY", MSG_FASTFORWARD_EMPTY(name));
|
|
46
46
|
}
|
|
47
47
|
const base = composeBlock(name, steps);
|
|
48
48
|
const origAct = base.instruction.act.bind(base.instruction);
|
|
@@ -2,10 +2,8 @@ import type { Block, Checkpoint } from "../types.js";
|
|
|
2
2
|
import type { EngineConfig } from "./config.js";
|
|
3
3
|
import type { EndMarker, StartMarker } from "./run-graph.js";
|
|
4
4
|
import type { Flow } from "./flow.js";
|
|
5
|
-
import
|
|
6
|
-
import type {
|
|
7
|
-
import type { AssertBlock, MethodBlock } from "./blocks/method.js";
|
|
8
|
-
import type { EffectBlock } from "./blocks/effect.js";
|
|
5
|
+
import { MapBuilder } from "./map-builder.js";
|
|
6
|
+
import type { MapBuilderOptions } from "./map-builder.js";
|
|
9
7
|
type S = Checkpoint<"__start__">;
|
|
10
8
|
/**
|
|
11
9
|
* Holds engine-level configuration shared across every flow defined from it -
|
|
@@ -187,135 +185,6 @@ export declare class Engine {
|
|
|
187
185
|
*/
|
|
188
186
|
map(options?: MapBuilderOptions): MapBuilder<S>;
|
|
189
187
|
}
|
|
190
|
-
export interface MapBuilderOptions {
|
|
191
|
-
/**
|
|
192
|
-
* This project's own origin (e.g. `"https://app.example.com"`) - enables
|
|
193
|
-
* `.gotoPage()`/`.gotoExternal()`'s origin check against a Block's static
|
|
194
|
-
* `url`. Omit to skip that check entirely (still fully kind-checked either
|
|
195
|
-
* way; only the internal/external origin distinction is opt-in).
|
|
196
|
-
*/
|
|
197
|
-
homeOrigin?: string;
|
|
198
|
-
}
|
|
199
|
-
/**
|
|
200
|
-
* Fluent builder over {@link Engine.defineFlow} - see `map()`'s own doc
|
|
201
|
-
* comment for why this exists. Each step method is scoped to exactly the
|
|
202
|
-
* Block kind its name promises, checked at RUNTIME against the
|
|
203
|
-
* `__waygraphKind`/`__waygraphSalt` markers `defineNavBlock`/`definePageBlock`/
|
|
204
|
-
* `defineAssertBlock`/`defineMethodBlock`/`defineEffectBlock` already set
|
|
205
|
-
* (the same markers `graph.ts` and `map-check.ts` trust) - not just a type
|
|
206
|
-
* hint, since a hand-rolled object can satisfy the TypeScript `Block<In,Out>`
|
|
207
|
-
* shape without ever going through a real factory. Each call also
|
|
208
|
-
* typechecks the accumulated Checkpoint chain exactly like `defineFlow`'s
|
|
209
|
-
* own tuple overloads do (a step's `In` must equal the previous step's
|
|
210
|
-
* `Out`) - this is what "no teleporting" means: there is no method on this
|
|
211
|
-
* builder that can skip from one Checkpoint to an unrelated one without a
|
|
212
|
-
* real, kind-correct Block in between.
|
|
213
|
-
*/
|
|
214
|
-
export declare class MapBuilder<Out extends Checkpoint<string>> {
|
|
215
|
-
private readonly engine;
|
|
216
|
-
private readonly steps;
|
|
217
|
-
private readonly homeOrigin;
|
|
218
|
-
private readonly ff;
|
|
219
|
-
private constructor();
|
|
220
|
-
/** @internal - use `engine.map()` or the standalone `map()` export. */
|
|
221
|
-
static begin(engine: Engine, homeOrigin: string | undefined): MapBuilder<S>;
|
|
222
|
-
/** Readable chain-opener - mirrors `defineFlow`'s leading `start` sentinel. Returns `this` unchanged; entirely optional. */
|
|
223
|
-
start(): MapBuilder<Out>;
|
|
224
|
-
/**
|
|
225
|
-
* Open a fast-forward window - steps until {@link ffEnd} collapse into one
|
|
226
|
-
* opaque `fastForwardComposeBlock` (blitz theater). Kind/salt checks still
|
|
227
|
-
* run on each inner step as it is added.
|
|
228
|
-
*/
|
|
229
|
-
ffStart(name?: string): MapBuilder<Out>;
|
|
230
|
-
/**
|
|
231
|
-
* Close the current fast-forward window and append one FFCompose step.
|
|
232
|
-
* Throws if empty or if {@link ffStart} was never opened.
|
|
233
|
-
*/
|
|
234
|
-
ffEnd(): MapBuilder<Out>;
|
|
235
|
-
private appendStep;
|
|
236
|
-
/**
|
|
237
|
-
* Appends an internal navigation/page-arrival step - requires a Block from
|
|
238
|
-
* `defineNavBlock`/`defineMemNavBlock`/`definePageBlock`. Throws if given
|
|
239
|
-
* anything else, including a `homeOrigin`-mismatched static `url`.
|
|
240
|
-
* Compile-time: {@link NavBlock} or {@link PageBlock} only (not Assert/Method).
|
|
241
|
-
*/
|
|
242
|
-
gotoPage<NextOut extends Checkpoint<string>>(block: (NavBlock<NextOut> | PageBlock<NextOut>) & {
|
|
243
|
-
name: string;
|
|
244
|
-
}): MapBuilder<NextOut>;
|
|
245
|
-
/**
|
|
246
|
-
* Appends a genuinely cross-origin navigation step (e.g. `(external)/`
|
|
247
|
-
* Blocks in the Waygraph Map convention: mailpit, maildrop.cc) - same
|
|
248
|
-
* kind requirement as {@link gotoPage}, plus the inverse `homeOrigin` check.
|
|
249
|
-
* Compile-time: {@link NavBlock} or {@link PageBlock} only.
|
|
250
|
-
*/
|
|
251
|
-
gotoExternal<NextOut extends Checkpoint<string>>(block: (NavBlock<NextOut> | PageBlock<NextOut>) & {
|
|
252
|
-
name: string;
|
|
253
|
-
}): MapBuilder<NextOut>;
|
|
254
|
-
/**
|
|
255
|
-
* Appends a self-loop verification step - requires a Block from
|
|
256
|
-
* `defineAssertBlock`. Compile-time: {@link AssertBlock} only (not `.method()`).
|
|
257
|
-
*/
|
|
258
|
-
assert(block: AssertBlock<Out> & {
|
|
259
|
-
name: string;
|
|
260
|
-
}): MapBuilder<Out>;
|
|
261
|
-
/**
|
|
262
|
-
* Appends a non-navigating page action (submit, upload, add/remove an
|
|
263
|
-
* instance) - requires a Block from `defineMethodBlock`/`defineActionBlock`/
|
|
264
|
-
* `defineEffectBlock`/`defineMemEffectBlock`.
|
|
265
|
-
* Compile-time: {@link MethodBlock} or {@link EffectBlock} only - Assert
|
|
266
|
-
* Blocks must use `.assert()`. Runtime also rejects `__waygraphKind =
|
|
267
|
-
* "assert"` (those still carry method salt from the factory internals).
|
|
268
|
-
*/
|
|
269
|
-
method<NextOut extends Checkpoint<string>>(block: (MethodBlock<Out, NextOut> | EffectBlock<Out, NextOut>) & {
|
|
270
|
-
name: string;
|
|
271
|
-
}): MapBuilder<NextOut>;
|
|
272
|
-
/**
|
|
273
|
-
* Branch: run everything added so far, then continue into whichever `routes[tag]` matches the
|
|
274
|
-
* resolved Checkpoint's tag - same page, same context, same mem. `routes` must cover every tag
|
|
275
|
-
* of `Out` (a missing one is a compile error, matching {@link branch}'s own exhaustiveness);
|
|
276
|
-
* `null` means that tag is terminal (the branched Flow just returns that Checkpoint).
|
|
277
|
-
*
|
|
278
|
-
* Each non-null route is a function, not a ready-made `Flow` - a fresh Flow always starts at the
|
|
279
|
-
* special `S` (start) Checkpoint, but a branch's blocks start from the TAG it routes on (e.g.
|
|
280
|
-
* `LoggedIn`), so the function is handed a brand-new `MapBuilder` already seeded at that exact
|
|
281
|
-
* Checkpoint to chain `.method()/.gotoPage()/.assert()/.end()` (or another `.branch()`) off of.
|
|
282
|
-
*
|
|
283
|
-
* Real gap this fixes: the plain `branch()` helper's `.next` routing is only ever consulted by
|
|
284
|
-
* `runGraph`'s own graph walk - `defineFlow`/`.end()` compose steps pairwise via `connect()`,
|
|
285
|
-
* which never looks at `.next` at all, so a Map-built Flow had no way to branch. This method
|
|
286
|
-
* branches at the Flow level instead: it finalizes the prefix, runs it, and picks the next Flow
|
|
287
|
-
* itself once the real tag is known - no engine-level routing involved.
|
|
288
|
-
*
|
|
289
|
-
* Only the `run(context, mem[, options])` signature is supported - the page must survive across
|
|
290
|
-
* the branch, and the bare `run(mem, config)` convenience form always closes its own browser
|
|
291
|
-
* before a tag is even known, so it throws instead of silently reopening a fresh (state-losing) page.
|
|
292
|
-
*
|
|
293
|
-
* The route's first Block still sees `input.__state === "__start__"` in `act()`, not the tag that
|
|
294
|
-
* routed there - `runGraph` seeds every Flow's entry Block that way unconditionally, the same as
|
|
295
|
-
* any standalone `defineFlow([start, block, end])` already does. Read `page`/`mem`, not `input`,
|
|
296
|
-
* in `act()` - every real Block in this codebase already follows that convention.
|
|
297
|
-
*
|
|
298
|
-
* @example
|
|
299
|
-
* map({ homeOrigin }).gotoPage(NavCartBlock).branch({
|
|
300
|
-
* ItemInCart: (m) => m.method(RemoveFromCartBlock).end(),
|
|
301
|
-
* LoggedIn: (m) => m.method(AddToCartBlock).end(),
|
|
302
|
-
* });
|
|
303
|
-
*/
|
|
304
|
-
branch<Routes extends {
|
|
305
|
-
[K in Out["__state"]]: ((m: MapBuilder<Extract<Out, Checkpoint<K>>>) => Flow<any>) | null;
|
|
306
|
-
}>(routes: Routes): Flow<{
|
|
307
|
-
[K in keyof Routes & string]: Routes[K] extends (m: any) => Flow<infer R> ? R : Extract<Out, Checkpoint<K>>;
|
|
308
|
-
}[keyof Routes & string]>;
|
|
309
|
-
/**
|
|
310
|
-
* Finalizes this chain into a real, runnable {@link Flow} - same object
|
|
311
|
-
* `defineFlow` returns, so `withBlockVerify`/`modBlockVerify` and every
|
|
312
|
-
* `withTitle`/`withHighlightFixtures`/etc. decorator still apply exactly
|
|
313
|
-
* as they do today; this builder only changes how the chain is assembled,
|
|
314
|
-
* never what it produces. Throws if no step was ever added - an empty map
|
|
315
|
-
* isn't a flow.
|
|
316
|
-
*/
|
|
317
|
-
end(): Flow<Out>;
|
|
318
|
-
}
|
|
319
188
|
/**
|
|
320
189
|
* Standalone convenience for `new Engine(config).map(options)` - use this
|
|
321
190
|
* when a call site doesn't otherwise need its own `Engine` instance (no
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { buildFlow } from "./flow.js";
|
|
2
|
+
import { MapBuilder } from "./map-builder.js";
|
|
3
|
+
/**
|
|
4
|
+
* Holds engine-level configuration shared across every flow defined from it -
|
|
5
|
+
* for now, just how to launch a browser when a Flow owns its own
|
|
6
|
+
* (`headless`/`browserName`/`slowMo`); traits/interstitials/watchers land here
|
|
7
|
+
* in a later change.
|
|
8
|
+
* @example const engine = new Engine({ headless: false, slowMo: 250 });
|
|
9
|
+
*/
|
|
10
|
+
export class Engine {
|
|
11
|
+
config;
|
|
12
|
+
constructor(config = {}) {
|
|
13
|
+
this.config = config;
|
|
14
|
+
}
|
|
15
|
+
defineFlow(blocks) {
|
|
16
|
+
return buildFlow(blocks.slice(1, -1), this.config);
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Fluent, kind-checked alternative to `defineFlow([start, ...blocks, end])` -
|
|
20
|
+
* see {@link MapBuilder}. Real, direct request this responds to: pia/zsign's
|
|
21
|
+
* own agents kept hand-editing/hand-composing Blocks into ad hoc shapes
|
|
22
|
+
* ("locks" convention tried, still got broken) - `map()` forces every step
|
|
23
|
+
* through this Engine's own `define*Block` factories (checked by the same
|
|
24
|
+
* `__waygraphKind`/`__waygraphSalt` runtime markers `graph.ts`/`map-check.ts`
|
|
25
|
+
* already trust), so a hand-rolled plain-object Block can never silently
|
|
26
|
+
* pass as a real navigation/assertion/method step. `homeOrigin`, if given,
|
|
27
|
+
* also gates `.gotoPage()`/`.gotoExternal()` against each Nav/Page Block's
|
|
28
|
+
* own static `url` (skipped, honestly, for click-based/dynamic nav - not
|
|
29
|
+
* statically checkable, same limitation `map-check.ts` already documents).
|
|
30
|
+
* @example
|
|
31
|
+
* const flow = engine.map({ homeOrigin: "https://app.example.com" })
|
|
32
|
+
* .start()
|
|
33
|
+
* .gotoPage(NavHomeBlock)
|
|
34
|
+
* .assert(AssertHelloBlock)
|
|
35
|
+
* .gotoExternal(NavMailpitBlock)
|
|
36
|
+
* .end();
|
|
37
|
+
*/
|
|
38
|
+
map(options) {
|
|
39
|
+
return MapBuilder.begin(this.defineFlow.bind(this), options?.homeOrigin);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Standalone convenience for `new Engine(config).map(options)` - use this
|
|
44
|
+
* when a call site doesn't otherwise need its own `Engine` instance (no
|
|
45
|
+
* shared `headless`/`slowMo`/`layouts` across several flows).
|
|
46
|
+
* @example const flow = map({ homeOrigin: "https://app.example.com" }).gotoPage(NavHomeBlock).end();
|
|
47
|
+
*/
|
|
48
|
+
export function map(options) {
|
|
49
|
+
return new Engine(options).map(options);
|
|
50
|
+
}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
// Split out of the former 2,900-line engine.ts (see src/ARCHITECTURE.md). Behavior unchanged.
|
|
2
2
|
import { connect } from "../types.js";
|
|
3
|
-
import { WaygraphError } from "../errors.js";
|
|
3
|
+
import { WaygraphError, MSG_CHAINFLOW_BLOCK_NOT_FOUND_BY_INDEX, MSG_CHAINFLOW_BLOCK_NOT_FOUND_BY_NAME, MSG_CHAINFLOW_EMPTY, } from "../errors.js";
|
|
4
4
|
import { preflight, runGraph } from "./run-graph.js";
|
|
5
5
|
import { resolveLauncher } from "./config.js";
|
|
6
6
|
import { MemPage } from "../mem-page.js";
|
|
7
|
-
import { findBlockIndex, modVerify, withVerify } from "./
|
|
7
|
+
import { findBlockIndex, modVerify, withVerify } from "./block.js";
|
|
8
8
|
import { normalizeHighlightSize, normalizeHighlightTone, normalizeHighlightWeight } from "../highlights.js";
|
|
9
9
|
export function buildFlow(middle, engineConfig) {
|
|
10
10
|
// resetSession/title start false/unset here - defineFlow itself carries
|
|
@@ -268,7 +268,7 @@ function locateInChain(flows, block) {
|
|
|
268
268
|
return { flowIndex: fi, localIndex: remaining };
|
|
269
269
|
remaining -= len;
|
|
270
270
|
}
|
|
271
|
-
throw new WaygraphError("WG_FLOW_BLOCK_NOT_FOUND",
|
|
271
|
+
throw new WaygraphError("WG_FLOW_BLOCK_NOT_FOUND", MSG_CHAINFLOW_BLOCK_NOT_FOUND_BY_INDEX(block, flows.length));
|
|
272
272
|
}
|
|
273
273
|
const blockName = typeof block === "string" ? block : block.name;
|
|
274
274
|
for (let fi = 0; fi < flows.length; fi++) {
|
|
@@ -276,7 +276,7 @@ function locateInChain(flows, block) {
|
|
|
276
276
|
if (localIndex !== -1)
|
|
277
277
|
return { flowIndex: fi, localIndex };
|
|
278
278
|
}
|
|
279
|
-
throw new WaygraphError("WG_FLOW_BLOCK_NOT_FOUND",
|
|
279
|
+
throw new WaygraphError("WG_FLOW_BLOCK_NOT_FOUND", MSG_CHAINFLOW_BLOCK_NOT_FOUND_BY_NAME(blockName));
|
|
280
280
|
}
|
|
281
281
|
async function clearSessionState(context, page) {
|
|
282
282
|
await context.clearCookies().catch(() => { });
|
|
@@ -312,7 +312,7 @@ async function clearSessionState(context, page) {
|
|
|
312
312
|
*/
|
|
313
313
|
export function chainFlow(...flows) {
|
|
314
314
|
if (flows.length === 0) {
|
|
315
|
-
throw new WaygraphError("WG_CHAINFLOW_EMPTY",
|
|
315
|
+
throw new WaygraphError("WG_CHAINFLOW_EMPTY", MSG_CHAINFLOW_EMPTY);
|
|
316
316
|
}
|
|
317
317
|
const run = async function run(contextOrMem, memOrConfig, options) {
|
|
318
318
|
if (contextOrMem instanceof MemPage) {
|