waygraph 0.10.6 → 0.10.7
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/cli.js +79 -12
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -1286,10 +1286,12 @@ function extractVerifyHighlights(block, resultTag) {
|
|
|
1286
1286
|
* __wgNext no-ops once already consumed - but looked live when it wasn't).
|
|
1287
1287
|
* Disables the button and mem-key textareas, and swaps whichever gate
|
|
1288
1288
|
* text was showing (manual button or "Auto-advancing...") to "Running...".
|
|
1289
|
+
* When autoCollapsePanel is set (QA video / autoplay), tuck the stepper
|
|
1290
|
+
* away so ring captions + the app fill the frame - Dan: stepper + auto panels.
|
|
1289
1291
|
*/
|
|
1290
|
-
async function markStepRunning(page) {
|
|
1292
|
+
async function markStepRunning(page, opts?: { autoCollapsePanel?: boolean }) {
|
|
1291
1293
|
await page
|
|
1292
|
-
.evaluate(() => {
|
|
1294
|
+
.evaluate(({ autoCollapsePanel }) => {
|
|
1293
1295
|
const runBtn = document.getElementById("wg-run");
|
|
1294
1296
|
if (runBtn) {
|
|
1295
1297
|
runBtn.disabled = true;
|
|
@@ -1300,7 +1302,15 @@ async function markStepRunning(page) {
|
|
|
1300
1302
|
document.querySelectorAll("#wg-panel textarea[data-key]").forEach((ta) => {
|
|
1301
1303
|
ta.disabled = true;
|
|
1302
1304
|
});
|
|
1303
|
-
|
|
1305
|
+
if (autoCollapsePanel) {
|
|
1306
|
+
const panel = document.getElementById("wg-panel");
|
|
1307
|
+
if (panel) {
|
|
1308
|
+
panel.classList.add("wg-collapsed");
|
|
1309
|
+
const toggle = panel.querySelector("[data-wg-toggle]");
|
|
1310
|
+
if (toggle) toggle.textContent = "Show";
|
|
1311
|
+
}
|
|
1312
|
+
}
|
|
1313
|
+
}, { autoCollapsePanel: !!opts?.autoCollapsePanel })
|
|
1304
1314
|
.catch(() => {});
|
|
1305
1315
|
}
|
|
1306
1316
|
|
|
@@ -1815,7 +1825,9 @@ async function runStepMode(engine, start, end, context, page, mem, resolved, slo
|
|
|
1815
1825
|
}
|
|
1816
1826
|
}
|
|
1817
1827
|
}
|
|
1818
|
-
|
|
1828
|
+
const recordingVideo = !!process.env.WAYGRAPH_VIDEO;
|
|
1829
|
+
const autoCollapsePanel = recordingVideo || (await currentAutoplay());
|
|
1830
|
+
await markStepRunning(page, { autoCollapsePanel });
|
|
1819
1831
|
// NavBlock click-nav: label the upcoming Locator.click demo cursor as
|
|
1820
1832
|
// "nav: <block>" so pia/demo watchers see cursor+pulse on click nav
|
|
1821
1833
|
// (not only on regular Block clicks).
|
|
@@ -1997,6 +2009,18 @@ async function runChainedFlows(chainFlow, chainFlows, context, mem, page) {
|
|
|
1997
2009
|
}
|
|
1998
2010
|
}
|
|
1999
2011
|
|
|
2012
|
+
/** Parses WAYGRAPH_VIDEO_VIEWPORT / --video-viewport: "1920x1080" or "1920,1080". */
|
|
2013
|
+
function parseVideoViewport(raw: string | undefined): { width: number; height: number } | null {
|
|
2014
|
+
if (!raw?.trim()) return null;
|
|
2015
|
+
const m = raw.trim().match(/^(\d{3,5})[xX,](\d{3,5})$/);
|
|
2016
|
+
if (!m) return null;
|
|
2017
|
+
const width = Number(m[1]);
|
|
2018
|
+
const height = Number(m[2]);
|
|
2019
|
+
if (!Number.isFinite(width) || !Number.isFinite(height)) return null;
|
|
2020
|
+
if (width < 320 || height < 240 || width > 7680 || height > 4320) return null;
|
|
2021
|
+
return { width, height };
|
|
2022
|
+
}
|
|
2023
|
+
|
|
2000
2024
|
async function main() {
|
|
2001
2025
|
const projectDir = process.argv[2];
|
|
2002
2026
|
const spec = process.argv[3];
|
|
@@ -2170,6 +2194,13 @@ async function main() {
|
|
|
2170
2194
|
videoDir = videoEnv === "1" ? join(projectDir, ".waygraph-videos") : videoEnv;
|
|
2171
2195
|
mkdirSync(videoDir, { recursive: true });
|
|
2172
2196
|
}
|
|
2197
|
+
/** Fixed 16:9 capture for --video (demo QA and headless run). Step+video no longer maximizes. */
|
|
2198
|
+
const DEFAULT_VIDEO_VIEWPORT = { width: 1920, height: 1080 };
|
|
2199
|
+
const DEFAULT_RUN_VIDEO_VIEWPORT = { width: 1280, height: 720 };
|
|
2200
|
+
const videoViewportParsed = parseVideoViewport(process.env.WAYGRAPH_VIDEO_VIEWPORT);
|
|
2201
|
+
const fixedVideoViewport = videoDir
|
|
2202
|
+
? (videoViewportParsed ?? (step ? DEFAULT_VIDEO_VIEWPORT : DEFAULT_RUN_VIDEO_VIEWPORT))
|
|
2203
|
+
: null;
|
|
2173
2204
|
const engine = new Engine({ headless: !headed, slowMo });
|
|
2174
2205
|
let result;
|
|
2175
2206
|
// Non-interactive execution (no --step) runs the whole chain as one
|
|
@@ -2200,14 +2231,20 @@ async function main() {
|
|
|
2200
2231
|
const browser = await chromium.launch({
|
|
2201
2232
|
headless: !headed,
|
|
2202
2233
|
slowMo,
|
|
2203
|
-
|
|
2234
|
+
// Maximized only for interactive step mode WITHOUT a fixed video viewport -
|
|
2235
|
+
// recording uses a locked 16:9 viewport so .webm has no gray letterboxing.
|
|
2236
|
+
args: step && !fixedVideoViewport ? ["--start-maximized"] : [],
|
|
2204
2237
|
...(executablePath ? { executablePath } : {}),
|
|
2205
2238
|
});
|
|
2206
|
-
const contextOpts =
|
|
2207
|
-
? { baseURL, viewport:
|
|
2208
|
-
:
|
|
2239
|
+
const contextOpts = fixedVideoViewport
|
|
2240
|
+
? { baseURL, viewport: fixedVideoViewport }
|
|
2241
|
+
: step
|
|
2242
|
+
? { baseURL, viewport: null }
|
|
2243
|
+
: { baseURL, viewport: { width: 1280, height: 720 } };
|
|
2209
2244
|
if (videoDir) {
|
|
2210
|
-
contextOpts.recordVideo =
|
|
2245
|
+
contextOpts.recordVideo = fixedVideoViewport
|
|
2246
|
+
? { dir: videoDir, size: fixedVideoViewport }
|
|
2247
|
+
: { dir: videoDir };
|
|
2211
2248
|
}
|
|
2212
2249
|
const context = await browser.newContext(contextOpts);
|
|
2213
2250
|
let pageForVideo = null;
|
|
@@ -2693,6 +2730,7 @@ function initCommand(projectName) {
|
|
|
2693
2730
|
process.exit(1);
|
|
2694
2731
|
}
|
|
2695
2732
|
const targetDir = resolve(process.cwd(), projectName);
|
|
2733
|
+
const pkgName = basename(targetDir);
|
|
2696
2734
|
if (existsSync(targetDir)) {
|
|
2697
2735
|
const entries = readdirSync(targetDir);
|
|
2698
2736
|
if (entries.length > 0) {
|
|
@@ -2715,10 +2753,10 @@ function initCommand(projectName) {
|
|
|
2715
2753
|
rmSync(gitignoreSrc);
|
|
2716
2754
|
}
|
|
2717
2755
|
const packageJsonPath = join(targetDir, "package.json");
|
|
2718
|
-
writeFileSync(packageJsonPath, readFileSync(packageJsonPath, "utf-8").replaceAll("__PROJECT_NAME__",
|
|
2719
|
-
console.log(`Scaffolded ${
|
|
2756
|
+
writeFileSync(packageJsonPath, readFileSync(packageJsonPath, "utf-8").replaceAll("__PROJECT_NAME__", pkgName));
|
|
2757
|
+
console.log(`Scaffolded ${pkgName}/`);
|
|
2720
2758
|
console.log("");
|
|
2721
|
-
console.log(` cd ${
|
|
2759
|
+
console.log(` cd ${relative(process.cwd(), targetDir) || pkgName}`);
|
|
2722
2760
|
console.log(" npm install");
|
|
2723
2761
|
console.log(" npx playwright install chromium");
|
|
2724
2762
|
console.log(" npm test");
|
|
@@ -2847,6 +2885,11 @@ function parseRunFlags(argv) {
|
|
|
2847
2885
|
}
|
|
2848
2886
|
}
|
|
2849
2887
|
}
|
|
2888
|
+
else if (a === "--video-viewport" || a.startsWith("--video-viewport=")) {
|
|
2889
|
+
const t = takeFlagValue(argv, i, a, "--video-viewport");
|
|
2890
|
+
out.videoViewport = t.value;
|
|
2891
|
+
i = t.nextI;
|
|
2892
|
+
}
|
|
2850
2893
|
else if (a === "--blocks" || a.startsWith("--blocks=")) {
|
|
2851
2894
|
if (a.startsWith("--blocks=")) {
|
|
2852
2895
|
out.blocks = a.slice("--blocks=".length);
|
|
@@ -2873,6 +2916,21 @@ function parseRunFlags(argv) {
|
|
|
2873
2916
|
}
|
|
2874
2917
|
return out;
|
|
2875
2918
|
}
|
|
2919
|
+
/** Parses WAYGRAPH_VIDEO_VIEWPORT / --video-viewport: "1920x1080" or "1920,1080". */
|
|
2920
|
+
function parseVideoViewportFlag(raw) {
|
|
2921
|
+
if (!raw?.trim())
|
|
2922
|
+
return null;
|
|
2923
|
+
const m = raw.trim().match(/^(\d{3,5})[xX,](\d{3,5})$/);
|
|
2924
|
+
if (!m)
|
|
2925
|
+
return null;
|
|
2926
|
+
const width = Number(m[1]);
|
|
2927
|
+
const height = Number(m[2]);
|
|
2928
|
+
if (!Number.isFinite(width) || !Number.isFinite(height))
|
|
2929
|
+
return null;
|
|
2930
|
+
if (width < 320 || height < 240 || width > 7680 || height > 4320)
|
|
2931
|
+
return null;
|
|
2932
|
+
return { width, height };
|
|
2933
|
+
}
|
|
2876
2934
|
/** Writes flag values into process.env so the chain child inherits them. Flags beat prior env. */
|
|
2877
2935
|
function applyRunFlags(flags, opts) {
|
|
2878
2936
|
if (flags.autoPlayVideo) {
|
|
@@ -2912,6 +2970,13 @@ function applyRunFlags(flags, opts) {
|
|
|
2912
2970
|
if (flags.video !== undefined) {
|
|
2913
2971
|
process.env.WAYGRAPH_VIDEO = flags.video || "1";
|
|
2914
2972
|
}
|
|
2973
|
+
if (flags.videoViewport !== undefined) {
|
|
2974
|
+
if (!parseVideoViewportFlag(flags.videoViewport)) {
|
|
2975
|
+
console.error('waygraph: --video-viewport must look like "1920x1080"');
|
|
2976
|
+
process.exit(1);
|
|
2977
|
+
}
|
|
2978
|
+
process.env.WAYGRAPH_VIDEO_VIEWPORT = flags.videoViewport;
|
|
2979
|
+
}
|
|
2915
2980
|
if (flags.data !== undefined) {
|
|
2916
2981
|
process.env.WAYGRAPH_DATA = flags.data;
|
|
2917
2982
|
}
|
|
@@ -3071,11 +3136,13 @@ Primary (less is more):
|
|
|
3071
3136
|
--data '{...}' Mem seed JSON (or inline flow({...}))
|
|
3072
3137
|
--auto-next Auto-advance steps (alias: --autoplay)
|
|
3073
3138
|
--auto-play-video QA: --auto-next + --video (+ step)
|
|
3139
|
+
--video-viewport WxH Recording size (default demo: 1920x1080)
|
|
3074
3140
|
--title / --base-url
|
|
3075
3141
|
waygraph run [--blocks <flow|file|spec>] Execute (no overlay unless --step)
|
|
3076
3142
|
--data '{...}'
|
|
3077
3143
|
--non-headless Show browser
|
|
3078
3144
|
--video [dir] Record .webm
|
|
3145
|
+
--video-viewport WxH Recording size (default run: 1280x720)
|
|
3079
3146
|
|
|
3080
3147
|
Also:
|
|
3081
3148
|
waygraph list | nav | validate | check | graph | init <name>
|