pi-agent-browser-native 0.9.4 → 0.9.5
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 +29 -0
- package/README.md +58 -813
- package/dist/extensions/agent-browser/index.js +927 -883
- package/dist/extensions/agent-browser/lib/browser-execution-claims.js +5 -5
- package/dist/extensions/agent-browser/lib/config-policy.js +1 -1
- package/dist/extensions/agent-browser/lib/config-validation.js +21 -8
- package/dist/extensions/agent-browser/lib/config.js +1 -1
- package/dist/extensions/agent-browser/lib/electron/cdp.js +5 -1
- package/dist/extensions/agent-browser/lib/electron/cleanup.js +13 -47
- package/dist/extensions/agent-browser/lib/electron/discovery-evidence.js +1 -0
- package/dist/extensions/agent-browser/lib/electron/launch.js +12 -1
- package/dist/extensions/agent-browser/lib/fs-utils.js +1 -9
- package/dist/extensions/agent-browser/lib/input-modes/job.js +7 -4
- package/dist/extensions/agent-browser/lib/input-modes/lookup-network-evidence.js +15 -3
- package/dist/extensions/agent-browser/lib/input-modes/lookups.js +3 -2
- package/dist/extensions/agent-browser/lib/input-modes/params.js +23 -23
- package/dist/extensions/agent-browser/lib/orchestration/browser-run/electron-observation.js +9 -8
- package/dist/extensions/agent-browser/lib/orchestration/browser-run/final-result-electron.js +8 -0
- package/dist/extensions/agent-browser/lib/orchestration/browser-run/prepare/scroll-shims.js +2 -2
- package/dist/extensions/agent-browser/lib/orchestration/browser-run/prepare/snapshot-filter.js +9 -0
- package/dist/extensions/agent-browser/lib/orchestration/browser-run/session-state-electron.js +4 -2
- package/dist/extensions/agent-browser/lib/orchestration/browser-run/session-state-refs.js +9 -11
- package/dist/extensions/agent-browser/lib/orchestration/electron-host/branch.js +1 -0
- package/dist/extensions/agent-browser/lib/orchestration/electron-host/probe-collection.js +5 -6
- package/dist/extensions/agent-browser/lib/orchestration/electron-host/probe-data.js +4 -2
- package/dist/extensions/agent-browser/lib/orchestration/electron-host/probe-presentation.js +20 -2
- package/dist/extensions/agent-browser/lib/orchestration/electron-host/status.js +4 -2
- package/dist/extensions/agent-browser/lib/orchestration/execution-queue.js +1 -1
- package/dist/extensions/agent-browser/lib/results/presentation/skills.js +7 -2
- package/dist/extensions/agent-browser/lib/temp-artifact-budget.js +4 -1
- package/dist/extensions/agent-browser/lib/temp-root.js +22 -18
- package/dist/extensions/agent-browser/lib/temp.js +1 -1
- package/dist/extensions/agent-browser/lib/web-search-providers.js +0 -36
- package/dist/extensions/agent-browser/lib/web-search-request.js +20 -26
- package/dist/extensions/agent-browser/lib/web-search-schema.js +5 -5
- package/dist/extensions/agent-browser/lib/web-search.js +22 -4
- package/docs/ARCHITECTURE.md +3 -2
- package/docs/CODE_QUALITY.md +28 -3
- package/docs/COMMAND_REFERENCE.md +20 -20
- package/docs/ELECTRON.md +24 -2
- package/docs/REFERENCE.md +869 -0
- package/docs/RELEASE.md +9 -9
- package/docs/REQUIREMENTS.md +1 -1
- package/docs/SUPPORT_MATRIX.md +9 -8
- package/docs/TOOL_CONTRACT.md +13 -9
- package/docs/platform-smoke.md +3 -3
- package/package.json +3 -2
- package/scripts/config.mjs +23 -19
- package/scripts/doctor.mjs +2 -2
- package/scripts/platform-smoke/lease-evidence.mjs +2 -4
- package/scripts/platform-smoke/linux-image/Dockerfile +8 -2
- package/scripts/platform-smoke/targets.mjs +1 -5
|
@@ -5122,18 +5122,26 @@ async function cleanupSecureTempArtifacts(options = {}) {
|
|
|
5122
5122
|
});
|
|
5123
5123
|
});
|
|
5124
5124
|
}
|
|
5125
|
-
async function
|
|
5126
|
-
|
|
5127
|
-
|
|
5128
|
-
|
|
5129
|
-
|
|
5130
|
-
|
|
5131
|
-
|
|
5132
|
-
|
|
5133
|
-
|
|
5134
|
-
|
|
5135
|
-
})()
|
|
5125
|
+
async function allocateSessionTempRoot() {
|
|
5126
|
+
const tempRoot = await mkdtemp(join3(tmpdir(), TEMP_ROOT_PREFIX));
|
|
5127
|
+
try {
|
|
5128
|
+
await chmod2(tempRoot, 448).catch(() => {
|
|
5129
|
+
});
|
|
5130
|
+
await writeSecureTempRootOwnershipMarker(tempRoot);
|
|
5131
|
+
ownedTempRoots.add(tempRoot);
|
|
5132
|
+
registerExitCleanup();
|
|
5133
|
+
return tempRoot;
|
|
5134
|
+
} catch (error) {
|
|
5135
|
+
await rm2(tempRoot, { force: true, recursive: true }).catch(() => {
|
|
5136
|
+
});
|
|
5137
|
+
throw error;
|
|
5136
5138
|
}
|
|
5139
|
+
}
|
|
5140
|
+
async function getSessionTempRoot() {
|
|
5141
|
+
sessionTempRootPromise ??= allocateSessionTempRoot().catch((error) => {
|
|
5142
|
+
sessionTempRootPromise = void 0;
|
|
5143
|
+
throw error;
|
|
5144
|
+
});
|
|
5137
5145
|
const tempRoot = await sessionTempRootPromise;
|
|
5138
5146
|
await refreshSecureTempRootLease(tempRoot).catch(() => {
|
|
5139
5147
|
});
|
|
@@ -5237,7 +5245,10 @@ async function prunePersistentSessionArtifactsToBudget(sessionArtifactDir, addit
|
|
|
5237
5245
|
if (protectedPaths.has(file.path)) {
|
|
5238
5246
|
continue;
|
|
5239
5247
|
}
|
|
5240
|
-
await rm3(file.path, { force: true }).
|
|
5248
|
+
const removed = await rm3(file.path, { force: true }).then(() => true, () => false);
|
|
5249
|
+
if (!removed) {
|
|
5250
|
+
continue;
|
|
5251
|
+
}
|
|
5241
5252
|
evictedArtifacts.push({ mtimeMs: file.mtimeMs, path: file.path, sizeBytes: file.size });
|
|
5242
5253
|
totalBytes -= file.size;
|
|
5243
5254
|
if (totalBytes + additionalBytes <= maxBytes) {
|
|
@@ -8265,9 +8276,10 @@ function buildQaVisibleTextPredicate(text3) {
|
|
|
8265
8276
|
if (style.display === "none" || style.visibility === "hidden" || Number(style.opacity) === 0) return false;
|
|
8266
8277
|
return element.getClientRects().length > 0;
|
|
8267
8278
|
};
|
|
8268
|
-
const
|
|
8279
|
+
const ancestorsAllowVisibility = (node) => {
|
|
8269
8280
|
for (let element = node.parentElement; element; element = element.parentElement) {
|
|
8270
|
-
|
|
8281
|
+
const style = window.getComputedStyle(element);
|
|
8282
|
+
if (style.display === "none" || Number(style.opacity) === 0) return false;
|
|
8271
8283
|
if (element === root) break;
|
|
8272
8284
|
}
|
|
8273
8285
|
return true;
|
|
@@ -8275,14 +8287,16 @@ function buildQaVisibleTextPredicate(text3) {
|
|
|
8275
8287
|
const textWalker = document.createTreeWalker(root, NodeFilter.SHOW_TEXT);
|
|
8276
8288
|
let visitedText = 0;
|
|
8277
8289
|
for (let node = textWalker.nextNode(); node && visitedText < 6000; node = textWalker.nextNode(), visitedText += 1) {
|
|
8278
|
-
|
|
8290
|
+
const parent = node.parentElement;
|
|
8291
|
+
if (!(parent instanceof HTMLElement) || skipTags.has(parent.tagName)) continue;
|
|
8292
|
+
if (window.getComputedStyle(parent).visibility === "hidden" || !ancestorsAllowVisibility(node)) continue;
|
|
8279
8293
|
if (normalize(node.nodeValue).includes(expected)) return true;
|
|
8280
8294
|
}
|
|
8281
8295
|
const elementWalker = document.createTreeWalker(root, NodeFilter.SHOW_ELEMENT);
|
|
8282
8296
|
let visitedElements = 0;
|
|
8283
8297
|
for (let node = elementWalker.nextNode(); node && visitedElements < 3000; node = elementWalker.nextNode(), visitedElements += 1) {
|
|
8284
8298
|
const element = node;
|
|
8285
|
-
if (!isVisibleElement(element) || !("value" in element)) continue;
|
|
8299
|
+
if (!isVisibleElement(element) || !ancestorsAllowVisibility(element) || !("value" in element)) continue;
|
|
8286
8300
|
if (normalize(element.value).includes(expected)) return true;
|
|
8287
8301
|
}
|
|
8288
8302
|
return false;
|
|
@@ -8862,7 +8876,17 @@ function getFailedNetworkRequests(data, queryText) {
|
|
|
8862
8876
|
});
|
|
8863
8877
|
}
|
|
8864
8878
|
}
|
|
8865
|
-
|
|
8879
|
+
const seenRequestIds = /* @__PURE__ */ new Set();
|
|
8880
|
+
return failed.filter(({ requestId: id }) => {
|
|
8881
|
+
if (id === void 0) {
|
|
8882
|
+
return true;
|
|
8883
|
+
}
|
|
8884
|
+
if (seenRequestIds.has(id)) {
|
|
8885
|
+
return false;
|
|
8886
|
+
}
|
|
8887
|
+
seenRequestIds.add(id);
|
|
8888
|
+
return true;
|
|
8889
|
+
});
|
|
8866
8890
|
}
|
|
8867
8891
|
function distinctNetworkCandidates(candidates) {
|
|
8868
8892
|
const keys = /* @__PURE__ */ new Set();
|
|
@@ -8899,7 +8923,7 @@ function correlatesWithFailure(value, failedIds, failedUrls) {
|
|
|
8899
8923
|
const url = typeof value.url === "string" ? value.url : void 0;
|
|
8900
8924
|
return id !== void 0 && failedIds.has(id) || url !== void 0 && failedUrls.has(url);
|
|
8901
8925
|
}
|
|
8902
|
-
function observeInitiatorCandidates(data, failedRequests) {
|
|
8926
|
+
function observeInitiatorCandidates(data, failedRequests, queryText) {
|
|
8903
8927
|
const failedIds = new Set(failedRequests.map((request) => request.requestId).filter((value) => value !== void 0));
|
|
8904
8928
|
const failedUrls = new Set(failedRequests.map((request) => request.url).filter((value) => value !== void 0));
|
|
8905
8929
|
const candidates = [];
|
|
@@ -8910,7 +8934,8 @@ function observeInitiatorCandidates(data, failedRequests) {
|
|
|
8910
8934
|
if (!isRecord(value)) {
|
|
8911
8935
|
continue;
|
|
8912
8936
|
}
|
|
8913
|
-
|
|
8937
|
+
const url = typeof value.url === "string" ? value.url : void 0;
|
|
8938
|
+
if (networkRequestMatchesQuery(url, queryText) && (correlatesWithFailure(value, failedIds, failedUrls) || isFailedNetworkRecord(value))) {
|
|
8914
8939
|
candidates.push(...initiatorCandidates(value));
|
|
8915
8940
|
}
|
|
8916
8941
|
}
|
|
@@ -9132,8 +9157,9 @@ function networkSummary(status, failedCount, candidateCount) {
|
|
|
9132
9157
|
async function analyzeNetworkSourceLookupResults(data, compiled, cwd) {
|
|
9133
9158
|
const { distinctNetworkCandidates: distinctNetworkCandidates2, getFailedNetworkRequests: getFailedNetworkRequests2, observeInitiatorCandidates: observeInitiatorCandidates2 } = await Promise.resolve().then(() => (init_lookup_network_evidence(), lookup_network_evidence_exports));
|
|
9134
9159
|
const { scanWorkspaceRequests: scanWorkspaceRequests2 } = await Promise.resolve().then(() => (init_lookup_workspace(), lookup_workspace_exports));
|
|
9135
|
-
const
|
|
9136
|
-
const
|
|
9160
|
+
const queryText = compiled.query.filter ?? compiled.query.url;
|
|
9161
|
+
const failedRequests = getFailedNetworkRequests2(data, queryText);
|
|
9162
|
+
const observed = observeInitiatorCandidates2(data, failedRequests, queryText);
|
|
9137
9163
|
const workspace = await scanWorkspaceRequests2(compiled.query, failedRequests, cwd);
|
|
9138
9164
|
const candidates = distinctNetworkCandidates2([...observed, ...workspace.candidates]);
|
|
9139
9165
|
const status = networkStatus(failedRequests.length, candidates.length);
|
|
@@ -11134,6 +11160,253 @@ var init_discovery_types = __esm({
|
|
|
11134
11160
|
}
|
|
11135
11161
|
});
|
|
11136
11162
|
|
|
11163
|
+
// dist/extensions/agent-browser/lib/results/presentation/diagnostic-storage.js
|
|
11164
|
+
function storageTextContainsSecret(text3) {
|
|
11165
|
+
if (STORAGE_TOKEN_VALUE_PATTERN.test(text3) || STORAGE_SECRET_VALUE_WORD_PATTERN.test(text3) || STORAGE_EMAIL_VALUE_PATTERN.test(text3) || STORAGE_IDENTITY_VALUE_PATTERN.test(text3)) {
|
|
11166
|
+
return true;
|
|
11167
|
+
}
|
|
11168
|
+
if (storageTextIsSensitiveUrl(text3) || redactSensitiveText(text3) !== text3) {
|
|
11169
|
+
return true;
|
|
11170
|
+
}
|
|
11171
|
+
try {
|
|
11172
|
+
const parsed = JSON.parse(text3);
|
|
11173
|
+
return valueContainsStorageSecret(parsed);
|
|
11174
|
+
} catch {
|
|
11175
|
+
return false;
|
|
11176
|
+
}
|
|
11177
|
+
}
|
|
11178
|
+
function storageTextIsSensitiveUrl(text3) {
|
|
11179
|
+
try {
|
|
11180
|
+
const url = new URL(text3);
|
|
11181
|
+
return url.protocol === "http:" || url.protocol === "https:" || url.username.length > 0 || url.password.length > 0 || url.search.length > 0;
|
|
11182
|
+
} catch {
|
|
11183
|
+
return false;
|
|
11184
|
+
}
|
|
11185
|
+
}
|
|
11186
|
+
function valueContainsStorageSecret(value) {
|
|
11187
|
+
if (typeof value === "string") {
|
|
11188
|
+
const trimmed = value.trim();
|
|
11189
|
+
return trimmed.length > 0 && storageTextContainsSecret(trimmed);
|
|
11190
|
+
}
|
|
11191
|
+
if (Array.isArray(value)) {
|
|
11192
|
+
return value.some((item) => valueContainsStorageSecret(item));
|
|
11193
|
+
}
|
|
11194
|
+
if (!isRecord(value)) {
|
|
11195
|
+
return false;
|
|
11196
|
+
}
|
|
11197
|
+
return Object.entries(value).some(([key, entryValue]) => STORAGE_SECRET_KEY_PATTERN.test(key) || valueContainsStorageSecret(entryValue));
|
|
11198
|
+
}
|
|
11199
|
+
function shouldRevealStorageValue(key, value) {
|
|
11200
|
+
if (key === void 0 || key.length === 0 || STORAGE_SECRET_KEY_PATTERN.test(key) || !STORAGE_BENIGN_KEY_PATTERN.test(key)) {
|
|
11201
|
+
return false;
|
|
11202
|
+
}
|
|
11203
|
+
if (valueContainsStorageSecret(value)) {
|
|
11204
|
+
return false;
|
|
11205
|
+
}
|
|
11206
|
+
if (typeof value === "string") {
|
|
11207
|
+
return value.length <= STORAGE_VALUE_PREVIEW_MAX_CHARS;
|
|
11208
|
+
}
|
|
11209
|
+
return value === null || typeof value === "number" || typeof value === "boolean";
|
|
11210
|
+
}
|
|
11211
|
+
function formatStorageValue(key, value) {
|
|
11212
|
+
if (!shouldRevealStorageValue(key, value)) {
|
|
11213
|
+
return "[REDACTED]";
|
|
11214
|
+
}
|
|
11215
|
+
return typeof value === "string" ? redactModelFacingText(value) : stringifyModelFacing(value);
|
|
11216
|
+
}
|
|
11217
|
+
function storageRedactionReason(key) {
|
|
11218
|
+
return key !== void 0 && key.length > 0 && STORAGE_SECRET_KEY_PATTERN.test(key) ? "sensitive-key" : "sensitive-value";
|
|
11219
|
+
}
|
|
11220
|
+
function redactStorageEntryValue(item) {
|
|
11221
|
+
const key = getStringField(item, "key") ?? getStringField(item, "name");
|
|
11222
|
+
if (!Object.hasOwn(item, "value") || shouldRevealStorageValue(key, item.value)) {
|
|
11223
|
+
return redactSensitiveValue(item);
|
|
11224
|
+
}
|
|
11225
|
+
const redacted = redactSensitiveValue({ ...item, value: void 0 });
|
|
11226
|
+
if (!isRecord(redacted)) {
|
|
11227
|
+
throw new Error("Storage record redaction did not return a record");
|
|
11228
|
+
}
|
|
11229
|
+
return {
|
|
11230
|
+
...redacted,
|
|
11231
|
+
value: "[REDACTED]",
|
|
11232
|
+
valueRedacted: true,
|
|
11233
|
+
valueRedactionReason: storageRedactionReason(key)
|
|
11234
|
+
};
|
|
11235
|
+
}
|
|
11236
|
+
function redactStorageField(owner, key, value) {
|
|
11237
|
+
if (key === "data" && isRecord(value)) {
|
|
11238
|
+
return Object.fromEntries(Object.entries(value).map(([storageKey, storageValue]) => [
|
|
11239
|
+
storageKey,
|
|
11240
|
+
shouldRevealStorageValue(storageKey, storageValue) ? redactSensitiveValue(storageValue) : "[REDACTED]"
|
|
11241
|
+
]));
|
|
11242
|
+
}
|
|
11243
|
+
if ((key === "entries" || key === "items") && Array.isArray(value)) {
|
|
11244
|
+
return value.map((item) => isRecord(item) ? redactStorageEntryValue(item) : redactSensitiveValue(item));
|
|
11245
|
+
}
|
|
11246
|
+
if (key === "value") {
|
|
11247
|
+
const itemKey = getStringField(owner, "key") ?? getStringField(owner, "name");
|
|
11248
|
+
return shouldRevealStorageValue(itemKey, value) ? redactSensitiveValue(value) : "[REDACTED]";
|
|
11249
|
+
}
|
|
11250
|
+
return redactSensitiveValue(value);
|
|
11251
|
+
}
|
|
11252
|
+
function redactStorageData(value) {
|
|
11253
|
+
if (Array.isArray(value)) {
|
|
11254
|
+
return value.map((item) => redactStorageData(item));
|
|
11255
|
+
}
|
|
11256
|
+
if (!isRecord(value)) {
|
|
11257
|
+
return redactSensitiveValue(value);
|
|
11258
|
+
}
|
|
11259
|
+
const entries = Object.fromEntries(Object.entries(value).map(([key2, entryValue]) => [
|
|
11260
|
+
key2,
|
|
11261
|
+
redactStorageField(value, key2, entryValue)
|
|
11262
|
+
]));
|
|
11263
|
+
const key = getStringField(value, "key") ?? getStringField(value, "name");
|
|
11264
|
+
if (Object.hasOwn(value, "value") && !shouldRevealStorageValue(key, value.value)) {
|
|
11265
|
+
entries.valueRedacted = true;
|
|
11266
|
+
entries.valueRedactionReason = storageRedactionReason(key);
|
|
11267
|
+
}
|
|
11268
|
+
return entries;
|
|
11269
|
+
}
|
|
11270
|
+
function formatStorageEntry(item, index) {
|
|
11271
|
+
if (!isRecord(item)) {
|
|
11272
|
+
return `${index + 1}. [REDACTED]`;
|
|
11273
|
+
}
|
|
11274
|
+
const rawKey = getStringField(item, "key") ?? getStringField(item, "name") ?? `(entry ${index + 1})`;
|
|
11275
|
+
const key = redactModelFacingText(rawKey);
|
|
11276
|
+
return Object.hasOwn(item, "value") ? `${key}: ${formatStorageValue(rawKey, item.value)}` : key;
|
|
11277
|
+
}
|
|
11278
|
+
function formatStorageMutationText(data, type) {
|
|
11279
|
+
const key = getStringField(data, "key");
|
|
11280
|
+
if (key !== void 0 && Object.hasOwn(data, "value")) {
|
|
11281
|
+
return `${type} ${redactModelFacingText(key)}: ${formatStorageValue(key, data.value)}`;
|
|
11282
|
+
}
|
|
11283
|
+
if (key !== void 0 && data.set === true) {
|
|
11284
|
+
return `${type} set: ${redactModelFacingText(key)}`;
|
|
11285
|
+
}
|
|
11286
|
+
return data.cleared === true || data.clear === true ? `${type} cleared.` : void 0;
|
|
11287
|
+
}
|
|
11288
|
+
function formatStorageText(data) {
|
|
11289
|
+
const type = getStringField(data, "type") ?? getStringField(data, "storage") ?? "storage";
|
|
11290
|
+
if (isRecord(data.data)) {
|
|
11291
|
+
const text3 = Object.entries(data.data).map(([key, value]) => `${redactModelFacingText(key)}: ${formatStorageValue(key, value)}`).join("\n");
|
|
11292
|
+
return text3.length > 0 ? text3 : `${type}: no entries.`;
|
|
11293
|
+
}
|
|
11294
|
+
const entries = getArrayField(data, "entries") ?? getArrayField(data, "items");
|
|
11295
|
+
if (entries) {
|
|
11296
|
+
return entries.length === 0 ? `${type}: no entries.` : entries.map(formatStorageEntry).join("\n");
|
|
11297
|
+
}
|
|
11298
|
+
return formatStorageMutationText(data, type);
|
|
11299
|
+
}
|
|
11300
|
+
function formatCookieRecordText(item, fallbackName) {
|
|
11301
|
+
const name = redactModelFacingText(getStringField(item, "name") ?? fallbackName);
|
|
11302
|
+
const domain = getStringField(item, "domain");
|
|
11303
|
+
const path = getStringField(item, "path");
|
|
11304
|
+
const flags = [
|
|
11305
|
+
item.httpOnly === true ? "httpOnly" : void 0,
|
|
11306
|
+
item.secure === true ? "secure" : void 0
|
|
11307
|
+
].filter(Boolean).join(", ");
|
|
11308
|
+
const location = [domain, path].filter(Boolean).join("");
|
|
11309
|
+
return [
|
|
11310
|
+
name,
|
|
11311
|
+
location.length > 0 ? `(${redactModelFacingText(location)})` : void 0,
|
|
11312
|
+
flags.length > 0 ? `[${flags}]` : void 0
|
|
11313
|
+
].filter(Boolean).join(" ");
|
|
11314
|
+
}
|
|
11315
|
+
function formatCookiesText(data) {
|
|
11316
|
+
const cookies = getArrayField(data, "cookies");
|
|
11317
|
+
if (cookies) {
|
|
11318
|
+
return cookies.length === 0 ? "No cookies." : cookies.map((item, index) => isRecord(item) ? formatCookieRecordText(item, `(cookie ${index + 1})`) : `${index + 1}. [REDACTED]`).join("\n");
|
|
11319
|
+
}
|
|
11320
|
+
if (getStringField(data, "name") !== void 0 || getStringField(data, "domain") !== void 0 || getStringField(data, "path") !== void 0 || Object.hasOwn(data, "value")) {
|
|
11321
|
+
return formatCookieRecordText(data, "cookie");
|
|
11322
|
+
}
|
|
11323
|
+
if (data.set === true) {
|
|
11324
|
+
return "Cookie set.";
|
|
11325
|
+
}
|
|
11326
|
+
return data.cleared === true || data.clear === true ? "Cookies cleared." : void 0;
|
|
11327
|
+
}
|
|
11328
|
+
var STORAGE_VALUE_PREVIEW_MAX_CHARS, STORAGE_SECRET_KEY_PATTERN, STORAGE_BENIGN_KEY_PATTERN, STORAGE_TOKEN_VALUE_PATTERN, STORAGE_SECRET_VALUE_WORD_PATTERN, STORAGE_EMAIL_VALUE_PATTERN, STORAGE_IDENTITY_VALUE_PATTERN;
|
|
11329
|
+
var init_diagnostic_storage = __esm({
|
|
11330
|
+
"dist/extensions/agent-browser/lib/results/presentation/diagnostic-storage.js"() {
|
|
11331
|
+
"use strict";
|
|
11332
|
+
init_parsing();
|
|
11333
|
+
init_runtime();
|
|
11334
|
+
init_common();
|
|
11335
|
+
STORAGE_VALUE_PREVIEW_MAX_CHARS = 160;
|
|
11336
|
+
STORAGE_SECRET_KEY_PATTERN = /(?:access(?:_|-)?token|account|api(?:_|-)?key|auth(?:orization)?|bearer|client(?:_|-)?secret|cookie|credential|csrf|email|id(?:_|-)?token|jwt|pass(?:word)?|private(?:_|-)?key|profile|refresh(?:_|-)?token|secret|session|sid|sig(?:nature)?|token|user(?:name)?|x(?:_|-)?api(?:_|-)?key|xsrf)/i;
|
|
11337
|
+
STORAGE_BENIGN_KEY_PATTERN = /^(?:color(?:scheme)?|debug|dev|experiment|feature(?:flag)?|flag|language|layout|locale|mode|onboarding|sort|tab|theme|timezone|tour|variant|view)$/i;
|
|
11338
|
+
STORAGE_TOKEN_VALUE_PATTERN = /(?:\bBearer\s+[A-Za-z0-9._~-]+|\bBasic\s+[A-Za-z0-9+/=]+|^[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+$|(?=.*[A-Za-z])(?=.*\d)[A-Za-z0-9_~+/=-]{32,})/;
|
|
11339
|
+
STORAGE_SECRET_VALUE_WORD_PATTERN = /(?:secret|token|password|passwd|bearer|credential|authorization|cookie|session[-_ ]?id)/i;
|
|
11340
|
+
STORAGE_EMAIL_VALUE_PATTERN = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
|
11341
|
+
STORAGE_IDENTITY_VALUE_PATTERN = /(?:^|[\s:=/_-])(?:account|profile|session|sid|user(?:id|name)?)(?:[\s:=/_-]|$)/i;
|
|
11342
|
+
}
|
|
11343
|
+
});
|
|
11344
|
+
|
|
11345
|
+
// dist/extensions/agent-browser/lib/results/presentation/diagnostic-redaction.js
|
|
11346
|
+
function redactStatefulValues(value) {
|
|
11347
|
+
if (Array.isArray(value)) {
|
|
11348
|
+
return value.map((item) => redactStatefulValues(item));
|
|
11349
|
+
}
|
|
11350
|
+
if (!isRecord(value)) {
|
|
11351
|
+
return redactSensitiveValue(value);
|
|
11352
|
+
}
|
|
11353
|
+
return Object.fromEntries(Object.entries(value).map(([key, entryValue]) => [
|
|
11354
|
+
key,
|
|
11355
|
+
key.toLowerCase() === "value" ? "[REDACTED]" : redactStatefulValues(entryValue)
|
|
11356
|
+
]));
|
|
11357
|
+
}
|
|
11358
|
+
function storageTextKey(command) {
|
|
11359
|
+
const operation = command.commandTokens?.[2];
|
|
11360
|
+
if (operation === "get") {
|
|
11361
|
+
return command.commandTokens?.[3];
|
|
11362
|
+
}
|
|
11363
|
+
return operation === "set" || operation === "clear" ? void 0 : operation;
|
|
11364
|
+
}
|
|
11365
|
+
function redactStorageText(command, text3) {
|
|
11366
|
+
const key = storageTextKey(command);
|
|
11367
|
+
if (key !== void 0 && text3.startsWith(`${key}: `)) {
|
|
11368
|
+
const suffix = text3.endsWith("\n") ? "\n" : "";
|
|
11369
|
+
const value = text3.slice(key.length + 2, suffix.length > 0 ? -1 : void 0);
|
|
11370
|
+
return `${key}: ${formatStorageValue(key, value)}${suffix}`;
|
|
11371
|
+
}
|
|
11372
|
+
return text3.replace(/^([^\r\n]*?): ([^\r\n]*)/gm, (_line, entryKey, value) => `${entryKey}: ${formatStorageValue(entryKey, value)}`);
|
|
11373
|
+
}
|
|
11374
|
+
function redactNativeContextText(command, text3, stdin) {
|
|
11375
|
+
if (command.command === "batch") {
|
|
11376
|
+
const steps = getUpstreamEffectiveBatchSteps(command.commandTokens ?? ["batch"], stdin);
|
|
11377
|
+
const cookieRedacted = steps.some((step) => step[0] === "cookies") ? redactNativeContextText({ command: "cookies" }, text3) : text3;
|
|
11378
|
+
return steps.some((step) => step[0] === "storage") ? redactNativeContextText({ command: "storage" }, cookieRedacted) : cookieRedacted;
|
|
11379
|
+
}
|
|
11380
|
+
if (command.command === "cookies") {
|
|
11381
|
+
return text3.replace(/^([^=\r\n]*)=([^\r\n]*)/gm, "$1=[REDACTED]");
|
|
11382
|
+
}
|
|
11383
|
+
return command.command === "storage" ? redactStorageText(command, text3) : text3;
|
|
11384
|
+
}
|
|
11385
|
+
function redactPresentationData(command, data, stdin) {
|
|
11386
|
+
if (typeof data === "string") {
|
|
11387
|
+
return redactSensitiveText(redactNativeContextText(command, data, stdin));
|
|
11388
|
+
}
|
|
11389
|
+
if (command.command === "cookies") {
|
|
11390
|
+
return redactStatefulValues(data);
|
|
11391
|
+
}
|
|
11392
|
+
if (command.command === "storage") {
|
|
11393
|
+
return redactStorageData(data);
|
|
11394
|
+
}
|
|
11395
|
+
if (command.command === "state" && command.subcommand === "show") {
|
|
11396
|
+
return redactStatefulValues(data);
|
|
11397
|
+
}
|
|
11398
|
+
return redactSensitiveValue(data);
|
|
11399
|
+
}
|
|
11400
|
+
var init_diagnostic_redaction = __esm({
|
|
11401
|
+
"dist/extensions/agent-browser/lib/results/presentation/diagnostic-redaction.js"() {
|
|
11402
|
+
"use strict";
|
|
11403
|
+
init_parsing();
|
|
11404
|
+
init_batch_stdin();
|
|
11405
|
+
init_runtime();
|
|
11406
|
+
init_diagnostic_storage();
|
|
11407
|
+
}
|
|
11408
|
+
});
|
|
11409
|
+
|
|
11137
11410
|
// dist/extensions/agent-browser/lib/results/next-actions.js
|
|
11138
11411
|
function withOptionalNamespaceArgs(namespace, args) {
|
|
11139
11412
|
return namespace !== void 0 && args[0] !== "--namespace" ? ["--namespace", namespace, ...args] : args;
|
|
@@ -11552,7 +11825,7 @@ function isSafeSameSnapshotFormBatchStep(step, refSnapshot) {
|
|
|
11552
11825
|
return false;
|
|
11553
11826
|
}
|
|
11554
11827
|
}
|
|
11555
|
-
function
|
|
11828
|
+
function getBatchRefInvalidationFailure(commandTokens, stdin, refSnapshot) {
|
|
11556
11829
|
if (commandTokens[0] !== "batch") {
|
|
11557
11830
|
return;
|
|
11558
11831
|
}
|
|
@@ -11563,7 +11836,11 @@ function getBatchRefInvalidationMessage(commandTokens, stdin, refSnapshot) {
|
|
|
11563
11836
|
}
|
|
11564
11837
|
const refIds = collectRefsFromTokens(step);
|
|
11565
11838
|
if (refIds.length > 0 && isRefGuardedCommand(step[0]) && priorStepInvalidatesRefs) {
|
|
11566
|
-
return
|
|
11839
|
+
return {
|
|
11840
|
+
message: `Batch step ${step[0]} uses page-scoped ref ${refIds.map((refId) => `@${refId}`).join(", ")} after an earlier batch step can navigate or mutate the page. Split the batch, run snapshot -i after the page-changing step, then retry with current refs.`,
|
|
11841
|
+
refIds,
|
|
11842
|
+
snapshot: refSnapshot
|
|
11843
|
+
};
|
|
11567
11844
|
}
|
|
11568
11845
|
if (isRefInvalidatingBatchCommand(step) && !isSafeSameSnapshotFormBatchStep(step, refSnapshot)) {
|
|
11569
11846
|
priorStepInvalidatesRefs = true;
|
|
@@ -11608,13 +11885,9 @@ function buildStaleRefPreflight(facts) {
|
|
|
11608
11885
|
includeRefsAfterBatchSnapshot: true
|
|
11609
11886
|
}))
|
|
11610
11887
|
] : guardedRefIds;
|
|
11611
|
-
const
|
|
11612
|
-
if (
|
|
11613
|
-
return
|
|
11614
|
-
message: batchInvalidationMessage,
|
|
11615
|
-
refIds: guardedRefIds,
|
|
11616
|
-
snapshot: facts.refSnapshot
|
|
11617
|
-
};
|
|
11888
|
+
const batchInvalidationFailure = getBatchRefInvalidationFailure(facts.commandTokens, facts.stdin, facts.refSnapshot);
|
|
11889
|
+
if (batchInvalidationFailure) {
|
|
11890
|
+
return batchInvalidationFailure;
|
|
11618
11891
|
}
|
|
11619
11892
|
if (usedRefIds.length === 0) {
|
|
11620
11893
|
return;
|
|
@@ -14004,6 +14277,364 @@ var init_action_recommendations = __esm({
|
|
|
14004
14277
|
}
|
|
14005
14278
|
});
|
|
14006
14279
|
|
|
14280
|
+
// dist/extensions/agent-browser/lib/electron/cdp.js
|
|
14281
|
+
function asString(value) {
|
|
14282
|
+
return typeof value === "string" && value.trim().length > 0 ? value : void 0;
|
|
14283
|
+
}
|
|
14284
|
+
function parseCdpVersion(value) {
|
|
14285
|
+
if (!isRecord(value)) {
|
|
14286
|
+
return void 0;
|
|
14287
|
+
}
|
|
14288
|
+
const browser = asString(value.Browser) ?? asString(value.browser);
|
|
14289
|
+
if (browser === void 0) {
|
|
14290
|
+
return void 0;
|
|
14291
|
+
}
|
|
14292
|
+
return {
|
|
14293
|
+
browser,
|
|
14294
|
+
protocolVersion: asString(value["Protocol-Version"]) ?? asString(value.protocolVersion),
|
|
14295
|
+
userAgent: asString(value["User-Agent"]) ?? asString(value.userAgent),
|
|
14296
|
+
v8Version: asString(value["V8-Version"]) ?? asString(value.v8Version),
|
|
14297
|
+
webKitVersion: asString(value["WebKit-Version"]) ?? asString(value.webKitVersion),
|
|
14298
|
+
webSocketDebuggerUrl: asString(value.webSocketDebuggerUrl)
|
|
14299
|
+
};
|
|
14300
|
+
}
|
|
14301
|
+
function parseCdpTargets(value) {
|
|
14302
|
+
if (!Array.isArray(value)) {
|
|
14303
|
+
return [];
|
|
14304
|
+
}
|
|
14305
|
+
return value.filter(isRecord).map((target) => ({
|
|
14306
|
+
id: asString(target.id),
|
|
14307
|
+
title: asString(target.title),
|
|
14308
|
+
type: asString(target.type),
|
|
14309
|
+
url: asString(target.url),
|
|
14310
|
+
webSocketDebuggerUrl: asString(target.webSocketDebuggerUrl)
|
|
14311
|
+
}));
|
|
14312
|
+
}
|
|
14313
|
+
async function fetchCdpJson(url, signal) {
|
|
14314
|
+
const controller = new AbortController();
|
|
14315
|
+
const timeout = setTimeout(() => controller.abort(), ELECTRON_CDP_FETCH_TIMEOUT_MS);
|
|
14316
|
+
try {
|
|
14317
|
+
const response = await fetch(url, {
|
|
14318
|
+
signal: signal ? AbortSignal.any([signal, controller.signal]) : controller.signal
|
|
14319
|
+
});
|
|
14320
|
+
if (!response.ok) {
|
|
14321
|
+
return void 0;
|
|
14322
|
+
}
|
|
14323
|
+
return await response.json();
|
|
14324
|
+
} catch {
|
|
14325
|
+
return void 0;
|
|
14326
|
+
} finally {
|
|
14327
|
+
clearTimeout(timeout);
|
|
14328
|
+
}
|
|
14329
|
+
}
|
|
14330
|
+
function boundElectronProbeString(value, maxLength = 240) {
|
|
14331
|
+
const trimmed = value?.trim();
|
|
14332
|
+
if (trimmed === void 0 || trimmed.length === 0) {
|
|
14333
|
+
return void 0;
|
|
14334
|
+
}
|
|
14335
|
+
return trimmed.length > maxLength ? `${trimmed.slice(0, Math.max(0, maxLength - 3))}...` : trimmed;
|
|
14336
|
+
}
|
|
14337
|
+
var ELECTRON_CDP_FETCH_TIMEOUT_MS;
|
|
14338
|
+
var init_cdp = __esm({
|
|
14339
|
+
"dist/extensions/agent-browser/lib/electron/cdp.js"() {
|
|
14340
|
+
"use strict";
|
|
14341
|
+
init_parsing();
|
|
14342
|
+
ELECTRON_CDP_FETCH_TIMEOUT_MS = 1e3;
|
|
14343
|
+
}
|
|
14344
|
+
});
|
|
14345
|
+
|
|
14346
|
+
// dist/extensions/agent-browser/lib/orchestration/browser-run/final-result-redaction.js
|
|
14347
|
+
function redactExactSensitiveText(text3, sensitiveValues) {
|
|
14348
|
+
let redacted = text3;
|
|
14349
|
+
for (const value of sensitiveValues) {
|
|
14350
|
+
redacted = redacted.split(value).join("[REDACTED]");
|
|
14351
|
+
}
|
|
14352
|
+
return redacted;
|
|
14353
|
+
}
|
|
14354
|
+
function redactExactSensitiveValue(value, sensitiveValues) {
|
|
14355
|
+
if (sensitiveValues.length === 0) {
|
|
14356
|
+
return value;
|
|
14357
|
+
}
|
|
14358
|
+
if (typeof value === "string") {
|
|
14359
|
+
return redactExactSensitiveText(value, sensitiveValues);
|
|
14360
|
+
}
|
|
14361
|
+
if (Array.isArray(value)) {
|
|
14362
|
+
const entries = value;
|
|
14363
|
+
return entries.map((item) => redactExactSensitiveValue(item, sensitiveValues));
|
|
14364
|
+
}
|
|
14365
|
+
if (!isRecord(value)) {
|
|
14366
|
+
return value;
|
|
14367
|
+
}
|
|
14368
|
+
return Object.fromEntries(Object.entries(value).map(([key, entryValue]) => [
|
|
14369
|
+
key,
|
|
14370
|
+
redactExactSensitiveValue(entryValue, sensitiveValues)
|
|
14371
|
+
]));
|
|
14372
|
+
}
|
|
14373
|
+
function redactToolDetails(details, sensitiveValues) {
|
|
14374
|
+
const redacted = redactSensitiveValue(redactExactSensitiveValue(details, sensitiveValues));
|
|
14375
|
+
if (!isRecord(redacted)) {
|
|
14376
|
+
throw new Error("Browser result details must remain an object after redaction.");
|
|
14377
|
+
}
|
|
14378
|
+
return redacted;
|
|
14379
|
+
}
|
|
14380
|
+
function redactRecoveryHint(recoveryHint) {
|
|
14381
|
+
if (!recoveryHint) {
|
|
14382
|
+
return void 0;
|
|
14383
|
+
}
|
|
14384
|
+
const exampleArgs = redactInvocationArgs(recoveryHint.exampleArgs);
|
|
14385
|
+
return {
|
|
14386
|
+
...recoveryHint,
|
|
14387
|
+
exampleArgs,
|
|
14388
|
+
exampleParams: { ...recoveryHint.exampleParams, args: exampleArgs }
|
|
14389
|
+
};
|
|
14390
|
+
}
|
|
14391
|
+
function buildJsonVisibleContent(options) {
|
|
14392
|
+
const { error, presentation, succeeded, warnings } = options;
|
|
14393
|
+
const payload = projectAgentBrowserObservation({
|
|
14394
|
+
...presentation,
|
|
14395
|
+
...options.details,
|
|
14396
|
+
error,
|
|
14397
|
+
warnings: warnings !== void 0 && warnings.length > 0 ? warnings : void 0
|
|
14398
|
+
}, succeeded);
|
|
14399
|
+
const images = presentation.content.filter((item) => item.type === "image");
|
|
14400
|
+
return [{ type: "text", text: JSON.stringify(payload, null, 2) }, ...images];
|
|
14401
|
+
}
|
|
14402
|
+
function warningLines(text3) {
|
|
14403
|
+
return text3 === void 0 || text3.length === 0 ? void 0 : [text3];
|
|
14404
|
+
}
|
|
14405
|
+
function contentWithWarnings(options) {
|
|
14406
|
+
if (options.userRequestedJson && !options.plainTextInspection) {
|
|
14407
|
+
return buildJsonVisibleContent({
|
|
14408
|
+
error: options.presentationEnvelope?.error,
|
|
14409
|
+
presentation: options.presentation,
|
|
14410
|
+
succeeded: options.succeeded,
|
|
14411
|
+
warnings: warningLines(options.warningText)
|
|
14412
|
+
});
|
|
14413
|
+
}
|
|
14414
|
+
const content = [...options.presentation.content];
|
|
14415
|
+
if (options.warningText === void 0 || options.warningText.length === 0 || options.userRequestedJson) {
|
|
14416
|
+
return content;
|
|
14417
|
+
}
|
|
14418
|
+
if (content[0]?.type === "text") {
|
|
14419
|
+
content[0] = { ...content[0], text: `${options.warningText}
|
|
14420
|
+
|
|
14421
|
+
${content[0].text}` };
|
|
14422
|
+
} else {
|
|
14423
|
+
content.unshift({ type: "text", text: options.warningText });
|
|
14424
|
+
}
|
|
14425
|
+
return content;
|
|
14426
|
+
}
|
|
14427
|
+
function buildRedactedPresentationContent(options) {
|
|
14428
|
+
return contentWithWarnings(options).map((item) => {
|
|
14429
|
+
if (item.type !== "text") {
|
|
14430
|
+
return item;
|
|
14431
|
+
}
|
|
14432
|
+
const text3 = options.userRequestedJson && !options.plainTextInspection ? JSON.stringify(redactExactSensitiveValue(JSON.parse(item.text), options.exactSensitiveValues), null, 2) : redactSensitiveText(redactExactSensitiveText(item.text, options.exactSensitiveValues));
|
|
14433
|
+
return { type: "text", text: text3 };
|
|
14434
|
+
});
|
|
14435
|
+
}
|
|
14436
|
+
function readJsonWarnings(content) {
|
|
14437
|
+
if (content[0]?.type !== "text") {
|
|
14438
|
+
return void 0;
|
|
14439
|
+
}
|
|
14440
|
+
const prior = JSON.parse(content[0].text);
|
|
14441
|
+
if (!isRecord(prior) || !Array.isArray(prior.warnings)) {
|
|
14442
|
+
return void 0;
|
|
14443
|
+
}
|
|
14444
|
+
const warnings = prior.warnings;
|
|
14445
|
+
return warnings;
|
|
14446
|
+
}
|
|
14447
|
+
var init_final_result_redaction = __esm({
|
|
14448
|
+
"dist/extensions/agent-browser/lib/orchestration/browser-run/final-result-redaction.js"() {
|
|
14449
|
+
"use strict";
|
|
14450
|
+
init_parsing();
|
|
14451
|
+
init_runtime_redaction();
|
|
14452
|
+
init_content();
|
|
14453
|
+
}
|
|
14454
|
+
});
|
|
14455
|
+
|
|
14456
|
+
// dist/extensions/agent-browser/lib/orchestration/browser-run/final-result-electron.js
|
|
14457
|
+
function presentElectronManagedSessionTarget(target) {
|
|
14458
|
+
return {
|
|
14459
|
+
...target,
|
|
14460
|
+
title: boundElectronProbeString(target.title, 160),
|
|
14461
|
+
url: boundElectronProbeString(target.url, 300)
|
|
14462
|
+
};
|
|
14463
|
+
}
|
|
14464
|
+
function getElectronLaunchFailureCategory(failure) {
|
|
14465
|
+
switch (failure.reason) {
|
|
14466
|
+
case "aborted":
|
|
14467
|
+
return "aborted";
|
|
14468
|
+
case "policy-blocked":
|
|
14469
|
+
return "policy-blocked";
|
|
14470
|
+
case "timeout":
|
|
14471
|
+
return "timeout";
|
|
14472
|
+
case "non-electron-target":
|
|
14473
|
+
return "validation-error";
|
|
14474
|
+
case "port-not-found":
|
|
14475
|
+
case "single-instance-conflict":
|
|
14476
|
+
case "spawn-error":
|
|
14477
|
+
return "upstream-error";
|
|
14478
|
+
}
|
|
14479
|
+
}
|
|
14480
|
+
function pidState(pidAlive) {
|
|
14481
|
+
if (pidAlive === void 0) {
|
|
14482
|
+
return "state unknown";
|
|
14483
|
+
}
|
|
14484
|
+
return pidAlive ? "alive before cleanup" : "not alive before cleanup";
|
|
14485
|
+
}
|
|
14486
|
+
function formatProcessDiagnostics(diagnostics) {
|
|
14487
|
+
const lines = [];
|
|
14488
|
+
if (diagnostics.pid !== void 0) {
|
|
14489
|
+
lines.push(`- PID: ${diagnostics.pid} (${pidState(diagnostics.pidAlive)}).`);
|
|
14490
|
+
}
|
|
14491
|
+
if (diagnostics.exitCode !== void 0 || diagnostics.exitSignal !== void 0) {
|
|
14492
|
+
const exitParts = [
|
|
14493
|
+
diagnostics.exitCode !== void 0 ? `code ${String(diagnostics.exitCode)}` : void 0,
|
|
14494
|
+
diagnostics.exitSignal !== void 0 && diagnostics.exitSignal !== null && diagnostics.exitSignal.length > 0 ? `signal ${diagnostics.exitSignal}` : void 0
|
|
14495
|
+
].filter(Boolean).join(", ");
|
|
14496
|
+
lines.push(`- Process exit: ${exitParts.length > 0 ? exitParts : "not observed before cleanup"}.`);
|
|
14497
|
+
}
|
|
14498
|
+
return lines;
|
|
14499
|
+
}
|
|
14500
|
+
function formatActivePort(activePort) {
|
|
14501
|
+
const error = activePort.error !== void 0 && activePort.error.length > 0 ? ` (${activePort.error})` : "";
|
|
14502
|
+
let state;
|
|
14503
|
+
if (activePort.port !== void 0 && activePort.port !== 0) {
|
|
14504
|
+
state = `found port ${activePort.port}`;
|
|
14505
|
+
} else {
|
|
14506
|
+
state = activePort.found ? `found but invalid${error}` : `missing${error}`;
|
|
14507
|
+
}
|
|
14508
|
+
return `- DevToolsActivePort: ${state} at ${activePort.path}.`;
|
|
14509
|
+
}
|
|
14510
|
+
function formatConnectionDiagnostics(diagnostics) {
|
|
14511
|
+
const lines = [];
|
|
14512
|
+
if (diagnostics.userDataDir !== void 0 && diagnostics.userDataDir.length > 0) {
|
|
14513
|
+
lines.push(`- Wrapper profile: ${diagnostics.userDataDir}`);
|
|
14514
|
+
}
|
|
14515
|
+
if (diagnostics.devToolsActivePort) {
|
|
14516
|
+
lines.push(formatActivePort(diagnostics.devToolsActivePort));
|
|
14517
|
+
}
|
|
14518
|
+
if (diagnostics.cdpVersionReached === false) {
|
|
14519
|
+
lines.push("- CDP /json/version: did not return a valid payload before timeout.");
|
|
14520
|
+
}
|
|
14521
|
+
if (diagnostics.timeoutMs !== void 0 || diagnostics.elapsedMs !== void 0) {
|
|
14522
|
+
lines.push(`- Timing: ${diagnostics.elapsedMs ?? "unknown"}ms elapsed${diagnostics.timeoutMs !== void 0 ? ` of ${diagnostics.timeoutMs}ms timeout` : ""}.`);
|
|
14523
|
+
}
|
|
14524
|
+
if (!diagnostics.outputCaptured) {
|
|
14525
|
+
lines.push("- App stdout/stderr: not captured by this wrapper launch path.");
|
|
14526
|
+
}
|
|
14527
|
+
return lines;
|
|
14528
|
+
}
|
|
14529
|
+
function formatElectronLaunchFailureDiagnostics(failure) {
|
|
14530
|
+
const diagnostics = failure?.diagnostics;
|
|
14531
|
+
if (!diagnostics) {
|
|
14532
|
+
return void 0;
|
|
14533
|
+
}
|
|
14534
|
+
const lines = [
|
|
14535
|
+
"Electron launch diagnostics:",
|
|
14536
|
+
...formatProcessDiagnostics(diagnostics),
|
|
14537
|
+
...formatConnectionDiagnostics(diagnostics)
|
|
14538
|
+
];
|
|
14539
|
+
if (failure.reason !== "aborted") {
|
|
14540
|
+
lines.push("Retry guidance: increase electron.timeoutMs, try targetType:'any', pass an explicit appPath/executablePath, quit any already-running singleton instance, then retry launch.");
|
|
14541
|
+
}
|
|
14542
|
+
return lines.join("\n");
|
|
14543
|
+
}
|
|
14544
|
+
function buildElectronHostFailureResult(options) {
|
|
14545
|
+
const text3 = [
|
|
14546
|
+
options.errorText,
|
|
14547
|
+
formatElectronLaunchFailureDiagnostics(options.launchFailure),
|
|
14548
|
+
options.launchFailure?.cleanupError !== void 0 && options.launchFailure.cleanupError.length > 0 ? `Electron launch cleanup warning: ${options.launchFailure.cleanupError}` : void 0
|
|
14549
|
+
].filter((item) => item !== void 0 && item.length > 0).join("\n");
|
|
14550
|
+
const details = {
|
|
14551
|
+
args: [],
|
|
14552
|
+
compiledElectron: options.compiledElectron,
|
|
14553
|
+
electron: {
|
|
14554
|
+
action: options.compiledElectron.action,
|
|
14555
|
+
error: options.errorText,
|
|
14556
|
+
failure: options.launchFailure,
|
|
14557
|
+
status: options.status ?? "failed"
|
|
14558
|
+
},
|
|
14559
|
+
managedSessionOutcome: options.managedSessionOutcome,
|
|
14560
|
+
...buildAgentBrowserResultCategoryDetails({
|
|
14561
|
+
args: [],
|
|
14562
|
+
errorText: options.errorText,
|
|
14563
|
+
failureCategory: options.failureCategory,
|
|
14564
|
+
succeeded: false,
|
|
14565
|
+
timedOut: options.failureCategory === "timeout"
|
|
14566
|
+
}),
|
|
14567
|
+
summary: options.errorText
|
|
14568
|
+
};
|
|
14569
|
+
return {
|
|
14570
|
+
content: [{ type: "text", text: redactSensitiveText(text3) }],
|
|
14571
|
+
details: redactToolDetails(details, []),
|
|
14572
|
+
isError: true
|
|
14573
|
+
};
|
|
14574
|
+
}
|
|
14575
|
+
function formatElectronTargetLines(targets, limit = 8) {
|
|
14576
|
+
const shownTargets = targets.slice(0, limit);
|
|
14577
|
+
const lines = shownTargets.map((target) => {
|
|
14578
|
+
const typeTitle = [target.type, target.title].filter(Boolean).join(" ");
|
|
14579
|
+
const fallback = target.id === void 0 || target.id.length === 0 ? "target" : target.id;
|
|
14580
|
+
const label = typeTitle.length > 0 ? typeTitle : fallback;
|
|
14581
|
+
return `- ${label}${target.url !== void 0 && target.url.length > 0 ? ` \u2014 ${target.url}` : ""}`;
|
|
14582
|
+
});
|
|
14583
|
+
if (targets.length > shownTargets.length) {
|
|
14584
|
+
lines.push(`- ... ${targets.length - shownTargets.length} more target(s) omitted`);
|
|
14585
|
+
}
|
|
14586
|
+
return lines;
|
|
14587
|
+
}
|
|
14588
|
+
function formatSnapshotHandoff(handoff) {
|
|
14589
|
+
if (handoff.refSnapshot && handoff.refSnapshot.refIds.length > 0) {
|
|
14590
|
+
const retries = handoff.snapshotRetryCount;
|
|
14591
|
+
return `Snapshot handoff: ${handoff.refSnapshot.refIds.length} interactive ref(s)${retries !== void 0 && retries !== 0 ? ` after ${retries} retry attempt(s)` : ""}.`;
|
|
14592
|
+
}
|
|
14593
|
+
return "Snapshot handoff: no interactive refs returned after a short readiness retry; run snapshot -i once more before assuming the Electron UI is unusable.";
|
|
14594
|
+
}
|
|
14595
|
+
function formatHandoffText(handoff) {
|
|
14596
|
+
switch (handoff?.handoff) {
|
|
14597
|
+
case "snapshot":
|
|
14598
|
+
return formatSnapshotHandoff(handoff);
|
|
14599
|
+
case "tabs":
|
|
14600
|
+
return "Tabs handoff completed: safer diagnostic starting point; no interactive refs were captured.";
|
|
14601
|
+
case "connect":
|
|
14602
|
+
return "Connect handoff completed: run snapshot -i before using interactive refs.";
|
|
14603
|
+
case void 0:
|
|
14604
|
+
return void 0;
|
|
14605
|
+
}
|
|
14606
|
+
}
|
|
14607
|
+
function formatElectronLaunchText(options) {
|
|
14608
|
+
const lines = [
|
|
14609
|
+
`Electron launch: ${options.record.appName} attached as ${options.record.sessionName ?? "managed session"} (launchId ${options.record.launchId}, port ${options.record.port}).`,
|
|
14610
|
+
`Identifiers: launchId ${options.record.launchId} for electron.status/electron.cleanup/electron.probe; sessionName ${options.record.sessionName ?? "not attached"} for browser snapshot/tab commands.`,
|
|
14611
|
+
"Profile note: electron.launch starts an isolated temporary profile; it does not reuse the app's normal signed-in profile or attach to an already-running authenticated app.",
|
|
14612
|
+
"For already-authenticated desktop app content, do not stop here: if host tools are allowed and the app is not running, launch the normal app with --remote-debugging-port=<port>, verify the port, then run agent_browser connect <port>; if it is already running without a debug port, ask before relaunching it.",
|
|
14613
|
+
...formatElectronTargetLines(options.targets)
|
|
14614
|
+
];
|
|
14615
|
+
const handoffText = formatHandoffText(options.handoff);
|
|
14616
|
+
if (handoffText !== void 0) {
|
|
14617
|
+
lines.push(handoffText);
|
|
14618
|
+
}
|
|
14619
|
+
lines.push(`Cleanup: use details.nextActions cleanup-electron-launch or call electron.cleanup with launchId ${options.record.launchId} when finished.`);
|
|
14620
|
+
if (options.handoff?.error !== void 0 && options.handoff.error.length > 0) {
|
|
14621
|
+
lines.push(`Handoff warning: ${options.handoff.error}`);
|
|
14622
|
+
}
|
|
14623
|
+
if (options.upstreamText.trim().length > 0) {
|
|
14624
|
+
lines.push("", options.upstreamText.trim());
|
|
14625
|
+
}
|
|
14626
|
+
return lines.join("\n");
|
|
14627
|
+
}
|
|
14628
|
+
var init_final_result_electron = __esm({
|
|
14629
|
+
"dist/extensions/agent-browser/lib/orchestration/browser-run/final-result-electron.js"() {
|
|
14630
|
+
"use strict";
|
|
14631
|
+
init_cdp();
|
|
14632
|
+
init_categories();
|
|
14633
|
+
init_runtime_redaction();
|
|
14634
|
+
init_final_result_redaction();
|
|
14635
|
+
}
|
|
14636
|
+
});
|
|
14637
|
+
|
|
14007
14638
|
// dist/extensions/agent-browser/lib/orchestration/browser-run/session-state-electron.js
|
|
14008
14639
|
function isLiveElectronRendererTarget(target) {
|
|
14009
14640
|
const normalizedUrl = normalizeComparableUrl(target.url);
|
|
@@ -14099,15 +14730,16 @@ function buildElectronSessionMismatch(options) {
|
|
|
14099
14730
|
return;
|
|
14100
14731
|
}
|
|
14101
14732
|
const nextActions = buildElectronMismatchNextActions(options.record, liveTarget);
|
|
14733
|
+
const managedSession = presentElectronManagedSessionTarget(options.managedSession);
|
|
14102
14734
|
return {
|
|
14103
14735
|
launchId: options.record.launchId,
|
|
14104
14736
|
liveTarget,
|
|
14105
|
-
managedSession
|
|
14737
|
+
managedSession,
|
|
14106
14738
|
nextActionIds: nextActions.map((action) => action.id),
|
|
14107
14739
|
reason,
|
|
14108
14740
|
sessionName: options.record.sessionName,
|
|
14109
14741
|
statusTargets: options.statusTargets,
|
|
14110
|
-
summary: describeElectronMismatch(
|
|
14742
|
+
summary: describeElectronMismatch(managedSession, options.record, liveTarget, reason)
|
|
14111
14743
|
};
|
|
14112
14744
|
}
|
|
14113
14745
|
function formatElectronSessionMismatchText(mismatch) {
|
|
@@ -14209,6 +14841,7 @@ var init_session_state_electron = __esm({
|
|
|
14209
14841
|
init_action_recommendations();
|
|
14210
14842
|
init_session_page_state();
|
|
14211
14843
|
init_session_state_refs();
|
|
14844
|
+
init_final_result_electron();
|
|
14212
14845
|
}
|
|
14213
14846
|
});
|
|
14214
14847
|
|
|
@@ -14307,68 +14940,6 @@ var init_session_state = __esm({
|
|
|
14307
14940
|
}
|
|
14308
14941
|
});
|
|
14309
14942
|
|
|
14310
|
-
// dist/extensions/agent-browser/lib/electron/cdp.js
|
|
14311
|
-
function asString(value) {
|
|
14312
|
-
return typeof value === "string" && value.trim().length > 0 ? value : void 0;
|
|
14313
|
-
}
|
|
14314
|
-
function parseCdpVersion(value) {
|
|
14315
|
-
if (!isRecord(value)) {
|
|
14316
|
-
return void 0;
|
|
14317
|
-
}
|
|
14318
|
-
return {
|
|
14319
|
-
browser: asString(value.Browser) ?? asString(value.browser),
|
|
14320
|
-
protocolVersion: asString(value["Protocol-Version"]) ?? asString(value.protocolVersion),
|
|
14321
|
-
userAgent: asString(value["User-Agent"]) ?? asString(value.userAgent),
|
|
14322
|
-
v8Version: asString(value["V8-Version"]) ?? asString(value.v8Version),
|
|
14323
|
-
webKitVersion: asString(value["WebKit-Version"]) ?? asString(value.webKitVersion),
|
|
14324
|
-
webSocketDebuggerUrl: asString(value.webSocketDebuggerUrl)
|
|
14325
|
-
};
|
|
14326
|
-
}
|
|
14327
|
-
function parseCdpTargets(value) {
|
|
14328
|
-
if (!Array.isArray(value)) {
|
|
14329
|
-
return [];
|
|
14330
|
-
}
|
|
14331
|
-
return value.filter(isRecord).map((target) => ({
|
|
14332
|
-
id: asString(target.id),
|
|
14333
|
-
title: asString(target.title),
|
|
14334
|
-
type: asString(target.type),
|
|
14335
|
-
url: asString(target.url),
|
|
14336
|
-
webSocketDebuggerUrl: asString(target.webSocketDebuggerUrl)
|
|
14337
|
-
}));
|
|
14338
|
-
}
|
|
14339
|
-
async function fetchCdpJson(url, signal) {
|
|
14340
|
-
const controller = new AbortController();
|
|
14341
|
-
const timeout = setTimeout(() => controller.abort(), ELECTRON_CDP_FETCH_TIMEOUT_MS);
|
|
14342
|
-
try {
|
|
14343
|
-
const response = await fetch(url, {
|
|
14344
|
-
signal: signal ? AbortSignal.any([signal, controller.signal]) : controller.signal
|
|
14345
|
-
});
|
|
14346
|
-
if (!response.ok) {
|
|
14347
|
-
return void 0;
|
|
14348
|
-
}
|
|
14349
|
-
return await response.json();
|
|
14350
|
-
} catch {
|
|
14351
|
-
return void 0;
|
|
14352
|
-
} finally {
|
|
14353
|
-
clearTimeout(timeout);
|
|
14354
|
-
}
|
|
14355
|
-
}
|
|
14356
|
-
function boundElectronProbeString(value, maxLength = 240) {
|
|
14357
|
-
const trimmed = value?.trim();
|
|
14358
|
-
if (trimmed === void 0 || trimmed.length === 0) {
|
|
14359
|
-
return void 0;
|
|
14360
|
-
}
|
|
14361
|
-
return trimmed.length > maxLength ? `${trimmed.slice(0, Math.max(0, maxLength - 3))}...` : trimmed;
|
|
14362
|
-
}
|
|
14363
|
-
var ELECTRON_CDP_FETCH_TIMEOUT_MS;
|
|
14364
|
-
var init_cdp = __esm({
|
|
14365
|
-
"dist/extensions/agent-browser/lib/electron/cdp.js"() {
|
|
14366
|
-
"use strict";
|
|
14367
|
-
init_parsing();
|
|
14368
|
-
ELECTRON_CDP_FETCH_TIMEOUT_MS = 1e3;
|
|
14369
|
-
}
|
|
14370
|
-
});
|
|
14371
|
-
|
|
14372
14943
|
// dist/extensions/agent-browser/lib/electron/launch-types.js
|
|
14373
14944
|
var ELECTRON_LAUNCH_RECORD_VERSION, ELECTRON_PROFILE_DIR_PREFIX;
|
|
14374
14945
|
var init_launch_types = __esm({
|
|
@@ -14380,7 +14951,7 @@ var init_launch_types = __esm({
|
|
|
14380
14951
|
});
|
|
14381
14952
|
|
|
14382
14953
|
// dist/extensions/agent-browser/lib/fs-utils.js
|
|
14383
|
-
import { access
|
|
14954
|
+
import { access } from "node:fs/promises";
|
|
14384
14955
|
async function pathExists(path) {
|
|
14385
14956
|
try {
|
|
14386
14957
|
await access(path);
|
|
@@ -14396,10 +14967,7 @@ var init_fs_utils = __esm({
|
|
|
14396
14967
|
});
|
|
14397
14968
|
|
|
14398
14969
|
// dist/extensions/agent-browser/lib/electron/cleanup.js
|
|
14399
|
-
import { execFile as execFile2 } from "node:child_process";
|
|
14400
14970
|
import { lstat as lstat2, rm as rm7 } from "node:fs/promises";
|
|
14401
|
-
import { win32 as win323 } from "node:path";
|
|
14402
|
-
import { promisify as promisify2 } from "node:util";
|
|
14403
14971
|
function sleep(ms) {
|
|
14404
14972
|
return new Promise((resolve19) => {
|
|
14405
14973
|
setTimeout(resolve19, ms);
|
|
@@ -14457,39 +15025,16 @@ async function waitForProcessExit(child, pid, deadlineMs) {
|
|
|
14457
15025
|
}
|
|
14458
15026
|
return hasProcessExited(child, pid);
|
|
14459
15027
|
}
|
|
14460
|
-
async function readPidCommandLine(pid) {
|
|
14461
|
-
if (!Number.isSafeInteger(pid) || pid <= 0) {
|
|
14462
|
-
return void 0;
|
|
14463
|
-
}
|
|
14464
|
-
try {
|
|
14465
|
-
const systemRoot = process.env.SystemRoot;
|
|
14466
|
-
const windowsRoot = systemRoot !== void 0 && systemRoot.length > 0 && win323.isAbsolute(systemRoot) ? systemRoot : "C:\\Windows";
|
|
14467
|
-
const file = process.platform === "win32" ? win323.join(windowsRoot, "System32", "WindowsPowerShell", "v1.0", "powershell.exe") : "ps";
|
|
14468
|
-
const args = process.platform === "win32" ? [
|
|
14469
|
-
"-NoProfile",
|
|
14470
|
-
"-NonInteractive",
|
|
14471
|
-
"-Command",
|
|
14472
|
-
`[Console]::OutputEncoding = [System.Text.UTF8Encoding]::new(); $p = [wmi]"Win32_Process.Handle='${pid}'"; [Console]::WriteLine($p.CommandLine)`
|
|
14473
|
-
] : ["-ww", "-p", String(pid), "-o", "command="];
|
|
14474
|
-
const { stdout } = await execFileAsync(file, args, {
|
|
14475
|
-
timeout: RESTORED_PROCESS_COMMAND_TIMEOUT_MS
|
|
14476
|
-
});
|
|
14477
|
-
const commandLine = stdout.trim();
|
|
14478
|
-
return commandLine.length === 0 ? void 0 : commandLine;
|
|
14479
|
-
} catch {
|
|
14480
|
-
return void 0;
|
|
14481
|
-
}
|
|
14482
|
-
}
|
|
14483
|
-
function restoredLaunchCommandMatchesRecord(record, commandLine) {
|
|
14484
|
-
return commandLine?.includes(`--user-data-dir=${record.userDataDir}`) === true;
|
|
14485
|
-
}
|
|
14486
15028
|
async function getRestoredProcessVerificationError(record) {
|
|
14487
|
-
|
|
14488
|
-
|
|
14489
|
-
return `PID ${String(record.pid)} is alive, but this session has no tracked child handle and its command line could not be inspected; refusing to signal a restored PID that may have been reused.`;
|
|
15029
|
+
if (record.startIdentity === void 0 || record.startIdentity.length === 0) {
|
|
15030
|
+
return `PID ${String(record.pid)} is alive, but this session has no tracked child handle or recorded start identity; refusing to signal a restored PID that may have been reused.`;
|
|
14490
15031
|
}
|
|
14491
|
-
|
|
14492
|
-
|
|
15032
|
+
const currentIdentity = record.pid === void 0 ? void 0 : await readProcessStartIdentity(record.pid);
|
|
15033
|
+
if (currentIdentity === void 0) {
|
|
15034
|
+
return `PID ${String(record.pid)} is alive, but its current start identity could not be inspected; refusing to signal a restored PID that may have been reused.`;
|
|
15035
|
+
}
|
|
15036
|
+
if (!processStartIdentitiesMatch(record.startIdentity, currentIdentity)) {
|
|
15037
|
+
return `PID ${String(record.pid)} is alive, but its start identity does not match the wrapper launch record; refusing to signal a restored PID that may have been reused.`;
|
|
14493
15038
|
}
|
|
14494
15039
|
return void 0;
|
|
14495
15040
|
}
|
|
@@ -14542,6 +15087,10 @@ async function cleanupRestoredProcess(record, deadlineMs) {
|
|
|
14542
15087
|
if (await waitForProcessExit(void 0, record.pid, deadlineMs)) {
|
|
14543
15088
|
return { resource: "process", state: "removed" };
|
|
14544
15089
|
}
|
|
15090
|
+
const killVerificationError = await getRestoredProcessVerificationError(record);
|
|
15091
|
+
if (killVerificationError !== void 0) {
|
|
15092
|
+
return { error: killVerificationError, resource: "process", state: "failed" };
|
|
15093
|
+
}
|
|
14545
15094
|
signalRestoredLaunchProcess(record, "SIGKILL");
|
|
14546
15095
|
if (await waitForProcessExit(void 0, record.pid, Date.now() + 1e3)) {
|
|
14547
15096
|
return { resource: "process", state: "removed" };
|
|
@@ -14651,7 +15200,7 @@ async function cleanupElectronLaunchResources(options) {
|
|
|
14651
15200
|
summary: summary.summary
|
|
14652
15201
|
};
|
|
14653
15202
|
}
|
|
14654
|
-
var ELECTRON_CLEANUP_DEFAULT_TIMEOUT_MS, ELECTRON_CLEANUP_POLL_INTERVAL_MS
|
|
15203
|
+
var ELECTRON_CLEANUP_DEFAULT_TIMEOUT_MS, ELECTRON_CLEANUP_POLL_INTERVAL_MS;
|
|
14655
15204
|
var init_cleanup = __esm({
|
|
14656
15205
|
"dist/extensions/agent-browser/lib/electron/cleanup.js"() {
|
|
14657
15206
|
"use strict";
|
|
@@ -14659,12 +15208,11 @@ var init_cleanup = __esm({
|
|
|
14659
15208
|
init_launch_types();
|
|
14660
15209
|
init_fs_utils();
|
|
14661
15210
|
init_parsing();
|
|
15211
|
+
init_process_identity();
|
|
14662
15212
|
init_text();
|
|
14663
15213
|
init_temp();
|
|
14664
15214
|
ELECTRON_CLEANUP_DEFAULT_TIMEOUT_MS = 5e3;
|
|
14665
15215
|
ELECTRON_CLEANUP_POLL_INTERVAL_MS = 100;
|
|
14666
|
-
RESTORED_PROCESS_COMMAND_TIMEOUT_MS = 1e3;
|
|
14667
|
-
execFileAsync = promisify2(execFile2);
|
|
14668
15216
|
}
|
|
14669
15217
|
});
|
|
14670
15218
|
|
|
@@ -15123,8 +15671,8 @@ async function publishTicket(claim) {
|
|
|
15123
15671
|
await rename2(candidate, join20(claim.path, LOCK_TICKET_FILE));
|
|
15124
15672
|
return ticket.ticket;
|
|
15125
15673
|
}
|
|
15126
|
-
function
|
|
15127
|
-
return budget.signal?.aborted === true
|
|
15674
|
+
function acquisitionCancelled(budget) {
|
|
15675
|
+
return budget.signal?.aborted === true;
|
|
15128
15676
|
}
|
|
15129
15677
|
async function waitForTurn(claim, ticket, budget, deadline) {
|
|
15130
15678
|
while (budget.signal?.aborted !== true) {
|
|
@@ -15138,7 +15686,7 @@ async function waitForTurn(claim, ticket, budget, deadline) {
|
|
|
15138
15686
|
}
|
|
15139
15687
|
if (!await anyPredecessorBlocks(claims, own, budget)) {
|
|
15140
15688
|
await cleanDeadPolicyArtifacts(claim.directory, budget);
|
|
15141
|
-
return !
|
|
15689
|
+
return !acquisitionCancelled(budget);
|
|
15142
15690
|
}
|
|
15143
15691
|
if (Date.now() >= deadline) {
|
|
15144
15692
|
return false;
|
|
@@ -15755,290 +16303,6 @@ var init_managed_session_daemon_policy = __esm({
|
|
|
15755
16303
|
}
|
|
15756
16304
|
});
|
|
15757
16305
|
|
|
15758
|
-
// dist/extensions/agent-browser/lib/orchestration/browser-run/final-result-redaction.js
|
|
15759
|
-
function redactExactSensitiveText(text3, sensitiveValues) {
|
|
15760
|
-
let redacted = text3;
|
|
15761
|
-
for (const value of sensitiveValues) {
|
|
15762
|
-
redacted = redacted.split(value).join("[REDACTED]");
|
|
15763
|
-
}
|
|
15764
|
-
return redacted;
|
|
15765
|
-
}
|
|
15766
|
-
function redactExactSensitiveValue(value, sensitiveValues) {
|
|
15767
|
-
if (sensitiveValues.length === 0) {
|
|
15768
|
-
return value;
|
|
15769
|
-
}
|
|
15770
|
-
if (typeof value === "string") {
|
|
15771
|
-
return redactExactSensitiveText(value, sensitiveValues);
|
|
15772
|
-
}
|
|
15773
|
-
if (Array.isArray(value)) {
|
|
15774
|
-
const entries = value;
|
|
15775
|
-
return entries.map((item) => redactExactSensitiveValue(item, sensitiveValues));
|
|
15776
|
-
}
|
|
15777
|
-
if (!isRecord(value)) {
|
|
15778
|
-
return value;
|
|
15779
|
-
}
|
|
15780
|
-
return Object.fromEntries(Object.entries(value).map(([key, entryValue]) => [
|
|
15781
|
-
key,
|
|
15782
|
-
redactExactSensitiveValue(entryValue, sensitiveValues)
|
|
15783
|
-
]));
|
|
15784
|
-
}
|
|
15785
|
-
function redactToolDetails(details, sensitiveValues) {
|
|
15786
|
-
const redacted = redactSensitiveValue(redactExactSensitiveValue(details, sensitiveValues));
|
|
15787
|
-
if (!isRecord(redacted)) {
|
|
15788
|
-
throw new Error("Browser result details must remain an object after redaction.");
|
|
15789
|
-
}
|
|
15790
|
-
return redacted;
|
|
15791
|
-
}
|
|
15792
|
-
function redactRecoveryHint(recoveryHint) {
|
|
15793
|
-
if (!recoveryHint) {
|
|
15794
|
-
return void 0;
|
|
15795
|
-
}
|
|
15796
|
-
const exampleArgs = redactInvocationArgs(recoveryHint.exampleArgs);
|
|
15797
|
-
return {
|
|
15798
|
-
...recoveryHint,
|
|
15799
|
-
exampleArgs,
|
|
15800
|
-
exampleParams: { ...recoveryHint.exampleParams, args: exampleArgs }
|
|
15801
|
-
};
|
|
15802
|
-
}
|
|
15803
|
-
function buildJsonVisibleContent(options) {
|
|
15804
|
-
const { error, presentation, succeeded, warnings } = options;
|
|
15805
|
-
const payload = projectAgentBrowserObservation({
|
|
15806
|
-
...presentation,
|
|
15807
|
-
...options.details,
|
|
15808
|
-
error,
|
|
15809
|
-
warnings: warnings !== void 0 && warnings.length > 0 ? warnings : void 0
|
|
15810
|
-
}, succeeded);
|
|
15811
|
-
const images = presentation.content.filter((item) => item.type === "image");
|
|
15812
|
-
return [{ type: "text", text: JSON.stringify(payload, null, 2) }, ...images];
|
|
15813
|
-
}
|
|
15814
|
-
function warningLines(text3) {
|
|
15815
|
-
return text3 === void 0 || text3.length === 0 ? void 0 : [text3];
|
|
15816
|
-
}
|
|
15817
|
-
function contentWithWarnings(options) {
|
|
15818
|
-
if (options.userRequestedJson && !options.plainTextInspection) {
|
|
15819
|
-
return buildJsonVisibleContent({
|
|
15820
|
-
error: options.presentationEnvelope?.error,
|
|
15821
|
-
presentation: options.presentation,
|
|
15822
|
-
succeeded: options.succeeded,
|
|
15823
|
-
warnings: warningLines(options.warningText)
|
|
15824
|
-
});
|
|
15825
|
-
}
|
|
15826
|
-
const content = [...options.presentation.content];
|
|
15827
|
-
if (options.warningText === void 0 || options.warningText.length === 0 || options.userRequestedJson) {
|
|
15828
|
-
return content;
|
|
15829
|
-
}
|
|
15830
|
-
if (content[0]?.type === "text") {
|
|
15831
|
-
content[0] = { ...content[0], text: `${options.warningText}
|
|
15832
|
-
|
|
15833
|
-
${content[0].text}` };
|
|
15834
|
-
} else {
|
|
15835
|
-
content.unshift({ type: "text", text: options.warningText });
|
|
15836
|
-
}
|
|
15837
|
-
return content;
|
|
15838
|
-
}
|
|
15839
|
-
function buildRedactedPresentationContent(options) {
|
|
15840
|
-
return contentWithWarnings(options).map((item) => {
|
|
15841
|
-
if (item.type !== "text") {
|
|
15842
|
-
return item;
|
|
15843
|
-
}
|
|
15844
|
-
const text3 = options.userRequestedJson && !options.plainTextInspection ? JSON.stringify(redactExactSensitiveValue(JSON.parse(item.text), options.exactSensitiveValues), null, 2) : redactSensitiveText(redactExactSensitiveText(item.text, options.exactSensitiveValues));
|
|
15845
|
-
return { type: "text", text: text3 };
|
|
15846
|
-
});
|
|
15847
|
-
}
|
|
15848
|
-
function readJsonWarnings(content) {
|
|
15849
|
-
if (content[0]?.type !== "text") {
|
|
15850
|
-
return void 0;
|
|
15851
|
-
}
|
|
15852
|
-
const prior = JSON.parse(content[0].text);
|
|
15853
|
-
if (!isRecord(prior) || !Array.isArray(prior.warnings)) {
|
|
15854
|
-
return void 0;
|
|
15855
|
-
}
|
|
15856
|
-
const warnings = prior.warnings;
|
|
15857
|
-
return warnings;
|
|
15858
|
-
}
|
|
15859
|
-
var init_final_result_redaction = __esm({
|
|
15860
|
-
"dist/extensions/agent-browser/lib/orchestration/browser-run/final-result-redaction.js"() {
|
|
15861
|
-
"use strict";
|
|
15862
|
-
init_parsing();
|
|
15863
|
-
init_runtime_redaction();
|
|
15864
|
-
init_content();
|
|
15865
|
-
}
|
|
15866
|
-
});
|
|
15867
|
-
|
|
15868
|
-
// dist/extensions/agent-browser/lib/orchestration/browser-run/final-result-electron.js
|
|
15869
|
-
function getElectronLaunchFailureCategory(failure) {
|
|
15870
|
-
switch (failure.reason) {
|
|
15871
|
-
case "aborted":
|
|
15872
|
-
return "aborted";
|
|
15873
|
-
case "policy-blocked":
|
|
15874
|
-
return "policy-blocked";
|
|
15875
|
-
case "timeout":
|
|
15876
|
-
return "timeout";
|
|
15877
|
-
case "non-electron-target":
|
|
15878
|
-
return "validation-error";
|
|
15879
|
-
case "port-not-found":
|
|
15880
|
-
case "single-instance-conflict":
|
|
15881
|
-
case "spawn-error":
|
|
15882
|
-
return "upstream-error";
|
|
15883
|
-
}
|
|
15884
|
-
}
|
|
15885
|
-
function pidState(pidAlive) {
|
|
15886
|
-
if (pidAlive === void 0) {
|
|
15887
|
-
return "state unknown";
|
|
15888
|
-
}
|
|
15889
|
-
return pidAlive ? "alive before cleanup" : "not alive before cleanup";
|
|
15890
|
-
}
|
|
15891
|
-
function formatProcessDiagnostics(diagnostics) {
|
|
15892
|
-
const lines = [];
|
|
15893
|
-
if (diagnostics.pid !== void 0) {
|
|
15894
|
-
lines.push(`- PID: ${diagnostics.pid} (${pidState(diagnostics.pidAlive)}).`);
|
|
15895
|
-
}
|
|
15896
|
-
if (diagnostics.exitCode !== void 0 || diagnostics.exitSignal !== void 0) {
|
|
15897
|
-
const exitParts = [
|
|
15898
|
-
diagnostics.exitCode !== void 0 ? `code ${String(diagnostics.exitCode)}` : void 0,
|
|
15899
|
-
diagnostics.exitSignal !== void 0 && diagnostics.exitSignal !== null && diagnostics.exitSignal.length > 0 ? `signal ${diagnostics.exitSignal}` : void 0
|
|
15900
|
-
].filter(Boolean).join(", ");
|
|
15901
|
-
lines.push(`- Process exit: ${exitParts.length > 0 ? exitParts : "not observed before cleanup"}.`);
|
|
15902
|
-
}
|
|
15903
|
-
return lines;
|
|
15904
|
-
}
|
|
15905
|
-
function formatActivePort(activePort) {
|
|
15906
|
-
const error = activePort.error !== void 0 && activePort.error.length > 0 ? ` (${activePort.error})` : "";
|
|
15907
|
-
let state;
|
|
15908
|
-
if (activePort.port !== void 0 && activePort.port !== 0) {
|
|
15909
|
-
state = `found port ${activePort.port}`;
|
|
15910
|
-
} else {
|
|
15911
|
-
state = activePort.found ? `found but invalid${error}` : `missing${error}`;
|
|
15912
|
-
}
|
|
15913
|
-
return `- DevToolsActivePort: ${state} at ${activePort.path}.`;
|
|
15914
|
-
}
|
|
15915
|
-
function formatConnectionDiagnostics(diagnostics) {
|
|
15916
|
-
const lines = [];
|
|
15917
|
-
if (diagnostics.userDataDir !== void 0 && diagnostics.userDataDir.length > 0) {
|
|
15918
|
-
lines.push(`- Wrapper profile: ${diagnostics.userDataDir}`);
|
|
15919
|
-
}
|
|
15920
|
-
if (diagnostics.devToolsActivePort) {
|
|
15921
|
-
lines.push(formatActivePort(diagnostics.devToolsActivePort));
|
|
15922
|
-
}
|
|
15923
|
-
if (diagnostics.cdpVersionReached === false) {
|
|
15924
|
-
lines.push("- CDP /json/version: did not return a valid payload before timeout.");
|
|
15925
|
-
}
|
|
15926
|
-
if (diagnostics.timeoutMs !== void 0 || diagnostics.elapsedMs !== void 0) {
|
|
15927
|
-
lines.push(`- Timing: ${diagnostics.elapsedMs ?? "unknown"}ms elapsed${diagnostics.timeoutMs !== void 0 ? ` of ${diagnostics.timeoutMs}ms timeout` : ""}.`);
|
|
15928
|
-
}
|
|
15929
|
-
if (!diagnostics.outputCaptured) {
|
|
15930
|
-
lines.push("- App stdout/stderr: not captured by this wrapper launch path.");
|
|
15931
|
-
}
|
|
15932
|
-
return lines;
|
|
15933
|
-
}
|
|
15934
|
-
function formatElectronLaunchFailureDiagnostics(failure) {
|
|
15935
|
-
const diagnostics = failure?.diagnostics;
|
|
15936
|
-
if (!diagnostics) {
|
|
15937
|
-
return void 0;
|
|
15938
|
-
}
|
|
15939
|
-
const lines = [
|
|
15940
|
-
"Electron launch diagnostics:",
|
|
15941
|
-
...formatProcessDiagnostics(diagnostics),
|
|
15942
|
-
...formatConnectionDiagnostics(diagnostics)
|
|
15943
|
-
];
|
|
15944
|
-
if (failure.reason !== "aborted") {
|
|
15945
|
-
lines.push("Retry guidance: increase electron.timeoutMs, try targetType:'any', pass an explicit appPath/executablePath, quit any already-running singleton instance, then retry launch.");
|
|
15946
|
-
}
|
|
15947
|
-
return lines.join("\n");
|
|
15948
|
-
}
|
|
15949
|
-
function buildElectronHostFailureResult(options) {
|
|
15950
|
-
const text3 = [
|
|
15951
|
-
options.errorText,
|
|
15952
|
-
formatElectronLaunchFailureDiagnostics(options.launchFailure),
|
|
15953
|
-
options.launchFailure?.cleanupError !== void 0 && options.launchFailure.cleanupError.length > 0 ? `Electron launch cleanup warning: ${options.launchFailure.cleanupError}` : void 0
|
|
15954
|
-
].filter((item) => item !== void 0 && item.length > 0).join("\n");
|
|
15955
|
-
const details = {
|
|
15956
|
-
args: [],
|
|
15957
|
-
compiledElectron: options.compiledElectron,
|
|
15958
|
-
electron: {
|
|
15959
|
-
action: options.compiledElectron.action,
|
|
15960
|
-
error: options.errorText,
|
|
15961
|
-
failure: options.launchFailure,
|
|
15962
|
-
status: options.status ?? "failed"
|
|
15963
|
-
},
|
|
15964
|
-
managedSessionOutcome: options.managedSessionOutcome,
|
|
15965
|
-
...buildAgentBrowserResultCategoryDetails({
|
|
15966
|
-
args: [],
|
|
15967
|
-
errorText: options.errorText,
|
|
15968
|
-
failureCategory: options.failureCategory,
|
|
15969
|
-
succeeded: false,
|
|
15970
|
-
timedOut: options.failureCategory === "timeout"
|
|
15971
|
-
}),
|
|
15972
|
-
summary: options.errorText
|
|
15973
|
-
};
|
|
15974
|
-
return {
|
|
15975
|
-
content: [{ type: "text", text: redactSensitiveText(text3) }],
|
|
15976
|
-
details: redactToolDetails(details, []),
|
|
15977
|
-
isError: true
|
|
15978
|
-
};
|
|
15979
|
-
}
|
|
15980
|
-
function formatElectronTargetLines(targets, limit = 8) {
|
|
15981
|
-
const shownTargets = targets.slice(0, limit);
|
|
15982
|
-
const lines = shownTargets.map((target) => {
|
|
15983
|
-
const typeTitle = [target.type, target.title].filter(Boolean).join(" ");
|
|
15984
|
-
const fallback = target.id === void 0 || target.id.length === 0 ? "target" : target.id;
|
|
15985
|
-
const label = typeTitle.length > 0 ? typeTitle : fallback;
|
|
15986
|
-
return `- ${label}${target.url !== void 0 && target.url.length > 0 ? ` \u2014 ${target.url}` : ""}`;
|
|
15987
|
-
});
|
|
15988
|
-
if (targets.length > shownTargets.length) {
|
|
15989
|
-
lines.push(`- ... ${targets.length - shownTargets.length} more target(s) omitted`);
|
|
15990
|
-
}
|
|
15991
|
-
return lines;
|
|
15992
|
-
}
|
|
15993
|
-
function formatSnapshotHandoff(handoff) {
|
|
15994
|
-
if (handoff.refSnapshot && handoff.refSnapshot.refIds.length > 0) {
|
|
15995
|
-
const retries = handoff.snapshotRetryCount;
|
|
15996
|
-
return `Snapshot handoff: ${handoff.refSnapshot.refIds.length} interactive ref(s)${retries !== void 0 && retries !== 0 ? ` after ${retries} retry attempt(s)` : ""}.`;
|
|
15997
|
-
}
|
|
15998
|
-
return "Snapshot handoff: no interactive refs returned after a short readiness retry; run snapshot -i once more before assuming the Electron UI is unusable.";
|
|
15999
|
-
}
|
|
16000
|
-
function formatHandoffText(handoff) {
|
|
16001
|
-
switch (handoff?.handoff) {
|
|
16002
|
-
case "snapshot":
|
|
16003
|
-
return formatSnapshotHandoff(handoff);
|
|
16004
|
-
case "tabs":
|
|
16005
|
-
return "Tabs handoff completed: safer diagnostic starting point; no interactive refs were captured.";
|
|
16006
|
-
case "connect":
|
|
16007
|
-
return "Connect handoff completed: run snapshot -i before using interactive refs.";
|
|
16008
|
-
case void 0:
|
|
16009
|
-
return void 0;
|
|
16010
|
-
}
|
|
16011
|
-
}
|
|
16012
|
-
function formatElectronLaunchText(options) {
|
|
16013
|
-
const lines = [
|
|
16014
|
-
`Electron launch: ${options.record.appName} attached as ${options.record.sessionName ?? "managed session"} (launchId ${options.record.launchId}, port ${options.record.port}).`,
|
|
16015
|
-
`Identifiers: launchId ${options.record.launchId} for electron.status/electron.cleanup/electron.probe; sessionName ${options.record.sessionName ?? "not attached"} for browser snapshot/tab commands.`,
|
|
16016
|
-
"Profile note: electron.launch starts an isolated temporary profile; it does not reuse the app's normal signed-in profile or attach to an already-running authenticated app.",
|
|
16017
|
-
"For already-authenticated desktop app content, do not stop here: if host tools are allowed and the app is not running, launch the normal app with --remote-debugging-port=<port>, verify the port, then run agent_browser connect <port>; if it is already running without a debug port, ask before relaunching it.",
|
|
16018
|
-
...formatElectronTargetLines(options.targets)
|
|
16019
|
-
];
|
|
16020
|
-
const handoffText = formatHandoffText(options.handoff);
|
|
16021
|
-
if (handoffText !== void 0) {
|
|
16022
|
-
lines.push(handoffText);
|
|
16023
|
-
}
|
|
16024
|
-
lines.push(`Cleanup: use details.nextActions cleanup-electron-launch or call electron.cleanup with launchId ${options.record.launchId} when finished.`);
|
|
16025
|
-
if (options.handoff?.error !== void 0 && options.handoff.error.length > 0) {
|
|
16026
|
-
lines.push(`Handoff warning: ${options.handoff.error}`);
|
|
16027
|
-
}
|
|
16028
|
-
if (options.upstreamText.trim().length > 0) {
|
|
16029
|
-
lines.push("", options.upstreamText.trim());
|
|
16030
|
-
}
|
|
16031
|
-
return lines.join("\n");
|
|
16032
|
-
}
|
|
16033
|
-
var init_final_result_electron = __esm({
|
|
16034
|
-
"dist/extensions/agent-browser/lib/orchestration/browser-run/final-result-electron.js"() {
|
|
16035
|
-
"use strict";
|
|
16036
|
-
init_categories();
|
|
16037
|
-
init_runtime_redaction();
|
|
16038
|
-
init_final_result_redaction();
|
|
16039
|
-
}
|
|
16040
|
-
});
|
|
16041
|
-
|
|
16042
16306
|
// dist/extensions/agent-browser/lib/orchestration/electron-host/branch.js
|
|
16043
16307
|
function isLaunchIdentity(value) {
|
|
16044
16308
|
return value.version === 1 && value.launchedByWrapper === true && typeof value.launchId === "string" && typeof value.appName === "string" && typeof value.executablePath === "string" && typeof value.userDataDir === "string" && typeof value.port === "number" && typeof value.createdAtMs === "number";
|
|
@@ -16053,6 +16317,7 @@ function hasValidOptionalFields(value) {
|
|
|
16053
16317
|
"packageSource",
|
|
16054
16318
|
"platform",
|
|
16055
16319
|
"sessionName",
|
|
16320
|
+
"startIdentity",
|
|
16056
16321
|
"webSocketDebuggerUrl"
|
|
16057
16322
|
];
|
|
16058
16323
|
return strings.every((field) => value[field] === void 0 || typeof value[field] === "string") && ["pid", "processGroupId"].every((field) => value[field] === void 0 || typeof value[field] === "number");
|
|
@@ -16128,25 +16393,25 @@ var init_branch = __esm({
|
|
|
16128
16393
|
|
|
16129
16394
|
// dist/extensions/agent-browser/lib/electron/discovery-evidence.js
|
|
16130
16395
|
import { constants as fsConstants } from "node:fs";
|
|
16131
|
-
import { access as access2, readdir as readdir7, realpath as realpath2, stat as
|
|
16396
|
+
import { access as access2, readdir as readdir7, realpath as realpath2, stat as stat9 } from "node:fs/promises";
|
|
16132
16397
|
import { basename as basename6, dirname as dirname12, extname as extname4, join as join21 } from "node:path";
|
|
16133
16398
|
async function isDirectory(path) {
|
|
16134
16399
|
try {
|
|
16135
|
-
return (await
|
|
16400
|
+
return (await stat9(path)).isDirectory();
|
|
16136
16401
|
} catch {
|
|
16137
16402
|
return false;
|
|
16138
16403
|
}
|
|
16139
16404
|
}
|
|
16140
16405
|
async function isFile(path) {
|
|
16141
16406
|
try {
|
|
16142
|
-
return (await
|
|
16407
|
+
return (await stat9(path)).isFile();
|
|
16143
16408
|
} catch {
|
|
16144
16409
|
return false;
|
|
16145
16410
|
}
|
|
16146
16411
|
}
|
|
16147
16412
|
async function isExecutableFile(path) {
|
|
16148
16413
|
try {
|
|
16149
|
-
if (!(await
|
|
16414
|
+
if (!(await stat9(path)).isFile()) {
|
|
16150
16415
|
return false;
|
|
16151
16416
|
}
|
|
16152
16417
|
await access2(path, fsConstants.X_OK);
|
|
@@ -16171,7 +16436,7 @@ async function directoryContainsChromePak(directory) {
|
|
|
16171
16436
|
}
|
|
16172
16437
|
}
|
|
16173
16438
|
async function hasElectronAppPayload(resourcesDirectory) {
|
|
16174
|
-
return await pathExists(join21(resourcesDirectory, "app.asar")) || await isDirectory(join21(resourcesDirectory, "app"));
|
|
16439
|
+
return await pathExists(join21(resourcesDirectory, "app.asar")) || await pathExists(join21(resourcesDirectory, "default_app.asar")) || await isDirectory(join21(resourcesDirectory, "app"));
|
|
16175
16440
|
}
|
|
16176
16441
|
async function hasLinuxElectronEvidence(executablePath) {
|
|
16177
16442
|
const resolved = await resolveRealPath(executablePath);
|
|
@@ -18936,7 +19201,7 @@ var init_final_result_actions = __esm({
|
|
|
18936
19201
|
});
|
|
18937
19202
|
|
|
18938
19203
|
// dist/extensions/agent-browser/lib/orchestration/browser-run/timeout-diagnostics.js
|
|
18939
|
-
import { stat as
|
|
19204
|
+
import { stat as stat10 } from "node:fs/promises";
|
|
18940
19205
|
import { isAbsolute as isAbsolute8, resolve as resolve11 } from "node:path";
|
|
18941
19206
|
import { setTimeout as sleepMs } from "node:timers/promises";
|
|
18942
19207
|
function getTimeoutProgressSteps(options) {
|
|
@@ -18971,7 +19236,7 @@ function getTimeoutStepArtifactPath(commandTokens) {
|
|
|
18971
19236
|
async function statTimeoutArtifactPath(absolutePath) {
|
|
18972
19237
|
for (let attempt = 0; attempt < 3; attempt += 1) {
|
|
18973
19238
|
try {
|
|
18974
|
-
const stats = await
|
|
19239
|
+
const stats = await stat10(absolutePath);
|
|
18975
19240
|
return { exists: true, sizeBytes: stats.size };
|
|
18976
19241
|
} catch {
|
|
18977
19242
|
if (attempt < 2) {
|
|
@@ -19180,12 +19445,12 @@ var init_timeout_diagnostics = __esm({
|
|
|
19180
19445
|
|
|
19181
19446
|
// dist/extensions/agent-browser/lib/executable-path.js
|
|
19182
19447
|
import { constants as fsConstants2 } from "node:fs";
|
|
19183
|
-
import { access as access3, stat as
|
|
19448
|
+
import { access as access3, stat as stat11 } from "node:fs/promises";
|
|
19184
19449
|
import { delimiter, join as join26 } from "node:path";
|
|
19185
19450
|
async function isExecutableFile2(candidate) {
|
|
19186
19451
|
try {
|
|
19187
19452
|
await access3(candidate, fsConstants2.X_OK);
|
|
19188
|
-
return (await
|
|
19453
|
+
return (await stat11(candidate)).isFile();
|
|
19189
19454
|
} catch {
|
|
19190
19455
|
return false;
|
|
19191
19456
|
}
|
|
@@ -19208,8 +19473,8 @@ var init_executable_path = __esm({
|
|
|
19208
19473
|
|
|
19209
19474
|
// dist/extensions/agent-browser/lib/orchestration/browser-run/electron-observation.js
|
|
19210
19475
|
import { setTimeout as sleepMs2 } from "node:timers/promises";
|
|
19211
|
-
function
|
|
19212
|
-
return
|
|
19476
|
+
function sessionResult(data, field) {
|
|
19477
|
+
return extractStringResultField2(data, "result") ?? extractStringResultField2(data, field);
|
|
19213
19478
|
}
|
|
19214
19479
|
async function collectManagedSessionCommandData(options) {
|
|
19215
19480
|
try {
|
|
@@ -19220,7 +19485,7 @@ async function collectManagedSessionCommandData(options) {
|
|
|
19220
19485
|
}
|
|
19221
19486
|
async function collectElectronManagedSessionUrl(options) {
|
|
19222
19487
|
const urlResult = await collectManagedSessionCommandData({ ...options, args: ["get", "url"] });
|
|
19223
|
-
const url =
|
|
19488
|
+
const url = sessionResult(urlResult.data, "url");
|
|
19224
19489
|
return urlResult.error !== void 0 && urlResult.error !== "" ? { error: urlResult.error } : { url };
|
|
19225
19490
|
}
|
|
19226
19491
|
async function collectElectronManagedSessionTarget(options) {
|
|
@@ -19229,8 +19494,8 @@ async function collectElectronManagedSessionTarget(options) {
|
|
|
19229
19494
|
}
|
|
19230
19495
|
const request = { ...options, sessionName: options.sessionName };
|
|
19231
19496
|
const urlResult = await collectManagedSessionCommandData({ ...request, args: ["get", "url"] });
|
|
19232
|
-
const url =
|
|
19233
|
-
if ((urlResult.error ?? "") !== "" || url === void 0 || url === "") {
|
|
19497
|
+
const url = sessionResult(urlResult.data, "url");
|
|
19498
|
+
if ((urlResult.error ?? "") !== "" || url === void 0 || url.trim() === "") {
|
|
19234
19499
|
return {
|
|
19235
19500
|
error: urlResult.error ?? "get url returned no active page URL.",
|
|
19236
19501
|
sessionName: options.sessionName
|
|
@@ -19240,7 +19505,7 @@ async function collectElectronManagedSessionTarget(options) {
|
|
|
19240
19505
|
...request,
|
|
19241
19506
|
args: ["get", "title"]
|
|
19242
19507
|
});
|
|
19243
|
-
const title =
|
|
19508
|
+
const title = boundElectronProbeString(sessionResult(titleResult.data, "title"), 160);
|
|
19244
19509
|
return {
|
|
19245
19510
|
sessionName: options.sessionName,
|
|
19246
19511
|
title,
|
|
@@ -19260,12 +19525,13 @@ async function collectQaAttachedTarget(options) {
|
|
|
19260
19525
|
url: target.url
|
|
19261
19526
|
};
|
|
19262
19527
|
}
|
|
19263
|
-
|
|
19528
|
+
const observed = await collectElectronManagedSessionTarget({
|
|
19264
19529
|
cwd: options.cwd,
|
|
19265
19530
|
namespace: options.namespace,
|
|
19266
19531
|
sessionName: options.sessionName,
|
|
19267
19532
|
signal: options.signal
|
|
19268
19533
|
});
|
|
19534
|
+
return observed ? presentElectronManagedSessionTarget(observed) : void 0;
|
|
19269
19535
|
}
|
|
19270
19536
|
function formatQaAttachedTargetText(target) {
|
|
19271
19537
|
return target ? ["QA attached target:", target.sessionName, target.title, target.url].filter((part) => typeof part === "string" && part.length > 0).join(" \u2014 ") : void 0;
|
|
@@ -19394,11 +19660,12 @@ var init_electron_observation = __esm({
|
|
|
19394
19660
|
init_session_page_state();
|
|
19395
19661
|
init_session_state();
|
|
19396
19662
|
init_diagnostic_values();
|
|
19663
|
+
init_final_result_electron();
|
|
19397
19664
|
}
|
|
19398
19665
|
});
|
|
19399
19666
|
|
|
19400
19667
|
// dist/extensions/agent-browser/lib/orchestration/browser-run/diagnostics.js
|
|
19401
|
-
import { stat as
|
|
19668
|
+
import { stat as stat12 } from "node:fs/promises";
|
|
19402
19669
|
import { setTimeout as sleepMs3 } from "node:timers/promises";
|
|
19403
19670
|
import { isAbsolute as isAbsolute9, resolve as resolve12 } from "node:path";
|
|
19404
19671
|
function comparePriorNavigationUrl(priorUrl, url) {
|
|
@@ -19541,7 +19808,7 @@ async function collectExistingExplicitArtifactPaths(entries, cwd) {
|
|
|
19541
19808
|
}
|
|
19542
19809
|
const absolutePath = entry.absolutePath ?? (isAbsolute9(entry.path) ? entry.path : resolve12(cwd, entry.path));
|
|
19543
19810
|
try {
|
|
19544
|
-
await
|
|
19811
|
+
await stat12(absolutePath);
|
|
19545
19812
|
} catch {
|
|
19546
19813
|
continue;
|
|
19547
19814
|
}
|
|
@@ -20312,6 +20579,7 @@ function statusNextActions(options) {
|
|
|
20312
20579
|
}
|
|
20313
20580
|
function buildElectronStatusResult(options) {
|
|
20314
20581
|
const nextActions = statusNextActions(options);
|
|
20582
|
+
const managedSessions = options.managedSessions.map(presentElectronManagedSessionTarget);
|
|
20315
20583
|
const soleRecord = options.records.length === 1 ? options.records[0] : void 0;
|
|
20316
20584
|
const details = {
|
|
20317
20585
|
args: [],
|
|
@@ -20321,8 +20589,8 @@ function buildElectronStatusResult(options) {
|
|
|
20321
20589
|
identifierList: options.records.length > 1 ? options.records.map(buildElectronIdentifiers) : void 0,
|
|
20322
20590
|
identifiers: soleRecord ? buildElectronIdentifiers(soleRecord) : void 0,
|
|
20323
20591
|
launches: options.records,
|
|
20324
|
-
managedSession:
|
|
20325
|
-
managedSessions:
|
|
20592
|
+
managedSession: managedSessions.length === 1 ? managedSessions[0] : void 0,
|
|
20593
|
+
managedSessions: managedSessions.length > 0 ? managedSessions : void 0,
|
|
20326
20594
|
sessionMismatch: options.mismatches.length === 1 ? options.mismatches[0] : void 0,
|
|
20327
20595
|
sessionMismatches: options.mismatches.length > 1 ? options.mismatches : void 0,
|
|
20328
20596
|
status: "succeeded",
|
|
@@ -20405,6 +20673,7 @@ var init_status = __esm({
|
|
|
20405
20673
|
init_session_state();
|
|
20406
20674
|
init_branch();
|
|
20407
20675
|
init_policy();
|
|
20676
|
+
init_final_result_electron();
|
|
20408
20677
|
}
|
|
20409
20678
|
});
|
|
20410
20679
|
|
|
@@ -20459,7 +20728,7 @@ function extractElectronProbeTabs(data) {
|
|
|
20459
20728
|
tabId: getTrimmedString(tab.tabId) ?? getTrimmedString(tab.id),
|
|
20460
20729
|
title: getTrimmedString(tab.title) ?? getTrimmedString(tab.label),
|
|
20461
20730
|
type: getTrimmedString(tab.type),
|
|
20462
|
-
url:
|
|
20731
|
+
url: typeof tab.url === "string" ? tab.url : void 0
|
|
20463
20732
|
}));
|
|
20464
20733
|
if (allTabs.length === 0) {
|
|
20465
20734
|
return {};
|
|
@@ -20521,7 +20790,7 @@ function summarizeElectronProbeSnapshot(data) {
|
|
|
20521
20790
|
function getElectronProbeSummary(probe) {
|
|
20522
20791
|
const parts = [
|
|
20523
20792
|
probe.title !== void 0 && probe.title.length > 0 ? `title "${probe.title}"` : void 0,
|
|
20524
|
-
probe.url !== void 0 && probe.url.length > 0 ? `url ${probe.url}` : void 0,
|
|
20793
|
+
probe.url !== void 0 && probe.url.length > 0 ? `url ${boundElectronProbeString(probe.url, 300) ?? ""}` : void 0,
|
|
20525
20794
|
probe.focusedElement ? "focused element" : void 0,
|
|
20526
20795
|
probe.tabs ? `${probe.tabs.total} tab(s)` : void 0,
|
|
20527
20796
|
probe.snapshot ? `${probe.snapshot.refCount} ref(s)` : void 0
|
|
@@ -20588,17 +20857,14 @@ async function runElectronProbeCommandData(options) {
|
|
|
20588
20857
|
function probeCommandError(result, label) {
|
|
20589
20858
|
return result.error !== void 0 && result.error.length > 0 ? `${label}: ${result.error}` : void 0;
|
|
20590
20859
|
}
|
|
20591
|
-
function probeString(data, field, limit) {
|
|
20592
|
-
return boundElectronProbeString(extractStringResultField2(data, "result") ?? extractStringResultField2(data, field), limit);
|
|
20593
|
-
}
|
|
20594
20860
|
async function collectElectronProbe(options) {
|
|
20595
20861
|
const urlResult = await runElectronProbeCommandData({ ...options, args: ["get", "url"] });
|
|
20596
20862
|
const urlError = probeCommandError(urlResult, "get url");
|
|
20597
20863
|
if (urlError !== void 0) {
|
|
20598
20864
|
throw new Error(urlError);
|
|
20599
20865
|
}
|
|
20600
|
-
const url =
|
|
20601
|
-
if (url === void 0 || url.length === 0) {
|
|
20866
|
+
const url = extractStringResultField2(urlResult.data, "result") ?? extractStringResultField2(urlResult.data, "url");
|
|
20867
|
+
if (url === void 0 || url.trim().length === 0) {
|
|
20602
20868
|
throw new Error("get url returned no active page URL.");
|
|
20603
20869
|
}
|
|
20604
20870
|
const titleResult = await runElectronProbeCommandData({ ...options, args: ["get", "title"] });
|
|
@@ -20629,7 +20895,7 @@ async function collectElectronProbe(options) {
|
|
|
20629
20895
|
snapshot,
|
|
20630
20896
|
status: errors.length === 0 ? "succeeded" : "partial",
|
|
20631
20897
|
tabs,
|
|
20632
|
-
title:
|
|
20898
|
+
title: boundElectronProbeString(extractStringResultField2(titleResult.data, "result") ?? extractStringResultField2(titleResult.data, "title"), 160),
|
|
20633
20899
|
url
|
|
20634
20900
|
};
|
|
20635
20901
|
return { ...probe, summary: getElectronProbeSummary(probe) };
|
|
@@ -20645,6 +20911,17 @@ var init_probe_collection = __esm({
|
|
|
20645
20911
|
});
|
|
20646
20912
|
|
|
20647
20913
|
// dist/extensions/agent-browser/lib/orchestration/electron-host/probe-presentation.js
|
|
20914
|
+
function presentProbeTab(tab) {
|
|
20915
|
+
return { ...tab, url: boundElectronProbeString(tab.url) };
|
|
20916
|
+
}
|
|
20917
|
+
function presentProbe(probe) {
|
|
20918
|
+
return {
|
|
20919
|
+
...probe,
|
|
20920
|
+
activeTab: probe.activeTab ? presentProbeTab(probe.activeTab) : void 0,
|
|
20921
|
+
tabs: probe.tabs ? { ...probe.tabs, shown: probe.tabs.shown.map(presentProbeTab) } : void 0,
|
|
20922
|
+
url: boundElectronProbeString(probe.url, 300)
|
|
20923
|
+
};
|
|
20924
|
+
}
|
|
20648
20925
|
function presentStrings(values) {
|
|
20649
20926
|
return values.filter((value) => value !== void 0 && value.length > 0);
|
|
20650
20927
|
}
|
|
@@ -20757,7 +21034,8 @@ function probeNextActions(options) {
|
|
|
20757
21034
|
return options.mismatch ? appendUniqueAgentBrowserNextActions([...mismatch], base) : appendUniqueAgentBrowserNextActions([...base], mismatch);
|
|
20758
21035
|
}
|
|
20759
21036
|
function buildElectronProbeResult(options) {
|
|
20760
|
-
const
|
|
21037
|
+
const probe = presentProbe(options.probe);
|
|
21038
|
+
const { refSnapshot: _refSnapshot, ...boundedProbe } = probe;
|
|
20761
21039
|
const nextActions = probeNextActions(options);
|
|
20762
21040
|
const details = {
|
|
20763
21041
|
args: [],
|
|
@@ -20784,7 +21062,12 @@ function buildElectronProbeResult(options) {
|
|
|
20784
21062
|
usedImplicitSession: options.probeContext.mode === "current-managed-session"
|
|
20785
21063
|
};
|
|
20786
21064
|
return {
|
|
20787
|
-
content: [
|
|
21065
|
+
content: [
|
|
21066
|
+
{
|
|
21067
|
+
type: "text",
|
|
21068
|
+
text: redactSensitiveText(formatElectronProbeVisibleText({ ...options, probe }))
|
|
21069
|
+
}
|
|
21070
|
+
],
|
|
20788
21071
|
details: redactToolDetails(details, []),
|
|
20789
21072
|
isError: false
|
|
20790
21073
|
};
|
|
@@ -20792,6 +21075,7 @@ function buildElectronProbeResult(options) {
|
|
|
20792
21075
|
var init_probe_presentation = __esm({
|
|
20793
21076
|
"dist/extensions/agent-browser/lib/orchestration/electron-host/probe-presentation.js"() {
|
|
20794
21077
|
"use strict";
|
|
21078
|
+
init_cdp();
|
|
20795
21079
|
init_action_recommendations();
|
|
20796
21080
|
init_categories();
|
|
20797
21081
|
init_next_actions();
|
|
@@ -20967,253 +21251,6 @@ var init_probe = __esm({
|
|
|
20967
21251
|
}
|
|
20968
21252
|
});
|
|
20969
21253
|
|
|
20970
|
-
// dist/extensions/agent-browser/lib/results/presentation/diagnostic-storage.js
|
|
20971
|
-
function storageTextContainsSecret(text3) {
|
|
20972
|
-
if (STORAGE_TOKEN_VALUE_PATTERN.test(text3) || STORAGE_SECRET_VALUE_WORD_PATTERN.test(text3) || STORAGE_EMAIL_VALUE_PATTERN.test(text3) || STORAGE_IDENTITY_VALUE_PATTERN.test(text3)) {
|
|
20973
|
-
return true;
|
|
20974
|
-
}
|
|
20975
|
-
if (storageTextIsSensitiveUrl(text3) || redactSensitiveText(text3) !== text3) {
|
|
20976
|
-
return true;
|
|
20977
|
-
}
|
|
20978
|
-
try {
|
|
20979
|
-
const parsed = JSON.parse(text3);
|
|
20980
|
-
return valueContainsStorageSecret(parsed);
|
|
20981
|
-
} catch {
|
|
20982
|
-
return false;
|
|
20983
|
-
}
|
|
20984
|
-
}
|
|
20985
|
-
function storageTextIsSensitiveUrl(text3) {
|
|
20986
|
-
try {
|
|
20987
|
-
const url = new URL(text3);
|
|
20988
|
-
return url.protocol === "http:" || url.protocol === "https:" || url.username.length > 0 || url.password.length > 0 || url.search.length > 0;
|
|
20989
|
-
} catch {
|
|
20990
|
-
return false;
|
|
20991
|
-
}
|
|
20992
|
-
}
|
|
20993
|
-
function valueContainsStorageSecret(value) {
|
|
20994
|
-
if (typeof value === "string") {
|
|
20995
|
-
const trimmed = value.trim();
|
|
20996
|
-
return trimmed.length > 0 && storageTextContainsSecret(trimmed);
|
|
20997
|
-
}
|
|
20998
|
-
if (Array.isArray(value)) {
|
|
20999
|
-
return value.some((item) => valueContainsStorageSecret(item));
|
|
21000
|
-
}
|
|
21001
|
-
if (!isRecord(value)) {
|
|
21002
|
-
return false;
|
|
21003
|
-
}
|
|
21004
|
-
return Object.entries(value).some(([key, entryValue]) => STORAGE_SECRET_KEY_PATTERN.test(key) || valueContainsStorageSecret(entryValue));
|
|
21005
|
-
}
|
|
21006
|
-
function shouldRevealStorageValue(key, value) {
|
|
21007
|
-
if (key === void 0 || key.length === 0 || STORAGE_SECRET_KEY_PATTERN.test(key) || !STORAGE_BENIGN_KEY_PATTERN.test(key)) {
|
|
21008
|
-
return false;
|
|
21009
|
-
}
|
|
21010
|
-
if (valueContainsStorageSecret(value)) {
|
|
21011
|
-
return false;
|
|
21012
|
-
}
|
|
21013
|
-
if (typeof value === "string") {
|
|
21014
|
-
return value.length <= STORAGE_VALUE_PREVIEW_MAX_CHARS;
|
|
21015
|
-
}
|
|
21016
|
-
return value === null || typeof value === "number" || typeof value === "boolean";
|
|
21017
|
-
}
|
|
21018
|
-
function formatStorageValue(key, value) {
|
|
21019
|
-
if (!shouldRevealStorageValue(key, value)) {
|
|
21020
|
-
return "[REDACTED]";
|
|
21021
|
-
}
|
|
21022
|
-
return typeof value === "string" ? redactModelFacingText(value) : stringifyModelFacing(value);
|
|
21023
|
-
}
|
|
21024
|
-
function storageRedactionReason(key) {
|
|
21025
|
-
return key !== void 0 && key.length > 0 && STORAGE_SECRET_KEY_PATTERN.test(key) ? "sensitive-key" : "sensitive-value";
|
|
21026
|
-
}
|
|
21027
|
-
function redactStorageEntryValue(item) {
|
|
21028
|
-
const key = getStringField(item, "key") ?? getStringField(item, "name");
|
|
21029
|
-
if (!Object.hasOwn(item, "value") || shouldRevealStorageValue(key, item.value)) {
|
|
21030
|
-
return redactSensitiveValue(item);
|
|
21031
|
-
}
|
|
21032
|
-
const redacted = redactSensitiveValue({ ...item, value: void 0 });
|
|
21033
|
-
if (!isRecord(redacted)) {
|
|
21034
|
-
throw new Error("Storage record redaction did not return a record");
|
|
21035
|
-
}
|
|
21036
|
-
return {
|
|
21037
|
-
...redacted,
|
|
21038
|
-
value: "[REDACTED]",
|
|
21039
|
-
valueRedacted: true,
|
|
21040
|
-
valueRedactionReason: storageRedactionReason(key)
|
|
21041
|
-
};
|
|
21042
|
-
}
|
|
21043
|
-
function redactStorageField(owner, key, value) {
|
|
21044
|
-
if (key === "data" && isRecord(value)) {
|
|
21045
|
-
return Object.fromEntries(Object.entries(value).map(([storageKey, storageValue]) => [
|
|
21046
|
-
storageKey,
|
|
21047
|
-
shouldRevealStorageValue(storageKey, storageValue) ? redactSensitiveValue(storageValue) : "[REDACTED]"
|
|
21048
|
-
]));
|
|
21049
|
-
}
|
|
21050
|
-
if ((key === "entries" || key === "items") && Array.isArray(value)) {
|
|
21051
|
-
return value.map((item) => isRecord(item) ? redactStorageEntryValue(item) : redactSensitiveValue(item));
|
|
21052
|
-
}
|
|
21053
|
-
if (key === "value") {
|
|
21054
|
-
const itemKey = getStringField(owner, "key") ?? getStringField(owner, "name");
|
|
21055
|
-
return shouldRevealStorageValue(itemKey, value) ? redactSensitiveValue(value) : "[REDACTED]";
|
|
21056
|
-
}
|
|
21057
|
-
return redactSensitiveValue(value);
|
|
21058
|
-
}
|
|
21059
|
-
function redactStorageData(value) {
|
|
21060
|
-
if (Array.isArray(value)) {
|
|
21061
|
-
return value.map((item) => redactStorageData(item));
|
|
21062
|
-
}
|
|
21063
|
-
if (!isRecord(value)) {
|
|
21064
|
-
return redactSensitiveValue(value);
|
|
21065
|
-
}
|
|
21066
|
-
const entries = Object.fromEntries(Object.entries(value).map(([key2, entryValue]) => [
|
|
21067
|
-
key2,
|
|
21068
|
-
redactStorageField(value, key2, entryValue)
|
|
21069
|
-
]));
|
|
21070
|
-
const key = getStringField(value, "key") ?? getStringField(value, "name");
|
|
21071
|
-
if (Object.hasOwn(value, "value") && !shouldRevealStorageValue(key, value.value)) {
|
|
21072
|
-
entries.valueRedacted = true;
|
|
21073
|
-
entries.valueRedactionReason = storageRedactionReason(key);
|
|
21074
|
-
}
|
|
21075
|
-
return entries;
|
|
21076
|
-
}
|
|
21077
|
-
function formatStorageEntry(item, index) {
|
|
21078
|
-
if (!isRecord(item)) {
|
|
21079
|
-
return `${index + 1}. [REDACTED]`;
|
|
21080
|
-
}
|
|
21081
|
-
const rawKey = getStringField(item, "key") ?? getStringField(item, "name") ?? `(entry ${index + 1})`;
|
|
21082
|
-
const key = redactModelFacingText(rawKey);
|
|
21083
|
-
return Object.hasOwn(item, "value") ? `${key}: ${formatStorageValue(rawKey, item.value)}` : key;
|
|
21084
|
-
}
|
|
21085
|
-
function formatStorageMutationText(data, type) {
|
|
21086
|
-
const key = getStringField(data, "key");
|
|
21087
|
-
if (key !== void 0 && Object.hasOwn(data, "value")) {
|
|
21088
|
-
return `${type} ${redactModelFacingText(key)}: ${formatStorageValue(key, data.value)}`;
|
|
21089
|
-
}
|
|
21090
|
-
if (key !== void 0 && data.set === true) {
|
|
21091
|
-
return `${type} set: ${redactModelFacingText(key)}`;
|
|
21092
|
-
}
|
|
21093
|
-
return data.cleared === true || data.clear === true ? `${type} cleared.` : void 0;
|
|
21094
|
-
}
|
|
21095
|
-
function formatStorageText(data) {
|
|
21096
|
-
const type = getStringField(data, "type") ?? getStringField(data, "storage") ?? "storage";
|
|
21097
|
-
if (isRecord(data.data)) {
|
|
21098
|
-
const text3 = Object.entries(data.data).map(([key, value]) => `${redactModelFacingText(key)}: ${formatStorageValue(key, value)}`).join("\n");
|
|
21099
|
-
return text3.length > 0 ? text3 : `${type}: no entries.`;
|
|
21100
|
-
}
|
|
21101
|
-
const entries = getArrayField(data, "entries") ?? getArrayField(data, "items");
|
|
21102
|
-
if (entries) {
|
|
21103
|
-
return entries.length === 0 ? `${type}: no entries.` : entries.map(formatStorageEntry).join("\n");
|
|
21104
|
-
}
|
|
21105
|
-
return formatStorageMutationText(data, type);
|
|
21106
|
-
}
|
|
21107
|
-
function formatCookieRecordText(item, fallbackName) {
|
|
21108
|
-
const name = redactModelFacingText(getStringField(item, "name") ?? fallbackName);
|
|
21109
|
-
const domain = getStringField(item, "domain");
|
|
21110
|
-
const path = getStringField(item, "path");
|
|
21111
|
-
const flags = [
|
|
21112
|
-
item.httpOnly === true ? "httpOnly" : void 0,
|
|
21113
|
-
item.secure === true ? "secure" : void 0
|
|
21114
|
-
].filter(Boolean).join(", ");
|
|
21115
|
-
const location = [domain, path].filter(Boolean).join("");
|
|
21116
|
-
return [
|
|
21117
|
-
name,
|
|
21118
|
-
location.length > 0 ? `(${redactModelFacingText(location)})` : void 0,
|
|
21119
|
-
flags.length > 0 ? `[${flags}]` : void 0
|
|
21120
|
-
].filter(Boolean).join(" ");
|
|
21121
|
-
}
|
|
21122
|
-
function formatCookiesText(data) {
|
|
21123
|
-
const cookies = getArrayField(data, "cookies");
|
|
21124
|
-
if (cookies) {
|
|
21125
|
-
return cookies.length === 0 ? "No cookies." : cookies.map((item, index) => isRecord(item) ? formatCookieRecordText(item, `(cookie ${index + 1})`) : `${index + 1}. [REDACTED]`).join("\n");
|
|
21126
|
-
}
|
|
21127
|
-
if (getStringField(data, "name") !== void 0 || getStringField(data, "domain") !== void 0 || getStringField(data, "path") !== void 0 || Object.hasOwn(data, "value")) {
|
|
21128
|
-
return formatCookieRecordText(data, "cookie");
|
|
21129
|
-
}
|
|
21130
|
-
if (data.set === true) {
|
|
21131
|
-
return "Cookie set.";
|
|
21132
|
-
}
|
|
21133
|
-
return data.cleared === true || data.clear === true ? "Cookies cleared." : void 0;
|
|
21134
|
-
}
|
|
21135
|
-
var STORAGE_VALUE_PREVIEW_MAX_CHARS, STORAGE_SECRET_KEY_PATTERN, STORAGE_BENIGN_KEY_PATTERN, STORAGE_TOKEN_VALUE_PATTERN, STORAGE_SECRET_VALUE_WORD_PATTERN, STORAGE_EMAIL_VALUE_PATTERN, STORAGE_IDENTITY_VALUE_PATTERN;
|
|
21136
|
-
var init_diagnostic_storage = __esm({
|
|
21137
|
-
"dist/extensions/agent-browser/lib/results/presentation/diagnostic-storage.js"() {
|
|
21138
|
-
"use strict";
|
|
21139
|
-
init_parsing();
|
|
21140
|
-
init_runtime();
|
|
21141
|
-
init_common();
|
|
21142
|
-
STORAGE_VALUE_PREVIEW_MAX_CHARS = 160;
|
|
21143
|
-
STORAGE_SECRET_KEY_PATTERN = /(?:access(?:_|-)?token|account|api(?:_|-)?key|auth(?:orization)?|bearer|client(?:_|-)?secret|cookie|credential|csrf|email|id(?:_|-)?token|jwt|pass(?:word)?|private(?:_|-)?key|profile|refresh(?:_|-)?token|secret|session|sid|sig(?:nature)?|token|user(?:name)?|x(?:_|-)?api(?:_|-)?key|xsrf)/i;
|
|
21144
|
-
STORAGE_BENIGN_KEY_PATTERN = /^(?:color(?:scheme)?|debug|dev|experiment|feature(?:flag)?|flag|language|layout|locale|mode|onboarding|sort|tab|theme|timezone|tour|variant|view)$/i;
|
|
21145
|
-
STORAGE_TOKEN_VALUE_PATTERN = /(?:\bBearer\s+[A-Za-z0-9._~-]+|\bBasic\s+[A-Za-z0-9+/=]+|^[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+$|(?=.*[A-Za-z])(?=.*\d)[A-Za-z0-9_~+/=-]{32,})/;
|
|
21146
|
-
STORAGE_SECRET_VALUE_WORD_PATTERN = /(?:secret|token|password|passwd|bearer|credential|authorization|cookie|session[-_ ]?id)/i;
|
|
21147
|
-
STORAGE_EMAIL_VALUE_PATTERN = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
|
21148
|
-
STORAGE_IDENTITY_VALUE_PATTERN = /(?:^|[\s:=/_-])(?:account|profile|session|sid|user(?:id|name)?)(?:[\s:=/_-]|$)/i;
|
|
21149
|
-
}
|
|
21150
|
-
});
|
|
21151
|
-
|
|
21152
|
-
// dist/extensions/agent-browser/lib/results/presentation/diagnostic-redaction.js
|
|
21153
|
-
function redactStatefulValues(value) {
|
|
21154
|
-
if (Array.isArray(value)) {
|
|
21155
|
-
return value.map((item) => redactStatefulValues(item));
|
|
21156
|
-
}
|
|
21157
|
-
if (!isRecord(value)) {
|
|
21158
|
-
return redactSensitiveValue(value);
|
|
21159
|
-
}
|
|
21160
|
-
return Object.fromEntries(Object.entries(value).map(([key, entryValue]) => [
|
|
21161
|
-
key,
|
|
21162
|
-
key.toLowerCase() === "value" ? "[REDACTED]" : redactStatefulValues(entryValue)
|
|
21163
|
-
]));
|
|
21164
|
-
}
|
|
21165
|
-
function storageTextKey(command) {
|
|
21166
|
-
const operation = command.commandTokens?.[2];
|
|
21167
|
-
if (operation === "get") {
|
|
21168
|
-
return command.commandTokens?.[3];
|
|
21169
|
-
}
|
|
21170
|
-
return operation === "set" || operation === "clear" ? void 0 : operation;
|
|
21171
|
-
}
|
|
21172
|
-
function redactStorageText(command, text3) {
|
|
21173
|
-
const key = storageTextKey(command);
|
|
21174
|
-
if (key !== void 0 && text3.startsWith(`${key}: `)) {
|
|
21175
|
-
const suffix = text3.endsWith("\n") ? "\n" : "";
|
|
21176
|
-
const value = text3.slice(key.length + 2, suffix.length > 0 ? -1 : void 0);
|
|
21177
|
-
return `${key}: ${formatStorageValue(key, value)}${suffix}`;
|
|
21178
|
-
}
|
|
21179
|
-
return text3.replace(/^([^\r\n]*?): ([^\r\n]*)/gm, (_line, entryKey, value) => `${entryKey}: ${formatStorageValue(entryKey, value)}`);
|
|
21180
|
-
}
|
|
21181
|
-
function redactNativeContextText(command, text3, stdin) {
|
|
21182
|
-
if (command.command === "batch") {
|
|
21183
|
-
const steps = getUpstreamEffectiveBatchSteps(command.commandTokens ?? ["batch"], stdin);
|
|
21184
|
-
const cookieRedacted = steps.some((step) => step[0] === "cookies") ? redactNativeContextText({ command: "cookies" }, text3) : text3;
|
|
21185
|
-
return steps.some((step) => step[0] === "storage") ? redactNativeContextText({ command: "storage" }, cookieRedacted) : cookieRedacted;
|
|
21186
|
-
}
|
|
21187
|
-
if (command.command === "cookies") {
|
|
21188
|
-
return text3.replace(/^([^=\r\n]*)=([^\r\n]*)/gm, "$1=[REDACTED]");
|
|
21189
|
-
}
|
|
21190
|
-
return command.command === "storage" ? redactStorageText(command, text3) : text3;
|
|
21191
|
-
}
|
|
21192
|
-
function redactPresentationData(command, data, stdin) {
|
|
21193
|
-
if (typeof data === "string") {
|
|
21194
|
-
return redactSensitiveText(redactNativeContextText(command, data, stdin));
|
|
21195
|
-
}
|
|
21196
|
-
if (command.command === "cookies") {
|
|
21197
|
-
return redactStatefulValues(data);
|
|
21198
|
-
}
|
|
21199
|
-
if (command.command === "storage") {
|
|
21200
|
-
return redactStorageData(data);
|
|
21201
|
-
}
|
|
21202
|
-
if (command.command === "state" && command.subcommand === "show") {
|
|
21203
|
-
return redactStatefulValues(data);
|
|
21204
|
-
}
|
|
21205
|
-
return redactSensitiveValue(data);
|
|
21206
|
-
}
|
|
21207
|
-
var init_diagnostic_redaction = __esm({
|
|
21208
|
-
"dist/extensions/agent-browser/lib/results/presentation/diagnostic-redaction.js"() {
|
|
21209
|
-
"use strict";
|
|
21210
|
-
init_parsing();
|
|
21211
|
-
init_batch_stdin();
|
|
21212
|
-
init_runtime();
|
|
21213
|
-
init_diagnostic_storage();
|
|
21214
|
-
}
|
|
21215
|
-
});
|
|
21216
|
-
|
|
21217
21254
|
// dist/extensions/agent-browser/lib/orchestration/browser-run/screenshot-capture.js
|
|
21218
21255
|
function getScreenshotCapture(command) {
|
|
21219
21256
|
if (command[0] !== "screenshot") {
|
|
@@ -22904,11 +22941,11 @@ var init_batch_step = __esm({
|
|
|
22904
22941
|
});
|
|
22905
22942
|
|
|
22906
22943
|
// dist/extensions/agent-browser/lib/results/presentation/batch-recording.js
|
|
22907
|
-
import { stat as
|
|
22944
|
+
import { stat as stat15 } from "node:fs/promises";
|
|
22908
22945
|
async function unverifiedRecordingArtifact(artifact, subcommand) {
|
|
22909
22946
|
const { recordingState: _recordingState, willExistOnStop: _willExistOnStop, ...terminal } = artifact;
|
|
22910
22947
|
try {
|
|
22911
|
-
const file = await
|
|
22948
|
+
const file = await stat15(artifact.absolutePath);
|
|
22912
22949
|
return {
|
|
22913
22950
|
...terminal,
|
|
22914
22951
|
exists: file.isFile(),
|
|
@@ -24712,6 +24749,7 @@ var init_skills = __esm({
|
|
|
24712
24749
|
SkillShellWords = class {
|
|
24713
24750
|
words = [];
|
|
24714
24751
|
current = "";
|
|
24752
|
+
wordStarted = false;
|
|
24715
24753
|
quote;
|
|
24716
24754
|
index = 0;
|
|
24717
24755
|
input;
|
|
@@ -24719,9 +24757,10 @@ var init_skills = __esm({
|
|
|
24719
24757
|
this.input = input;
|
|
24720
24758
|
}
|
|
24721
24759
|
flush() {
|
|
24722
|
-
if (this.
|
|
24760
|
+
if (this.wordStarted) {
|
|
24723
24761
|
this.words.push(this.current);
|
|
24724
24762
|
this.current = "";
|
|
24763
|
+
this.wordStarted = false;
|
|
24725
24764
|
}
|
|
24726
24765
|
}
|
|
24727
24766
|
appendEscape() {
|
|
@@ -24744,14 +24783,17 @@ var init_skills = __esm({
|
|
|
24744
24783
|
}
|
|
24745
24784
|
consumeUnquoted(char) {
|
|
24746
24785
|
if (char === "'" || char === '"') {
|
|
24786
|
+
this.wordStarted = true;
|
|
24747
24787
|
this.quote = char === "'" ? "single" : "double";
|
|
24748
24788
|
} else if (char === "\\") {
|
|
24789
|
+
this.wordStarted = true;
|
|
24749
24790
|
this.appendEscape();
|
|
24750
|
-
} else if (char === "#" && this.
|
|
24791
|
+
} else if (char === "#" && !this.wordStarted) {
|
|
24751
24792
|
return false;
|
|
24752
24793
|
} else if (/\s/.test(char)) {
|
|
24753
24794
|
this.flush();
|
|
24754
24795
|
} else {
|
|
24796
|
+
this.wordStarted = true;
|
|
24755
24797
|
this.current += char;
|
|
24756
24798
|
}
|
|
24757
24799
|
return true;
|
|
@@ -26048,7 +26090,7 @@ function launchFailureMessage(reason, target, detail) {
|
|
|
26048
26090
|
case "aborted":
|
|
26049
26091
|
return `Electron launch was aborted${target ? ` before ${label} finished starting` : " before the app started"}.`;
|
|
26050
26092
|
case "non-electron-target":
|
|
26051
|
-
return `Electron launch rejected: ${label} does not have Electron
|
|
26093
|
+
return `Electron launch rejected: ${label} does not have the required Electron runtime and app payload evidence.`;
|
|
26052
26094
|
case "policy-blocked":
|
|
26053
26095
|
return detail ?? `Electron launch blocked by caller policy for ${label}.`;
|
|
26054
26096
|
case "single-instance-conflict":
|
|
@@ -26138,6 +26180,7 @@ var init_launch = __esm({
|
|
|
26138
26180
|
init_discovery();
|
|
26139
26181
|
init_temp();
|
|
26140
26182
|
init_text();
|
|
26183
|
+
init_process_identity();
|
|
26141
26184
|
init_launch_monitor();
|
|
26142
26185
|
init_launch_process();
|
|
26143
26186
|
init_launch_types();
|
|
@@ -26154,6 +26197,7 @@ var init_launch = __esm({
|
|
|
26154
26197
|
timeoutMs;
|
|
26155
26198
|
deadlineMs;
|
|
26156
26199
|
appArgs;
|
|
26200
|
+
startIdentity;
|
|
26157
26201
|
constructor(options, target, userDataDir, timing) {
|
|
26158
26202
|
this.options = options;
|
|
26159
26203
|
this.target = target;
|
|
@@ -26228,6 +26272,7 @@ var init_launch = __esm({
|
|
|
26228
26272
|
platform: this.target.platform,
|
|
26229
26273
|
port,
|
|
26230
26274
|
processGroupId: process.platform === "win32" ? void 0 : pid,
|
|
26275
|
+
startIdentity: this.startIdentity,
|
|
26231
26276
|
targetType: this.options.targetType,
|
|
26232
26277
|
userDataDir: this.userDataDir,
|
|
26233
26278
|
version: ELECTRON_LAUNCH_RECORD_VERSION,
|
|
@@ -26245,6 +26290,11 @@ var init_launch = __esm({
|
|
|
26245
26290
|
if (this.process.child === void 0) {
|
|
26246
26291
|
return this.fail(isElectronLaunchAborted(this.options.signal) ? "aborted" : "spawn-error", this.process.spawnError?.message);
|
|
26247
26292
|
}
|
|
26293
|
+
const pid = this.process.child.pid;
|
|
26294
|
+
this.startIdentity = pid === void 0 ? void 0 : await readProcessStartIdentity(pid, process.platform, {
|
|
26295
|
+
deadline: this.deadlineMs,
|
|
26296
|
+
signal: this.options.signal
|
|
26297
|
+
});
|
|
26248
26298
|
const portResult = await pollDevToolsActivePort({
|
|
26249
26299
|
deadlineMs: this.deadlineMs,
|
|
26250
26300
|
getChildExit: this.process.childExit,
|
|
@@ -28020,6 +28070,13 @@ async function collectSnapshotEvidence(options, request) {
|
|
|
28020
28070
|
const fullSnapshot = extractRefSnapshotFromData(snapshotData);
|
|
28021
28071
|
const diff = request.diff ? buildSnapshotDiff(options.previousRefSnapshot, fullSnapshot) : void 0;
|
|
28022
28072
|
if (fullSnapshot) {
|
|
28073
|
+
if (fullSnapshot.target) {
|
|
28074
|
+
options.sessionPageState.applyTabTarget({
|
|
28075
|
+
sessionName: options.sessionStateKey ?? options.sessionName,
|
|
28076
|
+
target: fullSnapshot.target,
|
|
28077
|
+
update: options.sessionPageStateUpdate
|
|
28078
|
+
});
|
|
28079
|
+
}
|
|
28023
28080
|
options.sessionPageState.applyRefSnapshot({
|
|
28024
28081
|
sessionName: options.sessionStateKey ?? options.sessionName,
|
|
28025
28082
|
snapshot: fullSnapshot,
|
|
@@ -28092,6 +28149,7 @@ function snapshotToolResult(options, request, evidence, presentation) {
|
|
|
28092
28149
|
fullOutputPaths: presentation.fullOutputPaths,
|
|
28093
28150
|
refSnapshot: evidence.fullSnapshot,
|
|
28094
28151
|
sessionMode: options.sessionMode,
|
|
28152
|
+
sessionTabTarget: options.sessionPageState.get(options.sessionStateKey ?? options.sessionName).tabTarget,
|
|
28095
28153
|
snapshotDiff: evidence.diff,
|
|
28096
28154
|
snapshotFilter: snapshotFilterDetails(request, evidence),
|
|
28097
28155
|
snapshotViewport: evidence.viewport,
|
|
@@ -28332,7 +28390,7 @@ var init_network_page_filter = __esm({
|
|
|
28332
28390
|
|
|
28333
28391
|
// dist/extensions/agent-browser/lib/orchestration/browser-run/prepare/scroll-shims.js
|
|
28334
28392
|
function getContainerScrollRequest(commandTokens) {
|
|
28335
|
-
if (commandTokens[0] !== "scroll" || commandTokens.length < 3) {
|
|
28393
|
+
if (commandTokens[0] !== "scroll" || commandTokens.length < 3 || commandTokens.length > 4) {
|
|
28336
28394
|
return void 0;
|
|
28337
28395
|
}
|
|
28338
28396
|
const selector = commandTokens[1];
|
|
@@ -28456,7 +28514,7 @@ function getPageScrollToRequest(commandTokens) {
|
|
|
28456
28514
|
return void 0;
|
|
28457
28515
|
}
|
|
28458
28516
|
if (commandTokens[1]?.toLowerCase() === "to") {
|
|
28459
|
-
return getPageScrollTarget(commandTokens.at(2));
|
|
28517
|
+
return commandTokens.length === 3 ? getPageScrollTarget(commandTokens.at(2)) : void 0;
|
|
28460
28518
|
}
|
|
28461
28519
|
const direction = commandTokens[1]?.toLowerCase();
|
|
28462
28520
|
if (!isPageScrollDirection(direction) || commandTokens.length > 3) {
|
|
@@ -33164,7 +33222,7 @@ var KeyedAsyncExecutionQueue = class {
|
|
|
33164
33222
|
async run(key, namespace, work, signal) {
|
|
33165
33223
|
const entry = this.entries.get(key) ?? { queue: new AsyncExecutionQueue(), users: 0 };
|
|
33166
33224
|
if (entry.queue.isCurrent()) {
|
|
33167
|
-
return work
|
|
33225
|
+
return entry.queue.run(work, signal);
|
|
33168
33226
|
}
|
|
33169
33227
|
const barrier = this.barriers.get(getAgentBrowserSessionIdentityKey("", namespace)) ?? Promise.resolve();
|
|
33170
33228
|
entry.users += 1;
|
|
@@ -34331,133 +34389,133 @@ function StringEnum(values, options) {
|
|
|
34331
34389
|
init_discovery_types();
|
|
34332
34390
|
init_types();
|
|
34333
34391
|
var AGENT_BROWSER_ADVANCED_TOOLS = ["action", "qa", "electron", "source", "network"];
|
|
34334
|
-
function outputProperties(
|
|
34392
|
+
function outputProperties() {
|
|
34335
34393
|
return {
|
|
34336
|
-
outputPath:
|
|
34394
|
+
outputPath: JsonSchema.Optional(JsonSchema.String({
|
|
34337
34395
|
description: "Result-data path, separate from browser artifact paths.",
|
|
34338
34396
|
minLength: 1
|
|
34339
34397
|
})),
|
|
34340
|
-
timeoutMs:
|
|
34398
|
+
timeoutMs: JsonSchema.Optional(JsonSchema.Integer({ description: "Timeout in ms; exceed explicit waits.", minimum: 1 }))
|
|
34341
34399
|
};
|
|
34342
34400
|
}
|
|
34343
|
-
function sessionModeProperty(
|
|
34344
|
-
return
|
|
34401
|
+
function sessionModeProperty() {
|
|
34402
|
+
return JsonSchema.Optional(StringEnum(["auto", "fresh"], {
|
|
34345
34403
|
description: "Native configured sessions win; auto reuses the browser, fresh intentionally launches a separate managed browser.",
|
|
34346
34404
|
default: DEFAULT_SESSION_MODE
|
|
34347
34405
|
}));
|
|
34348
34406
|
}
|
|
34349
|
-
function createAgentBrowserParamsSchema(
|
|
34350
|
-
return
|
|
34351
|
-
args:
|
|
34407
|
+
function createAgentBrowserParamsSchema() {
|
|
34408
|
+
return JsonSchema.Unsafe(JsonSchema.Object({
|
|
34409
|
+
args: JsonSchema.Array(JsonSchema.String(), {
|
|
34352
34410
|
description: "Native agent-browser argv without the binary or shell syntax. Fixed sequences: batch --bail with JSON-array stdin.",
|
|
34353
34411
|
minItems: 1
|
|
34354
34412
|
}),
|
|
34355
|
-
stdin:
|
|
34413
|
+
stdin: JsonSchema.Optional(JsonSchema.String({
|
|
34356
34414
|
description: "Native batch JSON, eval --stdin source, or auth save --password-stdin text."
|
|
34357
34415
|
})),
|
|
34358
|
-
...outputProperties(
|
|
34359
|
-
sessionMode: sessionModeProperty(
|
|
34416
|
+
...outputProperties(),
|
|
34417
|
+
sessionMode: sessionModeProperty()
|
|
34360
34418
|
}, { additionalProperties: false }));
|
|
34361
34419
|
}
|
|
34362
|
-
function createAgentBrowserCodeParamsSchema(
|
|
34363
|
-
return
|
|
34364
|
-
code:
|
|
34420
|
+
function createAgentBrowserCodeParamsSchema() {
|
|
34421
|
+
return JsonSchema.Unsafe(JsonSchema.Object({
|
|
34422
|
+
code: JsonSchema.String({
|
|
34365
34423
|
description: "JavaScript with await browser({args, stdin?, timeoutMs?}), emit(JSON), and emitImage(image handle). Fresh JS context; persistent browser.",
|
|
34366
34424
|
minLength: 1,
|
|
34367
34425
|
maxLength: 65536
|
|
34368
34426
|
}),
|
|
34369
|
-
session:
|
|
34427
|
+
session: JsonSchema.Optional(JsonSchema.String({
|
|
34370
34428
|
description: "Explicit native session; omitted uses the ordinary default browser.",
|
|
34371
34429
|
minLength: 1
|
|
34372
34430
|
})),
|
|
34373
|
-
namespace:
|
|
34431
|
+
namespace: JsonSchema.Optional(JsonSchema.String({
|
|
34374
34432
|
description: "Native namespace; empty string selects the default namespace."
|
|
34375
34433
|
})),
|
|
34376
|
-
...outputProperties(
|
|
34377
|
-
timeoutMs:
|
|
34434
|
+
...outputProperties(),
|
|
34435
|
+
timeoutMs: JsonSchema.Optional(JsonSchema.Integer({ minimum: 1, maximum: AGENT_BROWSER_CODE_MAX_TIMEOUT_MS }))
|
|
34378
34436
|
}, { additionalProperties: false }));
|
|
34379
34437
|
}
|
|
34380
|
-
function createAgentBrowserActionParamsSchema(
|
|
34381
|
-
return
|
|
34382
|
-
action:
|
|
34383
|
-
locator:
|
|
34438
|
+
function createAgentBrowserActionParamsSchema() {
|
|
34439
|
+
return JsonSchema.Unsafe(JsonSchema.Object({
|
|
34440
|
+
action: StringEnum(AGENT_BROWSER_SEMANTIC_ACTIONS),
|
|
34441
|
+
locator: JsonSchema.Optional(StringEnum(AGENT_BROWSER_SEMANTIC_LOCATORS, {
|
|
34384
34442
|
description: "Select supports role or label."
|
|
34385
34443
|
})),
|
|
34386
|
-
value:
|
|
34444
|
+
value: JsonSchema.Optional(JsonSchema.String({
|
|
34387
34445
|
description: "Locator value or select option; label text for select by label."
|
|
34388
34446
|
})),
|
|
34389
|
-
values:
|
|
34447
|
+
values: JsonSchema.Optional(JsonSchema.Array(JsonSchema.String(), {
|
|
34390
34448
|
description: "Select options; required for select by label.",
|
|
34391
34449
|
minItems: 1
|
|
34392
34450
|
})),
|
|
34393
|
-
selector:
|
|
34394
|
-
text:
|
|
34395
|
-
role:
|
|
34396
|
-
name:
|
|
34397
|
-
session:
|
|
34398
|
-
...outputProperties(
|
|
34451
|
+
selector: JsonSchema.Optional(JsonSchema.String({ description: "Direct selector or current @ref." })),
|
|
34452
|
+
text: JsonSchema.Optional(JsonSchema.String({ description: "Fill text." })),
|
|
34453
|
+
role: JsonSchema.Optional(JsonSchema.String({ description: "Role locator; select needs combobox or listbox." })),
|
|
34454
|
+
name: JsonSchema.Optional(JsonSchema.String({ description: "Accessible name." })),
|
|
34455
|
+
session: JsonSchema.Optional(JsonSchema.String({ description: "Upstream session name." })),
|
|
34456
|
+
...outputProperties()
|
|
34399
34457
|
}, {
|
|
34400
34458
|
additionalProperties: false,
|
|
34401
34459
|
// Top-level properties let Pi normalize optional nulls before validating branches.
|
|
34402
34460
|
anyOf: [
|
|
34403
|
-
|
|
34404
|
-
action:
|
|
34405
|
-
locator:
|
|
34461
|
+
JsonSchema.Object({
|
|
34462
|
+
action: StringEnum(["select"]),
|
|
34463
|
+
locator: JsonSchema.Optional(StringEnum(["role", "label"]))
|
|
34406
34464
|
}, { not: { required: ["text"] } }),
|
|
34407
|
-
|
|
34465
|
+
JsonSchema.Object({ action: StringEnum(["check", "click", "fill"]) }, { not: { required: ["values"] } })
|
|
34408
34466
|
]
|
|
34409
34467
|
}));
|
|
34410
34468
|
}
|
|
34411
|
-
function createAgentBrowserQaParamsSchema(
|
|
34412
|
-
return
|
|
34413
|
-
url:
|
|
34414
|
-
attached:
|
|
34415
|
-
expectedText:
|
|
34416
|
-
expectedSelector:
|
|
34417
|
-
screenshotPath:
|
|
34418
|
-
checkConsole:
|
|
34419
|
-
checkErrors:
|
|
34420
|
-
checkNetwork:
|
|
34421
|
-
loadState:
|
|
34422
|
-
...outputProperties(
|
|
34423
|
-
sessionMode: sessionModeProperty(
|
|
34469
|
+
function createAgentBrowserQaParamsSchema() {
|
|
34470
|
+
return JsonSchema.Unsafe(JsonSchema.Object({
|
|
34471
|
+
url: JsonSchema.Optional(JsonSchema.String()),
|
|
34472
|
+
attached: JsonSchema.Optional(JsonSchema.Boolean()),
|
|
34473
|
+
expectedText: JsonSchema.Optional(JsonSchema.Union([JsonSchema.String(), JsonSchema.Array(JsonSchema.String())])),
|
|
34474
|
+
expectedSelector: JsonSchema.Optional(JsonSchema.String()),
|
|
34475
|
+
screenshotPath: JsonSchema.Optional(JsonSchema.String()),
|
|
34476
|
+
checkConsole: JsonSchema.Optional(JsonSchema.Boolean()),
|
|
34477
|
+
checkErrors: JsonSchema.Optional(JsonSchema.Boolean()),
|
|
34478
|
+
checkNetwork: JsonSchema.Optional(JsonSchema.Boolean()),
|
|
34479
|
+
loadState: JsonSchema.Optional(StringEnum(AGENT_BROWSER_QA_LOAD_STATES)),
|
|
34480
|
+
...outputProperties(),
|
|
34481
|
+
sessionMode: sessionModeProperty()
|
|
34424
34482
|
}, {
|
|
34425
34483
|
additionalProperties: false,
|
|
34426
34484
|
anyOf: [
|
|
34427
|
-
|
|
34428
|
-
attached:
|
|
34429
|
-
sessionMode:
|
|
34485
|
+
JsonSchema.Object({
|
|
34486
|
+
attached: JsonSchema.Literal(true),
|
|
34487
|
+
sessionMode: JsonSchema.Optional(StringEnum(["auto"]))
|
|
34430
34488
|
}, { not: { required: ["url"] } }),
|
|
34431
|
-
|
|
34489
|
+
JsonSchema.Object({ url: JsonSchema.String(), attached: JsonSchema.Optional(JsonSchema.Literal(false)) })
|
|
34432
34490
|
]
|
|
34433
34491
|
}));
|
|
34434
34492
|
}
|
|
34435
|
-
function createAgentBrowserElectronParamsSchema(
|
|
34436
|
-
const common = { outputPath: outputProperties(
|
|
34437
|
-
const timeoutMs =
|
|
34493
|
+
function createAgentBrowserElectronParamsSchema() {
|
|
34494
|
+
const common = { outputPath: outputProperties().outputPath };
|
|
34495
|
+
const timeoutMs = JsonSchema.Optional(JsonSchema.Integer({ minimum: 1 }));
|
|
34438
34496
|
const list = {
|
|
34439
|
-
query:
|
|
34440
|
-
maxResults:
|
|
34497
|
+
query: JsonSchema.Optional(JsonSchema.String({ description: "Case-insensitive app filter.", minLength: 1 })),
|
|
34498
|
+
maxResults: JsonSchema.Optional(JsonSchema.Integer({
|
|
34441
34499
|
description: `Result cap; default ${ELECTRON_DISCOVERY_DEFAULT_MAX_RESULTS}, clamped to ${ELECTRON_DISCOVERY_MAX_RESULTS}.`,
|
|
34442
34500
|
minimum: 1
|
|
34443
34501
|
}))
|
|
34444
34502
|
};
|
|
34445
34503
|
const launch = {
|
|
34446
|
-
appPath:
|
|
34447
|
-
appName:
|
|
34448
|
-
bundleId:
|
|
34449
|
-
executablePath:
|
|
34450
|
-
appArgs:
|
|
34451
|
-
handoff:
|
|
34452
|
-
targetType:
|
|
34504
|
+
appPath: JsonSchema.Optional(JsonSchema.String({ description: "macOS .app path.", minLength: 1 })),
|
|
34505
|
+
appName: JsonSchema.Optional(JsonSchema.String({ description: "Name from agent_browser_electron list.", minLength: 1 })),
|
|
34506
|
+
bundleId: JsonSchema.Optional(JsonSchema.String({ minLength: 1 })),
|
|
34507
|
+
executablePath: JsonSchema.Optional(JsonSchema.String({ minLength: 1 })),
|
|
34508
|
+
appArgs: JsonSchema.Optional(JsonSchema.Array(JsonSchema.String({ minLength: 1 }))),
|
|
34509
|
+
handoff: JsonSchema.Optional(StringEnum(AGENT_BROWSER_ELECTRON_HANDOFFS)),
|
|
34510
|
+
targetType: JsonSchema.Optional(StringEnum(AGENT_BROWSER_ELECTRON_TARGET_TYPES)),
|
|
34453
34511
|
timeoutMs,
|
|
34454
|
-
allow:
|
|
34455
|
-
deny:
|
|
34512
|
+
allow: JsonSchema.Optional(JsonSchema.Array(JsonSchema.String({ minLength: 1 }))),
|
|
34513
|
+
deny: JsonSchema.Optional(JsonSchema.Array(JsonSchema.String({ minLength: 1 })))
|
|
34456
34514
|
};
|
|
34457
|
-
const probe = { launchId:
|
|
34458
|
-
const lifecycle = { ...probe, all:
|
|
34459
|
-
return
|
|
34460
|
-
action:
|
|
34515
|
+
const probe = { launchId: JsonSchema.Optional(JsonSchema.String({ minLength: 1 })), timeoutMs };
|
|
34516
|
+
const lifecycle = { ...probe, all: JsonSchema.Optional(JsonSchema.Literal(true)) };
|
|
34517
|
+
return JsonSchema.Unsafe(JsonSchema.Object({
|
|
34518
|
+
action: StringEnum(["list", "launch", "status", "cleanup", "probe"]),
|
|
34461
34519
|
...list,
|
|
34462
34520
|
...launch,
|
|
34463
34521
|
...lifecycle,
|
|
@@ -34465,47 +34523,47 @@ function createAgentBrowserElectronParamsSchema(Type = JsonSchema, StringEnum2 =
|
|
|
34465
34523
|
}, {
|
|
34466
34524
|
additionalProperties: false,
|
|
34467
34525
|
anyOf: [
|
|
34468
|
-
|
|
34469
|
-
|
|
34470
|
-
|
|
34471
|
-
|
|
34526
|
+
JsonSchema.Object({ action: StringEnum(["list"]), ...list, ...common }, { additionalProperties: false }),
|
|
34527
|
+
JsonSchema.Object({ action: StringEnum(["launch"]), ...launch, ...common }, { additionalProperties: false }),
|
|
34528
|
+
JsonSchema.Object({ action: StringEnum(["status", "cleanup"]), ...lifecycle, ...common }, { additionalProperties: false, not: { required: ["launchId", "all"] } }),
|
|
34529
|
+
JsonSchema.Object({ action: StringEnum(["probe"]), ...probe, ...common }, { additionalProperties: false })
|
|
34472
34530
|
]
|
|
34473
34531
|
}));
|
|
34474
34532
|
}
|
|
34475
|
-
function createAgentBrowserSourceParamsSchema(
|
|
34476
|
-
return
|
|
34477
|
-
selector:
|
|
34478
|
-
reactFiberId:
|
|
34479
|
-
componentName:
|
|
34480
|
-
includeDomHints:
|
|
34481
|
-
maxWorkspaceFiles:
|
|
34533
|
+
function createAgentBrowserSourceParamsSchema() {
|
|
34534
|
+
return JsonSchema.Unsafe(JsonSchema.Object({
|
|
34535
|
+
selector: JsonSchema.Optional(JsonSchema.String({ description: "Visible selector or @ref." })),
|
|
34536
|
+
reactFiberId: JsonSchema.Optional(JsonSchema.String({ description: "React fiber id; requires --enable react-devtools." })),
|
|
34537
|
+
componentName: JsonSchema.Optional(JsonSchema.String({ description: "Component for local source search." })),
|
|
34538
|
+
includeDomHints: JsonSchema.Optional(JsonSchema.Boolean({ description: "Inspect DOM hints; default true." })),
|
|
34539
|
+
maxWorkspaceFiles: JsonSchema.Optional(JsonSchema.Integer({
|
|
34482
34540
|
description: "Source scan cap; default 2000.",
|
|
34483
34541
|
minimum: 1,
|
|
34484
34542
|
maximum: SOURCE_LOOKUP_MAX_WORKSPACE_FILES
|
|
34485
34543
|
})),
|
|
34486
|
-
...outputProperties(
|
|
34487
|
-
sessionMode: sessionModeProperty(
|
|
34544
|
+
...outputProperties(),
|
|
34545
|
+
sessionMode: sessionModeProperty()
|
|
34488
34546
|
}, { additionalProperties: false }));
|
|
34489
34547
|
}
|
|
34490
|
-
function createAgentBrowserNetworkSourceParamsSchema(
|
|
34491
|
-
return
|
|
34492
|
-
filter:
|
|
34493
|
-
namespace:
|
|
34494
|
-
requestId:
|
|
34495
|
-
session:
|
|
34496
|
-
url:
|
|
34497
|
-
maxWorkspaceFiles:
|
|
34548
|
+
function createAgentBrowserNetworkSourceParamsSchema() {
|
|
34549
|
+
return JsonSchema.Unsafe(JsonSchema.Object({
|
|
34550
|
+
filter: JsonSchema.Optional(JsonSchema.String({ description: "Network request filter." })),
|
|
34551
|
+
namespace: JsonSchema.Optional(JsonSchema.String()),
|
|
34552
|
+
requestId: JsonSchema.Optional(JsonSchema.String({ description: "Request id to inspect." })),
|
|
34553
|
+
session: JsonSchema.Optional(JsonSchema.String()),
|
|
34554
|
+
url: JsonSchema.Optional(JsonSchema.String({ description: "Failed URL or fragment." })),
|
|
34555
|
+
maxWorkspaceFiles: JsonSchema.Optional(JsonSchema.Integer({
|
|
34498
34556
|
description: "Source scan cap; default 2000.",
|
|
34499
34557
|
minimum: 1,
|
|
34500
34558
|
maximum: SOURCE_LOOKUP_MAX_WORKSPACE_FILES
|
|
34501
34559
|
})),
|
|
34502
|
-
...outputProperties(
|
|
34503
|
-
sessionMode: sessionModeProperty(
|
|
34560
|
+
...outputProperties(),
|
|
34561
|
+
sessionMode: sessionModeProperty()
|
|
34504
34562
|
}, { additionalProperties: false }));
|
|
34505
34563
|
}
|
|
34506
|
-
function createAgentBrowserToolsParamsSchema(
|
|
34507
|
-
return
|
|
34508
|
-
enable:
|
|
34564
|
+
function createAgentBrowserToolsParamsSchema() {
|
|
34565
|
+
return JsonSchema.Unsafe(JsonSchema.Object({
|
|
34566
|
+
enable: JsonSchema.Optional(JsonSchema.Array(StringEnum(AGENT_BROWSER_ADVANCED_TOOLS), {
|
|
34509
34567
|
description: "Add capabilities to active tools; omit to list inventory."
|
|
34510
34568
|
}))
|
|
34511
34569
|
}, { additionalProperties: false }));
|
|
@@ -34934,15 +34992,24 @@ function validateAgentBrowserConfig(value, path, errors, warnings) {
|
|
|
34934
34992
|
...browser !== void 0 ? { browser } : {}
|
|
34935
34993
|
};
|
|
34936
34994
|
}
|
|
34937
|
-
function
|
|
34938
|
-
let parsed;
|
|
34995
|
+
function parseAgentBrowserConfigJson(raw) {
|
|
34939
34996
|
try {
|
|
34940
|
-
|
|
34997
|
+
return { ok: true, value: JSON.parse(raw) };
|
|
34941
34998
|
} catch (error) {
|
|
34942
|
-
|
|
34999
|
+
const location = error instanceof Error ? error.message.match(/at position \d+(?: \(line \d+ column \d+\))?/)?.[0] : void 0;
|
|
35000
|
+
return {
|
|
35001
|
+
ok: false,
|
|
35002
|
+
error: location === void 0 ? "Invalid JSON." : `Invalid JSON ${location}.`
|
|
35003
|
+
};
|
|
35004
|
+
}
|
|
35005
|
+
}
|
|
35006
|
+
function parseAgentBrowserConfigLayer(raw, path, scope, errors, warnings) {
|
|
35007
|
+
const parsed = parseAgentBrowserConfigJson(raw);
|
|
35008
|
+
if (!parsed.ok) {
|
|
35009
|
+
errors.push(`Could not parse ${scope} config ${path}: ${parsed.error}`);
|
|
34943
35010
|
return;
|
|
34944
35011
|
}
|
|
34945
|
-
const config = validateAgentBrowserConfig(parsed, path, errors, warnings);
|
|
35012
|
+
const config = validateAgentBrowserConfig(parsed.value, path, errors, warnings);
|
|
34946
35013
|
return config ? { config, path, scope } : void 0;
|
|
34947
35014
|
}
|
|
34948
35015
|
function describeUnknownError(value) {
|
|
@@ -35313,6 +35380,9 @@ async function resolvePreferredWebSearchCredential(state, options = {}) {
|
|
|
35313
35380
|
|
|
35314
35381
|
// dist/extensions/agent-browser/lib/web-search.js
|
|
35315
35382
|
init_runtime();
|
|
35383
|
+
init_parsing();
|
|
35384
|
+
init_content();
|
|
35385
|
+
init_diagnostic_redaction();
|
|
35316
35386
|
|
|
35317
35387
|
// dist/extensions/agent-browser/lib/web-search-schema.js
|
|
35318
35388
|
var DEFAULT_SEARCH_RESULT_COUNT = 5;
|
|
@@ -35328,67 +35398,67 @@ var EXA_SEARCH_CATEGORIES = [
|
|
|
35328
35398
|
];
|
|
35329
35399
|
var MAX_EXA_DOMAIN_FILTERS = 20;
|
|
35330
35400
|
var MAX_EXA_ADDITIONAL_QUERIES = 10;
|
|
35331
|
-
function createExaFilterProperties(
|
|
35401
|
+
function createExaFilterProperties() {
|
|
35332
35402
|
return {
|
|
35333
|
-
includeDomains:
|
|
35403
|
+
includeDomains: JsonSchema.Optional(JsonSchema.Array(JsonSchema.String({ minLength: 1 }), {
|
|
35334
35404
|
minItems: 1,
|
|
35335
35405
|
maxItems: MAX_EXA_DOMAIN_FILTERS,
|
|
35336
35406
|
description: `Exa only. Limit results to 1\u2013${MAX_EXA_DOMAIN_FILTERS} hostnames, path prefixes (exa.ai/docs), or wildcard subdomains (*.substack.com).`
|
|
35337
35407
|
})),
|
|
35338
|
-
excludeDomains:
|
|
35408
|
+
excludeDomains: JsonSchema.Optional(JsonSchema.Array(JsonSchema.String({ minLength: 1 }), {
|
|
35339
35409
|
minItems: 1,
|
|
35340
35410
|
maxItems: MAX_EXA_DOMAIN_FILTERS,
|
|
35341
35411
|
description: `Exa only. Exclude 1\u2013${MAX_EXA_DOMAIN_FILTERS} hostnames, path prefixes, or wildcard subdomains. Not compatible with category company or people.`
|
|
35342
35412
|
})),
|
|
35343
|
-
category:
|
|
35413
|
+
category: JsonSchema.Optional(StringEnum(EXA_SEARCH_CATEGORIES, {
|
|
35344
35414
|
description: "Exa-only result category. company and people cannot be combined with freshness or excludeDomains."
|
|
35345
35415
|
})),
|
|
35346
|
-
additionalQueries:
|
|
35416
|
+
additionalQueries: JsonSchema.Optional(JsonSchema.Array(JsonSchema.String({ minLength: 1 }), {
|
|
35347
35417
|
minItems: 1,
|
|
35348
35418
|
maxItems: MAX_EXA_ADDITIONAL_QUERIES,
|
|
35349
35419
|
description: `Exa only. Add 1\u2013${MAX_EXA_ADDITIONAL_QUERIES} query variations when the effective searchType is deep-lite, deep, or deep-reasoning.`
|
|
35350
35420
|
})),
|
|
35351
|
-
highlightsDynamic:
|
|
35421
|
+
highlightsDynamic: JsonSchema.Optional(JsonSchema.Boolean({
|
|
35352
35422
|
description: "Exa-only research preview. Allocate one highlight budget across all results; the wrapper sends the required Exa-Beta header. Regular per-page highlights remain the default."
|
|
35353
35423
|
}))
|
|
35354
35424
|
};
|
|
35355
35425
|
}
|
|
35356
|
-
function createAgentBrowserWebSearchParamsSchema(
|
|
35357
|
-
return
|
|
35358
|
-
query:
|
|
35426
|
+
function createAgentBrowserWebSearchParamsSchema() {
|
|
35427
|
+
return JsonSchema.Object({
|
|
35428
|
+
query: JsonSchema.String({
|
|
35359
35429
|
minLength: 1,
|
|
35360
35430
|
description: "Search query to run with the configured Exa or Brave web search provider."
|
|
35361
35431
|
}),
|
|
35362
|
-
provider:
|
|
35432
|
+
provider: JsonSchema.Optional(StringEnum(WEB_SEARCH_PROVIDER_PARAM_VALUES, {
|
|
35363
35433
|
description: `Optional provider override. auto uses configured keys and preferredProvider; when both Exa and Brave are available, the default preferred provider is ${DEFAULT_WEB_SEARCH_PROVIDER}.`
|
|
35364
35434
|
})),
|
|
35365
|
-
searchType:
|
|
35435
|
+
searchType: JsonSchema.Optional(StringEnum(EXA_SEARCH_TYPES, {
|
|
35366
35436
|
description: "Exa mode; omitted uses webSearch.defaultSearchType, then auto. instant (~250ms) is only for trivial lookups; fast (~450ms) favors latency; auto (~1s) is balanced. Pass searchType: deep-lite (~4s) for research before implementation unless config already defaults it; do not assume auto is deep enough. deep (4\u201315s) handles hard multi-source research; deep-reasoning (12\u201340s) is only for the hardest work. Brave ignores this field."
|
|
35367
35437
|
})),
|
|
35368
|
-
...createExaFilterProperties(
|
|
35369
|
-
count:
|
|
35438
|
+
...createExaFilterProperties(),
|
|
35439
|
+
count: JsonSchema.Optional(JsonSchema.Integer({
|
|
35370
35440
|
minimum: 1,
|
|
35371
35441
|
maximum: MAX_SEARCH_RESULT_COUNT,
|
|
35372
35442
|
description: `Number of web results to return. Defaults to ${DEFAULT_SEARCH_RESULT_COUNT}; max ${MAX_SEARCH_RESULT_COUNT}.`
|
|
35373
35443
|
})),
|
|
35374
|
-
offset:
|
|
35444
|
+
offset: JsonSchema.Optional(JsonSchema.Integer({
|
|
35375
35445
|
minimum: 0,
|
|
35376
35446
|
maximum: 9,
|
|
35377
35447
|
description: "Zero-based result offset for pagination. Defaults to 0."
|
|
35378
35448
|
})),
|
|
35379
|
-
country:
|
|
35449
|
+
country: JsonSchema.Optional(JsonSchema.String({
|
|
35380
35450
|
pattern: "^[A-Za-z]{2}$",
|
|
35381
35451
|
description: "Optional 2-letter country code, such as US or GB."
|
|
35382
35452
|
})),
|
|
35383
|
-
searchLang:
|
|
35453
|
+
searchLang: JsonSchema.Optional(JsonSchema.String({
|
|
35384
35454
|
minLength: 2,
|
|
35385
35455
|
maxLength: 8,
|
|
35386
35456
|
description: "Optional Brave search language code, such as en or en-US."
|
|
35387
35457
|
})),
|
|
35388
|
-
safesearch:
|
|
35458
|
+
safesearch: JsonSchema.Optional(StringEnum(["off", "moderate", "strict"], {
|
|
35389
35459
|
description: "Optional search safety setting. Brave forwards this as safesearch; Exa maps moderate/strict to moderation=true."
|
|
35390
35460
|
})),
|
|
35391
|
-
freshness:
|
|
35461
|
+
freshness: JsonSchema.Optional(StringEnum(["pd", "pw", "pm", "py"], {
|
|
35392
35462
|
description: "Optional freshness window: pd=past day, pw=past week, pm=past month, py=past year."
|
|
35393
35463
|
}))
|
|
35394
35464
|
}, { additionalProperties: false });
|
|
@@ -35685,25 +35755,19 @@ function sleepWithAbort(ms, signal) {
|
|
|
35685
35755
|
});
|
|
35686
35756
|
}
|
|
35687
35757
|
var WebSearchRequestGate = class {
|
|
35688
|
-
now;
|
|
35689
|
-
sleep;
|
|
35690
35758
|
lastRequestStartedAt = 0;
|
|
35691
35759
|
tail = Promise.resolve();
|
|
35692
|
-
constructor(now = Date.now, sleep2 = sleepWithAbort) {
|
|
35693
|
-
this.now = now;
|
|
35694
|
-
this.sleep = sleep2;
|
|
35695
|
-
}
|
|
35696
35760
|
run(signal, task) {
|
|
35697
35761
|
const runTask = async () => {
|
|
35698
|
-
const elapsedMs = this.lastRequestStartedAt === 0 ? WEB_SEARCH_MIN_REQUEST_INTERVAL_MS :
|
|
35762
|
+
const elapsedMs = this.lastRequestStartedAt === 0 ? WEB_SEARCH_MIN_REQUEST_INTERVAL_MS : Date.now() - this.lastRequestStartedAt;
|
|
35699
35763
|
const waitMs = Math.max(0, WEB_SEARCH_MIN_REQUEST_INTERVAL_MS - elapsedMs);
|
|
35700
35764
|
if (waitMs > 0) {
|
|
35701
|
-
await
|
|
35765
|
+
await sleepWithAbort(waitMs, signal);
|
|
35702
35766
|
}
|
|
35703
35767
|
if (signal?.aborted === true) {
|
|
35704
35768
|
signal.throwIfAborted();
|
|
35705
35769
|
}
|
|
35706
|
-
this.lastRequestStartedAt =
|
|
35770
|
+
this.lastRequestStartedAt = Date.now();
|
|
35707
35771
|
return task();
|
|
35708
35772
|
};
|
|
35709
35773
|
const result = this.tail.then(runTask, runTask);
|
|
@@ -35712,18 +35776,19 @@ var WebSearchRequestGate = class {
|
|
|
35712
35776
|
return result;
|
|
35713
35777
|
}
|
|
35714
35778
|
};
|
|
35715
|
-
function redactSearchSecret(text3, apiKey) {
|
|
35716
|
-
return apiKey.length > 0 ? text3.split(apiKey).join("[REDACTED]") : text3;
|
|
35717
|
-
}
|
|
35718
35779
|
function formatSearchHttpError(options) {
|
|
35719
|
-
const { provider, status
|
|
35780
|
+
const { provider, status } = options;
|
|
35720
35781
|
const providerLabel = getProviderLabel(provider);
|
|
35721
|
-
const errorPreview = cleanSearchText(redactSearchSecret(body, apiKey), 300);
|
|
35722
35782
|
if (status === 429) {
|
|
35723
|
-
|
|
35724
|
-
|
|
35783
|
+
return `${providerLabel} search rate limit exceeded (HTTP 429). Do not issue parallel or repeated agent_browser_web_search calls; use one high-signal query, inspect those results, then wait before retrying or ask the user to adjust their ${providerLabel} API plan/limits.`;
|
|
35784
|
+
}
|
|
35785
|
+
if (status === 401 || status === 403) {
|
|
35786
|
+
return `${providerLabel} search failed with HTTP ${status}: Check your API credential and permissions.`;
|
|
35725
35787
|
}
|
|
35726
|
-
|
|
35788
|
+
if (status >= 500) {
|
|
35789
|
+
return `${providerLabel} search failed with HTTP ${status}: Provider unavailable; retry later.`;
|
|
35790
|
+
}
|
|
35791
|
+
return `${providerLabel} search failed with HTTP ${status}: Request rejected; check the search parameters.`;
|
|
35727
35792
|
}
|
|
35728
35793
|
async function fetchSearchJson(options) {
|
|
35729
35794
|
if (options.signal?.aborted === true) {
|
|
@@ -35735,20 +35800,19 @@ async function fetchSearchJson(options) {
|
|
|
35735
35800
|
options.signal?.addEventListener("abort", abort, { once: true });
|
|
35736
35801
|
try {
|
|
35737
35802
|
const response = await fetch(options.request, { ...options.init, signal: controller.signal });
|
|
35738
|
-
const text3 = await response.text();
|
|
35739
35803
|
if (!response.ok) {
|
|
35804
|
+
await response.body?.cancel().catch(() => {
|
|
35805
|
+
});
|
|
35740
35806
|
throw new Error(formatSearchHttpError({
|
|
35741
35807
|
provider: options.provider,
|
|
35742
|
-
status: response.status
|
|
35743
|
-
statusText: response.statusText,
|
|
35744
|
-
body: text3,
|
|
35745
|
-
apiKey: options.apiKey
|
|
35808
|
+
status: response.status
|
|
35746
35809
|
}));
|
|
35747
35810
|
}
|
|
35811
|
+
const text3 = await response.text();
|
|
35748
35812
|
try {
|
|
35749
35813
|
return JSON.parse(text3);
|
|
35750
|
-
} catch
|
|
35751
|
-
throw new Error(
|
|
35814
|
+
} catch {
|
|
35815
|
+
throw new Error(options.invalidJsonMessage);
|
|
35752
35816
|
}
|
|
35753
35817
|
} finally {
|
|
35754
35818
|
clearTimeout(timeout);
|
|
@@ -35827,7 +35891,6 @@ function buildExaSearchRequestBody(params, now = () => /* @__PURE__ */ new Date(
|
|
|
35827
35891
|
}
|
|
35828
35892
|
async function fetchBraveSearchJson(url, apiKey, signal) {
|
|
35829
35893
|
const data = await fetchSearchJson({
|
|
35830
|
-
apiKey,
|
|
35831
35894
|
cancelMessage: "Brave search cancelled",
|
|
35832
35895
|
init: { headers: { Accept: "application/json", "X-Subscription-Token": apiKey } },
|
|
35833
35896
|
invalidJsonMessage: "Brave search returned invalid JSON",
|
|
@@ -35860,7 +35923,6 @@ function usesDynamicHighlights(body) {
|
|
|
35860
35923
|
}
|
|
35861
35924
|
async function fetchExaSearchJson(body, apiKey, signal, timeoutMs = SEARCH_REQUEST_TIMEOUT_MS) {
|
|
35862
35925
|
const data = await fetchSearchJson({
|
|
35863
|
-
apiKey,
|
|
35864
35926
|
cancelMessage: "Exa search cancelled",
|
|
35865
35927
|
init: {
|
|
35866
35928
|
body: JSON.stringify(body),
|
|
@@ -35916,34 +35978,6 @@ var EXA_WEB_SEARCH_ADAPTER = {
|
|
|
35916
35978
|
};
|
|
35917
35979
|
}
|
|
35918
35980
|
};
|
|
35919
|
-
var WEB_SEARCH_PROVIDER_ADAPTERS = {
|
|
35920
|
-
brave: {
|
|
35921
|
-
provider: "brave",
|
|
35922
|
-
buildRequest: BRAVE_WEB_SEARCH_ADAPTER.buildRequest,
|
|
35923
|
-
fetchJson(request, apiKey, signal) {
|
|
35924
|
-
if (!(request instanceof URL)) {
|
|
35925
|
-
throw new Error("Brave search request must be a URL");
|
|
35926
|
-
}
|
|
35927
|
-
return BRAVE_WEB_SEARCH_ADAPTER.fetchJson(request, apiKey, signal);
|
|
35928
|
-
},
|
|
35929
|
-
normalizeResponse(response, params) {
|
|
35930
|
-
return BRAVE_WEB_SEARCH_ADAPTER.normalizeResponse(parseBraveSearchResponse(response), params);
|
|
35931
|
-
}
|
|
35932
|
-
},
|
|
35933
|
-
exa: {
|
|
35934
|
-
provider: "exa",
|
|
35935
|
-
buildRequest: EXA_WEB_SEARCH_ADAPTER.buildRequest,
|
|
35936
|
-
fetchJson(request, apiKey, signal) {
|
|
35937
|
-
if (!isRecord(request) || !isRecord(request.body) || typeof request.timeoutMs !== "number") {
|
|
35938
|
-
throw new Error("Exa search request must contain a body and timeout");
|
|
35939
|
-
}
|
|
35940
|
-
return fetchExaSearchJson(request.body, apiKey, signal, request.timeoutMs);
|
|
35941
|
-
},
|
|
35942
|
-
normalizeResponse(response, params) {
|
|
35943
|
-
return EXA_WEB_SEARCH_ADAPTER.normalizeResponse(parseExaSearchResponse(response), params);
|
|
35944
|
-
}
|
|
35945
|
-
}
|
|
35946
|
-
};
|
|
35947
35981
|
function prepareWebSearchRequest(provider, params, apiKey, signal) {
|
|
35948
35982
|
if (provider === "exa") {
|
|
35949
35983
|
const request2 = EXA_WEB_SEARCH_ADAPTER.buildRequest(params);
|
|
@@ -36041,8 +36075,12 @@ async function runWebSearch(state, params, gate, signal) {
|
|
|
36041
36075
|
duplicatesRemoved: duplicatesRemoved > 0 ? duplicatesRemoved : void 0
|
|
36042
36076
|
};
|
|
36043
36077
|
}
|
|
36044
|
-
async function presentSearchSuccess(
|
|
36045
|
-
const
|
|
36078
|
+
async function presentSearchSuccess(rawDetails, params) {
|
|
36079
|
+
const details = redactPresentationData({ command: "web-search" }, rawDetails);
|
|
36080
|
+
if (!isRecord(details) || !isWebSearchProvider(details.provider) || typeof details.returnedQuery !== "string" || !Array.isArray(details.results) || !details.results.every(isNormalizedSearchResult)) {
|
|
36081
|
+
throw new Error("Web search presentation has invalid result structure.");
|
|
36082
|
+
}
|
|
36083
|
+
const duplicateNotice = typeof details.duplicatesRemoved === "number" ? `
|
|
36046
36084
|
|
|
36047
36085
|
Duplicate URLs removed: ${details.duplicatesRemoved}.` : "";
|
|
36048
36086
|
const result = await finalizeAgentBrowserNativeResult({
|
|
@@ -36057,6 +36095,12 @@ Duplicate URLs removed: ${details.duplicatesRemoved}.` : "";
|
|
|
36057
36095
|
const finalizedManifest = result.details.artifactManifest;
|
|
36058
36096
|
return finalizedManifest === void 0 ? { ...result, details } : { ...result, details: { ...details, artifactManifest: finalizedManifest } };
|
|
36059
36097
|
}
|
|
36098
|
+
function isNormalizedSearchResult(value) {
|
|
36099
|
+
if (!isRecord(value) || typeof value.title !== "string" || typeof value.url !== "string") {
|
|
36100
|
+
return false;
|
|
36101
|
+
}
|
|
36102
|
+
return ["description", "source", "age", "pageDate", "language"].every((field) => value[field] === void 0 || typeof value[field] === "string") && (value.highlights === void 0 || isStringArray2(value.highlights));
|
|
36103
|
+
}
|
|
36060
36104
|
function failureCategory(error, signal) {
|
|
36061
36105
|
if (signal?.aborted === true) {
|
|
36062
36106
|
return "aborted";
|
|
@@ -38370,7 +38414,7 @@ async function runAgentBrowserScript(options) {
|
|
|
38370
38414
|
}
|
|
38371
38415
|
|
|
38372
38416
|
// dist/extensions/agent-browser/lib/orchestration/script-mode.js
|
|
38373
|
-
import { stat as
|
|
38417
|
+
import { stat as stat13 } from "node:fs/promises";
|
|
38374
38418
|
import { randomUUID as randomUUID7 } from "node:crypto";
|
|
38375
38419
|
init_parsing();
|
|
38376
38420
|
init_browser_transcript();
|
|
@@ -38621,7 +38665,7 @@ var BrowserCodeOutput = class {
|
|
|
38621
38665
|
if (image === void 0) {
|
|
38622
38666
|
throw new Error("Browser capture returned invalid image observation geometry.");
|
|
38623
38667
|
}
|
|
38624
|
-
const file = await
|
|
38668
|
+
const file = await stat13(image.path);
|
|
38625
38669
|
const id = `image-${this.images.size + 1}`;
|
|
38626
38670
|
this.images.set(id, { observation: image, size: file.size, mtime: file.mtimeMs });
|
|
38627
38671
|
return { ...image, id };
|
|
@@ -38644,7 +38688,7 @@ var BrowserCodeOutput = class {
|
|
|
38644
38688
|
if (this.selected.size >= 8 || this.selectedBytes + image.size > 20 * 1024 * 1024) {
|
|
38645
38689
|
throw new Error("Selected images exceed the code output limit (8 images / 20 MiB). Emit fewer images.");
|
|
38646
38690
|
}
|
|
38647
|
-
const file = await
|
|
38691
|
+
const file = await stat13(image.observation.path);
|
|
38648
38692
|
if (!file.isFile() || file.size !== image.size || file.mtimeMs !== image.mtime) {
|
|
38649
38693
|
throw new Error("The selected image changed since capture. Capture it again before emitting it.");
|
|
38650
38694
|
}
|
|
@@ -40379,7 +40423,7 @@ init_argv_grammar();
|
|
|
40379
40423
|
init_artifact_manifest();
|
|
40380
40424
|
init_runtime();
|
|
40381
40425
|
init_text();
|
|
40382
|
-
import { mkdir as mkdir5, readFile as readFile10, realpath as realpath3, stat as
|
|
40426
|
+
import { mkdir as mkdir5, readFile as readFile10, realpath as realpath3, stat as stat14, writeFile as writeFile3 } from "node:fs/promises";
|
|
40383
40427
|
import { dirname as dirname15, extname as extname7, isAbsolute as isAbsolute12, resolve as resolve14 } from "node:path";
|
|
40384
40428
|
function normalizeRequestedOutputPath(path) {
|
|
40385
40429
|
return path.startsWith("@") ? path.slice(1) : path;
|
|
@@ -40537,7 +40581,7 @@ async function pathsReferToSameFile(left, right) {
|
|
|
40537
40581
|
} catch {
|
|
40538
40582
|
}
|
|
40539
40583
|
try {
|
|
40540
|
-
const [leftStat, rightStat] = await Promise.all([
|
|
40584
|
+
const [leftStat, rightStat] = await Promise.all([stat14(left), stat14(right)]);
|
|
40541
40585
|
return leftStat.dev === rightStat.dev && leftStat.ino === rightStat.ino;
|
|
40542
40586
|
} catch {
|
|
40543
40587
|
return false;
|