opensteer 0.8.8 → 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 +4 -4
- package/dist/{chunk-3QJGBVWT.js → chunk-RO6WAWWG.js} +1562 -790
- package/dist/chunk-RO6WAWWG.js.map +1 -0
- package/dist/cli/bin.cjs +1538 -848
- package/dist/cli/bin.cjs.map +1 -1
- package/dist/cli/bin.js +13 -71
- package/dist/cli/bin.js.map +1 -1
- package/dist/index.cjs +1602 -831
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +186 -10
- package/dist/index.d.ts +186 -10
- package/dist/index.js +6 -3
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
- package/skills/opensteer/SKILL.md +29 -72
- package/skills/opensteer/references/cli-reference.md +2 -0
- package/skills/opensteer/references/request-workflow.md +3 -16
- package/skills/opensteer/references/sdk-reference.md +2 -0
- package/dist/chunk-3QJGBVWT.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
|
}
|
|
@@ -7048,9 +7596,9 @@ function compareByCreatedAtAndId(left, right) {
|
|
|
7048
7596
|
var FilesystemRegistryStore = class {
|
|
7049
7597
|
constructor(rootPath, registryRelativePath) {
|
|
7050
7598
|
this.registryRelativePath = registryRelativePath;
|
|
7051
|
-
const basePath =
|
|
7052
|
-
this.recordsDirectory =
|
|
7053
|
-
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");
|
|
7054
7602
|
}
|
|
7055
7603
|
recordsDirectory;
|
|
7056
7604
|
indexesDirectory;
|
|
@@ -7119,7 +7667,7 @@ var FilesystemRegistryStore = class {
|
|
|
7119
7667
|
async readRecordsFromDirectory() {
|
|
7120
7668
|
const files = await listJsonFiles(this.recordsDirectory);
|
|
7121
7669
|
const records = await Promise.all(
|
|
7122
|
-
files.map((fileName) => readJsonFile(
|
|
7670
|
+
files.map((fileName) => readJsonFile(path7.join(this.recordsDirectory, fileName)))
|
|
7123
7671
|
);
|
|
7124
7672
|
records.sort(compareByCreatedAtAndId);
|
|
7125
7673
|
return records;
|
|
@@ -7151,17 +7699,17 @@ var FilesystemRegistryStore = class {
|
|
|
7151
7699
|
return record;
|
|
7152
7700
|
}
|
|
7153
7701
|
recordPath(id) {
|
|
7154
|
-
return
|
|
7702
|
+
return path7.join(this.recordsDirectory, `${encodePathSegment(id)}.json`);
|
|
7155
7703
|
}
|
|
7156
7704
|
indexPath(key, version) {
|
|
7157
|
-
return
|
|
7705
|
+
return path7.join(
|
|
7158
7706
|
this.indexesDirectory,
|
|
7159
7707
|
encodePathSegment(key),
|
|
7160
7708
|
`${encodePathSegment(version)}.json`
|
|
7161
7709
|
);
|
|
7162
7710
|
}
|
|
7163
7711
|
writeLockPath() {
|
|
7164
|
-
return
|
|
7712
|
+
return path7.join(path7.dirname(this.recordsDirectory), ".write.lock");
|
|
7165
7713
|
}
|
|
7166
7714
|
};
|
|
7167
7715
|
var FilesystemDescriptorRegistry = class extends FilesystemRegistryStore {
|
|
@@ -7531,7 +8079,7 @@ var SqliteSavedNetworkStore = class {
|
|
|
7531
8079
|
directoryInitialization;
|
|
7532
8080
|
databaseInitialization;
|
|
7533
8081
|
constructor(rootPath) {
|
|
7534
|
-
this.databasePath =
|
|
8082
|
+
this.databasePath = path7.join(rootPath, "registry", "saved-network.sqlite");
|
|
7535
8083
|
}
|
|
7536
8084
|
async initialize() {
|
|
7537
8085
|
await this.ensureDatabaseDirectory();
|
|
@@ -7741,7 +8289,7 @@ var SqliteSavedNetworkStore = class {
|
|
|
7741
8289
|
}
|
|
7742
8290
|
}
|
|
7743
8291
|
async ensureDatabaseDirectory() {
|
|
7744
|
-
this.directoryInitialization ??= ensureDirectory(
|
|
8292
|
+
this.directoryInitialization ??= ensureDirectory(path7.dirname(this.databasePath)).catch(
|
|
7745
8293
|
(error) => {
|
|
7746
8294
|
this.directoryInitialization = void 0;
|
|
7747
8295
|
throw error;
|
|
@@ -8147,7 +8695,7 @@ var FilesystemTraceStore = class {
|
|
|
8147
8695
|
constructor(rootPath, artifacts) {
|
|
8148
8696
|
this.rootPath = rootPath;
|
|
8149
8697
|
this.artifacts = artifacts;
|
|
8150
|
-
this.runsDirectory =
|
|
8698
|
+
this.runsDirectory = path7.join(this.rootPath, "traces", "runs");
|
|
8151
8699
|
}
|
|
8152
8700
|
runsDirectory;
|
|
8153
8701
|
async initialize() {
|
|
@@ -8224,7 +8772,7 @@ var FilesystemTraceStore = class {
|
|
|
8224
8772
|
...input.error === void 0 ? {} : { error: input.error }
|
|
8225
8773
|
};
|
|
8226
8774
|
await writeJsonFileExclusive(
|
|
8227
|
-
|
|
8775
|
+
path7.join(this.runEntriesDirectory(runId), sequenceFileName(sequence)),
|
|
8228
8776
|
entry
|
|
8229
8777
|
);
|
|
8230
8778
|
await writeJsonFileAtomic(this.runManifestPath(runId), {
|
|
@@ -8243,7 +8791,7 @@ var FilesystemTraceStore = class {
|
|
|
8243
8791
|
const files = await listJsonFiles(entriesDirectory);
|
|
8244
8792
|
return Promise.all(
|
|
8245
8793
|
files.map(
|
|
8246
|
-
(fileName) => readJsonFile(
|
|
8794
|
+
(fileName) => readJsonFile(path7.join(entriesDirectory, fileName))
|
|
8247
8795
|
)
|
|
8248
8796
|
);
|
|
8249
8797
|
}
|
|
@@ -8289,16 +8837,16 @@ var FilesystemTraceStore = class {
|
|
|
8289
8837
|
return { trace, artifacts };
|
|
8290
8838
|
}
|
|
8291
8839
|
runDirectory(runId) {
|
|
8292
|
-
return
|
|
8840
|
+
return path7.join(this.runsDirectory, encodeURIComponent(runId));
|
|
8293
8841
|
}
|
|
8294
8842
|
runEntriesDirectory(runId) {
|
|
8295
|
-
return
|
|
8843
|
+
return path7.join(this.runDirectory(runId), "entries");
|
|
8296
8844
|
}
|
|
8297
8845
|
runManifestPath(runId) {
|
|
8298
|
-
return
|
|
8846
|
+
return path7.join(this.runDirectory(runId), "manifest.json");
|
|
8299
8847
|
}
|
|
8300
8848
|
runWriteLockPath(runId) {
|
|
8301
|
-
return
|
|
8849
|
+
return path7.join(this.runDirectory(runId), ".append.lock");
|
|
8302
8850
|
}
|
|
8303
8851
|
};
|
|
8304
8852
|
function createTraceStore(rootPath, artifacts) {
|
|
@@ -8312,7 +8860,7 @@ function normalizeWorkspaceId(workspace) {
|
|
|
8312
8860
|
return encodePathSegment(workspace);
|
|
8313
8861
|
}
|
|
8314
8862
|
function resolveFilesystemWorkspacePath(input) {
|
|
8315
|
-
return
|
|
8863
|
+
return path7.join(
|
|
8316
8864
|
input.rootDir,
|
|
8317
8865
|
".opensteer",
|
|
8318
8866
|
"workspaces",
|
|
@@ -8321,17 +8869,18 @@ function resolveFilesystemWorkspacePath(input) {
|
|
|
8321
8869
|
}
|
|
8322
8870
|
async function createFilesystemOpensteerWorkspace(options) {
|
|
8323
8871
|
await ensureDirectory(options.rootPath);
|
|
8324
|
-
const manifestPath =
|
|
8325
|
-
const browserPath =
|
|
8326
|
-
const browserManifestPath =
|
|
8327
|
-
const browserUserDataDir =
|
|
8328
|
-
const livePath =
|
|
8329
|
-
const liveLocalPath =
|
|
8330
|
-
const liveCloudPath =
|
|
8331
|
-
const artifactsPath =
|
|
8332
|
-
const tracesPath =
|
|
8333
|
-
const
|
|
8334
|
-
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");
|
|
8335
8884
|
let manifest;
|
|
8336
8885
|
if (await pathExists(manifestPath)) {
|
|
8337
8886
|
manifest = await readJsonFile(manifestPath);
|
|
@@ -8345,6 +8894,17 @@ async function createFilesystemOpensteerWorkspace(options) {
|
|
|
8345
8894
|
`workspace ${options.rootPath} uses unsupported version ${String(manifest.version)}`
|
|
8346
8895
|
);
|
|
8347
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
|
+
}
|
|
8348
8908
|
} else {
|
|
8349
8909
|
const createdAt = normalizeTimestamp("createdAt", options.createdAt ?? Date.now());
|
|
8350
8910
|
manifest = {
|
|
@@ -8359,6 +8919,7 @@ async function createFilesystemOpensteerWorkspace(options) {
|
|
|
8359
8919
|
live: "live",
|
|
8360
8920
|
artifacts: "artifacts",
|
|
8361
8921
|
traces: "traces",
|
|
8922
|
+
observations: "observations",
|
|
8362
8923
|
registry: "registry"
|
|
8363
8924
|
}
|
|
8364
8925
|
};
|
|
@@ -8370,6 +8931,7 @@ async function createFilesystemOpensteerWorkspace(options) {
|
|
|
8370
8931
|
ensureDirectory(livePath),
|
|
8371
8932
|
ensureDirectory(artifactsPath),
|
|
8372
8933
|
ensureDirectory(tracesPath),
|
|
8934
|
+
ensureDirectory(observationsPath),
|
|
8373
8935
|
ensureDirectory(registryPath)
|
|
8374
8936
|
]);
|
|
8375
8937
|
const artifacts = createArtifactStore(options.rootPath);
|
|
@@ -8394,6 +8956,8 @@ async function createFilesystemOpensteerWorkspace(options) {
|
|
|
8394
8956
|
await reverseReports.initialize();
|
|
8395
8957
|
const traces = createTraceStore(options.rootPath, artifacts);
|
|
8396
8958
|
await traces.initialize();
|
|
8959
|
+
const observations = createObservationStore(options.rootPath, artifacts);
|
|
8960
|
+
await observations.initialize();
|
|
8397
8961
|
return {
|
|
8398
8962
|
rootPath: options.rootPath,
|
|
8399
8963
|
manifestPath,
|
|
@@ -8406,10 +8970,12 @@ async function createFilesystemOpensteerWorkspace(options) {
|
|
|
8406
8970
|
liveCloudPath,
|
|
8407
8971
|
artifactsPath,
|
|
8408
8972
|
tracesPath,
|
|
8973
|
+
observationsPath,
|
|
8409
8974
|
registryPath,
|
|
8410
8975
|
lockPath,
|
|
8411
8976
|
artifacts,
|
|
8412
8977
|
traces,
|
|
8978
|
+
observations,
|
|
8413
8979
|
registry: {
|
|
8414
8980
|
descriptors,
|
|
8415
8981
|
requestPlans,
|
|
@@ -8596,10 +9162,10 @@ function delayWithSignal(delayMs, signal) {
|
|
|
8596
9162
|
if (signal.aborted) {
|
|
8597
9163
|
return Promise.reject(signal.reason ?? abortError());
|
|
8598
9164
|
}
|
|
8599
|
-
return new Promise((
|
|
9165
|
+
return new Promise((resolve4, reject) => {
|
|
8600
9166
|
const timer = setTimeout(() => {
|
|
8601
9167
|
signal.removeEventListener("abort", onAbort);
|
|
8602
|
-
|
|
9168
|
+
resolve4();
|
|
8603
9169
|
}, delayMs);
|
|
8604
9170
|
const onAbort = () => {
|
|
8605
9171
|
clearTimeout(timer);
|
|
@@ -9064,9 +9630,9 @@ var IFRAME_URL_ATTRIBUTES = /* @__PURE__ */ new Set([
|
|
|
9064
9630
|
"poster",
|
|
9065
9631
|
"ping"
|
|
9066
9632
|
]);
|
|
9067
|
-
function buildArrayFieldPathCandidates(
|
|
9068
|
-
const strict =
|
|
9069
|
-
const relaxedNodes = stripPositionClauses(
|
|
9633
|
+
function buildArrayFieldPathCandidates(path15) {
|
|
9634
|
+
const strict = path15.nodes.length ? buildPathCandidates(path15.nodes) : [];
|
|
9635
|
+
const relaxedNodes = stripPositionClauses(path15.nodes);
|
|
9070
9636
|
const relaxed = relaxedNodes.length ? buildPathCandidates(relaxedNodes) : [];
|
|
9071
9637
|
return dedupeSelectors([...strict, ...relaxed]);
|
|
9072
9638
|
}
|
|
@@ -9596,18 +10162,18 @@ function cloneStructuralElementAnchor(anchor) {
|
|
|
9596
10162
|
nodes: anchor.nodes.map(clonePathNode)
|
|
9597
10163
|
};
|
|
9598
10164
|
}
|
|
9599
|
-
function cloneReplayElementPath(
|
|
10165
|
+
function cloneReplayElementPath(path15) {
|
|
9600
10166
|
return {
|
|
9601
10167
|
resolution: "deterministic",
|
|
9602
|
-
context: cloneContext(
|
|
9603
|
-
nodes:
|
|
10168
|
+
context: cloneContext(path15.context),
|
|
10169
|
+
nodes: path15.nodes.map(clonePathNode)
|
|
9604
10170
|
};
|
|
9605
10171
|
}
|
|
9606
|
-
function cloneElementPath(
|
|
9607
|
-
return cloneReplayElementPath(
|
|
10172
|
+
function cloneElementPath(path15) {
|
|
10173
|
+
return cloneReplayElementPath(path15);
|
|
9608
10174
|
}
|
|
9609
|
-
function buildPathSelectorHint(
|
|
9610
|
-
const nodes =
|
|
10175
|
+
function buildPathSelectorHint(path15) {
|
|
10176
|
+
const nodes = path15?.nodes || [];
|
|
9611
10177
|
const last = nodes[nodes.length - 1];
|
|
9612
10178
|
if (!last) {
|
|
9613
10179
|
return "*";
|
|
@@ -9656,15 +10222,15 @@ function sanitizeStructuralElementAnchor(anchor) {
|
|
|
9656
10222
|
nodes: sanitizeNodes(anchor.nodes)
|
|
9657
10223
|
};
|
|
9658
10224
|
}
|
|
9659
|
-
function sanitizeReplayElementPath(
|
|
10225
|
+
function sanitizeReplayElementPath(path15) {
|
|
9660
10226
|
return {
|
|
9661
10227
|
resolution: "deterministic",
|
|
9662
|
-
context: sanitizeContext(
|
|
9663
|
-
nodes: sanitizeNodes(
|
|
10228
|
+
context: sanitizeContext(path15.context),
|
|
10229
|
+
nodes: sanitizeNodes(path15.nodes)
|
|
9664
10230
|
};
|
|
9665
10231
|
}
|
|
9666
|
-
function sanitizeElementPath(
|
|
9667
|
-
return sanitizeReplayElementPath(
|
|
10232
|
+
function sanitizeElementPath(path15) {
|
|
10233
|
+
return sanitizeReplayElementPath(path15);
|
|
9668
10234
|
}
|
|
9669
10235
|
function buildLocalStructuralElementAnchor(index, rawTargetNode) {
|
|
9670
10236
|
const targetNode = requireElementNode(index, rawTargetNode);
|
|
@@ -9787,8 +10353,8 @@ function buildTargetNotFoundMessage(domPath, diagnostics) {
|
|
|
9787
10353
|
}
|
|
9788
10354
|
return `${base} Target depth ${String(depth)}. Candidate counts: ${sample}.`;
|
|
9789
10355
|
}
|
|
9790
|
-
function buildArrayFieldCandidates(
|
|
9791
|
-
return buildArrayFieldPathCandidates(
|
|
10356
|
+
function buildArrayFieldCandidates(path15) {
|
|
10357
|
+
return buildArrayFieldPathCandidates(path15);
|
|
9792
10358
|
}
|
|
9793
10359
|
function firstDefinedAttribute(node, keys) {
|
|
9794
10360
|
for (const key of keys) {
|
|
@@ -10295,14 +10861,16 @@ var DomActionExecutor = class {
|
|
|
10295
10861
|
...input.timeout === void 0 ? {} : { timeout: input.timeout }
|
|
10296
10862
|
},
|
|
10297
10863
|
async (pointerTarget, point, timeout) => {
|
|
10298
|
-
|
|
10864
|
+
const events = [];
|
|
10865
|
+
const moved = await timeout.runStep(
|
|
10299
10866
|
() => this.options.engine.mouseMove({
|
|
10300
10867
|
pageRef: pointerTarget.resolved.pageRef,
|
|
10301
10868
|
point,
|
|
10302
10869
|
coordinateSpace: "document-css"
|
|
10303
10870
|
})
|
|
10304
10871
|
);
|
|
10305
|
-
|
|
10872
|
+
events.push(...moved.events);
|
|
10873
|
+
const clicked = await timeout.runStep(
|
|
10306
10874
|
() => this.options.engine.mouseClick({
|
|
10307
10875
|
pageRef: pointerTarget.resolved.pageRef,
|
|
10308
10876
|
point,
|
|
@@ -10312,7 +10880,12 @@ var DomActionExecutor = class {
|
|
|
10312
10880
|
...input.modifiers === void 0 ? {} : { modifiers: input.modifiers }
|
|
10313
10881
|
})
|
|
10314
10882
|
);
|
|
10315
|
-
|
|
10883
|
+
events.push(...clicked.events);
|
|
10884
|
+
return {
|
|
10885
|
+
resolved: pointerTarget.original,
|
|
10886
|
+
point,
|
|
10887
|
+
...events.length === 0 ? {} : { events }
|
|
10888
|
+
};
|
|
10316
10889
|
}
|
|
10317
10890
|
);
|
|
10318
10891
|
}
|
|
@@ -10326,14 +10899,18 @@ var DomActionExecutor = class {
|
|
|
10326
10899
|
...input.timeout === void 0 ? {} : { timeout: input.timeout }
|
|
10327
10900
|
},
|
|
10328
10901
|
async (pointerTarget, point, timeout) => {
|
|
10329
|
-
await timeout.runStep(
|
|
10902
|
+
const moved = await timeout.runStep(
|
|
10330
10903
|
() => this.options.engine.mouseMove({
|
|
10331
10904
|
pageRef: pointerTarget.resolved.pageRef,
|
|
10332
10905
|
point,
|
|
10333
10906
|
coordinateSpace: "document-css"
|
|
10334
10907
|
})
|
|
10335
10908
|
);
|
|
10336
|
-
return {
|
|
10909
|
+
return {
|
|
10910
|
+
resolved: pointerTarget.original,
|
|
10911
|
+
point,
|
|
10912
|
+
...moved.events.length === 0 ? {} : { events: moved.events }
|
|
10913
|
+
};
|
|
10337
10914
|
}
|
|
10338
10915
|
);
|
|
10339
10916
|
}
|
|
@@ -10347,14 +10924,16 @@ var DomActionExecutor = class {
|
|
|
10347
10924
|
...input.timeout === void 0 ? {} : { timeout: input.timeout }
|
|
10348
10925
|
},
|
|
10349
10926
|
async (pointerTarget, point, timeout) => {
|
|
10350
|
-
|
|
10927
|
+
const events = [];
|
|
10928
|
+
const moved = await timeout.runStep(
|
|
10351
10929
|
() => this.options.engine.mouseMove({
|
|
10352
10930
|
pageRef: pointerTarget.resolved.pageRef,
|
|
10353
10931
|
point,
|
|
10354
10932
|
coordinateSpace: "document-css"
|
|
10355
10933
|
})
|
|
10356
10934
|
);
|
|
10357
|
-
|
|
10935
|
+
events.push(...moved.events);
|
|
10936
|
+
const scrolled = await timeout.runStep(
|
|
10358
10937
|
() => this.options.engine.mouseScroll({
|
|
10359
10938
|
pageRef: pointerTarget.resolved.pageRef,
|
|
10360
10939
|
point,
|
|
@@ -10362,7 +10941,12 @@ var DomActionExecutor = class {
|
|
|
10362
10941
|
delta: input.delta
|
|
10363
10942
|
})
|
|
10364
10943
|
);
|
|
10365
|
-
|
|
10944
|
+
events.push(...scrolled.events);
|
|
10945
|
+
return {
|
|
10946
|
+
resolved: pointerTarget.original,
|
|
10947
|
+
point,
|
|
10948
|
+
...events.length === 0 ? {} : { events }
|
|
10949
|
+
};
|
|
10366
10950
|
}
|
|
10367
10951
|
);
|
|
10368
10952
|
}
|
|
@@ -11288,21 +11872,21 @@ var DefaultDomRuntime = class {
|
|
|
11288
11872
|
return match;
|
|
11289
11873
|
}
|
|
11290
11874
|
async resolvePathTarget(session, pageRef, rawPath, source, description, descriptor) {
|
|
11291
|
-
const
|
|
11292
|
-
const context = await this.resolvePathContext(session, pageRef,
|
|
11293
|
-
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);
|
|
11294
11878
|
if (!target) {
|
|
11295
|
-
throwTargetNotFound(context.index,
|
|
11879
|
+
throwTargetNotFound(context.index, path15.nodes, context.scope);
|
|
11296
11880
|
}
|
|
11297
11881
|
if (target.node.nodeRef === void 0) {
|
|
11298
11882
|
throw new Error(
|
|
11299
|
-
`resolved path "${buildPathSelectorHint(
|
|
11883
|
+
`resolved path "${buildPathSelectorHint(path15)}" does not point to a live element`
|
|
11300
11884
|
);
|
|
11301
11885
|
}
|
|
11302
11886
|
const anchor = await this.buildAnchorFromSnapshotNode(session, context.snapshot, target.node);
|
|
11303
11887
|
return this.createResolvedTarget(source, context.snapshot, target.node, anchor, {
|
|
11304
11888
|
...description === void 0 ? {} : { description },
|
|
11305
|
-
replayPath:
|
|
11889
|
+
replayPath: path15,
|
|
11306
11890
|
...source === "path" || source === "descriptor" ? { selectorUsed: target.selector } : {},
|
|
11307
11891
|
...descriptor === void 0 ? {} : { descriptor }
|
|
11308
11892
|
});
|
|
@@ -11323,9 +11907,9 @@ var DefaultDomRuntime = class {
|
|
|
11323
11907
|
});
|
|
11324
11908
|
}
|
|
11325
11909
|
async queryAllByElementPath(session, pageRef, rawPath) {
|
|
11326
|
-
const
|
|
11327
|
-
const context = await this.resolvePathContext(session, pageRef,
|
|
11328
|
-
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(
|
|
11329
11913
|
(node) => node.nodeRef !== void 0
|
|
11330
11914
|
).map((node) => this.createSnapshotTarget(context.snapshot, node));
|
|
11331
11915
|
}
|
|
@@ -11511,16 +12095,16 @@ var DefaultDomRuntime = class {
|
|
|
11511
12095
|
const index = createSnapshotIndex(item.snapshot);
|
|
11512
12096
|
return this.resolveFirstArrayFieldTargetInNode(index, item.node, field.path);
|
|
11513
12097
|
}
|
|
11514
|
-
resolveFirstArrayFieldTargetInNode(index, rootNode,
|
|
11515
|
-
const normalizedPath = sanitizeElementPath(
|
|
12098
|
+
resolveFirstArrayFieldTargetInNode(index, rootNode, path15) {
|
|
12099
|
+
const normalizedPath = sanitizeElementPath(path15);
|
|
11516
12100
|
const selectors = buildArrayFieldCandidates(normalizedPath);
|
|
11517
12101
|
if (!selectors.length) {
|
|
11518
12102
|
return rootNode;
|
|
11519
12103
|
}
|
|
11520
12104
|
return resolveFirstWithinNodeBySelectors(index, rootNode, selectors);
|
|
11521
12105
|
}
|
|
11522
|
-
resolveUniqueArrayFieldTargetInNode(index, rootNode,
|
|
11523
|
-
const normalizedPath = sanitizeElementPath(
|
|
12106
|
+
resolveUniqueArrayFieldTargetInNode(index, rootNode, path15) {
|
|
12107
|
+
const normalizedPath = sanitizeElementPath(path15);
|
|
11524
12108
|
const selectors = buildArrayFieldCandidates(normalizedPath);
|
|
11525
12109
|
if (!selectors.length) {
|
|
11526
12110
|
return rootNode;
|
|
@@ -11609,8 +12193,8 @@ function encodeDataPath(tokens) {
|
|
|
11609
12193
|
}
|
|
11610
12194
|
return out;
|
|
11611
12195
|
}
|
|
11612
|
-
function parseDataPath(
|
|
11613
|
-
const input =
|
|
12196
|
+
function parseDataPath(path15) {
|
|
12197
|
+
const input = path15.trim();
|
|
11614
12198
|
if (input.length === 0) {
|
|
11615
12199
|
return [];
|
|
11616
12200
|
}
|
|
@@ -11660,8 +12244,8 @@ function parseDataPath(path13) {
|
|
|
11660
12244
|
function inflateDataPathObject(flat) {
|
|
11661
12245
|
let root = {};
|
|
11662
12246
|
let initialized = false;
|
|
11663
|
-
for (const [
|
|
11664
|
-
const tokens = parseDataPath(
|
|
12247
|
+
for (const [path15, value] of Object.entries(flat)) {
|
|
12248
|
+
const tokens = parseDataPath(path15);
|
|
11665
12249
|
if (!tokens || tokens.length === 0) {
|
|
11666
12250
|
continue;
|
|
11667
12251
|
}
|
|
@@ -11993,8 +12577,8 @@ function buildVariantDescriptorFromCluster(descriptors) {
|
|
|
11993
12577
|
fields: mergedFields
|
|
11994
12578
|
};
|
|
11995
12579
|
}
|
|
11996
|
-
function minimizePathMatchClauses(
|
|
11997
|
-
const normalized = sanitizeElementPath(
|
|
12580
|
+
function minimizePathMatchClauses(path15, mode) {
|
|
12581
|
+
const normalized = sanitizeElementPath(path15);
|
|
11998
12582
|
const nodes = normalized.nodes.map((node, index) => {
|
|
11999
12583
|
const isLast = index === normalized.nodes.length - 1;
|
|
12000
12584
|
const attrs = node.attrs || {};
|
|
@@ -12098,8 +12682,8 @@ function seedMinimalAttrClause(attrs) {
|
|
|
12098
12682
|
}
|
|
12099
12683
|
return null;
|
|
12100
12684
|
}
|
|
12101
|
-
function relaxPathForSingleSample(
|
|
12102
|
-
const normalized = sanitizeElementPath(
|
|
12685
|
+
function relaxPathForSingleSample(path15, mode) {
|
|
12686
|
+
const normalized = sanitizeElementPath(path15);
|
|
12103
12687
|
const relaxedNodes = normalized.nodes.map((node, index) => {
|
|
12104
12688
|
const isLast = index === normalized.nodes.length - 1;
|
|
12105
12689
|
const attrs = normalizeAttrsForSingleSample(node.attrs || {});
|
|
@@ -12184,8 +12768,8 @@ function shouldKeepAttrForSingleSample(key) {
|
|
|
12184
12768
|
}
|
|
12185
12769
|
return true;
|
|
12186
12770
|
}
|
|
12187
|
-
function buildPathStructureKey(
|
|
12188
|
-
const normalized = sanitizeElementPath(
|
|
12771
|
+
function buildPathStructureKey(path15) {
|
|
12772
|
+
const normalized = sanitizeElementPath(path15);
|
|
12189
12773
|
return canonicalJsonString({
|
|
12190
12774
|
context: (normalized.context || []).map((hop) => ({
|
|
12191
12775
|
kind: hop.kind,
|
|
@@ -12312,30 +12896,30 @@ function buildArrayItemNode(fields) {
|
|
|
12312
12896
|
}
|
|
12313
12897
|
return node;
|
|
12314
12898
|
}
|
|
12315
|
-
function insertNodeAtPath(root,
|
|
12316
|
-
const tokens = parseDataPath(
|
|
12899
|
+
function insertNodeAtPath(root, path15, node) {
|
|
12900
|
+
const tokens = parseDataPath(path15);
|
|
12317
12901
|
if (!tokens || !tokens.length) {
|
|
12318
12902
|
throw new Error(
|
|
12319
|
-
`Invalid persisted extraction path "${
|
|
12903
|
+
`Invalid persisted extraction path "${path15}": expected a non-empty object path.`
|
|
12320
12904
|
);
|
|
12321
12905
|
}
|
|
12322
12906
|
if (tokens.some((token) => token.kind === "index")) {
|
|
12323
12907
|
throw new Error(
|
|
12324
|
-
`Invalid persisted extraction path "${
|
|
12908
|
+
`Invalid persisted extraction path "${path15}": nested array indices are not supported in cached descriptors.`
|
|
12325
12909
|
);
|
|
12326
12910
|
}
|
|
12327
12911
|
let current = root;
|
|
12328
12912
|
for (let index = 0; index < tokens.length; index += 1) {
|
|
12329
12913
|
const token = tokens[index];
|
|
12330
12914
|
if (!token || token.kind !== "prop") {
|
|
12331
|
-
throw new Error(`Invalid persisted extraction path "${
|
|
12915
|
+
throw new Error(`Invalid persisted extraction path "${path15}": expected object segment.`);
|
|
12332
12916
|
}
|
|
12333
12917
|
const isLast = index === tokens.length - 1;
|
|
12334
12918
|
if (isLast) {
|
|
12335
12919
|
const existing = current[token.key];
|
|
12336
12920
|
if (existing) {
|
|
12337
12921
|
throw new Error(
|
|
12338
|
-
`Conflicting persisted extraction path "${
|
|
12922
|
+
`Conflicting persisted extraction path "${path15}" detected while building descriptor tree.`
|
|
12339
12923
|
);
|
|
12340
12924
|
}
|
|
12341
12925
|
current[token.key] = node;
|
|
@@ -12350,7 +12934,7 @@ function insertNodeAtPath(root, path13, node) {
|
|
|
12350
12934
|
}
|
|
12351
12935
|
if (!isPersistedObjectNode(next)) {
|
|
12352
12936
|
throw new Error(
|
|
12353
|
-
`Conflicting persisted extraction path "${
|
|
12937
|
+
`Conflicting persisted extraction path "${path15}" detected at "${token.key}".`
|
|
12354
12938
|
);
|
|
12355
12939
|
}
|
|
12356
12940
|
current = next;
|
|
@@ -12385,7 +12969,7 @@ function buildItemRootForArrayIndex(entries) {
|
|
|
12385
12969
|
}
|
|
12386
12970
|
const paths = entries.map(
|
|
12387
12971
|
(entry) => isPersistablePathField(entry.source) ? sanitizeElementPath(entry.source.path) : null
|
|
12388
|
-
).filter((
|
|
12972
|
+
).filter((path15) => path15 !== null);
|
|
12389
12973
|
if (!paths.length) {
|
|
12390
12974
|
return null;
|
|
12391
12975
|
}
|
|
@@ -12406,7 +12990,7 @@ function getCommonPathPrefixLength(paths) {
|
|
|
12406
12990
|
if (!paths.length) {
|
|
12407
12991
|
return 0;
|
|
12408
12992
|
}
|
|
12409
|
-
const nodeChains = paths.map((
|
|
12993
|
+
const nodeChains = paths.map((path15) => path15.nodes);
|
|
12410
12994
|
const minLength = Math.min(...nodeChains.map((nodes) => nodes.length));
|
|
12411
12995
|
if (!Number.isFinite(minLength) || minLength <= 0) {
|
|
12412
12996
|
return 0;
|
|
@@ -12475,30 +13059,30 @@ function mergeElementPathsByMajority(paths) {
|
|
|
12475
13059
|
if (!paths.length) {
|
|
12476
13060
|
return null;
|
|
12477
13061
|
}
|
|
12478
|
-
const normalized = paths.map((
|
|
13062
|
+
const normalized = paths.map((path15) => sanitizeElementPath(path15));
|
|
12479
13063
|
const contextKey = pickModeString(
|
|
12480
|
-
normalized.map((
|
|
13064
|
+
normalized.map((path15) => canonicalJsonString(path15.context)),
|
|
12481
13065
|
1
|
|
12482
13066
|
);
|
|
12483
13067
|
if (!contextKey) {
|
|
12484
13068
|
return null;
|
|
12485
13069
|
}
|
|
12486
|
-
const sameContext = normalized.filter((
|
|
13070
|
+
const sameContext = normalized.filter((path15) => canonicalJsonString(path15.context) === contextKey);
|
|
12487
13071
|
if (!sameContext.length) {
|
|
12488
13072
|
return null;
|
|
12489
13073
|
}
|
|
12490
13074
|
const targetLength = pickModeNumber(
|
|
12491
|
-
sameContext.map((
|
|
13075
|
+
sameContext.map((path15) => path15.nodes.length),
|
|
12492
13076
|
1
|
|
12493
13077
|
) ?? sameContext[0]?.nodes.length ?? 0;
|
|
12494
|
-
const aligned = sameContext.filter((
|
|
13078
|
+
const aligned = sameContext.filter((path15) => path15.nodes.length === targetLength);
|
|
12495
13079
|
if (!aligned.length) {
|
|
12496
13080
|
return null;
|
|
12497
13081
|
}
|
|
12498
13082
|
const threshold = majorityThreshold(aligned.length);
|
|
12499
13083
|
const nodes = [];
|
|
12500
13084
|
for (let index = 0; index < targetLength; index += 1) {
|
|
12501
|
-
const nodesAtIndex = aligned.map((
|
|
13085
|
+
const nodesAtIndex = aligned.map((path15) => path15.nodes[index]).filter((node) => node !== void 0);
|
|
12502
13086
|
if (!nodesAtIndex.length) {
|
|
12503
13087
|
return null;
|
|
12504
13088
|
}
|
|
@@ -12744,8 +13328,8 @@ function clonePathContext(context) {
|
|
|
12744
13328
|
function clonePathNodes(nodes) {
|
|
12745
13329
|
return JSON.parse(JSON.stringify(nodes || []));
|
|
12746
13330
|
}
|
|
12747
|
-
function cloneElementPath2(
|
|
12748
|
-
return JSON.parse(JSON.stringify(
|
|
13331
|
+
function cloneElementPath2(path15) {
|
|
13332
|
+
return JSON.parse(JSON.stringify(path15));
|
|
12749
13333
|
}
|
|
12750
13334
|
function clonePersistedOpensteerExtractionNode(node) {
|
|
12751
13335
|
return JSON.parse(JSON.stringify(node));
|
|
@@ -13063,8 +13647,8 @@ function collectPersistedValueNodeRefs(node) {
|
|
|
13063
13647
|
return [
|
|
13064
13648
|
{
|
|
13065
13649
|
path: sanitizeElementPath(node.$path),
|
|
13066
|
-
replacePath: (
|
|
13067
|
-
node.$path = sanitizeElementPath(
|
|
13650
|
+
replacePath: (path15) => {
|
|
13651
|
+
node.$path = sanitizeElementPath(path15);
|
|
13068
13652
|
}
|
|
13069
13653
|
}
|
|
13070
13654
|
];
|
|
@@ -13078,13 +13662,13 @@ function collectPersistedValueNodeRefs(node) {
|
|
|
13078
13662
|
}
|
|
13079
13663
|
return refs;
|
|
13080
13664
|
}
|
|
13081
|
-
function hasPositionClause(
|
|
13082
|
-
return
|
|
13665
|
+
function hasPositionClause(path15) {
|
|
13666
|
+
return path15.nodes.some((node) => node.match.some((clause) => clause.kind === "position"));
|
|
13083
13667
|
}
|
|
13084
|
-
function stripPositionClauses2(
|
|
13668
|
+
function stripPositionClauses2(path15) {
|
|
13085
13669
|
return sanitizeElementPath({
|
|
13086
|
-
context:
|
|
13087
|
-
nodes:
|
|
13670
|
+
context: path15.context,
|
|
13671
|
+
nodes: path15.nodes.map((node) => ({
|
|
13088
13672
|
...node,
|
|
13089
13673
|
match: node.match.filter((clause) => clause.kind !== "position")
|
|
13090
13674
|
}))
|
|
@@ -13494,14 +14078,13 @@ function normalizeNonEmptyString2(name, value) {
|
|
|
13494
14078
|
function normalizeKey(value) {
|
|
13495
14079
|
return String(value ?? "").trim();
|
|
13496
14080
|
}
|
|
13497
|
-
function labelForPath(
|
|
13498
|
-
return
|
|
14081
|
+
function labelForPath(path15) {
|
|
14082
|
+
return path15.trim().length === 0 ? "$" : path15;
|
|
13499
14083
|
}
|
|
13500
14084
|
function sha256Hex3(value) {
|
|
13501
14085
|
return createHash("sha256").update(value).digest("hex");
|
|
13502
14086
|
}
|
|
13503
|
-
|
|
13504
|
-
var PS_COMMAND_ENV = { ...process.env, LC_ALL: "C" };
|
|
14087
|
+
({ ...process.env});
|
|
13505
14088
|
var WINDOWS_PROGRAM_FILES = process.env.PROGRAMFILES ?? "C:\\Program Files";
|
|
13506
14089
|
var WINDOWS_PROGRAM_FILES_X86 = process.env["PROGRAMFILES(X86)"] ?? "C:\\Program Files (x86)";
|
|
13507
14090
|
var BROWSER_BRANDS = [
|
|
@@ -13687,9 +14270,6 @@ var BROWSER_BRANDS = [
|
|
|
13687
14270
|
}
|
|
13688
14271
|
}
|
|
13689
14272
|
];
|
|
13690
|
-
function getAllBrowserBrands() {
|
|
13691
|
-
return BROWSER_BRANDS;
|
|
13692
|
-
}
|
|
13693
14273
|
function getBrowserBrand(id) {
|
|
13694
14274
|
const brand2 = BROWSER_BRANDS.find((candidate) => candidate.id === id);
|
|
13695
14275
|
if (!brand2) {
|
|
@@ -13732,28 +14312,6 @@ function detectInstalledBrowserBrands() {
|
|
|
13732
14312
|
}
|
|
13733
14313
|
return installations;
|
|
13734
14314
|
}
|
|
13735
|
-
function resolveBrandExecutablePath(brand2, explicitPath) {
|
|
13736
|
-
if (explicitPath !== void 0) {
|
|
13737
|
-
const resolvedPath2 = resolve(expandHome(explicitPath));
|
|
13738
|
-
if (!existsSync(resolvedPath2)) {
|
|
13739
|
-
throw new Error(`${brand2.displayName} executable was not found at "${resolvedPath2}".`);
|
|
13740
|
-
}
|
|
13741
|
-
return resolvedPath2;
|
|
13742
|
-
}
|
|
13743
|
-
const platformConfig = resolveBrandPlatformConfig(brand2);
|
|
13744
|
-
if (!platformConfig) {
|
|
13745
|
-
throw new Error(`${brand2.displayName} is not supported on ${process.platform}.`);
|
|
13746
|
-
}
|
|
13747
|
-
const resolvedPath = firstExistingPath(
|
|
13748
|
-
resolveExecutableCandidates(platformConfig.executableCandidates)
|
|
13749
|
-
);
|
|
13750
|
-
if (!resolvedPath) {
|
|
13751
|
-
throw new Error(
|
|
13752
|
-
`Could not find a ${brand2.displayName} executable. Pass --executable-path or browser.executablePath.`
|
|
13753
|
-
);
|
|
13754
|
-
}
|
|
13755
|
-
return resolvedPath;
|
|
13756
|
-
}
|
|
13757
14315
|
function resolveBrandUserDataDir(brand2, explicitDir) {
|
|
13758
14316
|
if (explicitDir !== void 0) {
|
|
13759
14317
|
return resolve(expandHome(explicitDir));
|
|
@@ -13764,129 +14322,9 @@ function resolveBrandUserDataDir(brand2, explicitDir) {
|
|
|
13764
14322
|
}
|
|
13765
14323
|
return resolve(expandHome(platformConfig.userDataDir));
|
|
13766
14324
|
}
|
|
13767
|
-
function isBrandProcess(brand2, commandLine) {
|
|
13768
|
-
const normalizedCommand = normalizeCommand(commandLine);
|
|
13769
|
-
if (!normalizedCommand) {
|
|
13770
|
-
return false;
|
|
13771
|
-
}
|
|
13772
|
-
if (normalizedCommand.includes("crashpad_handler")) {
|
|
13773
|
-
return false;
|
|
13774
|
-
}
|
|
13775
|
-
if (/\s--type=/.test(normalizedCommand)) {
|
|
13776
|
-
return false;
|
|
13777
|
-
}
|
|
13778
|
-
return getBrandProcessMarkers(brand2).some((marker) => normalizedCommand.includes(marker));
|
|
13779
|
-
}
|
|
13780
|
-
function findBrandProcess(brand2) {
|
|
13781
|
-
for (const processEntry of listProcesses()) {
|
|
13782
|
-
if (isBrandProcess(brand2, processEntry.commandLine)) {
|
|
13783
|
-
return { pid: processEntry.pid };
|
|
13784
|
-
}
|
|
13785
|
-
}
|
|
13786
|
-
return null;
|
|
13787
|
-
}
|
|
13788
|
-
function getBrandProcessMarkers(brand2) {
|
|
13789
|
-
const markers = /* @__PURE__ */ new Set();
|
|
13790
|
-
for (const config of [brand2.darwin, brand2.win32, brand2.linux]) {
|
|
13791
|
-
if (!config) {
|
|
13792
|
-
continue;
|
|
13793
|
-
}
|
|
13794
|
-
for (const processName of config.processNames) {
|
|
13795
|
-
const normalized = normalizeCommand(processName);
|
|
13796
|
-
if (normalized) {
|
|
13797
|
-
markers.add(normalized);
|
|
13798
|
-
}
|
|
13799
|
-
}
|
|
13800
|
-
for (const candidate of config.executableCandidates) {
|
|
13801
|
-
if (!candidate) {
|
|
13802
|
-
continue;
|
|
13803
|
-
}
|
|
13804
|
-
const normalized = normalizeCommand(resolve(expandHome(candidate)));
|
|
13805
|
-
if (normalized) {
|
|
13806
|
-
markers.add(normalized);
|
|
13807
|
-
}
|
|
13808
|
-
}
|
|
13809
|
-
}
|
|
13810
|
-
return [...markers];
|
|
13811
|
-
}
|
|
13812
14325
|
function resolveExecutableCandidates(candidates) {
|
|
13813
14326
|
return candidates.map((candidate) => candidate ? resolve(expandHome(candidate)) : null);
|
|
13814
14327
|
}
|
|
13815
|
-
function listProcesses() {
|
|
13816
|
-
if (process.platform === "win32") {
|
|
13817
|
-
return listWindowsProcesses();
|
|
13818
|
-
}
|
|
13819
|
-
return listUnixProcesses();
|
|
13820
|
-
}
|
|
13821
|
-
function listUnixProcesses() {
|
|
13822
|
-
try {
|
|
13823
|
-
const output = execFileSync("ps", ["-A", "-o", "pid=,command="], {
|
|
13824
|
-
encoding: "utf8",
|
|
13825
|
-
env: PS_COMMAND_ENV,
|
|
13826
|
-
maxBuffer: PROCESS_LIST_MAX_BUFFER_BYTES,
|
|
13827
|
-
stdio: ["ignore", "pipe", "ignore"]
|
|
13828
|
-
});
|
|
13829
|
-
return output.split(/\r?\n/).map((line) => line.trim()).filter((line) => line.length > 0).map((line) => {
|
|
13830
|
-
const match = /^(\d+)\s+(.*)$/.exec(line);
|
|
13831
|
-
if (!match) {
|
|
13832
|
-
return null;
|
|
13833
|
-
}
|
|
13834
|
-
const pid = Number.parseInt(match[1] ?? "", 10);
|
|
13835
|
-
const commandLine = match[2]?.trim() ?? "";
|
|
13836
|
-
if (!Number.isInteger(pid) || pid <= 0 || commandLine.length === 0) {
|
|
13837
|
-
return null;
|
|
13838
|
-
}
|
|
13839
|
-
return {
|
|
13840
|
-
pid,
|
|
13841
|
-
commandLine
|
|
13842
|
-
};
|
|
13843
|
-
}).filter(
|
|
13844
|
-
(entry) => entry !== null
|
|
13845
|
-
).sort((left, right) => left.pid - right.pid);
|
|
13846
|
-
} catch {
|
|
13847
|
-
return [];
|
|
13848
|
-
}
|
|
13849
|
-
}
|
|
13850
|
-
function listWindowsProcesses() {
|
|
13851
|
-
try {
|
|
13852
|
-
const output = execFileSync(
|
|
13853
|
-
"powershell.exe",
|
|
13854
|
-
[
|
|
13855
|
-
"-NoProfile",
|
|
13856
|
-
"-Command",
|
|
13857
|
-
"Get-CimInstance Win32_Process | Select-Object ProcessId,CommandLine | ConvertTo-Json -Compress"
|
|
13858
|
-
],
|
|
13859
|
-
{
|
|
13860
|
-
encoding: "utf8",
|
|
13861
|
-
maxBuffer: PROCESS_LIST_MAX_BUFFER_BYTES,
|
|
13862
|
-
stdio: ["ignore", "pipe", "ignore"]
|
|
13863
|
-
}
|
|
13864
|
-
).trim();
|
|
13865
|
-
if (!output) {
|
|
13866
|
-
return [];
|
|
13867
|
-
}
|
|
13868
|
-
const parsed = JSON.parse(output);
|
|
13869
|
-
const records = Array.isArray(parsed) ? parsed : [parsed];
|
|
13870
|
-
return records.map((record) => {
|
|
13871
|
-
const pid = Number(record.ProcessId);
|
|
13872
|
-
const commandLine = typeof record.CommandLine === "string" ? record.CommandLine.trim() : "";
|
|
13873
|
-
if (!Number.isInteger(pid) || pid <= 0 || commandLine.length === 0) {
|
|
13874
|
-
return null;
|
|
13875
|
-
}
|
|
13876
|
-
return {
|
|
13877
|
-
pid,
|
|
13878
|
-
commandLine
|
|
13879
|
-
};
|
|
13880
|
-
}).filter(
|
|
13881
|
-
(entry) => entry !== null
|
|
13882
|
-
).sort((left, right) => left.pid - right.pid);
|
|
13883
|
-
} catch {
|
|
13884
|
-
return [];
|
|
13885
|
-
}
|
|
13886
|
-
}
|
|
13887
|
-
function normalizeCommand(value) {
|
|
13888
|
-
return value.trim().replaceAll("\\", "/").toLowerCase();
|
|
13889
|
-
}
|
|
13890
14328
|
|
|
13891
14329
|
// src/local-browser/chrome-discovery.ts
|
|
13892
14330
|
function expandHome(value) {
|
|
@@ -14253,8 +14691,8 @@ function buildBrowserWebSocketUrl(httpUrl, webSocketPath) {
|
|
|
14253
14691
|
const protocol = httpUrl.protocol === "https:" ? "wss:" : "ws:";
|
|
14254
14692
|
return `${protocol}//${httpUrl.host}${normalizeWebSocketPath(webSocketPath)}`;
|
|
14255
14693
|
}
|
|
14256
|
-
function normalizeWebSocketPath(
|
|
14257
|
-
return
|
|
14694
|
+
function normalizeWebSocketPath(path15) {
|
|
14695
|
+
return path15.startsWith("/") ? path15 : `/${path15}`;
|
|
14258
14696
|
}
|
|
14259
14697
|
function rewriteBrowserWebSocketHost(browserWsUrl, requestedUrl) {
|
|
14260
14698
|
try {
|
|
@@ -14274,7 +14712,7 @@ function readPort(url) {
|
|
|
14274
14712
|
var OPENSTEER_LIVE_SESSION_LAYOUT = "opensteer-session";
|
|
14275
14713
|
var OPENSTEER_LIVE_SESSION_VERSION = 1;
|
|
14276
14714
|
function resolveLiveSessionRecordPath(rootPath, provider) {
|
|
14277
|
-
return
|
|
14715
|
+
return path7.join(rootPath, "live", provider === "local" ? "local.json" : "cloud.json");
|
|
14278
14716
|
}
|
|
14279
14717
|
function resolveLocalSessionRecordPath(rootPath) {
|
|
14280
14718
|
return resolveLiveSessionRecordPath(rootPath, "local");
|
|
@@ -15079,8 +15517,8 @@ var OpensteerBrowserManager = class {
|
|
|
15079
15517
|
...options.browser === void 0 ? {} : { browser: options.browser },
|
|
15080
15518
|
...this.contextOptions === void 0 ? {} : { context: this.contextOptions }
|
|
15081
15519
|
});
|
|
15082
|
-
this.rootPath = options.rootPath ?? (this.workspace === void 0 ?
|
|
15083
|
-
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()),
|
|
15084
15522
|
workspace: this.workspace
|
|
15085
15523
|
}));
|
|
15086
15524
|
this.cleanupRootOnDisconnect = this.workspace === void 0;
|
|
@@ -15150,7 +15588,7 @@ var OpensteerBrowserManager = class {
|
|
|
15150
15588
|
userDataDir: "browser/user-data",
|
|
15151
15589
|
bootstrap: {
|
|
15152
15590
|
kind: "cloneLocalProfile",
|
|
15153
|
-
sourceUserDataDir:
|
|
15591
|
+
sourceUserDataDir: path7.resolve(input.sourceUserDataDir),
|
|
15154
15592
|
...input.sourceProfileDirectory === void 0 ? {} : { sourceProfileDirectory: input.sourceProfileDirectory }
|
|
15155
15593
|
}
|
|
15156
15594
|
};
|
|
@@ -15277,7 +15715,7 @@ var OpensteerBrowserManager = class {
|
|
|
15277
15715
|
});
|
|
15278
15716
|
}
|
|
15279
15717
|
async createTemporaryEngine() {
|
|
15280
|
-
const userDataDir = await mkdtemp(
|
|
15718
|
+
const userDataDir = await mkdtemp(path7.join(tmpdir(), "opensteer-temporary-browser-"));
|
|
15281
15719
|
await clearChromeSingletonEntries(userDataDir);
|
|
15282
15720
|
const launched = await launchOwnedBrowser({
|
|
15283
15721
|
userDataDir,
|
|
@@ -15724,7 +16162,7 @@ async function terminateProcess(pid) {
|
|
|
15724
16162
|
}
|
|
15725
16163
|
}
|
|
15726
16164
|
async function requestBrowserClose(endpoint) {
|
|
15727
|
-
await new Promise((
|
|
16165
|
+
await new Promise((resolve4, reject) => {
|
|
15728
16166
|
const socket = new WebSocket(endpoint);
|
|
15729
16167
|
const timeout = setTimeout(() => {
|
|
15730
16168
|
socket.close();
|
|
@@ -15741,7 +16179,7 @@ async function requestBrowserClose(endpoint) {
|
|
|
15741
16179
|
reject(error);
|
|
15742
16180
|
return;
|
|
15743
16181
|
}
|
|
15744
|
-
|
|
16182
|
+
resolve4();
|
|
15745
16183
|
};
|
|
15746
16184
|
socket.addEventListener("open", () => {
|
|
15747
16185
|
socket.send(JSON.stringify({ id: 1, method: "Browser.close" }));
|
|
@@ -15779,7 +16217,7 @@ async function waitForProcessExit(pid, timeoutMs) {
|
|
|
15779
16217
|
return !isProcessRunning(pid);
|
|
15780
16218
|
}
|
|
15781
16219
|
function resolveAbpSessionDir(workspace) {
|
|
15782
|
-
return
|
|
16220
|
+
return path7.join(workspace.livePath, "abp-session");
|
|
15783
16221
|
}
|
|
15784
16222
|
async function allocateEphemeralPort() {
|
|
15785
16223
|
const { allocatePort } = await loadAbpModule();
|
|
@@ -15837,7 +16275,7 @@ function isStealthProfile(input) {
|
|
|
15837
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;
|
|
15838
16276
|
}
|
|
15839
16277
|
async function sleep(ms) {
|
|
15840
|
-
await new Promise((
|
|
16278
|
+
await new Promise((resolve4) => setTimeout(resolve4, ms));
|
|
15841
16279
|
}
|
|
15842
16280
|
|
|
15843
16281
|
// ../runtime-core/src/sdk/semantic-dispatch.ts
|
|
@@ -17451,7 +17889,7 @@ function diffStringMap(prefix, left, right, includeUnchanged, output) {
|
|
|
17451
17889
|
diffScalarField(`${prefix}.${key}`, left[key], right[key], includeUnchanged, output);
|
|
17452
17890
|
}
|
|
17453
17891
|
}
|
|
17454
|
-
function diffScalarField(
|
|
17892
|
+
function diffScalarField(path15, left, right, includeUnchanged, output) {
|
|
17455
17893
|
const leftValue = stringifyFieldValue(left);
|
|
17456
17894
|
const rightValue = stringifyFieldValue(right);
|
|
17457
17895
|
const kind = leftValue === void 0 ? rightValue === void 0 ? "unchanged" : "added" : rightValue === void 0 ? "removed" : leftValue === rightValue ? "unchanged" : "changed";
|
|
@@ -17459,7 +17897,7 @@ function diffScalarField(path13, left, right, includeUnchanged, output) {
|
|
|
17459
17897
|
return;
|
|
17460
17898
|
}
|
|
17461
17899
|
output.push({
|
|
17462
|
-
path:
|
|
17900
|
+
path: path15,
|
|
17463
17901
|
kind,
|
|
17464
17902
|
...leftValue === void 0 ? {} : { leftValue },
|
|
17465
17903
|
...rightValue === void 0 ? {} : { rightValue },
|
|
@@ -18465,9 +18903,9 @@ function matchReverseTargetHints(channel, codec, targetHints) {
|
|
|
18465
18903
|
matches.add(`host:${host}`);
|
|
18466
18904
|
}
|
|
18467
18905
|
}
|
|
18468
|
-
for (const
|
|
18469
|
-
if (url.pathname.includes(
|
|
18470
|
-
matches.add(`path:${
|
|
18906
|
+
for (const path15 of targetHints.paths ?? []) {
|
|
18907
|
+
if (url.pathname.includes(path15)) {
|
|
18908
|
+
matches.add(`path:${path15}`);
|
|
18471
18909
|
}
|
|
18472
18910
|
}
|
|
18473
18911
|
for (const operationName of targetHints.operationNames ?? []) {
|
|
@@ -19428,11 +19866,11 @@ function inferClusterRelationship(seed, record) {
|
|
|
19428
19866
|
var MATCHED_TLS_BINARY_NAMES = ["curl-impersonate-chrome", "curl_chrome"];
|
|
19429
19867
|
async function executeMatchedTlsTransportRequest(input) {
|
|
19430
19868
|
const binary = await resolveMatchedTlsBinary();
|
|
19431
|
-
const workingDirectory = await mkdtemp(
|
|
19432
|
-
const headersPath =
|
|
19433
|
-
const bodyPath =
|
|
19434
|
-
const cookiesPath =
|
|
19435
|
-
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");
|
|
19436
19874
|
try {
|
|
19437
19875
|
await writeFile(cookiesPath, toNetscapeCookieJar(input.cookies ?? []), "utf8");
|
|
19438
19876
|
if (input.request.body !== void 0) {
|
|
@@ -19489,10 +19927,10 @@ async function executeMatchedTlsTransportRequest(input) {
|
|
|
19489
19927
|
}
|
|
19490
19928
|
}
|
|
19491
19929
|
async function resolveMatchedTlsBinary() {
|
|
19492
|
-
const pathEntries = (process.env.PATH ?? "").split(
|
|
19930
|
+
const pathEntries = (process.env.PATH ?? "").split(path7.delimiter).filter((entry) => entry.length > 0);
|
|
19493
19931
|
for (const directory of pathEntries) {
|
|
19494
19932
|
for (const name of MATCHED_TLS_BINARY_NAMES) {
|
|
19495
|
-
const candidate =
|
|
19933
|
+
const candidate = path7.join(directory, name);
|
|
19496
19934
|
if (await isExecutable(candidate)) {
|
|
19497
19935
|
return candidate;
|
|
19498
19936
|
}
|
|
@@ -19500,7 +19938,7 @@ async function resolveMatchedTlsBinary() {
|
|
|
19500
19938
|
const files = await readDirSafe(directory);
|
|
19501
19939
|
const discovered = files.find((file) => file.startsWith("curl_chrome"));
|
|
19502
19940
|
if (discovered !== void 0) {
|
|
19503
|
-
const candidate =
|
|
19941
|
+
const candidate = path7.join(directory, discovered);
|
|
19504
19942
|
if (await isExecutable(candidate)) {
|
|
19505
19943
|
return candidate;
|
|
19506
19944
|
}
|
|
@@ -19511,7 +19949,7 @@ async function resolveMatchedTlsBinary() {
|
|
|
19511
19949
|
);
|
|
19512
19950
|
}
|
|
19513
19951
|
async function spawnAndCollect(command, args, signal) {
|
|
19514
|
-
return await new Promise((
|
|
19952
|
+
return await new Promise((resolve4, reject) => {
|
|
19515
19953
|
const child = spawn(command, args, {
|
|
19516
19954
|
stdio: ["ignore", "pipe", "pipe"]
|
|
19517
19955
|
});
|
|
@@ -19544,7 +19982,7 @@ async function spawnAndCollect(command, args, signal) {
|
|
|
19544
19982
|
);
|
|
19545
19983
|
return;
|
|
19546
19984
|
}
|
|
19547
|
-
|
|
19985
|
+
resolve4({ stdout, stderr });
|
|
19548
19986
|
});
|
|
19549
19987
|
});
|
|
19550
19988
|
}
|
|
@@ -22206,8 +22644,8 @@ function readString(value) {
|
|
|
22206
22644
|
return typeof value === "string" && value.length > 0 ? value : void 0;
|
|
22207
22645
|
}
|
|
22208
22646
|
function sleep2(ms, signal) {
|
|
22209
|
-
return new Promise((
|
|
22210
|
-
const timeout = setTimeout(
|
|
22647
|
+
return new Promise((resolve4, reject) => {
|
|
22648
|
+
const timeout = setTimeout(resolve4, ms);
|
|
22211
22649
|
const abort = () => {
|
|
22212
22650
|
clearTimeout(timeout);
|
|
22213
22651
|
reject(new Error("captcha solve aborted"));
|
|
@@ -22304,8 +22742,8 @@ function readString2(value) {
|
|
|
22304
22742
|
return typeof value === "string" && value.length > 0 ? value : void 0;
|
|
22305
22743
|
}
|
|
22306
22744
|
function sleep3(ms, signal) {
|
|
22307
|
-
return new Promise((
|
|
22308
|
-
const timeout = setTimeout(
|
|
22745
|
+
return new Promise((resolve4, reject) => {
|
|
22746
|
+
const timeout = setTimeout(resolve4, ms);
|
|
22309
22747
|
const abort = () => {
|
|
22310
22748
|
clearTimeout(timeout);
|
|
22311
22749
|
reject(new Error("captcha solve aborted"));
|
|
@@ -22504,6 +22942,8 @@ function diffInteractionTraces(left, right) {
|
|
|
22504
22942
|
// ../runtime-core/src/sdk/runtime.ts
|
|
22505
22943
|
var requireForAuthRecipeHook = createRequire(import.meta.url);
|
|
22506
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;
|
|
22507
22947
|
var OpensteerSessionRuntime = class {
|
|
22508
22948
|
workspace;
|
|
22509
22949
|
rootPath;
|
|
@@ -22516,6 +22956,9 @@ var OpensteerSessionRuntime = class {
|
|
|
22516
22956
|
registryOverrides;
|
|
22517
22957
|
cleanupRootOnClose;
|
|
22518
22958
|
sessionInfoBase;
|
|
22959
|
+
observationConfig;
|
|
22960
|
+
observationSessionId;
|
|
22961
|
+
injectedObservationSink;
|
|
22519
22962
|
root;
|
|
22520
22963
|
engine;
|
|
22521
22964
|
dom;
|
|
@@ -22525,6 +22968,9 @@ var OpensteerSessionRuntime = class {
|
|
|
22525
22968
|
sessionRef;
|
|
22526
22969
|
pageRef;
|
|
22527
22970
|
runId;
|
|
22971
|
+
observations;
|
|
22972
|
+
operationEventStorage = new AsyncLocalStorage();
|
|
22973
|
+
pendingOperationEventCaptures = [];
|
|
22528
22974
|
cookieJars = /* @__PURE__ */ new Map();
|
|
22529
22975
|
recipeCache = /* @__PURE__ */ new Map();
|
|
22530
22976
|
ownsEngine = false;
|
|
@@ -22532,7 +22978,7 @@ var OpensteerSessionRuntime = class {
|
|
|
22532
22978
|
this.workspace = normalizeNamespace2(options.name);
|
|
22533
22979
|
this.workspaceName = options.workspaceName?.trim() === void 0 || options.workspaceName?.trim().length === 0 ? void 0 : options.workspaceName.trim();
|
|
22534
22980
|
this.root = options.workspace;
|
|
22535
|
-
this.rootPath = options.workspace?.rootPath ?? options.rootPath ??
|
|
22981
|
+
this.rootPath = options.workspace?.rootPath ?? options.rootPath ?? path7.resolve(process.cwd(), ".opensteer", "temporary", randomUUID());
|
|
22536
22982
|
this.injectedEngine = options.engine;
|
|
22537
22983
|
this.engineFactory = options.engineFactory;
|
|
22538
22984
|
this.policy = options.policy ?? defaultPolicy();
|
|
@@ -22541,6 +22987,9 @@ var OpensteerSessionRuntime = class {
|
|
|
22541
22987
|
this.registryOverrides = options.registryOverrides;
|
|
22542
22988
|
this.cleanupRootOnClose = options.cleanupRootOnClose ?? options.workspace === void 0;
|
|
22543
22989
|
this.sessionInfoBase = options.sessionInfo ?? {};
|
|
22990
|
+
this.observationConfig = normalizeObservabilityConfig(options.observability);
|
|
22991
|
+
this.observationSessionId = options.observationSessionId;
|
|
22992
|
+
this.injectedObservationSink = options.observationSink;
|
|
22544
22993
|
if (this.injectedEngine === void 0 && this.engineFactory === void 0) {
|
|
22545
22994
|
throw new Error("OpensteerSessionRuntime requires an engine or engineFactory.");
|
|
22546
22995
|
}
|
|
@@ -22572,6 +23021,20 @@ var OpensteerSessionRuntime = class {
|
|
|
22572
23021
|
}
|
|
22573
23022
|
};
|
|
22574
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
|
+
}
|
|
22575
23038
|
async open(input = {}, options = {}) {
|
|
22576
23039
|
assertValidSemanticOperationInput("session.open", input);
|
|
22577
23040
|
if (input.workspace !== void 0 && normalizeNamespace2(input.workspace) !== this.workspace) {
|
|
@@ -22670,6 +23133,10 @@ var OpensteerSessionRuntime = class {
|
|
|
22670
23133
|
return { pages: [] };
|
|
22671
23134
|
}
|
|
22672
23135
|
const startedAt = Date.now();
|
|
23136
|
+
const context = buildRuntimeTraceContext({
|
|
23137
|
+
sessionRef: this.sessionRef,
|
|
23138
|
+
pageRef: this.pageRef
|
|
23139
|
+
});
|
|
22673
23140
|
try {
|
|
22674
23141
|
const output = await this.runWithOperationTimeout(
|
|
22675
23142
|
"page.list",
|
|
@@ -22684,19 +23151,18 @@ var OpensteerSessionRuntime = class {
|
|
|
22684
23151
|
},
|
|
22685
23152
|
options
|
|
22686
23153
|
);
|
|
23154
|
+
const events = await this.drainPendingEngineEvents(context);
|
|
22687
23155
|
await this.appendTrace({
|
|
22688
23156
|
operation: "page.list",
|
|
22689
23157
|
startedAt,
|
|
22690
23158
|
completedAt: Date.now(),
|
|
22691
23159
|
outcome: "ok",
|
|
23160
|
+
...events === void 0 ? {} : { events },
|
|
22692
23161
|
data: {
|
|
22693
23162
|
count: output.pages.length,
|
|
22694
23163
|
...output.activePageRef === void 0 ? {} : { activePageRef: output.activePageRef }
|
|
22695
23164
|
},
|
|
22696
|
-
context
|
|
22697
|
-
sessionRef: this.sessionRef,
|
|
22698
|
-
pageRef: this.pageRef
|
|
22699
|
-
})
|
|
23165
|
+
context
|
|
22700
23166
|
});
|
|
22701
23167
|
return output;
|
|
22702
23168
|
} catch (error) {
|
|
@@ -22706,10 +23172,7 @@ var OpensteerSessionRuntime = class {
|
|
|
22706
23172
|
completedAt: Date.now(),
|
|
22707
23173
|
outcome: "error",
|
|
22708
23174
|
error,
|
|
22709
|
-
context
|
|
22710
|
-
sessionRef: this.sessionRef,
|
|
22711
|
-
pageRef: this.pageRef
|
|
22712
|
-
})
|
|
23175
|
+
context
|
|
22713
23176
|
});
|
|
22714
23177
|
throw error;
|
|
22715
23178
|
}
|
|
@@ -23097,22 +23560,25 @@ var OpensteerSessionRuntime = class {
|
|
|
23097
23560
|
},
|
|
23098
23561
|
options
|
|
23099
23562
|
);
|
|
23563
|
+
const context = buildRuntimeTraceContext({
|
|
23564
|
+
sessionRef: this.sessionRef,
|
|
23565
|
+
pageRef
|
|
23566
|
+
});
|
|
23567
|
+
const events = await this.drainPendingEngineEvents(context);
|
|
23100
23568
|
await this.appendTrace({
|
|
23101
23569
|
operation: "page.snapshot",
|
|
23102
23570
|
startedAt,
|
|
23103
23571
|
completedAt: Date.now(),
|
|
23104
23572
|
outcome: "ok",
|
|
23105
23573
|
artifacts,
|
|
23574
|
+
...events === void 0 ? {} : { events },
|
|
23106
23575
|
data: {
|
|
23107
23576
|
mode,
|
|
23108
23577
|
url: output.url,
|
|
23109
23578
|
title: output.title,
|
|
23110
23579
|
counterCount: output.counters.length
|
|
23111
23580
|
},
|
|
23112
|
-
context
|
|
23113
|
-
sessionRef: this.sessionRef,
|
|
23114
|
-
pageRef
|
|
23115
|
-
})
|
|
23581
|
+
context
|
|
23116
23582
|
});
|
|
23117
23583
|
return output;
|
|
23118
23584
|
} catch (error) {
|
|
@@ -26537,11 +27003,13 @@ var OpensteerSessionRuntime = class {
|
|
|
26537
27003
|
}
|
|
26538
27004
|
);
|
|
26539
27005
|
const output = toOpensteerActionResult(executed.result, preparedTarget.persistedDescription);
|
|
27006
|
+
const actionEvents = "events" in executed.result ? executed.result.events : void 0;
|
|
26540
27007
|
await this.appendTrace({
|
|
26541
27008
|
operation,
|
|
26542
27009
|
startedAt,
|
|
26543
27010
|
completedAt: Date.now(),
|
|
26544
27011
|
outcome: "ok",
|
|
27012
|
+
...actionEvents === void 0 ? {} : { events: actionEvents },
|
|
26545
27013
|
data: {
|
|
26546
27014
|
target: output.target,
|
|
26547
27015
|
...output.point === void 0 ? {} : { point: output.point },
|
|
@@ -28291,7 +28759,7 @@ var OpensteerSessionRuntime = class {
|
|
|
28291
28759
|
}
|
|
28292
28760
|
async executeAuthRecipeHook(step, variables) {
|
|
28293
28761
|
const resolved = requireForAuthRecipeHook.resolve(step.hook.specifier, {
|
|
28294
|
-
paths: [
|
|
28762
|
+
paths: [path7.dirname(this.rootPath)]
|
|
28295
28763
|
});
|
|
28296
28764
|
const module = await import(pathToFileURL(resolved).href);
|
|
28297
28765
|
const handler = module[step.hook.export];
|
|
@@ -28663,14 +29131,18 @@ var OpensteerSessionRuntime = class {
|
|
|
28663
29131
|
return this.engine;
|
|
28664
29132
|
}
|
|
28665
29133
|
if (this.injectedEngine) {
|
|
28666
|
-
this.engine = this.
|
|
29134
|
+
this.engine = this.wrapEngineWithObservationCapture(
|
|
29135
|
+
this.injectedEngine
|
|
29136
|
+
);
|
|
28667
29137
|
this.ownsEngine = false;
|
|
28668
29138
|
return this.engine;
|
|
28669
29139
|
}
|
|
28670
29140
|
if (this.engineFactory === void 0) {
|
|
28671
29141
|
throw new Error("Opensteer engine factory is not initialized");
|
|
28672
29142
|
}
|
|
28673
|
-
this.engine =
|
|
29143
|
+
this.engine = this.wrapEngineWithObservationCapture(
|
|
29144
|
+
await this.engineFactory(overrides)
|
|
29145
|
+
);
|
|
28674
29146
|
this.ownsEngine = true;
|
|
28675
29147
|
return this.engine;
|
|
28676
29148
|
}
|
|
@@ -28870,6 +29342,15 @@ var OpensteerSessionRuntime = class {
|
|
|
28870
29342
|
return;
|
|
28871
29343
|
}
|
|
28872
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);
|
|
28873
29354
|
const artifacts = input.artifacts === void 0 ? void 0 : await Promise.all(
|
|
28874
29355
|
input.artifacts.manifests.map(async (manifest) => {
|
|
28875
29356
|
const reference = await root.artifacts.toProtocolArtifactReference(
|
|
@@ -28882,19 +29363,56 @@ var OpensteerSessionRuntime = class {
|
|
|
28882
29363
|
return reference;
|
|
28883
29364
|
})
|
|
28884
29365
|
);
|
|
28885
|
-
await root.traces.append(runId, {
|
|
29366
|
+
const traceEntry = await root.traces.append(runId, {
|
|
28886
29367
|
operation: input.operation,
|
|
28887
29368
|
outcome: input.outcome,
|
|
28888
29369
|
startedAt: input.startedAt,
|
|
28889
29370
|
completedAt: input.completedAt,
|
|
28890
29371
|
...input.context === void 0 ? {} : { context: input.context },
|
|
28891
|
-
...
|
|
29372
|
+
...stepEvents === void 0 ? {} : { events: stepEvents },
|
|
28892
29373
|
...artifacts === void 0 ? {} : { artifacts },
|
|
28893
|
-
...
|
|
28894
|
-
...
|
|
28895
|
-
error:
|
|
29374
|
+
...normalizedData === void 0 ? {} : { data: normalizedData },
|
|
29375
|
+
...normalizedError === void 0 ? {} : {
|
|
29376
|
+
error: normalizedError
|
|
28896
29377
|
}
|
|
28897
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
|
+
}
|
|
28898
29416
|
}
|
|
28899
29417
|
async cleanupSessionResources(engine, pageRef, sessionRef) {
|
|
28900
29418
|
if (pageRef !== void 0) {
|
|
@@ -28906,6 +29424,7 @@ var OpensteerSessionRuntime = class {
|
|
|
28906
29424
|
}
|
|
28907
29425
|
async resetRuntimeState(options) {
|
|
28908
29426
|
const engine = this.engine;
|
|
29427
|
+
const observations = this.observations;
|
|
28909
29428
|
this.networkHistory.clear();
|
|
28910
29429
|
this.sessionRef = void 0;
|
|
28911
29430
|
this.pageRef = void 0;
|
|
@@ -28914,20 +29433,140 @@ var OpensteerSessionRuntime = class {
|
|
|
28914
29433
|
this.computer = void 0;
|
|
28915
29434
|
this.extractionDescriptors = void 0;
|
|
28916
29435
|
this.engine = void 0;
|
|
29436
|
+
this.observations = void 0;
|
|
29437
|
+
this.pendingOperationEventCaptures.length = 0;
|
|
29438
|
+
await observations?.close("runtime_reset").catch(() => void 0);
|
|
28917
29439
|
if (options.disposeEngine && this.ownsEngine && engine?.dispose) {
|
|
28918
29440
|
await engine.dispose();
|
|
28919
29441
|
}
|
|
28920
29442
|
this.ownsEngine = false;
|
|
28921
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
|
+
}
|
|
28922
29466
|
runWithOperationTimeout(operation, callback, options = {}) {
|
|
28923
|
-
|
|
28924
|
-
|
|
28925
|
-
|
|
28926
|
-
|
|
28927
|
-
|
|
28928
|
-
|
|
28929
|
-
|
|
28930
|
-
|
|
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;
|
|
28931
29570
|
}
|
|
28932
29571
|
async navigatePage(input, timeout) {
|
|
28933
29572
|
const remainingMs = timeout.remainingMs();
|
|
@@ -28963,6 +29602,34 @@ function buildRuntimeTraceContext(input) {
|
|
|
28963
29602
|
function buildArtifactScope(input) {
|
|
28964
29603
|
return buildRuntimeTraceContext(input);
|
|
28965
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
|
+
}
|
|
28966
29633
|
function selectLiveQueryPageRef(input, currentPageRef) {
|
|
28967
29634
|
if (input.pageRef !== void 0) {
|
|
28968
29635
|
return input.pageRef;
|
|
@@ -29925,12 +30592,12 @@ function extractReverseRuntimeValue(value, pointer) {
|
|
|
29925
30592
|
}
|
|
29926
30593
|
return readDotPath(value, pointer);
|
|
29927
30594
|
}
|
|
29928
|
-
function readDotPath(value,
|
|
29929
|
-
if (
|
|
30595
|
+
function readDotPath(value, path15) {
|
|
30596
|
+
if (path15.length === 0) {
|
|
29930
30597
|
return value;
|
|
29931
30598
|
}
|
|
29932
30599
|
let current = value;
|
|
29933
|
-
for (const segment of
|
|
30600
|
+
for (const segment of path15.split(".").filter((entry) => entry.length > 0)) {
|
|
29934
30601
|
if (current === null || current === void 0) {
|
|
29935
30602
|
return void 0;
|
|
29936
30603
|
}
|
|
@@ -30299,7 +30966,7 @@ function normalizeRuntimeErrorMessage(error) {
|
|
|
30299
30966
|
return error instanceof Error ? error.message : String(error);
|
|
30300
30967
|
}
|
|
30301
30968
|
function runtimeDelay(ms) {
|
|
30302
|
-
return new Promise((
|
|
30969
|
+
return new Promise((resolve4) => setTimeout(resolve4, ms));
|
|
30303
30970
|
}
|
|
30304
30971
|
function applyBrowserCookiesToTransportRequest(request, cookies) {
|
|
30305
30972
|
if (cookies.length === 0) {
|
|
@@ -30403,7 +31070,7 @@ function parseSetCookieHeader(value, requestUrl) {
|
|
|
30403
31070
|
}
|
|
30404
31071
|
const url = new URL(requestUrl);
|
|
30405
31072
|
let domain = url.hostname;
|
|
30406
|
-
let
|
|
31073
|
+
let path15 = defaultCookiePath(url.pathname);
|
|
30407
31074
|
let secure = url.protocol === "https:";
|
|
30408
31075
|
let expiresAt;
|
|
30409
31076
|
const cookieValue = rawValueParts.join("=").trim();
|
|
@@ -30416,7 +31083,7 @@ function parseSetCookieHeader(value, requestUrl) {
|
|
|
30416
31083
|
continue;
|
|
30417
31084
|
}
|
|
30418
31085
|
if (key === "path" && attributeValue.length > 0) {
|
|
30419
|
-
|
|
31086
|
+
path15 = attributeValue;
|
|
30420
31087
|
continue;
|
|
30421
31088
|
}
|
|
30422
31089
|
if (key === "secure") {
|
|
@@ -30442,7 +31109,7 @@ function parseSetCookieHeader(value, requestUrl) {
|
|
|
30442
31109
|
name,
|
|
30443
31110
|
value: cookieValue,
|
|
30444
31111
|
domain,
|
|
30445
|
-
path:
|
|
31112
|
+
path: path15,
|
|
30446
31113
|
secure,
|
|
30447
31114
|
...expiresAt === void 0 ? {} : { expiresAt }
|
|
30448
31115
|
}
|
|
@@ -31394,7 +32061,7 @@ async function pollUntilResult(timeout, producer) {
|
|
|
31394
32061
|
if (produced !== void 0) {
|
|
31395
32062
|
return produced;
|
|
31396
32063
|
}
|
|
31397
|
-
await new Promise((
|
|
32064
|
+
await new Promise((resolve4) => setTimeout(resolve4, 100));
|
|
31398
32065
|
}
|
|
31399
32066
|
}
|
|
31400
32067
|
async function getMainFrame(engine, pageRef) {
|
|
@@ -31452,6 +32119,133 @@ function toOpensteerResolvedTarget2(target) {
|
|
|
31452
32119
|
function normalizeOpensteerError(error) {
|
|
31453
32120
|
return normalizeThrownOpensteerError(error, "Unknown Opensteer runtime failure");
|
|
31454
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
|
+
}
|
|
31455
32249
|
function buildMutationCaptureTraceData(diagnostics) {
|
|
31456
32250
|
if (diagnostics?.finalizeError === void 0) {
|
|
31457
32251
|
return {};
|
|
@@ -31501,8 +32295,8 @@ function screenshotMediaType(format2) {
|
|
|
31501
32295
|
var OpensteerRuntime = class extends OpensteerSessionRuntime {
|
|
31502
32296
|
constructor(options = {}) {
|
|
31503
32297
|
const publicWorkspace = normalizeWorkspace2(options.workspace);
|
|
31504
|
-
const rootPath = options.rootPath ?? (publicWorkspace === void 0 ?
|
|
31505
|
-
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()),
|
|
31506
32300
|
workspace: publicWorkspace
|
|
31507
32301
|
}));
|
|
31508
32302
|
const cleanupRootOnClose = options.cleanupRootOnClose ?? publicWorkspace === void 0;
|
|
@@ -31527,14 +32321,17 @@ var OpensteerRuntime = class extends OpensteerSessionRuntime {
|
|
|
31527
32321
|
...options.descriptorStore === void 0 ? {} : { descriptorStore: options.descriptorStore },
|
|
31528
32322
|
...options.extractionDescriptorStore === void 0 ? {} : { extractionDescriptorStore: options.extractionDescriptorStore },
|
|
31529
32323
|
...options.registryOverrides === void 0 ? {} : { registryOverrides: options.registryOverrides },
|
|
31530
|
-
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 }
|
|
31531
32328
|
})
|
|
31532
32329
|
);
|
|
31533
32330
|
}
|
|
31534
32331
|
};
|
|
31535
32332
|
var OpensteerSessionRuntime2 = class extends OpensteerSessionRuntime {
|
|
31536
32333
|
constructor(options) {
|
|
31537
|
-
const rootPath = options.rootPath ??
|
|
32334
|
+
const rootPath = options.rootPath ?? path7.resolve(options.rootDir ?? process.cwd());
|
|
31538
32335
|
const cleanupRootOnClose = options.cleanupRootOnClose ?? false;
|
|
31539
32336
|
const engineName = options.engineName ?? DEFAULT_OPENSTEER_ENGINE;
|
|
31540
32337
|
assertSupportedEngineOptions({
|
|
@@ -31556,7 +32353,10 @@ var OpensteerSessionRuntime2 = class extends OpensteerSessionRuntime {
|
|
|
31556
32353
|
...options.descriptorStore === void 0 ? {} : { descriptorStore: options.descriptorStore },
|
|
31557
32354
|
...options.extractionDescriptorStore === void 0 ? {} : { extractionDescriptorStore: options.extractionDescriptorStore },
|
|
31558
32355
|
...options.registryOverrides === void 0 ? {} : { registryOverrides: options.registryOverrides },
|
|
31559
|
-
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 }
|
|
31560
32360
|
})
|
|
31561
32361
|
);
|
|
31562
32362
|
}
|
|
@@ -31582,6 +32382,9 @@ function buildSharedRuntimeOptions(input) {
|
|
|
31582
32382
|
...input.extractionDescriptorStore === void 0 ? {} : { extractionDescriptorStore: input.extractionDescriptorStore },
|
|
31583
32383
|
...input.registryOverrides === void 0 ? {} : { registryOverrides: input.registryOverrides },
|
|
31584
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 },
|
|
31585
32388
|
sessionInfo: {
|
|
31586
32389
|
provider: {
|
|
31587
32390
|
mode: "local",
|
|
@@ -31644,345 +32447,267 @@ function resolveOpensteerProvider(input = {}) {
|
|
|
31644
32447
|
};
|
|
31645
32448
|
}
|
|
31646
32449
|
var execFile2 = promisify(execFile);
|
|
31647
|
-
var
|
|
31648
|
-
var
|
|
31649
|
-
var
|
|
31650
|
-
|
|
31651
|
-
async function resolveCookieCaptureStrategy(input = {}) {
|
|
31652
|
-
const timeoutMs = input.timeoutMs ?? DEFAULT_CAPTURE_TIMEOUT_MS;
|
|
31653
|
-
if (input.attachEndpoint !== void 0) {
|
|
31654
|
-
if (input.strategy !== void 0 && input.strategy !== "attach") {
|
|
31655
|
-
throw new Error(
|
|
31656
|
-
`Strategy "${input.strategy}" is incompatible with an explicit attach endpoint.`
|
|
31657
|
-
);
|
|
31658
|
-
}
|
|
31659
|
-
return {
|
|
31660
|
-
strategy: "attach",
|
|
31661
|
-
attachEndpoint: input.attachEndpoint,
|
|
31662
|
-
...input.profileDirectory === void 0 ? {} : { profileDirectory: input.profileDirectory },
|
|
31663
|
-
timeoutMs
|
|
31664
|
-
};
|
|
31665
|
-
}
|
|
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 = {}) {
|
|
31666
32454
|
const brand2 = resolveRequestedBrand(input);
|
|
31667
|
-
const executablePath = resolveBrandExecutablePath(brand2, input.executablePath);
|
|
31668
32455
|
const userDataDir = resolveBrandUserDataDir(brand2, input.userDataDir);
|
|
31669
|
-
const profileDirectory = input.profileDirectory;
|
|
31670
|
-
const
|
|
31671
|
-
|
|
31672
|
-
const autoStrategy = attachEndpoint !== void 0 ? "attach" : runningProcess !== null ? "managed-relaunch" : "headless";
|
|
31673
|
-
const strategy = input.strategy ?? autoStrategy;
|
|
31674
|
-
validateRequestedStrategy({
|
|
31675
|
-
strategy,
|
|
31676
|
-
brand: brand2,
|
|
31677
|
-
...attachEndpoint === void 0 ? {} : { attachEndpoint },
|
|
31678
|
-
...runningProcess?.pid === void 0 ? {} : { runningPid: runningProcess.pid }
|
|
31679
|
-
});
|
|
31680
|
-
return {
|
|
31681
|
-
strategy,
|
|
31682
|
-
brandId: brand2.id,
|
|
31683
|
-
brandDisplayName: brand2.displayName,
|
|
31684
|
-
executablePath,
|
|
31685
|
-
userDataDir,
|
|
31686
|
-
...profileDirectory === void 0 ? {} : { profileDirectory },
|
|
31687
|
-
...attachEndpoint === void 0 ? {} : { attachEndpoint },
|
|
31688
|
-
...runningProcess === null ? {} : { runningPid: runningProcess.pid },
|
|
31689
|
-
timeoutMs
|
|
31690
|
-
};
|
|
31691
|
-
}
|
|
31692
|
-
async function acquireCdpEndpoint(resolved) {
|
|
31693
|
-
if (resolved.strategy === "attach") {
|
|
31694
|
-
if (!resolved.attachEndpoint) {
|
|
31695
|
-
throw new Error("Attach capture requires a debuggable browser endpoint.");
|
|
31696
|
-
}
|
|
31697
|
-
const inspected = await inspectCdpEndpoint({
|
|
31698
|
-
endpoint: resolved.attachEndpoint,
|
|
31699
|
-
timeoutMs: Math.min(2e3, resolved.timeoutMs)
|
|
31700
|
-
});
|
|
31701
|
-
return {
|
|
31702
|
-
strategy: "attach",
|
|
31703
|
-
cdpEndpoint: inspected.endpoint,
|
|
31704
|
-
...resolved.brandId === void 0 ? {} : { brandId: resolved.brandId },
|
|
31705
|
-
...resolved.brandDisplayName === void 0 ? {} : { brandDisplayName: resolved.brandDisplayName },
|
|
31706
|
-
...resolved.userDataDir === void 0 ? {} : { userDataDir: resolved.userDataDir },
|
|
31707
|
-
...resolved.profileDirectory === void 0 ? {} : { profileDirectory: resolved.profileDirectory },
|
|
31708
|
-
cleanup: async () => void 0
|
|
31709
|
-
};
|
|
31710
|
-
}
|
|
31711
|
-
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)) {
|
|
31712
32459
|
throw new Error(
|
|
31713
|
-
|
|
32460
|
+
`Cookies database not found at "${cookiesPath}". Verify the browser brand, user-data-dir, and profile-directory are correct.`
|
|
31714
32461
|
);
|
|
31715
32462
|
}
|
|
31716
|
-
const
|
|
31717
|
-
if (resolved.strategy === "managed-relaunch") {
|
|
31718
|
-
if (resolved.runningPid === void 0) {
|
|
31719
|
-
throw new Error("Managed relaunch requires a running browser process.");
|
|
31720
|
-
}
|
|
31721
|
-
await gracefullyStopBrowser(
|
|
31722
|
-
getBrowserBrand(resolved.brandId),
|
|
31723
|
-
resolved.runningPid,
|
|
31724
|
-
resolved.timeoutMs
|
|
31725
|
-
);
|
|
31726
|
-
}
|
|
31727
|
-
await clearChromeSingletonEntries(userDataDir);
|
|
32463
|
+
const tempDir = await mkdtemp(join(tmpdir(), "opensteer-cookies-"));
|
|
31728
32464
|
try {
|
|
31729
|
-
|
|
31730
|
-
|
|
31731
|
-
|
|
31732
|
-
|
|
31733
|
-
...resolved.profileDirectory === void 0 ? {} : { profileDirectory: resolved.profileDirectory },
|
|
31734
|
-
timeoutMs: resolved.timeoutMs
|
|
31735
|
-
});
|
|
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);
|
|
31736
32469
|
return {
|
|
31737
|
-
|
|
31738
|
-
|
|
31739
|
-
|
|
31740
|
-
|
|
31741
|
-
|
|
31742
|
-
...resolved.profileDirectory === void 0 ? {} : { profileDirectory: resolved.profileDirectory },
|
|
31743
|
-
cleanup: async () => {
|
|
31744
|
-
await capture.kill().catch(() => void 0);
|
|
31745
|
-
await clearChromeSingletonEntries(userDataDir).catch(() => void 0);
|
|
31746
|
-
}
|
|
31747
|
-
};
|
|
31748
|
-
} catch (error) {
|
|
31749
|
-
await clearChromeSingletonEntries(userDataDir).catch(() => void 0);
|
|
31750
|
-
throw error;
|
|
31751
|
-
}
|
|
31752
|
-
}
|
|
31753
|
-
async function gracefullyStopBrowser(brand2, pid, timeoutMs = DEFAULT_STOP_TIMEOUT_MS) {
|
|
31754
|
-
if (pid <= 0) {
|
|
31755
|
-
return;
|
|
31756
|
-
}
|
|
31757
|
-
const platformConfig = resolveBrandPlatformConfig(brand2);
|
|
31758
|
-
if (process.platform === "darwin" && platformConfig?.bundleId) {
|
|
31759
|
-
await execFile2(
|
|
31760
|
-
"osascript",
|
|
31761
|
-
["-e", `tell application id "${platformConfig.bundleId}" to quit`],
|
|
31762
|
-
{
|
|
31763
|
-
maxBuffer: PROCESS_LIST_MAX_BUFFER_BYTES3
|
|
31764
|
-
}
|
|
31765
|
-
).catch(() => void 0);
|
|
31766
|
-
} else if (process.platform === "win32") {
|
|
31767
|
-
await execFile2("taskkill", ["/PID", String(pid)], {
|
|
31768
|
-
maxBuffer: PROCESS_LIST_MAX_BUFFER_BYTES3
|
|
31769
|
-
}).catch(() => void 0);
|
|
31770
|
-
} else {
|
|
31771
|
-
try {
|
|
31772
|
-
process.kill(pid, "SIGTERM");
|
|
31773
|
-
} catch {
|
|
31774
|
-
}
|
|
31775
|
-
}
|
|
31776
|
-
if (await waitForProcessExit2(pid, timeoutMs)) {
|
|
31777
|
-
return;
|
|
31778
|
-
}
|
|
31779
|
-
if (process.platform === "win32") {
|
|
31780
|
-
await execFile2("taskkill", ["/F", "/PID", String(pid)], {
|
|
31781
|
-
maxBuffer: PROCESS_LIST_MAX_BUFFER_BYTES3
|
|
31782
|
-
}).catch(() => void 0);
|
|
31783
|
-
} else {
|
|
31784
|
-
try {
|
|
31785
|
-
process.kill(pid, "SIGKILL");
|
|
31786
|
-
} catch {
|
|
31787
|
-
}
|
|
31788
|
-
}
|
|
31789
|
-
await waitForProcessExit2(pid, Math.min(5e3, timeoutMs));
|
|
31790
|
-
}
|
|
31791
|
-
async function launchCaptureChrome(input) {
|
|
31792
|
-
const stderrLines = [];
|
|
31793
|
-
const child = spawn(input.executablePath, buildCaptureChromeArgs(input), {
|
|
31794
|
-
detached: process.platform !== "win32",
|
|
31795
|
-
stdio: ["ignore", "ignore", "pipe"]
|
|
31796
|
-
});
|
|
31797
|
-
child.unref();
|
|
31798
|
-
child.stderr?.setEncoding("utf8");
|
|
31799
|
-
child.stderr?.on("data", (chunk) => {
|
|
31800
|
-
stderrLines.push(String(chunk));
|
|
31801
|
-
});
|
|
31802
|
-
try {
|
|
31803
|
-
const endpoint = await waitForCaptureEndpoint({
|
|
31804
|
-
brandDisplayName: input.brandDisplayName,
|
|
31805
|
-
child,
|
|
31806
|
-
stderrLines,
|
|
31807
|
-
timeoutMs: input.timeoutMs,
|
|
31808
|
-
userDataDir: input.userDataDir
|
|
31809
|
-
});
|
|
31810
|
-
return {
|
|
31811
|
-
endpoint,
|
|
31812
|
-
kill: async () => {
|
|
31813
|
-
await terminateChild(child);
|
|
31814
|
-
}
|
|
32470
|
+
cookies,
|
|
32471
|
+
brandId: brand2.id,
|
|
32472
|
+
brandDisplayName: brand2.displayName,
|
|
32473
|
+
userDataDir,
|
|
32474
|
+
profileDirectory
|
|
31815
32475
|
};
|
|
31816
|
-
}
|
|
31817
|
-
await
|
|
31818
|
-
throw error;
|
|
32476
|
+
} finally {
|
|
32477
|
+
await rm(tempDir, { recursive: true, force: true }).catch(() => void 0);
|
|
31819
32478
|
}
|
|
31820
32479
|
}
|
|
31821
|
-
function relaunchBrowserNormally(executablePath) {
|
|
31822
|
-
const child = spawn(executablePath, [], {
|
|
31823
|
-
detached: true,
|
|
31824
|
-
stdio: "ignore"
|
|
31825
|
-
});
|
|
31826
|
-
child.unref();
|
|
31827
|
-
}
|
|
31828
32480
|
function resolveRequestedBrand(input) {
|
|
31829
32481
|
if (input.brandId !== void 0) {
|
|
31830
32482
|
return getBrowserBrand(input.brandId);
|
|
31831
32483
|
}
|
|
31832
|
-
if (input.userDataDir !== void 0) {
|
|
31833
|
-
const inferred = inferBrandFromUserDataDir(input.userDataDir);
|
|
31834
|
-
if (!inferred) {
|
|
31835
|
-
throw new Error(
|
|
31836
|
-
`Could not infer a browser brand from user-data-dir "${input.userDataDir}". Pass --browser explicitly.`
|
|
31837
|
-
);
|
|
31838
|
-
}
|
|
31839
|
-
return inferred;
|
|
31840
|
-
}
|
|
31841
|
-
if (input.executablePath !== void 0) {
|
|
31842
|
-
const inferred = inferBrandFromExecutablePath(input.executablePath);
|
|
31843
|
-
if (!inferred) {
|
|
31844
|
-
throw new Error(
|
|
31845
|
-
`Could not infer a browser brand from executable path "${input.executablePath}". Pass --browser explicitly.`
|
|
31846
|
-
);
|
|
31847
|
-
}
|
|
31848
|
-
return inferred;
|
|
31849
|
-
}
|
|
31850
32484
|
const installed = detectInstalledBrowserBrands()[0];
|
|
31851
32485
|
if (!installed) {
|
|
31852
32486
|
throw new Error(
|
|
31853
|
-
"No Chromium browser found. Install a supported browser or pass
|
|
32487
|
+
"No Chromium browser found. Install a supported browser or pass brandId explicitly."
|
|
31854
32488
|
);
|
|
31855
32489
|
}
|
|
31856
32490
|
return installed.brand;
|
|
31857
32491
|
}
|
|
31858
|
-
async function
|
|
31859
|
-
|
|
31860
|
-
|
|
31861
|
-
|
|
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
|
+
}
|
|
31862
32499
|
}
|
|
32500
|
+
}
|
|
32501
|
+
function queryAllCookies(dbPath) {
|
|
32502
|
+
let DatabaseSync;
|
|
31863
32503
|
try {
|
|
31864
|
-
|
|
31865
|
-
endpoint: `http://127.0.0.1:${String(activePort.port)}`,
|
|
31866
|
-
timeoutMs: Math.min(2e3, timeoutMs)
|
|
31867
|
-
})).endpoint;
|
|
32504
|
+
({ DatabaseSync } = __require(NODE_SQLITE_SPECIFIER2));
|
|
31868
32505
|
} catch {
|
|
31869
|
-
|
|
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();
|
|
31870
32521
|
}
|
|
31871
32522
|
}
|
|
31872
|
-
function
|
|
31873
|
-
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 {
|
|
31874
32559
|
throw new Error(
|
|
31875
|
-
|
|
32560
|
+
`Failed to retrieve "${service}" from macOS Keychain. Ensure the browser has been opened at least once and Keychain access is allowed.`
|
|
31876
32561
|
);
|
|
31877
32562
|
}
|
|
31878
|
-
|
|
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 {
|
|
31879
32570
|
throw new Error(
|
|
31880
|
-
|
|
32571
|
+
`Failed to read "${localStatePath}". Ensure the browser has been opened at least once.`
|
|
31881
32572
|
);
|
|
31882
32573
|
}
|
|
31883
|
-
|
|
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 {
|
|
31884
32594
|
throw new Error(
|
|
31885
|
-
|
|
32595
|
+
"Failed to decrypt browser master key via Windows DPAPI. Ensure you are running as the same user who owns the browser profile."
|
|
31886
32596
|
);
|
|
31887
32597
|
}
|
|
31888
32598
|
}
|
|
31889
|
-
function
|
|
31890
|
-
const
|
|
31891
|
-
|
|
31892
|
-
|
|
31893
|
-
|
|
31894
|
-
|
|
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;
|
|
31895
32607
|
}
|
|
31896
|
-
const
|
|
31897
|
-
|
|
31898
|
-
|
|
31899
|
-
}
|
|
31900
|
-
function inferBrandFromExecutablePath(executablePath) {
|
|
31901
|
-
const normalized = normalizePath(executablePath);
|
|
31902
|
-
return getAllBrowserBrands().find((brand2) => {
|
|
31903
|
-
const config = resolveBrandPlatformConfig(brand2);
|
|
31904
|
-
if (!config) {
|
|
31905
|
-
return false;
|
|
32608
|
+
const value = decryptCookieValue(row, decryptionKey);
|
|
32609
|
+
if (value === null) {
|
|
32610
|
+
continue;
|
|
31906
32611
|
}
|
|
31907
|
-
|
|
31908
|
-
|
|
31909
|
-
)
|
|
31910
|
-
|
|
31911
|
-
}
|
|
31912
|
-
function buildCaptureChromeArgs(input) {
|
|
31913
|
-
const args = [
|
|
31914
|
-
"--remote-debugging-port=0",
|
|
31915
|
-
"--headless=new",
|
|
31916
|
-
"--no-first-run",
|
|
31917
|
-
"--no-default-browser-check",
|
|
31918
|
-
"--disable-background-networking",
|
|
31919
|
-
"--disable-sync",
|
|
31920
|
-
"--disable-component-update",
|
|
31921
|
-
`--user-data-dir=${input.userDataDir}`
|
|
31922
|
-
];
|
|
31923
|
-
if (input.profileDirectory !== void 0) {
|
|
31924
|
-
args.push(`--profile-directory=${input.profileDirectory}`);
|
|
31925
|
-
}
|
|
31926
|
-
return args;
|
|
31927
|
-
}
|
|
31928
|
-
async function waitForCaptureEndpoint(input) {
|
|
31929
|
-
const deadline = Date.now() + input.timeoutMs;
|
|
31930
|
-
while (Date.now() < deadline) {
|
|
31931
|
-
const activePort = readDevToolsActivePort(input.userDataDir);
|
|
31932
|
-
if (activePort) {
|
|
31933
|
-
try {
|
|
31934
|
-
return (await inspectCdpEndpoint({
|
|
31935
|
-
endpoint: `http://127.0.0.1:${String(activePort.port)}`,
|
|
31936
|
-
timeoutMs: Math.min(2e3, input.timeoutMs)
|
|
31937
|
-
})).endpoint;
|
|
31938
|
-
} catch {
|
|
31939
|
-
return `ws://127.0.0.1:${String(activePort.port)}${activePort.webSocketPath}`;
|
|
31940
|
-
}
|
|
32612
|
+
const expiresSeconds = chromeDateToUnixSeconds(row.expires_utc);
|
|
32613
|
+
const isSession = expiresSeconds <= 0;
|
|
32614
|
+
if (!isSession && expiresSeconds < nowSeconds) {
|
|
32615
|
+
continue;
|
|
31941
32616
|
}
|
|
31942
|
-
|
|
31943
|
-
|
|
32617
|
+
const sameSite = chromeSameSiteToString(row.samesite);
|
|
32618
|
+
let secure = Number(row.is_secure) === 1;
|
|
32619
|
+
if (sameSite === "None") {
|
|
32620
|
+
secure = true;
|
|
31944
32621
|
}
|
|
31945
|
-
|
|
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
|
+
});
|
|
31946
32632
|
}
|
|
31947
|
-
|
|
32633
|
+
return cookies;
|
|
31948
32634
|
}
|
|
31949
|
-
function
|
|
31950
|
-
|
|
31951
|
-
|
|
31952
|
-
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;
|
|
31953
32638
|
}
|
|
31954
|
-
const
|
|
31955
|
-
|
|
31956
|
-
|
|
31957
|
-
|
|
31958
|
-
|
|
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;
|
|
31959
32655
|
}
|
|
31960
|
-
|
|
31961
|
-
|
|
31962
|
-
|
|
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;
|
|
31963
32670
|
}
|
|
32671
|
+
}
|
|
32672
|
+
function decryptAes256Gcm(ciphertext, key) {
|
|
31964
32673
|
try {
|
|
31965
|
-
|
|
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");
|
|
31966
32684
|
} catch {
|
|
31967
|
-
return;
|
|
32685
|
+
return null;
|
|
31968
32686
|
}
|
|
31969
|
-
await sleep4(50);
|
|
31970
32687
|
}
|
|
31971
|
-
|
|
31972
|
-
const
|
|
31973
|
-
|
|
31974
|
-
|
|
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) {
|
|
31975
32693
|
return true;
|
|
31976
32694
|
}
|
|
31977
|
-
await sleep4(50);
|
|
31978
32695
|
}
|
|
31979
|
-
return
|
|
32696
|
+
return false;
|
|
31980
32697
|
}
|
|
31981
|
-
function
|
|
31982
|
-
|
|
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);
|
|
31983
32704
|
}
|
|
31984
|
-
|
|
31985
|
-
|
|
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;
|
|
31986
32711
|
}
|
|
31987
32712
|
|
|
31988
32713
|
// src/cloud/cookie-sync.ts
|
|
@@ -32038,14 +32763,14 @@ function toPortableBrowserProfileCookieRecord(cookie) {
|
|
|
32038
32763
|
if (!name || !domain) {
|
|
32039
32764
|
return null;
|
|
32040
32765
|
}
|
|
32041
|
-
const
|
|
32766
|
+
const path15 = typeof cookie.path === "string" && cookie.path.trim().length > 0 ? cookie.path : "/";
|
|
32042
32767
|
const expiresAt = typeof cookie.expires === "number" && Number.isFinite(cookie.expires) && cookie.expires > 0 ? Math.floor(cookie.expires * 1e3) : null;
|
|
32043
32768
|
const sameSite = normalizeSameSite(cookie.sameSite);
|
|
32044
32769
|
return {
|
|
32045
32770
|
name,
|
|
32046
32771
|
value: cookie.value,
|
|
32047
32772
|
domain,
|
|
32048
|
-
path:
|
|
32773
|
+
path: path15,
|
|
32049
32774
|
secure: cookie.secure,
|
|
32050
32775
|
httpOnly: cookie.httpOnly,
|
|
32051
32776
|
...sameSite === void 0 ? {} : { sameSite },
|
|
@@ -32061,114 +32786,48 @@ function normalizeSameSite(value) {
|
|
|
32061
32786
|
return void 0;
|
|
32062
32787
|
}
|
|
32063
32788
|
|
|
32064
|
-
// src/cloud/portable-cookie-snapshot.ts
|
|
32065
|
-
var gzip = promisify(gzip$1);
|
|
32066
|
-
async function capturePortableBrowserProfileSnapshot(input = {}) {
|
|
32067
|
-
const attached = input.attachEndpoint ? await inspectCdpEndpoint({
|
|
32068
|
-
endpoint: input.attachEndpoint,
|
|
32069
|
-
...input.timeoutMs === void 0 ? {} : { timeoutMs: input.timeoutMs }
|
|
32070
|
-
}) : await selectAttachBrowserCandidate({
|
|
32071
|
-
...input.timeoutMs === void 0 ? {} : { timeoutMs: input.timeoutMs }
|
|
32072
|
-
});
|
|
32073
|
-
const browser = await connectPlaywrightChromiumBrowser({
|
|
32074
|
-
url: attached.endpoint
|
|
32075
|
-
});
|
|
32076
|
-
try {
|
|
32077
|
-
const context = browser.contexts()[0];
|
|
32078
|
-
if (!context) {
|
|
32079
|
-
throw new Error("Attached browser did not expose a default browser context.");
|
|
32080
|
-
}
|
|
32081
|
-
const prepared = prepareBrowserProfileSyncCookies({
|
|
32082
|
-
cookies: await context.cookies(),
|
|
32083
|
-
...input.domains === void 0 ? {} : { domains: input.domains }
|
|
32084
|
-
});
|
|
32085
|
-
if (prepared.cookies.length === 0) {
|
|
32086
|
-
throw new Error("No syncable cookies found for the selected browser and scope.");
|
|
32087
|
-
}
|
|
32088
|
-
const browserVersion = browser.version();
|
|
32089
|
-
const source = parseSnapshotSource(attached.browser ?? browserVersion);
|
|
32090
|
-
return {
|
|
32091
|
-
version: "portable-cookies-v1",
|
|
32092
|
-
source: {
|
|
32093
|
-
browserFamily: "chromium",
|
|
32094
|
-
...source.browserName === void 0 ? {} : { browserName: source.browserName },
|
|
32095
|
-
...source.browserMajor === void 0 ? {} : { browserMajor: source.browserMajor },
|
|
32096
|
-
...input.browserBrand === void 0 ? {} : { browserBrand: input.browserBrand },
|
|
32097
|
-
...input.captureMethod === void 0 ? {} : { captureMethod: input.captureMethod },
|
|
32098
|
-
platform: normalizePlatform(process.platform),
|
|
32099
|
-
capturedAt: Date.now()
|
|
32100
|
-
},
|
|
32101
|
-
cookies: prepared.cookies
|
|
32102
|
-
};
|
|
32103
|
-
} finally {
|
|
32104
|
-
await browser.close().catch(() => void 0);
|
|
32105
|
-
}
|
|
32106
|
-
}
|
|
32107
|
-
async function encodePortableBrowserProfileSnapshot(snapshot) {
|
|
32108
|
-
return gzip(Buffer.from(JSON.stringify(snapshot), "utf8"));
|
|
32109
|
-
}
|
|
32110
|
-
function parseSnapshotSource(value) {
|
|
32111
|
-
if (!value) {
|
|
32112
|
-
return {};
|
|
32113
|
-
}
|
|
32114
|
-
const trimmed = value.trim();
|
|
32115
|
-
const browserName = trimmed.split("/")[0]?.trim() || void 0;
|
|
32116
|
-
const majorMatch = trimmed.match(/(\d+)/);
|
|
32117
|
-
return {
|
|
32118
|
-
...browserName === void 0 ? {} : { browserName },
|
|
32119
|
-
...majorMatch?.[1] === void 0 ? {} : { browserMajor: majorMatch[1] }
|
|
32120
|
-
};
|
|
32121
|
-
}
|
|
32122
|
-
function normalizePlatform(platform) {
|
|
32123
|
-
if (platform === "darwin") return "macos";
|
|
32124
|
-
if (platform === "win32") return "windows";
|
|
32125
|
-
return platform;
|
|
32126
|
-
}
|
|
32127
|
-
|
|
32128
32789
|
// src/cloud/profile-sync.ts
|
|
32790
|
+
var gzip = promisify(gzip$1);
|
|
32129
32791
|
var DEFAULT_POLL_INTERVAL_MS = 1e3;
|
|
32130
32792
|
var DEFAULT_POLL_TIMEOUT_MS = 5 * 6e4;
|
|
32131
32793
|
async function syncBrowserProfileCookies(client, input) {
|
|
32132
|
-
const
|
|
32133
|
-
...input.attachEndpoint === void 0 ? {} : { attachEndpoint: input.attachEndpoint },
|
|
32794
|
+
const result = await readBrowserCookies({
|
|
32134
32795
|
...input.brandId === void 0 ? {} : { brandId: input.brandId },
|
|
32135
32796
|
...input.userDataDir === void 0 ? {} : { userDataDir: input.userDataDir },
|
|
32136
|
-
...input.profileDirectory === void 0 ? {} : { profileDirectory: input.profileDirectory }
|
|
32137
|
-
...input.executablePath === void 0 ? {} : { executablePath: input.executablePath },
|
|
32138
|
-
...input.strategy === void 0 ? {} : { strategy: input.strategy },
|
|
32139
|
-
...input.timeoutMs === void 0 ? {} : { timeoutMs: input.timeoutMs }
|
|
32797
|
+
...input.profileDirectory === void 0 ? {} : { profileDirectory: input.profileDirectory }
|
|
32140
32798
|
});
|
|
32141
|
-
const
|
|
32142
|
-
|
|
32143
|
-
|
|
32144
|
-
|
|
32145
|
-
|
|
32146
|
-
|
|
32147
|
-
|
|
32148
|
-
|
|
32149
|
-
|
|
32150
|
-
|
|
32151
|
-
|
|
32152
|
-
|
|
32153
|
-
|
|
32154
|
-
|
|
32155
|
-
|
|
32156
|
-
|
|
32157
|
-
|
|
32158
|
-
|
|
32159
|
-
|
|
32160
|
-
|
|
32161
|
-
|
|
32162
|
-
|
|
32163
|
-
|
|
32164
|
-
|
|
32165
|
-
|
|
32166
|
-
|
|
32167
|
-
await captureSource?.cleanup().catch(() => void 0);
|
|
32168
|
-
if (shouldRestoreBrowser && resolved.executablePath !== void 0) {
|
|
32169
|
-
relaunchBrowserNormally(resolved.executablePath);
|
|
32170
|
-
}
|
|
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
|
+
);
|
|
32171
32825
|
}
|
|
32826
|
+
const uploaded = await client.uploadBrowserProfileImportPayload({
|
|
32827
|
+
uploadUrl: created.uploadUrl,
|
|
32828
|
+
payload
|
|
32829
|
+
});
|
|
32830
|
+
return uploaded.status === "ready" ? uploaded : waitForBrowserProfileImport(client, created.importId);
|
|
32172
32831
|
}
|
|
32173
32832
|
async function waitForBrowserProfileImport(client, importId) {
|
|
32174
32833
|
const deadline = Date.now() + DEFAULT_POLL_TIMEOUT_MS;
|
|
@@ -32180,12 +32839,17 @@ async function waitForBrowserProfileImport(client, importId) {
|
|
|
32180
32839
|
if (current.status === "failed") {
|
|
32181
32840
|
throw new Error(current.error ?? "Browser profile sync failed.");
|
|
32182
32841
|
}
|
|
32183
|
-
await
|
|
32842
|
+
await sleep4(DEFAULT_POLL_INTERVAL_MS);
|
|
32184
32843
|
}
|
|
32185
32844
|
throw new Error(`Timed out waiting for browser profile sync "${importId}" to finish.`);
|
|
32186
32845
|
}
|
|
32187
|
-
|
|
32188
|
-
|
|
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));
|
|
32189
32853
|
}
|
|
32190
32854
|
|
|
32191
32855
|
// src/cloud/client.ts
|
|
@@ -32205,7 +32869,8 @@ var OpensteerCloudClient = class {
|
|
|
32205
32869
|
...input.name === void 0 ? {} : { name: input.name },
|
|
32206
32870
|
...input.browser === void 0 ? {} : { browser: input.browser },
|
|
32207
32871
|
...input.context === void 0 ? {} : { context: input.context },
|
|
32208
|
-
...input.browserProfile === void 0 ? {} : { browserProfile: input.browserProfile }
|
|
32872
|
+
...input.browserProfile === void 0 ? {} : { browserProfile: input.browserProfile },
|
|
32873
|
+
...input.observability === void 0 ? {} : { observability: input.observability }
|
|
32209
32874
|
}
|
|
32210
32875
|
});
|
|
32211
32876
|
return await response.json();
|
|
@@ -32383,8 +33048,8 @@ var OpensteerCloudClient = class {
|
|
|
32383
33048
|
}
|
|
32384
33049
|
};
|
|
32385
33050
|
function delay(ms) {
|
|
32386
|
-
return new Promise((
|
|
32387
|
-
setTimeout(
|
|
33051
|
+
return new Promise((resolve4) => {
|
|
33052
|
+
setTimeout(resolve4, ms);
|
|
32388
33053
|
});
|
|
32389
33054
|
}
|
|
32390
33055
|
function wrapCloudFetchError(error, input) {
|
|
@@ -32407,17 +33072,17 @@ function wrapCloudFetchError(error, input) {
|
|
|
32407
33072
|
function resolveCloudConfig(input = {}) {
|
|
32408
33073
|
const provider = resolveOpensteerProvider({
|
|
32409
33074
|
...input.provider === void 0 ? {} : { provider: input.provider },
|
|
32410
|
-
...input.
|
|
33075
|
+
...input.environment?.OPENSTEER_PROVIDER === void 0 ? {} : { environmentProvider: input.environment.OPENSTEER_PROVIDER }
|
|
32411
33076
|
});
|
|
32412
33077
|
if (provider.mode !== "cloud") {
|
|
32413
33078
|
return void 0;
|
|
32414
33079
|
}
|
|
32415
33080
|
const cloudProvider = input.provider?.mode === "cloud" ? input.provider : void 0;
|
|
32416
|
-
const apiKey = cloudProvider?.apiKey ??
|
|
33081
|
+
const apiKey = cloudProvider?.apiKey ?? input.environment?.OPENSTEER_API_KEY;
|
|
32417
33082
|
if (!apiKey || apiKey.trim().length === 0) {
|
|
32418
33083
|
throw new Error("provider=cloud requires OPENSTEER_API_KEY or provider.apiKey.");
|
|
32419
33084
|
}
|
|
32420
|
-
const baseUrl = cloudProvider?.baseUrl ??
|
|
33085
|
+
const baseUrl = cloudProvider?.baseUrl ?? input.environment?.OPENSTEER_BASE_URL;
|
|
32421
33086
|
if (!baseUrl || baseUrl.trim().length === 0) {
|
|
32422
33087
|
throw new Error("provider=cloud requires OPENSTEER_BASE_URL or provider.baseUrl.");
|
|
32423
33088
|
}
|
|
@@ -32519,9 +33184,9 @@ var OpensteerCloudAutomationClient = class {
|
|
|
32519
33184
|
sentAt: Date.now(),
|
|
32520
33185
|
...input === void 0 ? {} : { input }
|
|
32521
33186
|
};
|
|
32522
|
-
return new Promise((
|
|
33187
|
+
return new Promise((resolve4, reject) => {
|
|
32523
33188
|
this.pending.set(requestId, {
|
|
32524
|
-
resolve: (value) =>
|
|
33189
|
+
resolve: (value) => resolve4(value),
|
|
32525
33190
|
reject
|
|
32526
33191
|
});
|
|
32527
33192
|
try {
|
|
@@ -32584,8 +33249,8 @@ var OpensteerCloudAutomationClient = class {
|
|
|
32584
33249
|
pending.reject(new Error(`automation connection closed before ${requestId} completed`));
|
|
32585
33250
|
}
|
|
32586
33251
|
this.pending.clear();
|
|
32587
|
-
await new Promise((
|
|
32588
|
-
socket.once("close", () =>
|
|
33252
|
+
await new Promise((resolve4) => {
|
|
33253
|
+
socket.once("close", () => resolve4());
|
|
32589
33254
|
socket.close();
|
|
32590
33255
|
}).catch(() => void 0);
|
|
32591
33256
|
}
|
|
@@ -32627,8 +33292,8 @@ var OpensteerCloudAutomationClient = class {
|
|
|
32627
33292
|
}
|
|
32628
33293
|
this.pending.clear();
|
|
32629
33294
|
});
|
|
32630
|
-
await new Promise((
|
|
32631
|
-
socket.once("open", () =>
|
|
33295
|
+
await new Promise((resolve4, reject) => {
|
|
33296
|
+
socket.once("open", () => resolve4());
|
|
32632
33297
|
socket.once("error", reject);
|
|
32633
33298
|
});
|
|
32634
33299
|
this.send({
|
|
@@ -32969,6 +33634,7 @@ var CloudSessionProxy = class {
|
|
|
32969
33634
|
workspace;
|
|
32970
33635
|
cleanupRootOnClose;
|
|
32971
33636
|
cloud;
|
|
33637
|
+
observability;
|
|
32972
33638
|
sessionId;
|
|
32973
33639
|
sessionBaseUrl;
|
|
32974
33640
|
client;
|
|
@@ -32977,8 +33643,9 @@ var CloudSessionProxy = class {
|
|
|
32977
33643
|
constructor(cloud, options = {}) {
|
|
32978
33644
|
this.cloud = cloud;
|
|
32979
33645
|
this.workspace = options.workspace;
|
|
32980
|
-
this.
|
|
32981
|
-
|
|
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()),
|
|
32982
33649
|
workspace: this.workspace
|
|
32983
33650
|
}));
|
|
32984
33651
|
this.cleanupRootOnClose = options.cleanupRootOnClose ?? this.workspace === void 0;
|
|
@@ -33321,6 +33988,7 @@ var CloudSessionProxy = class {
|
|
|
33321
33988
|
...this.workspace === void 0 ? {} : { name: this.workspace },
|
|
33322
33989
|
...input.launch === void 0 ? {} : { browser: input.launch },
|
|
33323
33990
|
...input.context === void 0 ? {} : { context: input.context },
|
|
33991
|
+
...this.observability === void 0 ? {} : { observability: this.observability },
|
|
33324
33992
|
...resolveCloudBrowserProfile(this.cloud, input) === void 0 ? {} : { browserProfile: resolveCloudBrowserProfile(this.cloud, input) }
|
|
33325
33993
|
});
|
|
33326
33994
|
const record = {
|
|
@@ -33418,16 +34086,17 @@ function isMissingCloudSessionError(error) {
|
|
|
33418
34086
|
|
|
33419
34087
|
// src/sdk/runtime-resolution.ts
|
|
33420
34088
|
function resolveOpensteerRuntimeConfig(input = {}) {
|
|
34089
|
+
const environment = input.environment ?? process.env;
|
|
33421
34090
|
const provider = resolveOpensteerProvider({
|
|
33422
34091
|
...input.provider === void 0 ? {} : { provider: input.provider },
|
|
33423
|
-
...
|
|
34092
|
+
...environment.OPENSTEER_PROVIDER === void 0 ? {} : { environmentProvider: environment.OPENSTEER_PROVIDER }
|
|
33424
34093
|
});
|
|
33425
34094
|
if (provider.mode === "cloud") {
|
|
33426
34095
|
return {
|
|
33427
34096
|
provider,
|
|
33428
34097
|
cloud: resolveCloudConfig({
|
|
33429
34098
|
...input.provider === void 0 ? {} : { provider: input.provider },
|
|
33430
|
-
|
|
34099
|
+
environment
|
|
33431
34100
|
})
|
|
33432
34101
|
};
|
|
33433
34102
|
}
|
|
@@ -33438,7 +34107,7 @@ function createOpensteerSemanticRuntime(input = {}) {
|
|
|
33438
34107
|
const engine = input.engine ?? runtimeOptions.engineName ?? DEFAULT_OPENSTEER_ENGINE;
|
|
33439
34108
|
const config = resolveOpensteerRuntimeConfig({
|
|
33440
34109
|
...input.provider === void 0 ? {} : { provider: input.provider },
|
|
33441
|
-
...
|
|
34110
|
+
...input.environment === void 0 ? {} : { environment: input.environment }
|
|
33442
34111
|
});
|
|
33443
34112
|
assertProviderSupportsEngine(config.provider.mode, engine);
|
|
33444
34113
|
if (config.provider.mode === "cloud") {
|
|
@@ -33446,7 +34115,8 @@ function createOpensteerSemanticRuntime(input = {}) {
|
|
|
33446
34115
|
...runtimeOptions.rootDir === void 0 ? {} : { rootDir: runtimeOptions.rootDir },
|
|
33447
34116
|
...runtimeOptions.rootPath === void 0 ? {} : { rootPath: runtimeOptions.rootPath },
|
|
33448
34117
|
...runtimeOptions.workspace === void 0 ? {} : { workspace: runtimeOptions.workspace },
|
|
33449
|
-
...runtimeOptions.cleanupRootOnClose === void 0 ? {} : { cleanupRootOnClose: runtimeOptions.cleanupRootOnClose }
|
|
34118
|
+
...runtimeOptions.cleanupRootOnClose === void 0 ? {} : { cleanupRootOnClose: runtimeOptions.cleanupRootOnClose },
|
|
34119
|
+
...runtimeOptions.observability === void 0 ? {} : { observability: runtimeOptions.observability }
|
|
33450
34120
|
});
|
|
33451
34121
|
}
|
|
33452
34122
|
return new OpensteerRuntime({
|
|
@@ -33454,7 +34124,109 @@ function createOpensteerSemanticRuntime(input = {}) {
|
|
|
33454
34124
|
engineName: engine
|
|
33455
34125
|
});
|
|
33456
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
|
+
}
|
|
33457
34229
|
|
|
33458
|
-
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 };
|
|
33459
|
-
//# sourceMappingURL=chunk-
|
|
33460
|
-
//# 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
|