opensteer 0.8.7 → 0.8.9
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/README.md +11 -11
- package/dist/{chunk-IAA57HNW.js → chunk-RO6WAWWG.js} +1948 -1008
- package/dist/chunk-RO6WAWWG.js.map +1 -0
- package/dist/cli/bin.cjs +1938 -1080
- package/dist/cli/bin.cjs.map +1 -1
- package/dist/cli/bin.js +14 -72
- package/dist/cli/bin.js.map +1 -1
- package/dist/index.cjs +1991 -1052
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +207 -24
- package/dist/index.d.ts +207 -24
- package/dist/index.js +9 -6
- package/dist/index.js.map +1 -1
- package/package.json +7 -7
- package/skills/opensteer/SKILL.md +29 -72
- package/skills/opensteer/references/cli-reference.md +6 -4
- package/skills/opensteer/references/request-workflow.md +21 -34
- package/skills/opensteer/references/sdk-reference.md +16 -14
- package/dist/chunk-IAA57HNW.js.map +0 -1
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import
|
|
2
|
-
import { createHash, randomUUID } from 'crypto';
|
|
3
|
-
import { access, rm, mkdtemp, mkdir, readFile, cp, readdir, writeFile, rename, stat, copyFile
|
|
1
|
+
import path7, { join, resolve, basename, relative } from 'path';
|
|
2
|
+
import { createHash, randomUUID, pbkdf2Sync, createDecipheriv } from 'crypto';
|
|
3
|
+
import { access, rm, mkdtemp, mkdir, readFile, cp, readdir, open, writeFile, rename, stat, copyFile } from 'fs/promises';
|
|
4
4
|
import { pathToFileURL } from 'url';
|
|
5
5
|
import { selectAll } from 'css-select';
|
|
6
6
|
import { execFileSync, execFile, spawn } from 'child_process';
|
|
@@ -8,6 +8,7 @@ import { existsSync, readFileSync } from 'fs';
|
|
|
8
8
|
import { tmpdir, homedir } from 'os';
|
|
9
9
|
import { connectPlaywrightChromiumBrowser, createPlaywrightBrowserCoreEngine, disconnectPlaywrightChromiumBrowser } from '@opensteer/engine-playwright';
|
|
10
10
|
import { promisify } from 'util';
|
|
11
|
+
import { AsyncLocalStorage } from 'async_hooks';
|
|
11
12
|
import { createRequire } from 'module';
|
|
12
13
|
import sharp from 'sharp';
|
|
13
14
|
import * as cheerio from 'cheerio';
|
|
@@ -16,15 +17,12 @@ import vm from 'vm';
|
|
|
16
17
|
import { gzip as gzip$1 } from 'zlib';
|
|
17
18
|
import WebSocket2 from 'ws';
|
|
18
19
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
const candidate = Reflect.get(engine, OPENSTEER_DOM_ACTION_BRIDGE_SYMBOL);
|
|
26
|
-
return isDomActionBridgeFactory(candidate) ? candidate.call(engine) : void 0;
|
|
27
|
-
}
|
|
20
|
+
var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
|
|
21
|
+
get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
|
|
22
|
+
}) : x)(function(x) {
|
|
23
|
+
if (typeof require !== "undefined") return require.apply(this, arguments);
|
|
24
|
+
throw Error('Dynamic require of "' + x + '" is not supported');
|
|
25
|
+
});
|
|
28
26
|
|
|
29
27
|
// ../runtime-core/src/json.ts
|
|
30
28
|
function isPlainObject(value) {
|
|
@@ -34,30 +32,30 @@ function isPlainObject(value) {
|
|
|
34
32
|
const prototype = Object.getPrototypeOf(value);
|
|
35
33
|
return prototype === Object.prototype || prototype === null;
|
|
36
34
|
}
|
|
37
|
-
function canonicalizeJsonValue(value,
|
|
35
|
+
function canonicalizeJsonValue(value, path15) {
|
|
38
36
|
if (value === null || typeof value === "string" || typeof value === "boolean") {
|
|
39
37
|
return value;
|
|
40
38
|
}
|
|
41
39
|
if (typeof value === "number") {
|
|
42
40
|
if (!Number.isFinite(value)) {
|
|
43
|
-
throw new TypeError(`${
|
|
41
|
+
throw new TypeError(`${path15} must be a finite JSON number`);
|
|
44
42
|
}
|
|
45
43
|
return value;
|
|
46
44
|
}
|
|
47
45
|
if (Array.isArray(value)) {
|
|
48
|
-
return value.map((entry, index) => canonicalizeJsonValue(entry, `${
|
|
46
|
+
return value.map((entry, index) => canonicalizeJsonValue(entry, `${path15}[${index}]`));
|
|
49
47
|
}
|
|
50
48
|
if (!isPlainObject(value)) {
|
|
51
|
-
throw new TypeError(`${
|
|
49
|
+
throw new TypeError(`${path15} must be a plain JSON object`);
|
|
52
50
|
}
|
|
53
51
|
const sorted = Object.keys(value).sort((left, right) => left.localeCompare(right));
|
|
54
52
|
const result = {};
|
|
55
53
|
for (const key of sorted) {
|
|
56
54
|
const entry = value[key];
|
|
57
55
|
if (entry === void 0) {
|
|
58
|
-
throw new TypeError(`${
|
|
56
|
+
throw new TypeError(`${path15}.${key} must not be undefined`);
|
|
59
57
|
}
|
|
60
|
-
result[key] = canonicalizeJsonValue(entry, `${
|
|
58
|
+
result[key] = canonicalizeJsonValue(entry, `${path15}.${key}`);
|
|
61
59
|
}
|
|
62
60
|
return result;
|
|
63
61
|
}
|
|
@@ -94,7 +92,7 @@ function joinStoragePath(...segments) {
|
|
|
94
92
|
return segments.join("/");
|
|
95
93
|
}
|
|
96
94
|
function resolveStoragePath(rootPath, relativePath) {
|
|
97
|
-
if (
|
|
95
|
+
if (path7.isAbsolute(relativePath)) {
|
|
98
96
|
throw new TypeError(`storage path ${relativePath} must be relative`);
|
|
99
97
|
}
|
|
100
98
|
const segments = relativePath.split("/");
|
|
@@ -106,7 +104,7 @@ function resolveStoragePath(rootPath, relativePath) {
|
|
|
106
104
|
throw new TypeError(`storage path ${relativePath} must not contain path traversal`);
|
|
107
105
|
}
|
|
108
106
|
}
|
|
109
|
-
return
|
|
107
|
+
return path7.join(rootPath, ...segments);
|
|
110
108
|
}
|
|
111
109
|
async function ensureDirectory(directoryPath) {
|
|
112
110
|
await mkdir(directoryPath, { recursive: true });
|
|
@@ -126,7 +124,7 @@ async function writeJsonFileAtomic(filePath, value) {
|
|
|
126
124
|
await writeTextFileAtomic(filePath, stableJsonString(value));
|
|
127
125
|
}
|
|
128
126
|
async function writeTextFileAtomic(filePath, value) {
|
|
129
|
-
await ensureDirectory(
|
|
127
|
+
await ensureDirectory(path7.dirname(filePath));
|
|
130
128
|
const temporaryPath = `${filePath}.${randomUUID()}.tmp`;
|
|
131
129
|
await writeFile(temporaryPath, value, "utf8");
|
|
132
130
|
await rename(temporaryPath, filePath);
|
|
@@ -135,7 +133,7 @@ async function writeJsonFileExclusive(filePath, value) {
|
|
|
135
133
|
await writeTextFileExclusive(filePath, stableJsonString(value));
|
|
136
134
|
}
|
|
137
135
|
async function writeTextFileExclusive(filePath, value) {
|
|
138
|
-
await ensureDirectory(
|
|
136
|
+
await ensureDirectory(path7.dirname(filePath));
|
|
139
137
|
const handle = await open(filePath, "wx");
|
|
140
138
|
try {
|
|
141
139
|
await handle.writeFile(value, "utf8");
|
|
@@ -144,7 +142,7 @@ async function writeTextFileExclusive(filePath, value) {
|
|
|
144
142
|
}
|
|
145
143
|
}
|
|
146
144
|
async function writeBufferIfMissing(filePath, value) {
|
|
147
|
-
await ensureDirectory(
|
|
145
|
+
await ensureDirectory(path7.dirname(filePath));
|
|
148
146
|
try {
|
|
149
147
|
const handle = await open(filePath, "wx");
|
|
150
148
|
try {
|
|
@@ -178,7 +176,7 @@ function isAlreadyExistsError(error) {
|
|
|
178
176
|
return error?.code === "EEXIST";
|
|
179
177
|
}
|
|
180
178
|
async function withFilesystemLock(lockPath, task) {
|
|
181
|
-
await ensureDirectory(
|
|
179
|
+
await ensureDirectory(path7.dirname(lockPath));
|
|
182
180
|
let attempt = 0;
|
|
183
181
|
while (true) {
|
|
184
182
|
try {
|
|
@@ -190,7 +188,7 @@ async function withFilesystemLock(lockPath, task) {
|
|
|
190
188
|
}
|
|
191
189
|
const delayMs = LOCK_RETRY_DELAYS_MS[Math.min(attempt, LOCK_RETRY_DELAYS_MS.length - 1)];
|
|
192
190
|
attempt += 1;
|
|
193
|
-
await new Promise((
|
|
191
|
+
await new Promise((resolve4) => setTimeout(resolve4, delayMs));
|
|
194
192
|
}
|
|
195
193
|
}
|
|
196
194
|
try {
|
|
@@ -233,8 +231,8 @@ async function readStructuredPayload(objectPath) {
|
|
|
233
231
|
var FilesystemArtifactStore = class {
|
|
234
232
|
constructor(rootPath) {
|
|
235
233
|
this.rootPath = rootPath;
|
|
236
|
-
this.manifestsDirectory =
|
|
237
|
-
this.objectsDirectory =
|
|
234
|
+
this.manifestsDirectory = path7.join(this.rootPath, "artifacts", "manifests");
|
|
235
|
+
this.objectsDirectory = path7.join(this.rootPath, "artifacts", "objects", "sha256");
|
|
238
236
|
}
|
|
239
237
|
manifestsDirectory;
|
|
240
238
|
objectsDirectory;
|
|
@@ -459,7 +457,7 @@ var FilesystemArtifactStore = class {
|
|
|
459
457
|
}
|
|
460
458
|
}
|
|
461
459
|
manifestPath(artifactId) {
|
|
462
|
-
return
|
|
460
|
+
return path7.join(this.manifestsDirectory, `${encodePathSegment(artifactId)}.json`);
|
|
463
461
|
}
|
|
464
462
|
};
|
|
465
463
|
function createArtifactStore(rootPath) {
|
|
@@ -487,6 +485,556 @@ function mediaTypeExtension(mediaType) {
|
|
|
487
485
|
}
|
|
488
486
|
}
|
|
489
487
|
|
|
488
|
+
// ../protocol/src/dom-action-bridge.ts
|
|
489
|
+
var OPENSTEER_DOM_ACTION_BRIDGE_SYMBOL = /* @__PURE__ */ Symbol.for("@opensteer/dom-action-bridge");
|
|
490
|
+
function isDomActionBridgeFactory(value) {
|
|
491
|
+
return typeof value === "function";
|
|
492
|
+
}
|
|
493
|
+
function resolveDomActionBridge(engine) {
|
|
494
|
+
const candidate = Reflect.get(engine, OPENSTEER_DOM_ACTION_BRIDGE_SYMBOL);
|
|
495
|
+
return isDomActionBridgeFactory(candidate) ? candidate.call(engine) : void 0;
|
|
496
|
+
}
|
|
497
|
+
|
|
498
|
+
// ../runtime-core/src/observation-utils.ts
|
|
499
|
+
var REDACTED = "[REDACTED]";
|
|
500
|
+
var SENSITIVE_KEY_PATTERN = /(authorization|proxy[_-]?authorization|cookie|set-cookie|api[_-]?key|access[_-]?token|refresh[_-]?token|auth[_-]?token|token|secret|password|passwd|private[_-]?key|database[_-]?url|db[_-]?url|session(?:id)?|csrf(?:token)?)/i;
|
|
501
|
+
var SENSITIVE_VALUE_PATTERNS = [
|
|
502
|
+
/\bsk-[A-Za-z0-9_-]{20,}\b/g,
|
|
503
|
+
/\bAIza[0-9A-Za-z_-]{20,}\b/g,
|
|
504
|
+
/\b(?:gh[pousr]_[A-Za-z0-9]{20,}|github_pat_[A-Za-z0-9_]{20,})\b/g,
|
|
505
|
+
/\beyJ[A-Za-z0-9_-]{10,}\.[A-Za-z0-9_-]{10,}\.[A-Za-z0-9_-]{10,}\b/g,
|
|
506
|
+
/\bBearer\s+[A-Za-z0-9._~+/=-]{16,}\b/gi
|
|
507
|
+
];
|
|
508
|
+
function normalizeObservationContext(context) {
|
|
509
|
+
if (context === void 0) {
|
|
510
|
+
return void 0;
|
|
511
|
+
}
|
|
512
|
+
const normalized = {
|
|
513
|
+
...context.sessionRef === void 0 ? {} : { sessionRef: context.sessionRef },
|
|
514
|
+
...context.pageRef === void 0 ? {} : { pageRef: context.pageRef },
|
|
515
|
+
...context.frameRef === void 0 ? {} : { frameRef: context.frameRef },
|
|
516
|
+
...context.documentRef === void 0 ? {} : { documentRef: context.documentRef },
|
|
517
|
+
...context.documentEpoch === void 0 ? {} : { documentEpoch: context.documentEpoch }
|
|
518
|
+
};
|
|
519
|
+
return Object.keys(normalized).length === 0 ? void 0 : normalized;
|
|
520
|
+
}
|
|
521
|
+
function createObservationRedactor(config) {
|
|
522
|
+
const state = createRedactionState(config);
|
|
523
|
+
return {
|
|
524
|
+
redactText(value) {
|
|
525
|
+
return redactString(value, state);
|
|
526
|
+
},
|
|
527
|
+
redactJson(value) {
|
|
528
|
+
return value === void 0 ? void 0 : redactUnknown(value, state, /* @__PURE__ */ new WeakSet());
|
|
529
|
+
},
|
|
530
|
+
redactError(error) {
|
|
531
|
+
if (error === void 0) {
|
|
532
|
+
return void 0;
|
|
533
|
+
}
|
|
534
|
+
return {
|
|
535
|
+
...error.code === void 0 ? {} : { code: redactString(error.code, state) },
|
|
536
|
+
message: redactString(error.message, state),
|
|
537
|
+
...error.retriable === void 0 ? {} : { retriable: error.retriable },
|
|
538
|
+
...error.details === void 0 ? {} : { details: toCanonicalJsonValue(redactUnknown(error.details, state, /* @__PURE__ */ new WeakSet())) }
|
|
539
|
+
};
|
|
540
|
+
},
|
|
541
|
+
redactLabels(labels) {
|
|
542
|
+
if (labels === void 0) {
|
|
543
|
+
return void 0;
|
|
544
|
+
}
|
|
545
|
+
const next = Object.entries(labels).reduce(
|
|
546
|
+
(accumulator, [key, value]) => {
|
|
547
|
+
accumulator[key] = isSensitiveKey(key, state) ? REDACTED : redactString(value, state);
|
|
548
|
+
return accumulator;
|
|
549
|
+
},
|
|
550
|
+
{}
|
|
551
|
+
);
|
|
552
|
+
return Object.keys(next).length === 0 ? void 0 : next;
|
|
553
|
+
},
|
|
554
|
+
redactTraceContext(traceContext) {
|
|
555
|
+
if (traceContext === void 0) {
|
|
556
|
+
return void 0;
|
|
557
|
+
}
|
|
558
|
+
const next = {
|
|
559
|
+
...traceContext.traceparent === void 0 ? {} : { traceparent: redactString(traceContext.traceparent, state) },
|
|
560
|
+
...traceContext.baggage === void 0 ? {} : { baggage: redactString(traceContext.baggage, state) }
|
|
561
|
+
};
|
|
562
|
+
return Object.keys(next).length === 0 ? void 0 : next;
|
|
563
|
+
}
|
|
564
|
+
};
|
|
565
|
+
}
|
|
566
|
+
function createRedactionState(config) {
|
|
567
|
+
return {
|
|
568
|
+
sensitiveKeys: new Set(
|
|
569
|
+
(config?.redaction?.sensitiveKeys ?? []).map((value) => value.trim().toLowerCase()).filter((value) => value.length > 0)
|
|
570
|
+
),
|
|
571
|
+
sensitiveValues: [
|
|
572
|
+
...new Set(
|
|
573
|
+
(config?.redaction?.sensitiveValues ?? []).map((value) => value.trim()).filter((value) => value.length > 0)
|
|
574
|
+
)
|
|
575
|
+
]
|
|
576
|
+
};
|
|
577
|
+
}
|
|
578
|
+
function redactUnknown(value, state, seen) {
|
|
579
|
+
if (value === null || value === void 0) {
|
|
580
|
+
return value;
|
|
581
|
+
}
|
|
582
|
+
if (typeof value === "string") {
|
|
583
|
+
return redactString(value, state);
|
|
584
|
+
}
|
|
585
|
+
if (typeof value !== "object") {
|
|
586
|
+
return value;
|
|
587
|
+
}
|
|
588
|
+
if (seen.has(value)) {
|
|
589
|
+
return REDACTED;
|
|
590
|
+
}
|
|
591
|
+
seen.add(value);
|
|
592
|
+
if (Array.isArray(value)) {
|
|
593
|
+
return value.map((entry) => redactUnknown(entry, state, seen));
|
|
594
|
+
}
|
|
595
|
+
const next = {};
|
|
596
|
+
for (const [key, nestedValue] of Object.entries(value)) {
|
|
597
|
+
next[key] = isSensitiveKey(key, state) ? REDACTED : redactUnknown(nestedValue, state, seen);
|
|
598
|
+
}
|
|
599
|
+
return next;
|
|
600
|
+
}
|
|
601
|
+
function redactString(value, state) {
|
|
602
|
+
let next = value;
|
|
603
|
+
for (const secret of state.sensitiveValues) {
|
|
604
|
+
next = next.split(secret).join(REDACTED);
|
|
605
|
+
}
|
|
606
|
+
for (const pattern of SENSITIVE_VALUE_PATTERNS) {
|
|
607
|
+
next = next.replace(pattern, REDACTED);
|
|
608
|
+
}
|
|
609
|
+
return redactUrlString(next, state);
|
|
610
|
+
}
|
|
611
|
+
function redactUrlString(value, state) {
|
|
612
|
+
let parsed;
|
|
613
|
+
try {
|
|
614
|
+
parsed = new URL(value);
|
|
615
|
+
} catch {
|
|
616
|
+
return value;
|
|
617
|
+
}
|
|
618
|
+
let changed = false;
|
|
619
|
+
if (parsed.username) {
|
|
620
|
+
parsed.username = REDACTED;
|
|
621
|
+
changed = true;
|
|
622
|
+
}
|
|
623
|
+
if (parsed.password) {
|
|
624
|
+
parsed.password = REDACTED;
|
|
625
|
+
changed = true;
|
|
626
|
+
}
|
|
627
|
+
for (const [key] of parsed.searchParams) {
|
|
628
|
+
if (!isSensitiveKey(key, state)) {
|
|
629
|
+
continue;
|
|
630
|
+
}
|
|
631
|
+
parsed.searchParams.set(key, REDACTED);
|
|
632
|
+
changed = true;
|
|
633
|
+
}
|
|
634
|
+
return changed ? parsed.toString() : value;
|
|
635
|
+
}
|
|
636
|
+
function isSensitiveKey(key, state) {
|
|
637
|
+
return state.sensitiveKeys.has(key.trim().toLowerCase()) || SENSITIVE_KEY_PATTERN.test(key);
|
|
638
|
+
}
|
|
639
|
+
|
|
640
|
+
// ../runtime-core/src/observations.ts
|
|
641
|
+
function normalizeObservabilityConfig(input) {
|
|
642
|
+
const profile = input?.profile ?? "diagnostic";
|
|
643
|
+
const labels = input?.labels === void 0 ? void 0 : Object.entries(input.labels).reduce((accumulator, [key, value]) => {
|
|
644
|
+
const normalizedKey = key.trim();
|
|
645
|
+
const normalizedValue = value.trim();
|
|
646
|
+
if (normalizedKey.length === 0 || normalizedValue.length === 0) {
|
|
647
|
+
return accumulator;
|
|
648
|
+
}
|
|
649
|
+
if (Object.keys(accumulator).length >= 20) {
|
|
650
|
+
return accumulator;
|
|
651
|
+
}
|
|
652
|
+
accumulator[normalizedKey] = normalizedValue;
|
|
653
|
+
return accumulator;
|
|
654
|
+
}, {});
|
|
655
|
+
const redaction = input?.redaction === void 0 ? void 0 : {
|
|
656
|
+
...input.redaction.sensitiveKeys === void 0 ? {} : {
|
|
657
|
+
sensitiveKeys: input.redaction.sensitiveKeys.map((value) => value.trim()).filter((value) => value.length > 0)
|
|
658
|
+
},
|
|
659
|
+
...input.redaction.sensitiveValues === void 0 ? {} : {
|
|
660
|
+
sensitiveValues: input.redaction.sensitiveValues.map((value) => value.trim()).filter((value) => value.length > 0)
|
|
661
|
+
}
|
|
662
|
+
};
|
|
663
|
+
return {
|
|
664
|
+
profile,
|
|
665
|
+
...labels === void 0 || Object.keys(labels).length === 0 ? {} : { labels },
|
|
666
|
+
...input?.traceContext === void 0 ? {} : {
|
|
667
|
+
traceContext: {
|
|
668
|
+
...input.traceContext.traceparent === void 0 ? {} : { traceparent: input.traceContext.traceparent.trim() },
|
|
669
|
+
...input.traceContext.baggage === void 0 ? {} : { baggage: input.traceContext.baggage.trim() }
|
|
670
|
+
}
|
|
671
|
+
},
|
|
672
|
+
...redaction === void 0 ? {} : { redaction }
|
|
673
|
+
};
|
|
674
|
+
}
|
|
675
|
+
function eventFileName(sequence) {
|
|
676
|
+
return `${String(sequence).padStart(12, "0")}.json`;
|
|
677
|
+
}
|
|
678
|
+
var FilesystemSessionSink = class {
|
|
679
|
+
constructor(store, sessionId) {
|
|
680
|
+
this.store = store;
|
|
681
|
+
this.sessionId = sessionId;
|
|
682
|
+
}
|
|
683
|
+
append(input) {
|
|
684
|
+
return this.store.appendEvent(this.sessionId, input);
|
|
685
|
+
}
|
|
686
|
+
appendBatch(input) {
|
|
687
|
+
return this.store.appendEvents(this.sessionId, input);
|
|
688
|
+
}
|
|
689
|
+
writeArtifact(input) {
|
|
690
|
+
return this.store.writeArtifact(this.sessionId, input);
|
|
691
|
+
}
|
|
692
|
+
async flush() {
|
|
693
|
+
}
|
|
694
|
+
close(reason) {
|
|
695
|
+
return this.store.closeSession(this.sessionId, reason);
|
|
696
|
+
}
|
|
697
|
+
};
|
|
698
|
+
var FilesystemObservationStoreImpl = class {
|
|
699
|
+
constructor(rootPath, artifacts) {
|
|
700
|
+
this.rootPath = rootPath;
|
|
701
|
+
this.artifacts = artifacts;
|
|
702
|
+
this.sessionsDirectory = path7.join(this.rootPath, "observations", "sessions");
|
|
703
|
+
}
|
|
704
|
+
sessionsDirectory;
|
|
705
|
+
redactors = /* @__PURE__ */ new Map();
|
|
706
|
+
async initialize() {
|
|
707
|
+
await ensureDirectory(this.sessionsDirectory);
|
|
708
|
+
}
|
|
709
|
+
async openSession(input) {
|
|
710
|
+
const sessionId = normalizeNonEmptyString("sessionId", input.sessionId);
|
|
711
|
+
const openedAt = normalizeTimestamp("openedAt", input.openedAt ?? Date.now());
|
|
712
|
+
const config = normalizeObservabilityConfig(input.config);
|
|
713
|
+
const redactor = createObservationRedactor(config);
|
|
714
|
+
this.redactors.set(sessionId, redactor);
|
|
715
|
+
const redactedLabels = redactor.redactLabels(config.labels);
|
|
716
|
+
const redactedTraceContext = redactor.redactTraceContext(config.traceContext);
|
|
717
|
+
await withFilesystemLock(this.sessionLockPath(sessionId), async () => {
|
|
718
|
+
const existing = await this.reconcileSessionManifest(sessionId);
|
|
719
|
+
if (existing === void 0) {
|
|
720
|
+
await ensureDirectory(this.sessionEventsDirectory(sessionId));
|
|
721
|
+
await ensureDirectory(this.sessionArtifactsDirectory(sessionId));
|
|
722
|
+
const session = {
|
|
723
|
+
sessionId,
|
|
724
|
+
profile: config.profile,
|
|
725
|
+
...redactedLabels === void 0 ? {} : { labels: redactedLabels },
|
|
726
|
+
...redactedTraceContext === void 0 ? {} : { traceContext: redactedTraceContext },
|
|
727
|
+
openedAt,
|
|
728
|
+
updatedAt: openedAt,
|
|
729
|
+
currentSequence: 0,
|
|
730
|
+
eventCount: 0,
|
|
731
|
+
artifactCount: 0
|
|
732
|
+
};
|
|
733
|
+
await writeJsonFileExclusive(this.sessionManifestPath(sessionId), session);
|
|
734
|
+
return;
|
|
735
|
+
}
|
|
736
|
+
const patched = {
|
|
737
|
+
...existing,
|
|
738
|
+
profile: config.profile,
|
|
739
|
+
...redactedLabels === void 0 ? {} : { labels: redactedLabels },
|
|
740
|
+
...redactedTraceContext === void 0 ? {} : { traceContext: redactedTraceContext },
|
|
741
|
+
updatedAt: Math.max(existing.updatedAt, openedAt)
|
|
742
|
+
};
|
|
743
|
+
await writeJsonFileAtomic(this.sessionManifestPath(sessionId), patched);
|
|
744
|
+
});
|
|
745
|
+
return new FilesystemSessionSink(this, sessionId);
|
|
746
|
+
}
|
|
747
|
+
async getSession(sessionId) {
|
|
748
|
+
const manifestPath = this.sessionManifestPath(sessionId);
|
|
749
|
+
if (!await pathExists(manifestPath)) {
|
|
750
|
+
return void 0;
|
|
751
|
+
}
|
|
752
|
+
return readJsonFile(manifestPath);
|
|
753
|
+
}
|
|
754
|
+
async appendEvent(sessionId, input) {
|
|
755
|
+
const [event] = await this.appendEvents(sessionId, [input]);
|
|
756
|
+
if (event === void 0) {
|
|
757
|
+
throw new Error(`failed to append observation event for session ${sessionId}`);
|
|
758
|
+
}
|
|
759
|
+
return event;
|
|
760
|
+
}
|
|
761
|
+
async appendEvents(sessionId, input) {
|
|
762
|
+
if (input.length === 0) {
|
|
763
|
+
return [];
|
|
764
|
+
}
|
|
765
|
+
return withFilesystemLock(this.sessionLockPath(sessionId), async () => {
|
|
766
|
+
const session = await this.reconcileSessionManifest(sessionId);
|
|
767
|
+
if (session === void 0) {
|
|
768
|
+
throw new Error(`observation session ${sessionId} was not found`);
|
|
769
|
+
}
|
|
770
|
+
const redactor = this.redactors.get(sessionId) ?? createObservationRedactor(void 0);
|
|
771
|
+
const events = [];
|
|
772
|
+
let sequence = session.currentSequence;
|
|
773
|
+
let updatedAt = session.updatedAt;
|
|
774
|
+
for (const raw of input) {
|
|
775
|
+
sequence += 1;
|
|
776
|
+
const createdAt = normalizeTimestamp("createdAt", raw.createdAt);
|
|
777
|
+
const context = normalizeObservationContext(raw.context);
|
|
778
|
+
const redactedData = raw.data === void 0 ? void 0 : redactor.redactJson(toCanonicalJsonValue(raw.data));
|
|
779
|
+
const redactedError = redactor.redactError(raw.error);
|
|
780
|
+
const event = {
|
|
781
|
+
eventId: normalizeNonEmptyString(
|
|
782
|
+
"eventId",
|
|
783
|
+
raw.eventId ?? `observation:${sessionId}:${String(sequence).padStart(12, "0")}`
|
|
784
|
+
),
|
|
785
|
+
sessionId,
|
|
786
|
+
sequence,
|
|
787
|
+
kind: raw.kind,
|
|
788
|
+
phase: raw.phase,
|
|
789
|
+
createdAt,
|
|
790
|
+
correlationId: normalizeNonEmptyString("correlationId", raw.correlationId),
|
|
791
|
+
...raw.spanId === void 0 ? {} : { spanId: normalizeNonEmptyString("spanId", raw.spanId) },
|
|
792
|
+
...raw.parentSpanId === void 0 ? {} : { parentSpanId: normalizeNonEmptyString("parentSpanId", raw.parentSpanId) },
|
|
793
|
+
...context === void 0 ? {} : { context },
|
|
794
|
+
...redactedData === void 0 ? {} : { data: redactedData },
|
|
795
|
+
...redactedError === void 0 ? {} : { error: redactedError },
|
|
796
|
+
...raw.artifactIds === void 0 || raw.artifactIds.length === 0 ? {} : { artifactIds: [...raw.artifactIds] }
|
|
797
|
+
};
|
|
798
|
+
await writeJsonFileExclusive(
|
|
799
|
+
path7.join(this.sessionEventsDirectory(sessionId), eventFileName(sequence)),
|
|
800
|
+
event
|
|
801
|
+
);
|
|
802
|
+
updatedAt = Math.max(updatedAt, createdAt);
|
|
803
|
+
events.push(event);
|
|
804
|
+
}
|
|
805
|
+
await writeJsonFileAtomic(this.sessionManifestPath(sessionId), {
|
|
806
|
+
...session,
|
|
807
|
+
currentSequence: sequence,
|
|
808
|
+
eventCount: session.eventCount + events.length,
|
|
809
|
+
updatedAt
|
|
810
|
+
});
|
|
811
|
+
return events;
|
|
812
|
+
});
|
|
813
|
+
}
|
|
814
|
+
async writeArtifact(sessionId, input) {
|
|
815
|
+
return withFilesystemLock(this.sessionLockPath(sessionId), async () => {
|
|
816
|
+
const session = await this.reconcileSessionManifest(sessionId);
|
|
817
|
+
if (session === void 0) {
|
|
818
|
+
throw new Error(`observation session ${sessionId} was not found`);
|
|
819
|
+
}
|
|
820
|
+
const redactor = this.redactors.get(sessionId) ?? createObservationRedactor(void 0);
|
|
821
|
+
const createdAt = normalizeTimestamp("createdAt", input.createdAt);
|
|
822
|
+
const context = normalizeObservationContext(input.context);
|
|
823
|
+
const redactedStorageKey = input.storageKey === void 0 ? void 0 : redactor.redactText(input.storageKey);
|
|
824
|
+
const redactedMetadata = input.metadata === void 0 ? void 0 : redactor.redactJson(toCanonicalJsonValue(input.metadata));
|
|
825
|
+
const artifact = {
|
|
826
|
+
artifactId: normalizeNonEmptyString("artifactId", input.artifactId),
|
|
827
|
+
sessionId,
|
|
828
|
+
kind: input.kind,
|
|
829
|
+
createdAt,
|
|
830
|
+
...context === void 0 ? {} : { context },
|
|
831
|
+
...input.mediaType === void 0 ? {} : { mediaType: input.mediaType },
|
|
832
|
+
...input.byteLength === void 0 ? {} : { byteLength: input.byteLength },
|
|
833
|
+
...input.sha256 === void 0 ? {} : { sha256: input.sha256 },
|
|
834
|
+
...input.opensteerArtifactId === void 0 ? {} : { opensteerArtifactId: input.opensteerArtifactId },
|
|
835
|
+
...redactedStorageKey === void 0 ? {} : { storageKey: redactedStorageKey },
|
|
836
|
+
...redactedMetadata === void 0 ? {} : { metadata: redactedMetadata }
|
|
837
|
+
};
|
|
838
|
+
const artifactPath = this.sessionArtifactPath(sessionId, artifact.artifactId);
|
|
839
|
+
if (!await pathExists(artifactPath)) {
|
|
840
|
+
await writeJsonFileExclusive(artifactPath, artifact);
|
|
841
|
+
await writeJsonFileAtomic(this.sessionManifestPath(sessionId), {
|
|
842
|
+
...session,
|
|
843
|
+
artifactCount: session.artifactCount + 1,
|
|
844
|
+
updatedAt: Math.max(session.updatedAt, createdAt)
|
|
845
|
+
});
|
|
846
|
+
}
|
|
847
|
+
return artifact;
|
|
848
|
+
});
|
|
849
|
+
}
|
|
850
|
+
async listEvents(sessionId, input = {}) {
|
|
851
|
+
const directoryPath = this.sessionEventsDirectory(sessionId);
|
|
852
|
+
if (!await pathExists(directoryPath)) {
|
|
853
|
+
return [];
|
|
854
|
+
}
|
|
855
|
+
const files = await listJsonFiles(directoryPath);
|
|
856
|
+
const events = await Promise.all(
|
|
857
|
+
files.map((fileName) => readJsonFile(path7.join(directoryPath, fileName)))
|
|
858
|
+
);
|
|
859
|
+
const filtered = events.filter((event) => {
|
|
860
|
+
if (input.kind !== void 0 && event.kind !== input.kind) return false;
|
|
861
|
+
if (input.phase !== void 0 && event.phase !== input.phase) return false;
|
|
862
|
+
if (input.correlationId !== void 0 && event.correlationId !== input.correlationId) {
|
|
863
|
+
return false;
|
|
864
|
+
}
|
|
865
|
+
if (input.pageRef !== void 0 && event.context?.pageRef !== input.pageRef) return false;
|
|
866
|
+
if (input.afterSequence !== void 0 && event.sequence <= input.afterSequence) return false;
|
|
867
|
+
if (input.from !== void 0 && event.createdAt < input.from) return false;
|
|
868
|
+
if (input.to !== void 0 && event.createdAt > input.to) return false;
|
|
869
|
+
return true;
|
|
870
|
+
});
|
|
871
|
+
if (input.limit === void 0 || filtered.length <= input.limit) {
|
|
872
|
+
return filtered;
|
|
873
|
+
}
|
|
874
|
+
return filtered.slice(-input.limit);
|
|
875
|
+
}
|
|
876
|
+
async listArtifacts(sessionId, input = {}) {
|
|
877
|
+
const directoryPath = this.sessionArtifactsDirectory(sessionId);
|
|
878
|
+
if (!await pathExists(directoryPath)) {
|
|
879
|
+
return [];
|
|
880
|
+
}
|
|
881
|
+
const files = await listJsonFiles(directoryPath);
|
|
882
|
+
const artifacts = await Promise.all(
|
|
883
|
+
files.map(
|
|
884
|
+
(fileName) => readJsonFile(path7.join(directoryPath, fileName))
|
|
885
|
+
)
|
|
886
|
+
);
|
|
887
|
+
const filtered = artifacts.filter((artifact) => {
|
|
888
|
+
if (input.kind !== void 0 && artifact.kind !== input.kind) return false;
|
|
889
|
+
if (input.pageRef !== void 0 && artifact.context?.pageRef !== input.pageRef) return false;
|
|
890
|
+
return true;
|
|
891
|
+
});
|
|
892
|
+
if (input.limit === void 0 || filtered.length <= input.limit) {
|
|
893
|
+
return filtered;
|
|
894
|
+
}
|
|
895
|
+
return filtered.slice(-input.limit);
|
|
896
|
+
}
|
|
897
|
+
async getArtifact(sessionId, artifactId) {
|
|
898
|
+
const artifactPath = this.sessionArtifactPath(sessionId, artifactId);
|
|
899
|
+
if (!await pathExists(artifactPath)) {
|
|
900
|
+
return void 0;
|
|
901
|
+
}
|
|
902
|
+
return readJsonFile(artifactPath);
|
|
903
|
+
}
|
|
904
|
+
async closeSession(sessionId, _reason) {
|
|
905
|
+
await withFilesystemLock(this.sessionLockPath(sessionId), async () => {
|
|
906
|
+
const session = await this.reconcileSessionManifest(sessionId);
|
|
907
|
+
if (session === void 0 || session.closedAt !== void 0) {
|
|
908
|
+
return;
|
|
909
|
+
}
|
|
910
|
+
const now = Date.now();
|
|
911
|
+
await writeJsonFileAtomic(this.sessionManifestPath(sessionId), {
|
|
912
|
+
...session,
|
|
913
|
+
updatedAt: Math.max(session.updatedAt, now),
|
|
914
|
+
closedAt: now
|
|
915
|
+
});
|
|
916
|
+
});
|
|
917
|
+
this.redactors.delete(sessionId);
|
|
918
|
+
}
|
|
919
|
+
async writeArtifactFromManifest(sessionId, manifest, kind, metadata) {
|
|
920
|
+
return this.writeArtifact(sessionId, {
|
|
921
|
+
artifactId: manifest.artifactId,
|
|
922
|
+
kind,
|
|
923
|
+
createdAt: manifest.createdAt,
|
|
924
|
+
context: manifest.scope,
|
|
925
|
+
mediaType: manifest.mediaType,
|
|
926
|
+
byteLength: manifest.byteLength,
|
|
927
|
+
sha256: manifest.sha256,
|
|
928
|
+
opensteerArtifactId: manifest.artifactId,
|
|
929
|
+
storageKey: manifestToExternalBinaryLocation(this.rootPath, manifest).uri,
|
|
930
|
+
...metadata === void 0 ? {} : { metadata }
|
|
931
|
+
});
|
|
932
|
+
}
|
|
933
|
+
async ensureArtifactLinked(sessionId, manifest) {
|
|
934
|
+
const existing = await this.getArtifact(sessionId, manifest.artifactId);
|
|
935
|
+
if (existing !== void 0) {
|
|
936
|
+
return existing;
|
|
937
|
+
}
|
|
938
|
+
const kind = toObservationArtifactKind(manifest.kind);
|
|
939
|
+
return this.writeArtifactFromManifest(sessionId, manifest, kind);
|
|
940
|
+
}
|
|
941
|
+
async hydrateArtifactManifests(artifactIds) {
|
|
942
|
+
return (await Promise.all(
|
|
943
|
+
artifactIds.map(async (artifactId) => this.artifacts.getManifest(artifactId))
|
|
944
|
+
)).filter((value) => value !== void 0);
|
|
945
|
+
}
|
|
946
|
+
sessionDirectory(sessionId) {
|
|
947
|
+
return path7.join(this.sessionsDirectory, encodePathSegment(sessionId));
|
|
948
|
+
}
|
|
949
|
+
sessionManifestPath(sessionId) {
|
|
950
|
+
return path7.join(this.sessionDirectory(sessionId), "session.json");
|
|
951
|
+
}
|
|
952
|
+
sessionEventsDirectory(sessionId) {
|
|
953
|
+
return path7.join(this.sessionDirectory(sessionId), "events");
|
|
954
|
+
}
|
|
955
|
+
sessionArtifactsDirectory(sessionId) {
|
|
956
|
+
return path7.join(this.sessionDirectory(sessionId), "artifacts");
|
|
957
|
+
}
|
|
958
|
+
sessionArtifactPath(sessionId, artifactId) {
|
|
959
|
+
return path7.join(
|
|
960
|
+
this.sessionArtifactsDirectory(sessionId),
|
|
961
|
+
`${encodePathSegment(artifactId)}.json`
|
|
962
|
+
);
|
|
963
|
+
}
|
|
964
|
+
sessionLockPath(sessionId) {
|
|
965
|
+
return path7.join(this.sessionDirectory(sessionId), ".lock");
|
|
966
|
+
}
|
|
967
|
+
async reconcileSessionManifest(sessionId) {
|
|
968
|
+
const session = await this.getSession(sessionId);
|
|
969
|
+
if (session === void 0) {
|
|
970
|
+
return void 0;
|
|
971
|
+
}
|
|
972
|
+
const [hasEventDirectory, hasArtifactDirectory] = await Promise.all([
|
|
973
|
+
pathExists(this.sessionEventsDirectory(sessionId)),
|
|
974
|
+
pathExists(this.sessionArtifactsDirectory(sessionId))
|
|
975
|
+
]);
|
|
976
|
+
const [eventFiles, artifactFiles] = await Promise.all([
|
|
977
|
+
hasEventDirectory ? listJsonFiles(this.sessionEventsDirectory(sessionId)) : Promise.resolve([]),
|
|
978
|
+
hasArtifactDirectory ? listJsonFiles(this.sessionArtifactsDirectory(sessionId)) : Promise.resolve([])
|
|
979
|
+
]);
|
|
980
|
+
const currentSequence = eventFiles.reduce((maxSequence, fileName) => {
|
|
981
|
+
const parsed = Number.parseInt(fileName.replace(/\.json$/u, ""), 10);
|
|
982
|
+
return Number.isFinite(parsed) ? Math.max(maxSequence, parsed) : maxSequence;
|
|
983
|
+
}, 0);
|
|
984
|
+
const eventCount = eventFiles.length;
|
|
985
|
+
const artifactCount = artifactFiles.length;
|
|
986
|
+
if (session.currentSequence === currentSequence && session.eventCount === eventCount && session.artifactCount === artifactCount) {
|
|
987
|
+
return session;
|
|
988
|
+
}
|
|
989
|
+
const [events, artifacts] = await Promise.all([
|
|
990
|
+
Promise.all(
|
|
991
|
+
eventFiles.map(
|
|
992
|
+
(fileName) => readJsonFile(
|
|
993
|
+
path7.join(this.sessionEventsDirectory(sessionId), fileName)
|
|
994
|
+
)
|
|
995
|
+
)
|
|
996
|
+
),
|
|
997
|
+
Promise.all(
|
|
998
|
+
artifactFiles.map(
|
|
999
|
+
(fileName) => readJsonFile(
|
|
1000
|
+
path7.join(this.sessionArtifactsDirectory(sessionId), fileName)
|
|
1001
|
+
)
|
|
1002
|
+
)
|
|
1003
|
+
)
|
|
1004
|
+
]);
|
|
1005
|
+
const updatedAt = Math.max(
|
|
1006
|
+
session.openedAt,
|
|
1007
|
+
session.closedAt ?? 0,
|
|
1008
|
+
...events.map((event) => event.createdAt),
|
|
1009
|
+
...artifacts.map((artifact) => artifact.createdAt)
|
|
1010
|
+
);
|
|
1011
|
+
const reconciled = {
|
|
1012
|
+
...session,
|
|
1013
|
+
currentSequence,
|
|
1014
|
+
eventCount,
|
|
1015
|
+
artifactCount,
|
|
1016
|
+
updatedAt
|
|
1017
|
+
};
|
|
1018
|
+
await writeJsonFileAtomic(this.sessionManifestPath(sessionId), reconciled);
|
|
1019
|
+
return reconciled;
|
|
1020
|
+
}
|
|
1021
|
+
};
|
|
1022
|
+
function toObservationArtifactKind(kind) {
|
|
1023
|
+
switch (kind) {
|
|
1024
|
+
case "screenshot":
|
|
1025
|
+
return "screenshot";
|
|
1026
|
+
case "dom-snapshot":
|
|
1027
|
+
return "dom-snapshot";
|
|
1028
|
+
case "html-snapshot":
|
|
1029
|
+
return "html-snapshot";
|
|
1030
|
+
default:
|
|
1031
|
+
return "other";
|
|
1032
|
+
}
|
|
1033
|
+
}
|
|
1034
|
+
function createObservationStore(rootPath, artifacts) {
|
|
1035
|
+
return new FilesystemObservationStoreImpl(rootPath, artifacts);
|
|
1036
|
+
}
|
|
1037
|
+
|
|
490
1038
|
// ../protocol/src/json.ts
|
|
491
1039
|
var JSON_SCHEMA_DRAFT_2020_12 = "https://json-schema.org/draft/2020-12/schema";
|
|
492
1040
|
function defineSchema(schema) {
|
|
@@ -554,31 +1102,31 @@ function oneOfSchema(members, options = {}) {
|
|
|
554
1102
|
}
|
|
555
1103
|
|
|
556
1104
|
// ../protocol/src/validation.ts
|
|
557
|
-
function validateJsonSchema(schema, value,
|
|
558
|
-
return validateSchemaNode(schema, value,
|
|
1105
|
+
function validateJsonSchema(schema, value, path15 = "$") {
|
|
1106
|
+
return validateSchemaNode(schema, value, path15);
|
|
559
1107
|
}
|
|
560
|
-
function validateSchemaNode(schema, value,
|
|
1108
|
+
function validateSchemaNode(schema, value, path15) {
|
|
561
1109
|
const issues = [];
|
|
562
1110
|
if ("const" in schema && !isJsonValueEqual(schema.const, value)) {
|
|
563
1111
|
issues.push({
|
|
564
|
-
path:
|
|
1112
|
+
path: path15,
|
|
565
1113
|
message: `must equal ${JSON.stringify(schema.const)}`
|
|
566
1114
|
});
|
|
567
1115
|
return issues;
|
|
568
1116
|
}
|
|
569
1117
|
if (schema.enum !== void 0 && !schema.enum.some((candidate) => isJsonValueEqual(candidate, value))) {
|
|
570
1118
|
issues.push({
|
|
571
|
-
path:
|
|
1119
|
+
path: path15,
|
|
572
1120
|
message: `must be one of ${schema.enum.map((candidate) => JSON.stringify(candidate)).join(", ")}`
|
|
573
1121
|
});
|
|
574
1122
|
return issues;
|
|
575
1123
|
}
|
|
576
1124
|
if (schema.oneOf !== void 0) {
|
|
577
|
-
const branchIssues = schema.oneOf.map((member) => validateSchemaNode(member, value,
|
|
1125
|
+
const branchIssues = schema.oneOf.map((member) => validateSchemaNode(member, value, path15));
|
|
578
1126
|
const validBranches = branchIssues.filter((current) => current.length === 0).length;
|
|
579
1127
|
if (validBranches !== 1) {
|
|
580
1128
|
issues.push({
|
|
581
|
-
path:
|
|
1129
|
+
path: path15,
|
|
582
1130
|
message: validBranches === 0 ? "must match exactly one supported shape" : "matches multiple supported shapes"
|
|
583
1131
|
});
|
|
584
1132
|
return issues;
|
|
@@ -586,11 +1134,11 @@ function validateSchemaNode(schema, value, path13) {
|
|
|
586
1134
|
}
|
|
587
1135
|
if (schema.anyOf !== void 0) {
|
|
588
1136
|
const hasMatch = schema.anyOf.some(
|
|
589
|
-
(member) => validateSchemaNode(member, value,
|
|
1137
|
+
(member) => validateSchemaNode(member, value, path15).length === 0
|
|
590
1138
|
);
|
|
591
1139
|
if (!hasMatch) {
|
|
592
1140
|
issues.push({
|
|
593
|
-
path:
|
|
1141
|
+
path: path15,
|
|
594
1142
|
message: "must match at least one supported shape"
|
|
595
1143
|
});
|
|
596
1144
|
return issues;
|
|
@@ -598,7 +1146,7 @@ function validateSchemaNode(schema, value, path13) {
|
|
|
598
1146
|
}
|
|
599
1147
|
if (schema.allOf !== void 0) {
|
|
600
1148
|
for (const member of schema.allOf) {
|
|
601
|
-
issues.push(...validateSchemaNode(member, value,
|
|
1149
|
+
issues.push(...validateSchemaNode(member, value, path15));
|
|
602
1150
|
}
|
|
603
1151
|
if (issues.length > 0) {
|
|
604
1152
|
return issues;
|
|
@@ -606,7 +1154,7 @@ function validateSchemaNode(schema, value, path13) {
|
|
|
606
1154
|
}
|
|
607
1155
|
if (schema.type !== void 0 && !matchesSchemaType(schema.type, value)) {
|
|
608
1156
|
issues.push({
|
|
609
|
-
path:
|
|
1157
|
+
path: path15,
|
|
610
1158
|
message: `must be ${describeSchemaType(schema.type)}`
|
|
611
1159
|
});
|
|
612
1160
|
return issues;
|
|
@@ -614,19 +1162,19 @@ function validateSchemaNode(schema, value, path13) {
|
|
|
614
1162
|
if (typeof value === "string") {
|
|
615
1163
|
if (schema.minLength !== void 0 && value.length < schema.minLength) {
|
|
616
1164
|
issues.push({
|
|
617
|
-
path:
|
|
1165
|
+
path: path15,
|
|
618
1166
|
message: `must have length >= ${String(schema.minLength)}`
|
|
619
1167
|
});
|
|
620
1168
|
}
|
|
621
1169
|
if (schema.maxLength !== void 0 && value.length > schema.maxLength) {
|
|
622
1170
|
issues.push({
|
|
623
|
-
path:
|
|
1171
|
+
path: path15,
|
|
624
1172
|
message: `must have length <= ${String(schema.maxLength)}`
|
|
625
1173
|
});
|
|
626
1174
|
}
|
|
627
1175
|
if (schema.pattern !== void 0 && !new RegExp(schema.pattern).test(value)) {
|
|
628
1176
|
issues.push({
|
|
629
|
-
path:
|
|
1177
|
+
path: path15,
|
|
630
1178
|
message: `must match pattern ${schema.pattern}`
|
|
631
1179
|
});
|
|
632
1180
|
}
|
|
@@ -635,25 +1183,25 @@ function validateSchemaNode(schema, value, path13) {
|
|
|
635
1183
|
if (typeof value === "number") {
|
|
636
1184
|
if (schema.minimum !== void 0 && value < schema.minimum) {
|
|
637
1185
|
issues.push({
|
|
638
|
-
path:
|
|
1186
|
+
path: path15,
|
|
639
1187
|
message: `must be >= ${String(schema.minimum)}`
|
|
640
1188
|
});
|
|
641
1189
|
}
|
|
642
1190
|
if (schema.maximum !== void 0 && value > schema.maximum) {
|
|
643
1191
|
issues.push({
|
|
644
|
-
path:
|
|
1192
|
+
path: path15,
|
|
645
1193
|
message: `must be <= ${String(schema.maximum)}`
|
|
646
1194
|
});
|
|
647
1195
|
}
|
|
648
1196
|
if (schema.exclusiveMinimum !== void 0 && value <= schema.exclusiveMinimum) {
|
|
649
1197
|
issues.push({
|
|
650
|
-
path:
|
|
1198
|
+
path: path15,
|
|
651
1199
|
message: `must be > ${String(schema.exclusiveMinimum)}`
|
|
652
1200
|
});
|
|
653
1201
|
}
|
|
654
1202
|
if (schema.exclusiveMaximum !== void 0 && value >= schema.exclusiveMaximum) {
|
|
655
1203
|
issues.push({
|
|
656
|
-
path:
|
|
1204
|
+
path: path15,
|
|
657
1205
|
message: `must be < ${String(schema.exclusiveMaximum)}`
|
|
658
1206
|
});
|
|
659
1207
|
}
|
|
@@ -662,13 +1210,13 @@ function validateSchemaNode(schema, value, path13) {
|
|
|
662
1210
|
if (Array.isArray(value)) {
|
|
663
1211
|
if (schema.minItems !== void 0 && value.length < schema.minItems) {
|
|
664
1212
|
issues.push({
|
|
665
|
-
path:
|
|
1213
|
+
path: path15,
|
|
666
1214
|
message: `must have at least ${String(schema.minItems)} items`
|
|
667
1215
|
});
|
|
668
1216
|
}
|
|
669
1217
|
if (schema.maxItems !== void 0 && value.length > schema.maxItems) {
|
|
670
1218
|
issues.push({
|
|
671
|
-
path:
|
|
1219
|
+
path: path15,
|
|
672
1220
|
message: `must have at most ${String(schema.maxItems)} items`
|
|
673
1221
|
});
|
|
674
1222
|
}
|
|
@@ -678,7 +1226,7 @@ function validateSchemaNode(schema, value, path13) {
|
|
|
678
1226
|
const key = JSON.stringify(item);
|
|
679
1227
|
if (seen.has(key)) {
|
|
680
1228
|
issues.push({
|
|
681
|
-
path:
|
|
1229
|
+
path: path15,
|
|
682
1230
|
message: "must not contain duplicate items"
|
|
683
1231
|
});
|
|
684
1232
|
break;
|
|
@@ -688,7 +1236,7 @@ function validateSchemaNode(schema, value, path13) {
|
|
|
688
1236
|
}
|
|
689
1237
|
if (schema.items !== void 0) {
|
|
690
1238
|
for (let index = 0; index < value.length; index += 1) {
|
|
691
|
-
issues.push(...validateSchemaNode(schema.items, value[index], `${
|
|
1239
|
+
issues.push(...validateSchemaNode(schema.items, value[index], `${path15}[${String(index)}]`));
|
|
692
1240
|
}
|
|
693
1241
|
}
|
|
694
1242
|
return issues;
|
|
@@ -698,7 +1246,7 @@ function validateSchemaNode(schema, value, path13) {
|
|
|
698
1246
|
for (const requiredKey of schema.required ?? []) {
|
|
699
1247
|
if (!(requiredKey in value)) {
|
|
700
1248
|
issues.push({
|
|
701
|
-
path: joinObjectPath(
|
|
1249
|
+
path: joinObjectPath(path15, requiredKey),
|
|
702
1250
|
message: "is required"
|
|
703
1251
|
});
|
|
704
1252
|
}
|
|
@@ -707,13 +1255,13 @@ function validateSchemaNode(schema, value, path13) {
|
|
|
707
1255
|
const propertySchema = properties[key];
|
|
708
1256
|
if (propertySchema !== void 0) {
|
|
709
1257
|
issues.push(
|
|
710
|
-
...validateSchemaNode(propertySchema, propertyValue, joinObjectPath(
|
|
1258
|
+
...validateSchemaNode(propertySchema, propertyValue, joinObjectPath(path15, key))
|
|
711
1259
|
);
|
|
712
1260
|
continue;
|
|
713
1261
|
}
|
|
714
1262
|
if (schema.additionalProperties === false) {
|
|
715
1263
|
issues.push({
|
|
716
|
-
path: joinObjectPath(
|
|
1264
|
+
path: joinObjectPath(path15, key),
|
|
717
1265
|
message: "is not allowed"
|
|
718
1266
|
});
|
|
719
1267
|
continue;
|
|
@@ -723,7 +1271,7 @@ function validateSchemaNode(schema, value, path13) {
|
|
|
723
1271
|
...validateSchemaNode(
|
|
724
1272
|
schema.additionalProperties,
|
|
725
1273
|
propertyValue,
|
|
726
|
-
joinObjectPath(
|
|
1274
|
+
joinObjectPath(path15, key)
|
|
727
1275
|
)
|
|
728
1276
|
);
|
|
729
1277
|
}
|
|
@@ -967,8 +1515,8 @@ function matchesNetworkRecordFilters(record, filters) {
|
|
|
967
1515
|
}
|
|
968
1516
|
}
|
|
969
1517
|
if (filters.path !== void 0) {
|
|
970
|
-
const
|
|
971
|
-
if (!includesCaseInsensitive(
|
|
1518
|
+
const path15 = getParsedUrl().pathname;
|
|
1519
|
+
if (!includesCaseInsensitive(path15, filters.path)) {
|
|
972
1520
|
return false;
|
|
973
1521
|
}
|
|
974
1522
|
}
|
|
@@ -1442,7 +1990,7 @@ var networkRecordSchema = objectSchema(
|
|
|
1442
1990
|
var networkQueryRecordSchema = objectSchema(
|
|
1443
1991
|
{
|
|
1444
1992
|
recordId: stringSchema({ minLength: 1 }),
|
|
1445
|
-
|
|
1993
|
+
capture: stringSchema({ minLength: 1 }),
|
|
1446
1994
|
tags: arraySchema(stringSchema({ minLength: 1 }), {
|
|
1447
1995
|
uniqueItems: true
|
|
1448
1996
|
}),
|
|
@@ -1922,8 +2470,7 @@ var opensteerRecipeStepSchema = oneOfSchema(
|
|
|
1922
2470
|
objectSchema(
|
|
1923
2471
|
{
|
|
1924
2472
|
kind: enumSchema(["goto"]),
|
|
1925
|
-
url: stringSchema({ minLength: 1 })
|
|
1926
|
-
networkTag: stringSchema({ minLength: 1 })
|
|
2473
|
+
url: stringSchema({ minLength: 1 })
|
|
1927
2474
|
},
|
|
1928
2475
|
{
|
|
1929
2476
|
title: "OpensteerAuthRecipeGotoStep",
|
|
@@ -1932,8 +2479,7 @@ var opensteerRecipeStepSchema = oneOfSchema(
|
|
|
1932
2479
|
),
|
|
1933
2480
|
objectSchema(
|
|
1934
2481
|
{
|
|
1935
|
-
kind: enumSchema(["reload"])
|
|
1936
|
-
networkTag: stringSchema({ minLength: 1 })
|
|
2482
|
+
kind: enumSchema(["reload"])
|
|
1937
2483
|
},
|
|
1938
2484
|
{
|
|
1939
2485
|
title: "OpensteerAuthRecipeReloadStep",
|
|
@@ -2150,7 +2696,7 @@ var opensteerNetworkQueryInputSchema = objectSchema(
|
|
|
2150
2696
|
pageRef: pageRefSchema,
|
|
2151
2697
|
recordId: stringSchema({ minLength: 1 }),
|
|
2152
2698
|
requestId: stringSchema({ minLength: 1 }),
|
|
2153
|
-
|
|
2699
|
+
capture: stringSchema({ minLength: 1 }),
|
|
2154
2700
|
tag: stringSchema({ minLength: 1 }),
|
|
2155
2701
|
url: stringSchema({ minLength: 1 }),
|
|
2156
2702
|
hostname: stringSchema({ minLength: 1 }),
|
|
@@ -2179,7 +2725,7 @@ var opensteerNetworkTagInputSchema = objectSchema(
|
|
|
2179
2725
|
pageRef: pageRefSchema,
|
|
2180
2726
|
recordId: stringSchema({ minLength: 1 }),
|
|
2181
2727
|
requestId: stringSchema({ minLength: 1 }),
|
|
2182
|
-
|
|
2728
|
+
capture: stringSchema({ minLength: 1 }),
|
|
2183
2729
|
tag: stringSchema({ minLength: 1 }),
|
|
2184
2730
|
url: stringSchema({ minLength: 1 }),
|
|
2185
2731
|
hostname: stringSchema({ minLength: 1 }),
|
|
@@ -2204,6 +2750,7 @@ var opensteerNetworkTagOutputSchema = objectSchema(
|
|
|
2204
2750
|
);
|
|
2205
2751
|
var opensteerNetworkClearInputSchema = objectSchema(
|
|
2206
2752
|
{
|
|
2753
|
+
capture: stringSchema({ minLength: 1 }),
|
|
2207
2754
|
tag: stringSchema({ minLength: 1 })
|
|
2208
2755
|
},
|
|
2209
2756
|
{
|
|
@@ -6055,7 +6602,7 @@ var opensteerPageCloseOutputSchema = objectSchema(
|
|
|
6055
6602
|
var opensteerPageGotoInputSchema = objectSchema(
|
|
6056
6603
|
{
|
|
6057
6604
|
url: stringSchema(),
|
|
6058
|
-
|
|
6605
|
+
captureNetwork: stringSchema({ minLength: 1 })
|
|
6059
6606
|
},
|
|
6060
6607
|
{
|
|
6061
6608
|
title: "OpensteerPageGotoInput",
|
|
@@ -6206,7 +6753,7 @@ var opensteerDomClickInputSchema = objectSchema(
|
|
|
6206
6753
|
{
|
|
6207
6754
|
target: opensteerTargetInputSchema,
|
|
6208
6755
|
persistAsDescription: stringSchema(),
|
|
6209
|
-
|
|
6756
|
+
captureNetwork: stringSchema({ minLength: 1 })
|
|
6210
6757
|
},
|
|
6211
6758
|
{
|
|
6212
6759
|
title: "OpensteerDomClickInput",
|
|
@@ -6217,7 +6764,7 @@ var opensteerDomHoverInputSchema = objectSchema(
|
|
|
6217
6764
|
{
|
|
6218
6765
|
target: opensteerTargetInputSchema,
|
|
6219
6766
|
persistAsDescription: stringSchema(),
|
|
6220
|
-
|
|
6767
|
+
captureNetwork: stringSchema({ minLength: 1 })
|
|
6221
6768
|
},
|
|
6222
6769
|
{
|
|
6223
6770
|
title: "OpensteerDomHoverInput",
|
|
@@ -6230,7 +6777,7 @@ var opensteerDomInputInputSchema = objectSchema(
|
|
|
6230
6777
|
text: stringSchema(),
|
|
6231
6778
|
pressEnter: { type: "boolean" },
|
|
6232
6779
|
persistAsDescription: stringSchema(),
|
|
6233
|
-
|
|
6780
|
+
captureNetwork: stringSchema({ minLength: 1 })
|
|
6234
6781
|
},
|
|
6235
6782
|
{
|
|
6236
6783
|
title: "OpensteerDomInputInput",
|
|
@@ -6243,7 +6790,7 @@ var opensteerDomScrollInputSchema = objectSchema(
|
|
|
6243
6790
|
direction: enumSchema(["up", "down", "left", "right"]),
|
|
6244
6791
|
amount: integerSchema({ minimum: 1 }),
|
|
6245
6792
|
persistAsDescription: stringSchema(),
|
|
6246
|
-
|
|
6793
|
+
captureNetwork: stringSchema({ minLength: 1 })
|
|
6247
6794
|
},
|
|
6248
6795
|
{
|
|
6249
6796
|
title: "OpensteerDomScrollInput",
|
|
@@ -6444,7 +6991,7 @@ var opensteerComputerExecuteInputSchema = objectSchema(
|
|
|
6444
6991
|
{
|
|
6445
6992
|
action: opensteerComputerActionSchema,
|
|
6446
6993
|
screenshot: opensteerComputerScreenshotOptionsSchema,
|
|
6447
|
-
|
|
6994
|
+
captureNetwork: stringSchema({ minLength: 1 })
|
|
6448
6995
|
},
|
|
6449
6996
|
{
|
|
6450
6997
|
title: "OpensteerComputerExecuteInput",
|
|
@@ -7049,9 +7596,9 @@ function compareByCreatedAtAndId(left, right) {
|
|
|
7049
7596
|
var FilesystemRegistryStore = class {
|
|
7050
7597
|
constructor(rootPath, registryRelativePath) {
|
|
7051
7598
|
this.registryRelativePath = registryRelativePath;
|
|
7052
|
-
const basePath =
|
|
7053
|
-
this.recordsDirectory =
|
|
7054
|
-
this.indexesDirectory =
|
|
7599
|
+
const basePath = path7.join(rootPath, ...registryRelativePath);
|
|
7600
|
+
this.recordsDirectory = path7.join(basePath, "records");
|
|
7601
|
+
this.indexesDirectory = path7.join(basePath, "indexes", "by-key");
|
|
7055
7602
|
}
|
|
7056
7603
|
recordsDirectory;
|
|
7057
7604
|
indexesDirectory;
|
|
@@ -7120,7 +7667,7 @@ var FilesystemRegistryStore = class {
|
|
|
7120
7667
|
async readRecordsFromDirectory() {
|
|
7121
7668
|
const files = await listJsonFiles(this.recordsDirectory);
|
|
7122
7669
|
const records = await Promise.all(
|
|
7123
|
-
files.map((fileName) => readJsonFile(
|
|
7670
|
+
files.map((fileName) => readJsonFile(path7.join(this.recordsDirectory, fileName)))
|
|
7124
7671
|
);
|
|
7125
7672
|
records.sort(compareByCreatedAtAndId);
|
|
7126
7673
|
return records;
|
|
@@ -7152,17 +7699,17 @@ var FilesystemRegistryStore = class {
|
|
|
7152
7699
|
return record;
|
|
7153
7700
|
}
|
|
7154
7701
|
recordPath(id) {
|
|
7155
|
-
return
|
|
7702
|
+
return path7.join(this.recordsDirectory, `${encodePathSegment(id)}.json`);
|
|
7156
7703
|
}
|
|
7157
7704
|
indexPath(key, version) {
|
|
7158
|
-
return
|
|
7705
|
+
return path7.join(
|
|
7159
7706
|
this.indexesDirectory,
|
|
7160
7707
|
encodePathSegment(key),
|
|
7161
7708
|
`${encodePathSegment(version)}.json`
|
|
7162
7709
|
);
|
|
7163
7710
|
}
|
|
7164
7711
|
writeLockPath() {
|
|
7165
|
-
return
|
|
7712
|
+
return path7.join(path7.dirname(this.recordsDirectory), ".write.lock");
|
|
7166
7713
|
}
|
|
7167
7714
|
};
|
|
7168
7715
|
var FilesystemDescriptorRegistry = class extends FilesystemRegistryStore {
|
|
@@ -7532,7 +8079,7 @@ var SqliteSavedNetworkStore = class {
|
|
|
7532
8079
|
directoryInitialization;
|
|
7533
8080
|
databaseInitialization;
|
|
7534
8081
|
constructor(rootPath) {
|
|
7535
|
-
this.databasePath =
|
|
8082
|
+
this.databasePath = path7.join(rootPath, "registry", "saved-network.sqlite");
|
|
7536
8083
|
}
|
|
7537
8084
|
async initialize() {
|
|
7538
8085
|
await this.ensureDatabaseDirectory();
|
|
@@ -7570,7 +8117,7 @@ var SqliteSavedNetworkStore = class {
|
|
|
7570
8117
|
page_ref_key: pageRefKey,
|
|
7571
8118
|
frame_ref: entry.record.frameRef ?? null,
|
|
7572
8119
|
document_ref: entry.record.documentRef ?? null,
|
|
7573
|
-
|
|
8120
|
+
capture: entry.capture ?? null,
|
|
7574
8121
|
method: entry.record.method,
|
|
7575
8122
|
method_lc: entry.record.method.toLowerCase(),
|
|
7576
8123
|
url: entry.record.url,
|
|
@@ -7683,39 +8230,31 @@ var SqliteSavedNetworkStore = class {
|
|
|
7683
8230
|
}
|
|
7684
8231
|
async clear(input = {}) {
|
|
7685
8232
|
const database = await this.requireDatabase();
|
|
7686
|
-
const countAll = database.prepare(`
|
|
7687
|
-
SELECT COUNT(*) AS cleared
|
|
7688
|
-
FROM saved_network_records
|
|
7689
|
-
`);
|
|
7690
|
-
const countByTag = database.prepare(`
|
|
7691
|
-
SELECT COUNT(DISTINCT record_id) AS cleared
|
|
7692
|
-
FROM saved_network_tags
|
|
7693
|
-
WHERE tag = @tag
|
|
7694
|
-
`);
|
|
7695
|
-
const deleteAllTags = database.prepare(`DELETE FROM saved_network_tags`);
|
|
8233
|
+
const countAll = database.prepare(`SELECT COUNT(*) AS cleared FROM saved_network_records`);
|
|
7696
8234
|
const deleteAllRecords = database.prepare(`DELETE FROM saved_network_records`);
|
|
7697
|
-
const
|
|
7698
|
-
|
|
7699
|
-
|
|
8235
|
+
const { whereSql, parameters } = buildSavedNetworkWhere(input);
|
|
8236
|
+
const countFiltered = database.prepare(`
|
|
8237
|
+
SELECT COUNT(*) AS cleared
|
|
8238
|
+
FROM saved_network_records r
|
|
8239
|
+
${whereSql}
|
|
7700
8240
|
`);
|
|
7701
|
-
const
|
|
8241
|
+
const deleteFiltered = database.prepare(`
|
|
7702
8242
|
DELETE FROM saved_network_records
|
|
7703
|
-
WHERE
|
|
7704
|
-
SELECT
|
|
7705
|
-
FROM
|
|
7706
|
-
|
|
8243
|
+
WHERE record_id IN (
|
|
8244
|
+
SELECT r.record_id
|
|
8245
|
+
FROM saved_network_records r
|
|
8246
|
+
${whereSql}
|
|
7707
8247
|
)
|
|
7708
8248
|
`);
|
|
7709
8249
|
return withSqliteTransaction(database, () => {
|
|
7710
|
-
|
|
7711
|
-
|
|
7712
|
-
if (tag === void 0) {
|
|
7713
|
-
deleteAllTags.run();
|
|
8250
|
+
if (input.capture === void 0 && input.tag === void 0) {
|
|
8251
|
+
const cleared2 = countAll.get().cleared;
|
|
7714
8252
|
deleteAllRecords.run();
|
|
7715
|
-
return
|
|
8253
|
+
return cleared2;
|
|
7716
8254
|
}
|
|
7717
|
-
|
|
7718
|
-
|
|
8255
|
+
const args = parameters;
|
|
8256
|
+
const cleared = countFiltered.get(...args).cleared;
|
|
8257
|
+
deleteFiltered.run(...args);
|
|
7719
8258
|
return cleared;
|
|
7720
8259
|
});
|
|
7721
8260
|
}
|
|
@@ -7750,7 +8289,7 @@ var SqliteSavedNetworkStore = class {
|
|
|
7750
8289
|
}
|
|
7751
8290
|
}
|
|
7752
8291
|
async ensureDatabaseDirectory() {
|
|
7753
|
-
this.directoryInitialization ??= ensureDirectory(
|
|
8292
|
+
this.directoryInitialization ??= ensureDirectory(path7.dirname(this.databasePath)).catch(
|
|
7754
8293
|
(error) => {
|
|
7755
8294
|
this.directoryInitialization = void 0;
|
|
7756
8295
|
throw error;
|
|
@@ -7770,7 +8309,7 @@ var SqliteSavedNetworkStore = class {
|
|
|
7770
8309
|
page_ref_key TEXT NOT NULL,
|
|
7771
8310
|
frame_ref TEXT,
|
|
7772
8311
|
document_ref TEXT,
|
|
7773
|
-
|
|
8312
|
+
capture TEXT,
|
|
7774
8313
|
method TEXT NOT NULL,
|
|
7775
8314
|
method_lc TEXT NOT NULL,
|
|
7776
8315
|
url TEXT NOT NULL,
|
|
@@ -7809,6 +8348,9 @@ var SqliteSavedNetworkStore = class {
|
|
|
7809
8348
|
CREATE INDEX IF NOT EXISTS saved_network_records_saved_at
|
|
7810
8349
|
ON saved_network_records (saved_at DESC);
|
|
7811
8350
|
|
|
8351
|
+
CREATE INDEX IF NOT EXISTS saved_network_records_capture
|
|
8352
|
+
ON saved_network_records (capture);
|
|
8353
|
+
|
|
7812
8354
|
CREATE TABLE IF NOT EXISTS saved_network_tags (
|
|
7813
8355
|
record_id TEXT NOT NULL REFERENCES saved_network_records(record_id) ON DELETE CASCADE,
|
|
7814
8356
|
tag TEXT NOT NULL,
|
|
@@ -7824,6 +8366,7 @@ var SqliteSavedNetworkStore = class {
|
|
|
7824
8366
|
"capture_state",
|
|
7825
8367
|
"TEXT NOT NULL DEFAULT 'complete'"
|
|
7826
8368
|
);
|
|
8369
|
+
this.ensureColumn(database, "saved_network_records", "capture", "TEXT");
|
|
7827
8370
|
this.ensureColumn(
|
|
7828
8371
|
database,
|
|
7829
8372
|
"saved_network_records",
|
|
@@ -7864,9 +8407,9 @@ function buildSavedNetworkWhere(input) {
|
|
|
7864
8407
|
clauses.push("r.request_id = ?");
|
|
7865
8408
|
parameters.push(input.requestId);
|
|
7866
8409
|
}
|
|
7867
|
-
if (input.
|
|
7868
|
-
clauses.push("r.
|
|
7869
|
-
parameters.push(input.
|
|
8410
|
+
if (input.capture !== void 0) {
|
|
8411
|
+
clauses.push("r.capture = ?");
|
|
8412
|
+
parameters.push(input.capture);
|
|
7870
8413
|
}
|
|
7871
8414
|
if (input.tag !== void 0) {
|
|
7872
8415
|
clauses.push(`
|
|
@@ -7928,7 +8471,7 @@ function buildSavedNetworkUpsertSql(bodyWriteMode) {
|
|
|
7928
8471
|
page_ref_key,
|
|
7929
8472
|
frame_ref,
|
|
7930
8473
|
document_ref,
|
|
7931
|
-
|
|
8474
|
+
capture,
|
|
7932
8475
|
method,
|
|
7933
8476
|
method_lc,
|
|
7934
8477
|
url,
|
|
@@ -7967,7 +8510,7 @@ function buildSavedNetworkUpsertSql(bodyWriteMode) {
|
|
|
7967
8510
|
@page_ref_key,
|
|
7968
8511
|
@frame_ref,
|
|
7969
8512
|
@document_ref,
|
|
7970
|
-
@
|
|
8513
|
+
@capture,
|
|
7971
8514
|
@method,
|
|
7972
8515
|
@method_lc,
|
|
7973
8516
|
@url,
|
|
@@ -8004,7 +8547,7 @@ function buildSavedNetworkUpsertSql(bodyWriteMode) {
|
|
|
8004
8547
|
page_ref_key = excluded.page_ref_key,
|
|
8005
8548
|
frame_ref = excluded.frame_ref,
|
|
8006
8549
|
document_ref = excluded.document_ref,
|
|
8007
|
-
|
|
8550
|
+
capture = excluded.capture,
|
|
8008
8551
|
method = excluded.method,
|
|
8009
8552
|
method_lc = excluded.method_lc,
|
|
8010
8553
|
url = excluded.url,
|
|
@@ -8099,7 +8642,7 @@ function inflateSavedNetworkRow(row, includeBodies) {
|
|
|
8099
8642
|
}
|
|
8100
8643
|
return {
|
|
8101
8644
|
recordId: row.record_id,
|
|
8102
|
-
...row.
|
|
8645
|
+
...row.capture === null ? {} : { capture: row.capture },
|
|
8103
8646
|
...row.tags === null || row.tags.length === 0 ? {} : { tags: row.tags.split(TAG_DELIMITER).filter((tag) => tag.length > 0) },
|
|
8104
8647
|
savedAt: row.saved_at,
|
|
8105
8648
|
record
|
|
@@ -8152,7 +8695,7 @@ var FilesystemTraceStore = class {
|
|
|
8152
8695
|
constructor(rootPath, artifacts) {
|
|
8153
8696
|
this.rootPath = rootPath;
|
|
8154
8697
|
this.artifacts = artifacts;
|
|
8155
|
-
this.runsDirectory =
|
|
8698
|
+
this.runsDirectory = path7.join(this.rootPath, "traces", "runs");
|
|
8156
8699
|
}
|
|
8157
8700
|
runsDirectory;
|
|
8158
8701
|
async initialize() {
|
|
@@ -8229,7 +8772,7 @@ var FilesystemTraceStore = class {
|
|
|
8229
8772
|
...input.error === void 0 ? {} : { error: input.error }
|
|
8230
8773
|
};
|
|
8231
8774
|
await writeJsonFileExclusive(
|
|
8232
|
-
|
|
8775
|
+
path7.join(this.runEntriesDirectory(runId), sequenceFileName(sequence)),
|
|
8233
8776
|
entry
|
|
8234
8777
|
);
|
|
8235
8778
|
await writeJsonFileAtomic(this.runManifestPath(runId), {
|
|
@@ -8248,7 +8791,7 @@ var FilesystemTraceStore = class {
|
|
|
8248
8791
|
const files = await listJsonFiles(entriesDirectory);
|
|
8249
8792
|
return Promise.all(
|
|
8250
8793
|
files.map(
|
|
8251
|
-
(fileName) => readJsonFile(
|
|
8794
|
+
(fileName) => readJsonFile(path7.join(entriesDirectory, fileName))
|
|
8252
8795
|
)
|
|
8253
8796
|
);
|
|
8254
8797
|
}
|
|
@@ -8294,16 +8837,16 @@ var FilesystemTraceStore = class {
|
|
|
8294
8837
|
return { trace, artifacts };
|
|
8295
8838
|
}
|
|
8296
8839
|
runDirectory(runId) {
|
|
8297
|
-
return
|
|
8840
|
+
return path7.join(this.runsDirectory, encodeURIComponent(runId));
|
|
8298
8841
|
}
|
|
8299
8842
|
runEntriesDirectory(runId) {
|
|
8300
|
-
return
|
|
8843
|
+
return path7.join(this.runDirectory(runId), "entries");
|
|
8301
8844
|
}
|
|
8302
8845
|
runManifestPath(runId) {
|
|
8303
|
-
return
|
|
8846
|
+
return path7.join(this.runDirectory(runId), "manifest.json");
|
|
8304
8847
|
}
|
|
8305
8848
|
runWriteLockPath(runId) {
|
|
8306
|
-
return
|
|
8849
|
+
return path7.join(this.runDirectory(runId), ".append.lock");
|
|
8307
8850
|
}
|
|
8308
8851
|
};
|
|
8309
8852
|
function createTraceStore(rootPath, artifacts) {
|
|
@@ -8317,7 +8860,7 @@ function normalizeWorkspaceId(workspace) {
|
|
|
8317
8860
|
return encodePathSegment(workspace);
|
|
8318
8861
|
}
|
|
8319
8862
|
function resolveFilesystemWorkspacePath(input) {
|
|
8320
|
-
return
|
|
8863
|
+
return path7.join(
|
|
8321
8864
|
input.rootDir,
|
|
8322
8865
|
".opensteer",
|
|
8323
8866
|
"workspaces",
|
|
@@ -8326,17 +8869,18 @@ function resolveFilesystemWorkspacePath(input) {
|
|
|
8326
8869
|
}
|
|
8327
8870
|
async function createFilesystemOpensteerWorkspace(options) {
|
|
8328
8871
|
await ensureDirectory(options.rootPath);
|
|
8329
|
-
const manifestPath =
|
|
8330
|
-
const browserPath =
|
|
8331
|
-
const browserManifestPath =
|
|
8332
|
-
const browserUserDataDir =
|
|
8333
|
-
const livePath =
|
|
8334
|
-
const liveLocalPath =
|
|
8335
|
-
const liveCloudPath =
|
|
8336
|
-
const artifactsPath =
|
|
8337
|
-
const tracesPath =
|
|
8338
|
-
const
|
|
8339
|
-
const
|
|
8872
|
+
const manifestPath = path7.join(options.rootPath, "workspace.json");
|
|
8873
|
+
const browserPath = path7.join(options.rootPath, "browser");
|
|
8874
|
+
const browserManifestPath = path7.join(browserPath, "manifest.json");
|
|
8875
|
+
const browserUserDataDir = path7.join(browserPath, "user-data");
|
|
8876
|
+
const livePath = path7.join(options.rootPath, "live");
|
|
8877
|
+
const liveLocalPath = path7.join(livePath, "local.json");
|
|
8878
|
+
const liveCloudPath = path7.join(livePath, "cloud.json");
|
|
8879
|
+
const artifactsPath = path7.join(options.rootPath, "artifacts");
|
|
8880
|
+
const tracesPath = path7.join(options.rootPath, "traces");
|
|
8881
|
+
const observationsPath = path7.join(options.rootPath, "observations");
|
|
8882
|
+
const registryPath = path7.join(options.rootPath, "registry");
|
|
8883
|
+
const lockPath = path7.join(options.rootPath, ".lock");
|
|
8340
8884
|
let manifest;
|
|
8341
8885
|
if (await pathExists(manifestPath)) {
|
|
8342
8886
|
manifest = await readJsonFile(manifestPath);
|
|
@@ -8350,6 +8894,17 @@ async function createFilesystemOpensteerWorkspace(options) {
|
|
|
8350
8894
|
`workspace ${options.rootPath} uses unsupported version ${String(manifest.version)}`
|
|
8351
8895
|
);
|
|
8352
8896
|
}
|
|
8897
|
+
if (manifest.paths.observations === void 0) {
|
|
8898
|
+
manifest = {
|
|
8899
|
+
...manifest,
|
|
8900
|
+
updatedAt: Date.now(),
|
|
8901
|
+
paths: {
|
|
8902
|
+
...manifest.paths,
|
|
8903
|
+
observations: "observations"
|
|
8904
|
+
}
|
|
8905
|
+
};
|
|
8906
|
+
await writeJsonFileAtomic(manifestPath, manifest);
|
|
8907
|
+
}
|
|
8353
8908
|
} else {
|
|
8354
8909
|
const createdAt = normalizeTimestamp("createdAt", options.createdAt ?? Date.now());
|
|
8355
8910
|
manifest = {
|
|
@@ -8364,6 +8919,7 @@ async function createFilesystemOpensteerWorkspace(options) {
|
|
|
8364
8919
|
live: "live",
|
|
8365
8920
|
artifacts: "artifacts",
|
|
8366
8921
|
traces: "traces",
|
|
8922
|
+
observations: "observations",
|
|
8367
8923
|
registry: "registry"
|
|
8368
8924
|
}
|
|
8369
8925
|
};
|
|
@@ -8375,6 +8931,7 @@ async function createFilesystemOpensteerWorkspace(options) {
|
|
|
8375
8931
|
ensureDirectory(livePath),
|
|
8376
8932
|
ensureDirectory(artifactsPath),
|
|
8377
8933
|
ensureDirectory(tracesPath),
|
|
8934
|
+
ensureDirectory(observationsPath),
|
|
8378
8935
|
ensureDirectory(registryPath)
|
|
8379
8936
|
]);
|
|
8380
8937
|
const artifacts = createArtifactStore(options.rootPath);
|
|
@@ -8399,6 +8956,8 @@ async function createFilesystemOpensteerWorkspace(options) {
|
|
|
8399
8956
|
await reverseReports.initialize();
|
|
8400
8957
|
const traces = createTraceStore(options.rootPath, artifacts);
|
|
8401
8958
|
await traces.initialize();
|
|
8959
|
+
const observations = createObservationStore(options.rootPath, artifacts);
|
|
8960
|
+
await observations.initialize();
|
|
8402
8961
|
return {
|
|
8403
8962
|
rootPath: options.rootPath,
|
|
8404
8963
|
manifestPath,
|
|
@@ -8411,10 +8970,12 @@ async function createFilesystemOpensteerWorkspace(options) {
|
|
|
8411
8970
|
liveCloudPath,
|
|
8412
8971
|
artifactsPath,
|
|
8413
8972
|
tracesPath,
|
|
8973
|
+
observationsPath,
|
|
8414
8974
|
registryPath,
|
|
8415
8975
|
lockPath,
|
|
8416
8976
|
artifacts,
|
|
8417
8977
|
traces,
|
|
8978
|
+
observations,
|
|
8418
8979
|
registry: {
|
|
8419
8980
|
descriptors,
|
|
8420
8981
|
requestPlans,
|
|
@@ -8439,9 +9000,9 @@ var DEFAULT_TIMEOUTS = {
|
|
|
8439
9000
|
"page.add-init-script": 1e4,
|
|
8440
9001
|
"page.snapshot": 15e3,
|
|
8441
9002
|
"computer.execute": 3e4,
|
|
8442
|
-
"dom.click":
|
|
9003
|
+
"dom.click": 3e4,
|
|
8443
9004
|
"dom.hover": 1e4,
|
|
8444
|
-
"dom.input":
|
|
9005
|
+
"dom.input": 3e4,
|
|
8445
9006
|
"dom.scroll": 1e4,
|
|
8446
9007
|
"dom.extract": 15e3,
|
|
8447
9008
|
"network.query": 15e3,
|
|
@@ -8601,10 +9162,10 @@ function delayWithSignal(delayMs, signal) {
|
|
|
8601
9162
|
if (signal.aborted) {
|
|
8602
9163
|
return Promise.reject(signal.reason ?? abortError());
|
|
8603
9164
|
}
|
|
8604
|
-
return new Promise((
|
|
9165
|
+
return new Promise((resolve4, reject) => {
|
|
8605
9166
|
const timer = setTimeout(() => {
|
|
8606
9167
|
signal.removeEventListener("abort", onAbort);
|
|
8607
|
-
|
|
9168
|
+
resolve4();
|
|
8608
9169
|
}, delayMs);
|
|
8609
9170
|
const onAbort = () => {
|
|
8610
9171
|
clearTimeout(timer);
|
|
@@ -9069,9 +9630,9 @@ var IFRAME_URL_ATTRIBUTES = /* @__PURE__ */ new Set([
|
|
|
9069
9630
|
"poster",
|
|
9070
9631
|
"ping"
|
|
9071
9632
|
]);
|
|
9072
|
-
function buildArrayFieldPathCandidates(
|
|
9073
|
-
const strict =
|
|
9074
|
-
const relaxedNodes = stripPositionClauses(
|
|
9633
|
+
function buildArrayFieldPathCandidates(path15) {
|
|
9634
|
+
const strict = path15.nodes.length ? buildPathCandidates(path15.nodes) : [];
|
|
9635
|
+
const relaxedNodes = stripPositionClauses(path15.nodes);
|
|
9075
9636
|
const relaxed = relaxedNodes.length ? buildPathCandidates(relaxedNodes) : [];
|
|
9076
9637
|
return dedupeSelectors([...strict, ...relaxed]);
|
|
9077
9638
|
}
|
|
@@ -9601,18 +10162,18 @@ function cloneStructuralElementAnchor(anchor) {
|
|
|
9601
10162
|
nodes: anchor.nodes.map(clonePathNode)
|
|
9602
10163
|
};
|
|
9603
10164
|
}
|
|
9604
|
-
function cloneReplayElementPath(
|
|
10165
|
+
function cloneReplayElementPath(path15) {
|
|
9605
10166
|
return {
|
|
9606
10167
|
resolution: "deterministic",
|
|
9607
|
-
context: cloneContext(
|
|
9608
|
-
nodes:
|
|
10168
|
+
context: cloneContext(path15.context),
|
|
10169
|
+
nodes: path15.nodes.map(clonePathNode)
|
|
9609
10170
|
};
|
|
9610
10171
|
}
|
|
9611
|
-
function cloneElementPath(
|
|
9612
|
-
return cloneReplayElementPath(
|
|
10172
|
+
function cloneElementPath(path15) {
|
|
10173
|
+
return cloneReplayElementPath(path15);
|
|
9613
10174
|
}
|
|
9614
|
-
function buildPathSelectorHint(
|
|
9615
|
-
const nodes =
|
|
10175
|
+
function buildPathSelectorHint(path15) {
|
|
10176
|
+
const nodes = path15?.nodes || [];
|
|
9616
10177
|
const last = nodes[nodes.length - 1];
|
|
9617
10178
|
if (!last) {
|
|
9618
10179
|
return "*";
|
|
@@ -9661,15 +10222,15 @@ function sanitizeStructuralElementAnchor(anchor) {
|
|
|
9661
10222
|
nodes: sanitizeNodes(anchor.nodes)
|
|
9662
10223
|
};
|
|
9663
10224
|
}
|
|
9664
|
-
function sanitizeReplayElementPath(
|
|
10225
|
+
function sanitizeReplayElementPath(path15) {
|
|
9665
10226
|
return {
|
|
9666
10227
|
resolution: "deterministic",
|
|
9667
|
-
context: sanitizeContext(
|
|
9668
|
-
nodes: sanitizeNodes(
|
|
10228
|
+
context: sanitizeContext(path15.context),
|
|
10229
|
+
nodes: sanitizeNodes(path15.nodes)
|
|
9669
10230
|
};
|
|
9670
10231
|
}
|
|
9671
|
-
function sanitizeElementPath(
|
|
9672
|
-
return sanitizeReplayElementPath(
|
|
10232
|
+
function sanitizeElementPath(path15) {
|
|
10233
|
+
return sanitizeReplayElementPath(path15);
|
|
9673
10234
|
}
|
|
9674
10235
|
function buildLocalStructuralElementAnchor(index, rawTargetNode) {
|
|
9675
10236
|
const targetNode = requireElementNode(index, rawTargetNode);
|
|
@@ -9792,8 +10353,8 @@ function buildTargetNotFoundMessage(domPath, diagnostics) {
|
|
|
9792
10353
|
}
|
|
9793
10354
|
return `${base} Target depth ${String(depth)}. Candidate counts: ${sample}.`;
|
|
9794
10355
|
}
|
|
9795
|
-
function buildArrayFieldCandidates(
|
|
9796
|
-
return buildArrayFieldPathCandidates(
|
|
10356
|
+
function buildArrayFieldCandidates(path15) {
|
|
10357
|
+
return buildArrayFieldPathCandidates(path15);
|
|
9797
10358
|
}
|
|
9798
10359
|
function firstDefinedAttribute(node, keys) {
|
|
9799
10360
|
for (const key of keys) {
|
|
@@ -10236,6 +10797,7 @@ var MemoryDomDescriptorStore = class {
|
|
|
10236
10797
|
};
|
|
10237
10798
|
|
|
10238
10799
|
// ../runtime-core/src/action-boundary.ts
|
|
10800
|
+
var actionBoundaryDiagnosticsBySignal = /* @__PURE__ */ new WeakMap();
|
|
10239
10801
|
async function captureActionBoundarySnapshot(engine, pageRef) {
|
|
10240
10802
|
const frames = await engine.listFrames({ pageRef });
|
|
10241
10803
|
const mainFrame = frames.find((frame) => frame.isMainFrame);
|
|
@@ -10247,6 +10809,35 @@ async function captureActionBoundarySnapshot(engine, pageRef) {
|
|
|
10247
10809
|
documentRef: mainFrame.documentRef
|
|
10248
10810
|
};
|
|
10249
10811
|
}
|
|
10812
|
+
function createActionBoundaryDiagnostics(input) {
|
|
10813
|
+
return {
|
|
10814
|
+
trigger: input.boundary.trigger,
|
|
10815
|
+
crossDocument: input.boundary.crossDocument,
|
|
10816
|
+
bootstrapSettled: input.boundary.bootstrapSettled,
|
|
10817
|
+
visualSettled: input.visualSettled,
|
|
10818
|
+
...input.boundary.timedOutPhase !== void 0 ? { timedOutPhase: input.boundary.timedOutPhase } : !input.visualSettled ? { timedOutPhase: "visual" } : {}
|
|
10819
|
+
};
|
|
10820
|
+
}
|
|
10821
|
+
function recordActionBoundaryDiagnostics(signal, diagnostics) {
|
|
10822
|
+
actionBoundaryDiagnosticsBySignal.set(signal, diagnostics);
|
|
10823
|
+
}
|
|
10824
|
+
function takeActionBoundaryDiagnostics(signal) {
|
|
10825
|
+
const diagnostics = actionBoundaryDiagnosticsBySignal.get(signal);
|
|
10826
|
+
actionBoundaryDiagnosticsBySignal.delete(signal);
|
|
10827
|
+
return diagnostics;
|
|
10828
|
+
}
|
|
10829
|
+
function isSoftSettleTimeoutError(error, signal) {
|
|
10830
|
+
if (isTimeoutError(error)) {
|
|
10831
|
+
return true;
|
|
10832
|
+
}
|
|
10833
|
+
return signal?.aborted === true && isTimeoutError(signal.reason) && (error === signal.reason || isAbortError(error));
|
|
10834
|
+
}
|
|
10835
|
+
function isAbortError(error) {
|
|
10836
|
+
return error instanceof Error && error.name === "AbortError";
|
|
10837
|
+
}
|
|
10838
|
+
function isTimeoutError(error) {
|
|
10839
|
+
return isOpensteerProtocolError(error) && error.code === "timeout";
|
|
10840
|
+
}
|
|
10250
10841
|
|
|
10251
10842
|
// ../runtime-core/src/runtimes/dom/executor.ts
|
|
10252
10843
|
var MAX_DOM_ACTION_ATTEMPTS = 3;
|
|
@@ -10270,14 +10861,16 @@ var DomActionExecutor = class {
|
|
|
10270
10861
|
...input.timeout === void 0 ? {} : { timeout: input.timeout }
|
|
10271
10862
|
},
|
|
10272
10863
|
async (pointerTarget, point, timeout) => {
|
|
10273
|
-
|
|
10864
|
+
const events = [];
|
|
10865
|
+
const moved = await timeout.runStep(
|
|
10274
10866
|
() => this.options.engine.mouseMove({
|
|
10275
10867
|
pageRef: pointerTarget.resolved.pageRef,
|
|
10276
10868
|
point,
|
|
10277
10869
|
coordinateSpace: "document-css"
|
|
10278
10870
|
})
|
|
10279
10871
|
);
|
|
10280
|
-
|
|
10872
|
+
events.push(...moved.events);
|
|
10873
|
+
const clicked = await timeout.runStep(
|
|
10281
10874
|
() => this.options.engine.mouseClick({
|
|
10282
10875
|
pageRef: pointerTarget.resolved.pageRef,
|
|
10283
10876
|
point,
|
|
@@ -10287,7 +10880,12 @@ var DomActionExecutor = class {
|
|
|
10287
10880
|
...input.modifiers === void 0 ? {} : { modifiers: input.modifiers }
|
|
10288
10881
|
})
|
|
10289
10882
|
);
|
|
10290
|
-
|
|
10883
|
+
events.push(...clicked.events);
|
|
10884
|
+
return {
|
|
10885
|
+
resolved: pointerTarget.original,
|
|
10886
|
+
point,
|
|
10887
|
+
...events.length === 0 ? {} : { events }
|
|
10888
|
+
};
|
|
10291
10889
|
}
|
|
10292
10890
|
);
|
|
10293
10891
|
}
|
|
@@ -10301,14 +10899,18 @@ var DomActionExecutor = class {
|
|
|
10301
10899
|
...input.timeout === void 0 ? {} : { timeout: input.timeout }
|
|
10302
10900
|
},
|
|
10303
10901
|
async (pointerTarget, point, timeout) => {
|
|
10304
|
-
await timeout.runStep(
|
|
10902
|
+
const moved = await timeout.runStep(
|
|
10305
10903
|
() => this.options.engine.mouseMove({
|
|
10306
10904
|
pageRef: pointerTarget.resolved.pageRef,
|
|
10307
10905
|
point,
|
|
10308
10906
|
coordinateSpace: "document-css"
|
|
10309
10907
|
})
|
|
10310
10908
|
);
|
|
10311
|
-
return {
|
|
10909
|
+
return {
|
|
10910
|
+
resolved: pointerTarget.original,
|
|
10911
|
+
point,
|
|
10912
|
+
...moved.events.length === 0 ? {} : { events: moved.events }
|
|
10913
|
+
};
|
|
10312
10914
|
}
|
|
10313
10915
|
);
|
|
10314
10916
|
}
|
|
@@ -10322,14 +10924,16 @@ var DomActionExecutor = class {
|
|
|
10322
10924
|
...input.timeout === void 0 ? {} : { timeout: input.timeout }
|
|
10323
10925
|
},
|
|
10324
10926
|
async (pointerTarget, point, timeout) => {
|
|
10325
|
-
|
|
10927
|
+
const events = [];
|
|
10928
|
+
const moved = await timeout.runStep(
|
|
10326
10929
|
() => this.options.engine.mouseMove({
|
|
10327
10930
|
pageRef: pointerTarget.resolved.pageRef,
|
|
10328
10931
|
point,
|
|
10329
10932
|
coordinateSpace: "document-css"
|
|
10330
10933
|
})
|
|
10331
10934
|
);
|
|
10332
|
-
|
|
10935
|
+
events.push(...moved.events);
|
|
10936
|
+
const scrolled = await timeout.runStep(
|
|
10333
10937
|
() => this.options.engine.mouseScroll({
|
|
10334
10938
|
pageRef: pointerTarget.resolved.pageRef,
|
|
10335
10939
|
point,
|
|
@@ -10337,7 +10941,12 @@ var DomActionExecutor = class {
|
|
|
10337
10941
|
delta: input.delta
|
|
10338
10942
|
})
|
|
10339
10943
|
);
|
|
10340
|
-
|
|
10944
|
+
events.push(...scrolled.events);
|
|
10945
|
+
return {
|
|
10946
|
+
resolved: pointerTarget.original,
|
|
10947
|
+
point,
|
|
10948
|
+
...events.length === 0 ? {} : { events }
|
|
10949
|
+
};
|
|
10341
10950
|
}
|
|
10342
10951
|
);
|
|
10343
10952
|
}
|
|
@@ -10379,7 +10988,7 @@ var DomActionExecutor = class {
|
|
|
10379
10988
|
let finalResolved = resolved;
|
|
10380
10989
|
let finalSnapshot;
|
|
10381
10990
|
if (input.pressEnter) {
|
|
10382
|
-
await this.
|
|
10991
|
+
await this.waitForPressEnterReaction(timeout);
|
|
10383
10992
|
const enterSession = this.options.createResolutionSession();
|
|
10384
10993
|
const enterResolved = await timeout.runStep(
|
|
10385
10994
|
() => this.options.resolveTarget(enterSession, {
|
|
@@ -10403,7 +11012,15 @@ var DomActionExecutor = class {
|
|
|
10403
11012
|
);
|
|
10404
11013
|
finalResolved = enterResolved;
|
|
10405
11014
|
}
|
|
10406
|
-
await this.settle(
|
|
11015
|
+
const settleDiagnostics = await this.settle(
|
|
11016
|
+
finalResolved.pageRef,
|
|
11017
|
+
"dom.input",
|
|
11018
|
+
timeout,
|
|
11019
|
+
finalSnapshot
|
|
11020
|
+
);
|
|
11021
|
+
if (finalSnapshot !== void 0) {
|
|
11022
|
+
recordActionBoundaryDiagnostics(timeout.signal, settleDiagnostics);
|
|
11023
|
+
}
|
|
10407
11024
|
return finalResolved;
|
|
10408
11025
|
} catch (error) {
|
|
10409
11026
|
lastError = error;
|
|
@@ -10480,12 +11097,13 @@ var DomActionExecutor = class {
|
|
|
10480
11097
|
() => captureActionBoundarySnapshot(this.options.engine, pointerTarget.resolved.pageRef)
|
|
10481
11098
|
);
|
|
10482
11099
|
const outcome = await dispatch(pointerTarget, point, timeout);
|
|
10483
|
-
await this.settle(
|
|
11100
|
+
const settleDiagnostics = await this.settle(
|
|
10484
11101
|
pointerTarget.resolved.pageRef,
|
|
10485
11102
|
input.operation,
|
|
10486
11103
|
timeout,
|
|
10487
11104
|
actionBoundarySnapshot
|
|
10488
11105
|
);
|
|
11106
|
+
recordActionBoundaryDiagnostics(timeout.signal, settleDiagnostics);
|
|
10489
11107
|
return outcome;
|
|
10490
11108
|
} catch (error) {
|
|
10491
11109
|
lastError = error;
|
|
@@ -10505,22 +11123,47 @@ var DomActionExecutor = class {
|
|
|
10505
11123
|
}
|
|
10506
11124
|
async settle(pageRef, operation, timeout, snapshot) {
|
|
10507
11125
|
const bridge = this.requireBridge();
|
|
10508
|
-
|
|
11126
|
+
let visualSettled = true;
|
|
11127
|
+
const boundary = await timeout.runStep(
|
|
10509
11128
|
() => bridge.finalizeDomAction(pageRef, {
|
|
10510
11129
|
operation,
|
|
10511
11130
|
...snapshot === void 0 ? {} : { snapshot },
|
|
10512
11131
|
signal: timeout.signal,
|
|
10513
11132
|
remainingMs: () => timeout.remainingMs(),
|
|
10514
|
-
policySettle: (targetPageRef, trigger) =>
|
|
10515
|
-
|
|
10516
|
-
|
|
10517
|
-
|
|
10518
|
-
|
|
10519
|
-
|
|
10520
|
-
|
|
10521
|
-
|
|
11133
|
+
policySettle: async (targetPageRef, trigger) => {
|
|
11134
|
+
try {
|
|
11135
|
+
await settleWithPolicy(this.options.policy.settle, {
|
|
11136
|
+
operation,
|
|
11137
|
+
trigger,
|
|
11138
|
+
engine: this.options.engine,
|
|
11139
|
+
pageRef: targetPageRef,
|
|
11140
|
+
signal: timeout.signal,
|
|
11141
|
+
remainingMs: timeout.remainingMs()
|
|
11142
|
+
});
|
|
11143
|
+
} catch (error) {
|
|
11144
|
+
if (snapshot !== void 0 && isSoftSettleTimeoutError(error, timeout.signal)) {
|
|
11145
|
+
visualSettled = false;
|
|
11146
|
+
return;
|
|
11147
|
+
}
|
|
11148
|
+
throw error;
|
|
11149
|
+
}
|
|
11150
|
+
}
|
|
10522
11151
|
})
|
|
10523
11152
|
);
|
|
11153
|
+
return createActionBoundaryDiagnostics({
|
|
11154
|
+
boundary,
|
|
11155
|
+
visualSettled
|
|
11156
|
+
});
|
|
11157
|
+
}
|
|
11158
|
+
async waitForPressEnterReaction(timeout) {
|
|
11159
|
+
const delayMs = this.options.policy.settle.resolveDelayMs({
|
|
11160
|
+
operation: "dom.input",
|
|
11161
|
+
trigger: "dom-action"
|
|
11162
|
+
});
|
|
11163
|
+
if (delayMs <= 0) {
|
|
11164
|
+
return;
|
|
11165
|
+
}
|
|
11166
|
+
await delayWithSignal(delayMs, timeout.signal);
|
|
10524
11167
|
}
|
|
10525
11168
|
requireBridge() {
|
|
10526
11169
|
if (this.bridge !== void 0) {
|
|
@@ -11229,21 +11872,21 @@ var DefaultDomRuntime = class {
|
|
|
11229
11872
|
return match;
|
|
11230
11873
|
}
|
|
11231
11874
|
async resolvePathTarget(session, pageRef, rawPath, source, description, descriptor) {
|
|
11232
|
-
const
|
|
11233
|
-
const context = await this.resolvePathContext(session, pageRef,
|
|
11234
|
-
const target = resolveDomPathInScope(context.index,
|
|
11875
|
+
const path15 = sanitizeReplayElementPath(rawPath);
|
|
11876
|
+
const context = await this.resolvePathContext(session, pageRef, path15.context);
|
|
11877
|
+
const target = resolveDomPathInScope(context.index, path15.nodes, context.scope);
|
|
11235
11878
|
if (!target) {
|
|
11236
|
-
throwTargetNotFound(context.index,
|
|
11879
|
+
throwTargetNotFound(context.index, path15.nodes, context.scope);
|
|
11237
11880
|
}
|
|
11238
11881
|
if (target.node.nodeRef === void 0) {
|
|
11239
11882
|
throw new Error(
|
|
11240
|
-
`resolved path "${buildPathSelectorHint(
|
|
11883
|
+
`resolved path "${buildPathSelectorHint(path15)}" does not point to a live element`
|
|
11241
11884
|
);
|
|
11242
11885
|
}
|
|
11243
11886
|
const anchor = await this.buildAnchorFromSnapshotNode(session, context.snapshot, target.node);
|
|
11244
11887
|
return this.createResolvedTarget(source, context.snapshot, target.node, anchor, {
|
|
11245
11888
|
...description === void 0 ? {} : { description },
|
|
11246
|
-
replayPath:
|
|
11889
|
+
replayPath: path15,
|
|
11247
11890
|
...source === "path" || source === "descriptor" ? { selectorUsed: target.selector } : {},
|
|
11248
11891
|
...descriptor === void 0 ? {} : { descriptor }
|
|
11249
11892
|
});
|
|
@@ -11264,9 +11907,9 @@ var DefaultDomRuntime = class {
|
|
|
11264
11907
|
});
|
|
11265
11908
|
}
|
|
11266
11909
|
async queryAllByElementPath(session, pageRef, rawPath) {
|
|
11267
|
-
const
|
|
11268
|
-
const context = await this.resolvePathContext(session, pageRef,
|
|
11269
|
-
return queryAllDomPathInScope(context.index,
|
|
11910
|
+
const path15 = sanitizeReplayElementPath(rawPath);
|
|
11911
|
+
const context = await this.resolvePathContext(session, pageRef, path15.context);
|
|
11912
|
+
return queryAllDomPathInScope(context.index, path15.nodes, context.scope).filter(
|
|
11270
11913
|
(node) => node.nodeRef !== void 0
|
|
11271
11914
|
).map((node) => this.createSnapshotTarget(context.snapshot, node));
|
|
11272
11915
|
}
|
|
@@ -11452,16 +12095,16 @@ var DefaultDomRuntime = class {
|
|
|
11452
12095
|
const index = createSnapshotIndex(item.snapshot);
|
|
11453
12096
|
return this.resolveFirstArrayFieldTargetInNode(index, item.node, field.path);
|
|
11454
12097
|
}
|
|
11455
|
-
resolveFirstArrayFieldTargetInNode(index, rootNode,
|
|
11456
|
-
const normalizedPath = sanitizeElementPath(
|
|
12098
|
+
resolveFirstArrayFieldTargetInNode(index, rootNode, path15) {
|
|
12099
|
+
const normalizedPath = sanitizeElementPath(path15);
|
|
11457
12100
|
const selectors = buildArrayFieldCandidates(normalizedPath);
|
|
11458
12101
|
if (!selectors.length) {
|
|
11459
12102
|
return rootNode;
|
|
11460
12103
|
}
|
|
11461
12104
|
return resolveFirstWithinNodeBySelectors(index, rootNode, selectors);
|
|
11462
12105
|
}
|
|
11463
|
-
resolveUniqueArrayFieldTargetInNode(index, rootNode,
|
|
11464
|
-
const normalizedPath = sanitizeElementPath(
|
|
12106
|
+
resolveUniqueArrayFieldTargetInNode(index, rootNode, path15) {
|
|
12107
|
+
const normalizedPath = sanitizeElementPath(path15);
|
|
11465
12108
|
const selectors = buildArrayFieldCandidates(normalizedPath);
|
|
11466
12109
|
if (!selectors.length) {
|
|
11467
12110
|
return rootNode;
|
|
@@ -11550,8 +12193,8 @@ function encodeDataPath(tokens) {
|
|
|
11550
12193
|
}
|
|
11551
12194
|
return out;
|
|
11552
12195
|
}
|
|
11553
|
-
function parseDataPath(
|
|
11554
|
-
const input =
|
|
12196
|
+
function parseDataPath(path15) {
|
|
12197
|
+
const input = path15.trim();
|
|
11555
12198
|
if (input.length === 0) {
|
|
11556
12199
|
return [];
|
|
11557
12200
|
}
|
|
@@ -11601,8 +12244,8 @@ function parseDataPath(path13) {
|
|
|
11601
12244
|
function inflateDataPathObject(flat) {
|
|
11602
12245
|
let root = {};
|
|
11603
12246
|
let initialized = false;
|
|
11604
|
-
for (const [
|
|
11605
|
-
const tokens = parseDataPath(
|
|
12247
|
+
for (const [path15, value] of Object.entries(flat)) {
|
|
12248
|
+
const tokens = parseDataPath(path15);
|
|
11606
12249
|
if (!tokens || tokens.length === 0) {
|
|
11607
12250
|
continue;
|
|
11608
12251
|
}
|
|
@@ -11934,8 +12577,8 @@ function buildVariantDescriptorFromCluster(descriptors) {
|
|
|
11934
12577
|
fields: mergedFields
|
|
11935
12578
|
};
|
|
11936
12579
|
}
|
|
11937
|
-
function minimizePathMatchClauses(
|
|
11938
|
-
const normalized = sanitizeElementPath(
|
|
12580
|
+
function minimizePathMatchClauses(path15, mode) {
|
|
12581
|
+
const normalized = sanitizeElementPath(path15);
|
|
11939
12582
|
const nodes = normalized.nodes.map((node, index) => {
|
|
11940
12583
|
const isLast = index === normalized.nodes.length - 1;
|
|
11941
12584
|
const attrs = node.attrs || {};
|
|
@@ -12039,8 +12682,8 @@ function seedMinimalAttrClause(attrs) {
|
|
|
12039
12682
|
}
|
|
12040
12683
|
return null;
|
|
12041
12684
|
}
|
|
12042
|
-
function relaxPathForSingleSample(
|
|
12043
|
-
const normalized = sanitizeElementPath(
|
|
12685
|
+
function relaxPathForSingleSample(path15, mode) {
|
|
12686
|
+
const normalized = sanitizeElementPath(path15);
|
|
12044
12687
|
const relaxedNodes = normalized.nodes.map((node, index) => {
|
|
12045
12688
|
const isLast = index === normalized.nodes.length - 1;
|
|
12046
12689
|
const attrs = normalizeAttrsForSingleSample(node.attrs || {});
|
|
@@ -12125,8 +12768,8 @@ function shouldKeepAttrForSingleSample(key) {
|
|
|
12125
12768
|
}
|
|
12126
12769
|
return true;
|
|
12127
12770
|
}
|
|
12128
|
-
function buildPathStructureKey(
|
|
12129
|
-
const normalized = sanitizeElementPath(
|
|
12771
|
+
function buildPathStructureKey(path15) {
|
|
12772
|
+
const normalized = sanitizeElementPath(path15);
|
|
12130
12773
|
return canonicalJsonString({
|
|
12131
12774
|
context: (normalized.context || []).map((hop) => ({
|
|
12132
12775
|
kind: hop.kind,
|
|
@@ -12253,30 +12896,30 @@ function buildArrayItemNode(fields) {
|
|
|
12253
12896
|
}
|
|
12254
12897
|
return node;
|
|
12255
12898
|
}
|
|
12256
|
-
function insertNodeAtPath(root,
|
|
12257
|
-
const tokens = parseDataPath(
|
|
12899
|
+
function insertNodeAtPath(root, path15, node) {
|
|
12900
|
+
const tokens = parseDataPath(path15);
|
|
12258
12901
|
if (!tokens || !tokens.length) {
|
|
12259
12902
|
throw new Error(
|
|
12260
|
-
`Invalid persisted extraction path "${
|
|
12903
|
+
`Invalid persisted extraction path "${path15}": expected a non-empty object path.`
|
|
12261
12904
|
);
|
|
12262
12905
|
}
|
|
12263
12906
|
if (tokens.some((token) => token.kind === "index")) {
|
|
12264
12907
|
throw new Error(
|
|
12265
|
-
`Invalid persisted extraction path "${
|
|
12908
|
+
`Invalid persisted extraction path "${path15}": nested array indices are not supported in cached descriptors.`
|
|
12266
12909
|
);
|
|
12267
12910
|
}
|
|
12268
12911
|
let current = root;
|
|
12269
12912
|
for (let index = 0; index < tokens.length; index += 1) {
|
|
12270
12913
|
const token = tokens[index];
|
|
12271
12914
|
if (!token || token.kind !== "prop") {
|
|
12272
|
-
throw new Error(`Invalid persisted extraction path "${
|
|
12915
|
+
throw new Error(`Invalid persisted extraction path "${path15}": expected object segment.`);
|
|
12273
12916
|
}
|
|
12274
12917
|
const isLast = index === tokens.length - 1;
|
|
12275
12918
|
if (isLast) {
|
|
12276
12919
|
const existing = current[token.key];
|
|
12277
12920
|
if (existing) {
|
|
12278
12921
|
throw new Error(
|
|
12279
|
-
`Conflicting persisted extraction path "${
|
|
12922
|
+
`Conflicting persisted extraction path "${path15}" detected while building descriptor tree.`
|
|
12280
12923
|
);
|
|
12281
12924
|
}
|
|
12282
12925
|
current[token.key] = node;
|
|
@@ -12291,7 +12934,7 @@ function insertNodeAtPath(root, path13, node) {
|
|
|
12291
12934
|
}
|
|
12292
12935
|
if (!isPersistedObjectNode(next)) {
|
|
12293
12936
|
throw new Error(
|
|
12294
|
-
`Conflicting persisted extraction path "${
|
|
12937
|
+
`Conflicting persisted extraction path "${path15}" detected at "${token.key}".`
|
|
12295
12938
|
);
|
|
12296
12939
|
}
|
|
12297
12940
|
current = next;
|
|
@@ -12326,7 +12969,7 @@ function buildItemRootForArrayIndex(entries) {
|
|
|
12326
12969
|
}
|
|
12327
12970
|
const paths = entries.map(
|
|
12328
12971
|
(entry) => isPersistablePathField(entry.source) ? sanitizeElementPath(entry.source.path) : null
|
|
12329
|
-
).filter((
|
|
12972
|
+
).filter((path15) => path15 !== null);
|
|
12330
12973
|
if (!paths.length) {
|
|
12331
12974
|
return null;
|
|
12332
12975
|
}
|
|
@@ -12347,7 +12990,7 @@ function getCommonPathPrefixLength(paths) {
|
|
|
12347
12990
|
if (!paths.length) {
|
|
12348
12991
|
return 0;
|
|
12349
12992
|
}
|
|
12350
|
-
const nodeChains = paths.map((
|
|
12993
|
+
const nodeChains = paths.map((path15) => path15.nodes);
|
|
12351
12994
|
const minLength = Math.min(...nodeChains.map((nodes) => nodes.length));
|
|
12352
12995
|
if (!Number.isFinite(minLength) || minLength <= 0) {
|
|
12353
12996
|
return 0;
|
|
@@ -12416,30 +13059,30 @@ function mergeElementPathsByMajority(paths) {
|
|
|
12416
13059
|
if (!paths.length) {
|
|
12417
13060
|
return null;
|
|
12418
13061
|
}
|
|
12419
|
-
const normalized = paths.map((
|
|
13062
|
+
const normalized = paths.map((path15) => sanitizeElementPath(path15));
|
|
12420
13063
|
const contextKey = pickModeString(
|
|
12421
|
-
normalized.map((
|
|
13064
|
+
normalized.map((path15) => canonicalJsonString(path15.context)),
|
|
12422
13065
|
1
|
|
12423
13066
|
);
|
|
12424
13067
|
if (!contextKey) {
|
|
12425
13068
|
return null;
|
|
12426
13069
|
}
|
|
12427
|
-
const sameContext = normalized.filter((
|
|
13070
|
+
const sameContext = normalized.filter((path15) => canonicalJsonString(path15.context) === contextKey);
|
|
12428
13071
|
if (!sameContext.length) {
|
|
12429
13072
|
return null;
|
|
12430
13073
|
}
|
|
12431
13074
|
const targetLength = pickModeNumber(
|
|
12432
|
-
sameContext.map((
|
|
13075
|
+
sameContext.map((path15) => path15.nodes.length),
|
|
12433
13076
|
1
|
|
12434
13077
|
) ?? sameContext[0]?.nodes.length ?? 0;
|
|
12435
|
-
const aligned = sameContext.filter((
|
|
13078
|
+
const aligned = sameContext.filter((path15) => path15.nodes.length === targetLength);
|
|
12436
13079
|
if (!aligned.length) {
|
|
12437
13080
|
return null;
|
|
12438
13081
|
}
|
|
12439
13082
|
const threshold = majorityThreshold(aligned.length);
|
|
12440
13083
|
const nodes = [];
|
|
12441
13084
|
for (let index = 0; index < targetLength; index += 1) {
|
|
12442
|
-
const nodesAtIndex = aligned.map((
|
|
13085
|
+
const nodesAtIndex = aligned.map((path15) => path15.nodes[index]).filter((node) => node !== void 0);
|
|
12443
13086
|
if (!nodesAtIndex.length) {
|
|
12444
13087
|
return null;
|
|
12445
13088
|
}
|
|
@@ -12685,8 +13328,8 @@ function clonePathContext(context) {
|
|
|
12685
13328
|
function clonePathNodes(nodes) {
|
|
12686
13329
|
return JSON.parse(JSON.stringify(nodes || []));
|
|
12687
13330
|
}
|
|
12688
|
-
function cloneElementPath2(
|
|
12689
|
-
return JSON.parse(JSON.stringify(
|
|
13331
|
+
function cloneElementPath2(path15) {
|
|
13332
|
+
return JSON.parse(JSON.stringify(path15));
|
|
12690
13333
|
}
|
|
12691
13334
|
function clonePersistedOpensteerExtractionNode(node) {
|
|
12692
13335
|
return JSON.parse(JSON.stringify(node));
|
|
@@ -13004,8 +13647,8 @@ function collectPersistedValueNodeRefs(node) {
|
|
|
13004
13647
|
return [
|
|
13005
13648
|
{
|
|
13006
13649
|
path: sanitizeElementPath(node.$path),
|
|
13007
|
-
replacePath: (
|
|
13008
|
-
node.$path = sanitizeElementPath(
|
|
13650
|
+
replacePath: (path15) => {
|
|
13651
|
+
node.$path = sanitizeElementPath(path15);
|
|
13009
13652
|
}
|
|
13010
13653
|
}
|
|
13011
13654
|
];
|
|
@@ -13019,13 +13662,13 @@ function collectPersistedValueNodeRefs(node) {
|
|
|
13019
13662
|
}
|
|
13020
13663
|
return refs;
|
|
13021
13664
|
}
|
|
13022
|
-
function hasPositionClause(
|
|
13023
|
-
return
|
|
13665
|
+
function hasPositionClause(path15) {
|
|
13666
|
+
return path15.nodes.some((node) => node.match.some((clause) => clause.kind === "position"));
|
|
13024
13667
|
}
|
|
13025
|
-
function stripPositionClauses2(
|
|
13668
|
+
function stripPositionClauses2(path15) {
|
|
13026
13669
|
return sanitizeElementPath({
|
|
13027
|
-
context:
|
|
13028
|
-
nodes:
|
|
13670
|
+
context: path15.context,
|
|
13671
|
+
nodes: path15.nodes.map((node) => ({
|
|
13029
13672
|
...node,
|
|
13030
13673
|
match: node.match.filter((clause) => clause.kind !== "position")
|
|
13031
13674
|
}))
|
|
@@ -13435,14 +14078,13 @@ function normalizeNonEmptyString2(name, value) {
|
|
|
13435
14078
|
function normalizeKey(value) {
|
|
13436
14079
|
return String(value ?? "").trim();
|
|
13437
14080
|
}
|
|
13438
|
-
function labelForPath(
|
|
13439
|
-
return
|
|
14081
|
+
function labelForPath(path15) {
|
|
14082
|
+
return path15.trim().length === 0 ? "$" : path15;
|
|
13440
14083
|
}
|
|
13441
14084
|
function sha256Hex3(value) {
|
|
13442
14085
|
return createHash("sha256").update(value).digest("hex");
|
|
13443
14086
|
}
|
|
13444
|
-
|
|
13445
|
-
var PS_COMMAND_ENV = { ...process.env, LC_ALL: "C" };
|
|
14087
|
+
({ ...process.env});
|
|
13446
14088
|
var WINDOWS_PROGRAM_FILES = process.env.PROGRAMFILES ?? "C:\\Program Files";
|
|
13447
14089
|
var WINDOWS_PROGRAM_FILES_X86 = process.env["PROGRAMFILES(X86)"] ?? "C:\\Program Files (x86)";
|
|
13448
14090
|
var BROWSER_BRANDS = [
|
|
@@ -13628,9 +14270,6 @@ var BROWSER_BRANDS = [
|
|
|
13628
14270
|
}
|
|
13629
14271
|
}
|
|
13630
14272
|
];
|
|
13631
|
-
function getAllBrowserBrands() {
|
|
13632
|
-
return BROWSER_BRANDS;
|
|
13633
|
-
}
|
|
13634
14273
|
function getBrowserBrand(id) {
|
|
13635
14274
|
const brand2 = BROWSER_BRANDS.find((candidate) => candidate.id === id);
|
|
13636
14275
|
if (!brand2) {
|
|
@@ -13673,28 +14312,6 @@ function detectInstalledBrowserBrands() {
|
|
|
13673
14312
|
}
|
|
13674
14313
|
return installations;
|
|
13675
14314
|
}
|
|
13676
|
-
function resolveBrandExecutablePath(brand2, explicitPath) {
|
|
13677
|
-
if (explicitPath !== void 0) {
|
|
13678
|
-
const resolvedPath2 = resolve(expandHome(explicitPath));
|
|
13679
|
-
if (!existsSync(resolvedPath2)) {
|
|
13680
|
-
throw new Error(`${brand2.displayName} executable was not found at "${resolvedPath2}".`);
|
|
13681
|
-
}
|
|
13682
|
-
return resolvedPath2;
|
|
13683
|
-
}
|
|
13684
|
-
const platformConfig = resolveBrandPlatformConfig(brand2);
|
|
13685
|
-
if (!platformConfig) {
|
|
13686
|
-
throw new Error(`${brand2.displayName} is not supported on ${process.platform}.`);
|
|
13687
|
-
}
|
|
13688
|
-
const resolvedPath = firstExistingPath(
|
|
13689
|
-
resolveExecutableCandidates(platformConfig.executableCandidates)
|
|
13690
|
-
);
|
|
13691
|
-
if (!resolvedPath) {
|
|
13692
|
-
throw new Error(
|
|
13693
|
-
`Could not find a ${brand2.displayName} executable. Pass --executable-path or browser.executablePath.`
|
|
13694
|
-
);
|
|
13695
|
-
}
|
|
13696
|
-
return resolvedPath;
|
|
13697
|
-
}
|
|
13698
14315
|
function resolveBrandUserDataDir(brand2, explicitDir) {
|
|
13699
14316
|
if (explicitDir !== void 0) {
|
|
13700
14317
|
return resolve(expandHome(explicitDir));
|
|
@@ -13705,129 +14322,9 @@ function resolveBrandUserDataDir(brand2, explicitDir) {
|
|
|
13705
14322
|
}
|
|
13706
14323
|
return resolve(expandHome(platformConfig.userDataDir));
|
|
13707
14324
|
}
|
|
13708
|
-
function isBrandProcess(brand2, commandLine) {
|
|
13709
|
-
const normalizedCommand = normalizeCommand(commandLine);
|
|
13710
|
-
if (!normalizedCommand) {
|
|
13711
|
-
return false;
|
|
13712
|
-
}
|
|
13713
|
-
if (normalizedCommand.includes("crashpad_handler")) {
|
|
13714
|
-
return false;
|
|
13715
|
-
}
|
|
13716
|
-
if (/\s--type=/.test(normalizedCommand)) {
|
|
13717
|
-
return false;
|
|
13718
|
-
}
|
|
13719
|
-
return getBrandProcessMarkers(brand2).some((marker) => normalizedCommand.includes(marker));
|
|
13720
|
-
}
|
|
13721
|
-
function findBrandProcess(brand2) {
|
|
13722
|
-
for (const processEntry of listProcesses()) {
|
|
13723
|
-
if (isBrandProcess(brand2, processEntry.commandLine)) {
|
|
13724
|
-
return { pid: processEntry.pid };
|
|
13725
|
-
}
|
|
13726
|
-
}
|
|
13727
|
-
return null;
|
|
13728
|
-
}
|
|
13729
|
-
function getBrandProcessMarkers(brand2) {
|
|
13730
|
-
const markers = /* @__PURE__ */ new Set();
|
|
13731
|
-
for (const config of [brand2.darwin, brand2.win32, brand2.linux]) {
|
|
13732
|
-
if (!config) {
|
|
13733
|
-
continue;
|
|
13734
|
-
}
|
|
13735
|
-
for (const processName of config.processNames) {
|
|
13736
|
-
const normalized = normalizeCommand(processName);
|
|
13737
|
-
if (normalized) {
|
|
13738
|
-
markers.add(normalized);
|
|
13739
|
-
}
|
|
13740
|
-
}
|
|
13741
|
-
for (const candidate of config.executableCandidates) {
|
|
13742
|
-
if (!candidate) {
|
|
13743
|
-
continue;
|
|
13744
|
-
}
|
|
13745
|
-
const normalized = normalizeCommand(resolve(expandHome(candidate)));
|
|
13746
|
-
if (normalized) {
|
|
13747
|
-
markers.add(normalized);
|
|
13748
|
-
}
|
|
13749
|
-
}
|
|
13750
|
-
}
|
|
13751
|
-
return [...markers];
|
|
13752
|
-
}
|
|
13753
14325
|
function resolveExecutableCandidates(candidates) {
|
|
13754
14326
|
return candidates.map((candidate) => candidate ? resolve(expandHome(candidate)) : null);
|
|
13755
14327
|
}
|
|
13756
|
-
function listProcesses() {
|
|
13757
|
-
if (process.platform === "win32") {
|
|
13758
|
-
return listWindowsProcesses();
|
|
13759
|
-
}
|
|
13760
|
-
return listUnixProcesses();
|
|
13761
|
-
}
|
|
13762
|
-
function listUnixProcesses() {
|
|
13763
|
-
try {
|
|
13764
|
-
const output = execFileSync("ps", ["-A", "-o", "pid=,command="], {
|
|
13765
|
-
encoding: "utf8",
|
|
13766
|
-
env: PS_COMMAND_ENV,
|
|
13767
|
-
maxBuffer: PROCESS_LIST_MAX_BUFFER_BYTES,
|
|
13768
|
-
stdio: ["ignore", "pipe", "ignore"]
|
|
13769
|
-
});
|
|
13770
|
-
return output.split(/\r?\n/).map((line) => line.trim()).filter((line) => line.length > 0).map((line) => {
|
|
13771
|
-
const match = /^(\d+)\s+(.*)$/.exec(line);
|
|
13772
|
-
if (!match) {
|
|
13773
|
-
return null;
|
|
13774
|
-
}
|
|
13775
|
-
const pid = Number.parseInt(match[1] ?? "", 10);
|
|
13776
|
-
const commandLine = match[2]?.trim() ?? "";
|
|
13777
|
-
if (!Number.isInteger(pid) || pid <= 0 || commandLine.length === 0) {
|
|
13778
|
-
return null;
|
|
13779
|
-
}
|
|
13780
|
-
return {
|
|
13781
|
-
pid,
|
|
13782
|
-
commandLine
|
|
13783
|
-
};
|
|
13784
|
-
}).filter(
|
|
13785
|
-
(entry) => entry !== null
|
|
13786
|
-
).sort((left, right) => left.pid - right.pid);
|
|
13787
|
-
} catch {
|
|
13788
|
-
return [];
|
|
13789
|
-
}
|
|
13790
|
-
}
|
|
13791
|
-
function listWindowsProcesses() {
|
|
13792
|
-
try {
|
|
13793
|
-
const output = execFileSync(
|
|
13794
|
-
"powershell.exe",
|
|
13795
|
-
[
|
|
13796
|
-
"-NoProfile",
|
|
13797
|
-
"-Command",
|
|
13798
|
-
"Get-CimInstance Win32_Process | Select-Object ProcessId,CommandLine | ConvertTo-Json -Compress"
|
|
13799
|
-
],
|
|
13800
|
-
{
|
|
13801
|
-
encoding: "utf8",
|
|
13802
|
-
maxBuffer: PROCESS_LIST_MAX_BUFFER_BYTES,
|
|
13803
|
-
stdio: ["ignore", "pipe", "ignore"]
|
|
13804
|
-
}
|
|
13805
|
-
).trim();
|
|
13806
|
-
if (!output) {
|
|
13807
|
-
return [];
|
|
13808
|
-
}
|
|
13809
|
-
const parsed = JSON.parse(output);
|
|
13810
|
-
const records = Array.isArray(parsed) ? parsed : [parsed];
|
|
13811
|
-
return records.map((record) => {
|
|
13812
|
-
const pid = Number(record.ProcessId);
|
|
13813
|
-
const commandLine = typeof record.CommandLine === "string" ? record.CommandLine.trim() : "";
|
|
13814
|
-
if (!Number.isInteger(pid) || pid <= 0 || commandLine.length === 0) {
|
|
13815
|
-
return null;
|
|
13816
|
-
}
|
|
13817
|
-
return {
|
|
13818
|
-
pid,
|
|
13819
|
-
commandLine
|
|
13820
|
-
};
|
|
13821
|
-
}).filter(
|
|
13822
|
-
(entry) => entry !== null
|
|
13823
|
-
).sort((left, right) => left.pid - right.pid);
|
|
13824
|
-
} catch {
|
|
13825
|
-
return [];
|
|
13826
|
-
}
|
|
13827
|
-
}
|
|
13828
|
-
function normalizeCommand(value) {
|
|
13829
|
-
return value.trim().replaceAll("\\", "/").toLowerCase();
|
|
13830
|
-
}
|
|
13831
14328
|
|
|
13832
14329
|
// src/local-browser/chrome-discovery.ts
|
|
13833
14330
|
function expandHome(value) {
|
|
@@ -14194,8 +14691,8 @@ function buildBrowserWebSocketUrl(httpUrl, webSocketPath) {
|
|
|
14194
14691
|
const protocol = httpUrl.protocol === "https:" ? "wss:" : "ws:";
|
|
14195
14692
|
return `${protocol}//${httpUrl.host}${normalizeWebSocketPath(webSocketPath)}`;
|
|
14196
14693
|
}
|
|
14197
|
-
function normalizeWebSocketPath(
|
|
14198
|
-
return
|
|
14694
|
+
function normalizeWebSocketPath(path15) {
|
|
14695
|
+
return path15.startsWith("/") ? path15 : `/${path15}`;
|
|
14199
14696
|
}
|
|
14200
14697
|
function rewriteBrowserWebSocketHost(browserWsUrl, requestedUrl) {
|
|
14201
14698
|
try {
|
|
@@ -14215,7 +14712,7 @@ function readPort(url) {
|
|
|
14215
14712
|
var OPENSTEER_LIVE_SESSION_LAYOUT = "opensteer-session";
|
|
14216
14713
|
var OPENSTEER_LIVE_SESSION_VERSION = 1;
|
|
14217
14714
|
function resolveLiveSessionRecordPath(rootPath, provider) {
|
|
14218
|
-
return
|
|
14715
|
+
return path7.join(rootPath, "live", provider === "local" ? "local.json" : "cloud.json");
|
|
14219
14716
|
}
|
|
14220
14717
|
function resolveLocalSessionRecordPath(rootPath) {
|
|
14221
14718
|
return resolveLiveSessionRecordPath(rootPath, "local");
|
|
@@ -15020,8 +15517,8 @@ var OpensteerBrowserManager = class {
|
|
|
15020
15517
|
...options.browser === void 0 ? {} : { browser: options.browser },
|
|
15021
15518
|
...this.contextOptions === void 0 ? {} : { context: this.contextOptions }
|
|
15022
15519
|
});
|
|
15023
|
-
this.rootPath = options.rootPath ?? (this.workspace === void 0 ?
|
|
15024
|
-
rootDir:
|
|
15520
|
+
this.rootPath = options.rootPath ?? (this.workspace === void 0 ? path7.join(tmpdir(), `${TEMPORARY_WORKSPACE_PREFIX}${randomUUID()}`) : resolveFilesystemWorkspacePath({
|
|
15521
|
+
rootDir: path7.resolve(options.rootDir ?? process.cwd()),
|
|
15025
15522
|
workspace: this.workspace
|
|
15026
15523
|
}));
|
|
15027
15524
|
this.cleanupRootOnDisconnect = this.workspace === void 0;
|
|
@@ -15091,7 +15588,7 @@ var OpensteerBrowserManager = class {
|
|
|
15091
15588
|
userDataDir: "browser/user-data",
|
|
15092
15589
|
bootstrap: {
|
|
15093
15590
|
kind: "cloneLocalProfile",
|
|
15094
|
-
sourceUserDataDir:
|
|
15591
|
+
sourceUserDataDir: path7.resolve(input.sourceUserDataDir),
|
|
15095
15592
|
...input.sourceProfileDirectory === void 0 ? {} : { sourceProfileDirectory: input.sourceProfileDirectory }
|
|
15096
15593
|
}
|
|
15097
15594
|
};
|
|
@@ -15218,7 +15715,7 @@ var OpensteerBrowserManager = class {
|
|
|
15218
15715
|
});
|
|
15219
15716
|
}
|
|
15220
15717
|
async createTemporaryEngine() {
|
|
15221
|
-
const userDataDir = await mkdtemp(
|
|
15718
|
+
const userDataDir = await mkdtemp(path7.join(tmpdir(), "opensteer-temporary-browser-"));
|
|
15222
15719
|
await clearChromeSingletonEntries(userDataDir);
|
|
15223
15720
|
const launched = await launchOwnedBrowser({
|
|
15224
15721
|
userDataDir,
|
|
@@ -15665,7 +16162,7 @@ async function terminateProcess(pid) {
|
|
|
15665
16162
|
}
|
|
15666
16163
|
}
|
|
15667
16164
|
async function requestBrowserClose(endpoint) {
|
|
15668
|
-
await new Promise((
|
|
16165
|
+
await new Promise((resolve4, reject) => {
|
|
15669
16166
|
const socket = new WebSocket(endpoint);
|
|
15670
16167
|
const timeout = setTimeout(() => {
|
|
15671
16168
|
socket.close();
|
|
@@ -15682,7 +16179,7 @@ async function requestBrowserClose(endpoint) {
|
|
|
15682
16179
|
reject(error);
|
|
15683
16180
|
return;
|
|
15684
16181
|
}
|
|
15685
|
-
|
|
16182
|
+
resolve4();
|
|
15686
16183
|
};
|
|
15687
16184
|
socket.addEventListener("open", () => {
|
|
15688
16185
|
socket.send(JSON.stringify({ id: 1, method: "Browser.close" }));
|
|
@@ -15720,7 +16217,7 @@ async function waitForProcessExit(pid, timeoutMs) {
|
|
|
15720
16217
|
return !isProcessRunning(pid);
|
|
15721
16218
|
}
|
|
15722
16219
|
function resolveAbpSessionDir(workspace) {
|
|
15723
|
-
return
|
|
16220
|
+
return path7.join(workspace.livePath, "abp-session");
|
|
15724
16221
|
}
|
|
15725
16222
|
async function allocateEphemeralPort() {
|
|
15726
16223
|
const { allocatePort } = await loadAbpModule();
|
|
@@ -15778,7 +16275,7 @@ function isStealthProfile(input) {
|
|
|
15778
16275
|
return input.id !== void 0 && input.platform !== void 0 && input.browserBrand !== void 0 && input.browserVersion !== void 0 && input.userAgent !== void 0 && input.viewport !== void 0 && input.screenResolution !== void 0 && input.devicePixelRatio !== void 0 && input.maxTouchPoints !== void 0 && input.webglVendor !== void 0 && input.webglRenderer !== void 0 && input.fonts !== void 0 && input.canvasNoiseSeed !== void 0 && input.audioNoiseSeed !== void 0 && input.locale !== void 0 && input.timezoneId !== void 0;
|
|
15779
16276
|
}
|
|
15780
16277
|
async function sleep(ms) {
|
|
15781
|
-
await new Promise((
|
|
16278
|
+
await new Promise((resolve4) => setTimeout(resolve4, ms));
|
|
15782
16279
|
}
|
|
15783
16280
|
|
|
15784
16281
|
// ../runtime-core/src/sdk/semantic-dispatch.ts
|
|
@@ -16044,7 +16541,7 @@ async function dispatchSemanticOperation(runtime, operation, input, options = {}
|
|
|
16044
16541
|
|
|
16045
16542
|
// ../runtime-core/package.json
|
|
16046
16543
|
var package_default = {
|
|
16047
|
-
version: "0.1.
|
|
16544
|
+
version: "0.1.2"};
|
|
16048
16545
|
|
|
16049
16546
|
// ../runtime-core/src/version.ts
|
|
16050
16547
|
var OPENSTEER_RUNTIME_CORE_VERSION = package_default.version;
|
|
@@ -16345,6 +16842,7 @@ var DefaultComputerUseRuntime = class {
|
|
|
16345
16842
|
const snapshot = await input.timeout.runStep(
|
|
16346
16843
|
() => captureActionBoundarySnapshot(this.options.engine, input.pageRef)
|
|
16347
16844
|
);
|
|
16845
|
+
let visualSettled = true;
|
|
16348
16846
|
const executed = await input.timeout.runStep(
|
|
16349
16847
|
() => bridge.execute({
|
|
16350
16848
|
pageRef: input.pageRef,
|
|
@@ -16353,16 +16851,35 @@ var DefaultComputerUseRuntime = class {
|
|
|
16353
16851
|
screenshot,
|
|
16354
16852
|
signal: input.timeout.signal,
|
|
16355
16853
|
remainingMs: () => input.timeout.remainingMs(),
|
|
16356
|
-
policySettle: async (pageRef, trigger) =>
|
|
16357
|
-
|
|
16358
|
-
|
|
16359
|
-
|
|
16360
|
-
|
|
16361
|
-
|
|
16362
|
-
|
|
16363
|
-
|
|
16854
|
+
policySettle: async (pageRef, trigger) => {
|
|
16855
|
+
try {
|
|
16856
|
+
await settleWithPolicy(this.options.policy.settle, {
|
|
16857
|
+
operation: "computer.execute",
|
|
16858
|
+
trigger,
|
|
16859
|
+
engine: this.options.engine,
|
|
16860
|
+
pageRef,
|
|
16861
|
+
signal: input.timeout.signal,
|
|
16862
|
+
remainingMs: input.timeout.remainingMs()
|
|
16863
|
+
});
|
|
16864
|
+
} catch (error) {
|
|
16865
|
+
if (pageRef === input.pageRef && isSoftSettleTimeoutError(error, input.timeout.signal)) {
|
|
16866
|
+
visualSettled = false;
|
|
16867
|
+
return;
|
|
16868
|
+
}
|
|
16869
|
+
throw error;
|
|
16870
|
+
}
|
|
16871
|
+
}
|
|
16364
16872
|
})
|
|
16365
16873
|
);
|
|
16874
|
+
if (executed.boundary !== void 0 && executed.pageRef === input.pageRef) {
|
|
16875
|
+
recordActionBoundaryDiagnostics(
|
|
16876
|
+
input.timeout.signal,
|
|
16877
|
+
createActionBoundaryDiagnostics({
|
|
16878
|
+
boundary: executed.boundary,
|
|
16879
|
+
visualSettled
|
|
16880
|
+
})
|
|
16881
|
+
);
|
|
16882
|
+
}
|
|
16366
16883
|
let trace = void 0;
|
|
16367
16884
|
if (!input.timeout.signal.aborted) {
|
|
16368
16885
|
try {
|
|
@@ -17372,7 +17889,7 @@ function diffStringMap(prefix, left, right, includeUnchanged, output) {
|
|
|
17372
17889
|
diffScalarField(`${prefix}.${key}`, left[key], right[key], includeUnchanged, output);
|
|
17373
17890
|
}
|
|
17374
17891
|
}
|
|
17375
|
-
function diffScalarField(
|
|
17892
|
+
function diffScalarField(path15, left, right, includeUnchanged, output) {
|
|
17376
17893
|
const leftValue = stringifyFieldValue(left);
|
|
17377
17894
|
const rightValue = stringifyFieldValue(right);
|
|
17378
17895
|
const kind = leftValue === void 0 ? rightValue === void 0 ? "unchanged" : "added" : rightValue === void 0 ? "removed" : leftValue === rightValue ? "unchanged" : "changed";
|
|
@@ -17380,7 +17897,7 @@ function diffScalarField(path13, left, right, includeUnchanged, output) {
|
|
|
17380
17897
|
return;
|
|
17381
17898
|
}
|
|
17382
17899
|
output.push({
|
|
17383
|
-
path:
|
|
17900
|
+
path: path15,
|
|
17384
17901
|
kind,
|
|
17385
17902
|
...leftValue === void 0 ? {} : { leftValue },
|
|
17386
17903
|
...rightValue === void 0 ? {} : { rightValue },
|
|
@@ -17474,7 +17991,7 @@ function resolveBodyEncoding(charset) {
|
|
|
17474
17991
|
var NetworkHistory = class {
|
|
17475
17992
|
metadataByRequestId = /* @__PURE__ */ new Map();
|
|
17476
17993
|
requestIdByRecordId = /* @__PURE__ */ new Map();
|
|
17477
|
-
|
|
17994
|
+
requestIdsByCapture = /* @__PURE__ */ new Map();
|
|
17478
17995
|
requestIdsByTag = /* @__PURE__ */ new Map();
|
|
17479
17996
|
tombstonedRequestIds = /* @__PURE__ */ new Set();
|
|
17480
17997
|
materialize(records, options = {}) {
|
|
@@ -17521,17 +18038,17 @@ var NetworkHistory = class {
|
|
|
17521
18038
|
}
|
|
17522
18039
|
return persisted;
|
|
17523
18040
|
}
|
|
17524
|
-
|
|
18041
|
+
assignCapture(records, capture) {
|
|
17525
18042
|
for (const record of records) {
|
|
17526
18043
|
const metadata = this.metadataByRequestId.get(record.record.requestId);
|
|
17527
|
-
if (!metadata || metadata.
|
|
18044
|
+
if (!metadata || metadata.capture === capture) {
|
|
17528
18045
|
continue;
|
|
17529
18046
|
}
|
|
17530
|
-
if (metadata.
|
|
17531
|
-
this.
|
|
18047
|
+
if (metadata.capture !== void 0) {
|
|
18048
|
+
this.requestIdsByCapture.get(metadata.capture)?.delete(record.record.requestId);
|
|
17532
18049
|
}
|
|
17533
|
-
metadata.
|
|
17534
|
-
this.addIndexedRequestId(this.
|
|
18050
|
+
metadata.capture = capture;
|
|
18051
|
+
this.addIndexedRequestId(this.requestIdsByCapture, capture, record.record.requestId);
|
|
17535
18052
|
}
|
|
17536
18053
|
}
|
|
17537
18054
|
addTag(records, tag) {
|
|
@@ -17551,8 +18068,8 @@ var NetworkHistory = class {
|
|
|
17551
18068
|
getRequestId(recordId) {
|
|
17552
18069
|
return this.requestIdByRecordId.get(recordId);
|
|
17553
18070
|
}
|
|
17554
|
-
|
|
17555
|
-
return new Set(this.
|
|
18071
|
+
getRequestIdsForCapture(capture) {
|
|
18072
|
+
return new Set(this.requestIdsByCapture.get(capture) ?? []);
|
|
17556
18073
|
}
|
|
17557
18074
|
getRequestIdsForTag(tag) {
|
|
17558
18075
|
return new Set(this.requestIdsByTag.get(tag) ?? []);
|
|
@@ -17563,20 +18080,6 @@ var NetworkHistory = class {
|
|
|
17563
18080
|
getKnownRequestIds() {
|
|
17564
18081
|
return new Set(this.metadataByRequestId.keys());
|
|
17565
18082
|
}
|
|
17566
|
-
clearTag(tag) {
|
|
17567
|
-
const requestIds = [...this.requestIdsByTag.get(tag) ?? []];
|
|
17568
|
-
this.requestIdsByTag.delete(tag);
|
|
17569
|
-
for (const requestId of requestIds) {
|
|
17570
|
-
const metadata = this.metadataByRequestId.get(requestId);
|
|
17571
|
-
if (!metadata) {
|
|
17572
|
-
continue;
|
|
17573
|
-
}
|
|
17574
|
-
metadata.tags.delete(tag);
|
|
17575
|
-
if (metadata.tags.size === 0) {
|
|
17576
|
-
this.tombstoneRequestIds([requestId]);
|
|
17577
|
-
}
|
|
17578
|
-
}
|
|
17579
|
-
}
|
|
17580
18083
|
tombstoneRequestIds(requestIds) {
|
|
17581
18084
|
for (const requestId of requestIds) {
|
|
17582
18085
|
this.tombstonedRequestIds.add(requestId);
|
|
@@ -17586,8 +18089,8 @@ var NetworkHistory = class {
|
|
|
17586
18089
|
}
|
|
17587
18090
|
this.metadataByRequestId.delete(requestId);
|
|
17588
18091
|
this.requestIdByRecordId.delete(metadata.recordId);
|
|
17589
|
-
if (metadata.
|
|
17590
|
-
this.
|
|
18092
|
+
if (metadata.capture !== void 0) {
|
|
18093
|
+
this.requestIdsByCapture.get(metadata.capture)?.delete(requestId);
|
|
17591
18094
|
}
|
|
17592
18095
|
for (const tag of metadata.tags) {
|
|
17593
18096
|
this.requestIdsByTag.get(tag)?.delete(requestId);
|
|
@@ -17597,7 +18100,7 @@ var NetworkHistory = class {
|
|
|
17597
18100
|
clear() {
|
|
17598
18101
|
this.metadataByRequestId.clear();
|
|
17599
18102
|
this.requestIdByRecordId.clear();
|
|
17600
|
-
this.
|
|
18103
|
+
this.requestIdsByCapture.clear();
|
|
17601
18104
|
this.requestIdsByTag.clear();
|
|
17602
18105
|
this.tombstonedRequestIds.clear();
|
|
17603
18106
|
}
|
|
@@ -17620,7 +18123,7 @@ var NetworkHistory = class {
|
|
|
17620
18123
|
}
|
|
17621
18124
|
return {
|
|
17622
18125
|
recordId: metadata.recordId,
|
|
17623
|
-
...metadata.
|
|
18126
|
+
...metadata.capture === void 0 ? {} : { capture: metadata.capture },
|
|
17624
18127
|
...metadata.tags.size === 0 ? {} : { tags: [...metadata.tags].sort() },
|
|
17625
18128
|
...metadata.savedAt === void 0 ? {} : { savedAt: metadata.savedAt },
|
|
17626
18129
|
record: toProtocolNetworkRecord(record, {
|
|
@@ -18400,9 +18903,9 @@ function matchReverseTargetHints(channel, codec, targetHints) {
|
|
|
18400
18903
|
matches.add(`host:${host}`);
|
|
18401
18904
|
}
|
|
18402
18905
|
}
|
|
18403
|
-
for (const
|
|
18404
|
-
if (url.pathname.includes(
|
|
18405
|
-
matches.add(`path:${
|
|
18906
|
+
for (const path15 of targetHints.paths ?? []) {
|
|
18907
|
+
if (url.pathname.includes(path15)) {
|
|
18908
|
+
matches.add(`path:${path15}`);
|
|
18406
18909
|
}
|
|
18407
18910
|
}
|
|
18408
18911
|
for (const operationName of targetHints.operationNames ?? []) {
|
|
@@ -19363,11 +19866,11 @@ function inferClusterRelationship(seed, record) {
|
|
|
19363
19866
|
var MATCHED_TLS_BINARY_NAMES = ["curl-impersonate-chrome", "curl_chrome"];
|
|
19364
19867
|
async function executeMatchedTlsTransportRequest(input) {
|
|
19365
19868
|
const binary = await resolveMatchedTlsBinary();
|
|
19366
|
-
const workingDirectory = await mkdtemp(
|
|
19367
|
-
const headersPath =
|
|
19368
|
-
const bodyPath =
|
|
19369
|
-
const cookiesPath =
|
|
19370
|
-
const requestBodyPath =
|
|
19869
|
+
const workingDirectory = await mkdtemp(path7.join(tmpdir(), "opensteer-matched-tls-"));
|
|
19870
|
+
const headersPath = path7.join(workingDirectory, "headers.txt");
|
|
19871
|
+
const bodyPath = path7.join(workingDirectory, "body.bin");
|
|
19872
|
+
const cookiesPath = path7.join(workingDirectory, "cookies.txt");
|
|
19873
|
+
const requestBodyPath = path7.join(workingDirectory, "request-body.bin");
|
|
19371
19874
|
try {
|
|
19372
19875
|
await writeFile(cookiesPath, toNetscapeCookieJar(input.cookies ?? []), "utf8");
|
|
19373
19876
|
if (input.request.body !== void 0) {
|
|
@@ -19424,10 +19927,10 @@ async function executeMatchedTlsTransportRequest(input) {
|
|
|
19424
19927
|
}
|
|
19425
19928
|
}
|
|
19426
19929
|
async function resolveMatchedTlsBinary() {
|
|
19427
|
-
const pathEntries = (process.env.PATH ?? "").split(
|
|
19930
|
+
const pathEntries = (process.env.PATH ?? "").split(path7.delimiter).filter((entry) => entry.length > 0);
|
|
19428
19931
|
for (const directory of pathEntries) {
|
|
19429
19932
|
for (const name of MATCHED_TLS_BINARY_NAMES) {
|
|
19430
|
-
const candidate =
|
|
19933
|
+
const candidate = path7.join(directory, name);
|
|
19431
19934
|
if (await isExecutable(candidate)) {
|
|
19432
19935
|
return candidate;
|
|
19433
19936
|
}
|
|
@@ -19435,7 +19938,7 @@ async function resolveMatchedTlsBinary() {
|
|
|
19435
19938
|
const files = await readDirSafe(directory);
|
|
19436
19939
|
const discovered = files.find((file) => file.startsWith("curl_chrome"));
|
|
19437
19940
|
if (discovered !== void 0) {
|
|
19438
|
-
const candidate =
|
|
19941
|
+
const candidate = path7.join(directory, discovered);
|
|
19439
19942
|
if (await isExecutable(candidate)) {
|
|
19440
19943
|
return candidate;
|
|
19441
19944
|
}
|
|
@@ -19446,7 +19949,7 @@ async function resolveMatchedTlsBinary() {
|
|
|
19446
19949
|
);
|
|
19447
19950
|
}
|
|
19448
19951
|
async function spawnAndCollect(command, args, signal) {
|
|
19449
|
-
return await new Promise((
|
|
19952
|
+
return await new Promise((resolve4, reject) => {
|
|
19450
19953
|
const child = spawn(command, args, {
|
|
19451
19954
|
stdio: ["ignore", "pipe", "pipe"]
|
|
19452
19955
|
});
|
|
@@ -19479,7 +19982,7 @@ async function spawnAndCollect(command, args, signal) {
|
|
|
19479
19982
|
);
|
|
19480
19983
|
return;
|
|
19481
19984
|
}
|
|
19482
|
-
|
|
19985
|
+
resolve4({ stdout, stderr });
|
|
19483
19986
|
});
|
|
19484
19987
|
});
|
|
19485
19988
|
}
|
|
@@ -22141,8 +22644,8 @@ function readString(value) {
|
|
|
22141
22644
|
return typeof value === "string" && value.length > 0 ? value : void 0;
|
|
22142
22645
|
}
|
|
22143
22646
|
function sleep2(ms, signal) {
|
|
22144
|
-
return new Promise((
|
|
22145
|
-
const timeout = setTimeout(
|
|
22647
|
+
return new Promise((resolve4, reject) => {
|
|
22648
|
+
const timeout = setTimeout(resolve4, ms);
|
|
22146
22649
|
const abort = () => {
|
|
22147
22650
|
clearTimeout(timeout);
|
|
22148
22651
|
reject(new Error("captcha solve aborted"));
|
|
@@ -22239,8 +22742,8 @@ function readString2(value) {
|
|
|
22239
22742
|
return typeof value === "string" && value.length > 0 ? value : void 0;
|
|
22240
22743
|
}
|
|
22241
22744
|
function sleep3(ms, signal) {
|
|
22242
|
-
return new Promise((
|
|
22243
|
-
const timeout = setTimeout(
|
|
22745
|
+
return new Promise((resolve4, reject) => {
|
|
22746
|
+
const timeout = setTimeout(resolve4, ms);
|
|
22244
22747
|
const abort = () => {
|
|
22245
22748
|
clearTimeout(timeout);
|
|
22246
22749
|
reject(new Error("captcha solve aborted"));
|
|
@@ -22438,6 +22941,9 @@ function diffInteractionTraces(left, right) {
|
|
|
22438
22941
|
|
|
22439
22942
|
// ../runtime-core/src/sdk/runtime.ts
|
|
22440
22943
|
var requireForAuthRecipeHook = createRequire(import.meta.url);
|
|
22944
|
+
var MUTATION_CAPTURE_FINALIZE_TIMEOUT_MS = 5e3;
|
|
22945
|
+
var PENDING_OPERATION_EVENT_CAPTURE_LIMIT = 64;
|
|
22946
|
+
var PENDING_OPERATION_EVENT_CAPTURE_SKEW_MS = 1e3;
|
|
22441
22947
|
var OpensteerSessionRuntime = class {
|
|
22442
22948
|
workspace;
|
|
22443
22949
|
rootPath;
|
|
@@ -22450,6 +22956,9 @@ var OpensteerSessionRuntime = class {
|
|
|
22450
22956
|
registryOverrides;
|
|
22451
22957
|
cleanupRootOnClose;
|
|
22452
22958
|
sessionInfoBase;
|
|
22959
|
+
observationConfig;
|
|
22960
|
+
observationSessionId;
|
|
22961
|
+
injectedObservationSink;
|
|
22453
22962
|
root;
|
|
22454
22963
|
engine;
|
|
22455
22964
|
dom;
|
|
@@ -22459,6 +22968,9 @@ var OpensteerSessionRuntime = class {
|
|
|
22459
22968
|
sessionRef;
|
|
22460
22969
|
pageRef;
|
|
22461
22970
|
runId;
|
|
22971
|
+
observations;
|
|
22972
|
+
operationEventStorage = new AsyncLocalStorage();
|
|
22973
|
+
pendingOperationEventCaptures = [];
|
|
22462
22974
|
cookieJars = /* @__PURE__ */ new Map();
|
|
22463
22975
|
recipeCache = /* @__PURE__ */ new Map();
|
|
22464
22976
|
ownsEngine = false;
|
|
@@ -22466,7 +22978,7 @@ var OpensteerSessionRuntime = class {
|
|
|
22466
22978
|
this.workspace = normalizeNamespace2(options.name);
|
|
22467
22979
|
this.workspaceName = options.workspaceName?.trim() === void 0 || options.workspaceName?.trim().length === 0 ? void 0 : options.workspaceName.trim();
|
|
22468
22980
|
this.root = options.workspace;
|
|
22469
|
-
this.rootPath = options.workspace?.rootPath ?? options.rootPath ??
|
|
22981
|
+
this.rootPath = options.workspace?.rootPath ?? options.rootPath ?? path7.resolve(process.cwd(), ".opensteer", "temporary", randomUUID());
|
|
22470
22982
|
this.injectedEngine = options.engine;
|
|
22471
22983
|
this.engineFactory = options.engineFactory;
|
|
22472
22984
|
this.policy = options.policy ?? defaultPolicy();
|
|
@@ -22475,6 +22987,9 @@ var OpensteerSessionRuntime = class {
|
|
|
22475
22987
|
this.registryOverrides = options.registryOverrides;
|
|
22476
22988
|
this.cleanupRootOnClose = options.cleanupRootOnClose ?? options.workspace === void 0;
|
|
22477
22989
|
this.sessionInfoBase = options.sessionInfo ?? {};
|
|
22990
|
+
this.observationConfig = normalizeObservabilityConfig(options.observability);
|
|
22991
|
+
this.observationSessionId = options.observationSessionId;
|
|
22992
|
+
this.injectedObservationSink = options.observationSink;
|
|
22478
22993
|
if (this.injectedEngine === void 0 && this.engineFactory === void 0) {
|
|
22479
22994
|
throw new Error("OpensteerSessionRuntime requires an engine or engineFactory.");
|
|
22480
22995
|
}
|
|
@@ -22506,6 +23021,20 @@ var OpensteerSessionRuntime = class {
|
|
|
22506
23021
|
}
|
|
22507
23022
|
};
|
|
22508
23023
|
}
|
|
23024
|
+
async setObservabilityConfig(input) {
|
|
23025
|
+
this.observationConfig = normalizeObservabilityConfig(input);
|
|
23026
|
+
const observationSessionId = this.resolveObservationSessionId();
|
|
23027
|
+
if (observationSessionId === void 0) {
|
|
23028
|
+
return this.observationConfig;
|
|
23029
|
+
}
|
|
23030
|
+
const sink = this.injectedObservationSink ?? (await this.ensureRoot()).observations;
|
|
23031
|
+
this.observations = await sink.openSession({
|
|
23032
|
+
sessionId: observationSessionId,
|
|
23033
|
+
openedAt: Date.now(),
|
|
23034
|
+
config: this.observationConfig
|
|
23035
|
+
});
|
|
23036
|
+
return this.observationConfig;
|
|
23037
|
+
}
|
|
22509
23038
|
async open(input = {}, options = {}) {
|
|
22510
23039
|
assertValidSemanticOperationInput("session.open", input);
|
|
22511
23040
|
if (input.workspace !== void 0 && normalizeNamespace2(input.workspace) !== this.workspace) {
|
|
@@ -22604,6 +23133,10 @@ var OpensteerSessionRuntime = class {
|
|
|
22604
23133
|
return { pages: [] };
|
|
22605
23134
|
}
|
|
22606
23135
|
const startedAt = Date.now();
|
|
23136
|
+
const context = buildRuntimeTraceContext({
|
|
23137
|
+
sessionRef: this.sessionRef,
|
|
23138
|
+
pageRef: this.pageRef
|
|
23139
|
+
});
|
|
22607
23140
|
try {
|
|
22608
23141
|
const output = await this.runWithOperationTimeout(
|
|
22609
23142
|
"page.list",
|
|
@@ -22618,19 +23151,18 @@ var OpensteerSessionRuntime = class {
|
|
|
22618
23151
|
},
|
|
22619
23152
|
options
|
|
22620
23153
|
);
|
|
23154
|
+
const events = await this.drainPendingEngineEvents(context);
|
|
22621
23155
|
await this.appendTrace({
|
|
22622
23156
|
operation: "page.list",
|
|
22623
23157
|
startedAt,
|
|
22624
23158
|
completedAt: Date.now(),
|
|
22625
23159
|
outcome: "ok",
|
|
23160
|
+
...events === void 0 ? {} : { events },
|
|
22626
23161
|
data: {
|
|
22627
23162
|
count: output.pages.length,
|
|
22628
23163
|
...output.activePageRef === void 0 ? {} : { activePageRef: output.activePageRef }
|
|
22629
23164
|
},
|
|
22630
|
-
context
|
|
22631
|
-
sessionRef: this.sessionRef,
|
|
22632
|
-
pageRef: this.pageRef
|
|
22633
|
-
})
|
|
23165
|
+
context
|
|
22634
23166
|
});
|
|
22635
23167
|
return output;
|
|
22636
23168
|
} catch (error) {
|
|
@@ -22640,10 +23172,7 @@ var OpensteerSessionRuntime = class {
|
|
|
22640
23172
|
completedAt: Date.now(),
|
|
22641
23173
|
outcome: "error",
|
|
22642
23174
|
error,
|
|
22643
|
-
context
|
|
22644
|
-
sessionRef: this.sessionRef,
|
|
22645
|
-
pageRef: this.pageRef
|
|
22646
|
-
})
|
|
23175
|
+
context
|
|
22647
23176
|
});
|
|
22648
23177
|
throw error;
|
|
22649
23178
|
}
|
|
@@ -22820,34 +23349,32 @@ var OpensteerSessionRuntime = class {
|
|
|
22820
23349
|
assertValidSemanticOperationInput("page.goto", input);
|
|
22821
23350
|
const pageRef = await this.ensurePageRef();
|
|
22822
23351
|
const startedAt = Date.now();
|
|
23352
|
+
let mutationCaptureDiagnostics;
|
|
22823
23353
|
try {
|
|
22824
|
-
const { navigation, state } = await this.
|
|
23354
|
+
const { navigation, state } = await this.runMutationCapturedOperation(
|
|
22825
23355
|
"page.goto",
|
|
23356
|
+
{
|
|
23357
|
+
...input.captureNetwork === void 0 ? {} : { captureNetwork: input.captureNetwork },
|
|
23358
|
+
options
|
|
23359
|
+
},
|
|
22826
23360
|
async (timeout) => {
|
|
22827
|
-
const
|
|
22828
|
-
|
|
22829
|
-
|
|
22830
|
-
|
|
22831
|
-
|
|
22832
|
-
|
|
22833
|
-
|
|
22834
|
-
|
|
22835
|
-
|
|
22836
|
-
|
|
22837
|
-
|
|
22838
|
-
await
|
|
22839
|
-
|
|
22840
|
-
navigation: navigation2,
|
|
22841
|
-
state: await timeout.runStep(() => this.readSessionState())
|
|
22842
|
-
};
|
|
22843
|
-
} catch (error) {
|
|
22844
|
-
await this.completeMutationCapture(timeout, baselineRequestIds, input.networkTag).catch(
|
|
22845
|
-
() => void 0
|
|
22846
|
-
);
|
|
22847
|
-
throw error;
|
|
22848
|
-
}
|
|
23361
|
+
const navigation2 = await this.navigatePage(
|
|
23362
|
+
{
|
|
23363
|
+
operation: "page.goto",
|
|
23364
|
+
pageRef,
|
|
23365
|
+
url: input.url
|
|
23366
|
+
},
|
|
23367
|
+
timeout
|
|
23368
|
+
);
|
|
23369
|
+
timeout.throwIfAborted();
|
|
23370
|
+
return {
|
|
23371
|
+
navigation: navigation2,
|
|
23372
|
+
state: await timeout.runStep(() => this.readSessionState())
|
|
23373
|
+
};
|
|
22849
23374
|
},
|
|
22850
|
-
|
|
23375
|
+
(diagnostics) => {
|
|
23376
|
+
mutationCaptureDiagnostics = diagnostics;
|
|
23377
|
+
}
|
|
22851
23378
|
);
|
|
22852
23379
|
await this.appendTrace({
|
|
22853
23380
|
operation: "page.goto",
|
|
@@ -22856,7 +23383,8 @@ var OpensteerSessionRuntime = class {
|
|
|
22856
23383
|
outcome: "ok",
|
|
22857
23384
|
data: {
|
|
22858
23385
|
url: input.url,
|
|
22859
|
-
state
|
|
23386
|
+
state,
|
|
23387
|
+
...buildMutationCaptureTraceData(mutationCaptureDiagnostics)
|
|
22860
23388
|
},
|
|
22861
23389
|
context: buildRuntimeTraceContext({
|
|
22862
23390
|
sessionRef: this.sessionRef,
|
|
@@ -22872,6 +23400,7 @@ var OpensteerSessionRuntime = class {
|
|
|
22872
23400
|
completedAt: Date.now(),
|
|
22873
23401
|
outcome: "error",
|
|
22874
23402
|
error,
|
|
23403
|
+
data: buildMutationCaptureTraceData(mutationCaptureDiagnostics),
|
|
22875
23404
|
context: buildRuntimeTraceContext({
|
|
22876
23405
|
sessionRef: this.sessionRef,
|
|
22877
23406
|
pageRef
|
|
@@ -22884,34 +23413,29 @@ var OpensteerSessionRuntime = class {
|
|
|
22884
23413
|
assertValidSemanticOperationInput("page.evaluate", input);
|
|
22885
23414
|
const pageRef = input.pageRef ?? await this.ensurePageRef();
|
|
22886
23415
|
const startedAt = Date.now();
|
|
23416
|
+
let mutationCaptureDiagnostics;
|
|
22887
23417
|
try {
|
|
22888
|
-
const output = await this.
|
|
23418
|
+
const output = await this.runMutationCapturedOperation(
|
|
22889
23419
|
"page.evaluate",
|
|
23420
|
+
{ options },
|
|
22890
23421
|
async (timeout) => {
|
|
22891
|
-
const
|
|
22892
|
-
|
|
22893
|
-
|
|
22894
|
-
const evaluated = await timeout.runStep(
|
|
22895
|
-
() => this.requireEngine().evaluatePage({
|
|
22896
|
-
pageRef,
|
|
22897
|
-
script: input.script,
|
|
22898
|
-
...input.args === void 0 ? {} : { args: input.args },
|
|
22899
|
-
...remainingMs === void 0 ? {} : { timeoutMs: remainingMs }
|
|
22900
|
-
})
|
|
22901
|
-
);
|
|
22902
|
-
await this.completeMutationCapture(timeout, baselineRequestIds, void 0);
|
|
22903
|
-
return {
|
|
23422
|
+
const remainingMs = timeout.remainingMs();
|
|
23423
|
+
const evaluated = await timeout.runStep(
|
|
23424
|
+
() => this.requireEngine().evaluatePage({
|
|
22904
23425
|
pageRef,
|
|
22905
|
-
|
|
22906
|
-
|
|
22907
|
-
|
|
22908
|
-
|
|
22909
|
-
|
|
22910
|
-
|
|
22911
|
-
|
|
22912
|
-
|
|
23426
|
+
script: input.script,
|
|
23427
|
+
...input.args === void 0 ? {} : { args: input.args },
|
|
23428
|
+
...remainingMs === void 0 ? {} : { timeoutMs: remainingMs }
|
|
23429
|
+
})
|
|
23430
|
+
);
|
|
23431
|
+
return {
|
|
23432
|
+
pageRef,
|
|
23433
|
+
value: toJsonValueOrNull(evaluated.data)
|
|
23434
|
+
};
|
|
22913
23435
|
},
|
|
22914
|
-
|
|
23436
|
+
(diagnostics) => {
|
|
23437
|
+
mutationCaptureDiagnostics = diagnostics;
|
|
23438
|
+
}
|
|
22915
23439
|
);
|
|
22916
23440
|
await this.appendTrace({
|
|
22917
23441
|
operation: "page.evaluate",
|
|
@@ -22920,7 +23444,8 @@ var OpensteerSessionRuntime = class {
|
|
|
22920
23444
|
outcome: "ok",
|
|
22921
23445
|
data: {
|
|
22922
23446
|
pageRef: output.pageRef,
|
|
22923
|
-
value: output.value
|
|
23447
|
+
value: output.value,
|
|
23448
|
+
...buildMutationCaptureTraceData(mutationCaptureDiagnostics)
|
|
22924
23449
|
},
|
|
22925
23450
|
context: buildRuntimeTraceContext({
|
|
22926
23451
|
sessionRef: this.sessionRef,
|
|
@@ -22935,6 +23460,7 @@ var OpensteerSessionRuntime = class {
|
|
|
22935
23460
|
completedAt: Date.now(),
|
|
22936
23461
|
outcome: "error",
|
|
22937
23462
|
error,
|
|
23463
|
+
data: buildMutationCaptureTraceData(mutationCaptureDiagnostics),
|
|
22938
23464
|
context: buildRuntimeTraceContext({
|
|
22939
23465
|
sessionRef: this.sessionRef,
|
|
22940
23466
|
pageRef
|
|
@@ -23034,22 +23560,25 @@ var OpensteerSessionRuntime = class {
|
|
|
23034
23560
|
},
|
|
23035
23561
|
options
|
|
23036
23562
|
);
|
|
23563
|
+
const context = buildRuntimeTraceContext({
|
|
23564
|
+
sessionRef: this.sessionRef,
|
|
23565
|
+
pageRef
|
|
23566
|
+
});
|
|
23567
|
+
const events = await this.drainPendingEngineEvents(context);
|
|
23037
23568
|
await this.appendTrace({
|
|
23038
23569
|
operation: "page.snapshot",
|
|
23039
23570
|
startedAt,
|
|
23040
23571
|
completedAt: Date.now(),
|
|
23041
23572
|
outcome: "ok",
|
|
23042
23573
|
artifacts,
|
|
23574
|
+
...events === void 0 ? {} : { events },
|
|
23043
23575
|
data: {
|
|
23044
23576
|
mode,
|
|
23045
23577
|
url: output.url,
|
|
23046
23578
|
title: output.title,
|
|
23047
23579
|
counterCount: output.counters.length
|
|
23048
23580
|
},
|
|
23049
|
-
context
|
|
23050
|
-
sessionRef: this.sessionRef,
|
|
23051
|
-
pageRef
|
|
23052
|
-
})
|
|
23581
|
+
context
|
|
23053
23582
|
});
|
|
23054
23583
|
return output;
|
|
23055
23584
|
} catch (error) {
|
|
@@ -23374,17 +23903,29 @@ var OpensteerSessionRuntime = class {
|
|
|
23374
23903
|
"network.clear",
|
|
23375
23904
|
async (timeout) => {
|
|
23376
23905
|
if (this.sessionRef !== void 0) {
|
|
23377
|
-
|
|
23378
|
-
|
|
23379
|
-
|
|
23380
|
-
|
|
23906
|
+
if (input.capture !== void 0 || input.tag !== void 0) {
|
|
23907
|
+
const records = await this.queryLiveNetwork(
|
|
23908
|
+
{
|
|
23909
|
+
...input.capture === void 0 ? {} : { capture: input.capture },
|
|
23910
|
+
...input.tag === void 0 ? {} : { tag: input.tag }
|
|
23911
|
+
},
|
|
23912
|
+
timeout,
|
|
23913
|
+
{
|
|
23914
|
+
ignoreLimit: true
|
|
23915
|
+
}
|
|
23916
|
+
);
|
|
23917
|
+
this.networkHistory.tombstoneRequestIds(
|
|
23918
|
+
records.map((record) => record.record.requestId)
|
|
23919
|
+
);
|
|
23920
|
+
} else {
|
|
23921
|
+
const liveRequestIds = await this.readLiveRequestIds(timeout, {
|
|
23922
|
+
includeCurrentPageOnly: false
|
|
23923
|
+
});
|
|
23381
23924
|
this.networkHistory.tombstoneRequestIds(liveRequestIds);
|
|
23382
23925
|
}
|
|
23383
23926
|
}
|
|
23384
|
-
if (input.tag === void 0) {
|
|
23927
|
+
if (input.capture === void 0 && input.tag === void 0) {
|
|
23385
23928
|
this.networkHistory.tombstoneRequestIds(this.networkHistory.getKnownRequestIds());
|
|
23386
|
-
} else {
|
|
23387
|
-
this.networkHistory.clearTag(input.tag);
|
|
23388
23929
|
}
|
|
23389
23930
|
return {
|
|
23390
23931
|
clearedCount: await timeout.runStep(() => root.registry.savedNetwork.clear(input))
|
|
@@ -23398,6 +23939,7 @@ var OpensteerSessionRuntime = class {
|
|
|
23398
23939
|
completedAt: Date.now(),
|
|
23399
23940
|
outcome: "ok",
|
|
23400
23941
|
data: {
|
|
23942
|
+
...input.capture === void 0 ? {} : { capture: input.capture },
|
|
23401
23943
|
...input.tag === void 0 ? {} : { tag: input.tag },
|
|
23402
23944
|
clearedCount: output.clearedCount
|
|
23403
23945
|
}
|
|
@@ -24579,7 +25121,9 @@ var OpensteerSessionRuntime = class {
|
|
|
24579
25121
|
};
|
|
24580
25122
|
}
|
|
24581
25123
|
const bindings = /* @__PURE__ */ new Map();
|
|
24582
|
-
const baselineRequestIds = await this.
|
|
25124
|
+
const baselineRequestIds = await this.readLiveRequestIds(timeout, {
|
|
25125
|
+
includeCurrentPageOnly: true
|
|
25126
|
+
});
|
|
24583
25127
|
const pageRef = explicitPageRef ?? await this.ensurePageRef();
|
|
24584
25128
|
const validatorMap = new Map(
|
|
24585
25129
|
packageRecord.payload.validators.map((validator) => [validator.id, validator])
|
|
@@ -26251,33 +26795,38 @@ var OpensteerSessionRuntime = class {
|
|
|
26251
26795
|
assertValidSemanticOperationInput("computer.execute", input);
|
|
26252
26796
|
const pageRef = await this.ensurePageRef();
|
|
26253
26797
|
const startedAt = Date.now();
|
|
26798
|
+
let mutationCaptureDiagnostics;
|
|
26799
|
+
let boundaryDiagnostics;
|
|
26254
26800
|
try {
|
|
26255
|
-
const { artifacts, output } = await this.
|
|
26801
|
+
const { artifacts, output } = await this.runMutationCapturedOperation(
|
|
26256
26802
|
"computer.execute",
|
|
26803
|
+
{
|
|
26804
|
+
...input.captureNetwork === void 0 ? {} : { captureNetwork: input.captureNetwork },
|
|
26805
|
+
options
|
|
26806
|
+
},
|
|
26257
26807
|
async (timeout) => {
|
|
26258
|
-
const baselineRequestIds = await this.beginMutationCapture(timeout);
|
|
26259
26808
|
try {
|
|
26260
26809
|
const output2 = await this.requireComputer().execute({
|
|
26261
26810
|
pageRef,
|
|
26262
26811
|
input,
|
|
26263
26812
|
timeout
|
|
26264
26813
|
});
|
|
26814
|
+
boundaryDiagnostics = takeActionBoundaryDiagnostics(timeout.signal);
|
|
26265
26815
|
timeout.throwIfAborted();
|
|
26266
26816
|
this.pageRef = output2.pageRef;
|
|
26267
|
-
await this.completeMutationCapture(timeout, baselineRequestIds, input.networkTag);
|
|
26268
26817
|
const artifacts2 = await this.persistComputerArtifacts(output2, timeout);
|
|
26269
26818
|
return {
|
|
26270
26819
|
artifacts: { manifests: artifacts2.manifests },
|
|
26271
26820
|
output: artifacts2.output
|
|
26272
26821
|
};
|
|
26273
26822
|
} catch (error) {
|
|
26274
|
-
|
|
26275
|
-
() => void 0
|
|
26276
|
-
);
|
|
26823
|
+
boundaryDiagnostics ??= takeActionBoundaryDiagnostics(timeout.signal);
|
|
26277
26824
|
throw error;
|
|
26278
26825
|
}
|
|
26279
26826
|
},
|
|
26280
|
-
|
|
26827
|
+
(diagnostics) => {
|
|
26828
|
+
mutationCaptureDiagnostics = diagnostics;
|
|
26829
|
+
}
|
|
26281
26830
|
);
|
|
26282
26831
|
await this.appendTrace({
|
|
26283
26832
|
operation: "computer.execute",
|
|
@@ -26293,6 +26842,8 @@ var OpensteerSessionRuntime = class {
|
|
|
26293
26842
|
nativeViewport: output.nativeViewport,
|
|
26294
26843
|
displayScale: output.displayScale,
|
|
26295
26844
|
timing: output.timing,
|
|
26845
|
+
...boundaryDiagnostics === void 0 ? {} : { settle: boundaryDiagnostics },
|
|
26846
|
+
...buildMutationCaptureTraceData(mutationCaptureDiagnostics),
|
|
26296
26847
|
...output.trace === void 0 ? {} : { trace: output.trace }
|
|
26297
26848
|
},
|
|
26298
26849
|
context: buildRuntimeTraceContext({
|
|
@@ -26311,6 +26862,10 @@ var OpensteerSessionRuntime = class {
|
|
|
26311
26862
|
completedAt: Date.now(),
|
|
26312
26863
|
outcome: "error",
|
|
26313
26864
|
error,
|
|
26865
|
+
data: {
|
|
26866
|
+
...boundaryDiagnostics === void 0 ? {} : { settle: boundaryDiagnostics },
|
|
26867
|
+
...buildMutationCaptureTraceData(mutationCaptureDiagnostics)
|
|
26868
|
+
},
|
|
26314
26869
|
context: buildRuntimeTraceContext({
|
|
26315
26870
|
sessionRef: this.sessionRef,
|
|
26316
26871
|
pageRef: this.pageRef
|
|
@@ -26414,44 +26969,53 @@ var OpensteerSessionRuntime = class {
|
|
|
26414
26969
|
async runDomAction(operation, input, executor, options = {}) {
|
|
26415
26970
|
const pageRef = await this.ensurePageRef();
|
|
26416
26971
|
const startedAt = Date.now();
|
|
26972
|
+
let mutationCaptureDiagnostics;
|
|
26973
|
+
let boundaryDiagnostics;
|
|
26417
26974
|
try {
|
|
26418
|
-
const { executed, preparedTarget } = await this.
|
|
26975
|
+
const { executed, preparedTarget } = await this.runMutationCapturedOperation(
|
|
26419
26976
|
operation,
|
|
26977
|
+
{
|
|
26978
|
+
...input.captureNetwork === void 0 ? {} : { captureNetwork: input.captureNetwork },
|
|
26979
|
+
options
|
|
26980
|
+
},
|
|
26420
26981
|
async (timeout) => {
|
|
26421
|
-
const
|
|
26982
|
+
const preparedTarget2 = await this.prepareDomTarget(
|
|
26983
|
+
pageRef,
|
|
26984
|
+
operation,
|
|
26985
|
+
input.target,
|
|
26986
|
+
input.persistAsDescription,
|
|
26987
|
+
timeout
|
|
26988
|
+
);
|
|
26422
26989
|
try {
|
|
26423
|
-
const preparedTarget2 = await this.prepareDomTarget(
|
|
26424
|
-
pageRef,
|
|
26425
|
-
operation,
|
|
26426
|
-
input.target,
|
|
26427
|
-
input.persistAsDescription,
|
|
26428
|
-
timeout
|
|
26429
|
-
);
|
|
26430
26990
|
const executed2 = await executor(pageRef, preparedTarget2.target, timeout);
|
|
26431
|
-
|
|
26991
|
+
boundaryDiagnostics = takeActionBoundaryDiagnostics(timeout.signal);
|
|
26432
26992
|
return {
|
|
26433
26993
|
executed: executed2,
|
|
26434
26994
|
preparedTarget: preparedTarget2
|
|
26435
26995
|
};
|
|
26436
26996
|
} catch (error) {
|
|
26437
|
-
|
|
26438
|
-
() => void 0
|
|
26439
|
-
);
|
|
26997
|
+
boundaryDiagnostics ??= takeActionBoundaryDiagnostics(timeout.signal);
|
|
26440
26998
|
throw error;
|
|
26441
26999
|
}
|
|
26442
27000
|
},
|
|
26443
|
-
|
|
27001
|
+
(diagnostics) => {
|
|
27002
|
+
mutationCaptureDiagnostics = diagnostics;
|
|
27003
|
+
}
|
|
26444
27004
|
);
|
|
26445
27005
|
const output = toOpensteerActionResult(executed.result, preparedTarget.persistedDescription);
|
|
27006
|
+
const actionEvents = "events" in executed.result ? executed.result.events : void 0;
|
|
26446
27007
|
await this.appendTrace({
|
|
26447
27008
|
operation,
|
|
26448
27009
|
startedAt,
|
|
26449
27010
|
completedAt: Date.now(),
|
|
26450
27011
|
outcome: "ok",
|
|
27012
|
+
...actionEvents === void 0 ? {} : { events: actionEvents },
|
|
26451
27013
|
data: {
|
|
26452
27014
|
target: output.target,
|
|
26453
27015
|
...output.point === void 0 ? {} : { point: output.point },
|
|
26454
|
-
...output.persistedDescription === void 0 ? {} : { persistedDescription: output.persistedDescription }
|
|
27016
|
+
...output.persistedDescription === void 0 ? {} : { persistedDescription: output.persistedDescription },
|
|
27017
|
+
...boundaryDiagnostics === void 0 ? {} : { settle: boundaryDiagnostics },
|
|
27018
|
+
...buildMutationCaptureTraceData(mutationCaptureDiagnostics)
|
|
26455
27019
|
},
|
|
26456
27020
|
context: buildRuntimeTraceContext({
|
|
26457
27021
|
sessionRef: this.sessionRef,
|
|
@@ -26469,6 +27033,10 @@ var OpensteerSessionRuntime = class {
|
|
|
26469
27033
|
completedAt: Date.now(),
|
|
26470
27034
|
outcome: "error",
|
|
26471
27035
|
error,
|
|
27036
|
+
data: {
|
|
27037
|
+
...boundaryDiagnostics === void 0 ? {} : { settle: boundaryDiagnostics },
|
|
27038
|
+
...buildMutationCaptureTraceData(mutationCaptureDiagnostics)
|
|
27039
|
+
},
|
|
26472
27040
|
context: buildRuntimeTraceContext({
|
|
26473
27041
|
sessionRef: this.sessionRef,
|
|
26474
27042
|
pageRef
|
|
@@ -26578,7 +27146,7 @@ var OpensteerSessionRuntime = class {
|
|
|
26578
27146
|
const filtered = filterNetworkQueryRecords(metadataRecords, {
|
|
26579
27147
|
...input.recordId === void 0 ? {} : { recordId: input.recordId },
|
|
26580
27148
|
...input.requestId === void 0 ? {} : { requestId: input.requestId },
|
|
26581
|
-
...input.
|
|
27149
|
+
...input.capture === void 0 ? {} : { capture: input.capture },
|
|
26582
27150
|
...input.tag === void 0 ? {} : { tag: input.tag },
|
|
26583
27151
|
...input.url === void 0 ? {} : { url: input.url },
|
|
26584
27152
|
...input.hostname === void 0 ? {} : { hostname: input.hostname },
|
|
@@ -26784,32 +27352,68 @@ var OpensteerSessionRuntime = class {
|
|
|
26784
27352
|
artifactId: manifest.artifactId
|
|
26785
27353
|
};
|
|
26786
27354
|
}
|
|
26787
|
-
|
|
26788
|
-
|
|
26789
|
-
|
|
26790
|
-
|
|
26791
|
-
|
|
26792
|
-
|
|
26793
|
-
|
|
26794
|
-
|
|
26795
|
-
{
|
|
26796
|
-
includeBodies: false,
|
|
26797
|
-
includeCurrentPageOnly: true
|
|
27355
|
+
async runMutationCapturedOperation(operation, input, execute, onFinalized) {
|
|
27356
|
+
let plan;
|
|
27357
|
+
try {
|
|
27358
|
+
const result = await this.runWithOperationTimeout(
|
|
27359
|
+
operation,
|
|
27360
|
+
async (timeout) => {
|
|
27361
|
+
plan = await this.beginMutationCapture(timeout, input.captureNetwork);
|
|
27362
|
+
return execute(timeout);
|
|
26798
27363
|
},
|
|
26799
|
-
|
|
26800
|
-
)
|
|
27364
|
+
input.options
|
|
27365
|
+
);
|
|
27366
|
+
const diagnostics = await this.finalizeMutationCaptureBestEffort(plan);
|
|
27367
|
+
onFinalized?.(diagnostics);
|
|
27368
|
+
return result;
|
|
27369
|
+
} catch (error) {
|
|
27370
|
+
const diagnostics = await this.finalizeMutationCaptureBestEffort(plan);
|
|
27371
|
+
onFinalized?.(diagnostics);
|
|
27372
|
+
throw error;
|
|
27373
|
+
}
|
|
27374
|
+
}
|
|
27375
|
+
async beginMutationCapture(timeout, capture) {
|
|
27376
|
+
if (capture === void 0) {
|
|
27377
|
+
return void 0;
|
|
27378
|
+
}
|
|
27379
|
+
return {
|
|
27380
|
+
baselineRequestIds: await this.readLiveRequestIds(timeout, {
|
|
27381
|
+
includeCurrentPageOnly: true
|
|
27382
|
+
}),
|
|
27383
|
+
capture
|
|
27384
|
+
};
|
|
27385
|
+
}
|
|
27386
|
+
async finalizeMutationCaptureBestEffort(plan) {
|
|
27387
|
+
if (plan === void 0) {
|
|
27388
|
+
return {};
|
|
27389
|
+
}
|
|
27390
|
+
try {
|
|
27391
|
+
await withDetachedTimeoutSignal(MUTATION_CAPTURE_FINALIZE_TIMEOUT_MS, async (signal) => {
|
|
27392
|
+
await this.completeMutationCaptureWithSignal(signal, plan);
|
|
27393
|
+
});
|
|
27394
|
+
return {};
|
|
27395
|
+
} catch (error) {
|
|
27396
|
+
return {
|
|
27397
|
+
finalizeError: normalizeOpensteerError(error)
|
|
27398
|
+
};
|
|
27399
|
+
}
|
|
27400
|
+
}
|
|
27401
|
+
async completeMutationCaptureWithSignal(signal, plan) {
|
|
27402
|
+
const records = await this.readLiveNetworkRecords(
|
|
27403
|
+
{
|
|
27404
|
+
includeBodies: false,
|
|
27405
|
+
includeCurrentPageOnly: true
|
|
27406
|
+
},
|
|
27407
|
+
signal
|
|
26801
27408
|
);
|
|
26802
|
-
const delta = records.filter((record) => !baselineRequestIds.has(record.record.requestId));
|
|
27409
|
+
const delta = records.filter((record) => !plan.baselineRequestIds.has(record.record.requestId));
|
|
26803
27410
|
if (delta.length === 0) {
|
|
26804
27411
|
return;
|
|
26805
27412
|
}
|
|
26806
|
-
this.networkHistory.
|
|
26807
|
-
|
|
26808
|
-
this.networkHistory.addTag(delta, networkTag);
|
|
26809
|
-
}
|
|
26810
|
-
await this.persistLiveRequestIds(
|
|
27413
|
+
this.networkHistory.assignCapture(delta, plan.capture);
|
|
27414
|
+
await this.persistLiveRequestIdsWithSignal(
|
|
26811
27415
|
delta.map((record) => record.record.requestId),
|
|
26812
|
-
|
|
27416
|
+
signal,
|
|
26813
27417
|
{
|
|
26814
27418
|
includeCurrentPageOnly: true
|
|
26815
27419
|
}
|
|
@@ -27216,27 +27820,28 @@ var OpensteerSessionRuntime = class {
|
|
|
27216
27820
|
});
|
|
27217
27821
|
}
|
|
27218
27822
|
async persistLiveRequestIds(requestIds, timeout, options) {
|
|
27823
|
+
return timeout.runStep(
|
|
27824
|
+
() => this.persistLiveRequestIdsWithSignal(requestIds, timeout.signal, options)
|
|
27825
|
+
);
|
|
27826
|
+
}
|
|
27827
|
+
async persistLiveRequestIdsWithSignal(requestIds, signal, options) {
|
|
27219
27828
|
if (requestIds.length === 0) {
|
|
27220
27829
|
return [];
|
|
27221
27830
|
}
|
|
27222
27831
|
const root = await this.ensureRoot();
|
|
27223
|
-
const browserRecords = await
|
|
27224
|
-
|
|
27225
|
-
|
|
27226
|
-
|
|
27227
|
-
|
|
27228
|
-
|
|
27229
|
-
|
|
27230
|
-
|
|
27231
|
-
timeout.signal
|
|
27232
|
-
)
|
|
27233
|
-
);
|
|
27234
|
-
return timeout.runStep(
|
|
27235
|
-
() => this.networkHistory.persist(browserRecords, root.registry.savedNetwork, {
|
|
27236
|
-
bodyWriteMode: "authoritative",
|
|
27237
|
-
redactSecretHeaders: false
|
|
27238
|
-
})
|
|
27832
|
+
const browserRecords = await this.readBrowserNetworkRecords(
|
|
27833
|
+
{
|
|
27834
|
+
includeBodies: true,
|
|
27835
|
+
includeCurrentPageOnly: options.includeCurrentPageOnly,
|
|
27836
|
+
...options.pageRef === void 0 ? {} : { pageRef: options.pageRef },
|
|
27837
|
+
requestIds
|
|
27838
|
+
},
|
|
27839
|
+
signal
|
|
27239
27840
|
);
|
|
27841
|
+
return this.networkHistory.persist(browserRecords, root.registry.savedNetwork, {
|
|
27842
|
+
bodyWriteMode: "authoritative",
|
|
27843
|
+
redactSecretHeaders: false
|
|
27844
|
+
});
|
|
27240
27845
|
}
|
|
27241
27846
|
async syncPersistedNetworkSelection(timeout, input, options) {
|
|
27242
27847
|
if (this.sessionRef === void 0) {
|
|
@@ -27278,7 +27883,7 @@ var OpensteerSessionRuntime = class {
|
|
|
27278
27883
|
...input.pageRef === void 0 ? {} : { pageRef: input.pageRef },
|
|
27279
27884
|
...input.recordId === void 0 ? {} : { recordId: input.recordId },
|
|
27280
27885
|
...input.requestId === void 0 ? {} : { requestId: input.requestId },
|
|
27281
|
-
...input.
|
|
27886
|
+
...input.capture === void 0 ? {} : { capture: input.capture },
|
|
27282
27887
|
...input.tag === void 0 ? {} : { tag: input.tag },
|
|
27283
27888
|
...input.url === void 0 ? {} : { url: input.url },
|
|
27284
27889
|
...input.hostname === void 0 ? {} : { hostname: input.hostname },
|
|
@@ -27295,7 +27900,7 @@ var OpensteerSessionRuntime = class {
|
|
|
27295
27900
|
...input.pageRef === void 0 ? {} : { pageRef: input.pageRef },
|
|
27296
27901
|
...input.recordId === void 0 ? {} : { recordId: input.recordId },
|
|
27297
27902
|
...input.requestId === void 0 ? {} : { requestId: input.requestId },
|
|
27298
|
-
...input.
|
|
27903
|
+
...input.capture === void 0 ? {} : { capture: input.capture },
|
|
27299
27904
|
...input.url === void 0 ? {} : { url: input.url },
|
|
27300
27905
|
...input.hostname === void 0 ? {} : { hostname: input.hostname },
|
|
27301
27906
|
...input.path === void 0 ? {} : { path: input.path },
|
|
@@ -28154,7 +28759,7 @@ var OpensteerSessionRuntime = class {
|
|
|
28154
28759
|
}
|
|
28155
28760
|
async executeAuthRecipeHook(step, variables) {
|
|
28156
28761
|
const resolved = requireForAuthRecipeHook.resolve(step.hook.specifier, {
|
|
28157
|
-
paths: [
|
|
28762
|
+
paths: [path7.dirname(this.rootPath)]
|
|
28158
28763
|
});
|
|
28159
28764
|
const module = await import(pathToFileURL(resolved).href);
|
|
28160
28765
|
const handler = module[step.hook.export];
|
|
@@ -28526,14 +29131,18 @@ var OpensteerSessionRuntime = class {
|
|
|
28526
29131
|
return this.engine;
|
|
28527
29132
|
}
|
|
28528
29133
|
if (this.injectedEngine) {
|
|
28529
|
-
this.engine = this.
|
|
29134
|
+
this.engine = this.wrapEngineWithObservationCapture(
|
|
29135
|
+
this.injectedEngine
|
|
29136
|
+
);
|
|
28530
29137
|
this.ownsEngine = false;
|
|
28531
29138
|
return this.engine;
|
|
28532
29139
|
}
|
|
28533
29140
|
if (this.engineFactory === void 0) {
|
|
28534
29141
|
throw new Error("Opensteer engine factory is not initialized");
|
|
28535
29142
|
}
|
|
28536
|
-
this.engine =
|
|
29143
|
+
this.engine = this.wrapEngineWithObservationCapture(
|
|
29144
|
+
await this.engineFactory(overrides)
|
|
29145
|
+
);
|
|
28537
29146
|
this.ownsEngine = true;
|
|
28538
29147
|
return this.engine;
|
|
28539
29148
|
}
|
|
@@ -28733,6 +29342,15 @@ var OpensteerSessionRuntime = class {
|
|
|
28733
29342
|
return;
|
|
28734
29343
|
}
|
|
28735
29344
|
const root = await this.ensureRoot();
|
|
29345
|
+
const capturedStepEvents = input.events ?? this.consumePendingOperationEventCapture(
|
|
29346
|
+
input.operation,
|
|
29347
|
+
input.startedAt,
|
|
29348
|
+
input.completedAt
|
|
29349
|
+
);
|
|
29350
|
+
const drainedStepEvents = input.events === void 0 ? await this.drainPendingEngineEvents(input.context) : void 0;
|
|
29351
|
+
const stepEvents = mergeObservedStepEvents(capturedStepEvents, drainedStepEvents);
|
|
29352
|
+
const normalizedData = input.data === void 0 ? void 0 : toCanonicalJsonValue(input.data);
|
|
29353
|
+
const normalizedError = input.error === void 0 ? void 0 : normalizeOpensteerError(input.error);
|
|
28736
29354
|
const artifacts = input.artifacts === void 0 ? void 0 : await Promise.all(
|
|
28737
29355
|
input.artifacts.manifests.map(async (manifest) => {
|
|
28738
29356
|
const reference = await root.artifacts.toProtocolArtifactReference(
|
|
@@ -28745,19 +29363,56 @@ var OpensteerSessionRuntime = class {
|
|
|
28745
29363
|
return reference;
|
|
28746
29364
|
})
|
|
28747
29365
|
);
|
|
28748
|
-
await root.traces.append(runId, {
|
|
29366
|
+
const traceEntry = await root.traces.append(runId, {
|
|
28749
29367
|
operation: input.operation,
|
|
28750
29368
|
outcome: input.outcome,
|
|
28751
29369
|
startedAt: input.startedAt,
|
|
28752
29370
|
completedAt: input.completedAt,
|
|
28753
29371
|
...input.context === void 0 ? {} : { context: input.context },
|
|
28754
|
-
...
|
|
29372
|
+
...stepEvents === void 0 ? {} : { events: stepEvents },
|
|
28755
29373
|
...artifacts === void 0 ? {} : { artifacts },
|
|
28756
|
-
...
|
|
28757
|
-
...
|
|
28758
|
-
error:
|
|
29374
|
+
...normalizedData === void 0 ? {} : { data: normalizedData },
|
|
29375
|
+
...normalizedError === void 0 ? {} : {
|
|
29376
|
+
error: normalizedError
|
|
28759
29377
|
}
|
|
28760
29378
|
});
|
|
29379
|
+
const observationSession = await this.ensureObservationSession().catch(() => void 0);
|
|
29380
|
+
if (observationSession === void 0 || this.observationConfig.profile === "off") {
|
|
29381
|
+
return;
|
|
29382
|
+
}
|
|
29383
|
+
const observationArtifactIds = input.artifacts === void 0 ? void 0 : (await Promise.allSettled(
|
|
29384
|
+
input.artifacts.manifests.map(async (manifest) => {
|
|
29385
|
+
const artifact = await observationSession.writeArtifact({
|
|
29386
|
+
artifactId: manifest.artifactId,
|
|
29387
|
+
kind: observationArtifactKindFromManifest(manifest.kind),
|
|
29388
|
+
createdAt: manifest.createdAt,
|
|
29389
|
+
context: manifest.scope,
|
|
29390
|
+
mediaType: manifest.mediaType,
|
|
29391
|
+
byteLength: manifest.byteLength,
|
|
29392
|
+
sha256: manifest.sha256,
|
|
29393
|
+
opensteerArtifactId: manifest.artifactId,
|
|
29394
|
+
storageKey: manifestToExternalBinaryLocation(root.rootPath, manifest).uri
|
|
29395
|
+
});
|
|
29396
|
+
return artifact.artifactId;
|
|
29397
|
+
})
|
|
29398
|
+
)).flatMap((result) => result.status === "fulfilled" ? [result.value] : []);
|
|
29399
|
+
const observationEvents = buildObservationEventsFromTrace({
|
|
29400
|
+
traceId: traceEntry.traceId,
|
|
29401
|
+
stepId: traceEntry.stepId,
|
|
29402
|
+
operation: input.operation,
|
|
29403
|
+
outcome: input.outcome,
|
|
29404
|
+
startedAt: input.startedAt,
|
|
29405
|
+
completedAt: input.completedAt,
|
|
29406
|
+
...input.context === void 0 ? {} : { context: input.context },
|
|
29407
|
+
...stepEvents === void 0 ? {} : { events: stepEvents },
|
|
29408
|
+
...normalizedData === void 0 ? {} : { data: normalizedData },
|
|
29409
|
+
...normalizedError === void 0 ? {} : { error: normalizedError },
|
|
29410
|
+
...observationArtifactIds === void 0 ? {} : { artifactIds: observationArtifactIds },
|
|
29411
|
+
profile: this.observationConfig.profile
|
|
29412
|
+
});
|
|
29413
|
+
if (observationEvents.length > 0) {
|
|
29414
|
+
await observationSession.appendBatch(observationEvents).catch(() => void 0);
|
|
29415
|
+
}
|
|
28761
29416
|
}
|
|
28762
29417
|
async cleanupSessionResources(engine, pageRef, sessionRef) {
|
|
28763
29418
|
if (pageRef !== void 0) {
|
|
@@ -28769,6 +29424,7 @@ var OpensteerSessionRuntime = class {
|
|
|
28769
29424
|
}
|
|
28770
29425
|
async resetRuntimeState(options) {
|
|
28771
29426
|
const engine = this.engine;
|
|
29427
|
+
const observations = this.observations;
|
|
28772
29428
|
this.networkHistory.clear();
|
|
28773
29429
|
this.sessionRef = void 0;
|
|
28774
29430
|
this.pageRef = void 0;
|
|
@@ -28777,20 +29433,140 @@ var OpensteerSessionRuntime = class {
|
|
|
28777
29433
|
this.computer = void 0;
|
|
28778
29434
|
this.extractionDescriptors = void 0;
|
|
28779
29435
|
this.engine = void 0;
|
|
29436
|
+
this.observations = void 0;
|
|
29437
|
+
this.pendingOperationEventCaptures.length = 0;
|
|
29438
|
+
await observations?.close("runtime_reset").catch(() => void 0);
|
|
28780
29439
|
if (options.disposeEngine && this.ownsEngine && engine?.dispose) {
|
|
28781
29440
|
await engine.dispose();
|
|
28782
29441
|
}
|
|
28783
29442
|
this.ownsEngine = false;
|
|
28784
29443
|
}
|
|
29444
|
+
async ensureObservationSession() {
|
|
29445
|
+
if (this.observationConfig.profile === "off") {
|
|
29446
|
+
return void 0;
|
|
29447
|
+
}
|
|
29448
|
+
if (this.observations !== void 0) {
|
|
29449
|
+
return this.observations;
|
|
29450
|
+
}
|
|
29451
|
+
const observationSessionId = this.resolveObservationSessionId();
|
|
29452
|
+
if (observationSessionId === void 0) {
|
|
29453
|
+
return void 0;
|
|
29454
|
+
}
|
|
29455
|
+
const sink = this.injectedObservationSink ?? (await this.ensureRoot()).observations;
|
|
29456
|
+
this.observations = await sink.openSession({
|
|
29457
|
+
sessionId: observationSessionId,
|
|
29458
|
+
openedAt: Date.now(),
|
|
29459
|
+
config: this.observationConfig
|
|
29460
|
+
});
|
|
29461
|
+
return this.observations;
|
|
29462
|
+
}
|
|
29463
|
+
resolveObservationSessionId() {
|
|
29464
|
+
return this.observationSessionId ?? this.sessionRef;
|
|
29465
|
+
}
|
|
28785
29466
|
runWithOperationTimeout(operation, callback, options = {}) {
|
|
28786
|
-
|
|
28787
|
-
|
|
28788
|
-
|
|
28789
|
-
|
|
28790
|
-
|
|
28791
|
-
|
|
28792
|
-
|
|
28793
|
-
|
|
29467
|
+
const existingCollector = this.operationEventStorage.getStore();
|
|
29468
|
+
if (existingCollector !== void 0) {
|
|
29469
|
+
return runWithPolicyTimeout(
|
|
29470
|
+
this.policy.timeout,
|
|
29471
|
+
{
|
|
29472
|
+
operation,
|
|
29473
|
+
...options.signal === void 0 ? {} : { signal: options.signal }
|
|
29474
|
+
},
|
|
29475
|
+
callback
|
|
29476
|
+
);
|
|
29477
|
+
}
|
|
29478
|
+
const collector = [];
|
|
29479
|
+
const startedAt = Date.now();
|
|
29480
|
+
return this.operationEventStorage.run(collector, async () => {
|
|
29481
|
+
try {
|
|
29482
|
+
return await runWithPolicyTimeout(
|
|
29483
|
+
this.policy.timeout,
|
|
29484
|
+
{
|
|
29485
|
+
operation,
|
|
29486
|
+
...options.signal === void 0 ? {} : { signal: options.signal }
|
|
29487
|
+
},
|
|
29488
|
+
callback
|
|
29489
|
+
);
|
|
29490
|
+
} finally {
|
|
29491
|
+
this.recordPendingOperationEventCapture({
|
|
29492
|
+
operation,
|
|
29493
|
+
startedAt,
|
|
29494
|
+
completedAt: Date.now(),
|
|
29495
|
+
events: collector
|
|
29496
|
+
});
|
|
29497
|
+
}
|
|
29498
|
+
});
|
|
29499
|
+
}
|
|
29500
|
+
wrapEngineWithObservationCapture(engine) {
|
|
29501
|
+
return new Proxy(engine, {
|
|
29502
|
+
get: (target, property, receiver) => {
|
|
29503
|
+
const value = Reflect.get(target, property, receiver);
|
|
29504
|
+
if (typeof value !== "function") {
|
|
29505
|
+
return value;
|
|
29506
|
+
}
|
|
29507
|
+
return (...args) => {
|
|
29508
|
+
const result = Reflect.apply(value, target, args);
|
|
29509
|
+
if (!(result instanceof Promise)) {
|
|
29510
|
+
return result;
|
|
29511
|
+
}
|
|
29512
|
+
return result.then((resolved) => {
|
|
29513
|
+
this.captureObservedStepEvents(resolved);
|
|
29514
|
+
return resolved;
|
|
29515
|
+
});
|
|
29516
|
+
};
|
|
29517
|
+
}
|
|
29518
|
+
});
|
|
29519
|
+
}
|
|
29520
|
+
captureObservedStepEvents(value) {
|
|
29521
|
+
const collector = this.operationEventStorage.getStore();
|
|
29522
|
+
if (collector === void 0) {
|
|
29523
|
+
return;
|
|
29524
|
+
}
|
|
29525
|
+
const events = readStepResultEvents(value);
|
|
29526
|
+
if (events === void 0 || events.length === 0) {
|
|
29527
|
+
return;
|
|
29528
|
+
}
|
|
29529
|
+
collector.push(...events);
|
|
29530
|
+
}
|
|
29531
|
+
recordPendingOperationEventCapture(capture) {
|
|
29532
|
+
if (capture.events.length === 0) {
|
|
29533
|
+
return;
|
|
29534
|
+
}
|
|
29535
|
+
this.pendingOperationEventCaptures.push({
|
|
29536
|
+
...capture,
|
|
29537
|
+
events: [...capture.events]
|
|
29538
|
+
});
|
|
29539
|
+
if (this.pendingOperationEventCaptures.length > PENDING_OPERATION_EVENT_CAPTURE_LIMIT) {
|
|
29540
|
+
this.pendingOperationEventCaptures.splice(
|
|
29541
|
+
0,
|
|
29542
|
+
this.pendingOperationEventCaptures.length - PENDING_OPERATION_EVENT_CAPTURE_LIMIT
|
|
29543
|
+
);
|
|
29544
|
+
}
|
|
29545
|
+
}
|
|
29546
|
+
consumePendingOperationEventCapture(operation, startedAt, completedAt) {
|
|
29547
|
+
for (let index = this.pendingOperationEventCaptures.length - 1; index >= 0; index -= 1) {
|
|
29548
|
+
const capture = this.pendingOperationEventCaptures[index];
|
|
29549
|
+
if (capture === void 0) {
|
|
29550
|
+
continue;
|
|
29551
|
+
}
|
|
29552
|
+
if (capture.operation !== operation) {
|
|
29553
|
+
continue;
|
|
29554
|
+
}
|
|
29555
|
+
if (capture.startedAt < startedAt - PENDING_OPERATION_EVENT_CAPTURE_SKEW_MS || capture.completedAt > completedAt + PENDING_OPERATION_EVENT_CAPTURE_SKEW_MS) {
|
|
29556
|
+
continue;
|
|
29557
|
+
}
|
|
29558
|
+
this.pendingOperationEventCaptures.splice(index, 1);
|
|
29559
|
+
return capture.events;
|
|
29560
|
+
}
|
|
29561
|
+
return void 0;
|
|
29562
|
+
}
|
|
29563
|
+
async drainPendingEngineEvents(context) {
|
|
29564
|
+
const pageRef = context?.pageRef ?? this.pageRef;
|
|
29565
|
+
if (pageRef === void 0 || this.engine === void 0) {
|
|
29566
|
+
return void 0;
|
|
29567
|
+
}
|
|
29568
|
+
const events = await this.engine.drainEvents({ pageRef }).catch(() => []);
|
|
29569
|
+
return events.length > 0 ? events : void 0;
|
|
28794
29570
|
}
|
|
28795
29571
|
async navigatePage(input, timeout) {
|
|
28796
29572
|
const remainingMs = timeout.remainingMs();
|
|
@@ -28826,6 +29602,34 @@ function buildRuntimeTraceContext(input) {
|
|
|
28826
29602
|
function buildArtifactScope(input) {
|
|
28827
29603
|
return buildRuntimeTraceContext(input);
|
|
28828
29604
|
}
|
|
29605
|
+
function readStepResultEvents(value) {
|
|
29606
|
+
if (value === null || typeof value !== "object") {
|
|
29607
|
+
return void 0;
|
|
29608
|
+
}
|
|
29609
|
+
if (!("events" in value)) {
|
|
29610
|
+
return void 0;
|
|
29611
|
+
}
|
|
29612
|
+
const events = value.events;
|
|
29613
|
+
return Array.isArray(events) ? events : void 0;
|
|
29614
|
+
}
|
|
29615
|
+
function mergeObservedStepEvents(primary, secondary) {
|
|
29616
|
+
if (primary === void 0 || primary.length === 0) {
|
|
29617
|
+
return secondary === void 0 || secondary.length === 0 ? void 0 : secondary;
|
|
29618
|
+
}
|
|
29619
|
+
if (secondary === void 0 || secondary.length === 0) {
|
|
29620
|
+
return primary;
|
|
29621
|
+
}
|
|
29622
|
+
const merged = /* @__PURE__ */ new Map();
|
|
29623
|
+
for (const event of primary) {
|
|
29624
|
+
merged.set(event.eventId, event);
|
|
29625
|
+
}
|
|
29626
|
+
for (const event of secondary) {
|
|
29627
|
+
merged.set(event.eventId, event);
|
|
29628
|
+
}
|
|
29629
|
+
return [...merged.values()].sort(
|
|
29630
|
+
(left, right) => (left.timestamp ?? 0) - (right.timestamp ?? 0)
|
|
29631
|
+
);
|
|
29632
|
+
}
|
|
28829
29633
|
function selectLiveQueryPageRef(input, currentPageRef) {
|
|
28830
29634
|
if (input.pageRef !== void 0) {
|
|
28831
29635
|
return input.pageRef;
|
|
@@ -28857,8 +29661,8 @@ function resolveLiveQueryRequestIds(input, history) {
|
|
|
28857
29661
|
if (input.requestId !== void 0) {
|
|
28858
29662
|
requestIdCandidates.push(/* @__PURE__ */ new Set([input.requestId]));
|
|
28859
29663
|
}
|
|
28860
|
-
if (input.
|
|
28861
|
-
requestIdCandidates.push(history.
|
|
29664
|
+
if (input.capture !== void 0) {
|
|
29665
|
+
requestIdCandidates.push(history.getRequestIdsForCapture(input.capture));
|
|
28862
29666
|
}
|
|
28863
29667
|
if (input.tag !== void 0) {
|
|
28864
29668
|
requestIdCandidates.push(history.getRequestIdsForTag(input.tag));
|
|
@@ -28905,7 +29709,7 @@ function filterNetworkQueryRecords(records, input) {
|
|
|
28905
29709
|
if (input.requestId !== void 0 && record.record.requestId !== input.requestId) {
|
|
28906
29710
|
return false;
|
|
28907
29711
|
}
|
|
28908
|
-
if (input.
|
|
29712
|
+
if (input.capture !== void 0 && record.capture !== input.capture) {
|
|
28909
29713
|
return false;
|
|
28910
29714
|
}
|
|
28911
29715
|
if (input.tag !== void 0 && !(record.tags ?? []).includes(input.tag)) {
|
|
@@ -29788,12 +30592,12 @@ function extractReverseRuntimeValue(value, pointer) {
|
|
|
29788
30592
|
}
|
|
29789
30593
|
return readDotPath(value, pointer);
|
|
29790
30594
|
}
|
|
29791
|
-
function readDotPath(value,
|
|
29792
|
-
if (
|
|
30595
|
+
function readDotPath(value, path15) {
|
|
30596
|
+
if (path15.length === 0) {
|
|
29793
30597
|
return value;
|
|
29794
30598
|
}
|
|
29795
30599
|
let current = value;
|
|
29796
|
-
for (const segment of
|
|
30600
|
+
for (const segment of path15.split(".").filter((entry) => entry.length > 0)) {
|
|
29797
30601
|
if (current === null || current === void 0) {
|
|
29798
30602
|
return void 0;
|
|
29799
30603
|
}
|
|
@@ -30162,7 +30966,7 @@ function normalizeRuntimeErrorMessage(error) {
|
|
|
30162
30966
|
return error instanceof Error ? error.message : String(error);
|
|
30163
30967
|
}
|
|
30164
30968
|
function runtimeDelay(ms) {
|
|
30165
|
-
return new Promise((
|
|
30969
|
+
return new Promise((resolve4) => setTimeout(resolve4, ms));
|
|
30166
30970
|
}
|
|
30167
30971
|
function applyBrowserCookiesToTransportRequest(request, cookies) {
|
|
30168
30972
|
if (cookies.length === 0) {
|
|
@@ -30266,7 +31070,7 @@ function parseSetCookieHeader(value, requestUrl) {
|
|
|
30266
31070
|
}
|
|
30267
31071
|
const url = new URL(requestUrl);
|
|
30268
31072
|
let domain = url.hostname;
|
|
30269
|
-
let
|
|
31073
|
+
let path15 = defaultCookiePath(url.pathname);
|
|
30270
31074
|
let secure = url.protocol === "https:";
|
|
30271
31075
|
let expiresAt;
|
|
30272
31076
|
const cookieValue = rawValueParts.join("=").trim();
|
|
@@ -30279,7 +31083,7 @@ function parseSetCookieHeader(value, requestUrl) {
|
|
|
30279
31083
|
continue;
|
|
30280
31084
|
}
|
|
30281
31085
|
if (key === "path" && attributeValue.length > 0) {
|
|
30282
|
-
|
|
31086
|
+
path15 = attributeValue;
|
|
30283
31087
|
continue;
|
|
30284
31088
|
}
|
|
30285
31089
|
if (key === "secure") {
|
|
@@ -30305,7 +31109,7 @@ function parseSetCookieHeader(value, requestUrl) {
|
|
|
30305
31109
|
name,
|
|
30306
31110
|
value: cookieValue,
|
|
30307
31111
|
domain,
|
|
30308
|
-
path:
|
|
31112
|
+
path: path15,
|
|
30309
31113
|
secure,
|
|
30310
31114
|
...expiresAt === void 0 ? {} : { expiresAt }
|
|
30311
31115
|
}
|
|
@@ -31257,7 +32061,7 @@ async function pollUntilResult(timeout, producer) {
|
|
|
31257
32061
|
if (produced !== void 0) {
|
|
31258
32062
|
return produced;
|
|
31259
32063
|
}
|
|
31260
|
-
await new Promise((
|
|
32064
|
+
await new Promise((resolve4) => setTimeout(resolve4, 100));
|
|
31261
32065
|
}
|
|
31262
32066
|
}
|
|
31263
32067
|
async function getMainFrame(engine, pageRef) {
|
|
@@ -31315,9 +32119,167 @@ function toOpensteerResolvedTarget2(target) {
|
|
|
31315
32119
|
function normalizeOpensteerError(error) {
|
|
31316
32120
|
return normalizeThrownOpensteerError(error, "Unknown Opensteer runtime failure");
|
|
31317
32121
|
}
|
|
32122
|
+
function observationArtifactKindFromManifest(kind) {
|
|
32123
|
+
switch (kind) {
|
|
32124
|
+
case "screenshot":
|
|
32125
|
+
return "screenshot";
|
|
32126
|
+
case "dom-snapshot":
|
|
32127
|
+
return "dom-snapshot";
|
|
32128
|
+
case "html-snapshot":
|
|
32129
|
+
return "html-snapshot";
|
|
32130
|
+
default:
|
|
32131
|
+
return "other";
|
|
32132
|
+
}
|
|
32133
|
+
}
|
|
32134
|
+
function buildObservationEventsFromTrace(input) {
|
|
32135
|
+
const context = normalizeObservationContext(input.context);
|
|
32136
|
+
const baseCorrelationId = input.traceId;
|
|
32137
|
+
const startedEvent = {
|
|
32138
|
+
kind: input.operation === "session.open" || input.operation === "session.close" ? "session" : "operation",
|
|
32139
|
+
phase: "started",
|
|
32140
|
+
createdAt: input.startedAt,
|
|
32141
|
+
correlationId: baseCorrelationId,
|
|
32142
|
+
spanId: input.stepId,
|
|
32143
|
+
...context === void 0 ? {} : { context },
|
|
32144
|
+
data: {
|
|
32145
|
+
operation: input.operation
|
|
32146
|
+
}
|
|
32147
|
+
};
|
|
32148
|
+
const stepEvents = (input.events ?? []).filter((event) => shouldCaptureObservationStepEvent(event, input.profile)).map((event) => {
|
|
32149
|
+
const eventContext = buildObservationContextFromEvent(event);
|
|
32150
|
+
return {
|
|
32151
|
+
kind: observationKindForStepEvent(event),
|
|
32152
|
+
phase: "occurred",
|
|
32153
|
+
createdAt: event.timestamp,
|
|
32154
|
+
correlationId: baseCorrelationId,
|
|
32155
|
+
parentSpanId: input.stepId,
|
|
32156
|
+
...eventContext === void 0 ? {} : { context: eventContext },
|
|
32157
|
+
data: stripObservationStepEvent(event),
|
|
32158
|
+
...event.kind === "page-error" ? {
|
|
32159
|
+
error: {
|
|
32160
|
+
message: event.message,
|
|
32161
|
+
...event.stack === void 0 ? {} : { details: { stack: event.stack } }
|
|
32162
|
+
}
|
|
32163
|
+
} : {}
|
|
32164
|
+
};
|
|
32165
|
+
});
|
|
32166
|
+
const completedEvent = {
|
|
32167
|
+
kind: input.operation === "session.open" || input.operation === "session.close" ? "session" : "operation",
|
|
32168
|
+
phase: input.outcome === "ok" ? "completed" : "failed",
|
|
32169
|
+
createdAt: input.completedAt,
|
|
32170
|
+
correlationId: baseCorrelationId,
|
|
32171
|
+
spanId: input.stepId,
|
|
32172
|
+
...context === void 0 ? {} : { context },
|
|
32173
|
+
data: {
|
|
32174
|
+
operation: input.operation,
|
|
32175
|
+
startedAt: input.startedAt,
|
|
32176
|
+
completedAt: input.completedAt,
|
|
32177
|
+
durationMs: input.completedAt - input.startedAt,
|
|
32178
|
+
...input.data === void 0 ? {} : { output: input.data }
|
|
32179
|
+
},
|
|
32180
|
+
...input.error === void 0 ? {} : {
|
|
32181
|
+
error: {
|
|
32182
|
+
...input.error.code === void 0 ? {} : { code: input.error.code },
|
|
32183
|
+
message: input.error.message,
|
|
32184
|
+
...input.error.retriable === void 0 ? {} : { retriable: input.error.retriable },
|
|
32185
|
+
...input.error.details === void 0 ? {} : { details: toCanonicalJsonValue(input.error.details) }
|
|
32186
|
+
}
|
|
32187
|
+
},
|
|
32188
|
+
...input.artifactIds === void 0 || input.artifactIds.length === 0 ? {} : { artifactIds: input.artifactIds }
|
|
32189
|
+
};
|
|
32190
|
+
return [startedEvent, ...stepEvents, completedEvent];
|
|
32191
|
+
}
|
|
32192
|
+
function buildObservationContextFromEvent(event) {
|
|
32193
|
+
return normalizeObservationContext({
|
|
32194
|
+
sessionRef: event.sessionRef,
|
|
32195
|
+
...event.pageRef === void 0 ? {} : { pageRef: event.pageRef },
|
|
32196
|
+
...event.frameRef === void 0 ? {} : { frameRef: event.frameRef },
|
|
32197
|
+
...event.documentRef === void 0 ? {} : { documentRef: event.documentRef },
|
|
32198
|
+
...event.documentEpoch === void 0 ? {} : { documentEpoch: event.documentEpoch }
|
|
32199
|
+
});
|
|
32200
|
+
}
|
|
32201
|
+
function shouldCaptureObservationStepEvent(event, profile) {
|
|
32202
|
+
if (profile === "diagnostic") {
|
|
32203
|
+
return true;
|
|
32204
|
+
}
|
|
32205
|
+
switch (event.kind) {
|
|
32206
|
+
case "page-created":
|
|
32207
|
+
case "popup-opened":
|
|
32208
|
+
case "page-closed":
|
|
32209
|
+
case "page-error":
|
|
32210
|
+
return true;
|
|
32211
|
+
case "console":
|
|
32212
|
+
return event.level === "warn" || event.level === "error";
|
|
32213
|
+
default:
|
|
32214
|
+
return false;
|
|
32215
|
+
}
|
|
32216
|
+
}
|
|
32217
|
+
function observationKindForStepEvent(event) {
|
|
32218
|
+
switch (event.kind) {
|
|
32219
|
+
case "console":
|
|
32220
|
+
return "console";
|
|
32221
|
+
case "page-error":
|
|
32222
|
+
return "error";
|
|
32223
|
+
case "paused":
|
|
32224
|
+
case "resumed":
|
|
32225
|
+
case "frozen":
|
|
32226
|
+
return "runtime";
|
|
32227
|
+
default:
|
|
32228
|
+
return "page";
|
|
32229
|
+
}
|
|
32230
|
+
}
|
|
32231
|
+
function stripObservationStepEvent(event) {
|
|
32232
|
+
const {
|
|
32233
|
+
eventId: _eventId,
|
|
32234
|
+
kind,
|
|
32235
|
+
timestamp,
|
|
32236
|
+
sessionRef: _sessionRef,
|
|
32237
|
+
pageRef: _pageRef,
|
|
32238
|
+
frameRef: _frameRef,
|
|
32239
|
+
documentRef: _documentRef,
|
|
32240
|
+
documentEpoch: _documentEpoch,
|
|
32241
|
+
...rest
|
|
32242
|
+
} = event;
|
|
32243
|
+
return toCanonicalJsonValue({
|
|
32244
|
+
eventKind: kind,
|
|
32245
|
+
timestamp,
|
|
32246
|
+
...rest
|
|
32247
|
+
});
|
|
32248
|
+
}
|
|
32249
|
+
function buildMutationCaptureTraceData(diagnostics) {
|
|
32250
|
+
if (diagnostics?.finalizeError === void 0) {
|
|
32251
|
+
return {};
|
|
32252
|
+
}
|
|
32253
|
+
return {
|
|
32254
|
+
networkCapture: {
|
|
32255
|
+
finalizeError: diagnostics.finalizeError
|
|
32256
|
+
}
|
|
32257
|
+
};
|
|
32258
|
+
}
|
|
31318
32259
|
function isIgnorableRuntimeBindingError(error) {
|
|
31319
32260
|
return isBrowserCoreError(error) && (error.code === "not-found" || error.code === "page-closed" || error.code === "session-closed");
|
|
31320
32261
|
}
|
|
32262
|
+
async function withDetachedTimeoutSignal(timeoutMs, operation) {
|
|
32263
|
+
const controller = new AbortController();
|
|
32264
|
+
const timeoutError = new OpensteerProtocolError(
|
|
32265
|
+
"timeout",
|
|
32266
|
+
`mutation capture finalization exceeded ${String(timeoutMs)}ms timeout`,
|
|
32267
|
+
{
|
|
32268
|
+
details: {
|
|
32269
|
+
policy: "mutation-capture-finalize",
|
|
32270
|
+
budgetMs: timeoutMs
|
|
32271
|
+
}
|
|
32272
|
+
}
|
|
32273
|
+
);
|
|
32274
|
+
const timer = setTimeout(() => {
|
|
32275
|
+
controller.abort(timeoutError);
|
|
32276
|
+
}, timeoutMs);
|
|
32277
|
+
try {
|
|
32278
|
+
return await operation(controller.signal);
|
|
32279
|
+
} finally {
|
|
32280
|
+
clearTimeout(timer);
|
|
32281
|
+
}
|
|
32282
|
+
}
|
|
31321
32283
|
function screenshotMediaType(format2) {
|
|
31322
32284
|
switch (format2) {
|
|
31323
32285
|
case "png":
|
|
@@ -31333,8 +32295,8 @@ function screenshotMediaType(format2) {
|
|
|
31333
32295
|
var OpensteerRuntime = class extends OpensteerSessionRuntime {
|
|
31334
32296
|
constructor(options = {}) {
|
|
31335
32297
|
const publicWorkspace = normalizeWorkspace2(options.workspace);
|
|
31336
|
-
const rootPath = options.rootPath ?? (publicWorkspace === void 0 ?
|
|
31337
|
-
rootDir:
|
|
32298
|
+
const rootPath = options.rootPath ?? (publicWorkspace === void 0 ? path7.resolve(options.rootDir ?? process.cwd(), ".opensteer", "temporary", randomUUID()) : resolveFilesystemWorkspacePath({
|
|
32299
|
+
rootDir: path7.resolve(options.rootDir ?? process.cwd()),
|
|
31338
32300
|
workspace: publicWorkspace
|
|
31339
32301
|
}));
|
|
31340
32302
|
const cleanupRootOnClose = options.cleanupRootOnClose ?? publicWorkspace === void 0;
|
|
@@ -31359,14 +32321,17 @@ var OpensteerRuntime = class extends OpensteerSessionRuntime {
|
|
|
31359
32321
|
...options.descriptorStore === void 0 ? {} : { descriptorStore: options.descriptorStore },
|
|
31360
32322
|
...options.extractionDescriptorStore === void 0 ? {} : { extractionDescriptorStore: options.extractionDescriptorStore },
|
|
31361
32323
|
...options.registryOverrides === void 0 ? {} : { registryOverrides: options.registryOverrides },
|
|
31362
|
-
cleanupRootOnClose
|
|
32324
|
+
cleanupRootOnClose,
|
|
32325
|
+
...options.observability === void 0 ? {} : { observability: options.observability },
|
|
32326
|
+
...options.observationSessionId === void 0 ? {} : { observationSessionId: options.observationSessionId },
|
|
32327
|
+
...options.observationSink === void 0 ? {} : { observationSink: options.observationSink }
|
|
31363
32328
|
})
|
|
31364
32329
|
);
|
|
31365
32330
|
}
|
|
31366
32331
|
};
|
|
31367
32332
|
var OpensteerSessionRuntime2 = class extends OpensteerSessionRuntime {
|
|
31368
32333
|
constructor(options) {
|
|
31369
|
-
const rootPath = options.rootPath ??
|
|
32334
|
+
const rootPath = options.rootPath ?? path7.resolve(options.rootDir ?? process.cwd());
|
|
31370
32335
|
const cleanupRootOnClose = options.cleanupRootOnClose ?? false;
|
|
31371
32336
|
const engineName = options.engineName ?? DEFAULT_OPENSTEER_ENGINE;
|
|
31372
32337
|
assertSupportedEngineOptions({
|
|
@@ -31388,7 +32353,10 @@ var OpensteerSessionRuntime2 = class extends OpensteerSessionRuntime {
|
|
|
31388
32353
|
...options.descriptorStore === void 0 ? {} : { descriptorStore: options.descriptorStore },
|
|
31389
32354
|
...options.extractionDescriptorStore === void 0 ? {} : { extractionDescriptorStore: options.extractionDescriptorStore },
|
|
31390
32355
|
...options.registryOverrides === void 0 ? {} : { registryOverrides: options.registryOverrides },
|
|
31391
|
-
cleanupRootOnClose
|
|
32356
|
+
cleanupRootOnClose,
|
|
32357
|
+
...options.observability === void 0 ? {} : { observability: options.observability },
|
|
32358
|
+
...options.observationSessionId === void 0 ? {} : { observationSessionId: options.observationSessionId },
|
|
32359
|
+
...options.observationSink === void 0 ? {} : { observationSink: options.observationSink }
|
|
31392
32360
|
})
|
|
31393
32361
|
);
|
|
31394
32362
|
}
|
|
@@ -31414,6 +32382,9 @@ function buildSharedRuntimeOptions(input) {
|
|
|
31414
32382
|
...input.extractionDescriptorStore === void 0 ? {} : { extractionDescriptorStore: input.extractionDescriptorStore },
|
|
31415
32383
|
...input.registryOverrides === void 0 ? {} : { registryOverrides: input.registryOverrides },
|
|
31416
32384
|
cleanupRootOnClose: input.cleanupRootOnClose,
|
|
32385
|
+
...input.observability === void 0 ? {} : { observability: input.observability },
|
|
32386
|
+
...input.observationSessionId === void 0 ? {} : { observationSessionId: input.observationSessionId },
|
|
32387
|
+
...input.observationSink === void 0 ? {} : { observationSink: input.observationSink },
|
|
31417
32388
|
sessionInfo: {
|
|
31418
32389
|
provider: {
|
|
31419
32390
|
mode: "local",
|
|
@@ -31476,345 +32447,267 @@ function resolveOpensteerProvider(input = {}) {
|
|
|
31476
32447
|
};
|
|
31477
32448
|
}
|
|
31478
32449
|
var execFile2 = promisify(execFile);
|
|
31479
|
-
var
|
|
31480
|
-
var
|
|
31481
|
-
var
|
|
31482
|
-
|
|
31483
|
-
async function resolveCookieCaptureStrategy(input = {}) {
|
|
31484
|
-
const timeoutMs = input.timeoutMs ?? DEFAULT_CAPTURE_TIMEOUT_MS;
|
|
31485
|
-
if (input.attachEndpoint !== void 0) {
|
|
31486
|
-
if (input.strategy !== void 0 && input.strategy !== "attach") {
|
|
31487
|
-
throw new Error(
|
|
31488
|
-
`Strategy "${input.strategy}" is incompatible with an explicit attach endpoint.`
|
|
31489
|
-
);
|
|
31490
|
-
}
|
|
31491
|
-
return {
|
|
31492
|
-
strategy: "attach",
|
|
31493
|
-
attachEndpoint: input.attachEndpoint,
|
|
31494
|
-
...input.profileDirectory === void 0 ? {} : { profileDirectory: input.profileDirectory },
|
|
31495
|
-
timeoutMs
|
|
31496
|
-
};
|
|
31497
|
-
}
|
|
32450
|
+
var NODE_SQLITE_SPECIFIER2 = `node:${"sqlite"}`;
|
|
32451
|
+
var CHROME_EPOCH_OFFSET = 11644473600000000n;
|
|
32452
|
+
var CHROME_HMAC_PREFIX_LENGTH = 32;
|
|
32453
|
+
async function readBrowserCookies(input = {}) {
|
|
31498
32454
|
const brand2 = resolveRequestedBrand(input);
|
|
31499
|
-
const executablePath = resolveBrandExecutablePath(brand2, input.executablePath);
|
|
31500
32455
|
const userDataDir = resolveBrandUserDataDir(brand2, input.userDataDir);
|
|
31501
|
-
const profileDirectory = input.profileDirectory;
|
|
31502
|
-
const
|
|
31503
|
-
|
|
31504
|
-
const autoStrategy = attachEndpoint !== void 0 ? "attach" : runningProcess !== null ? "managed-relaunch" : "headless";
|
|
31505
|
-
const strategy = input.strategy ?? autoStrategy;
|
|
31506
|
-
validateRequestedStrategy({
|
|
31507
|
-
strategy,
|
|
31508
|
-
brand: brand2,
|
|
31509
|
-
...attachEndpoint === void 0 ? {} : { attachEndpoint },
|
|
31510
|
-
...runningProcess?.pid === void 0 ? {} : { runningPid: runningProcess.pid }
|
|
31511
|
-
});
|
|
31512
|
-
return {
|
|
31513
|
-
strategy,
|
|
31514
|
-
brandId: brand2.id,
|
|
31515
|
-
brandDisplayName: brand2.displayName,
|
|
31516
|
-
executablePath,
|
|
31517
|
-
userDataDir,
|
|
31518
|
-
...profileDirectory === void 0 ? {} : { profileDirectory },
|
|
31519
|
-
...attachEndpoint === void 0 ? {} : { attachEndpoint },
|
|
31520
|
-
...runningProcess === null ? {} : { runningPid: runningProcess.pid },
|
|
31521
|
-
timeoutMs
|
|
31522
|
-
};
|
|
31523
|
-
}
|
|
31524
|
-
async function acquireCdpEndpoint(resolved) {
|
|
31525
|
-
if (resolved.strategy === "attach") {
|
|
31526
|
-
if (!resolved.attachEndpoint) {
|
|
31527
|
-
throw new Error("Attach capture requires a debuggable browser endpoint.");
|
|
31528
|
-
}
|
|
31529
|
-
const inspected = await inspectCdpEndpoint({
|
|
31530
|
-
endpoint: resolved.attachEndpoint,
|
|
31531
|
-
timeoutMs: Math.min(2e3, resolved.timeoutMs)
|
|
31532
|
-
});
|
|
31533
|
-
return {
|
|
31534
|
-
strategy: "attach",
|
|
31535
|
-
cdpEndpoint: inspected.endpoint,
|
|
31536
|
-
...resolved.brandId === void 0 ? {} : { brandId: resolved.brandId },
|
|
31537
|
-
...resolved.brandDisplayName === void 0 ? {} : { brandDisplayName: resolved.brandDisplayName },
|
|
31538
|
-
...resolved.userDataDir === void 0 ? {} : { userDataDir: resolved.userDataDir },
|
|
31539
|
-
...resolved.profileDirectory === void 0 ? {} : { profileDirectory: resolved.profileDirectory },
|
|
31540
|
-
cleanup: async () => void 0
|
|
31541
|
-
};
|
|
31542
|
-
}
|
|
31543
|
-
if (!resolved.brandId || !resolved.brandDisplayName || !resolved.executablePath || !resolved.userDataDir) {
|
|
32456
|
+
const profileDirectory = input.profileDirectory ?? "Default";
|
|
32457
|
+
const cookiesPath = join(userDataDir, profileDirectory, "Cookies");
|
|
32458
|
+
if (!existsSync(cookiesPath)) {
|
|
31544
32459
|
throw new Error(
|
|
31545
|
-
|
|
32460
|
+
`Cookies database not found at "${cookiesPath}". Verify the browser brand, user-data-dir, and profile-directory are correct.`
|
|
31546
32461
|
);
|
|
31547
32462
|
}
|
|
31548
|
-
const
|
|
31549
|
-
if (resolved.strategy === "managed-relaunch") {
|
|
31550
|
-
if (resolved.runningPid === void 0) {
|
|
31551
|
-
throw new Error("Managed relaunch requires a running browser process.");
|
|
31552
|
-
}
|
|
31553
|
-
await gracefullyStopBrowser(
|
|
31554
|
-
getBrowserBrand(resolved.brandId),
|
|
31555
|
-
resolved.runningPid,
|
|
31556
|
-
resolved.timeoutMs
|
|
31557
|
-
);
|
|
31558
|
-
}
|
|
31559
|
-
await clearChromeSingletonEntries(userDataDir);
|
|
31560
|
-
try {
|
|
31561
|
-
const capture = await launchCaptureChrome({
|
|
31562
|
-
brandDisplayName: resolved.brandDisplayName,
|
|
31563
|
-
executablePath: resolved.executablePath,
|
|
31564
|
-
userDataDir,
|
|
31565
|
-
...resolved.profileDirectory === void 0 ? {} : { profileDirectory: resolved.profileDirectory },
|
|
31566
|
-
timeoutMs: resolved.timeoutMs
|
|
31567
|
-
});
|
|
31568
|
-
return {
|
|
31569
|
-
strategy: resolved.strategy,
|
|
31570
|
-
cdpEndpoint: capture.endpoint,
|
|
31571
|
-
brandId: resolved.brandId,
|
|
31572
|
-
brandDisplayName: resolved.brandDisplayName,
|
|
31573
|
-
userDataDir: resolved.userDataDir,
|
|
31574
|
-
...resolved.profileDirectory === void 0 ? {} : { profileDirectory: resolved.profileDirectory },
|
|
31575
|
-
cleanup: async () => {
|
|
31576
|
-
await capture.kill().catch(() => void 0);
|
|
31577
|
-
await clearChromeSingletonEntries(userDataDir).catch(() => void 0);
|
|
31578
|
-
}
|
|
31579
|
-
};
|
|
31580
|
-
} catch (error) {
|
|
31581
|
-
await clearChromeSingletonEntries(userDataDir).catch(() => void 0);
|
|
31582
|
-
throw error;
|
|
31583
|
-
}
|
|
31584
|
-
}
|
|
31585
|
-
async function gracefullyStopBrowser(brand2, pid, timeoutMs = DEFAULT_STOP_TIMEOUT_MS) {
|
|
31586
|
-
if (pid <= 0) {
|
|
31587
|
-
return;
|
|
31588
|
-
}
|
|
31589
|
-
const platformConfig = resolveBrandPlatformConfig(brand2);
|
|
31590
|
-
if (process.platform === "darwin" && platformConfig?.bundleId) {
|
|
31591
|
-
await execFile2(
|
|
31592
|
-
"osascript",
|
|
31593
|
-
["-e", `tell application id "${platformConfig.bundleId}" to quit`],
|
|
31594
|
-
{
|
|
31595
|
-
maxBuffer: PROCESS_LIST_MAX_BUFFER_BYTES3
|
|
31596
|
-
}
|
|
31597
|
-
).catch(() => void 0);
|
|
31598
|
-
} else if (process.platform === "win32") {
|
|
31599
|
-
await execFile2("taskkill", ["/PID", String(pid)], {
|
|
31600
|
-
maxBuffer: PROCESS_LIST_MAX_BUFFER_BYTES3
|
|
31601
|
-
}).catch(() => void 0);
|
|
31602
|
-
} else {
|
|
31603
|
-
try {
|
|
31604
|
-
process.kill(pid, "SIGTERM");
|
|
31605
|
-
} catch {
|
|
31606
|
-
}
|
|
31607
|
-
}
|
|
31608
|
-
if (await waitForProcessExit2(pid, timeoutMs)) {
|
|
31609
|
-
return;
|
|
31610
|
-
}
|
|
31611
|
-
if (process.platform === "win32") {
|
|
31612
|
-
await execFile2("taskkill", ["/F", "/PID", String(pid)], {
|
|
31613
|
-
maxBuffer: PROCESS_LIST_MAX_BUFFER_BYTES3
|
|
31614
|
-
}).catch(() => void 0);
|
|
31615
|
-
} else {
|
|
31616
|
-
try {
|
|
31617
|
-
process.kill(pid, "SIGKILL");
|
|
31618
|
-
} catch {
|
|
31619
|
-
}
|
|
31620
|
-
}
|
|
31621
|
-
await waitForProcessExit2(pid, Math.min(5e3, timeoutMs));
|
|
31622
|
-
}
|
|
31623
|
-
async function launchCaptureChrome(input) {
|
|
31624
|
-
const stderrLines = [];
|
|
31625
|
-
const child = spawn(input.executablePath, buildCaptureChromeArgs(input), {
|
|
31626
|
-
detached: process.platform !== "win32",
|
|
31627
|
-
stdio: ["ignore", "ignore", "pipe"]
|
|
31628
|
-
});
|
|
31629
|
-
child.unref();
|
|
31630
|
-
child.stderr?.setEncoding("utf8");
|
|
31631
|
-
child.stderr?.on("data", (chunk) => {
|
|
31632
|
-
stderrLines.push(String(chunk));
|
|
31633
|
-
});
|
|
32463
|
+
const tempDir = await mkdtemp(join(tmpdir(), "opensteer-cookies-"));
|
|
31634
32464
|
try {
|
|
31635
|
-
|
|
31636
|
-
|
|
31637
|
-
|
|
31638
|
-
|
|
31639
|
-
timeoutMs: input.timeoutMs,
|
|
31640
|
-
userDataDir: input.userDataDir
|
|
31641
|
-
});
|
|
32465
|
+
await copyCookiesDatabase(cookiesPath, tempDir);
|
|
32466
|
+
const decryptionKey = await resolveDecryptionKey(brand2.id, userDataDir);
|
|
32467
|
+
const rows = queryAllCookies(join(tempDir, "Cookies"));
|
|
32468
|
+
const cookies = decryptCookieRows(rows, decryptionKey);
|
|
31642
32469
|
return {
|
|
31643
|
-
|
|
31644
|
-
|
|
31645
|
-
|
|
31646
|
-
|
|
32470
|
+
cookies,
|
|
32471
|
+
brandId: brand2.id,
|
|
32472
|
+
brandDisplayName: brand2.displayName,
|
|
32473
|
+
userDataDir,
|
|
32474
|
+
profileDirectory
|
|
31647
32475
|
};
|
|
31648
|
-
}
|
|
31649
|
-
await
|
|
31650
|
-
throw error;
|
|
32476
|
+
} finally {
|
|
32477
|
+
await rm(tempDir, { recursive: true, force: true }).catch(() => void 0);
|
|
31651
32478
|
}
|
|
31652
32479
|
}
|
|
31653
|
-
function relaunchBrowserNormally(executablePath) {
|
|
31654
|
-
const child = spawn(executablePath, [], {
|
|
31655
|
-
detached: true,
|
|
31656
|
-
stdio: "ignore"
|
|
31657
|
-
});
|
|
31658
|
-
child.unref();
|
|
31659
|
-
}
|
|
31660
32480
|
function resolveRequestedBrand(input) {
|
|
31661
32481
|
if (input.brandId !== void 0) {
|
|
31662
32482
|
return getBrowserBrand(input.brandId);
|
|
31663
32483
|
}
|
|
31664
|
-
if (input.userDataDir !== void 0) {
|
|
31665
|
-
const inferred = inferBrandFromUserDataDir(input.userDataDir);
|
|
31666
|
-
if (!inferred) {
|
|
31667
|
-
throw new Error(
|
|
31668
|
-
`Could not infer a browser brand from user-data-dir "${input.userDataDir}". Pass --browser explicitly.`
|
|
31669
|
-
);
|
|
31670
|
-
}
|
|
31671
|
-
return inferred;
|
|
31672
|
-
}
|
|
31673
|
-
if (input.executablePath !== void 0) {
|
|
31674
|
-
const inferred = inferBrandFromExecutablePath(input.executablePath);
|
|
31675
|
-
if (!inferred) {
|
|
31676
|
-
throw new Error(
|
|
31677
|
-
`Could not infer a browser brand from executable path "${input.executablePath}". Pass --browser explicitly.`
|
|
31678
|
-
);
|
|
31679
|
-
}
|
|
31680
|
-
return inferred;
|
|
31681
|
-
}
|
|
31682
32484
|
const installed = detectInstalledBrowserBrands()[0];
|
|
31683
32485
|
if (!installed) {
|
|
31684
32486
|
throw new Error(
|
|
31685
|
-
"No Chromium browser found. Install a supported browser or pass
|
|
32487
|
+
"No Chromium browser found. Install a supported browser or pass brandId explicitly."
|
|
31686
32488
|
);
|
|
31687
32489
|
}
|
|
31688
32490
|
return installed.brand;
|
|
31689
32491
|
}
|
|
31690
|
-
async function
|
|
31691
|
-
|
|
31692
|
-
|
|
31693
|
-
|
|
32492
|
+
async function copyCookiesDatabase(cookiesPath, destDir) {
|
|
32493
|
+
await copyFile(cookiesPath, join(destDir, "Cookies"));
|
|
32494
|
+
for (const suffix of ["-wal", "-journal", "-shm"]) {
|
|
32495
|
+
const src = cookiesPath + suffix;
|
|
32496
|
+
if (existsSync(src)) {
|
|
32497
|
+
await copyFile(src, join(destDir, "Cookies" + suffix)).catch(() => void 0);
|
|
32498
|
+
}
|
|
31694
32499
|
}
|
|
32500
|
+
}
|
|
32501
|
+
function queryAllCookies(dbPath) {
|
|
32502
|
+
let DatabaseSync;
|
|
31695
32503
|
try {
|
|
31696
|
-
|
|
31697
|
-
endpoint: `http://127.0.0.1:${String(activePort.port)}`,
|
|
31698
|
-
timeoutMs: Math.min(2e3, timeoutMs)
|
|
31699
|
-
})).endpoint;
|
|
32504
|
+
({ DatabaseSync } = __require(NODE_SQLITE_SPECIFIER2));
|
|
31700
32505
|
} catch {
|
|
31701
|
-
|
|
32506
|
+
throw new Error(
|
|
32507
|
+
"Reading browser cookies requires Node's built-in SQLite support. Use Node 22.5+ or a build with node:sqlite enabled."
|
|
32508
|
+
);
|
|
32509
|
+
}
|
|
32510
|
+
const database = new DatabaseSync(dbPath, { readOnly: true });
|
|
32511
|
+
try {
|
|
32512
|
+
const stmt = database.prepare(
|
|
32513
|
+
`SELECT host_key, name, value, encrypted_value, path,
|
|
32514
|
+
expires_utc, is_secure, is_httponly, samesite, is_persistent
|
|
32515
|
+
FROM cookies`
|
|
32516
|
+
);
|
|
32517
|
+
stmt.setReadBigInts(true);
|
|
32518
|
+
return stmt.all();
|
|
32519
|
+
} finally {
|
|
32520
|
+
database.close();
|
|
31702
32521
|
}
|
|
31703
32522
|
}
|
|
31704
|
-
function
|
|
31705
|
-
if (
|
|
32523
|
+
async function resolveDecryptionKey(brandId, userDataDir) {
|
|
32524
|
+
if (process.platform === "darwin") {
|
|
32525
|
+
const password = await resolveKeychainPassword(brandId);
|
|
32526
|
+
const key = pbkdf2Sync(password, "saltysalt", 1003, 16, "sha1");
|
|
32527
|
+
return { platform: "darwin", key, algorithm: "aes-128-cbc" };
|
|
32528
|
+
}
|
|
32529
|
+
if (process.platform === "linux") {
|
|
32530
|
+
const key = pbkdf2Sync("peanuts", "saltysalt", 1, 16, "sha1");
|
|
32531
|
+
return { platform: "linux", key, algorithm: "aes-128-cbc" };
|
|
32532
|
+
}
|
|
32533
|
+
if (process.platform === "win32") {
|
|
32534
|
+
const key = await resolveWindowsMasterKey(userDataDir);
|
|
32535
|
+
return { platform: "win32", key, algorithm: "aes-256-gcm" };
|
|
32536
|
+
}
|
|
32537
|
+
throw new Error(`Unsupported platform "${process.platform}" for cookie decryption.`);
|
|
32538
|
+
}
|
|
32539
|
+
var BRAND_KEYCHAIN_SERVICE = {
|
|
32540
|
+
chrome: "Chrome Safe Storage",
|
|
32541
|
+
"chrome-canary": "Chrome Safe Storage",
|
|
32542
|
+
chromium: "Chromium Safe Storage",
|
|
32543
|
+
brave: "Brave Safe Storage",
|
|
32544
|
+
edge: "Microsoft Edge Safe Storage",
|
|
32545
|
+
vivaldi: "Chrome Safe Storage",
|
|
32546
|
+
helium: "Chrome Safe Storage"
|
|
32547
|
+
};
|
|
32548
|
+
async function resolveKeychainPassword(brandId) {
|
|
32549
|
+
const service = BRAND_KEYCHAIN_SERVICE[brandId];
|
|
32550
|
+
try {
|
|
32551
|
+
const { stdout } = await execFile2("security", [
|
|
32552
|
+
"find-generic-password",
|
|
32553
|
+
"-s",
|
|
32554
|
+
service,
|
|
32555
|
+
"-w"
|
|
32556
|
+
]);
|
|
32557
|
+
return stdout.trim();
|
|
32558
|
+
} catch {
|
|
31706
32559
|
throw new Error(
|
|
31707
|
-
|
|
32560
|
+
`Failed to retrieve "${service}" from macOS Keychain. Ensure the browser has been opened at least once and Keychain access is allowed.`
|
|
31708
32561
|
);
|
|
31709
32562
|
}
|
|
31710
|
-
|
|
32563
|
+
}
|
|
32564
|
+
async function resolveWindowsMasterKey(userDataDir) {
|
|
32565
|
+
const localStatePath = join(userDataDir, "Local State");
|
|
32566
|
+
let localState;
|
|
32567
|
+
try {
|
|
32568
|
+
localState = JSON.parse(await readFile(localStatePath, "utf8"));
|
|
32569
|
+
} catch {
|
|
31711
32570
|
throw new Error(
|
|
31712
|
-
|
|
32571
|
+
`Failed to read "${localStatePath}". Ensure the browser has been opened at least once.`
|
|
31713
32572
|
);
|
|
31714
32573
|
}
|
|
31715
|
-
|
|
32574
|
+
const encodedKey = localState.os_crypt?.encrypted_key;
|
|
32575
|
+
if (!encodedKey) {
|
|
32576
|
+
throw new Error(`No encrypted key found in "${localStatePath}".`);
|
|
32577
|
+
}
|
|
32578
|
+
const rawKey = Buffer.from(encodedKey, "base64").subarray(5);
|
|
32579
|
+
const psScript = `
|
|
32580
|
+
Add-Type -AssemblyName System.Security
|
|
32581
|
+
$bytes = [byte[]]@(${Array.from(rawKey).join(",")})
|
|
32582
|
+
$decrypted = [System.Security.Cryptography.ProtectedData]::Unprotect($bytes, $null, 'CurrentUser')
|
|
32583
|
+
[Convert]::ToBase64String($decrypted)
|
|
32584
|
+
`;
|
|
32585
|
+
try {
|
|
32586
|
+
const { stdout } = await execFile2("powershell", [
|
|
32587
|
+
"-NoProfile",
|
|
32588
|
+
"-NonInteractive",
|
|
32589
|
+
"-Command",
|
|
32590
|
+
psScript
|
|
32591
|
+
]);
|
|
32592
|
+
return Buffer.from(stdout.trim(), "base64");
|
|
32593
|
+
} catch {
|
|
31716
32594
|
throw new Error(
|
|
31717
|
-
|
|
32595
|
+
"Failed to decrypt browser master key via Windows DPAPI. Ensure you are running as the same user who owns the browser profile."
|
|
31718
32596
|
);
|
|
31719
32597
|
}
|
|
31720
32598
|
}
|
|
31721
|
-
function
|
|
31722
|
-
const
|
|
31723
|
-
|
|
31724
|
-
|
|
31725
|
-
|
|
31726
|
-
|
|
32599
|
+
function decryptCookieRows(rows, decryptionKey) {
|
|
32600
|
+
const cookies = [];
|
|
32601
|
+
const nowSeconds = Math.floor(Date.now() / 1e3);
|
|
32602
|
+
for (const row of rows) {
|
|
32603
|
+
const name = row.name.trim();
|
|
32604
|
+
const domain = row.host_key.trim();
|
|
32605
|
+
if (!name || !domain) {
|
|
32606
|
+
continue;
|
|
31727
32607
|
}
|
|
31728
|
-
const
|
|
31729
|
-
|
|
31730
|
-
|
|
31731
|
-
}
|
|
31732
|
-
function inferBrandFromExecutablePath(executablePath) {
|
|
31733
|
-
const normalized = normalizePath(executablePath);
|
|
31734
|
-
return getAllBrowserBrands().find((brand2) => {
|
|
31735
|
-
const config = resolveBrandPlatformConfig(brand2);
|
|
31736
|
-
if (!config) {
|
|
31737
|
-
return false;
|
|
32608
|
+
const value = decryptCookieValue(row, decryptionKey);
|
|
32609
|
+
if (value === null) {
|
|
32610
|
+
continue;
|
|
31738
32611
|
}
|
|
31739
|
-
|
|
31740
|
-
|
|
31741
|
-
)
|
|
31742
|
-
|
|
31743
|
-
}
|
|
31744
|
-
function buildCaptureChromeArgs(input) {
|
|
31745
|
-
const args = [
|
|
31746
|
-
"--remote-debugging-port=0",
|
|
31747
|
-
"--headless=new",
|
|
31748
|
-
"--no-first-run",
|
|
31749
|
-
"--no-default-browser-check",
|
|
31750
|
-
"--disable-background-networking",
|
|
31751
|
-
"--disable-sync",
|
|
31752
|
-
"--disable-component-update",
|
|
31753
|
-
`--user-data-dir=${input.userDataDir}`
|
|
31754
|
-
];
|
|
31755
|
-
if (input.profileDirectory !== void 0) {
|
|
31756
|
-
args.push(`--profile-directory=${input.profileDirectory}`);
|
|
31757
|
-
}
|
|
31758
|
-
return args;
|
|
31759
|
-
}
|
|
31760
|
-
async function waitForCaptureEndpoint(input) {
|
|
31761
|
-
const deadline = Date.now() + input.timeoutMs;
|
|
31762
|
-
while (Date.now() < deadline) {
|
|
31763
|
-
const activePort = readDevToolsActivePort(input.userDataDir);
|
|
31764
|
-
if (activePort) {
|
|
31765
|
-
try {
|
|
31766
|
-
return (await inspectCdpEndpoint({
|
|
31767
|
-
endpoint: `http://127.0.0.1:${String(activePort.port)}`,
|
|
31768
|
-
timeoutMs: Math.min(2e3, input.timeoutMs)
|
|
31769
|
-
})).endpoint;
|
|
31770
|
-
} catch {
|
|
31771
|
-
return `ws://127.0.0.1:${String(activePort.port)}${activePort.webSocketPath}`;
|
|
31772
|
-
}
|
|
32612
|
+
const expiresSeconds = chromeDateToUnixSeconds(row.expires_utc);
|
|
32613
|
+
const isSession = expiresSeconds <= 0;
|
|
32614
|
+
if (!isSession && expiresSeconds < nowSeconds) {
|
|
32615
|
+
continue;
|
|
31773
32616
|
}
|
|
31774
|
-
|
|
31775
|
-
|
|
32617
|
+
const sameSite = chromeSameSiteToString(row.samesite);
|
|
32618
|
+
let secure = Number(row.is_secure) === 1;
|
|
32619
|
+
if (sameSite === "None") {
|
|
32620
|
+
secure = true;
|
|
31776
32621
|
}
|
|
31777
|
-
|
|
32622
|
+
cookies.push({
|
|
32623
|
+
name,
|
|
32624
|
+
value,
|
|
32625
|
+
domain,
|
|
32626
|
+
path: row.path || "/",
|
|
32627
|
+
secure,
|
|
32628
|
+
httpOnly: Number(row.is_httponly) === 1,
|
|
32629
|
+
...isSession ? {} : { expires: expiresSeconds },
|
|
32630
|
+
...sameSite !== void 0 ? { sameSite } : {}
|
|
32631
|
+
});
|
|
31778
32632
|
}
|
|
31779
|
-
|
|
32633
|
+
return cookies;
|
|
31780
32634
|
}
|
|
31781
|
-
function
|
|
31782
|
-
|
|
31783
|
-
|
|
31784
|
-
return `${brandDisplayName} failed to launch before exposing a DevTools endpoint.`;
|
|
32635
|
+
function decryptCookieValue(row, decryptionKey) {
|
|
32636
|
+
if (row.value && row.value.length > 0) {
|
|
32637
|
+
return row.value;
|
|
31785
32638
|
}
|
|
31786
|
-
const
|
|
31787
|
-
|
|
31788
|
-
|
|
31789
|
-
|
|
31790
|
-
|
|
32639
|
+
const encrypted = Buffer.isBuffer(row.encrypted_value) ? row.encrypted_value : Buffer.from(row.encrypted_value);
|
|
32640
|
+
if (encrypted.length === 0) {
|
|
32641
|
+
return "";
|
|
32642
|
+
}
|
|
32643
|
+
const prefix = encrypted.subarray(0, 3).toString("ascii");
|
|
32644
|
+
if (prefix !== "v10" && prefix !== "v11") {
|
|
32645
|
+
return encrypted.toString("utf8");
|
|
32646
|
+
}
|
|
32647
|
+
const ciphertext = encrypted.subarray(3);
|
|
32648
|
+
if (decryptionKey.algorithm === "aes-128-cbc") {
|
|
32649
|
+
return decryptAes128Cbc(ciphertext, decryptionKey.key);
|
|
32650
|
+
}
|
|
32651
|
+
if (decryptionKey.algorithm === "aes-256-gcm") {
|
|
32652
|
+
return decryptAes256Gcm(ciphertext, decryptionKey.key);
|
|
32653
|
+
}
|
|
32654
|
+
return null;
|
|
31791
32655
|
}
|
|
31792
|
-
|
|
31793
|
-
|
|
31794
|
-
|
|
32656
|
+
function decryptAes128Cbc(ciphertext, key) {
|
|
32657
|
+
try {
|
|
32658
|
+
const iv = Buffer.alloc(16, 32);
|
|
32659
|
+
const decipher = createDecipheriv("aes-128-cbc", key, iv);
|
|
32660
|
+
let decrypted = Buffer.concat([decipher.update(ciphertext), decipher.final()]);
|
|
32661
|
+
if (decrypted.length > CHROME_HMAC_PREFIX_LENGTH && containsNonPrintableAscii(decrypted, CHROME_HMAC_PREFIX_LENGTH)) {
|
|
32662
|
+
decrypted = decrypted.subarray(CHROME_HMAC_PREFIX_LENGTH);
|
|
32663
|
+
}
|
|
32664
|
+
if (containsNonPrintableAscii(decrypted, decrypted.length)) {
|
|
32665
|
+
return null;
|
|
32666
|
+
}
|
|
32667
|
+
return decrypted.toString("utf8");
|
|
32668
|
+
} catch {
|
|
32669
|
+
return null;
|
|
31795
32670
|
}
|
|
32671
|
+
}
|
|
32672
|
+
function decryptAes256Gcm(ciphertext, key) {
|
|
31796
32673
|
try {
|
|
31797
|
-
|
|
32674
|
+
const nonce = ciphertext.subarray(0, 12);
|
|
32675
|
+
const authTag = ciphertext.subarray(ciphertext.length - 16);
|
|
32676
|
+
const encrypted = ciphertext.subarray(12, ciphertext.length - 16);
|
|
32677
|
+
const decipher = createDecipheriv("aes-256-gcm", key, nonce);
|
|
32678
|
+
decipher.setAuthTag(authTag);
|
|
32679
|
+
const decrypted = Buffer.concat([decipher.update(encrypted), decipher.final()]);
|
|
32680
|
+
if (containsNonPrintableAscii(decrypted, decrypted.length)) {
|
|
32681
|
+
return null;
|
|
32682
|
+
}
|
|
32683
|
+
return decrypted.toString("utf8");
|
|
31798
32684
|
} catch {
|
|
31799
|
-
return;
|
|
32685
|
+
return null;
|
|
31800
32686
|
}
|
|
31801
|
-
await sleep4(50);
|
|
31802
32687
|
}
|
|
31803
|
-
|
|
31804
|
-
const
|
|
31805
|
-
|
|
31806
|
-
|
|
32688
|
+
function containsNonPrintableAscii(buffer, length) {
|
|
32689
|
+
const end = Math.min(length, buffer.length);
|
|
32690
|
+
for (let i = 0; i < end; i++) {
|
|
32691
|
+
const byte = buffer[i];
|
|
32692
|
+
if (byte < 32 || byte > 126) {
|
|
31807
32693
|
return true;
|
|
31808
32694
|
}
|
|
31809
|
-
await sleep4(50);
|
|
31810
32695
|
}
|
|
31811
|
-
return
|
|
32696
|
+
return false;
|
|
31812
32697
|
}
|
|
31813
|
-
function
|
|
31814
|
-
|
|
32698
|
+
function chromeDateToUnixSeconds(chromeTimestamp) {
|
|
32699
|
+
const ts = BigInt(chromeTimestamp);
|
|
32700
|
+
if (ts <= 0n) {
|
|
32701
|
+
return -1;
|
|
32702
|
+
}
|
|
32703
|
+
return Number((ts - CHROME_EPOCH_OFFSET) / 1000000n);
|
|
31815
32704
|
}
|
|
31816
|
-
|
|
31817
|
-
|
|
32705
|
+
function chromeSameSiteToString(value) {
|
|
32706
|
+
const v = Number(value);
|
|
32707
|
+
if (v === 0) return "None";
|
|
32708
|
+
if (v === 1) return "Lax";
|
|
32709
|
+
if (v === 2) return "Strict";
|
|
32710
|
+
return void 0;
|
|
31818
32711
|
}
|
|
31819
32712
|
|
|
31820
32713
|
// src/cloud/cookie-sync.ts
|
|
@@ -31870,14 +32763,14 @@ function toPortableBrowserProfileCookieRecord(cookie) {
|
|
|
31870
32763
|
if (!name || !domain) {
|
|
31871
32764
|
return null;
|
|
31872
32765
|
}
|
|
31873
|
-
const
|
|
32766
|
+
const path15 = typeof cookie.path === "string" && cookie.path.trim().length > 0 ? cookie.path : "/";
|
|
31874
32767
|
const expiresAt = typeof cookie.expires === "number" && Number.isFinite(cookie.expires) && cookie.expires > 0 ? Math.floor(cookie.expires * 1e3) : null;
|
|
31875
32768
|
const sameSite = normalizeSameSite(cookie.sameSite);
|
|
31876
32769
|
return {
|
|
31877
32770
|
name,
|
|
31878
32771
|
value: cookie.value,
|
|
31879
32772
|
domain,
|
|
31880
|
-
path:
|
|
32773
|
+
path: path15,
|
|
31881
32774
|
secure: cookie.secure,
|
|
31882
32775
|
httpOnly: cookie.httpOnly,
|
|
31883
32776
|
...sameSite === void 0 ? {} : { sameSite },
|
|
@@ -31893,114 +32786,48 @@ function normalizeSameSite(value) {
|
|
|
31893
32786
|
return void 0;
|
|
31894
32787
|
}
|
|
31895
32788
|
|
|
31896
|
-
// src/cloud/portable-cookie-snapshot.ts
|
|
31897
|
-
var gzip = promisify(gzip$1);
|
|
31898
|
-
async function capturePortableBrowserProfileSnapshot(input = {}) {
|
|
31899
|
-
const attached = input.attachEndpoint ? await inspectCdpEndpoint({
|
|
31900
|
-
endpoint: input.attachEndpoint,
|
|
31901
|
-
...input.timeoutMs === void 0 ? {} : { timeoutMs: input.timeoutMs }
|
|
31902
|
-
}) : await selectAttachBrowserCandidate({
|
|
31903
|
-
...input.timeoutMs === void 0 ? {} : { timeoutMs: input.timeoutMs }
|
|
31904
|
-
});
|
|
31905
|
-
const browser = await connectPlaywrightChromiumBrowser({
|
|
31906
|
-
url: attached.endpoint
|
|
31907
|
-
});
|
|
31908
|
-
try {
|
|
31909
|
-
const context = browser.contexts()[0];
|
|
31910
|
-
if (!context) {
|
|
31911
|
-
throw new Error("Attached browser did not expose a default browser context.");
|
|
31912
|
-
}
|
|
31913
|
-
const prepared = prepareBrowserProfileSyncCookies({
|
|
31914
|
-
cookies: await context.cookies(),
|
|
31915
|
-
...input.domains === void 0 ? {} : { domains: input.domains }
|
|
31916
|
-
});
|
|
31917
|
-
if (prepared.cookies.length === 0) {
|
|
31918
|
-
throw new Error("No syncable cookies found for the selected browser and scope.");
|
|
31919
|
-
}
|
|
31920
|
-
const browserVersion = browser.version();
|
|
31921
|
-
const source = parseSnapshotSource(attached.browser ?? browserVersion);
|
|
31922
|
-
return {
|
|
31923
|
-
version: "portable-cookies-v1",
|
|
31924
|
-
source: {
|
|
31925
|
-
browserFamily: "chromium",
|
|
31926
|
-
...source.browserName === void 0 ? {} : { browserName: source.browserName },
|
|
31927
|
-
...source.browserMajor === void 0 ? {} : { browserMajor: source.browserMajor },
|
|
31928
|
-
...input.browserBrand === void 0 ? {} : { browserBrand: input.browserBrand },
|
|
31929
|
-
...input.captureMethod === void 0 ? {} : { captureMethod: input.captureMethod },
|
|
31930
|
-
platform: normalizePlatform(process.platform),
|
|
31931
|
-
capturedAt: Date.now()
|
|
31932
|
-
},
|
|
31933
|
-
cookies: prepared.cookies
|
|
31934
|
-
};
|
|
31935
|
-
} finally {
|
|
31936
|
-
await browser.close().catch(() => void 0);
|
|
31937
|
-
}
|
|
31938
|
-
}
|
|
31939
|
-
async function encodePortableBrowserProfileSnapshot(snapshot) {
|
|
31940
|
-
return gzip(Buffer.from(JSON.stringify(snapshot), "utf8"));
|
|
31941
|
-
}
|
|
31942
|
-
function parseSnapshotSource(value) {
|
|
31943
|
-
if (!value) {
|
|
31944
|
-
return {};
|
|
31945
|
-
}
|
|
31946
|
-
const trimmed = value.trim();
|
|
31947
|
-
const browserName = trimmed.split("/")[0]?.trim() || void 0;
|
|
31948
|
-
const majorMatch = trimmed.match(/(\d+)/);
|
|
31949
|
-
return {
|
|
31950
|
-
...browserName === void 0 ? {} : { browserName },
|
|
31951
|
-
...majorMatch?.[1] === void 0 ? {} : { browserMajor: majorMatch[1] }
|
|
31952
|
-
};
|
|
31953
|
-
}
|
|
31954
|
-
function normalizePlatform(platform) {
|
|
31955
|
-
if (platform === "darwin") return "macos";
|
|
31956
|
-
if (platform === "win32") return "windows";
|
|
31957
|
-
return platform;
|
|
31958
|
-
}
|
|
31959
|
-
|
|
31960
32789
|
// src/cloud/profile-sync.ts
|
|
32790
|
+
var gzip = promisify(gzip$1);
|
|
31961
32791
|
var DEFAULT_POLL_INTERVAL_MS = 1e3;
|
|
31962
32792
|
var DEFAULT_POLL_TIMEOUT_MS = 5 * 6e4;
|
|
31963
32793
|
async function syncBrowserProfileCookies(client, input) {
|
|
31964
|
-
const
|
|
31965
|
-
...input.attachEndpoint === void 0 ? {} : { attachEndpoint: input.attachEndpoint },
|
|
32794
|
+
const result = await readBrowserCookies({
|
|
31966
32795
|
...input.brandId === void 0 ? {} : { brandId: input.brandId },
|
|
31967
32796
|
...input.userDataDir === void 0 ? {} : { userDataDir: input.userDataDir },
|
|
31968
|
-
...input.profileDirectory === void 0 ? {} : { profileDirectory: input.profileDirectory }
|
|
31969
|
-
...input.executablePath === void 0 ? {} : { executablePath: input.executablePath },
|
|
31970
|
-
...input.strategy === void 0 ? {} : { strategy: input.strategy },
|
|
31971
|
-
...input.timeoutMs === void 0 ? {} : { timeoutMs: input.timeoutMs }
|
|
32797
|
+
...input.profileDirectory === void 0 ? {} : { profileDirectory: input.profileDirectory }
|
|
31972
32798
|
});
|
|
31973
|
-
const
|
|
31974
|
-
|
|
31975
|
-
|
|
31976
|
-
|
|
31977
|
-
|
|
31978
|
-
|
|
31979
|
-
|
|
31980
|
-
|
|
31981
|
-
|
|
31982
|
-
|
|
31983
|
-
|
|
31984
|
-
|
|
31985
|
-
|
|
31986
|
-
|
|
31987
|
-
|
|
31988
|
-
|
|
31989
|
-
|
|
31990
|
-
|
|
31991
|
-
|
|
31992
|
-
|
|
31993
|
-
|
|
31994
|
-
|
|
31995
|
-
|
|
31996
|
-
|
|
31997
|
-
|
|
31998
|
-
|
|
31999
|
-
await captureSource?.cleanup().catch(() => void 0);
|
|
32000
|
-
if (shouldRestoreBrowser && resolved.executablePath !== void 0) {
|
|
32001
|
-
relaunchBrowserNormally(resolved.executablePath);
|
|
32002
|
-
}
|
|
32799
|
+
const prepared = prepareBrowserProfileSyncCookies({
|
|
32800
|
+
cookies: result.cookies,
|
|
32801
|
+
...input.domains === void 0 ? {} : { domains: input.domains }
|
|
32802
|
+
});
|
|
32803
|
+
if (prepared.cookies.length === 0) {
|
|
32804
|
+
throw new Error("No syncable cookies found for the selected browser and scope.");
|
|
32805
|
+
}
|
|
32806
|
+
const snapshot = {
|
|
32807
|
+
version: "portable-cookies-v1",
|
|
32808
|
+
source: {
|
|
32809
|
+
browserFamily: "chromium",
|
|
32810
|
+
browserBrand: result.brandId,
|
|
32811
|
+
captureMethod: "sqlite",
|
|
32812
|
+
platform: normalizePlatform(process.platform),
|
|
32813
|
+
capturedAt: Date.now()
|
|
32814
|
+
},
|
|
32815
|
+
cookies: prepared.cookies
|
|
32816
|
+
};
|
|
32817
|
+
const payload = await gzip(Buffer.from(JSON.stringify(snapshot), "utf8"));
|
|
32818
|
+
const created = await client.createBrowserProfileImport({
|
|
32819
|
+
profileId: input.profileId
|
|
32820
|
+
});
|
|
32821
|
+
if (payload.length > created.maxUploadBytes) {
|
|
32822
|
+
throw new Error(
|
|
32823
|
+
`Compressed cookie snapshot is ${String(payload.length)} bytes, exceeding the ${String(created.maxUploadBytes)} byte upload limit.`
|
|
32824
|
+
);
|
|
32003
32825
|
}
|
|
32826
|
+
const uploaded = await client.uploadBrowserProfileImportPayload({
|
|
32827
|
+
uploadUrl: created.uploadUrl,
|
|
32828
|
+
payload
|
|
32829
|
+
});
|
|
32830
|
+
return uploaded.status === "ready" ? uploaded : waitForBrowserProfileImport(client, created.importId);
|
|
32004
32831
|
}
|
|
32005
32832
|
async function waitForBrowserProfileImport(client, importId) {
|
|
32006
32833
|
const deadline = Date.now() + DEFAULT_POLL_TIMEOUT_MS;
|
|
@@ -32012,12 +32839,17 @@ async function waitForBrowserProfileImport(client, importId) {
|
|
|
32012
32839
|
if (current.status === "failed") {
|
|
32013
32840
|
throw new Error(current.error ?? "Browser profile sync failed.");
|
|
32014
32841
|
}
|
|
32015
|
-
await
|
|
32842
|
+
await sleep4(DEFAULT_POLL_INTERVAL_MS);
|
|
32016
32843
|
}
|
|
32017
32844
|
throw new Error(`Timed out waiting for browser profile sync "${importId}" to finish.`);
|
|
32018
32845
|
}
|
|
32019
|
-
|
|
32020
|
-
|
|
32846
|
+
function normalizePlatform(platform) {
|
|
32847
|
+
if (platform === "darwin") return "macos";
|
|
32848
|
+
if (platform === "win32") return "windows";
|
|
32849
|
+
return platform;
|
|
32850
|
+
}
|
|
32851
|
+
async function sleep4(ms) {
|
|
32852
|
+
await new Promise((resolve4) => setTimeout(resolve4, ms));
|
|
32021
32853
|
}
|
|
32022
32854
|
|
|
32023
32855
|
// src/cloud/client.ts
|
|
@@ -32037,7 +32869,8 @@ var OpensteerCloudClient = class {
|
|
|
32037
32869
|
...input.name === void 0 ? {} : { name: input.name },
|
|
32038
32870
|
...input.browser === void 0 ? {} : { browser: input.browser },
|
|
32039
32871
|
...input.context === void 0 ? {} : { context: input.context },
|
|
32040
|
-
...input.browserProfile === void 0 ? {} : { browserProfile: input.browserProfile }
|
|
32872
|
+
...input.browserProfile === void 0 ? {} : { browserProfile: input.browserProfile },
|
|
32873
|
+
...input.observability === void 0 ? {} : { observability: input.observability }
|
|
32041
32874
|
}
|
|
32042
32875
|
});
|
|
32043
32876
|
return await response.json();
|
|
@@ -32215,8 +33048,8 @@ var OpensteerCloudClient = class {
|
|
|
32215
33048
|
}
|
|
32216
33049
|
};
|
|
32217
33050
|
function delay(ms) {
|
|
32218
|
-
return new Promise((
|
|
32219
|
-
setTimeout(
|
|
33051
|
+
return new Promise((resolve4) => {
|
|
33052
|
+
setTimeout(resolve4, ms);
|
|
32220
33053
|
});
|
|
32221
33054
|
}
|
|
32222
33055
|
function wrapCloudFetchError(error, input) {
|
|
@@ -32239,17 +33072,17 @@ function wrapCloudFetchError(error, input) {
|
|
|
32239
33072
|
function resolveCloudConfig(input = {}) {
|
|
32240
33073
|
const provider = resolveOpensteerProvider({
|
|
32241
33074
|
...input.provider === void 0 ? {} : { provider: input.provider },
|
|
32242
|
-
...input.
|
|
33075
|
+
...input.environment?.OPENSTEER_PROVIDER === void 0 ? {} : { environmentProvider: input.environment.OPENSTEER_PROVIDER }
|
|
32243
33076
|
});
|
|
32244
33077
|
if (provider.mode !== "cloud") {
|
|
32245
33078
|
return void 0;
|
|
32246
33079
|
}
|
|
32247
33080
|
const cloudProvider = input.provider?.mode === "cloud" ? input.provider : void 0;
|
|
32248
|
-
const apiKey = cloudProvider?.apiKey ??
|
|
33081
|
+
const apiKey = cloudProvider?.apiKey ?? input.environment?.OPENSTEER_API_KEY;
|
|
32249
33082
|
if (!apiKey || apiKey.trim().length === 0) {
|
|
32250
33083
|
throw new Error("provider=cloud requires OPENSTEER_API_KEY or provider.apiKey.");
|
|
32251
33084
|
}
|
|
32252
|
-
const baseUrl = cloudProvider?.baseUrl ??
|
|
33085
|
+
const baseUrl = cloudProvider?.baseUrl ?? input.environment?.OPENSTEER_BASE_URL;
|
|
32253
33086
|
if (!baseUrl || baseUrl.trim().length === 0) {
|
|
32254
33087
|
throw new Error("provider=cloud requires OPENSTEER_BASE_URL or provider.baseUrl.");
|
|
32255
33088
|
}
|
|
@@ -32351,9 +33184,9 @@ var OpensteerCloudAutomationClient = class {
|
|
|
32351
33184
|
sentAt: Date.now(),
|
|
32352
33185
|
...input === void 0 ? {} : { input }
|
|
32353
33186
|
};
|
|
32354
|
-
return new Promise((
|
|
33187
|
+
return new Promise((resolve4, reject) => {
|
|
32355
33188
|
this.pending.set(requestId, {
|
|
32356
|
-
resolve: (value) =>
|
|
33189
|
+
resolve: (value) => resolve4(value),
|
|
32357
33190
|
reject
|
|
32358
33191
|
});
|
|
32359
33192
|
try {
|
|
@@ -32416,8 +33249,8 @@ var OpensteerCloudAutomationClient = class {
|
|
|
32416
33249
|
pending.reject(new Error(`automation connection closed before ${requestId} completed`));
|
|
32417
33250
|
}
|
|
32418
33251
|
this.pending.clear();
|
|
32419
|
-
await new Promise((
|
|
32420
|
-
socket.once("close", () =>
|
|
33252
|
+
await new Promise((resolve4) => {
|
|
33253
|
+
socket.once("close", () => resolve4());
|
|
32421
33254
|
socket.close();
|
|
32422
33255
|
}).catch(() => void 0);
|
|
32423
33256
|
}
|
|
@@ -32459,8 +33292,8 @@ var OpensteerCloudAutomationClient = class {
|
|
|
32459
33292
|
}
|
|
32460
33293
|
this.pending.clear();
|
|
32461
33294
|
});
|
|
32462
|
-
await new Promise((
|
|
32463
|
-
socket.once("open", () =>
|
|
33295
|
+
await new Promise((resolve4, reject) => {
|
|
33296
|
+
socket.once("open", () => resolve4());
|
|
32464
33297
|
socket.once("error", reject);
|
|
32465
33298
|
});
|
|
32466
33299
|
this.send({
|
|
@@ -32801,6 +33634,7 @@ var CloudSessionProxy = class {
|
|
|
32801
33634
|
workspace;
|
|
32802
33635
|
cleanupRootOnClose;
|
|
32803
33636
|
cloud;
|
|
33637
|
+
observability;
|
|
32804
33638
|
sessionId;
|
|
32805
33639
|
sessionBaseUrl;
|
|
32806
33640
|
client;
|
|
@@ -32809,8 +33643,9 @@ var CloudSessionProxy = class {
|
|
|
32809
33643
|
constructor(cloud, options = {}) {
|
|
32810
33644
|
this.cloud = cloud;
|
|
32811
33645
|
this.workspace = options.workspace;
|
|
32812
|
-
this.
|
|
32813
|
-
|
|
33646
|
+
this.observability = options.observability;
|
|
33647
|
+
this.rootPath = options.rootPath ?? (this.workspace === void 0 ? path7.join(tmpdir(), `${TEMPORARY_CLOUD_WORKSPACE_PREFIX}${randomUUID()}`) : resolveFilesystemWorkspacePath({
|
|
33648
|
+
rootDir: path7.resolve(options.rootDir ?? process.cwd()),
|
|
32814
33649
|
workspace: this.workspace
|
|
32815
33650
|
}));
|
|
32816
33651
|
this.cleanupRootOnClose = options.cleanupRootOnClose ?? this.workspace === void 0;
|
|
@@ -33153,6 +33988,7 @@ var CloudSessionProxy = class {
|
|
|
33153
33988
|
...this.workspace === void 0 ? {} : { name: this.workspace },
|
|
33154
33989
|
...input.launch === void 0 ? {} : { browser: input.launch },
|
|
33155
33990
|
...input.context === void 0 ? {} : { context: input.context },
|
|
33991
|
+
...this.observability === void 0 ? {} : { observability: this.observability },
|
|
33156
33992
|
...resolveCloudBrowserProfile(this.cloud, input) === void 0 ? {} : { browserProfile: resolveCloudBrowserProfile(this.cloud, input) }
|
|
33157
33993
|
});
|
|
33158
33994
|
const record = {
|
|
@@ -33250,16 +34086,17 @@ function isMissingCloudSessionError(error) {
|
|
|
33250
34086
|
|
|
33251
34087
|
// src/sdk/runtime-resolution.ts
|
|
33252
34088
|
function resolveOpensteerRuntimeConfig(input = {}) {
|
|
34089
|
+
const environment = input.environment ?? process.env;
|
|
33253
34090
|
const provider = resolveOpensteerProvider({
|
|
33254
34091
|
...input.provider === void 0 ? {} : { provider: input.provider },
|
|
33255
|
-
...
|
|
34092
|
+
...environment.OPENSTEER_PROVIDER === void 0 ? {} : { environmentProvider: environment.OPENSTEER_PROVIDER }
|
|
33256
34093
|
});
|
|
33257
34094
|
if (provider.mode === "cloud") {
|
|
33258
34095
|
return {
|
|
33259
34096
|
provider,
|
|
33260
34097
|
cloud: resolveCloudConfig({
|
|
33261
34098
|
...input.provider === void 0 ? {} : { provider: input.provider },
|
|
33262
|
-
|
|
34099
|
+
environment
|
|
33263
34100
|
})
|
|
33264
34101
|
};
|
|
33265
34102
|
}
|
|
@@ -33270,7 +34107,7 @@ function createOpensteerSemanticRuntime(input = {}) {
|
|
|
33270
34107
|
const engine = input.engine ?? runtimeOptions.engineName ?? DEFAULT_OPENSTEER_ENGINE;
|
|
33271
34108
|
const config = resolveOpensteerRuntimeConfig({
|
|
33272
34109
|
...input.provider === void 0 ? {} : { provider: input.provider },
|
|
33273
|
-
...
|
|
34110
|
+
...input.environment === void 0 ? {} : { environment: input.environment }
|
|
33274
34111
|
});
|
|
33275
34112
|
assertProviderSupportsEngine(config.provider.mode, engine);
|
|
33276
34113
|
if (config.provider.mode === "cloud") {
|
|
@@ -33278,7 +34115,8 @@ function createOpensteerSemanticRuntime(input = {}) {
|
|
|
33278
34115
|
...runtimeOptions.rootDir === void 0 ? {} : { rootDir: runtimeOptions.rootDir },
|
|
33279
34116
|
...runtimeOptions.rootPath === void 0 ? {} : { rootPath: runtimeOptions.rootPath },
|
|
33280
34117
|
...runtimeOptions.workspace === void 0 ? {} : { workspace: runtimeOptions.workspace },
|
|
33281
|
-
...runtimeOptions.cleanupRootOnClose === void 0 ? {} : { cleanupRootOnClose: runtimeOptions.cleanupRootOnClose }
|
|
34118
|
+
...runtimeOptions.cleanupRootOnClose === void 0 ? {} : { cleanupRootOnClose: runtimeOptions.cleanupRootOnClose },
|
|
34119
|
+
...runtimeOptions.observability === void 0 ? {} : { observability: runtimeOptions.observability }
|
|
33282
34120
|
});
|
|
33283
34121
|
}
|
|
33284
34122
|
return new OpensteerRuntime({
|
|
@@ -33286,7 +34124,109 @@ function createOpensteerSemanticRuntime(input = {}) {
|
|
|
33286
34124
|
engineName: engine
|
|
33287
34125
|
});
|
|
33288
34126
|
}
|
|
34127
|
+
var ENV_FILENAMES = [".env", ".env.local"];
|
|
34128
|
+
var OPENSTEER_ENV_PREFIX = "OPENSTEER_";
|
|
34129
|
+
var opensteerEnvironmentCache = /* @__PURE__ */ new Map();
|
|
34130
|
+
function resolveOpensteerEnvironment(cwd = process.cwd(), baseEnv = process.env) {
|
|
34131
|
+
const resolvedCwd = path7.resolve(cwd);
|
|
34132
|
+
const signature = buildEnvironmentSignature(baseEnv, isOpensteerEnvironmentKey);
|
|
34133
|
+
const cached = opensteerEnvironmentCache.get(resolvedCwd);
|
|
34134
|
+
if (cached && cached.signature === signature) {
|
|
34135
|
+
return { ...cached.values };
|
|
34136
|
+
}
|
|
34137
|
+
const resolved = resolveEnvironmentFiles(resolvedCwd, baseEnv, isOpensteerEnvironmentKey);
|
|
34138
|
+
opensteerEnvironmentCache.set(resolvedCwd, {
|
|
34139
|
+
signature,
|
|
34140
|
+
values: { ...resolved }
|
|
34141
|
+
});
|
|
34142
|
+
return { ...resolved };
|
|
34143
|
+
}
|
|
34144
|
+
function loadEnvironment(cwd = process.cwd()) {
|
|
34145
|
+
const resolved = resolveEnvironmentFiles(path7.resolve(cwd), process.env);
|
|
34146
|
+
for (const [key, value] of Object.entries(resolved)) {
|
|
34147
|
+
process.env[key] = value;
|
|
34148
|
+
}
|
|
34149
|
+
}
|
|
34150
|
+
function collectDirectories(cwd) {
|
|
34151
|
+
const directories = [];
|
|
34152
|
+
let current = path7.resolve(cwd);
|
|
34153
|
+
for (; ; ) {
|
|
34154
|
+
directories.unshift(current);
|
|
34155
|
+
const parent = path7.dirname(current);
|
|
34156
|
+
if (parent === current) {
|
|
34157
|
+
return directories;
|
|
34158
|
+
}
|
|
34159
|
+
current = parent;
|
|
34160
|
+
}
|
|
34161
|
+
}
|
|
34162
|
+
function parseEnvFile(contents) {
|
|
34163
|
+
const parsed = {};
|
|
34164
|
+
for (const rawLine of contents.split(/\r?\n/u)) {
|
|
34165
|
+
const trimmed = rawLine.trim();
|
|
34166
|
+
if (!trimmed || trimmed.startsWith("#")) {
|
|
34167
|
+
continue;
|
|
34168
|
+
}
|
|
34169
|
+
const line = trimmed.startsWith("export ") ? trimmed.slice("export ".length) : trimmed;
|
|
34170
|
+
const separatorIndex = line.indexOf("=");
|
|
34171
|
+
if (separatorIndex <= 0) {
|
|
34172
|
+
continue;
|
|
34173
|
+
}
|
|
34174
|
+
const key = line.slice(0, separatorIndex).trim();
|
|
34175
|
+
if (!/^[A-Za-z_][A-Za-z0-9_]*$/u.test(key)) {
|
|
34176
|
+
continue;
|
|
34177
|
+
}
|
|
34178
|
+
const rawValue = line.slice(separatorIndex + 1).trim();
|
|
34179
|
+
parsed[key] = parseEnvValue(rawValue);
|
|
34180
|
+
}
|
|
34181
|
+
return parsed;
|
|
34182
|
+
}
|
|
34183
|
+
function parseEnvValue(rawValue) {
|
|
34184
|
+
if (rawValue.length >= 2 && rawValue.startsWith('"') && rawValue.endsWith('"')) {
|
|
34185
|
+
return rawValue.slice(1, -1).replace(/\\n/g, "\n").replace(/\\r/g, "\r").replace(/\\t/g, " ").replace(/\\"/g, '"');
|
|
34186
|
+
}
|
|
34187
|
+
if (rawValue.length >= 2 && rawValue.startsWith("'") && rawValue.endsWith("'")) {
|
|
34188
|
+
return rawValue.slice(1, -1);
|
|
34189
|
+
}
|
|
34190
|
+
return rawValue.replace(/\s+#.*$/u, "").trimEnd();
|
|
34191
|
+
}
|
|
34192
|
+
function resolveEnvironmentFiles(cwd, baseEnv, predicate) {
|
|
34193
|
+
const resolved = collectEnvironment(baseEnv, predicate);
|
|
34194
|
+
const protectedKeys = new Set(Object.keys(resolved));
|
|
34195
|
+
const directories = collectDirectories(cwd);
|
|
34196
|
+
for (const directory of directories) {
|
|
34197
|
+
for (const filename of ENV_FILENAMES) {
|
|
34198
|
+
const filePath = path7.join(directory, filename);
|
|
34199
|
+
if (!existsSync(filePath)) {
|
|
34200
|
+
continue;
|
|
34201
|
+
}
|
|
34202
|
+
const parsed = parseEnvFile(readFileSync(filePath, "utf8"));
|
|
34203
|
+
for (const [key, value] of Object.entries(parsed)) {
|
|
34204
|
+
if (predicate && !predicate(key) || protectedKeys.has(key)) {
|
|
34205
|
+
continue;
|
|
34206
|
+
}
|
|
34207
|
+
resolved[key] = value;
|
|
34208
|
+
}
|
|
34209
|
+
}
|
|
34210
|
+
}
|
|
34211
|
+
return resolved;
|
|
34212
|
+
}
|
|
34213
|
+
function collectEnvironment(baseEnv, predicate) {
|
|
34214
|
+
const resolved = {};
|
|
34215
|
+
for (const [key, value] of Object.entries(baseEnv)) {
|
|
34216
|
+
if (predicate && !predicate(key) || value === void 0) {
|
|
34217
|
+
continue;
|
|
34218
|
+
}
|
|
34219
|
+
resolved[key] = value;
|
|
34220
|
+
}
|
|
34221
|
+
return resolved;
|
|
34222
|
+
}
|
|
34223
|
+
function buildEnvironmentSignature(baseEnv, predicate) {
|
|
34224
|
+
return Object.entries(baseEnv).filter(([key, value]) => predicate(key) && value !== void 0).sort(([leftKey], [rightKey]) => leftKey.localeCompare(rightKey)).map(([key, value]) => `${key}=${value}`).join("\n");
|
|
34225
|
+
}
|
|
34226
|
+
function isOpensteerEnvironmentKey(key) {
|
|
34227
|
+
return key.startsWith(OPENSTEER_ENV_PREFIX);
|
|
34228
|
+
}
|
|
33289
34229
|
|
|
33290
|
-
export { CloudSessionProxy, DEFAULT_OPENSTEER_ENGINE, DEFERRED_MATCH_ATTR_KEYS, ElementPathError, MATCH_ATTRIBUTE_PRIORITY, OPENSTEER_DOM_ACTION_BRIDGE_SYMBOL, OPENSTEER_ENGINE_NAMES, OPENSTEER_FILESYSTEM_WORKSPACE_LAYOUT, OPENSTEER_FILESYSTEM_WORKSPACE_VERSION, OpensteerAttachAmbiguousError, OpensteerBrowserManager, OpensteerCloudClient, OpensteerRuntime, OpensteerSessionRuntime2 as OpensteerSessionRuntime, STABLE_PRIMARY_ATTR_KEYS, assertProviderSupportsEngine, buildArrayFieldPathCandidates, buildDomDescriptorKey, buildDomDescriptorPayload, buildDomDescriptorVersion, buildPathCandidates, buildPathSelectorHint, buildSegmentSelector, clearPersistedSessionRecord, cloneElementPath, cloneReplayElementPath, cloneStructuralElementAnchor, createDomRuntime, createFilesystemOpensteerWorkspace, createOpensteerExtractionDescriptorStore, createOpensteerSemanticRuntime, defaultFallbackPolicy, defaultPolicy, defaultRetryPolicy, defaultSettlePolicy, defaultTimeoutPolicy, delayWithSignal, discoverLocalCdpBrowsers, dispatchSemanticOperation, hashDomDescriptorDescription, inspectCdpEndpoint, isCurrentUrlField, isProcessRunning, isValidCssAttributeKey, listLocalChromeProfiles, normalizeExtractedValue, normalizeOpensteerEngineName, normalizeOpensteerProviderMode, normalizeWorkspaceId, parseDomDescriptorRecord, parseExtractionDescriptorRecord, pathExists, readPersistedCloudSessionRecord, readPersistedLocalBrowserSessionRecord, readPersistedSessionRecord, resolveCloudConfig, resolveCloudSessionRecordPath, resolveDomActionBridge, resolveExtractedValueInContext, resolveFilesystemWorkspacePath, resolveLiveSessionRecordPath, resolveLocalSessionRecordPath, resolveOpensteerEngineName, resolveOpensteerProvider, resolveOpensteerRuntimeConfig, runWithPolicyTimeout, sanitizeElementPath, sanitizeReplayElementPath, sanitizeStructuralElementAnchor, settleWithPolicy, shouldKeepAttributeForPath, writePersistedSessionRecord };
|
|
33291
|
-
//# sourceMappingURL=chunk-
|
|
33292
|
-
//# sourceMappingURL=chunk-
|
|
34230
|
+
export { CloudSessionProxy, DEFAULT_OPENSTEER_ENGINE, DEFERRED_MATCH_ATTR_KEYS, ElementPathError, MATCH_ATTRIBUTE_PRIORITY, OPENSTEER_DOM_ACTION_BRIDGE_SYMBOL, OPENSTEER_ENGINE_NAMES, OPENSTEER_FILESYSTEM_WORKSPACE_LAYOUT, OPENSTEER_FILESYSTEM_WORKSPACE_VERSION, OpensteerAttachAmbiguousError, OpensteerBrowserManager, OpensteerCloudClient, OpensteerRuntime, OpensteerSessionRuntime2 as OpensteerSessionRuntime, STABLE_PRIMARY_ATTR_KEYS, assertProviderSupportsEngine, buildArrayFieldPathCandidates, buildDomDescriptorKey, buildDomDescriptorPayload, buildDomDescriptorVersion, buildPathCandidates, buildPathSelectorHint, buildSegmentSelector, clearPersistedSessionRecord, cloneElementPath, cloneReplayElementPath, cloneStructuralElementAnchor, createArtifactStore, createDomRuntime, createFilesystemOpensteerWorkspace, createObservationStore, createOpensteerExtractionDescriptorStore, createOpensteerSemanticRuntime, defaultFallbackPolicy, defaultPolicy, defaultRetryPolicy, defaultSettlePolicy, defaultTimeoutPolicy, delayWithSignal, discoverLocalCdpBrowsers, dispatchSemanticOperation, hashDomDescriptorDescription, inspectCdpEndpoint, isCurrentUrlField, isProcessRunning, isValidCssAttributeKey, listLocalChromeProfiles, loadEnvironment, manifestToExternalBinaryLocation, normalizeExtractedValue, normalizeObservabilityConfig, normalizeOpensteerEngineName, normalizeOpensteerProviderMode, normalizeWorkspaceId, parseDomDescriptorRecord, parseExtractionDescriptorRecord, pathExists, readPersistedCloudSessionRecord, readPersistedLocalBrowserSessionRecord, readPersistedSessionRecord, resolveCloudConfig, resolveCloudSessionRecordPath, resolveDomActionBridge, resolveExtractedValueInContext, resolveFilesystemWorkspacePath, resolveLiveSessionRecordPath, resolveLocalSessionRecordPath, resolveOpensteerEngineName, resolveOpensteerEnvironment, resolveOpensteerProvider, resolveOpensteerRuntimeConfig, runWithPolicyTimeout, sanitizeElementPath, sanitizeReplayElementPath, sanitizeStructuralElementAnchor, settleWithPolicy, shouldKeepAttributeForPath, writePersistedSessionRecord };
|
|
34231
|
+
//# sourceMappingURL=chunk-RO6WAWWG.js.map
|
|
34232
|
+
//# sourceMappingURL=chunk-RO6WAWWG.js.map
|