@vforsh/argus 0.1.14 → 0.1.16
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 +1861 -1171
- package/dist/cli/defineWatcherCommand.d.ts +17 -0
- package/dist/cli/defineWatcherCommand.d.ts.map +1 -1
- package/dist/cli/defineWatcherCommand.js +19 -2
- package/dist/cli/defineWatcherCommand.js.map +1 -1
- package/dist/cli/plugins/pluginAliases.d.ts +6 -0
- package/dist/cli/plugins/pluginAliases.d.ts.map +1 -0
- package/dist/cli/plugins/pluginAliases.js +10 -0
- package/dist/cli/plugins/pluginAliases.js.map +1 -0
- package/dist/cli/plugins/pluginHost.d.ts +3 -0
- package/dist/cli/plugins/pluginHost.d.ts.map +1 -0
- package/dist/cli/plugins/pluginHost.js +30 -0
- package/dist/cli/plugins/pluginHost.js.map +1 -0
- package/dist/cli/plugins/registerPlugins.d.ts +32 -1
- package/dist/cli/plugins/registerPlugins.d.ts.map +1 -1
- package/dist/cli/plugins/registerPlugins.js +102 -12
- package/dist/cli/plugins/registerPlugins.js.map +1 -1
- package/dist/cli/program.d.ts.map +1 -1
- package/dist/cli/program.js +2 -0
- package/dist/cli/program.js.map +1 -1
- package/dist/cli/register/index.d.ts.map +1 -1
- package/dist/cli/register/index.js +2 -0
- package/dist/cli/register/index.js.map +1 -1
- package/dist/cli/register/registerAuth.d.ts.map +1 -1
- package/dist/cli/register/registerAuth.js +13 -8
- package/dist/cli/register/registerAuth.js.map +1 -1
- package/dist/cli/register/registerEval.d.ts.map +1 -1
- package/dist/cli/register/registerEval.js +12 -0
- package/dist/cli/register/registerEval.js.map +1 -1
- package/dist/cli/register/registerExtension.d.ts.map +1 -1
- package/dist/cli/register/registerExtension.js +24 -1
- package/dist/cli/register/registerExtension.js.map +1 -1
- package/dist/cli/register/registerPlugin.d.ts +3 -0
- package/dist/cli/register/registerPlugin.d.ts.map +1 -0
- package/dist/cli/register/registerPlugin.js +34 -0
- package/dist/cli/register/registerPlugin.js.map +1 -0
- package/dist/cli/register/registerWatcher.d.ts.map +1 -1
- package/dist/cli/register/registerWatcher.js +1 -0
- package/dist/cli/register/registerWatcher.js.map +1 -1
- package/dist/commands/auth.d.ts.map +1 -1
- package/dist/commands/auth.js +4 -9
- package/dist/commands/auth.js.map +1 -1
- package/dist/commands/authCookieSupport.d.ts.map +1 -1
- package/dist/commands/authCookieSupport.js +4 -6
- package/dist/commands/authCookieSupport.js.map +1 -1
- package/dist/commands/authCookies.d.ts +4 -4
- package/dist/commands/authCookies.d.ts.map +1 -1
- package/dist/commands/authCookies.js +85 -105
- package/dist/commands/authCookies.js.map +1 -1
- package/dist/commands/code.js +3 -25
- package/dist/commands/code.js.map +1 -1
- package/dist/commands/codeEdit.js +3 -3
- package/dist/commands/codeEdit.js.map +1 -1
- package/dist/commands/configInit.d.ts.map +1 -1
- package/dist/commands/configInit.js +1 -0
- package/dist/commands/configInit.js.map +1 -1
- package/dist/commands/domAdd.d.ts +1 -1
- package/dist/commands/domAdd.d.ts.map +1 -1
- package/dist/commands/domAdd.js +26 -30
- package/dist/commands/domAdd.js.map +1 -1
- package/dist/commands/domInfo.d.ts +1 -1
- package/dist/commands/domInfo.d.ts.map +1 -1
- package/dist/commands/domInfo.js +18 -23
- package/dist/commands/domInfo.js.map +1 -1
- package/dist/commands/domKeydown.d.ts +1 -1
- package/dist/commands/domKeydown.d.ts.map +1 -1
- package/dist/commands/domKeydown.js +22 -43
- package/dist/commands/domKeydown.js.map +1 -1
- package/dist/commands/domModify.js +27 -30
- package/dist/commands/domModify.js.map +1 -1
- package/dist/commands/domScroll.d.ts +1 -1
- package/dist/commands/domScroll.d.ts.map +1 -1
- package/dist/commands/domScroll.js +18 -24
- package/dist/commands/domScroll.js.map +1 -1
- package/dist/commands/domScrollTo.d.ts +1 -1
- package/dist/commands/domScrollTo.d.ts.map +1 -1
- package/dist/commands/domScrollTo.js +15 -24
- package/dist/commands/domScrollTo.js.map +1 -1
- package/dist/commands/domTree.d.ts +1 -1
- package/dist/commands/domTree.d.ts.map +1 -1
- package/dist/commands/domTree.js +18 -24
- package/dist/commands/domTree.js.map +1 -1
- package/dist/commands/eval.d.ts +4 -0
- package/dist/commands/eval.d.ts.map +1 -1
- package/dist/commands/eval.js +43 -62
- package/dist/commands/eval.js.map +1 -1
- package/dist/commands/evalBundle.d.ts +17 -0
- package/dist/commands/evalBundle.d.ts.map +1 -0
- package/dist/commands/evalBundle.js +119 -0
- package/dist/commands/evalBundle.js.map +1 -0
- package/dist/commands/evalPolling.d.ts +55 -0
- package/dist/commands/evalPolling.d.ts.map +1 -0
- package/dist/commands/evalPolling.js +59 -0
- package/dist/commands/evalPolling.js.map +1 -0
- package/dist/commands/evalShared.d.ts +14 -0
- package/dist/commands/evalShared.d.ts.map +1 -1
- package/dist/commands/evalShared.js +75 -10
- package/dist/commands/evalShared.js.map +1 -1
- package/dist/commands/evalUntil.d.ts +4 -0
- package/dist/commands/evalUntil.d.ts.map +1 -1
- package/dist/commands/evalUntil.js +47 -70
- package/dist/commands/evalUntil.js.map +1 -1
- package/dist/commands/extension/attach.d.ts +12 -0
- package/dist/commands/extension/attach.d.ts.map +1 -0
- package/dist/commands/extension/attach.js +175 -0
- package/dist/commands/extension/attach.js.map +1 -0
- package/dist/commands/extension/info.d.ts.map +1 -1
- package/dist/commands/extension/info.js +13 -33
- package/dist/commands/extension/info.js.map +1 -1
- package/dist/commands/extension/nativeHost.d.ts +35 -5
- package/dist/commands/extension/nativeHost.d.ts.map +1 -1
- package/dist/commands/extension/nativeHost.js +95 -12
- package/dist/commands/extension/nativeHost.js.map +1 -1
- package/dist/commands/extension/remove.d.ts.map +1 -1
- package/dist/commands/extension/remove.js +18 -38
- package/dist/commands/extension/remove.js.map +1 -1
- package/dist/commands/extension/resolveExtensionWatcher.d.ts +1 -1
- package/dist/commands/extension/resolveExtensionWatcher.d.ts.map +1 -1
- package/dist/commands/extension/resolveExtensionWatcher.js +15 -29
- package/dist/commands/extension/resolveExtensionWatcher.js.map +1 -1
- package/dist/commands/extension/setup.d.ts.map +1 -1
- package/dist/commands/extension/setup.js +20 -35
- package/dist/commands/extension/setup.js.map +1 -1
- package/dist/commands/extension/status.d.ts.map +1 -1
- package/dist/commands/extension/status.js +12 -38
- package/dist/commands/extension/status.js.map +1 -1
- package/dist/commands/locate.js +2 -2
- package/dist/commands/locate.js.map +1 -1
- package/dist/commands/logs.d.ts +1 -1
- package/dist/commands/logs.d.ts.map +1 -1
- package/dist/commands/logs.js +18 -27
- package/dist/commands/logs.js.map +1 -1
- package/dist/commands/net.d.ts +1 -1
- package/dist/commands/net.d.ts.map +1 -1
- package/dist/commands/net.js +14 -19
- package/dist/commands/net.js.map +1 -1
- package/dist/commands/netClear.d.ts +1 -1
- package/dist/commands/netClear.d.ts.map +1 -1
- package/dist/commands/netClear.js +7 -19
- package/dist/commands/netClear.js.map +1 -1
- package/dist/commands/netSse.js +2 -2
- package/dist/commands/netSse.js.map +1 -1
- package/dist/commands/netWebSocket.js +3 -3
- package/dist/commands/netWebSocket.js.map +1 -1
- package/dist/commands/pageEmulation.d.ts +3 -3
- package/dist/commands/pageEmulation.d.ts.map +1 -1
- package/dist/commands/pageEmulation.js +72 -143
- package/dist/commands/pageEmulation.js.map +1 -1
- package/dist/commands/pluginConfig.d.ts +7 -0
- package/dist/commands/pluginConfig.d.ts.map +1 -0
- package/dist/commands/pluginConfig.js +199 -0
- package/dist/commands/pluginConfig.js.map +1 -0
- package/dist/commands/pluginList.d.ts +5 -0
- package/dist/commands/pluginList.d.ts.map +1 -0
- package/dist/commands/pluginList.js +26 -0
- package/dist/commands/pluginList.js.map +1 -0
- package/dist/commands/screenshot.d.ts +1 -1
- package/dist/commands/screenshot.d.ts.map +1 -1
- package/dist/commands/screenshot.js +12 -18
- package/dist/commands/screenshot.js.map +1 -1
- package/dist/commands/watcherNativeHost.d.ts +1 -0
- package/dist/commands/watcherNativeHost.d.ts.map +1 -1
- package/dist/commands/watcherNativeHost.js +8 -2
- package/dist/commands/watcherNativeHost.js.map +1 -1
- package/dist/commands/watcherStatus.d.ts +1 -1
- package/dist/commands/watcherStatus.d.ts.map +1 -1
- package/dist/commands/watcherStatus.js +8 -21
- package/dist/commands/watcherStatus.js.map +1 -1
- package/dist/config/argusConfig.d.ts +5 -0
- package/dist/config/argusConfig.d.ts.map +1 -1
- package/dist/config/argusConfig.js +33 -2
- package/dist/config/argusConfig.js.map +1 -1
- package/package.json +3 -2
- package/schemas/argus.config.schema.json +16 -0
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.1.
|
|
2133
|
+
version: "0.1.16",
|
|
2134
2134
|
repository: {
|
|
2135
2135
|
type: "git",
|
|
2136
2136
|
url: "git+https://github.com/vforsh/argus.git",
|
|
@@ -2158,12 +2158,13 @@ var package_default = {
|
|
|
2158
2158
|
dependencies: {
|
|
2159
2159
|
"@vforsh/argus-plugin-api": "workspace:*",
|
|
2160
2160
|
commander: "14.0.2",
|
|
2161
|
+
esbuild: "0.25.12",
|
|
2161
2162
|
prettier: "3.7.4"
|
|
2162
2163
|
},
|
|
2163
2164
|
scripts: {
|
|
2164
2165
|
clean: "node ../../scripts/clean-dist.mjs",
|
|
2165
2166
|
build: "npm run clean && tsc -b && bun run bundle",
|
|
2166
|
-
bundle: "bun build dist/bin.js --outfile dist/argus.js --target node",
|
|
2167
|
+
bundle: "bun build dist/bin.js --outfile dist/argus.js --target node --external esbuild",
|
|
2167
2168
|
typecheck: "tsc -b --pretty false",
|
|
2168
2169
|
"chrome:start": "bun src/bin.ts chrome start"
|
|
2169
2170
|
}
|
|
@@ -2172,7 +2173,7 @@ var package_default = {
|
|
|
2172
2173
|
// dist/cli/program.js
|
|
2173
2174
|
function createProgram() {
|
|
2174
2175
|
const program2 = new Command;
|
|
2175
|
-
program2.name("argus").description("Argus CLI for local watcher servers").version(package_default.version).configureOutput({
|
|
2176
|
+
program2.name("argus").description("Argus CLI for local watcher servers").version(package_default.version).option("--plugin <specifier>", "Load an extra CLI plugin for this invocation", collectPluginOption, []).configureOutput({
|
|
2176
2177
|
outputError: (str, write) => write(str)
|
|
2177
2178
|
}).showSuggestionAfterError(true).exitOverride((error) => {
|
|
2178
2179
|
if (error.code === "commander.helpDisplayed" || error.code === "commander.version") {
|
|
@@ -2183,6 +2184,7 @@ function createProgram() {
|
|
|
2183
2184
|
});
|
|
2184
2185
|
return program2;
|
|
2185
2186
|
}
|
|
2187
|
+
var collectPluginOption = (value, previous) => [...previous, value];
|
|
2186
2188
|
|
|
2187
2189
|
// ../argus-core/dist/protocol/logs.js
|
|
2188
2190
|
var formatLogLevelTag = (level) => {
|
|
@@ -3311,11 +3313,20 @@ function writeResolveError(resolved, output) {
|
|
|
3311
3313
|
|
|
3312
3314
|
// dist/cli/defineWatcherCommand.js
|
|
3313
3315
|
var DEFAULT_TIMEOUT_MS = 30000;
|
|
3316
|
+
var requestWatcherCommandJson = async (input, output) => {
|
|
3317
|
+
const result = await requestWatcherJson(input);
|
|
3318
|
+
if (!result.ok) {
|
|
3319
|
+
writeRequestError(result, output);
|
|
3320
|
+
return null;
|
|
3321
|
+
}
|
|
3322
|
+
return result;
|
|
3323
|
+
};
|
|
3324
|
+
var requestWatcherCommandAction = requestWatcherAction;
|
|
3314
3325
|
var defineWatcherCommand = (spec) => async (id, ...rest) => {
|
|
3315
3326
|
const tail = rest.length - 1;
|
|
3316
3327
|
const options = rest[tail];
|
|
3317
3328
|
const args = rest.slice(0, tail);
|
|
3318
|
-
const output = createOutput(options);
|
|
3329
|
+
const output = createOutput({ ...options, json: options.json === true || spec.isJson?.(options) === true });
|
|
3319
3330
|
const plan = await spec.build(args, options, output);
|
|
3320
3331
|
if (plan == null)
|
|
3321
3332
|
return;
|
|
@@ -4368,20 +4379,15 @@ var loadAuthStateSnapshot = async (inputPath) => {
|
|
|
4368
4379
|
return parseAuthStateSnapshot(parsed, `auth state ${source}`);
|
|
4369
4380
|
};
|
|
4370
4381
|
var requestAuthStateSnapshot = async (id, input, output) => {
|
|
4371
|
-
|
|
4382
|
+
return requestWatcherCommandJson({
|
|
4372
4383
|
id,
|
|
4373
4384
|
path: "/auth/state",
|
|
4374
4385
|
query: buildStateQuery(input),
|
|
4375
4386
|
timeoutMs: 1e4
|
|
4376
|
-
});
|
|
4377
|
-
if (!result.ok) {
|
|
4378
|
-
writeRequestError(result, output);
|
|
4379
|
-
return null;
|
|
4380
|
-
}
|
|
4381
|
-
return result;
|
|
4387
|
+
}, output);
|
|
4382
4388
|
};
|
|
4383
4389
|
var loadAuthStateIntoWatcher = async (id, snapshot, input, output) => {
|
|
4384
|
-
const result = await
|
|
4390
|
+
const result = await requestWatcherCommandAction({
|
|
4385
4391
|
id,
|
|
4386
4392
|
path: "/auth/state/load",
|
|
4387
4393
|
method: "POST",
|
|
@@ -6427,19 +6433,62 @@ var handle11 = (_req, res, url, ctx) => {
|
|
|
6427
6433
|
respondJson(res, response);
|
|
6428
6434
|
};
|
|
6429
6435
|
|
|
6436
|
+
// ../argus-watcher/dist/http/routes/defineRoute.js
|
|
6437
|
+
var defineJsonRoute = (input) => ({
|
|
6438
|
+
method: input.method,
|
|
6439
|
+
path: input.path,
|
|
6440
|
+
extensionOnly: input.extensionOnly,
|
|
6441
|
+
handler: async (req, res, url, ctx) => {
|
|
6442
|
+
const shouldReadBody = input.bodySchema != null || input.parseBody === true;
|
|
6443
|
+
const rawBody = shouldReadBody ? await readJsonBody(req, res) : undefined;
|
|
6444
|
+
if (shouldReadBody && rawBody == null) {
|
|
6445
|
+
return;
|
|
6446
|
+
}
|
|
6447
|
+
const parsedBody = input.bodySchema?.parse(rawBody);
|
|
6448
|
+
if (parsedBody && !parsedBody.ok) {
|
|
6449
|
+
return respondInvalidBody(res, formatProtocolValidationIssues(parsedBody.issues));
|
|
6450
|
+
}
|
|
6451
|
+
if (input.endpoint) {
|
|
6452
|
+
emitRequest(ctx, res, input.endpoint);
|
|
6453
|
+
}
|
|
6454
|
+
try {
|
|
6455
|
+
const response = await input.handle({
|
|
6456
|
+
req,
|
|
6457
|
+
res,
|
|
6458
|
+
url,
|
|
6459
|
+
ctx,
|
|
6460
|
+
body: parsedBody?.value ?? rawBody
|
|
6461
|
+
});
|
|
6462
|
+
if (response) {
|
|
6463
|
+
respondJson(res, response);
|
|
6464
|
+
}
|
|
6465
|
+
} catch (error) {
|
|
6466
|
+
if (input.handleError?.(res, error)) {
|
|
6467
|
+
return;
|
|
6468
|
+
}
|
|
6469
|
+
respondError(res, error);
|
|
6470
|
+
}
|
|
6471
|
+
}
|
|
6472
|
+
});
|
|
6473
|
+
|
|
6430
6474
|
// ../argus-watcher/dist/http/routes/postNetClear.js
|
|
6431
|
-
var handle12 = (
|
|
6432
|
-
|
|
6433
|
-
|
|
6475
|
+
var handle12 = defineJsonRoute({
|
|
6476
|
+
method: "POST",
|
|
6477
|
+
path: "/net/clear",
|
|
6478
|
+
handle: ({ res, ctx }) => {
|
|
6479
|
+
if (!ctx.netBuffer) {
|
|
6480
|
+
respondJson(res, { ok: false, error: { code: "net_disabled", message: "Network capture is disabled for this watcher" } }, 400);
|
|
6481
|
+
return;
|
|
6482
|
+
}
|
|
6483
|
+
emitRequest(ctx, res, "net/clear");
|
|
6484
|
+
const realtimeCleared = ctx.realtimeNetBuffer?.clear() ?? 0;
|
|
6485
|
+
const response = {
|
|
6486
|
+
ok: true,
|
|
6487
|
+
cleared: ctx.netBuffer.clear() + realtimeCleared
|
|
6488
|
+
};
|
|
6489
|
+
return response;
|
|
6434
6490
|
}
|
|
6435
|
-
|
|
6436
|
-
const realtimeCleared = ctx.realtimeNetBuffer?.clear() ?? 0;
|
|
6437
|
-
const response = {
|
|
6438
|
-
ok: true,
|
|
6439
|
-
cleared: ctx.netBuffer.clear() + realtimeCleared
|
|
6440
|
-
};
|
|
6441
|
-
respondJson(res, response);
|
|
6442
|
-
};
|
|
6491
|
+
}).handler;
|
|
6443
6492
|
|
|
6444
6493
|
// ../argus-watcher/dist/cdp/auth.js
|
|
6445
6494
|
var inspectAuthCookies = async (session, options) => {
|
|
@@ -7304,23 +7353,19 @@ var handle18 = async (req, res, _url, ctx) => {
|
|
|
7304
7353
|
};
|
|
7305
7354
|
|
|
7306
7355
|
// ../argus-watcher/dist/http/routes/postScreenshot.js
|
|
7307
|
-
var handle19 =
|
|
7308
|
-
|
|
7309
|
-
|
|
7310
|
-
|
|
7311
|
-
}
|
|
7312
|
-
|
|
7313
|
-
|
|
7314
|
-
|
|
7315
|
-
|
|
7316
|
-
|
|
7317
|
-
|
|
7318
|
-
const response = await ctx.screenshotter.capture(payload);
|
|
7319
|
-
respondJson(res, response);
|
|
7320
|
-
} catch (error) {
|
|
7321
|
-
respondError(res, error);
|
|
7356
|
+
var handle19 = defineJsonRoute({
|
|
7357
|
+
method: "POST",
|
|
7358
|
+
path: "/screenshot",
|
|
7359
|
+
parseBody: true,
|
|
7360
|
+
handle: async ({ res, ctx, body: payload }) => {
|
|
7361
|
+
const validationError = validateScreenshotRequest(payload);
|
|
7362
|
+
if (validationError) {
|
|
7363
|
+
return respondInvalidBody(res, validationError);
|
|
7364
|
+
}
|
|
7365
|
+
emitRequest(ctx, res, "screenshot");
|
|
7366
|
+
return ctx.screenshotter.capture(payload);
|
|
7322
7367
|
}
|
|
7323
|
-
};
|
|
7368
|
+
}).handler;
|
|
7324
7369
|
var validateScreenshotRequest = (payload) => {
|
|
7325
7370
|
if (payload.selector != null && (typeof payload.selector !== "string" || !payload.selector.trim())) {
|
|
7326
7371
|
return "selector must be a non-empty string";
|
|
@@ -7825,29 +7870,25 @@ var countNodes = (nodes) => {
|
|
|
7825
7870
|
};
|
|
7826
7871
|
|
|
7827
7872
|
// ../argus-watcher/dist/http/routes/postSnapshot.js
|
|
7828
|
-
var handle20 =
|
|
7829
|
-
|
|
7830
|
-
|
|
7831
|
-
|
|
7832
|
-
}
|
|
7833
|
-
|
|
7834
|
-
|
|
7835
|
-
|
|
7836
|
-
|
|
7837
|
-
|
|
7838
|
-
|
|
7839
|
-
|
|
7840
|
-
|
|
7841
|
-
const response = await fetchAccessibilitySnapshot(ctx.cdpSession, {
|
|
7873
|
+
var handle20 = defineJsonRoute({
|
|
7874
|
+
method: "POST",
|
|
7875
|
+
path: "/snapshot",
|
|
7876
|
+
parseBody: true,
|
|
7877
|
+
handle: async ({ res, ctx, body: payload }) => {
|
|
7878
|
+
if (payload.selector != null && (typeof payload.selector !== "string" || payload.selector.trim() === "")) {
|
|
7879
|
+
return respondInvalidBody(res, "selector must be a non-empty string");
|
|
7880
|
+
}
|
|
7881
|
+
if (payload.depth != null && (!Number.isFinite(payload.depth) || payload.depth < 0 || !Number.isInteger(payload.depth))) {
|
|
7882
|
+
return respondInvalidBody(res, "depth must be a non-negative integer");
|
|
7883
|
+
}
|
|
7884
|
+
emitRequest(ctx, res, "snapshot");
|
|
7885
|
+
return fetchAccessibilitySnapshot(ctx.cdpSession, {
|
|
7842
7886
|
selector: payload.selector,
|
|
7843
7887
|
depth: payload.depth,
|
|
7844
7888
|
interactive: payload.interactive ?? false
|
|
7845
7889
|
}, ctx.elementRefs);
|
|
7846
|
-
respondJson(res, response);
|
|
7847
|
-
} catch (error) {
|
|
7848
|
-
respondError(res, error);
|
|
7849
7890
|
}
|
|
7850
|
-
};
|
|
7891
|
+
}).handler;
|
|
7851
7892
|
|
|
7852
7893
|
// ../argus-watcher/dist/http/routes/domSelectorRoute.js
|
|
7853
7894
|
var readDomTargetPayload = async (req, res) => {
|
|
@@ -8741,43 +8782,6 @@ var route = defineDomTargetRoute({
|
|
|
8741
8782
|
}
|
|
8742
8783
|
});
|
|
8743
8784
|
|
|
8744
|
-
// ../argus-watcher/dist/http/routes/defineRoute.js
|
|
8745
|
-
var defineJsonRoute = (input) => ({
|
|
8746
|
-
method: input.method,
|
|
8747
|
-
path: input.path,
|
|
8748
|
-
extensionOnly: input.extensionOnly,
|
|
8749
|
-
handler: async (req, res, url, ctx) => {
|
|
8750
|
-
const rawBody = input.bodySchema ? await readJsonBody(req, res) : undefined;
|
|
8751
|
-
if (input.bodySchema && rawBody == null) {
|
|
8752
|
-
return;
|
|
8753
|
-
}
|
|
8754
|
-
const parsedBody = input.bodySchema?.parse(rawBody);
|
|
8755
|
-
if (parsedBody && !parsedBody.ok) {
|
|
8756
|
-
return respondInvalidBody(res, formatProtocolValidationIssues(parsedBody.issues));
|
|
8757
|
-
}
|
|
8758
|
-
if (input.endpoint) {
|
|
8759
|
-
emitRequest(ctx, res, input.endpoint);
|
|
8760
|
-
}
|
|
8761
|
-
try {
|
|
8762
|
-
const response = await input.handle({
|
|
8763
|
-
req,
|
|
8764
|
-
res,
|
|
8765
|
-
url,
|
|
8766
|
-
ctx,
|
|
8767
|
-
body: parsedBody?.value
|
|
8768
|
-
});
|
|
8769
|
-
if (response) {
|
|
8770
|
-
respondJson(res, response);
|
|
8771
|
-
}
|
|
8772
|
-
} catch (error) {
|
|
8773
|
-
if (input.handleError?.(res, error)) {
|
|
8774
|
-
return;
|
|
8775
|
-
}
|
|
8776
|
-
respondError(res, error);
|
|
8777
|
-
}
|
|
8778
|
-
}
|
|
8779
|
-
});
|
|
8780
|
-
|
|
8781
8785
|
// ../argus-watcher/dist/http/routes/postDomClick.js
|
|
8782
8786
|
var route2 = defineJsonRoute({
|
|
8783
8787
|
method: "POST",
|
|
@@ -9427,78 +9431,75 @@ var handle37 = async (req, res, _url, ctx) => {
|
|
|
9427
9431
|
};
|
|
9428
9432
|
|
|
9429
9433
|
// ../argus-watcher/dist/http/routes/getThrottle.js
|
|
9430
|
-
var handle38 = (
|
|
9431
|
-
|
|
9432
|
-
|
|
9433
|
-
|
|
9434
|
-
}
|
|
9434
|
+
var handle38 = defineJsonRoute({
|
|
9435
|
+
method: "GET",
|
|
9436
|
+
path: "/throttle",
|
|
9437
|
+
endpoint: "throttle",
|
|
9438
|
+
handle: ({ ctx }) => ctx.throttleController.getStatus({ attached: ctx.getCdpStatus().attached })
|
|
9439
|
+
}).handler;
|
|
9435
9440
|
|
|
9436
9441
|
// ../argus-watcher/dist/http/routes/postThrottle.js
|
|
9437
|
-
var handle39 =
|
|
9438
|
-
|
|
9439
|
-
|
|
9440
|
-
|
|
9441
|
-
}
|
|
9442
|
-
|
|
9443
|
-
|
|
9444
|
-
|
|
9445
|
-
|
|
9446
|
-
|
|
9447
|
-
|
|
9448
|
-
|
|
9449
|
-
|
|
9450
|
-
|
|
9451
|
-
const response = await ctx.throttleController.clearDesired(session);
|
|
9452
|
-
respondJson(res, response);
|
|
9453
|
-
} catch (error) {
|
|
9454
|
-
respondError(res, error);
|
|
9442
|
+
var handle39 = defineJsonRoute({
|
|
9443
|
+
method: "POST",
|
|
9444
|
+
path: "/throttle",
|
|
9445
|
+
parseBody: true,
|
|
9446
|
+
handle: async ({ res, ctx, body: payload }) => {
|
|
9447
|
+
const validActions = ["set", "clear"];
|
|
9448
|
+
const action = payload.action;
|
|
9449
|
+
if (!action || !validActions.includes(action)) {
|
|
9450
|
+
return respondInvalidBody(res, `action must be one of: ${validActions.join(", ")}`);
|
|
9451
|
+
}
|
|
9452
|
+
emitRequest(ctx, res, "throttle");
|
|
9453
|
+
const session = ctx.cdpSession.isAttached() ? ctx.cdpSession : null;
|
|
9454
|
+
if (action === "clear") {
|
|
9455
|
+
return ctx.throttleController.clearDesired(session);
|
|
9455
9456
|
}
|
|
9456
|
-
|
|
9457
|
-
|
|
9458
|
-
|
|
9459
|
-
|
|
9460
|
-
return
|
|
9461
|
-
}
|
|
9462
|
-
try {
|
|
9463
|
-
const response = await ctx.throttleController.setDesired(setPayload.rate, session);
|
|
9464
|
-
respondJson(res, response);
|
|
9465
|
-
} catch (error) {
|
|
9466
|
-
respondError(res, error);
|
|
9457
|
+
const setPayload = payload;
|
|
9458
|
+
if (typeof setPayload.rate !== "number" || !Number.isFinite(setPayload.rate) || setPayload.rate < 1) {
|
|
9459
|
+
return respondInvalidBody(res, "rate must be a finite number >= 1");
|
|
9460
|
+
}
|
|
9461
|
+
return ctx.throttleController.setDesired(setPayload.rate, session);
|
|
9467
9462
|
}
|
|
9468
|
-
};
|
|
9463
|
+
}).handler;
|
|
9469
9464
|
|
|
9470
9465
|
// ../argus-watcher/dist/http/routes/getDialog.js
|
|
9471
|
-
var handle40 = (
|
|
9472
|
-
|
|
9473
|
-
|
|
9474
|
-
|
|
9475
|
-
|
|
9476
|
-
|
|
9477
|
-
|
|
9478
|
-
|
|
9466
|
+
var handle40 = defineJsonRoute({
|
|
9467
|
+
method: "GET",
|
|
9468
|
+
path: "/dialog",
|
|
9469
|
+
endpoint: "dialog/status",
|
|
9470
|
+
handle: ({ ctx }) => {
|
|
9471
|
+
const response = {
|
|
9472
|
+
ok: true,
|
|
9473
|
+
dialog: ctx.getDialog()
|
|
9474
|
+
};
|
|
9475
|
+
return response;
|
|
9476
|
+
}
|
|
9477
|
+
}).handler;
|
|
9479
9478
|
|
|
9480
9479
|
// ../argus-watcher/dist/http/routes/postDialog.js
|
|
9481
|
-
var handle41 =
|
|
9482
|
-
|
|
9483
|
-
|
|
9484
|
-
|
|
9485
|
-
|
|
9486
|
-
|
|
9487
|
-
|
|
9488
|
-
|
|
9489
|
-
|
|
9490
|
-
|
|
9491
|
-
|
|
9492
|
-
|
|
9493
|
-
|
|
9494
|
-
|
|
9495
|
-
|
|
9496
|
-
|
|
9497
|
-
|
|
9498
|
-
|
|
9499
|
-
|
|
9500
|
-
|
|
9501
|
-
|
|
9480
|
+
var handle41 = defineJsonRoute({
|
|
9481
|
+
method: "POST",
|
|
9482
|
+
path: "/dialog",
|
|
9483
|
+
parseBody: true,
|
|
9484
|
+
endpoint: "dialog/handle",
|
|
9485
|
+
handle: async ({ res, ctx, body: payload }) => {
|
|
9486
|
+
const action = payload.action;
|
|
9487
|
+
if (action !== "accept" && action !== "dismiss") {
|
|
9488
|
+
respondInvalidBody(res, 'Dialog action must be "accept" or "dismiss"');
|
|
9489
|
+
return;
|
|
9490
|
+
}
|
|
9491
|
+
const dialog = ctx.getDialog();
|
|
9492
|
+
if (!dialog) {
|
|
9493
|
+
respondJson(res, { ok: false, error: { message: "No active browser dialog", code: "no_active_dialog" } }, 409);
|
|
9494
|
+
return;
|
|
9495
|
+
}
|
|
9496
|
+
if (payload.promptText != null && dialog.type !== "prompt") {
|
|
9497
|
+
respondJson(res, {
|
|
9498
|
+
ok: false,
|
|
9499
|
+
error: { message: "Prompt text can only be sent to prompt dialogs", code: "dialog_not_prompt" }
|
|
9500
|
+
}, 409);
|
|
9501
|
+
return;
|
|
9502
|
+
}
|
|
9502
9503
|
await ctx.pageCdpSession.sendAndWait("Page.handleJavaScriptDialog", {
|
|
9503
9504
|
accept: action === "accept",
|
|
9504
9505
|
promptText: payload.promptText
|
|
@@ -9508,36 +9509,30 @@ var handle41 = async (req, res, _url, ctx) => {
|
|
|
9508
9509
|
action,
|
|
9509
9510
|
dialog
|
|
9510
9511
|
};
|
|
9511
|
-
|
|
9512
|
-
} catch (error) {
|
|
9513
|
-
respondError(res, error);
|
|
9512
|
+
return response;
|
|
9514
9513
|
}
|
|
9515
|
-
};
|
|
9514
|
+
}).handler;
|
|
9516
9515
|
|
|
9517
9516
|
// ../argus-watcher/dist/http/routes/postVisibility.js
|
|
9518
|
-
var handle42 =
|
|
9519
|
-
|
|
9520
|
-
|
|
9521
|
-
|
|
9522
|
-
}
|
|
9523
|
-
|
|
9524
|
-
|
|
9525
|
-
|
|
9526
|
-
|
|
9527
|
-
|
|
9528
|
-
|
|
9529
|
-
|
|
9530
|
-
|
|
9531
|
-
|
|
9532
|
-
try {
|
|
9517
|
+
var handle42 = defineJsonRoute({
|
|
9518
|
+
method: "POST",
|
|
9519
|
+
path: "/visibility",
|
|
9520
|
+
parseBody: true,
|
|
9521
|
+
handle: async ({ res, ctx, body: payload }) => {
|
|
9522
|
+
const action = payload.action;
|
|
9523
|
+
if (action !== "show" && action !== "hide") {
|
|
9524
|
+
respondInvalidBody(res, 'Visibility action must be "show" or "hide"');
|
|
9525
|
+
return;
|
|
9526
|
+
}
|
|
9527
|
+
emitRequest(ctx, res, "visibility");
|
|
9528
|
+
const lock = action === "show" ? "shown" : "default";
|
|
9529
|
+
const session = ctx.pageCdpSession;
|
|
9530
|
+
const attached = session.isAttached();
|
|
9533
9531
|
await ctx.visibilityController.setLock(attached ? session : null, lock);
|
|
9534
|
-
|
|
9535
|
-
|
|
9536
|
-
return;
|
|
9532
|
+
const response = { ok: true, attached, state: lock };
|
|
9533
|
+
return response;
|
|
9537
9534
|
}
|
|
9538
|
-
|
|
9539
|
-
respondJson(res, response);
|
|
9540
|
-
};
|
|
9535
|
+
}).handler;
|
|
9541
9536
|
|
|
9542
9537
|
// ../argus-watcher/dist/cdp/storage.js
|
|
9543
9538
|
var storageAccessors = {
|
|
@@ -9652,22 +9647,18 @@ var handle43 = createStorageHandler("local");
|
|
|
9652
9647
|
var handle44 = createStorageHandler("session");
|
|
9653
9648
|
|
|
9654
9649
|
// ../argus-watcher/dist/http/routes/postReload.js
|
|
9655
|
-
var handle45 =
|
|
9656
|
-
|
|
9657
|
-
|
|
9658
|
-
|
|
9659
|
-
|
|
9660
|
-
|
|
9661
|
-
try {
|
|
9650
|
+
var handle45 = defineJsonRoute({
|
|
9651
|
+
method: "POST",
|
|
9652
|
+
path: "/reload",
|
|
9653
|
+
parseBody: true,
|
|
9654
|
+
endpoint: "reload",
|
|
9655
|
+
handle: async ({ ctx, body: payload }) => {
|
|
9662
9656
|
await ctx.pageCdpSession.sendAndWait("Page.reload", {
|
|
9663
9657
|
ignoreCache: payload.ignoreCache ?? false
|
|
9664
9658
|
});
|
|
9665
|
-
|
|
9666
|
-
respondJson(res, response);
|
|
9667
|
-
} catch (error) {
|
|
9668
|
-
respondError(res, error);
|
|
9659
|
+
return { ok: true };
|
|
9669
9660
|
}
|
|
9670
|
-
};
|
|
9661
|
+
}).handler;
|
|
9671
9662
|
|
|
9672
9663
|
// ../argus-watcher/dist/http/routes/postShutdown.js
|
|
9673
9664
|
var handle46 = (_req, res, _url, ctx) => {
|
|
@@ -11316,6 +11307,7 @@ var createVisibilityController = () => {
|
|
|
11316
11307
|
// ../argus-watcher/dist/runtime/watcherSetup.js
|
|
11317
11308
|
var normalizeWatcherSetup = (options, watcherId) => {
|
|
11318
11309
|
const sourceMode = options.source ?? "cdp";
|
|
11310
|
+
const extensionRole = options.extensionRole ?? "tab";
|
|
11319
11311
|
const host = options.host ?? "127.0.0.1";
|
|
11320
11312
|
const port = options.port ?? 0;
|
|
11321
11313
|
const chrome = options.chrome ?? { host: "127.0.0.1", port: 9222 };
|
|
@@ -11359,6 +11351,7 @@ var normalizeWatcherSetup = (options, watcherId) => {
|
|
|
11359
11351
|
};
|
|
11360
11352
|
return {
|
|
11361
11353
|
sourceMode,
|
|
11354
|
+
extensionRole,
|
|
11362
11355
|
host,
|
|
11363
11356
|
port,
|
|
11364
11357
|
chrome,
|
|
@@ -14064,6 +14057,57 @@ var createNativeMessaging = () => {
|
|
|
14064
14057
|
};
|
|
14065
14058
|
};
|
|
14066
14059
|
|
|
14060
|
+
// ../argus-watcher/dist/native-messaging/control-session-manager.js
|
|
14061
|
+
class ControlSessionManager {
|
|
14062
|
+
messaging;
|
|
14063
|
+
pendingTabsRequest = null;
|
|
14064
|
+
constructor(messaging) {
|
|
14065
|
+
this.messaging = messaging;
|
|
14066
|
+
this.messaging.onMessage((message) => {
|
|
14067
|
+
this.handleMessage(message);
|
|
14068
|
+
});
|
|
14069
|
+
}
|
|
14070
|
+
attachTabWatcher(tabId) {
|
|
14071
|
+
this.messaging.send({
|
|
14072
|
+
type: "attach_tab_watcher",
|
|
14073
|
+
tabId
|
|
14074
|
+
});
|
|
14075
|
+
}
|
|
14076
|
+
detachTabWatcher(tabId) {
|
|
14077
|
+
this.messaging.send({
|
|
14078
|
+
type: "detach_tab_watcher",
|
|
14079
|
+
tabId
|
|
14080
|
+
});
|
|
14081
|
+
}
|
|
14082
|
+
async listTabs(filter) {
|
|
14083
|
+
return new Promise((resolve2, reject) => {
|
|
14084
|
+
this.pendingTabsRequest = { resolve: resolve2, reject };
|
|
14085
|
+
this.messaging.send({
|
|
14086
|
+
type: "list_tabs",
|
|
14087
|
+
filter
|
|
14088
|
+
});
|
|
14089
|
+
setTimeout(() => {
|
|
14090
|
+
if (!this.pendingTabsRequest) {
|
|
14091
|
+
return;
|
|
14092
|
+
}
|
|
14093
|
+
this.pendingTabsRequest.reject(new Error("List tabs request timed out"));
|
|
14094
|
+
this.pendingTabsRequest = null;
|
|
14095
|
+
}, 5000);
|
|
14096
|
+
});
|
|
14097
|
+
}
|
|
14098
|
+
handleMessage(message) {
|
|
14099
|
+
switch (message.type) {
|
|
14100
|
+
case "list_tabs_response":
|
|
14101
|
+
this.handleListTabsResponse(message);
|
|
14102
|
+
return;
|
|
14103
|
+
}
|
|
14104
|
+
}
|
|
14105
|
+
handleListTabsResponse(message) {
|
|
14106
|
+
this.pendingTabsRequest?.resolve(message.tabs);
|
|
14107
|
+
this.pendingTabsRequest = null;
|
|
14108
|
+
}
|
|
14109
|
+
}
|
|
14110
|
+
|
|
14067
14111
|
// ../argus-watcher/dist/native-messaging/session-manager.js
|
|
14068
14112
|
var nextRequestId = 1;
|
|
14069
14113
|
|
|
@@ -14073,7 +14117,6 @@ class SessionManager {
|
|
|
14073
14117
|
pendingRequests = new Map;
|
|
14074
14118
|
eventHandlers = new Map;
|
|
14075
14119
|
events;
|
|
14076
|
-
pendingTabsRequest = null;
|
|
14077
14120
|
constructor(messaging, events) {
|
|
14078
14121
|
this.messaging = messaging;
|
|
14079
14122
|
this.events = events;
|
|
@@ -14101,9 +14144,6 @@ class SessionManager {
|
|
|
14101
14144
|
case "cookie_query_response":
|
|
14102
14145
|
this.handleCookieQueryResponse(message);
|
|
14103
14146
|
break;
|
|
14104
|
-
case "list_tabs_response":
|
|
14105
|
-
this.handleListTabsResponse(message);
|
|
14106
|
-
break;
|
|
14107
14147
|
case "target_selected":
|
|
14108
14148
|
this.events.onTargetSelected(message.tabId, message.frameId ?? null);
|
|
14109
14149
|
break;
|
|
@@ -14156,13 +14196,6 @@ class SessionManager {
|
|
|
14156
14196
|
pending.resolve(result);
|
|
14157
14197
|
}
|
|
14158
14198
|
}
|
|
14159
|
-
handleListTabsResponse(message) {
|
|
14160
|
-
if (this.pendingTabsRequest) {
|
|
14161
|
-
this.pendingTabsRequest.resolve(message.tabs);
|
|
14162
|
-
this.pendingTabsRequest = null;
|
|
14163
|
-
}
|
|
14164
|
-
this.events.onTabsUpdated(message.tabs);
|
|
14165
|
-
}
|
|
14166
14199
|
createSession(message) {
|
|
14167
14200
|
const { tabId, url, title, faviconUrl } = message;
|
|
14168
14201
|
const enabledDomains = new Set;
|
|
@@ -14243,22 +14276,6 @@ class SessionManager {
|
|
|
14243
14276
|
};
|
|
14244
14277
|
this.messaging.send(message);
|
|
14245
14278
|
}
|
|
14246
|
-
async listTabs(filter) {
|
|
14247
|
-
return new Promise((resolve2, reject) => {
|
|
14248
|
-
this.pendingTabsRequest = { resolve: resolve2, reject };
|
|
14249
|
-
const message = {
|
|
14250
|
-
type: "list_tabs",
|
|
14251
|
-
filter
|
|
14252
|
-
};
|
|
14253
|
-
this.messaging.send(message);
|
|
14254
|
-
setTimeout(() => {
|
|
14255
|
-
if (this.pendingTabsRequest) {
|
|
14256
|
-
this.pendingTabsRequest.reject(new Error("List tabs request timed out"));
|
|
14257
|
-
this.pendingTabsRequest = null;
|
|
14258
|
-
}
|
|
14259
|
-
}, 5000);
|
|
14260
|
-
});
|
|
14261
|
-
}
|
|
14262
14279
|
getSession(tabId) {
|
|
14263
14280
|
return this.sessions.get(tabId);
|
|
14264
14281
|
}
|
|
@@ -14919,7 +14936,87 @@ var TARGET_RECOVERY_INTERVAL_MS = 500;
|
|
|
14919
14936
|
var TARGET_RECOVERY_TIMEOUT_MS = 30000;
|
|
14920
14937
|
var FRAME_COMMAND_READY_TIMEOUT_MS = 3000;
|
|
14921
14938
|
var FRAME_COMMAND_READY_POLL_MS = 100;
|
|
14939
|
+
var createDetachedSession = (message) => ({
|
|
14940
|
+
isAttached: () => false,
|
|
14941
|
+
sendAndWait: async () => {
|
|
14942
|
+
const error = new Error(message);
|
|
14943
|
+
error.code = "cdp_not_attached";
|
|
14944
|
+
throw error;
|
|
14945
|
+
},
|
|
14946
|
+
onEvent: () => () => {}
|
|
14947
|
+
});
|
|
14948
|
+
var createControlExtensionSource = (options) => {
|
|
14949
|
+
const { events, watcherId, watcherHost, watcherPort } = options;
|
|
14950
|
+
const messaging = createNativeMessaging();
|
|
14951
|
+
const controlSession = new ControlSessionManager(messaging);
|
|
14952
|
+
const hostInfo = {
|
|
14953
|
+
watcherId: watcherId ?? "extension-control",
|
|
14954
|
+
watcherHost: watcherHost ?? "127.0.0.1",
|
|
14955
|
+
watcherPort: watcherPort ?? 0,
|
|
14956
|
+
watcherPid: process.pid
|
|
14957
|
+
};
|
|
14958
|
+
let stopping = false;
|
|
14959
|
+
messaging.start();
|
|
14960
|
+
messaging.send({ type: "host_ready" });
|
|
14961
|
+
sendHostInfo();
|
|
14962
|
+
events.onStatus({
|
|
14963
|
+
attached: false,
|
|
14964
|
+
target: null,
|
|
14965
|
+
reason: "control_watcher"
|
|
14966
|
+
});
|
|
14967
|
+
messaging.onDisconnect(() => {
|
|
14968
|
+
console.error("[ExtensionControlSource] Extension disconnected");
|
|
14969
|
+
if (!stopping) {
|
|
14970
|
+
events.onStatus({ attached: false, target: null, reason: "extension_disconnected" });
|
|
14971
|
+
events.onDetach?.("extension_disconnected");
|
|
14972
|
+
}
|
|
14973
|
+
});
|
|
14974
|
+
return {
|
|
14975
|
+
session: createDetachedSession("Extension control watcher does not expose a CDP tab session"),
|
|
14976
|
+
syncWatcherInfo: (info) => {
|
|
14977
|
+
hostInfo.watcherId = info.watcherId;
|
|
14978
|
+
hostInfo.watcherHost = info.watcherHost;
|
|
14979
|
+
hostInfo.watcherPort = info.watcherPort;
|
|
14980
|
+
hostInfo.watcherPid = info.watcherPid;
|
|
14981
|
+
sendHostInfo();
|
|
14982
|
+
},
|
|
14983
|
+
stop: async () => {
|
|
14984
|
+
stopping = true;
|
|
14985
|
+
messaging.stop();
|
|
14986
|
+
},
|
|
14987
|
+
listTargets: async () => [],
|
|
14988
|
+
listTabs: async (filter) => await controlSession.listTabs(filter),
|
|
14989
|
+
attachTarget: (targetId) => {
|
|
14990
|
+
controlSession.attachTabWatcher(parseControlTabTarget(targetId, "attach"));
|
|
14991
|
+
},
|
|
14992
|
+
detachTarget: (targetId) => {
|
|
14993
|
+
controlSession.detachTabWatcher(parseControlTabTarget(targetId, "detach"));
|
|
14994
|
+
}
|
|
14995
|
+
};
|
|
14996
|
+
function sendHostInfo() {
|
|
14997
|
+
messaging.send({
|
|
14998
|
+
type: "host_info",
|
|
14999
|
+
watcherId: hostInfo.watcherId,
|
|
15000
|
+
watcherHost: hostInfo.watcherHost,
|
|
15001
|
+
watcherPort: hostInfo.watcherPort,
|
|
15002
|
+
pid: hostInfo.watcherPid
|
|
15003
|
+
});
|
|
15004
|
+
}
|
|
15005
|
+
};
|
|
15006
|
+
var parseControlTabTarget = (targetId, action) => {
|
|
15007
|
+
const target = parseExtensionTargetId(targetId);
|
|
15008
|
+
if (!target.frameId) {
|
|
15009
|
+
return target.tabId;
|
|
15010
|
+
}
|
|
15011
|
+
if (action === "attach") {
|
|
15012
|
+
throw new Error(`Cannot attach iframe ${target.frameId} from extension-control before tab ${target.tabId} has a tab watcher`);
|
|
15013
|
+
}
|
|
15014
|
+
throw new Error(`Cannot detach iframe ${target.frameId} from extension-control. Detach tab ${target.tabId} instead.`);
|
|
15015
|
+
};
|
|
14922
15016
|
var createExtensionSource = (options) => {
|
|
15017
|
+
if (options.role === "control") {
|
|
15018
|
+
return createControlExtensionSource(options);
|
|
15019
|
+
}
|
|
14923
15020
|
const { events, ignoreMatcher, stripUrlPrefixes: stripUrlPrefixes2, watcherId, watcherHost, watcherPort } = options;
|
|
14924
15021
|
const messaging = createNativeMessaging();
|
|
14925
15022
|
const hostInfo = {
|
|
@@ -14958,7 +15055,6 @@ var createExtensionSource = (options) => {
|
|
|
14958
15055
|
emitStatus(null, reason);
|
|
14959
15056
|
events.onDetach?.(reason);
|
|
14960
15057
|
},
|
|
14961
|
-
onTabsUpdated: () => {},
|
|
14962
15058
|
onTargetSelected: (tabId, frameId) => {
|
|
14963
15059
|
const session = currentSession;
|
|
14964
15060
|
if (!session || session.tabId !== tabId) {
|
|
@@ -14998,6 +15094,7 @@ var createExtensionSource = (options) => {
|
|
|
14998
15094
|
});
|
|
14999
15095
|
delegatingSessions.add(pageController);
|
|
15000
15096
|
messaging.start();
|
|
15097
|
+
messaging.send({ type: "host_ready" });
|
|
15001
15098
|
sendHostInfo();
|
|
15002
15099
|
messaging.onDisconnect(() => {
|
|
15003
15100
|
console.error("[ExtensionSource] Extension disconnected");
|
|
@@ -15030,13 +15127,26 @@ var createExtensionSource = (options) => {
|
|
|
15030
15127
|
};
|
|
15031
15128
|
const attachTarget = (targetId) => {
|
|
15032
15129
|
const target = parseExtensionTargetId(targetId);
|
|
15033
|
-
const session =
|
|
15130
|
+
const session = currentSession;
|
|
15131
|
+
if (!session) {
|
|
15132
|
+
if (target.frameId) {
|
|
15133
|
+
throw new Error(`Cannot attach iframe ${target.frameId} before tab ${target.tabId} is attached`);
|
|
15134
|
+
}
|
|
15135
|
+
throw new Error(`Watcher ${hostInfo.watcherId} is a tab watcher. Use extension-control to attach tab ${target.tabId}.`);
|
|
15136
|
+
}
|
|
15137
|
+
if (session.tabId !== target.tabId) {
|
|
15138
|
+
throw new Error(`Watcher ${hostInfo.watcherId} is pinned to tab ${session.tabId}, not tab ${target.tabId}`);
|
|
15139
|
+
}
|
|
15034
15140
|
requestTargetSelection(session, target.frameId);
|
|
15035
15141
|
};
|
|
15036
15142
|
const detachTarget = (targetId) => {
|
|
15037
15143
|
const target = parseExtensionTargetId(targetId);
|
|
15038
|
-
const session =
|
|
15039
|
-
|
|
15144
|
+
const session = currentSession;
|
|
15145
|
+
if (!session || session.tabId === target.tabId) {
|
|
15146
|
+
sessionManager.detachTab(target.tabId);
|
|
15147
|
+
return;
|
|
15148
|
+
}
|
|
15149
|
+
throw new Error(`Watcher ${hostInfo.watcherId} is pinned to tab ${session.tabId}, not tab ${target.tabId}`);
|
|
15040
15150
|
};
|
|
15041
15151
|
return {
|
|
15042
15152
|
session: proxySession,
|
|
@@ -15080,9 +15190,6 @@ var createExtensionSource = (options) => {
|
|
|
15080
15190
|
},
|
|
15081
15191
|
stop,
|
|
15082
15192
|
listTargets,
|
|
15083
|
-
listTabs: async (filter) => {
|
|
15084
|
-
return await sessionManager.listTabs(filter);
|
|
15085
|
-
},
|
|
15086
15193
|
attachTarget,
|
|
15087
15194
|
detachTarget
|
|
15088
15195
|
};
|
|
@@ -15095,16 +15202,6 @@ var createExtensionSource = (options) => {
|
|
|
15095
15202
|
pid: hostInfo.watcherPid
|
|
15096
15203
|
});
|
|
15097
15204
|
}
|
|
15098
|
-
function requireOwnedSession(tabId) {
|
|
15099
|
-
const session = currentSession;
|
|
15100
|
-
if (!session) {
|
|
15101
|
-
throw createNotAttachedError();
|
|
15102
|
-
}
|
|
15103
|
-
if (session.tabId !== tabId) {
|
|
15104
|
-
throw new Error(`Watcher ${hostInfo.watcherId} is pinned to tab ${session.tabId}, not tab ${tabId}`);
|
|
15105
|
-
}
|
|
15106
|
-
return session;
|
|
15107
|
-
}
|
|
15108
15205
|
function rebindDelegatingSessions() {
|
|
15109
15206
|
for (const controller of delegatingSessions) {
|
|
15110
15207
|
controller.rebind();
|
|
@@ -15207,13 +15304,15 @@ var createExtensionSource = (options) => {
|
|
|
15207
15304
|
if (state2.activeAttachedAt == null) {
|
|
15208
15305
|
state2.activeAttachedAt = Date.now();
|
|
15209
15306
|
}
|
|
15307
|
+
const targetReady = isTargetReady(session.tabId);
|
|
15210
15308
|
emitStatus(target, null);
|
|
15211
15309
|
messaging.send({
|
|
15212
15310
|
type: "target_info",
|
|
15213
15311
|
targetId: target.id,
|
|
15214
15312
|
title: target.title,
|
|
15215
15313
|
url: target.url,
|
|
15216
|
-
attachedAt: state2.activeAttachedAt
|
|
15314
|
+
attachedAt: state2.activeAttachedAt,
|
|
15315
|
+
targetReady
|
|
15217
15316
|
});
|
|
15218
15317
|
events.onTargetChanged?.(session.handle, target);
|
|
15219
15318
|
}
|
|
@@ -15354,7 +15453,7 @@ function delay4(ms) {
|
|
|
15354
15453
|
|
|
15355
15454
|
// ../argus-watcher/dist/runtime/watcherServices.js
|
|
15356
15455
|
var createWatcherRuntimeServices = (options, setup, callbacks) => {
|
|
15357
|
-
const { sourceMode, chrome, artifactsBaseDir, netBuffer, realtimeNetBuffer, sessionHandle, ignoreMatcher, stripUrlPrefixes: stripUrlPrefixes2, watcherId, host, record } = setup;
|
|
15456
|
+
const { sourceMode, chrome, artifactsBaseDir, netBuffer, realtimeNetBuffer, sessionHandle, ignoreMatcher, stripUrlPrefixes: stripUrlPrefixes2, watcherId, host, record, extensionRole } = setup;
|
|
15358
15457
|
if (sourceMode === "extension") {
|
|
15359
15458
|
const sourceHandle2 = createExtensionSource({
|
|
15360
15459
|
events: {
|
|
@@ -15372,6 +15471,7 @@ var createWatcherRuntimeServices = (options, setup, callbacks) => {
|
|
|
15372
15471
|
watcherId,
|
|
15373
15472
|
watcherHost: host,
|
|
15374
15473
|
watcherPort: record.port,
|
|
15474
|
+
role: extensionRole,
|
|
15375
15475
|
ignoreMatcher: ignoreMatcher ? (url) => ignoreMatcher.matches(url) : null,
|
|
15376
15476
|
stripUrlPrefixes: stripUrlPrefixes2
|
|
15377
15477
|
});
|
|
@@ -16085,7 +16185,7 @@ var runReload = defineWatcherCommand({
|
|
|
16085
16185
|
import fs8 from "node:fs";
|
|
16086
16186
|
import path10 from "node:path";
|
|
16087
16187
|
var AUTO_CONFIG_CANDIDATES = [".argus/config.json", ".config/argus.json", "argus.config.json", "argus/config.json"];
|
|
16088
|
-
var EXPECTED_SHAPE_HINT = 'Expected shape: { chrome?: { start?: { url?: string, watcherId?: string, profile?: "temp"|"default-full"|"default-medium"|"default-lite", devTools?: boolean, headless?: boolean } }, watcher?: { start?: { id?: string, url?: string, chromeHost?: string, chromePort?: number, artifacts?: string, pageIndicator?: boolean, pageConsoleLogging?: "none"|"minimal"|"full", inject?: { file: string, exposeArgus?: boolean } } } }.';
|
|
16188
|
+
var EXPECTED_SHAPE_HINT = 'Expected shape: { plugins?: string[], pluginAliases?: Record<string, string>, chrome?: { start?: { url?: string, watcherId?: string, profile?: "temp"|"default-full"|"default-medium"|"default-lite", devTools?: boolean, headless?: boolean } }, watcher?: { start?: { id?: string, url?: string, chromeHost?: string, chromePort?: number, artifacts?: string, pageIndicator?: boolean, pageConsoleLogging?: "none"|"minimal"|"full", inject?: { file: string, exposeArgus?: boolean } } } }.';
|
|
16089
16189
|
var isRecord = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
|
|
16090
16190
|
var invalidConfig = (configPath, message) => {
|
|
16091
16191
|
console.error(`Invalid Argus config at ${configPath}: ${message} ${EXPECTED_SHAPE_HINT}`);
|
|
@@ -16159,6 +16259,25 @@ var validateOptionalStringArray = (value, label) => {
|
|
|
16159
16259
|
}
|
|
16160
16260
|
return { ok: true, value };
|
|
16161
16261
|
};
|
|
16262
|
+
var validateOptionalStringMap = (value, label) => {
|
|
16263
|
+
if (value === undefined) {
|
|
16264
|
+
return { ok: true };
|
|
16265
|
+
}
|
|
16266
|
+
if (!isRecord(value)) {
|
|
16267
|
+
return { ok: false, error: `${label} must be an object with string values.` };
|
|
16268
|
+
}
|
|
16269
|
+
const entries = [];
|
|
16270
|
+
for (const [key, item] of Object.entries(value)) {
|
|
16271
|
+
if (key.trim() === "") {
|
|
16272
|
+
return { ok: false, error: `${label} keys must be non-empty strings.` };
|
|
16273
|
+
}
|
|
16274
|
+
if (typeof item !== "string" || item.trim() === "") {
|
|
16275
|
+
return { ok: false, error: `${label}.${key} must be a non-empty string.` };
|
|
16276
|
+
}
|
|
16277
|
+
entries.push([key, item]);
|
|
16278
|
+
}
|
|
16279
|
+
return { ok: true, value: Object.fromEntries(entries) };
|
|
16280
|
+
};
|
|
16162
16281
|
var validateOptionalSection = (value, label, validate) => {
|
|
16163
16282
|
if (value === undefined) {
|
|
16164
16283
|
return { ok: true };
|
|
@@ -16290,6 +16409,10 @@ var validateArgusConfig = (value) => {
|
|
|
16290
16409
|
if (!pluginsResult.ok) {
|
|
16291
16410
|
return pluginsResult;
|
|
16292
16411
|
}
|
|
16412
|
+
const pluginAliasesResult = validateOptionalStringMap(value.pluginAliases, '"pluginAliases"');
|
|
16413
|
+
if (!pluginAliasesResult.ok) {
|
|
16414
|
+
return pluginAliasesResult;
|
|
16415
|
+
}
|
|
16293
16416
|
const chromeResult = validateOptionalSection(value.chrome, '"chrome"', (section) => {
|
|
16294
16417
|
if (section.start === undefined) {
|
|
16295
16418
|
return { ok: true, value: {} };
|
|
@@ -16316,7 +16439,15 @@ var validateArgusConfig = (value) => {
|
|
|
16316
16439
|
if (!watcherResult.ok) {
|
|
16317
16440
|
return watcherResult;
|
|
16318
16441
|
}
|
|
16319
|
-
return {
|
|
16442
|
+
return {
|
|
16443
|
+
ok: true,
|
|
16444
|
+
value: {
|
|
16445
|
+
chrome: chromeResult.value,
|
|
16446
|
+
watcher: watcherResult.value,
|
|
16447
|
+
plugins: pluginsResult.value,
|
|
16448
|
+
pluginAliases: pluginAliasesResult.value
|
|
16449
|
+
}
|
|
16450
|
+
};
|
|
16320
16451
|
};
|
|
16321
16452
|
var resolveArgusConfigPath = ({ cliPath, cwd }) => {
|
|
16322
16453
|
if (cliPath) {
|
|
@@ -16767,25 +16898,13 @@ var runWatcherStart = async (options) => {
|
|
|
16767
16898
|
var generateWatcherId = () => crypto2.randomBytes(3).toString("hex");
|
|
16768
16899
|
|
|
16769
16900
|
// dist/commands/watcherStatus.js
|
|
16770
|
-
var runWatcherStatus =
|
|
16771
|
-
|
|
16772
|
-
|
|
16773
|
-
|
|
16774
|
-
|
|
16775
|
-
timeoutMs: 2000
|
|
16776
|
-
});
|
|
16777
|
-
if (!result.ok) {
|
|
16778
|
-
writeRequestError(result, output);
|
|
16779
|
-
return;
|
|
16780
|
-
}
|
|
16781
|
-
if (options.json) {
|
|
16782
|
-
output.writeJson(result.data);
|
|
16783
|
-
return;
|
|
16901
|
+
var runWatcherStatus = defineWatcherCommand({
|
|
16902
|
+
build: () => ({ path: "/status", timeoutMs: 2000 }),
|
|
16903
|
+
formatHuman: (status, { output, watcher }) => {
|
|
16904
|
+
const readinessSuffix = status.targetReady === false ? " targetReady=false" : "";
|
|
16905
|
+
output.writeHuman(`ok ${watcher.id} ${watcher.host}:${watcher.port} pid=${status.pid} attached=${status.attached}${readinessSuffix}`);
|
|
16784
16906
|
}
|
|
16785
|
-
|
|
16786
|
-
const readinessSuffix = status.targetReady === false ? " targetReady=false" : "";
|
|
16787
|
-
output.writeHuman(`ok ${watcher.id} ${watcher.host}:${watcher.port} pid=${status.pid} attached=${status.attached}${readinessSuffix}`);
|
|
16788
|
-
};
|
|
16907
|
+
});
|
|
16789
16908
|
|
|
16790
16909
|
// dist/commands/watcherStop.js
|
|
16791
16910
|
var runWatcherStop = async (id, _options) => {
|
|
@@ -16943,21 +17062,27 @@ var checkWatcherReachable = async (watcher) => {
|
|
|
16943
17062
|
// dist/commands/watcherNativeHost.js
|
|
16944
17063
|
var runWatcherNativeHost = async (options) => {
|
|
16945
17064
|
const watcherId = options.id?.trim() || "extension";
|
|
17065
|
+
const role = options.role?.trim() || "tab";
|
|
17066
|
+
if (role !== "tab" && role !== "control") {
|
|
17067
|
+
console.error(`Invalid native host role: ${role}. Expected "tab" or "control".`);
|
|
17068
|
+
process.exit(2);
|
|
17069
|
+
}
|
|
16946
17070
|
let handle51;
|
|
16947
17071
|
try {
|
|
16948
17072
|
handle51 = await startWatcher({
|
|
16949
17073
|
id: watcherId,
|
|
16950
17074
|
source: "extension",
|
|
17075
|
+
extensionRole: role,
|
|
16951
17076
|
host: "127.0.0.1",
|
|
16952
17077
|
port: 0,
|
|
16953
17078
|
net: { enabled: true },
|
|
16954
|
-
pageIndicator: { enabled:
|
|
17079
|
+
pageIndicator: { enabled: role === "tab" }
|
|
16955
17080
|
});
|
|
16956
17081
|
} catch (error) {
|
|
16957
17082
|
console.error(`Failed to start watcher: ${error instanceof Error ? error.message : error}`);
|
|
16958
17083
|
process.exit(1);
|
|
16959
17084
|
}
|
|
16960
|
-
console.error(`[NativeHost] Watcher started: id=${handle51.watcher.id} port=${handle51.watcher.port}`);
|
|
17085
|
+
console.error(`[NativeHost] Watcher started: id=${handle51.watcher.id} role=${role} port=${handle51.watcher.port}`);
|
|
16961
17086
|
const cleanup = async () => {
|
|
16962
17087
|
try {
|
|
16963
17088
|
await handle51.close();
|
|
@@ -17080,7 +17205,7 @@ Examples:
|
|
|
17080
17205
|
`).action(async (options) => {
|
|
17081
17206
|
await runWatcherPrune(options);
|
|
17082
17207
|
});
|
|
17083
|
-
watcher.command("native-host").description("[internal] Start as Native Messaging host for Chrome extension").option("--id <watcherId>", "Watcher id (default: extension)").option("--json", "Output JSON for automation").action(async (options) => {
|
|
17208
|
+
watcher.command("native-host").description("[internal] Start as Native Messaging host for Chrome extension").option("--id <watcherId>", "Watcher id (default: extension)").option("--role <role>", "Native host role: tab or control (default: tab)").option("--json", "Output JSON for automation").action(async (options) => {
|
|
17084
17209
|
await runWatcherNativeHost(options);
|
|
17085
17210
|
});
|
|
17086
17211
|
}
|
|
@@ -17361,16 +17486,38 @@ var listPresetNames = () => {
|
|
|
17361
17486
|
};
|
|
17362
17487
|
|
|
17363
17488
|
// dist/commands/pageEmulation.js
|
|
17364
|
-
var runPageEmulationSet =
|
|
17365
|
-
|
|
17489
|
+
var runPageEmulationSet = defineWatcherCommand({
|
|
17490
|
+
build: (_args, options, output) => buildPageEmulationSetPlan(options, output),
|
|
17491
|
+
formatHuman: (res, { output, options }) => {
|
|
17492
|
+
const state2 = buildEmulationState(options);
|
|
17493
|
+
const label = formatViewportLabel(state2.viewport, state2.touch.enabled, state2.userAgent.value);
|
|
17494
|
+
if (res.applied) {
|
|
17495
|
+
output.writeHuman(`Applied emulation: ${label}`);
|
|
17496
|
+
} else if (!res.attached) {
|
|
17497
|
+
output.writeHuman(`Queued emulation (watcher detached): ${label}`);
|
|
17498
|
+
} else {
|
|
17499
|
+
output.writeHuman(`Emulation set but not applied: ${label}`);
|
|
17500
|
+
if (res.error) {
|
|
17501
|
+
output.writeWarn(`Error: ${res.error.message}`);
|
|
17502
|
+
}
|
|
17503
|
+
}
|
|
17504
|
+
}
|
|
17505
|
+
});
|
|
17506
|
+
var buildPageEmulationSetPlan = (options, output) => {
|
|
17507
|
+
const state2 = buildEmulationState(options, output);
|
|
17508
|
+
if (!state2)
|
|
17509
|
+
return null;
|
|
17510
|
+
return { path: "/emulation", method: "POST", body: { action: "set", state: state2 }, timeoutMs: 1e4 };
|
|
17511
|
+
};
|
|
17512
|
+
var buildEmulationState = (options, output) => {
|
|
17366
17513
|
let base = null;
|
|
17367
17514
|
if (options.device) {
|
|
17368
17515
|
const preset = resolvePreset(options.device);
|
|
17369
17516
|
if (!preset) {
|
|
17370
|
-
output
|
|
17371
|
-
output
|
|
17517
|
+
output?.writeWarn(`Unknown device: ${options.device}`);
|
|
17518
|
+
output?.writeWarn(`Available: ${listPresetNames().join(", ")}`);
|
|
17372
17519
|
process.exitCode = 2;
|
|
17373
|
-
return;
|
|
17520
|
+
return null;
|
|
17374
17521
|
}
|
|
17375
17522
|
base = { viewport: preset.viewport, touch: preset.touch, userAgent: preset.userAgent };
|
|
17376
17523
|
}
|
|
@@ -17378,34 +17525,34 @@ var runPageEmulationSet = async (id, options) => {
|
|
|
17378
17525
|
const heightRaw = options.height != null ? Number(options.height) : null;
|
|
17379
17526
|
const dprRaw = options.dpr != null ? Number(options.dpr) : null;
|
|
17380
17527
|
if (widthRaw != null && (!Number.isInteger(widthRaw) || widthRaw <= 0)) {
|
|
17381
|
-
output
|
|
17528
|
+
output?.writeWarn("--width must be a positive integer");
|
|
17382
17529
|
process.exitCode = 2;
|
|
17383
|
-
return;
|
|
17530
|
+
return null;
|
|
17384
17531
|
}
|
|
17385
17532
|
if (heightRaw != null && (!Number.isInteger(heightRaw) || heightRaw <= 0)) {
|
|
17386
|
-
output
|
|
17533
|
+
output?.writeWarn("--height must be a positive integer");
|
|
17387
17534
|
process.exitCode = 2;
|
|
17388
|
-
return;
|
|
17535
|
+
return null;
|
|
17389
17536
|
}
|
|
17390
17537
|
if (dprRaw != null && (!Number.isFinite(dprRaw) || dprRaw <= 0)) {
|
|
17391
|
-
output
|
|
17538
|
+
output?.writeWarn("--dpr must be a positive number");
|
|
17392
17539
|
process.exitCode = 2;
|
|
17393
|
-
return;
|
|
17540
|
+
return null;
|
|
17394
17541
|
}
|
|
17395
17542
|
const hasWidth = widthRaw != null;
|
|
17396
17543
|
const hasHeight = heightRaw != null;
|
|
17397
17544
|
if ((hasWidth || hasHeight) && !base) {
|
|
17398
17545
|
if (!hasWidth || !hasHeight) {
|
|
17399
|
-
output
|
|
17546
|
+
output?.writeWarn("Both --width and --height are required when not using --device");
|
|
17400
17547
|
process.exitCode = 2;
|
|
17401
|
-
return;
|
|
17548
|
+
return null;
|
|
17402
17549
|
}
|
|
17403
17550
|
}
|
|
17404
17551
|
if (!base && !hasWidth) {
|
|
17405
|
-
output
|
|
17406
|
-
output
|
|
17552
|
+
output?.writeWarn("Provide --device or --width + --height");
|
|
17553
|
+
output?.writeWarn(`Available devices: ${listPresetNames().join(", ")}`);
|
|
17407
17554
|
process.exitCode = 2;
|
|
17408
|
-
return;
|
|
17555
|
+
return null;
|
|
17409
17556
|
}
|
|
17410
17557
|
const baseViewport = base?.viewport ?? null;
|
|
17411
17558
|
const width = widthRaw ?? baseViewport?.width ?? 0;
|
|
@@ -17415,137 +17562,48 @@ var runPageEmulationSet = async (id, options) => {
|
|
|
17415
17562
|
const viewport = { width, height, deviceScaleFactor: dpr, mobile };
|
|
17416
17563
|
const touchEnabled = options.touch ?? base?.touch ?? false;
|
|
17417
17564
|
const uaValue = options.ua !== undefined ? options.ua : base?.userAgent ?? null;
|
|
17418
|
-
|
|
17565
|
+
return {
|
|
17419
17566
|
viewport,
|
|
17420
17567
|
touch: { enabled: touchEnabled },
|
|
17421
17568
|
userAgent: { value: uaValue }
|
|
17422
17569
|
};
|
|
17423
|
-
const result = await requestWatcherJson({
|
|
17424
|
-
id,
|
|
17425
|
-
path: "/emulation",
|
|
17426
|
-
method: "POST",
|
|
17427
|
-
body: { action: "set", state: state2 },
|
|
17428
|
-
timeoutMs: 1e4,
|
|
17429
|
-
returnErrorResponse: true
|
|
17430
|
-
});
|
|
17431
|
-
if (!result.ok) {
|
|
17432
|
-
writeRequestError(result, output);
|
|
17433
|
-
return;
|
|
17434
|
-
}
|
|
17435
|
-
const response = result.data;
|
|
17436
|
-
if (!response.ok) {
|
|
17437
|
-
const err = response;
|
|
17438
|
-
if (options.json) {
|
|
17439
|
-
output.writeJson(response);
|
|
17440
|
-
} else {
|
|
17441
|
-
output.writeWarn(`Error: ${err.error.message}`);
|
|
17442
|
-
}
|
|
17443
|
-
process.exitCode = 1;
|
|
17444
|
-
return;
|
|
17445
|
-
}
|
|
17446
|
-
if (options.json) {
|
|
17447
|
-
output.writeJson(response);
|
|
17448
|
-
return;
|
|
17449
|
-
}
|
|
17450
|
-
const res = response;
|
|
17451
|
-
const label = formatViewportLabel(viewport, touchEnabled, uaValue);
|
|
17452
|
-
if (res.applied) {
|
|
17453
|
-
output.writeHuman(`Applied emulation: ${label}`);
|
|
17454
|
-
} else if (!res.attached) {
|
|
17455
|
-
output.writeHuman(`Queued emulation (watcher detached): ${label}`);
|
|
17456
|
-
} else {
|
|
17457
|
-
output.writeHuman(`Emulation set but not applied: ${label}`);
|
|
17458
|
-
if (res.error) {
|
|
17459
|
-
output.writeWarn(`Error: ${res.error.message}`);
|
|
17460
|
-
}
|
|
17461
|
-
}
|
|
17462
17570
|
};
|
|
17463
|
-
var runPageEmulationClear =
|
|
17464
|
-
|
|
17465
|
-
|
|
17466
|
-
|
|
17467
|
-
path: "/emulation",
|
|
17468
|
-
method: "POST",
|
|
17469
|
-
body: { action: "clear" },
|
|
17470
|
-
timeoutMs: 1e4,
|
|
17471
|
-
returnErrorResponse: true
|
|
17472
|
-
});
|
|
17473
|
-
if (!result.ok) {
|
|
17474
|
-
writeRequestError(result, output);
|
|
17475
|
-
return;
|
|
17571
|
+
var runPageEmulationClear = defineWatcherCommand({
|
|
17572
|
+
build: () => ({ path: "/emulation", method: "POST", body: { action: "clear" }, timeoutMs: 1e4 }),
|
|
17573
|
+
formatHuman: (_response, { output }) => {
|
|
17574
|
+
output.writeHuman("Cleared emulation");
|
|
17476
17575
|
}
|
|
17477
|
-
|
|
17478
|
-
|
|
17479
|
-
|
|
17480
|
-
|
|
17481
|
-
|
|
17576
|
+
});
|
|
17577
|
+
var runPageEmulationStatus = defineWatcherCommand({
|
|
17578
|
+
build: () => ({ path: "/emulation", method: "GET", timeoutMs: 5000 }),
|
|
17579
|
+
formatHuman: (res, { output }) => {
|
|
17580
|
+
const lines = [];
|
|
17581
|
+
lines.push(`attached: ${res.attached}`);
|
|
17582
|
+
lines.push(`applied: ${res.applied}`);
|
|
17583
|
+
if (res.state?.viewport) {
|
|
17584
|
+
const vp = res.state.viewport;
|
|
17585
|
+
lines.push(`viewport: ${vp.width}x${vp.height}@${vp.deviceScaleFactor} ${vp.mobile ? "mobile" : "desktop"}`);
|
|
17482
17586
|
} else {
|
|
17483
|
-
|
|
17587
|
+
lines.push("viewport: none");
|
|
17484
17588
|
}
|
|
17485
|
-
|
|
17486
|
-
|
|
17487
|
-
|
|
17488
|
-
|
|
17489
|
-
output.writeJson(response);
|
|
17490
|
-
return;
|
|
17491
|
-
}
|
|
17492
|
-
output.writeHuman("Cleared emulation");
|
|
17493
|
-
};
|
|
17494
|
-
var runPageEmulationStatus = async (id, options) => {
|
|
17495
|
-
const output = createOutput(options);
|
|
17496
|
-
const result = await requestWatcherJson({
|
|
17497
|
-
id,
|
|
17498
|
-
path: "/emulation",
|
|
17499
|
-
method: "GET",
|
|
17500
|
-
timeoutMs: 5000,
|
|
17501
|
-
returnErrorResponse: true
|
|
17502
|
-
});
|
|
17503
|
-
if (!result.ok) {
|
|
17504
|
-
writeRequestError(result, output);
|
|
17505
|
-
return;
|
|
17506
|
-
}
|
|
17507
|
-
const response = result.data;
|
|
17508
|
-
if (!response.ok) {
|
|
17509
|
-
const err = response;
|
|
17510
|
-
if (options.json) {
|
|
17511
|
-
output.writeJson(response);
|
|
17589
|
+
lines.push(`touch: ${res.state?.touch?.enabled ? "enabled" : "disabled"}`);
|
|
17590
|
+
if (res.state?.userAgent?.value) {
|
|
17591
|
+
const ua = res.state.userAgent.value;
|
|
17592
|
+
lines.push(`ua: ${ua.length > 80 ? ua.slice(0, 77) + "..." : ua}`);
|
|
17512
17593
|
} else {
|
|
17513
|
-
|
|
17594
|
+
lines.push("ua: default");
|
|
17514
17595
|
}
|
|
17515
|
-
|
|
17516
|
-
|
|
17517
|
-
|
|
17518
|
-
|
|
17519
|
-
|
|
17520
|
-
|
|
17521
|
-
|
|
17522
|
-
|
|
17523
|
-
const lines = [];
|
|
17524
|
-
lines.push(`attached: ${res.attached}`);
|
|
17525
|
-
lines.push(`applied: ${res.applied}`);
|
|
17526
|
-
if (res.state?.viewport) {
|
|
17527
|
-
const vp = res.state.viewport;
|
|
17528
|
-
lines.push(`viewport: ${vp.width}x${vp.height}@${vp.deviceScaleFactor} ${vp.mobile ? "mobile" : "desktop"}`);
|
|
17529
|
-
} else {
|
|
17530
|
-
lines.push("viewport: none");
|
|
17531
|
-
}
|
|
17532
|
-
lines.push(`touch: ${res.state?.touch?.enabled ? "enabled" : "disabled"}`);
|
|
17533
|
-
if (res.state?.userAgent?.value) {
|
|
17534
|
-
const ua = res.state.userAgent.value;
|
|
17535
|
-
lines.push(`ua: ${ua.length > 80 ? ua.slice(0, 77) + "..." : ua}`);
|
|
17536
|
-
} else {
|
|
17537
|
-
lines.push("ua: default");
|
|
17538
|
-
}
|
|
17539
|
-
if (res.baseline.userAgent) {
|
|
17540
|
-
const bua = res.baseline.userAgent;
|
|
17541
|
-
lines.push(`baseline: ${bua.length > 80 ? bua.slice(0, 77) + "..." : bua}`);
|
|
17542
|
-
}
|
|
17543
|
-
if (res.lastError) {
|
|
17544
|
-
lines.push(`error: ${res.lastError.message}`);
|
|
17545
|
-
}
|
|
17546
|
-
output.writeHuman(lines.join(`
|
|
17596
|
+
if (res.baseline.userAgent) {
|
|
17597
|
+
const bua = res.baseline.userAgent;
|
|
17598
|
+
lines.push(`baseline: ${bua.length > 80 ? bua.slice(0, 77) + "..." : bua}`);
|
|
17599
|
+
}
|
|
17600
|
+
if (res.lastError) {
|
|
17601
|
+
lines.push(`error: ${res.lastError.message}`);
|
|
17602
|
+
}
|
|
17603
|
+
output.writeHuman(lines.join(`
|
|
17547
17604
|
`));
|
|
17548
|
-
}
|
|
17605
|
+
}
|
|
17606
|
+
});
|
|
17549
17607
|
var formatViewportLabel = (viewport, touch, ua) => {
|
|
17550
17608
|
const parts = [`${viewport.width}x${viewport.height}@${viewport.deviceScaleFactor}`];
|
|
17551
17609
|
if (viewport.mobile)
|
|
@@ -17915,46 +17973,38 @@ var appendRepeatedParams = (params, key, values) => {
|
|
|
17915
17973
|
};
|
|
17916
17974
|
|
|
17917
17975
|
// dist/commands/logs.js
|
|
17918
|
-
var runLogs =
|
|
17919
|
-
|
|
17976
|
+
var runLogs = defineWatcherCommand({
|
|
17977
|
+
isJson: (options) => options.jsonFull === true,
|
|
17978
|
+
build: (_args, options, output) => buildLogsPlan(options, output),
|
|
17979
|
+
formatJson: (response, { options }) => options.jsonFull ? response.events : response.events.map((event) => previewLogEvent(event)),
|
|
17980
|
+
formatHuman: (response, { output, watcher }) => {
|
|
17981
|
+
for (const event of response.events) {
|
|
17982
|
+
output.writeHuman(formatLogEvent(event, {
|
|
17983
|
+
includeTimestamps: watcher.includeTimestamps
|
|
17984
|
+
}));
|
|
17985
|
+
}
|
|
17986
|
+
}
|
|
17987
|
+
});
|
|
17988
|
+
var buildLogsPlan = (options, output) => {
|
|
17920
17989
|
const params = new URLSearchParams;
|
|
17921
17990
|
appendAfterLimitParams(params, options);
|
|
17922
17991
|
const filters = appendLogFilterParams(params, options);
|
|
17923
17992
|
if (filters.error) {
|
|
17924
17993
|
output.writeWarn(filters.error);
|
|
17925
17994
|
process.exitCode = 2;
|
|
17926
|
-
return;
|
|
17995
|
+
return null;
|
|
17927
17996
|
}
|
|
17928
17997
|
const since = appendSinceParam(params, options.since);
|
|
17929
17998
|
if (since.error) {
|
|
17930
17999
|
output.writeWarn(since.error);
|
|
17931
18000
|
process.exitCode = 2;
|
|
17932
|
-
return;
|
|
18001
|
+
return null;
|
|
17933
18002
|
}
|
|
17934
|
-
|
|
17935
|
-
id,
|
|
18003
|
+
return {
|
|
17936
18004
|
path: "/logs",
|
|
17937
18005
|
query: params,
|
|
17938
18006
|
timeoutMs: 5000
|
|
17939
|
-
}
|
|
17940
|
-
if (!result.ok) {
|
|
17941
|
-
writeRequestError(result, output);
|
|
17942
|
-
return;
|
|
17943
|
-
}
|
|
17944
|
-
if (options.jsonFull) {
|
|
17945
|
-
output.writeJson(result.data.events);
|
|
17946
|
-
return;
|
|
17947
|
-
}
|
|
17948
|
-
if (options.json) {
|
|
17949
|
-
const previewEvents = result.data.events.map((event) => previewLogEvent(event));
|
|
17950
|
-
output.writeJson(previewEvents);
|
|
17951
|
-
return;
|
|
17952
|
-
}
|
|
17953
|
-
for (const event of result.data.events) {
|
|
17954
|
-
output.writeHuman(formatLogEvent(event, {
|
|
17955
|
-
includeTimestamps: result.watcher.includeTimestamps
|
|
17956
|
-
}));
|
|
17957
|
-
}
|
|
18007
|
+
};
|
|
17958
18008
|
};
|
|
17959
18009
|
|
|
17960
18010
|
// dist/commands/tail.js
|
|
@@ -18060,27 +18110,16 @@ Examples:
|
|
|
18060
18110
|
}
|
|
18061
18111
|
|
|
18062
18112
|
// dist/commands/netClear.js
|
|
18063
|
-
var runNetClear =
|
|
18064
|
-
|
|
18065
|
-
|
|
18066
|
-
id
|
|
18067
|
-
path: "/net/clear",
|
|
18068
|
-
method: "POST",
|
|
18069
|
-
timeoutMs: 5000
|
|
18070
|
-
}, output);
|
|
18071
|
-
if (!result) {
|
|
18072
|
-
return;
|
|
18113
|
+
var runNetClear = defineWatcherCommand({
|
|
18114
|
+
build: () => ({ path: "/net/clear", method: "POST", timeoutMs: 5000 }),
|
|
18115
|
+
formatHuman: (response, { output, watcher }) => {
|
|
18116
|
+
output.writeHuman(`cleared ${response.cleared} requests from ${watcher.id}`);
|
|
18073
18117
|
}
|
|
18074
|
-
|
|
18075
|
-
output.writeJson(result.data);
|
|
18076
|
-
return;
|
|
18077
|
-
}
|
|
18078
|
-
output.writeHuman(`cleared ${result.data.cleared} requests from ${result.watcher.id}`);
|
|
18079
|
-
};
|
|
18118
|
+
});
|
|
18080
18119
|
|
|
18081
18120
|
// dist/commands/netExport.js
|
|
18082
18121
|
import fs9 from "node:fs/promises";
|
|
18083
|
-
import
|
|
18122
|
+
import path12 from "node:path";
|
|
18084
18123
|
|
|
18085
18124
|
// dist/eval/evalClient.js
|
|
18086
18125
|
var evalOnce = async (input) => {
|
|
@@ -18256,10 +18295,147 @@ var resolveDerivedNetFilters = (options) => {
|
|
|
18256
18295
|
|
|
18257
18296
|
// dist/commands/evalShared.js
|
|
18258
18297
|
import { readFile as readFile2 } from "node:fs/promises";
|
|
18298
|
+
|
|
18299
|
+
// dist/commands/evalBundle.js
|
|
18300
|
+
import { realpath } from "node:fs/promises";
|
|
18301
|
+
import path11 from "node:path";
|
|
18302
|
+
var esbuildModulePromise;
|
|
18303
|
+
var nodeModulesSegment = `${path11.sep}node_modules${path11.sep}`;
|
|
18304
|
+
var loadEsbuild = () => esbuildModulePromise ??= import("esbuild");
|
|
18305
|
+
var bundleEvalEntry = async (entryPath) => {
|
|
18306
|
+
let entryPoint;
|
|
18307
|
+
try {
|
|
18308
|
+
entryPoint = await realpath(path11.resolve(entryPath));
|
|
18309
|
+
} catch {
|
|
18310
|
+
return { ok: false, error: `Failed to read entry file: ${entryPath}` };
|
|
18311
|
+
}
|
|
18312
|
+
const bundleRoot = path11.dirname(entryPoint);
|
|
18313
|
+
try {
|
|
18314
|
+
const esbuild = await loadEsbuild();
|
|
18315
|
+
const result = await esbuild.build({
|
|
18316
|
+
absWorkingDir: bundleRoot,
|
|
18317
|
+
entryPoints: [entryPoint],
|
|
18318
|
+
bundle: true,
|
|
18319
|
+
write: false,
|
|
18320
|
+
splitting: false,
|
|
18321
|
+
format: "esm",
|
|
18322
|
+
platform: "browser",
|
|
18323
|
+
target: "es2022",
|
|
18324
|
+
sourcemap: false,
|
|
18325
|
+
logLevel: "silent",
|
|
18326
|
+
plugins: [createLocalFilesPlugin(bundleRoot)]
|
|
18327
|
+
});
|
|
18328
|
+
const output = result.outputFiles[0];
|
|
18329
|
+
if (output == null) {
|
|
18330
|
+
return { ok: false, error: "Bundle produced no output." };
|
|
18331
|
+
}
|
|
18332
|
+
const code = `${output.text.trimEnd()}
|
|
18333
|
+
//# sourceURL=argus-file://${entryPoint}
|
|
18334
|
+
`;
|
|
18335
|
+
return { ok: true, code };
|
|
18336
|
+
} catch (error) {
|
|
18337
|
+
return { ok: false, error: formatBundleFailure(error) };
|
|
18338
|
+
}
|
|
18339
|
+
};
|
|
18340
|
+
var createLocalFilesPlugin = (bundleRoot) => {
|
|
18341
|
+
const bundleRootPrefix = bundleRoot.endsWith(path11.sep) ? bundleRoot : `${bundleRoot}${path11.sep}`;
|
|
18342
|
+
return {
|
|
18343
|
+
name: "argus-eval-bundle",
|
|
18344
|
+
setup(build) {
|
|
18345
|
+
build.onResolve({ filter: /.*/ }, (args) => {
|
|
18346
|
+
if (args.kind === "entry-point") {
|
|
18347
|
+
return;
|
|
18348
|
+
}
|
|
18349
|
+
if (args.path.startsWith("node:")) {
|
|
18350
|
+
return bundleError(`Node built-in import ${JSON.stringify(args.path)} is not allowed in page eval.`);
|
|
18351
|
+
}
|
|
18352
|
+
if (!args.path.startsWith(".") && !path11.isAbsolute(args.path)) {
|
|
18353
|
+
return bundleError(`Import ${JSON.stringify(args.path)} is not allowed. Use relative local files under ${bundleRoot}.`);
|
|
18354
|
+
}
|
|
18355
|
+
return;
|
|
18356
|
+
});
|
|
18357
|
+
build.onLoad({ filter: /.*/ }, async (args) => {
|
|
18358
|
+
let resolvedPath;
|
|
18359
|
+
try {
|
|
18360
|
+
resolvedPath = await realpath(args.path);
|
|
18361
|
+
} catch {
|
|
18362
|
+
return bundleError(`Failed to read file: ${args.path}`);
|
|
18363
|
+
}
|
|
18364
|
+
if (resolvedPath !== bundleRoot && !resolvedPath.startsWith(bundleRootPrefix)) {
|
|
18365
|
+
return bundleError(`Import escapes the entry directory: ${args.path}`);
|
|
18366
|
+
}
|
|
18367
|
+
if (resolvedPath.includes(nodeModulesSegment)) {
|
|
18368
|
+
return bundleError(`Import from node_modules is not allowed: ${args.path}`);
|
|
18369
|
+
}
|
|
18370
|
+
return;
|
|
18371
|
+
});
|
|
18372
|
+
build.onEnd((result) => {
|
|
18373
|
+
if (result.errors.length > 0) {
|
|
18374
|
+
return;
|
|
18375
|
+
}
|
|
18376
|
+
const outputs = result.outputFiles ?? [];
|
|
18377
|
+
if (outputs.length !== 1) {
|
|
18378
|
+
return bundleError(`Bundle produced ${outputs.length} outputs; expected exactly one script.`);
|
|
18379
|
+
}
|
|
18380
|
+
if (/\bexport\b/.test(outputs[0]?.text ?? "")) {
|
|
18381
|
+
return bundleError("Bundled script contains top-level export statements, which page eval cannot run. Remove exports from the entry file (helpers may still export symbols for import).");
|
|
18382
|
+
}
|
|
18383
|
+
});
|
|
18384
|
+
}
|
|
18385
|
+
};
|
|
18386
|
+
};
|
|
18387
|
+
var bundleError = (text) => ({ errors: [{ text }] });
|
|
18388
|
+
var formatBundleFailure = (error) => {
|
|
18389
|
+
if (isEsbuildFailure(error)) {
|
|
18390
|
+
return error.errors.map(formatEsbuildMessage).join(`
|
|
18391
|
+
`);
|
|
18392
|
+
}
|
|
18393
|
+
return error instanceof Error ? error.message : String(error);
|
|
18394
|
+
};
|
|
18395
|
+
var isEsbuildFailure = (error) => error instanceof Error && ("errors" in error) && Array.isArray(error.errors) && error.errors.length > 0;
|
|
18396
|
+
var formatEsbuildMessage = (issue) => {
|
|
18397
|
+
const message = issue.text || "Bundle failed.";
|
|
18398
|
+
const { file, line, column } = issue.location ?? {};
|
|
18399
|
+
if (!file) {
|
|
18400
|
+
return message;
|
|
18401
|
+
}
|
|
18402
|
+
if (line == null || column == null) {
|
|
18403
|
+
return `${file}: ${message}`;
|
|
18404
|
+
}
|
|
18405
|
+
return `${file}:${line}:${column}: ${message}`;
|
|
18406
|
+
};
|
|
18407
|
+
|
|
18408
|
+
// dist/commands/evalShared.js
|
|
18409
|
+
var prepareEvalExpression = async (inline, options, output) => {
|
|
18410
|
+
const evalArgs = parseEvalArgs(options.arg);
|
|
18411
|
+
if (evalArgs.error) {
|
|
18412
|
+
output.writeWarn(evalArgs.error);
|
|
18413
|
+
return null;
|
|
18414
|
+
}
|
|
18415
|
+
const resolvedExpression = await resolveExpression(inline, options, output);
|
|
18416
|
+
if (resolvedExpression == null) {
|
|
18417
|
+
return null;
|
|
18418
|
+
}
|
|
18419
|
+
const args = evalArgs.value;
|
|
18420
|
+
if (!options.iframe) {
|
|
18421
|
+
return {
|
|
18422
|
+
expression: resolvedExpression,
|
|
18423
|
+
args: hasEvalArgs2(args) ? args : undefined
|
|
18424
|
+
};
|
|
18425
|
+
}
|
|
18426
|
+
return {
|
|
18427
|
+
expression: wrapForIframeEval(wrapExpressionWithArgs(resolvedExpression, args), {
|
|
18428
|
+
selector: options.iframe,
|
|
18429
|
+
namespace: options.iframeNamespace ?? "argus",
|
|
18430
|
+
timeoutMs: parseNumber(options.iframeTimeout) ?? 5000
|
|
18431
|
+
})
|
|
18432
|
+
};
|
|
18433
|
+
};
|
|
18259
18434
|
var resolveExpression = async (inline, options, output) => {
|
|
18260
18435
|
const wantsStdin = options.stdin === true || inline === "-";
|
|
18261
18436
|
const hasInline = inline != null && inline !== "-";
|
|
18262
|
-
const
|
|
18437
|
+
const filePath = options.file;
|
|
18438
|
+
const hasFile = filePath != null;
|
|
18263
18439
|
if (hasInline && hasFile) {
|
|
18264
18440
|
output.writeWarn("Cannot combine an inline expression with --file");
|
|
18265
18441
|
return null;
|
|
@@ -18272,41 +18448,74 @@ var resolveExpression = async (inline, options, output) => {
|
|
|
18272
18448
|
output.writeWarn("Cannot combine --file with stdin input");
|
|
18273
18449
|
return null;
|
|
18274
18450
|
}
|
|
18275
|
-
if (hasFile) {
|
|
18451
|
+
if (options.bundle && !hasFile) {
|
|
18452
|
+
output.writeWarn("--bundle requires --file");
|
|
18453
|
+
return null;
|
|
18454
|
+
}
|
|
18455
|
+
let expression;
|
|
18456
|
+
if (hasFile && options.bundle) {
|
|
18457
|
+
const bundled = await bundleEvalEntry(filePath);
|
|
18458
|
+
if (!bundled.ok) {
|
|
18459
|
+
output.writeWarn(`Failed to bundle --file: ${bundled.error}`);
|
|
18460
|
+
return null;
|
|
18461
|
+
}
|
|
18462
|
+
if (!bundled.code.trim()) {
|
|
18463
|
+
output.writeWarn(`Bundled file is empty: ${options.file}`);
|
|
18464
|
+
return null;
|
|
18465
|
+
}
|
|
18466
|
+
expression = bundled.code;
|
|
18467
|
+
} else if (hasFile) {
|
|
18276
18468
|
try {
|
|
18277
|
-
const content = await readFile2(
|
|
18469
|
+
const content = await readFile2(filePath, "utf8");
|
|
18278
18470
|
if (!content.trim()) {
|
|
18279
18471
|
output.writeWarn(`File is empty: ${options.file}`);
|
|
18280
18472
|
return null;
|
|
18281
18473
|
}
|
|
18282
|
-
|
|
18474
|
+
expression = content;
|
|
18283
18475
|
} catch (error) {
|
|
18284
18476
|
output.writeWarn(`Failed to read --file: ${formatError(error)}`);
|
|
18285
18477
|
return null;
|
|
18286
18478
|
}
|
|
18287
|
-
}
|
|
18288
|
-
if (wantsStdin) {
|
|
18479
|
+
} else if (wantsStdin) {
|
|
18289
18480
|
try {
|
|
18290
18481
|
const content = await readStdin();
|
|
18291
18482
|
if (!content.trim()) {
|
|
18292
18483
|
output.writeWarn("Stdin input is empty");
|
|
18293
18484
|
return null;
|
|
18294
18485
|
}
|
|
18295
|
-
|
|
18486
|
+
expression = content;
|
|
18296
18487
|
} catch (error) {
|
|
18297
18488
|
output.writeWarn(`Failed to read stdin: ${formatError(error)}`);
|
|
18298
18489
|
return null;
|
|
18299
18490
|
}
|
|
18300
|
-
}
|
|
18301
|
-
if (hasInline) {
|
|
18491
|
+
} else if (hasInline) {
|
|
18302
18492
|
if (!inline.trim()) {
|
|
18303
18493
|
output.writeWarn("Expression is empty");
|
|
18304
18494
|
return null;
|
|
18305
18495
|
}
|
|
18306
|
-
|
|
18496
|
+
expression = inline;
|
|
18497
|
+
} else {
|
|
18498
|
+
output.writeWarn("Expression is required. Provide an inline expression, --file, or --stdin (or pass - as expression).");
|
|
18499
|
+
return null;
|
|
18500
|
+
}
|
|
18501
|
+
return await prependInjectSource(expression, options.inject, output);
|
|
18502
|
+
};
|
|
18503
|
+
var prependInjectSource = async (expression, injectPath, output) => {
|
|
18504
|
+
if (injectPath == null) {
|
|
18505
|
+
return expression;
|
|
18506
|
+
}
|
|
18507
|
+
try {
|
|
18508
|
+
const injectSource = await readFile2(injectPath, "utf8");
|
|
18509
|
+
if (!injectSource.trim()) {
|
|
18510
|
+
output.writeWarn(`Inject file is empty: ${injectPath}`);
|
|
18511
|
+
return null;
|
|
18512
|
+
}
|
|
18513
|
+
return `${injectSource}
|
|
18514
|
+
${expression}`;
|
|
18515
|
+
} catch (error) {
|
|
18516
|
+
output.writeWarn(`Failed to read --inject: ${formatError(error)}`);
|
|
18517
|
+
return null;
|
|
18307
18518
|
}
|
|
18308
|
-
output.writeWarn("Expression is required. Provide an inline expression, --file, or --stdin (or pass - as expression).");
|
|
18309
|
-
return null;
|
|
18310
18519
|
};
|
|
18311
18520
|
var readStdin = async () => new Promise((resolve2, reject) => {
|
|
18312
18521
|
let data = "";
|
|
@@ -18822,7 +19031,7 @@ var validateNetExportOptions = (options) => {
|
|
|
18822
19031
|
return { value: { out, format: "har" } };
|
|
18823
19032
|
};
|
|
18824
19033
|
var writeHarFile = async (outPath, har) => {
|
|
18825
|
-
await fs9.mkdir(
|
|
19034
|
+
await fs9.mkdir(path12.dirname(outPath), { recursive: true });
|
|
18826
19035
|
await fs9.writeFile(outPath, `${JSON.stringify(har, null, 2)}
|
|
18827
19036
|
`, "utf8");
|
|
18828
19037
|
};
|
|
@@ -19169,10 +19378,10 @@ var fetchNetRequestBody = async (watcher, query, part, output, config = {}) => {
|
|
|
19169
19378
|
bodyQuery.set("part", part);
|
|
19170
19379
|
return await fetchNetRequestRoute(watcher, "/net/request/body", bodyQuery, NET_REQUEST_BODY_TIMEOUT_MS, output, config);
|
|
19171
19380
|
};
|
|
19172
|
-
var fetchNetRequestRoute = async (watcher,
|
|
19381
|
+
var fetchNetRequestRoute = async (watcher, path13, query, timeoutMs, output, config = {}) => {
|
|
19173
19382
|
try {
|
|
19174
19383
|
const response = await fetchWatcherJson(watcher, {
|
|
19175
|
-
path:
|
|
19384
|
+
path: path13,
|
|
19176
19385
|
query,
|
|
19177
19386
|
timeoutMs,
|
|
19178
19387
|
returnErrorResponse: true
|
|
@@ -19380,32 +19589,28 @@ var writeInspectNoMatch = (output, pattern, settleMs, timedOut) => {
|
|
|
19380
19589
|
};
|
|
19381
19590
|
|
|
19382
19591
|
// dist/commands/net.js
|
|
19383
|
-
var runNet =
|
|
19384
|
-
|
|
19592
|
+
var runNet = defineWatcherCommand({
|
|
19593
|
+
build: (_args, options, output) => buildNetPlan(options, output),
|
|
19594
|
+
formatJson: (response) => response.requests,
|
|
19595
|
+
formatHuman: (response, { output }) => {
|
|
19596
|
+
for (const request of response.requests) {
|
|
19597
|
+
output.writeHuman(formatNetworkRequest(request));
|
|
19598
|
+
}
|
|
19599
|
+
}
|
|
19600
|
+
});
|
|
19601
|
+
var buildNetPlan = (options, output) => {
|
|
19385
19602
|
const params = new URLSearchParams;
|
|
19386
19603
|
const query = appendNetCommandParams(params, options);
|
|
19387
19604
|
if (query.error) {
|
|
19388
19605
|
output.writeWarn(query.error);
|
|
19389
19606
|
process.exitCode = 2;
|
|
19390
|
-
return;
|
|
19607
|
+
return null;
|
|
19391
19608
|
}
|
|
19392
|
-
|
|
19393
|
-
id,
|
|
19609
|
+
return {
|
|
19394
19610
|
path: "/net",
|
|
19395
19611
|
query: params,
|
|
19396
19612
|
timeoutMs: 5000
|
|
19397
|
-
}
|
|
19398
|
-
if (!result.ok) {
|
|
19399
|
-
writeRequestError(result, output);
|
|
19400
|
-
return;
|
|
19401
|
-
}
|
|
19402
|
-
if (options.json) {
|
|
19403
|
-
output.writeJson(result.data.requests);
|
|
19404
|
-
return;
|
|
19405
|
-
}
|
|
19406
|
-
for (const request of result.data.requests) {
|
|
19407
|
-
output.writeHuman(formatNetworkRequest(request));
|
|
19408
|
-
}
|
|
19613
|
+
};
|
|
19409
19614
|
};
|
|
19410
19615
|
|
|
19411
19616
|
// dist/commands/netRequestTarget.js
|
|
@@ -19717,7 +19922,7 @@ var runNetSse = async (id, options) => {
|
|
|
19717
19922
|
process.exitCode = 2;
|
|
19718
19923
|
return;
|
|
19719
19924
|
}
|
|
19720
|
-
const result = await
|
|
19925
|
+
const result = await requestWatcherCommandAction({ id, path: "/net/sse", query: params, timeoutMs: 5000 }, output);
|
|
19721
19926
|
if (!result) {
|
|
19722
19927
|
return;
|
|
19723
19928
|
}
|
|
@@ -19836,7 +20041,7 @@ var runNetWebSocket = async (id, options) => {
|
|
|
19836
20041
|
process.exitCode = 2;
|
|
19837
20042
|
return;
|
|
19838
20043
|
}
|
|
19839
|
-
const result = await
|
|
20044
|
+
const result = await requestWatcherCommandAction({ id, path: "/net/ws", query: params, timeoutMs: 5000 }, output);
|
|
19840
20045
|
if (!result) {
|
|
19841
20046
|
return;
|
|
19842
20047
|
}
|
|
@@ -19854,7 +20059,7 @@ var runNetWebSocketShow = async (id, connection, options) => {
|
|
|
19854
20059
|
if (!query) {
|
|
19855
20060
|
return;
|
|
19856
20061
|
}
|
|
19857
|
-
const result = await
|
|
20062
|
+
const result = await requestWatcherCommandAction({ id, path: "/net/ws/connection", query, timeoutMs: 5000 }, output);
|
|
19858
20063
|
if (!result) {
|
|
19859
20064
|
return;
|
|
19860
20065
|
}
|
|
@@ -20142,35 +20347,33 @@ var toCamelCase = (flag) => flag.replace(/^--/, "").replace(/-([a-z])/g, (_match
|
|
|
20142
20347
|
import { writeFile as writeFile2 } from "node:fs/promises";
|
|
20143
20348
|
var COOKIE_EXPORT_FORMATS = new Set(["netscape", "json", "header"]);
|
|
20144
20349
|
var fetchAuthCookies = async (id, input, output) => {
|
|
20145
|
-
const result = await
|
|
20350
|
+
const result = await requestWatcherCommandJson({
|
|
20146
20351
|
id,
|
|
20147
20352
|
path: "/auth/cookies",
|
|
20148
20353
|
query: buildCookieQuery(input),
|
|
20149
20354
|
timeoutMs: 1e4
|
|
20150
|
-
});
|
|
20151
|
-
if (!result
|
|
20152
|
-
writeRequestError(result, output);
|
|
20355
|
+
}, output);
|
|
20356
|
+
if (!result)
|
|
20153
20357
|
return null;
|
|
20154
|
-
}
|
|
20155
20358
|
return result.data;
|
|
20156
20359
|
};
|
|
20157
20360
|
var normalizeCookieIdentityInput = (input, output) => {
|
|
20158
20361
|
const name = input.name.trim();
|
|
20159
20362
|
const domain = input.domain.trim();
|
|
20160
|
-
const
|
|
20363
|
+
const path13 = input.path.trim();
|
|
20161
20364
|
if (!name) {
|
|
20162
20365
|
return writeCookieInputError(output, "name is required");
|
|
20163
20366
|
}
|
|
20164
20367
|
if (!domain) {
|
|
20165
20368
|
return writeCookieInputError(output, "domain is required");
|
|
20166
20369
|
}
|
|
20167
|
-
if (!
|
|
20370
|
+
if (!path13) {
|
|
20168
20371
|
return writeCookieInputError(output, "path is required");
|
|
20169
20372
|
}
|
|
20170
|
-
if (!
|
|
20373
|
+
if (!path13.startsWith("/")) {
|
|
20171
20374
|
return writeCookieInputError(output, 'path must start with "/"');
|
|
20172
20375
|
}
|
|
20173
|
-
return { name, domain, path:
|
|
20376
|
+
return { name, domain, path: path13 };
|
|
20174
20377
|
};
|
|
20175
20378
|
var parseCookieSetInput = (input, output) => {
|
|
20176
20379
|
const identity = normalizeCookieIdentityInput(input, output);
|
|
@@ -20380,116 +20583,104 @@ var runAuthExportCookies = async (id, options) => {
|
|
|
20380
20583
|
const serialized = serializeCookies(filterCookies(response.origin, response.cookies, options), format);
|
|
20381
20584
|
await writeOutput2(serialized, options.out);
|
|
20382
20585
|
};
|
|
20383
|
-
var runAuthCookieGet =
|
|
20384
|
-
|
|
20385
|
-
|
|
20386
|
-
|
|
20387
|
-
|
|
20388
|
-
}
|
|
20389
|
-
const result = await requestWatcherAction({
|
|
20390
|
-
id,
|
|
20391
|
-
path: "/auth/cookies/get",
|
|
20392
|
-
method: "POST",
|
|
20393
|
-
body: {
|
|
20394
|
-
...identity,
|
|
20395
|
-
includeValue: options.showValue === true
|
|
20586
|
+
var runAuthCookieGet = defineWatcherCommand({
|
|
20587
|
+
build: ([name], options, output) => {
|
|
20588
|
+
const identity = normalizeCookieIdentityInput({ name, domain: options.domain, path: options.path }, output);
|
|
20589
|
+
if (!identity) {
|
|
20590
|
+
return null;
|
|
20396
20591
|
}
|
|
20397
|
-
|
|
20398
|
-
|
|
20399
|
-
|
|
20400
|
-
|
|
20401
|
-
|
|
20402
|
-
|
|
20403
|
-
|
|
20404
|
-
|
|
20405
|
-
|
|
20406
|
-
|
|
20407
|
-
|
|
20408
|
-
|
|
20409
|
-
|
|
20410
|
-
}
|
|
20411
|
-
|
|
20412
|
-
const output = createOutput(options);
|
|
20413
|
-
const cookie = parseCookieSetInput({ name, value, ...options }, output);
|
|
20414
|
-
if (!cookie) {
|
|
20415
|
-
return;
|
|
20416
|
-
}
|
|
20417
|
-
const result = await requestWatcherAction({
|
|
20418
|
-
id,
|
|
20419
|
-
path: "/auth/cookies/set",
|
|
20420
|
-
method: "POST",
|
|
20421
|
-
body: { cookie }
|
|
20422
|
-
}, output);
|
|
20423
|
-
if (!result) {
|
|
20424
|
-
return;
|
|
20425
|
-
}
|
|
20426
|
-
if (options.json) {
|
|
20427
|
-
output.writeJson(result.data);
|
|
20428
|
-
return;
|
|
20429
|
-
}
|
|
20430
|
-
output.writeHuman(`Set ${formatCookieLine(result.data.cookie, false)}`);
|
|
20431
|
-
};
|
|
20432
|
-
var runAuthCookieDelete = async (id, name, options) => {
|
|
20433
|
-
const output = createOutput(options);
|
|
20434
|
-
const identity = normalizeCookieIdentityInput({ name, domain: options.domain, path: options.path }, output);
|
|
20435
|
-
if (!identity) {
|
|
20436
|
-
return;
|
|
20437
|
-
}
|
|
20438
|
-
const result = await requestWatcherAction({
|
|
20439
|
-
id,
|
|
20440
|
-
path: "/auth/cookies/delete",
|
|
20441
|
-
method: "POST",
|
|
20442
|
-
body: identity
|
|
20443
|
-
}, output);
|
|
20444
|
-
if (!result) {
|
|
20445
|
-
return;
|
|
20446
|
-
}
|
|
20447
|
-
if (options.json) {
|
|
20448
|
-
output.writeJson(result.data);
|
|
20449
|
-
return;
|
|
20450
|
-
}
|
|
20451
|
-
if (!result.data.deleted) {
|
|
20452
|
-
output.writeHuman("No cookie matched exact identity.");
|
|
20453
|
-
return;
|
|
20454
|
-
}
|
|
20455
|
-
output.writeHuman(`Deleted ${formatCookieIdentityLine(result.data.cookie)}`);
|
|
20456
|
-
};
|
|
20457
|
-
var runAuthCookieClear = async (id, options) => {
|
|
20458
|
-
const output = createOutput(options);
|
|
20459
|
-
const scope = resolveCookieClearScope(options, output);
|
|
20460
|
-
if (!scope) {
|
|
20461
|
-
return;
|
|
20592
|
+
return {
|
|
20593
|
+
path: "/auth/cookies/get",
|
|
20594
|
+
method: "POST",
|
|
20595
|
+
body: {
|
|
20596
|
+
...identity,
|
|
20597
|
+
includeValue: options.showValue === true
|
|
20598
|
+
}
|
|
20599
|
+
};
|
|
20600
|
+
},
|
|
20601
|
+
formatHuman: (response, { output, options }) => {
|
|
20602
|
+
if (!response.cookie) {
|
|
20603
|
+
output.writeHuman("No cookie matched exact identity.");
|
|
20604
|
+
return;
|
|
20605
|
+
}
|
|
20606
|
+
output.writeHuman(formatCookieLine(response.cookie, options.showValue === true));
|
|
20462
20607
|
}
|
|
20463
|
-
|
|
20464
|
-
|
|
20465
|
-
|
|
20466
|
-
|
|
20467
|
-
|
|
20468
|
-
|
|
20469
|
-
domain: scope === "domain" ? options.domain : undefined,
|
|
20470
|
-
sessionOnly: options.sessionOnly === true,
|
|
20471
|
-
authOnly: options.authOnly === true
|
|
20608
|
+
});
|
|
20609
|
+
var runAuthCookieSet = defineWatcherCommand({
|
|
20610
|
+
build: ([name, value], options, output) => {
|
|
20611
|
+
const cookie = parseCookieSetInput({ name, value, ...options }, output);
|
|
20612
|
+
if (!cookie) {
|
|
20613
|
+
return null;
|
|
20472
20614
|
}
|
|
20473
|
-
|
|
20474
|
-
|
|
20475
|
-
|
|
20615
|
+
return {
|
|
20616
|
+
path: "/auth/cookies/set",
|
|
20617
|
+
method: "POST",
|
|
20618
|
+
body: { cookie }
|
|
20619
|
+
};
|
|
20620
|
+
},
|
|
20621
|
+
formatHuman: (response, { output }) => {
|
|
20622
|
+
output.writeHuman(`Set ${formatCookieLine(response.cookie, false)}`);
|
|
20476
20623
|
}
|
|
20477
|
-
|
|
20478
|
-
|
|
20479
|
-
|
|
20624
|
+
});
|
|
20625
|
+
var runAuthCookieDelete = defineWatcherCommand({
|
|
20626
|
+
build: ([name], options, output) => {
|
|
20627
|
+
const identity = normalizeCookieIdentityInput({ name, domain: options.domain, path: options.path }, output);
|
|
20628
|
+
if (!identity) {
|
|
20629
|
+
return null;
|
|
20630
|
+
}
|
|
20631
|
+
return {
|
|
20632
|
+
path: "/auth/cookies/delete",
|
|
20633
|
+
method: "POST",
|
|
20634
|
+
body: identity
|
|
20635
|
+
};
|
|
20636
|
+
},
|
|
20637
|
+
formatHuman: (response, { output }) => {
|
|
20638
|
+
if (!response.deleted) {
|
|
20639
|
+
output.writeHuman("No cookie matched exact identity.");
|
|
20640
|
+
return;
|
|
20641
|
+
}
|
|
20642
|
+
output.writeHuman(`Deleted ${formatCookieIdentityLine(response.cookie)}`);
|
|
20480
20643
|
}
|
|
20481
|
-
|
|
20482
|
-
|
|
20483
|
-
|
|
20484
|
-
output
|
|
20644
|
+
});
|
|
20645
|
+
var runAuthCookieClear = defineWatcherCommand({
|
|
20646
|
+
build: (_args, options, output) => {
|
|
20647
|
+
const scope = resolveCookieClearScope(options, output);
|
|
20648
|
+
if (!scope) {
|
|
20649
|
+
return null;
|
|
20650
|
+
}
|
|
20651
|
+
return {
|
|
20652
|
+
path: "/auth/cookies/clear",
|
|
20653
|
+
method: "POST",
|
|
20654
|
+
body: {
|
|
20655
|
+
scope,
|
|
20656
|
+
domain: scope === "domain" ? options.domain : undefined,
|
|
20657
|
+
sessionOnly: options.sessionOnly === true,
|
|
20658
|
+
authOnly: options.authOnly === true
|
|
20659
|
+
}
|
|
20660
|
+
};
|
|
20661
|
+
},
|
|
20662
|
+
formatHuman: (response, { output }) => {
|
|
20663
|
+
const scopeSuffix = response.scopeValue ? ` (${response.scopeValue})` : "";
|
|
20664
|
+
output.writeHuman(`Cleared ${response.cleared} cookie(s) from ${response.scope}${scopeSuffix}`);
|
|
20665
|
+
for (const cookie of response.cookies) {
|
|
20666
|
+
output.writeHuman(formatCookieIdentityLine(cookie));
|
|
20667
|
+
}
|
|
20485
20668
|
}
|
|
20486
|
-
};
|
|
20669
|
+
});
|
|
20487
20670
|
|
|
20488
20671
|
// dist/cli/register/registerAuth.js
|
|
20489
20672
|
function registerAuth(program2) {
|
|
20490
20673
|
const auth = program2.command("auth").description("Inspect, export, and load browser auth state");
|
|
20491
|
-
const cookies2 = auth.command("cookies").description("Inspect and mutate browser cookies")
|
|
20492
|
-
|
|
20674
|
+
const cookies2 = addCookieListOptions(auth.command("cookies").argument("[id]", "Watcher id").description("Inspect and mutate browser cookies"), "Only include first-party cookies for the attached page origin").addHelpText("after", `
|
|
20675
|
+
Examples:
|
|
20676
|
+
$ argus auth cookies app
|
|
20677
|
+
$ argus auth cookies app --for-origin --exclude-tracking
|
|
20678
|
+
$ argus auth cookies app --domain example.com
|
|
20679
|
+
$ argus auth cookies app --session-only --show-values
|
|
20680
|
+
`).action(async (id, options) => {
|
|
20681
|
+
await runAuthCookies(id, options);
|
|
20682
|
+
});
|
|
20683
|
+
addCookieListOptions(cookies2.command("list").alias("ls"), "Only include first-party cookies for the attached page origin").argument("[id]", "Watcher id").description("List cookies for the attached page").addHelpText("after", `
|
|
20493
20684
|
Examples:
|
|
20494
20685
|
$ argus auth cookies list app
|
|
20495
20686
|
$ argus auth cookies ls app --for-origin --exclude-tracking
|
|
@@ -20571,27 +20762,71 @@ Examples:
|
|
|
20571
20762
|
});
|
|
20572
20763
|
}
|
|
20573
20764
|
var addCookieScopeOptions = (command, forOriginDescription) => command.option("--for-origin", forOriginDescription).option("--exclude-tracking", "Hide common analytics/tracking cookies such as _ga and _ym");
|
|
20765
|
+
var addCookieListOptions = (command, forOriginDescription) => addCookieScopeOptions(command, forOriginDescription).option("--domain <domain>", "Filter cookies by domain suffix").option("--session-only", "Show only session cookies").option("--http-only", "Show only HttpOnly cookies").option("--secure", "Show only Secure cookies").option("--show-values", "Reveal raw cookie values instead of previews").option("--json", "Output JSON for automation");
|
|
20766
|
+
|
|
20767
|
+
// dist/commands/evalPolling.js
|
|
20768
|
+
var pollEval = async (input) => {
|
|
20769
|
+
let running = true;
|
|
20770
|
+
const stop = () => {
|
|
20771
|
+
running = false;
|
|
20772
|
+
};
|
|
20773
|
+
process.on("SIGINT", stop);
|
|
20774
|
+
process.on("SIGTERM", stop);
|
|
20775
|
+
try {
|
|
20776
|
+
const startTime = Date.now();
|
|
20777
|
+
let iteration = 0;
|
|
20778
|
+
while (running) {
|
|
20779
|
+
if (input.totalTimeoutMs != null) {
|
|
20780
|
+
const elapsed = Date.now() - startTime;
|
|
20781
|
+
if (elapsed >= input.totalTimeoutMs) {
|
|
20782
|
+
return { kind: "timeout", elapsedMs: elapsed };
|
|
20783
|
+
}
|
|
20784
|
+
}
|
|
20785
|
+
iteration += 1;
|
|
20786
|
+
const result = await evalWithRetries({
|
|
20787
|
+
watcher: input.watcher,
|
|
20788
|
+
expression: input.expression,
|
|
20789
|
+
args: input.args,
|
|
20790
|
+
awaitPromise: input.awaitPromise,
|
|
20791
|
+
returnByValue: input.returnByValue,
|
|
20792
|
+
timeoutMs: input.timeoutMs,
|
|
20793
|
+
failOnException: input.failOnException,
|
|
20794
|
+
retryCount: input.retryCount
|
|
20795
|
+
});
|
|
20796
|
+
if (!result.ok) {
|
|
20797
|
+
return { kind: "eval-error", failure: result };
|
|
20798
|
+
}
|
|
20799
|
+
const context = { response: result.response, iteration, attempt: result.attempt };
|
|
20800
|
+
input.onResult?.(result.response, context);
|
|
20801
|
+
const stopResult = input.shouldStop?.(context);
|
|
20802
|
+
if (stopResult) {
|
|
20803
|
+
if (!stopResult.ok) {
|
|
20804
|
+
return { kind: "condition-error", error: stopResult.error };
|
|
20805
|
+
}
|
|
20806
|
+
if (stopResult.matched) {
|
|
20807
|
+
return { kind: "matched", response: result.response, iteration, attempt: result.attempt };
|
|
20808
|
+
}
|
|
20809
|
+
}
|
|
20810
|
+
if (input.count != null && iteration >= input.count) {
|
|
20811
|
+
return { kind: "exhausted", iterations: iteration };
|
|
20812
|
+
}
|
|
20813
|
+
await sleep3(input.intervalMs);
|
|
20814
|
+
}
|
|
20815
|
+
return { kind: "interrupted" };
|
|
20816
|
+
} finally {
|
|
20817
|
+
process.off("SIGINT", stop);
|
|
20818
|
+
process.off("SIGTERM", stop);
|
|
20819
|
+
}
|
|
20820
|
+
};
|
|
20574
20821
|
|
|
20575
20822
|
// dist/commands/eval.js
|
|
20576
20823
|
var runEval = async (id, rawExpression, options) => {
|
|
20577
20824
|
const output = createOutput(options);
|
|
20578
|
-
const
|
|
20579
|
-
if (
|
|
20580
|
-
output.writeWarn(evalArgs.error);
|
|
20581
|
-
process.exitCode = 2;
|
|
20582
|
-
return;
|
|
20583
|
-
}
|
|
20584
|
-
const resolvedExpression = await resolveExpression(rawExpression, options, output);
|
|
20585
|
-
if (resolvedExpression == null) {
|
|
20825
|
+
const prepared = await prepareEvalExpression(rawExpression, options, output);
|
|
20826
|
+
if (prepared == null) {
|
|
20586
20827
|
process.exitCode = 2;
|
|
20587
20828
|
return;
|
|
20588
20829
|
}
|
|
20589
|
-
const requestArgs = !options.iframe && hasEvalArgs2(evalArgs.value) ? evalArgs.value : undefined;
|
|
20590
|
-
const expression = options.iframe ? wrapForIframeEval(wrapExpressionWithArgs(resolvedExpression, evalArgs.value), {
|
|
20591
|
-
selector: options.iframe,
|
|
20592
|
-
namespace: options.iframeNamespace ?? "argus",
|
|
20593
|
-
timeoutMs: parseNumber(options.iframeTimeout) ?? 5000
|
|
20594
|
-
}) : resolvedExpression;
|
|
20595
20830
|
const retryCount = parseRetryCount(options.retry);
|
|
20596
20831
|
if (retryCount.error) {
|
|
20597
20832
|
output.writeWarn(retryCount.error);
|
|
@@ -20634,8 +20869,8 @@ var runEval = async (id, rawExpression, options) => {
|
|
|
20634
20869
|
if (intervalMs.value == null) {
|
|
20635
20870
|
const singleResult = await evalWithRetries({
|
|
20636
20871
|
watcher,
|
|
20637
|
-
expression,
|
|
20638
|
-
args:
|
|
20872
|
+
expression: prepared.expression,
|
|
20873
|
+
args: prepared.args,
|
|
20639
20874
|
awaitPromise: options.await ?? true,
|
|
20640
20875
|
returnByValue: options.returnByValue ?? true,
|
|
20641
20876
|
timeoutMs,
|
|
@@ -20650,51 +20885,45 @@ var runEval = async (id, rawExpression, options) => {
|
|
|
20650
20885
|
printSuccess(singleResult.response, options, output, false);
|
|
20651
20886
|
return;
|
|
20652
20887
|
}
|
|
20653
|
-
|
|
20654
|
-
|
|
20655
|
-
|
|
20656
|
-
|
|
20657
|
-
|
|
20658
|
-
|
|
20659
|
-
|
|
20660
|
-
|
|
20661
|
-
|
|
20662
|
-
|
|
20663
|
-
|
|
20664
|
-
|
|
20665
|
-
|
|
20666
|
-
|
|
20667
|
-
|
|
20668
|
-
|
|
20669
|
-
|
|
20670
|
-
|
|
20671
|
-
});
|
|
20672
|
-
if (!iterationResult.ok) {
|
|
20673
|
-
printError(iterationResult, options, output);
|
|
20674
|
-
process.exitCode = 1;
|
|
20675
|
-
return;
|
|
20676
|
-
}
|
|
20677
|
-
printSuccess(iterationResult.response, options, output, true);
|
|
20678
|
-
if (untilEvaluator.evaluator) {
|
|
20888
|
+
const pollResult = await pollEval({
|
|
20889
|
+
watcher,
|
|
20890
|
+
expression: prepared.expression,
|
|
20891
|
+
args: prepared.args,
|
|
20892
|
+
awaitPromise: options.await ?? true,
|
|
20893
|
+
returnByValue: options.returnByValue ?? true,
|
|
20894
|
+
timeoutMs,
|
|
20895
|
+
failOnException: options.failOnException ?? true,
|
|
20896
|
+
retryCount: retryCount.value,
|
|
20897
|
+
intervalMs: intervalMs.value,
|
|
20898
|
+
count: countValue.value,
|
|
20899
|
+
onResult: (response) => {
|
|
20900
|
+
printSuccess(response, options, output, true);
|
|
20901
|
+
},
|
|
20902
|
+
shouldStop: (context) => {
|
|
20903
|
+
if (!untilEvaluator.evaluator) {
|
|
20904
|
+
return { ok: true, matched: false };
|
|
20905
|
+
}
|
|
20679
20906
|
const untilResult = untilEvaluator.evaluator({
|
|
20680
|
-
result:
|
|
20681
|
-
exception:
|
|
20682
|
-
iteration,
|
|
20683
|
-
attempt:
|
|
20907
|
+
result: context.response.result,
|
|
20908
|
+
exception: context.response.exception ?? null,
|
|
20909
|
+
iteration: context.iteration,
|
|
20910
|
+
attempt: context.attempt
|
|
20684
20911
|
});
|
|
20685
|
-
|
|
20686
|
-
printError({ kind: "until", error: untilResult.error }, options, output);
|
|
20687
|
-
process.exitCode = 1;
|
|
20688
|
-
return;
|
|
20689
|
-
}
|
|
20690
|
-
if (untilResult.matched) {
|
|
20691
|
-
return;
|
|
20692
|
-
}
|
|
20693
|
-
}
|
|
20694
|
-
if (countValue.value != null && iteration >= countValue.value) {
|
|
20695
|
-
return;
|
|
20912
|
+
return untilResult.ok ? { ok: true, matched: untilResult.matched } : { ok: false, error: untilResult.error };
|
|
20696
20913
|
}
|
|
20697
|
-
|
|
20914
|
+
});
|
|
20915
|
+
if (pollResult.kind === "eval-error") {
|
|
20916
|
+
printError(pollResult.failure, options, output);
|
|
20917
|
+
process.exitCode = 1;
|
|
20918
|
+
return;
|
|
20919
|
+
}
|
|
20920
|
+
if (pollResult.kind === "condition-error") {
|
|
20921
|
+
printError({ kind: "until", error: pollResult.error }, options, output);
|
|
20922
|
+
process.exitCode = 1;
|
|
20923
|
+
return;
|
|
20924
|
+
}
|
|
20925
|
+
if (pollResult.kind === "interrupted") {
|
|
20926
|
+
process.exitCode = 130;
|
|
20698
20927
|
}
|
|
20699
20928
|
};
|
|
20700
20929
|
var compileUntil = (condition) => {
|
|
@@ -20725,23 +20954,11 @@ var compileUntil = (condition) => {
|
|
|
20725
20954
|
// dist/commands/evalUntil.js
|
|
20726
20955
|
var runEvalUntil = async (id, rawExpression, options) => {
|
|
20727
20956
|
const output = createOutput(options);
|
|
20728
|
-
const
|
|
20729
|
-
if (
|
|
20730
|
-
output.writeWarn(evalArgs.error);
|
|
20957
|
+
const prepared = await prepareEvalExpression(rawExpression, options, output);
|
|
20958
|
+
if (prepared == null) {
|
|
20731
20959
|
process.exitCode = 2;
|
|
20732
20960
|
return;
|
|
20733
20961
|
}
|
|
20734
|
-
const resolvedExpression = await resolveExpression(rawExpression, options, output);
|
|
20735
|
-
if (resolvedExpression == null) {
|
|
20736
|
-
process.exitCode = 2;
|
|
20737
|
-
return;
|
|
20738
|
-
}
|
|
20739
|
-
const requestArgs = !options.iframe && hasEvalArgs2(evalArgs.value) ? evalArgs.value : undefined;
|
|
20740
|
-
const expression = options.iframe ? wrapForIframeEval(wrapExpressionWithArgs(resolvedExpression, evalArgs.value), {
|
|
20741
|
-
selector: options.iframe,
|
|
20742
|
-
namespace: options.iframeNamespace ?? "argus",
|
|
20743
|
-
timeoutMs: parseNumber(options.iframeTimeout) ?? 5000
|
|
20744
|
-
}) : resolvedExpression;
|
|
20745
20962
|
const retryCount = parseRetryCount(options.retry);
|
|
20746
20963
|
if (retryCount.error) {
|
|
20747
20964
|
output.writeWarn(retryCount.error);
|
|
@@ -20772,57 +20989,50 @@ var runEvalUntil = async (id, rawExpression, options) => {
|
|
|
20772
20989
|
return;
|
|
20773
20990
|
const { watcher } = resolved;
|
|
20774
20991
|
const timeoutMs = parseNumber(options.timeout);
|
|
20775
|
-
|
|
20776
|
-
|
|
20777
|
-
|
|
20778
|
-
|
|
20779
|
-
|
|
20780
|
-
|
|
20781
|
-
|
|
20782
|
-
|
|
20783
|
-
|
|
20784
|
-
|
|
20785
|
-
|
|
20786
|
-
|
|
20787
|
-
|
|
20788
|
-
if (
|
|
20789
|
-
|
|
20790
|
-
process.exitCode = 1;
|
|
20791
|
-
return;
|
|
20992
|
+
const pollResult = await pollEval({
|
|
20993
|
+
watcher,
|
|
20994
|
+
expression: prepared.expression,
|
|
20995
|
+
args: prepared.args,
|
|
20996
|
+
awaitPromise: options.await ?? true,
|
|
20997
|
+
returnByValue: options.returnByValue ?? true,
|
|
20998
|
+
timeoutMs,
|
|
20999
|
+
failOnException: options.failOnException ?? true,
|
|
21000
|
+
retryCount: retryCount.value,
|
|
21001
|
+
intervalMs: pollIntervalMs,
|
|
21002
|
+
count: countValue.value,
|
|
21003
|
+
totalTimeoutMs: totalTimeoutMs.value,
|
|
21004
|
+
onResult: (response) => {
|
|
21005
|
+
if (!response.result && options.verbose) {
|
|
21006
|
+
printSuccess(response, options, output, true);
|
|
20792
21007
|
}
|
|
20793
|
-
}
|
|
20794
|
-
|
|
20795
|
-
|
|
20796
|
-
|
|
20797
|
-
|
|
20798
|
-
|
|
20799
|
-
|
|
20800
|
-
|
|
20801
|
-
|
|
20802
|
-
|
|
20803
|
-
|
|
20804
|
-
|
|
20805
|
-
|
|
20806
|
-
|
|
20807
|
-
|
|
20808
|
-
|
|
20809
|
-
}
|
|
20810
|
-
const isTruthy = Boolean(iterationResult.response.result);
|
|
20811
|
-
if (isTruthy) {
|
|
20812
|
-
printSuccess(iterationResult.response, options, output, false);
|
|
20813
|
-
return;
|
|
20814
|
-
}
|
|
20815
|
-
if (options.verbose) {
|
|
20816
|
-
printSuccess(iterationResult.response, options, output, true);
|
|
20817
|
-
}
|
|
20818
|
-
if (countValue.value != null && iteration >= countValue.value) {
|
|
20819
|
-
output.writeWarn(`Exhausted after ${iteration} iterations without a truthy result`);
|
|
20820
|
-
process.exitCode = 1;
|
|
20821
|
-
return;
|
|
20822
|
-
}
|
|
20823
|
-
await sleep3(pollIntervalMs);
|
|
21008
|
+
},
|
|
21009
|
+
shouldStop: ({ response }) => ({ ok: true, matched: Boolean(response.result) })
|
|
21010
|
+
});
|
|
21011
|
+
if (pollResult.kind === "matched") {
|
|
21012
|
+
printSuccess(pollResult.response, options, output, false);
|
|
21013
|
+
return;
|
|
21014
|
+
}
|
|
21015
|
+
if (pollResult.kind === "eval-error") {
|
|
21016
|
+
printError(pollResult.failure, options, output);
|
|
21017
|
+
process.exitCode = 1;
|
|
21018
|
+
return;
|
|
21019
|
+
}
|
|
21020
|
+
if (pollResult.kind === "timeout") {
|
|
21021
|
+
output.writeWarn(`Total timeout exceeded (${options.totalTimeout})`);
|
|
21022
|
+
process.exitCode = 1;
|
|
21023
|
+
return;
|
|
20824
21024
|
}
|
|
20825
|
-
if (
|
|
21025
|
+
if (pollResult.kind === "exhausted") {
|
|
21026
|
+
output.writeWarn(`Exhausted after ${pollResult.iterations} iterations without a truthy result`);
|
|
21027
|
+
process.exitCode = 1;
|
|
21028
|
+
return;
|
|
21029
|
+
}
|
|
21030
|
+
if (pollResult.kind === "condition-error") {
|
|
21031
|
+
output.writeWarn(pollResult.error);
|
|
21032
|
+
process.exitCode = 1;
|
|
21033
|
+
return;
|
|
21034
|
+
}
|
|
21035
|
+
if (pollResult.kind === "interrupted") {
|
|
20826
21036
|
process.exitCode = 130;
|
|
20827
21037
|
}
|
|
20828
21038
|
};
|
|
@@ -20911,11 +21121,13 @@ ${script}})();
|
|
|
20911
21121
|
// dist/cli/register/registerEval.js
|
|
20912
21122
|
var collectValue = (value, previous = []) => [...previous, value];
|
|
20913
21123
|
function registerEval(program2) {
|
|
20914
|
-
const evalCmd = program2.command("eval").alias("js").argument("[id]", "Watcher id to query").argument("[expression]", "JS expression to evaluate (or use --file / --stdin)").description("Evaluate a JS expression in the connected page").option("--no-await", "Do not await promises").option("--timeout <ms>", "Eval timeout in milliseconds").option("--json", "Output JSON for automation").option("--no-return-by-value", "Disable returnByValue (use preview)").option("--no-fail-on-exception", "Do not exit with code 1 when the evaluation throws").option("--retry <n>", "Retry failed evaluations up to N times").option("-q, --silent", "Suppress success output; only emit output on error").option("--interval <ms|duration>", "Re-evaluate every interval (e.g. 500, 3s)").option("--count <n>", "Stop after N iterations (requires --interval)").option("--until <condition>", "Stop when local condition becomes truthy (requires --interval)").option("-f, --file <path>", "Read expression from a file").option("--stdin", "Read expression from stdin").option("--iframe <selector>", "Eval in iframe via postMessage (requires helper script)").option("--iframe-namespace <name>", "Message type prefix for iframe eval (default: argus)").option("--iframe-timeout <ms>", "Timeout for iframe postMessage response (default: 5000)").option("--arg <key=value>", "Argument exposed to eval scripts as args[key]", collectValue, []).addHelpText("after", `
|
|
21124
|
+
const evalCmd = program2.command("eval").alias("js").argument("[id]", "Watcher id to query").argument("[expression]", "JS expression to evaluate (or use --file / --stdin)").description("Evaluate a JS expression in the connected page").option("--no-await", "Do not await promises").option("--timeout <ms>", "Eval timeout in milliseconds").option("--json", "Output JSON for automation").option("--no-return-by-value", "Disable returnByValue (use preview)").option("--no-fail-on-exception", "Do not exit with code 1 when the evaluation throws").option("--retry <n>", "Retry failed evaluations up to N times").option("-q, --silent", "Suppress success output; only emit output on error").option("--interval <ms|duration>", "Re-evaluate every interval (e.g. 500, 3s)").option("--count <n>", "Stop after N iterations (requires --interval)").option("--until <condition>", "Stop when local condition becomes truthy (requires --interval)").option("-f, --file <path>", "Read expression from a file").option("--bundle", "Bundle local imports from --file into one script before eval").option("--stdin", "Read expression from stdin").option("--inject <path>", "Read setup code from a file and run it before the expression").option("--iframe <selector>", "Eval in iframe via postMessage (requires helper script)").option("--iframe-namespace <name>", "Message type prefix for iframe eval (default: argus)").option("--iframe-timeout <ms>", "Timeout for iframe postMessage response (default: 5000)").option("--arg <key=value>", "Argument exposed to eval scripts as args[key]", collectValue, []).addHelpText("after", `
|
|
20915
21125
|
Examples:
|
|
20916
21126
|
$ argus eval app "location.href"
|
|
20917
21127
|
$ argus eval app "await fetch('/ping').then(r => r.status)"
|
|
20918
21128
|
$ argus eval app --file ./script.js
|
|
21129
|
+
$ argus eval app --file ./script.js --bundle
|
|
21130
|
+
$ argus eval app "window.store.getState()" --inject ./debug-hooks.js
|
|
20919
21131
|
$ argus eval app --file ./script.js --arg level=10 --arg mode=fast
|
|
20920
21132
|
$ cat script.js | argus eval app --stdin
|
|
20921
21133
|
$ argus eval app - < script.js
|
|
@@ -20939,7 +21151,9 @@ Examples:
|
|
|
20939
21151
|
count: options.count,
|
|
20940
21152
|
until: options.until,
|
|
20941
21153
|
file: options.file,
|
|
21154
|
+
bundle: options.bundle,
|
|
20942
21155
|
stdin: options.stdin,
|
|
21156
|
+
inject: options.inject,
|
|
20943
21157
|
iframe: options.iframe,
|
|
20944
21158
|
iframeNamespace: options.iframeNamespace,
|
|
20945
21159
|
iframeTimeout: options.iframeTimeout,
|
|
@@ -20955,7 +21169,7 @@ Examples:
|
|
|
20955
21169
|
`).action(async (options) => {
|
|
20956
21170
|
await runIframeHelper(options);
|
|
20957
21171
|
});
|
|
20958
|
-
program2.command("eval-until").alias("wait").argument("[id]", "Watcher id to query").argument("[expression]", "JS expression to poll until truthy (or use --file / --stdin)").description("Poll a JS expression until it returns a truthy value").option("--no-await", "Do not await promises").option("--timeout <ms>", "Per-eval timeout in milliseconds").option("--json", "Output JSON for automation").option("--no-return-by-value", "Disable returnByValue (use preview)").option("--no-fail-on-exception", "Do not exit with code 1 when the evaluation throws").option("--retry <n>", "Retry failed evaluations up to N times").option("-q, --silent", "Suppress success output; only emit output on error").option("--interval <ms|duration>", "Polling interval (default: 250ms)").option("--count <n>", "Stop after N iterations").option("--total-timeout <duration>", "Max wall-clock time (e.g. 30s, 2m)").option("--verbose", "Print intermediate (falsy) results").option("-f, --file <path>", "Read expression from a file").option("--stdin", "Read expression from stdin").option("--iframe <selector>", "Eval in iframe via postMessage (requires helper script)").option("--iframe-namespace <name>", "Message type prefix for iframe eval (default: argus)").option("--iframe-timeout <ms>", "Timeout for iframe postMessage response (default: 5000)").option("--arg <key=value>", "Argument exposed to eval scripts as args[key]", collectValue, []).addHelpText("after", `
|
|
21172
|
+
program2.command("eval-until").alias("wait").argument("[id]", "Watcher id to query").argument("[expression]", "JS expression to poll until truthy (or use --file / --stdin)").description("Poll a JS expression until it returns a truthy value").option("--no-await", "Do not await promises").option("--timeout <ms>", "Per-eval timeout in milliseconds").option("--json", "Output JSON for automation").option("--no-return-by-value", "Disable returnByValue (use preview)").option("--no-fail-on-exception", "Do not exit with code 1 when the evaluation throws").option("--retry <n>", "Retry failed evaluations up to N times").option("-q, --silent", "Suppress success output; only emit output on error").option("--interval <ms|duration>", "Polling interval (default: 250ms)").option("--count <n>", "Stop after N iterations").option("--total-timeout <duration>", "Max wall-clock time (e.g. 30s, 2m)").option("--verbose", "Print intermediate (falsy) results").option("-f, --file <path>", "Read expression from a file").option("--bundle", "Bundle local imports from --file into one script before eval").option("--stdin", "Read expression from stdin").option("--inject <path>", "Read setup code from a file and run it before the expression").option("--iframe <selector>", "Eval in iframe via postMessage (requires helper script)").option("--iframe-namespace <name>", "Message type prefix for iframe eval (default: argus)").option("--iframe-timeout <ms>", "Timeout for iframe postMessage response (default: 5000)").option("--arg <key=value>", "Argument exposed to eval scripts as args[key]", collectValue, []).addHelpText("after", `
|
|
20959
21173
|
Examples:
|
|
20960
21174
|
$ argus eval-until app "document.querySelector('#loaded')"
|
|
20961
21175
|
$ argus eval-until app "await window.appReadyPromise"
|
|
@@ -20964,6 +21178,8 @@ Examples:
|
|
|
20964
21178
|
$ argus eval-until app "window.data" --verbose
|
|
20965
21179
|
$ argus eval-until app "window.data" --count 20 --interval 1s
|
|
20966
21180
|
$ argus eval-until app --file ./check.js --total-timeout 1m
|
|
21181
|
+
$ argus eval-until app --file ./check.js --bundle --total-timeout 1m
|
|
21182
|
+
$ argus wait app "window.appReady" --inject ./debug-hooks.js --total-timeout 20s
|
|
20967
21183
|
$ argus wait app --file ./ready.js --arg level=10 --total-timeout 20s
|
|
20968
21184
|
`).action(async (id, expression, options) => {
|
|
20969
21185
|
await runEvalUntil(id, expression, {
|
|
@@ -20979,7 +21195,9 @@ Examples:
|
|
|
20979
21195
|
totalTimeout: options.totalTimeout,
|
|
20980
21196
|
verbose: options.verbose,
|
|
20981
21197
|
file: options.file,
|
|
21198
|
+
bundle: options.bundle,
|
|
20982
21199
|
stdin: options.stdin,
|
|
21200
|
+
inject: options.inject,
|
|
20983
21201
|
iframe: options.iframe,
|
|
20984
21202
|
iframeNamespace: options.iframeNamespace,
|
|
20985
21203
|
iframeTimeout: options.iframeTimeout,
|
|
@@ -21072,26 +21290,35 @@ var escapeAttrValue = (value) => {
|
|
|
21072
21290
|
};
|
|
21073
21291
|
|
|
21074
21292
|
// dist/commands/domTree.js
|
|
21075
|
-
var runDomTree =
|
|
21076
|
-
|
|
21293
|
+
var runDomTree = defineWatcherCommand({
|
|
21294
|
+
build: (_args, options, output) => buildDomTreePlan(options, output),
|
|
21295
|
+
formatHuman: (response, { output, options }) => {
|
|
21296
|
+
if (response.matches === 0) {
|
|
21297
|
+
writeNoElementFound(options.selector, output);
|
|
21298
|
+
return;
|
|
21299
|
+
}
|
|
21300
|
+
const formatted = formatDomTree(response.roots, response.truncated, response.truncatedReason);
|
|
21301
|
+
output.writeHuman(formatted);
|
|
21302
|
+
}
|
|
21303
|
+
});
|
|
21304
|
+
var buildDomTreePlan = (options, output) => {
|
|
21077
21305
|
const selector = requireSelector(options, output);
|
|
21078
21306
|
if (!selector) {
|
|
21079
|
-
return;
|
|
21307
|
+
return null;
|
|
21080
21308
|
}
|
|
21081
21309
|
const depth = parsePositiveInt(options.depth, { allowZero: true });
|
|
21082
21310
|
if (options.depth !== undefined && depth === undefined) {
|
|
21083
21311
|
output.writeWarn("--depth must be a non-negative integer");
|
|
21084
21312
|
process.exitCode = 2;
|
|
21085
|
-
return;
|
|
21313
|
+
return null;
|
|
21086
21314
|
}
|
|
21087
21315
|
const maxNodes = parsePositiveInt(options.maxNodes);
|
|
21088
21316
|
if (options.maxNodes !== undefined && maxNodes === undefined) {
|
|
21089
21317
|
output.writeWarn("--max-nodes must be a positive integer");
|
|
21090
21318
|
process.exitCode = 2;
|
|
21091
|
-
return;
|
|
21319
|
+
return null;
|
|
21092
21320
|
}
|
|
21093
|
-
|
|
21094
|
-
id,
|
|
21321
|
+
return {
|
|
21095
21322
|
path: "/dom/tree",
|
|
21096
21323
|
method: "POST",
|
|
21097
21324
|
body: {
|
|
@@ -21102,38 +21329,34 @@ var runDomTree = async (id, options) => {
|
|
|
21102
21329
|
text: options.text
|
|
21103
21330
|
},
|
|
21104
21331
|
timeoutMs: 30000
|
|
21105
|
-
}
|
|
21106
|
-
if (!result) {
|
|
21107
|
-
return;
|
|
21108
|
-
}
|
|
21109
|
-
const successResp = result.data;
|
|
21110
|
-
if (options.json) {
|
|
21111
|
-
output.writeJson(successResp);
|
|
21112
|
-
return;
|
|
21113
|
-
}
|
|
21114
|
-
if (successResp.matches === 0) {
|
|
21115
|
-
writeNoElementFound(selector, output);
|
|
21116
|
-
return;
|
|
21117
|
-
}
|
|
21118
|
-
const formatted = formatDomTree(successResp.roots, successResp.truncated, successResp.truncatedReason);
|
|
21119
|
-
output.writeHuman(formatted);
|
|
21332
|
+
};
|
|
21120
21333
|
};
|
|
21121
21334
|
|
|
21122
21335
|
// dist/commands/domInfo.js
|
|
21123
|
-
var runDomInfo =
|
|
21124
|
-
|
|
21336
|
+
var runDomInfo = defineWatcherCommand({
|
|
21337
|
+
build: (_args, options, output) => buildDomInfoPlan(options, output),
|
|
21338
|
+
formatHuman: (response, { output, options }) => {
|
|
21339
|
+
const target = { selector: options.selector, ref: options.ref };
|
|
21340
|
+
if (response.matches === 0) {
|
|
21341
|
+
writeNoElementFound(target.selector ?? target.ref, output);
|
|
21342
|
+
return;
|
|
21343
|
+
}
|
|
21344
|
+
const formatted = formatDomInfo(response.elements);
|
|
21345
|
+
output.writeHuman(formatted);
|
|
21346
|
+
}
|
|
21347
|
+
});
|
|
21348
|
+
var buildDomInfoPlan = (options, output) => {
|
|
21125
21349
|
const target = requireElementTarget({ selector: options.selector, ref: options.ref }, output);
|
|
21126
21350
|
if (!target) {
|
|
21127
|
-
return;
|
|
21351
|
+
return null;
|
|
21128
21352
|
}
|
|
21129
21353
|
const outerHtmlMaxChars = parsePositiveInt(options.outerHtmlMax);
|
|
21130
21354
|
if (options.outerHtmlMax !== undefined && outerHtmlMaxChars === undefined) {
|
|
21131
21355
|
output.writeWarn("--outer-html-max must be a positive integer");
|
|
21132
21356
|
process.exitCode = 2;
|
|
21133
|
-
return;
|
|
21357
|
+
return null;
|
|
21134
21358
|
}
|
|
21135
|
-
|
|
21136
|
-
id,
|
|
21359
|
+
return {
|
|
21137
21360
|
path: "/dom/info",
|
|
21138
21361
|
method: "POST",
|
|
21139
21362
|
body: {
|
|
@@ -21144,21 +21367,7 @@ var runDomInfo = async (id, options) => {
|
|
|
21144
21367
|
text: options.text
|
|
21145
21368
|
},
|
|
21146
21369
|
timeoutMs: 30000
|
|
21147
|
-
}
|
|
21148
|
-
if (!result) {
|
|
21149
|
-
return;
|
|
21150
|
-
}
|
|
21151
|
-
const successResp = result.data;
|
|
21152
|
-
if (options.json) {
|
|
21153
|
-
output.writeJson(successResp);
|
|
21154
|
-
return;
|
|
21155
|
-
}
|
|
21156
|
-
if (successResp.matches === 0) {
|
|
21157
|
-
writeNoElementFound(target.selector ?? target.ref, output);
|
|
21158
|
-
return;
|
|
21159
|
-
}
|
|
21160
|
-
const formatted = formatDomInfo(successResp.elements);
|
|
21161
|
-
output.writeHuman(formatted);
|
|
21370
|
+
};
|
|
21162
21371
|
};
|
|
21163
21372
|
|
|
21164
21373
|
// dist/commands/domFocus.js
|
|
@@ -21191,50 +21400,62 @@ var runDomFocus = defineWatcherCommand({
|
|
|
21191
21400
|
|
|
21192
21401
|
// dist/commands/domAdd.js
|
|
21193
21402
|
import { readFile as readFile3 } from "node:fs/promises";
|
|
21194
|
-
var runDomAdd =
|
|
21195
|
-
|
|
21403
|
+
var runDomAdd = defineWatcherCommand({
|
|
21404
|
+
build: (_args, options, output) => buildDomAddPlan(options, output),
|
|
21405
|
+
formatHuman: (successResp, { output, options, watcher }) => {
|
|
21406
|
+
const selector = options.selector;
|
|
21407
|
+
const position = normalizePosition(options.position);
|
|
21408
|
+
if (successResp.matches === 0) {
|
|
21409
|
+
writeNoElementFound(selector, output, `Hint: run \`argus dom tree ${watcher.id} --selector "${selector}" --all\``);
|
|
21410
|
+
return;
|
|
21411
|
+
}
|
|
21412
|
+
const label = successResp.inserted === 1 ? "element" : "elements";
|
|
21413
|
+
const prefix = watcher.id ? `${watcher.id}: ` : "";
|
|
21414
|
+
output.writeHuman(`${prefix}Inserted at ${successResp.inserted}/${successResp.matches} ${label} (${position}) for selector: ${selector}`);
|
|
21415
|
+
}
|
|
21416
|
+
});
|
|
21417
|
+
var buildDomAddPlan = async (options, output) => {
|
|
21196
21418
|
const selector = requireSelector(options, output);
|
|
21197
21419
|
if (!selector) {
|
|
21198
|
-
return;
|
|
21420
|
+
return null;
|
|
21199
21421
|
}
|
|
21200
21422
|
const position = normalizePosition(options.position);
|
|
21201
21423
|
if (!position) {
|
|
21202
21424
|
output.writeWarn("--position must be one of: beforebegin, afterbegin, beforeend, afterend (aliases: before, after, prepend, append)");
|
|
21203
21425
|
process.exitCode = 2;
|
|
21204
|
-
return;
|
|
21426
|
+
return null;
|
|
21205
21427
|
}
|
|
21206
21428
|
if (options.all && (options.nth != null || options.first)) {
|
|
21207
21429
|
output.writeWarn("Cannot combine --all with --nth or --first");
|
|
21208
21430
|
process.exitCode = 2;
|
|
21209
|
-
return;
|
|
21431
|
+
return null;
|
|
21210
21432
|
}
|
|
21211
21433
|
if (options.nth != null && options.first) {
|
|
21212
21434
|
output.writeWarn("Cannot combine --nth with --first");
|
|
21213
21435
|
process.exitCode = 2;
|
|
21214
|
-
return;
|
|
21436
|
+
return null;
|
|
21215
21437
|
}
|
|
21216
21438
|
const nth = options.first ? 0 : parseNonNegativeInt(options.nth, "--nth", output);
|
|
21217
21439
|
if (options.nth != null && nth == null) {
|
|
21218
21440
|
process.exitCode = 2;
|
|
21219
|
-
return;
|
|
21441
|
+
return null;
|
|
21220
21442
|
}
|
|
21221
21443
|
const expect = parseNonNegativeInt(options.expect, "--expect", output);
|
|
21222
21444
|
if (options.expect != null && expect == null) {
|
|
21223
21445
|
process.exitCode = 2;
|
|
21224
|
-
return;
|
|
21446
|
+
return null;
|
|
21225
21447
|
}
|
|
21226
21448
|
const html = await resolveHtmlInput(options, output);
|
|
21227
21449
|
if (html == null) {
|
|
21228
21450
|
process.exitCode = 2;
|
|
21229
|
-
return;
|
|
21451
|
+
return null;
|
|
21230
21452
|
}
|
|
21231
21453
|
if (!html) {
|
|
21232
21454
|
output.writeWarn("HTML content is empty. Provide non-empty --html, --html-file, or --html-stdin input.");
|
|
21233
21455
|
process.exitCode = 2;
|
|
21234
|
-
return;
|
|
21456
|
+
return null;
|
|
21235
21457
|
}
|
|
21236
|
-
|
|
21237
|
-
id,
|
|
21458
|
+
return {
|
|
21238
21459
|
path: "/dom/add",
|
|
21239
21460
|
method: "POST",
|
|
21240
21461
|
body: {
|
|
@@ -21247,22 +21468,7 @@ var runDomAdd = async (id, options) => {
|
|
|
21247
21468
|
text: options.text ?? false
|
|
21248
21469
|
},
|
|
21249
21470
|
timeoutMs: 30000
|
|
21250
|
-
}
|
|
21251
|
-
if (!result) {
|
|
21252
|
-
return;
|
|
21253
|
-
}
|
|
21254
|
-
const successResp = result.data;
|
|
21255
|
-
if (options.json) {
|
|
21256
|
-
output.writeJson(successResp);
|
|
21257
|
-
return;
|
|
21258
|
-
}
|
|
21259
|
-
if (successResp.matches === 0) {
|
|
21260
|
-
writeNoElementFound(selector, output, `Hint: run \`argus dom tree${id ? ` ${id}` : ""} --selector "${selector}" --all\``);
|
|
21261
|
-
return;
|
|
21262
|
-
}
|
|
21263
|
-
const label = successResp.inserted === 1 ? "element" : "elements";
|
|
21264
|
-
const prefix = result.watcher.id ? `${result.watcher.id}: ` : "";
|
|
21265
|
-
output.writeHuman(`${prefix}Inserted at ${successResp.inserted}/${successResp.matches} ${label} (${position}) for selector: ${selector}`);
|
|
21471
|
+
};
|
|
21266
21472
|
};
|
|
21267
21473
|
var normalizePosition = (value) => {
|
|
21268
21474
|
if (!value) {
|
|
@@ -21591,25 +21797,28 @@ var buildSetFilePlan = (options, output) => {
|
|
|
21591
21797
|
};
|
|
21592
21798
|
|
|
21593
21799
|
// dist/commands/domScroll.js
|
|
21594
|
-
var runDomScroll =
|
|
21595
|
-
|
|
21800
|
+
var runDomScroll = defineWatcherCommand({
|
|
21801
|
+
build: (_args, options, output) => buildDomScrollPlan(options, output),
|
|
21802
|
+
formatHuman: formatDomScrollHuman
|
|
21803
|
+
});
|
|
21804
|
+
var buildDomScrollPlan = (options, output) => {
|
|
21596
21805
|
if (options.by == null) {
|
|
21597
21806
|
output.writeWarn("--by is required (e.g. --by 0,300)");
|
|
21598
21807
|
process.exitCode = 2;
|
|
21599
|
-
return;
|
|
21808
|
+
return null;
|
|
21600
21809
|
}
|
|
21601
21810
|
const delta = parseXY(options.by);
|
|
21602
21811
|
if (!delta) {
|
|
21603
21812
|
output.writeWarn('--by must be in the format "x,y" (e.g. --by 0,300)');
|
|
21604
21813
|
process.exitCode = 2;
|
|
21605
|
-
return;
|
|
21814
|
+
return null;
|
|
21606
21815
|
}
|
|
21607
21816
|
const hasSelector = options.selector != null && options.selector.trim() !== "";
|
|
21608
21817
|
const hasPos = options.pos != null;
|
|
21609
21818
|
if (hasSelector && hasPos) {
|
|
21610
21819
|
output.writeWarn("--selector and --pos are mutually exclusive");
|
|
21611
21820
|
process.exitCode = 2;
|
|
21612
|
-
return;
|
|
21821
|
+
return null;
|
|
21613
21822
|
}
|
|
21614
21823
|
let x;
|
|
21615
21824
|
let y;
|
|
@@ -21618,7 +21827,7 @@ var runDomScroll = async (id, options) => {
|
|
|
21618
21827
|
if (!parsed) {
|
|
21619
21828
|
output.writeWarn('--pos must be in the format "x,y" (e.g. --pos 400,300)');
|
|
21620
21829
|
process.exitCode = 2;
|
|
21621
|
-
return;
|
|
21830
|
+
return null;
|
|
21622
21831
|
}
|
|
21623
21832
|
x = parsed.x;
|
|
21624
21833
|
y = parsed.y;
|
|
@@ -21635,21 +21844,12 @@ var runDomScroll = async (id, options) => {
|
|
|
21635
21844
|
body.x = x;
|
|
21636
21845
|
body.y = y;
|
|
21637
21846
|
}
|
|
21638
|
-
|
|
21639
|
-
|
|
21640
|
-
|
|
21641
|
-
|
|
21642
|
-
|
|
21643
|
-
|
|
21644
|
-
}, output);
|
|
21645
|
-
if (!result) {
|
|
21646
|
-
return;
|
|
21647
|
-
}
|
|
21648
|
-
const successResp = result.data;
|
|
21649
|
-
if (options.json) {
|
|
21650
|
-
output.writeJson(successResp);
|
|
21651
|
-
return;
|
|
21652
|
-
}
|
|
21847
|
+
return { path: "/dom/scroll", method: "POST", body, timeoutMs: 30000 };
|
|
21848
|
+
};
|
|
21849
|
+
function formatDomScrollHuman(successResp, { output, options }) {
|
|
21850
|
+
const delta = parseXY(options.by);
|
|
21851
|
+
const hasSelector = options.selector != null && options.selector.trim() !== "";
|
|
21852
|
+
const hasPos = options.pos != null;
|
|
21653
21853
|
if (hasSelector) {
|
|
21654
21854
|
if (successResp.matches === 0) {
|
|
21655
21855
|
writeNoElementFound(options.selector, output);
|
|
@@ -21658,27 +21858,31 @@ var runDomScroll = async (id, options) => {
|
|
|
21658
21858
|
const label = successResp.scrolled === 1 ? "element" : "elements";
|
|
21659
21859
|
output.writeHuman(`Emulated scroll on ${successResp.scrolled} ${label} by (${delta.x}, ${delta.y})`);
|
|
21660
21860
|
} else if (hasPos) {
|
|
21861
|
+
const { x, y } = parseXY(options.pos);
|
|
21661
21862
|
output.writeHuman(`Emulated scroll at (${x}, ${y}) by (${delta.x}, ${delta.y})`);
|
|
21662
21863
|
} else {
|
|
21663
21864
|
output.writeHuman(`Emulated scroll at viewport center by (${delta.x}, ${delta.y})`);
|
|
21664
21865
|
}
|
|
21665
|
-
}
|
|
21866
|
+
}
|
|
21666
21867
|
|
|
21667
21868
|
// dist/commands/domScrollTo.js
|
|
21668
|
-
var runDomScrollTo =
|
|
21669
|
-
|
|
21869
|
+
var runDomScrollTo = defineWatcherCommand({
|
|
21870
|
+
build: (_args, options, output) => buildDomScrollToPlan(options, output),
|
|
21871
|
+
formatHuman: formatDomScrollToHuman
|
|
21872
|
+
});
|
|
21873
|
+
var buildDomScrollToPlan = (options, output) => {
|
|
21670
21874
|
const hasSelector = options.selector != null && options.selector.trim() !== "";
|
|
21671
21875
|
const hasTo = options.to != null;
|
|
21672
21876
|
const hasBy = options.by != null;
|
|
21673
21877
|
if (!hasSelector && !hasTo && !hasBy) {
|
|
21674
21878
|
output.writeWarn("--selector, --to, or --by is required");
|
|
21675
21879
|
process.exitCode = 2;
|
|
21676
|
-
return;
|
|
21880
|
+
return null;
|
|
21677
21881
|
}
|
|
21678
21882
|
if (hasTo && hasBy) {
|
|
21679
21883
|
output.writeWarn("--to and --by are mutually exclusive");
|
|
21680
21884
|
process.exitCode = 2;
|
|
21681
|
-
return;
|
|
21885
|
+
return null;
|
|
21682
21886
|
}
|
|
21683
21887
|
let to;
|
|
21684
21888
|
let by;
|
|
@@ -21687,7 +21891,7 @@ var runDomScrollTo = async (id, options) => {
|
|
|
21687
21891
|
if (!parsed) {
|
|
21688
21892
|
output.writeWarn('--to must be in the format "x,y" (e.g. --to 0,1000)');
|
|
21689
21893
|
process.exitCode = 2;
|
|
21690
|
-
return;
|
|
21894
|
+
return null;
|
|
21691
21895
|
}
|
|
21692
21896
|
to = parsed;
|
|
21693
21897
|
}
|
|
@@ -21696,7 +21900,7 @@ var runDomScrollTo = async (id, options) => {
|
|
|
21696
21900
|
if (!parsed) {
|
|
21697
21901
|
output.writeWarn('--by must be in the format "x,y" (e.g. --by 0,500)');
|
|
21698
21902
|
process.exitCode = 2;
|
|
21699
|
-
return;
|
|
21903
|
+
return null;
|
|
21700
21904
|
}
|
|
21701
21905
|
by = parsed;
|
|
21702
21906
|
}
|
|
@@ -21714,21 +21918,10 @@ var runDomScrollTo = async (id, options) => {
|
|
|
21714
21918
|
if (by) {
|
|
21715
21919
|
body.by = by;
|
|
21716
21920
|
}
|
|
21717
|
-
|
|
21718
|
-
|
|
21719
|
-
|
|
21720
|
-
|
|
21721
|
-
body,
|
|
21722
|
-
timeoutMs: 30000
|
|
21723
|
-
}, output);
|
|
21724
|
-
if (!result) {
|
|
21725
|
-
return;
|
|
21726
|
-
}
|
|
21727
|
-
const successResp = result.data;
|
|
21728
|
-
if (options.json) {
|
|
21729
|
-
output.writeJson(successResp);
|
|
21730
|
-
return;
|
|
21731
|
-
}
|
|
21921
|
+
return { path: "/dom/scroll-to", method: "POST", body, timeoutMs: 30000 };
|
|
21922
|
+
};
|
|
21923
|
+
function formatDomScrollToHuman(successResp, { output, options }) {
|
|
21924
|
+
const hasSelector = options.selector != null && options.selector.trim() !== "";
|
|
21732
21925
|
if (hasSelector && successResp.matches === 0) {
|
|
21733
21926
|
writeNoElementFound(options.selector, output);
|
|
21734
21927
|
return;
|
|
@@ -21739,40 +21932,37 @@ var runDomScrollTo = async (id, options) => {
|
|
|
21739
21932
|
} else {
|
|
21740
21933
|
output.writeHuman(`Scrolled viewport (scrollX=${successResp.scrollX}, scrollY=${successResp.scrollY})`);
|
|
21741
21934
|
}
|
|
21742
|
-
}
|
|
21935
|
+
}
|
|
21743
21936
|
|
|
21744
21937
|
// dist/commands/domModify.js
|
|
21745
21938
|
var executeModify = async (id, options, payload, successMessage) => {
|
|
21746
|
-
|
|
21747
|
-
const selector = requireSelector(options, output);
|
|
21748
|
-
if (!selector) {
|
|
21749
|
-
return;
|
|
21750
|
-
}
|
|
21751
|
-
const result = await requestWatcherAction({
|
|
21752
|
-
id,
|
|
21753
|
-
path: "/dom/modify",
|
|
21754
|
-
method: "POST",
|
|
21755
|
-
body: {
|
|
21756
|
-
...payload,
|
|
21757
|
-
selector,
|
|
21758
|
-
...options.text != null ? { text: options.text } : {}
|
|
21759
|
-
},
|
|
21760
|
-
timeoutMs: 30000
|
|
21761
|
-
}, output);
|
|
21762
|
-
if (!result) {
|
|
21763
|
-
return;
|
|
21764
|
-
}
|
|
21765
|
-
const successResp = result.data;
|
|
21766
|
-
if (options.json) {
|
|
21767
|
-
output.writeJson(successResp);
|
|
21768
|
-
return;
|
|
21769
|
-
}
|
|
21770
|
-
if (successResp.matches === 0) {
|
|
21771
|
-
writeNoElementFound(selector, output);
|
|
21772
|
-
return;
|
|
21773
|
-
}
|
|
21774
|
-
output.writeHuman(successMessage(successResp));
|
|
21939
|
+
await runDomModifyRequest(id, payload, successMessage, options);
|
|
21775
21940
|
};
|
|
21941
|
+
var runDomModifyRequest = defineWatcherCommand({
|
|
21942
|
+
build: ([payload], options, output) => {
|
|
21943
|
+
const selector = requireSelector(options, output);
|
|
21944
|
+
if (!selector) {
|
|
21945
|
+
return null;
|
|
21946
|
+
}
|
|
21947
|
+
return {
|
|
21948
|
+
path: "/dom/modify",
|
|
21949
|
+
method: "POST",
|
|
21950
|
+
body: {
|
|
21951
|
+
...payload,
|
|
21952
|
+
selector,
|
|
21953
|
+
...options.text != null ? { text: options.text } : {}
|
|
21954
|
+
},
|
|
21955
|
+
timeoutMs: 30000
|
|
21956
|
+
};
|
|
21957
|
+
},
|
|
21958
|
+
formatHuman: (successResp, { output, options, args }) => {
|
|
21959
|
+
if (successResp.matches === 0) {
|
|
21960
|
+
writeNoElementFound(options.selector, output);
|
|
21961
|
+
return;
|
|
21962
|
+
}
|
|
21963
|
+
output.writeHuman(args[1](successResp));
|
|
21964
|
+
}
|
|
21965
|
+
});
|
|
21776
21966
|
var parseAttrArgs = (attrs) => {
|
|
21777
21967
|
const result = {};
|
|
21778
21968
|
for (const attr of attrs) {
|
|
@@ -22150,47 +22340,28 @@ Examples:
|
|
|
22150
22340
|
}
|
|
22151
22341
|
|
|
22152
22342
|
// dist/commands/domKeydown.js
|
|
22153
|
-
var runDomKeydown =
|
|
22154
|
-
|
|
22155
|
-
|
|
22156
|
-
|
|
22157
|
-
|
|
22158
|
-
|
|
22159
|
-
}
|
|
22160
|
-
const result = await requestWatcherJson({
|
|
22161
|
-
id,
|
|
22162
|
-
path: "/dom/keydown",
|
|
22163
|
-
method: "POST",
|
|
22164
|
-
body: {
|
|
22165
|
-
key: options.key,
|
|
22166
|
-
selector: options.selector,
|
|
22167
|
-
modifiers: options.modifiers
|
|
22168
|
-
},
|
|
22169
|
-
timeoutMs: 30000,
|
|
22170
|
-
returnErrorResponse: true
|
|
22171
|
-
});
|
|
22172
|
-
if (!result.ok) {
|
|
22173
|
-
writeRequestError(result, output);
|
|
22174
|
-
return;
|
|
22175
|
-
}
|
|
22176
|
-
const response = result.data;
|
|
22177
|
-
if (!response.ok) {
|
|
22178
|
-
const errorResp = response;
|
|
22179
|
-
if (options.json) {
|
|
22180
|
-
output.writeJson(response);
|
|
22181
|
-
} else {
|
|
22182
|
-
output.writeWarn(`Error: ${errorResp.error.message}`);
|
|
22343
|
+
var runDomKeydown = defineWatcherCommand({
|
|
22344
|
+
build: (_args, options, output) => {
|
|
22345
|
+
if (!options.key || options.key.trim() === "") {
|
|
22346
|
+
output.writeWarn("--key is required");
|
|
22347
|
+
process.exitCode = 2;
|
|
22348
|
+
return null;
|
|
22183
22349
|
}
|
|
22184
|
-
|
|
22185
|
-
|
|
22186
|
-
|
|
22187
|
-
|
|
22188
|
-
|
|
22189
|
-
|
|
22190
|
-
|
|
22350
|
+
return {
|
|
22351
|
+
path: "/dom/keydown",
|
|
22352
|
+
method: "POST",
|
|
22353
|
+
body: {
|
|
22354
|
+
key: options.key,
|
|
22355
|
+
selector: options.selector,
|
|
22356
|
+
modifiers: options.modifiers
|
|
22357
|
+
},
|
|
22358
|
+
timeoutMs: 30000
|
|
22359
|
+
};
|
|
22360
|
+
},
|
|
22361
|
+
formatHuman: (response, { output }) => {
|
|
22362
|
+
output.writeHuman(`Dispatched keydown: ${response.key}`);
|
|
22191
22363
|
}
|
|
22192
|
-
|
|
22193
|
-
};
|
|
22364
|
+
});
|
|
22194
22365
|
|
|
22195
22366
|
// dist/cli/register/registerKeydown.js
|
|
22196
22367
|
function registerKeydown(program2) {
|
|
@@ -22531,19 +22702,23 @@ Examples:
|
|
|
22531
22702
|
|
|
22532
22703
|
// dist/commands/screenshot.js
|
|
22533
22704
|
var SCREENSHOT_REQUEST_TIMEOUT_MS = 45000;
|
|
22534
|
-
var runScreenshot =
|
|
22535
|
-
|
|
22705
|
+
var runScreenshot = defineWatcherCommand({
|
|
22706
|
+
build: (_args, options, output) => buildScreenshotPlan(options, output),
|
|
22707
|
+
formatHuman: (response, { output }) => {
|
|
22708
|
+
output.writeHuman(`Screenshot saved: ${response.outFile}`);
|
|
22709
|
+
}
|
|
22710
|
+
});
|
|
22711
|
+
var buildScreenshotPlan = (options, output) => {
|
|
22536
22712
|
const clip = parseScreenshotClip(options.clip, output);
|
|
22537
22713
|
if (clip === null) {
|
|
22538
|
-
return;
|
|
22714
|
+
return null;
|
|
22539
22715
|
}
|
|
22540
22716
|
const selector = normalizeSelector(options.selector);
|
|
22541
22717
|
if (selector && clip) {
|
|
22542
22718
|
writeScreenshotOptionError(output, "Cannot use both --selector and --clip");
|
|
22543
|
-
return;
|
|
22719
|
+
return null;
|
|
22544
22720
|
}
|
|
22545
|
-
|
|
22546
|
-
id,
|
|
22721
|
+
return {
|
|
22547
22722
|
path: "/screenshot",
|
|
22548
22723
|
method: "POST",
|
|
22549
22724
|
body: {
|
|
@@ -22553,16 +22728,7 @@ var runScreenshot = async (id, options) => {
|
|
|
22553
22728
|
format: "png"
|
|
22554
22729
|
},
|
|
22555
22730
|
timeoutMs: SCREENSHOT_REQUEST_TIMEOUT_MS
|
|
22556
|
-
}
|
|
22557
|
-
if (!result.ok) {
|
|
22558
|
-
writeRequestError(result, output);
|
|
22559
|
-
return;
|
|
22560
|
-
}
|
|
22561
|
-
if (options.json) {
|
|
22562
|
-
output.writeJson(result.data);
|
|
22563
|
-
return;
|
|
22564
|
-
}
|
|
22565
|
-
output.writeHuman(`Screenshot saved: ${result.data.outFile}`);
|
|
22731
|
+
};
|
|
22566
22732
|
};
|
|
22567
22733
|
var normalizeSelector = (selector) => {
|
|
22568
22734
|
const trimmed = selector?.trim();
|
|
@@ -22844,12 +23010,13 @@ function resolveActionOptions(options, command) {
|
|
|
22844
23010
|
|
|
22845
23011
|
// dist/commands/configInit.js
|
|
22846
23012
|
import fs12 from "node:fs/promises";
|
|
22847
|
-
import
|
|
23013
|
+
import path13 from "node:path";
|
|
22848
23014
|
import { fileURLToPath, pathToFileURL } from "node:url";
|
|
22849
23015
|
var DEFAULT_CONFIG_PATH = ".argus/config.json";
|
|
22850
23016
|
var buildConfigTemplate = (schemaRef) => ({
|
|
22851
23017
|
$schema: schemaRef,
|
|
22852
23018
|
plugins: [],
|
|
23019
|
+
pluginAliases: {},
|
|
22853
23020
|
chrome: {
|
|
22854
23021
|
start: {
|
|
22855
23022
|
url: "http://localhost:3000",
|
|
@@ -22870,12 +23037,12 @@ var buildConfigTemplate = (schemaRef) => ({
|
|
|
22870
23037
|
});
|
|
22871
23038
|
var resolveConfigPath = (cwd, targetPath) => {
|
|
22872
23039
|
if (!targetPath) {
|
|
22873
|
-
return
|
|
23040
|
+
return path13.resolve(cwd, DEFAULT_CONFIG_PATH);
|
|
22874
23041
|
}
|
|
22875
|
-
return
|
|
23042
|
+
return path13.isAbsolute(targetPath) ? targetPath : path13.resolve(cwd, targetPath);
|
|
22876
23043
|
};
|
|
22877
23044
|
var ensureParentDir2 = async (filePath) => {
|
|
22878
|
-
const dir =
|
|
23045
|
+
const dir = path13.dirname(filePath);
|
|
22879
23046
|
try {
|
|
22880
23047
|
await fs12.mkdir(dir, { recursive: true });
|
|
22881
23048
|
return true;
|
|
@@ -22954,33 +23121,33 @@ Examples:
|
|
|
22954
23121
|
});
|
|
22955
23122
|
}
|
|
22956
23123
|
|
|
22957
|
-
// dist/commands/extension/setup.js
|
|
22958
|
-
import fs14 from "node:fs";
|
|
22959
|
-
import { execSync as execSync2 } from "node:child_process";
|
|
22960
|
-
|
|
22961
23124
|
// dist/commands/extension/nativeHost.js
|
|
22962
23125
|
import fs13 from "node:fs";
|
|
22963
|
-
import
|
|
23126
|
+
import path14 from "node:path";
|
|
22964
23127
|
import os4 from "node:os";
|
|
22965
23128
|
import { execSync } from "node:child_process";
|
|
22966
|
-
var
|
|
23129
|
+
var BRIDGE_HOST_NAME = "com.vforsh.argus.bridge";
|
|
23130
|
+
var CONTROL_HOST_NAME = "com.vforsh.argus.control";
|
|
23131
|
+
var CONTROL_WATCHER_ID = "extension-control";
|
|
23132
|
+
var HOST_NAMES = [BRIDGE_HOST_NAME, CONTROL_HOST_NAME];
|
|
22967
23133
|
var getManifestDir = (platform) => {
|
|
22968
23134
|
switch (platform) {
|
|
22969
23135
|
case "darwin":
|
|
22970
|
-
return
|
|
23136
|
+
return path14.join(os4.homedir(), "Library/Application Support/Google/Chrome/NativeMessagingHosts");
|
|
22971
23137
|
case "linux":
|
|
22972
|
-
return
|
|
23138
|
+
return path14.join(os4.homedir(), ".config/google-chrome/NativeMessagingHosts");
|
|
22973
23139
|
case "win32":
|
|
22974
|
-
return
|
|
23140
|
+
return path14.join(process.env.LOCALAPPDATA ?? os4.homedir(), "Google/Chrome/User Data/NativeMessagingHosts");
|
|
22975
23141
|
default:
|
|
22976
23142
|
throw new Error(`Unsupported platform: ${platform}`);
|
|
22977
23143
|
}
|
|
22978
23144
|
};
|
|
22979
|
-
var getManifestPath = (platform) => {
|
|
22980
|
-
return
|
|
23145
|
+
var getManifestPath = (platform, hostName = BRIDGE_HOST_NAME) => {
|
|
23146
|
+
return path14.join(getManifestDir(platform), `${hostName}.json`);
|
|
22981
23147
|
};
|
|
22982
|
-
var getWrapperPath = (platform) => {
|
|
22983
|
-
|
|
23148
|
+
var getWrapperPath = (platform, hostName = BRIDGE_HOST_NAME) => {
|
|
23149
|
+
const filename = hostName === CONTROL_HOST_NAME ? "argus-native-control-host.sh" : "argus-native-host.sh";
|
|
23150
|
+
return path14.join(getManifestDir(platform), filename);
|
|
22984
23151
|
};
|
|
22985
23152
|
var getPlatform = () => {
|
|
22986
23153
|
const platform = os4.platform();
|
|
@@ -22992,7 +23159,7 @@ var getPlatform = () => {
|
|
|
22992
23159
|
var findArgusExecutable = () => {
|
|
22993
23160
|
try {
|
|
22994
23161
|
const npmGlobalPrefix = execSync("npm config get prefix", { encoding: "utf8" }).trim();
|
|
22995
|
-
const globalBinPath =
|
|
23162
|
+
const globalBinPath = path14.join(npmGlobalPrefix, "bin", "argus");
|
|
22996
23163
|
if (fs13.existsSync(globalBinPath)) {
|
|
22997
23164
|
return globalBinPath;
|
|
22998
23165
|
}
|
|
@@ -23008,25 +23175,71 @@ var findArgusExecutable = () => {
|
|
|
23008
23175
|
var findNodePath = () => {
|
|
23009
23176
|
return fs13.realpathSync(process.execPath);
|
|
23010
23177
|
};
|
|
23011
|
-
var createManifest = (extensionId, executablePath) => {
|
|
23178
|
+
var createManifest = (extensionId, executablePath, hostName = BRIDGE_HOST_NAME) => {
|
|
23012
23179
|
return {
|
|
23013
|
-
name:
|
|
23014
|
-
description: "Argus Watcher Native Messaging Host",
|
|
23180
|
+
name: hostName,
|
|
23181
|
+
description: hostName === CONTROL_HOST_NAME ? "Argus Extension Control Native Messaging Host" : "Argus Watcher Native Messaging Host",
|
|
23015
23182
|
path: executablePath,
|
|
23016
23183
|
type: "stdio",
|
|
23017
23184
|
allowed_origins: [`chrome-extension://${extensionId}/`]
|
|
23018
23185
|
};
|
|
23019
23186
|
};
|
|
23020
|
-
var createWrapperScript = (platform, executablePath) => {
|
|
23021
|
-
const
|
|
23022
|
-
const wrapperPath = path13.join(wrapperDir, "argus-native-host.sh");
|
|
23187
|
+
var createWrapperScript = (platform, executablePath, hostName = BRIDGE_HOST_NAME) => {
|
|
23188
|
+
const wrapperPath = getWrapperPath(platform, hostName);
|
|
23023
23189
|
const nodePath = findNodePath();
|
|
23190
|
+
const args = hostName === CONTROL_HOST_NAME ? `watcher native-host --role control --id ${CONTROL_WATCHER_ID}` : "watcher native-host --role tab";
|
|
23024
23191
|
const script = `#!/bin/bash
|
|
23025
|
-
exec "${nodePath}" "${executablePath}"
|
|
23192
|
+
exec "${nodePath}" "${executablePath}" ${args}
|
|
23026
23193
|
`;
|
|
23027
23194
|
fs13.writeFileSync(wrapperPath, script, { mode: 493 });
|
|
23028
23195
|
return wrapperPath;
|
|
23029
23196
|
};
|
|
23197
|
+
var installNativeHosts = (platform, extensionId, executablePath) => {
|
|
23198
|
+
fs13.mkdirSync(getManifestDir(platform), { recursive: true });
|
|
23199
|
+
return HOST_NAMES.map((hostName) => {
|
|
23200
|
+
const wrapperPath = createWrapperScript(platform, executablePath, hostName);
|
|
23201
|
+
const manifestPath = getManifestPath(platform, hostName);
|
|
23202
|
+
const manifest = createManifest(extensionId, wrapperPath, hostName);
|
|
23203
|
+
fs13.writeFileSync(manifestPath, JSON.stringify(manifest, null, 2));
|
|
23204
|
+
registerWindowsNativeHost(platform, hostName, manifestPath);
|
|
23205
|
+
return { hostName, manifestPath, wrapperPath };
|
|
23206
|
+
});
|
|
23207
|
+
};
|
|
23208
|
+
var inspectNativeHosts = (platform) => {
|
|
23209
|
+
return HOST_NAMES.map((hostName) => inspectNativeHost(platform, hostName));
|
|
23210
|
+
};
|
|
23211
|
+
var removeNativeHosts = (platform) => {
|
|
23212
|
+
return HOST_NAMES.map((hostName) => {
|
|
23213
|
+
const host = inspectNativeHost(platform, hostName);
|
|
23214
|
+
const manifestRemoved = removeFileIfExists(host.manifestPath);
|
|
23215
|
+
const wrapperRemoved = removeFileIfExists(host.wrapperPath);
|
|
23216
|
+
unregisterWindowsNativeHost(platform, hostName);
|
|
23217
|
+
return { ...host, manifestRemoved, wrapperRemoved };
|
|
23218
|
+
});
|
|
23219
|
+
};
|
|
23220
|
+
var inspectNativeHost = (platform, hostName) => {
|
|
23221
|
+
const manifestPath = getManifestPath(platform, hostName);
|
|
23222
|
+
const wrapperPath = getWrapperPath(platform, hostName);
|
|
23223
|
+
const manifestExists = fs13.existsSync(manifestPath);
|
|
23224
|
+
const wrapperExists = fs13.existsSync(wrapperPath);
|
|
23225
|
+
const wrapperExecutable = wrapperExists && isWrapperExecutable(wrapperPath);
|
|
23226
|
+
const manifest = manifestExists ? readManifest(manifestPath) : null;
|
|
23227
|
+
const manifestValid = Boolean(manifest && manifest.name === hostName && manifest.type === "stdio" && Array.isArray(manifest.allowed_origins));
|
|
23228
|
+
const extensionId = extractExtensionId(manifest?.allowed_origins?.[0]);
|
|
23229
|
+
return {
|
|
23230
|
+
hostName,
|
|
23231
|
+
manifestPath,
|
|
23232
|
+
wrapperPath,
|
|
23233
|
+
manifestExists,
|
|
23234
|
+
manifestValid,
|
|
23235
|
+
wrapperExists,
|
|
23236
|
+
wrapperExecutable,
|
|
23237
|
+
configured: manifestExists && manifestValid && wrapperExists && wrapperExecutable,
|
|
23238
|
+
installed: manifestExists && wrapperExists,
|
|
23239
|
+
extensionId,
|
|
23240
|
+
argusPath: manifest?.path ?? null
|
|
23241
|
+
};
|
|
23242
|
+
};
|
|
23030
23243
|
var readManifest = (manifestPath) => {
|
|
23031
23244
|
try {
|
|
23032
23245
|
const content = fs13.readFileSync(manifestPath, "utf8");
|
|
@@ -23050,6 +23263,36 @@ var shortenPath = (filePath) => {
|
|
|
23050
23263
|
}
|
|
23051
23264
|
return filePath;
|
|
23052
23265
|
};
|
|
23266
|
+
var extractExtensionId = (origin) => {
|
|
23267
|
+
if (!origin) {
|
|
23268
|
+
return null;
|
|
23269
|
+
}
|
|
23270
|
+
const match = origin.match(/^chrome-extension:\/\/([^/]+)\/$/);
|
|
23271
|
+
return match?.[1] ?? null;
|
|
23272
|
+
};
|
|
23273
|
+
var removeFileIfExists = (filePath) => {
|
|
23274
|
+
if (!fs13.existsSync(filePath)) {
|
|
23275
|
+
return false;
|
|
23276
|
+
}
|
|
23277
|
+
fs13.unlinkSync(filePath);
|
|
23278
|
+
return true;
|
|
23279
|
+
};
|
|
23280
|
+
var registerWindowsNativeHost = (platform, hostName, manifestPath) => {
|
|
23281
|
+
if (platform !== "win32") {
|
|
23282
|
+
return;
|
|
23283
|
+
}
|
|
23284
|
+
const regKey = `HKCU\\Software\\Google\\Chrome\\NativeMessagingHosts\\${hostName}`;
|
|
23285
|
+
execSync(`reg add "${regKey}" /ve /t REG_SZ /d "${manifestPath}" /f`, { stdio: "pipe" });
|
|
23286
|
+
};
|
|
23287
|
+
var unregisterWindowsNativeHost = (platform, hostName) => {
|
|
23288
|
+
if (platform !== "win32") {
|
|
23289
|
+
return;
|
|
23290
|
+
}
|
|
23291
|
+
const regKey = `HKCU\\Software\\Google\\Chrome\\NativeMessagingHosts\\${hostName}`;
|
|
23292
|
+
try {
|
|
23293
|
+
execSync(`reg delete "${regKey}" /f`, { stdio: "pipe" });
|
|
23294
|
+
} catch {}
|
|
23295
|
+
};
|
|
23053
23296
|
|
|
23054
23297
|
// dist/commands/extension/setup.js
|
|
23055
23298
|
var runExtensionSetup = async (options) => {
|
|
@@ -23067,10 +23310,6 @@ var runExtensionSetup = async (options) => {
|
|
|
23067
23310
|
process.exitCode = 1;
|
|
23068
23311
|
return;
|
|
23069
23312
|
}
|
|
23070
|
-
const manifestDir = getManifestDir(platform);
|
|
23071
|
-
const manifestPath = getManifestPath(platform);
|
|
23072
|
-
const wrapperPath = getWrapperPath(platform);
|
|
23073
|
-
fs14.mkdirSync(manifestDir, { recursive: true });
|
|
23074
23313
|
let executablePath;
|
|
23075
23314
|
try {
|
|
23076
23315
|
executablePath = findArgusExecutable();
|
|
@@ -23083,51 +23322,44 @@ var runExtensionSetup = async (options) => {
|
|
|
23083
23322
|
process.exitCode = 1;
|
|
23084
23323
|
return;
|
|
23085
23324
|
}
|
|
23086
|
-
|
|
23087
|
-
|
|
23088
|
-
|
|
23089
|
-
|
|
23090
|
-
|
|
23091
|
-
|
|
23092
|
-
|
|
23093
|
-
|
|
23094
|
-
if (options.json) {
|
|
23095
|
-
output.writeJson({ success: false, error: `Failed to add registry key: ${error.message}` });
|
|
23096
|
-
} else {
|
|
23097
|
-
console.error("Failed to add registry key:", error);
|
|
23098
|
-
}
|
|
23099
|
-
process.exitCode = 1;
|
|
23100
|
-
return;
|
|
23325
|
+
let installedHosts;
|
|
23326
|
+
try {
|
|
23327
|
+
installedHosts = installNativeHosts(platform, extensionId, executablePath);
|
|
23328
|
+
} catch (error) {
|
|
23329
|
+
if (options.json) {
|
|
23330
|
+
output.writeJson({ success: false, error: `Failed to install native hosts: ${error.message}` });
|
|
23331
|
+
} else {
|
|
23332
|
+
console.error("Failed to install native hosts:", error);
|
|
23101
23333
|
}
|
|
23334
|
+
process.exitCode = 1;
|
|
23335
|
+
return;
|
|
23102
23336
|
}
|
|
23103
23337
|
if (options.json) {
|
|
23104
23338
|
output.writeJson({
|
|
23105
23339
|
success: true,
|
|
23106
|
-
hostName: HOST_NAME,
|
|
23107
23340
|
extensionId,
|
|
23108
|
-
|
|
23109
|
-
wrapperPath,
|
|
23341
|
+
hosts: installedHosts,
|
|
23110
23342
|
argusPath: executablePath
|
|
23111
23343
|
});
|
|
23112
23344
|
} else {
|
|
23113
23345
|
output.writeHuman("");
|
|
23114
|
-
output.writeHuman("Native messaging
|
|
23346
|
+
output.writeHuman("Native messaging hosts installed");
|
|
23115
23347
|
output.writeHuman("");
|
|
23116
|
-
output.writeHuman(` Host name: ${HOST_NAME}`);
|
|
23117
23348
|
output.writeHuman(` Extension ID: ${extensionId}`);
|
|
23118
|
-
|
|
23119
|
-
|
|
23349
|
+
for (const host of installedHosts) {
|
|
23350
|
+
output.writeHuman(` Host name: ${host.hostName}`);
|
|
23351
|
+
output.writeHuman(` Manifest: ${shortenPath(host.manifestPath)}`);
|
|
23352
|
+
output.writeHuman(` Wrapper: ${shortenPath(host.wrapperPath)}`);
|
|
23353
|
+
}
|
|
23120
23354
|
output.writeHuman("");
|
|
23121
23355
|
output.writeHuman("Next steps:");
|
|
23122
23356
|
output.writeHuman(" 1. Reload the extension in chrome://extensions");
|
|
23123
|
-
output.writeHuman(" 2.
|
|
23357
|
+
output.writeHuman(" 2. Run `argus ext tabs` or open the extension popup and attach a tab");
|
|
23124
23358
|
output.writeHuman("");
|
|
23125
23359
|
}
|
|
23126
23360
|
};
|
|
23127
23361
|
|
|
23128
23362
|
// dist/commands/extension/remove.js
|
|
23129
|
-
import fs15 from "node:fs";
|
|
23130
|
-
import { execSync as execSync3 } from "node:child_process";
|
|
23131
23363
|
var runExtensionRemove = async (options) => {
|
|
23132
23364
|
const output = createOutput(options);
|
|
23133
23365
|
let platform;
|
|
@@ -23142,55 +23374,42 @@ var runExtensionRemove = async (options) => {
|
|
|
23142
23374
|
process.exitCode = 1;
|
|
23143
23375
|
return;
|
|
23144
23376
|
}
|
|
23145
|
-
const
|
|
23146
|
-
const
|
|
23147
|
-
|
|
23148
|
-
let wrapperRemoved = false;
|
|
23149
|
-
if (fs15.existsSync(manifestPath)) {
|
|
23150
|
-
fs15.unlinkSync(manifestPath);
|
|
23151
|
-
manifestRemoved = true;
|
|
23152
|
-
}
|
|
23153
|
-
if (fs15.existsSync(wrapperPath)) {
|
|
23154
|
-
fs15.unlinkSync(wrapperPath);
|
|
23155
|
-
wrapperRemoved = true;
|
|
23156
|
-
}
|
|
23157
|
-
if (platform === "win32") {
|
|
23158
|
-
const regKey = `HKCU\\Software\\Google\\Chrome\\NativeMessagingHosts\\${HOST_NAME}`;
|
|
23159
|
-
try {
|
|
23160
|
-
execSync3(`reg delete "${regKey}" /f`, { stdio: "pipe" });
|
|
23161
|
-
} catch {}
|
|
23162
|
-
}
|
|
23377
|
+
const removedHosts = removeNativeHosts(platform);
|
|
23378
|
+
const manifestRemoved = removedHosts.some((host) => host.manifestRemoved);
|
|
23379
|
+
const wrapperRemoved = removedHosts.some((host) => host.wrapperRemoved);
|
|
23163
23380
|
if (options.json) {
|
|
23164
23381
|
output.writeJson({
|
|
23165
23382
|
success: true,
|
|
23166
23383
|
manifestRemoved,
|
|
23167
23384
|
wrapperRemoved,
|
|
23168
|
-
|
|
23169
|
-
wrapperPath
|
|
23385
|
+
hosts: removedHosts
|
|
23170
23386
|
});
|
|
23171
23387
|
} else {
|
|
23172
23388
|
output.writeHuman("");
|
|
23173
23389
|
if (manifestRemoved || wrapperRemoved) {
|
|
23174
|
-
output.writeHuman("Native messaging
|
|
23390
|
+
output.writeHuman("Native messaging hosts removed");
|
|
23175
23391
|
output.writeHuman("");
|
|
23176
|
-
|
|
23177
|
-
|
|
23178
|
-
|
|
23179
|
-
|
|
23180
|
-
|
|
23392
|
+
for (const host of removedHosts) {
|
|
23393
|
+
if (host.manifestRemoved) {
|
|
23394
|
+
output.writeHuman(` Removed manifest: ${shortenPath(host.manifestPath)}`);
|
|
23395
|
+
}
|
|
23396
|
+
if (host.wrapperRemoved) {
|
|
23397
|
+
output.writeHuman(` Removed wrapper: ${shortenPath(host.wrapperPath)}`);
|
|
23398
|
+
}
|
|
23181
23399
|
}
|
|
23182
23400
|
} else {
|
|
23183
|
-
output.writeHuman("Native messaging
|
|
23401
|
+
output.writeHuman("Native messaging hosts were not installed");
|
|
23184
23402
|
output.writeHuman("");
|
|
23185
|
-
|
|
23186
|
-
|
|
23403
|
+
for (const host of removedHosts) {
|
|
23404
|
+
output.writeHuman(` Manifest not found: ${shortenPath(host.manifestPath)}`);
|
|
23405
|
+
output.writeHuman(` Wrapper not found: ${shortenPath(host.wrapperPath)}`);
|
|
23406
|
+
}
|
|
23187
23407
|
}
|
|
23188
23408
|
output.writeHuman("");
|
|
23189
23409
|
}
|
|
23190
23410
|
};
|
|
23191
23411
|
|
|
23192
23412
|
// dist/commands/extension/status.js
|
|
23193
|
-
import fs16 from "node:fs";
|
|
23194
23413
|
var runExtensionStatus = async (options) => {
|
|
23195
23414
|
const output = createOutput(options);
|
|
23196
23415
|
let platform;
|
|
@@ -23205,40 +23424,14 @@ var runExtensionStatus = async (options) => {
|
|
|
23205
23424
|
process.exitCode = 1;
|
|
23206
23425
|
return;
|
|
23207
23426
|
}
|
|
23208
|
-
const
|
|
23209
|
-
const
|
|
23210
|
-
const
|
|
23211
|
-
const wrapperExists = fs16.existsSync(wrapperPath);
|
|
23212
|
-
const wrapperExecutable = wrapperExists && isWrapperExecutable(wrapperPath);
|
|
23213
|
-
let manifest = null;
|
|
23214
|
-
let manifestValid = false;
|
|
23215
|
-
let extensionId = null;
|
|
23216
|
-
if (manifestExists) {
|
|
23217
|
-
manifest = readManifest(manifestPath);
|
|
23218
|
-
if (manifest && manifest.name === HOST_NAME && manifest.type === "stdio" && Array.isArray(manifest.allowed_origins)) {
|
|
23219
|
-
manifestValid = true;
|
|
23220
|
-
const origin = manifest.allowed_origins[0];
|
|
23221
|
-
if (origin) {
|
|
23222
|
-
const match = origin.match(/^chrome-extension:\/\/([^/]+)\/$/);
|
|
23223
|
-
if (match) {
|
|
23224
|
-
extensionId = match[1];
|
|
23225
|
-
}
|
|
23226
|
-
}
|
|
23227
|
-
}
|
|
23228
|
-
}
|
|
23229
|
-
const configured = manifestExists && manifestValid && wrapperExists && wrapperExecutable;
|
|
23427
|
+
const hosts = inspectNativeHosts(platform);
|
|
23428
|
+
const configured = hosts.every((host) => host.configured);
|
|
23429
|
+
const extensionId = hosts.find((host) => host.extensionId)?.extensionId ?? null;
|
|
23230
23430
|
if (options.json) {
|
|
23231
23431
|
output.writeJson({
|
|
23232
23432
|
configured,
|
|
23233
|
-
|
|
23234
|
-
|
|
23235
|
-
wrapperPath,
|
|
23236
|
-
manifestExists,
|
|
23237
|
-
manifestValid,
|
|
23238
|
-
wrapperExists,
|
|
23239
|
-
wrapperExecutable,
|
|
23240
|
-
extensionId,
|
|
23241
|
-
argusPath: manifest?.path ?? null
|
|
23433
|
+
hosts,
|
|
23434
|
+
extensionId
|
|
23242
23435
|
});
|
|
23243
23436
|
if (!configured) {
|
|
23244
23437
|
process.exitCode = 1;
|
|
@@ -23247,16 +23440,17 @@ var runExtensionStatus = async (options) => {
|
|
|
23247
23440
|
}
|
|
23248
23441
|
output.writeHuman("");
|
|
23249
23442
|
if (configured) {
|
|
23250
|
-
output.writeHuman("Native messaging
|
|
23443
|
+
output.writeHuman("Native messaging hosts are configured");
|
|
23251
23444
|
output.writeHuman("");
|
|
23252
|
-
output.writeHuman(` Manifest: exists`);
|
|
23253
|
-
output.writeHuman(` Wrapper: exists, executable`);
|
|
23254
23445
|
output.writeHuman(` Extension ID: ${extensionId}`);
|
|
23255
23446
|
} else {
|
|
23256
|
-
output.writeHuman("Native messaging
|
|
23447
|
+
output.writeHuman("Native messaging hosts not configured");
|
|
23257
23448
|
output.writeHuman("");
|
|
23258
|
-
|
|
23259
|
-
|
|
23449
|
+
for (const host of hosts) {
|
|
23450
|
+
output.writeHuman(` ${host.hostName}`);
|
|
23451
|
+
output.writeHuman(` Manifest: ${host.manifestExists ? host.manifestValid ? "exists" : "exists, invalid" : "not found"}`);
|
|
23452
|
+
output.writeHuman(` Wrapper: ${host.wrapperExists ? host.wrapperExecutable ? "exists, executable" : "exists, not executable" : "not found"}`);
|
|
23453
|
+
}
|
|
23260
23454
|
if (extensionId) {
|
|
23261
23455
|
output.writeHuman(` Extension ID: ${extensionId}`);
|
|
23262
23456
|
}
|
|
@@ -23268,7 +23462,6 @@ var runExtensionStatus = async (options) => {
|
|
|
23268
23462
|
};
|
|
23269
23463
|
|
|
23270
23464
|
// dist/commands/extension/info.js
|
|
23271
|
-
import fs17 from "node:fs";
|
|
23272
23465
|
var runExtensionInfo = async (options) => {
|
|
23273
23466
|
const output = createOutput(options);
|
|
23274
23467
|
let platform;
|
|
@@ -23283,51 +23476,32 @@ var runExtensionInfo = async (options) => {
|
|
|
23283
23476
|
process.exitCode = 1;
|
|
23284
23477
|
return;
|
|
23285
23478
|
}
|
|
23286
|
-
const
|
|
23287
|
-
const
|
|
23288
|
-
const manifestExists = fs17.existsSync(manifestPath);
|
|
23289
|
-
const wrapperExists = fs17.existsSync(wrapperPath);
|
|
23290
|
-
let extensionId = null;
|
|
23291
|
-
let argusPath = null;
|
|
23292
|
-
if (manifestExists) {
|
|
23293
|
-
const manifest = readManifest(manifestPath);
|
|
23294
|
-
if (manifest) {
|
|
23295
|
-
argusPath = manifest.path;
|
|
23296
|
-
const origin = manifest.allowed_origins?.[0];
|
|
23297
|
-
if (origin) {
|
|
23298
|
-
const match = origin.match(/^chrome-extension:\/\/([^/]+)\/$/);
|
|
23299
|
-
if (match) {
|
|
23300
|
-
extensionId = match[1];
|
|
23301
|
-
}
|
|
23302
|
-
}
|
|
23303
|
-
}
|
|
23304
|
-
}
|
|
23305
|
-
const installed = manifestExists && wrapperExists;
|
|
23479
|
+
const hosts = inspectNativeHosts(platform);
|
|
23480
|
+
const installed = hosts.every((host) => host.installed);
|
|
23306
23481
|
if (options.json) {
|
|
23307
23482
|
output.writeJson({
|
|
23308
|
-
hostName: HOST_NAME,
|
|
23309
23483
|
platform,
|
|
23310
|
-
manifestPath,
|
|
23311
|
-
wrapperPath,
|
|
23312
23484
|
installed,
|
|
23313
|
-
|
|
23314
|
-
argusPath
|
|
23485
|
+
hosts
|
|
23315
23486
|
});
|
|
23316
23487
|
return;
|
|
23317
23488
|
}
|
|
23318
23489
|
output.writeHuman("");
|
|
23319
23490
|
output.writeHuman("Native Messaging Host Info");
|
|
23320
23491
|
output.writeHuman("");
|
|
23321
|
-
output.writeHuman(` Host name: ${HOST_NAME}`);
|
|
23322
23492
|
output.writeHuman(` Platform: ${platform}`);
|
|
23323
|
-
|
|
23324
|
-
|
|
23493
|
+
for (const host of hosts) {
|
|
23494
|
+
output.writeHuman(` Host name: ${host.hostName}`);
|
|
23495
|
+
output.writeHuman(` Manifest path: ${shortenPath(host.manifestPath)}`);
|
|
23496
|
+
output.writeHuman(` Wrapper path: ${shortenPath(host.wrapperPath)}`);
|
|
23497
|
+
}
|
|
23325
23498
|
output.writeHuman("");
|
|
23326
23499
|
output.writeHuman("Current configuration:");
|
|
23327
23500
|
output.writeHuman(` Installed: ${installed ? "yes" : "no"}`);
|
|
23328
|
-
|
|
23329
|
-
output.writeHuman(`
|
|
23330
|
-
output.writeHuman(`
|
|
23501
|
+
for (const host of hosts.filter((entry) => entry.installed)) {
|
|
23502
|
+
output.writeHuman(` ${host.hostName}`);
|
|
23503
|
+
output.writeHuman(` Extension ID: ${host.extensionId ?? "(unknown)"}`);
|
|
23504
|
+
output.writeHuman(` Argus path: ${host.argusPath ?? "(unknown)"}`);
|
|
23331
23505
|
}
|
|
23332
23506
|
output.writeHuman("");
|
|
23333
23507
|
};
|
|
@@ -23355,38 +23529,23 @@ var resolveExtensionWatcher = async (input) => {
|
|
|
23355
23529
|
if (extensionWatchers.length === 0) {
|
|
23356
23530
|
return {
|
|
23357
23531
|
ok: false,
|
|
23358
|
-
error: "No extension-backed watchers found.
|
|
23532
|
+
error: "No extension-backed watchers found. Reload the extension after `argus extension setup`, or attach a tab in the extension popup.",
|
|
23359
23533
|
exitCode: 2
|
|
23360
23534
|
};
|
|
23361
23535
|
}
|
|
23362
|
-
const
|
|
23363
|
-
|
|
23364
|
-
status
|
|
23365
|
-
|
|
23366
|
-
|
|
23367
|
-
|
|
23368
|
-
return { ok: true, watcher: attached[0].watcher, registry: registry2 };
|
|
23369
|
-
}
|
|
23370
|
-
const cwd = process.cwd();
|
|
23371
|
-
const cwdMatches = extensionWatchers.filter((watcher) => watcher.cwd === cwd);
|
|
23372
|
-
const attachedCwdMatches = attached.filter((entry) => entry.watcher.cwd === cwd);
|
|
23373
|
-
if (attachedCwdMatches.length === 1) {
|
|
23374
|
-
return { ok: true, watcher: attachedCwdMatches[0].watcher, registry: registry2 };
|
|
23375
|
-
}
|
|
23376
|
-
if (attached.length > 1) {
|
|
23377
|
-
return { ok: false, error: "Watcher id required.", exitCode: 2, candidates: attached.map((entry) => entry.watcher) };
|
|
23378
|
-
}
|
|
23379
|
-
if (cwdMatches.length === 1) {
|
|
23380
|
-
return { ok: true, watcher: cwdMatches[0], registry: registry2 };
|
|
23381
|
-
}
|
|
23382
|
-
if (cwdMatches.length > 1) {
|
|
23383
|
-
return { ok: false, error: "Watcher id required.", exitCode: 2, candidates: cwdMatches };
|
|
23384
|
-
}
|
|
23385
|
-
const reachable = reachability.filter((entry) => entry.status.ok);
|
|
23386
|
-
if (reachable.length === 1) {
|
|
23387
|
-
return { ok: true, watcher: reachable[0].watcher, registry: registry2 };
|
|
23536
|
+
const controlWatcher = registry2.watchers[CONTROL_WATCHER_ID];
|
|
23537
|
+
if (controlWatcher?.source === "extension") {
|
|
23538
|
+
const status = await checkWatcherStatus3(controlWatcher);
|
|
23539
|
+
if (status.ok) {
|
|
23540
|
+
return { ok: true, watcher: controlWatcher, registry: registry2 };
|
|
23541
|
+
}
|
|
23388
23542
|
}
|
|
23389
|
-
return {
|
|
23543
|
+
return {
|
|
23544
|
+
ok: false,
|
|
23545
|
+
error: "extension-control watcher is unavailable. Reload the extension after `argus extension setup`.",
|
|
23546
|
+
exitCode: 2,
|
|
23547
|
+
candidates: extensionWatchers
|
|
23548
|
+
};
|
|
23390
23549
|
};
|
|
23391
23550
|
var getExtensionWatchers = (watchers) => watchers.filter((watcher) => watcher.source === "extension");
|
|
23392
23551
|
var checkWatcherStatus3 = async (watcher) => {
|
|
@@ -23479,6 +23638,173 @@ var writeCommandError = (output, options, humanMessage, jsonPayload) => {
|
|
|
23479
23638
|
};
|
|
23480
23639
|
var formatError4 = (error) => error instanceof Error ? error.message : String(error);
|
|
23481
23640
|
|
|
23641
|
+
// dist/commands/extension/attach.js
|
|
23642
|
+
var runExtensionAttach = async (options) => {
|
|
23643
|
+
await runExtensionTabAction("attach", options);
|
|
23644
|
+
};
|
|
23645
|
+
var runExtensionDetach = async (options) => {
|
|
23646
|
+
await runExtensionTabAction("detach", options);
|
|
23647
|
+
};
|
|
23648
|
+
var runExtensionTabAction = async (action, options) => {
|
|
23649
|
+
const output = createOutput(options);
|
|
23650
|
+
const resolved = await resolveExtensionWatcher({});
|
|
23651
|
+
if (!resolved.ok) {
|
|
23652
|
+
writeResolveFailure2(output, options, resolved);
|
|
23653
|
+
return;
|
|
23654
|
+
}
|
|
23655
|
+
const selector = parseTabSelector(options);
|
|
23656
|
+
if (!selector.ok) {
|
|
23657
|
+
writeTabResolutionFailure(output, options, selector);
|
|
23658
|
+
return;
|
|
23659
|
+
}
|
|
23660
|
+
const tabs = await fetchTabs(resolved.watcher, selector.selector, output, options);
|
|
23661
|
+
if (!tabs) {
|
|
23662
|
+
return;
|
|
23663
|
+
}
|
|
23664
|
+
const tab = resolveTab(tabs, selector.selector);
|
|
23665
|
+
if (!tab.ok) {
|
|
23666
|
+
writeTabResolutionFailure(output, options, tab);
|
|
23667
|
+
return;
|
|
23668
|
+
}
|
|
23669
|
+
let response;
|
|
23670
|
+
try {
|
|
23671
|
+
response = await fetchWatcherJson(resolved.watcher, {
|
|
23672
|
+
path: action === "attach" ? "/attach" : "/detach",
|
|
23673
|
+
method: "POST",
|
|
23674
|
+
body: { tabId: tab.tab.tabId },
|
|
23675
|
+
timeoutMs: 5000,
|
|
23676
|
+
returnErrorResponse: true
|
|
23677
|
+
});
|
|
23678
|
+
} catch (error) {
|
|
23679
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
23680
|
+
writeCommandError2(output, options, `${resolved.watcher.id}: failed to ${action} tab (${message})`, message);
|
|
23681
|
+
return;
|
|
23682
|
+
}
|
|
23683
|
+
if (!response.ok) {
|
|
23684
|
+
writeCommandError2(output, options, `Error: ${response.error.message}`, response);
|
|
23685
|
+
return;
|
|
23686
|
+
}
|
|
23687
|
+
if (options.json) {
|
|
23688
|
+
output.writeJson({
|
|
23689
|
+
ok: true,
|
|
23690
|
+
tab: tab.tab,
|
|
23691
|
+
watcherId: resolved.watcher.id
|
|
23692
|
+
});
|
|
23693
|
+
return;
|
|
23694
|
+
}
|
|
23695
|
+
const verb = action === "attach" ? "Attach" : "Detach";
|
|
23696
|
+
output.writeHuman(`${verb} request sent via ${resolved.watcher.id}`);
|
|
23697
|
+
output.writeHuman(` ${formatExtensionTabLine2(tab.tab)}`);
|
|
23698
|
+
};
|
|
23699
|
+
var fetchTabs = async (watcher, selector, output, options) => {
|
|
23700
|
+
const query = buildTabsQuery2(selector);
|
|
23701
|
+
try {
|
|
23702
|
+
const response = await fetchWatcherJson(watcher, {
|
|
23703
|
+
path: "/tabs",
|
|
23704
|
+
query,
|
|
23705
|
+
timeoutMs: 5000,
|
|
23706
|
+
returnErrorResponse: true
|
|
23707
|
+
});
|
|
23708
|
+
if (!response.ok) {
|
|
23709
|
+
writeCommandError2(output, options, `Error: ${response.error.message}`, response);
|
|
23710
|
+
return null;
|
|
23711
|
+
}
|
|
23712
|
+
return response.tabs;
|
|
23713
|
+
} catch (error) {
|
|
23714
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
23715
|
+
writeCommandError2(output, options, `${watcher.id}: failed to list extension tabs (${message})`, message);
|
|
23716
|
+
return null;
|
|
23717
|
+
}
|
|
23718
|
+
};
|
|
23719
|
+
var parseTabSelector = (options) => {
|
|
23720
|
+
const tabId = parseTabId(options.tab);
|
|
23721
|
+
const url = options.url?.trim();
|
|
23722
|
+
const title = options.title?.trim();
|
|
23723
|
+
if (tabId !== null && (url || title)) {
|
|
23724
|
+
return { ok: false, reason: "Use --tab by itself, or resolve by --url/--title.", exitCode: 2 };
|
|
23725
|
+
}
|
|
23726
|
+
if (tabId === null && !url && !title) {
|
|
23727
|
+
return { ok: false, reason: "Specify --tab <tabId>, --url <substring>, or --title <substring>.", exitCode: 2 };
|
|
23728
|
+
}
|
|
23729
|
+
if (options.tab != null && tabId === null) {
|
|
23730
|
+
return { ok: false, reason: `Invalid --tab value: ${options.tab}`, exitCode: 2 };
|
|
23731
|
+
}
|
|
23732
|
+
if (tabId !== null) {
|
|
23733
|
+
return { ok: true, selector: { kind: "tab", tabId } };
|
|
23734
|
+
}
|
|
23735
|
+
return { ok: true, selector: { kind: "query", url, title } };
|
|
23736
|
+
};
|
|
23737
|
+
var resolveTab = (tabs, selector) => {
|
|
23738
|
+
const matches = selector.kind === "tab" ? tabs.filter((tab) => tab.tabId === selector.tabId) : tabs;
|
|
23739
|
+
if (matches.length === 0) {
|
|
23740
|
+
return { ok: false, reason: "No extension tab matched.", exitCode: 2 };
|
|
23741
|
+
}
|
|
23742
|
+
if (matches.length > 1) {
|
|
23743
|
+
return { ok: false, reason: "Multiple extension tabs matched. Use --tab to pick one.", exitCode: 2, matches };
|
|
23744
|
+
}
|
|
23745
|
+
return { ok: true, tab: matches[0] };
|
|
23746
|
+
};
|
|
23747
|
+
var parseTabId = (value) => {
|
|
23748
|
+
if (value === undefined) {
|
|
23749
|
+
return null;
|
|
23750
|
+
}
|
|
23751
|
+
const tabId = typeof value === "number" ? value : Number(value);
|
|
23752
|
+
return Number.isInteger(tabId) ? tabId : null;
|
|
23753
|
+
};
|
|
23754
|
+
var buildTabsQuery2 = (selector) => {
|
|
23755
|
+
const query = new URLSearchParams;
|
|
23756
|
+
if (selector.kind === "tab") {
|
|
23757
|
+
return query;
|
|
23758
|
+
}
|
|
23759
|
+
if (selector.url) {
|
|
23760
|
+
query.set("url", selector.url);
|
|
23761
|
+
}
|
|
23762
|
+
if (selector.title) {
|
|
23763
|
+
query.set("title", selector.title);
|
|
23764
|
+
}
|
|
23765
|
+
return query;
|
|
23766
|
+
};
|
|
23767
|
+
var writeTabResolutionFailure = (output, options, result) => {
|
|
23768
|
+
const matches = "matches" in result ? result.matches : undefined;
|
|
23769
|
+
if (options.json) {
|
|
23770
|
+
output.writeJson({ ok: false, error: result.reason, matches: matches ?? [] });
|
|
23771
|
+
} else {
|
|
23772
|
+
output.writeWarn(result.reason);
|
|
23773
|
+
if (matches) {
|
|
23774
|
+
for (const tab of matches) {
|
|
23775
|
+
output.writeWarn(` ${formatExtensionTabLine2(tab)}`);
|
|
23776
|
+
}
|
|
23777
|
+
}
|
|
23778
|
+
}
|
|
23779
|
+
process.exitCode = result.exitCode;
|
|
23780
|
+
};
|
|
23781
|
+
var writeResolveFailure2 = (output, options, resolved) => {
|
|
23782
|
+
if (options.json) {
|
|
23783
|
+
output.writeJson({ ok: false, error: resolved.error, candidates: resolved.candidates?.map((watcher) => watcher.id) ?? [] });
|
|
23784
|
+
} else {
|
|
23785
|
+
output.writeWarn(resolved.error);
|
|
23786
|
+
if (resolved.candidates && resolved.candidates.length > 0) {
|
|
23787
|
+
for (const watcher of resolved.candidates) {
|
|
23788
|
+
output.writeWarn(formatWatcherLine(watcher));
|
|
23789
|
+
}
|
|
23790
|
+
}
|
|
23791
|
+
}
|
|
23792
|
+
process.exitCode = resolved.exitCode;
|
|
23793
|
+
};
|
|
23794
|
+
var writeCommandError2 = (output, options, humanMessage, jsonPayload) => {
|
|
23795
|
+
if (options.json) {
|
|
23796
|
+
output.writeJson(typeof jsonPayload === "string" ? { ok: false, error: jsonPayload } : jsonPayload);
|
|
23797
|
+
} else {
|
|
23798
|
+
output.writeWarn(humanMessage);
|
|
23799
|
+
}
|
|
23800
|
+
process.exitCode = 1;
|
|
23801
|
+
};
|
|
23802
|
+
var formatExtensionTabLine2 = (tab) => {
|
|
23803
|
+
const state2 = tab.attached ? "attached" : "available";
|
|
23804
|
+
const label = tab.title || "(untitled)";
|
|
23805
|
+
return `${tab.tabId} [${state2}] ${label} - ${tab.url}`;
|
|
23806
|
+
};
|
|
23807
|
+
|
|
23482
23808
|
// dist/cli/register/registerExtension.js
|
|
23483
23809
|
function registerExtension(program2) {
|
|
23484
23810
|
const extension = program2.command("extension").alias("ext").description("Browser extension management");
|
|
@@ -23500,7 +23826,7 @@ To get your extension ID:
|
|
|
23500
23826
|
extension.command("info").description("Show native messaging host paths and configuration").option("--json", "Output JSON for automation").action(async (options) => {
|
|
23501
23827
|
await runExtensionInfo(options);
|
|
23502
23828
|
});
|
|
23503
|
-
extension.command("tabs").description("List browser tabs visible to the extension transport").option("--id <watcherId>", "Extension-backed watcher id to use as the transport").option("--url <substring>", "Filter tabs by URL substring").option("--title <substring>", "Filter tabs by title substring").option("--json", "Output JSON for automation").addHelpText("after", `
|
|
23829
|
+
extension.command("tabs").description("List browser tabs visible to the extension transport").option("--id <watcherId>", "Extension-backed watcher id to use as the transport (default: extension-control)").option("--url <substring>", "Filter tabs by URL substring").option("--title <substring>", "Filter tabs by title substring").option("--json", "Output JSON for automation").addHelpText("after", `
|
|
23504
23830
|
Examples:
|
|
23505
23831
|
$ argus ext tabs
|
|
23506
23832
|
$ argus ext tabs --url localhost
|
|
@@ -23509,6 +23835,22 @@ Examples:
|
|
|
23509
23835
|
`).action(async (options) => {
|
|
23510
23836
|
await runExtensionTabs(options);
|
|
23511
23837
|
});
|
|
23838
|
+
extension.command("attach").description("Ask the extension control watcher to attach a browser tab").option("--tab <tabId>", "Browser tab id to attach").option("--url <substring>", "Resolve tab by URL substring").option("--title <substring>", "Resolve tab by title substring").option("--json", "Output JSON for automation").addHelpText("after", `
|
|
23839
|
+
Examples:
|
|
23840
|
+
$ argus ext attach --tab 123
|
|
23841
|
+
$ argus ext attach --url localhost
|
|
23842
|
+
$ argus ext attach --title Docs --json
|
|
23843
|
+
`).action(async (options) => {
|
|
23844
|
+
await runExtensionAttach(options);
|
|
23845
|
+
});
|
|
23846
|
+
extension.command("detach").description("Ask the extension control watcher to detach a browser tab").option("--tab <tabId>", "Browser tab id to detach").option("--url <substring>", "Resolve tab by URL substring").option("--title <substring>", "Resolve tab by title substring").option("--json", "Output JSON for automation").addHelpText("after", `
|
|
23847
|
+
Examples:
|
|
23848
|
+
$ argus ext detach --tab 123
|
|
23849
|
+
$ argus ext detach --url localhost
|
|
23850
|
+
$ argus ext detach --title Docs --json
|
|
23851
|
+
`).action(async (options) => {
|
|
23852
|
+
await runExtensionDetach(options);
|
|
23853
|
+
});
|
|
23512
23854
|
}
|
|
23513
23855
|
|
|
23514
23856
|
// dist/output/code.js
|
|
@@ -33771,7 +34113,7 @@ function hr2(a2, t, e) {
|
|
|
33771
34113
|
}
|
|
33772
34114
|
return t;
|
|
33773
34115
|
}
|
|
33774
|
-
var
|
|
34116
|
+
var fs14 = hr2;
|
|
33775
34117
|
function cr2(a2, t) {
|
|
33776
34118
|
return t === false ? false : a2.charAt(t) === "/" && a2.charAt(t + 1) === "/" ? ls(a2, t) : t;
|
|
33777
34119
|
}
|
|
@@ -33779,7 +34121,7 @@ var ds = cr2;
|
|
|
33779
34121
|
function lr2(a2, t) {
|
|
33780
34122
|
let e = null, s = t;
|
|
33781
34123
|
for (;s !== e; )
|
|
33782
|
-
e = s, s = cs(a2, s), s = ps(a2, s), s = ds(a2, s), s =
|
|
34124
|
+
e = s, s = cs(a2, s), s = ps(a2, s), s = ds(a2, s), s = fs14(a2, s);
|
|
33783
34125
|
return s;
|
|
33784
34126
|
}
|
|
33785
34127
|
var ms = lr2;
|
|
@@ -35779,13 +36121,13 @@ function kc({ node: e, parent: t }) {
|
|
|
35779
36121
|
let r = /^[fx]?(?:describe|it|test)$/u;
|
|
35780
36122
|
return t.type === "TaggedTemplateExpression" && t.quasi === e && t.tag.type === "MemberExpression" && t.tag.property.type === "Identifier" && t.tag.property.name === "each" && (t.tag.object.type === "Identifier" && r.test(t.tag.object.name) || t.tag.object.type === "MemberExpression" && t.tag.object.property.type === "Identifier" && (t.tag.object.property.name === "only" || t.tag.object.property.name === "skip") && t.tag.object.object.type === "Identifier" && r.test(t.tag.object.object.name));
|
|
35781
36123
|
}
|
|
35782
|
-
var
|
|
36124
|
+
var fs15 = [(e, t) => e.type === "ObjectExpression" && t === "properties", (e, t) => e.type === "CallExpression" && e.callee.type === "Identifier" && e.callee.name === "Component" && t === "arguments", (e, t) => e.type === "Decorator" && t === "expression"];
|
|
35783
36125
|
function oo2(e) {
|
|
35784
36126
|
let t = (n) => n.type === "TemplateLiteral", r = (n, s) => Oe3(n) && !n.computed && n.key.type === "Identifier" && n.key.name === "styles" && s === "value";
|
|
35785
|
-
return e.match(t, (n, s) => q3(n) && s === "elements", r, ...
|
|
36127
|
+
return e.match(t, (n, s) => q3(n) && s === "elements", r, ...fs15) || e.match(t, r, ...fs15);
|
|
35786
36128
|
}
|
|
35787
36129
|
function ys2(e) {
|
|
35788
|
-
return e.match((t) => t.type === "TemplateLiteral", (t, r) => Oe3(t) && !t.computed && t.key.type === "Identifier" && t.key.name === "template" && r === "value", ...
|
|
36130
|
+
return e.match((t) => t.type === "TemplateLiteral", (t, r) => Oe3(t) && !t.computed && t.key.type === "Identifier" && t.key.name === "template" && r === "value", ...fs15);
|
|
35789
36131
|
}
|
|
35790
36132
|
function Ds2(e, t) {
|
|
35791
36133
|
return T3(e, x2.Block | x2.Leading, ({ value: r }) => r === ` ${t} `);
|
|
@@ -39692,7 +40034,7 @@ var ft4 = w4((gx, Mi3) => {
|
|
|
39692
40034
|
ct4.default = ct4;
|
|
39693
40035
|
});
|
|
39694
40036
|
var fe3 = w4((wx, zi3) => {
|
|
39695
|
-
var Bi3 = Me4(), Ui3 = ft4(), Fc2 = ut4(), { isClean: Fi3, my: $i3 } = Ht4(),
|
|
40037
|
+
var Bi3 = Me4(), Ui3 = ft4(), Fc2 = ut4(), { isClean: Fi3, my: $i3 } = Ht4(), fs16, Wi3, Gi3, ps3;
|
|
39696
40038
|
function Yi3(t) {
|
|
39697
40039
|
return t.map((e) => (e.nodes && (e.nodes = Yi3(e.nodes)), delete e.source, e));
|
|
39698
40040
|
}
|
|
@@ -39791,7 +40133,7 @@ var fe3 = w4((wx, zi3) => {
|
|
|
39791
40133
|
} else if (e.selector || e.selectors)
|
|
39792
40134
|
e = [new ps3(e)];
|
|
39793
40135
|
else if (e.name)
|
|
39794
|
-
e = [new
|
|
40136
|
+
e = [new fs16(e)];
|
|
39795
40137
|
else if (e.text)
|
|
39796
40138
|
e = [new Bi3(e)];
|
|
39797
40139
|
else
|
|
@@ -39893,7 +40235,7 @@ var fe3 = w4((wx, zi3) => {
|
|
|
39893
40235
|
ps3 = t;
|
|
39894
40236
|
};
|
|
39895
40237
|
z3.registerAtRule = (t) => {
|
|
39896
|
-
|
|
40238
|
+
fs16 = t;
|
|
39897
40239
|
};
|
|
39898
40240
|
z3.registerRoot = (t) => {
|
|
39899
40241
|
Gi3 = t;
|
|
@@ -39901,7 +40243,7 @@ var fe3 = w4((wx, zi3) => {
|
|
|
39901
40243
|
zi3.exports = z3;
|
|
39902
40244
|
z3.default = z3;
|
|
39903
40245
|
z3.rebuild = (t) => {
|
|
39904
|
-
t.type === "atrule" ? Object.setPrototypeOf(t,
|
|
40246
|
+
t.type === "atrule" ? Object.setPrototypeOf(t, fs16.prototype) : t.type === "rule" ? Object.setPrototypeOf(t, ps3.prototype) : t.type === "decl" ? Object.setPrototypeOf(t, Ui3.prototype) : t.type === "comment" ? Object.setPrototypeOf(t, Bi3.prototype) : t.type === "root" && Object.setPrototypeOf(t, Gi3.prototype), t[$i3] = true, t.nodes && t.nodes.forEach((e) => {
|
|
39905
40247
|
z3.rebuild(e);
|
|
39906
40248
|
});
|
|
39907
40249
|
};
|
|
@@ -45252,30 +45594,9 @@ var writeCodeGrepWarnings = (skippedResources, output) => {
|
|
|
45252
45594
|
}
|
|
45253
45595
|
output.writeWarn(warning);
|
|
45254
45596
|
};
|
|
45255
|
-
var writeErrorResponse2 = (response, output) => {
|
|
45256
|
-
if (output.json) {
|
|
45257
|
-
output.writeJson(response);
|
|
45258
|
-
} else {
|
|
45259
|
-
output.writeWarn(`Error: ${response.error.message}`);
|
|
45260
|
-
}
|
|
45261
|
-
process.exitCode = 1;
|
|
45262
|
-
};
|
|
45263
45597
|
var requestCodeResponse = async (id, output, input) => {
|
|
45264
|
-
const result = await
|
|
45265
|
-
|
|
45266
|
-
id,
|
|
45267
|
-
timeoutMs: 30000,
|
|
45268
|
-
returnErrorResponse: true
|
|
45269
|
-
});
|
|
45270
|
-
if (!result.ok) {
|
|
45271
|
-
writeRequestError(result, output);
|
|
45272
|
-
return null;
|
|
45273
|
-
}
|
|
45274
|
-
if (!result.data.ok) {
|
|
45275
|
-
writeErrorResponse2(result.data, output);
|
|
45276
|
-
return null;
|
|
45277
|
-
}
|
|
45278
|
-
return result.data;
|
|
45598
|
+
const result = await requestWatcherCommandAction({ ...input, id, timeoutMs: 30000 }, output);
|
|
45599
|
+
return result?.data ?? null;
|
|
45279
45600
|
};
|
|
45280
45601
|
|
|
45281
45602
|
// dist/commands/codeEdit.js
|
|
@@ -45292,7 +45613,7 @@ var runCodeEdit = async (id, url, options) => {
|
|
|
45292
45613
|
if (source === null) {
|
|
45293
45614
|
return;
|
|
45294
45615
|
}
|
|
45295
|
-
const result = await
|
|
45616
|
+
const result = await requestWatcherCommandAction({
|
|
45296
45617
|
id,
|
|
45297
45618
|
path: "/code/edit",
|
|
45298
45619
|
method: "POST",
|
|
@@ -45327,9 +45648,9 @@ async function resolveEditSource(id, url, options, output) {
|
|
|
45327
45648
|
}
|
|
45328
45649
|
return readStdinSource(output);
|
|
45329
45650
|
}
|
|
45330
|
-
async function readFileSource(
|
|
45651
|
+
async function readFileSource(path15, output) {
|
|
45331
45652
|
try {
|
|
45332
|
-
return { text: await readFile6(
|
|
45653
|
+
return { text: await readFile6(path15, "utf8") };
|
|
45333
45654
|
} catch (error) {
|
|
45334
45655
|
output.writeWarn(`Failed to read file: ${error instanceof Error ? error.message : error}`);
|
|
45335
45656
|
process.exitCode = 1;
|
|
@@ -45403,7 +45724,7 @@ async function loadFullSource(id, url, output) {
|
|
|
45403
45724
|
const chunks = [];
|
|
45404
45725
|
let offset = 0;
|
|
45405
45726
|
for (;; ) {
|
|
45406
|
-
const result = await
|
|
45727
|
+
const result = await requestWatcherCommandAction({
|
|
45407
45728
|
id,
|
|
45408
45729
|
path: "/code/read",
|
|
45409
45730
|
method: "POST",
|
|
@@ -45538,7 +45859,7 @@ var runLocateLabel = async (id, label, options) => {
|
|
|
45538
45859
|
exact: options.exact
|
|
45539
45860
|
}, options);
|
|
45540
45861
|
};
|
|
45541
|
-
var runLocateRequest = async (id,
|
|
45862
|
+
var runLocateRequest = async (id, path15, body, options) => {
|
|
45542
45863
|
const output = createOutput(options);
|
|
45543
45864
|
const action = normalizeLocateAction(options.action, output);
|
|
45544
45865
|
if (action == null && options.action) {
|
|
@@ -45554,9 +45875,9 @@ var runLocateRequest = async (id, path14, body, options) => {
|
|
|
45554
45875
|
process.exitCode = 2;
|
|
45555
45876
|
return;
|
|
45556
45877
|
}
|
|
45557
|
-
const result = await
|
|
45878
|
+
const result = await requestWatcherCommandAction({
|
|
45558
45879
|
id,
|
|
45559
|
-
path:
|
|
45880
|
+
path: path15,
|
|
45560
45881
|
method: "POST",
|
|
45561
45882
|
body,
|
|
45562
45883
|
timeoutMs: 30000
|
|
@@ -45643,44 +45964,60 @@ Examples:
|
|
|
45643
45964
|
});
|
|
45644
45965
|
}
|
|
45645
45966
|
|
|
45646
|
-
// dist/cli/register/index.js
|
|
45647
|
-
var registerDefinedCommands = (program2) => {
|
|
45648
|
-
defineCommands(program2, [domClickCommandDefinition]);
|
|
45649
|
-
};
|
|
45650
|
-
var coreProgramRegistrars = [
|
|
45651
|
-
registerQuickAccess,
|
|
45652
|
-
registerChrome,
|
|
45653
|
-
registerWatcher,
|
|
45654
|
-
registerPage,
|
|
45655
|
-
registerDialog,
|
|
45656
|
-
registerLogs,
|
|
45657
|
-
registerNet,
|
|
45658
|
-
registerAuth,
|
|
45659
|
-
registerEval,
|
|
45660
|
-
registerLocate,
|
|
45661
|
-
registerCode,
|
|
45662
|
-
registerDom,
|
|
45663
|
-
registerDefinedCommands,
|
|
45664
|
-
registerKeydown,
|
|
45665
|
-
registerFill,
|
|
45666
|
-
registerHover,
|
|
45667
|
-
registerScrollTo,
|
|
45668
|
-
registerStorage,
|
|
45669
|
-
registerThrottle,
|
|
45670
|
-
registerSnapshot,
|
|
45671
|
-
registerTrace,
|
|
45672
|
-
registerConfig,
|
|
45673
|
-
registerExtension
|
|
45674
|
-
];
|
|
45675
|
-
|
|
45676
45967
|
// dist/cli/plugins/registerPlugins.js
|
|
45677
|
-
import
|
|
45968
|
+
import path15 from "node:path";
|
|
45969
|
+
import { existsSync as existsSync3 } from "node:fs";
|
|
45678
45970
|
import { pathToFileURL as pathToFileURL2 } from "node:url";
|
|
45679
45971
|
|
|
45680
45972
|
// ../argus-plugin-api/dist/index.js
|
|
45681
45973
|
var ARGUS_PLUGIN_API_VERSION = 1;
|
|
45682
45974
|
|
|
45975
|
+
// dist/cli/plugins/pluginAliases.js
|
|
45976
|
+
var BUILTIN_PLUGIN_ALIASES = {
|
|
45977
|
+
gsheets: "@vforsh/argus-plugin-google-sheets",
|
|
45978
|
+
gs: "@vforsh/argus-plugin-google-sheets"
|
|
45979
|
+
};
|
|
45980
|
+
var resolvePluginAlias = (spec, aliases) => {
|
|
45981
|
+
const trimmed = spec.trim();
|
|
45982
|
+
const resolved = aliases[trimmed];
|
|
45983
|
+
return resolved ? { spec: resolved, alias: trimmed } : { spec: trimmed, alias: null };
|
|
45984
|
+
};
|
|
45985
|
+
|
|
45986
|
+
// dist/cli/plugins/pluginHost.js
|
|
45987
|
+
var DEFAULT_TIMEOUT_MS2 = 30000;
|
|
45988
|
+
var postWatcherJson = (id, path15, body, timeoutMs = DEFAULT_TIMEOUT_MS2) => requestWatcherJson({
|
|
45989
|
+
id,
|
|
45990
|
+
path: path15,
|
|
45991
|
+
method: "POST",
|
|
45992
|
+
body,
|
|
45993
|
+
timeoutMs
|
|
45994
|
+
});
|
|
45995
|
+
var argus = {
|
|
45996
|
+
eval: (id, request, options) => postWatcherJson(id, "/eval", request, options?.timeoutMs ?? request.timeoutMs ?? DEFAULT_TIMEOUT_MS2),
|
|
45997
|
+
dom: {
|
|
45998
|
+
click: (id, request, options) => postWatcherJson(id, "/dom/click", request, options?.timeoutMs),
|
|
45999
|
+
info: (id, request, options) => postWatcherJson(id, "/dom/info", request, options?.timeoutMs),
|
|
46000
|
+
keydown: (id, request, options) => postWatcherJson(id, "/dom/keydown", request, options?.timeoutMs)
|
|
46001
|
+
},
|
|
46002
|
+
screenshot: (id, request = {}, options) => postWatcherJson(id, "/screenshot", request, options?.timeoutMs)
|
|
46003
|
+
};
|
|
46004
|
+
var createPluginHost = () => ({
|
|
46005
|
+
createOutput,
|
|
46006
|
+
requestWatcherJson,
|
|
46007
|
+
writeRequestError,
|
|
46008
|
+
runChromeOpen,
|
|
46009
|
+
defineWatcherCommand,
|
|
46010
|
+
argus
|
|
46011
|
+
});
|
|
46012
|
+
|
|
45683
46013
|
// dist/cli/plugins/registerPlugins.js
|
|
46014
|
+
var lastPluginLoadReport = {
|
|
46015
|
+
configPath: null,
|
|
46016
|
+
configDir: null,
|
|
46017
|
+
cwd: process.cwd(),
|
|
46018
|
+
entries: []
|
|
46019
|
+
};
|
|
46020
|
+
var getPluginLoadReport = () => lastPluginLoadReport;
|
|
45684
46021
|
var parseEnvPlugins = () => {
|
|
45685
46022
|
const raw = process.env.ARGUS_PLUGINS;
|
|
45686
46023
|
if (!raw)
|
|
@@ -45688,6 +46025,30 @@ var parseEnvPlugins = () => {
|
|
|
45688
46025
|
return raw.split(",").map((s) => s.trim()).filter(Boolean);
|
|
45689
46026
|
};
|
|
45690
46027
|
var uniq = (values) => Array.from(new Set(values));
|
|
46028
|
+
var createPluginInput = (source, spec, aliases) => {
|
|
46029
|
+
const resolved = resolvePluginAlias(spec, aliases);
|
|
46030
|
+
return { source, spec, resolvedSpec: resolved.spec, alias: resolved.alias };
|
|
46031
|
+
};
|
|
46032
|
+
var parseCliPlugins = (argv) => {
|
|
46033
|
+
const plugins = [];
|
|
46034
|
+
for (let i = 0;i < argv.length; i++) {
|
|
46035
|
+
const arg = argv[i];
|
|
46036
|
+
if (arg === "--plugin") {
|
|
46037
|
+
const value = argv[i + 1];
|
|
46038
|
+
if (value && !value.startsWith("-")) {
|
|
46039
|
+
plugins.push(value);
|
|
46040
|
+
i++;
|
|
46041
|
+
}
|
|
46042
|
+
continue;
|
|
46043
|
+
}
|
|
46044
|
+
if (arg.startsWith("--plugin=")) {
|
|
46045
|
+
const value = arg.slice("--plugin=".length).trim();
|
|
46046
|
+
if (value)
|
|
46047
|
+
plugins.push(value);
|
|
46048
|
+
}
|
|
46049
|
+
}
|
|
46050
|
+
return plugins;
|
|
46051
|
+
};
|
|
45691
46052
|
var resolveWithImportMeta = (specifier, parentUrl) => {
|
|
45692
46053
|
const resolver2 = import.meta.resolve;
|
|
45693
46054
|
if (typeof resolver2 !== "function") {
|
|
@@ -45695,6 +46056,7 @@ var resolveWithImportMeta = (specifier, parentUrl) => {
|
|
|
45695
46056
|
}
|
|
45696
46057
|
return resolver2(specifier, parentUrl);
|
|
45697
46058
|
};
|
|
46059
|
+
var isPathLikeSpecifier = (specifier) => specifier.startsWith(".") || specifier.startsWith("/");
|
|
45698
46060
|
var resolvePluginModuleUrl = (specifier, baseDirs) => {
|
|
45699
46061
|
const trimmed = specifier.trim();
|
|
45700
46062
|
if (!trimmed) {
|
|
@@ -45704,6 +46066,23 @@ var resolvePluginModuleUrl = (specifier, baseDirs) => {
|
|
|
45704
46066
|
return { ok: true, url: trimmed };
|
|
45705
46067
|
}
|
|
45706
46068
|
const errors = [];
|
|
46069
|
+
if (isPathLikeSpecifier(trimmed)) {
|
|
46070
|
+
for (const baseDir of baseDirs) {
|
|
46071
|
+
try {
|
|
46072
|
+
const resolvedPath = path15.resolve(baseDir, trimmed);
|
|
46073
|
+
if (existsSync3(resolvedPath)) {
|
|
46074
|
+
return { ok: true, url: pathToFileURL2(resolvedPath).href };
|
|
46075
|
+
}
|
|
46076
|
+
errors.push(`${baseDir}: ${resolvedPath} does not exist`);
|
|
46077
|
+
} catch (error) {
|
|
46078
|
+
const msg = error instanceof Error ? error.message : String(error);
|
|
46079
|
+
errors.push(`${baseDir}: ${msg}`);
|
|
46080
|
+
}
|
|
46081
|
+
}
|
|
46082
|
+
return { ok: false, error: `Failed to resolve plugin path "${specifier}". Tried:
|
|
46083
|
+
${errors.map((e) => `- ${e}`).join(`
|
|
46084
|
+
`)}` };
|
|
46085
|
+
}
|
|
45707
46086
|
try {
|
|
45708
46087
|
return { ok: true, url: resolveWithImportMeta(trimmed, import.meta.url) };
|
|
45709
46088
|
} catch (error) {
|
|
@@ -45712,7 +46091,7 @@ var resolvePluginModuleUrl = (specifier, baseDirs) => {
|
|
|
45712
46091
|
}
|
|
45713
46092
|
for (const baseDir of baseDirs) {
|
|
45714
46093
|
try {
|
|
45715
|
-
const baseUrl = pathToFileURL2(
|
|
46094
|
+
const baseUrl = pathToFileURL2(path15.join(baseDir, "noop.js")).href;
|
|
45716
46095
|
return { ok: true, url: resolveWithImportMeta(trimmed, baseUrl) };
|
|
45717
46096
|
} catch (error) {
|
|
45718
46097
|
const msg = error instanceof Error ? error.message : String(error);
|
|
@@ -45739,26 +46118,62 @@ var extractPlugin = (mod) => {
|
|
|
45739
46118
|
return null;
|
|
45740
46119
|
return plugin;
|
|
45741
46120
|
};
|
|
46121
|
+
var normalizeOptionalString = (value) => typeof value === "string" && value.trim() ? value.trim() : null;
|
|
46122
|
+
var normalizeCommands = (value) => {
|
|
46123
|
+
if (!Array.isArray(value))
|
|
46124
|
+
return [];
|
|
46125
|
+
const commands = value.filter((item) => typeof item === "string").map((item) => item.trim()).filter(Boolean);
|
|
46126
|
+
return Array.from(new Set(commands));
|
|
46127
|
+
};
|
|
45742
46128
|
var warnPluginLoad = (source, spec, message) => {
|
|
45743
46129
|
const output = createOutput({ json: false });
|
|
45744
46130
|
output.writeWarn(`[plugins] Failed to load (${source}) "${spec}": ${message}`);
|
|
45745
46131
|
};
|
|
45746
|
-
var
|
|
46132
|
+
var recordPluginFailure = (entries, entry, error, url) => {
|
|
46133
|
+
entries.push({ source: entry.source, spec: entry.spec, resolvedSpec: entry.resolvedSpec, alias: entry.alias, status: "failed", url, error });
|
|
46134
|
+
warnPluginLoad(entry.source, entry.spec, error);
|
|
46135
|
+
};
|
|
46136
|
+
var createLoadedEntry = (entry, plugin, url) => ({
|
|
46137
|
+
source: entry.source,
|
|
46138
|
+
spec: entry.spec,
|
|
46139
|
+
resolvedSpec: entry.resolvedSpec,
|
|
46140
|
+
alias: entry.alias,
|
|
46141
|
+
status: "loaded",
|
|
46142
|
+
name: plugin.name,
|
|
46143
|
+
version: normalizeOptionalString(plugin.version),
|
|
46144
|
+
description: normalizeOptionalString(plugin.description),
|
|
46145
|
+
commands: normalizeCommands(plugin.commands),
|
|
46146
|
+
homepage: normalizeOptionalString(plugin.homepage),
|
|
46147
|
+
minArgusVersion: normalizeOptionalString(plugin.minArgusVersion),
|
|
46148
|
+
url
|
|
46149
|
+
});
|
|
46150
|
+
var registerPlugins = async (program2, argv = process.argv.slice(2)) => {
|
|
45747
46151
|
const cwd = process.cwd();
|
|
45748
46152
|
const configPath = resolveArgusConfigPath({ cwd });
|
|
45749
46153
|
const configResult = configPath ? loadArgusConfig(configPath) : null;
|
|
46154
|
+
const aliases = { ...BUILTIN_PLUGIN_ALIASES, ...configResult?.config.pluginAliases ?? {} };
|
|
45750
46155
|
const configPlugins = configResult?.config.plugins ?? [];
|
|
45751
46156
|
const envPlugins = parseEnvPlugins();
|
|
46157
|
+
const cliPlugins = parseCliPlugins(argv);
|
|
45752
46158
|
const all = [];
|
|
45753
46159
|
for (const spec of configPlugins)
|
|
45754
|
-
all.push(
|
|
46160
|
+
all.push(createPluginInput("config", spec, aliases));
|
|
45755
46161
|
for (const spec of envPlugins)
|
|
45756
|
-
all.push(
|
|
46162
|
+
all.push(createPluginInput("env", spec, aliases));
|
|
46163
|
+
for (const spec of cliPlugins)
|
|
46164
|
+
all.push(createPluginInput("cli", spec, aliases));
|
|
46165
|
+
const entries = [];
|
|
46166
|
+
lastPluginLoadReport = {
|
|
46167
|
+
configPath,
|
|
46168
|
+
configDir: configResult?.configDir ?? null,
|
|
46169
|
+
cwd,
|
|
46170
|
+
entries
|
|
46171
|
+
};
|
|
45757
46172
|
if (all.length === 0)
|
|
45758
46173
|
return;
|
|
45759
46174
|
const seen = new Set;
|
|
45760
46175
|
const ordered = all.filter((p2) => {
|
|
45761
|
-
const key = p2.
|
|
46176
|
+
const key = p2.resolvedSpec.trim();
|
|
45762
46177
|
if (!key)
|
|
45763
46178
|
return false;
|
|
45764
46179
|
if (seen.has(key))
|
|
@@ -45769,37 +46184,312 @@ var registerPlugins = async (program2) => {
|
|
|
45769
46184
|
const baseDirs = uniq([configResult?.configDir, cwd].filter((v4) => Boolean(v4)));
|
|
45770
46185
|
const ctxBase = {
|
|
45771
46186
|
apiVersion: ARGUS_PLUGIN_API_VERSION,
|
|
45772
|
-
host:
|
|
46187
|
+
host: createPluginHost(),
|
|
45773
46188
|
cwd,
|
|
45774
46189
|
configPath,
|
|
45775
46190
|
configDir: configResult?.configDir ?? null
|
|
45776
46191
|
};
|
|
45777
46192
|
for (const entry of ordered) {
|
|
45778
|
-
const resolved = resolvePluginModuleUrl(entry.
|
|
46193
|
+
const resolved = resolvePluginModuleUrl(entry.resolvedSpec, baseDirs);
|
|
45779
46194
|
if (!resolved.ok) {
|
|
45780
|
-
|
|
46195
|
+
recordPluginFailure(entries, entry, resolved.error);
|
|
45781
46196
|
continue;
|
|
45782
46197
|
}
|
|
45783
46198
|
let mod;
|
|
45784
46199
|
try {
|
|
45785
46200
|
mod = await import(resolved.url);
|
|
45786
46201
|
} catch (error) {
|
|
45787
|
-
|
|
46202
|
+
recordPluginFailure(entries, entry, error instanceof Error ? error.message : String(error), resolved.url);
|
|
45788
46203
|
continue;
|
|
45789
46204
|
}
|
|
45790
46205
|
const plugin = extractPlugin(mod);
|
|
45791
46206
|
if (!plugin) {
|
|
45792
|
-
|
|
46207
|
+
recordPluginFailure(entries, entry, "Invalid plugin export (expected default export with { apiVersion: 1, name, register() }).", resolved.url);
|
|
45793
46208
|
continue;
|
|
45794
46209
|
}
|
|
45795
46210
|
try {
|
|
45796
46211
|
await plugin.register({ ...ctxBase, program: program2 });
|
|
46212
|
+
entries.push(createLoadedEntry(entry, plugin, resolved.url));
|
|
45797
46213
|
} catch (error) {
|
|
45798
|
-
|
|
46214
|
+
recordPluginFailure(entries, entry, error instanceof Error ? error.message : String(error), resolved.url);
|
|
45799
46215
|
}
|
|
45800
46216
|
}
|
|
45801
46217
|
};
|
|
45802
46218
|
|
|
46219
|
+
// dist/commands/pluginList.js
|
|
46220
|
+
var runPluginList = (options) => {
|
|
46221
|
+
const output = createOutput(options);
|
|
46222
|
+
const report = getPluginLoadReport();
|
|
46223
|
+
if (options.json) {
|
|
46224
|
+
output.writeJson(report);
|
|
46225
|
+
return;
|
|
46226
|
+
}
|
|
46227
|
+
if (report.entries.length === 0) {
|
|
46228
|
+
output.writeHuman("No plugins configured for this invocation.");
|
|
46229
|
+
return;
|
|
46230
|
+
}
|
|
46231
|
+
for (const entry of report.entries) {
|
|
46232
|
+
const spec = entry.alias ? `${entry.alias} -> ${entry.resolvedSpec}` : entry.spec;
|
|
46233
|
+
if (entry.status === "failed") {
|
|
46234
|
+
output.writeHuman(`${entry.source} ${spec} failed ${entry.error}`);
|
|
46235
|
+
continue;
|
|
46236
|
+
}
|
|
46237
|
+
const version2 = entry.version ? ` v${entry.version}` : "";
|
|
46238
|
+
const commands = entry.commands.length > 0 ? ` commands: ${entry.commands.join(", ")}` : "";
|
|
46239
|
+
const description = entry.description ? ` — ${entry.description}` : "";
|
|
46240
|
+
output.writeHuman(`${entry.source} ${entry.name}${version2} ${spec} loaded${commands}${description}`);
|
|
46241
|
+
}
|
|
46242
|
+
};
|
|
46243
|
+
|
|
46244
|
+
// dist/commands/pluginConfig.js
|
|
46245
|
+
import fs16 from "node:fs/promises";
|
|
46246
|
+
import { existsSync as existsSync4 } from "node:fs";
|
|
46247
|
+
import path16 from "node:path";
|
|
46248
|
+
var DEFAULT_CONFIG_PATH2 = ".argus/config.json";
|
|
46249
|
+
var isRecord2 = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
|
|
46250
|
+
var resolveTargetConfigPath = (cwd, cliPath) => {
|
|
46251
|
+
if (cliPath) {
|
|
46252
|
+
const resolved = path16.isAbsolute(cliPath) ? cliPath : path16.resolve(cwd, cliPath);
|
|
46253
|
+
return { path: resolved, exists: existsSync4(resolved) };
|
|
46254
|
+
}
|
|
46255
|
+
const discovered = resolveArgusConfigPath({ cwd });
|
|
46256
|
+
if (discovered)
|
|
46257
|
+
return { path: discovered, exists: true };
|
|
46258
|
+
if (process.exitCode)
|
|
46259
|
+
return null;
|
|
46260
|
+
return { path: path16.resolve(cwd, DEFAULT_CONFIG_PATH2), exists: false };
|
|
46261
|
+
};
|
|
46262
|
+
var readConfigObject = async (configPath, exists) => {
|
|
46263
|
+
if (!exists)
|
|
46264
|
+
return {};
|
|
46265
|
+
let raw;
|
|
46266
|
+
try {
|
|
46267
|
+
raw = await fs16.readFile(configPath, "utf8");
|
|
46268
|
+
} catch (error) {
|
|
46269
|
+
console.error(`Failed to read Argus config at ${configPath}: ${error instanceof Error ? error.message : String(error)}`);
|
|
46270
|
+
process.exitCode = 2;
|
|
46271
|
+
return null;
|
|
46272
|
+
}
|
|
46273
|
+
try {
|
|
46274
|
+
const parsed = JSON.parse(raw);
|
|
46275
|
+
if (isRecord2(parsed))
|
|
46276
|
+
return parsed;
|
|
46277
|
+
console.error(`Invalid Argus config at ${configPath}: config root must be an object.`);
|
|
46278
|
+
process.exitCode = 2;
|
|
46279
|
+
return null;
|
|
46280
|
+
} catch (error) {
|
|
46281
|
+
console.error(`Invalid Argus config at ${configPath}: ${error instanceof Error ? error.message : String(error)}`);
|
|
46282
|
+
process.exitCode = 2;
|
|
46283
|
+
return null;
|
|
46284
|
+
}
|
|
46285
|
+
};
|
|
46286
|
+
var getPluginSpecs = (config, configPath) => {
|
|
46287
|
+
const value = config.plugins;
|
|
46288
|
+
if (value === undefined)
|
|
46289
|
+
return [];
|
|
46290
|
+
if (!Array.isArray(value) || value.some((item) => typeof item !== "string" || item.trim() === "")) {
|
|
46291
|
+
console.error(`Invalid Argus config at ${configPath}: "plugins" must be an array of non-empty strings.`);
|
|
46292
|
+
process.exitCode = 2;
|
|
46293
|
+
return null;
|
|
46294
|
+
}
|
|
46295
|
+
return value;
|
|
46296
|
+
};
|
|
46297
|
+
var getPluginAliases = (config, configPath) => {
|
|
46298
|
+
const value = config.pluginAliases;
|
|
46299
|
+
if (value === undefined)
|
|
46300
|
+
return {};
|
|
46301
|
+
if (!isRecord2(value)) {
|
|
46302
|
+
console.error(`Invalid Argus config at ${configPath}: "pluginAliases" must be an object with string values.`);
|
|
46303
|
+
process.exitCode = 2;
|
|
46304
|
+
return null;
|
|
46305
|
+
}
|
|
46306
|
+
const aliases = {};
|
|
46307
|
+
for (const [alias, spec] of Object.entries(value)) {
|
|
46308
|
+
if (alias.trim() === "" || typeof spec !== "string" || spec.trim() === "") {
|
|
46309
|
+
console.error(`Invalid Argus config at ${configPath}: "pluginAliases" keys and values must be non-empty strings.`);
|
|
46310
|
+
process.exitCode = 2;
|
|
46311
|
+
return null;
|
|
46312
|
+
}
|
|
46313
|
+
aliases[alias] = spec;
|
|
46314
|
+
}
|
|
46315
|
+
return aliases;
|
|
46316
|
+
};
|
|
46317
|
+
var writeConfigObject = async (configPath, config) => {
|
|
46318
|
+
try {
|
|
46319
|
+
await fs16.mkdir(path16.dirname(configPath), { recursive: true });
|
|
46320
|
+
await fs16.writeFile(configPath, `${JSON.stringify(config, null, "\t")}
|
|
46321
|
+
`, "utf8");
|
|
46322
|
+
return true;
|
|
46323
|
+
} catch (error) {
|
|
46324
|
+
console.error(`Failed to write Argus config at ${configPath}: ${error instanceof Error ? error.message : String(error)}`);
|
|
46325
|
+
process.exitCode = 2;
|
|
46326
|
+
return false;
|
|
46327
|
+
}
|
|
46328
|
+
};
|
|
46329
|
+
var loadMutablePluginConfig = async (options) => {
|
|
46330
|
+
const target = resolveTargetConfigPath(process.cwd(), options.path);
|
|
46331
|
+
if (!target)
|
|
46332
|
+
return null;
|
|
46333
|
+
const config = await readConfigObject(target.path, target.exists);
|
|
46334
|
+
if (!config)
|
|
46335
|
+
return null;
|
|
46336
|
+
const plugins = getPluginSpecs(config, target.path);
|
|
46337
|
+
if (!plugins)
|
|
46338
|
+
return null;
|
|
46339
|
+
const pluginAliases = getPluginAliases(config, target.path);
|
|
46340
|
+
if (!pluginAliases)
|
|
46341
|
+
return null;
|
|
46342
|
+
return { path: target.path, config, plugins, pluginAliases };
|
|
46343
|
+
};
|
|
46344
|
+
var parsePluginAddTarget = (raw, aliases) => {
|
|
46345
|
+
const trimmed = raw.trim();
|
|
46346
|
+
if (!trimmed)
|
|
46347
|
+
return null;
|
|
46348
|
+
const separator = trimmed.indexOf("=");
|
|
46349
|
+
if (separator < 0) {
|
|
46350
|
+
const resolved = resolvePluginAlias(trimmed, aliases);
|
|
46351
|
+
return { spec: trimmed, alias: resolved.alias, resolvedSpec: resolved.spec };
|
|
46352
|
+
}
|
|
46353
|
+
const alias = trimmed.slice(0, separator).trim();
|
|
46354
|
+
const spec = trimmed.slice(separator + 1).trim();
|
|
46355
|
+
return alias && spec ? { spec: alias, alias, resolvedSpec: spec } : null;
|
|
46356
|
+
};
|
|
46357
|
+
var runPluginAdd = async (targetSpec, options) => {
|
|
46358
|
+
const output = createOutput(options);
|
|
46359
|
+
const loaded = await loadMutablePluginConfig(options);
|
|
46360
|
+
if (!loaded)
|
|
46361
|
+
return;
|
|
46362
|
+
const parsed = parsePluginAddTarget(targetSpec, { ...BUILTIN_PLUGIN_ALIASES, ...loaded.pluginAliases });
|
|
46363
|
+
if (!parsed) {
|
|
46364
|
+
output.writeWarn("Plugin specifier is required.");
|
|
46365
|
+
process.exitCode = 2;
|
|
46366
|
+
return;
|
|
46367
|
+
}
|
|
46368
|
+
const aliases = { ...BUILTIN_PLUGIN_ALIASES, ...loaded.pluginAliases };
|
|
46369
|
+
const hasSameResolvedPlugin = loaded.plugins.some((spec) => resolvePluginAlias(spec, aliases).spec === parsed.resolvedSpec);
|
|
46370
|
+
const changed = !loaded.plugins.includes(parsed.spec) && !hasSameResolvedPlugin;
|
|
46371
|
+
const aliasChanged = parsed.alias !== null && loaded.pluginAliases[parsed.alias] !== parsed.resolvedSpec;
|
|
46372
|
+
if (changed) {
|
|
46373
|
+
loaded.plugins = [...loaded.plugins, parsed.spec];
|
|
46374
|
+
loaded.config.plugins = loaded.plugins;
|
|
46375
|
+
}
|
|
46376
|
+
if (aliasChanged && parsed.alias) {
|
|
46377
|
+
loaded.pluginAliases[parsed.alias] = parsed.resolvedSpec;
|
|
46378
|
+
loaded.config.pluginAliases = loaded.pluginAliases;
|
|
46379
|
+
}
|
|
46380
|
+
if ((changed || aliasChanged) && !await writeConfigObject(loaded.path, loaded.config))
|
|
46381
|
+
return;
|
|
46382
|
+
const response = {
|
|
46383
|
+
configPath: loaded.path,
|
|
46384
|
+
spec: parsed.spec,
|
|
46385
|
+
alias: parsed.alias,
|
|
46386
|
+
resolvedSpec: parsed.resolvedSpec,
|
|
46387
|
+
changed: changed || aliasChanged,
|
|
46388
|
+
plugins: loaded.plugins,
|
|
46389
|
+
pluginAliases: loaded.pluginAliases
|
|
46390
|
+
};
|
|
46391
|
+
if (options.json)
|
|
46392
|
+
output.writeJson(response);
|
|
46393
|
+
else
|
|
46394
|
+
output.writeHuman(response.changed ? `Added plugin ${parsed.spec} to ${loaded.path}` : `Plugin already configured: ${parsed.spec}`);
|
|
46395
|
+
};
|
|
46396
|
+
var runPluginRemove = async (targetSpec, options) => {
|
|
46397
|
+
const output = createOutput(options);
|
|
46398
|
+
const normalized = targetSpec.trim();
|
|
46399
|
+
if (!normalized) {
|
|
46400
|
+
output.writeWarn("Plugin specifier or name is required.");
|
|
46401
|
+
process.exitCode = 2;
|
|
46402
|
+
return;
|
|
46403
|
+
}
|
|
46404
|
+
const loaded = await loadMutablePluginConfig(options);
|
|
46405
|
+
if (!loaded)
|
|
46406
|
+
return;
|
|
46407
|
+
const aliases = { ...BUILTIN_PLUGIN_ALIASES, ...loaded.pluginAliases };
|
|
46408
|
+
const next = loaded.plugins.filter((spec) => !matchesPluginSpecifier(spec, normalized, aliases));
|
|
46409
|
+
const nextAliases = Object.fromEntries(Object.entries(loaded.pluginAliases).filter(([alias, spec]) => !matchesPluginAlias(alias, spec, normalized)));
|
|
46410
|
+
const changed = next.length !== loaded.plugins.length;
|
|
46411
|
+
const aliasChanged = Object.keys(nextAliases).length !== Object.keys(loaded.pluginAliases).length;
|
|
46412
|
+
if (changed || aliasChanged) {
|
|
46413
|
+
loaded.config.plugins = next;
|
|
46414
|
+
loaded.config.pluginAliases = Object.keys(nextAliases).length > 0 ? nextAliases : undefined;
|
|
46415
|
+
if (!await writeConfigObject(loaded.path, loaded.config))
|
|
46416
|
+
return;
|
|
46417
|
+
}
|
|
46418
|
+
const response = { configPath: loaded.path, target: normalized, changed: changed || aliasChanged, plugins: next, pluginAliases: nextAliases };
|
|
46419
|
+
if (options.json)
|
|
46420
|
+
output.writeJson(response);
|
|
46421
|
+
else
|
|
46422
|
+
output.writeHuman(response.changed ? `Removed plugin ${normalized} from ${loaded.path}` : `Plugin not configured: ${normalized}`);
|
|
46423
|
+
};
|
|
46424
|
+
var matchesPluginSpecifier = (spec, target, aliases) => {
|
|
46425
|
+
const resolved = resolvePluginAlias(spec, aliases);
|
|
46426
|
+
return spec === target || resolved.spec === target || resolved.alias === target || pluginKey(spec) === pluginKey(target) || pluginKey(resolved.spec) === pluginKey(target);
|
|
46427
|
+
};
|
|
46428
|
+
var matchesPluginAlias = (alias, spec, target) => alias === target || spec === target || pluginKey(alias) === pluginKey(target) || pluginKey(spec) === pluginKey(target);
|
|
46429
|
+
var pluginKey = (value) => {
|
|
46430
|
+
const withoutPath = value.replace(/\\/g, "/").split("/").filter(Boolean).pop() ?? value;
|
|
46431
|
+
const withoutExt = withoutPath.replace(/\.(mjs|js|ts)$/, "");
|
|
46432
|
+
return withoutExt.replace(/^argus-plugin-/, "").replace(/^@[^/]+\/argus-plugin-/, "");
|
|
46433
|
+
};
|
|
46434
|
+
|
|
46435
|
+
// dist/cli/register/registerPlugin.js
|
|
46436
|
+
function registerPlugin(program2) {
|
|
46437
|
+
const plugin = program2.command("plugin").alias("plugins").description("Manage Argus CLI plugins");
|
|
46438
|
+
plugin.command("list").alias("ls").description("List plugins discovered for this invocation").option("--json", "Output JSON for automation").addHelpText("after", `
|
|
46439
|
+
Examples:
|
|
46440
|
+
$ argus plugin list
|
|
46441
|
+
$ argus --plugin ./plugins/foo.js plugin list --json
|
|
46442
|
+
`).action((options) => {
|
|
46443
|
+
runPluginList(options);
|
|
46444
|
+
});
|
|
46445
|
+
plugin.command("add <specifier>").description("Add a plugin specifier or alias to the Argus config").option("--path <file>", "Config file to update (default: discovered config or .argus/config.json)").option("--json", "Output JSON for automation").addHelpText("after", `
|
|
46446
|
+
Examples:
|
|
46447
|
+
$ argus plugin add gsheets
|
|
46448
|
+
$ argus plugin add gs=@vforsh/argus-plugin-google-sheets
|
|
46449
|
+
$ argus plugin add ./plugins/foo.js
|
|
46450
|
+
`).action(async (specifier, options) => {
|
|
46451
|
+
await runPluginAdd(specifier, options);
|
|
46452
|
+
});
|
|
46453
|
+
plugin.command("remove <specifierOrName>").alias("rm").description("Remove a plugin from the Argus config").option("--path <file>", "Config file to update (default: discovered config or .argus/config.json)").option("--json", "Output JSON for automation").addHelpText("after", `
|
|
46454
|
+
Examples:
|
|
46455
|
+
$ argus plugin remove @vforsh/argus-plugin-google-sheets
|
|
46456
|
+
$ argus plugin remove google-sheets
|
|
46457
|
+
`).action(async (specifierOrName, options) => {
|
|
46458
|
+
await runPluginRemove(specifierOrName, options);
|
|
46459
|
+
});
|
|
46460
|
+
}
|
|
46461
|
+
|
|
46462
|
+
// dist/cli/register/index.js
|
|
46463
|
+
var registerDefinedCommands = (program2) => {
|
|
46464
|
+
defineCommands(program2, [domClickCommandDefinition]);
|
|
46465
|
+
};
|
|
46466
|
+
var coreProgramRegistrars = [
|
|
46467
|
+
registerQuickAccess,
|
|
46468
|
+
registerChrome,
|
|
46469
|
+
registerWatcher,
|
|
46470
|
+
registerPage,
|
|
46471
|
+
registerDialog,
|
|
46472
|
+
registerLogs,
|
|
46473
|
+
registerNet,
|
|
46474
|
+
registerAuth,
|
|
46475
|
+
registerEval,
|
|
46476
|
+
registerLocate,
|
|
46477
|
+
registerCode,
|
|
46478
|
+
registerDom,
|
|
46479
|
+
registerDefinedCommands,
|
|
46480
|
+
registerKeydown,
|
|
46481
|
+
registerFill,
|
|
46482
|
+
registerHover,
|
|
46483
|
+
registerScrollTo,
|
|
46484
|
+
registerStorage,
|
|
46485
|
+
registerThrottle,
|
|
46486
|
+
registerSnapshot,
|
|
46487
|
+
registerTrace,
|
|
46488
|
+
registerConfig,
|
|
46489
|
+
registerPlugin,
|
|
46490
|
+
registerExtension
|
|
46491
|
+
];
|
|
46492
|
+
|
|
45803
46493
|
// dist/bin.js
|
|
45804
46494
|
var program2 = createProgram();
|
|
45805
46495
|
for (const registerProgramPart of coreProgramRegistrars) {
|