@vforsh/argus 0.5.1 → 0.5.3
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/.tsbuildinfo +1 -1
- package/dist/argus.js +232 -51
- package/dist/cli/register/recordCommands.d.ts.map +1 -1
- package/dist/cli/register/recordCommands.js +6 -3
- package/dist/cli/register/recordCommands.js.map +1 -1
- package/dist/cli/register/snapshotCommands.js +1 -1
- package/dist/cli/register/snapshotCommands.js.map +1 -1
- package/dist/cli/register/traceCommands.d.ts.map +1 -1
- package/dist/cli/register/traceCommands.js +6 -3
- package/dist/cli/register/traceCommands.js.map +1 -1
- package/dist/commands/domKeydown.d.ts.map +1 -1
- package/dist/commands/domKeydown.js +7 -2
- package/dist/commands/domKeydown.js.map +1 -1
- package/dist/commands/page.js +2 -2
- package/dist/commands/page.js.map +1 -1
- package/dist/commands/record.d.ts.map +1 -1
- package/dist/commands/record.js +3 -2
- package/dist/commands/record.js.map +1 -1
- package/dist/commands/screenshot.d.ts.map +1 -1
- package/dist/commands/screenshot.js +2 -1
- package/dist/commands/screenshot.js.map +1 -1
- package/dist/commands/trace.d.ts.map +1 -1
- package/dist/commands/trace.js +3 -2
- package/dist/commands/trace.js.map +1 -1
- package/dist/eval/evalClient.d.ts +9 -1
- package/dist/eval/evalClient.d.ts.map +1 -1
- package/dist/eval/evalClient.js +31 -8
- package/dist/eval/evalClient.js.map +1 -1
- package/dist/skill/argus/SKILL.md +6 -0
- package/dist/skill/argus/reference/CAPTURE.md +6 -0
- package/dist/skill/argus/reference/EVAL.md +2 -0
- package/dist/skill/argus/reference/INSPECT.md +6 -0
- package/dist/utils/paths.d.ts +12 -0
- package/dist/utils/paths.d.ts.map +1 -1
- package/dist/utils/paths.js +15 -0
- package/dist/utils/paths.js.map +1 -1
- package/package.json +1 -1
package/dist/argus.js
CHANGED
|
@@ -2130,7 +2130,7 @@ var {
|
|
|
2130
2130
|
// package.json
|
|
2131
2131
|
var package_default = {
|
|
2132
2132
|
name: "@vforsh/argus",
|
|
2133
|
-
version: "0.5.
|
|
2133
|
+
version: "0.5.3",
|
|
2134
2134
|
repository: {
|
|
2135
2135
|
type: "git",
|
|
2136
2136
|
url: "git+https://github.com/vforsh/argus.git",
|
|
@@ -3551,6 +3551,11 @@ var ARGUS_ERROR_CODES = [
|
|
|
3551
3551
|
"argus_executable_not_found",
|
|
3552
3552
|
"body_not_available",
|
|
3553
3553
|
"cdp_not_attached",
|
|
3554
|
+
"cdp_renderer_unresponsive",
|
|
3555
|
+
"cdp_target_replaced",
|
|
3556
|
+
"cdp_timeout",
|
|
3557
|
+
"chrome_unreachable",
|
|
3558
|
+
"dialog_blocking",
|
|
3554
3559
|
"dialog_not_prompt",
|
|
3555
3560
|
"extension_action_failed",
|
|
3556
3561
|
"extension_frame_not_ready",
|
|
@@ -3580,6 +3585,7 @@ var ARGUS_ERROR_CODES = [
|
|
|
3580
3585
|
"session_invalid_request",
|
|
3581
3586
|
"session_request_timeout",
|
|
3582
3587
|
"session_unknown_command",
|
|
3588
|
+
"target_not_focused",
|
|
3583
3589
|
"unexpected_matches",
|
|
3584
3590
|
"unsupported_platform"
|
|
3585
3591
|
];
|
|
@@ -4451,7 +4457,7 @@ var buildWatcherUrl = (watcher, path4, query2) => {
|
|
|
4451
4457
|
const qs = query2?.toString();
|
|
4452
4458
|
return `http://${watcher.host}:${watcher.port}${path4}${qs ? `?${qs}` : ""}`;
|
|
4453
4459
|
};
|
|
4454
|
-
var formatWatcherTransportError = (watcher, error) => `${watcher.id}: failed to reach watcher (${formatError(error)})`;
|
|
4460
|
+
var formatWatcherTransportError = (watcher, error) => classifyWatcherFailure(error) === "api-rejection" ? `${watcher.id}: watcher rejected the request (${formatError(error)})` : `${watcher.id}: failed to reach watcher (${formatError(error)})`;
|
|
4455
4461
|
var classifyWatcherFailure = (error) => {
|
|
4456
4462
|
if (isHttpResponseError(error)) {
|
|
4457
4463
|
return "api-rejection";
|
|
@@ -6104,6 +6110,10 @@ var resolvePath = (input) => {
|
|
|
6104
6110
|
const expanded = input.startsWith("~/") || input === "~" ? path4.join(homedir(), input.slice(1)) : input;
|
|
6105
6111
|
return path4.resolve(expanded);
|
|
6106
6112
|
};
|
|
6113
|
+
var resolveArtifactOutFile = (out) => {
|
|
6114
|
+
const trimmed = out?.trim();
|
|
6115
|
+
return trimmed ? resolvePath(trimmed) : undefined;
|
|
6116
|
+
};
|
|
6107
6117
|
|
|
6108
6118
|
// dist/commands/startShared.js
|
|
6109
6119
|
var resolveInjectScript = async (inject, output) => {
|
|
@@ -7105,6 +7115,63 @@ var getErrorCode = (error) => {
|
|
|
7105
7115
|
var hasErrorCode = (error, code2) => getErrorCode(error) === code2;
|
|
7106
7116
|
var createNotAttachedError = (message = "No tab attached via extension") => codedError("cdp_not_attached", message);
|
|
7107
7117
|
|
|
7118
|
+
// ../argus-watcher/dist/cdp/health.js
|
|
7119
|
+
var CDP_HEALTH_PROBE_TIMEOUT_MS = 2000;
|
|
7120
|
+
var diagnoseCdpHealth = async (probe) => {
|
|
7121
|
+
const id = probe.watcherId ?? "<id>";
|
|
7122
|
+
if (!probe.isAttached()) {
|
|
7123
|
+
return {
|
|
7124
|
+
code: "cdp_not_attached",
|
|
7125
|
+
message: `The watcher is not attached to a target. Check \`argus watcher status ${id}\` and \`argus doctor\`.`
|
|
7126
|
+
};
|
|
7127
|
+
}
|
|
7128
|
+
const transport = await probe.checkTransport?.() ?? { state: "ok" };
|
|
7129
|
+
if (transport.state === "unreachable") {
|
|
7130
|
+
return {
|
|
7131
|
+
code: "chrome_unreachable",
|
|
7132
|
+
message: `Chrome's CDP endpoint did not answer (${transport.detail}). Restart the browser, then \`argus doctor\`.`
|
|
7133
|
+
};
|
|
7134
|
+
}
|
|
7135
|
+
if (transport.state === "target_gone") {
|
|
7136
|
+
probe.onTargetGone?.();
|
|
7137
|
+
return {
|
|
7138
|
+
code: "cdp_target_replaced",
|
|
7139
|
+
message: `The attached page target is gone (${transport.detail}) — a navigation replaced it. ` + `Argus is reattaching; retry the command, or check \`argus watcher status ${id}\`.`
|
|
7140
|
+
};
|
|
7141
|
+
}
|
|
7142
|
+
const dialog2 = probe.getBlockingDialog?.();
|
|
7143
|
+
if (dialog2) {
|
|
7144
|
+
return {
|
|
7145
|
+
code: "dialog_blocking",
|
|
7146
|
+
message: `A ${dialog2.type} dialog is open and blocking the page. ` + `Dismiss it with \`argus dialog accept ${id}\` or \`argus dialog dismiss ${id}\`, then retry.`
|
|
7147
|
+
};
|
|
7148
|
+
}
|
|
7149
|
+
if (!await probe.probeRenderer()) {
|
|
7150
|
+
return {
|
|
7151
|
+
code: "cdp_renderer_unresponsive",
|
|
7152
|
+
message: `The page's renderer did not answer a trivial evaluation within ${CDP_HEALTH_PROBE_TIMEOUT_MS}ms — its main thread is ` + `blocked, or a cross-origin navigation stranded it. A longer timeout will not help: reload with \`argus reload ${id}\`, ` + "or restart Chrome."
|
|
7153
|
+
};
|
|
7154
|
+
}
|
|
7155
|
+
return {
|
|
7156
|
+
code: "cdp_timeout",
|
|
7157
|
+
message: "The watcher, target, and renderer all answered, so the expression itself exceeded its deadline. Pass a longer timeout."
|
|
7158
|
+
};
|
|
7159
|
+
};
|
|
7160
|
+
var toDiagnosedError = (diagnosis, original) => {
|
|
7161
|
+
const detail = original instanceof Error ? original.message : String(original);
|
|
7162
|
+
return codedError(diagnosis.code, `${detail}. ${diagnosis.message}`);
|
|
7163
|
+
};
|
|
7164
|
+
var isCdpTimeoutError = (error) => error instanceof Error && /\b(?:CDP|Bridge|Control) request timed out\b/i.test(error.message);
|
|
7165
|
+
var createSessionRendererProbe = (session2) => async () => {
|
|
7166
|
+
try {
|
|
7167
|
+
const params = { expression: "1", returnByValue: true, silent: true };
|
|
7168
|
+
await session2.sendAndWait("Runtime.evaluate", params, { timeoutMs: CDP_HEALTH_PROBE_TIMEOUT_MS });
|
|
7169
|
+
return true;
|
|
7170
|
+
} catch {
|
|
7171
|
+
return false;
|
|
7172
|
+
}
|
|
7173
|
+
};
|
|
7174
|
+
|
|
7108
7175
|
// ../argus-watcher/dist/http/httpUtils.js
|
|
7109
7176
|
var respondJson = (res, body, status2 = 200) => {
|
|
7110
7177
|
const payload = JSON.stringify(body);
|
|
@@ -7133,6 +7200,17 @@ var respondPayloadTooLarge = (res) => {
|
|
|
7133
7200
|
var respondError = (res, error) => {
|
|
7134
7201
|
respondApiError(res, 500, getErrorCode(error), formatError(error));
|
|
7135
7202
|
};
|
|
7203
|
+
var respondCdpError = async (res, error, diagnose) => {
|
|
7204
|
+
if (!diagnose || !isCdpTimeoutError(error)) {
|
|
7205
|
+
respondError(res, error);
|
|
7206
|
+
return;
|
|
7207
|
+
}
|
|
7208
|
+
try {
|
|
7209
|
+
respondError(res, toDiagnosedError(await diagnose(), error));
|
|
7210
|
+
} catch {
|
|
7211
|
+
respondError(res, error);
|
|
7212
|
+
}
|
|
7213
|
+
};
|
|
7136
7214
|
var readJsonBody = async (req, res) => {
|
|
7137
7215
|
const chunks = [];
|
|
7138
7216
|
let size = 0;
|
|
@@ -7274,7 +7352,7 @@ var normalizeTimeout = (value) => {
|
|
|
7274
7352
|
// ../argus-watcher/package.json
|
|
7275
7353
|
var package_default2 = {
|
|
7276
7354
|
name: "@vforsh/argus-watcher",
|
|
7277
|
-
version: "0.5.
|
|
7355
|
+
version: "0.5.3",
|
|
7278
7356
|
repository: {
|
|
7279
7357
|
type: "git",
|
|
7280
7358
|
url: "git+https://github.com/vforsh/argus.git",
|
|
@@ -7351,7 +7429,7 @@ var defineJsonRoute = (input) => ({
|
|
|
7351
7429
|
if (input.handleError?.(res, error)) {
|
|
7352
7430
|
return;
|
|
7353
7431
|
}
|
|
7354
|
-
|
|
7432
|
+
await respondCdpError(res, error, ctx.diagnoseCdp);
|
|
7355
7433
|
}
|
|
7356
7434
|
}
|
|
7357
7435
|
});
|
|
@@ -9470,6 +9548,7 @@ var shouldMaterializeByValue = (record2) => {
|
|
|
9470
9548
|
};
|
|
9471
9549
|
|
|
9472
9550
|
// ../argus-watcher/dist/http/routes/postEval.js
|
|
9551
|
+
var DEFAULT_EVAL_CDP_TIMEOUT_MS = 30000;
|
|
9473
9552
|
var route18 = defineJsonRoute({
|
|
9474
9553
|
method: "POST",
|
|
9475
9554
|
path: "/eval",
|
|
@@ -9482,7 +9561,7 @@ var route18 = defineJsonRoute({
|
|
|
9482
9561
|
replMode: normalizeBoolean(payload.replMode, true),
|
|
9483
9562
|
returnByValue: normalizeBoolean(payload.returnByValue, true),
|
|
9484
9563
|
jsonValue: normalizeBoolean(payload.jsonValue, false),
|
|
9485
|
-
timeoutMs: normalizeTimeout(payload.timeoutMs),
|
|
9564
|
+
timeoutMs: normalizeTimeout(payload.timeoutMs) ?? DEFAULT_EVAL_CDP_TIMEOUT_MS,
|
|
9486
9565
|
scenario: normalizeBoolean(payload.scenario, false),
|
|
9487
9566
|
scenarioServices: {
|
|
9488
9567
|
buffer: ctx.buffer,
|
|
@@ -11071,25 +11150,44 @@ var dispatchKeydown = async (session2, options) => {
|
|
|
11071
11150
|
await session2.sendAndWait("DOM.focus", { nodeId });
|
|
11072
11151
|
focused = true;
|
|
11073
11152
|
}
|
|
11074
|
-
const
|
|
11153
|
+
const carriesText = event.text != null;
|
|
11075
11154
|
const baseParams = {
|
|
11076
11155
|
code: event.code,
|
|
11077
11156
|
key: event.key,
|
|
11078
11157
|
windowsVirtualKeyCode: event.keyCode,
|
|
11079
|
-
nativeVirtualKeyCode: event.keyCode,
|
|
11080
11158
|
modifiers: event.modifiers
|
|
11081
11159
|
};
|
|
11082
|
-
|
|
11083
|
-
|
|
11084
|
-
|
|
11085
|
-
await session2.sendAndWait("Input.dispatchKeyEvent", { ...baseParams, type: "keyUp" });
|
|
11086
|
-
} else {
|
|
11087
|
-
await session2.sendAndWait("Input.dispatchKeyEvent", { ...baseParams, type: "rawKeyDown", text: event.text });
|
|
11088
|
-
await session2.sendAndWait("Input.dispatchKeyEvent", { ...baseParams, type: "keyUp" });
|
|
11089
|
-
}
|
|
11160
|
+
const keyDownParams = carriesText ? { ...baseParams, type: "keyDown", text: event.text, unmodifiedText: event.text } : { ...baseParams, type: "rawKeyDown" };
|
|
11161
|
+
await session2.sendAndWait("Input.dispatchKeyEvent", keyDownParams);
|
|
11162
|
+
await session2.sendAndWait("Input.dispatchKeyEvent", { ...baseParams, type: "keyUp" });
|
|
11090
11163
|
return { key: event.key, code: event.code, modifiers: event.modifiers, focused, event };
|
|
11091
11164
|
};
|
|
11092
11165
|
|
|
11166
|
+
// ../argus-watcher/dist/cdp/pageFocus.js
|
|
11167
|
+
var FOCUS_PROBE_TIMEOUT_MS = 3000;
|
|
11168
|
+
var ensurePageInputFocus = async (pageSession, visibility2) => {
|
|
11169
|
+
if (!pageSession.isAttached()) {
|
|
11170
|
+
return { activated: false };
|
|
11171
|
+
}
|
|
11172
|
+
if (await hasPageFocus(pageSession)) {
|
|
11173
|
+
return { activated: false };
|
|
11174
|
+
}
|
|
11175
|
+
try {
|
|
11176
|
+
await visibility2.setLock(pageSession, "shown");
|
|
11177
|
+
} catch (error) {
|
|
11178
|
+
throw notFocusedError(`activating it failed: ${formatError(error)}`);
|
|
11179
|
+
}
|
|
11180
|
+
if (!await hasPageFocus(pageSession)) {
|
|
11181
|
+
throw notFocusedError("activating it did not give it focus");
|
|
11182
|
+
}
|
|
11183
|
+
return { activated: true };
|
|
11184
|
+
};
|
|
11185
|
+
var hasPageFocus = async (pageSession) => {
|
|
11186
|
+
const focused = await tryEvaluateInPage(pageSession, "document.hasFocus()", { timeoutMs: FOCUS_PROBE_TIMEOUT_MS });
|
|
11187
|
+
return focused !== false;
|
|
11188
|
+
};
|
|
11189
|
+
var notFocusedError = (reason) => codedError("target_not_focused", `The page is not focused, so Chrome would drop the keyboard event — ${reason}. ` + "Run `argus page show <id>` and retry, or start the watcher against a visible page.");
|
|
11190
|
+
|
|
11093
11191
|
// ../argus-watcher/dist/http/routes/postDomKeydown.js
|
|
11094
11192
|
var route32 = defineJsonRoute({
|
|
11095
11193
|
method: "POST",
|
|
@@ -11097,6 +11195,7 @@ var route32 = defineJsonRoute({
|
|
|
11097
11195
|
bodySchema: domKeydownRequestSchema,
|
|
11098
11196
|
endpoint: "dom/keydown",
|
|
11099
11197
|
handle: async ({ ctx, body: payload }) => {
|
|
11198
|
+
const activation = await ensurePageInputFocus(ctx.pageCdpSession, ctx.visibilityController);
|
|
11100
11199
|
const result = await dispatchKeydown(ctx.cdpSession, {
|
|
11101
11200
|
key: payload.key,
|
|
11102
11201
|
code: payload.code,
|
|
@@ -11109,6 +11208,7 @@ var route32 = defineJsonRoute({
|
|
|
11109
11208
|
code: result.code,
|
|
11110
11209
|
modifiers: result.modifiers,
|
|
11111
11210
|
focused: result.focused,
|
|
11211
|
+
activated: activation.activated,
|
|
11112
11212
|
event: result.event
|
|
11113
11213
|
};
|
|
11114
11214
|
}
|
|
@@ -13468,6 +13568,47 @@ var decodeInlineSourcemap = (value) => {
|
|
|
13468
13568
|
}
|
|
13469
13569
|
};
|
|
13470
13570
|
|
|
13571
|
+
// ../argus-watcher/dist/sourcemaps/scriptFetcher.js
|
|
13572
|
+
var createScriptFetcher = () => {
|
|
13573
|
+
const rangeHostileOrigins = new Set;
|
|
13574
|
+
return async (scriptUrl, tailBytes) => {
|
|
13575
|
+
const origin = originOf(scriptUrl);
|
|
13576
|
+
const ranged = tailBytes !== null && tailBytes > 0 && !rangeHostileOrigins.has(origin);
|
|
13577
|
+
const response = await fetch(scriptUrl, ranged ? { headers: { Range: `bytes=-${tailBytes}` } } : undefined);
|
|
13578
|
+
if (response.ok) {
|
|
13579
|
+
return readBody(response);
|
|
13580
|
+
}
|
|
13581
|
+
if (!ranged || !looksLikeRangeRejection(response.status)) {
|
|
13582
|
+
return null;
|
|
13583
|
+
}
|
|
13584
|
+
await discardBody(response);
|
|
13585
|
+
const whole = await fetch(scriptUrl);
|
|
13586
|
+
if (!whole.ok) {
|
|
13587
|
+
await discardBody(whole);
|
|
13588
|
+
return null;
|
|
13589
|
+
}
|
|
13590
|
+
if (!rangeHostileOrigins.has(origin)) {
|
|
13591
|
+
rangeHostileOrigins.add(origin);
|
|
13592
|
+
console.warn(`[Sourcemaps] ${origin} rejected a suffix Range request (HTTP ${response.status}); refetching scripts whole.`);
|
|
13593
|
+
}
|
|
13594
|
+
return readBody(whole);
|
|
13595
|
+
};
|
|
13596
|
+
};
|
|
13597
|
+
var looksLikeRangeRejection = (status2) => status2 === 416 || status2 >= 500;
|
|
13598
|
+
var originOf = (scriptUrl) => {
|
|
13599
|
+
try {
|
|
13600
|
+
return new URL(scriptUrl).origin;
|
|
13601
|
+
} catch {
|
|
13602
|
+
return scriptUrl;
|
|
13603
|
+
}
|
|
13604
|
+
};
|
|
13605
|
+
var readBody = async (response) => ({ text: await response.text(), partial: response.status === 206 });
|
|
13606
|
+
var discardBody = async (response) => {
|
|
13607
|
+
try {
|
|
13608
|
+
await response.body?.cancel();
|
|
13609
|
+
} catch {}
|
|
13610
|
+
};
|
|
13611
|
+
|
|
13471
13612
|
// ../argus-watcher/dist/sourcemaps/resolveLocation.js
|
|
13472
13613
|
var resolveSourcemappedLocationWithMap = (traceMap, location) => {
|
|
13473
13614
|
if (location.line <= 0 || location.column <= 0) {
|
|
@@ -13495,6 +13636,7 @@ var createSourcemapResolver = (options = {}) => {
|
|
|
13495
13636
|
const maxEntries = options.maxEntries ?? DEFAULT_MAX_ENTRIES;
|
|
13496
13637
|
const negativeTtlMs = options.negativeTtlMs ?? DEFAULT_NEGATIVE_TTL_MS;
|
|
13497
13638
|
const tailBytes = options.tailBytes ?? DEFAULT_TAIL_BYTES;
|
|
13639
|
+
const fetchScript = createScriptFetcher();
|
|
13498
13640
|
const cache = new Map;
|
|
13499
13641
|
const pending = new Map;
|
|
13500
13642
|
let generation = 0;
|
|
@@ -13536,7 +13678,7 @@ var createSourcemapResolver = (options = {}) => {
|
|
|
13536
13678
|
return inFlight;
|
|
13537
13679
|
}
|
|
13538
13680
|
const startedAt = generation;
|
|
13539
|
-
const promise = loadTraceMap(scriptUrl, tailBytes).catch(() => null).then((traceMap) => {
|
|
13681
|
+
const promise = loadTraceMap(scriptUrl, tailBytes, fetchScript).catch(() => null).then((traceMap) => {
|
|
13540
13682
|
if (startedAt === generation) {
|
|
13541
13683
|
writeCache(scriptUrl, traceMap);
|
|
13542
13684
|
}
|
|
@@ -13563,7 +13705,7 @@ var createSourcemapResolver = (options = {}) => {
|
|
|
13563
13705
|
};
|
|
13564
13706
|
return { resolve: resolve2, clear };
|
|
13565
13707
|
};
|
|
13566
|
-
var loadTraceMap = async (scriptUrl, tailBytes) => {
|
|
13708
|
+
var loadTraceMap = async (scriptUrl, tailBytes, fetchScript) => {
|
|
13567
13709
|
const tail = await fetchScript(scriptUrl, tailBytes);
|
|
13568
13710
|
if (!tail) {
|
|
13569
13711
|
return null;
|
|
@@ -13585,14 +13727,6 @@ var loadTraceMap = async (scriptUrl, tailBytes) => {
|
|
|
13585
13727
|
}
|
|
13586
13728
|
return new TraceMap(rawMap, reference.url);
|
|
13587
13729
|
};
|
|
13588
|
-
var fetchScript = async (scriptUrl, tailBytes) => {
|
|
13589
|
-
const init = tailBytes ? { headers: { Range: `bytes=-${tailBytes}` } } : undefined;
|
|
13590
|
-
const response = await fetch(scriptUrl, init);
|
|
13591
|
-
if (!response.ok) {
|
|
13592
|
-
return null;
|
|
13593
|
-
}
|
|
13594
|
-
return { text: await response.text(), partial: response.status === 206 };
|
|
13595
|
-
};
|
|
13596
13730
|
var fetchSourcemap = async (mapUrl) => {
|
|
13597
13731
|
const response = await fetch(mapUrl);
|
|
13598
13732
|
if (!response.ok) {
|
|
@@ -16211,7 +16345,7 @@ var formatArgs = (args) => {
|
|
|
16211
16345
|
|
|
16212
16346
|
// ../argus-watcher/dist/cdp/watcherTargets.js
|
|
16213
16347
|
var findTarget = async (chrome, match) => {
|
|
16214
|
-
const targets = await
|
|
16348
|
+
const targets = await fetchCdpTargets(chrome);
|
|
16215
16349
|
if (targets.length === 0) {
|
|
16216
16350
|
throw new Error("No CDP targets available");
|
|
16217
16351
|
}
|
|
@@ -16268,8 +16402,9 @@ var matchesTarget = (target, match, targetById, urlRegex2, titleRegex) => {
|
|
|
16268
16402
|
}
|
|
16269
16403
|
return true;
|
|
16270
16404
|
};
|
|
16271
|
-
var
|
|
16272
|
-
|
|
16405
|
+
var TARGET_LIST_TIMEOUT_MS = 5000;
|
|
16406
|
+
var fetchCdpTargets = async (chrome, timeoutMs = TARGET_LIST_TIMEOUT_MS) => {
|
|
16407
|
+
const response = await fetch(`http://${chrome.host}:${chrome.port}/json`, { signal: AbortSignal.timeout(timeoutMs) });
|
|
16273
16408
|
if (!response.ok) {
|
|
16274
16409
|
throw new Error(`Failed to fetch CDP targets (status ${response.status})`);
|
|
16275
16410
|
}
|
|
@@ -16313,6 +16448,12 @@ var startCdpWatcher = (options) => {
|
|
|
16313
16448
|
socket.close();
|
|
16314
16449
|
}
|
|
16315
16450
|
};
|
|
16451
|
+
const reconnect = () => {
|
|
16452
|
+
if (stopped) {
|
|
16453
|
+
return;
|
|
16454
|
+
}
|
|
16455
|
+
socket?.close();
|
|
16456
|
+
};
|
|
16316
16457
|
runLoop();
|
|
16317
16458
|
session2.onEvent("Runtime.consoleAPICalled", (params) => {
|
|
16318
16459
|
if (!currentTarget) {
|
|
@@ -16345,6 +16486,7 @@ var startCdpWatcher = (options) => {
|
|
|
16345
16486
|
});
|
|
16346
16487
|
return {
|
|
16347
16488
|
stop,
|
|
16489
|
+
reconnect,
|
|
16348
16490
|
session: session2,
|
|
16349
16491
|
getTarget: () => currentTarget ? { ...currentTarget } : null
|
|
16350
16492
|
};
|
|
@@ -16534,9 +16676,29 @@ var createCdpSource = (options) => {
|
|
|
16534
16676
|
pageUrl: target?.url ?? null
|
|
16535
16677
|
};
|
|
16536
16678
|
},
|
|
16679
|
+
healthChecks: {
|
|
16680
|
+
checkTransport: () => checkCdpTransport(chrome, watcher2),
|
|
16681
|
+
onTargetGone: watcher2.reconnect
|
|
16682
|
+
},
|
|
16537
16683
|
stop: watcher2.stop
|
|
16538
16684
|
};
|
|
16539
16685
|
};
|
|
16686
|
+
var checkCdpTransport = async (chrome, watcher2) => {
|
|
16687
|
+
let targets;
|
|
16688
|
+
try {
|
|
16689
|
+
targets = await fetchCdpTargets(chrome, CDP_HEALTH_PROBE_TIMEOUT_MS);
|
|
16690
|
+
} catch (error) {
|
|
16691
|
+
return { state: "unreachable", detail: `${chrome.host}:${chrome.port}: ${formatError(error)}` };
|
|
16692
|
+
}
|
|
16693
|
+
const target = watcher2.getTarget();
|
|
16694
|
+
if (!target) {
|
|
16695
|
+
return { state: "target_gone", detail: "the watcher holds no target" };
|
|
16696
|
+
}
|
|
16697
|
+
if (!targets.some((candidate) => candidate.id === target.id)) {
|
|
16698
|
+
return { state: "target_gone", detail: `Chrome no longer lists target ${target.id} (${target.url})` };
|
|
16699
|
+
}
|
|
16700
|
+
return { state: "ok" };
|
|
16701
|
+
};
|
|
16540
16702
|
|
|
16541
16703
|
// ../argus-watcher/dist/native-messaging/messaging.js
|
|
16542
16704
|
var createNativeMessaging = () => {
|
|
@@ -18231,6 +18393,13 @@ var createWatcherHandle = async (options, watcherId) => {
|
|
|
18231
18393
|
};
|
|
18232
18394
|
}
|
|
18233
18395
|
});
|
|
18396
|
+
const diagnoseCdp = () => diagnoseCdpHealth({
|
|
18397
|
+
watcherId,
|
|
18398
|
+
isAttached: () => sourceHandle.session.isAttached(),
|
|
18399
|
+
probeRenderer: createSessionRendererProbe(sourceHandle.session),
|
|
18400
|
+
getBlockingDialog: () => dialogTracker.getActive(),
|
|
18401
|
+
...sourceHandle.healthChecks
|
|
18402
|
+
});
|
|
18234
18403
|
const dialogSession = getPageSession();
|
|
18235
18404
|
dialogSession.onEvent("Page.javascriptDialogOpening", (params) => {
|
|
18236
18405
|
const dialog2 = parseDialogStatus(params);
|
|
@@ -18263,6 +18432,7 @@ var createWatcherHandle = async (options, watcherId) => {
|
|
|
18263
18432
|
throttleController,
|
|
18264
18433
|
visibilityController,
|
|
18265
18434
|
netMockController,
|
|
18435
|
+
diagnoseCdp,
|
|
18266
18436
|
getNetFilterContext: sourceHandle.getNetFilterContext,
|
|
18267
18437
|
readBrowserCookies: sourceHandle.readBrowserCookies,
|
|
18268
18438
|
sourceHandle: sourceMode === "extension" ? sourceHandle : undefined,
|
|
@@ -19973,7 +20143,7 @@ var resolveAttachedTarget = async (options, output) => {
|
|
|
19973
20143
|
try {
|
|
19974
20144
|
status2 = await fetchJson(statusUrl, { timeoutMs: 2000 });
|
|
19975
20145
|
} catch (error) {
|
|
19976
|
-
output.writeWarn(
|
|
20146
|
+
output.writeWarn(formatWatcherTransportError(resolved.watcher, error));
|
|
19977
20147
|
process.exitCode = 1;
|
|
19978
20148
|
return null;
|
|
19979
20149
|
}
|
|
@@ -20898,19 +21068,21 @@ import fs10 from "node:fs/promises";
|
|
|
20898
21068
|
import path14 from "node:path";
|
|
20899
21069
|
|
|
20900
21070
|
// dist/eval/evalClient.js
|
|
20901
|
-
var
|
|
21071
|
+
var DEFAULT_EVAL_TIMEOUT_MS = 1e4;
|
|
21072
|
+
var REQUEST_TIMEOUT_GRACE_MS = 8000;
|
|
20902
21073
|
var MIN_SUGGESTED_TIMEOUT_MS = 60000;
|
|
20903
21074
|
var evalOnce = async (input) => {
|
|
21075
|
+
const evalTimeoutMs = input.timeoutMs ?? DEFAULT_EVAL_TIMEOUT_MS;
|
|
20904
21076
|
const body = {
|
|
20905
21077
|
expression: input.expression,
|
|
20906
21078
|
args: input.args,
|
|
20907
21079
|
awaitPromise: input.awaitPromise,
|
|
20908
21080
|
replMode: input.replMode,
|
|
20909
21081
|
returnByValue: input.returnByValue,
|
|
20910
|
-
timeoutMs:
|
|
21082
|
+
timeoutMs: evalTimeoutMs,
|
|
20911
21083
|
scenario: input.scenario
|
|
20912
21084
|
};
|
|
20913
|
-
const requestTimeoutMs =
|
|
21085
|
+
const requestTimeoutMs = evalTimeoutMs + REQUEST_TIMEOUT_GRACE_MS;
|
|
20914
21086
|
let response;
|
|
20915
21087
|
try {
|
|
20916
21088
|
response = await fetchWatcherJson(input.watcher, {
|
|
@@ -20938,11 +21110,11 @@ var evalOnce = async (input) => {
|
|
|
20938
21110
|
};
|
|
20939
21111
|
var formatEvalTransportError = (watcher2, error, timeoutMs) => {
|
|
20940
21112
|
const baseMessage = formatWatcherTransportError(watcher2, error);
|
|
20941
|
-
if (!isTimeoutError(error)) {
|
|
21113
|
+
if (classifyWatcherFailure(error) === "api-rejection" || !isTimeoutError(error)) {
|
|
20942
21114
|
return baseMessage;
|
|
20943
21115
|
}
|
|
20944
|
-
const suggestedTimeoutMs = Math.max(MIN_SUGGESTED_TIMEOUT_MS, (timeoutMs ??
|
|
20945
|
-
return `${baseMessage}. ` + `
|
|
21116
|
+
const suggestedTimeoutMs = Math.max(MIN_SUGGESTED_TIMEOUT_MS, (timeoutMs ?? DEFAULT_EVAL_TIMEOUT_MS) * 2);
|
|
21117
|
+
return `${baseMessage}. ` + `The watcher did not answer at all, so it may be unresponsive rather than slow: check \`argus watcher status ${watcher2.id}\` ` + `and \`argus doctor\`. If the watcher is healthy, the expression needs more time; pass a longer timeout as milliseconds or a ` + `duration, for example: \`argus eval ${watcher2.id} --timeout ${formatSuggestedDuration(suggestedTimeoutMs)} ...\``;
|
|
20946
21118
|
};
|
|
20947
21119
|
var isTimeoutError = (error) => {
|
|
20948
21120
|
const message = formatError(error);
|
|
@@ -48313,9 +48485,12 @@ var runDomKeydown = defineWatcherCommand({
|
|
|
48313
48485
|
formatHuman: (response, { options, output }) => {
|
|
48314
48486
|
if (options.printEvent) {
|
|
48315
48487
|
output.writeHuman(`Dispatched keydown event: ${JSON.stringify(response.event)}`);
|
|
48316
|
-
|
|
48488
|
+
} else {
|
|
48489
|
+
output.writeHuman(`Dispatched keydown: ${response.key} (code=${response.code})`);
|
|
48490
|
+
}
|
|
48491
|
+
if (response.activated) {
|
|
48492
|
+
output.writeHuman("Page was hidden and has been activated (as `argus page show`); release it with `argus page hide`.");
|
|
48317
48493
|
}
|
|
48318
|
-
output.writeHuman(`Dispatched keydown: ${response.key} (code=${response.code})`);
|
|
48319
48494
|
}
|
|
48320
48495
|
});
|
|
48321
48496
|
|
|
@@ -48678,7 +48853,7 @@ var buildScreenshotPlan = (options, output) => {
|
|
|
48678
48853
|
path: "/screenshot",
|
|
48679
48854
|
method: "POST",
|
|
48680
48855
|
body: {
|
|
48681
|
-
outFile: options.out,
|
|
48856
|
+
outFile: resolveArtifactOutFile(options.out),
|
|
48682
48857
|
selector,
|
|
48683
48858
|
clip,
|
|
48684
48859
|
format: "png"
|
|
@@ -48800,7 +48975,7 @@ var snapshotCommands = [
|
|
|
48800
48975
|
description: "Capture a screenshot to disk on the watcher",
|
|
48801
48976
|
arguments: [{ flags: "[id]", description: "Watcher id to query" }],
|
|
48802
48977
|
options: [
|
|
48803
|
-
{ flags: "--out <file>", description: "Output file path (absolute or relative to
|
|
48978
|
+
{ flags: "--out <file>", description: "Output file path (absolute, or relative to the current working directory)" },
|
|
48804
48979
|
{ flags: "--selector <selector>", description: "Optional CSS selector for element-only capture" },
|
|
48805
48980
|
{ flags: "--clip <x,y,width,height>", description: "Viewport-relative rectangle crop in CSS pixels" },
|
|
48806
48981
|
{ flags: "--testid <id>", description: `Shorthand for --selector "[data-testid='<id>']"` },
|
|
@@ -48915,7 +49090,7 @@ var buildRecordStopPlan = (options, output) => {
|
|
|
48915
49090
|
method: "POST",
|
|
48916
49091
|
body: {
|
|
48917
49092
|
recordId: normalizeString2(options.recordId),
|
|
48918
|
-
outFile: options.out
|
|
49093
|
+
outFile: resolveArtifactOutFile(options.out)
|
|
48919
49094
|
},
|
|
48920
49095
|
timeoutMs: RECORD_STOP_TIMEOUT_MS
|
|
48921
49096
|
};
|
|
@@ -48939,7 +49114,7 @@ var buildRecordBody = (options, output) => {
|
|
|
48939
49114
|
return null;
|
|
48940
49115
|
}
|
|
48941
49116
|
return {
|
|
48942
|
-
outFile: options.out,
|
|
49117
|
+
outFile: resolveArtifactOutFile(options.out),
|
|
48943
49118
|
selector,
|
|
48944
49119
|
clip,
|
|
48945
49120
|
fps,
|
|
@@ -49064,7 +49239,7 @@ var recordCommands = [
|
|
|
49064
49239
|
arguments: [{ flags: "[id]", description: "Watcher id to query" }],
|
|
49065
49240
|
options: [
|
|
49066
49241
|
{ flags: "--duration <duration>", description: "Capture for duration (e.g. 3s, 500ms)" },
|
|
49067
|
-
{ flags: "--out <file>", description: "Output .mp4 or .webm path (absolute or relative to
|
|
49242
|
+
{ flags: "--out <file>", description: "Output .mp4 or .webm path (absolute, or relative to the current working directory)" },
|
|
49068
49243
|
{ flags: "--selector <selector>", description: "Optional CSS selector for element-only recording" },
|
|
49069
49244
|
{ flags: "--clip <x,y,width,height>", description: "Viewport-relative rectangle crop in CSS pixels" },
|
|
49070
49245
|
{ flags: "--testid <id>", description: `Shorthand for --selector "[data-testid='<id>']"` },
|
|
@@ -49089,7 +49264,7 @@ var recordCommands = [
|
|
|
49089
49264
|
description: "Start a silent video recording",
|
|
49090
49265
|
arguments: [{ flags: "[id]", description: "Watcher id to query" }],
|
|
49091
49266
|
options: [
|
|
49092
|
-
{ flags: "--out <file>", description: "Output .mp4 or .webm path (absolute or relative to
|
|
49267
|
+
{ flags: "--out <file>", description: "Output .mp4 or .webm path (absolute, or relative to the current working directory)" },
|
|
49093
49268
|
{ flags: "--selector <selector>", description: "Optional CSS selector for element-only recording" },
|
|
49094
49269
|
{ flags: "--clip <x,y,width,height>", description: "Viewport-relative rectangle crop in CSS pixels" },
|
|
49095
49270
|
{ flags: "--testid <id>", description: `Shorthand for --selector "[data-testid='<id>']"` },
|
|
@@ -49110,7 +49285,10 @@ var recordCommands = [
|
|
|
49110
49285
|
arguments: [{ flags: "[id]", description: "Watcher id to query" }],
|
|
49111
49286
|
options: [
|
|
49112
49287
|
{ flags: "--record-id <id>", description: "Record id returned from start" },
|
|
49113
|
-
{
|
|
49288
|
+
{
|
|
49289
|
+
flags: "--out <file>",
|
|
49290
|
+
description: "Move the saved recording to this .mp4 or .webm path (absolute, or relative to the current working directory)"
|
|
49291
|
+
},
|
|
49114
49292
|
jsonOption
|
|
49115
49293
|
],
|
|
49116
49294
|
examples: ["argus record stop app", "argus record stop app --out demo.mp4 --json"],
|
|
@@ -49193,7 +49371,7 @@ var runTraceStartInternal = async (watcher2, options, output) => {
|
|
|
49193
49371
|
path: "/trace/start",
|
|
49194
49372
|
method: "POST",
|
|
49195
49373
|
body: {
|
|
49196
|
-
outFile: options.out,
|
|
49374
|
+
outFile: resolveArtifactOutFile(options.out),
|
|
49197
49375
|
categories: options.categories,
|
|
49198
49376
|
options: options.options
|
|
49199
49377
|
},
|
|
@@ -49211,7 +49389,7 @@ var runTraceStopInternal = async (watcher2, options, output) => {
|
|
|
49211
49389
|
const response = await fetchWatcherJson(watcher2, {
|
|
49212
49390
|
path: "/trace/stop",
|
|
49213
49391
|
method: "POST",
|
|
49214
|
-
body: { traceId: options.traceId, outFile: options.outFile },
|
|
49392
|
+
body: { traceId: options.traceId, outFile: resolveArtifactOutFile(options.outFile) },
|
|
49215
49393
|
timeoutMs: 20000
|
|
49216
49394
|
});
|
|
49217
49395
|
return response;
|
|
@@ -49231,7 +49409,7 @@ var traceCommands = [
|
|
|
49231
49409
|
arguments: [{ flags: "[id]", description: "Watcher id to query" }],
|
|
49232
49410
|
options: [
|
|
49233
49411
|
{ flags: "--duration <duration>", description: "Capture for duration (e.g. 3s, 500ms)" },
|
|
49234
|
-
{ flags: "--out <file>", description: "Output trace file path (relative to
|
|
49412
|
+
{ flags: "--out <file>", description: "Output trace file path (absolute, or relative to the current working directory)" },
|
|
49235
49413
|
{ flags: "--categories <categories>", description: "Comma-separated tracing categories" },
|
|
49236
49414
|
{ flags: "--options <options>", description: "Tracing options string" },
|
|
49237
49415
|
jsonOption
|
|
@@ -49246,7 +49424,7 @@ var traceCommands = [
|
|
|
49246
49424
|
description: "Start Chrome tracing",
|
|
49247
49425
|
arguments: [{ flags: "[id]", description: "Watcher id to query" }],
|
|
49248
49426
|
options: [
|
|
49249
|
-
{ flags: "--out <file>", description: "Output trace file path (relative to
|
|
49427
|
+
{ flags: "--out <file>", description: "Output trace file path (absolute, or relative to the current working directory)" },
|
|
49250
49428
|
{ flags: "--categories <categories>", description: "Comma-separated tracing categories" },
|
|
49251
49429
|
{ flags: "--options <options>", description: "Tracing options string" },
|
|
49252
49430
|
jsonOption
|
|
@@ -49262,7 +49440,10 @@ var traceCommands = [
|
|
|
49262
49440
|
arguments: [{ flags: "[id]", description: "Watcher id to query" }],
|
|
49263
49441
|
options: [
|
|
49264
49442
|
{ flags: "--trace-id <id>", description: "Trace id returned from start" },
|
|
49265
|
-
{
|
|
49443
|
+
{
|
|
49444
|
+
flags: "--out <file>",
|
|
49445
|
+
description: "Move the saved trace file to this path (absolute, or relative to the current working directory)"
|
|
49446
|
+
},
|
|
49266
49447
|
jsonOption
|
|
49267
49448
|
],
|
|
49268
49449
|
examples: ["argus trace stop app", "argus trace stop app --out trace.json --json"],
|
|
@@ -51238,7 +51419,7 @@ var resolveAutoIframe = (iframes, allTargets) => {
|
|
|
51238
51419
|
};
|
|
51239
51420
|
var scoreIframeTarget = (target, page) => {
|
|
51240
51421
|
let score = 0;
|
|
51241
|
-
if (
|
|
51422
|
+
if (originOf2(target.url) && originOf2(target.url) !== originOf2(page?.url)) {
|
|
51242
51423
|
score += 4;
|
|
51243
51424
|
}
|
|
51244
51425
|
if (target.title && target.title !== target.url && !target.title.startsWith("http")) {
|
|
@@ -51290,7 +51471,7 @@ var statusMatchesTarget = (status2, target) => {
|
|
|
51290
51471
|
return Boolean(status2.target.title && status2.target.title === target.title && status2.target.url === target.url);
|
|
51291
51472
|
};
|
|
51292
51473
|
var includesIgnoreCase = (value, needle) => value.toLowerCase().includes(needle.toLowerCase());
|
|
51293
|
-
var
|
|
51474
|
+
var originOf2 = (url) => {
|
|
51294
51475
|
if (!url) {
|
|
51295
51476
|
return null;
|
|
51296
51477
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"recordCommands.d.ts","sourceRoot":"","sources":["../../../src/cli/register/recordCommands.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,qBAAqB,CAAA;AAKjE,eAAO,MAAM,cAAc,EAAE,SAAS,sBAAsB,
|
|
1
|
+
{"version":3,"file":"recordCommands.d.ts","sourceRoot":"","sources":["../../../src/cli/register/recordCommands.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,qBAAqB,CAAA;AAKjE,eAAO,MAAM,cAAc,EAAE,SAAS,sBAAsB,EAgE3D,CAAA"}
|
|
@@ -8,7 +8,7 @@ export const recordCommands = [
|
|
|
8
8
|
arguments: [{ flags: '[id]', description: 'Watcher id to query' }],
|
|
9
9
|
options: [
|
|
10
10
|
{ flags: '--duration <duration>', description: 'Capture for duration (e.g. 3s, 500ms)' },
|
|
11
|
-
{ flags: '--out <file>', description: 'Output .mp4 or .webm path (absolute or relative to
|
|
11
|
+
{ flags: '--out <file>', description: 'Output .mp4 or .webm path (absolute, or relative to the current working directory)' },
|
|
12
12
|
{ flags: '--selector <selector>', description: 'Optional CSS selector for element-only recording' },
|
|
13
13
|
{ flags: '--clip <x,y,width,height>', description: 'Viewport-relative rectangle crop in CSS pixels' },
|
|
14
14
|
{ flags: '--testid <id>', description: 'Shorthand for --selector "[data-testid=\'<id>\']"' },
|
|
@@ -33,7 +33,7 @@ export const recordCommands = [
|
|
|
33
33
|
description: 'Start a silent video recording',
|
|
34
34
|
arguments: [{ flags: '[id]', description: 'Watcher id to query' }],
|
|
35
35
|
options: [
|
|
36
|
-
{ flags: '--out <file>', description: 'Output .mp4 or .webm path (absolute or relative to
|
|
36
|
+
{ flags: '--out <file>', description: 'Output .mp4 or .webm path (absolute, or relative to the current working directory)' },
|
|
37
37
|
{ flags: '--selector <selector>', description: 'Optional CSS selector for element-only recording' },
|
|
38
38
|
{ flags: '--clip <x,y,width,height>', description: 'Viewport-relative rectangle crop in CSS pixels' },
|
|
39
39
|
{ flags: '--testid <id>', description: 'Shorthand for --selector "[data-testid=\'<id>\']"' },
|
|
@@ -54,7 +54,10 @@ export const recordCommands = [
|
|
|
54
54
|
arguments: [{ flags: '[id]', description: 'Watcher id to query' }],
|
|
55
55
|
options: [
|
|
56
56
|
{ flags: '--record-id <id>', description: 'Record id returned from start' },
|
|
57
|
-
{
|
|
57
|
+
{
|
|
58
|
+
flags: '--out <file>',
|
|
59
|
+
description: 'Move the saved recording to this .mp4 or .webm path (absolute, or relative to the current working directory)',
|
|
60
|
+
},
|
|
58
61
|
jsonOption,
|
|
59
62
|
],
|
|
60
63
|
examples: ['argus record stop app', 'argus record stop app --out demo.mp4 --json'],
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"recordCommands.js","sourceRoot":"","sources":["../../../src/cli/register/recordCommands.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAE,MAAM,iCAAiC,CAAA;AAC/D,OAAO,EAAE,SAAS,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAA;AACnF,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAA;AAE/C,MAAM,CAAC,MAAM,cAAc,GAAsC;IAChE;QACC,IAAI,EAAE,QAAQ;QACd,WAAW,EAAE,yDAAyD;QACtE,SAAS,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,WAAW,EAAE,qBAAqB,EAAE,CAAC;QAClE,OAAO,EAAE;YACR,EAAE,KAAK,EAAE,uBAAuB,EAAE,WAAW,EAAE,uCAAuC,EAAE;YACxF,EAAE,KAAK,EAAE,cAAc,EAAE,WAAW,EAAE,
|
|
1
|
+
{"version":3,"file":"recordCommands.js","sourceRoot":"","sources":["../../../src/cli/register/recordCommands.ts"],"names":[],"mappings":"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"}
|
|
@@ -8,7 +8,7 @@ export const snapshotCommands = [
|
|
|
8
8
|
description: 'Capture a screenshot to disk on the watcher',
|
|
9
9
|
arguments: [{ flags: '[id]', description: 'Watcher id to query' }],
|
|
10
10
|
options: [
|
|
11
|
-
{ flags: '--out <file>', description: 'Output file path (absolute or relative to
|
|
11
|
+
{ flags: '--out <file>', description: 'Output file path (absolute, or relative to the current working directory)' },
|
|
12
12
|
{ flags: '--selector <selector>', description: 'Optional CSS selector for element-only capture' },
|
|
13
13
|
{ flags: '--clip <x,y,width,height>', description: 'Viewport-relative rectangle crop in CSS pixels' },
|
|
14
14
|
{ flags: '--testid <id>', description: 'Shorthand for --selector "[data-testid=\'<id>\']"' },
|