waygraph 0.16.0 → 0.16.2
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/commands/browser.d.ts +2 -0
- package/dist/cli/commands/browser.js +109 -0
- package/dist/cli/commands/codemod-stubs.js +90 -2
- package/dist/cli/commands/pilot.d.ts +2 -0
- package/dist/cli/commands/pilot.js +102 -0
- package/dist/cli/commands/session-ops.d.ts +3 -0
- package/dist/cli/commands/session-ops.js +257 -0
- package/dist/cli/commands/session.js +20 -461
- package/dist/cli/run-chain.js +2 -2
- package/dist/cli/usage.d.ts +1 -1
- package/dist/cli/util.js +1 -1
- package/dist/demo/narration/demo-pace.d.ts +2 -2
- package/dist/demo/narration/demo-pace.js +1 -1
- package/dist/demo/narration/device.d.ts +2 -2
- package/dist/demo/narration/merge.d.ts +5 -3
- package/dist/demo/narration/merge.js +3 -7
- package/dist/demo/narration/narration.d.ts +9 -13
- package/dist/demo/narration/narration.js +5 -17
- package/dist/demo/narration/stub-ctx.js +3 -3
- package/dist/demo/narration/todo-dock.d.ts +5 -5
- package/dist/demo/overlay/cursor.d.ts +9 -2
- package/dist/demo/overlay/cursor.js +1 -1
- package/dist/demo/overlay/device-stage.d.ts +15 -2
- package/dist/demo/overlay/inpage/banner.d.ts +2 -1
- package/dist/demo/overlay/inpage/banner.js +3 -3
- package/dist/demo/overlay/inpage/caption.d.ts +1 -1
- package/dist/demo/overlay/inpage/core.d.ts +2 -1
- package/dist/demo/overlay/inpage/core.js +1 -7
- package/dist/demo/overlay/inpage/device-chip.d.ts +1 -1
- package/dist/demo/overlay/inpage/device-chip.js +6 -6
- package/dist/demo/overlay/inpage/network.d.ts +3 -2
- package/dist/demo/overlay/inpage/network.js +1 -12
- package/dist/demo/overlay/inpage/panel-chrome.d.ts +1 -1
- package/dist/demo/overlay/inpage/panel-chrome.js +1 -1
- package/dist/demo/overlay/inpage/stamp.d.ts +1 -1
- package/dist/demo/overlay/inpage/stamp.js +1 -1
- package/dist/demo/overlay/inpage/swipe-zoom.d.ts +1 -1
- package/dist/demo/overlay/inpage/swipe-zoom.js +1 -1
- package/dist/demo/overlay/inpage/todos.d.ts +2 -1
- package/dist/demo/overlay/inpage/todos.js +1 -2
- package/dist/demo/overlay/network-capture.d.ts +2 -2
- package/dist/demo/overlay/network-capture.js +1 -1
- package/dist/demo/overlay/overlay-css.js +1 -55
- package/dist/demo/overlay/overlay-stage.d.ts +19 -11
- package/dist/demo/overlay/overlay.d.ts +2 -2
- package/dist/demo/overlay/overlay.js +3 -2
- package/dist/demo/overlay/rings.d.ts +38 -18
- package/dist/demo/overlay/rings.js +21 -62
- package/dist/demo/overlay/ui/overlay.css +40 -0
- package/dist/demo/stepper/after.js +11 -34
- package/dist/demo/stepper/banner-log.d.ts +4 -6
- package/dist/demo/stepper/banner-log.js +3 -1
- package/dist/demo/stepper/before.js +6 -4
- package/dist/demo/stepper/demo-log.d.ts +26 -9
- package/dist/demo/stepper/demo-log.js +10 -27
- package/dist/demo/stepper/interaction-patch.d.ts +3 -2
- package/dist/demo/stepper/interaction-patch.js +22 -34
- package/dist/demo/stepper/panel-after.d.ts +17 -0
- package/dist/demo/stepper/panel-after.js +166 -0
- package/dist/demo/stepper/panel-before.d.ts +12 -0
- package/dist/demo/stepper/panel-before.js +241 -0
- package/dist/demo/stepper/slides.d.ts +16 -1
- package/dist/demo/stepper/slides.js +21 -5
- package/dist/demo/stepper/step-panels.d.ts +57 -9
- package/dist/demo/stepper/step-panels.js +10 -427
- package/dist/demo/stepper/stepper.js +1 -1
- package/dist/demo/stepper/teardown.d.ts +4 -5
- package/dist/demo/stepper/teardown.js +4 -6
- package/dist/demo/stepper/todo-advance.d.ts +3 -2
- package/dist/demo/stepper/todo-advance.js +2 -2
- package/dist/demo/stepper/view.d.ts +4 -14
- package/dist/demo/types.d.ts +69 -1
- package/dist/demo/verbose-log.js +1 -1
- package/dist/engine/block/action-page.d.ts +53 -0
- package/dist/engine/block/action-page.js +1 -0
- package/dist/engine/block/block.d.ts +24 -90
- package/dist/engine/block/block.js +2 -77
- package/dist/engine/block/branch.d.ts +17 -0
- package/dist/engine/block/branch.js +40 -0
- package/dist/engine/block/dialog.d.ts +13 -0
- package/dist/engine/block/dialog.js +37 -0
- package/dist/engine/block/kinds/method.d.ts +0 -2
- package/dist/engine/block/kinds/method.js +0 -1
- package/dist/engine/block/kinds/nav.js +1 -1
- package/dist/engine/flow/map-branch.d.ts +9 -0
- package/dist/engine/flow/map-branch.js +57 -0
- package/dist/engine/flow/map-builder.d.ts +7 -22
- package/dist/engine/flow/map-builder.js +6 -145
- package/dist/engine/flow/map-steps.d.ts +30 -0
- package/dist/engine/flow/map-steps.js +87 -0
- package/dist/engine/run/run.d.ts +1 -19
- package/dist/engine/run/run.js +0 -88
- package/dist/engine/stub/ring.d.ts +2 -4
- package/dist/engine/stub/ring.js +1 -0
- package/dist/engine/stub/stub.d.ts +16 -8
- package/dist/engine/trait/trait.js +1 -1
- package/dist/index.d.ts +15 -12
- package/dist/index.js +9 -7
- package/dist/live/auto/auto.d.ts +3 -15
- package/dist/live/auto/auto.js +10 -420
- package/dist/live/auto/explore.d.ts +2 -2
- package/dist/live/auto/mem.d.ts +11 -0
- package/dist/live/auto/mem.js +85 -0
- package/dist/live/auto/menu.d.ts +30 -0
- package/dist/live/auto/menu.js +335 -0
- package/dist/live/auto-session/auto-session.d.ts +23 -103
- package/dist/live/auto-session/auto-session.js +100 -370
- package/dist/live/auto-session/console.d.ts +4 -0
- package/dist/live/auto-session/console.js +41 -0
- package/dist/live/auto-session/files.d.ts +44 -0
- package/dist/live/auto-session/files.js +145 -0
- package/dist/live/auto-session/helpers.d.ts +5 -2
- package/dist/live/auto-session/helpers.js +17 -0
- package/dist/live/auto-session/inspect.d.ts +4 -0
- package/dist/live/auto-session/inspect.js +75 -0
- package/dist/live/auto-session/ipc.d.ts +3 -22
- package/dist/live/auto-session/ipc.js +7 -147
- package/dist/live/auto-session/open-browser.d.ts +6 -0
- package/dist/live/auto-session/open-browser.js +47 -0
- package/dist/live/pilot/pilot.d.ts +1 -1
- package/dist/live/pilot/pilot.js +2 -1
- package/dist/live/traverse/traverse.js +6 -200
- package/dist/live/traverse/worker.d.ts +37 -0
- package/dist/live/traverse/worker.js +200 -0
- package/dist/runner/plan/find.js +2 -2
- package/dist/runner/plan/plan.js +1 -1
- package/dist/runner/plan/seed-mem.js +5 -5
- package/dist/runner/plan/spec.js +1 -1
- package/examples/saucedemo/src/blocks/saucedemo-web/checkout-step-two/methods/finish-order.method.block.ts +2 -34
- package/examples/saucedemo/src/flows/checkout-then-browse-again.flow.ts +2 -1
- package/examples/saucedemo/src/flows/checkout.flow.ts +2 -1
- package/examples/saucedemo/src/flows/shop.flow.ts +2 -1
- package/examples/saucedemo/src/stubs/device-showcase.ts +37 -43
- package/examples/saucedemo/src/stubs/finish-order.ts +38 -0
- package/package.json +5 -1
- package/templates/quickstart/src/blocks/saucedemo-web/checkout-step-two/methods/finish-order.method.block.ts +2 -34
- package/templates/quickstart/src/flows/checkout-then-browse-again.flow.ts +2 -1
- package/templates/quickstart/src/flows/checkout.flow.ts +2 -1
- package/templates/quickstart/src/flows/shop.flow.ts +2 -1
- package/templates/quickstart/src/stubs/device-showcase.ts +37 -43
- package/templates/quickstart/src/stubs/finish-order.ts +38 -0
- package/templates/scaffold/src/flows/home/hello.flow.ts +3 -0
- package/templates/scaffold/src/map/(app_base)/home/_methods/assert-hello.method.block.ts +1 -9
|
@@ -1,468 +1,27 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
import { applyRunFlags, looksLikeFlowFileRef, parseRunFlags } from "../flags.js";
|
|
4
|
-
import { runChain } from "../run-chain.js";
|
|
5
|
-
import { runChainAuto } from "../run-chain.js";
|
|
6
|
-
import { resolve } from "node:path";
|
|
7
|
-
import { browserStart } from "../../live/auto-session/start.js";
|
|
8
|
-
import { listBrowserSessions, stopAllBrowserSessions, stopBrowserSession } from "../../live/auto-session/ipc.js";
|
|
1
|
+
// `waygraph auto` / `graph` / `browser` / `pilot`: hands `browser` and `pilot` subcommands and session ops to their
|
|
2
|
+
// files, then runs the interactive explore (or the graph print) for a project; `__auto-serve` is the session child.
|
|
9
3
|
import { existsSync, statSync } from "node:fs";
|
|
10
|
-
import {
|
|
11
|
-
import { requestSession, resolveSessionMeta, runAttachLoop, runAutoServeCommand } from "../../live/auto-session/ipc.js";
|
|
12
|
-
import { pilotAttach, pilotStart } from "../../live/pilot/pilot.js";
|
|
13
|
-
import { parseHighlightShorthand } from "../../demo/narration/shorthand.js";
|
|
14
|
-
import { isFileSelectToken, parseBlocksSelect } from "../../manifest/select.js";
|
|
15
|
-
import { runAutoExplore } from "../../live/auto/auto.js";
|
|
4
|
+
import { resolve } from "node:path";
|
|
16
5
|
import { discoverGraph, findOrphanBlocks, toMermaid } from "../../analysis/graph.js";
|
|
17
6
|
import { envString, setEnv } from "../../engine/env.js";
|
|
18
|
-
import {
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
};
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
};
|
|
7
|
+
import { runAutoServeCommand } from "../../live/auto-session/ipc.js";
|
|
8
|
+
import { runAutoExplore } from "../../live/auto/auto.js";
|
|
9
|
+
import { resolveInjectRoots } from "../../manifest/roots.js";
|
|
10
|
+
import { isFileSelectToken, parseBlocksSelect } from "../../manifest/select.js";
|
|
11
|
+
import { resolveBaseUrl } from "../../runtime/waygraph-config.js";
|
|
12
|
+
import { applyRunFlags, looksLikeFlowFileRef, parseRunFlags } from "../flags.js";
|
|
13
|
+
import { runChain, runChainAuto } from "../run-chain.js";
|
|
14
|
+
import { browserCase } from "./browser.js";
|
|
15
|
+
import { pilotCase } from "./pilot.js";
|
|
16
|
+
import { isSessionOp, sessionOpCase } from "./session-ops.js";
|
|
27
17
|
export async function sessionCase(args, command) {
|
|
28
|
-
if (command === "browser")
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
if (json) {
|
|
36
|
-
console.log(JSON.stringify(sessions, null, 2));
|
|
37
|
-
}
|
|
38
|
-
else {
|
|
39
|
-
printBrowserSessionsList(sessions, proj);
|
|
40
|
-
}
|
|
41
|
-
return;
|
|
42
|
-
}
|
|
43
|
-
if (sub === "stop") {
|
|
44
|
-
const proj = resolve(args[3] ?? process.cwd());
|
|
45
|
-
const target = args[2];
|
|
46
|
-
if (!target) {
|
|
47
|
-
console.error("waygraph browser stop: usage: waygraph browser stop <sessionId|--all> [project]");
|
|
48
|
-
process.exit(1);
|
|
49
|
-
}
|
|
50
|
-
if (target === "--all") {
|
|
51
|
-
const n = stopAllBrowserSessions(proj);
|
|
52
|
-
console.log(JSON.stringify({ stopped: n, projectDir: proj }));
|
|
53
|
-
return;
|
|
54
|
-
}
|
|
55
|
-
if (!stopBrowserSession(proj, target)) {
|
|
56
|
-
console.error(`waygraph browser stop: no such session "${target}"`);
|
|
57
|
-
process.exit(1);
|
|
58
|
-
}
|
|
59
|
-
console.log(JSON.stringify({ stopped: target }));
|
|
60
|
-
return;
|
|
61
|
-
}
|
|
62
|
-
if (!sub) {
|
|
63
|
-
printBrowserUsage();
|
|
64
|
-
return;
|
|
65
|
-
}
|
|
66
|
-
if (sub === "start" || sub.startsWith("-")) {
|
|
67
|
-
const flagArgs = sub === "start" ? args.slice(2) : args.slice(1);
|
|
68
|
-
const flags = parseRunFlags(flagArgs, "browser");
|
|
69
|
-
applyRunFlags(flags);
|
|
70
|
-
const proj = resolve(flags.positionals[0] ?? process.cwd());
|
|
71
|
-
if (!existsSync(proj)) {
|
|
72
|
-
console.error(`waygraph browser: no such directory: ${proj}`);
|
|
73
|
-
process.exit(1);
|
|
74
|
-
}
|
|
75
|
-
const baseURL = flags.baseUrl ?? envString("WAYGRAPH_BASE_URL") ?? (await resolveBaseUrl(proj));
|
|
76
|
-
try {
|
|
77
|
-
const inject = flags.inject?.length ? resolveInjectRoots(flags.inject, proj) : undefined;
|
|
78
|
-
const result = await browserStart({
|
|
79
|
-
projectDir: proj,
|
|
80
|
-
...(inject?.length ? { inject } : {}),
|
|
81
|
-
...(baseURL ? { baseURL } : {}),
|
|
82
|
-
...(flags.goto
|
|
83
|
-
? { startUrl: flags.goto, skipInitialNavigation: false }
|
|
84
|
-
: { skipInitialNavigation: flags.blank !== false }),
|
|
85
|
-
headless: flags.headlessBrowser === true,
|
|
86
|
-
});
|
|
87
|
-
console.log(JSON.stringify(result));
|
|
88
|
-
if (!result.headless) {
|
|
89
|
-
console.error(`Session ${result.sessionId} started. List all: waygraph browser sessions`);
|
|
90
|
-
}
|
|
91
|
-
if (flags.cli) {
|
|
92
|
-
await runAttachLoop(proj, result.sessionId);
|
|
93
|
-
}
|
|
94
|
-
}
|
|
95
|
-
catch (err) {
|
|
96
|
-
console.error(`waygraph browser start: ${err instanceof Error ? err.message : String(err)}`);
|
|
97
|
-
process.exit(1);
|
|
98
|
-
}
|
|
99
|
-
return;
|
|
100
|
-
}
|
|
101
|
-
if (sub !== "send" &&
|
|
102
|
-
sub !== "status" &&
|
|
103
|
-
sub !== "attach" &&
|
|
104
|
-
sub !== "dom" &&
|
|
105
|
-
sub !== "trace" &&
|
|
106
|
-
sub !== "console" &&
|
|
107
|
-
sub !== "storage" &&
|
|
108
|
-
sub !== "upload" &&
|
|
109
|
-
sub !== "click" &&
|
|
110
|
-
sub !== "type" &&
|
|
111
|
-
sub !== "press" &&
|
|
112
|
-
sub !== "goto" &&
|
|
113
|
-
sub !== "reload" &&
|
|
114
|
-
sub !== "reach" &&
|
|
115
|
-
sub !== "resync" &&
|
|
116
|
-
sub !== "highlight") {
|
|
117
|
-
console.error("waygraph browser: unknown subcommand — run `waygraph browser` for usage");
|
|
118
|
-
printBrowserUsage();
|
|
119
|
-
process.exit(1);
|
|
120
|
-
}
|
|
121
|
-
}
|
|
122
|
-
if (command === "pilot") {
|
|
123
|
-
if (args[1] === "sessions") {
|
|
124
|
-
const { values, positionals: positional } = parseCommand("sessions", { json: { type: "boolean", help: "Machine-readable JSON" } }, args.slice(2));
|
|
125
|
-
const json = values.json === true;
|
|
126
|
-
const proj = resolve(positional[0] ?? process.cwd());
|
|
127
|
-
const sessions = listBrowserSessions(proj);
|
|
128
|
-
if (json) {
|
|
129
|
-
console.log(JSON.stringify(sessions, null, 2));
|
|
130
|
-
}
|
|
131
|
-
else {
|
|
132
|
-
printBrowserSessionsList(sessions, proj);
|
|
133
|
-
}
|
|
134
|
-
return;
|
|
135
|
-
}
|
|
136
|
-
if (args[1] === "attach") {
|
|
137
|
-
const sessionId = args[2];
|
|
138
|
-
if (!sessionId) {
|
|
139
|
-
console.error("waygraph pilot attach: usage: waygraph pilot attach <sessionId> [--inject …] [project]");
|
|
140
|
-
process.exit(1);
|
|
141
|
-
}
|
|
142
|
-
const flags = parseRunFlags(args.slice(3), "pilot");
|
|
143
|
-
const proj = resolve(flags.positionals[0] ?? process.cwd());
|
|
144
|
-
try {
|
|
145
|
-
const inject = flags.inject?.length ? resolveInjectRoots(flags.inject, proj) : undefined;
|
|
146
|
-
const result = await pilotAttach(proj, sessionId, inject);
|
|
147
|
-
console.log(JSON.stringify(result));
|
|
148
|
-
}
|
|
149
|
-
catch (err) {
|
|
150
|
-
console.error(`waygraph pilot attach: ${err instanceof Error ? err.message : String(err)}`);
|
|
151
|
-
process.exit(1);
|
|
152
|
-
}
|
|
153
|
-
return;
|
|
154
|
-
}
|
|
155
|
-
if (args[1] === "start" || !args[1] || args[1].startsWith("-")) {
|
|
156
|
-
const flagArgs = args[1] === "start" ? args.slice(2) : args.slice(1);
|
|
157
|
-
const flags = parseRunFlags(flagArgs, "pilot");
|
|
158
|
-
applyRunFlags(flags);
|
|
159
|
-
const proj = resolve(flags.positionals[0] ?? process.cwd());
|
|
160
|
-
const baseURL = flags.baseUrl ?? envString("WAYGRAPH_BASE_URL") ?? (await resolveBaseUrl(proj));
|
|
161
|
-
try {
|
|
162
|
-
const result = await pilotStart({
|
|
163
|
-
projectDir: proj,
|
|
164
|
-
...(flags.inject?.length ? { injectTokens: flags.inject } : {}),
|
|
165
|
-
...(baseURL ? { baseURL } : {}),
|
|
166
|
-
...(flags.goto
|
|
167
|
-
? { startUrl: flags.goto, skipInitialNavigation: false }
|
|
168
|
-
: flags.blank === true
|
|
169
|
-
? { skipInitialNavigation: true }
|
|
170
|
-
: {}),
|
|
171
|
-
headless: flags.headlessBrowser === true,
|
|
172
|
-
});
|
|
173
|
-
console.log(JSON.stringify(result));
|
|
174
|
-
if (!result.headless) {
|
|
175
|
-
console.error(`Chromium window opened (session ${result.sessionId}). ` +
|
|
176
|
-
`Terminal menu: waygraph pilot attach ${result.sessionId}`);
|
|
177
|
-
}
|
|
178
|
-
if (flags.cli) {
|
|
179
|
-
await runAttachLoop(proj, result.sessionId);
|
|
180
|
-
}
|
|
181
|
-
}
|
|
182
|
-
catch (err) {
|
|
183
|
-
console.error(`waygraph pilot start: ${err instanceof Error ? err.message : String(err)}`);
|
|
184
|
-
process.exit(1);
|
|
185
|
-
}
|
|
186
|
-
return;
|
|
187
|
-
}
|
|
188
|
-
if (args[1] !== "send" &&
|
|
189
|
-
args[1] !== "status" &&
|
|
190
|
-
args[1] !== "dom" &&
|
|
191
|
-
args[1] !== "trace" &&
|
|
192
|
-
args[1] !== "console" &&
|
|
193
|
-
args[1] !== "storage" &&
|
|
194
|
-
args[1] !== "upload" &&
|
|
195
|
-
args[1] !== "click" &&
|
|
196
|
-
args[1] !== "type" &&
|
|
197
|
-
args[1] !== "press" &&
|
|
198
|
-
args[1] !== "goto" &&
|
|
199
|
-
args[1] !== "reload" &&
|
|
200
|
-
args[1] !== "reach" &&
|
|
201
|
-
args[1] !== "resync" &&
|
|
202
|
-
args[1] !== "highlight") {
|
|
203
|
-
console.error("waygraph pilot: usage:\n" +
|
|
204
|
-
" waygraph pilot start [--inject …] [--goto <url>] [--headless] [--cli] [--base-url <url>] [project]\n" +
|
|
205
|
-
" waygraph pilot sessions [project] # list live browser sessions\n" +
|
|
206
|
-
" waygraph pilot attach <sessionId> # graph + snapshot for an existing session\n" +
|
|
207
|
-
" waygraph pilot send|status|attach|highlight|… <sessionId> … (controls browser — same as browser/auto)");
|
|
208
|
-
process.exit(1);
|
|
209
|
-
}
|
|
210
|
-
}
|
|
211
|
-
// auto send|status|attach <sessionId> - session control against a
|
|
212
|
-
// --detach'd background session. Intercepted before the normal
|
|
213
|
-
// project-directory resolution below, same pattern `try demo|auto|
|
|
214
|
-
// auto:cli` already uses for a sub-verb positional.
|
|
215
|
-
if ((command === "auto" || command === "browser" || command === "pilot") &&
|
|
216
|
-
(args[1] === "send" ||
|
|
217
|
-
args[1] === "status" ||
|
|
218
|
-
(args[1] === "attach" && command !== "pilot") ||
|
|
219
|
-
args[1] === "dom" ||
|
|
220
|
-
args[1] === "trace" ||
|
|
221
|
-
args[1] === "console" ||
|
|
222
|
-
args[1] === "storage" ||
|
|
223
|
-
args[1] === "upload" ||
|
|
224
|
-
args[1] === "click" ||
|
|
225
|
-
args[1] === "type" ||
|
|
226
|
-
args[1] === "press" ||
|
|
227
|
-
args[1] === "goto" ||
|
|
228
|
-
args[1] === "reload" ||
|
|
229
|
-
args[1] === "reach" ||
|
|
230
|
-
args[1] === "resync" ||
|
|
231
|
-
args[1] === "highlight")) {
|
|
232
|
-
const sub = args[1];
|
|
233
|
-
const sessionId = args[2];
|
|
234
|
-
if (!sessionId) {
|
|
235
|
-
console.error(`waygraph ${command} ${sub}: missing <sessionId>`);
|
|
236
|
-
process.exit(1);
|
|
237
|
-
}
|
|
238
|
-
const projHint = resolve(process.cwd());
|
|
239
|
-
const meta = resolveSessionMeta(sessionId, projHint);
|
|
240
|
-
if (!meta) {
|
|
241
|
-
console.error(`waygraph ${command} ${sub}: no such session "${sessionId}" — ` +
|
|
242
|
-
"wrong directory? run `waygraph pilot sessions` from the project that started it");
|
|
243
|
-
process.exit(1);
|
|
244
|
-
}
|
|
245
|
-
const proj = meta.projectDir;
|
|
246
|
-
if (sub === "attach") {
|
|
247
|
-
await runAttachLoop(proj, sessionId);
|
|
248
|
-
return;
|
|
249
|
-
}
|
|
250
|
-
if (sub === "send") {
|
|
251
|
-
const pick = args[3];
|
|
252
|
-
if (pick === undefined) {
|
|
253
|
-
console.error('waygraph auto send: usage: waygraph auto send <sessionId> "<pick>" [--timeout <ms>]');
|
|
254
|
-
process.exit(1);
|
|
255
|
-
}
|
|
256
|
-
// Real, direct need found live: a single Block can legitimately
|
|
257
|
-
// run a genuinely slow real interaction (e.g. a multi-step mouse
|
|
258
|
-
// drag) that exceeds the 15s default - same reasoning `auto
|
|
259
|
-
// reach` already gets a 90s default for (multiple Blocks in one
|
|
260
|
-
// call). Unlike reach, send has no way to know ahead of time
|
|
261
|
-
// whether the ONE Block it's running is fast or slow, so this is
|
|
262
|
-
// opt-in via a flag rather than a raised default.
|
|
263
|
-
let timeoutMs;
|
|
264
|
-
const raw = parseCommand("auto send", SEND_OPTIONS, args.slice(4)).values.timeout;
|
|
265
|
-
if (raw !== undefined) {
|
|
266
|
-
const n = Number(raw);
|
|
267
|
-
if (!Number.isFinite(n) || n <= 0) {
|
|
268
|
-
console.error(`waygraph auto send: --timeout must be a positive number of ms, got "${raw}"`);
|
|
269
|
-
process.exit(1);
|
|
270
|
-
}
|
|
271
|
-
timeoutMs = n;
|
|
272
|
-
}
|
|
273
|
-
const res = await requestSession(proj, sessionId, { op: "send", pick }, timeoutMs);
|
|
274
|
-
console.log(JSON.stringify(res));
|
|
275
|
-
if (!res.ok)
|
|
276
|
-
process.exitCode = 1;
|
|
277
|
-
return;
|
|
278
|
-
}
|
|
279
|
-
if (sub === "dom") {
|
|
280
|
-
const domArgs = args.slice(3);
|
|
281
|
-
let mode;
|
|
282
|
-
let selector;
|
|
283
|
-
let depth;
|
|
284
|
-
const dom = parseCommand("auto dom", DOM_OPTIONS, domArgs).values;
|
|
285
|
-
if (dom.mode !== undefined) {
|
|
286
|
-
if (dom.mode !== "aria" && dom.mode !== "full") {
|
|
287
|
-
console.error(`waygraph auto dom: --mode must be "aria" or "full", got "${dom.mode}"`);
|
|
288
|
-
process.exit(1);
|
|
289
|
-
}
|
|
290
|
-
mode = dom.mode;
|
|
291
|
-
}
|
|
292
|
-
selector = dom.selector;
|
|
293
|
-
if (dom.depth !== undefined) {
|
|
294
|
-
const n = Number(dom.depth);
|
|
295
|
-
if (!Number.isInteger(n) || n < 1) {
|
|
296
|
-
console.error(`waygraph auto dom: --depth must be a positive integer, got "${dom.depth}"`);
|
|
297
|
-
process.exit(1);
|
|
298
|
-
}
|
|
299
|
-
depth = n;
|
|
300
|
-
}
|
|
301
|
-
const res = await requestSession(proj, sessionId, {
|
|
302
|
-
op: "dom",
|
|
303
|
-
...(mode ? { mode } : {}),
|
|
304
|
-
...(selector ? { selector } : {}),
|
|
305
|
-
...(depth !== undefined ? { depth } : {}),
|
|
306
|
-
});
|
|
307
|
-
console.log(JSON.stringify(res));
|
|
308
|
-
if (!res.ok)
|
|
309
|
-
process.exitCode = 1;
|
|
310
|
-
return;
|
|
311
|
-
}
|
|
312
|
-
if (sub === "trace") {
|
|
313
|
-
const res = await requestSession(proj, sessionId, { op: "trace" });
|
|
314
|
-
console.log(JSON.stringify(res));
|
|
315
|
-
if (!res.ok)
|
|
316
|
-
process.exitCode = 1;
|
|
317
|
-
return;
|
|
318
|
-
}
|
|
319
|
-
if (sub === "console") {
|
|
320
|
-
const res = await requestSession(proj, sessionId, { op: "console" });
|
|
321
|
-
console.log(JSON.stringify(res));
|
|
322
|
-
if (!res.ok)
|
|
323
|
-
process.exitCode = 1;
|
|
324
|
-
return;
|
|
325
|
-
}
|
|
326
|
-
if (sub === "storage") {
|
|
327
|
-
const res = await requestSession(proj, sessionId, { op: "storage" });
|
|
328
|
-
console.log(JSON.stringify(res));
|
|
329
|
-
if (!res.ok)
|
|
330
|
-
process.exitCode = 1;
|
|
331
|
-
return;
|
|
332
|
-
}
|
|
333
|
-
if (sub === "click") {
|
|
334
|
-
const selector = args[3];
|
|
335
|
-
if (selector === undefined) {
|
|
336
|
-
console.error('waygraph auto click: usage: waygraph auto click <sessionId> "<selector>"');
|
|
337
|
-
process.exit(1);
|
|
338
|
-
}
|
|
339
|
-
const res = await requestSession(proj, sessionId, { op: "click", selector });
|
|
340
|
-
console.log(JSON.stringify(res));
|
|
341
|
-
if (!res.ok)
|
|
342
|
-
process.exitCode = 1;
|
|
343
|
-
return;
|
|
344
|
-
}
|
|
345
|
-
if (sub === "type") {
|
|
346
|
-
const selector = args[3];
|
|
347
|
-
const text = args[4];
|
|
348
|
-
if (selector === undefined || text === undefined) {
|
|
349
|
-
console.error('waygraph auto type: usage: waygraph auto type <sessionId> "<selector>" "<text>"');
|
|
350
|
-
process.exit(1);
|
|
351
|
-
}
|
|
352
|
-
const res = await requestSession(proj, sessionId, { op: "type", selector, text });
|
|
353
|
-
console.log(JSON.stringify(res));
|
|
354
|
-
if (!res.ok)
|
|
355
|
-
process.exitCode = 1;
|
|
356
|
-
return;
|
|
357
|
-
}
|
|
358
|
-
if (sub === "press") {
|
|
359
|
-
const selector = args[3];
|
|
360
|
-
const key = args[4];
|
|
361
|
-
if (selector === undefined || key === undefined) {
|
|
362
|
-
console.error('waygraph auto press: usage: waygraph auto press <sessionId> "<selector>" <key>');
|
|
363
|
-
process.exit(1);
|
|
364
|
-
}
|
|
365
|
-
const res = await requestSession(proj, sessionId, { op: "press", selector, key });
|
|
366
|
-
console.log(JSON.stringify(res));
|
|
367
|
-
if (!res.ok)
|
|
368
|
-
process.exitCode = 1;
|
|
369
|
-
return;
|
|
370
|
-
}
|
|
371
|
-
if (sub === "goto") {
|
|
372
|
-
const url = args[3];
|
|
373
|
-
if (url === undefined) {
|
|
374
|
-
console.error("waygraph auto goto: usage: waygraph auto goto <sessionId> <url>");
|
|
375
|
-
process.exit(1);
|
|
376
|
-
}
|
|
377
|
-
const res = await requestSession(proj, sessionId, { op: "goto", url });
|
|
378
|
-
console.log(JSON.stringify(res));
|
|
379
|
-
if (!res.ok)
|
|
380
|
-
process.exitCode = 1;
|
|
381
|
-
return;
|
|
382
|
-
}
|
|
383
|
-
if (sub === "upload") {
|
|
384
|
-
const selector = args[3];
|
|
385
|
-
const kindOrPath = args[4];
|
|
386
|
-
if (selector === undefined || kindOrPath === undefined) {
|
|
387
|
-
console.error('waygraph auto upload: usage: waygraph auto upload <sessionId> "<selector>" <image|pdf|video|path-to-file>');
|
|
388
|
-
process.exit(1);
|
|
389
|
-
}
|
|
390
|
-
const stub = kindOrPath === "image" || kindOrPath === "pdf" || kindOrPath === "video"
|
|
391
|
-
? { selector, stub: kindOrPath }
|
|
392
|
-
: { selector, stub: { filePath: resolve(process.cwd(), kindOrPath) } };
|
|
393
|
-
const res = await requestSession(proj, sessionId, { op: "upload", ...stub });
|
|
394
|
-
console.log(JSON.stringify(res));
|
|
395
|
-
if (!res.ok)
|
|
396
|
-
process.exitCode = 1;
|
|
397
|
-
return;
|
|
398
|
-
}
|
|
399
|
-
if (sub === "reload") {
|
|
400
|
-
const res = await requestSession(proj, sessionId, { op: "reload" });
|
|
401
|
-
console.log(JSON.stringify(res));
|
|
402
|
-
if (!res.ok)
|
|
403
|
-
process.exitCode = 1;
|
|
404
|
-
return;
|
|
405
|
-
}
|
|
406
|
-
if (sub === "reach") {
|
|
407
|
-
const checkpoint = args[3];
|
|
408
|
-
if (checkpoint === undefined) {
|
|
409
|
-
console.error("waygraph auto reach: usage: waygraph auto reach <sessionId> <Checkpoint>");
|
|
410
|
-
process.exit(1);
|
|
411
|
-
}
|
|
412
|
-
// Longer than every other op's default (15s): a real multi-step
|
|
413
|
-
// route runs several real Blocks in sequence server-side before
|
|
414
|
-
// responding - a legitimately slow single request, not a hang.
|
|
415
|
-
const res = await requestSession(proj, sessionId, { op: "reach", checkpoint }, 90_000);
|
|
416
|
-
console.log(JSON.stringify(res));
|
|
417
|
-
if (!res.ok)
|
|
418
|
-
process.exitCode = 1;
|
|
419
|
-
return;
|
|
420
|
-
}
|
|
421
|
-
if (sub === "resync") {
|
|
422
|
-
const res = await requestSession(proj, sessionId, { op: "resync" });
|
|
423
|
-
console.log(JSON.stringify(res));
|
|
424
|
-
if (!res.ok)
|
|
425
|
-
process.exitCode = 1;
|
|
426
|
-
return;
|
|
427
|
-
}
|
|
428
|
-
if (sub === "highlight") {
|
|
429
|
-
const raw = args[3];
|
|
430
|
-
if (raw === undefined) {
|
|
431
|
-
console.error(`waygraph ${command} highlight: usage:\n` +
|
|
432
|
-
` waygraph ${command} highlight <sessionId> '{"rings":[{"selector":"#x","label":"X"}]}'\n` +
|
|
433
|
-
` waygraph ${command} highlight <sessionId> "#x|X" (shorthand: <selector>|<label>[|<tone>], rings separated by ";")`);
|
|
434
|
-
process.exit(1);
|
|
435
|
-
}
|
|
436
|
-
let fixtures;
|
|
437
|
-
try {
|
|
438
|
-
fixtures = JSON.parse(raw);
|
|
439
|
-
}
|
|
440
|
-
catch (jsonErr) {
|
|
441
|
-
const shorthand = parseHighlightShorthand(raw);
|
|
442
|
-
if (shorthand.type === "error") {
|
|
443
|
-
console.error(`waygraph ${command} highlight: body is neither valid JSON (${jsonErr instanceof Error ? jsonErr.message : String(jsonErr)}) nor valid shorthand (${shorthand.reason})`);
|
|
444
|
-
process.exit(1);
|
|
445
|
-
}
|
|
446
|
-
fixtures = shorthand.fixtures;
|
|
447
|
-
}
|
|
448
|
-
if (fixtures.op !== undefined && fixtures.op !== "highlight") {
|
|
449
|
-
console.error(`waygraph ${command} highlight: do not set "op" (or set it to "highlight")`);
|
|
450
|
-
process.exit(1);
|
|
451
|
-
}
|
|
452
|
-
const { op: _ignore, ...rest } = fixtures;
|
|
453
|
-
const res = await requestSession(proj, sessionId, {
|
|
454
|
-
op: "highlight",
|
|
455
|
-
...rest,
|
|
456
|
-
});
|
|
457
|
-
console.log(JSON.stringify(res));
|
|
458
|
-
if (!res.ok)
|
|
459
|
-
process.exitCode = 1;
|
|
460
|
-
return;
|
|
461
|
-
}
|
|
462
|
-
const res = await requestSession(proj, sessionId, { op: "status" });
|
|
463
|
-
console.log(JSON.stringify(res));
|
|
464
|
-
if (!res.ok)
|
|
465
|
-
process.exitCode = 1;
|
|
18
|
+
if (command === "browser" && (await browserCase(args)))
|
|
19
|
+
return;
|
|
20
|
+
if (command === "pilot" && (await pilotCase(args)))
|
|
21
|
+
return;
|
|
22
|
+
// A session op (`auto|browser|pilot send <sessionId> ...`) runs against a running session, before any project path.
|
|
23
|
+
if ((command === "auto" || command === "browser" || command === "pilot") && isSessionOp(command, args[1])) {
|
|
24
|
+
await sessionOpCase(args, command);
|
|
466
25
|
return;
|
|
467
26
|
}
|
|
468
27
|
const flags = parseRunFlags(args.slice(1), command ?? "auto");
|
package/dist/cli/run-chain.js
CHANGED
|
@@ -92,12 +92,12 @@ export async function runChainAuto(projectDir, fromTag, toTag) {
|
|
|
92
92
|
const graph = await discoverGraph(projectDir);
|
|
93
93
|
const path = findBlockPath(graph, fromTag, toTag);
|
|
94
94
|
if (!path) {
|
|
95
|
-
console.error(`waygraph
|
|
95
|
+
console.error(`waygraph auto --blocks: no Block path from "${fromTag}" to "${toTag}" in the discovered graph`);
|
|
96
96
|
process.exitCode = 1;
|
|
97
97
|
return;
|
|
98
98
|
}
|
|
99
99
|
const spec = path.join(" then ");
|
|
100
|
-
console.error(`waygraph
|
|
100
|
+
console.error(`waygraph auto --blocks: ${fromTag} -> ${toTag} via ${spec}`);
|
|
101
101
|
if (!envString("WAYGRAPH_BASE_URL")) {
|
|
102
102
|
const resolved = await resolveBaseUrl(projectDir);
|
|
103
103
|
if (resolved)
|
package/dist/cli/usage.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { SessionMeta } from "../live/auto-session/
|
|
1
|
+
import type { SessionMeta } from "../live/auto-session/files.js";
|
|
2
2
|
export declare function printBrowserUsage(): void;
|
|
3
3
|
export declare function printBrowserSessionsList(sessions: SessionMeta[], projectDir: string): void;
|
|
4
4
|
export declare function usage(): void;
|
package/dist/cli/util.js
CHANGED
|
@@ -4,7 +4,7 @@ import { spawn } from "node:child_process";
|
|
|
4
4
|
// ---------------------------------------------------------------------------
|
|
5
5
|
// `try` - a bundled, self-contained showcase. No .flow.ts to write, no
|
|
6
6
|
// scenario to design - copies a small real Flow (nav/action Blocks, Trait
|
|
7
|
-
// verify,
|
|
7
|
+
// verify, ctx stubs) into the target project and runs it in step mode
|
|
8
8
|
// against a public demo site, so a curious dev sees the real overlay/panel
|
|
9
9
|
// experience in under a minute, then gets pointed at the plain waygraph
|
|
10
10
|
// source that produced it.
|
|
@@ -29,7 +29,7 @@ export declare function formatDemoPaceBadge(pace: DemoPace, baseAutoplayMs?: num
|
|
|
29
29
|
*/
|
|
30
30
|
export declare function formatDemoPaceLabel(pace: DemoPace, baseAutoplayMs?: number): string;
|
|
31
31
|
/**
|
|
32
|
-
* Resolve min dwell ms for any fixture (stub
|
|
32
|
+
* Resolve min dwell ms for any fixture (a stub ring or a yap slide),
|
|
33
33
|
* or `null` when duration is unset (caller keeps its default timing).
|
|
34
34
|
*
|
|
35
35
|
* Authoring wins: an explicit slow/numeric pace is not crushed by CLI `--fast`
|
|
@@ -37,7 +37,7 @@ export declare function formatDemoPaceLabel(pace: DemoPace, baseAutoplayMs?: num
|
|
|
37
37
|
*/
|
|
38
38
|
export declare function resolveFixtureDwellMs(fixture: FixtureDurationFields, opts?: {
|
|
39
39
|
gatesFast?: boolean;
|
|
40
|
-
pace?: DemoPace;
|
|
40
|
+
pace?: DemoPace | undefined;
|
|
41
41
|
}): number | null;
|
|
42
42
|
/**
|
|
43
43
|
* Effective demo pace for a step: block override > flow episode > normal.
|
|
@@ -150,7 +150,7 @@ export function formatDemoPaceLabel(pace, baseAutoplayMs = 1800) {
|
|
|
150
150
|
return `pace normal (1x, ~${gate}ms gates)`;
|
|
151
151
|
}
|
|
152
152
|
/**
|
|
153
|
-
* Resolve min dwell ms for any fixture (stub
|
|
153
|
+
* Resolve min dwell ms for any fixture (a stub ring or a yap slide),
|
|
154
154
|
* or `null` when duration is unset (caller keeps its default timing).
|
|
155
155
|
*
|
|
156
156
|
* Authoring wins: an explicit slow/numeric pace is not crushed by CLI `--fast`
|
|
@@ -23,8 +23,8 @@ export declare function resolveDeviceState(input: DevicePreset | DeviceState | D
|
|
|
23
23
|
* - keep: omit - preserve previous (whole episode remain)
|
|
24
24
|
*/
|
|
25
25
|
export declare function applyDevicePhase(prev: DeviceState | undefined, phase: {
|
|
26
|
-
deviceSync?: "set" | "clear" | "keep";
|
|
27
|
-
device?: DeviceState;
|
|
26
|
+
deviceSync?: "set" | "clear" | "keep" | undefined;
|
|
27
|
+
device?: DeviceState | undefined;
|
|
28
28
|
}): {
|
|
29
29
|
device: DeviceState | undefined;
|
|
30
30
|
sync: "set" | "clear" | "keep";
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import type { HighlightStubPhase, ResolvedHighlight } from "../../engine/stub/ring.js";
|
|
2
2
|
import type { HighlightStubPhaseName, StubLifecycleFn } from "../../engine/stub/stub.js";
|
|
3
|
-
import type {
|
|
3
|
+
import type { SomeBlock } from "../../engine/block/block.js";
|
|
4
|
+
import type { Checkpoint } from "../../engine/checkpoint/checkpoint.js";
|
|
4
5
|
export declare function applyDefaultZoom(slots: ResolvedHighlight[], defaultZoom?: number): ResolvedHighlight[];
|
|
5
6
|
export declare function applyDefaultZoomOut(slots: ResolvedHighlight[], defaultZoomOut?: boolean): ResolvedHighlight[];
|
|
6
|
-
/** A stub phase's
|
|
7
|
+
/** A stub phase's rings (by id, as ctx.ring set them) as an ordered list of resolved highlights. */
|
|
7
8
|
export declare function resolvePhaseMap(phaseMap: HighlightStubPhase): ResolvedHighlight[];
|
|
8
|
-
|
|
9
|
+
/** The stub a Block's flow chained for this phase, if any. */
|
|
10
|
+
export declare function readStubRaw(block: SomeBlock, phase: HighlightStubPhaseName): StubLifecycleFn<Checkpoint<string>> | undefined;
|
|
@@ -40,7 +40,7 @@ export function applyDefaultZoomOut(slots, defaultZoomOut) {
|
|
|
40
40
|
return slots;
|
|
41
41
|
return slots.map((h) => h.zoomOut !== undefined ? h : { ...h, zoomOut: defaultZoomOut });
|
|
42
42
|
}
|
|
43
|
-
/** A stub phase's
|
|
43
|
+
/** A stub phase's rings (by id, as ctx.ring set them) as an ordered list of resolved highlights. */
|
|
44
44
|
export function resolvePhaseMap(phaseMap) {
|
|
45
45
|
const phaseKeys = Object.keys(phaseMap);
|
|
46
46
|
const allNumeric = phaseKeys.length > 0 && phaseKeys.every((k) => Number.isFinite(Number(k)) && String(Number(k)) === k);
|
|
@@ -61,11 +61,7 @@ export function resolvePhaseMap(phaseMap) {
|
|
|
61
61
|
}
|
|
62
62
|
return resolved;
|
|
63
63
|
}
|
|
64
|
+
/** The stub a Block's flow chained for this phase, if any. */
|
|
64
65
|
export function readStubRaw(block, phase) {
|
|
65
|
-
|
|
66
|
-
if (phase === "stubBefore")
|
|
67
|
-
return instr.stubBefore;
|
|
68
|
-
if (phase === "stubAfter")
|
|
69
|
-
return instr.stubAfter;
|
|
70
|
-
return instr.stubOnError;
|
|
66
|
+
return block.instruction[phase];
|
|
71
67
|
}
|
|
@@ -1,39 +1,35 @@
|
|
|
1
1
|
import type { HighlightStubPhaseName, StubPhaseResult } from "../../engine/stub/stub.js";
|
|
2
|
-
import type { ResolvedHighlight
|
|
3
|
-
import type {
|
|
2
|
+
import type { ResolvedHighlight } from "../../engine/stub/ring.js";
|
|
3
|
+
import type { SomeBlock } from "../../engine/block/block.js";
|
|
4
4
|
import type { Checkpoint } from "../../engine/checkpoint/checkpoint.js";
|
|
5
5
|
import type { MemPage } from "../../engine/mem/mem.js";
|
|
6
6
|
/**
|
|
7
|
-
*
|
|
7
|
+
* Runs a Block's stub for one phase and returns what it painted.
|
|
8
8
|
* Returns rings + episode fixtures (todos / todoIndex / zoom).
|
|
9
9
|
*
|
|
10
10
|
* @example
|
|
11
11
|
* const before = await runStubPhase(block, "stubBefore", { mem });
|
|
12
12
|
* // before.todos, before.highlights
|
|
13
13
|
*/
|
|
14
|
-
export declare function runStubPhase(block:
|
|
15
|
-
out?: Checkpoint<string
|
|
14
|
+
export declare function runStubPhase(block: SomeBlock, phase: HighlightStubPhaseName, opts?: {
|
|
15
|
+
out?: Checkpoint<string> | undefined;
|
|
16
16
|
error?: unknown;
|
|
17
|
-
mem?: MemPage;
|
|
17
|
+
mem?: MemPage | undefined;
|
|
18
18
|
}): Promise<StubPhaseResult>;
|
|
19
19
|
/**
|
|
20
20
|
* Sync resolve of highlight slots. Prefer {@link runStubPhase} for open
|
|
21
21
|
* async lifecycles + episode fixtures (todos/zoom).
|
|
22
22
|
*/
|
|
23
|
-
export declare function resolveHighlightSlots(block:
|
|
23
|
+
export declare function resolveHighlightSlots(block: SomeBlock, phase: HighlightStubPhaseName, opts?: {
|
|
24
24
|
out?: Checkpoint<string>;
|
|
25
25
|
}): ResolvedHighlight[];
|
|
26
|
-
/** Resolve multi-step yap slides from `instruction.slides` (function form allowed). */
|
|
27
|
-
export declare function resolveSlides(block: Block<any, any>, opts?: {
|
|
28
|
-
out?: Checkpoint<string>;
|
|
29
|
-
}): WaygraphSlide[];
|
|
30
26
|
/**
|
|
31
27
|
* True when the block authored stubAfter (lifecycle fn or slots).
|
|
32
28
|
* When true, demo should not use verify-trait fallback.
|
|
33
29
|
*/
|
|
34
|
-
export declare function hasAuthoredStubAfter(block:
|
|
30
|
+
export declare function hasAuthoredStubAfter(block: SomeBlock, out?: Checkpoint<string>): boolean;
|
|
35
31
|
/**
|
|
36
32
|
* True when stubOnError is authored (lifecycle fn and/or rings).
|
|
37
33
|
* Demo fail path only - success never consults this.
|
|
38
34
|
*/
|
|
39
|
-
export declare function hasAuthoredStubOnError(block:
|
|
35
|
+
export declare function hasAuthoredStubOnError(block: SomeBlock): boolean;
|