pi-agent-browser-native 0.5.0 → 0.6.6
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/CHANGELOG.md +144 -0
- package/README.md +75 -42
- package/dist/extensions/agent-browser/index.js +13 -83
- package/dist/extensions/agent-browser/lib/argv-grammar.js +8 -2
- package/dist/extensions/agent-browser/lib/batch-lifecycle.js +1 -1
- package/dist/extensions/agent-browser/lib/command-policy.js +4 -7
- package/dist/extensions/agent-browser/lib/command-taxonomy.js +19 -11
- package/dist/extensions/agent-browser/lib/config-policy.js +25 -1
- package/dist/extensions/agent-browser/lib/config.js +1 -1
- package/dist/extensions/agent-browser/lib/input-modes/job.js +0 -9
- package/dist/extensions/agent-browser/lib/input-modes/params.js +1 -1
- package/dist/extensions/agent-browser/lib/launch-scoped-flags.js +18 -4
- package/dist/extensions/agent-browser/lib/managed-session-policy-lock.js +3 -138
- package/dist/extensions/agent-browser/lib/managed-session-restore.js +1 -81
- package/dist/extensions/agent-browser/lib/managed-session-storage.js +4 -1
- package/dist/extensions/agent-browser/lib/orchestration/browser-run/diagnostics.js +31 -26
- package/dist/extensions/agent-browser/lib/orchestration/browser-run/final-result.js +60 -8
- package/dist/extensions/agent-browser/lib/orchestration/browser-run/managed-session-daemon-policy.js +1 -4
- package/dist/extensions/agent-browser/lib/orchestration/browser-run/prepare/snapshot-filter.js +119 -2
- package/dist/extensions/agent-browser/lib/orchestration/browser-run/prepare/wait-timeouts.js +7 -6
- package/dist/extensions/agent-browser/lib/orchestration/browser-run/prepare.js +31 -40
- package/dist/extensions/agent-browser/lib/orchestration/browser-run/process-output.js +76 -70
- package/dist/extensions/agent-browser/lib/orchestration/browser-run/session-state.js +6 -8
- package/dist/extensions/agent-browser/lib/orchestration/electron-host/index.js +5 -10
- package/dist/extensions/agent-browser/lib/orchestration/output-file.js +41 -21
- package/dist/extensions/agent-browser/lib/page-target-validation.js +270 -0
- package/dist/extensions/agent-browser/lib/playbook.js +13 -12
- package/dist/extensions/agent-browser/lib/process-identity.js +11 -10
- package/dist/extensions/agent-browser/lib/process.js +18 -82
- package/dist/extensions/agent-browser/lib/recording-reservations.js +11 -78
- package/dist/extensions/agent-browser/lib/results/action-recommendations.js +1 -1
- package/dist/extensions/agent-browser/lib/results/presentation/batch.js +27 -14
- package/dist/extensions/agent-browser/lib/results/presentation/common.js +20 -2
- package/dist/extensions/agent-browser/lib/results/presentation/diagnostics.js +11 -16
- package/dist/extensions/agent-browser/lib/results/presentation/navigation.js +12 -9
- package/dist/extensions/agent-browser/lib/results/presentation/registry.js +2 -2
- package/dist/extensions/agent-browser/lib/results/presentation.js +31 -4
- package/dist/extensions/agent-browser/lib/results/recovery-actions.js +1 -1
- package/dist/extensions/agent-browser/lib/results/recovery-next-actions.js +9 -0
- package/dist/extensions/agent-browser/lib/results/selector-recovery.js +3 -3
- package/dist/extensions/agent-browser/lib/results/snapshot-spill.js +2 -1
- package/dist/extensions/agent-browser/lib/results/snapshot.js +4 -4
- package/dist/extensions/agent-browser/lib/runtime.js +73 -72
- package/dist/extensions/agent-browser/lib/session-page-state.js +12 -3
- package/dist/extensions/agent-browser/lib/temp.js +1 -2
- package/dist/extensions/agent-browser/lib/upstream-version.js +5 -5
- package/dist/extensions/agent-browser/lib/web-search.js +108 -24
- package/dist/scripts/agent-browser-target.mjs +19 -1
- package/docs/ARCHITECTURE.md +24 -20
- package/docs/COMMAND_REFERENCE.md +181 -49
- package/docs/ELECTRON.md +2 -2
- package/docs/RELEASE.md +10 -8
- package/docs/REQUIREMENTS.md +8 -7
- package/docs/SUPPORT_MATRIX.md +31 -26
- package/docs/TOOL_CONTRACT.md +89 -56
- package/package.json +1 -1
- package/scripts/agent-browser-capability-baseline.mjs +65 -5
- package/scripts/agent-browser-target.mjs +19 -1
- package/scripts/config.mjs +1 -0
- package/scripts/doctor.mjs +15 -9
- package/dist/extensions/agent-browser/lib/managed-session-capabilities.js +0 -20
- package/dist/extensions/agent-browser/lib/managed-session-state-policy.js +0 -601
- package/dist/extensions/agent-browser/lib/navigation-policy.js +0 -78
- package/dist/extensions/agent-browser/lib/results/presentation/managed-list-filter.js +0 -37
|
@@ -9,25 +9,24 @@ import { canUseHeadlessCompatibilityUserAgent, createEphemeralSessionSeed, creat
|
|
|
9
9
|
import { extractExplicitNamespace, extractExplicitSessionName, getAgentBrowserSessionIdentityKey, isAgentBrowserSessionIdentityKeyInNamespace, isUpstreamEnvFlagEnabled, resolveAgentBrowserNamespace } from "./lib/argv-grammar.js";
|
|
10
10
|
import { parseArgvDescriptor } from "./lib/argv-descriptor.js";
|
|
11
11
|
import { needsManagedSession } from "./lib/command-policy.js";
|
|
12
|
-
import {
|
|
12
|
+
import { ManagedSessionRestoreState } from "./lib/managed-session-restore.js";
|
|
13
13
|
import { isRecord } from "./lib/parsing.js";
|
|
14
14
|
import { runAgentBrowserProcess } from "./lib/process.js";
|
|
15
15
|
import { getAgentBrowserProcessEnvironment, withIsolatedAgentBrowserEnvironment } from "./lib/process-environment.js";
|
|
16
|
-
import {
|
|
16
|
+
import { MINIMUM_AGENT_BROWSER_VERSION, SUPPORTED_AGENT_BROWSER_VERSION_LABEL, TARGET_AGENT_BROWSER_VERSION, getAgentBrowserVersionValidationError, parseAgentBrowserVersionOutput, } from "./lib/upstream-version.js";
|
|
17
17
|
import { buildPromptPolicy, getLatestUserPrompt, shouldAppendBrowserSystemPrompt } from "./lib/prompt-policy.js";
|
|
18
18
|
import { isCloseAllCommand, isCloseCommand } from "./lib/command-taxonomy.js";
|
|
19
19
|
import { hasLaunchScopedFlagToken } from "./lib/launch-scoped-flags.js";
|
|
20
20
|
import { cleanupSecureTempArtifacts } from "./lib/temp.js";
|
|
21
21
|
import { AGENT_BROWSER_PARAMS } from "./lib/input-modes/params.js";
|
|
22
22
|
import { AGENT_BROWSER_SCRIPT_DEFAULT_TIMEOUT_MS, AGENT_BROWSER_SCRIPT_NAMESPACE, createAgentBrowserScriptSessionName, isAgentBrowserScriptSessionName, runAgentBrowserScript, } from "./lib/input-modes/script.js";
|
|
23
|
-
import { parseAllowedDomainsPolicyFromArgs } from "./lib/navigation-policy.js";
|
|
24
23
|
import { closeManagedSession, getSessionContextKey, runAgentBrowserTool } from "./lib/orchestration/browser-run/index.js";
|
|
25
24
|
import { canonicalizeExplicitArtifactDestination, getExplicitArtifactDestination } from "./lib/orchestration/browser-run/artifact-paths.js";
|
|
26
25
|
import { findElectronLaunchRecordForSession, getActiveElectronRecords } from "./lib/orchestration/browser-run/session-state.js";
|
|
27
26
|
import { parseBatchCommandArgument, parseUserBatchStdin } from "./lib/orchestration/batch-stdin.js";
|
|
28
27
|
import { ELECTRON_POST_COMMAND_STATUS_SETTLE_MS, ELECTRON_PROFILE_ISOLATION_DETAILS, cleanupActiveElectronHostLaunches, handleElectronHostInput, restoreElectronLaunchRecordsFromBranch, } from "./lib/orchestration/electron-host/index.js";
|
|
29
28
|
import { buildValidationFailureResult, resolveAgentBrowserInput } from "./lib/orchestration/input-plan.js";
|
|
30
|
-
import { applyAgentBrowserOutputPath,
|
|
29
|
+
import { applyAgentBrowserOutputPath, normalizeRequestedOutputPath } from "./lib/orchestration/output-file.js";
|
|
31
30
|
import { appendScriptSessionLease, buildScriptBrowserEnvelope, buildScriptToolResult, getScriptSessionLeasesFromBranch } from "./lib/orchestration/script-mode.js";
|
|
32
31
|
import { formatSessionArtifactRetentionSummary, getSessionArtifactManifestEntryKey, isPendingRecordingCommand, isSessionArtifactManifest, mergeSessionArtifactManifest, retirePendingRecordingManifestEntries } from "./lib/results/artifact-manifest.js";
|
|
33
32
|
import { appendUniqueAgentBrowserNextActions, applyNamespaceToNextActions, applySessionToNextActions, buildNextToolAction } from "./lib/results/next-actions.js";
|
|
@@ -97,7 +96,7 @@ function getArtifactPreflightValidationError(options) {
|
|
|
97
96
|
for (const [index, step] of steps.entries()) {
|
|
98
97
|
const commandStep = extractUpstreamCommandTokens(step);
|
|
99
98
|
if (batch) {
|
|
100
|
-
const stepValidationError = validateToolArgs(step);
|
|
99
|
+
const stepValidationError = validateToolArgs(step, { batchStep: true });
|
|
101
100
|
if (stepValidationError)
|
|
102
101
|
return `Unsupported batch step ${index + 1}: ${stepValidationError}`;
|
|
103
102
|
if (sawBatchClose && commandStep[0] === "record" && (commandStep[1] === "start" || commandStep[1] === "restart")) {
|
|
@@ -359,65 +358,6 @@ function restoreAttachedSessionKeysFromBranch(branch) {
|
|
|
359
358
|
}
|
|
360
359
|
return attachedSessionKeys;
|
|
361
360
|
}
|
|
362
|
-
function restoreAllowedDomainsBySessionFromBranch(branch) {
|
|
363
|
-
const restoredPolicies = new Map();
|
|
364
|
-
for (const entry of branch) {
|
|
365
|
-
if (!isRecord(entry) || entry.type !== "message")
|
|
366
|
-
continue;
|
|
367
|
-
const message = isRecord(entry.message) ? entry.message : undefined;
|
|
368
|
-
if (!message || message.toolName !== "agent_browser")
|
|
369
|
-
continue;
|
|
370
|
-
const details = isRecord(message.details) ? message.details : undefined;
|
|
371
|
-
if (!details)
|
|
372
|
-
continue;
|
|
373
|
-
const succeeded = getSuccessfulToolResult(details, message);
|
|
374
|
-
const batchCloseLifecycle = getSuccessfulBatchCloseLifecycle(details.batchSteps);
|
|
375
|
-
const args = getToolResultArgs(details);
|
|
376
|
-
const command = typeof details.command === "string" ? details.command : extractUpstreamCommandTokens(args)[0];
|
|
377
|
-
const sessionName = typeof details.sessionName === "string" ? details.sessionName : undefined;
|
|
378
|
-
const namespace = typeof details.namespace === "string" ? details.namespace : undefined;
|
|
379
|
-
const sessionKey = getSessionContextKey(sessionName, namespace);
|
|
380
|
-
const explicitSessionName = extractExplicitSessionName(args);
|
|
381
|
-
if (detailsReportCloseAllApplied(details, succeeded))
|
|
382
|
-
deleteIdentityKeysInNamespace(restoredPolicies, namespace);
|
|
383
|
-
const outcome = getManagedSessionOutcome(details);
|
|
384
|
-
const outcomeSucceeded = outcome?.succeeded === true;
|
|
385
|
-
const outcomeStatus = typeof outcome?.status === "string" ? outcome.status : undefined;
|
|
386
|
-
const outcomeCurrentSessionName = typeof outcome?.currentSessionName === "string" ? outcome.currentSessionName : undefined;
|
|
387
|
-
const outcomeAttemptedSessionName = typeof outcome?.attemptedSessionName === "string" ? outcome.attemptedSessionName : undefined;
|
|
388
|
-
if (outcomeSucceeded && outcomeStatus === "closed") {
|
|
389
|
-
const closedSessionName = outcomeAttemptedSessionName ?? outcomeCurrentSessionName ?? sessionName;
|
|
390
|
-
if (closedSessionName)
|
|
391
|
-
restoredPolicies.delete(getSessionContextKey(closedSessionName, namespace) ?? closedSessionName);
|
|
392
|
-
}
|
|
393
|
-
if (outcomeSucceeded && outcomeStatus === "replaced") {
|
|
394
|
-
const replacedSessionName = typeof outcome.replacedSessionName === "string" ? outcome.replacedSessionName : undefined;
|
|
395
|
-
const replacedSessionNamespace = typeof outcome.replacedSessionNamespace === "string" ? outcome.replacedSessionNamespace : namespace;
|
|
396
|
-
if (replacedSessionName)
|
|
397
|
-
restoredPolicies.delete(getSessionContextKey(replacedSessionName, replacedSessionNamespace) ?? replacedSessionName);
|
|
398
|
-
}
|
|
399
|
-
if ((succeeded && isCloseCommand(command)) || batchCloseLifecycle) {
|
|
400
|
-
const closedSessionName = explicitSessionName ?? sessionName ?? outcomeAttemptedSessionName ?? outcomeCurrentSessionName;
|
|
401
|
-
if (closedSessionName)
|
|
402
|
-
restoredPolicies.delete(getSessionContextKey(closedSessionName, namespace) ?? closedSessionName);
|
|
403
|
-
}
|
|
404
|
-
const electron = isRecord(details.electron) ? details.electron : undefined;
|
|
405
|
-
const cleanup = isRecord(electron?.cleanup) ? electron.cleanup : undefined;
|
|
406
|
-
const cleanupResults = Array.isArray(cleanup?.results) ? cleanup.results : [];
|
|
407
|
-
for (const cleanupResult of cleanupResults) {
|
|
408
|
-
for (const identity of getCleanupResultClosedManagedSessionIdentities(cleanupResult, namespace)) {
|
|
409
|
-
restoredPolicies.delete(getSessionContextKey(identity.sessionName, identity.namespace) ?? identity.sessionName);
|
|
410
|
-
}
|
|
411
|
-
}
|
|
412
|
-
const outcomeKeepsSessionCurrent = outcome?.activeAfter === true
|
|
413
|
-
&& (outcomeStatus === "created" || outcomeStatus === "replaced" || outcomeStatus === "unchanged")
|
|
414
|
-
&& outcomeCurrentSessionName === sessionName;
|
|
415
|
-
const policy = (succeeded || outcomeKeepsSessionCurrent) && sessionKey && !isCloseCommand(command) && batchCloseLifecycle?.endsClosed !== true ? parseAllowedDomainsPolicyFromArgs(args) : undefined;
|
|
416
|
-
if (policy && sessionKey)
|
|
417
|
-
restoredPolicies.set(sessionKey, policy);
|
|
418
|
-
}
|
|
419
|
-
return restoredPolicies;
|
|
420
|
-
}
|
|
421
361
|
function trackOwnedManagedSession(sessions, sessionName, cwd, options = {}) {
|
|
422
362
|
if (!sessionName)
|
|
423
363
|
return;
|
|
@@ -905,7 +845,6 @@ export default function agentBrowserExtension(pi) {
|
|
|
905
845
|
let activeRecordingReservations = new Map();
|
|
906
846
|
let recordingSessionTombstones = new Map();
|
|
907
847
|
let recordingSessionTombstonesToPersist = new Map();
|
|
908
|
-
let allowedDomainsBySession = new Map();
|
|
909
848
|
let attachedSessionKeys = new Set();
|
|
910
849
|
let networkRoutesBySession = new Map();
|
|
911
850
|
let electronLaunchRecords = new Map();
|
|
@@ -1064,15 +1003,14 @@ export default function agentBrowserExtension(pi) {
|
|
|
1064
1003
|
failureCategory: "validation-error",
|
|
1065
1004
|
observedVersion,
|
|
1066
1005
|
resultCategory: "failure",
|
|
1067
|
-
|
|
1006
|
+
minimumSupportedVersion: MINIMUM_AGENT_BROWSER_VERSION,
|
|
1007
|
+
versionValidation: { expected: SUPPORTED_AGENT_BROWSER_VERSION_LABEL, observed: observedVersion },
|
|
1068
1008
|
},
|
|
1069
1009
|
isError: true,
|
|
1070
1010
|
};
|
|
1071
1011
|
};
|
|
1072
1012
|
const clearSessionScopedBrowserState = (sessionName, namespace) => {
|
|
1073
1013
|
const key = getSessionContextKey(sessionName, namespace) ?? sessionName;
|
|
1074
|
-
allowedDomainsBySession = new Map(allowedDomainsBySession);
|
|
1075
|
-
allowedDomainsBySession.delete(key);
|
|
1076
1014
|
attachedSessionKeys.delete(key);
|
|
1077
1015
|
networkRoutesBySession = new Map(networkRoutesBySession);
|
|
1078
1016
|
networkRoutesBySession.delete(key);
|
|
@@ -1184,7 +1122,6 @@ export default function agentBrowserExtension(pi) {
|
|
|
1184
1122
|
for (const [key, reservation] of activeRecordingReservations)
|
|
1185
1123
|
restoredRecordingState.active.set(key, reservation);
|
|
1186
1124
|
activeRecordingReservations = restoredRecordingState.active;
|
|
1187
|
-
allowedDomainsBySession = restoreAllowedDomainsBySessionFromBranch(branch);
|
|
1188
1125
|
attachedSessionKeys = restoreAttachedSessionKeysFromBranch(branch);
|
|
1189
1126
|
networkRoutesBySession = new Map();
|
|
1190
1127
|
electronLaunchRecords = restoreElectronLaunchRecordsFromBranch(branch);
|
|
@@ -1350,7 +1287,6 @@ export default function agentBrowserExtension(pi) {
|
|
|
1350
1287
|
activeRecordingReservations = new Map();
|
|
1351
1288
|
recordingSessionTombstones = new Map();
|
|
1352
1289
|
recordingSessionTombstonesToPersist = new Map();
|
|
1353
|
-
allowedDomainsBySession = new Map();
|
|
1354
1290
|
attachedSessionKeys = new Set();
|
|
1355
1291
|
networkRoutesBySession = new Map();
|
|
1356
1292
|
electronLaunchRecords = new Map();
|
|
@@ -1358,7 +1294,6 @@ export default function agentBrowserExtension(pi) {
|
|
|
1358
1294
|
branchOwnedElectronLaunchIds = new Set();
|
|
1359
1295
|
electronChildProcesses = new Map();
|
|
1360
1296
|
ownedManagedSessions.clear();
|
|
1361
|
-
cleanupManagedSessionRestoreConfig();
|
|
1362
1297
|
await cleanupSecureTempArtifacts({ preservePaths: preservedElectronProfileDirs });
|
|
1363
1298
|
});
|
|
1364
1299
|
pi.on("before_agent_start", async (event, ctx) => {
|
|
@@ -1401,7 +1336,7 @@ export default function agentBrowserExtension(pi) {
|
|
|
1401
1336
|
const agentBrowserTool = {
|
|
1402
1337
|
name: "agent_browser",
|
|
1403
1338
|
label: "Agent Browser",
|
|
1404
|
-
description: "Browse and interact with websites using agent-browser. Use this for
|
|
1339
|
+
description: "Browse and interact with websites using agent-browser. Use this for reading live pages, opening known URLs, taking snapshots or screenshots, clicking links, filling forms, extracting page content, and authenticated/profile-based browser work. Input choice: `script` for one-shot JavaScript orchestration; default `args` for open → snapshot -i → click/fill @refs; `semanticAction` for stable role/text/label targets; `job` or `qa` for multi-step checks; `electron` only for desktop apps; experimental `sourceLookup` / `networkSourceLookup` for candidates only.",
|
|
1405
1340
|
promptSnippet: "Browse websites, read live docs, click and fill pages, extract browser content, take screenshots, and automate real web workflows.",
|
|
1406
1341
|
promptGuidelines: toolPromptGuidelines,
|
|
1407
1342
|
parameters: AGENT_BROWSER_PARAMS,
|
|
@@ -1428,10 +1363,6 @@ export default function agentBrowserExtension(pi) {
|
|
|
1428
1363
|
if (resolvedInput.status === "invalid") {
|
|
1429
1364
|
return buildValidationFailureResult(resolvedInput);
|
|
1430
1365
|
}
|
|
1431
|
-
const outputPathValidationError = getAgentBrowserOutputPathValidationError(outputPath, ctx.cwd);
|
|
1432
|
-
if (outputPathValidationError) {
|
|
1433
|
-
return buildValidationFailureResult({ attemptedKind: resolvedInput.kind, kind: "invalid", redactedArgs: resolvedInput.redactedArgs, status: "invalid", toolArgs: resolvedInput.toolArgs, toolStdin: resolvedInput.toolStdin, validationError: outputPathValidationError });
|
|
1434
|
-
}
|
|
1435
1366
|
const applyUnserializedOutputPath = async (result, preserveTextContent = false) => {
|
|
1436
1367
|
if (!outputPath || result.isError === true || (isRecord(result.details) && result.details.resultCategory === "failure"))
|
|
1437
1368
|
return result;
|
|
@@ -1451,10 +1382,8 @@ export default function agentBrowserExtension(pi) {
|
|
|
1451
1382
|
const versionCheckCommand = extractUpstreamCommandTokens(resolvedInput.toolArgs)[0];
|
|
1452
1383
|
const electronHostOnlyAction = resolvedInput.kind === "electron" && ["cleanup", "list", "status"].includes(resolvedInput.compiledElectron.action);
|
|
1453
1384
|
const browserBackedVersionCheck = needsManagedSession(parseArgvDescriptor(resolvedInput.toolArgs));
|
|
1454
|
-
if (!electronHostOnlyAction && browserBackedVersionCheck && !isPlainTextInspectionArgs(resolvedInput.toolArgs) && !isCloseCommand(versionCheckCommand) && signal?.aborted !== true) {
|
|
1455
|
-
const versionFailure =
|
|
1456
|
-
? await withIsolatedAgentBrowserEnvironment(() => validateUpstreamVersion(ctx.cwd, signal))
|
|
1457
|
-
: await validateUpstreamVersion(ctx.cwd, signal);
|
|
1385
|
+
if (resolvedInput.kind !== "script" && !electronHostOnlyAction && browserBackedVersionCheck && !isPlainTextInspectionArgs(resolvedInput.toolArgs) && !isCloseCommand(versionCheckCommand) && signal?.aborted !== true) {
|
|
1386
|
+
const versionFailure = await validateUpstreamVersion(ctx.cwd, signal);
|
|
1458
1387
|
if (versionFailure)
|
|
1459
1388
|
return applyAgentBrowserOutputPath({ cwd: ctx.cwd, outputPath, result: versionFailure });
|
|
1460
1389
|
}
|
|
@@ -1496,6 +1425,10 @@ export default function agentBrowserExtension(pi) {
|
|
|
1496
1425
|
});
|
|
1497
1426
|
activeScriptExecutions.add(scriptExecution);
|
|
1498
1427
|
try {
|
|
1428
|
+
// Keep preflight inside shutdown tracking so quit cannot race into starting the sandbox afterward.
|
|
1429
|
+
const versionFailure = await withIsolatedAgentBrowserEnvironment(() => validateUpstreamVersion(ctx.cwd, scriptController.signal));
|
|
1430
|
+
if (versionFailure)
|
|
1431
|
+
return applyAgentBrowserOutputPath({ cwd: ctx.cwd, outputPath, result: versionFailure });
|
|
1499
1432
|
const pendingRun = runAgentBrowserScript({
|
|
1500
1433
|
beforeFirstCall() {
|
|
1501
1434
|
appendScriptSessionLease(pi, sessionName, "active");
|
|
@@ -1666,7 +1599,6 @@ export default function agentBrowserExtension(pi) {
|
|
|
1666
1599
|
const generationAtStart = branchStateGeneration;
|
|
1667
1600
|
const sessionPageStateUpdate = sessionPageState.beginUpdate();
|
|
1668
1601
|
const browserRunState = {
|
|
1669
|
-
allowedDomainsBySession,
|
|
1670
1602
|
artifactManifest,
|
|
1671
1603
|
attachedSessionKeys,
|
|
1672
1604
|
closedManagedSessionNames: new Set(),
|
|
@@ -1688,7 +1620,6 @@ export default function agentBrowserExtension(pi) {
|
|
|
1688
1620
|
sessionPageState,
|
|
1689
1621
|
traceOwners,
|
|
1690
1622
|
};
|
|
1691
|
-
const initialAllowedDomainsBySession = browserRunState.allowedDomainsBySession;
|
|
1692
1623
|
const initialArtifactManifest = browserRunState.artifactManifest;
|
|
1693
1624
|
const initialNetworkRoutesBySession = browserRunState.networkRoutesBySession;
|
|
1694
1625
|
const attachedSessionRequested = isAttachedBrowserInvocation(toolArgs)
|
|
@@ -1748,7 +1679,6 @@ export default function agentBrowserExtension(pi) {
|
|
|
1748
1679
|
}
|
|
1749
1680
|
}
|
|
1750
1681
|
if (branchRestoreStillCurrent) {
|
|
1751
|
-
allowedDomainsBySession = mergeBrowserRunMap(allowedDomainsBySession, initialAllowedDomainsBySession, browserRunState.allowedDomainsBySession);
|
|
1752
1682
|
networkRoutesBySession = mergeBrowserRunMap(networkRoutesBySession, initialNetworkRoutesBySession, browserRunState.networkRoutesBySession);
|
|
1753
1683
|
artifactManifest = mergeBrowserRunArtifactManifest(artifactManifest, initialArtifactManifest, browserRunState.artifactManifest);
|
|
1754
1684
|
const handledBatchCloseKeys = syncRecordingReservationsFromResult(result);
|
|
@@ -12,6 +12,7 @@ export const GLOBAL_VALUE_FLAGS = [
|
|
|
12
12
|
"--restore-check-fn",
|
|
13
13
|
"--proxy",
|
|
14
14
|
"--proxy-bypass",
|
|
15
|
+
"--ca-cert",
|
|
15
16
|
"--headers",
|
|
16
17
|
"--executable-path",
|
|
17
18
|
"--extension",
|
|
@@ -37,6 +38,7 @@ export const GLOBAL_VALUE_FLAGS = [
|
|
|
37
38
|
"--idle-timeout",
|
|
38
39
|
];
|
|
39
40
|
export const COMMAND_VALUE_FLAGS = [
|
|
41
|
+
"--allowed-origins",
|
|
40
42
|
"--baseline",
|
|
41
43
|
"--body",
|
|
42
44
|
"--categories",
|
|
@@ -47,6 +49,7 @@ export const COMMAND_VALUE_FLAGS = [
|
|
|
47
49
|
"--domain",
|
|
48
50
|
"--expires",
|
|
49
51
|
"--filter",
|
|
52
|
+
"--frame",
|
|
50
53
|
"--fn",
|
|
51
54
|
"--label",
|
|
52
55
|
"--load",
|
|
@@ -57,6 +60,7 @@ export const COMMAND_VALUE_FLAGS = [
|
|
|
57
60
|
"--prefix",
|
|
58
61
|
"--path",
|
|
59
62
|
"--port",
|
|
63
|
+
"--params",
|
|
60
64
|
"--resource-type",
|
|
61
65
|
"--resource-types",
|
|
62
66
|
"--sameSite",
|
|
@@ -90,7 +94,9 @@ export const GLOBAL_BOOLEAN_FLAGS_WITH_OPTIONAL_VALUES = new Set([
|
|
|
90
94
|
"--ignore-https-errors",
|
|
91
95
|
"--json",
|
|
92
96
|
"--no-auto-dialog",
|
|
97
|
+
"--no-ca-cert",
|
|
93
98
|
"--no-pin-tab",
|
|
99
|
+
"--no-webmcp",
|
|
94
100
|
"--offline",
|
|
95
101
|
"--pin-tab",
|
|
96
102
|
"--quick",
|
|
@@ -169,7 +175,7 @@ export function isAgentBrowserSessionIdentityKeyInNamespace(identityKey, namespa
|
|
|
169
175
|
const prefix = getAgentBrowserSessionIdentityKey("", namespace);
|
|
170
176
|
return prefix ? identityKey.startsWith(prefix) : !identityKey.includes("\0");
|
|
171
177
|
}
|
|
172
|
-
/** Mirror upstream
|
|
178
|
+
/** Mirror upstream global parsing: full argv, no `--` sentinel, and only global value payloads are skipped. */
|
|
173
179
|
export function scanUpstreamGlobalFlagOccurrences(args, targetFlag) {
|
|
174
180
|
const occurrences = [];
|
|
175
181
|
for (let index = 0; index < args.length; index += 1) {
|
|
@@ -295,7 +301,7 @@ export function projectUpstreamGlobalFlags(args) {
|
|
|
295
301
|
}
|
|
296
302
|
return { indices, tokens };
|
|
297
303
|
}
|
|
298
|
-
/** Mirror upstream
|
|
304
|
+
/** Mirror upstream clean_args: remove global flags wherever they appear before command parsing. */
|
|
299
305
|
export function stripUpstreamGlobalFlags(args) {
|
|
300
306
|
return projectUpstreamGlobalFlags(args).tokens;
|
|
301
307
|
}
|
|
@@ -53,7 +53,7 @@ export function getSuccessfulBatchCloseLifecycle(rows, fallbackCommands = []) {
|
|
|
53
53
|
statePath = typeof result?.statePath === "string" ? result.statePath : undefined;
|
|
54
54
|
}
|
|
55
55
|
else if (sawClose && command === "record") {
|
|
56
|
-
if (browserLaunched
|
|
56
|
+
if (browserLaunched !== false) {
|
|
57
57
|
endsClosed = false;
|
|
58
58
|
browserActiveAfterClose = true;
|
|
59
59
|
}
|
|
@@ -5,8 +5,7 @@ const EMPTY_BOOLEAN_FLAGS = new Set();
|
|
|
5
5
|
const JSON_BOOLEAN_FLAGS = new Set(["--json"]);
|
|
6
6
|
const AUTH_SAVE_BOOLEAN_FLAGS = new Set(["--json", "--password-stdin"]);
|
|
7
7
|
const AUTH_SAVE_VALUE_FLAGS = new Set(["--password", "--password-selector", "--submit-selector", "--url", "--username", "--username-selector"]);
|
|
8
|
-
const
|
|
9
|
-
const DASHBOARD_START_VALUE_FLAGS = new Set(["--port"]);
|
|
8
|
+
const DASHBOARD_VALUE_FLAGS = new Set(["--allowed-origins", "--port"]);
|
|
10
9
|
const DOCTOR_BOOLEAN_FLAGS = new Set(["--fix", "--headed", "--json", "--offline", "--quick", "--webgpu"]);
|
|
11
10
|
const INSTALL_BOOLEAN_FLAGS = new Set(["--with-deps", "-d"]);
|
|
12
11
|
const STATE_SESSIONLESS_SUBCOMMANDS = new Set(["list", "show", "clear", "clean", "rename"]);
|
|
@@ -26,11 +25,9 @@ function isSessionlessAuthCommand(commandTokens) {
|
|
|
26
25
|
}
|
|
27
26
|
function isSessionlessDashboardCommand(commandTokens) {
|
|
28
27
|
const [, subcommand, ...rest] = commandTokens;
|
|
29
|
-
if (subcommand ===
|
|
30
|
-
return
|
|
31
|
-
|
|
32
|
-
return false;
|
|
33
|
-
return subcommand === "start" ? hasOnlyOptionFlags(rest, JSON_BOOLEAN_FLAGS, DASHBOARD_START_VALUE_FLAGS) : rest.length === 0;
|
|
28
|
+
if (subcommand === "stop")
|
|
29
|
+
return rest.length === 0;
|
|
30
|
+
return hasOnlyOptionFlags(subcommand === "start" ? rest : commandTokens.slice(1), JSON_BOOLEAN_FLAGS, DASHBOARD_VALUE_FLAGS);
|
|
34
31
|
}
|
|
35
32
|
function isSessionlessStateCommand(commandTokens) {
|
|
36
33
|
const [, subcommand, firstArg, secondArg, ...rest] = commandTokens;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
const ADDITIONAL_COMMAND_TOKENS = [
|
|
2
|
-
"a11y", "auth", "chat", "clipboard", "confirm", "connect", "dashboard", "deny", "device", "dialog", "diff", "doctor", "errors", "eval", "find", "frame", "get", "highlight", "inspect", "install", "is", "mcp", "plugin", "plugins", "profiles", "profiler", "react", "record", "removeinitscript", "session", "set", "skills", "snapshot", "state", "stream", "trace", "upgrade", "vitals", "wait", "web-vitals", "window",
|
|
2
|
+
"a11y", "auth", "chat", "clipboard", "confirm", "connect", "dashboard", "deny", "device", "dialog", "diff", "doctor", "errors", "eval", "find", "frame", "get", "highlight", "inspect", "install", "is", "mcp", "plugin", "plugins", "profiles", "profiler", "react", "record", "removeinitscript", "session", "set", "skills", "snapshot", "state", "stream", "trace", "upgrade", "vitals", "wait", "web-vitals", "webmcp", "window",
|
|
3
3
|
];
|
|
4
|
+
const WEBMCP_PAGE_MUTATION_SUBCOMMANDS = new Set(["invoke", "result", "cancel"]);
|
|
4
5
|
const COMMAND_CAPABILITIES = [
|
|
5
6
|
{
|
|
6
7
|
command: "back",
|
|
@@ -309,8 +310,8 @@ export function isCloseAllCommand(commandTokens) {
|
|
|
309
310
|
export function isOpenNavigationCommand(command) {
|
|
310
311
|
return hasCommandCapability(command, "openNavigation");
|
|
311
312
|
}
|
|
312
|
-
export function isReadOnlyDiagnosticSessionTargetCommand(command,
|
|
313
|
-
return hasCommandCapability(command, "readOnlyDiagnosticSessionTarget");
|
|
313
|
+
export function isReadOnlyDiagnosticSessionTargetCommand(command, subcommand) {
|
|
314
|
+
return hasCommandCapability(command, "readOnlyDiagnosticSessionTarget") || (command === "webmcp" && subcommand === "list");
|
|
314
315
|
}
|
|
315
316
|
export function isSessionTabPinningExcludedCommand(command) {
|
|
316
317
|
return hasCommandCapability(command, "excludedFromPinning");
|
|
@@ -326,8 +327,11 @@ export function isRecordPageTransitionCommand(tokens) {
|
|
|
326
327
|
return true;
|
|
327
328
|
return tokens[1] === "restart" && tokens.length >= 4;
|
|
328
329
|
}
|
|
330
|
+
export function isWebMcpPageMutationCommand(tokens) {
|
|
331
|
+
return isWebMcpPageMutation(tokens[0], tokens[1]);
|
|
332
|
+
}
|
|
329
333
|
export function isRefInvalidatingBatchCommand(step) {
|
|
330
|
-
return hasCommandCapability(step[0], "invalidatesBatchRefs") || isRecordPageTransitionCommand(step);
|
|
334
|
+
return hasCommandCapability(step[0], "invalidatesBatchRefs") || isRecordPageTransitionCommand(step) || isWebMcpPageMutationCommand(step);
|
|
331
335
|
}
|
|
332
336
|
export function isRefGuardedCommand(command) {
|
|
333
337
|
return hasCommandCapability(command, "guardsPageRefs");
|
|
@@ -335,17 +339,21 @@ export function isRefGuardedCommand(command) {
|
|
|
335
339
|
export function isElectronPostCommandHealthCommand(command) {
|
|
336
340
|
return hasCommandCapability(command, "eligibleForElectronHealthProbe");
|
|
337
341
|
}
|
|
338
|
-
|
|
339
|
-
return
|
|
342
|
+
function isWebMcpPageMutation(command, subcommand) {
|
|
343
|
+
return command === "webmcp" && WEBMCP_PAGE_MUTATION_SUBCOMMANDS.has(subcommand ?? "");
|
|
344
|
+
}
|
|
345
|
+
export function isNavigationObservableCommandName(command, subcommand) {
|
|
346
|
+
return hasCommandCapability(command, "navigationObservable") || isWebMcpPageMutation(command, subcommand);
|
|
340
347
|
}
|
|
341
348
|
export function isUnverifiedPageTransitionCommand(command, subcommand) {
|
|
342
349
|
return ["back", "connect", "eval", "forward", "reload"].includes(command ?? "")
|
|
343
350
|
|| (command === "state" && subcommand === "load")
|
|
344
|
-
|| (command === "tab" && subcommand !== undefined && !["list", "new"].includes(subcommand))
|
|
351
|
+
|| (command === "tab" && subcommand !== undefined && !["list", "new"].includes(subcommand))
|
|
352
|
+
|| isWebMcpPageMutation(command, subcommand);
|
|
345
353
|
}
|
|
346
|
-
export function isPageMutationCommand(command) {
|
|
347
|
-
return hasCommandCapability(command, "triggersPostMutationSnapshot");
|
|
354
|
+
export function isPageMutationCommand(command, subcommand) {
|
|
355
|
+
return hasCommandCapability(command, "triggersPostMutationSnapshot") || isWebMcpPageMutation(command, subcommand);
|
|
348
356
|
}
|
|
349
|
-
export function isPageChangeSummaryCommand(command) {
|
|
350
|
-
return hasCommandCapability(command, "eligibleForPageChangeSummary");
|
|
357
|
+
export function isPageChangeSummaryCommand(command, subcommand) {
|
|
358
|
+
return hasCommandCapability(command, "eligibleForPageChangeSummary") || isWebMcpPageMutation(command, subcommand);
|
|
351
359
|
}
|
|
@@ -7,10 +7,11 @@ import { join, resolve } from "node:path";
|
|
|
7
7
|
/** @typedef {"global" | "project" | "override"} ConfigLayerScope */
|
|
8
8
|
/** @typedef {"literal" | "env" | "command"} CredentialSourceKind */
|
|
9
9
|
/** @typedef {"exa" | "brave"} WebSearchProvider */
|
|
10
|
+
/** @typedef {"auto" | "fast" | "instant" | "deep-lite" | "deep" | "deep-reasoning"} ExaSearchType */
|
|
10
11
|
/** @typedef {"exaApiKey" | "braveApiKey"} WebSearchProviderConfigKey */
|
|
11
12
|
/** @typedef {{ provider: WebSearchProvider; apiKeyEnv: string; configKey: WebSearchProviderConfigKey; label: string }} WebSearchProviderDescriptor */
|
|
12
13
|
/** @typedef {{ name: string; policy?: BrowserDefaultProfilePolicy }} BrowserDefaultProfileConfig */
|
|
13
|
-
/** @typedef {{ enabled?: boolean; preferredProvider?: WebSearchProvider; braveApiKey?: string; exaApiKey?: string }} WebSearchConfig */
|
|
14
|
+
/** @typedef {{ enabled?: boolean; preferredProvider?: WebSearchProvider; defaultSearchType?: ExaSearchType; braveApiKey?: string; exaApiKey?: string }} WebSearchConfig */
|
|
14
15
|
/** @typedef {{ defaultProfile?: BrowserDefaultProfileConfig; executablePath?: string }} BrowserConfig */
|
|
15
16
|
/** @typedef {{ version?: 1; webSearch?: WebSearchConfig; browser?: BrowserConfig }} AgentBrowserConfig */
|
|
16
17
|
/** @typedef {{ config: AgentBrowserConfig; path: string; scope: ConfigLayerScope }} ConfigLayer */
|
|
@@ -45,6 +46,8 @@ export const WEB_SEARCH_PROVIDER_DESCRIPTORS = Object.freeze({
|
|
|
45
46
|
export const WEB_SEARCH_PROVIDERS = Object.freeze(["exa", "brave"]);
|
|
46
47
|
/** @type {WebSearchProvider} */
|
|
47
48
|
export const DEFAULT_WEB_SEARCH_PROVIDER = "exa";
|
|
49
|
+
/** @type {readonly ExaSearchType[]} */
|
|
50
|
+
export const EXA_SEARCH_TYPES = Object.freeze(["auto", "fast", "instant", "deep-lite", "deep", "deep-reasoning"]);
|
|
48
51
|
/** @type {Readonly<Record<WebSearchProvider, WebSearchProviderConfigKey>>} */
|
|
49
52
|
export const WEB_SEARCH_PROVIDER_CONFIG_KEYS = Object.freeze({
|
|
50
53
|
exa: WEB_SEARCH_PROVIDER_DESCRIPTORS.exa.configKey,
|
|
@@ -182,6 +185,24 @@ export function validateWebSearchProvider(value, path, errors) {
|
|
|
182
185
|
}
|
|
183
186
|
return provider;
|
|
184
187
|
}
|
|
188
|
+
/**
|
|
189
|
+
* @param {unknown} value
|
|
190
|
+
* @param {string} path
|
|
191
|
+
* @param {string[]} errors
|
|
192
|
+
* @returns {ExaSearchType | undefined}
|
|
193
|
+
*/
|
|
194
|
+
function validateExaSearchType(value, path, errors) {
|
|
195
|
+
if (value === undefined)
|
|
196
|
+
return undefined;
|
|
197
|
+
const searchType = validateString(value, path, errors)?.trim();
|
|
198
|
+
if (searchType === undefined)
|
|
199
|
+
return undefined;
|
|
200
|
+
if (!EXA_SEARCH_TYPES.includes(/** @type {ExaSearchType} */ (searchType))) {
|
|
201
|
+
errors.push(`${path} must be one of ${EXA_SEARCH_TYPES.join(", ")}.`);
|
|
202
|
+
return undefined;
|
|
203
|
+
}
|
|
204
|
+
return /** @type {ExaSearchType} */ (searchType);
|
|
205
|
+
}
|
|
185
206
|
/**
|
|
186
207
|
* @param {unknown} value
|
|
187
208
|
* @param {string} path
|
|
@@ -251,6 +272,9 @@ export function validateAgentBrowserConfig(value, path, errors, warnings) {
|
|
|
251
272
|
const preferredProvider = validateWebSearchProvider(value.webSearch.preferredProvider, `${path}.webSearch.preferredProvider`, errors);
|
|
252
273
|
if (preferredProvider)
|
|
253
274
|
webSearch.preferredProvider = preferredProvider;
|
|
275
|
+
const defaultSearchType = validateExaSearchType(value.webSearch.defaultSearchType, `${path}.webSearch.defaultSearchType`, errors);
|
|
276
|
+
if (defaultSearchType)
|
|
277
|
+
webSearch.defaultSearchType = defaultSearchType;
|
|
254
278
|
for (const provider of WEB_SEARCH_PROVIDERS) {
|
|
255
279
|
const descriptor = getWebSearchProviderDescriptor(provider);
|
|
256
280
|
const apiKey = validateString(value.webSearch[descriptor.configKey], `${path}.webSearch.${descriptor.configKey}`, errors);
|
|
@@ -2,7 +2,7 @@ import { exec as execCallback } from "node:child_process";
|
|
|
2
2
|
import { readFile } from "node:fs/promises";
|
|
3
3
|
import { promisify } from "node:util";
|
|
4
4
|
import { SECRET_COMMAND_TIMEOUT_MS, buildAgentBrowserConfigState, getAgentBrowserConfigPaths, getWebSearchCredentialSource, getWebSearchProviderOrder, loadAgentBrowserConfigStateSync, mergeAgentBrowserConfig, parseAgentBrowserConfigLayer, resolveEnvInterpolations, } from "./config-policy.js";
|
|
5
|
-
export { AGENT_BROWSER_CONFIG_ENV, BRAVE_API_KEY_ENV, CONFIG_RELATIVE_PATH, DEFAULT_WEB_SEARCH_PROVIDER, EXA_API_KEY_ENV, GLOBAL_CONFIG_RELATIVE_PATH, SECRET_COMMAND_TIMEOUT_MS, WEB_SEARCH_PROVIDER_CONFIG_KEYS, WEB_SEARCH_PROVIDER_DESCRIPTORS, WEB_SEARCH_PROVIDER_ENV_VARS, WEB_SEARCH_PROVIDERS, buildAgentBrowserConfigState, buildWebSearchCredentialSources, canRegisterWebSearchTool, classifyCredentialSource, formatBrowserExecutableStatus, formatBrowserProfileStatus, getAgentBrowserConfigPaths, getCredentialSourceSummary, getGlobalAgentBrowserConfigPath, getProjectAgentBrowserConfigPath, getWebSearchCredentialSource, getWebSearchProviderConfigKey, getWebSearchProviderDescriptor, getWebSearchProviderEnvVar, getWebSearchProviderLabel, getWebSearchProviderOrder, hasPotentialCredentialSource, isPlaintextCredentialValue, isProjectSafeCredentialValueForProvider, isWebSearchProvider, loadAgentBrowserConfigStateSync, mergeAgentBrowserConfig, parseAgentBrowserConfigLayer, resolveEnvInterpolations, summarizeConfigFiles, validateAgentBrowserConfig, validateWebSearchProvider, } from "./config-policy.js";
|
|
5
|
+
export { AGENT_BROWSER_CONFIG_ENV, BRAVE_API_KEY_ENV, CONFIG_RELATIVE_PATH, DEFAULT_WEB_SEARCH_PROVIDER, EXA_API_KEY_ENV, EXA_SEARCH_TYPES, GLOBAL_CONFIG_RELATIVE_PATH, SECRET_COMMAND_TIMEOUT_MS, WEB_SEARCH_PROVIDER_CONFIG_KEYS, WEB_SEARCH_PROVIDER_DESCRIPTORS, WEB_SEARCH_PROVIDER_ENV_VARS, WEB_SEARCH_PROVIDERS, buildAgentBrowserConfigState, buildWebSearchCredentialSources, canRegisterWebSearchTool, classifyCredentialSource, formatBrowserExecutableStatus, formatBrowserProfileStatus, getAgentBrowserConfigPaths, getCredentialSourceSummary, getGlobalAgentBrowserConfigPath, getProjectAgentBrowserConfigPath, getWebSearchCredentialSource, getWebSearchProviderConfigKey, getWebSearchProviderDescriptor, getWebSearchProviderEnvVar, getWebSearchProviderLabel, getWebSearchProviderOrder, hasPotentialCredentialSource, isPlaintextCredentialValue, isProjectSafeCredentialValueForProvider, isWebSearchProvider, loadAgentBrowserConfigStateSync, mergeAgentBrowserConfig, parseAgentBrowserConfigLayer, resolveEnvInterpolations, summarizeConfigFiles, validateAgentBrowserConfig, validateWebSearchProvider, } from "./config-policy.js";
|
|
6
6
|
const exec = promisify(execCallback);
|
|
7
7
|
async function readConfigLayer(path, scope, errors, warnings) {
|
|
8
8
|
let raw;
|
|
@@ -213,15 +213,6 @@ export function compileAgentBrowserJob(input) {
|
|
|
213
213
|
}
|
|
214
214
|
return { compiled: { args: failFast ? ["batch", "--bail"] : ["batch"], failFast, stdin: JSON.stringify(steps.map((step) => step.args)), steps } };
|
|
215
215
|
}
|
|
216
|
-
export function isHttpOrHttpsUrl(url) {
|
|
217
|
-
try {
|
|
218
|
-
const protocol = new URL(url).protocol;
|
|
219
|
-
return protocol === "http:" || protocol === "https:";
|
|
220
|
-
}
|
|
221
|
-
catch {
|
|
222
|
-
return false;
|
|
223
|
-
}
|
|
224
|
-
}
|
|
225
216
|
function describeQaChecksRun(checks) {
|
|
226
217
|
const parts = [`load:${checks.loadState}`];
|
|
227
218
|
if (checks.expectedText.length > 0)
|
|
@@ -106,7 +106,7 @@ export function createAgentBrowserParamsSchema(Type = JsonSchema, StringEnum = l
|
|
|
106
106
|
failFast: Type.Optional(Type.Boolean({ description: "Stop on first failure; default true." })),
|
|
107
107
|
steps: Type.Array(Type.Object({
|
|
108
108
|
action: StringEnum(AGENT_BROWSER_JOB_STEP_ACTIONS),
|
|
109
|
-
url: Type.Optional(Type.String({ description: "Open URL or assertUrl glob." })),
|
|
109
|
+
url: Type.Optional(Type.String({ description: "Open URL, or assertUrl exact URL/glob that distinguishes the expected state from the starting page." })),
|
|
110
110
|
loadState: Type.Optional(StringEnum(AGENT_BROWSER_QA_LOAD_STATES, { description: "Readiness wait after open." })),
|
|
111
111
|
selector: Type.Optional(Type.String({ description: "Selector or @ref." })),
|
|
112
112
|
locator: Type.Optional(StringEnum(AGENT_BROWSER_SEMANTIC_LOCATORS, { description: "Locator when selector is omitted." })),
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { findCommandStartIndex } from "./argv-descriptor.js";
|
|
2
|
-
import { isBooleanFlagEnabled
|
|
2
|
+
import { isBooleanFlagEnabled } from "./argv-grammar.js";
|
|
3
3
|
export const LAUNCH_SCOPED_FLAG_DEFINITIONS = [
|
|
4
4
|
{
|
|
5
5
|
flag: "--auto-connect",
|
|
@@ -17,6 +17,14 @@ export const LAUNCH_SCOPED_FLAG_DEFINITIONS = [
|
|
|
17
17
|
flag: "--cdp",
|
|
18
18
|
reason: "selects the browser/CDP endpoint used when an upstream session is launched",
|
|
19
19
|
},
|
|
20
|
+
{
|
|
21
|
+
flag: "--ca-cert",
|
|
22
|
+
reason: "selects isolated Chromium CA trust and may relaunch the browser",
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
flag: "--no-ca-cert",
|
|
26
|
+
reason: "clears retained isolated Chromium CA trust and may relaunch the browser",
|
|
27
|
+
},
|
|
20
28
|
{
|
|
21
29
|
flag: "--enable",
|
|
22
30
|
reason: "selects built-in page init scripts before the upstream browser session is launched",
|
|
@@ -29,6 +37,10 @@ export const LAUNCH_SCOPED_FLAG_DEFINITIONS = [
|
|
|
29
37
|
flag: "--webgpu",
|
|
30
38
|
reason: "selects the platform-specific WebGPU browser launch preset",
|
|
31
39
|
},
|
|
40
|
+
{
|
|
41
|
+
flag: "--no-webmcp",
|
|
42
|
+
reason: "selects whether locally launched Chrome enables experimental WebMCP support",
|
|
43
|
+
},
|
|
32
44
|
{
|
|
33
45
|
flag: "--init-script",
|
|
34
46
|
reason: "registers page init scripts before the upstream browser session is launched",
|
|
@@ -120,6 +132,7 @@ export const MANAGED_RESTORE_INCOMPATIBLE_FLAGS = [
|
|
|
120
132
|
"--user-agent",
|
|
121
133
|
"--proxy",
|
|
122
134
|
"--proxy-bypass",
|
|
135
|
+
"--ca-cert",
|
|
123
136
|
"--ignore-https-errors",
|
|
124
137
|
"--allow-file-access",
|
|
125
138
|
"--webgpu",
|
|
@@ -148,6 +161,7 @@ export const MANAGED_RESTORE_INCOMPATIBLE_ENVS = [
|
|
|
148
161
|
"AGENT_BROWSER_USER_AGENT",
|
|
149
162
|
"AGENT_BROWSER_PROXY",
|
|
150
163
|
"AGENT_BROWSER_PROXY_BYPASS",
|
|
164
|
+
"AGENT_BROWSER_CA_CERT",
|
|
151
165
|
"AGENT_BROWSER_PLUGINS",
|
|
152
166
|
"AGENT_BROWSER_IOS_DEVICE",
|
|
153
167
|
"AGENT_BROWSER_IOS_UDID",
|
|
@@ -170,12 +184,12 @@ export function hasLaunchScopedFlagToken(args, flag) {
|
|
|
170
184
|
const commandStartIndex = findCommandStartIndex(args);
|
|
171
185
|
const command = commandStartIndex === undefined ? undefined : args[commandStartIndex];
|
|
172
186
|
return args.some((token, index) => {
|
|
173
|
-
if (token
|
|
187
|
+
if (token.startsWith(`${flag}=`))
|
|
188
|
+
return flag === "--restore";
|
|
189
|
+
if (token !== flag)
|
|
174
190
|
return false;
|
|
175
191
|
if (flag === "--auto-connect")
|
|
176
192
|
return isBooleanFlagEnabled(args, flag);
|
|
177
|
-
if (flag === "--restore" && token === "--restore" && optionalGlobalValueFlagConsumesNext(flag, args[index + 1]))
|
|
178
|
-
return true;
|
|
179
193
|
if (flag === "--state" && command === "wait" && commandStartIndex !== undefined && index > commandStartIndex)
|
|
180
194
|
return false;
|
|
181
195
|
return true;
|