@vforsh/argus 0.1.19 → 0.1.21
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 +642 -191
- package/dist/cli/register/extensionCommands.d.ts.map +1 -1
- package/dist/cli/register/extensionCommands.js +28 -3
- package/dist/cli/register/extensionCommands.js.map +1 -1
- package/dist/cli/register/keydownCommand.d.ts.map +1 -1
- package/dist/cli/register/keydownCommand.js +15 -2
- package/dist/cli/register/keydownCommand.js.map +1 -1
- package/dist/cli/register/netCommands.d.ts +5 -0
- package/dist/cli/register/netCommands.d.ts.map +1 -1
- package/dist/cli/register/netCommands.js +23 -6
- package/dist/cli/register/netCommands.js.map +1 -1
- package/dist/commands/domKeydown.d.ts +8 -1
- package/dist/commands/domKeydown.d.ts.map +1 -1
- package/dist/commands/domKeydown.js +35 -6
- package/dist/commands/domKeydown.js.map +1 -1
- package/dist/commands/extension/extensionId.d.ts +27 -0
- package/dist/commands/extension/extensionId.d.ts.map +1 -0
- package/dist/commands/extension/extensionId.js +37 -0
- package/dist/commands/extension/extensionId.js.map +1 -0
- package/dist/commands/extension/extensionPath.d.ts +15 -0
- package/dist/commands/extension/extensionPath.d.ts.map +1 -0
- package/dist/commands/extension/extensionPath.js +61 -0
- package/dist/commands/extension/extensionPath.js.map +1 -0
- package/dist/commands/extension/install.d.ts +16 -0
- package/dist/commands/extension/install.d.ts.map +1 -0
- package/dist/commands/extension/install.js +154 -0
- package/dist/commands/extension/install.js.map +1 -0
- package/dist/commands/extension/setup.d.ts +2 -1
- package/dist/commands/extension/setup.d.ts.map +1 -1
- package/dist/commands/extension/setup.js +5 -2
- package/dist/commands/extension/setup.js.map +1 -1
- package/dist/commands/netMock.d.ts +2 -0
- package/dist/commands/netMock.d.ts.map +1 -1
- package/dist/commands/netMock.js +22 -1
- package/dist/commands/netMock.js.map +1 -1
- package/dist/extension/dist/background/auth-header-monitor.js +77 -0
- package/dist/extension/dist/background/bridge-client.js +120 -0
- package/dist/extension/dist/background/cdp-proxy.js +201 -0
- package/dist/extension/dist/background/debugger-manager.js +296 -0
- package/dist/extension/dist/background/service-worker.js +2004 -0
- package/dist/extension/dist/background/service-worker.js.map +7 -0
- package/dist/extension/dist/popup/popup.js +730 -0
- package/dist/extension/dist/popup/popup.js.map +7 -0
- package/dist/extension/dist/popup/tabMarkup.js +104 -0
- package/dist/extension/dist/popup/viewState.js +60 -0
- package/dist/extension/dist/types/messages.js +5 -0
- package/dist/extension/icons/icon-128.png +0 -0
- package/dist/extension/icons/icon-16.png +0 -0
- package/dist/extension/icons/icon-48.png +0 -0
- package/dist/extension/manifest.json +26 -0
- package/dist/extension/src/popup/popup.html +756 -0
- package/dist/skill/argus/SKILL.md +6 -1
- package/dist/skill/argus/reference/EXTENSION.md +13 -8
- package/dist/skill/argus/reference/INSPECT.md +3 -1
- package/dist/skill/argus/reference/NET.md +4 -1
- package/package.json +2 -2
package/dist/argus.js
CHANGED
|
@@ -2144,7 +2144,7 @@ var {
|
|
|
2144
2144
|
// package.json
|
|
2145
2145
|
var package_default = {
|
|
2146
2146
|
name: "@vforsh/argus",
|
|
2147
|
-
version: "0.1.
|
|
2147
|
+
version: "0.1.21",
|
|
2148
2148
|
repository: {
|
|
2149
2149
|
type: "git",
|
|
2150
2150
|
url: "git+https://github.com/vforsh/argus.git",
|
|
@@ -2180,7 +2180,7 @@ var package_default = {
|
|
|
2180
2180
|
scripts: {
|
|
2181
2181
|
clean: "node ../../scripts/clean-dist.mjs",
|
|
2182
2182
|
build: "npm run clean && tsc -b && bun run bundle",
|
|
2183
|
-
bundle: "bun build dist/bin.js --outfile dist/argus.js --target node --external esbuild && node ../../scripts/copy-argus-skill.mjs",
|
|
2183
|
+
bundle: "bun build dist/bin.js --outfile dist/argus.js --target node --external esbuild && node ../../scripts/copy-argus-skill.mjs && node ../../scripts/copy-argus-extension.mjs",
|
|
2184
2184
|
typecheck: "tsc -b --pretty false",
|
|
2185
2185
|
"chrome:start": "bun src/bin.ts chrome start"
|
|
2186
2186
|
}
|
|
@@ -6852,6 +6852,9 @@ function validateAddRequest(body) {
|
|
|
6852
6852
|
if (payload.times !== undefined && (!Number.isInteger(payload.times) || payload.times < 1)) {
|
|
6853
6853
|
return "times must be an integer >= 1";
|
|
6854
6854
|
}
|
|
6855
|
+
if (payload.scope !== undefined && payload.scope !== "page" && payload.scope !== "selected") {
|
|
6856
|
+
return "scope must be one of: page, selected";
|
|
6857
|
+
}
|
|
6855
6858
|
return null;
|
|
6856
6859
|
}
|
|
6857
6860
|
var validateMatch = (match) => {
|
|
@@ -9372,10 +9375,12 @@ var route29 = defineJsonRoute({
|
|
|
9372
9375
|
});
|
|
9373
9376
|
|
|
9374
9377
|
// ../argus-watcher/dist/cdp/keyboard.js
|
|
9375
|
-
var
|
|
9376
|
-
const
|
|
9378
|
+
var buildKeyMaps = () => {
|
|
9379
|
+
const byKey = new Map;
|
|
9380
|
+
const byCode = new Map;
|
|
9377
9381
|
const put = (lookup, def) => {
|
|
9378
|
-
|
|
9382
|
+
byKey.set(lookup.toLowerCase(), def);
|
|
9383
|
+
byCode.set(def.code.toLowerCase(), def);
|
|
9379
9384
|
};
|
|
9380
9385
|
for (let i = 0;i < 26; i++) {
|
|
9381
9386
|
const lower = String.fromCharCode(97 + i);
|
|
@@ -9410,11 +9415,14 @@ var buildKeyMap = () => {
|
|
|
9410
9415
|
const name = `F${i}`;
|
|
9411
9416
|
put(name, { key: name, code: name, keyCode: 111 + i });
|
|
9412
9417
|
}
|
|
9413
|
-
return
|
|
9418
|
+
return { byKey, byCode };
|
|
9414
9419
|
};
|
|
9415
|
-
var
|
|
9420
|
+
var KEY_MAPS = buildKeyMaps();
|
|
9416
9421
|
var resolveKeyDefinition = (key) => {
|
|
9417
|
-
return
|
|
9422
|
+
return KEY_MAPS.byKey.get(key.toLowerCase());
|
|
9423
|
+
};
|
|
9424
|
+
var resolveCodeDefinition = (code) => {
|
|
9425
|
+
return KEY_MAPS.byCode.get(code.toLowerCase());
|
|
9418
9426
|
};
|
|
9419
9427
|
var MODIFIER_BITS = {
|
|
9420
9428
|
alt: 1,
|
|
@@ -9444,8 +9452,61 @@ var parseModifiers = (input) => {
|
|
|
9444
9452
|
}
|
|
9445
9453
|
return mask;
|
|
9446
9454
|
};
|
|
9455
|
+
var resolveKeyboardEvent = (options) => {
|
|
9456
|
+
const modifiers = options.modifiers ?? 0;
|
|
9457
|
+
const keyInput = normalizeOptionalString(options.key);
|
|
9458
|
+
const codeInput = normalizeOptionalString(options.code);
|
|
9459
|
+
if (!keyInput && !codeInput) {
|
|
9460
|
+
throw new Error("key or code is required");
|
|
9461
|
+
}
|
|
9462
|
+
const keyDef = keyInput ? resolveKeyDefinition(keyInput) : undefined;
|
|
9463
|
+
const codeDef = codeInput ? resolveCodeDefinition(codeInput) : undefined;
|
|
9464
|
+
const baseDef = codeDef ?? keyDef;
|
|
9465
|
+
if (!baseDef) {
|
|
9466
|
+
if (codeInput && !keyInput) {
|
|
9467
|
+
throw new Error(`Unknown code: "${codeInput}"`);
|
|
9468
|
+
}
|
|
9469
|
+
throw new Error(`Unknown key: "${keyInput}"`);
|
|
9470
|
+
}
|
|
9471
|
+
const key = resolveEventKey(keyInput, baseDef, modifiers);
|
|
9472
|
+
const text = resolveEventText(key, baseDef);
|
|
9473
|
+
const event = {
|
|
9474
|
+
key,
|
|
9475
|
+
code: codeInput ?? baseDef.code,
|
|
9476
|
+
keyCode: baseDef.keyCode,
|
|
9477
|
+
modifiers,
|
|
9478
|
+
altKey: (modifiers & MODIFIER_BITS.alt) !== 0,
|
|
9479
|
+
ctrlKey: (modifiers & MODIFIER_BITS.ctrl) !== 0,
|
|
9480
|
+
metaKey: (modifiers & MODIFIER_BITS.meta) !== 0,
|
|
9481
|
+
shiftKey: (modifiers & MODIFIER_BITS.shift) !== 0
|
|
9482
|
+
};
|
|
9483
|
+
if (text !== undefined) {
|
|
9484
|
+
event.text = text;
|
|
9485
|
+
}
|
|
9486
|
+
return event;
|
|
9487
|
+
};
|
|
9488
|
+
var normalizeOptionalString = (value) => {
|
|
9489
|
+
const normalized = value?.trim();
|
|
9490
|
+
return normalized ? normalized : undefined;
|
|
9491
|
+
};
|
|
9492
|
+
var resolveEventKey = (keyInput, def, modifiers) => {
|
|
9493
|
+
const semanticKey = keyInput ?? def.key;
|
|
9494
|
+
if (isSingleLetter(semanticKey)) {
|
|
9495
|
+
return isShift(modifiers) ? semanticKey.toUpperCase() : semanticKey.toLowerCase();
|
|
9496
|
+
}
|
|
9497
|
+
return semanticKey;
|
|
9498
|
+
};
|
|
9499
|
+
var resolveEventText = (key, def) => {
|
|
9500
|
+
if (key.length === 1) {
|
|
9501
|
+
return key;
|
|
9502
|
+
}
|
|
9503
|
+
return def.text;
|
|
9504
|
+
};
|
|
9505
|
+
var isSingleLetter = (value) => /^[a-z]$/i.test(value);
|
|
9506
|
+
var isShift = (modifiers) => (modifiers & MODIFIER_BITS.shift) !== 0;
|
|
9447
9507
|
var dispatchKeydown = async (session, options) => {
|
|
9448
|
-
const {
|
|
9508
|
+
const { selector } = options;
|
|
9509
|
+
const event = resolveKeyboardEvent(options);
|
|
9449
9510
|
let focused = false;
|
|
9450
9511
|
if (selector) {
|
|
9451
9512
|
const { allNodeIds, nodeIds } = await resolveDomSelectorMatches(session, selector, false);
|
|
@@ -9461,31 +9522,23 @@ var dispatchKeydown = async (session, options) => {
|
|
|
9461
9522
|
await session.sendAndWait("DOM.focus", { nodeId });
|
|
9462
9523
|
focused = true;
|
|
9463
9524
|
}
|
|
9464
|
-
const
|
|
9465
|
-
if (!def) {
|
|
9466
|
-
throw new Error(`Unknown key: "${key}"`);
|
|
9467
|
-
}
|
|
9468
|
-
let text = def.text;
|
|
9469
|
-
if (text && text.length === 1 && (modifiers & 8) !== 0) {
|
|
9470
|
-
text = text.toUpperCase();
|
|
9471
|
-
}
|
|
9472
|
-
const isPrintable = text != null && text !== "\r";
|
|
9525
|
+
const isPrintable = event.text != null && event.text !== "\r";
|
|
9473
9526
|
const baseParams = {
|
|
9474
|
-
code:
|
|
9475
|
-
key:
|
|
9476
|
-
windowsVirtualKeyCode:
|
|
9477
|
-
nativeVirtualKeyCode:
|
|
9478
|
-
modifiers
|
|
9527
|
+
code: event.code,
|
|
9528
|
+
key: event.key,
|
|
9529
|
+
windowsVirtualKeyCode: event.keyCode,
|
|
9530
|
+
nativeVirtualKeyCode: event.keyCode,
|
|
9531
|
+
modifiers: event.modifiers
|
|
9479
9532
|
};
|
|
9480
9533
|
if (isPrintable) {
|
|
9481
|
-
await session.sendAndWait("Input.dispatchKeyEvent", { ...baseParams, type: "keyDown", text });
|
|
9482
|
-
await session.sendAndWait("Input.dispatchKeyEvent", { ...baseParams, type: "char", text });
|
|
9534
|
+
await session.sendAndWait("Input.dispatchKeyEvent", { ...baseParams, type: "keyDown", text: event.text });
|
|
9535
|
+
await session.sendAndWait("Input.dispatchKeyEvent", { ...baseParams, type: "char", text: event.text });
|
|
9483
9536
|
await session.sendAndWait("Input.dispatchKeyEvent", { ...baseParams, type: "keyUp" });
|
|
9484
9537
|
} else {
|
|
9485
|
-
await session.sendAndWait("Input.dispatchKeyEvent", { ...baseParams, type: "rawKeyDown", text:
|
|
9538
|
+
await session.sendAndWait("Input.dispatchKeyEvent", { ...baseParams, type: "rawKeyDown", text: event.text });
|
|
9486
9539
|
await session.sendAndWait("Input.dispatchKeyEvent", { ...baseParams, type: "keyUp" });
|
|
9487
9540
|
}
|
|
9488
|
-
return { key:
|
|
9541
|
+
return { key: event.key, code: event.code, modifiers: event.modifiers, focused, event };
|
|
9489
9542
|
};
|
|
9490
9543
|
|
|
9491
9544
|
// ../argus-watcher/dist/http/routes/postDomKeydown.js
|
|
@@ -9495,12 +9548,23 @@ var route30 = defineJsonRoute({
|
|
|
9495
9548
|
parseBody: true,
|
|
9496
9549
|
endpoint: "dom/keydown",
|
|
9497
9550
|
validate: (payload) => {
|
|
9498
|
-
|
|
9499
|
-
|
|
9551
|
+
const hasKey = typeof payload.key === "string" && payload.key.trim() !== "";
|
|
9552
|
+
const hasCode = typeof payload.code === "string" && payload.code.trim() !== "";
|
|
9553
|
+
if (payload.key != null && !hasKey) {
|
|
9554
|
+
return "key must be a non-empty string";
|
|
9555
|
+
}
|
|
9556
|
+
if (payload.code != null && !hasCode) {
|
|
9557
|
+
return "code must be a non-empty string";
|
|
9558
|
+
}
|
|
9559
|
+
if (!hasKey && !hasCode) {
|
|
9560
|
+
return "key or code is required";
|
|
9500
9561
|
}
|
|
9501
9562
|
if (payload.selector != null && (typeof payload.selector !== "string" || payload.selector.trim() === "")) {
|
|
9502
9563
|
return "selector must be a non-empty string";
|
|
9503
9564
|
}
|
|
9565
|
+
if (payload.modifiers != null && typeof payload.modifiers !== "string") {
|
|
9566
|
+
return "modifiers must be a string";
|
|
9567
|
+
}
|
|
9504
9568
|
try {
|
|
9505
9569
|
parseModifiers(payload.modifiers);
|
|
9506
9570
|
} catch (error) {
|
|
@@ -9511,10 +9575,18 @@ var route30 = defineJsonRoute({
|
|
|
9511
9575
|
handle: async ({ ctx, body: payload }) => {
|
|
9512
9576
|
const result = await dispatchKeydown(ctx.cdpSession, {
|
|
9513
9577
|
key: payload.key,
|
|
9578
|
+
code: payload.code,
|
|
9514
9579
|
selector: payload.selector,
|
|
9515
9580
|
modifiers: parseModifiers(payload.modifiers)
|
|
9516
9581
|
});
|
|
9517
|
-
return {
|
|
9582
|
+
return {
|
|
9583
|
+
ok: true,
|
|
9584
|
+
key: result.key,
|
|
9585
|
+
code: result.code,
|
|
9586
|
+
modifiers: result.modifiers,
|
|
9587
|
+
focused: result.focused,
|
|
9588
|
+
event: result.event
|
|
9589
|
+
};
|
|
9518
9590
|
}
|
|
9519
9591
|
});
|
|
9520
9592
|
|
|
@@ -11919,73 +11991,169 @@ var createThrottleController = () => {
|
|
|
11919
11991
|
return { getStatus, setDesired, clearDesired, onAttach };
|
|
11920
11992
|
};
|
|
11921
11993
|
|
|
11922
|
-
// ../argus-watcher/dist/net/
|
|
11923
|
-
var
|
|
11924
|
-
|
|
11925
|
-
|
|
11926
|
-
|
|
11927
|
-
|
|
11928
|
-
|
|
11929
|
-
|
|
11930
|
-
|
|
11931
|
-
|
|
11932
|
-
|
|
11933
|
-
|
|
11934
|
-
|
|
11935
|
-
|
|
11994
|
+
// ../argus-watcher/dist/net/NetMockInterception.js
|
|
11995
|
+
var PAGE_TARGET = { key: "page", sessionId: null };
|
|
11996
|
+
|
|
11997
|
+
class NetMockInterception {
|
|
11998
|
+
onPaused;
|
|
11999
|
+
onError;
|
|
12000
|
+
binding = null;
|
|
12001
|
+
bound = false;
|
|
12002
|
+
enabledTargets = new Map;
|
|
12003
|
+
reconcileTail = Promise.resolve();
|
|
12004
|
+
constructor(onPaused, onError) {
|
|
12005
|
+
this.onPaused = onPaused;
|
|
12006
|
+
this.onError = onError;
|
|
12007
|
+
}
|
|
12008
|
+
bind(binding) {
|
|
12009
|
+
this.binding = binding;
|
|
12010
|
+
if (this.bound) {
|
|
12011
|
+
return;
|
|
11936
12012
|
}
|
|
11937
|
-
|
|
11938
|
-
|
|
11939
|
-
|
|
11940
|
-
|
|
11941
|
-
|
|
12013
|
+
this.bound = true;
|
|
12014
|
+
binding.pageSession.onEvent("Fetch.requestPaused", (params, meta) => {
|
|
12015
|
+
const request = parsePausedRequest(params, meta);
|
|
12016
|
+
if (request) {
|
|
12017
|
+
this.onPaused(request);
|
|
12018
|
+
}
|
|
12019
|
+
});
|
|
12020
|
+
}
|
|
12021
|
+
get enabled() {
|
|
12022
|
+
return this.enabledTargets.size > 0;
|
|
12023
|
+
}
|
|
12024
|
+
matchesScope(scope, request) {
|
|
12025
|
+
if (scope === "page") {
|
|
12026
|
+
return request.sessionId === null;
|
|
11942
12027
|
}
|
|
11943
|
-
|
|
11944
|
-
|
|
11945
|
-
|
|
11946
|
-
|
|
11947
|
-
|
|
11948
|
-
enabled = false;
|
|
11949
|
-
recordError(error);
|
|
12028
|
+
const selected = this.binding?.getSelectedTarget() ?? null;
|
|
12029
|
+
if (selected?.sessionId) {
|
|
12030
|
+
return request.sessionId === selected.sessionId;
|
|
12031
|
+
}
|
|
12032
|
+
if (request.sessionId !== null) {
|
|
11950
12033
|
return false;
|
|
11951
12034
|
}
|
|
11952
|
-
|
|
11953
|
-
|
|
11954
|
-
|
|
12035
|
+
const selectedFrameId = selected?.frameId ?? null;
|
|
12036
|
+
const selectedIsChildFrame = selectedFrameId !== null && selectedFrameId !== selected?.topFrameId;
|
|
12037
|
+
return !selectedIsChildFrame || request.frameId === selectedFrameId;
|
|
12038
|
+
}
|
|
12039
|
+
async sendRequestCommand(request, method, params) {
|
|
12040
|
+
await this.sendCommand({ key: request.sessionId ? `session:${request.sessionId}` : "page", sessionId: request.sessionId }, method, params);
|
|
12041
|
+
}
|
|
12042
|
+
reconcile(scopes, reset = false) {
|
|
12043
|
+
const requestedScopes = new Set(scopes);
|
|
12044
|
+
const operation = this.reconcileTail.then(() => this.applyReconcile(requestedScopes, reset));
|
|
12045
|
+
this.reconcileTail = operation.then(() => {
|
|
11955
12046
|
return;
|
|
11956
|
-
}
|
|
11957
|
-
enabled = false;
|
|
11958
|
-
if (!session || !session.isAttached()) {
|
|
12047
|
+
}, () => {
|
|
11959
12048
|
return;
|
|
12049
|
+
});
|
|
12050
|
+
return operation;
|
|
12051
|
+
}
|
|
12052
|
+
async applyReconcile(scopes, reset) {
|
|
12053
|
+
if (reset) {
|
|
12054
|
+
this.enabledTargets.clear();
|
|
12055
|
+
}
|
|
12056
|
+
const session = this.binding?.pageSession;
|
|
12057
|
+
if (!session?.isAttached()) {
|
|
12058
|
+
this.enabledTargets.clear();
|
|
12059
|
+
return false;
|
|
12060
|
+
}
|
|
12061
|
+
const desiredTargets = this.getDesiredTargets(scopes);
|
|
12062
|
+
for (const [key, target] of this.enabledTargets) {
|
|
12063
|
+
if (!desiredTargets.has(key)) {
|
|
12064
|
+
await this.sendCommand(target, "Fetch.disable");
|
|
12065
|
+
this.enabledTargets.delete(key);
|
|
12066
|
+
}
|
|
12067
|
+
}
|
|
12068
|
+
for (const [key, target] of desiredTargets) {
|
|
12069
|
+
if (this.enabledTargets.has(key)) {
|
|
12070
|
+
continue;
|
|
12071
|
+
}
|
|
12072
|
+
const enabled = await this.sendCommand(target, "Fetch.enable", { patterns: [{ urlPattern: "*", requestStage: "Request" }] });
|
|
12073
|
+
if (enabled) {
|
|
12074
|
+
this.enabledTargets.set(key, target);
|
|
12075
|
+
}
|
|
12076
|
+
}
|
|
12077
|
+
return this.enabled;
|
|
12078
|
+
}
|
|
12079
|
+
onDetach() {
|
|
12080
|
+
this.enabledTargets.clear();
|
|
12081
|
+
}
|
|
12082
|
+
getDesiredTargets(scopes) {
|
|
12083
|
+
const targets = new Map;
|
|
12084
|
+
if (scopes.has("page")) {
|
|
12085
|
+
targets.set(PAGE_TARGET.key, PAGE_TARGET);
|
|
12086
|
+
}
|
|
12087
|
+
if (!scopes.has("selected")) {
|
|
12088
|
+
return targets;
|
|
12089
|
+
}
|
|
12090
|
+
const sessionId = this.binding?.getSelectedTarget()?.sessionId ?? null;
|
|
12091
|
+
const selectedTarget = sessionId ? { key: `session:${sessionId}`, sessionId } : PAGE_TARGET;
|
|
12092
|
+
targets.set(selectedTarget.key, selectedTarget);
|
|
12093
|
+
return targets;
|
|
12094
|
+
}
|
|
12095
|
+
async sendCommand(target, method, params = {}) {
|
|
12096
|
+
const session = this.binding?.pageSession;
|
|
12097
|
+
if (!session?.isAttached()) {
|
|
12098
|
+
return false;
|
|
11960
12099
|
}
|
|
11961
12100
|
try {
|
|
11962
|
-
await session.sendAndWait(
|
|
12101
|
+
await session.sendAndWait(method, params, target.sessionId ? { sessionId: target.sessionId } : undefined);
|
|
12102
|
+
return true;
|
|
11963
12103
|
} catch (error) {
|
|
11964
|
-
|
|
12104
|
+
if (!isBenignInterceptionError(error)) {
|
|
12105
|
+
this.onError(error);
|
|
12106
|
+
}
|
|
12107
|
+
return false;
|
|
11965
12108
|
}
|
|
12109
|
+
}
|
|
12110
|
+
}
|
|
12111
|
+
var parsePausedRequest = (params, meta) => {
|
|
12112
|
+
const paused = params;
|
|
12113
|
+
const requestId = paused?.requestId;
|
|
12114
|
+
if (typeof requestId !== "string" || requestId === "") {
|
|
12115
|
+
return null;
|
|
12116
|
+
}
|
|
12117
|
+
return {
|
|
12118
|
+
requestId,
|
|
12119
|
+
url: paused.request?.url ?? "",
|
|
12120
|
+
method: paused.request?.method ?? "GET",
|
|
12121
|
+
resourceType: paused.resourceType ?? "",
|
|
12122
|
+
frameId: paused.frameId ?? null,
|
|
12123
|
+
sessionId: meta.sessionId ?? null,
|
|
12124
|
+
headers: paused.request?.headers ?? {}
|
|
11966
12125
|
};
|
|
11967
|
-
|
|
11968
|
-
|
|
11969
|
-
|
|
11970
|
-
|
|
12126
|
+
};
|
|
12127
|
+
var isBenignInterceptionError = (error) => {
|
|
12128
|
+
const code = error?.code;
|
|
12129
|
+
if (code === "cdp_not_attached") {
|
|
12130
|
+
return true;
|
|
12131
|
+
}
|
|
12132
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
12133
|
+
return message.includes("Invalid InterceptionId") || message.includes("Inspected target navigated or closed") || message.includes("Session with given id not found") || message.includes("No target with given id");
|
|
12134
|
+
};
|
|
12135
|
+
|
|
12136
|
+
// ../argus-watcher/dist/net/NetMockController.js
|
|
12137
|
+
var createNetMockController = () => {
|
|
12138
|
+
let lastError = null;
|
|
12139
|
+
let nextRuleId = 1;
|
|
12140
|
+
const rules = [];
|
|
12141
|
+
const recordError = (error) => {
|
|
12142
|
+
lastError = { message: error instanceof Error ? error.message : String(error) };
|
|
12143
|
+
const code = error?.code;
|
|
12144
|
+
if (typeof code === "string") {
|
|
12145
|
+
lastError.code = code;
|
|
11971
12146
|
}
|
|
11972
|
-
bound = true;
|
|
11973
|
-
nextSession.onEvent("Fetch.requestPaused", (params) => {
|
|
11974
|
-
handleRequestPaused(params);
|
|
11975
|
-
});
|
|
11976
12147
|
};
|
|
11977
|
-
const
|
|
11978
|
-
|
|
11979
|
-
|
|
11980
|
-
|
|
11981
|
-
|
|
11982
|
-
|
|
11983
|
-
const
|
|
11984
|
-
const method = paused.request?.method ?? "GET";
|
|
11985
|
-
const resourceType = paused.resourceType ?? "";
|
|
11986
|
-
const rule = rules.find((candidate) => ruleMatches(candidate, url, method, resourceType));
|
|
12148
|
+
const interception = new NetMockInterception((request) => void handleRequestPaused(request), recordError);
|
|
12149
|
+
const bind = (binding) => {
|
|
12150
|
+
interception.bind(binding);
|
|
12151
|
+
interception.reconcile(getActiveScopes(rules));
|
|
12152
|
+
};
|
|
12153
|
+
const handleRequestPaused = async (paused) => {
|
|
12154
|
+
const rule = rules.find((candidate) => interception.matchesScope(candidate.scope ?? "page", paused) && ruleMatches(candidate, paused.url, paused.method, paused.resourceType));
|
|
11987
12155
|
if (!rule) {
|
|
11988
|
-
await sendAction("Fetch.continueRequest", { requestId });
|
|
12156
|
+
await sendAction(paused, "Fetch.continueRequest", { requestId: paused.requestId });
|
|
11989
12157
|
return;
|
|
11990
12158
|
}
|
|
11991
12159
|
rule.hits += 1;
|
|
@@ -11994,53 +12162,41 @@ var createNetMockController = () => {
|
|
|
11994
12162
|
}
|
|
11995
12163
|
const action = rule.action;
|
|
11996
12164
|
if (action.kind === "block") {
|
|
11997
|
-
await sendAction("Fetch.failRequest", { requestId, errorReason: "BlockedByClient" });
|
|
12165
|
+
await sendAction(paused, "Fetch.failRequest", { requestId: paused.requestId, errorReason: "BlockedByClient" });
|
|
11998
12166
|
return;
|
|
11999
12167
|
}
|
|
12000
12168
|
if (action.kind === "fail") {
|
|
12001
|
-
await sendAction("Fetch.failRequest", { requestId, errorReason: action.reason });
|
|
12169
|
+
await sendAction(paused, "Fetch.failRequest", { requestId: paused.requestId, errorReason: action.reason });
|
|
12002
12170
|
return;
|
|
12003
12171
|
}
|
|
12004
12172
|
if (action.kind === "fulfill") {
|
|
12005
|
-
const fulfillParams = { requestId, responseCode: action.status };
|
|
12173
|
+
const fulfillParams = { requestId: paused.requestId, responseCode: action.status };
|
|
12006
12174
|
if (action.headers && action.headers.length > 0) {
|
|
12007
12175
|
fulfillParams.responseHeaders = action.headers;
|
|
12008
12176
|
}
|
|
12009
12177
|
if (action.bodyBase64 != null) {
|
|
12010
12178
|
fulfillParams.body = action.bodyBase64;
|
|
12011
12179
|
}
|
|
12012
|
-
await sendAction("Fetch.fulfillRequest", fulfillParams);
|
|
12180
|
+
await sendAction(paused, "Fetch.fulfillRequest", fulfillParams);
|
|
12013
12181
|
return;
|
|
12014
12182
|
}
|
|
12015
|
-
const continueParams = { requestId };
|
|
12183
|
+
const continueParams = { requestId: paused.requestId };
|
|
12016
12184
|
if (action.rewriteHost) {
|
|
12017
|
-
const rewritten = rewriteUrlHost(url, action.rewriteHost);
|
|
12185
|
+
const rewritten = rewriteUrlHost(paused.url, action.rewriteHost);
|
|
12018
12186
|
if (rewritten) {
|
|
12019
12187
|
continueParams.url = rewritten;
|
|
12020
12188
|
}
|
|
12021
12189
|
}
|
|
12022
12190
|
if (action.setHeaders && action.setHeaders.length > 0) {
|
|
12023
|
-
continueParams.headers = mergeHeaders(paused.
|
|
12024
|
-
}
|
|
12025
|
-
await sendAction("Fetch.continueRequest", continueParams);
|
|
12026
|
-
};
|
|
12027
|
-
const sendAction = async (cdpMethod, params) => {
|
|
12028
|
-
if (!session || !session.isAttached()) {
|
|
12029
|
-
return;
|
|
12030
|
-
}
|
|
12031
|
-
try {
|
|
12032
|
-
await session.sendAndWait(cdpMethod, params);
|
|
12033
|
-
} catch (error) {
|
|
12034
|
-
if (isBenignInterceptionError(error)) {
|
|
12035
|
-
return;
|
|
12036
|
-
}
|
|
12037
|
-
recordError(error);
|
|
12191
|
+
continueParams.headers = mergeHeaders(paused.headers, action.setHeaders);
|
|
12038
12192
|
}
|
|
12193
|
+
await sendAction(paused, "Fetch.continueRequest", continueParams);
|
|
12039
12194
|
};
|
|
12195
|
+
const sendAction = async (request, cdpMethod, params) => interception.sendRequestCommand(request, cdpMethod, params);
|
|
12040
12196
|
const getStatus = (ctx) => ({
|
|
12041
12197
|
ok: true,
|
|
12042
12198
|
attached: ctx.attached,
|
|
12043
|
-
enabled,
|
|
12199
|
+
enabled: interception.enabled,
|
|
12044
12200
|
rules: rules.map(toPublicRule),
|
|
12045
12201
|
lastError
|
|
12046
12202
|
});
|
|
@@ -12048,6 +12204,7 @@ var createNetMockController = () => {
|
|
|
12048
12204
|
lastError = null;
|
|
12049
12205
|
const rule = {
|
|
12050
12206
|
id: nextRuleId++,
|
|
12207
|
+
scope: input.scope ?? "page",
|
|
12051
12208
|
match: input.match,
|
|
12052
12209
|
action: input.action,
|
|
12053
12210
|
delayMs: input.delayMs,
|
|
@@ -12060,7 +12217,7 @@ var createNetMockController = () => {
|
|
|
12060
12217
|
if (!attached) {
|
|
12061
12218
|
return { ok: true, attached: false, enabled: false, rule: toPublicRule(rule) };
|
|
12062
12219
|
}
|
|
12063
|
-
const applied =
|
|
12220
|
+
const applied = await interception.reconcile(getActiveScopes(rules));
|
|
12064
12221
|
return {
|
|
12065
12222
|
ok: true,
|
|
12066
12223
|
attached: true,
|
|
@@ -12076,32 +12233,33 @@ var createNetMockController = () => {
|
|
|
12076
12233
|
rules.splice(index, 1);
|
|
12077
12234
|
}
|
|
12078
12235
|
if (rules.length === 0) {
|
|
12079
|
-
await
|
|
12236
|
+
await interception.reconcile(new Set);
|
|
12237
|
+
} else {
|
|
12238
|
+
await interception.reconcile(getActiveScopes(rules));
|
|
12080
12239
|
}
|
|
12081
|
-
return { ok: true, removed, enabled };
|
|
12240
|
+
return { ok: true, removed, enabled: interception.enabled };
|
|
12082
12241
|
};
|
|
12083
12242
|
const clearRules = async () => {
|
|
12084
12243
|
const removed = rules.length;
|
|
12085
12244
|
rules.length = 0;
|
|
12086
|
-
await
|
|
12087
|
-
return { ok: true, removed, enabled };
|
|
12245
|
+
await interception.reconcile(new Set);
|
|
12246
|
+
return { ok: true, removed, enabled: interception.enabled };
|
|
12088
12247
|
};
|
|
12089
|
-
const onAttach = async (
|
|
12090
|
-
|
|
12091
|
-
enabled = false;
|
|
12092
|
-
if (!hasActiveRules()) {
|
|
12093
|
-
return;
|
|
12094
|
-
}
|
|
12095
|
-
const applied = await enableInterception();
|
|
12248
|
+
const onAttach = async () => {
|
|
12249
|
+
const applied = await interception.reconcile(getActiveScopes(rules), true);
|
|
12096
12250
|
if (!applied && lastError) {
|
|
12097
12251
|
console.warn(`[NetMock] Failed to re-enable interception on attach: ${lastError.message}`);
|
|
12098
12252
|
}
|
|
12099
12253
|
};
|
|
12254
|
+
const onTargetChanged = async () => {
|
|
12255
|
+
await interception.reconcile(getActiveScopes(rules));
|
|
12256
|
+
};
|
|
12100
12257
|
const onDetach = () => {
|
|
12101
|
-
|
|
12258
|
+
interception.onDetach();
|
|
12102
12259
|
};
|
|
12103
|
-
return { bind, getStatus, addRule, removeRule, clearRules, onAttach, onDetach };
|
|
12260
|
+
return { bind, getStatus, addRule, removeRule, clearRules, onAttach, onTargetChanged, onDetach };
|
|
12104
12261
|
};
|
|
12262
|
+
var getActiveScopes = (rules) => new Set(rules.filter(isRuleActive).map((rule) => rule.scope ?? "page"));
|
|
12105
12263
|
var isRuleActive = (rule) => rule.times == null || rule.hits < rule.times;
|
|
12106
12264
|
var ruleMatches = (rule, url, method, resourceType) => {
|
|
12107
12265
|
if (!isRuleActive(rule)) {
|
|
@@ -12145,16 +12303,9 @@ var mergeHeaders = (original, overrides) => {
|
|
|
12145
12303
|
}
|
|
12146
12304
|
return [...merged.values()];
|
|
12147
12305
|
};
|
|
12148
|
-
var isBenignInterceptionError = (error) => {
|
|
12149
|
-
const code = error?.code;
|
|
12150
|
-
if (code === "cdp_not_attached") {
|
|
12151
|
-
return true;
|
|
12152
|
-
}
|
|
12153
|
-
const message = error instanceof Error ? error.message : String(error);
|
|
12154
|
-
return message.includes("Invalid InterceptionId") || message.includes("Inspected target navigated or closed");
|
|
12155
|
-
};
|
|
12156
12306
|
var toPublicRule = (rule) => ({
|
|
12157
12307
|
id: rule.id,
|
|
12308
|
+
scope: rule.scope ?? "page",
|
|
12158
12309
|
match: rule.match,
|
|
12159
12310
|
action: rule.action,
|
|
12160
12311
|
delayMs: rule.delayMs,
|
|
@@ -17067,7 +17218,7 @@ var createWatcherHandle = async (options, watcherId) => {
|
|
|
17067
17218
|
await emulationController.onAttach(session);
|
|
17068
17219
|
await throttleController.onAttach(session);
|
|
17069
17220
|
await visibilityController.onAttach(sourceHandle.pageSession ?? session);
|
|
17070
|
-
await netMockController.onAttach(
|
|
17221
|
+
await netMockController.onAttach();
|
|
17071
17222
|
await networkCapture?.onAttached();
|
|
17072
17223
|
onIndicatorAttach(session, target);
|
|
17073
17224
|
await maybeInjectOnAttach(session, target);
|
|
@@ -17084,6 +17235,7 @@ var createWatcherHandle = async (options, watcherId) => {
|
|
|
17084
17235
|
},
|
|
17085
17236
|
reason: null
|
|
17086
17237
|
});
|
|
17238
|
+
netMockController.onTargetChanged();
|
|
17087
17239
|
onIndicatorAttach(session, target);
|
|
17088
17240
|
};
|
|
17089
17241
|
const handleSourceDetach = (reason) => {
|
|
@@ -17111,7 +17263,18 @@ var createWatcherHandle = async (options, watcherId) => {
|
|
|
17111
17263
|
indicatorController?.setRecording(recording);
|
|
17112
17264
|
}
|
|
17113
17265
|
});
|
|
17114
|
-
netMockController.bind(
|
|
17266
|
+
netMockController.bind({
|
|
17267
|
+
pageSession: sourceHandle.pageSession ?? sourceHandle.session,
|
|
17268
|
+
getSelectedTarget: () => {
|
|
17269
|
+
const context = sourceHandle.getNetFilterContext?.() ?? null;
|
|
17270
|
+
const frameId = context?.selectedFrameId ?? null;
|
|
17271
|
+
return {
|
|
17272
|
+
frameId,
|
|
17273
|
+
topFrameId: context?.topFrameId ?? null,
|
|
17274
|
+
sessionId: frameId ? sourceHandle.getFrameSessionId?.(frameId) ?? null : null
|
|
17275
|
+
};
|
|
17276
|
+
}
|
|
17277
|
+
});
|
|
17115
17278
|
const dialogSession = sourceHandle.pageSession ?? sourceHandle.session;
|
|
17116
17279
|
dialogSession.onEvent("Page.javascriptDialogOpening", (params) => {
|
|
17117
17280
|
const dialog = parseDialogStatus(params);
|
|
@@ -22115,6 +22278,10 @@ var buildAddRequest = async (options, output) => {
|
|
|
22115
22278
|
if (!action) {
|
|
22116
22279
|
return null;
|
|
22117
22280
|
}
|
|
22281
|
+
const scope = resolveMockScope(options, output);
|
|
22282
|
+
if (!scope) {
|
|
22283
|
+
return null;
|
|
22284
|
+
}
|
|
22118
22285
|
const match = { url: urlPattern };
|
|
22119
22286
|
if (options.method) {
|
|
22120
22287
|
match.method = options.method;
|
|
@@ -22122,7 +22289,21 @@ var buildAddRequest = async (options, output) => {
|
|
|
22122
22289
|
if (options.resourceType) {
|
|
22123
22290
|
match.resourceType = options.resourceType;
|
|
22124
22291
|
}
|
|
22125
|
-
return { match, action, delayMs, times };
|
|
22292
|
+
return { scope, match, action, delayMs, times };
|
|
22293
|
+
};
|
|
22294
|
+
var resolveMockScope = (options, output) => {
|
|
22295
|
+
if (options.scope && options.frame) {
|
|
22296
|
+
output.writeWarn("Cannot combine --scope and --frame. Use one or the other.");
|
|
22297
|
+
process.exitCode = 2;
|
|
22298
|
+
return null;
|
|
22299
|
+
}
|
|
22300
|
+
const value = (options.scope ?? options.frame ?? "page").trim().toLowerCase();
|
|
22301
|
+
if (value === "page" || value === "selected") {
|
|
22302
|
+
return value;
|
|
22303
|
+
}
|
|
22304
|
+
output.writeWarn(`Invalid mock scope: ${value}. Expected page or selected.`);
|
|
22305
|
+
process.exitCode = 2;
|
|
22306
|
+
return null;
|
|
22126
22307
|
};
|
|
22127
22308
|
var buildAction = async (options, responseHeaders, requestHeaders, delayMs, output) => {
|
|
22128
22309
|
const invalid = (message) => {
|
|
@@ -22310,6 +22491,9 @@ var describeRule = (rule) => {
|
|
|
22310
22491
|
if (rule.times != null) {
|
|
22311
22492
|
extras.push(`times ${Math.min(rule.hits, rule.times)}/${rule.times}`);
|
|
22312
22493
|
}
|
|
22494
|
+
if (rule.scope === "selected") {
|
|
22495
|
+
extras.push("scope selected");
|
|
22496
|
+
}
|
|
22313
22497
|
extras.push(`hits ${rule.hits}`);
|
|
22314
22498
|
return `#${rule.id} ${match} → ${describeAction(rule.action)} [${extras.join(", ")}]`;
|
|
22315
22499
|
};
|
|
@@ -22429,6 +22613,8 @@ var netMockCommand = {
|
|
|
22429
22613
|
{ flags: "--url <pattern>", description: "URL wildcard pattern; substring match when it contains no *" },
|
|
22430
22614
|
{ flags: "--method <method>", description: "Only match this HTTP method" },
|
|
22431
22615
|
{ flags: "--resource-type <type>", description: "Only match this CDP resource type (Fetch, XHR, Document, ...)" },
|
|
22616
|
+
{ flags: "--scope <scope>", description: "Intercept the top-level page or currently selected target (page|selected)" },
|
|
22617
|
+
{ flags: "--frame <frame>", description: "Alias for --scope; accepts page or selected" },
|
|
22432
22618
|
{ flags: "--block", description: "Abort matching requests as BlockedByClient" },
|
|
22433
22619
|
{ flags: "--fail <reason>", description: "Abort with a network error (TimedOut, ConnectionRefused, ...)" },
|
|
22434
22620
|
{ flags: "--status <code>", description: "Stub a response with this HTTP status (default 200 when a body is given)" },
|
|
@@ -22455,12 +22641,13 @@ var netMockCommand = {
|
|
|
22455
22641
|
'argus net mock add app --url "*/analytics/*" --block',
|
|
22456
22642
|
'argus net mock add app --url "*/api/save" --fail ConnectionRefused --times 1',
|
|
22457
22643
|
'argus net mock add app --url "*/api/config" --status 200 --body-file ./fixtures/config.json',
|
|
22644
|
+
'argus net mock add extension --scope selected --url "*/api/config" --status 200 --body-file ./fixtures/config.json',
|
|
22458
22645
|
`argus net mock add app --url "*/game/init" --status 500 --body '{"error":"maintenance"}'`,
|
|
22459
22646
|
'argus net mock add app --url "*/api/*" --delay 2s --method POST',
|
|
22460
22647
|
'argus net mock add app --url "cdn.prod.com" --rewrite-host localhost:3000'
|
|
22461
22648
|
],
|
|
22462
22649
|
action: async (id, options) => {
|
|
22463
|
-
await runNetMockAdd(id, options);
|
|
22650
|
+
await runNetMockAdd(id, resolveNetMockAddOptions(options));
|
|
22464
22651
|
}
|
|
22465
22652
|
},
|
|
22466
22653
|
{
|
|
@@ -22471,7 +22658,7 @@ var netMockCommand = {
|
|
|
22471
22658
|
options: [jsonOption],
|
|
22472
22659
|
examples: ["argus net mock ls app", "argus net mock ls app --json"],
|
|
22473
22660
|
action: async (id, options) => {
|
|
22474
|
-
await runNetMockList(id, options);
|
|
22661
|
+
await runNetMockList(id, resolveCommandOptions(options));
|
|
22475
22662
|
}
|
|
22476
22663
|
},
|
|
22477
22664
|
{
|
|
@@ -22485,7 +22672,7 @@ var netMockCommand = {
|
|
|
22485
22672
|
options: [jsonOption],
|
|
22486
22673
|
examples: ["argus net mock rm 2 app", "argus net mock rm 2 app --json"],
|
|
22487
22674
|
action: async (rule, id, options) => {
|
|
22488
|
-
await runNetMockRemove(id, rule, options);
|
|
22675
|
+
await runNetMockRemove(id, rule, resolveCommandOptions(options));
|
|
22489
22676
|
}
|
|
22490
22677
|
},
|
|
22491
22678
|
{
|
|
@@ -22495,7 +22682,7 @@ var netMockCommand = {
|
|
|
22495
22682
|
options: [jsonOption],
|
|
22496
22683
|
examples: ["argus net mock clear app", "argus net mock clear app --json"],
|
|
22497
22684
|
action: async (id, options) => {
|
|
22498
|
-
await runNetMockClear(id, options);
|
|
22685
|
+
await runNetMockClear(id, resolveCommandOptions(options));
|
|
22499
22686
|
}
|
|
22500
22687
|
}
|
|
22501
22688
|
]
|
|
@@ -22718,8 +22905,8 @@ Examples:
|
|
|
22718
22905
|
]
|
|
22719
22906
|
}
|
|
22720
22907
|
];
|
|
22721
|
-
var resolveCommandOptions = (value) => {
|
|
22722
|
-
const fallback = parseNetArgv(
|
|
22908
|
+
var resolveCommandOptions = (value, argv = process.argv.slice(2)) => {
|
|
22909
|
+
const fallback = parseNetArgv(argv);
|
|
22723
22910
|
if (value && typeof value === "object" && "opts" in value && typeof value.opts === "function") {
|
|
22724
22911
|
return {
|
|
22725
22912
|
...value.opts(),
|
|
@@ -22731,6 +22918,16 @@ var resolveCommandOptions = (value) => {
|
|
|
22731
22918
|
...fallback
|
|
22732
22919
|
};
|
|
22733
22920
|
};
|
|
22921
|
+
var resolveNetMockAddOptions = (value, argv = process.argv.slice(2)) => {
|
|
22922
|
+
const resolved = resolveCommandOptions(value, argv);
|
|
22923
|
+
for (const key of ["method", "status", "resourceType"]) {
|
|
22924
|
+
const option = resolved[key];
|
|
22925
|
+
if (Array.isArray(option)) {
|
|
22926
|
+
resolved[key] = option.at(-1);
|
|
22927
|
+
}
|
|
22928
|
+
}
|
|
22929
|
+
return resolved;
|
|
22930
|
+
};
|
|
22734
22931
|
var parseNetArgv = (argv) => {
|
|
22735
22932
|
const parsed = {};
|
|
22736
22933
|
const readValue = (flag) => {
|
|
@@ -47431,10 +47628,34 @@ var domCommands = [
|
|
|
47431
47628
|
];
|
|
47432
47629
|
|
|
47433
47630
|
// dist/commands/domKeydown.js
|
|
47631
|
+
var normalizeOptionalString2 = (value) => {
|
|
47632
|
+
const normalized = value?.trim();
|
|
47633
|
+
return normalized ? normalized : undefined;
|
|
47634
|
+
};
|
|
47635
|
+
var mergeModifierOptions = (options) => {
|
|
47636
|
+
const modifiers = new Set;
|
|
47637
|
+
for (const part of (options.modifiers ?? "").split(",")) {
|
|
47638
|
+
const name = part.trim().toLowerCase();
|
|
47639
|
+
if (name) {
|
|
47640
|
+
modifiers.add(name);
|
|
47641
|
+
}
|
|
47642
|
+
}
|
|
47643
|
+
if (options.shift)
|
|
47644
|
+
modifiers.add("shift");
|
|
47645
|
+
if (options.ctrl)
|
|
47646
|
+
modifiers.add("ctrl");
|
|
47647
|
+
if (options.alt)
|
|
47648
|
+
modifiers.add("alt");
|
|
47649
|
+
if (options.meta || options.cmd)
|
|
47650
|
+
modifiers.add("meta");
|
|
47651
|
+
return modifiers.size > 0 ? Array.from(modifiers).join(",") : undefined;
|
|
47652
|
+
};
|
|
47434
47653
|
var runDomKeydown = defineWatcherCommand({
|
|
47435
47654
|
build: (_args, options, output) => {
|
|
47436
|
-
|
|
47437
|
-
|
|
47655
|
+
const key = normalizeOptionalString2(options.key);
|
|
47656
|
+
const code = normalizeOptionalString2(options.code);
|
|
47657
|
+
if (!key && !code) {
|
|
47658
|
+
output.writeWarn("--key or --code is required");
|
|
47438
47659
|
process.exitCode = 2;
|
|
47439
47660
|
return null;
|
|
47440
47661
|
}
|
|
@@ -47442,15 +47663,20 @@ var runDomKeydown = defineWatcherCommand({
|
|
|
47442
47663
|
path: "/dom/keydown",
|
|
47443
47664
|
method: "POST",
|
|
47444
47665
|
body: {
|
|
47445
|
-
key
|
|
47666
|
+
key,
|
|
47667
|
+
code,
|
|
47446
47668
|
selector: options.selector,
|
|
47447
|
-
modifiers: options
|
|
47669
|
+
modifiers: mergeModifierOptions(options)
|
|
47448
47670
|
},
|
|
47449
47671
|
timeoutMs: 30000
|
|
47450
47672
|
};
|
|
47451
47673
|
},
|
|
47452
|
-
formatHuman: (response, { output }) => {
|
|
47453
|
-
|
|
47674
|
+
formatHuman: (response, { options, output }) => {
|
|
47675
|
+
if (options.printEvent) {
|
|
47676
|
+
output.writeHuman(`Dispatched keydown event: ${JSON.stringify(response.event)}`);
|
|
47677
|
+
return;
|
|
47678
|
+
}
|
|
47679
|
+
output.writeHuman(`Dispatched keydown: ${response.key} (code=${response.code})`);
|
|
47454
47680
|
}
|
|
47455
47681
|
});
|
|
47456
47682
|
|
|
@@ -47460,13 +47686,26 @@ var keydownCommand = {
|
|
|
47460
47686
|
description: "Dispatch a keyboard event to the connected page",
|
|
47461
47687
|
arguments: [{ flags: "[id]", description: "Watcher id to query" }],
|
|
47462
47688
|
options: [
|
|
47463
|
-
{ flags: "--key <name>", description: "
|
|
47689
|
+
{ flags: "--key <name>", description: "KeyboardEvent.key value (e.g. Enter, a, ArrowUp)" },
|
|
47690
|
+
{ flags: "--code <code>", description: "KeyboardEvent.code value (e.g. KeyG, Digit1)" },
|
|
47464
47691
|
{ flags: "--selector <css>", description: "Focus element before dispatching" },
|
|
47465
47692
|
{ flags: "--testid <id>", description: `Shorthand for --selector "[data-testid='<id>']"` },
|
|
47466
47693
|
{ flags: "--modifiers <list>", description: "Comma-separated modifiers: shift,ctrl,alt,meta" },
|
|
47694
|
+
{ flags: "--shift", description: "Shortcut for --modifiers shift" },
|
|
47695
|
+
{ flags: "--ctrl", description: "Shortcut for --modifiers ctrl" },
|
|
47696
|
+
{ flags: "--alt", description: "Shortcut for --modifiers alt" },
|
|
47697
|
+
{ flags: "--meta", description: "Shortcut for --modifiers meta" },
|
|
47698
|
+
{ flags: "--cmd", description: "Alias for --meta" },
|
|
47699
|
+
{ flags: "--print-event", description: "Print resolved key/code/modifier event details" },
|
|
47467
47700
|
{ flags: "--json", description: "Output JSON for automation" }
|
|
47468
47701
|
],
|
|
47469
|
-
examples: [
|
|
47702
|
+
examples: [
|
|
47703
|
+
"argus keydown app --key Enter",
|
|
47704
|
+
"argus keydown app --key G",
|
|
47705
|
+
"argus keydown app --code KeyG",
|
|
47706
|
+
'argus keydown app --key a --selector "#input"',
|
|
47707
|
+
"argus keydown app --key a --shift --ctrl"
|
|
47708
|
+
],
|
|
47470
47709
|
action: async (id, options) => {
|
|
47471
47710
|
if (!resolveTestId(options))
|
|
47472
47711
|
return;
|
|
@@ -48729,7 +48968,7 @@ var extractPlugin = (mod) => {
|
|
|
48729
48968
|
return null;
|
|
48730
48969
|
return plugin;
|
|
48731
48970
|
};
|
|
48732
|
-
var
|
|
48971
|
+
var normalizeOptionalString3 = (value) => typeof value === "string" && value.trim() ? value.trim() : null;
|
|
48733
48972
|
var normalizeCommands = (value) => {
|
|
48734
48973
|
if (!Array.isArray(value))
|
|
48735
48974
|
return [];
|
|
@@ -48751,11 +48990,11 @@ var createLoadedEntry = (entry, plugin, url) => ({
|
|
|
48751
48990
|
alias: entry.alias,
|
|
48752
48991
|
status: "loaded",
|
|
48753
48992
|
name: plugin.name,
|
|
48754
|
-
version:
|
|
48755
|
-
description:
|
|
48993
|
+
version: normalizeOptionalString3(plugin.version),
|
|
48994
|
+
description: normalizeOptionalString3(plugin.description),
|
|
48756
48995
|
commands: normalizeCommands(plugin.commands),
|
|
48757
|
-
homepage:
|
|
48758
|
-
minArgusVersion:
|
|
48996
|
+
homepage: normalizeOptionalString3(plugin.homepage),
|
|
48997
|
+
minArgusVersion: normalizeOptionalString3(plugin.minArgusVersion),
|
|
48759
48998
|
url
|
|
48760
48999
|
});
|
|
48761
49000
|
var registerPlugins = async (program2, argv = process.argv.slice(2)) => {
|
|
@@ -49110,9 +49349,63 @@ var pluginCommands = [
|
|
|
49110
49349
|
}
|
|
49111
49350
|
];
|
|
49112
49351
|
|
|
49113
|
-
// dist/commands/extension/
|
|
49352
|
+
// dist/commands/extension/install.js
|
|
49353
|
+
import { spawn as spawn3 } from "node:child_process";
|
|
49354
|
+
|
|
49355
|
+
// dist/commands/extension/extensionId.js
|
|
49356
|
+
var ARGUS_EXTENSION_ID = "ibhecpfiodfmkpflcnnkkgnjifheefhb";
|
|
49357
|
+
|
|
49358
|
+
// dist/commands/extension/extensionPath.js
|
|
49114
49359
|
import fs17 from "node:fs";
|
|
49115
49360
|
import path22 from "node:path";
|
|
49361
|
+
import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
49362
|
+
var runExtensionPath = (options) => {
|
|
49363
|
+
const output = createOutput(options);
|
|
49364
|
+
const extensionDir = resolveExtensionDir();
|
|
49365
|
+
if (!extensionDir) {
|
|
49366
|
+
const message = `Packaged Argus extension not found. Checked:
|
|
49367
|
+
${resolveExtensionCandidates().join(`
|
|
49368
|
+
`)}`;
|
|
49369
|
+
if (options.json) {
|
|
49370
|
+
output.writeJson({ ok: false, error: { message } });
|
|
49371
|
+
} else {
|
|
49372
|
+
console.error(message);
|
|
49373
|
+
}
|
|
49374
|
+
process.exitCode = 2;
|
|
49375
|
+
return;
|
|
49376
|
+
}
|
|
49377
|
+
if (options.json) {
|
|
49378
|
+
output.writeJson({ ok: true, path: extensionDir });
|
|
49379
|
+
return;
|
|
49380
|
+
}
|
|
49381
|
+
output.writeHuman(extensionDir);
|
|
49382
|
+
};
|
|
49383
|
+
var resolveExtensionDir = () => {
|
|
49384
|
+
for (const candidate of resolveExtensionCandidates()) {
|
|
49385
|
+
if (isLoadableExtensionDir(candidate)) {
|
|
49386
|
+
return candidate;
|
|
49387
|
+
}
|
|
49388
|
+
}
|
|
49389
|
+
return null;
|
|
49390
|
+
};
|
|
49391
|
+
var isLoadableExtensionDir = (dir) => {
|
|
49392
|
+
return fs17.existsSync(path22.join(dir, "manifest.json")) && fs17.existsSync(path22.join(dir, "dist", "background", "service-worker.js"));
|
|
49393
|
+
};
|
|
49394
|
+
var resolveExtensionCandidates = () => {
|
|
49395
|
+
const moduleDir = path22.dirname(fileURLToPath2(import.meta.url));
|
|
49396
|
+
const candidates = [
|
|
49397
|
+
path22.resolve(moduleDir, "extension"),
|
|
49398
|
+
path22.resolve(moduleDir, "..", "..", "extension"),
|
|
49399
|
+
path22.resolve(moduleDir, "..", "extension"),
|
|
49400
|
+
path22.resolve(moduleDir, "..", "..", "..", "argus-extension"),
|
|
49401
|
+
path22.resolve(moduleDir, "..", "..", "..", "..", "argus-extension")
|
|
49402
|
+
];
|
|
49403
|
+
return [...new Set(candidates)];
|
|
49404
|
+
};
|
|
49405
|
+
|
|
49406
|
+
// dist/commands/extension/nativeHost.js
|
|
49407
|
+
import fs18 from "node:fs";
|
|
49408
|
+
import path23 from "node:path";
|
|
49116
49409
|
import os8 from "node:os";
|
|
49117
49410
|
import { execSync } from "node:child_process";
|
|
49118
49411
|
var BRIDGE_HOST_NAME = "com.vforsh.argus.bridge";
|
|
@@ -49122,21 +49415,21 @@ var HOST_NAMES = [BRIDGE_HOST_NAME, CONTROL_HOST_NAME];
|
|
|
49122
49415
|
var getManifestDir = (platform) => {
|
|
49123
49416
|
switch (platform) {
|
|
49124
49417
|
case "darwin":
|
|
49125
|
-
return
|
|
49418
|
+
return path23.join(os8.homedir(), "Library/Application Support/Google/Chrome/NativeMessagingHosts");
|
|
49126
49419
|
case "linux":
|
|
49127
|
-
return
|
|
49420
|
+
return path23.join(os8.homedir(), ".config/google-chrome/NativeMessagingHosts");
|
|
49128
49421
|
case "win32":
|
|
49129
|
-
return
|
|
49422
|
+
return path23.join(process.env.LOCALAPPDATA ?? os8.homedir(), "Google/Chrome/User Data/NativeMessagingHosts");
|
|
49130
49423
|
default:
|
|
49131
49424
|
throw new Error(`Unsupported platform: ${platform}`);
|
|
49132
49425
|
}
|
|
49133
49426
|
};
|
|
49134
49427
|
var getManifestPath = (platform, hostName = BRIDGE_HOST_NAME) => {
|
|
49135
|
-
return
|
|
49428
|
+
return path23.join(getManifestDir(platform), `${hostName}.json`);
|
|
49136
49429
|
};
|
|
49137
49430
|
var getWrapperPath = (platform, hostName = BRIDGE_HOST_NAME) => {
|
|
49138
49431
|
const filename = hostName === CONTROL_HOST_NAME ? "argus-native-control-host.sh" : "argus-native-host.sh";
|
|
49139
|
-
return
|
|
49432
|
+
return path23.join(getManifestDir(platform), filename);
|
|
49140
49433
|
};
|
|
49141
49434
|
var getPlatform = () => {
|
|
49142
49435
|
const platform = os8.platform();
|
|
@@ -49148,8 +49441,8 @@ var getPlatform = () => {
|
|
|
49148
49441
|
var findArgusExecutable = () => {
|
|
49149
49442
|
try {
|
|
49150
49443
|
const npmGlobalPrefix = execSync("npm config get prefix", { encoding: "utf8" }).trim();
|
|
49151
|
-
const globalBinPath =
|
|
49152
|
-
if (
|
|
49444
|
+
const globalBinPath = path23.join(npmGlobalPrefix, "bin", "argus");
|
|
49445
|
+
if (fs18.existsSync(globalBinPath)) {
|
|
49153
49446
|
return globalBinPath;
|
|
49154
49447
|
}
|
|
49155
49448
|
} catch {}
|
|
@@ -49162,7 +49455,7 @@ var findArgusExecutable = () => {
|
|
|
49162
49455
|
throw new Error("Could not find argus executable. Please install argus globally (npm install -g @vforsh/argus) or ensure it is in your PATH.");
|
|
49163
49456
|
};
|
|
49164
49457
|
var findNodePath = () => {
|
|
49165
|
-
return
|
|
49458
|
+
return fs18.realpathSync(process.execPath);
|
|
49166
49459
|
};
|
|
49167
49460
|
var createManifest = (extensionId, executablePath, hostName = BRIDGE_HOST_NAME) => {
|
|
49168
49461
|
return {
|
|
@@ -49180,16 +49473,16 @@ var createWrapperScript = (platform, executablePath, hostName = BRIDGE_HOST_NAME
|
|
|
49180
49473
|
const script = `#!/bin/bash
|
|
49181
49474
|
exec "${nodePath}" "${executablePath}" ${args}
|
|
49182
49475
|
`;
|
|
49183
|
-
|
|
49476
|
+
fs18.writeFileSync(wrapperPath, script, { mode: 493 });
|
|
49184
49477
|
return wrapperPath;
|
|
49185
49478
|
};
|
|
49186
49479
|
var installNativeHosts = (platform, extensionId, executablePath) => {
|
|
49187
|
-
|
|
49480
|
+
fs18.mkdirSync(getManifestDir(platform), { recursive: true });
|
|
49188
49481
|
return HOST_NAMES.map((hostName) => {
|
|
49189
49482
|
const wrapperPath = createWrapperScript(platform, executablePath, hostName);
|
|
49190
49483
|
const manifestPath = getManifestPath(platform, hostName);
|
|
49191
49484
|
const manifest = createManifest(extensionId, wrapperPath, hostName);
|
|
49192
|
-
|
|
49485
|
+
fs18.writeFileSync(manifestPath, JSON.stringify(manifest, null, 2));
|
|
49193
49486
|
registerWindowsNativeHost(platform, hostName, manifestPath);
|
|
49194
49487
|
return { hostName, manifestPath, wrapperPath };
|
|
49195
49488
|
});
|
|
@@ -49209,8 +49502,8 @@ var removeNativeHosts = (platform) => {
|
|
|
49209
49502
|
var inspectNativeHost = (platform, hostName) => {
|
|
49210
49503
|
const manifestPath = getManifestPath(platform, hostName);
|
|
49211
49504
|
const wrapperPath = getWrapperPath(platform, hostName);
|
|
49212
|
-
const manifestExists =
|
|
49213
|
-
const wrapperExists =
|
|
49505
|
+
const manifestExists = fs18.existsSync(manifestPath);
|
|
49506
|
+
const wrapperExists = fs18.existsSync(wrapperPath);
|
|
49214
49507
|
const wrapperExecutable = wrapperExists && isWrapperExecutable(wrapperPath);
|
|
49215
49508
|
const manifest = manifestExists ? readManifest(manifestPath) : null;
|
|
49216
49509
|
const manifestValid = Boolean(manifest && manifest.name === hostName && manifest.type === "stdio" && Array.isArray(manifest.allowed_origins));
|
|
@@ -49231,7 +49524,7 @@ var inspectNativeHost = (platform, hostName) => {
|
|
|
49231
49524
|
};
|
|
49232
49525
|
var readManifest = (manifestPath) => {
|
|
49233
49526
|
try {
|
|
49234
|
-
const content =
|
|
49527
|
+
const content = fs18.readFileSync(manifestPath, "utf8");
|
|
49235
49528
|
return JSON.parse(content);
|
|
49236
49529
|
} catch {
|
|
49237
49530
|
return null;
|
|
@@ -49239,7 +49532,7 @@ var readManifest = (manifestPath) => {
|
|
|
49239
49532
|
};
|
|
49240
49533
|
var isWrapperExecutable = (wrapperPath) => {
|
|
49241
49534
|
try {
|
|
49242
|
-
|
|
49535
|
+
fs18.accessSync(wrapperPath, fs18.constants.X_OK);
|
|
49243
49536
|
return true;
|
|
49244
49537
|
} catch {
|
|
49245
49538
|
return false;
|
|
@@ -49260,10 +49553,10 @@ var extractExtensionId = (origin) => {
|
|
|
49260
49553
|
return match?.[1] ?? null;
|
|
49261
49554
|
};
|
|
49262
49555
|
var removeFileIfExists = (filePath) => {
|
|
49263
|
-
if (!
|
|
49556
|
+
if (!fs18.existsSync(filePath)) {
|
|
49264
49557
|
return false;
|
|
49265
49558
|
}
|
|
49266
|
-
|
|
49559
|
+
fs18.unlinkSync(filePath);
|
|
49267
49560
|
return true;
|
|
49268
49561
|
};
|
|
49269
49562
|
var registerWindowsNativeHost = (platform, hostName, manifestPath) => {
|
|
@@ -49283,10 +49576,145 @@ var unregisterWindowsNativeHost = (platform, hostName) => {
|
|
|
49283
49576
|
} catch {}
|
|
49284
49577
|
};
|
|
49285
49578
|
|
|
49579
|
+
// dist/commands/extension/install.js
|
|
49580
|
+
var DEFAULT_TIMEOUT_SECONDS = 120;
|
|
49581
|
+
var POLL_INTERVAL_MS = 700;
|
|
49582
|
+
var runExtensionInstall = async (options) => {
|
|
49583
|
+
const output = createOutput(options);
|
|
49584
|
+
let platform;
|
|
49585
|
+
try {
|
|
49586
|
+
platform = getPlatform();
|
|
49587
|
+
} catch (error) {
|
|
49588
|
+
return fail(output, error.message);
|
|
49589
|
+
}
|
|
49590
|
+
const extensionDir = resolveExtensionDir();
|
|
49591
|
+
if (!extensionDir) {
|
|
49592
|
+
return fail(output, "Packaged Argus extension not found. Build the CLI (npm run build:packages) or run from a built checkout.");
|
|
49593
|
+
}
|
|
49594
|
+
let executablePath;
|
|
49595
|
+
try {
|
|
49596
|
+
executablePath = findArgusExecutable();
|
|
49597
|
+
} catch (error) {
|
|
49598
|
+
return fail(output, error.message);
|
|
49599
|
+
}
|
|
49600
|
+
let hosts;
|
|
49601
|
+
try {
|
|
49602
|
+
hosts = installNativeHosts(platform, ARGUS_EXTENSION_ID, executablePath);
|
|
49603
|
+
} catch (error) {
|
|
49604
|
+
return fail(output, `Failed to install native hosts: ${error.message}`);
|
|
49605
|
+
}
|
|
49606
|
+
await pruneRegistry();
|
|
49607
|
+
let connected = await isControlConnected();
|
|
49608
|
+
const shouldOpen = options.open !== false && !connected;
|
|
49609
|
+
const opened = shouldOpen ? openExtensionsPage() : false;
|
|
49610
|
+
if (!output.json) {
|
|
49611
|
+
printSummary(output, { extensionDir, hosts, connected, opened, shouldOpen });
|
|
49612
|
+
}
|
|
49613
|
+
const shouldWait = options.wait !== false && !connected;
|
|
49614
|
+
if (shouldWait) {
|
|
49615
|
+
connected = await waitForControl(parseTimeoutMs2(options.timeout), output);
|
|
49616
|
+
}
|
|
49617
|
+
if (output.json) {
|
|
49618
|
+
output.writeJson({ success: true, extensionId: ARGUS_EXTENSION_ID, extensionPath: extensionDir, hosts, connected });
|
|
49619
|
+
if (!connected && shouldWait) {
|
|
49620
|
+
process.exitCode = 1;
|
|
49621
|
+
}
|
|
49622
|
+
return;
|
|
49623
|
+
}
|
|
49624
|
+
printResult(output, connected, shouldWait);
|
|
49625
|
+
};
|
|
49626
|
+
var isControlConnected = async () => {
|
|
49627
|
+
const { registry: registry2 } = await readRegistry();
|
|
49628
|
+
return Boolean(registry2.watchers[CONTROL_WATCHER_ID]);
|
|
49629
|
+
};
|
|
49630
|
+
var openExtensionsPage = () => {
|
|
49631
|
+
const chromeBin = resolveChromeBin();
|
|
49632
|
+
if (!chromeBin) {
|
|
49633
|
+
return false;
|
|
49634
|
+
}
|
|
49635
|
+
try {
|
|
49636
|
+
const child = spawn3(chromeBin, ["chrome://extensions/"], { stdio: "ignore", detached: true });
|
|
49637
|
+
child.unref();
|
|
49638
|
+
return true;
|
|
49639
|
+
} catch {
|
|
49640
|
+
return false;
|
|
49641
|
+
}
|
|
49642
|
+
};
|
|
49643
|
+
var waitForControl = async (timeoutMs, output) => {
|
|
49644
|
+
if (!output.json) {
|
|
49645
|
+
output.writeHuman(`Waiting for the extension to connect (up to ${Math.round(timeoutMs / 1000)}s)...`);
|
|
49646
|
+
}
|
|
49647
|
+
const deadline = Date.now() + timeoutMs;
|
|
49648
|
+
while (Date.now() < deadline) {
|
|
49649
|
+
if (await isControlConnected()) {
|
|
49650
|
+
return true;
|
|
49651
|
+
}
|
|
49652
|
+
await delay7(POLL_INTERVAL_MS);
|
|
49653
|
+
}
|
|
49654
|
+
return isControlConnected();
|
|
49655
|
+
};
|
|
49656
|
+
var printSummary = (output, info) => {
|
|
49657
|
+
output.writeHuman("");
|
|
49658
|
+
output.writeHuman("Argus extension setup");
|
|
49659
|
+
output.writeHuman("");
|
|
49660
|
+
output.writeHuman(` Native hosts: installed (${info.hosts.map((host) => host.hostName).join(", ")})`);
|
|
49661
|
+
output.writeHuman(` Extension ID: ${ARGUS_EXTENSION_ID}`);
|
|
49662
|
+
output.writeHuman(` Load unpacked: ${info.extensionDir}`);
|
|
49663
|
+
output.writeHuman("");
|
|
49664
|
+
if (info.connected) {
|
|
49665
|
+
return;
|
|
49666
|
+
}
|
|
49667
|
+
if (info.opened) {
|
|
49668
|
+
output.writeHuman('Opened chrome://extensions. Click "Load unpacked" and select the folder above.');
|
|
49669
|
+
} else if (info.shouldOpen) {
|
|
49670
|
+
output.writeHuman('Open chrome://extensions, then click "Load unpacked" and select the folder above.');
|
|
49671
|
+
} else {
|
|
49672
|
+
output.writeHuman('Open chrome://extensions and "Load unpacked" the folder above.');
|
|
49673
|
+
}
|
|
49674
|
+
output.writeHuman('(Enable Developer mode if the "Load unpacked" button is hidden.)');
|
|
49675
|
+
output.writeHuman("");
|
|
49676
|
+
};
|
|
49677
|
+
var printResult = (output, connected, waited) => {
|
|
49678
|
+
if (connected) {
|
|
49679
|
+
output.writeHuman("Extension connected.");
|
|
49680
|
+
output.writeHuman("");
|
|
49681
|
+
output.writeHuman("Try it:");
|
|
49682
|
+
output.writeHuman(" argus ext tabs");
|
|
49683
|
+
output.writeHuman("");
|
|
49684
|
+
return;
|
|
49685
|
+
}
|
|
49686
|
+
if (waited) {
|
|
49687
|
+
output.writeHuman("Extension did not connect yet.");
|
|
49688
|
+
output.writeHuman(" - If it is already loaded, open its popup or reload it in chrome://extensions.");
|
|
49689
|
+
output.writeHuman(" - Then check `argus extension status` and `argus ext doctor`.");
|
|
49690
|
+
output.writeHuman("");
|
|
49691
|
+
process.exitCode = 1;
|
|
49692
|
+
return;
|
|
49693
|
+
}
|
|
49694
|
+
output.writeHuman("Once loaded, verify with `argus ext tabs`.");
|
|
49695
|
+
output.writeHuman("");
|
|
49696
|
+
};
|
|
49697
|
+
var parseTimeoutMs2 = (value) => {
|
|
49698
|
+
const seconds = value ? Number.parseInt(value, 10) : DEFAULT_TIMEOUT_SECONDS;
|
|
49699
|
+
if (!Number.isFinite(seconds) || seconds < 5) {
|
|
49700
|
+
return DEFAULT_TIMEOUT_SECONDS * 1000;
|
|
49701
|
+
}
|
|
49702
|
+
return seconds * 1000;
|
|
49703
|
+
};
|
|
49704
|
+
var fail = (output, message) => {
|
|
49705
|
+
if (output.json) {
|
|
49706
|
+
output.writeJson({ success: false, error: { message } });
|
|
49707
|
+
} else {
|
|
49708
|
+
console.error(message);
|
|
49709
|
+
}
|
|
49710
|
+
process.exitCode = 1;
|
|
49711
|
+
};
|
|
49712
|
+
var delay7 = (ms3) => new Promise((resolve2) => setTimeout(resolve2, ms3));
|
|
49713
|
+
|
|
49286
49714
|
// dist/commands/extension/setup.js
|
|
49287
49715
|
var runExtensionSetup = async (options) => {
|
|
49288
49716
|
const output = createOutput(options);
|
|
49289
|
-
const
|
|
49717
|
+
const extensionId = options.extensionId ?? ARGUS_EXTENSION_ID;
|
|
49290
49718
|
let platform;
|
|
49291
49719
|
try {
|
|
49292
49720
|
platform = getPlatform();
|
|
@@ -49342,9 +49770,11 @@ var runExtensionSetup = async (options) => {
|
|
|
49342
49770
|
}
|
|
49343
49771
|
output.writeHuman("");
|
|
49344
49772
|
output.writeHuman("Next steps:");
|
|
49345
|
-
output.writeHuman(" 1.
|
|
49773
|
+
output.writeHuman(" 1. Load the unpacked extension from `argus extension path` (if not already loaded)");
|
|
49346
49774
|
output.writeHuman(" 2. Run `argus ext tabs` or open the extension popup and attach a tab");
|
|
49347
49775
|
output.writeHuman("");
|
|
49776
|
+
output.writeHuman("Tip: `argus extension install` does this end-to-end and waits for the extension to connect.");
|
|
49777
|
+
output.writeHuman("");
|
|
49348
49778
|
}
|
|
49349
49779
|
};
|
|
49350
49780
|
|
|
@@ -49733,7 +50163,7 @@ var waitForTabWatcher = async (controlWatcher, selector, tab, watcherId) => {
|
|
|
49733
50163
|
if (watcher) {
|
|
49734
50164
|
const status = await fetchStatus(watcher);
|
|
49735
50165
|
if (!status || !statusMatchesTabWatcher(status, latestTab ?? tab, latestTab?.watcherId === explicitWatcherId)) {
|
|
49736
|
-
await
|
|
50166
|
+
await delay8(WATCHER_POLL_INTERVAL_MS);
|
|
49737
50167
|
continue;
|
|
49738
50168
|
}
|
|
49739
50169
|
return { ok: true, watcher, status, tab: latestTab ?? tab };
|
|
@@ -49743,7 +50173,7 @@ var waitForTabWatcher = async (controlWatcher, selector, tab, watcherId) => {
|
|
|
49743
50173
|
if (lastResult.ok) {
|
|
49744
50174
|
return lastResult;
|
|
49745
50175
|
}
|
|
49746
|
-
await
|
|
50176
|
+
await delay8(WATCHER_POLL_INTERVAL_MS);
|
|
49747
50177
|
}
|
|
49748
50178
|
return lastResult;
|
|
49749
50179
|
};
|
|
@@ -49797,7 +50227,7 @@ var targetMatchesTab = (target, tab) => {
|
|
|
49797
50227
|
}
|
|
49798
50228
|
return Boolean(target.title && target.title === tab.title && target.url === tab.url);
|
|
49799
50229
|
};
|
|
49800
|
-
var
|
|
50230
|
+
var delay8 = (ms3) => new Promise((resolve2) => setTimeout(resolve2, ms3));
|
|
49801
50231
|
var formatError6 = (error) => error instanceof Error ? error.message : String(error);
|
|
49802
50232
|
|
|
49803
50233
|
// dist/commands/extension/show.js
|
|
@@ -50176,19 +50606,19 @@ var waitForSelectedTarget = async (watcher, target, options = {}) => {
|
|
|
50176
50606
|
const [status, targets] = await Promise.all([fetchWatcherStatus(watcher), fetchExtensionTargets(watcher)]);
|
|
50177
50607
|
if (!status.ok) {
|
|
50178
50608
|
lastError = status.error;
|
|
50179
|
-
await
|
|
50609
|
+
await delay9(intervalMs);
|
|
50180
50610
|
continue;
|
|
50181
50611
|
}
|
|
50182
50612
|
if (!targets.ok) {
|
|
50183
50613
|
lastError = targets.error;
|
|
50184
|
-
await
|
|
50614
|
+
await delay9(intervalMs);
|
|
50185
50615
|
continue;
|
|
50186
50616
|
}
|
|
50187
50617
|
const selected = targets.targets.find((entry) => entry.id === target.id && entry.attached === true);
|
|
50188
50618
|
if (selected && statusMatchesTarget(status.status, selected) && status.status.targetReady !== false) {
|
|
50189
50619
|
return { ok: true, status: status.status, target: selected };
|
|
50190
50620
|
}
|
|
50191
|
-
await
|
|
50621
|
+
await delay9(intervalMs);
|
|
50192
50622
|
}
|
|
50193
50623
|
return { ok: false, error: lastError };
|
|
50194
50624
|
};
|
|
@@ -50334,7 +50764,7 @@ var originOf = (url) => {
|
|
|
50334
50764
|
}
|
|
50335
50765
|
};
|
|
50336
50766
|
var shortenId = (id) => id.length > 18 ? `${id.slice(0, 14)}...` : id;
|
|
50337
|
-
var
|
|
50767
|
+
var delay9 = (ms3) => new Promise((resolve2) => setTimeout(resolve2, ms3));
|
|
50338
50768
|
var formatError8 = (error) => error instanceof Error ? error.message : String(error);
|
|
50339
50769
|
|
|
50340
50770
|
// dist/commands/extension/use.js
|
|
@@ -50750,22 +51180,43 @@ var extensionCommands = [
|
|
|
50750
51180
|
description: "Browser extension management",
|
|
50751
51181
|
subcommands: [
|
|
50752
51182
|
{
|
|
50753
|
-
name: "
|
|
50754
|
-
description: "
|
|
51183
|
+
name: "install",
|
|
51184
|
+
description: "Set up the extension end-to-end: install hosts, open chrome://extensions, wait for connect",
|
|
51185
|
+
options: [
|
|
51186
|
+
{ flags: "--no-open", description: "Do not open chrome://extensions automatically" },
|
|
51187
|
+
{ flags: "--no-wait", description: "Do not wait for the extension to connect" },
|
|
51188
|
+
{ flags: "--timeout <seconds>", description: "Seconds to wait for the extension to connect (default 120)" },
|
|
51189
|
+
jsonOption2
|
|
51190
|
+
],
|
|
51191
|
+
examples: ["argus extension install", "argus extension install --no-open", "argus extension install --no-wait --json"],
|
|
51192
|
+
action: async (options) => {
|
|
51193
|
+
await runExtensionInstall(options);
|
|
51194
|
+
}
|
|
51195
|
+
},
|
|
51196
|
+
{
|
|
51197
|
+
name: "setup [extensionId]",
|
|
51198
|
+
description: "Install native messaging host (uses the pinned extension ID by default)",
|
|
50755
51199
|
options: [jsonOption2],
|
|
50756
51200
|
configure: (command) => {
|
|
50757
51201
|
command.addHelpText("after", `
|
|
50758
|
-
|
|
50759
|
-
|
|
50760
|
-
|
|
50761
|
-
3. Load argus-extension as unpacked
|
|
50762
|
-
4. Copy the ID from the extension card
|
|
51202
|
+
The Argus extension pins a stable ID, so no argument is needed.
|
|
51203
|
+
Prefer \`argus extension install\` for the guided, end-to-end flow.
|
|
51204
|
+
Pass an explicit id only when loading a differently-keyed build.
|
|
50763
51205
|
`);
|
|
50764
51206
|
},
|
|
50765
51207
|
action: async (extensionId, options) => {
|
|
50766
51208
|
await runExtensionSetup({ extensionId, ...options });
|
|
50767
51209
|
}
|
|
50768
51210
|
},
|
|
51211
|
+
{
|
|
51212
|
+
name: "path",
|
|
51213
|
+
description: 'Print the path to the unpacked extension for chrome://extensions "Load unpacked"',
|
|
51214
|
+
options: [jsonOption2],
|
|
51215
|
+
examples: ["argus extension path", "argus extension path --json"],
|
|
51216
|
+
action: (options) => {
|
|
51217
|
+
runExtensionPath(options);
|
|
51218
|
+
}
|
|
51219
|
+
},
|
|
50769
51220
|
{
|
|
50770
51221
|
name: "remove",
|
|
50771
51222
|
description: "Uninstall native messaging host",
|
|
@@ -50923,9 +51374,9 @@ same sticky shown+focused lock as \`argus page show <watcherId>\`.
|
|
|
50923
51374
|
];
|
|
50924
51375
|
|
|
50925
51376
|
// dist/commands/skill.js
|
|
50926
|
-
import
|
|
50927
|
-
import
|
|
50928
|
-
import { fileURLToPath as
|
|
51377
|
+
import fs19 from "node:fs";
|
|
51378
|
+
import path24 from "node:path";
|
|
51379
|
+
import { fileURLToPath as fileURLToPath3 } from "node:url";
|
|
50929
51380
|
var SKILL_PATH_PARTS = ["skill", "argus", "SKILL.md"];
|
|
50930
51381
|
var runSkill = (options) => {
|
|
50931
51382
|
const output = createOutput(options);
|
|
@@ -50950,18 +51401,18 @@ ${resolveArgusSkillCandidates().join(`
|
|
|
50950
51401
|
};
|
|
50951
51402
|
var resolveArgusSkillPath = () => {
|
|
50952
51403
|
for (const candidate of resolveArgusSkillCandidates()) {
|
|
50953
|
-
if (
|
|
51404
|
+
if (fs19.existsSync(candidate)) {
|
|
50954
51405
|
return candidate;
|
|
50955
51406
|
}
|
|
50956
51407
|
}
|
|
50957
51408
|
return null;
|
|
50958
51409
|
};
|
|
50959
51410
|
var resolveArgusSkillCandidates = () => {
|
|
50960
|
-
const moduleDir =
|
|
51411
|
+
const moduleDir = path24.dirname(fileURLToPath3(import.meta.url));
|
|
50961
51412
|
return [
|
|
50962
|
-
|
|
50963
|
-
|
|
50964
|
-
|
|
51413
|
+
path24.resolve(moduleDir, ...SKILL_PATH_PARTS),
|
|
51414
|
+
path24.resolve(moduleDir, "..", ...SKILL_PATH_PARTS),
|
|
51415
|
+
path24.resolve(moduleDir, "..", "..", "..", "..", ...SKILL_PATH_PARTS)
|
|
50965
51416
|
];
|
|
50966
51417
|
};
|
|
50967
51418
|
|