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
package/dist/index.cjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var
|
|
3
|
+
var path7 = require('path');
|
|
4
4
|
var crypto = require('crypto');
|
|
5
5
|
var promises = require('fs/promises');
|
|
6
6
|
var url = require('url');
|
|
@@ -10,6 +10,7 @@ var os = require('os');
|
|
|
10
10
|
var enginePlaywright = require('@opensteer/engine-playwright');
|
|
11
11
|
var util = require('util');
|
|
12
12
|
var fs = require('fs');
|
|
13
|
+
var async_hooks = require('async_hooks');
|
|
13
14
|
var module$1 = require('module');
|
|
14
15
|
var sharp = require('sharp');
|
|
15
16
|
var cheerio = require('cheerio');
|
|
@@ -39,14 +40,19 @@ function _interopNamespace(e) {
|
|
|
39
40
|
return Object.freeze(n);
|
|
40
41
|
}
|
|
41
42
|
|
|
42
|
-
var
|
|
43
|
+
var path7__default = /*#__PURE__*/_interopDefault(path7);
|
|
43
44
|
var sharp__default = /*#__PURE__*/_interopDefault(sharp);
|
|
44
45
|
var cheerio__namespace = /*#__PURE__*/_interopNamespace(cheerio);
|
|
45
46
|
var prettier__namespace = /*#__PURE__*/_interopNamespace(prettier);
|
|
46
47
|
var vm__default = /*#__PURE__*/_interopDefault(vm);
|
|
47
48
|
var WebSocket2__default = /*#__PURE__*/_interopDefault(WebSocket2);
|
|
48
49
|
|
|
49
|
-
|
|
50
|
+
var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
|
|
51
|
+
get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
|
|
52
|
+
}) : x)(function(x) {
|
|
53
|
+
if (typeof require !== "undefined") return require.apply(this, arguments);
|
|
54
|
+
throw Error('Dynamic require of "' + x + '" is not supported');
|
|
55
|
+
});
|
|
50
56
|
|
|
51
57
|
// ../runtime-core/src/json.ts
|
|
52
58
|
function isPlainObject(value) {
|
|
@@ -56,30 +62,30 @@ function isPlainObject(value) {
|
|
|
56
62
|
const prototype = Object.getPrototypeOf(value);
|
|
57
63
|
return prototype === Object.prototype || prototype === null;
|
|
58
64
|
}
|
|
59
|
-
function canonicalizeJsonValue(value,
|
|
65
|
+
function canonicalizeJsonValue(value, path15) {
|
|
60
66
|
if (value === null || typeof value === "string" || typeof value === "boolean") {
|
|
61
67
|
return value;
|
|
62
68
|
}
|
|
63
69
|
if (typeof value === "number") {
|
|
64
70
|
if (!Number.isFinite(value)) {
|
|
65
|
-
throw new TypeError(`${
|
|
71
|
+
throw new TypeError(`${path15} must be a finite JSON number`);
|
|
66
72
|
}
|
|
67
73
|
return value;
|
|
68
74
|
}
|
|
69
75
|
if (Array.isArray(value)) {
|
|
70
|
-
return value.map((entry, index) => canonicalizeJsonValue(entry, `${
|
|
76
|
+
return value.map((entry, index) => canonicalizeJsonValue(entry, `${path15}[${index}]`));
|
|
71
77
|
}
|
|
72
78
|
if (!isPlainObject(value)) {
|
|
73
|
-
throw new TypeError(`${
|
|
79
|
+
throw new TypeError(`${path15} must be a plain JSON object`);
|
|
74
80
|
}
|
|
75
81
|
const sorted = Object.keys(value).sort((left, right) => left.localeCompare(right));
|
|
76
82
|
const result = {};
|
|
77
83
|
for (const key of sorted) {
|
|
78
84
|
const entry = value[key];
|
|
79
85
|
if (entry === void 0) {
|
|
80
|
-
throw new TypeError(`${
|
|
86
|
+
throw new TypeError(`${path15}.${key} must not be undefined`);
|
|
81
87
|
}
|
|
82
|
-
result[key] = canonicalizeJsonValue(entry, `${
|
|
88
|
+
result[key] = canonicalizeJsonValue(entry, `${path15}.${key}`);
|
|
83
89
|
}
|
|
84
90
|
return result;
|
|
85
91
|
}
|
|
@@ -116,7 +122,7 @@ function joinStoragePath(...segments) {
|
|
|
116
122
|
return segments.join("/");
|
|
117
123
|
}
|
|
118
124
|
function resolveStoragePath(rootPath, relativePath) {
|
|
119
|
-
if (
|
|
125
|
+
if (path7__default.default.isAbsolute(relativePath)) {
|
|
120
126
|
throw new TypeError(`storage path ${relativePath} must be relative`);
|
|
121
127
|
}
|
|
122
128
|
const segments = relativePath.split("/");
|
|
@@ -128,7 +134,7 @@ function resolveStoragePath(rootPath, relativePath) {
|
|
|
128
134
|
throw new TypeError(`storage path ${relativePath} must not contain path traversal`);
|
|
129
135
|
}
|
|
130
136
|
}
|
|
131
|
-
return
|
|
137
|
+
return path7__default.default.join(rootPath, ...segments);
|
|
132
138
|
}
|
|
133
139
|
async function ensureDirectory(directoryPath) {
|
|
134
140
|
await promises.mkdir(directoryPath, { recursive: true });
|
|
@@ -148,7 +154,7 @@ async function writeJsonFileAtomic(filePath, value) {
|
|
|
148
154
|
await writeTextFileAtomic(filePath, stableJsonString(value));
|
|
149
155
|
}
|
|
150
156
|
async function writeTextFileAtomic(filePath, value) {
|
|
151
|
-
await ensureDirectory(
|
|
157
|
+
await ensureDirectory(path7__default.default.dirname(filePath));
|
|
152
158
|
const temporaryPath = `${filePath}.${crypto.randomUUID()}.tmp`;
|
|
153
159
|
await promises.writeFile(temporaryPath, value, "utf8");
|
|
154
160
|
await promises.rename(temporaryPath, filePath);
|
|
@@ -157,7 +163,7 @@ async function writeJsonFileExclusive(filePath, value) {
|
|
|
157
163
|
await writeTextFileExclusive(filePath, stableJsonString(value));
|
|
158
164
|
}
|
|
159
165
|
async function writeTextFileExclusive(filePath, value) {
|
|
160
|
-
await ensureDirectory(
|
|
166
|
+
await ensureDirectory(path7__default.default.dirname(filePath));
|
|
161
167
|
const handle = await promises.open(filePath, "wx");
|
|
162
168
|
try {
|
|
163
169
|
await handle.writeFile(value, "utf8");
|
|
@@ -166,7 +172,7 @@ async function writeTextFileExclusive(filePath, value) {
|
|
|
166
172
|
}
|
|
167
173
|
}
|
|
168
174
|
async function writeBufferIfMissing(filePath, value) {
|
|
169
|
-
await ensureDirectory(
|
|
175
|
+
await ensureDirectory(path7__default.default.dirname(filePath));
|
|
170
176
|
try {
|
|
171
177
|
const handle = await promises.open(filePath, "wx");
|
|
172
178
|
try {
|
|
@@ -200,7 +206,7 @@ function isAlreadyExistsError(error) {
|
|
|
200
206
|
return error?.code === "EEXIST";
|
|
201
207
|
}
|
|
202
208
|
async function withFilesystemLock(lockPath, task) {
|
|
203
|
-
await ensureDirectory(
|
|
209
|
+
await ensureDirectory(path7__default.default.dirname(lockPath));
|
|
204
210
|
let attempt = 0;
|
|
205
211
|
while (true) {
|
|
206
212
|
try {
|
|
@@ -212,7 +218,7 @@ async function withFilesystemLock(lockPath, task) {
|
|
|
212
218
|
}
|
|
213
219
|
const delayMs = LOCK_RETRY_DELAYS_MS[Math.min(attempt, LOCK_RETRY_DELAYS_MS.length - 1)];
|
|
214
220
|
attempt += 1;
|
|
215
|
-
await new Promise((
|
|
221
|
+
await new Promise((resolve4) => setTimeout(resolve4, delayMs));
|
|
216
222
|
}
|
|
217
223
|
}
|
|
218
224
|
try {
|
|
@@ -255,8 +261,8 @@ async function readStructuredPayload(objectPath) {
|
|
|
255
261
|
var FilesystemArtifactStore = class {
|
|
256
262
|
constructor(rootPath) {
|
|
257
263
|
this.rootPath = rootPath;
|
|
258
|
-
this.manifestsDirectory =
|
|
259
|
-
this.objectsDirectory =
|
|
264
|
+
this.manifestsDirectory = path7__default.default.join(this.rootPath, "artifacts", "manifests");
|
|
265
|
+
this.objectsDirectory = path7__default.default.join(this.rootPath, "artifacts", "objects", "sha256");
|
|
260
266
|
}
|
|
261
267
|
manifestsDirectory;
|
|
262
268
|
objectsDirectory;
|
|
@@ -481,7 +487,7 @@ var FilesystemArtifactStore = class {
|
|
|
481
487
|
}
|
|
482
488
|
}
|
|
483
489
|
manifestPath(artifactId) {
|
|
484
|
-
return
|
|
490
|
+
return path7__default.default.join(this.manifestsDirectory, `${encodePathSegment(artifactId)}.json`);
|
|
485
491
|
}
|
|
486
492
|
};
|
|
487
493
|
function createArtifactStore(rootPath) {
|
|
@@ -576,31 +582,31 @@ function oneOfSchema(members, options = {}) {
|
|
|
576
582
|
}
|
|
577
583
|
|
|
578
584
|
// ../protocol/src/validation.ts
|
|
579
|
-
function validateJsonSchema(schema, value,
|
|
580
|
-
return validateSchemaNode(schema, value,
|
|
585
|
+
function validateJsonSchema(schema, value, path15 = "$") {
|
|
586
|
+
return validateSchemaNode(schema, value, path15);
|
|
581
587
|
}
|
|
582
|
-
function validateSchemaNode(schema, value,
|
|
588
|
+
function validateSchemaNode(schema, value, path15) {
|
|
583
589
|
const issues = [];
|
|
584
590
|
if ("const" in schema && !isJsonValueEqual(schema.const, value)) {
|
|
585
591
|
issues.push({
|
|
586
|
-
path:
|
|
592
|
+
path: path15,
|
|
587
593
|
message: `must equal ${JSON.stringify(schema.const)}`
|
|
588
594
|
});
|
|
589
595
|
return issues;
|
|
590
596
|
}
|
|
591
597
|
if (schema.enum !== void 0 && !schema.enum.some((candidate) => isJsonValueEqual(candidate, value))) {
|
|
592
598
|
issues.push({
|
|
593
|
-
path:
|
|
599
|
+
path: path15,
|
|
594
600
|
message: `must be one of ${schema.enum.map((candidate) => JSON.stringify(candidate)).join(", ")}`
|
|
595
601
|
});
|
|
596
602
|
return issues;
|
|
597
603
|
}
|
|
598
604
|
if (schema.oneOf !== void 0) {
|
|
599
|
-
const branchIssues = schema.oneOf.map((member) => validateSchemaNode(member, value,
|
|
605
|
+
const branchIssues = schema.oneOf.map((member) => validateSchemaNode(member, value, path15));
|
|
600
606
|
const validBranches = branchIssues.filter((current) => current.length === 0).length;
|
|
601
607
|
if (validBranches !== 1) {
|
|
602
608
|
issues.push({
|
|
603
|
-
path:
|
|
609
|
+
path: path15,
|
|
604
610
|
message: validBranches === 0 ? "must match exactly one supported shape" : "matches multiple supported shapes"
|
|
605
611
|
});
|
|
606
612
|
return issues;
|
|
@@ -608,11 +614,11 @@ function validateSchemaNode(schema, value, path13) {
|
|
|
608
614
|
}
|
|
609
615
|
if (schema.anyOf !== void 0) {
|
|
610
616
|
const hasMatch = schema.anyOf.some(
|
|
611
|
-
(member) => validateSchemaNode(member, value,
|
|
617
|
+
(member) => validateSchemaNode(member, value, path15).length === 0
|
|
612
618
|
);
|
|
613
619
|
if (!hasMatch) {
|
|
614
620
|
issues.push({
|
|
615
|
-
path:
|
|
621
|
+
path: path15,
|
|
616
622
|
message: "must match at least one supported shape"
|
|
617
623
|
});
|
|
618
624
|
return issues;
|
|
@@ -620,7 +626,7 @@ function validateSchemaNode(schema, value, path13) {
|
|
|
620
626
|
}
|
|
621
627
|
if (schema.allOf !== void 0) {
|
|
622
628
|
for (const member of schema.allOf) {
|
|
623
|
-
issues.push(...validateSchemaNode(member, value,
|
|
629
|
+
issues.push(...validateSchemaNode(member, value, path15));
|
|
624
630
|
}
|
|
625
631
|
if (issues.length > 0) {
|
|
626
632
|
return issues;
|
|
@@ -628,7 +634,7 @@ function validateSchemaNode(schema, value, path13) {
|
|
|
628
634
|
}
|
|
629
635
|
if (schema.type !== void 0 && !matchesSchemaType(schema.type, value)) {
|
|
630
636
|
issues.push({
|
|
631
|
-
path:
|
|
637
|
+
path: path15,
|
|
632
638
|
message: `must be ${describeSchemaType(schema.type)}`
|
|
633
639
|
});
|
|
634
640
|
return issues;
|
|
@@ -636,19 +642,19 @@ function validateSchemaNode(schema, value, path13) {
|
|
|
636
642
|
if (typeof value === "string") {
|
|
637
643
|
if (schema.minLength !== void 0 && value.length < schema.minLength) {
|
|
638
644
|
issues.push({
|
|
639
|
-
path:
|
|
645
|
+
path: path15,
|
|
640
646
|
message: `must have length >= ${String(schema.minLength)}`
|
|
641
647
|
});
|
|
642
648
|
}
|
|
643
649
|
if (schema.maxLength !== void 0 && value.length > schema.maxLength) {
|
|
644
650
|
issues.push({
|
|
645
|
-
path:
|
|
651
|
+
path: path15,
|
|
646
652
|
message: `must have length <= ${String(schema.maxLength)}`
|
|
647
653
|
});
|
|
648
654
|
}
|
|
649
655
|
if (schema.pattern !== void 0 && !new RegExp(schema.pattern).test(value)) {
|
|
650
656
|
issues.push({
|
|
651
|
-
path:
|
|
657
|
+
path: path15,
|
|
652
658
|
message: `must match pattern ${schema.pattern}`
|
|
653
659
|
});
|
|
654
660
|
}
|
|
@@ -657,25 +663,25 @@ function validateSchemaNode(schema, value, path13) {
|
|
|
657
663
|
if (typeof value === "number") {
|
|
658
664
|
if (schema.minimum !== void 0 && value < schema.minimum) {
|
|
659
665
|
issues.push({
|
|
660
|
-
path:
|
|
666
|
+
path: path15,
|
|
661
667
|
message: `must be >= ${String(schema.minimum)}`
|
|
662
668
|
});
|
|
663
669
|
}
|
|
664
670
|
if (schema.maximum !== void 0 && value > schema.maximum) {
|
|
665
671
|
issues.push({
|
|
666
|
-
path:
|
|
672
|
+
path: path15,
|
|
667
673
|
message: `must be <= ${String(schema.maximum)}`
|
|
668
674
|
});
|
|
669
675
|
}
|
|
670
676
|
if (schema.exclusiveMinimum !== void 0 && value <= schema.exclusiveMinimum) {
|
|
671
677
|
issues.push({
|
|
672
|
-
path:
|
|
678
|
+
path: path15,
|
|
673
679
|
message: `must be > ${String(schema.exclusiveMinimum)}`
|
|
674
680
|
});
|
|
675
681
|
}
|
|
676
682
|
if (schema.exclusiveMaximum !== void 0 && value >= schema.exclusiveMaximum) {
|
|
677
683
|
issues.push({
|
|
678
|
-
path:
|
|
684
|
+
path: path15,
|
|
679
685
|
message: `must be < ${String(schema.exclusiveMaximum)}`
|
|
680
686
|
});
|
|
681
687
|
}
|
|
@@ -684,13 +690,13 @@ function validateSchemaNode(schema, value, path13) {
|
|
|
684
690
|
if (Array.isArray(value)) {
|
|
685
691
|
if (schema.minItems !== void 0 && value.length < schema.minItems) {
|
|
686
692
|
issues.push({
|
|
687
|
-
path:
|
|
693
|
+
path: path15,
|
|
688
694
|
message: `must have at least ${String(schema.minItems)} items`
|
|
689
695
|
});
|
|
690
696
|
}
|
|
691
697
|
if (schema.maxItems !== void 0 && value.length > schema.maxItems) {
|
|
692
698
|
issues.push({
|
|
693
|
-
path:
|
|
699
|
+
path: path15,
|
|
694
700
|
message: `must have at most ${String(schema.maxItems)} items`
|
|
695
701
|
});
|
|
696
702
|
}
|
|
@@ -700,7 +706,7 @@ function validateSchemaNode(schema, value, path13) {
|
|
|
700
706
|
const key = JSON.stringify(item);
|
|
701
707
|
if (seen.has(key)) {
|
|
702
708
|
issues.push({
|
|
703
|
-
path:
|
|
709
|
+
path: path15,
|
|
704
710
|
message: "must not contain duplicate items"
|
|
705
711
|
});
|
|
706
712
|
break;
|
|
@@ -710,7 +716,7 @@ function validateSchemaNode(schema, value, path13) {
|
|
|
710
716
|
}
|
|
711
717
|
if (schema.items !== void 0) {
|
|
712
718
|
for (let index = 0; index < value.length; index += 1) {
|
|
713
|
-
issues.push(...validateSchemaNode(schema.items, value[index], `${
|
|
719
|
+
issues.push(...validateSchemaNode(schema.items, value[index], `${path15}[${String(index)}]`));
|
|
714
720
|
}
|
|
715
721
|
}
|
|
716
722
|
return issues;
|
|
@@ -720,7 +726,7 @@ function validateSchemaNode(schema, value, path13) {
|
|
|
720
726
|
for (const requiredKey of schema.required ?? []) {
|
|
721
727
|
if (!(requiredKey in value)) {
|
|
722
728
|
issues.push({
|
|
723
|
-
path: joinObjectPath(
|
|
729
|
+
path: joinObjectPath(path15, requiredKey),
|
|
724
730
|
message: "is required"
|
|
725
731
|
});
|
|
726
732
|
}
|
|
@@ -729,13 +735,13 @@ function validateSchemaNode(schema, value, path13) {
|
|
|
729
735
|
const propertySchema = properties[key];
|
|
730
736
|
if (propertySchema !== void 0) {
|
|
731
737
|
issues.push(
|
|
732
|
-
...validateSchemaNode(propertySchema, propertyValue, joinObjectPath(
|
|
738
|
+
...validateSchemaNode(propertySchema, propertyValue, joinObjectPath(path15, key))
|
|
733
739
|
);
|
|
734
740
|
continue;
|
|
735
741
|
}
|
|
736
742
|
if (schema.additionalProperties === false) {
|
|
737
743
|
issues.push({
|
|
738
|
-
path: joinObjectPath(
|
|
744
|
+
path: joinObjectPath(path15, key),
|
|
739
745
|
message: "is not allowed"
|
|
740
746
|
});
|
|
741
747
|
continue;
|
|
@@ -745,7 +751,7 @@ function validateSchemaNode(schema, value, path13) {
|
|
|
745
751
|
...validateSchemaNode(
|
|
746
752
|
schema.additionalProperties,
|
|
747
753
|
propertyValue,
|
|
748
|
-
joinObjectPath(
|
|
754
|
+
joinObjectPath(path15, key)
|
|
749
755
|
)
|
|
750
756
|
);
|
|
751
757
|
}
|
|
@@ -989,8 +995,8 @@ function matchesNetworkRecordFilters(record, filters) {
|
|
|
989
995
|
}
|
|
990
996
|
}
|
|
991
997
|
if (filters.path !== void 0) {
|
|
992
|
-
const
|
|
993
|
-
if (!includesCaseInsensitive(
|
|
998
|
+
const path15 = getParsedUrl().pathname;
|
|
999
|
+
if (!includesCaseInsensitive(path15, filters.path)) {
|
|
994
1000
|
return false;
|
|
995
1001
|
}
|
|
996
1002
|
}
|
|
@@ -7080,9 +7086,9 @@ function compareByCreatedAtAndId(left, right) {
|
|
|
7080
7086
|
var FilesystemRegistryStore = class {
|
|
7081
7087
|
constructor(rootPath, registryRelativePath) {
|
|
7082
7088
|
this.registryRelativePath = registryRelativePath;
|
|
7083
|
-
const basePath =
|
|
7084
|
-
this.recordsDirectory =
|
|
7085
|
-
this.indexesDirectory =
|
|
7089
|
+
const basePath = path7__default.default.join(rootPath, ...registryRelativePath);
|
|
7090
|
+
this.recordsDirectory = path7__default.default.join(basePath, "records");
|
|
7091
|
+
this.indexesDirectory = path7__default.default.join(basePath, "indexes", "by-key");
|
|
7086
7092
|
}
|
|
7087
7093
|
recordsDirectory;
|
|
7088
7094
|
indexesDirectory;
|
|
@@ -7151,7 +7157,7 @@ var FilesystemRegistryStore = class {
|
|
|
7151
7157
|
async readRecordsFromDirectory() {
|
|
7152
7158
|
const files = await listJsonFiles(this.recordsDirectory);
|
|
7153
7159
|
const records = await Promise.all(
|
|
7154
|
-
files.map((fileName) => readJsonFile(
|
|
7160
|
+
files.map((fileName) => readJsonFile(path7__default.default.join(this.recordsDirectory, fileName)))
|
|
7155
7161
|
);
|
|
7156
7162
|
records.sort(compareByCreatedAtAndId);
|
|
7157
7163
|
return records;
|
|
@@ -7183,17 +7189,17 @@ var FilesystemRegistryStore = class {
|
|
|
7183
7189
|
return record;
|
|
7184
7190
|
}
|
|
7185
7191
|
recordPath(id) {
|
|
7186
|
-
return
|
|
7192
|
+
return path7__default.default.join(this.recordsDirectory, `${encodePathSegment(id)}.json`);
|
|
7187
7193
|
}
|
|
7188
7194
|
indexPath(key, version) {
|
|
7189
|
-
return
|
|
7195
|
+
return path7__default.default.join(
|
|
7190
7196
|
this.indexesDirectory,
|
|
7191
7197
|
encodePathSegment(key),
|
|
7192
7198
|
`${encodePathSegment(version)}.json`
|
|
7193
7199
|
);
|
|
7194
7200
|
}
|
|
7195
7201
|
writeLockPath() {
|
|
7196
|
-
return
|
|
7202
|
+
return path7__default.default.join(path7__default.default.dirname(this.recordsDirectory), ".write.lock");
|
|
7197
7203
|
}
|
|
7198
7204
|
};
|
|
7199
7205
|
var FilesystemDescriptorRegistry = class extends FilesystemRegistryStore {
|
|
@@ -7563,7 +7569,7 @@ var SqliteSavedNetworkStore = class {
|
|
|
7563
7569
|
directoryInitialization;
|
|
7564
7570
|
databaseInitialization;
|
|
7565
7571
|
constructor(rootPath) {
|
|
7566
|
-
this.databasePath =
|
|
7572
|
+
this.databasePath = path7__default.default.join(rootPath, "registry", "saved-network.sqlite");
|
|
7567
7573
|
}
|
|
7568
7574
|
async initialize() {
|
|
7569
7575
|
await this.ensureDatabaseDirectory();
|
|
@@ -7773,7 +7779,7 @@ var SqliteSavedNetworkStore = class {
|
|
|
7773
7779
|
}
|
|
7774
7780
|
}
|
|
7775
7781
|
async ensureDatabaseDirectory() {
|
|
7776
|
-
this.directoryInitialization ??= ensureDirectory(
|
|
7782
|
+
this.directoryInitialization ??= ensureDirectory(path7__default.default.dirname(this.databasePath)).catch(
|
|
7777
7783
|
(error) => {
|
|
7778
7784
|
this.directoryInitialization = void 0;
|
|
7779
7785
|
throw error;
|
|
@@ -8163,6 +8169,546 @@ function withSqliteTransaction(database, task) {
|
|
|
8163
8169
|
function createSavedNetworkStore(rootPath) {
|
|
8164
8170
|
return new SqliteSavedNetworkStore(rootPath);
|
|
8165
8171
|
}
|
|
8172
|
+
|
|
8173
|
+
// ../runtime-core/src/observation-utils.ts
|
|
8174
|
+
var REDACTED = "[REDACTED]";
|
|
8175
|
+
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;
|
|
8176
|
+
var SENSITIVE_VALUE_PATTERNS = [
|
|
8177
|
+
/\bsk-[A-Za-z0-9_-]{20,}\b/g,
|
|
8178
|
+
/\bAIza[0-9A-Za-z_-]{20,}\b/g,
|
|
8179
|
+
/\b(?:gh[pousr]_[A-Za-z0-9]{20,}|github_pat_[A-Za-z0-9_]{20,})\b/g,
|
|
8180
|
+
/\beyJ[A-Za-z0-9_-]{10,}\.[A-Za-z0-9_-]{10,}\.[A-Za-z0-9_-]{10,}\b/g,
|
|
8181
|
+
/\bBearer\s+[A-Za-z0-9._~+/=-]{16,}\b/gi
|
|
8182
|
+
];
|
|
8183
|
+
function normalizeObservationContext(context) {
|
|
8184
|
+
if (context === void 0) {
|
|
8185
|
+
return void 0;
|
|
8186
|
+
}
|
|
8187
|
+
const normalized = {
|
|
8188
|
+
...context.sessionRef === void 0 ? {} : { sessionRef: context.sessionRef },
|
|
8189
|
+
...context.pageRef === void 0 ? {} : { pageRef: context.pageRef },
|
|
8190
|
+
...context.frameRef === void 0 ? {} : { frameRef: context.frameRef },
|
|
8191
|
+
...context.documentRef === void 0 ? {} : { documentRef: context.documentRef },
|
|
8192
|
+
...context.documentEpoch === void 0 ? {} : { documentEpoch: context.documentEpoch }
|
|
8193
|
+
};
|
|
8194
|
+
return Object.keys(normalized).length === 0 ? void 0 : normalized;
|
|
8195
|
+
}
|
|
8196
|
+
function createObservationRedactor(config) {
|
|
8197
|
+
const state = createRedactionState(config);
|
|
8198
|
+
return {
|
|
8199
|
+
redactText(value) {
|
|
8200
|
+
return redactString(value, state);
|
|
8201
|
+
},
|
|
8202
|
+
redactJson(value) {
|
|
8203
|
+
return value === void 0 ? void 0 : redactUnknown(value, state, /* @__PURE__ */ new WeakSet());
|
|
8204
|
+
},
|
|
8205
|
+
redactError(error) {
|
|
8206
|
+
if (error === void 0) {
|
|
8207
|
+
return void 0;
|
|
8208
|
+
}
|
|
8209
|
+
return {
|
|
8210
|
+
...error.code === void 0 ? {} : { code: redactString(error.code, state) },
|
|
8211
|
+
message: redactString(error.message, state),
|
|
8212
|
+
...error.retriable === void 0 ? {} : { retriable: error.retriable },
|
|
8213
|
+
...error.details === void 0 ? {} : { details: toCanonicalJsonValue(redactUnknown(error.details, state, /* @__PURE__ */ new WeakSet())) }
|
|
8214
|
+
};
|
|
8215
|
+
},
|
|
8216
|
+
redactLabels(labels) {
|
|
8217
|
+
if (labels === void 0) {
|
|
8218
|
+
return void 0;
|
|
8219
|
+
}
|
|
8220
|
+
const next = Object.entries(labels).reduce(
|
|
8221
|
+
(accumulator, [key, value]) => {
|
|
8222
|
+
accumulator[key] = isSensitiveKey(key, state) ? REDACTED : redactString(value, state);
|
|
8223
|
+
return accumulator;
|
|
8224
|
+
},
|
|
8225
|
+
{}
|
|
8226
|
+
);
|
|
8227
|
+
return Object.keys(next).length === 0 ? void 0 : next;
|
|
8228
|
+
},
|
|
8229
|
+
redactTraceContext(traceContext) {
|
|
8230
|
+
if (traceContext === void 0) {
|
|
8231
|
+
return void 0;
|
|
8232
|
+
}
|
|
8233
|
+
const next = {
|
|
8234
|
+
...traceContext.traceparent === void 0 ? {} : { traceparent: redactString(traceContext.traceparent, state) },
|
|
8235
|
+
...traceContext.baggage === void 0 ? {} : { baggage: redactString(traceContext.baggage, state) }
|
|
8236
|
+
};
|
|
8237
|
+
return Object.keys(next).length === 0 ? void 0 : next;
|
|
8238
|
+
}
|
|
8239
|
+
};
|
|
8240
|
+
}
|
|
8241
|
+
function createRedactionState(config) {
|
|
8242
|
+
return {
|
|
8243
|
+
sensitiveKeys: new Set(
|
|
8244
|
+
(config?.redaction?.sensitiveKeys ?? []).map((value) => value.trim().toLowerCase()).filter((value) => value.length > 0)
|
|
8245
|
+
),
|
|
8246
|
+
sensitiveValues: [
|
|
8247
|
+
...new Set(
|
|
8248
|
+
(config?.redaction?.sensitiveValues ?? []).map((value) => value.trim()).filter((value) => value.length > 0)
|
|
8249
|
+
)
|
|
8250
|
+
]
|
|
8251
|
+
};
|
|
8252
|
+
}
|
|
8253
|
+
function redactUnknown(value, state, seen) {
|
|
8254
|
+
if (value === null || value === void 0) {
|
|
8255
|
+
return value;
|
|
8256
|
+
}
|
|
8257
|
+
if (typeof value === "string") {
|
|
8258
|
+
return redactString(value, state);
|
|
8259
|
+
}
|
|
8260
|
+
if (typeof value !== "object") {
|
|
8261
|
+
return value;
|
|
8262
|
+
}
|
|
8263
|
+
if (seen.has(value)) {
|
|
8264
|
+
return REDACTED;
|
|
8265
|
+
}
|
|
8266
|
+
seen.add(value);
|
|
8267
|
+
if (Array.isArray(value)) {
|
|
8268
|
+
return value.map((entry) => redactUnknown(entry, state, seen));
|
|
8269
|
+
}
|
|
8270
|
+
const next = {};
|
|
8271
|
+
for (const [key, nestedValue] of Object.entries(value)) {
|
|
8272
|
+
next[key] = isSensitiveKey(key, state) ? REDACTED : redactUnknown(nestedValue, state, seen);
|
|
8273
|
+
}
|
|
8274
|
+
return next;
|
|
8275
|
+
}
|
|
8276
|
+
function redactString(value, state) {
|
|
8277
|
+
let next = value;
|
|
8278
|
+
for (const secret of state.sensitiveValues) {
|
|
8279
|
+
next = next.split(secret).join(REDACTED);
|
|
8280
|
+
}
|
|
8281
|
+
for (const pattern of SENSITIVE_VALUE_PATTERNS) {
|
|
8282
|
+
next = next.replace(pattern, REDACTED);
|
|
8283
|
+
}
|
|
8284
|
+
return redactUrlString(next, state);
|
|
8285
|
+
}
|
|
8286
|
+
function redactUrlString(value, state) {
|
|
8287
|
+
let parsed;
|
|
8288
|
+
try {
|
|
8289
|
+
parsed = new URL(value);
|
|
8290
|
+
} catch {
|
|
8291
|
+
return value;
|
|
8292
|
+
}
|
|
8293
|
+
let changed = false;
|
|
8294
|
+
if (parsed.username) {
|
|
8295
|
+
parsed.username = REDACTED;
|
|
8296
|
+
changed = true;
|
|
8297
|
+
}
|
|
8298
|
+
if (parsed.password) {
|
|
8299
|
+
parsed.password = REDACTED;
|
|
8300
|
+
changed = true;
|
|
8301
|
+
}
|
|
8302
|
+
for (const [key] of parsed.searchParams) {
|
|
8303
|
+
if (!isSensitiveKey(key, state)) {
|
|
8304
|
+
continue;
|
|
8305
|
+
}
|
|
8306
|
+
parsed.searchParams.set(key, REDACTED);
|
|
8307
|
+
changed = true;
|
|
8308
|
+
}
|
|
8309
|
+
return changed ? parsed.toString() : value;
|
|
8310
|
+
}
|
|
8311
|
+
function isSensitiveKey(key, state) {
|
|
8312
|
+
return state.sensitiveKeys.has(key.trim().toLowerCase()) || SENSITIVE_KEY_PATTERN.test(key);
|
|
8313
|
+
}
|
|
8314
|
+
|
|
8315
|
+
// ../runtime-core/src/observations.ts
|
|
8316
|
+
function normalizeObservabilityConfig(input) {
|
|
8317
|
+
const profile = input?.profile ?? "diagnostic";
|
|
8318
|
+
const labels = input?.labels === void 0 ? void 0 : Object.entries(input.labels).reduce((accumulator, [key, value]) => {
|
|
8319
|
+
const normalizedKey = key.trim();
|
|
8320
|
+
const normalizedValue = value.trim();
|
|
8321
|
+
if (normalizedKey.length === 0 || normalizedValue.length === 0) {
|
|
8322
|
+
return accumulator;
|
|
8323
|
+
}
|
|
8324
|
+
if (Object.keys(accumulator).length >= 20) {
|
|
8325
|
+
return accumulator;
|
|
8326
|
+
}
|
|
8327
|
+
accumulator[normalizedKey] = normalizedValue;
|
|
8328
|
+
return accumulator;
|
|
8329
|
+
}, {});
|
|
8330
|
+
const redaction = input?.redaction === void 0 ? void 0 : {
|
|
8331
|
+
...input.redaction.sensitiveKeys === void 0 ? {} : {
|
|
8332
|
+
sensitiveKeys: input.redaction.sensitiveKeys.map((value) => value.trim()).filter((value) => value.length > 0)
|
|
8333
|
+
},
|
|
8334
|
+
...input.redaction.sensitiveValues === void 0 ? {} : {
|
|
8335
|
+
sensitiveValues: input.redaction.sensitiveValues.map((value) => value.trim()).filter((value) => value.length > 0)
|
|
8336
|
+
}
|
|
8337
|
+
};
|
|
8338
|
+
return {
|
|
8339
|
+
profile,
|
|
8340
|
+
...labels === void 0 || Object.keys(labels).length === 0 ? {} : { labels },
|
|
8341
|
+
...input?.traceContext === void 0 ? {} : {
|
|
8342
|
+
traceContext: {
|
|
8343
|
+
...input.traceContext.traceparent === void 0 ? {} : { traceparent: input.traceContext.traceparent.trim() },
|
|
8344
|
+
...input.traceContext.baggage === void 0 ? {} : { baggage: input.traceContext.baggage.trim() }
|
|
8345
|
+
}
|
|
8346
|
+
},
|
|
8347
|
+
...redaction === void 0 ? {} : { redaction }
|
|
8348
|
+
};
|
|
8349
|
+
}
|
|
8350
|
+
function eventFileName(sequence) {
|
|
8351
|
+
return `${String(sequence).padStart(12, "0")}.json`;
|
|
8352
|
+
}
|
|
8353
|
+
var FilesystemSessionSink = class {
|
|
8354
|
+
constructor(store, sessionId) {
|
|
8355
|
+
this.store = store;
|
|
8356
|
+
this.sessionId = sessionId;
|
|
8357
|
+
}
|
|
8358
|
+
append(input) {
|
|
8359
|
+
return this.store.appendEvent(this.sessionId, input);
|
|
8360
|
+
}
|
|
8361
|
+
appendBatch(input) {
|
|
8362
|
+
return this.store.appendEvents(this.sessionId, input);
|
|
8363
|
+
}
|
|
8364
|
+
writeArtifact(input) {
|
|
8365
|
+
return this.store.writeArtifact(this.sessionId, input);
|
|
8366
|
+
}
|
|
8367
|
+
async flush() {
|
|
8368
|
+
}
|
|
8369
|
+
close(reason) {
|
|
8370
|
+
return this.store.closeSession(this.sessionId, reason);
|
|
8371
|
+
}
|
|
8372
|
+
};
|
|
8373
|
+
var FilesystemObservationStoreImpl = class {
|
|
8374
|
+
constructor(rootPath, artifacts) {
|
|
8375
|
+
this.rootPath = rootPath;
|
|
8376
|
+
this.artifacts = artifacts;
|
|
8377
|
+
this.sessionsDirectory = path7__default.default.join(this.rootPath, "observations", "sessions");
|
|
8378
|
+
}
|
|
8379
|
+
sessionsDirectory;
|
|
8380
|
+
redactors = /* @__PURE__ */ new Map();
|
|
8381
|
+
async initialize() {
|
|
8382
|
+
await ensureDirectory(this.sessionsDirectory);
|
|
8383
|
+
}
|
|
8384
|
+
async openSession(input) {
|
|
8385
|
+
const sessionId = normalizeNonEmptyString("sessionId", input.sessionId);
|
|
8386
|
+
const openedAt = normalizeTimestamp("openedAt", input.openedAt ?? Date.now());
|
|
8387
|
+
const config = normalizeObservabilityConfig(input.config);
|
|
8388
|
+
const redactor = createObservationRedactor(config);
|
|
8389
|
+
this.redactors.set(sessionId, redactor);
|
|
8390
|
+
const redactedLabels = redactor.redactLabels(config.labels);
|
|
8391
|
+
const redactedTraceContext = redactor.redactTraceContext(config.traceContext);
|
|
8392
|
+
await withFilesystemLock(this.sessionLockPath(sessionId), async () => {
|
|
8393
|
+
const existing = await this.reconcileSessionManifest(sessionId);
|
|
8394
|
+
if (existing === void 0) {
|
|
8395
|
+
await ensureDirectory(this.sessionEventsDirectory(sessionId));
|
|
8396
|
+
await ensureDirectory(this.sessionArtifactsDirectory(sessionId));
|
|
8397
|
+
const session = {
|
|
8398
|
+
sessionId,
|
|
8399
|
+
profile: config.profile,
|
|
8400
|
+
...redactedLabels === void 0 ? {} : { labels: redactedLabels },
|
|
8401
|
+
...redactedTraceContext === void 0 ? {} : { traceContext: redactedTraceContext },
|
|
8402
|
+
openedAt,
|
|
8403
|
+
updatedAt: openedAt,
|
|
8404
|
+
currentSequence: 0,
|
|
8405
|
+
eventCount: 0,
|
|
8406
|
+
artifactCount: 0
|
|
8407
|
+
};
|
|
8408
|
+
await writeJsonFileExclusive(this.sessionManifestPath(sessionId), session);
|
|
8409
|
+
return;
|
|
8410
|
+
}
|
|
8411
|
+
const patched = {
|
|
8412
|
+
...existing,
|
|
8413
|
+
profile: config.profile,
|
|
8414
|
+
...redactedLabels === void 0 ? {} : { labels: redactedLabels },
|
|
8415
|
+
...redactedTraceContext === void 0 ? {} : { traceContext: redactedTraceContext },
|
|
8416
|
+
updatedAt: Math.max(existing.updatedAt, openedAt)
|
|
8417
|
+
};
|
|
8418
|
+
await writeJsonFileAtomic(this.sessionManifestPath(sessionId), patched);
|
|
8419
|
+
});
|
|
8420
|
+
return new FilesystemSessionSink(this, sessionId);
|
|
8421
|
+
}
|
|
8422
|
+
async getSession(sessionId) {
|
|
8423
|
+
const manifestPath = this.sessionManifestPath(sessionId);
|
|
8424
|
+
if (!await pathExists(manifestPath)) {
|
|
8425
|
+
return void 0;
|
|
8426
|
+
}
|
|
8427
|
+
return readJsonFile(manifestPath);
|
|
8428
|
+
}
|
|
8429
|
+
async appendEvent(sessionId, input) {
|
|
8430
|
+
const [event] = await this.appendEvents(sessionId, [input]);
|
|
8431
|
+
if (event === void 0) {
|
|
8432
|
+
throw new Error(`failed to append observation event for session ${sessionId}`);
|
|
8433
|
+
}
|
|
8434
|
+
return event;
|
|
8435
|
+
}
|
|
8436
|
+
async appendEvents(sessionId, input) {
|
|
8437
|
+
if (input.length === 0) {
|
|
8438
|
+
return [];
|
|
8439
|
+
}
|
|
8440
|
+
return withFilesystemLock(this.sessionLockPath(sessionId), async () => {
|
|
8441
|
+
const session = await this.reconcileSessionManifest(sessionId);
|
|
8442
|
+
if (session === void 0) {
|
|
8443
|
+
throw new Error(`observation session ${sessionId} was not found`);
|
|
8444
|
+
}
|
|
8445
|
+
const redactor = this.redactors.get(sessionId) ?? createObservationRedactor(void 0);
|
|
8446
|
+
const events = [];
|
|
8447
|
+
let sequence = session.currentSequence;
|
|
8448
|
+
let updatedAt = session.updatedAt;
|
|
8449
|
+
for (const raw of input) {
|
|
8450
|
+
sequence += 1;
|
|
8451
|
+
const createdAt = normalizeTimestamp("createdAt", raw.createdAt);
|
|
8452
|
+
const context = normalizeObservationContext(raw.context);
|
|
8453
|
+
const redactedData = raw.data === void 0 ? void 0 : redactor.redactJson(toCanonicalJsonValue(raw.data));
|
|
8454
|
+
const redactedError = redactor.redactError(raw.error);
|
|
8455
|
+
const event = {
|
|
8456
|
+
eventId: normalizeNonEmptyString(
|
|
8457
|
+
"eventId",
|
|
8458
|
+
raw.eventId ?? `observation:${sessionId}:${String(sequence).padStart(12, "0")}`
|
|
8459
|
+
),
|
|
8460
|
+
sessionId,
|
|
8461
|
+
sequence,
|
|
8462
|
+
kind: raw.kind,
|
|
8463
|
+
phase: raw.phase,
|
|
8464
|
+
createdAt,
|
|
8465
|
+
correlationId: normalizeNonEmptyString("correlationId", raw.correlationId),
|
|
8466
|
+
...raw.spanId === void 0 ? {} : { spanId: normalizeNonEmptyString("spanId", raw.spanId) },
|
|
8467
|
+
...raw.parentSpanId === void 0 ? {} : { parentSpanId: normalizeNonEmptyString("parentSpanId", raw.parentSpanId) },
|
|
8468
|
+
...context === void 0 ? {} : { context },
|
|
8469
|
+
...redactedData === void 0 ? {} : { data: redactedData },
|
|
8470
|
+
...redactedError === void 0 ? {} : { error: redactedError },
|
|
8471
|
+
...raw.artifactIds === void 0 || raw.artifactIds.length === 0 ? {} : { artifactIds: [...raw.artifactIds] }
|
|
8472
|
+
};
|
|
8473
|
+
await writeJsonFileExclusive(
|
|
8474
|
+
path7__default.default.join(this.sessionEventsDirectory(sessionId), eventFileName(sequence)),
|
|
8475
|
+
event
|
|
8476
|
+
);
|
|
8477
|
+
updatedAt = Math.max(updatedAt, createdAt);
|
|
8478
|
+
events.push(event);
|
|
8479
|
+
}
|
|
8480
|
+
await writeJsonFileAtomic(this.sessionManifestPath(sessionId), {
|
|
8481
|
+
...session,
|
|
8482
|
+
currentSequence: sequence,
|
|
8483
|
+
eventCount: session.eventCount + events.length,
|
|
8484
|
+
updatedAt
|
|
8485
|
+
});
|
|
8486
|
+
return events;
|
|
8487
|
+
});
|
|
8488
|
+
}
|
|
8489
|
+
async writeArtifact(sessionId, input) {
|
|
8490
|
+
return withFilesystemLock(this.sessionLockPath(sessionId), async () => {
|
|
8491
|
+
const session = await this.reconcileSessionManifest(sessionId);
|
|
8492
|
+
if (session === void 0) {
|
|
8493
|
+
throw new Error(`observation session ${sessionId} was not found`);
|
|
8494
|
+
}
|
|
8495
|
+
const redactor = this.redactors.get(sessionId) ?? createObservationRedactor(void 0);
|
|
8496
|
+
const createdAt = normalizeTimestamp("createdAt", input.createdAt);
|
|
8497
|
+
const context = normalizeObservationContext(input.context);
|
|
8498
|
+
const redactedStorageKey = input.storageKey === void 0 ? void 0 : redactor.redactText(input.storageKey);
|
|
8499
|
+
const redactedMetadata = input.metadata === void 0 ? void 0 : redactor.redactJson(toCanonicalJsonValue(input.metadata));
|
|
8500
|
+
const artifact = {
|
|
8501
|
+
artifactId: normalizeNonEmptyString("artifactId", input.artifactId),
|
|
8502
|
+
sessionId,
|
|
8503
|
+
kind: input.kind,
|
|
8504
|
+
createdAt,
|
|
8505
|
+
...context === void 0 ? {} : { context },
|
|
8506
|
+
...input.mediaType === void 0 ? {} : { mediaType: input.mediaType },
|
|
8507
|
+
...input.byteLength === void 0 ? {} : { byteLength: input.byteLength },
|
|
8508
|
+
...input.sha256 === void 0 ? {} : { sha256: input.sha256 },
|
|
8509
|
+
...input.opensteerArtifactId === void 0 ? {} : { opensteerArtifactId: input.opensteerArtifactId },
|
|
8510
|
+
...redactedStorageKey === void 0 ? {} : { storageKey: redactedStorageKey },
|
|
8511
|
+
...redactedMetadata === void 0 ? {} : { metadata: redactedMetadata }
|
|
8512
|
+
};
|
|
8513
|
+
const artifactPath = this.sessionArtifactPath(sessionId, artifact.artifactId);
|
|
8514
|
+
if (!await pathExists(artifactPath)) {
|
|
8515
|
+
await writeJsonFileExclusive(artifactPath, artifact);
|
|
8516
|
+
await writeJsonFileAtomic(this.sessionManifestPath(sessionId), {
|
|
8517
|
+
...session,
|
|
8518
|
+
artifactCount: session.artifactCount + 1,
|
|
8519
|
+
updatedAt: Math.max(session.updatedAt, createdAt)
|
|
8520
|
+
});
|
|
8521
|
+
}
|
|
8522
|
+
return artifact;
|
|
8523
|
+
});
|
|
8524
|
+
}
|
|
8525
|
+
async listEvents(sessionId, input = {}) {
|
|
8526
|
+
const directoryPath = this.sessionEventsDirectory(sessionId);
|
|
8527
|
+
if (!await pathExists(directoryPath)) {
|
|
8528
|
+
return [];
|
|
8529
|
+
}
|
|
8530
|
+
const files = await listJsonFiles(directoryPath);
|
|
8531
|
+
const events = await Promise.all(
|
|
8532
|
+
files.map((fileName) => readJsonFile(path7__default.default.join(directoryPath, fileName)))
|
|
8533
|
+
);
|
|
8534
|
+
const filtered = events.filter((event) => {
|
|
8535
|
+
if (input.kind !== void 0 && event.kind !== input.kind) return false;
|
|
8536
|
+
if (input.phase !== void 0 && event.phase !== input.phase) return false;
|
|
8537
|
+
if (input.correlationId !== void 0 && event.correlationId !== input.correlationId) {
|
|
8538
|
+
return false;
|
|
8539
|
+
}
|
|
8540
|
+
if (input.pageRef !== void 0 && event.context?.pageRef !== input.pageRef) return false;
|
|
8541
|
+
if (input.afterSequence !== void 0 && event.sequence <= input.afterSequence) return false;
|
|
8542
|
+
if (input.from !== void 0 && event.createdAt < input.from) return false;
|
|
8543
|
+
if (input.to !== void 0 && event.createdAt > input.to) return false;
|
|
8544
|
+
return true;
|
|
8545
|
+
});
|
|
8546
|
+
if (input.limit === void 0 || filtered.length <= input.limit) {
|
|
8547
|
+
return filtered;
|
|
8548
|
+
}
|
|
8549
|
+
return filtered.slice(-input.limit);
|
|
8550
|
+
}
|
|
8551
|
+
async listArtifacts(sessionId, input = {}) {
|
|
8552
|
+
const directoryPath = this.sessionArtifactsDirectory(sessionId);
|
|
8553
|
+
if (!await pathExists(directoryPath)) {
|
|
8554
|
+
return [];
|
|
8555
|
+
}
|
|
8556
|
+
const files = await listJsonFiles(directoryPath);
|
|
8557
|
+
const artifacts = await Promise.all(
|
|
8558
|
+
files.map(
|
|
8559
|
+
(fileName) => readJsonFile(path7__default.default.join(directoryPath, fileName))
|
|
8560
|
+
)
|
|
8561
|
+
);
|
|
8562
|
+
const filtered = artifacts.filter((artifact) => {
|
|
8563
|
+
if (input.kind !== void 0 && artifact.kind !== input.kind) return false;
|
|
8564
|
+
if (input.pageRef !== void 0 && artifact.context?.pageRef !== input.pageRef) return false;
|
|
8565
|
+
return true;
|
|
8566
|
+
});
|
|
8567
|
+
if (input.limit === void 0 || filtered.length <= input.limit) {
|
|
8568
|
+
return filtered;
|
|
8569
|
+
}
|
|
8570
|
+
return filtered.slice(-input.limit);
|
|
8571
|
+
}
|
|
8572
|
+
async getArtifact(sessionId, artifactId) {
|
|
8573
|
+
const artifactPath = this.sessionArtifactPath(sessionId, artifactId);
|
|
8574
|
+
if (!await pathExists(artifactPath)) {
|
|
8575
|
+
return void 0;
|
|
8576
|
+
}
|
|
8577
|
+
return readJsonFile(artifactPath);
|
|
8578
|
+
}
|
|
8579
|
+
async closeSession(sessionId, _reason) {
|
|
8580
|
+
await withFilesystemLock(this.sessionLockPath(sessionId), async () => {
|
|
8581
|
+
const session = await this.reconcileSessionManifest(sessionId);
|
|
8582
|
+
if (session === void 0 || session.closedAt !== void 0) {
|
|
8583
|
+
return;
|
|
8584
|
+
}
|
|
8585
|
+
const now = Date.now();
|
|
8586
|
+
await writeJsonFileAtomic(this.sessionManifestPath(sessionId), {
|
|
8587
|
+
...session,
|
|
8588
|
+
updatedAt: Math.max(session.updatedAt, now),
|
|
8589
|
+
closedAt: now
|
|
8590
|
+
});
|
|
8591
|
+
});
|
|
8592
|
+
this.redactors.delete(sessionId);
|
|
8593
|
+
}
|
|
8594
|
+
async writeArtifactFromManifest(sessionId, manifest, kind, metadata) {
|
|
8595
|
+
return this.writeArtifact(sessionId, {
|
|
8596
|
+
artifactId: manifest.artifactId,
|
|
8597
|
+
kind,
|
|
8598
|
+
createdAt: manifest.createdAt,
|
|
8599
|
+
context: manifest.scope,
|
|
8600
|
+
mediaType: manifest.mediaType,
|
|
8601
|
+
byteLength: manifest.byteLength,
|
|
8602
|
+
sha256: manifest.sha256,
|
|
8603
|
+
opensteerArtifactId: manifest.artifactId,
|
|
8604
|
+
storageKey: manifestToExternalBinaryLocation(this.rootPath, manifest).uri,
|
|
8605
|
+
...metadata === void 0 ? {} : { metadata }
|
|
8606
|
+
});
|
|
8607
|
+
}
|
|
8608
|
+
async ensureArtifactLinked(sessionId, manifest) {
|
|
8609
|
+
const existing = await this.getArtifact(sessionId, manifest.artifactId);
|
|
8610
|
+
if (existing !== void 0) {
|
|
8611
|
+
return existing;
|
|
8612
|
+
}
|
|
8613
|
+
const kind = toObservationArtifactKind(manifest.kind);
|
|
8614
|
+
return this.writeArtifactFromManifest(sessionId, manifest, kind);
|
|
8615
|
+
}
|
|
8616
|
+
async hydrateArtifactManifests(artifactIds) {
|
|
8617
|
+
return (await Promise.all(
|
|
8618
|
+
artifactIds.map(async (artifactId) => this.artifacts.getManifest(artifactId))
|
|
8619
|
+
)).filter((value) => value !== void 0);
|
|
8620
|
+
}
|
|
8621
|
+
sessionDirectory(sessionId) {
|
|
8622
|
+
return path7__default.default.join(this.sessionsDirectory, encodePathSegment(sessionId));
|
|
8623
|
+
}
|
|
8624
|
+
sessionManifestPath(sessionId) {
|
|
8625
|
+
return path7__default.default.join(this.sessionDirectory(sessionId), "session.json");
|
|
8626
|
+
}
|
|
8627
|
+
sessionEventsDirectory(sessionId) {
|
|
8628
|
+
return path7__default.default.join(this.sessionDirectory(sessionId), "events");
|
|
8629
|
+
}
|
|
8630
|
+
sessionArtifactsDirectory(sessionId) {
|
|
8631
|
+
return path7__default.default.join(this.sessionDirectory(sessionId), "artifacts");
|
|
8632
|
+
}
|
|
8633
|
+
sessionArtifactPath(sessionId, artifactId) {
|
|
8634
|
+
return path7__default.default.join(
|
|
8635
|
+
this.sessionArtifactsDirectory(sessionId),
|
|
8636
|
+
`${encodePathSegment(artifactId)}.json`
|
|
8637
|
+
);
|
|
8638
|
+
}
|
|
8639
|
+
sessionLockPath(sessionId) {
|
|
8640
|
+
return path7__default.default.join(this.sessionDirectory(sessionId), ".lock");
|
|
8641
|
+
}
|
|
8642
|
+
async reconcileSessionManifest(sessionId) {
|
|
8643
|
+
const session = await this.getSession(sessionId);
|
|
8644
|
+
if (session === void 0) {
|
|
8645
|
+
return void 0;
|
|
8646
|
+
}
|
|
8647
|
+
const [hasEventDirectory, hasArtifactDirectory] = await Promise.all([
|
|
8648
|
+
pathExists(this.sessionEventsDirectory(sessionId)),
|
|
8649
|
+
pathExists(this.sessionArtifactsDirectory(sessionId))
|
|
8650
|
+
]);
|
|
8651
|
+
const [eventFiles, artifactFiles] = await Promise.all([
|
|
8652
|
+
hasEventDirectory ? listJsonFiles(this.sessionEventsDirectory(sessionId)) : Promise.resolve([]),
|
|
8653
|
+
hasArtifactDirectory ? listJsonFiles(this.sessionArtifactsDirectory(sessionId)) : Promise.resolve([])
|
|
8654
|
+
]);
|
|
8655
|
+
const currentSequence = eventFiles.reduce((maxSequence, fileName) => {
|
|
8656
|
+
const parsed = Number.parseInt(fileName.replace(/\.json$/u, ""), 10);
|
|
8657
|
+
return Number.isFinite(parsed) ? Math.max(maxSequence, parsed) : maxSequence;
|
|
8658
|
+
}, 0);
|
|
8659
|
+
const eventCount = eventFiles.length;
|
|
8660
|
+
const artifactCount = artifactFiles.length;
|
|
8661
|
+
if (session.currentSequence === currentSequence && session.eventCount === eventCount && session.artifactCount === artifactCount) {
|
|
8662
|
+
return session;
|
|
8663
|
+
}
|
|
8664
|
+
const [events, artifacts] = await Promise.all([
|
|
8665
|
+
Promise.all(
|
|
8666
|
+
eventFiles.map(
|
|
8667
|
+
(fileName) => readJsonFile(
|
|
8668
|
+
path7__default.default.join(this.sessionEventsDirectory(sessionId), fileName)
|
|
8669
|
+
)
|
|
8670
|
+
)
|
|
8671
|
+
),
|
|
8672
|
+
Promise.all(
|
|
8673
|
+
artifactFiles.map(
|
|
8674
|
+
(fileName) => readJsonFile(
|
|
8675
|
+
path7__default.default.join(this.sessionArtifactsDirectory(sessionId), fileName)
|
|
8676
|
+
)
|
|
8677
|
+
)
|
|
8678
|
+
)
|
|
8679
|
+
]);
|
|
8680
|
+
const updatedAt = Math.max(
|
|
8681
|
+
session.openedAt,
|
|
8682
|
+
session.closedAt ?? 0,
|
|
8683
|
+
...events.map((event) => event.createdAt),
|
|
8684
|
+
...artifacts.map((artifact) => artifact.createdAt)
|
|
8685
|
+
);
|
|
8686
|
+
const reconciled = {
|
|
8687
|
+
...session,
|
|
8688
|
+
currentSequence,
|
|
8689
|
+
eventCount,
|
|
8690
|
+
artifactCount,
|
|
8691
|
+
updatedAt
|
|
8692
|
+
};
|
|
8693
|
+
await writeJsonFileAtomic(this.sessionManifestPath(sessionId), reconciled);
|
|
8694
|
+
return reconciled;
|
|
8695
|
+
}
|
|
8696
|
+
};
|
|
8697
|
+
function toObservationArtifactKind(kind) {
|
|
8698
|
+
switch (kind) {
|
|
8699
|
+
case "screenshot":
|
|
8700
|
+
return "screenshot";
|
|
8701
|
+
case "dom-snapshot":
|
|
8702
|
+
return "dom-snapshot";
|
|
8703
|
+
case "html-snapshot":
|
|
8704
|
+
return "html-snapshot";
|
|
8705
|
+
default:
|
|
8706
|
+
return "other";
|
|
8707
|
+
}
|
|
8708
|
+
}
|
|
8709
|
+
function createObservationStore(rootPath, artifacts) {
|
|
8710
|
+
return new FilesystemObservationStoreImpl(rootPath, artifacts);
|
|
8711
|
+
}
|
|
8166
8712
|
function normalizeContext(context) {
|
|
8167
8713
|
return {
|
|
8168
8714
|
...context?.sessionRef === void 0 ? {} : { sessionRef: context.sessionRef },
|
|
@@ -8179,7 +8725,7 @@ var FilesystemTraceStore = class {
|
|
|
8179
8725
|
constructor(rootPath, artifacts) {
|
|
8180
8726
|
this.rootPath = rootPath;
|
|
8181
8727
|
this.artifacts = artifacts;
|
|
8182
|
-
this.runsDirectory =
|
|
8728
|
+
this.runsDirectory = path7__default.default.join(this.rootPath, "traces", "runs");
|
|
8183
8729
|
}
|
|
8184
8730
|
runsDirectory;
|
|
8185
8731
|
async initialize() {
|
|
@@ -8256,7 +8802,7 @@ var FilesystemTraceStore = class {
|
|
|
8256
8802
|
...input.error === void 0 ? {} : { error: input.error }
|
|
8257
8803
|
};
|
|
8258
8804
|
await writeJsonFileExclusive(
|
|
8259
|
-
|
|
8805
|
+
path7__default.default.join(this.runEntriesDirectory(runId), sequenceFileName(sequence)),
|
|
8260
8806
|
entry
|
|
8261
8807
|
);
|
|
8262
8808
|
await writeJsonFileAtomic(this.runManifestPath(runId), {
|
|
@@ -8275,7 +8821,7 @@ var FilesystemTraceStore = class {
|
|
|
8275
8821
|
const files = await listJsonFiles(entriesDirectory);
|
|
8276
8822
|
return Promise.all(
|
|
8277
8823
|
files.map(
|
|
8278
|
-
(fileName) => readJsonFile(
|
|
8824
|
+
(fileName) => readJsonFile(path7__default.default.join(entriesDirectory, fileName))
|
|
8279
8825
|
)
|
|
8280
8826
|
);
|
|
8281
8827
|
}
|
|
@@ -8321,16 +8867,16 @@ var FilesystemTraceStore = class {
|
|
|
8321
8867
|
return { trace, artifacts };
|
|
8322
8868
|
}
|
|
8323
8869
|
runDirectory(runId) {
|
|
8324
|
-
return
|
|
8870
|
+
return path7__default.default.join(this.runsDirectory, encodeURIComponent(runId));
|
|
8325
8871
|
}
|
|
8326
8872
|
runEntriesDirectory(runId) {
|
|
8327
|
-
return
|
|
8873
|
+
return path7__default.default.join(this.runDirectory(runId), "entries");
|
|
8328
8874
|
}
|
|
8329
8875
|
runManifestPath(runId) {
|
|
8330
|
-
return
|
|
8876
|
+
return path7__default.default.join(this.runDirectory(runId), "manifest.json");
|
|
8331
8877
|
}
|
|
8332
8878
|
runWriteLockPath(runId) {
|
|
8333
|
-
return
|
|
8879
|
+
return path7__default.default.join(this.runDirectory(runId), ".append.lock");
|
|
8334
8880
|
}
|
|
8335
8881
|
};
|
|
8336
8882
|
function createTraceStore(rootPath, artifacts) {
|
|
@@ -8344,7 +8890,7 @@ function normalizeWorkspaceId(workspace) {
|
|
|
8344
8890
|
return encodePathSegment(workspace);
|
|
8345
8891
|
}
|
|
8346
8892
|
function resolveFilesystemWorkspacePath(input) {
|
|
8347
|
-
return
|
|
8893
|
+
return path7__default.default.join(
|
|
8348
8894
|
input.rootDir,
|
|
8349
8895
|
".opensteer",
|
|
8350
8896
|
"workspaces",
|
|
@@ -8353,17 +8899,18 @@ function resolveFilesystemWorkspacePath(input) {
|
|
|
8353
8899
|
}
|
|
8354
8900
|
async function createFilesystemOpensteerWorkspace(options) {
|
|
8355
8901
|
await ensureDirectory(options.rootPath);
|
|
8356
|
-
const manifestPath =
|
|
8357
|
-
const browserPath =
|
|
8358
|
-
const browserManifestPath =
|
|
8359
|
-
const browserUserDataDir =
|
|
8360
|
-
const livePath =
|
|
8361
|
-
const liveLocalPath =
|
|
8362
|
-
const liveCloudPath =
|
|
8363
|
-
const artifactsPath =
|
|
8364
|
-
const tracesPath =
|
|
8365
|
-
const
|
|
8366
|
-
const
|
|
8902
|
+
const manifestPath = path7__default.default.join(options.rootPath, "workspace.json");
|
|
8903
|
+
const browserPath = path7__default.default.join(options.rootPath, "browser");
|
|
8904
|
+
const browserManifestPath = path7__default.default.join(browserPath, "manifest.json");
|
|
8905
|
+
const browserUserDataDir = path7__default.default.join(browserPath, "user-data");
|
|
8906
|
+
const livePath = path7__default.default.join(options.rootPath, "live");
|
|
8907
|
+
const liveLocalPath = path7__default.default.join(livePath, "local.json");
|
|
8908
|
+
const liveCloudPath = path7__default.default.join(livePath, "cloud.json");
|
|
8909
|
+
const artifactsPath = path7__default.default.join(options.rootPath, "artifacts");
|
|
8910
|
+
const tracesPath = path7__default.default.join(options.rootPath, "traces");
|
|
8911
|
+
const observationsPath = path7__default.default.join(options.rootPath, "observations");
|
|
8912
|
+
const registryPath = path7__default.default.join(options.rootPath, "registry");
|
|
8913
|
+
const lockPath = path7__default.default.join(options.rootPath, ".lock");
|
|
8367
8914
|
let manifest;
|
|
8368
8915
|
if (await pathExists(manifestPath)) {
|
|
8369
8916
|
manifest = await readJsonFile(manifestPath);
|
|
@@ -8377,6 +8924,17 @@ async function createFilesystemOpensteerWorkspace(options) {
|
|
|
8377
8924
|
`workspace ${options.rootPath} uses unsupported version ${String(manifest.version)}`
|
|
8378
8925
|
);
|
|
8379
8926
|
}
|
|
8927
|
+
if (manifest.paths.observations === void 0) {
|
|
8928
|
+
manifest = {
|
|
8929
|
+
...manifest,
|
|
8930
|
+
updatedAt: Date.now(),
|
|
8931
|
+
paths: {
|
|
8932
|
+
...manifest.paths,
|
|
8933
|
+
observations: "observations"
|
|
8934
|
+
}
|
|
8935
|
+
};
|
|
8936
|
+
await writeJsonFileAtomic(manifestPath, manifest);
|
|
8937
|
+
}
|
|
8380
8938
|
} else {
|
|
8381
8939
|
const createdAt = normalizeTimestamp("createdAt", options.createdAt ?? Date.now());
|
|
8382
8940
|
manifest = {
|
|
@@ -8391,6 +8949,7 @@ async function createFilesystemOpensteerWorkspace(options) {
|
|
|
8391
8949
|
live: "live",
|
|
8392
8950
|
artifacts: "artifacts",
|
|
8393
8951
|
traces: "traces",
|
|
8952
|
+
observations: "observations",
|
|
8394
8953
|
registry: "registry"
|
|
8395
8954
|
}
|
|
8396
8955
|
};
|
|
@@ -8402,6 +8961,7 @@ async function createFilesystemOpensteerWorkspace(options) {
|
|
|
8402
8961
|
ensureDirectory(livePath),
|
|
8403
8962
|
ensureDirectory(artifactsPath),
|
|
8404
8963
|
ensureDirectory(tracesPath),
|
|
8964
|
+
ensureDirectory(observationsPath),
|
|
8405
8965
|
ensureDirectory(registryPath)
|
|
8406
8966
|
]);
|
|
8407
8967
|
const artifacts = createArtifactStore(options.rootPath);
|
|
@@ -8426,6 +8986,8 @@ async function createFilesystemOpensteerWorkspace(options) {
|
|
|
8426
8986
|
await reverseReports.initialize();
|
|
8427
8987
|
const traces = createTraceStore(options.rootPath, artifacts);
|
|
8428
8988
|
await traces.initialize();
|
|
8989
|
+
const observations = createObservationStore(options.rootPath, artifacts);
|
|
8990
|
+
await observations.initialize();
|
|
8429
8991
|
return {
|
|
8430
8992
|
rootPath: options.rootPath,
|
|
8431
8993
|
manifestPath,
|
|
@@ -8438,10 +9000,12 @@ async function createFilesystemOpensteerWorkspace(options) {
|
|
|
8438
9000
|
liveCloudPath,
|
|
8439
9001
|
artifactsPath,
|
|
8440
9002
|
tracesPath,
|
|
9003
|
+
observationsPath,
|
|
8441
9004
|
registryPath,
|
|
8442
9005
|
lockPath,
|
|
8443
9006
|
artifacts,
|
|
8444
9007
|
traces,
|
|
9008
|
+
observations,
|
|
8445
9009
|
registry: {
|
|
8446
9010
|
descriptors,
|
|
8447
9011
|
requestPlans,
|
|
@@ -8628,10 +9192,10 @@ function delayWithSignal(delayMs, signal) {
|
|
|
8628
9192
|
if (signal.aborted) {
|
|
8629
9193
|
return Promise.reject(signal.reason ?? abortError());
|
|
8630
9194
|
}
|
|
8631
|
-
return new Promise((
|
|
9195
|
+
return new Promise((resolve4, reject) => {
|
|
8632
9196
|
const timer = setTimeout(() => {
|
|
8633
9197
|
signal.removeEventListener("abort", onAbort);
|
|
8634
|
-
|
|
9198
|
+
resolve4();
|
|
8635
9199
|
}, delayMs);
|
|
8636
9200
|
const onAbort = () => {
|
|
8637
9201
|
clearTimeout(timer);
|
|
@@ -9096,9 +9660,9 @@ var IFRAME_URL_ATTRIBUTES = /* @__PURE__ */ new Set([
|
|
|
9096
9660
|
"poster",
|
|
9097
9661
|
"ping"
|
|
9098
9662
|
]);
|
|
9099
|
-
function buildArrayFieldPathCandidates(
|
|
9100
|
-
const strict =
|
|
9101
|
-
const relaxedNodes = stripPositionClauses(
|
|
9663
|
+
function buildArrayFieldPathCandidates(path15) {
|
|
9664
|
+
const strict = path15.nodes.length ? buildPathCandidates(path15.nodes) : [];
|
|
9665
|
+
const relaxedNodes = stripPositionClauses(path15.nodes);
|
|
9102
9666
|
const relaxed = relaxedNodes.length ? buildPathCandidates(relaxedNodes) : [];
|
|
9103
9667
|
return dedupeSelectors([...strict, ...relaxed]);
|
|
9104
9668
|
}
|
|
@@ -9628,18 +10192,18 @@ function cloneStructuralElementAnchor(anchor) {
|
|
|
9628
10192
|
nodes: anchor.nodes.map(clonePathNode)
|
|
9629
10193
|
};
|
|
9630
10194
|
}
|
|
9631
|
-
function cloneReplayElementPath(
|
|
10195
|
+
function cloneReplayElementPath(path15) {
|
|
9632
10196
|
return {
|
|
9633
10197
|
resolution: "deterministic",
|
|
9634
|
-
context: cloneContext(
|
|
9635
|
-
nodes:
|
|
10198
|
+
context: cloneContext(path15.context),
|
|
10199
|
+
nodes: path15.nodes.map(clonePathNode)
|
|
9636
10200
|
};
|
|
9637
10201
|
}
|
|
9638
|
-
function cloneElementPath(
|
|
9639
|
-
return cloneReplayElementPath(
|
|
10202
|
+
function cloneElementPath(path15) {
|
|
10203
|
+
return cloneReplayElementPath(path15);
|
|
9640
10204
|
}
|
|
9641
|
-
function buildPathSelectorHint(
|
|
9642
|
-
const nodes =
|
|
10205
|
+
function buildPathSelectorHint(path15) {
|
|
10206
|
+
const nodes = path15?.nodes || [];
|
|
9643
10207
|
const last = nodes[nodes.length - 1];
|
|
9644
10208
|
if (!last) {
|
|
9645
10209
|
return "*";
|
|
@@ -9688,15 +10252,15 @@ function sanitizeStructuralElementAnchor(anchor) {
|
|
|
9688
10252
|
nodes: sanitizeNodes(anchor.nodes)
|
|
9689
10253
|
};
|
|
9690
10254
|
}
|
|
9691
|
-
function sanitizeReplayElementPath(
|
|
10255
|
+
function sanitizeReplayElementPath(path15) {
|
|
9692
10256
|
return {
|
|
9693
10257
|
resolution: "deterministic",
|
|
9694
|
-
context: sanitizeContext(
|
|
9695
|
-
nodes: sanitizeNodes(
|
|
10258
|
+
context: sanitizeContext(path15.context),
|
|
10259
|
+
nodes: sanitizeNodes(path15.nodes)
|
|
9696
10260
|
};
|
|
9697
10261
|
}
|
|
9698
|
-
function sanitizeElementPath(
|
|
9699
|
-
return sanitizeReplayElementPath(
|
|
10262
|
+
function sanitizeElementPath(path15) {
|
|
10263
|
+
return sanitizeReplayElementPath(path15);
|
|
9700
10264
|
}
|
|
9701
10265
|
function buildLocalStructuralElementAnchor(index, rawTargetNode) {
|
|
9702
10266
|
const targetNode = requireElementNode(index, rawTargetNode);
|
|
@@ -9819,8 +10383,8 @@ function buildTargetNotFoundMessage(domPath, diagnostics) {
|
|
|
9819
10383
|
}
|
|
9820
10384
|
return `${base} Target depth ${String(depth)}. Candidate counts: ${sample}.`;
|
|
9821
10385
|
}
|
|
9822
|
-
function buildArrayFieldCandidates(
|
|
9823
|
-
return buildArrayFieldPathCandidates(
|
|
10386
|
+
function buildArrayFieldCandidates(path15) {
|
|
10387
|
+
return buildArrayFieldPathCandidates(path15);
|
|
9824
10388
|
}
|
|
9825
10389
|
function firstDefinedAttribute(node, keys) {
|
|
9826
10390
|
for (const key of keys) {
|
|
@@ -10329,14 +10893,16 @@ var DomActionExecutor = class {
|
|
|
10329
10893
|
...input.timeout === void 0 ? {} : { timeout: input.timeout }
|
|
10330
10894
|
},
|
|
10331
10895
|
async (pointerTarget, point, timeout) => {
|
|
10332
|
-
|
|
10896
|
+
const events = [];
|
|
10897
|
+
const moved = await timeout.runStep(
|
|
10333
10898
|
() => this.options.engine.mouseMove({
|
|
10334
10899
|
pageRef: pointerTarget.resolved.pageRef,
|
|
10335
10900
|
point,
|
|
10336
10901
|
coordinateSpace: "document-css"
|
|
10337
10902
|
})
|
|
10338
10903
|
);
|
|
10339
|
-
|
|
10904
|
+
events.push(...moved.events);
|
|
10905
|
+
const clicked = await timeout.runStep(
|
|
10340
10906
|
() => this.options.engine.mouseClick({
|
|
10341
10907
|
pageRef: pointerTarget.resolved.pageRef,
|
|
10342
10908
|
point,
|
|
@@ -10346,7 +10912,12 @@ var DomActionExecutor = class {
|
|
|
10346
10912
|
...input.modifiers === void 0 ? {} : { modifiers: input.modifiers }
|
|
10347
10913
|
})
|
|
10348
10914
|
);
|
|
10349
|
-
|
|
10915
|
+
events.push(...clicked.events);
|
|
10916
|
+
return {
|
|
10917
|
+
resolved: pointerTarget.original,
|
|
10918
|
+
point,
|
|
10919
|
+
...events.length === 0 ? {} : { events }
|
|
10920
|
+
};
|
|
10350
10921
|
}
|
|
10351
10922
|
);
|
|
10352
10923
|
}
|
|
@@ -10360,14 +10931,18 @@ var DomActionExecutor = class {
|
|
|
10360
10931
|
...input.timeout === void 0 ? {} : { timeout: input.timeout }
|
|
10361
10932
|
},
|
|
10362
10933
|
async (pointerTarget, point, timeout) => {
|
|
10363
|
-
await timeout.runStep(
|
|
10934
|
+
const moved = await timeout.runStep(
|
|
10364
10935
|
() => this.options.engine.mouseMove({
|
|
10365
10936
|
pageRef: pointerTarget.resolved.pageRef,
|
|
10366
10937
|
point,
|
|
10367
10938
|
coordinateSpace: "document-css"
|
|
10368
10939
|
})
|
|
10369
10940
|
);
|
|
10370
|
-
return {
|
|
10941
|
+
return {
|
|
10942
|
+
resolved: pointerTarget.original,
|
|
10943
|
+
point,
|
|
10944
|
+
...moved.events.length === 0 ? {} : { events: moved.events }
|
|
10945
|
+
};
|
|
10371
10946
|
}
|
|
10372
10947
|
);
|
|
10373
10948
|
}
|
|
@@ -10381,14 +10956,16 @@ var DomActionExecutor = class {
|
|
|
10381
10956
|
...input.timeout === void 0 ? {} : { timeout: input.timeout }
|
|
10382
10957
|
},
|
|
10383
10958
|
async (pointerTarget, point, timeout) => {
|
|
10384
|
-
|
|
10959
|
+
const events = [];
|
|
10960
|
+
const moved = await timeout.runStep(
|
|
10385
10961
|
() => this.options.engine.mouseMove({
|
|
10386
10962
|
pageRef: pointerTarget.resolved.pageRef,
|
|
10387
10963
|
point,
|
|
10388
10964
|
coordinateSpace: "document-css"
|
|
10389
10965
|
})
|
|
10390
10966
|
);
|
|
10391
|
-
|
|
10967
|
+
events.push(...moved.events);
|
|
10968
|
+
const scrolled = await timeout.runStep(
|
|
10392
10969
|
() => this.options.engine.mouseScroll({
|
|
10393
10970
|
pageRef: pointerTarget.resolved.pageRef,
|
|
10394
10971
|
point,
|
|
@@ -10396,7 +10973,12 @@ var DomActionExecutor = class {
|
|
|
10396
10973
|
delta: input.delta
|
|
10397
10974
|
})
|
|
10398
10975
|
);
|
|
10399
|
-
|
|
10976
|
+
events.push(...scrolled.events);
|
|
10977
|
+
return {
|
|
10978
|
+
resolved: pointerTarget.original,
|
|
10979
|
+
point,
|
|
10980
|
+
...events.length === 0 ? {} : { events }
|
|
10981
|
+
};
|
|
10400
10982
|
}
|
|
10401
10983
|
);
|
|
10402
10984
|
}
|
|
@@ -11322,21 +11904,21 @@ var DefaultDomRuntime = class {
|
|
|
11322
11904
|
return match;
|
|
11323
11905
|
}
|
|
11324
11906
|
async resolvePathTarget(session, pageRef, rawPath, source, description, descriptor) {
|
|
11325
|
-
const
|
|
11326
|
-
const context = await this.resolvePathContext(session, pageRef,
|
|
11327
|
-
const target = resolveDomPathInScope(context.index,
|
|
11907
|
+
const path15 = sanitizeReplayElementPath(rawPath);
|
|
11908
|
+
const context = await this.resolvePathContext(session, pageRef, path15.context);
|
|
11909
|
+
const target = resolveDomPathInScope(context.index, path15.nodes, context.scope);
|
|
11328
11910
|
if (!target) {
|
|
11329
|
-
throwTargetNotFound(context.index,
|
|
11911
|
+
throwTargetNotFound(context.index, path15.nodes, context.scope);
|
|
11330
11912
|
}
|
|
11331
11913
|
if (target.node.nodeRef === void 0) {
|
|
11332
11914
|
throw new Error(
|
|
11333
|
-
`resolved path "${buildPathSelectorHint(
|
|
11915
|
+
`resolved path "${buildPathSelectorHint(path15)}" does not point to a live element`
|
|
11334
11916
|
);
|
|
11335
11917
|
}
|
|
11336
11918
|
const anchor = await this.buildAnchorFromSnapshotNode(session, context.snapshot, target.node);
|
|
11337
11919
|
return this.createResolvedTarget(source, context.snapshot, target.node, anchor, {
|
|
11338
11920
|
...description === void 0 ? {} : { description },
|
|
11339
|
-
replayPath:
|
|
11921
|
+
replayPath: path15,
|
|
11340
11922
|
...source === "path" || source === "descriptor" ? { selectorUsed: target.selector } : {},
|
|
11341
11923
|
...descriptor === void 0 ? {} : { descriptor }
|
|
11342
11924
|
});
|
|
@@ -11357,9 +11939,9 @@ var DefaultDomRuntime = class {
|
|
|
11357
11939
|
});
|
|
11358
11940
|
}
|
|
11359
11941
|
async queryAllByElementPath(session, pageRef, rawPath) {
|
|
11360
|
-
const
|
|
11361
|
-
const context = await this.resolvePathContext(session, pageRef,
|
|
11362
|
-
return queryAllDomPathInScope(context.index,
|
|
11942
|
+
const path15 = sanitizeReplayElementPath(rawPath);
|
|
11943
|
+
const context = await this.resolvePathContext(session, pageRef, path15.context);
|
|
11944
|
+
return queryAllDomPathInScope(context.index, path15.nodes, context.scope).filter(
|
|
11363
11945
|
(node) => node.nodeRef !== void 0
|
|
11364
11946
|
).map((node) => this.createSnapshotTarget(context.snapshot, node));
|
|
11365
11947
|
}
|
|
@@ -11545,16 +12127,16 @@ var DefaultDomRuntime = class {
|
|
|
11545
12127
|
const index = createSnapshotIndex(item.snapshot);
|
|
11546
12128
|
return this.resolveFirstArrayFieldTargetInNode(index, item.node, field.path);
|
|
11547
12129
|
}
|
|
11548
|
-
resolveFirstArrayFieldTargetInNode(index, rootNode,
|
|
11549
|
-
const normalizedPath = sanitizeElementPath(
|
|
12130
|
+
resolveFirstArrayFieldTargetInNode(index, rootNode, path15) {
|
|
12131
|
+
const normalizedPath = sanitizeElementPath(path15);
|
|
11550
12132
|
const selectors = buildArrayFieldCandidates(normalizedPath);
|
|
11551
12133
|
if (!selectors.length) {
|
|
11552
12134
|
return rootNode;
|
|
11553
12135
|
}
|
|
11554
12136
|
return resolveFirstWithinNodeBySelectors(index, rootNode, selectors);
|
|
11555
12137
|
}
|
|
11556
|
-
resolveUniqueArrayFieldTargetInNode(index, rootNode,
|
|
11557
|
-
const normalizedPath = sanitizeElementPath(
|
|
12138
|
+
resolveUniqueArrayFieldTargetInNode(index, rootNode, path15) {
|
|
12139
|
+
const normalizedPath = sanitizeElementPath(path15);
|
|
11558
12140
|
const selectors = buildArrayFieldCandidates(normalizedPath);
|
|
11559
12141
|
if (!selectors.length) {
|
|
11560
12142
|
return rootNode;
|
|
@@ -11643,8 +12225,8 @@ function encodeDataPath(tokens) {
|
|
|
11643
12225
|
}
|
|
11644
12226
|
return out;
|
|
11645
12227
|
}
|
|
11646
|
-
function parseDataPath(
|
|
11647
|
-
const input =
|
|
12228
|
+
function parseDataPath(path15) {
|
|
12229
|
+
const input = path15.trim();
|
|
11648
12230
|
if (input.length === 0) {
|
|
11649
12231
|
return [];
|
|
11650
12232
|
}
|
|
@@ -11694,8 +12276,8 @@ function parseDataPath(path13) {
|
|
|
11694
12276
|
function inflateDataPathObject(flat) {
|
|
11695
12277
|
let root = {};
|
|
11696
12278
|
let initialized = false;
|
|
11697
|
-
for (const [
|
|
11698
|
-
const tokens = parseDataPath(
|
|
12279
|
+
for (const [path15, value] of Object.entries(flat)) {
|
|
12280
|
+
const tokens = parseDataPath(path15);
|
|
11699
12281
|
if (!tokens || tokens.length === 0) {
|
|
11700
12282
|
continue;
|
|
11701
12283
|
}
|
|
@@ -12027,8 +12609,8 @@ function buildVariantDescriptorFromCluster(descriptors) {
|
|
|
12027
12609
|
fields: mergedFields
|
|
12028
12610
|
};
|
|
12029
12611
|
}
|
|
12030
|
-
function minimizePathMatchClauses(
|
|
12031
|
-
const normalized = sanitizeElementPath(
|
|
12612
|
+
function minimizePathMatchClauses(path15, mode) {
|
|
12613
|
+
const normalized = sanitizeElementPath(path15);
|
|
12032
12614
|
const nodes = normalized.nodes.map((node, index) => {
|
|
12033
12615
|
const isLast = index === normalized.nodes.length - 1;
|
|
12034
12616
|
const attrs = node.attrs || {};
|
|
@@ -12132,8 +12714,8 @@ function seedMinimalAttrClause(attrs) {
|
|
|
12132
12714
|
}
|
|
12133
12715
|
return null;
|
|
12134
12716
|
}
|
|
12135
|
-
function relaxPathForSingleSample(
|
|
12136
|
-
const normalized = sanitizeElementPath(
|
|
12717
|
+
function relaxPathForSingleSample(path15, mode) {
|
|
12718
|
+
const normalized = sanitizeElementPath(path15);
|
|
12137
12719
|
const relaxedNodes = normalized.nodes.map((node, index) => {
|
|
12138
12720
|
const isLast = index === normalized.nodes.length - 1;
|
|
12139
12721
|
const attrs = normalizeAttrsForSingleSample(node.attrs || {});
|
|
@@ -12218,8 +12800,8 @@ function shouldKeepAttrForSingleSample(key) {
|
|
|
12218
12800
|
}
|
|
12219
12801
|
return true;
|
|
12220
12802
|
}
|
|
12221
|
-
function buildPathStructureKey(
|
|
12222
|
-
const normalized = sanitizeElementPath(
|
|
12803
|
+
function buildPathStructureKey(path15) {
|
|
12804
|
+
const normalized = sanitizeElementPath(path15);
|
|
12223
12805
|
return canonicalJsonString({
|
|
12224
12806
|
context: (normalized.context || []).map((hop) => ({
|
|
12225
12807
|
kind: hop.kind,
|
|
@@ -12346,30 +12928,30 @@ function buildArrayItemNode(fields) {
|
|
|
12346
12928
|
}
|
|
12347
12929
|
return node;
|
|
12348
12930
|
}
|
|
12349
|
-
function insertNodeAtPath(root,
|
|
12350
|
-
const tokens = parseDataPath(
|
|
12931
|
+
function insertNodeAtPath(root, path15, node) {
|
|
12932
|
+
const tokens = parseDataPath(path15);
|
|
12351
12933
|
if (!tokens || !tokens.length) {
|
|
12352
12934
|
throw new Error(
|
|
12353
|
-
`Invalid persisted extraction path "${
|
|
12935
|
+
`Invalid persisted extraction path "${path15}": expected a non-empty object path.`
|
|
12354
12936
|
);
|
|
12355
12937
|
}
|
|
12356
12938
|
if (tokens.some((token) => token.kind === "index")) {
|
|
12357
12939
|
throw new Error(
|
|
12358
|
-
`Invalid persisted extraction path "${
|
|
12940
|
+
`Invalid persisted extraction path "${path15}": nested array indices are not supported in cached descriptors.`
|
|
12359
12941
|
);
|
|
12360
12942
|
}
|
|
12361
12943
|
let current = root;
|
|
12362
12944
|
for (let index = 0; index < tokens.length; index += 1) {
|
|
12363
12945
|
const token = tokens[index];
|
|
12364
12946
|
if (!token || token.kind !== "prop") {
|
|
12365
|
-
throw new Error(`Invalid persisted extraction path "${
|
|
12947
|
+
throw new Error(`Invalid persisted extraction path "${path15}": expected object segment.`);
|
|
12366
12948
|
}
|
|
12367
12949
|
const isLast = index === tokens.length - 1;
|
|
12368
12950
|
if (isLast) {
|
|
12369
12951
|
const existing = current[token.key];
|
|
12370
12952
|
if (existing) {
|
|
12371
12953
|
throw new Error(
|
|
12372
|
-
`Conflicting persisted extraction path "${
|
|
12954
|
+
`Conflicting persisted extraction path "${path15}" detected while building descriptor tree.`
|
|
12373
12955
|
);
|
|
12374
12956
|
}
|
|
12375
12957
|
current[token.key] = node;
|
|
@@ -12384,7 +12966,7 @@ function insertNodeAtPath(root, path13, node) {
|
|
|
12384
12966
|
}
|
|
12385
12967
|
if (!isPersistedObjectNode(next)) {
|
|
12386
12968
|
throw new Error(
|
|
12387
|
-
`Conflicting persisted extraction path "${
|
|
12969
|
+
`Conflicting persisted extraction path "${path15}" detected at "${token.key}".`
|
|
12388
12970
|
);
|
|
12389
12971
|
}
|
|
12390
12972
|
current = next;
|
|
@@ -12419,7 +13001,7 @@ function buildItemRootForArrayIndex(entries) {
|
|
|
12419
13001
|
}
|
|
12420
13002
|
const paths = entries.map(
|
|
12421
13003
|
(entry) => isPersistablePathField(entry.source) ? sanitizeElementPath(entry.source.path) : null
|
|
12422
|
-
).filter((
|
|
13004
|
+
).filter((path15) => path15 !== null);
|
|
12423
13005
|
if (!paths.length) {
|
|
12424
13006
|
return null;
|
|
12425
13007
|
}
|
|
@@ -12440,7 +13022,7 @@ function getCommonPathPrefixLength(paths) {
|
|
|
12440
13022
|
if (!paths.length) {
|
|
12441
13023
|
return 0;
|
|
12442
13024
|
}
|
|
12443
|
-
const nodeChains = paths.map((
|
|
13025
|
+
const nodeChains = paths.map((path15) => path15.nodes);
|
|
12444
13026
|
const minLength = Math.min(...nodeChains.map((nodes) => nodes.length));
|
|
12445
13027
|
if (!Number.isFinite(minLength) || minLength <= 0) {
|
|
12446
13028
|
return 0;
|
|
@@ -12509,30 +13091,30 @@ function mergeElementPathsByMajority(paths) {
|
|
|
12509
13091
|
if (!paths.length) {
|
|
12510
13092
|
return null;
|
|
12511
13093
|
}
|
|
12512
|
-
const normalized = paths.map((
|
|
13094
|
+
const normalized = paths.map((path15) => sanitizeElementPath(path15));
|
|
12513
13095
|
const contextKey = pickModeString(
|
|
12514
|
-
normalized.map((
|
|
13096
|
+
normalized.map((path15) => canonicalJsonString(path15.context)),
|
|
12515
13097
|
1
|
|
12516
13098
|
);
|
|
12517
13099
|
if (!contextKey) {
|
|
12518
13100
|
return null;
|
|
12519
13101
|
}
|
|
12520
|
-
const sameContext = normalized.filter((
|
|
13102
|
+
const sameContext = normalized.filter((path15) => canonicalJsonString(path15.context) === contextKey);
|
|
12521
13103
|
if (!sameContext.length) {
|
|
12522
13104
|
return null;
|
|
12523
13105
|
}
|
|
12524
13106
|
const targetLength = pickModeNumber(
|
|
12525
|
-
sameContext.map((
|
|
13107
|
+
sameContext.map((path15) => path15.nodes.length),
|
|
12526
13108
|
1
|
|
12527
13109
|
) ?? sameContext[0]?.nodes.length ?? 0;
|
|
12528
|
-
const aligned = sameContext.filter((
|
|
13110
|
+
const aligned = sameContext.filter((path15) => path15.nodes.length === targetLength);
|
|
12529
13111
|
if (!aligned.length) {
|
|
12530
13112
|
return null;
|
|
12531
13113
|
}
|
|
12532
13114
|
const threshold = majorityThreshold(aligned.length);
|
|
12533
13115
|
const nodes = [];
|
|
12534
13116
|
for (let index = 0; index < targetLength; index += 1) {
|
|
12535
|
-
const nodesAtIndex = aligned.map((
|
|
13117
|
+
const nodesAtIndex = aligned.map((path15) => path15.nodes[index]).filter((node) => node !== void 0);
|
|
12536
13118
|
if (!nodesAtIndex.length) {
|
|
12537
13119
|
return null;
|
|
12538
13120
|
}
|
|
@@ -12778,8 +13360,8 @@ function clonePathContext(context) {
|
|
|
12778
13360
|
function clonePathNodes(nodes) {
|
|
12779
13361
|
return JSON.parse(JSON.stringify(nodes || []));
|
|
12780
13362
|
}
|
|
12781
|
-
function cloneElementPath2(
|
|
12782
|
-
return JSON.parse(JSON.stringify(
|
|
13363
|
+
function cloneElementPath2(path15) {
|
|
13364
|
+
return JSON.parse(JSON.stringify(path15));
|
|
12783
13365
|
}
|
|
12784
13366
|
function clonePersistedOpensteerExtractionNode(node) {
|
|
12785
13367
|
return JSON.parse(JSON.stringify(node));
|
|
@@ -13097,8 +13679,8 @@ function collectPersistedValueNodeRefs(node) {
|
|
|
13097
13679
|
return [
|
|
13098
13680
|
{
|
|
13099
13681
|
path: sanitizeElementPath(node.$path),
|
|
13100
|
-
replacePath: (
|
|
13101
|
-
node.$path = sanitizeElementPath(
|
|
13682
|
+
replacePath: (path15) => {
|
|
13683
|
+
node.$path = sanitizeElementPath(path15);
|
|
13102
13684
|
}
|
|
13103
13685
|
}
|
|
13104
13686
|
];
|
|
@@ -13112,13 +13694,13 @@ function collectPersistedValueNodeRefs(node) {
|
|
|
13112
13694
|
}
|
|
13113
13695
|
return refs;
|
|
13114
13696
|
}
|
|
13115
|
-
function hasPositionClause(
|
|
13116
|
-
return
|
|
13697
|
+
function hasPositionClause(path15) {
|
|
13698
|
+
return path15.nodes.some((node) => node.match.some((clause) => clause.kind === "position"));
|
|
13117
13699
|
}
|
|
13118
|
-
function stripPositionClauses2(
|
|
13700
|
+
function stripPositionClauses2(path15) {
|
|
13119
13701
|
return sanitizeElementPath({
|
|
13120
|
-
context:
|
|
13121
|
-
nodes:
|
|
13702
|
+
context: path15.context,
|
|
13703
|
+
nodes: path15.nodes.map((node) => ({
|
|
13122
13704
|
...node,
|
|
13123
13705
|
match: node.match.filter((clause) => clause.kind !== "position")
|
|
13124
13706
|
}))
|
|
@@ -13528,8 +14110,8 @@ function normalizeNonEmptyString2(name, value) {
|
|
|
13528
14110
|
function normalizeKey(value) {
|
|
13529
14111
|
return String(value ?? "").trim();
|
|
13530
14112
|
}
|
|
13531
|
-
function labelForPath(
|
|
13532
|
-
return
|
|
14113
|
+
function labelForPath(path15) {
|
|
14114
|
+
return path15.trim().length === 0 ? "$" : path15;
|
|
13533
14115
|
}
|
|
13534
14116
|
function sha256Hex3(value) {
|
|
13535
14117
|
return crypto.createHash("sha256").update(value).digest("hex");
|
|
@@ -13558,7 +14140,7 @@ var CHROME_SINGLETON_ARTIFACTS = [
|
|
|
13558
14140
|
async function clearChromeSingletonEntries(userDataDir) {
|
|
13559
14141
|
await Promise.all(
|
|
13560
14142
|
CHROME_SINGLETON_ARTIFACTS.map(
|
|
13561
|
-
(entry) => promises.rm(
|
|
14143
|
+
(entry) => promises.rm(path7.join(userDataDir, entry), {
|
|
13562
14144
|
recursive: true,
|
|
13563
14145
|
force: true
|
|
13564
14146
|
}).catch(() => void 0)
|
|
@@ -13573,7 +14155,7 @@ async function sanitizeChromeProfile(userDataDir) {
|
|
|
13573
14155
|
await Promise.all(profileDirs.map((dir) => sanitizeProfilePreferences(userDataDir, dir)));
|
|
13574
14156
|
}
|
|
13575
14157
|
async function sanitizeProfilePreferences(userDataDir, profileDir) {
|
|
13576
|
-
const prefsPath =
|
|
14158
|
+
const prefsPath = path7.join(userDataDir, profileDir, "Preferences");
|
|
13577
14159
|
try {
|
|
13578
14160
|
const raw = await promises.readFile(prefsPath, "utf8");
|
|
13579
14161
|
const prefs = JSON.parse(raw);
|
|
@@ -13585,14 +14167,13 @@ async function sanitizeProfilePreferences(userDataDir, profileDir) {
|
|
|
13585
14167
|
profile.exited_cleanly = true;
|
|
13586
14168
|
prefs.profile = profile;
|
|
13587
14169
|
await promises.writeFile(prefsPath, JSON.stringify(prefs), "utf8");
|
|
13588
|
-
await promises.rm(
|
|
14170
|
+
await promises.rm(path7.join(userDataDir, profileDir, "Secure Preferences"), { force: true }).catch(
|
|
13589
14171
|
() => void 0
|
|
13590
14172
|
);
|
|
13591
14173
|
} catch {
|
|
13592
14174
|
}
|
|
13593
14175
|
}
|
|
13594
|
-
|
|
13595
|
-
var PS_COMMAND_ENV2 = { ...process.env, LC_ALL: "C" };
|
|
14176
|
+
({ ...process.env});
|
|
13596
14177
|
var WINDOWS_PROGRAM_FILES = process.env.PROGRAMFILES ?? "C:\\Program Files";
|
|
13597
14178
|
var WINDOWS_PROGRAM_FILES_X86 = process.env["PROGRAMFILES(X86)"] ?? "C:\\Program Files (x86)";
|
|
13598
14179
|
var BROWSER_BRANDS = [
|
|
@@ -13607,9 +14188,9 @@ var BROWSER_BRANDS = [
|
|
|
13607
14188
|
},
|
|
13608
14189
|
win32: {
|
|
13609
14190
|
executableCandidates: [
|
|
13610
|
-
|
|
13611
|
-
|
|
13612
|
-
|
|
14191
|
+
path7.join(WINDOWS_PROGRAM_FILES, "Google", "Chrome", "Application", "chrome.exe"),
|
|
14192
|
+
path7.join(WINDOWS_PROGRAM_FILES_X86, "Google", "Chrome", "Application", "chrome.exe"),
|
|
14193
|
+
path7.join("~", "AppData", "Local", "Google", "Chrome", "Application", "chrome.exe")
|
|
13613
14194
|
],
|
|
13614
14195
|
userDataDir: "~/AppData/Local/Google/Chrome/User Data",
|
|
13615
14196
|
processNames: ["/google/chrome/application/chrome.exe"]
|
|
@@ -13639,7 +14220,7 @@ var BROWSER_BRANDS = [
|
|
|
13639
14220
|
},
|
|
13640
14221
|
win32: {
|
|
13641
14222
|
executableCandidates: [
|
|
13642
|
-
|
|
14223
|
+
path7.join("~", "AppData", "Local", "Google", "Chrome SxS", "Application", "chrome.exe")
|
|
13643
14224
|
],
|
|
13644
14225
|
userDataDir: "~/AppData/Local/Google/Chrome SxS/User Data",
|
|
13645
14226
|
processNames: ["/google/chrome sxs/application/chrome.exe"]
|
|
@@ -13656,9 +14237,9 @@ var BROWSER_BRANDS = [
|
|
|
13656
14237
|
},
|
|
13657
14238
|
win32: {
|
|
13658
14239
|
executableCandidates: [
|
|
13659
|
-
|
|
13660
|
-
|
|
13661
|
-
|
|
14240
|
+
path7.join(WINDOWS_PROGRAM_FILES, "Chromium", "Application", "chrome.exe"),
|
|
14241
|
+
path7.join(WINDOWS_PROGRAM_FILES_X86, "Chromium", "Application", "chrome.exe"),
|
|
14242
|
+
path7.join("~", "AppData", "Local", "Chromium", "Application", "chrome.exe")
|
|
13662
14243
|
],
|
|
13663
14244
|
userDataDir: "~/AppData/Local/Chromium/User Data",
|
|
13664
14245
|
processNames: ["/chromium/application/chrome.exe"]
|
|
@@ -13685,15 +14266,15 @@ var BROWSER_BRANDS = [
|
|
|
13685
14266
|
},
|
|
13686
14267
|
win32: {
|
|
13687
14268
|
executableCandidates: [
|
|
13688
|
-
|
|
13689
|
-
|
|
14269
|
+
path7.join(WINDOWS_PROGRAM_FILES, "BraveSoftware", "Brave-Browser", "Application", "brave.exe"),
|
|
14270
|
+
path7.join(
|
|
13690
14271
|
WINDOWS_PROGRAM_FILES_X86,
|
|
13691
14272
|
"BraveSoftware",
|
|
13692
14273
|
"Brave-Browser",
|
|
13693
14274
|
"Application",
|
|
13694
14275
|
"brave.exe"
|
|
13695
14276
|
),
|
|
13696
|
-
|
|
14277
|
+
path7.join("~", "AppData", "Local", "BraveSoftware", "Brave-Browser", "Application", "brave.exe")
|
|
13697
14278
|
],
|
|
13698
14279
|
userDataDir: "~/AppData/Local/BraveSoftware/Brave-Browser/User Data",
|
|
13699
14280
|
processNames: ["/bravesoftware/brave-browser/application/brave.exe"]
|
|
@@ -13719,9 +14300,9 @@ var BROWSER_BRANDS = [
|
|
|
13719
14300
|
},
|
|
13720
14301
|
win32: {
|
|
13721
14302
|
executableCandidates: [
|
|
13722
|
-
|
|
13723
|
-
|
|
13724
|
-
|
|
14303
|
+
path7.join(WINDOWS_PROGRAM_FILES, "Microsoft", "Edge", "Application", "msedge.exe"),
|
|
14304
|
+
path7.join(WINDOWS_PROGRAM_FILES_X86, "Microsoft", "Edge", "Application", "msedge.exe"),
|
|
14305
|
+
path7.join("~", "AppData", "Local", "Microsoft", "Edge", "Application", "msedge.exe")
|
|
13725
14306
|
],
|
|
13726
14307
|
userDataDir: "~/AppData/Local/Microsoft/Edge/User Data",
|
|
13727
14308
|
processNames: ["/microsoft/edge/application/msedge.exe"]
|
|
@@ -13749,9 +14330,9 @@ var BROWSER_BRANDS = [
|
|
|
13749
14330
|
},
|
|
13750
14331
|
win32: {
|
|
13751
14332
|
executableCandidates: [
|
|
13752
|
-
|
|
13753
|
-
|
|
13754
|
-
|
|
14333
|
+
path7.join(WINDOWS_PROGRAM_FILES, "Vivaldi", "Application", "vivaldi.exe"),
|
|
14334
|
+
path7.join(WINDOWS_PROGRAM_FILES_X86, "Vivaldi", "Application", "vivaldi.exe"),
|
|
14335
|
+
path7.join("~", "AppData", "Local", "Vivaldi", "Application", "vivaldi.exe")
|
|
13755
14336
|
],
|
|
13756
14337
|
userDataDir: "~/AppData/Local/Vivaldi/User Data",
|
|
13757
14338
|
processNames: ["/vivaldi/application/vivaldi.exe"]
|
|
@@ -13778,9 +14359,6 @@ var BROWSER_BRANDS = [
|
|
|
13778
14359
|
}
|
|
13779
14360
|
}
|
|
13780
14361
|
];
|
|
13781
|
-
function getAllBrowserBrands() {
|
|
13782
|
-
return BROWSER_BRANDS;
|
|
13783
|
-
}
|
|
13784
14362
|
function getBrowserBrand(id) {
|
|
13785
14363
|
const brand2 = BROWSER_BRANDS.find((candidate) => candidate.id === id);
|
|
13786
14364
|
if (!brand2) {
|
|
@@ -13818,177 +14396,35 @@ function detectInstalledBrowserBrands() {
|
|
|
13818
14396
|
brandId: brand2.id,
|
|
13819
14397
|
displayName: brand2.displayName,
|
|
13820
14398
|
executablePath,
|
|
13821
|
-
userDataDir:
|
|
14399
|
+
userDataDir: path7.resolve(expandHome(platformConfig.userDataDir))
|
|
13822
14400
|
});
|
|
13823
14401
|
}
|
|
13824
14402
|
return installations;
|
|
13825
14403
|
}
|
|
13826
|
-
function resolveBrandExecutablePath(brand2, explicitPath) {
|
|
13827
|
-
if (explicitPath !== void 0) {
|
|
13828
|
-
const resolvedPath2 = path6.resolve(expandHome(explicitPath));
|
|
13829
|
-
if (!fs.existsSync(resolvedPath2)) {
|
|
13830
|
-
throw new Error(`${brand2.displayName} executable was not found at "${resolvedPath2}".`);
|
|
13831
|
-
}
|
|
13832
|
-
return resolvedPath2;
|
|
13833
|
-
}
|
|
13834
|
-
const platformConfig = resolveBrandPlatformConfig(brand2);
|
|
13835
|
-
if (!platformConfig) {
|
|
13836
|
-
throw new Error(`${brand2.displayName} is not supported on ${process.platform}.`);
|
|
13837
|
-
}
|
|
13838
|
-
const resolvedPath = firstExistingPath(
|
|
13839
|
-
resolveExecutableCandidates(platformConfig.executableCandidates)
|
|
13840
|
-
);
|
|
13841
|
-
if (!resolvedPath) {
|
|
13842
|
-
throw new Error(
|
|
13843
|
-
`Could not find a ${brand2.displayName} executable. Pass --executable-path or browser.executablePath.`
|
|
13844
|
-
);
|
|
13845
|
-
}
|
|
13846
|
-
return resolvedPath;
|
|
13847
|
-
}
|
|
13848
14404
|
function resolveBrandUserDataDir(brand2, explicitDir) {
|
|
13849
14405
|
if (explicitDir !== void 0) {
|
|
13850
|
-
return
|
|
14406
|
+
return path7.resolve(expandHome(explicitDir));
|
|
13851
14407
|
}
|
|
13852
14408
|
const platformConfig = resolveBrandPlatformConfig(brand2);
|
|
13853
14409
|
if (!platformConfig) {
|
|
13854
14410
|
throw new Error(`${brand2.displayName} is not supported on ${process.platform}.`);
|
|
13855
14411
|
}
|
|
13856
|
-
return
|
|
13857
|
-
}
|
|
13858
|
-
function isBrandProcess(brand2, commandLine) {
|
|
13859
|
-
const normalizedCommand = normalizeCommand(commandLine);
|
|
13860
|
-
if (!normalizedCommand) {
|
|
13861
|
-
return false;
|
|
13862
|
-
}
|
|
13863
|
-
if (normalizedCommand.includes("crashpad_handler")) {
|
|
13864
|
-
return false;
|
|
13865
|
-
}
|
|
13866
|
-
if (/\s--type=/.test(normalizedCommand)) {
|
|
13867
|
-
return false;
|
|
13868
|
-
}
|
|
13869
|
-
return getBrandProcessMarkers(brand2).some((marker) => normalizedCommand.includes(marker));
|
|
13870
|
-
}
|
|
13871
|
-
function findBrandProcess(brand2) {
|
|
13872
|
-
for (const processEntry of listProcesses()) {
|
|
13873
|
-
if (isBrandProcess(brand2, processEntry.commandLine)) {
|
|
13874
|
-
return { pid: processEntry.pid };
|
|
13875
|
-
}
|
|
13876
|
-
}
|
|
13877
|
-
return null;
|
|
13878
|
-
}
|
|
13879
|
-
function getBrandProcessMarkers(brand2) {
|
|
13880
|
-
const markers = /* @__PURE__ */ new Set();
|
|
13881
|
-
for (const config of [brand2.darwin, brand2.win32, brand2.linux]) {
|
|
13882
|
-
if (!config) {
|
|
13883
|
-
continue;
|
|
13884
|
-
}
|
|
13885
|
-
for (const processName of config.processNames) {
|
|
13886
|
-
const normalized = normalizeCommand(processName);
|
|
13887
|
-
if (normalized) {
|
|
13888
|
-
markers.add(normalized);
|
|
13889
|
-
}
|
|
13890
|
-
}
|
|
13891
|
-
for (const candidate of config.executableCandidates) {
|
|
13892
|
-
if (!candidate) {
|
|
13893
|
-
continue;
|
|
13894
|
-
}
|
|
13895
|
-
const normalized = normalizeCommand(path6.resolve(expandHome(candidate)));
|
|
13896
|
-
if (normalized) {
|
|
13897
|
-
markers.add(normalized);
|
|
13898
|
-
}
|
|
13899
|
-
}
|
|
13900
|
-
}
|
|
13901
|
-
return [...markers];
|
|
14412
|
+
return path7.resolve(expandHome(platformConfig.userDataDir));
|
|
13902
14413
|
}
|
|
13903
14414
|
function resolveExecutableCandidates(candidates) {
|
|
13904
|
-
return candidates.map((candidate) => candidate ?
|
|
13905
|
-
}
|
|
13906
|
-
function listProcesses() {
|
|
13907
|
-
if (process.platform === "win32") {
|
|
13908
|
-
return listWindowsProcesses();
|
|
13909
|
-
}
|
|
13910
|
-
return listUnixProcesses();
|
|
13911
|
-
}
|
|
13912
|
-
function listUnixProcesses() {
|
|
13913
|
-
try {
|
|
13914
|
-
const output = child_process.execFileSync("ps", ["-A", "-o", "pid=,command="], {
|
|
13915
|
-
encoding: "utf8",
|
|
13916
|
-
env: PS_COMMAND_ENV2,
|
|
13917
|
-
maxBuffer: PROCESS_LIST_MAX_BUFFER_BYTES2,
|
|
13918
|
-
stdio: ["ignore", "pipe", "ignore"]
|
|
13919
|
-
});
|
|
13920
|
-
return output.split(/\r?\n/).map((line) => line.trim()).filter((line) => line.length > 0).map((line) => {
|
|
13921
|
-
const match = /^(\d+)\s+(.*)$/.exec(line);
|
|
13922
|
-
if (!match) {
|
|
13923
|
-
return null;
|
|
13924
|
-
}
|
|
13925
|
-
const pid = Number.parseInt(match[1] ?? "", 10);
|
|
13926
|
-
const commandLine = match[2]?.trim() ?? "";
|
|
13927
|
-
if (!Number.isInteger(pid) || pid <= 0 || commandLine.length === 0) {
|
|
13928
|
-
return null;
|
|
13929
|
-
}
|
|
13930
|
-
return {
|
|
13931
|
-
pid,
|
|
13932
|
-
commandLine
|
|
13933
|
-
};
|
|
13934
|
-
}).filter(
|
|
13935
|
-
(entry) => entry !== null
|
|
13936
|
-
).sort((left, right) => left.pid - right.pid);
|
|
13937
|
-
} catch {
|
|
13938
|
-
return [];
|
|
13939
|
-
}
|
|
13940
|
-
}
|
|
13941
|
-
function listWindowsProcesses() {
|
|
13942
|
-
try {
|
|
13943
|
-
const output = child_process.execFileSync(
|
|
13944
|
-
"powershell.exe",
|
|
13945
|
-
[
|
|
13946
|
-
"-NoProfile",
|
|
13947
|
-
"-Command",
|
|
13948
|
-
"Get-CimInstance Win32_Process | Select-Object ProcessId,CommandLine | ConvertTo-Json -Compress"
|
|
13949
|
-
],
|
|
13950
|
-
{
|
|
13951
|
-
encoding: "utf8",
|
|
13952
|
-
maxBuffer: PROCESS_LIST_MAX_BUFFER_BYTES2,
|
|
13953
|
-
stdio: ["ignore", "pipe", "ignore"]
|
|
13954
|
-
}
|
|
13955
|
-
).trim();
|
|
13956
|
-
if (!output) {
|
|
13957
|
-
return [];
|
|
13958
|
-
}
|
|
13959
|
-
const parsed = JSON.parse(output);
|
|
13960
|
-
const records = Array.isArray(parsed) ? parsed : [parsed];
|
|
13961
|
-
return records.map((record) => {
|
|
13962
|
-
const pid = Number(record.ProcessId);
|
|
13963
|
-
const commandLine = typeof record.CommandLine === "string" ? record.CommandLine.trim() : "";
|
|
13964
|
-
if (!Number.isInteger(pid) || pid <= 0 || commandLine.length === 0) {
|
|
13965
|
-
return null;
|
|
13966
|
-
}
|
|
13967
|
-
return {
|
|
13968
|
-
pid,
|
|
13969
|
-
commandLine
|
|
13970
|
-
};
|
|
13971
|
-
}).filter(
|
|
13972
|
-
(entry) => entry !== null
|
|
13973
|
-
).sort((left, right) => left.pid - right.pid);
|
|
13974
|
-
} catch {
|
|
13975
|
-
return [];
|
|
13976
|
-
}
|
|
13977
|
-
}
|
|
13978
|
-
function normalizeCommand(value) {
|
|
13979
|
-
return value.trim().replaceAll("\\", "/").toLowerCase();
|
|
14415
|
+
return candidates.map((candidate) => candidate ? path7.resolve(expandHome(candidate)) : null);
|
|
13980
14416
|
}
|
|
13981
14417
|
|
|
13982
14418
|
// src/local-browser/chrome-discovery.ts
|
|
13983
14419
|
function expandHome(value) {
|
|
13984
14420
|
if (value === "~" || value.startsWith("~/")) {
|
|
13985
|
-
return
|
|
14421
|
+
return path7.join(os.homedir(), value.slice(1));
|
|
13986
14422
|
}
|
|
13987
14423
|
return value;
|
|
13988
14424
|
}
|
|
13989
14425
|
function resolveChromeUserDataDir(userDataDir) {
|
|
13990
14426
|
const installation = detectLocalChromeInstallations().find(
|
|
13991
|
-
(candidate) => fs.existsSync(
|
|
14427
|
+
(candidate) => fs.existsSync(path7.join(candidate.userDataDir, "Local State")) || candidate.executablePath !== null
|
|
13992
14428
|
);
|
|
13993
14429
|
if (!installation) {
|
|
13994
14430
|
throw new Error("Could not find a local Chrome or Chromium profile directory.");
|
|
@@ -13997,7 +14433,7 @@ function resolveChromeUserDataDir(userDataDir) {
|
|
|
13997
14433
|
}
|
|
13998
14434
|
function resolveChromeExecutablePath(executablePath) {
|
|
13999
14435
|
if (executablePath !== void 0) {
|
|
14000
|
-
const resolvedPath =
|
|
14436
|
+
const resolvedPath = path7.resolve(expandHome(executablePath));
|
|
14001
14437
|
if (!fs.existsSync(resolvedPath)) {
|
|
14002
14438
|
throw new Error(`Chrome executable was not found at "${resolvedPath}".`);
|
|
14003
14439
|
}
|
|
@@ -14021,37 +14457,37 @@ function detectLocalChromeInstallations() {
|
|
|
14021
14457
|
"/Applications/Google Chrome.app/Contents/MacOS/Google Chrome",
|
|
14022
14458
|
"/Applications/Google Chrome Canary.app/Contents/MacOS/Google Chrome Canary"
|
|
14023
14459
|
]),
|
|
14024
|
-
userDataDir:
|
|
14460
|
+
userDataDir: path7.join(os.homedir(), "Library", "Application Support", "Google", "Chrome")
|
|
14025
14461
|
},
|
|
14026
14462
|
{
|
|
14027
14463
|
brand: "chromium",
|
|
14028
14464
|
executablePath: firstExistingPath(["/Applications/Chromium.app/Contents/MacOS/Chromium"]),
|
|
14029
|
-
userDataDir:
|
|
14465
|
+
userDataDir: path7.join(os.homedir(), "Library", "Application Support", "Chromium")
|
|
14030
14466
|
}
|
|
14031
14467
|
];
|
|
14032
14468
|
}
|
|
14033
14469
|
if (process.platform === "win32") {
|
|
14034
14470
|
const programFiles = process.env.PROGRAMFILES ?? "C:\\Program Files";
|
|
14035
14471
|
const programFilesX86 = process.env["PROGRAMFILES(X86)"] ?? "C:\\Program Files (x86)";
|
|
14036
|
-
const localAppData = process.env.LOCALAPPDATA ??
|
|
14472
|
+
const localAppData = process.env.LOCALAPPDATA ?? path7.join(os.homedir(), "AppData", "Local");
|
|
14037
14473
|
return [
|
|
14038
14474
|
{
|
|
14039
14475
|
brand: "chrome",
|
|
14040
14476
|
executablePath: firstExistingPath([
|
|
14041
|
-
|
|
14042
|
-
|
|
14043
|
-
|
|
14477
|
+
path7.join(programFiles, "Google", "Chrome", "Application", "chrome.exe"),
|
|
14478
|
+
path7.join(programFilesX86, "Google", "Chrome", "Application", "chrome.exe"),
|
|
14479
|
+
path7.join(localAppData, "Google", "Chrome", "Application", "chrome.exe")
|
|
14044
14480
|
]),
|
|
14045
|
-
userDataDir:
|
|
14481
|
+
userDataDir: path7.join(localAppData, "Google", "Chrome", "User Data")
|
|
14046
14482
|
},
|
|
14047
14483
|
{
|
|
14048
14484
|
brand: "chromium",
|
|
14049
14485
|
executablePath: firstExistingPath([
|
|
14050
|
-
|
|
14051
|
-
|
|
14052
|
-
|
|
14486
|
+
path7.join(programFiles, "Chromium", "Application", "chrome.exe"),
|
|
14487
|
+
path7.join(programFilesX86, "Chromium", "Application", "chrome.exe"),
|
|
14488
|
+
path7.join(localAppData, "Chromium", "Application", "chrome.exe")
|
|
14053
14489
|
]),
|
|
14054
|
-
userDataDir:
|
|
14490
|
+
userDataDir: path7.join(localAppData, "Chromium", "User Data")
|
|
14055
14491
|
}
|
|
14056
14492
|
];
|
|
14057
14493
|
}
|
|
@@ -14064,7 +14500,7 @@ function detectLocalChromeInstallations() {
|
|
|
14064
14500
|
resolveBinaryFromPath("google-chrome"),
|
|
14065
14501
|
resolveBinaryFromPath("google-chrome-stable")
|
|
14066
14502
|
]),
|
|
14067
|
-
userDataDir:
|
|
14503
|
+
userDataDir: path7.join(os.homedir(), ".config", "google-chrome")
|
|
14068
14504
|
},
|
|
14069
14505
|
{
|
|
14070
14506
|
brand: "chromium",
|
|
@@ -14074,7 +14510,7 @@ function detectLocalChromeInstallations() {
|
|
|
14074
14510
|
resolveBinaryFromPath("chromium"),
|
|
14075
14511
|
resolveBinaryFromPath("chromium-browser")
|
|
14076
14512
|
]),
|
|
14077
|
-
userDataDir:
|
|
14513
|
+
userDataDir: path7.join(os.homedir(), ".config", "chromium")
|
|
14078
14514
|
}
|
|
14079
14515
|
];
|
|
14080
14516
|
}
|
|
@@ -14086,8 +14522,8 @@ function detectLocalBrowserInstallations() {
|
|
|
14086
14522
|
}));
|
|
14087
14523
|
}
|
|
14088
14524
|
function listLocalChromeProfiles(userDataDir = resolveChromeUserDataDir()) {
|
|
14089
|
-
const resolvedUserDataDir =
|
|
14090
|
-
const localStatePath =
|
|
14525
|
+
const resolvedUserDataDir = path7.resolve(expandHome(userDataDir));
|
|
14526
|
+
const localStatePath = path7.join(resolvedUserDataDir, "Local State");
|
|
14091
14527
|
if (!fs.existsSync(localStatePath)) {
|
|
14092
14528
|
return [];
|
|
14093
14529
|
}
|
|
@@ -14099,7 +14535,7 @@ function listLocalChromeProfiles(userDataDir = resolveChromeUserDataDir()) {
|
|
|
14099
14535
|
}
|
|
14100
14536
|
return Object.entries(infoCache).map(([directory, info]) => {
|
|
14101
14537
|
const record = info && typeof info === "object" && !Array.isArray(info) ? info : {};
|
|
14102
|
-
const name = typeof record.name === "string" && record.name.trim().length > 0 ? record.name.trim() : directory ||
|
|
14538
|
+
const name = typeof record.name === "string" && record.name.trim().length > 0 ? record.name.trim() : directory || path7.basename(directory);
|
|
14103
14539
|
return {
|
|
14104
14540
|
directory,
|
|
14105
14541
|
name,
|
|
@@ -14111,7 +14547,7 @@ function listLocalChromeProfiles(userDataDir = resolveChromeUserDataDir()) {
|
|
|
14111
14547
|
}
|
|
14112
14548
|
}
|
|
14113
14549
|
function readDevToolsActivePort(userDataDir) {
|
|
14114
|
-
const devToolsPath =
|
|
14550
|
+
const devToolsPath = path7.join(userDataDir, "DevToolsActivePort");
|
|
14115
14551
|
if (!fs.existsSync(devToolsPath)) {
|
|
14116
14552
|
return null;
|
|
14117
14553
|
}
|
|
@@ -14344,8 +14780,8 @@ function buildBrowserWebSocketUrl(httpUrl, webSocketPath) {
|
|
|
14344
14780
|
const protocol = httpUrl.protocol === "https:" ? "wss:" : "ws:";
|
|
14345
14781
|
return `${protocol}//${httpUrl.host}${normalizeWebSocketPath(webSocketPath)}`;
|
|
14346
14782
|
}
|
|
14347
|
-
function normalizeWebSocketPath(
|
|
14348
|
-
return
|
|
14783
|
+
function normalizeWebSocketPath(path15) {
|
|
14784
|
+
return path15.startsWith("/") ? path15 : `/${path15}`;
|
|
14349
14785
|
}
|
|
14350
14786
|
function rewriteBrowserWebSocketHost(browserWsUrl, requestedUrl) {
|
|
14351
14787
|
try {
|
|
@@ -14391,20 +14827,20 @@ var SESSION_SKIPPED_PROFILE_DIRECTORIES = /* @__PURE__ */ new Set([
|
|
|
14391
14827
|
"Network"
|
|
14392
14828
|
]);
|
|
14393
14829
|
async function createBrowserProfileSnapshot(input) {
|
|
14394
|
-
const sourceUserDataDir =
|
|
14395
|
-
const targetUserDataDir =
|
|
14830
|
+
const sourceUserDataDir = path7.resolve(expandHome(input.sourceUserDataDir));
|
|
14831
|
+
const targetUserDataDir = path7.resolve(expandHome(input.targetUserDataDir));
|
|
14396
14832
|
const profileDirectory = input.profileDirectory?.trim();
|
|
14397
14833
|
const copyMode = input.copyMode;
|
|
14398
14834
|
await promises.mkdir(targetUserDataDir, { recursive: true });
|
|
14399
14835
|
await clearChromeSingletonEntries(targetUserDataDir);
|
|
14400
14836
|
if (profileDirectory) {
|
|
14401
|
-
const sourceProfileDir =
|
|
14837
|
+
const sourceProfileDir = path7.join(sourceUserDataDir, profileDirectory);
|
|
14402
14838
|
if (!fs.existsSync(sourceProfileDir)) {
|
|
14403
14839
|
throw new Error(
|
|
14404
14840
|
`Chrome profile "${profileDirectory}" was not found in "${sourceUserDataDir}".`
|
|
14405
14841
|
);
|
|
14406
14842
|
}
|
|
14407
|
-
await promises.cp(sourceProfileDir,
|
|
14843
|
+
await promises.cp(sourceProfileDir, path7.join(targetUserDataDir, profileDirectory), {
|
|
14408
14844
|
recursive: true,
|
|
14409
14845
|
filter: (candidate) => shouldCopyEntry({
|
|
14410
14846
|
candidatePath: candidate,
|
|
@@ -14428,8 +14864,8 @@ async function copyRootLevelEntries(input) {
|
|
|
14428
14864
|
if (CHROME_SINGLETON_ENTRIES.has(entry) || entry === input.selectedProfileDirectory) {
|
|
14429
14865
|
continue;
|
|
14430
14866
|
}
|
|
14431
|
-
const sourcePath =
|
|
14432
|
-
const targetPath =
|
|
14867
|
+
const sourcePath = path7.join(input.sourceUserDataDir, entry);
|
|
14868
|
+
const targetPath = path7.join(input.targetUserDataDir, entry);
|
|
14433
14869
|
const entryStat = await promises.stat(sourcePath).catch(() => null);
|
|
14434
14870
|
if (!entryStat) {
|
|
14435
14871
|
continue;
|
|
@@ -14461,7 +14897,7 @@ async function copyRootLevelEntries(input) {
|
|
|
14461
14897
|
}
|
|
14462
14898
|
}
|
|
14463
14899
|
function isProfileDirectory(userDataDir, entry) {
|
|
14464
|
-
return fs.existsSync(
|
|
14900
|
+
return fs.existsSync(path7.join(userDataDir, entry, "Preferences"));
|
|
14465
14901
|
}
|
|
14466
14902
|
function shouldCopyEntry(input) {
|
|
14467
14903
|
const entryName = input.candidatePath.split("/").at(-1)?.split("\\").at(-1) ?? input.candidatePath;
|
|
@@ -14471,7 +14907,7 @@ function shouldCopyEntry(input) {
|
|
|
14471
14907
|
if (input.copyMode !== "session") {
|
|
14472
14908
|
return true;
|
|
14473
14909
|
}
|
|
14474
|
-
const relativePath =
|
|
14910
|
+
const relativePath = path7.relative(input.rootPath, input.candidatePath);
|
|
14475
14911
|
if (relativePath.length === 0) {
|
|
14476
14912
|
return true;
|
|
14477
14913
|
}
|
|
@@ -14953,7 +15389,7 @@ function pickStealthProfilePreset(overrides) {
|
|
|
14953
15389
|
var OPENSTEER_LIVE_SESSION_LAYOUT = "opensteer-session";
|
|
14954
15390
|
var OPENSTEER_LIVE_SESSION_VERSION = 1;
|
|
14955
15391
|
function resolveLiveSessionRecordPath(rootPath, provider) {
|
|
14956
|
-
return
|
|
15392
|
+
return path7__default.default.join(rootPath, "live", provider === "local" ? "local.json" : "cloud.json");
|
|
14957
15393
|
}
|
|
14958
15394
|
function resolveLocalSessionRecordPath(rootPath) {
|
|
14959
15395
|
return resolveLiveSessionRecordPath(rootPath, "local");
|
|
@@ -15113,8 +15549,8 @@ var OpensteerBrowserManager = class {
|
|
|
15113
15549
|
...options.browser === void 0 ? {} : { browser: options.browser },
|
|
15114
15550
|
...this.contextOptions === void 0 ? {} : { context: this.contextOptions }
|
|
15115
15551
|
});
|
|
15116
|
-
this.rootPath = options.rootPath ?? (this.workspace === void 0 ?
|
|
15117
|
-
rootDir:
|
|
15552
|
+
this.rootPath = options.rootPath ?? (this.workspace === void 0 ? path7__default.default.join(os.tmpdir(), `${TEMPORARY_WORKSPACE_PREFIX}${crypto.randomUUID()}`) : resolveFilesystemWorkspacePath({
|
|
15553
|
+
rootDir: path7__default.default.resolve(options.rootDir ?? process.cwd()),
|
|
15118
15554
|
workspace: this.workspace
|
|
15119
15555
|
}));
|
|
15120
15556
|
this.cleanupRootOnDisconnect = this.workspace === void 0;
|
|
@@ -15184,7 +15620,7 @@ var OpensteerBrowserManager = class {
|
|
|
15184
15620
|
userDataDir: "browser/user-data",
|
|
15185
15621
|
bootstrap: {
|
|
15186
15622
|
kind: "cloneLocalProfile",
|
|
15187
|
-
sourceUserDataDir:
|
|
15623
|
+
sourceUserDataDir: path7__default.default.resolve(input.sourceUserDataDir),
|
|
15188
15624
|
...input.sourceProfileDirectory === void 0 ? {} : { sourceProfileDirectory: input.sourceProfileDirectory }
|
|
15189
15625
|
}
|
|
15190
15626
|
};
|
|
@@ -15311,7 +15747,7 @@ var OpensteerBrowserManager = class {
|
|
|
15311
15747
|
});
|
|
15312
15748
|
}
|
|
15313
15749
|
async createTemporaryEngine() {
|
|
15314
|
-
const userDataDir = await promises.mkdtemp(
|
|
15750
|
+
const userDataDir = await promises.mkdtemp(path7__default.default.join(os.tmpdir(), "opensteer-temporary-browser-"));
|
|
15315
15751
|
await clearChromeSingletonEntries(userDataDir);
|
|
15316
15752
|
const launched = await launchOwnedBrowser({
|
|
15317
15753
|
userDataDir,
|
|
@@ -15758,7 +16194,7 @@ async function terminateProcess(pid) {
|
|
|
15758
16194
|
}
|
|
15759
16195
|
}
|
|
15760
16196
|
async function requestBrowserClose(endpoint) {
|
|
15761
|
-
await new Promise((
|
|
16197
|
+
await new Promise((resolve4, reject) => {
|
|
15762
16198
|
const socket = new WebSocket(endpoint);
|
|
15763
16199
|
const timeout = setTimeout(() => {
|
|
15764
16200
|
socket.close();
|
|
@@ -15775,7 +16211,7 @@ async function requestBrowserClose(endpoint) {
|
|
|
15775
16211
|
reject(error);
|
|
15776
16212
|
return;
|
|
15777
16213
|
}
|
|
15778
|
-
|
|
16214
|
+
resolve4();
|
|
15779
16215
|
};
|
|
15780
16216
|
socket.addEventListener("open", () => {
|
|
15781
16217
|
socket.send(JSON.stringify({ id: 1, method: "Browser.close" }));
|
|
@@ -15813,7 +16249,7 @@ async function waitForProcessExit(pid, timeoutMs) {
|
|
|
15813
16249
|
return !isProcessRunning(pid);
|
|
15814
16250
|
}
|
|
15815
16251
|
function resolveAbpSessionDir(workspace) {
|
|
15816
|
-
return
|
|
16252
|
+
return path7__default.default.join(workspace.livePath, "abp-session");
|
|
15817
16253
|
}
|
|
15818
16254
|
async function allocateEphemeralPort() {
|
|
15819
16255
|
const { allocatePort } = await loadAbpModule();
|
|
@@ -15871,7 +16307,103 @@ function isStealthProfile(input) {
|
|
|
15871
16307
|
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;
|
|
15872
16308
|
}
|
|
15873
16309
|
async function sleep(ms) {
|
|
15874
|
-
await new Promise((
|
|
16310
|
+
await new Promise((resolve4) => setTimeout(resolve4, ms));
|
|
16311
|
+
}
|
|
16312
|
+
var ENV_FILENAMES = [".env", ".env.local"];
|
|
16313
|
+
var OPENSTEER_ENV_PREFIX = "OPENSTEER_";
|
|
16314
|
+
var opensteerEnvironmentCache = /* @__PURE__ */ new Map();
|
|
16315
|
+
function resolveOpensteerEnvironment(cwd = process.cwd(), baseEnv = process.env) {
|
|
16316
|
+
const resolvedCwd = path7__default.default.resolve(cwd);
|
|
16317
|
+
const signature = buildEnvironmentSignature(baseEnv, isOpensteerEnvironmentKey);
|
|
16318
|
+
const cached = opensteerEnvironmentCache.get(resolvedCwd);
|
|
16319
|
+
if (cached && cached.signature === signature) {
|
|
16320
|
+
return { ...cached.values };
|
|
16321
|
+
}
|
|
16322
|
+
const resolved = resolveEnvironmentFiles(resolvedCwd, baseEnv, isOpensteerEnvironmentKey);
|
|
16323
|
+
opensteerEnvironmentCache.set(resolvedCwd, {
|
|
16324
|
+
signature,
|
|
16325
|
+
values: { ...resolved }
|
|
16326
|
+
});
|
|
16327
|
+
return { ...resolved };
|
|
16328
|
+
}
|
|
16329
|
+
function collectDirectories(cwd) {
|
|
16330
|
+
const directories = [];
|
|
16331
|
+
let current = path7__default.default.resolve(cwd);
|
|
16332
|
+
for (; ; ) {
|
|
16333
|
+
directories.unshift(current);
|
|
16334
|
+
const parent = path7__default.default.dirname(current);
|
|
16335
|
+
if (parent === current) {
|
|
16336
|
+
return directories;
|
|
16337
|
+
}
|
|
16338
|
+
current = parent;
|
|
16339
|
+
}
|
|
16340
|
+
}
|
|
16341
|
+
function parseEnvFile(contents) {
|
|
16342
|
+
const parsed = {};
|
|
16343
|
+
for (const rawLine of contents.split(/\r?\n/u)) {
|
|
16344
|
+
const trimmed = rawLine.trim();
|
|
16345
|
+
if (!trimmed || trimmed.startsWith("#")) {
|
|
16346
|
+
continue;
|
|
16347
|
+
}
|
|
16348
|
+
const line = trimmed.startsWith("export ") ? trimmed.slice("export ".length) : trimmed;
|
|
16349
|
+
const separatorIndex = line.indexOf("=");
|
|
16350
|
+
if (separatorIndex <= 0) {
|
|
16351
|
+
continue;
|
|
16352
|
+
}
|
|
16353
|
+
const key = line.slice(0, separatorIndex).trim();
|
|
16354
|
+
if (!/^[A-Za-z_][A-Za-z0-9_]*$/u.test(key)) {
|
|
16355
|
+
continue;
|
|
16356
|
+
}
|
|
16357
|
+
const rawValue = line.slice(separatorIndex + 1).trim();
|
|
16358
|
+
parsed[key] = parseEnvValue(rawValue);
|
|
16359
|
+
}
|
|
16360
|
+
return parsed;
|
|
16361
|
+
}
|
|
16362
|
+
function parseEnvValue(rawValue) {
|
|
16363
|
+
if (rawValue.length >= 2 && rawValue.startsWith('"') && rawValue.endsWith('"')) {
|
|
16364
|
+
return rawValue.slice(1, -1).replace(/\\n/g, "\n").replace(/\\r/g, "\r").replace(/\\t/g, " ").replace(/\\"/g, '"');
|
|
16365
|
+
}
|
|
16366
|
+
if (rawValue.length >= 2 && rawValue.startsWith("'") && rawValue.endsWith("'")) {
|
|
16367
|
+
return rawValue.slice(1, -1);
|
|
16368
|
+
}
|
|
16369
|
+
return rawValue.replace(/\s+#.*$/u, "").trimEnd();
|
|
16370
|
+
}
|
|
16371
|
+
function resolveEnvironmentFiles(cwd, baseEnv, predicate) {
|
|
16372
|
+
const resolved = collectEnvironment(baseEnv, predicate);
|
|
16373
|
+
const protectedKeys = new Set(Object.keys(resolved));
|
|
16374
|
+
const directories = collectDirectories(cwd);
|
|
16375
|
+
for (const directory of directories) {
|
|
16376
|
+
for (const filename of ENV_FILENAMES) {
|
|
16377
|
+
const filePath = path7__default.default.join(directory, filename);
|
|
16378
|
+
if (!fs.existsSync(filePath)) {
|
|
16379
|
+
continue;
|
|
16380
|
+
}
|
|
16381
|
+
const parsed = parseEnvFile(fs.readFileSync(filePath, "utf8"));
|
|
16382
|
+
for (const [key, value] of Object.entries(parsed)) {
|
|
16383
|
+
if (predicate && !predicate(key) || protectedKeys.has(key)) {
|
|
16384
|
+
continue;
|
|
16385
|
+
}
|
|
16386
|
+
resolved[key] = value;
|
|
16387
|
+
}
|
|
16388
|
+
}
|
|
16389
|
+
}
|
|
16390
|
+
return resolved;
|
|
16391
|
+
}
|
|
16392
|
+
function collectEnvironment(baseEnv, predicate) {
|
|
16393
|
+
const resolved = {};
|
|
16394
|
+
for (const [key, value] of Object.entries(baseEnv)) {
|
|
16395
|
+
if (predicate && !predicate(key) || value === void 0) {
|
|
16396
|
+
continue;
|
|
16397
|
+
}
|
|
16398
|
+
resolved[key] = value;
|
|
16399
|
+
}
|
|
16400
|
+
return resolved;
|
|
16401
|
+
}
|
|
16402
|
+
function buildEnvironmentSignature(baseEnv, predicate) {
|
|
16403
|
+
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");
|
|
16404
|
+
}
|
|
16405
|
+
function isOpensteerEnvironmentKey(key) {
|
|
16406
|
+
return key.startsWith(OPENSTEER_ENV_PREFIX);
|
|
15875
16407
|
}
|
|
15876
16408
|
|
|
15877
16409
|
// ../runtime-core/package.json
|
|
@@ -17485,7 +18017,7 @@ function diffStringMap(prefix, left, right, includeUnchanged, output) {
|
|
|
17485
18017
|
diffScalarField(`${prefix}.${key}`, left[key], right[key], includeUnchanged, output);
|
|
17486
18018
|
}
|
|
17487
18019
|
}
|
|
17488
|
-
function diffScalarField(
|
|
18020
|
+
function diffScalarField(path15, left, right, includeUnchanged, output) {
|
|
17489
18021
|
const leftValue = stringifyFieldValue(left);
|
|
17490
18022
|
const rightValue = stringifyFieldValue(right);
|
|
17491
18023
|
const kind = leftValue === void 0 ? rightValue === void 0 ? "unchanged" : "added" : rightValue === void 0 ? "removed" : leftValue === rightValue ? "unchanged" : "changed";
|
|
@@ -17493,7 +18025,7 @@ function diffScalarField(path13, left, right, includeUnchanged, output) {
|
|
|
17493
18025
|
return;
|
|
17494
18026
|
}
|
|
17495
18027
|
output.push({
|
|
17496
|
-
path:
|
|
18028
|
+
path: path15,
|
|
17497
18029
|
kind,
|
|
17498
18030
|
...leftValue === void 0 ? {} : { leftValue },
|
|
17499
18031
|
...rightValue === void 0 ? {} : { rightValue },
|
|
@@ -18499,9 +19031,9 @@ function matchReverseTargetHints(channel, codec, targetHints) {
|
|
|
18499
19031
|
matches.add(`host:${host}`);
|
|
18500
19032
|
}
|
|
18501
19033
|
}
|
|
18502
|
-
for (const
|
|
18503
|
-
if (url.pathname.includes(
|
|
18504
|
-
matches.add(`path:${
|
|
19034
|
+
for (const path15 of targetHints.paths ?? []) {
|
|
19035
|
+
if (url.pathname.includes(path15)) {
|
|
19036
|
+
matches.add(`path:${path15}`);
|
|
18505
19037
|
}
|
|
18506
19038
|
}
|
|
18507
19039
|
for (const operationName of targetHints.operationNames ?? []) {
|
|
@@ -19462,11 +19994,11 @@ function inferClusterRelationship(seed, record) {
|
|
|
19462
19994
|
var MATCHED_TLS_BINARY_NAMES = ["curl-impersonate-chrome", "curl_chrome"];
|
|
19463
19995
|
async function executeMatchedTlsTransportRequest(input) {
|
|
19464
19996
|
const binary = await resolveMatchedTlsBinary();
|
|
19465
|
-
const workingDirectory = await promises.mkdtemp(
|
|
19466
|
-
const headersPath =
|
|
19467
|
-
const bodyPath =
|
|
19468
|
-
const cookiesPath =
|
|
19469
|
-
const requestBodyPath =
|
|
19997
|
+
const workingDirectory = await promises.mkdtemp(path7__default.default.join(os.tmpdir(), "opensteer-matched-tls-"));
|
|
19998
|
+
const headersPath = path7__default.default.join(workingDirectory, "headers.txt");
|
|
19999
|
+
const bodyPath = path7__default.default.join(workingDirectory, "body.bin");
|
|
20000
|
+
const cookiesPath = path7__default.default.join(workingDirectory, "cookies.txt");
|
|
20001
|
+
const requestBodyPath = path7__default.default.join(workingDirectory, "request-body.bin");
|
|
19470
20002
|
try {
|
|
19471
20003
|
await promises.writeFile(cookiesPath, toNetscapeCookieJar(input.cookies ?? []), "utf8");
|
|
19472
20004
|
if (input.request.body !== void 0) {
|
|
@@ -19523,10 +20055,10 @@ async function executeMatchedTlsTransportRequest(input) {
|
|
|
19523
20055
|
}
|
|
19524
20056
|
}
|
|
19525
20057
|
async function resolveMatchedTlsBinary() {
|
|
19526
|
-
const pathEntries = (process.env.PATH ?? "").split(
|
|
20058
|
+
const pathEntries = (process.env.PATH ?? "").split(path7__default.default.delimiter).filter((entry) => entry.length > 0);
|
|
19527
20059
|
for (const directory of pathEntries) {
|
|
19528
20060
|
for (const name of MATCHED_TLS_BINARY_NAMES) {
|
|
19529
|
-
const candidate =
|
|
20061
|
+
const candidate = path7__default.default.join(directory, name);
|
|
19530
20062
|
if (await isExecutable(candidate)) {
|
|
19531
20063
|
return candidate;
|
|
19532
20064
|
}
|
|
@@ -19534,7 +20066,7 @@ async function resolveMatchedTlsBinary() {
|
|
|
19534
20066
|
const files = await readDirSafe(directory);
|
|
19535
20067
|
const discovered = files.find((file) => file.startsWith("curl_chrome"));
|
|
19536
20068
|
if (discovered !== void 0) {
|
|
19537
|
-
const candidate =
|
|
20069
|
+
const candidate = path7__default.default.join(directory, discovered);
|
|
19538
20070
|
if (await isExecutable(candidate)) {
|
|
19539
20071
|
return candidate;
|
|
19540
20072
|
}
|
|
@@ -19545,7 +20077,7 @@ async function resolveMatchedTlsBinary() {
|
|
|
19545
20077
|
);
|
|
19546
20078
|
}
|
|
19547
20079
|
async function spawnAndCollect(command, args, signal) {
|
|
19548
|
-
return await new Promise((
|
|
20080
|
+
return await new Promise((resolve4, reject) => {
|
|
19549
20081
|
const child = child_process.spawn(command, args, {
|
|
19550
20082
|
stdio: ["ignore", "pipe", "pipe"]
|
|
19551
20083
|
});
|
|
@@ -19578,7 +20110,7 @@ async function spawnAndCollect(command, args, signal) {
|
|
|
19578
20110
|
);
|
|
19579
20111
|
return;
|
|
19580
20112
|
}
|
|
19581
|
-
|
|
20113
|
+
resolve4({ stdout, stderr });
|
|
19582
20114
|
});
|
|
19583
20115
|
});
|
|
19584
20116
|
}
|
|
@@ -22240,8 +22772,8 @@ function readString(value) {
|
|
|
22240
22772
|
return typeof value === "string" && value.length > 0 ? value : void 0;
|
|
22241
22773
|
}
|
|
22242
22774
|
function sleep2(ms, signal) {
|
|
22243
|
-
return new Promise((
|
|
22244
|
-
const timeout = setTimeout(
|
|
22775
|
+
return new Promise((resolve4, reject) => {
|
|
22776
|
+
const timeout = setTimeout(resolve4, ms);
|
|
22245
22777
|
const abort = () => {
|
|
22246
22778
|
clearTimeout(timeout);
|
|
22247
22779
|
reject(new Error("captcha solve aborted"));
|
|
@@ -22338,8 +22870,8 @@ function readString2(value) {
|
|
|
22338
22870
|
return typeof value === "string" && value.length > 0 ? value : void 0;
|
|
22339
22871
|
}
|
|
22340
22872
|
function sleep3(ms, signal) {
|
|
22341
|
-
return new Promise((
|
|
22342
|
-
const timeout = setTimeout(
|
|
22873
|
+
return new Promise((resolve4, reject) => {
|
|
22874
|
+
const timeout = setTimeout(resolve4, ms);
|
|
22343
22875
|
const abort = () => {
|
|
22344
22876
|
clearTimeout(timeout);
|
|
22345
22877
|
reject(new Error("captcha solve aborted"));
|
|
@@ -22538,6 +23070,8 @@ function diffInteractionTraces(left, right) {
|
|
|
22538
23070
|
// ../runtime-core/src/sdk/runtime.ts
|
|
22539
23071
|
var requireForAuthRecipeHook = module$1.createRequire((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('index.cjs', document.baseURI).href)));
|
|
22540
23072
|
var MUTATION_CAPTURE_FINALIZE_TIMEOUT_MS = 5e3;
|
|
23073
|
+
var PENDING_OPERATION_EVENT_CAPTURE_LIMIT = 64;
|
|
23074
|
+
var PENDING_OPERATION_EVENT_CAPTURE_SKEW_MS = 1e3;
|
|
22541
23075
|
var OpensteerSessionRuntime = class {
|
|
22542
23076
|
workspace;
|
|
22543
23077
|
rootPath;
|
|
@@ -22550,6 +23084,9 @@ var OpensteerSessionRuntime = class {
|
|
|
22550
23084
|
registryOverrides;
|
|
22551
23085
|
cleanupRootOnClose;
|
|
22552
23086
|
sessionInfoBase;
|
|
23087
|
+
observationConfig;
|
|
23088
|
+
observationSessionId;
|
|
23089
|
+
injectedObservationSink;
|
|
22553
23090
|
root;
|
|
22554
23091
|
engine;
|
|
22555
23092
|
dom;
|
|
@@ -22559,6 +23096,9 @@ var OpensteerSessionRuntime = class {
|
|
|
22559
23096
|
sessionRef;
|
|
22560
23097
|
pageRef;
|
|
22561
23098
|
runId;
|
|
23099
|
+
observations;
|
|
23100
|
+
operationEventStorage = new async_hooks.AsyncLocalStorage();
|
|
23101
|
+
pendingOperationEventCaptures = [];
|
|
22562
23102
|
cookieJars = /* @__PURE__ */ new Map();
|
|
22563
23103
|
recipeCache = /* @__PURE__ */ new Map();
|
|
22564
23104
|
ownsEngine = false;
|
|
@@ -22566,7 +23106,7 @@ var OpensteerSessionRuntime = class {
|
|
|
22566
23106
|
this.workspace = normalizeNamespace2(options.name);
|
|
22567
23107
|
this.workspaceName = options.workspaceName?.trim() === void 0 || options.workspaceName?.trim().length === 0 ? void 0 : options.workspaceName.trim();
|
|
22568
23108
|
this.root = options.workspace;
|
|
22569
|
-
this.rootPath = options.workspace?.rootPath ?? options.rootPath ??
|
|
23109
|
+
this.rootPath = options.workspace?.rootPath ?? options.rootPath ?? path7__default.default.resolve(process.cwd(), ".opensteer", "temporary", crypto.randomUUID());
|
|
22570
23110
|
this.injectedEngine = options.engine;
|
|
22571
23111
|
this.engineFactory = options.engineFactory;
|
|
22572
23112
|
this.policy = options.policy ?? defaultPolicy();
|
|
@@ -22575,6 +23115,9 @@ var OpensteerSessionRuntime = class {
|
|
|
22575
23115
|
this.registryOverrides = options.registryOverrides;
|
|
22576
23116
|
this.cleanupRootOnClose = options.cleanupRootOnClose ?? options.workspace === void 0;
|
|
22577
23117
|
this.sessionInfoBase = options.sessionInfo ?? {};
|
|
23118
|
+
this.observationConfig = normalizeObservabilityConfig(options.observability);
|
|
23119
|
+
this.observationSessionId = options.observationSessionId;
|
|
23120
|
+
this.injectedObservationSink = options.observationSink;
|
|
22578
23121
|
if (this.injectedEngine === void 0 && this.engineFactory === void 0) {
|
|
22579
23122
|
throw new Error("OpensteerSessionRuntime requires an engine or engineFactory.");
|
|
22580
23123
|
}
|
|
@@ -22606,6 +23149,20 @@ var OpensteerSessionRuntime = class {
|
|
|
22606
23149
|
}
|
|
22607
23150
|
};
|
|
22608
23151
|
}
|
|
23152
|
+
async setObservabilityConfig(input) {
|
|
23153
|
+
this.observationConfig = normalizeObservabilityConfig(input);
|
|
23154
|
+
const observationSessionId = this.resolveObservationSessionId();
|
|
23155
|
+
if (observationSessionId === void 0) {
|
|
23156
|
+
return this.observationConfig;
|
|
23157
|
+
}
|
|
23158
|
+
const sink = this.injectedObservationSink ?? (await this.ensureRoot()).observations;
|
|
23159
|
+
this.observations = await sink.openSession({
|
|
23160
|
+
sessionId: observationSessionId,
|
|
23161
|
+
openedAt: Date.now(),
|
|
23162
|
+
config: this.observationConfig
|
|
23163
|
+
});
|
|
23164
|
+
return this.observationConfig;
|
|
23165
|
+
}
|
|
22609
23166
|
async open(input = {}, options = {}) {
|
|
22610
23167
|
assertValidSemanticOperationInput("session.open", input);
|
|
22611
23168
|
if (input.workspace !== void 0 && normalizeNamespace2(input.workspace) !== this.workspace) {
|
|
@@ -22704,6 +23261,10 @@ var OpensteerSessionRuntime = class {
|
|
|
22704
23261
|
return { pages: [] };
|
|
22705
23262
|
}
|
|
22706
23263
|
const startedAt = Date.now();
|
|
23264
|
+
const context = buildRuntimeTraceContext({
|
|
23265
|
+
sessionRef: this.sessionRef,
|
|
23266
|
+
pageRef: this.pageRef
|
|
23267
|
+
});
|
|
22707
23268
|
try {
|
|
22708
23269
|
const output = await this.runWithOperationTimeout(
|
|
22709
23270
|
"page.list",
|
|
@@ -22718,19 +23279,18 @@ var OpensteerSessionRuntime = class {
|
|
|
22718
23279
|
},
|
|
22719
23280
|
options
|
|
22720
23281
|
);
|
|
23282
|
+
const events = await this.drainPendingEngineEvents(context);
|
|
22721
23283
|
await this.appendTrace({
|
|
22722
23284
|
operation: "page.list",
|
|
22723
23285
|
startedAt,
|
|
22724
23286
|
completedAt: Date.now(),
|
|
22725
23287
|
outcome: "ok",
|
|
23288
|
+
...events === void 0 ? {} : { events },
|
|
22726
23289
|
data: {
|
|
22727
23290
|
count: output.pages.length,
|
|
22728
23291
|
...output.activePageRef === void 0 ? {} : { activePageRef: output.activePageRef }
|
|
22729
23292
|
},
|
|
22730
|
-
context
|
|
22731
|
-
sessionRef: this.sessionRef,
|
|
22732
|
-
pageRef: this.pageRef
|
|
22733
|
-
})
|
|
23293
|
+
context
|
|
22734
23294
|
});
|
|
22735
23295
|
return output;
|
|
22736
23296
|
} catch (error) {
|
|
@@ -22740,10 +23300,7 @@ var OpensteerSessionRuntime = class {
|
|
|
22740
23300
|
completedAt: Date.now(),
|
|
22741
23301
|
outcome: "error",
|
|
22742
23302
|
error,
|
|
22743
|
-
context
|
|
22744
|
-
sessionRef: this.sessionRef,
|
|
22745
|
-
pageRef: this.pageRef
|
|
22746
|
-
})
|
|
23303
|
+
context
|
|
22747
23304
|
});
|
|
22748
23305
|
throw error;
|
|
22749
23306
|
}
|
|
@@ -23131,22 +23688,25 @@ var OpensteerSessionRuntime = class {
|
|
|
23131
23688
|
},
|
|
23132
23689
|
options
|
|
23133
23690
|
);
|
|
23691
|
+
const context = buildRuntimeTraceContext({
|
|
23692
|
+
sessionRef: this.sessionRef,
|
|
23693
|
+
pageRef
|
|
23694
|
+
});
|
|
23695
|
+
const events = await this.drainPendingEngineEvents(context);
|
|
23134
23696
|
await this.appendTrace({
|
|
23135
23697
|
operation: "page.snapshot",
|
|
23136
23698
|
startedAt,
|
|
23137
23699
|
completedAt: Date.now(),
|
|
23138
23700
|
outcome: "ok",
|
|
23139
23701
|
artifacts,
|
|
23702
|
+
...events === void 0 ? {} : { events },
|
|
23140
23703
|
data: {
|
|
23141
23704
|
mode,
|
|
23142
23705
|
url: output.url,
|
|
23143
23706
|
title: output.title,
|
|
23144
23707
|
counterCount: output.counters.length
|
|
23145
23708
|
},
|
|
23146
|
-
context
|
|
23147
|
-
sessionRef: this.sessionRef,
|
|
23148
|
-
pageRef
|
|
23149
|
-
})
|
|
23709
|
+
context
|
|
23150
23710
|
});
|
|
23151
23711
|
return output;
|
|
23152
23712
|
} catch (error) {
|
|
@@ -26571,11 +27131,13 @@ var OpensteerSessionRuntime = class {
|
|
|
26571
27131
|
}
|
|
26572
27132
|
);
|
|
26573
27133
|
const output = toOpensteerActionResult(executed.result, preparedTarget.persistedDescription);
|
|
27134
|
+
const actionEvents = "events" in executed.result ? executed.result.events : void 0;
|
|
26574
27135
|
await this.appendTrace({
|
|
26575
27136
|
operation,
|
|
26576
27137
|
startedAt,
|
|
26577
27138
|
completedAt: Date.now(),
|
|
26578
27139
|
outcome: "ok",
|
|
27140
|
+
...actionEvents === void 0 ? {} : { events: actionEvents },
|
|
26579
27141
|
data: {
|
|
26580
27142
|
target: output.target,
|
|
26581
27143
|
...output.point === void 0 ? {} : { point: output.point },
|
|
@@ -28325,7 +28887,7 @@ var OpensteerSessionRuntime = class {
|
|
|
28325
28887
|
}
|
|
28326
28888
|
async executeAuthRecipeHook(step, variables) {
|
|
28327
28889
|
const resolved = requireForAuthRecipeHook.resolve(step.hook.specifier, {
|
|
28328
|
-
paths: [
|
|
28890
|
+
paths: [path7__default.default.dirname(this.rootPath)]
|
|
28329
28891
|
});
|
|
28330
28892
|
const module = await import(url.pathToFileURL(resolved).href);
|
|
28331
28893
|
const handler = module[step.hook.export];
|
|
@@ -28697,14 +29259,18 @@ var OpensteerSessionRuntime = class {
|
|
|
28697
29259
|
return this.engine;
|
|
28698
29260
|
}
|
|
28699
29261
|
if (this.injectedEngine) {
|
|
28700
|
-
this.engine = this.
|
|
29262
|
+
this.engine = this.wrapEngineWithObservationCapture(
|
|
29263
|
+
this.injectedEngine
|
|
29264
|
+
);
|
|
28701
29265
|
this.ownsEngine = false;
|
|
28702
29266
|
return this.engine;
|
|
28703
29267
|
}
|
|
28704
29268
|
if (this.engineFactory === void 0) {
|
|
28705
29269
|
throw new Error("Opensteer engine factory is not initialized");
|
|
28706
29270
|
}
|
|
28707
|
-
this.engine =
|
|
29271
|
+
this.engine = this.wrapEngineWithObservationCapture(
|
|
29272
|
+
await this.engineFactory(overrides)
|
|
29273
|
+
);
|
|
28708
29274
|
this.ownsEngine = true;
|
|
28709
29275
|
return this.engine;
|
|
28710
29276
|
}
|
|
@@ -28904,6 +29470,15 @@ var OpensteerSessionRuntime = class {
|
|
|
28904
29470
|
return;
|
|
28905
29471
|
}
|
|
28906
29472
|
const root = await this.ensureRoot();
|
|
29473
|
+
const capturedStepEvents = input.events ?? this.consumePendingOperationEventCapture(
|
|
29474
|
+
input.operation,
|
|
29475
|
+
input.startedAt,
|
|
29476
|
+
input.completedAt
|
|
29477
|
+
);
|
|
29478
|
+
const drainedStepEvents = input.events === void 0 ? await this.drainPendingEngineEvents(input.context) : void 0;
|
|
29479
|
+
const stepEvents = mergeObservedStepEvents(capturedStepEvents, drainedStepEvents);
|
|
29480
|
+
const normalizedData = input.data === void 0 ? void 0 : toCanonicalJsonValue(input.data);
|
|
29481
|
+
const normalizedError = input.error === void 0 ? void 0 : normalizeOpensteerError(input.error);
|
|
28907
29482
|
const artifacts = input.artifacts === void 0 ? void 0 : await Promise.all(
|
|
28908
29483
|
input.artifacts.manifests.map(async (manifest) => {
|
|
28909
29484
|
const reference = await root.artifacts.toProtocolArtifactReference(
|
|
@@ -28916,19 +29491,56 @@ var OpensteerSessionRuntime = class {
|
|
|
28916
29491
|
return reference;
|
|
28917
29492
|
})
|
|
28918
29493
|
);
|
|
28919
|
-
await root.traces.append(runId, {
|
|
29494
|
+
const traceEntry = await root.traces.append(runId, {
|
|
28920
29495
|
operation: input.operation,
|
|
28921
29496
|
outcome: input.outcome,
|
|
28922
29497
|
startedAt: input.startedAt,
|
|
28923
29498
|
completedAt: input.completedAt,
|
|
28924
29499
|
...input.context === void 0 ? {} : { context: input.context },
|
|
28925
|
-
...
|
|
29500
|
+
...stepEvents === void 0 ? {} : { events: stepEvents },
|
|
28926
29501
|
...artifacts === void 0 ? {} : { artifacts },
|
|
28927
|
-
...
|
|
28928
|
-
...
|
|
28929
|
-
error:
|
|
29502
|
+
...normalizedData === void 0 ? {} : { data: normalizedData },
|
|
29503
|
+
...normalizedError === void 0 ? {} : {
|
|
29504
|
+
error: normalizedError
|
|
28930
29505
|
}
|
|
28931
29506
|
});
|
|
29507
|
+
const observationSession = await this.ensureObservationSession().catch(() => void 0);
|
|
29508
|
+
if (observationSession === void 0 || this.observationConfig.profile === "off") {
|
|
29509
|
+
return;
|
|
29510
|
+
}
|
|
29511
|
+
const observationArtifactIds = input.artifacts === void 0 ? void 0 : (await Promise.allSettled(
|
|
29512
|
+
input.artifacts.manifests.map(async (manifest) => {
|
|
29513
|
+
const artifact = await observationSession.writeArtifact({
|
|
29514
|
+
artifactId: manifest.artifactId,
|
|
29515
|
+
kind: observationArtifactKindFromManifest(manifest.kind),
|
|
29516
|
+
createdAt: manifest.createdAt,
|
|
29517
|
+
context: manifest.scope,
|
|
29518
|
+
mediaType: manifest.mediaType,
|
|
29519
|
+
byteLength: manifest.byteLength,
|
|
29520
|
+
sha256: manifest.sha256,
|
|
29521
|
+
opensteerArtifactId: manifest.artifactId,
|
|
29522
|
+
storageKey: manifestToExternalBinaryLocation(root.rootPath, manifest).uri
|
|
29523
|
+
});
|
|
29524
|
+
return artifact.artifactId;
|
|
29525
|
+
})
|
|
29526
|
+
)).flatMap((result) => result.status === "fulfilled" ? [result.value] : []);
|
|
29527
|
+
const observationEvents = buildObservationEventsFromTrace({
|
|
29528
|
+
traceId: traceEntry.traceId,
|
|
29529
|
+
stepId: traceEntry.stepId,
|
|
29530
|
+
operation: input.operation,
|
|
29531
|
+
outcome: input.outcome,
|
|
29532
|
+
startedAt: input.startedAt,
|
|
29533
|
+
completedAt: input.completedAt,
|
|
29534
|
+
...input.context === void 0 ? {} : { context: input.context },
|
|
29535
|
+
...stepEvents === void 0 ? {} : { events: stepEvents },
|
|
29536
|
+
...normalizedData === void 0 ? {} : { data: normalizedData },
|
|
29537
|
+
...normalizedError === void 0 ? {} : { error: normalizedError },
|
|
29538
|
+
...observationArtifactIds === void 0 ? {} : { artifactIds: observationArtifactIds },
|
|
29539
|
+
profile: this.observationConfig.profile
|
|
29540
|
+
});
|
|
29541
|
+
if (observationEvents.length > 0) {
|
|
29542
|
+
await observationSession.appendBatch(observationEvents).catch(() => void 0);
|
|
29543
|
+
}
|
|
28932
29544
|
}
|
|
28933
29545
|
async cleanupSessionResources(engine, pageRef, sessionRef) {
|
|
28934
29546
|
if (pageRef !== void 0) {
|
|
@@ -28940,6 +29552,7 @@ var OpensteerSessionRuntime = class {
|
|
|
28940
29552
|
}
|
|
28941
29553
|
async resetRuntimeState(options) {
|
|
28942
29554
|
const engine = this.engine;
|
|
29555
|
+
const observations = this.observations;
|
|
28943
29556
|
this.networkHistory.clear();
|
|
28944
29557
|
this.sessionRef = void 0;
|
|
28945
29558
|
this.pageRef = void 0;
|
|
@@ -28948,20 +29561,140 @@ var OpensteerSessionRuntime = class {
|
|
|
28948
29561
|
this.computer = void 0;
|
|
28949
29562
|
this.extractionDescriptors = void 0;
|
|
28950
29563
|
this.engine = void 0;
|
|
29564
|
+
this.observations = void 0;
|
|
29565
|
+
this.pendingOperationEventCaptures.length = 0;
|
|
29566
|
+
await observations?.close("runtime_reset").catch(() => void 0);
|
|
28951
29567
|
if (options.disposeEngine && this.ownsEngine && engine?.dispose) {
|
|
28952
29568
|
await engine.dispose();
|
|
28953
29569
|
}
|
|
28954
29570
|
this.ownsEngine = false;
|
|
28955
29571
|
}
|
|
29572
|
+
async ensureObservationSession() {
|
|
29573
|
+
if (this.observationConfig.profile === "off") {
|
|
29574
|
+
return void 0;
|
|
29575
|
+
}
|
|
29576
|
+
if (this.observations !== void 0) {
|
|
29577
|
+
return this.observations;
|
|
29578
|
+
}
|
|
29579
|
+
const observationSessionId = this.resolveObservationSessionId();
|
|
29580
|
+
if (observationSessionId === void 0) {
|
|
29581
|
+
return void 0;
|
|
29582
|
+
}
|
|
29583
|
+
const sink = this.injectedObservationSink ?? (await this.ensureRoot()).observations;
|
|
29584
|
+
this.observations = await sink.openSession({
|
|
29585
|
+
sessionId: observationSessionId,
|
|
29586
|
+
openedAt: Date.now(),
|
|
29587
|
+
config: this.observationConfig
|
|
29588
|
+
});
|
|
29589
|
+
return this.observations;
|
|
29590
|
+
}
|
|
29591
|
+
resolveObservationSessionId() {
|
|
29592
|
+
return this.observationSessionId ?? this.sessionRef;
|
|
29593
|
+
}
|
|
28956
29594
|
runWithOperationTimeout(operation, callback, options = {}) {
|
|
28957
|
-
|
|
28958
|
-
|
|
28959
|
-
|
|
28960
|
-
|
|
28961
|
-
|
|
28962
|
-
|
|
28963
|
-
|
|
28964
|
-
|
|
29595
|
+
const existingCollector = this.operationEventStorage.getStore();
|
|
29596
|
+
if (existingCollector !== void 0) {
|
|
29597
|
+
return runWithPolicyTimeout(
|
|
29598
|
+
this.policy.timeout,
|
|
29599
|
+
{
|
|
29600
|
+
operation,
|
|
29601
|
+
...options.signal === void 0 ? {} : { signal: options.signal }
|
|
29602
|
+
},
|
|
29603
|
+
callback
|
|
29604
|
+
);
|
|
29605
|
+
}
|
|
29606
|
+
const collector = [];
|
|
29607
|
+
const startedAt = Date.now();
|
|
29608
|
+
return this.operationEventStorage.run(collector, async () => {
|
|
29609
|
+
try {
|
|
29610
|
+
return await runWithPolicyTimeout(
|
|
29611
|
+
this.policy.timeout,
|
|
29612
|
+
{
|
|
29613
|
+
operation,
|
|
29614
|
+
...options.signal === void 0 ? {} : { signal: options.signal }
|
|
29615
|
+
},
|
|
29616
|
+
callback
|
|
29617
|
+
);
|
|
29618
|
+
} finally {
|
|
29619
|
+
this.recordPendingOperationEventCapture({
|
|
29620
|
+
operation,
|
|
29621
|
+
startedAt,
|
|
29622
|
+
completedAt: Date.now(),
|
|
29623
|
+
events: collector
|
|
29624
|
+
});
|
|
29625
|
+
}
|
|
29626
|
+
});
|
|
29627
|
+
}
|
|
29628
|
+
wrapEngineWithObservationCapture(engine) {
|
|
29629
|
+
return new Proxy(engine, {
|
|
29630
|
+
get: (target, property, receiver) => {
|
|
29631
|
+
const value = Reflect.get(target, property, receiver);
|
|
29632
|
+
if (typeof value !== "function") {
|
|
29633
|
+
return value;
|
|
29634
|
+
}
|
|
29635
|
+
return (...args) => {
|
|
29636
|
+
const result = Reflect.apply(value, target, args);
|
|
29637
|
+
if (!(result instanceof Promise)) {
|
|
29638
|
+
return result;
|
|
29639
|
+
}
|
|
29640
|
+
return result.then((resolved) => {
|
|
29641
|
+
this.captureObservedStepEvents(resolved);
|
|
29642
|
+
return resolved;
|
|
29643
|
+
});
|
|
29644
|
+
};
|
|
29645
|
+
}
|
|
29646
|
+
});
|
|
29647
|
+
}
|
|
29648
|
+
captureObservedStepEvents(value) {
|
|
29649
|
+
const collector = this.operationEventStorage.getStore();
|
|
29650
|
+
if (collector === void 0) {
|
|
29651
|
+
return;
|
|
29652
|
+
}
|
|
29653
|
+
const events = readStepResultEvents(value);
|
|
29654
|
+
if (events === void 0 || events.length === 0) {
|
|
29655
|
+
return;
|
|
29656
|
+
}
|
|
29657
|
+
collector.push(...events);
|
|
29658
|
+
}
|
|
29659
|
+
recordPendingOperationEventCapture(capture) {
|
|
29660
|
+
if (capture.events.length === 0) {
|
|
29661
|
+
return;
|
|
29662
|
+
}
|
|
29663
|
+
this.pendingOperationEventCaptures.push({
|
|
29664
|
+
...capture,
|
|
29665
|
+
events: [...capture.events]
|
|
29666
|
+
});
|
|
29667
|
+
if (this.pendingOperationEventCaptures.length > PENDING_OPERATION_EVENT_CAPTURE_LIMIT) {
|
|
29668
|
+
this.pendingOperationEventCaptures.splice(
|
|
29669
|
+
0,
|
|
29670
|
+
this.pendingOperationEventCaptures.length - PENDING_OPERATION_EVENT_CAPTURE_LIMIT
|
|
29671
|
+
);
|
|
29672
|
+
}
|
|
29673
|
+
}
|
|
29674
|
+
consumePendingOperationEventCapture(operation, startedAt, completedAt) {
|
|
29675
|
+
for (let index = this.pendingOperationEventCaptures.length - 1; index >= 0; index -= 1) {
|
|
29676
|
+
const capture = this.pendingOperationEventCaptures[index];
|
|
29677
|
+
if (capture === void 0) {
|
|
29678
|
+
continue;
|
|
29679
|
+
}
|
|
29680
|
+
if (capture.operation !== operation) {
|
|
29681
|
+
continue;
|
|
29682
|
+
}
|
|
29683
|
+
if (capture.startedAt < startedAt - PENDING_OPERATION_EVENT_CAPTURE_SKEW_MS || capture.completedAt > completedAt + PENDING_OPERATION_EVENT_CAPTURE_SKEW_MS) {
|
|
29684
|
+
continue;
|
|
29685
|
+
}
|
|
29686
|
+
this.pendingOperationEventCaptures.splice(index, 1);
|
|
29687
|
+
return capture.events;
|
|
29688
|
+
}
|
|
29689
|
+
return void 0;
|
|
29690
|
+
}
|
|
29691
|
+
async drainPendingEngineEvents(context) {
|
|
29692
|
+
const pageRef = context?.pageRef ?? this.pageRef;
|
|
29693
|
+
if (pageRef === void 0 || this.engine === void 0) {
|
|
29694
|
+
return void 0;
|
|
29695
|
+
}
|
|
29696
|
+
const events = await this.engine.drainEvents({ pageRef }).catch(() => []);
|
|
29697
|
+
return events.length > 0 ? events : void 0;
|
|
28965
29698
|
}
|
|
28966
29699
|
async navigatePage(input, timeout) {
|
|
28967
29700
|
const remainingMs = timeout.remainingMs();
|
|
@@ -28997,6 +29730,34 @@ function buildRuntimeTraceContext(input) {
|
|
|
28997
29730
|
function buildArtifactScope(input) {
|
|
28998
29731
|
return buildRuntimeTraceContext(input);
|
|
28999
29732
|
}
|
|
29733
|
+
function readStepResultEvents(value) {
|
|
29734
|
+
if (value === null || typeof value !== "object") {
|
|
29735
|
+
return void 0;
|
|
29736
|
+
}
|
|
29737
|
+
if (!("events" in value)) {
|
|
29738
|
+
return void 0;
|
|
29739
|
+
}
|
|
29740
|
+
const events = value.events;
|
|
29741
|
+
return Array.isArray(events) ? events : void 0;
|
|
29742
|
+
}
|
|
29743
|
+
function mergeObservedStepEvents(primary, secondary) {
|
|
29744
|
+
if (primary === void 0 || primary.length === 0) {
|
|
29745
|
+
return secondary === void 0 || secondary.length === 0 ? void 0 : secondary;
|
|
29746
|
+
}
|
|
29747
|
+
if (secondary === void 0 || secondary.length === 0) {
|
|
29748
|
+
return primary;
|
|
29749
|
+
}
|
|
29750
|
+
const merged = /* @__PURE__ */ new Map();
|
|
29751
|
+
for (const event of primary) {
|
|
29752
|
+
merged.set(event.eventId, event);
|
|
29753
|
+
}
|
|
29754
|
+
for (const event of secondary) {
|
|
29755
|
+
merged.set(event.eventId, event);
|
|
29756
|
+
}
|
|
29757
|
+
return [...merged.values()].sort(
|
|
29758
|
+
(left, right) => (left.timestamp ?? 0) - (right.timestamp ?? 0)
|
|
29759
|
+
);
|
|
29760
|
+
}
|
|
29000
29761
|
function selectLiveQueryPageRef(input, currentPageRef) {
|
|
29001
29762
|
if (input.pageRef !== void 0) {
|
|
29002
29763
|
return input.pageRef;
|
|
@@ -29959,12 +30720,12 @@ function extractReverseRuntimeValue(value, pointer) {
|
|
|
29959
30720
|
}
|
|
29960
30721
|
return readDotPath(value, pointer);
|
|
29961
30722
|
}
|
|
29962
|
-
function readDotPath(value,
|
|
29963
|
-
if (
|
|
30723
|
+
function readDotPath(value, path15) {
|
|
30724
|
+
if (path15.length === 0) {
|
|
29964
30725
|
return value;
|
|
29965
30726
|
}
|
|
29966
30727
|
let current = value;
|
|
29967
|
-
for (const segment of
|
|
30728
|
+
for (const segment of path15.split(".").filter((entry) => entry.length > 0)) {
|
|
29968
30729
|
if (current === null || current === void 0) {
|
|
29969
30730
|
return void 0;
|
|
29970
30731
|
}
|
|
@@ -30333,7 +31094,7 @@ function normalizeRuntimeErrorMessage(error) {
|
|
|
30333
31094
|
return error instanceof Error ? error.message : String(error);
|
|
30334
31095
|
}
|
|
30335
31096
|
function runtimeDelay(ms) {
|
|
30336
|
-
return new Promise((
|
|
31097
|
+
return new Promise((resolve4) => setTimeout(resolve4, ms));
|
|
30337
31098
|
}
|
|
30338
31099
|
function applyBrowserCookiesToTransportRequest(request, cookies) {
|
|
30339
31100
|
if (cookies.length === 0) {
|
|
@@ -30437,7 +31198,7 @@ function parseSetCookieHeader(value, requestUrl) {
|
|
|
30437
31198
|
}
|
|
30438
31199
|
const url = new URL(requestUrl);
|
|
30439
31200
|
let domain = url.hostname;
|
|
30440
|
-
let
|
|
31201
|
+
let path15 = defaultCookiePath(url.pathname);
|
|
30441
31202
|
let secure = url.protocol === "https:";
|
|
30442
31203
|
let expiresAt;
|
|
30443
31204
|
const cookieValue = rawValueParts.join("=").trim();
|
|
@@ -30450,7 +31211,7 @@ function parseSetCookieHeader(value, requestUrl) {
|
|
|
30450
31211
|
continue;
|
|
30451
31212
|
}
|
|
30452
31213
|
if (key === "path" && attributeValue.length > 0) {
|
|
30453
|
-
|
|
31214
|
+
path15 = attributeValue;
|
|
30454
31215
|
continue;
|
|
30455
31216
|
}
|
|
30456
31217
|
if (key === "secure") {
|
|
@@ -30476,7 +31237,7 @@ function parseSetCookieHeader(value, requestUrl) {
|
|
|
30476
31237
|
name,
|
|
30477
31238
|
value: cookieValue,
|
|
30478
31239
|
domain,
|
|
30479
|
-
path:
|
|
31240
|
+
path: path15,
|
|
30480
31241
|
secure,
|
|
30481
31242
|
...expiresAt === void 0 ? {} : { expiresAt }
|
|
30482
31243
|
}
|
|
@@ -31428,7 +32189,7 @@ async function pollUntilResult(timeout, producer) {
|
|
|
31428
32189
|
if (produced !== void 0) {
|
|
31429
32190
|
return produced;
|
|
31430
32191
|
}
|
|
31431
|
-
await new Promise((
|
|
32192
|
+
await new Promise((resolve4) => setTimeout(resolve4, 100));
|
|
31432
32193
|
}
|
|
31433
32194
|
}
|
|
31434
32195
|
async function getMainFrame(engine, pageRef) {
|
|
@@ -31486,6 +32247,133 @@ function toOpensteerResolvedTarget2(target) {
|
|
|
31486
32247
|
function normalizeOpensteerError(error) {
|
|
31487
32248
|
return normalizeThrownOpensteerError(error, "Unknown Opensteer runtime failure");
|
|
31488
32249
|
}
|
|
32250
|
+
function observationArtifactKindFromManifest(kind) {
|
|
32251
|
+
switch (kind) {
|
|
32252
|
+
case "screenshot":
|
|
32253
|
+
return "screenshot";
|
|
32254
|
+
case "dom-snapshot":
|
|
32255
|
+
return "dom-snapshot";
|
|
32256
|
+
case "html-snapshot":
|
|
32257
|
+
return "html-snapshot";
|
|
32258
|
+
default:
|
|
32259
|
+
return "other";
|
|
32260
|
+
}
|
|
32261
|
+
}
|
|
32262
|
+
function buildObservationEventsFromTrace(input) {
|
|
32263
|
+
const context = normalizeObservationContext(input.context);
|
|
32264
|
+
const baseCorrelationId = input.traceId;
|
|
32265
|
+
const startedEvent = {
|
|
32266
|
+
kind: input.operation === "session.open" || input.operation === "session.close" ? "session" : "operation",
|
|
32267
|
+
phase: "started",
|
|
32268
|
+
createdAt: input.startedAt,
|
|
32269
|
+
correlationId: baseCorrelationId,
|
|
32270
|
+
spanId: input.stepId,
|
|
32271
|
+
...context === void 0 ? {} : { context },
|
|
32272
|
+
data: {
|
|
32273
|
+
operation: input.operation
|
|
32274
|
+
}
|
|
32275
|
+
};
|
|
32276
|
+
const stepEvents = (input.events ?? []).filter((event) => shouldCaptureObservationStepEvent(event, input.profile)).map((event) => {
|
|
32277
|
+
const eventContext = buildObservationContextFromEvent(event);
|
|
32278
|
+
return {
|
|
32279
|
+
kind: observationKindForStepEvent(event),
|
|
32280
|
+
phase: "occurred",
|
|
32281
|
+
createdAt: event.timestamp,
|
|
32282
|
+
correlationId: baseCorrelationId,
|
|
32283
|
+
parentSpanId: input.stepId,
|
|
32284
|
+
...eventContext === void 0 ? {} : { context: eventContext },
|
|
32285
|
+
data: stripObservationStepEvent(event),
|
|
32286
|
+
...event.kind === "page-error" ? {
|
|
32287
|
+
error: {
|
|
32288
|
+
message: event.message,
|
|
32289
|
+
...event.stack === void 0 ? {} : { details: { stack: event.stack } }
|
|
32290
|
+
}
|
|
32291
|
+
} : {}
|
|
32292
|
+
};
|
|
32293
|
+
});
|
|
32294
|
+
const completedEvent = {
|
|
32295
|
+
kind: input.operation === "session.open" || input.operation === "session.close" ? "session" : "operation",
|
|
32296
|
+
phase: input.outcome === "ok" ? "completed" : "failed",
|
|
32297
|
+
createdAt: input.completedAt,
|
|
32298
|
+
correlationId: baseCorrelationId,
|
|
32299
|
+
spanId: input.stepId,
|
|
32300
|
+
...context === void 0 ? {} : { context },
|
|
32301
|
+
data: {
|
|
32302
|
+
operation: input.operation,
|
|
32303
|
+
startedAt: input.startedAt,
|
|
32304
|
+
completedAt: input.completedAt,
|
|
32305
|
+
durationMs: input.completedAt - input.startedAt,
|
|
32306
|
+
...input.data === void 0 ? {} : { output: input.data }
|
|
32307
|
+
},
|
|
32308
|
+
...input.error === void 0 ? {} : {
|
|
32309
|
+
error: {
|
|
32310
|
+
...input.error.code === void 0 ? {} : { code: input.error.code },
|
|
32311
|
+
message: input.error.message,
|
|
32312
|
+
...input.error.retriable === void 0 ? {} : { retriable: input.error.retriable },
|
|
32313
|
+
...input.error.details === void 0 ? {} : { details: toCanonicalJsonValue(input.error.details) }
|
|
32314
|
+
}
|
|
32315
|
+
},
|
|
32316
|
+
...input.artifactIds === void 0 || input.artifactIds.length === 0 ? {} : { artifactIds: input.artifactIds }
|
|
32317
|
+
};
|
|
32318
|
+
return [startedEvent, ...stepEvents, completedEvent];
|
|
32319
|
+
}
|
|
32320
|
+
function buildObservationContextFromEvent(event) {
|
|
32321
|
+
return normalizeObservationContext({
|
|
32322
|
+
sessionRef: event.sessionRef,
|
|
32323
|
+
...event.pageRef === void 0 ? {} : { pageRef: event.pageRef },
|
|
32324
|
+
...event.frameRef === void 0 ? {} : { frameRef: event.frameRef },
|
|
32325
|
+
...event.documentRef === void 0 ? {} : { documentRef: event.documentRef },
|
|
32326
|
+
...event.documentEpoch === void 0 ? {} : { documentEpoch: event.documentEpoch }
|
|
32327
|
+
});
|
|
32328
|
+
}
|
|
32329
|
+
function shouldCaptureObservationStepEvent(event, profile) {
|
|
32330
|
+
if (profile === "diagnostic") {
|
|
32331
|
+
return true;
|
|
32332
|
+
}
|
|
32333
|
+
switch (event.kind) {
|
|
32334
|
+
case "page-created":
|
|
32335
|
+
case "popup-opened":
|
|
32336
|
+
case "page-closed":
|
|
32337
|
+
case "page-error":
|
|
32338
|
+
return true;
|
|
32339
|
+
case "console":
|
|
32340
|
+
return event.level === "warn" || event.level === "error";
|
|
32341
|
+
default:
|
|
32342
|
+
return false;
|
|
32343
|
+
}
|
|
32344
|
+
}
|
|
32345
|
+
function observationKindForStepEvent(event) {
|
|
32346
|
+
switch (event.kind) {
|
|
32347
|
+
case "console":
|
|
32348
|
+
return "console";
|
|
32349
|
+
case "page-error":
|
|
32350
|
+
return "error";
|
|
32351
|
+
case "paused":
|
|
32352
|
+
case "resumed":
|
|
32353
|
+
case "frozen":
|
|
32354
|
+
return "runtime";
|
|
32355
|
+
default:
|
|
32356
|
+
return "page";
|
|
32357
|
+
}
|
|
32358
|
+
}
|
|
32359
|
+
function stripObservationStepEvent(event) {
|
|
32360
|
+
const {
|
|
32361
|
+
eventId: _eventId,
|
|
32362
|
+
kind,
|
|
32363
|
+
timestamp,
|
|
32364
|
+
sessionRef: _sessionRef,
|
|
32365
|
+
pageRef: _pageRef,
|
|
32366
|
+
frameRef: _frameRef,
|
|
32367
|
+
documentRef: _documentRef,
|
|
32368
|
+
documentEpoch: _documentEpoch,
|
|
32369
|
+
...rest
|
|
32370
|
+
} = event;
|
|
32371
|
+
return toCanonicalJsonValue({
|
|
32372
|
+
eventKind: kind,
|
|
32373
|
+
timestamp,
|
|
32374
|
+
...rest
|
|
32375
|
+
});
|
|
32376
|
+
}
|
|
31489
32377
|
function buildMutationCaptureTraceData(diagnostics) {
|
|
31490
32378
|
if (diagnostics?.finalizeError === void 0) {
|
|
31491
32379
|
return {};
|
|
@@ -31535,8 +32423,8 @@ function screenshotMediaType(format2) {
|
|
|
31535
32423
|
var OpensteerRuntime = class extends OpensteerSessionRuntime {
|
|
31536
32424
|
constructor(options = {}) {
|
|
31537
32425
|
const publicWorkspace = normalizeWorkspace2(options.workspace);
|
|
31538
|
-
const rootPath = options.rootPath ?? (publicWorkspace === void 0 ?
|
|
31539
|
-
rootDir:
|
|
32426
|
+
const rootPath = options.rootPath ?? (publicWorkspace === void 0 ? path7__default.default.resolve(options.rootDir ?? process.cwd(), ".opensteer", "temporary", crypto.randomUUID()) : resolveFilesystemWorkspacePath({
|
|
32427
|
+
rootDir: path7__default.default.resolve(options.rootDir ?? process.cwd()),
|
|
31540
32428
|
workspace: publicWorkspace
|
|
31541
32429
|
}));
|
|
31542
32430
|
const cleanupRootOnClose = options.cleanupRootOnClose ?? publicWorkspace === void 0;
|
|
@@ -31561,14 +32449,17 @@ var OpensteerRuntime = class extends OpensteerSessionRuntime {
|
|
|
31561
32449
|
...options.descriptorStore === void 0 ? {} : { descriptorStore: options.descriptorStore },
|
|
31562
32450
|
...options.extractionDescriptorStore === void 0 ? {} : { extractionDescriptorStore: options.extractionDescriptorStore },
|
|
31563
32451
|
...options.registryOverrides === void 0 ? {} : { registryOverrides: options.registryOverrides },
|
|
31564
|
-
cleanupRootOnClose
|
|
32452
|
+
cleanupRootOnClose,
|
|
32453
|
+
...options.observability === void 0 ? {} : { observability: options.observability },
|
|
32454
|
+
...options.observationSessionId === void 0 ? {} : { observationSessionId: options.observationSessionId },
|
|
32455
|
+
...options.observationSink === void 0 ? {} : { observationSink: options.observationSink }
|
|
31565
32456
|
})
|
|
31566
32457
|
);
|
|
31567
32458
|
}
|
|
31568
32459
|
};
|
|
31569
32460
|
var OpensteerSessionRuntime2 = class extends OpensteerSessionRuntime {
|
|
31570
32461
|
constructor(options) {
|
|
31571
|
-
const rootPath = options.rootPath ??
|
|
32462
|
+
const rootPath = options.rootPath ?? path7__default.default.resolve(options.rootDir ?? process.cwd());
|
|
31572
32463
|
const cleanupRootOnClose = options.cleanupRootOnClose ?? false;
|
|
31573
32464
|
const engineName = options.engineName ?? DEFAULT_OPENSTEER_ENGINE;
|
|
31574
32465
|
assertSupportedEngineOptions({
|
|
@@ -31590,7 +32481,10 @@ var OpensteerSessionRuntime2 = class extends OpensteerSessionRuntime {
|
|
|
31590
32481
|
...options.descriptorStore === void 0 ? {} : { descriptorStore: options.descriptorStore },
|
|
31591
32482
|
...options.extractionDescriptorStore === void 0 ? {} : { extractionDescriptorStore: options.extractionDescriptorStore },
|
|
31592
32483
|
...options.registryOverrides === void 0 ? {} : { registryOverrides: options.registryOverrides },
|
|
31593
|
-
cleanupRootOnClose
|
|
32484
|
+
cleanupRootOnClose,
|
|
32485
|
+
...options.observability === void 0 ? {} : { observability: options.observability },
|
|
32486
|
+
...options.observationSessionId === void 0 ? {} : { observationSessionId: options.observationSessionId },
|
|
32487
|
+
...options.observationSink === void 0 ? {} : { observationSink: options.observationSink }
|
|
31594
32488
|
})
|
|
31595
32489
|
);
|
|
31596
32490
|
}
|
|
@@ -31616,6 +32510,9 @@ function buildSharedRuntimeOptions(input) {
|
|
|
31616
32510
|
...input.extractionDescriptorStore === void 0 ? {} : { extractionDescriptorStore: input.extractionDescriptorStore },
|
|
31617
32511
|
...input.registryOverrides === void 0 ? {} : { registryOverrides: input.registryOverrides },
|
|
31618
32512
|
cleanupRootOnClose: input.cleanupRootOnClose,
|
|
32513
|
+
...input.observability === void 0 ? {} : { observability: input.observability },
|
|
32514
|
+
...input.observationSessionId === void 0 ? {} : { observationSessionId: input.observationSessionId },
|
|
32515
|
+
...input.observationSink === void 0 ? {} : { observationSink: input.observationSink },
|
|
31619
32516
|
sessionInfo: {
|
|
31620
32517
|
provider: {
|
|
31621
32518
|
mode: "local",
|
|
@@ -31678,345 +32575,267 @@ function resolveOpensteerProvider(input = {}) {
|
|
|
31678
32575
|
};
|
|
31679
32576
|
}
|
|
31680
32577
|
var execFile2 = util.promisify(child_process.execFile);
|
|
31681
|
-
var
|
|
31682
|
-
var
|
|
31683
|
-
var
|
|
31684
|
-
|
|
31685
|
-
async function resolveCookieCaptureStrategy(input = {}) {
|
|
31686
|
-
const timeoutMs = input.timeoutMs ?? DEFAULT_CAPTURE_TIMEOUT_MS;
|
|
31687
|
-
if (input.attachEndpoint !== void 0) {
|
|
31688
|
-
if (input.strategy !== void 0 && input.strategy !== "attach") {
|
|
31689
|
-
throw new Error(
|
|
31690
|
-
`Strategy "${input.strategy}" is incompatible with an explicit attach endpoint.`
|
|
31691
|
-
);
|
|
31692
|
-
}
|
|
31693
|
-
return {
|
|
31694
|
-
strategy: "attach",
|
|
31695
|
-
attachEndpoint: input.attachEndpoint,
|
|
31696
|
-
...input.profileDirectory === void 0 ? {} : { profileDirectory: input.profileDirectory },
|
|
31697
|
-
timeoutMs
|
|
31698
|
-
};
|
|
31699
|
-
}
|
|
32578
|
+
var NODE_SQLITE_SPECIFIER2 = `node:${"sqlite"}`;
|
|
32579
|
+
var CHROME_EPOCH_OFFSET = 11644473600000000n;
|
|
32580
|
+
var CHROME_HMAC_PREFIX_LENGTH = 32;
|
|
32581
|
+
async function readBrowserCookies(input = {}) {
|
|
31700
32582
|
const brand2 = resolveRequestedBrand(input);
|
|
31701
|
-
const executablePath = resolveBrandExecutablePath(brand2, input.executablePath);
|
|
31702
32583
|
const userDataDir = resolveBrandUserDataDir(brand2, input.userDataDir);
|
|
31703
|
-
const profileDirectory = input.profileDirectory;
|
|
31704
|
-
const
|
|
31705
|
-
|
|
31706
|
-
const autoStrategy = attachEndpoint !== void 0 ? "attach" : runningProcess !== null ? "managed-relaunch" : "headless";
|
|
31707
|
-
const strategy = input.strategy ?? autoStrategy;
|
|
31708
|
-
validateRequestedStrategy({
|
|
31709
|
-
strategy,
|
|
31710
|
-
brand: brand2,
|
|
31711
|
-
...attachEndpoint === void 0 ? {} : { attachEndpoint },
|
|
31712
|
-
...runningProcess?.pid === void 0 ? {} : { runningPid: runningProcess.pid }
|
|
31713
|
-
});
|
|
31714
|
-
return {
|
|
31715
|
-
strategy,
|
|
31716
|
-
brandId: brand2.id,
|
|
31717
|
-
brandDisplayName: brand2.displayName,
|
|
31718
|
-
executablePath,
|
|
31719
|
-
userDataDir,
|
|
31720
|
-
...profileDirectory === void 0 ? {} : { profileDirectory },
|
|
31721
|
-
...attachEndpoint === void 0 ? {} : { attachEndpoint },
|
|
31722
|
-
...runningProcess === null ? {} : { runningPid: runningProcess.pid },
|
|
31723
|
-
timeoutMs
|
|
31724
|
-
};
|
|
31725
|
-
}
|
|
31726
|
-
async function acquireCdpEndpoint(resolved) {
|
|
31727
|
-
if (resolved.strategy === "attach") {
|
|
31728
|
-
if (!resolved.attachEndpoint) {
|
|
31729
|
-
throw new Error("Attach capture requires a debuggable browser endpoint.");
|
|
31730
|
-
}
|
|
31731
|
-
const inspected = await inspectCdpEndpoint({
|
|
31732
|
-
endpoint: resolved.attachEndpoint,
|
|
31733
|
-
timeoutMs: Math.min(2e3, resolved.timeoutMs)
|
|
31734
|
-
});
|
|
31735
|
-
return {
|
|
31736
|
-
strategy: "attach",
|
|
31737
|
-
cdpEndpoint: inspected.endpoint,
|
|
31738
|
-
...resolved.brandId === void 0 ? {} : { brandId: resolved.brandId },
|
|
31739
|
-
...resolved.brandDisplayName === void 0 ? {} : { brandDisplayName: resolved.brandDisplayName },
|
|
31740
|
-
...resolved.userDataDir === void 0 ? {} : { userDataDir: resolved.userDataDir },
|
|
31741
|
-
...resolved.profileDirectory === void 0 ? {} : { profileDirectory: resolved.profileDirectory },
|
|
31742
|
-
cleanup: async () => void 0
|
|
31743
|
-
};
|
|
31744
|
-
}
|
|
31745
|
-
if (!resolved.brandId || !resolved.brandDisplayName || !resolved.executablePath || !resolved.userDataDir) {
|
|
32584
|
+
const profileDirectory = input.profileDirectory ?? "Default";
|
|
32585
|
+
const cookiesPath = path7.join(userDataDir, profileDirectory, "Cookies");
|
|
32586
|
+
if (!fs.existsSync(cookiesPath)) {
|
|
31746
32587
|
throw new Error(
|
|
31747
|
-
|
|
31748
|
-
);
|
|
31749
|
-
}
|
|
31750
|
-
const userDataDir = resolved.userDataDir;
|
|
31751
|
-
if (resolved.strategy === "managed-relaunch") {
|
|
31752
|
-
if (resolved.runningPid === void 0) {
|
|
31753
|
-
throw new Error("Managed relaunch requires a running browser process.");
|
|
31754
|
-
}
|
|
31755
|
-
await gracefullyStopBrowser(
|
|
31756
|
-
getBrowserBrand(resolved.brandId),
|
|
31757
|
-
resolved.runningPid,
|
|
31758
|
-
resolved.timeoutMs
|
|
32588
|
+
`Cookies database not found at "${cookiesPath}". Verify the browser brand, user-data-dir, and profile-directory are correct.`
|
|
31759
32589
|
);
|
|
31760
32590
|
}
|
|
31761
|
-
await
|
|
31762
|
-
try {
|
|
31763
|
-
const capture = await launchCaptureChrome({
|
|
31764
|
-
brandDisplayName: resolved.brandDisplayName,
|
|
31765
|
-
executablePath: resolved.executablePath,
|
|
31766
|
-
userDataDir,
|
|
31767
|
-
...resolved.profileDirectory === void 0 ? {} : { profileDirectory: resolved.profileDirectory },
|
|
31768
|
-
timeoutMs: resolved.timeoutMs
|
|
31769
|
-
});
|
|
31770
|
-
return {
|
|
31771
|
-
strategy: resolved.strategy,
|
|
31772
|
-
cdpEndpoint: capture.endpoint,
|
|
31773
|
-
brandId: resolved.brandId,
|
|
31774
|
-
brandDisplayName: resolved.brandDisplayName,
|
|
31775
|
-
userDataDir: resolved.userDataDir,
|
|
31776
|
-
...resolved.profileDirectory === void 0 ? {} : { profileDirectory: resolved.profileDirectory },
|
|
31777
|
-
cleanup: async () => {
|
|
31778
|
-
await capture.kill().catch(() => void 0);
|
|
31779
|
-
await clearChromeSingletonEntries(userDataDir).catch(() => void 0);
|
|
31780
|
-
}
|
|
31781
|
-
};
|
|
31782
|
-
} catch (error) {
|
|
31783
|
-
await clearChromeSingletonEntries(userDataDir).catch(() => void 0);
|
|
31784
|
-
throw error;
|
|
31785
|
-
}
|
|
31786
|
-
}
|
|
31787
|
-
async function gracefullyStopBrowser(brand2, pid, timeoutMs = DEFAULT_STOP_TIMEOUT_MS) {
|
|
31788
|
-
if (pid <= 0) {
|
|
31789
|
-
return;
|
|
31790
|
-
}
|
|
31791
|
-
const platformConfig = resolveBrandPlatformConfig(brand2);
|
|
31792
|
-
if (process.platform === "darwin" && platformConfig?.bundleId) {
|
|
31793
|
-
await execFile2(
|
|
31794
|
-
"osascript",
|
|
31795
|
-
["-e", `tell application id "${platformConfig.bundleId}" to quit`],
|
|
31796
|
-
{
|
|
31797
|
-
maxBuffer: PROCESS_LIST_MAX_BUFFER_BYTES3
|
|
31798
|
-
}
|
|
31799
|
-
).catch(() => void 0);
|
|
31800
|
-
} else if (process.platform === "win32") {
|
|
31801
|
-
await execFile2("taskkill", ["/PID", String(pid)], {
|
|
31802
|
-
maxBuffer: PROCESS_LIST_MAX_BUFFER_BYTES3
|
|
31803
|
-
}).catch(() => void 0);
|
|
31804
|
-
} else {
|
|
31805
|
-
try {
|
|
31806
|
-
process.kill(pid, "SIGTERM");
|
|
31807
|
-
} catch {
|
|
31808
|
-
}
|
|
31809
|
-
}
|
|
31810
|
-
if (await waitForProcessExit2(pid, timeoutMs)) {
|
|
31811
|
-
return;
|
|
31812
|
-
}
|
|
31813
|
-
if (process.platform === "win32") {
|
|
31814
|
-
await execFile2("taskkill", ["/F", "/PID", String(pid)], {
|
|
31815
|
-
maxBuffer: PROCESS_LIST_MAX_BUFFER_BYTES3
|
|
31816
|
-
}).catch(() => void 0);
|
|
31817
|
-
} else {
|
|
31818
|
-
try {
|
|
31819
|
-
process.kill(pid, "SIGKILL");
|
|
31820
|
-
} catch {
|
|
31821
|
-
}
|
|
31822
|
-
}
|
|
31823
|
-
await waitForProcessExit2(pid, Math.min(5e3, timeoutMs));
|
|
31824
|
-
}
|
|
31825
|
-
async function launchCaptureChrome(input) {
|
|
31826
|
-
const stderrLines = [];
|
|
31827
|
-
const child = child_process.spawn(input.executablePath, buildCaptureChromeArgs(input), {
|
|
31828
|
-
detached: process.platform !== "win32",
|
|
31829
|
-
stdio: ["ignore", "ignore", "pipe"]
|
|
31830
|
-
});
|
|
31831
|
-
child.unref();
|
|
31832
|
-
child.stderr?.setEncoding("utf8");
|
|
31833
|
-
child.stderr?.on("data", (chunk) => {
|
|
31834
|
-
stderrLines.push(String(chunk));
|
|
31835
|
-
});
|
|
32591
|
+
const tempDir = await promises.mkdtemp(path7.join(os.tmpdir(), "opensteer-cookies-"));
|
|
31836
32592
|
try {
|
|
31837
|
-
|
|
31838
|
-
|
|
31839
|
-
|
|
31840
|
-
|
|
31841
|
-
timeoutMs: input.timeoutMs,
|
|
31842
|
-
userDataDir: input.userDataDir
|
|
31843
|
-
});
|
|
32593
|
+
await copyCookiesDatabase(cookiesPath, tempDir);
|
|
32594
|
+
const decryptionKey = await resolveDecryptionKey(brand2.id, userDataDir);
|
|
32595
|
+
const rows = queryAllCookies(path7.join(tempDir, "Cookies"));
|
|
32596
|
+
const cookies = decryptCookieRows(rows, decryptionKey);
|
|
31844
32597
|
return {
|
|
31845
|
-
|
|
31846
|
-
|
|
31847
|
-
|
|
31848
|
-
|
|
32598
|
+
cookies,
|
|
32599
|
+
brandId: brand2.id,
|
|
32600
|
+
brandDisplayName: brand2.displayName,
|
|
32601
|
+
userDataDir,
|
|
32602
|
+
profileDirectory
|
|
31849
32603
|
};
|
|
31850
|
-
}
|
|
31851
|
-
await
|
|
31852
|
-
throw error;
|
|
32604
|
+
} finally {
|
|
32605
|
+
await promises.rm(tempDir, { recursive: true, force: true }).catch(() => void 0);
|
|
31853
32606
|
}
|
|
31854
32607
|
}
|
|
31855
|
-
function relaunchBrowserNormally(executablePath) {
|
|
31856
|
-
const child = child_process.spawn(executablePath, [], {
|
|
31857
|
-
detached: true,
|
|
31858
|
-
stdio: "ignore"
|
|
31859
|
-
});
|
|
31860
|
-
child.unref();
|
|
31861
|
-
}
|
|
31862
32608
|
function resolveRequestedBrand(input) {
|
|
31863
32609
|
if (input.brandId !== void 0) {
|
|
31864
32610
|
return getBrowserBrand(input.brandId);
|
|
31865
32611
|
}
|
|
31866
|
-
if (input.userDataDir !== void 0) {
|
|
31867
|
-
const inferred = inferBrandFromUserDataDir(input.userDataDir);
|
|
31868
|
-
if (!inferred) {
|
|
31869
|
-
throw new Error(
|
|
31870
|
-
`Could not infer a browser brand from user-data-dir "${input.userDataDir}". Pass --browser explicitly.`
|
|
31871
|
-
);
|
|
31872
|
-
}
|
|
31873
|
-
return inferred;
|
|
31874
|
-
}
|
|
31875
|
-
if (input.executablePath !== void 0) {
|
|
31876
|
-
const inferred = inferBrandFromExecutablePath(input.executablePath);
|
|
31877
|
-
if (!inferred) {
|
|
31878
|
-
throw new Error(
|
|
31879
|
-
`Could not infer a browser brand from executable path "${input.executablePath}". Pass --browser explicitly.`
|
|
31880
|
-
);
|
|
31881
|
-
}
|
|
31882
|
-
return inferred;
|
|
31883
|
-
}
|
|
31884
32612
|
const installed = detectInstalledBrowserBrands()[0];
|
|
31885
32613
|
if (!installed) {
|
|
31886
32614
|
throw new Error(
|
|
31887
|
-
"No Chromium browser found. Install a supported browser or pass
|
|
32615
|
+
"No Chromium browser found. Install a supported browser or pass brandId explicitly."
|
|
31888
32616
|
);
|
|
31889
32617
|
}
|
|
31890
32618
|
return installed.brand;
|
|
31891
32619
|
}
|
|
31892
|
-
async function
|
|
31893
|
-
|
|
31894
|
-
|
|
31895
|
-
|
|
32620
|
+
async function copyCookiesDatabase(cookiesPath, destDir) {
|
|
32621
|
+
await promises.copyFile(cookiesPath, path7.join(destDir, "Cookies"));
|
|
32622
|
+
for (const suffix of ["-wal", "-journal", "-shm"]) {
|
|
32623
|
+
const src = cookiesPath + suffix;
|
|
32624
|
+
if (fs.existsSync(src)) {
|
|
32625
|
+
await promises.copyFile(src, path7.join(destDir, "Cookies" + suffix)).catch(() => void 0);
|
|
32626
|
+
}
|
|
31896
32627
|
}
|
|
32628
|
+
}
|
|
32629
|
+
function queryAllCookies(dbPath) {
|
|
32630
|
+
let DatabaseSync;
|
|
31897
32631
|
try {
|
|
31898
|
-
|
|
31899
|
-
endpoint: `http://127.0.0.1:${String(activePort.port)}`,
|
|
31900
|
-
timeoutMs: Math.min(2e3, timeoutMs)
|
|
31901
|
-
})).endpoint;
|
|
32632
|
+
({ DatabaseSync } = __require(NODE_SQLITE_SPECIFIER2));
|
|
31902
32633
|
} catch {
|
|
31903
|
-
|
|
32634
|
+
throw new Error(
|
|
32635
|
+
"Reading browser cookies requires Node's built-in SQLite support. Use Node 22.5+ or a build with node:sqlite enabled."
|
|
32636
|
+
);
|
|
32637
|
+
}
|
|
32638
|
+
const database = new DatabaseSync(dbPath, { readOnly: true });
|
|
32639
|
+
try {
|
|
32640
|
+
const stmt = database.prepare(
|
|
32641
|
+
`SELECT host_key, name, value, encrypted_value, path,
|
|
32642
|
+
expires_utc, is_secure, is_httponly, samesite, is_persistent
|
|
32643
|
+
FROM cookies`
|
|
32644
|
+
);
|
|
32645
|
+
stmt.setReadBigInts(true);
|
|
32646
|
+
return stmt.all();
|
|
32647
|
+
} finally {
|
|
32648
|
+
database.close();
|
|
31904
32649
|
}
|
|
31905
32650
|
}
|
|
31906
|
-
function
|
|
31907
|
-
if (
|
|
32651
|
+
async function resolveDecryptionKey(brandId, userDataDir) {
|
|
32652
|
+
if (process.platform === "darwin") {
|
|
32653
|
+
const password = await resolveKeychainPassword(brandId);
|
|
32654
|
+
const key = crypto.pbkdf2Sync(password, "saltysalt", 1003, 16, "sha1");
|
|
32655
|
+
return { platform: "darwin", key, algorithm: "aes-128-cbc" };
|
|
32656
|
+
}
|
|
32657
|
+
if (process.platform === "linux") {
|
|
32658
|
+
const key = crypto.pbkdf2Sync("peanuts", "saltysalt", 1, 16, "sha1");
|
|
32659
|
+
return { platform: "linux", key, algorithm: "aes-128-cbc" };
|
|
32660
|
+
}
|
|
32661
|
+
if (process.platform === "win32") {
|
|
32662
|
+
const key = await resolveWindowsMasterKey(userDataDir);
|
|
32663
|
+
return { platform: "win32", key, algorithm: "aes-256-gcm" };
|
|
32664
|
+
}
|
|
32665
|
+
throw new Error(`Unsupported platform "${process.platform}" for cookie decryption.`);
|
|
32666
|
+
}
|
|
32667
|
+
var BRAND_KEYCHAIN_SERVICE = {
|
|
32668
|
+
chrome: "Chrome Safe Storage",
|
|
32669
|
+
"chrome-canary": "Chrome Safe Storage",
|
|
32670
|
+
chromium: "Chromium Safe Storage",
|
|
32671
|
+
brave: "Brave Safe Storage",
|
|
32672
|
+
edge: "Microsoft Edge Safe Storage",
|
|
32673
|
+
vivaldi: "Chrome Safe Storage",
|
|
32674
|
+
helium: "Chrome Safe Storage"
|
|
32675
|
+
};
|
|
32676
|
+
async function resolveKeychainPassword(brandId) {
|
|
32677
|
+
const service = BRAND_KEYCHAIN_SERVICE[brandId];
|
|
32678
|
+
try {
|
|
32679
|
+
const { stdout } = await execFile2("security", [
|
|
32680
|
+
"find-generic-password",
|
|
32681
|
+
"-s",
|
|
32682
|
+
service,
|
|
32683
|
+
"-w"
|
|
32684
|
+
]);
|
|
32685
|
+
return stdout.trim();
|
|
32686
|
+
} catch {
|
|
31908
32687
|
throw new Error(
|
|
31909
|
-
|
|
32688
|
+
`Failed to retrieve "${service}" from macOS Keychain. Ensure the browser has been opened at least once and Keychain access is allowed.`
|
|
31910
32689
|
);
|
|
31911
32690
|
}
|
|
31912
|
-
|
|
32691
|
+
}
|
|
32692
|
+
async function resolveWindowsMasterKey(userDataDir) {
|
|
32693
|
+
const localStatePath = path7.join(userDataDir, "Local State");
|
|
32694
|
+
let localState;
|
|
32695
|
+
try {
|
|
32696
|
+
localState = JSON.parse(await promises.readFile(localStatePath, "utf8"));
|
|
32697
|
+
} catch {
|
|
31913
32698
|
throw new Error(
|
|
31914
|
-
|
|
32699
|
+
`Failed to read "${localStatePath}". Ensure the browser has been opened at least once.`
|
|
31915
32700
|
);
|
|
31916
32701
|
}
|
|
31917
|
-
|
|
32702
|
+
const encodedKey = localState.os_crypt?.encrypted_key;
|
|
32703
|
+
if (!encodedKey) {
|
|
32704
|
+
throw new Error(`No encrypted key found in "${localStatePath}".`);
|
|
32705
|
+
}
|
|
32706
|
+
const rawKey = Buffer.from(encodedKey, "base64").subarray(5);
|
|
32707
|
+
const psScript = `
|
|
32708
|
+
Add-Type -AssemblyName System.Security
|
|
32709
|
+
$bytes = [byte[]]@(${Array.from(rawKey).join(",")})
|
|
32710
|
+
$decrypted = [System.Security.Cryptography.ProtectedData]::Unprotect($bytes, $null, 'CurrentUser')
|
|
32711
|
+
[Convert]::ToBase64String($decrypted)
|
|
32712
|
+
`;
|
|
32713
|
+
try {
|
|
32714
|
+
const { stdout } = await execFile2("powershell", [
|
|
32715
|
+
"-NoProfile",
|
|
32716
|
+
"-NonInteractive",
|
|
32717
|
+
"-Command",
|
|
32718
|
+
psScript
|
|
32719
|
+
]);
|
|
32720
|
+
return Buffer.from(stdout.trim(), "base64");
|
|
32721
|
+
} catch {
|
|
31918
32722
|
throw new Error(
|
|
31919
|
-
|
|
32723
|
+
"Failed to decrypt browser master key via Windows DPAPI. Ensure you are running as the same user who owns the browser profile."
|
|
31920
32724
|
);
|
|
31921
32725
|
}
|
|
31922
32726
|
}
|
|
31923
|
-
function
|
|
31924
|
-
const
|
|
31925
|
-
|
|
31926
|
-
|
|
31927
|
-
|
|
31928
|
-
|
|
32727
|
+
function decryptCookieRows(rows, decryptionKey) {
|
|
32728
|
+
const cookies = [];
|
|
32729
|
+
const nowSeconds = Math.floor(Date.now() / 1e3);
|
|
32730
|
+
for (const row of rows) {
|
|
32731
|
+
const name = row.name.trim();
|
|
32732
|
+
const domain = row.host_key.trim();
|
|
32733
|
+
if (!name || !domain) {
|
|
32734
|
+
continue;
|
|
31929
32735
|
}
|
|
31930
|
-
const
|
|
31931
|
-
|
|
31932
|
-
|
|
31933
|
-
}
|
|
31934
|
-
function inferBrandFromExecutablePath(executablePath) {
|
|
31935
|
-
const normalized = normalizePath(executablePath);
|
|
31936
|
-
return getAllBrowserBrands().find((brand2) => {
|
|
31937
|
-
const config = resolveBrandPlatformConfig(brand2);
|
|
31938
|
-
if (!config) {
|
|
31939
|
-
return false;
|
|
32736
|
+
const value = decryptCookieValue(row, decryptionKey);
|
|
32737
|
+
if (value === null) {
|
|
32738
|
+
continue;
|
|
31940
32739
|
}
|
|
31941
|
-
|
|
31942
|
-
|
|
31943
|
-
)
|
|
31944
|
-
|
|
31945
|
-
}
|
|
31946
|
-
function buildCaptureChromeArgs(input) {
|
|
31947
|
-
const args = [
|
|
31948
|
-
"--remote-debugging-port=0",
|
|
31949
|
-
"--headless=new",
|
|
31950
|
-
"--no-first-run",
|
|
31951
|
-
"--no-default-browser-check",
|
|
31952
|
-
"--disable-background-networking",
|
|
31953
|
-
"--disable-sync",
|
|
31954
|
-
"--disable-component-update",
|
|
31955
|
-
`--user-data-dir=${input.userDataDir}`
|
|
31956
|
-
];
|
|
31957
|
-
if (input.profileDirectory !== void 0) {
|
|
31958
|
-
args.push(`--profile-directory=${input.profileDirectory}`);
|
|
31959
|
-
}
|
|
31960
|
-
return args;
|
|
31961
|
-
}
|
|
31962
|
-
async function waitForCaptureEndpoint(input) {
|
|
31963
|
-
const deadline = Date.now() + input.timeoutMs;
|
|
31964
|
-
while (Date.now() < deadline) {
|
|
31965
|
-
const activePort = readDevToolsActivePort(input.userDataDir);
|
|
31966
|
-
if (activePort) {
|
|
31967
|
-
try {
|
|
31968
|
-
return (await inspectCdpEndpoint({
|
|
31969
|
-
endpoint: `http://127.0.0.1:${String(activePort.port)}`,
|
|
31970
|
-
timeoutMs: Math.min(2e3, input.timeoutMs)
|
|
31971
|
-
})).endpoint;
|
|
31972
|
-
} catch {
|
|
31973
|
-
return `ws://127.0.0.1:${String(activePort.port)}${activePort.webSocketPath}`;
|
|
31974
|
-
}
|
|
32740
|
+
const expiresSeconds = chromeDateToUnixSeconds(row.expires_utc);
|
|
32741
|
+
const isSession = expiresSeconds <= 0;
|
|
32742
|
+
if (!isSession && expiresSeconds < nowSeconds) {
|
|
32743
|
+
continue;
|
|
31975
32744
|
}
|
|
31976
|
-
|
|
31977
|
-
|
|
32745
|
+
const sameSite = chromeSameSiteToString(row.samesite);
|
|
32746
|
+
let secure = Number(row.is_secure) === 1;
|
|
32747
|
+
if (sameSite === "None") {
|
|
32748
|
+
secure = true;
|
|
31978
32749
|
}
|
|
31979
|
-
|
|
32750
|
+
cookies.push({
|
|
32751
|
+
name,
|
|
32752
|
+
value,
|
|
32753
|
+
domain,
|
|
32754
|
+
path: row.path || "/",
|
|
32755
|
+
secure,
|
|
32756
|
+
httpOnly: Number(row.is_httponly) === 1,
|
|
32757
|
+
...isSession ? {} : { expires: expiresSeconds },
|
|
32758
|
+
...sameSite !== void 0 ? { sameSite } : {}
|
|
32759
|
+
});
|
|
31980
32760
|
}
|
|
31981
|
-
|
|
32761
|
+
return cookies;
|
|
31982
32762
|
}
|
|
31983
|
-
function
|
|
31984
|
-
|
|
31985
|
-
|
|
31986
|
-
return `${brandDisplayName} failed to launch before exposing a DevTools endpoint.`;
|
|
32763
|
+
function decryptCookieValue(row, decryptionKey) {
|
|
32764
|
+
if (row.value && row.value.length > 0) {
|
|
32765
|
+
return row.value;
|
|
31987
32766
|
}
|
|
31988
|
-
const
|
|
31989
|
-
|
|
31990
|
-
|
|
31991
|
-
|
|
31992
|
-
|
|
32767
|
+
const encrypted = Buffer.isBuffer(row.encrypted_value) ? row.encrypted_value : Buffer.from(row.encrypted_value);
|
|
32768
|
+
if (encrypted.length === 0) {
|
|
32769
|
+
return "";
|
|
32770
|
+
}
|
|
32771
|
+
const prefix = encrypted.subarray(0, 3).toString("ascii");
|
|
32772
|
+
if (prefix !== "v10" && prefix !== "v11") {
|
|
32773
|
+
return encrypted.toString("utf8");
|
|
32774
|
+
}
|
|
32775
|
+
const ciphertext = encrypted.subarray(3);
|
|
32776
|
+
if (decryptionKey.algorithm === "aes-128-cbc") {
|
|
32777
|
+
return decryptAes128Cbc(ciphertext, decryptionKey.key);
|
|
32778
|
+
}
|
|
32779
|
+
if (decryptionKey.algorithm === "aes-256-gcm") {
|
|
32780
|
+
return decryptAes256Gcm(ciphertext, decryptionKey.key);
|
|
32781
|
+
}
|
|
32782
|
+
return null;
|
|
31993
32783
|
}
|
|
31994
|
-
|
|
31995
|
-
|
|
31996
|
-
|
|
32784
|
+
function decryptAes128Cbc(ciphertext, key) {
|
|
32785
|
+
try {
|
|
32786
|
+
const iv = Buffer.alloc(16, 32);
|
|
32787
|
+
const decipher = crypto.createDecipheriv("aes-128-cbc", key, iv);
|
|
32788
|
+
let decrypted = Buffer.concat([decipher.update(ciphertext), decipher.final()]);
|
|
32789
|
+
if (decrypted.length > CHROME_HMAC_PREFIX_LENGTH && containsNonPrintableAscii(decrypted, CHROME_HMAC_PREFIX_LENGTH)) {
|
|
32790
|
+
decrypted = decrypted.subarray(CHROME_HMAC_PREFIX_LENGTH);
|
|
32791
|
+
}
|
|
32792
|
+
if (containsNonPrintableAscii(decrypted, decrypted.length)) {
|
|
32793
|
+
return null;
|
|
32794
|
+
}
|
|
32795
|
+
return decrypted.toString("utf8");
|
|
32796
|
+
} catch {
|
|
32797
|
+
return null;
|
|
31997
32798
|
}
|
|
32799
|
+
}
|
|
32800
|
+
function decryptAes256Gcm(ciphertext, key) {
|
|
31998
32801
|
try {
|
|
31999
|
-
|
|
32802
|
+
const nonce = ciphertext.subarray(0, 12);
|
|
32803
|
+
const authTag = ciphertext.subarray(ciphertext.length - 16);
|
|
32804
|
+
const encrypted = ciphertext.subarray(12, ciphertext.length - 16);
|
|
32805
|
+
const decipher = crypto.createDecipheriv("aes-256-gcm", key, nonce);
|
|
32806
|
+
decipher.setAuthTag(authTag);
|
|
32807
|
+
const decrypted = Buffer.concat([decipher.update(encrypted), decipher.final()]);
|
|
32808
|
+
if (containsNonPrintableAscii(decrypted, decrypted.length)) {
|
|
32809
|
+
return null;
|
|
32810
|
+
}
|
|
32811
|
+
return decrypted.toString("utf8");
|
|
32000
32812
|
} catch {
|
|
32001
|
-
return;
|
|
32813
|
+
return null;
|
|
32002
32814
|
}
|
|
32003
|
-
await sleep4(50);
|
|
32004
32815
|
}
|
|
32005
|
-
|
|
32006
|
-
const
|
|
32007
|
-
|
|
32008
|
-
|
|
32816
|
+
function containsNonPrintableAscii(buffer, length) {
|
|
32817
|
+
const end = Math.min(length, buffer.length);
|
|
32818
|
+
for (let i = 0; i < end; i++) {
|
|
32819
|
+
const byte = buffer[i];
|
|
32820
|
+
if (byte < 32 || byte > 126) {
|
|
32009
32821
|
return true;
|
|
32010
32822
|
}
|
|
32011
|
-
await sleep4(50);
|
|
32012
32823
|
}
|
|
32013
|
-
return
|
|
32824
|
+
return false;
|
|
32014
32825
|
}
|
|
32015
|
-
function
|
|
32016
|
-
|
|
32826
|
+
function chromeDateToUnixSeconds(chromeTimestamp) {
|
|
32827
|
+
const ts = BigInt(chromeTimestamp);
|
|
32828
|
+
if (ts <= 0n) {
|
|
32829
|
+
return -1;
|
|
32830
|
+
}
|
|
32831
|
+
return Number((ts - CHROME_EPOCH_OFFSET) / 1000000n);
|
|
32017
32832
|
}
|
|
32018
|
-
|
|
32019
|
-
|
|
32833
|
+
function chromeSameSiteToString(value) {
|
|
32834
|
+
const v = Number(value);
|
|
32835
|
+
if (v === 0) return "None";
|
|
32836
|
+
if (v === 1) return "Lax";
|
|
32837
|
+
if (v === 2) return "Strict";
|
|
32838
|
+
return void 0;
|
|
32020
32839
|
}
|
|
32021
32840
|
|
|
32022
32841
|
// src/cloud/cookie-sync.ts
|
|
@@ -32072,14 +32891,14 @@ function toPortableBrowserProfileCookieRecord(cookie) {
|
|
|
32072
32891
|
if (!name || !domain) {
|
|
32073
32892
|
return null;
|
|
32074
32893
|
}
|
|
32075
|
-
const
|
|
32894
|
+
const path15 = typeof cookie.path === "string" && cookie.path.trim().length > 0 ? cookie.path : "/";
|
|
32076
32895
|
const expiresAt = typeof cookie.expires === "number" && Number.isFinite(cookie.expires) && cookie.expires > 0 ? Math.floor(cookie.expires * 1e3) : null;
|
|
32077
32896
|
const sameSite = normalizeSameSite(cookie.sameSite);
|
|
32078
32897
|
return {
|
|
32079
32898
|
name,
|
|
32080
32899
|
value: cookie.value,
|
|
32081
32900
|
domain,
|
|
32082
|
-
path:
|
|
32901
|
+
path: path15,
|
|
32083
32902
|
secure: cookie.secure,
|
|
32084
32903
|
httpOnly: cookie.httpOnly,
|
|
32085
32904
|
...sameSite === void 0 ? {} : { sameSite },
|
|
@@ -32095,114 +32914,48 @@ function normalizeSameSite(value) {
|
|
|
32095
32914
|
return void 0;
|
|
32096
32915
|
}
|
|
32097
32916
|
|
|
32098
|
-
// src/cloud/portable-cookie-snapshot.ts
|
|
32099
|
-
var gzip = util.promisify(zlib.gzip);
|
|
32100
|
-
async function capturePortableBrowserProfileSnapshot(input = {}) {
|
|
32101
|
-
const attached = input.attachEndpoint ? await inspectCdpEndpoint({
|
|
32102
|
-
endpoint: input.attachEndpoint,
|
|
32103
|
-
...input.timeoutMs === void 0 ? {} : { timeoutMs: input.timeoutMs }
|
|
32104
|
-
}) : await selectAttachBrowserCandidate({
|
|
32105
|
-
...input.timeoutMs === void 0 ? {} : { timeoutMs: input.timeoutMs }
|
|
32106
|
-
});
|
|
32107
|
-
const browser = await enginePlaywright.connectPlaywrightChromiumBrowser({
|
|
32108
|
-
url: attached.endpoint
|
|
32109
|
-
});
|
|
32110
|
-
try {
|
|
32111
|
-
const context = browser.contexts()[0];
|
|
32112
|
-
if (!context) {
|
|
32113
|
-
throw new Error("Attached browser did not expose a default browser context.");
|
|
32114
|
-
}
|
|
32115
|
-
const prepared = prepareBrowserProfileSyncCookies({
|
|
32116
|
-
cookies: await context.cookies(),
|
|
32117
|
-
...input.domains === void 0 ? {} : { domains: input.domains }
|
|
32118
|
-
});
|
|
32119
|
-
if (prepared.cookies.length === 0) {
|
|
32120
|
-
throw new Error("No syncable cookies found for the selected browser and scope.");
|
|
32121
|
-
}
|
|
32122
|
-
const browserVersion = browser.version();
|
|
32123
|
-
const source = parseSnapshotSource(attached.browser ?? browserVersion);
|
|
32124
|
-
return {
|
|
32125
|
-
version: "portable-cookies-v1",
|
|
32126
|
-
source: {
|
|
32127
|
-
browserFamily: "chromium",
|
|
32128
|
-
...source.browserName === void 0 ? {} : { browserName: source.browserName },
|
|
32129
|
-
...source.browserMajor === void 0 ? {} : { browserMajor: source.browserMajor },
|
|
32130
|
-
...input.browserBrand === void 0 ? {} : { browserBrand: input.browserBrand },
|
|
32131
|
-
...input.captureMethod === void 0 ? {} : { captureMethod: input.captureMethod },
|
|
32132
|
-
platform: normalizePlatform(process.platform),
|
|
32133
|
-
capturedAt: Date.now()
|
|
32134
|
-
},
|
|
32135
|
-
cookies: prepared.cookies
|
|
32136
|
-
};
|
|
32137
|
-
} finally {
|
|
32138
|
-
await browser.close().catch(() => void 0);
|
|
32139
|
-
}
|
|
32140
|
-
}
|
|
32141
|
-
async function encodePortableBrowserProfileSnapshot(snapshot) {
|
|
32142
|
-
return gzip(Buffer.from(JSON.stringify(snapshot), "utf8"));
|
|
32143
|
-
}
|
|
32144
|
-
function parseSnapshotSource(value) {
|
|
32145
|
-
if (!value) {
|
|
32146
|
-
return {};
|
|
32147
|
-
}
|
|
32148
|
-
const trimmed = value.trim();
|
|
32149
|
-
const browserName = trimmed.split("/")[0]?.trim() || void 0;
|
|
32150
|
-
const majorMatch = trimmed.match(/(\d+)/);
|
|
32151
|
-
return {
|
|
32152
|
-
...browserName === void 0 ? {} : { browserName },
|
|
32153
|
-
...majorMatch?.[1] === void 0 ? {} : { browserMajor: majorMatch[1] }
|
|
32154
|
-
};
|
|
32155
|
-
}
|
|
32156
|
-
function normalizePlatform(platform) {
|
|
32157
|
-
if (platform === "darwin") return "macos";
|
|
32158
|
-
if (platform === "win32") return "windows";
|
|
32159
|
-
return platform;
|
|
32160
|
-
}
|
|
32161
|
-
|
|
32162
32917
|
// src/cloud/profile-sync.ts
|
|
32918
|
+
var gzip = util.promisify(zlib.gzip);
|
|
32163
32919
|
var DEFAULT_POLL_INTERVAL_MS = 1e3;
|
|
32164
32920
|
var DEFAULT_POLL_TIMEOUT_MS = 5 * 6e4;
|
|
32165
32921
|
async function syncBrowserProfileCookies(client, input) {
|
|
32166
|
-
const
|
|
32167
|
-
...input.attachEndpoint === void 0 ? {} : { attachEndpoint: input.attachEndpoint },
|
|
32922
|
+
const result = await readBrowserCookies({
|
|
32168
32923
|
...input.brandId === void 0 ? {} : { brandId: input.brandId },
|
|
32169
32924
|
...input.userDataDir === void 0 ? {} : { userDataDir: input.userDataDir },
|
|
32170
|
-
...input.profileDirectory === void 0 ? {} : { profileDirectory: input.profileDirectory }
|
|
32171
|
-
...input.executablePath === void 0 ? {} : { executablePath: input.executablePath },
|
|
32172
|
-
...input.strategy === void 0 ? {} : { strategy: input.strategy },
|
|
32173
|
-
...input.timeoutMs === void 0 ? {} : { timeoutMs: input.timeoutMs }
|
|
32925
|
+
...input.profileDirectory === void 0 ? {} : { profileDirectory: input.profileDirectory }
|
|
32174
32926
|
});
|
|
32175
|
-
const
|
|
32176
|
-
|
|
32177
|
-
|
|
32178
|
-
|
|
32179
|
-
|
|
32180
|
-
|
|
32181
|
-
|
|
32182
|
-
|
|
32183
|
-
|
|
32184
|
-
|
|
32185
|
-
|
|
32186
|
-
|
|
32187
|
-
|
|
32188
|
-
|
|
32189
|
-
|
|
32190
|
-
|
|
32191
|
-
|
|
32192
|
-
|
|
32193
|
-
|
|
32194
|
-
|
|
32195
|
-
|
|
32196
|
-
|
|
32197
|
-
|
|
32198
|
-
|
|
32199
|
-
|
|
32200
|
-
|
|
32201
|
-
await captureSource?.cleanup().catch(() => void 0);
|
|
32202
|
-
if (shouldRestoreBrowser && resolved.executablePath !== void 0) {
|
|
32203
|
-
relaunchBrowserNormally(resolved.executablePath);
|
|
32204
|
-
}
|
|
32927
|
+
const prepared = prepareBrowserProfileSyncCookies({
|
|
32928
|
+
cookies: result.cookies,
|
|
32929
|
+
...input.domains === void 0 ? {} : { domains: input.domains }
|
|
32930
|
+
});
|
|
32931
|
+
if (prepared.cookies.length === 0) {
|
|
32932
|
+
throw new Error("No syncable cookies found for the selected browser and scope.");
|
|
32933
|
+
}
|
|
32934
|
+
const snapshot = {
|
|
32935
|
+
version: "portable-cookies-v1",
|
|
32936
|
+
source: {
|
|
32937
|
+
browserFamily: "chromium",
|
|
32938
|
+
browserBrand: result.brandId,
|
|
32939
|
+
captureMethod: "sqlite",
|
|
32940
|
+
platform: normalizePlatform(process.platform),
|
|
32941
|
+
capturedAt: Date.now()
|
|
32942
|
+
},
|
|
32943
|
+
cookies: prepared.cookies
|
|
32944
|
+
};
|
|
32945
|
+
const payload = await gzip(Buffer.from(JSON.stringify(snapshot), "utf8"));
|
|
32946
|
+
const created = await client.createBrowserProfileImport({
|
|
32947
|
+
profileId: input.profileId
|
|
32948
|
+
});
|
|
32949
|
+
if (payload.length > created.maxUploadBytes) {
|
|
32950
|
+
throw new Error(
|
|
32951
|
+
`Compressed cookie snapshot is ${String(payload.length)} bytes, exceeding the ${String(created.maxUploadBytes)} byte upload limit.`
|
|
32952
|
+
);
|
|
32205
32953
|
}
|
|
32954
|
+
const uploaded = await client.uploadBrowserProfileImportPayload({
|
|
32955
|
+
uploadUrl: created.uploadUrl,
|
|
32956
|
+
payload
|
|
32957
|
+
});
|
|
32958
|
+
return uploaded.status === "ready" ? uploaded : waitForBrowserProfileImport(client, created.importId);
|
|
32206
32959
|
}
|
|
32207
32960
|
async function waitForBrowserProfileImport(client, importId) {
|
|
32208
32961
|
const deadline = Date.now() + DEFAULT_POLL_TIMEOUT_MS;
|
|
@@ -32214,12 +32967,17 @@ async function waitForBrowserProfileImport(client, importId) {
|
|
|
32214
32967
|
if (current.status === "failed") {
|
|
32215
32968
|
throw new Error(current.error ?? "Browser profile sync failed.");
|
|
32216
32969
|
}
|
|
32217
|
-
await
|
|
32970
|
+
await sleep4(DEFAULT_POLL_INTERVAL_MS);
|
|
32218
32971
|
}
|
|
32219
32972
|
throw new Error(`Timed out waiting for browser profile sync "${importId}" to finish.`);
|
|
32220
32973
|
}
|
|
32221
|
-
|
|
32222
|
-
|
|
32974
|
+
function normalizePlatform(platform) {
|
|
32975
|
+
if (platform === "darwin") return "macos";
|
|
32976
|
+
if (platform === "win32") return "windows";
|
|
32977
|
+
return platform;
|
|
32978
|
+
}
|
|
32979
|
+
async function sleep4(ms) {
|
|
32980
|
+
await new Promise((resolve4) => setTimeout(resolve4, ms));
|
|
32223
32981
|
}
|
|
32224
32982
|
|
|
32225
32983
|
// src/cloud/client.ts
|
|
@@ -32239,7 +32997,8 @@ var OpensteerCloudClient = class {
|
|
|
32239
32997
|
...input.name === void 0 ? {} : { name: input.name },
|
|
32240
32998
|
...input.browser === void 0 ? {} : { browser: input.browser },
|
|
32241
32999
|
...input.context === void 0 ? {} : { context: input.context },
|
|
32242
|
-
...input.browserProfile === void 0 ? {} : { browserProfile: input.browserProfile }
|
|
33000
|
+
...input.browserProfile === void 0 ? {} : { browserProfile: input.browserProfile },
|
|
33001
|
+
...input.observability === void 0 ? {} : { observability: input.observability }
|
|
32243
33002
|
}
|
|
32244
33003
|
});
|
|
32245
33004
|
return await response.json();
|
|
@@ -32417,8 +33176,8 @@ var OpensteerCloudClient = class {
|
|
|
32417
33176
|
}
|
|
32418
33177
|
};
|
|
32419
33178
|
function delay(ms) {
|
|
32420
|
-
return new Promise((
|
|
32421
|
-
setTimeout(
|
|
33179
|
+
return new Promise((resolve4) => {
|
|
33180
|
+
setTimeout(resolve4, ms);
|
|
32422
33181
|
});
|
|
32423
33182
|
}
|
|
32424
33183
|
function wrapCloudFetchError(error, input) {
|
|
@@ -32441,17 +33200,17 @@ function wrapCloudFetchError(error, input) {
|
|
|
32441
33200
|
function resolveCloudConfig(input = {}) {
|
|
32442
33201
|
const provider = resolveOpensteerProvider({
|
|
32443
33202
|
...input.provider === void 0 ? {} : { provider: input.provider },
|
|
32444
|
-
...input.
|
|
33203
|
+
...input.environment?.OPENSTEER_PROVIDER === void 0 ? {} : { environmentProvider: input.environment.OPENSTEER_PROVIDER }
|
|
32445
33204
|
});
|
|
32446
33205
|
if (provider.mode !== "cloud") {
|
|
32447
33206
|
return void 0;
|
|
32448
33207
|
}
|
|
32449
33208
|
const cloudProvider = input.provider?.mode === "cloud" ? input.provider : void 0;
|
|
32450
|
-
const apiKey = cloudProvider?.apiKey ??
|
|
33209
|
+
const apiKey = cloudProvider?.apiKey ?? input.environment?.OPENSTEER_API_KEY;
|
|
32451
33210
|
if (!apiKey || apiKey.trim().length === 0) {
|
|
32452
33211
|
throw new Error("provider=cloud requires OPENSTEER_API_KEY or provider.apiKey.");
|
|
32453
33212
|
}
|
|
32454
|
-
const baseUrl = cloudProvider?.baseUrl ??
|
|
33213
|
+
const baseUrl = cloudProvider?.baseUrl ?? input.environment?.OPENSTEER_BASE_URL;
|
|
32455
33214
|
if (!baseUrl || baseUrl.trim().length === 0) {
|
|
32456
33215
|
throw new Error("provider=cloud requires OPENSTEER_BASE_URL or provider.baseUrl.");
|
|
32457
33216
|
}
|
|
@@ -32553,9 +33312,9 @@ var OpensteerCloudAutomationClient = class {
|
|
|
32553
33312
|
sentAt: Date.now(),
|
|
32554
33313
|
...input === void 0 ? {} : { input }
|
|
32555
33314
|
};
|
|
32556
|
-
return new Promise((
|
|
33315
|
+
return new Promise((resolve4, reject) => {
|
|
32557
33316
|
this.pending.set(requestId, {
|
|
32558
|
-
resolve: (value) =>
|
|
33317
|
+
resolve: (value) => resolve4(value),
|
|
32559
33318
|
reject
|
|
32560
33319
|
});
|
|
32561
33320
|
try {
|
|
@@ -32618,8 +33377,8 @@ var OpensteerCloudAutomationClient = class {
|
|
|
32618
33377
|
pending.reject(new Error(`automation connection closed before ${requestId} completed`));
|
|
32619
33378
|
}
|
|
32620
33379
|
this.pending.clear();
|
|
32621
|
-
await new Promise((
|
|
32622
|
-
socket.once("close", () =>
|
|
33380
|
+
await new Promise((resolve4) => {
|
|
33381
|
+
socket.once("close", () => resolve4());
|
|
32623
33382
|
socket.close();
|
|
32624
33383
|
}).catch(() => void 0);
|
|
32625
33384
|
}
|
|
@@ -32661,8 +33420,8 @@ var OpensteerCloudAutomationClient = class {
|
|
|
32661
33420
|
}
|
|
32662
33421
|
this.pending.clear();
|
|
32663
33422
|
});
|
|
32664
|
-
await new Promise((
|
|
32665
|
-
socket.once("open", () =>
|
|
33423
|
+
await new Promise((resolve4, reject) => {
|
|
33424
|
+
socket.once("open", () => resolve4());
|
|
32666
33425
|
socket.once("error", reject);
|
|
32667
33426
|
});
|
|
32668
33427
|
this.send({
|
|
@@ -33003,6 +33762,7 @@ var CloudSessionProxy = class {
|
|
|
33003
33762
|
workspace;
|
|
33004
33763
|
cleanupRootOnClose;
|
|
33005
33764
|
cloud;
|
|
33765
|
+
observability;
|
|
33006
33766
|
sessionId;
|
|
33007
33767
|
sessionBaseUrl;
|
|
33008
33768
|
client;
|
|
@@ -33011,8 +33771,9 @@ var CloudSessionProxy = class {
|
|
|
33011
33771
|
constructor(cloud, options = {}) {
|
|
33012
33772
|
this.cloud = cloud;
|
|
33013
33773
|
this.workspace = options.workspace;
|
|
33014
|
-
this.
|
|
33015
|
-
|
|
33774
|
+
this.observability = options.observability;
|
|
33775
|
+
this.rootPath = options.rootPath ?? (this.workspace === void 0 ? path7__default.default.join(os.tmpdir(), `${TEMPORARY_CLOUD_WORKSPACE_PREFIX}${crypto.randomUUID()}`) : resolveFilesystemWorkspacePath({
|
|
33776
|
+
rootDir: path7__default.default.resolve(options.rootDir ?? process.cwd()),
|
|
33016
33777
|
workspace: this.workspace
|
|
33017
33778
|
}));
|
|
33018
33779
|
this.cleanupRootOnClose = options.cleanupRootOnClose ?? this.workspace === void 0;
|
|
@@ -33355,6 +34116,7 @@ var CloudSessionProxy = class {
|
|
|
33355
34116
|
...this.workspace === void 0 ? {} : { name: this.workspace },
|
|
33356
34117
|
...input.launch === void 0 ? {} : { browser: input.launch },
|
|
33357
34118
|
...input.context === void 0 ? {} : { context: input.context },
|
|
34119
|
+
...this.observability === void 0 ? {} : { observability: this.observability },
|
|
33358
34120
|
...resolveCloudBrowserProfile(this.cloud, input) === void 0 ? {} : { browserProfile: resolveCloudBrowserProfile(this.cloud, input) }
|
|
33359
34121
|
});
|
|
33360
34122
|
const record = {
|
|
@@ -33452,16 +34214,17 @@ function isMissingCloudSessionError(error) {
|
|
|
33452
34214
|
|
|
33453
34215
|
// src/sdk/runtime-resolution.ts
|
|
33454
34216
|
function resolveOpensteerRuntimeConfig(input = {}) {
|
|
34217
|
+
const environment = input.environment ?? process.env;
|
|
33455
34218
|
const provider = resolveOpensteerProvider({
|
|
33456
34219
|
...input.provider === void 0 ? {} : { provider: input.provider },
|
|
33457
|
-
...
|
|
34220
|
+
...environment.OPENSTEER_PROVIDER === void 0 ? {} : { environmentProvider: environment.OPENSTEER_PROVIDER }
|
|
33458
34221
|
});
|
|
33459
34222
|
if (provider.mode === "cloud") {
|
|
33460
34223
|
return {
|
|
33461
34224
|
provider,
|
|
33462
34225
|
cloud: resolveCloudConfig({
|
|
33463
34226
|
...input.provider === void 0 ? {} : { provider: input.provider },
|
|
33464
|
-
|
|
34227
|
+
environment
|
|
33465
34228
|
})
|
|
33466
34229
|
};
|
|
33467
34230
|
}
|
|
@@ -33472,7 +34235,7 @@ function createOpensteerSemanticRuntime(input = {}) {
|
|
|
33472
34235
|
const engine = input.engine ?? runtimeOptions.engineName ?? DEFAULT_OPENSTEER_ENGINE;
|
|
33473
34236
|
const config = resolveOpensteerRuntimeConfig({
|
|
33474
34237
|
...input.provider === void 0 ? {} : { provider: input.provider },
|
|
33475
|
-
...
|
|
34238
|
+
...input.environment === void 0 ? {} : { environment: input.environment }
|
|
33476
34239
|
});
|
|
33477
34240
|
assertProviderSupportsEngine(config.provider.mode, engine);
|
|
33478
34241
|
if (config.provider.mode === "cloud") {
|
|
@@ -33480,7 +34243,8 @@ function createOpensteerSemanticRuntime(input = {}) {
|
|
|
33480
34243
|
...runtimeOptions.rootDir === void 0 ? {} : { rootDir: runtimeOptions.rootDir },
|
|
33481
34244
|
...runtimeOptions.rootPath === void 0 ? {} : { rootPath: runtimeOptions.rootPath },
|
|
33482
34245
|
...runtimeOptions.workspace === void 0 ? {} : { workspace: runtimeOptions.workspace },
|
|
33483
|
-
...runtimeOptions.cleanupRootOnClose === void 0 ? {} : { cleanupRootOnClose: runtimeOptions.cleanupRootOnClose }
|
|
34246
|
+
...runtimeOptions.cleanupRootOnClose === void 0 ? {} : { cleanupRootOnClose: runtimeOptions.cleanupRootOnClose },
|
|
34247
|
+
...runtimeOptions.observability === void 0 ? {} : { observability: runtimeOptions.observability }
|
|
33484
34248
|
});
|
|
33485
34249
|
}
|
|
33486
34250
|
return new OpensteerRuntime({
|
|
@@ -33495,16 +34259,18 @@ var Opensteer = class {
|
|
|
33495
34259
|
browserManager;
|
|
33496
34260
|
browser;
|
|
33497
34261
|
constructor(options = {}) {
|
|
34262
|
+
const environment = resolveOpensteerEnvironment(options.rootDir);
|
|
33498
34263
|
const { provider, engineName, ...runtimeOptions } = options;
|
|
33499
34264
|
const runtimeConfig = resolveOpensteerRuntimeConfig({
|
|
33500
34265
|
...provider === void 0 ? {} : { provider },
|
|
33501
|
-
|
|
34266
|
+
environment
|
|
33502
34267
|
});
|
|
33503
34268
|
if (runtimeConfig.provider.mode === "cloud") {
|
|
33504
34269
|
this.browserManager = void 0;
|
|
33505
34270
|
this.runtime = createOpensteerSemanticRuntime({
|
|
33506
34271
|
...provider === void 0 ? {} : { provider },
|
|
33507
34272
|
...engineName === void 0 ? {} : { engine: engineName },
|
|
34273
|
+
environment,
|
|
33508
34274
|
runtimeOptions: {
|
|
33509
34275
|
...runtimeOptions
|
|
33510
34276
|
}
|
|
@@ -33524,6 +34290,7 @@ var Opensteer = class {
|
|
|
33524
34290
|
this.runtime = createOpensteerSemanticRuntime({
|
|
33525
34291
|
...provider === void 0 ? {} : { provider },
|
|
33526
34292
|
...engineName === void 0 ? {} : { engine: engineName },
|
|
34293
|
+
environment,
|
|
33527
34294
|
runtimeOptions: {
|
|
33528
34295
|
...runtimeOptions,
|
|
33529
34296
|
rootPath: this.browserManager.rootPath,
|
|
@@ -33865,7 +34632,7 @@ function normalizeTargetOptions(input) {
|
|
|
33865
34632
|
};
|
|
33866
34633
|
}
|
|
33867
34634
|
function delay2(ms) {
|
|
33868
|
-
return new Promise((
|
|
34635
|
+
return new Promise((resolve4) => setTimeout(resolve4, ms));
|
|
33869
34636
|
}
|
|
33870
34637
|
|
|
33871
34638
|
exports.CloudSessionProxy = CloudSessionProxy;
|
|
@@ -33896,8 +34663,10 @@ exports.clearPersistedSessionRecord = clearPersistedSessionRecord;
|
|
|
33896
34663
|
exports.cloneElementPath = cloneElementPath;
|
|
33897
34664
|
exports.cloneReplayElementPath = cloneReplayElementPath;
|
|
33898
34665
|
exports.cloneStructuralElementAnchor = cloneStructuralElementAnchor;
|
|
34666
|
+
exports.createArtifactStore = createArtifactStore;
|
|
33899
34667
|
exports.createDomRuntime = createDomRuntime;
|
|
33900
34668
|
exports.createFilesystemOpensteerWorkspace = createFilesystemOpensteerWorkspace;
|
|
34669
|
+
exports.createObservationStore = createObservationStore;
|
|
33901
34670
|
exports.createOpensteerExtractionDescriptorStore = createOpensteerExtractionDescriptorStore;
|
|
33902
34671
|
exports.createOpensteerSemanticRuntime = createOpensteerSemanticRuntime;
|
|
33903
34672
|
exports.defaultFallbackPolicy = defaultFallbackPolicy;
|
|
@@ -33913,7 +34682,9 @@ exports.inspectCdpEndpoint = inspectCdpEndpoint;
|
|
|
33913
34682
|
exports.isCurrentUrlField = isCurrentUrlField;
|
|
33914
34683
|
exports.isValidCssAttributeKey = isValidCssAttributeKey;
|
|
33915
34684
|
exports.listLocalChromeProfiles = listLocalChromeProfiles;
|
|
34685
|
+
exports.manifestToExternalBinaryLocation = manifestToExternalBinaryLocation;
|
|
33916
34686
|
exports.normalizeExtractedValue = normalizeExtractedValue;
|
|
34687
|
+
exports.normalizeObservabilityConfig = normalizeObservabilityConfig;
|
|
33917
34688
|
exports.normalizeOpensteerEngineName = normalizeOpensteerEngineName;
|
|
33918
34689
|
exports.normalizeOpensteerProviderMode = normalizeOpensteerProviderMode;
|
|
33919
34690
|
exports.normalizeWorkspaceId = normalizeWorkspaceId;
|